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 §ion) 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 §ion) 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