process.cc revision 2800
12SN/A/* 210298Salexandru.dutu@amd.com * Copyright (c) 2001-2005 The Regents of The University of Michigan 38852Sandreas.hansson@arm.com * All rights reserved. 48852Sandreas.hansson@arm.com * 58852Sandreas.hansson@arm.com * Redistribution and use in source and binary forms, with or without 68852Sandreas.hansson@arm.com * modification, are permitted provided that the following conditions are 78852Sandreas.hansson@arm.com * met: redistributions of source code must retain the above copyright 88852Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer; 98852Sandreas.hansson@arm.com * redistributions in binary form must reproduce the above copyright 108852Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer in the 118852Sandreas.hansson@arm.com * documentation and/or other materials provided with the distribution; 128852Sandreas.hansson@arm.com * neither the name of the copyright holders nor the names of its 138852Sandreas.hansson@arm.com * contributors may be used to endorse or promote products derived from 148852Sandreas.hansson@arm.com * this software without specific prior written permission. 151762SN/A * 162SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272SN/A * 282SN/A * Authors: Nathan Binkert 292SN/A * Steve Reinhardt 302SN/A * Ali Saidi 312SN/A */ 322SN/A 332SN/A#include <unistd.h> 342SN/A#include <fcntl.h> 352SN/A 362SN/A#include <string> 372SN/A 382SN/A#include "base/intmath.hh" 392SN/A#include "base/loader/object_file.hh" 402665Ssaidi@eecs.umich.edu#include "base/loader/symtab.hh" 412665Ssaidi@eecs.umich.edu#include "base/statistics.hh" 422665Ssaidi@eecs.umich.edu#include "config/full_system.hh" 432665Ssaidi@eecs.umich.edu#include "cpu/thread_context.hh" 442SN/A#include "mem/page_table.hh" 452SN/A#include "mem/physical.hh" 468229Snate@binkert.org#include "mem/translating_port.hh" 472SN/A#include "sim/builder.hh" 486712Snate@binkert.org#include "sim/process.hh" 496712Snate@binkert.org#include "sim/stats.hh" 502SN/A#include "sim/syscall_emul.hh" 512SN/A#include "sim/system.hh" 5256SN/A 531158SN/A#include "arch/isa_specific.hh" 548229Snate@binkert.org#if THE_ISA == ALPHA_ISA 55146SN/A#include "arch/alpha/linux/process.hh" 566658Snate@binkert.org#include "arch/alpha/tru64/process.hh" 572680Sktlim@umich.edu#elif THE_ISA == SPARC_ISA 582378SN/A#include "arch/sparc/linux/process.hh" 5910298Salexandru.dutu@amd.com#include "arch/sparc/solaris/process.hh" 608706Sandreas.hansson@arm.com#elif THE_ISA == MIPS_ISA 618229Snate@binkert.org#include "arch/mips/linux/process.hh" 625154Sgblack@eecs.umich.edu#else 635512SMichael.Adler@intel.com#error "THE_ISA not set" 64360SN/A#endif 654434Ssaidi@eecs.umich.edu 66695SN/A 672093SN/Ausing namespace std; 682378SN/Ausing namespace TheISA; 692SN/A 702715Sstever@eecs.umich.edu// 712715Sstever@eecs.umich.edu// The purpose of this code is to fake the loader & syscall mechanism 722715Sstever@eecs.umich.edu// when there's no OS: thus there's no resone to use it in FULL_SYSTEM 732715Sstever@eecs.umich.edu// mode when we do have an OS 742715Sstever@eecs.umich.edu// 752715Sstever@eecs.umich.edu#if FULL_SYSTEM 762715Sstever@eecs.umich.edu#error "process.cc not compatible with FULL_SYSTEM" 772715Sstever@eecs.umich.edu#endif 785335Shines@cs.fsu.edu 795335Shines@cs.fsu.edu// current number of allocated processes 804157Sgblack@eecs.umich.eduint num_processes = 0; 814166Sgblack@eecs.umich.edu 826691Stjones1@inf.ed.ac.ukProcess::Process(const string &nm, 836691Stjones1@inf.ed.ac.uk System *_system, 842715Sstever@eecs.umich.edu int stdin_fd, // initial I/O descriptors 852715Sstever@eecs.umich.edu int stdout_fd, 862715Sstever@eecs.umich.edu int stderr_fd) 872715Sstever@eecs.umich.edu : SimObject(nm), system(_system) 882715Sstever@eecs.umich.edu{ 892SN/A // initialize first 3 fds (stdin, stdout, stderr) 902107SN/A fd_map[STDIN_FILENO] = stdin_fd; 912SN/A fd_map[STDOUT_FILENO] = stdout_fd; 922SN/A fd_map[STDERR_FILENO] = stderr_fd; 932SN/A 942SN/A // mark remaining fds as free 955758Shsul@eecs.umich.edu for (int i = 3; i <= MAX_FD; ++i) { 965771Shsul@eecs.umich.edu fd_map[i] = -1; 975758Shsul@eecs.umich.edu } 985758Shsul@eecs.umich.edu 995758Shsul@eecs.umich.edu mmap_start = mmap_end = 0; 1005758Shsul@eecs.umich.edu nxm_start = nxm_end = 0; 1015758Shsul@eecs.umich.edu pTable = new PageTable(system); 1028737Skoansin.tan@gmail.com // other parameters will be initialized when the program is loaded 1038737Skoansin.tan@gmail.com} 1045758Shsul@eecs.umich.edu 1055154Sgblack@eecs.umich.edu 1067532Ssteve.reinhardt@amd.comvoid 10710559Sandreas.hansson@arm.comProcess::regStats() 1088852Sandreas.hansson@arm.com{ 10910559Sandreas.hansson@arm.com using namespace Stats; 1108852Sandreas.hansson@arm.com 11110299Salexandru.dutu@amd.com num_syscalls 11210554Salexandru.dutu@amd.com .name(name() + ".PROG:num_syscalls") 11310299Salexandru.dutu@amd.com .desc("Number of system calls") 11410299Salexandru.dutu@amd.com ; 11510299Salexandru.dutu@amd.com} 1168852Sandreas.hansson@arm.com 1178852Sandreas.hansson@arm.com// 1182SN/A// static helper functions 1195154Sgblack@eecs.umich.edu// 1205154Sgblack@eecs.umich.eduint 1215514SMichael.Adler@intel.comProcess::openInputFile(const string &filename) 1225154Sgblack@eecs.umich.edu{ 1235154Sgblack@eecs.umich.edu int fd = open(filename.c_str(), O_RDONLY); 1245154Sgblack@eecs.umich.edu 1255154Sgblack@eecs.umich.edu if (fd == -1) { 1265154Sgblack@eecs.umich.edu perror(NULL); 1275154Sgblack@eecs.umich.edu cerr << "unable to open \"" << filename << "\" for reading\n"; 1285154Sgblack@eecs.umich.edu fatal("can't open input file"); 1295154Sgblack@eecs.umich.edu } 1305154Sgblack@eecs.umich.edu 1315154Sgblack@eecs.umich.edu return fd; 1325154Sgblack@eecs.umich.edu} 1335154Sgblack@eecs.umich.edu 1345154Sgblack@eecs.umich.edu 1355154Sgblack@eecs.umich.eduint 1365154Sgblack@eecs.umich.eduProcess::openOutputFile(const string &filename) 1375154Sgblack@eecs.umich.edu{ 1385154Sgblack@eecs.umich.edu int fd = open(filename.c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0774); 1395154Sgblack@eecs.umich.edu 1405154Sgblack@eecs.umich.edu if (fd == -1) { 1415154Sgblack@eecs.umich.edu perror(NULL); 1425514SMichael.Adler@intel.com cerr << "unable to open \"" << filename << "\" for writing\n"; 1435514SMichael.Adler@intel.com fatal("can't open output file"); 1445514SMichael.Adler@intel.com } 1455514SMichael.Adler@intel.com 1465514SMichael.Adler@intel.com return fd; 1475514SMichael.Adler@intel.com} 1485514SMichael.Adler@intel.com 1495514SMichael.Adler@intel.com 1505514SMichael.Adler@intel.comint 1515514SMichael.Adler@intel.comProcess::registerThreadContext(ThreadContext *tc) 1525154Sgblack@eecs.umich.edu{ 1532SN/A // add to list 1545282Srstrong@cs.ucsd.edu int myIndex = threadContexts.size(); 1555282Srstrong@cs.ucsd.edu threadContexts.push_back(tc); 1565282Srstrong@cs.ucsd.edu 1575282Srstrong@cs.ucsd.edu // return CPU number to caller 1585282Srstrong@cs.ucsd.edu return myIndex; 1595282Srstrong@cs.ucsd.edu} 1605282Srstrong@cs.ucsd.edu 1615282Srstrong@cs.ucsd.eduvoid 1625282Srstrong@cs.ucsd.eduProcess::startup() 1635282Srstrong@cs.ucsd.edu{ 1645282Srstrong@cs.ucsd.edu if (threadContexts.empty()) 1655282Srstrong@cs.ucsd.edu fatal("Process %s is not associated with any CPUs!\n", name()); 1665282Srstrong@cs.ucsd.edu 1675282Srstrong@cs.ucsd.edu // first thread context for this process... initialize & enable 1685282Srstrong@cs.ucsd.edu ThreadContext *tc = threadContexts[0]; 1695282Srstrong@cs.ucsd.edu 1705514SMichael.Adler@intel.com // mark this context as active so it will start ticking. 1715282Srstrong@cs.ucsd.edu tc->activate(0); 1725282Srstrong@cs.ucsd.edu 1735282Srstrong@cs.ucsd.edu Port *mem_port; 1745282Srstrong@cs.ucsd.edu mem_port = system->physmem->getPort("functional"); 1752SN/A initVirtMem = new TranslatingPort("process init port", pTable, true); 1762SN/A mem_port->setPeer(initVirtMem); 1772SN/A initVirtMem->setPeer(mem_port); 1789550Sandreas.hansson@arm.com} 1795282Srstrong@cs.ucsd.edu 1802SN/Avoid 1812SN/AProcess::replaceThreadContext(ThreadContext *tc, int tcIndex) 1821450SN/A{ 1831514SN/A if (tcIndex >= threadContexts.size()) { 1842SN/A panic("replaceThreadContext: bad tcIndex, %d >= %d\n", 1852SN/A tcIndex, threadContexts.size()); 1862SN/A } 1872378SN/A 1882SN/A threadContexts[tcIndex] = tc; 1892SN/A} 1902SN/A 191729SN/A// map simulator fd sim_fd to target fd tgt_fd 1922SN/Avoid 1932SN/AProcess::dup_fd(int sim_fd, int tgt_fd) 1948240Snate@binkert.org{ 1952SN/A if (tgt_fd < 0 || tgt_fd > MAX_FD) 1962SN/A panic("Process::dup_fd tried to dup past MAX_FD (%d)", tgt_fd); 1972SN/A 1982SN/A fd_map[tgt_fd] = sim_fd; 1992SN/A} 2002SN/A 2012SN/A 2022SN/A// generate new target fd for sim_fd 2032SN/Aint 2042SN/AProcess::alloc_fd(int sim_fd) 2052SN/A{ 2062SN/A // in case open() returns an error, don't allocate a new fd 2072SN/A if (sim_fd == -1) 2082SN/A return -1; 2092SN/A 2102SN/A // find first free target fd 2112SN/A for (int free_fd = 0; free_fd < MAX_FD; ++free_fd) { 2122SN/A if (fd_map[free_fd] == -1) { 2132SN/A fd_map[free_fd] = sim_fd; 2142SN/A return free_fd; 2152SN/A } 2162SN/A } 2172SN/A 2182SN/A panic("Process::alloc_fd: out of file descriptors!"); 2192SN/A} 2205514SMichael.Adler@intel.com 2212SN/A 2222SN/A// free target fd (e.g., after close) 2232SN/Avoid 2242SN/AProcess::free_fd(int tgt_fd) 2252SN/A{ 2262SN/A if (fd_map[tgt_fd] == -1) 2272SN/A warn("Process::free_fd: request to free unused fd %d", tgt_fd); 2282SN/A 2292SN/A fd_map[tgt_fd] = -1; 2302SN/A} 2315713Shsul@eecs.umich.edu 2325713Shsul@eecs.umich.edu 2332SN/A// look up simulator fd for given target fd 2345713Shsul@eecs.umich.eduint 2355713Shsul@eecs.umich.eduProcess::sim_fd(int tgt_fd) 2365713Shsul@eecs.umich.edu{ 2375713Shsul@eecs.umich.edu if (tgt_fd > MAX_FD) 2386029Ssteve.reinhardt@amd.com return -1; 2395713Shsul@eecs.umich.edu 2405713Shsul@eecs.umich.edu return fd_map[tgt_fd]; 2415713Shsul@eecs.umich.edu} 2425512SMichael.Adler@intel.com 2435713Shsul@eecs.umich.edu 2442SN/A 2452SN/A// 2461395SN/A// need to declare these here since there is no concrete Process type 2477532Ssteve.reinhardt@amd.com// that can be constructed (i.e., no REGISTER_SIM_OBJECT() macro call, 2481395SN/A// which is where these get declared for concrete types). 2495713Shsul@eecs.umich.edu// 2505713Shsul@eecs.umich.eduDEFINE_SIM_OBJECT_CLASS_NAME("Process", Process) 2512378SN/A 2522680Sktlim@umich.edu 2535713Shsul@eecs.umich.edu//////////////////////////////////////////////////////////////////////// 2541395SN/A// 2551634SN/A// LiveProcess member definitions 25610407Smitch.hayenga@arm.com// 25710298Salexandru.dutu@amd.com//////////////////////////////////////////////////////////////////////// 25810298Salexandru.dutu@amd.com 2591395SN/A 2602SN/Avoid 2612SN/AcopyStringArray(vector<string> &strings, Addr array_ptr, Addr data_ptr, 2622SN/A TranslatingPort* memPort) 2632SN/A{ 2642SN/A Addr data_ptr_swap; 2652SN/A for (int i = 0; i < strings.size(); ++i) { 2662SN/A data_ptr_swap = htog(data_ptr); 2672SN/A memPort->writeBlob(array_ptr, (uint8_t*)&data_ptr_swap, sizeof(Addr)); 2685282Srstrong@cs.ucsd.edu memPort->writeString(data_ptr, strings[i].c_str()); 2695282Srstrong@cs.ucsd.edu array_ptr += sizeof(Addr); 2702SN/A data_ptr += strings[i].size() + 1; 2712SN/A } 2722SN/A // add NULL terminator 2732SN/A data_ptr = 0; 2742SN/A 2755282Srstrong@cs.ucsd.edu memPort->writeBlob(array_ptr, (uint8_t*)&data_ptr, sizeof(Addr)); 2762SN/A} 2772SN/A 2782SN/ALiveProcess::LiveProcess(const string &nm, ObjectFile *_objFile, 2792SN/A System *_system, 2802SN/A int stdin_fd, int stdout_fd, int stderr_fd, 2812SN/A vector<string> &_argv, vector<string> &_envp) 2825282Srstrong@cs.ucsd.edu : Process(nm, _system, stdin_fd, stdout_fd, stderr_fd), 2835282Srstrong@cs.ucsd.edu objFile(_objFile), argv(_argv), envp(_envp) 28410496Ssteve.reinhardt@amd.com{ 2855282Srstrong@cs.ucsd.edu prog_fname = argv[0]; 2865282Srstrong@cs.ucsd.edu 2875282Srstrong@cs.ucsd.edu // load up symbols, if any... these may be used for debugging or 2885282Srstrong@cs.ucsd.edu // profiling. 2895282Srstrong@cs.ucsd.edu if (!debugSymbolTable) { 2905282Srstrong@cs.ucsd.edu debugSymbolTable = new SymbolTable(); 2915282Srstrong@cs.ucsd.edu if (!objFile->loadGlobalSymbols(debugSymbolTable) || 2921970SN/A !objFile->loadLocalSymbols(debugSymbolTable)) { 2931970SN/A // didn't load any symbols 2942SN/A delete debugSymbolTable; 2952SN/A debugSymbolTable = NULL; 2961970SN/A } 2971970SN/A } 2982SN/A} 2991970SN/A 3001970SN/Avoid 3011970SN/ALiveProcess::argsInit(int intSize, int pageSize) 3021970SN/A{ 3031970SN/A Process::startup(); 3045282Srstrong@cs.ucsd.edu 3055282Srstrong@cs.ucsd.edu // load object file into target memory 3061970SN/A objFile->loadSections(initVirtMem); 3071970SN/A 3085282Srstrong@cs.ucsd.edu // Calculate how much space we need for arg & env arrays. 3095282Srstrong@cs.ucsd.edu int argv_array_size = intSize * (argv.size() + 1); 3105282Srstrong@cs.ucsd.edu int envp_array_size = intSize * (envp.size() + 1); 3115282Srstrong@cs.ucsd.edu int arg_data_size = 0; 3125282Srstrong@cs.ucsd.edu for (int i = 0; i < argv.size(); ++i) { 3135282Srstrong@cs.ucsd.edu arg_data_size += argv[i].size() + 1; 3145282Srstrong@cs.ucsd.edu } 31510496Ssteve.reinhardt@amd.com int env_data_size = 0; 3162SN/A for (int i = 0; i < envp.size(); ++i) { 3172SN/A env_data_size += envp[i].size() + 1; 3182SN/A } 3192SN/A 3202SN/A int space_needed = 3212SN/A argv_array_size + envp_array_size + arg_data_size + env_data_size; 3222SN/A // for SimpleScalar compatibility 3238324Ssteve.reinhardt@amd.com if (space_needed < 16384) 3242SN/A space_needed = 16384; 3252SN/A 3265282Srstrong@cs.ucsd.edu // set bottom of stack 3272SN/A stack_min = stack_base - space_needed; 3282SN/A // align it 3295282Srstrong@cs.ucsd.edu stack_min = roundDown(stack_min, pageSize); 3305282Srstrong@cs.ucsd.edu stack_size = stack_base - stack_min; 3315282Srstrong@cs.ucsd.edu // map memory 3328324Ssteve.reinhardt@amd.com pTable->allocate(stack_min, roundUp(stack_size, pageSize)); 3338324Ssteve.reinhardt@amd.com 3345282Srstrong@cs.ucsd.edu // map out initial stack contents 3355282Srstrong@cs.ucsd.edu Addr argv_array_base = stack_min + intSize; // room for argc 3365282Srstrong@cs.ucsd.edu Addr envp_array_base = argv_array_base + argv_array_size; 3377487Ssteve.reinhardt@amd.com Addr arg_data_base = envp_array_base + envp_array_size; 3388601Ssteve.reinhardt@amd.com Addr env_data_base = arg_data_base + arg_data_size; 3398601Ssteve.reinhardt@amd.com 3408601Ssteve.reinhardt@amd.com // write contents to stack 34110318Sandreas.hansson@arm.com uint64_t argc = argv.size(); 3428601Ssteve.reinhardt@amd.com if (intSize == 8) 34310558Salexandru.dutu@amd.com argc = htog((uint64_t)argc); 3448601Ssteve.reinhardt@amd.com else if (intSize == 4) 3458601Ssteve.reinhardt@amd.com argc = htog((uint32_t)argc); 3464434Ssaidi@eecs.umich.edu else 3478539Sgblack@eecs.umich.edu panic("Unknown int size"); 3484434Ssaidi@eecs.umich.edu 3498539Sgblack@eecs.umich.edu initVirtMem->writeBlob(stack_min, (uint8_t*)&argc, intSize); 3508539Sgblack@eecs.umich.edu 3514434Ssaidi@eecs.umich.edu copyStringArray(argv, argv_array_base, arg_data_base, initVirtMem); 35210318Sandreas.hansson@arm.com copyStringArray(envp, envp_array_base, env_data_base, initVirtMem); 3534434Ssaidi@eecs.umich.edu 3544434Ssaidi@eecs.umich.edu threadContexts[0]->setIntReg(ArgumentReg0, argc); 3554434Ssaidi@eecs.umich.edu threadContexts[0]->setIntReg(ArgumentReg1, argv_array_base); 3568539Sgblack@eecs.umich.edu threadContexts[0]->setIntReg(StackPointerReg, stack_min); 3578539Sgblack@eecs.umich.edu 3585154Sgblack@eecs.umich.edu Addr prog_entry = objFile->entryPoint(); 3595154Sgblack@eecs.umich.edu threadContexts[0]->setPC(prog_entry); 3605154Sgblack@eecs.umich.edu threadContexts[0]->setNextPC(prog_entry + sizeof(MachInst)); 3618539Sgblack@eecs.umich.edu threadContexts[0]->setNextNPC(prog_entry + (2 * sizeof(MachInst))); 3625154Sgblack@eecs.umich.edu 3638601Ssteve.reinhardt@amd.com num_processes++; 3645823Ssaidi@eecs.umich.edu} 3655154Sgblack@eecs.umich.edu 3664434Ssaidi@eecs.umich.eduvoid 3674434Ssaidi@eecs.umich.eduLiveProcess::syscall(int64_t callnum, ThreadContext *tc) 3684434Ssaidi@eecs.umich.edu{ 3694434Ssaidi@eecs.umich.edu num_syscalls++; 3704434Ssaidi@eecs.umich.edu 3717487Ssteve.reinhardt@amd.com SyscallDesc *desc = getDesc(callnum); 3725282Srstrong@cs.ucsd.edu if (desc == NULL) 3737487Ssteve.reinhardt@amd.com fatal("Syscall %d out of range", callnum); 3747487Ssteve.reinhardt@amd.com 3755282Srstrong@cs.ucsd.edu desc->doSyscall(callnum, this, tc); 3765282Srstrong@cs.ucsd.edu} 3775282Srstrong@cs.ucsd.edu 3785282Srstrong@cs.ucsd.eduLiveProcess * 3795282Srstrong@cs.ucsd.eduLiveProcess::create(const std::string &nm, System *system, int stdin_fd, 3805514SMichael.Adler@intel.com int stdout_fd, int stderr_fd, std::string executable, 3815282Srstrong@cs.ucsd.edu std::vector<std::string> &argv, 3825282Srstrong@cs.ucsd.edu std::vector<std::string> &envp) 3835282Srstrong@cs.ucsd.edu{ 3845282Srstrong@cs.ucsd.edu LiveProcess *process = NULL; 3855282Srstrong@cs.ucsd.edu 3865282Srstrong@cs.ucsd.edu ObjectFile *objFile = createObjectFile(executable); 3875282Srstrong@cs.ucsd.edu if (objFile == NULL) { 3885282Srstrong@cs.ucsd.edu fatal("Can't load object file %s", executable); 3897487Ssteve.reinhardt@amd.com } 3907487Ssteve.reinhardt@amd.com 3915282Srstrong@cs.ucsd.edu#if THE_ISA == ALPHA_ISA 3925282Srstrong@cs.ucsd.edu if (objFile->getArch() != ObjectFile::Alpha) 3935282Srstrong@cs.ucsd.edu fatal("Object file architecture does not match compiled ISA (Alpha)."); 3945282Srstrong@cs.ucsd.edu switch (objFile->getOpSys()) { 3955282Srstrong@cs.ucsd.edu case ObjectFile::Tru64: 3965282Srstrong@cs.ucsd.edu process = new AlphaTru64Process(nm, objFile, system, 3975282Srstrong@cs.ucsd.edu stdin_fd, stdout_fd, stderr_fd, 3985282Srstrong@cs.ucsd.edu argv, envp); 3995282Srstrong@cs.ucsd.edu break; 4005282Srstrong@cs.ucsd.edu 4015282Srstrong@cs.ucsd.edu case ObjectFile::Linux: 4027487Ssteve.reinhardt@amd.com process = new AlphaLinuxProcess(nm, objFile, system, 4035282Srstrong@cs.ucsd.edu stdin_fd, stdout_fd, stderr_fd, 4045514SMichael.Adler@intel.com argv, envp); 4055514SMichael.Adler@intel.com break; 4065282Srstrong@cs.ucsd.edu 4075282Srstrong@cs.ucsd.edu default: 4085514SMichael.Adler@intel.com fatal("Unknown/unsupported operating system."); 4095514SMichael.Adler@intel.com } 4105514SMichael.Adler@intel.com#elif THE_ISA == SPARC_ISA 4115514SMichael.Adler@intel.com if (objFile->getArch() != ObjectFile::SPARC) 4125514SMichael.Adler@intel.com fatal("Object file architecture does not match compiled ISA (SPARC)."); 4135514SMichael.Adler@intel.com switch (objFile->getOpSys()) { 4145514SMichael.Adler@intel.com case ObjectFile::Linux: 4155514SMichael.Adler@intel.com process = new SparcLinuxProcess(nm, objFile, system, 4165514SMichael.Adler@intel.com stdin_fd, stdout_fd, stderr_fd, 4175514SMichael.Adler@intel.com argv, envp); 4185514SMichael.Adler@intel.com break; 4195514SMichael.Adler@intel.com 4205514SMichael.Adler@intel.com 4215282Srstrong@cs.ucsd.edu case ObjectFile::Solaris: 4225282Srstrong@cs.ucsd.edu process = new SparcSolarisProcess(nm, objFile, system, 4235282Srstrong@cs.ucsd.edu stdin_fd, stdout_fd, stderr_fd, 4245282Srstrong@cs.ucsd.edu argv, envp); 4255282Srstrong@cs.ucsd.edu break; 4265282Srstrong@cs.ucsd.edu default: 4275282Srstrong@cs.ucsd.edu fatal("Unknown/unsupported operating system."); 4285282Srstrong@cs.ucsd.edu } 4295282Srstrong@cs.ucsd.edu#elif THE_ISA == MIPS_ISA 4305282Srstrong@cs.ucsd.edu if (objFile->getArch() != ObjectFile::Mips) 4315282Srstrong@cs.ucsd.edu fatal("Object file architecture does not match compiled ISA (MIPS)."); 4325282Srstrong@cs.ucsd.edu switch (objFile->getOpSys()) { 4335282Srstrong@cs.ucsd.edu case ObjectFile::Linux: 4345282Srstrong@cs.ucsd.edu process = new MipsLinuxProcess(nm, objFile, system, 4355282Srstrong@cs.ucsd.edu stdin_fd, stdout_fd, stderr_fd, 4365282Srstrong@cs.ucsd.edu argv, envp); 4375282Srstrong@cs.ucsd.edu break; 4385282Srstrong@cs.ucsd.edu 4395282Srstrong@cs.ucsd.edu default: 4405282Srstrong@cs.ucsd.edu fatal("Unknown/unsupported operating system."); 4415282Srstrong@cs.ucsd.edu } 4425282Srstrong@cs.ucsd.edu#else 4435282Srstrong@cs.ucsd.edu#error "THE_ISA not set" 4445282Srstrong@cs.ucsd.edu#endif 4455282Srstrong@cs.ucsd.edu 4465282Srstrong@cs.ucsd.edu 4475282Srstrong@cs.ucsd.edu if (process == NULL) 4485282Srstrong@cs.ucsd.edu fatal("Unknown error creating process object."); 4495282Srstrong@cs.ucsd.edu return process; 4505282Srstrong@cs.ucsd.edu} 4515282Srstrong@cs.ucsd.edu 4525282Srstrong@cs.ucsd.edu 4535282Srstrong@cs.ucsd.eduBEGIN_DECLARE_SIM_OBJECT_PARAMS(LiveProcess) 4545282Srstrong@cs.ucsd.edu 4555282Srstrong@cs.ucsd.edu VectorParam<string> cmd; 4565282Srstrong@cs.ucsd.edu Param<string> executable; 4575282Srstrong@cs.ucsd.edu Param<string> input; 4585282Srstrong@cs.ucsd.edu Param<string> output; 4595282Srstrong@cs.ucsd.edu VectorParam<string> env; 4607487Ssteve.reinhardt@amd.com SimObjectParam<System *> system; 4617487Ssteve.reinhardt@amd.com 4625282Srstrong@cs.ucsd.eduEND_DECLARE_SIM_OBJECT_PARAMS(LiveProcess) 4635282Srstrong@cs.ucsd.edu 4645282Srstrong@cs.ucsd.edu 4655282Srstrong@cs.ucsd.eduBEGIN_INIT_SIM_OBJECT_PARAMS(LiveProcess) 4667487Ssteve.reinhardt@amd.com 4675282Srstrong@cs.ucsd.edu INIT_PARAM(cmd, "command line (executable plus arguments)"), 4687487Ssteve.reinhardt@amd.com INIT_PARAM(executable, "executable (overrides cmd[0] if set)"), 4697487Ssteve.reinhardt@amd.com INIT_PARAM(input, "filename for stdin (dflt: use sim stdin)"), 4705282Srstrong@cs.ucsd.edu INIT_PARAM(output, "filename for stdout/stderr (dflt: use sim stdout)"), 4715282Srstrong@cs.ucsd.edu INIT_PARAM(env, "environment settings"), 4725282Srstrong@cs.ucsd.edu INIT_PARAM(system, "system") 4735282Srstrong@cs.ucsd.edu 4747487Ssteve.reinhardt@amd.comEND_INIT_SIM_OBJECT_PARAMS(LiveProcess) 4755282Srstrong@cs.ucsd.edu 4765282Srstrong@cs.ucsd.edu 4775282Srstrong@cs.ucsd.eduCREATE_SIM_OBJECT(LiveProcess) 4785282Srstrong@cs.ucsd.edu{ 4795282Srstrong@cs.ucsd.edu string in = input; 4805282Srstrong@cs.ucsd.edu string out = output; 4815282Srstrong@cs.ucsd.edu 4827487Ssteve.reinhardt@amd.com // initialize file descriptors to default: same as simulator 4837487Ssteve.reinhardt@amd.com int stdin_fd, stdout_fd, stderr_fd; 4845282Srstrong@cs.ucsd.edu 4855282Srstrong@cs.ucsd.edu if (in == "stdin" || in == "cin") 4865282Srstrong@cs.ucsd.edu stdin_fd = STDIN_FILENO; 4875282Srstrong@cs.ucsd.edu else 4885282Srstrong@cs.ucsd.edu stdin_fd = Process::openInputFile(input); 4895282Srstrong@cs.ucsd.edu 4905282Srstrong@cs.ucsd.edu if (out == "stdout" || out == "cout") 4915282Srstrong@cs.ucsd.edu stdout_fd = STDOUT_FILENO; 4925282Srstrong@cs.ucsd.edu else if (out == "stderr" || out == "cerr") 4935282Srstrong@cs.ucsd.edu stdout_fd = STDERR_FILENO; 4945282Srstrong@cs.ucsd.edu else 4955282Srstrong@cs.ucsd.edu stdout_fd = Process::openOutputFile(out); 4965282Srstrong@cs.ucsd.edu 4975282Srstrong@cs.ucsd.edu stderr_fd = (stdout_fd != STDOUT_FILENO) ? stdout_fd : STDERR_FILENO; 4985282Srstrong@cs.ucsd.edu 4995282Srstrong@cs.ucsd.edu return LiveProcess::create(getInstanceName(), system, 5005282Srstrong@cs.ucsd.edu stdin_fd, stdout_fd, stderr_fd, 5015282Srstrong@cs.ucsd.edu (string)executable == "" ? cmd[0] : executable, 5025282Srstrong@cs.ucsd.edu cmd, env); 5035282Srstrong@cs.ucsd.edu} 5045282Srstrong@cs.ucsd.edu 5055282Srstrong@cs.ucsd.edu 5065282Srstrong@cs.ucsd.eduREGISTER_SIM_OBJECT("LiveProcess", LiveProcess) 5075282Srstrong@cs.ucsd.edu