process.cc revision 10810
12632Sstever@eecs.umich.edu/*
22632Sstever@eecs.umich.edu * Copyright (c) 2014 Advanced Micro Devices, Inc.
32632Sstever@eecs.umich.edu * Copyright (c) 2012 ARM Limited
42632Sstever@eecs.umich.edu * All rights reserved
52632Sstever@eecs.umich.edu *
62632Sstever@eecs.umich.edu * The license below extends only to copyright in the software and shall
72632Sstever@eecs.umich.edu * not be construed as granting a license to any other intellectual
82632Sstever@eecs.umich.edu * property including but not limited to intellectual property relating
92632Sstever@eecs.umich.edu * to a hardware implementation of the functionality of the software
102632Sstever@eecs.umich.edu * licensed hereunder.  You may use the software subject to the license
112632Sstever@eecs.umich.edu * terms below provided that you ensure that this notice is replicated
122632Sstever@eecs.umich.edu * unmodified and in its entirety in all distributions of the software,
132632Sstever@eecs.umich.edu * modified or unmodified, in source code or in binary form.
142632Sstever@eecs.umich.edu *
152632Sstever@eecs.umich.edu * Copyright (c) 2001-2005 The Regents of The University of Michigan
162632Sstever@eecs.umich.edu * All rights reserved.
172632Sstever@eecs.umich.edu *
182632Sstever@eecs.umich.edu * Redistribution and use in source and binary forms, with or without
192632Sstever@eecs.umich.edu * modification, are permitted provided that the following conditions are
202632Sstever@eecs.umich.edu * met: redistributions of source code must retain the above copyright
212632Sstever@eecs.umich.edu * notice, this list of conditions and the following disclaimer;
222632Sstever@eecs.umich.edu * redistributions in binary form must reproduce the above copyright
232632Sstever@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the
242632Sstever@eecs.umich.edu * documentation and/or other materials provided with the distribution;
252632Sstever@eecs.umich.edu * neither the name of the copyright holders nor the names of its
262632Sstever@eecs.umich.edu * contributors may be used to endorse or promote products derived from
272632Sstever@eecs.umich.edu * this software without specific prior written permission.
282632Sstever@eecs.umich.edu *
292632Sstever@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
302632Sstever@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
312022SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
322022SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
332022SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
342022SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
352022SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
362469SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
372469SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
382469SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
392469SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
402516SN/A *
412516SN/A * Authors: Nathan Binkert
422944Sgblack@eecs.umich.edu *          Steve Reinhardt
432482SN/A *          Ali Saidi
443598Sgblack@eecs.umich.edu */
453056Sgblack@eecs.umich.edu
462469SN/A#include <fcntl.h>
473056Sgblack@eecs.umich.edu#include <unistd.h>
483056Sgblack@eecs.umich.edu
493056Sgblack@eecs.umich.edu#include <cstdio>
503598Sgblack@eecs.umich.edu#include <string>
512516SN/A
523056Sgblack@eecs.umich.edu#include "base/loader/object_file.hh"
533598Sgblack@eecs.umich.edu#include "base/loader/symtab.hh"
543056Sgblack@eecs.umich.edu#include "base/intmath.hh"
553056Sgblack@eecs.umich.edu#include "base/statistics.hh"
563056Sgblack@eecs.umich.edu#include "config/the_isa.hh"
573056Sgblack@eecs.umich.edu#include "cpu/thread_context.hh"
583056Sgblack@eecs.umich.edu#include "mem/page_table.hh"
593056Sgblack@eecs.umich.edu#include "mem/multi_level_page_table.hh"
603056Sgblack@eecs.umich.edu#include "mem/se_translating_port_proxy.hh"
613598Sgblack@eecs.umich.edu#include "params/LiveProcess.hh"
623056Sgblack@eecs.umich.edu#include "params/Process.hh"
633056Sgblack@eecs.umich.edu#include "sim/debug.hh"
643598Sgblack@eecs.umich.edu#include "sim/process.hh"
653056Sgblack@eecs.umich.edu#include "sim/process_impl.hh"
663056Sgblack@eecs.umich.edu#include "sim/stats.hh"
673056Sgblack@eecs.umich.edu#include "sim/syscall_emul.hh"
683056Sgblack@eecs.umich.edu#include "sim/system.hh"
693056Sgblack@eecs.umich.edu
703056Sgblack@eecs.umich.edu#if THE_ISA == ALPHA_ISA
713056Sgblack@eecs.umich.edu#include "arch/alpha/linux/process.hh"
723056Sgblack@eecs.umich.edu#include "arch/alpha/tru64/process.hh"
733056Sgblack@eecs.umich.edu#elif THE_ISA == SPARC_ISA
743056Sgblack@eecs.umich.edu#include "arch/sparc/linux/process.hh"
753056Sgblack@eecs.umich.edu#include "arch/sparc/solaris/process.hh"
763056Sgblack@eecs.umich.edu#elif THE_ISA == MIPS_ISA
773056Sgblack@eecs.umich.edu#include "arch/mips/linux/process.hh"
783056Sgblack@eecs.umich.edu#elif THE_ISA == ARM_ISA
793765Sgblack@eecs.umich.edu#include "arch/arm/linux/process.hh"
803765Sgblack@eecs.umich.edu#include "arch/arm/freebsd/process.hh"
813056Sgblack@eecs.umich.edu#elif THE_ISA == X86_ISA
823765Sgblack@eecs.umich.edu#include "arch/x86/linux/process.hh"
833056Sgblack@eecs.umich.edu#elif THE_ISA == POWER_ISA
843765Sgblack@eecs.umich.edu#include "arch/power/linux/process.hh"
853765Sgblack@eecs.umich.edu#else
863056Sgblack@eecs.umich.edu#error "THE_ISA not set"
873765Sgblack@eecs.umich.edu#endif
883056Sgblack@eecs.umich.edu
893056Sgblack@eecs.umich.edu
902482SN/Ausing namespace std;
913598Sgblack@eecs.umich.eduusing namespace TheISA;
923598Sgblack@eecs.umich.edu
933598Sgblack@eecs.umich.edu// current number of allocated processes
943598Sgblack@eecs.umich.eduint num_processes = 0;
953598Sgblack@eecs.umich.edu
963598Sgblack@eecs.umich.edutemplate<class IntType>
973598Sgblack@eecs.umich.eduAuxVector<IntType>::AuxVector(IntType type, IntType val)
983598Sgblack@eecs.umich.edu{
993598Sgblack@eecs.umich.edu    a_type = TheISA::htog(type);
1003598Sgblack@eecs.umich.edu    a_val = TheISA::htog(val);
1013598Sgblack@eecs.umich.edu}
1023598Sgblack@eecs.umich.edu
1033598Sgblack@eecs.umich.edutemplate struct AuxVector<uint32_t>;
1043598Sgblack@eecs.umich.edutemplate struct AuxVector<uint64_t>;
1053598Sgblack@eecs.umich.edu
1063598Sgblack@eecs.umich.eduProcess::Process(ProcessParams * params)
1073598Sgblack@eecs.umich.edu    : SimObject(params), system(params->system),
1083598Sgblack@eecs.umich.edu      brk_point(0), stack_base(0), stack_size(0), stack_min(0),
1093598Sgblack@eecs.umich.edu      max_stack_size(params->max_stack_size),
1103598Sgblack@eecs.umich.edu      next_thread_stack_base(0),
1113598Sgblack@eecs.umich.edu      M5_pid(system->allocatePID()),
1123598Sgblack@eecs.umich.edu      useArchPT(params->useArchPT),
1133598Sgblack@eecs.umich.edu      kvmInSE(params->kvmInSE),
1143598Sgblack@eecs.umich.edu      pTable(useArchPT ?
1153598Sgblack@eecs.umich.edu        static_cast<PageTableBase *>(new ArchPageTable(name(), M5_pid, system)) :
1163598Sgblack@eecs.umich.edu        static_cast<PageTableBase *>(new FuncPageTable(name(), M5_pid)) ),
1173598Sgblack@eecs.umich.edu      initVirtMem(system->getSystemPort(), this,
1183598Sgblack@eecs.umich.edu                  SETranslatingPortProxy::Always)
1193598Sgblack@eecs.umich.edu{
1203598Sgblack@eecs.umich.edu    string in = params->input;
1213598Sgblack@eecs.umich.edu    string out = params->output;
1223598Sgblack@eecs.umich.edu    string err = params->errout;
1232516SN/A
1242516SN/A    // initialize file descriptors to default: same as simulator
1252516SN/A    int stdin_fd, stdout_fd, stderr_fd;
1262516SN/A
1272482SN/A    if (in == "stdin" || in == "cin")
1282482SN/A        stdin_fd = STDIN_FILENO;
1292591SN/A    else if (in == "None")
1302516SN/A        stdin_fd = -1;
1312580SN/A    else
1322580SN/A        stdin_fd = Process::openInputFile(in);
1332482SN/A
1342482SN/A    if (out == "stdout" || out == "cout")
1352591SN/A        stdout_fd = STDOUT_FILENO;
1362516SN/A    else if (out == "stderr" || out == "cerr")
1372580SN/A        stdout_fd = STDERR_FILENO;
1382580SN/A    else if (out == "None")
1392482SN/A        stdout_fd = -1;
1402482SN/A    else
1412591SN/A        stdout_fd = Process::openOutputFile(out);
1422516SN/A
1432580SN/A    if (err == "stdout" || err == "cout")
1442580SN/A        stderr_fd = STDOUT_FILENO;
1452482SN/A    else if (err == "stderr" || err == "cerr")
1462482SN/A        stderr_fd = STDERR_FILENO;
1472591SN/A    else if (err == "None")
1482516SN/A        stderr_fd = -1;
1492580SN/A    else if (err == out)
1502580SN/A        stderr_fd = stdout_fd;
1512482SN/A    else
1522482SN/A        stderr_fd = Process::openOutputFile(err);
1532591SN/A
1542516SN/A    // initialize first 3 fds (stdin, stdout, stderr)
1552580SN/A    Process::FdMap *fdo = &fd_map[STDIN_FILENO];
1562580SN/A    fdo->fd = stdin_fd;
1572482SN/A    fdo->filename = in;
1582482SN/A    fdo->flags = O_RDONLY;
1592591SN/A    fdo->mode = -1;
1602516SN/A    fdo->fileOffset = 0;
1612580SN/A
1622580SN/A    fdo =  &fd_map[STDOUT_FILENO];
1632482SN/A    fdo->fd = stdout_fd;
1642469SN/A    fdo->filename = out;
1652482SN/A    fdo->flags =  O_WRONLY | O_CREAT | O_TRUNC;
1662516SN/A    fdo->mode = 0774;
1673042Sgblack@eecs.umich.edu    fdo->fileOffset = 0;
1682516SN/A
1692516SN/A    fdo = &fd_map[STDERR_FILENO];
1702469SN/A    fdo->fd = stderr_fd;
1712944Sgblack@eecs.umich.edu    fdo->filename = err;
1722516SN/A    fdo->flags = O_WRONLY;
1732516SN/A    fdo->mode = -1;
1742469SN/A    fdo->fileOffset = 0;
1752469SN/A
1762482SN/A
1772482SN/A    // mark remaining fds as free
1782974Sgblack@eecs.umich.edu    for (int i = 3; i <= MAX_FD; ++i) {
1792974Sgblack@eecs.umich.edu        fdo = &fd_map[i];
1802974Sgblack@eecs.umich.edu        fdo->fd = -1;
1812526SN/A    }
1822974Sgblack@eecs.umich.edu
1832974Sgblack@eecs.umich.edu    mmap_start = mmap_end = 0;
1842974Sgblack@eecs.umich.edu    nxm_start = nxm_end = 0;
1852646Ssaidi@eecs.umich.edu    // other parameters will be initialized when the program is loaded
1862974Sgblack@eecs.umich.edu}
1872469SN/A
1882516SN/A
1892646Ssaidi@eecs.umich.eduvoid
1902482SN/AProcess::regStats()
1912469SN/A{
1922516SN/A    using namespace Stats;
1932646Ssaidi@eecs.umich.edu
1942482SN/A    num_syscalls
1952954Sgblack@eecs.umich.edu        .name(name() + ".num_syscalls")
1962469SN/A        .desc("Number of system calls")
1972516SN/A        ;
1982516SN/A}
1992482SN/A
2002469SN/A//
2012516SN/A// static helper functions
2022482SN/A//
2032482SN/Aint
2042646Ssaidi@eecs.umich.eduProcess::openInputFile(const string &filename)
2052482SN/A{
2062482SN/A    int fd = open(filename.c_str(), O_RDONLY);
2072482SN/A
2082482SN/A    if (fd == -1) {
2092482SN/A        perror(NULL);
2102615SN/A        cerr << "unable to open \"" << filename << "\" for reading\n";
2112469SN/A        fatal("can't open input file");
2122469SN/A    }
2132482SN/A
2142646Ssaidi@eecs.umich.edu    return fd;
2152482SN/A}
2162482SN/A
2172482SN/A
2182588SN/Aint
2192482SN/AProcess::openOutputFile(const string &filename)
2202526SN/A{
2212469SN/A    int fd = open(filename.c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0664);
2222482SN/A
2232469SN/A    if (fd == -1) {
2242516SN/A        perror(NULL);
2252469SN/A        cerr << "unable to open \"" << filename << "\" for writing\n";
2262580SN/A        fatal("can't open output file");
2272469SN/A    }
2282580SN/A
2292469SN/A    return fd;
2302526SN/A}
2312482SN/A
2322482SN/AThreadContext *
2332482SN/AProcess::findFreeContext()
2342469SN/A{
2352580SN/A    int size = contextIds.size();
2362580SN/A    ThreadContext *tc;
2372580SN/A    for (int i = 0; i < size; ++i) {
2382580SN/A        tc = system->getThreadContext(contextIds[i]);
2392580SN/A        if (tc->status() == ThreadContext::Halted) {
2402580SN/A            // inactive context, free to use
2412580SN/A            return tc;
2422526SN/A        }
2432482SN/A    }
2442482SN/A    return NULL;
2452482SN/A}
2462469SN/A
2472516SN/Avoid
2482646Ssaidi@eecs.umich.eduProcess::initState()
2492469SN/A{
2502580SN/A    if (contextIds.empty())
2512469SN/A        fatal("Process %s is not associated with any HW contexts!\n", name());
2522580SN/A
2532580SN/A    // first thread context for this process... initialize & enable
2542469SN/A    ThreadContext *tc = system->getThreadContext(contextIds[0]);
2552526SN/A
2563765Sgblack@eecs.umich.edu    // mark this context as active so it will start ticking.
2572615SN/A    tc->activate();
2582615SN/A
2593765Sgblack@eecs.umich.edu    pTable->initState(tc);
2603765Sgblack@eecs.umich.edu}
2612615SN/A
2622615SN/A// map simulator fd sim_fd to target fd tgt_fd
2633765Sgblack@eecs.umich.eduvoid
2642469SN/AProcess::dup_fd(int sim_fd, int tgt_fd)
2652516SN/A{
2662646Ssaidi@eecs.umich.edu    if (tgt_fd < 0 || tgt_fd > MAX_FD)
2672954Sgblack@eecs.umich.edu        panic("Process::dup_fd tried to dup past MAX_FD (%d)", tgt_fd);
2682580SN/A
2692469SN/A    Process::FdMap *fdo = &fd_map[tgt_fd];
2702580SN/A    fdo->fd = sim_fd;
2712469SN/A}
2722526SN/A
2733765Sgblack@eecs.umich.edu
2742615SN/A// generate new target fd for sim_fd
2753765Sgblack@eecs.umich.eduint
2762469SN/AProcess::alloc_fd(int sim_fd, const string& filename, int flags, int mode,
2772615SN/A                  bool pipe)
2782989Ssaidi@eecs.umich.edu{
2792469SN/A    // in case open() returns an error, don't allocate a new fd
2802469SN/A    if (sim_fd == -1)
2812224SN/A        return -1;
2822646Ssaidi@eecs.umich.edu
2832516SN/A    // find first free target fd
2842516SN/A    for (int free_fd = 0; free_fd <= MAX_FD; ++free_fd) {
2852516SN/A        Process::FdMap *fdo = &fd_map[free_fd];
2862469SN/A        if (fdo->fd == -1 && fdo->driver == NULL) {
2872469SN/A            fdo->fd = sim_fd;
2882469SN/A            fdo->filename = filename;
2892469SN/A            fdo->mode = mode;
2902469SN/A            fdo->fileOffset = 0;
2912526SN/A            fdo->flags = flags;
2922469SN/A            fdo->isPipe = pipe;
2932996Sgblack@eecs.umich.edu            fdo->readPipeSource = 0;
2942996Sgblack@eecs.umich.edu            return free_fd;
2952469SN/A        }
2962469SN/A    }
2972469SN/A
2982996Sgblack@eecs.umich.edu    panic("Process::alloc_fd: out of file descriptors!");
2992996Sgblack@eecs.umich.edu}
3002996Sgblack@eecs.umich.edu
3012996Sgblack@eecs.umich.edu
3022996Sgblack@eecs.umich.edu// free target fd (e.g., after close)
3032469SN/Avoid
3042469SN/AProcess::free_fd(int tgt_fd)
3052469SN/A{
3062469SN/A    Process::FdMap *fdo = &fd_map[tgt_fd];
3072469SN/A    if (fdo->fd == -1)
3082526SN/A        warn("Process::free_fd: request to free unused fd %d", tgt_fd);
3092469SN/A
3102516SN/A    fdo->fd = -1;
3112469SN/A    fdo->filename = "NULL";
3122469SN/A    fdo->mode = 0;
3133753Sgblack@eecs.umich.edu    fdo->fileOffset = 0;
3142469SN/A    fdo->flags = 0;
3152469SN/A    fdo->isPipe = false;
3162469SN/A    fdo->readPipeSource = 0;
3172526SN/A    fdo->driver = NULL;
3182469SN/A}
3192516SN/A
3202469SN/A
3212469SN/A// look up simulator fd for given target fd
3223753Sgblack@eecs.umich.eduint
3232469SN/AProcess::sim_fd(int tgt_fd)
3242469SN/A{
3252469SN/A    if (tgt_fd < 0 || tgt_fd > MAX_FD)
3262526SN/A        return -1;
3272469SN/A
3282996Sgblack@eecs.umich.edu    return fd_map[tgt_fd].fd;
3292996Sgblack@eecs.umich.edu}
3302954Sgblack@eecs.umich.edu
3312954Sgblack@eecs.umich.eduProcess::FdMap *
3322469SN/AProcess::sim_fd_obj(int tgt_fd)
3333753Sgblack@eecs.umich.edu{
3342469SN/A    if (tgt_fd < 0 || tgt_fd > MAX_FD)
3352469SN/A        return NULL;
3362996Sgblack@eecs.umich.edu
3372526SN/A    return &fd_map[tgt_fd];
3382469SN/A}
3392516SN/A
3402469SN/Avoid
3412469SN/AProcess::allocateMem(Addr vaddr, int64_t size, bool clobber)
3422469SN/A{
3433753Sgblack@eecs.umich.edu    int npages = divCeil(size, (int64_t)PageBytes);
3442469SN/A    Addr paddr = system->allocPhysPages(npages);
3452469SN/A    pTable->map(vaddr, paddr, size, clobber ? PageTableBase::Clobber : 0);
3462469SN/A}
3472526SN/A
3482469SN/Abool
3492516SN/AProcess::fixupStackFault(Addr vaddr)
3502469SN/A{
3512469SN/A    // Check if this is already on the stack and there's just no page there
3522516SN/A    // yet.
3533753Sgblack@eecs.umich.edu    if (vaddr >= stack_min && vaddr < stack_base) {
3542646Ssaidi@eecs.umich.edu        allocateMem(roundDown(vaddr, PageBytes), PageBytes);
3552469SN/A        return true;
3562469SN/A    }
3572646Ssaidi@eecs.umich.edu
3583753Sgblack@eecs.umich.edu    // We've accessed the next page of the stack, so extend it to include
3592469SN/A    // this address.
3602469SN/A    if (vaddr < stack_min && vaddr >= stack_base - max_stack_size) {
3612469SN/A        while (vaddr < stack_min) {
3622526SN/A            stack_min -= TheISA::PageBytes;
3632526SN/A            if (stack_base - stack_min > max_stack_size)
3642526SN/A                fatal("Maximum stack size exceeded\n");
3652526SN/A            allocateMem(stack_min, TheISA::PageBytes);
3662526SN/A            inform("Increasing stack size by one page.");
3672526SN/A        };
3682526SN/A        return true;
3692469SN/A    }
3702526SN/A    return false;
3712526SN/A}
3722526SN/A
3732526SN/A// find all offsets for currently open files and save them
3742526SN/Avoid
3752526SN/AProcess::fix_file_offsets()
3762526SN/A{
3772526SN/A    Process::FdMap *fdo_stdin = &fd_map[STDIN_FILENO];
3782954Sgblack@eecs.umich.edu    Process::FdMap *fdo_stdout = &fd_map[STDOUT_FILENO];
3793587Sgblack@eecs.umich.edu    Process::FdMap *fdo_stderr = &fd_map[STDERR_FILENO];
3803587Sgblack@eecs.umich.edu    string in = fdo_stdin->filename;
3813587Sgblack@eecs.umich.edu    string out = fdo_stdout->filename;
3823587Sgblack@eecs.umich.edu    string err = fdo_stderr->filename;
3833587Sgblack@eecs.umich.edu
3843587Sgblack@eecs.umich.edu    // initialize file descriptors to default: same as simulator
3853587Sgblack@eecs.umich.edu    int stdin_fd, stdout_fd, stderr_fd;
3863587Sgblack@eecs.umich.edu
3873587Sgblack@eecs.umich.edu    if (in == "stdin" || in == "cin")
3883587Sgblack@eecs.umich.edu        stdin_fd = STDIN_FILENO;
3893587Sgblack@eecs.umich.edu    else if (in == "NULL")
3903587Sgblack@eecs.umich.edu        stdin_fd = -1;
3913587Sgblack@eecs.umich.edu    else {
3923587Sgblack@eecs.umich.edu        // open standard in and seek to the right location
3933587Sgblack@eecs.umich.edu        stdin_fd = Process::openInputFile(in);
3943587Sgblack@eecs.umich.edu        if (lseek(stdin_fd, fdo_stdin->fileOffset, SEEK_SET) < 0)
3952954Sgblack@eecs.umich.edu            panic("Unable to seek to correct location in file: %s", in);
3962954Sgblack@eecs.umich.edu    }
3972954Sgblack@eecs.umich.edu
3983587Sgblack@eecs.umich.edu    if (out == "stdout" || out == "cout")
3993587Sgblack@eecs.umich.edu        stdout_fd = STDOUT_FILENO;
4003587Sgblack@eecs.umich.edu    else if (out == "stderr" || out == "cerr")
4013587Sgblack@eecs.umich.edu        stdout_fd = STDERR_FILENO;
4023587Sgblack@eecs.umich.edu    else if (out == "NULL")
4033587Sgblack@eecs.umich.edu        stdout_fd = -1;
4043587Sgblack@eecs.umich.edu    else {
4053587Sgblack@eecs.umich.edu        stdout_fd = Process::openOutputFile(out);
4062954Sgblack@eecs.umich.edu        if (lseek(stdout_fd, fdo_stdout->fileOffset, SEEK_SET) < 0)
4073587Sgblack@eecs.umich.edu            panic("Unable to seek to correct location in file: %s", out);
4083587Sgblack@eecs.umich.edu    }
4093587Sgblack@eecs.umich.edu
4103587Sgblack@eecs.umich.edu    if (err == "stdout" || err == "cout")
4113587Sgblack@eecs.umich.edu        stderr_fd = STDOUT_FILENO;
4123598Sgblack@eecs.umich.edu    else if (err == "stderr" || err == "cerr")
4133598Sgblack@eecs.umich.edu        stderr_fd = STDERR_FILENO;
4143598Sgblack@eecs.umich.edu    else if (err == "NULL")
4153598Sgblack@eecs.umich.edu        stderr_fd = -1;
4163598Sgblack@eecs.umich.edu    else if (err == out)
4173598Sgblack@eecs.umich.edu        stderr_fd = stdout_fd;
4183598Sgblack@eecs.umich.edu    else {
4193598Sgblack@eecs.umich.edu        stderr_fd = Process::openOutputFile(err);
4203598Sgblack@eecs.umich.edu        if (lseek(stderr_fd, fdo_stderr->fileOffset, SEEK_SET) < 0)
4212954Sgblack@eecs.umich.edu            panic("Unable to seek to correct location in file: %s", err);
4223587Sgblack@eecs.umich.edu    }
4233587Sgblack@eecs.umich.edu
4243587Sgblack@eecs.umich.edu    fdo_stdin->fd = stdin_fd;
4253587Sgblack@eecs.umich.edu    fdo_stdout->fd = stdout_fd;
4263587Sgblack@eecs.umich.edu    fdo_stderr->fd = stderr_fd;
4273587Sgblack@eecs.umich.edu
4283587Sgblack@eecs.umich.edu
4293587Sgblack@eecs.umich.edu    for (int free_fd = 3; free_fd <= MAX_FD; ++free_fd) {
4303587Sgblack@eecs.umich.edu        Process::FdMap *fdo = &fd_map[free_fd];
4313587Sgblack@eecs.umich.edu        if (fdo->fd != -1) {
4323587Sgblack@eecs.umich.edu            if (fdo->isPipe){
4333587Sgblack@eecs.umich.edu                if (fdo->filename == "PIPE-WRITE")
4343587Sgblack@eecs.umich.edu                    continue;
4353587Sgblack@eecs.umich.edu                else {
4363587Sgblack@eecs.umich.edu                    assert (fdo->filename == "PIPE-READ");
4373587Sgblack@eecs.umich.edu                    //create a new pipe
4383587Sgblack@eecs.umich.edu                    int fds[2];
4393587Sgblack@eecs.umich.edu                    int pipe_retval = pipe(fds);
4403587Sgblack@eecs.umich.edu
4413587Sgblack@eecs.umich.edu                    if (pipe_retval < 0) {
4423587Sgblack@eecs.umich.edu                        // error
4433587Sgblack@eecs.umich.edu                        panic("Unable to create new pipe.");
4443587Sgblack@eecs.umich.edu                    }
4453587Sgblack@eecs.umich.edu                    fdo->fd = fds[0]; //set read pipe
4463587Sgblack@eecs.umich.edu                    Process::FdMap *fdo_write = &fd_map[fdo->readPipeSource];
4473587Sgblack@eecs.umich.edu                    if (fdo_write->filename != "PIPE-WRITE")
4483587Sgblack@eecs.umich.edu                        panic ("Couldn't find write end of the pipe");
4493587Sgblack@eecs.umich.edu
4503587Sgblack@eecs.umich.edu                    fdo_write->fd = fds[1];//set write pipe
4513587Sgblack@eecs.umich.edu               }
4523587Sgblack@eecs.umich.edu            } else {
4533587Sgblack@eecs.umich.edu                //Open file
4543587Sgblack@eecs.umich.edu                int fd = open(fdo->filename.c_str(), fdo->flags, fdo->mode);
4553587Sgblack@eecs.umich.edu
4563587Sgblack@eecs.umich.edu                if (fd == -1)
4573587Sgblack@eecs.umich.edu                    panic("Unable to open file: %s", fdo->filename);
4583587Sgblack@eecs.umich.edu                fdo->fd = fd;
4593587Sgblack@eecs.umich.edu
4603587Sgblack@eecs.umich.edu                //Seek to correct location before checkpoint
4613587Sgblack@eecs.umich.edu                if (lseek(fd, fdo->fileOffset, SEEK_SET) < 0)
4623587Sgblack@eecs.umich.edu                    panic("Unable to seek to correct location in file: %s",
4633587Sgblack@eecs.umich.edu                          fdo->filename);
4643587Sgblack@eecs.umich.edu            }
4653587Sgblack@eecs.umich.edu        }
4663587Sgblack@eecs.umich.edu    }
4673587Sgblack@eecs.umich.edu}
4683587Sgblack@eecs.umich.edu
4693587Sgblack@eecs.umich.eduvoid
4703587Sgblack@eecs.umich.eduProcess::find_file_offsets()
4713587Sgblack@eecs.umich.edu{
4723587Sgblack@eecs.umich.edu    for (int free_fd = 0; free_fd <= MAX_FD; ++free_fd) {
4732526SN/A        Process::FdMap *fdo = &fd_map[free_fd];
4742526SN/A        if (fdo->fd != -1) {
4752526SN/A            fdo->fileOffset = lseek(fdo->fd, 0, SEEK_CUR);
4762526SN/A        } else {
4772646Ssaidi@eecs.umich.edu            fdo->filename = "NULL";
4782526SN/A            fdo->fileOffset = 0;
4792646Ssaidi@eecs.umich.edu        }
4802526SN/A    }
4812526SN/A}
4822526SN/A
4832469SN/Avoid
4842526SN/AProcess::setReadPipeSource(int read_pipe_fd, int source_fd)
4852526SN/A{
4862526SN/A    Process::FdMap *fdo = &fd_map[read_pipe_fd];
4872526SN/A    fdo->readPipeSource = source_fd;
4882646Ssaidi@eecs.umich.edu}
4892591SN/A
4902591SN/Avoid
4912591SN/AProcess::FdMap::serialize(std::ostream &os)
4922526SN/A{
4932526SN/A    SERIALIZE_SCALAR(fd);
4942646Ssaidi@eecs.umich.edu    SERIALIZE_SCALAR(isPipe);
4952591SN/A    SERIALIZE_SCALAR(filename);
4962591SN/A    SERIALIZE_SCALAR(flags);
4972591SN/A    SERIALIZE_SCALAR(readPipeSource);
4982526SN/A    SERIALIZE_SCALAR(fileOffset);
4992224SN/A}
5002526SN/A
5012526SN/Avoid
5022615SN/AProcess::FdMap::unserialize(Checkpoint *cp, const std::string &section)
5032615SN/A{
5042526SN/A    UNSERIALIZE_SCALAR(fd);
5052526SN/A    UNSERIALIZE_SCALAR(isPipe);
5062526SN/A    UNSERIALIZE_SCALAR(filename);
5072526SN/A    UNSERIALIZE_SCALAR(flags);
5082526SN/A    UNSERIALIZE_SCALAR(readPipeSource);
5092526SN/A    UNSERIALIZE_SCALAR(fileOffset);
5102526SN/A}
5112526SN/A
5122469SN/Avoid
5132526SN/AProcess::serialize(std::ostream &os)
5142526SN/A{
5152516SN/A    SERIALIZE_SCALAR(brk_point);
5162591SN/A    SERIALIZE_SCALAR(stack_base);
5172516SN/A    SERIALIZE_SCALAR(stack_size);
5182526SN/A    SERIALIZE_SCALAR(stack_min);
5192526SN/A    SERIALIZE_SCALAR(next_thread_stack_base);
5202526SN/A    SERIALIZE_SCALAR(mmap_start);
5212615SN/A    SERIALIZE_SCALAR(mmap_end);
5222615SN/A    SERIALIZE_SCALAR(nxm_start);
5232615SN/A    SERIALIZE_SCALAR(nxm_end);
5242615SN/A    find_file_offsets();
5252615SN/A    pTable->serialize(os);
5262615SN/A    for (int x = 0; x <= MAX_FD; x++) {
5272526SN/A        nameOut(os, csprintf("%s.FdMap%d", name(), x));
5283587Sgblack@eecs.umich.edu        fd_map[x].serialize(os);
5293587Sgblack@eecs.umich.edu    }
5303587Sgblack@eecs.umich.edu    SERIALIZE_SCALAR(M5_pid);
5313587Sgblack@eecs.umich.edu
5323587Sgblack@eecs.umich.edu}
5333587Sgblack@eecs.umich.edu
5343587Sgblack@eecs.umich.eduvoid
5353587Sgblack@eecs.umich.eduProcess::unserialize(Checkpoint *cp, const std::string &section)
5363587Sgblack@eecs.umich.edu{
5373587Sgblack@eecs.umich.edu    UNSERIALIZE_SCALAR(brk_point);
5383587Sgblack@eecs.umich.edu    UNSERIALIZE_SCALAR(stack_base);
5393587Sgblack@eecs.umich.edu    UNSERIALIZE_SCALAR(stack_size);
5403587Sgblack@eecs.umich.edu    UNSERIALIZE_SCALAR(stack_min);
5413587Sgblack@eecs.umich.edu    UNSERIALIZE_SCALAR(next_thread_stack_base);
5423587Sgblack@eecs.umich.edu    UNSERIALIZE_SCALAR(mmap_start);
5433587Sgblack@eecs.umich.edu    UNSERIALIZE_SCALAR(mmap_end);
5443587Sgblack@eecs.umich.edu    UNSERIALIZE_SCALAR(nxm_start);
5453587Sgblack@eecs.umich.edu    UNSERIALIZE_SCALAR(nxm_end);
5463587Sgblack@eecs.umich.edu    pTable->unserialize(cp, section);
5473587Sgblack@eecs.umich.edu    for (int x = 0; x <= MAX_FD; x++) {
5483587Sgblack@eecs.umich.edu        fd_map[x].unserialize(cp, csprintf("%s.FdMap%d", section, x));
5493587Sgblack@eecs.umich.edu    }
5503587Sgblack@eecs.umich.edu    fix_file_offsets();
5513587Sgblack@eecs.umich.edu    UNSERIALIZE_OPT_SCALAR(M5_pid);
5523587Sgblack@eecs.umich.edu    // The above returns a bool so that you could do something if you don't
5533587Sgblack@eecs.umich.edu    // find the param in the checkpoint if you wanted to, like set a default
5543587Sgblack@eecs.umich.edu    // but in this case we'll just stick with the instantianted value if not
5553598Sgblack@eecs.umich.edu    // found.
5563598Sgblack@eecs.umich.edu}
5573598Sgblack@eecs.umich.edu
5583598Sgblack@eecs.umich.edu
5593598Sgblack@eecs.umich.edubool
5603598Sgblack@eecs.umich.eduProcess::map(Addr vaddr, Addr paddr, int size, bool cacheable)
5613598Sgblack@eecs.umich.edu{
5623598Sgblack@eecs.umich.edu    pTable->map(vaddr, paddr, size,
5633598Sgblack@eecs.umich.edu                cacheable ? 0 : PageTableBase::Uncacheable);
5643598Sgblack@eecs.umich.edu    return true;
5653587Sgblack@eecs.umich.edu}
5662526SN/A
5673417Sgblack@eecs.umich.edu
5683417Sgblack@eecs.umich.edu////////////////////////////////////////////////////////////////////////
5693417Sgblack@eecs.umich.edu//
5703417Sgblack@eecs.umich.edu// LiveProcess member definitions
5713417Sgblack@eecs.umich.edu//
5723417Sgblack@eecs.umich.edu////////////////////////////////////////////////////////////////////////
5733417Sgblack@eecs.umich.edu
5743417Sgblack@eecs.umich.edu
5753417Sgblack@eecs.umich.eduLiveProcess::LiveProcess(LiveProcessParams *params, ObjectFile *_objFile)
5763598Sgblack@eecs.umich.edu    : Process(params), objFile(_objFile),
5773417Sgblack@eecs.umich.edu      argv(params->cmd), envp(params->env), cwd(params->cwd),
5783417Sgblack@eecs.umich.edu      __uid(params->uid), __euid(params->euid),
5793417Sgblack@eecs.umich.edu      __gid(params->gid), __egid(params->egid),
5803417Sgblack@eecs.umich.edu      __pid(params->pid), __ppid(params->ppid),
5813417Sgblack@eecs.umich.edu      drivers(params->drivers)
5823417Sgblack@eecs.umich.edu{
5833417Sgblack@eecs.umich.edu
5843417Sgblack@eecs.umich.edu    // load up symbols, if any... these may be used for debugging or
5852526SN/A    // profiling.
5863587Sgblack@eecs.umich.edu    if (!debugSymbolTable) {
5873587Sgblack@eecs.umich.edu        debugSymbolTable = new SymbolTable();
5883587Sgblack@eecs.umich.edu        if (!objFile->loadGlobalSymbols(debugSymbolTable) ||
5893587Sgblack@eecs.umich.edu            !objFile->loadLocalSymbols(debugSymbolTable) ||
5903587Sgblack@eecs.umich.edu            !objFile->loadWeakSymbols(debugSymbolTable)) {
5913587Sgblack@eecs.umich.edu            // didn't load any symbols
5923587Sgblack@eecs.umich.edu            delete debugSymbolTable;
5933587Sgblack@eecs.umich.edu            debugSymbolTable = NULL;
5943587Sgblack@eecs.umich.edu        }
5953587Sgblack@eecs.umich.edu    }
5963587Sgblack@eecs.umich.edu}
5973587Sgblack@eecs.umich.edu
5983587Sgblack@eecs.umich.eduvoid
5993587Sgblack@eecs.umich.eduLiveProcess::syscall(int64_t callnum, ThreadContext *tc)
6003587Sgblack@eecs.umich.edu{
6013587Sgblack@eecs.umich.edu    num_syscalls++;
6023587Sgblack@eecs.umich.edu
6033587Sgblack@eecs.umich.edu    SyscallDesc *desc = getDesc(callnum);
6043587Sgblack@eecs.umich.edu    if (desc == NULL)
6053587Sgblack@eecs.umich.edu        fatal("Syscall %d out of range", callnum);
6063587Sgblack@eecs.umich.edu
6073587Sgblack@eecs.umich.edu    desc->doSyscall(callnum, this, tc);
6083587Sgblack@eecs.umich.edu}
6093587Sgblack@eecs.umich.edu
6103587Sgblack@eecs.umich.eduIntReg
6113587Sgblack@eecs.umich.eduLiveProcess::getSyscallArg(ThreadContext *tc, int &i, int width)
6123587Sgblack@eecs.umich.edu{
6133587Sgblack@eecs.umich.edu    return getSyscallArg(tc, i);
6143587Sgblack@eecs.umich.edu}
6153587Sgblack@eecs.umich.edu
6163587Sgblack@eecs.umich.edu
6173587Sgblack@eecs.umich.eduEmulatedDriver *
6183587Sgblack@eecs.umich.eduLiveProcess::findDriver(std::string filename)
6193587Sgblack@eecs.umich.edu{
6203587Sgblack@eecs.umich.edu    for (EmulatedDriver *d : drivers) {
6213587Sgblack@eecs.umich.edu        if (d->match(filename))
6223587Sgblack@eecs.umich.edu            return d;
6233587Sgblack@eecs.umich.edu    }
6243587Sgblack@eecs.umich.edu
6253587Sgblack@eecs.umich.edu    return NULL;
6263587Sgblack@eecs.umich.edu}
6273587Sgblack@eecs.umich.edu
6283587Sgblack@eecs.umich.edu
6293587Sgblack@eecs.umich.eduLiveProcess *
6303587Sgblack@eecs.umich.eduLiveProcess::create(LiveProcessParams * params)
6313587Sgblack@eecs.umich.edu{
6323587Sgblack@eecs.umich.edu    LiveProcess *process = NULL;
6333587Sgblack@eecs.umich.edu
6343587Sgblack@eecs.umich.edu    string executable =
6353587Sgblack@eecs.umich.edu        params->executable == "" ? params->cmd[0] : params->executable;
6363587Sgblack@eecs.umich.edu    ObjectFile *objFile = createObjectFile(executable);
6373587Sgblack@eecs.umich.edu    if (objFile == NULL) {
6383587Sgblack@eecs.umich.edu        fatal("Can't load object file %s", executable);
6393587Sgblack@eecs.umich.edu    }
6403587Sgblack@eecs.umich.edu
6413587Sgblack@eecs.umich.edu    if (objFile->isDynamic())
6423587Sgblack@eecs.umich.edu       fatal("Object file is a dynamic executable however only static "
6433587Sgblack@eecs.umich.edu             "executables are supported!\n       Please recompile your "
6443587Sgblack@eecs.umich.edu             "executable as a static binary and try again.\n");
6453587Sgblack@eecs.umich.edu
6463587Sgblack@eecs.umich.edu#if THE_ISA == ALPHA_ISA
6473587Sgblack@eecs.umich.edu    if (objFile->getArch() != ObjectFile::Alpha)
6483587Sgblack@eecs.umich.edu        fatal("Object file architecture does not match compiled ISA (Alpha).");
6493587Sgblack@eecs.umich.edu
6502954Sgblack@eecs.umich.edu    switch (objFile->getOpSys()) {
6512963Sgblack@eecs.umich.edu      case ObjectFile::Tru64:
6522963Sgblack@eecs.umich.edu        process = new AlphaTru64Process(params, objFile);
6533279Sgblack@eecs.umich.edu        break;
6542963Sgblack@eecs.umich.edu
6552963Sgblack@eecs.umich.edu      case ObjectFile::UnknownOpSys:
6562963Sgblack@eecs.umich.edu        warn("Unknown operating system; assuming Linux.");
6572963Sgblack@eecs.umich.edu        // fall through
6582963Sgblack@eecs.umich.edu      case ObjectFile::Linux:
6593057Sgblack@eecs.umich.edu        process = new AlphaLinuxProcess(params, objFile);
6602963Sgblack@eecs.umich.edu        break;
6612963Sgblack@eecs.umich.edu
6622963Sgblack@eecs.umich.edu      default:
6632963Sgblack@eecs.umich.edu        fatal("Unknown/unsupported operating system.");
6642963Sgblack@eecs.umich.edu    }
6652963Sgblack@eecs.umich.edu#elif THE_ISA == SPARC_ISA
6663279Sgblack@eecs.umich.edu    if (objFile->getArch() != ObjectFile::SPARC64 &&
6672963Sgblack@eecs.umich.edu        objFile->getArch() != ObjectFile::SPARC32)
6682963Sgblack@eecs.umich.edu        fatal("Object file architecture does not match compiled ISA (SPARC).");
6692963Sgblack@eecs.umich.edu    switch (objFile->getOpSys()) {
6702963Sgblack@eecs.umich.edu      case ObjectFile::UnknownOpSys:
6712963Sgblack@eecs.umich.edu        warn("Unknown operating system; assuming Linux.");
6723057Sgblack@eecs.umich.edu        // fall through
6732963Sgblack@eecs.umich.edu      case ObjectFile::Linux:
6742963Sgblack@eecs.umich.edu        if (objFile->getArch() == ObjectFile::SPARC64) {
6752963Sgblack@eecs.umich.edu            process = new Sparc64LinuxProcess(params, objFile);
6762963Sgblack@eecs.umich.edu        } else {
6772963Sgblack@eecs.umich.edu            process = new Sparc32LinuxProcess(params, objFile);
6782963Sgblack@eecs.umich.edu        }
6793279Sgblack@eecs.umich.edu        break;
6802963Sgblack@eecs.umich.edu
6812963Sgblack@eecs.umich.edu
6822963Sgblack@eecs.umich.edu      case ObjectFile::Solaris:
6832963Sgblack@eecs.umich.edu        process = new SparcSolarisProcess(params, objFile);
6842963Sgblack@eecs.umich.edu        break;
6853057Sgblack@eecs.umich.edu
6862963Sgblack@eecs.umich.edu      default:
6872963Sgblack@eecs.umich.edu        fatal("Unknown/unsupported operating system.");
6882963Sgblack@eecs.umich.edu    }
6892963Sgblack@eecs.umich.edu#elif THE_ISA == X86_ISA
6902963Sgblack@eecs.umich.edu    if (objFile->getArch() != ObjectFile::X86_64 &&
6913279Sgblack@eecs.umich.edu        objFile->getArch() != ObjectFile::I386)
6922963Sgblack@eecs.umich.edu        fatal("Object file architecture does not match compiled ISA (x86).");
6932963Sgblack@eecs.umich.edu    switch (objFile->getOpSys()) {
6943279Sgblack@eecs.umich.edu      case ObjectFile::UnknownOpSys:
6952963Sgblack@eecs.umich.edu        warn("Unknown operating system; assuming Linux.");
6962963Sgblack@eecs.umich.edu        // fall through
6973279Sgblack@eecs.umich.edu      case ObjectFile::Linux:
6982963Sgblack@eecs.umich.edu        if (objFile->getArch() == ObjectFile::X86_64) {
6992963Sgblack@eecs.umich.edu            process = new X86_64LinuxProcess(params, objFile);
7003279Sgblack@eecs.umich.edu        } else {
7012963Sgblack@eecs.umich.edu            process = new I386LinuxProcess(params, objFile);
7022963Sgblack@eecs.umich.edu        }
7033279Sgblack@eecs.umich.edu        break;
7042963Sgblack@eecs.umich.edu
7052963Sgblack@eecs.umich.edu      default:
7063279Sgblack@eecs.umich.edu        fatal("Unknown/unsupported operating system.");
7072963Sgblack@eecs.umich.edu    }
7082963Sgblack@eecs.umich.edu#elif THE_ISA == MIPS_ISA
7093279Sgblack@eecs.umich.edu    if (objFile->getArch() != ObjectFile::Mips)
7102963Sgblack@eecs.umich.edu        fatal("Object file architecture does not match compiled ISA (MIPS).");
7112963Sgblack@eecs.umich.edu    switch (objFile->getOpSys()) {
7122963Sgblack@eecs.umich.edu      case ObjectFile::UnknownOpSys:
7132963Sgblack@eecs.umich.edu        warn("Unknown operating system; assuming Linux.");
7142963Sgblack@eecs.umich.edu        // fall through
7152963Sgblack@eecs.umich.edu      case ObjectFile::Linux:
7163279Sgblack@eecs.umich.edu        process = new MipsLinuxProcess(params, objFile);
7172963Sgblack@eecs.umich.edu        break;
7182963Sgblack@eecs.umich.edu
7192963Sgblack@eecs.umich.edu      default:
7202963Sgblack@eecs.umich.edu        fatal("Unknown/unsupported operating system.");
7212963Sgblack@eecs.umich.edu    }
7222963Sgblack@eecs.umich.edu#elif THE_ISA == ARM_ISA
7233279Sgblack@eecs.umich.edu    ObjectFile::Arch arch = objFile->getArch();
7242963Sgblack@eecs.umich.edu    if (arch != ObjectFile::Arm && arch != ObjectFile::Thumb &&
7253279Sgblack@eecs.umich.edu        arch != ObjectFile::Arm64)
7262963Sgblack@eecs.umich.edu        fatal("Object file architecture does not match compiled ISA (ARM).");
7272963Sgblack@eecs.umich.edu    switch (objFile->getOpSys()) {
7283279Sgblack@eecs.umich.edu      case ObjectFile::UnknownOpSys:
7292963Sgblack@eecs.umich.edu        warn("Unknown operating system; assuming Linux.");
7303279Sgblack@eecs.umich.edu        // fall through
7312963Sgblack@eecs.umich.edu      case ObjectFile::Linux:
7322963Sgblack@eecs.umich.edu        if (arch == ObjectFile::Arm64) {
7332963Sgblack@eecs.umich.edu            process = new ArmLinuxProcess64(params, objFile,
7342963Sgblack@eecs.umich.edu                                            objFile->getArch());
7352963Sgblack@eecs.umich.edu        } else {
7363279Sgblack@eecs.umich.edu            process = new ArmLinuxProcess32(params, objFile,
7372963Sgblack@eecs.umich.edu                                            objFile->getArch());
7382963Sgblack@eecs.umich.edu        }
7393279Sgblack@eecs.umich.edu        break;
7402963Sgblack@eecs.umich.edu      case ObjectFile::FreeBSD:
7412963Sgblack@eecs.umich.edu        if (arch == ObjectFile::Arm64) {
7422963Sgblack@eecs.umich.edu            process = new ArmFreebsdProcess64(params, objFile,
7432963Sgblack@eecs.umich.edu                                              objFile->getArch());
7442954Sgblack@eecs.umich.edu        } else {
7452526SN/A            process = new ArmFreebsdProcess32(params, objFile,
7462954Sgblack@eecs.umich.edu                                              objFile->getArch());
7472954Sgblack@eecs.umich.edu        }
7482954Sgblack@eecs.umich.edu        break;
7492954Sgblack@eecs.umich.edu      case ObjectFile::LinuxArmOABI:
7502954Sgblack@eecs.umich.edu        fatal("M5 does not support ARM OABI binaries. Please recompile with an"
7512954Sgblack@eecs.umich.edu              " EABI compiler.");
7522954Sgblack@eecs.umich.edu      default:
7532954Sgblack@eecs.umich.edu        fatal("Unknown/unsupported operating system.");
7542954Sgblack@eecs.umich.edu    }
7552954Sgblack@eecs.umich.edu#elif THE_ISA == POWER_ISA
7562954Sgblack@eecs.umich.edu    if (objFile->getArch() != ObjectFile::Power)
7572954Sgblack@eecs.umich.edu        fatal("Object file architecture does not match compiled ISA (Power).");
7582954Sgblack@eecs.umich.edu    switch (objFile->getOpSys()) {
7592954Sgblack@eecs.umich.edu      case ObjectFile::UnknownOpSys:
7602954Sgblack@eecs.umich.edu        warn("Unknown operating system; assuming Linux.");
7612954Sgblack@eecs.umich.edu        // fall through
7622954Sgblack@eecs.umich.edu      case ObjectFile::Linux:
7632954Sgblack@eecs.umich.edu        process = new PowerLinuxProcess(params, objFile);
7643042Sgblack@eecs.umich.edu        break;
7652963Sgblack@eecs.umich.edu
7663042Sgblack@eecs.umich.edu      default:
7672963Sgblack@eecs.umich.edu        fatal("Unknown/unsupported operating system.");
7682963Sgblack@eecs.umich.edu    }
7692954Sgblack@eecs.umich.edu#else
7702963Sgblack@eecs.umich.edu#error "THE_ISA not set"
7712963Sgblack@eecs.umich.edu#endif
7723042Sgblack@eecs.umich.edu
7732963Sgblack@eecs.umich.edu    if (process == NULL)
7742963Sgblack@eecs.umich.edu        fatal("Unknown error creating process object.");
7752954Sgblack@eecs.umich.edu    return process;
7762954Sgblack@eecs.umich.edu}
7772954Sgblack@eecs.umich.edu
7782954Sgblack@eecs.umich.eduLiveProcess *
7792954Sgblack@eecs.umich.eduLiveProcessParams::create()
7802954Sgblack@eecs.umich.edu{
7812954Sgblack@eecs.umich.edu    return LiveProcess::create(this);
7822954Sgblack@eecs.umich.edu}
7832954Sgblack@eecs.umich.edu