process.cc revision 2107
11689SN/A/* 29608Sandreas.hansson@arm.com * Copyright (c) 2001-2005 The Regents of The University of Michigan 39919Ssteve.reinhardt@amd.com * All rights reserved. 48707Sandreas.hansson@arm.com * 58707Sandreas.hansson@arm.com * Redistribution and use in source and binary forms, with or without 68707Sandreas.hansson@arm.com * modification, are permitted provided that the following conditions are 78707Sandreas.hansson@arm.com * met: redistributions of source code must retain the above copyright 88707Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer; 98707Sandreas.hansson@arm.com * redistributions in binary form must reproduce the above copyright 108707Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer in the 118707Sandreas.hansson@arm.com * documentation and/or other materials provided with the distribution; 128707Sandreas.hansson@arm.com * neither the name of the copyright holders nor the names of its 138707Sandreas.hansson@arm.com * contributors may be used to endorse or promote products derived from 148707Sandreas.hansson@arm.com * this software without specific prior written permission. 151689SN/A * 167897Shestness@cs.utexas.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 171689SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 181689SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 191689SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 201689SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 211689SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 221689SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 231689SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 241689SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 251689SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 261689SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 271689SN/A */ 281689SN/A 291689SN/A#include <unistd.h> 301689SN/A#include <fcntl.h> 311689SN/A 321689SN/A#include <cstdio> 331689SN/A#include <string> 341689SN/A 351689SN/A#include "base/intmath.hh" 361689SN/A#include "base/loader/object_file.hh" 371689SN/A#include "base/loader/symtab.hh" 381689SN/A#include "base/statistics.hh" 391689SN/A#include "config/full_system.hh" 401689SN/A#include "cpu/exec_context.hh" 412665Ssaidi@eecs.umich.edu#include "cpu/smt.hh" 422665Ssaidi@eecs.umich.edu#include "encumbered/cpu/full/thread.hh" 432756Sksewell@umich.edu#include "encumbered/eio/eio.hh" 447897Shestness@cs.utexas.edu#include "encumbered/mem/functional/main.hh" 451689SN/A#include "sim/builder.hh" 461689SN/A#include "sim/fake_syscall.hh" 472325SN/A#include "sim/process.hh" 482325SN/A#include "sim/stats.hh" 491060SN/A 501060SN/A#ifdef TARGET_ALPHA 511060SN/A#include "arch/alpha/alpha_tru64_process.hh" 522292SN/A#include "arch/alpha/alpha_linux_process.hh" 532292SN/A#endif 541681SN/A 551060SN/Ausing namespace std; 562980Sgblack@eecs.umich.eduusing namespace TheISA; 571060SN/A 586658Snate@binkert.org// 591717SN/A// The purpose of this code is to fake the loader & syscall mechanism 601717SN/A// when there's no OS: thus there's no resone to use it in FULL_SYSTEM 612292SN/A// mode when we do have an OS 622292SN/A// 638229Snate@binkert.org#if FULL_SYSTEM 648229Snate@binkert.org#error "process.cc not compatible with FULL_SYSTEM" 658229Snate@binkert.org#endif 668229Snate@binkert.org 672817Sksewell@umich.edu// current number of allocated processes 688229Snate@binkert.orgint num_processes = 0; 691060SN/A 701060SN/AProcess::Process(const string &nm, 712316SN/A int stdin_fd, // initial I/O descriptors 722316SN/A int stdout_fd, 732680Sktlim@umich.edu int stderr_fd) 742817Sksewell@umich.edu : SimObject(nm) 752817Sksewell@umich.edu{ 762843Sktlim@umich.edu // allocate memory space 772843Sktlim@umich.edu memory = new MainMemory(nm + ".MainMem"); 782669Sktlim@umich.edu 791060SN/A // allocate initial register file 801060SN/A init_regs = new RegFile; 818737Skoansin.tan@gmail.com memset(init_regs, 0, sizeof(RegFile)); 825529Snate@binkert.org 832733Sktlim@umich.edu // initialize first 3 fds (stdin, stdout, stderr) 841060SN/A fd_map[STDIN_FILENO] = stdin_fd; 851060SN/A fd_map[STDOUT_FILENO] = stdout_fd; 861060SN/A fd_map[STDERR_FILENO] = stderr_fd; 875529Snate@binkert.org 882292SN/A // mark remaining fds as free 892292SN/A for (int i = 3; i <= MAX_FD; ++i) { 901060SN/A fd_map[i] = -1; 911060SN/A } 922348SN/A 932348SN/A mmap_start = mmap_end = 0; 942348SN/A nxm_start = nxm_end = 0; 952348SN/A // other parameters will be initialized when the program is loaded 962348SN/A} 971060SN/A 982733Sktlim@umich.eduvoid 991060SN/AProcess::regStats() 1001060SN/A{ 1012325SN/A using namespace Stats; 1021060SN/A 1031061SN/A num_syscalls 1044329Sktlim@umich.edu .name(name() + ".PROG:num_syscalls") 1051060SN/A .desc("Number of system calls") 1065595Sgblack@eecs.umich.edu ; 1072292SN/A} 1082292SN/A 1092292SN/A// 1102292SN/A// static helper functions 1112817Sksewell@umich.edu// 1122829Sksewell@umich.eduint 1131060SN/AProcess::openInputFile(const string &filename) 1141060SN/A{ 1151060SN/A int fd = open(filename.c_str(), O_RDONLY); 1161060SN/A 1171060SN/A if (fd == -1) { 1182307SN/A perror(NULL); 1192307SN/A cerr << "unable to open \"" << filename << "\" for reading\n"; 1201060SN/A fatal("can't open input file"); 1211060SN/A } 1226022Sgblack@eecs.umich.edu 1236022Sgblack@eecs.umich.edu return fd; 1243781Sgblack@eecs.umich.edu} 1252292SN/A 1261060SN/A 1271060SN/Aint 1281060SN/AProcess::openOutputFile(const string &filename) 1298707Sandreas.hansson@arm.com{ 1308707Sandreas.hansson@arm.com int fd = open(filename.c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0774); 1318707Sandreas.hansson@arm.com 1328707Sandreas.hansson@arm.com if (fd == -1) { 1339608Sandreas.hansson@arm.com perror(NULL); 1348707Sandreas.hansson@arm.com cerr << "unable to open \"" << filename << "\" for writing\n"; 1358707Sandreas.hansson@arm.com fatal("can't open output file"); 1368707Sandreas.hansson@arm.com } 1378707Sandreas.hansson@arm.com 1388707Sandreas.hansson@arm.com return fd; 1398707Sandreas.hansson@arm.com} 1408707Sandreas.hansson@arm.com 1418707Sandreas.hansson@arm.com 1429608Sandreas.hansson@arm.comint 1438707Sandreas.hansson@arm.comProcess::registerExecContext(ExecContext *xc) 1448707Sandreas.hansson@arm.com{ 1458707Sandreas.hansson@arm.com // add to list 1468707Sandreas.hansson@arm.com int myIndex = execContexts.size(); 1478707Sandreas.hansson@arm.com execContexts.push_back(xc); 1488707Sandreas.hansson@arm.com 1498975Sandreas.hansson@arm.com if (myIndex == 0) { 1508975Sandreas.hansson@arm.com // copy process's initial regs struct 1518707Sandreas.hansson@arm.com xc->regs = *init_regs; 1528707Sandreas.hansson@arm.com } 1538707Sandreas.hansson@arm.com 1548707Sandreas.hansson@arm.com // return CPU number to caller and increment available CPU count 1558707Sandreas.hansson@arm.com return myIndex; 1568707Sandreas.hansson@arm.com} 1578707Sandreas.hansson@arm.com 1588707Sandreas.hansson@arm.comvoid 1599608Sandreas.hansson@arm.comProcess::startup() 1608707Sandreas.hansson@arm.com{ 1618707Sandreas.hansson@arm.com if (execContexts.empty()) 1628707Sandreas.hansson@arm.com return; 1638707Sandreas.hansson@arm.com 1648707Sandreas.hansson@arm.com // first exec context for this process... initialize & enable 1658707Sandreas.hansson@arm.com ExecContext *xc = execContexts[0]; 1668707Sandreas.hansson@arm.com 1678707Sandreas.hansson@arm.com // mark this context as active so it will start ticking. 1688707Sandreas.hansson@arm.com xc->activate(0); 1699608Sandreas.hansson@arm.com} 1708707Sandreas.hansson@arm.com 1718707Sandreas.hansson@arm.comvoid 1728707Sandreas.hansson@arm.comProcess::replaceExecContext(ExecContext *xc, int xcIndex) 1738707Sandreas.hansson@arm.com{ 1748707Sandreas.hansson@arm.com if (xcIndex >= execContexts.size()) { 1758707Sandreas.hansson@arm.com panic("replaceExecContext: bad xcIndex, %d >= %d\n", 1768707Sandreas.hansson@arm.com xcIndex, execContexts.size()); 1778975Sandreas.hansson@arm.com } 1788975Sandreas.hansson@arm.com 1798707Sandreas.hansson@arm.com execContexts[xcIndex] = xc; 1809608Sandreas.hansson@arm.com} 1819608Sandreas.hansson@arm.com 1829608Sandreas.hansson@arm.com// map simulator fd sim_fd to target fd tgt_fd 1839608Sandreas.hansson@arm.comvoid 1849608Sandreas.hansson@arm.comProcess::dup_fd(int sim_fd, int tgt_fd) 1858707Sandreas.hansson@arm.com{ 1868707Sandreas.hansson@arm.com if (tgt_fd < 0 || tgt_fd > MAX_FD) 1878707Sandreas.hansson@arm.com panic("Process::dup_fd tried to dup past MAX_FD (%d)", tgt_fd); 1888707Sandreas.hansson@arm.com 1898707Sandreas.hansson@arm.com fd_map[tgt_fd] = sim_fd; 1908707Sandreas.hansson@arm.com} 1918707Sandreas.hansson@arm.com 1928711Sandreas.hansson@arm.com 1938707Sandreas.hansson@arm.com// generate new target fd for sim_fd 1948922Swilliam.wang@arm.comint 1958707Sandreas.hansson@arm.comProcess::alloc_fd(int sim_fd) 1968707Sandreas.hansson@arm.com{ 1971060SN/A // in case open() returns an error, don't allocate a new fd 1981060SN/A if (sim_fd == -1) 1991060SN/A return -1; 2002292SN/A 2011755SN/A // find first free target fd 2021060SN/A for (int free_fd = 0; free_fd < MAX_FD; ++free_fd) { 2031060SN/A if (fd_map[free_fd] == -1) { 2042292SN/A fd_map[free_fd] = sim_fd; 2051755SN/A return free_fd; 2062292SN/A } 2072292SN/A } 2081060SN/A 2092292SN/A panic("Process::alloc_fd: out of file descriptors!"); 2105336Shines@cs.fsu.edu} 2111060SN/A 2121060SN/A 2132292SN/A// free target fd (e.g., after close) 2141060SN/Avoid 2151060SN/AProcess::free_fd(int tgt_fd) 2162292SN/A{ 2179180Sandreas.hansson@arm.com if (fd_map[tgt_fd] == -1) 2181060SN/A warn("Process::free_fd: request to free unused fd %d", tgt_fd); 2191060SN/A 2209179Sandreas.hansson@arm.com fd_map[tgt_fd] = -1; 2211060SN/A} 2229179Sandreas.hansson@arm.com 2231060SN/A 2241060SN/A// look up simulator fd for given target fd 2252292SN/Aint 2261060SN/AProcess::sim_fd(int tgt_fd) 2271060SN/A{ 2281060SN/A if (tgt_fd > MAX_FD) 2291060SN/A return -1; 2301060SN/A 2311060SN/A return fd_map[tgt_fd]; 2322829Sksewell@umich.edu} 2332829Sksewell@umich.edu 2342829Sksewell@umich.edu 2352829Sksewell@umich.edu 2366221Snate@binkert.org// 2372829Sksewell@umich.edu// need to declare these here since there is no concrete Process type 2382829Sksewell@umich.edu// that can be constructed (i.e., no REGISTER_SIM_OBJECT() macro call, 2392829Sksewell@umich.edu// which is where these get declared for concrete types). 2402829Sksewell@umich.edu// 2412829Sksewell@umich.eduDEFINE_SIM_OBJECT_CLASS_NAME("Process", Process) 2422829Sksewell@umich.edu 2432829Sksewell@umich.edu 2442829Sksewell@umich.edu//////////////////////////////////////////////////////////////////////// 2452829Sksewell@umich.edu// 2462829Sksewell@umich.edu// LiveProcess member definitions 2472829Sksewell@umich.edu// 2482829Sksewell@umich.edu//////////////////////////////////////////////////////////////////////// 2492829Sksewell@umich.edu 2502829Sksewell@umich.edu 2512829Sksewell@umich.edustatic void 2525336Shines@cs.fsu.educopyStringArray(vector<string> &strings, Addr array_ptr, Addr data_ptr, 2532829Sksewell@umich.edu FunctionalMemory *memory) 2542829Sksewell@umich.edu{ 2552829Sksewell@umich.edu Addr data_ptr_swap; 2566221Snate@binkert.org for (int i = 0; i < strings.size(); ++i) { 2579180Sandreas.hansson@arm.com data_ptr_swap = htog(data_ptr); 2582829Sksewell@umich.edu memory->access(Write, array_ptr, &data_ptr_swap, sizeof(Addr)); 2592829Sksewell@umich.edu memory->writeString(data_ptr, strings[i].c_str()); 2602829Sksewell@umich.edu array_ptr += sizeof(Addr); 2615606Snate@binkert.org data_ptr += strings[i].size() + 1; 2629179Sandreas.hansson@arm.com } 2638518Sgeoffrey.blake@arm.com // add NULL terminator 2649179Sandreas.hansson@arm.com data_ptr = 0; 2658518Sgeoffrey.blake@arm.com memory->access(Write, array_ptr, &data_ptr, sizeof(Addr)); 2668518Sgeoffrey.blake@arm.com} 2678518Sgeoffrey.blake@arm.com 2688518Sgeoffrey.blake@arm.comLiveProcess::LiveProcess(const string &nm, ObjectFile *objFile, 2698518Sgeoffrey.blake@arm.com int stdin_fd, int stdout_fd, int stderr_fd, 2708518Sgeoffrey.blake@arm.com vector<string> &argv, vector<string> &envp) 2718518Sgeoffrey.blake@arm.com : Process(nm, stdin_fd, stdout_fd, stderr_fd) 2728518Sgeoffrey.blake@arm.com{ 2738518Sgeoffrey.blake@arm.com prog_fname = argv[0]; 2748518Sgeoffrey.blake@arm.com 2758518Sgeoffrey.blake@arm.com prog_entry = objFile->entryPoint(); 2762829Sksewell@umich.edu text_base = objFile->textBase(); 2772829Sksewell@umich.edu text_size = objFile->textSize(); 2782829Sksewell@umich.edu data_base = objFile->dataBase(); 2796221Snate@binkert.org data_size = objFile->dataSize() + objFile->bssSize(); 2806221Snate@binkert.org brk_point = roundUp(data_base + data_size, VMPageSize); 2812829Sksewell@umich.edu 2822829Sksewell@umich.edu // load object file into target memory 2832829Sksewell@umich.edu objFile->loadSections(memory); 2842829Sksewell@umich.edu 2852829Sksewell@umich.edu // load up symbols, if any... these may be used for debugging or 2862829Sksewell@umich.edu // profiling. 2872829Sksewell@umich.edu if (!debugSymbolTable) { 2882829Sksewell@umich.edu debugSymbolTable = new SymbolTable(); 2892875Sksewell@umich.edu if (!objFile->loadGlobalSymbols(debugSymbolTable) || 2902875Sksewell@umich.edu !objFile->loadLocalSymbols(debugSymbolTable)) { 2912875Sksewell@umich.edu // didn't load any symbols 2923221Sktlim@umich.edu delete debugSymbolTable; 2936221Snate@binkert.org debugSymbolTable = NULL; 2942875Sksewell@umich.edu } 2953221Sktlim@umich.edu } 2963221Sktlim@umich.edu 2973221Sktlim@umich.edu // Set up stack. On Alpha, stack goes below text section. This 2982875Sksewell@umich.edu // code should get moved to some architecture-specific spot. 2992875Sksewell@umich.edu stack_base = text_base - (409600+4096); 3002875Sksewell@umich.edu 3012875Sksewell@umich.edu // Set up region for mmaps. Tru64 seems to start just above 0 and 3022875Sksewell@umich.edu // grow up from there. 3032875Sksewell@umich.edu mmap_start = mmap_end = 0x10000; 3042875Sksewell@umich.edu 3052875Sksewell@umich.edu // Set pointer for next thread stack. Reserve 8M for main stack. 3062875Sksewell@umich.edu next_thread_stack_base = stack_base - (8 * 1024 * 1024); 3072875Sksewell@umich.edu 3082875Sksewell@umich.edu // Calculate how much space we need for arg & env arrays. 3092875Sksewell@umich.edu int argv_array_size = sizeof(Addr) * (argv.size() + 1); 3102875Sksewell@umich.edu int envp_array_size = sizeof(Addr) * (envp.size() + 1); 3113221Sktlim@umich.edu int arg_data_size = 0; 3123221Sktlim@umich.edu for (int i = 0; i < argv.size(); ++i) { 3133221Sktlim@umich.edu arg_data_size += argv[i].size() + 1; 3142875Sksewell@umich.edu } 3155336Shines@cs.fsu.edu int env_data_size = 0; 3162875Sksewell@umich.edu for (int i = 0; i < envp.size(); ++i) { 3172875Sksewell@umich.edu env_data_size += envp[i].size() + 1; 3182875Sksewell@umich.edu } 3196221Snate@binkert.org 3209180Sandreas.hansson@arm.com int space_needed = 3212875Sksewell@umich.edu argv_array_size + envp_array_size + arg_data_size + env_data_size; 3222875Sksewell@umich.edu // for SimpleScalar compatibility 3232875Sksewell@umich.edu if (space_needed < 16384) 3245606Snate@binkert.org space_needed = 16384; 3259179Sandreas.hansson@arm.com 3262875Sksewell@umich.edu // set bottom of stack 3275606Snate@binkert.org stack_min = stack_base - space_needed; 3289179Sandreas.hansson@arm.com // align it 3292875Sksewell@umich.edu stack_min &= ~7; 3302875Sksewell@umich.edu stack_size = stack_base - stack_min; 3312875Sksewell@umich.edu 3326221Snate@binkert.org // map out initial stack contents 3336221Snate@binkert.org Addr argv_array_base = stack_min + sizeof(uint64_t); // room for argc 3342875Sksewell@umich.edu Addr envp_array_base = argv_array_base + argv_array_size; 3352875Sksewell@umich.edu Addr arg_data_base = envp_array_base + envp_array_size; 3362875Sksewell@umich.edu Addr env_data_base = arg_data_base + arg_data_size; 3372875Sksewell@umich.edu 3382875Sksewell@umich.edu // write contents to stack 3392875Sksewell@umich.edu uint64_t argc = argv.size(); 3402875Sksewell@umich.edu argc = htog(argc); 3412875Sksewell@umich.edu memory->access(Write, stack_min, &argc, sizeof(uint64_t)); 3429444SAndreas.Sandberg@ARM.com 3439444SAndreas.Sandberg@ARM.com copyStringArray(argv, argv_array_base, arg_data_base, memory); 3449444SAndreas.Sandberg@ARM.com copyStringArray(envp, envp_array_base, env_data_base, memory); 3459444SAndreas.Sandberg@ARM.com 3469444SAndreas.Sandberg@ARM.com init_regs->intRegFile[ArgumentReg0] = argc; 3479444SAndreas.Sandberg@ARM.com init_regs->intRegFile[ArgumentReg1] = argv_array_base; 3489444SAndreas.Sandberg@ARM.com init_regs->intRegFile[StackPointerReg] = stack_min; 3499444SAndreas.Sandberg@ARM.com init_regs->intRegFile[GlobalPointerReg] = objFile->globalPointer(); 3509444SAndreas.Sandberg@ARM.com init_regs->pc = prog_entry; 3519444SAndreas.Sandberg@ARM.com init_regs->npc = prog_entry + sizeof(MachInst); 3529444SAndreas.Sandberg@ARM.com} 3539444SAndreas.Sandberg@ARM.com 3549444SAndreas.Sandberg@ARM.com 3559444SAndreas.Sandberg@ARM.comLiveProcess * 3569444SAndreas.Sandberg@ARM.comLiveProcess::create(const string &nm, 3579444SAndreas.Sandberg@ARM.com int stdin_fd, int stdout_fd, int stderr_fd, 3589444SAndreas.Sandberg@ARM.com string executable, 3599444SAndreas.Sandberg@ARM.com vector<string> &argv, vector<string> &envp) 3609444SAndreas.Sandberg@ARM.com{ 3619444SAndreas.Sandberg@ARM.com LiveProcess *process = NULL; 3629444SAndreas.Sandberg@ARM.com ObjectFile *objFile = createObjectFile(executable); 3639444SAndreas.Sandberg@ARM.com if (objFile == NULL) { 3649444SAndreas.Sandberg@ARM.com fatal("Can't load object file %s", executable); 3659444SAndreas.Sandberg@ARM.com } 3669444SAndreas.Sandberg@ARM.com 3679444SAndreas.Sandberg@ARM.com // check object type & set up syscall emulation pointer 3689444SAndreas.Sandberg@ARM.com if (objFile->getArch() == ObjectFile::Alpha) { 3691060SN/A switch (objFile->getOpSys()) { 3702292SN/A case ObjectFile::Tru64: 3715595Sgblack@eecs.umich.edu process = new AlphaTru64Process(nm, objFile, 3722292SN/A stdin_fd, stdout_fd, stderr_fd, 3731755SN/A argv, envp); 3741060SN/A break; 3752292SN/A 3765595Sgblack@eecs.umich.edu case ObjectFile::Linux: 3771684SN/A process = new AlphaLinuxProcess(nm, objFile, 37810023Smatt.horsnell@ARM.com stdin_fd, stdout_fd, stderr_fd, 37910023Smatt.horsnell@ARM.com argv, envp); 38010023Smatt.horsnell@ARM.com break; 38110023Smatt.horsnell@ARM.com 38210023Smatt.horsnell@ARM.com default: 38310023Smatt.horsnell@ARM.com fatal("Unknown/unsupported operating system."); 3845358Sgblack@eecs.umich.edu } 3855358Sgblack@eecs.umich.edu } else { 3865358Sgblack@eecs.umich.edu fatal("Unknown object file architecture."); 3875358Sgblack@eecs.umich.edu } 3885358Sgblack@eecs.umich.edu 3895358Sgblack@eecs.umich.edu delete objFile; 3905358Sgblack@eecs.umich.edu 3915358Sgblack@eecs.umich.edu if (process == NULL) 3925358Sgblack@eecs.umich.edu fatal("Unknown error creating process object."); 3935358Sgblack@eecs.umich.edu 3945358Sgblack@eecs.umich.edu return process; 3955358Sgblack@eecs.umich.edu} 3965358Sgblack@eecs.umich.edu 3975358Sgblack@eecs.umich.edu 3985358Sgblack@eecs.umich.eduBEGIN_DECLARE_SIM_OBJECT_PARAMS(LiveProcess) 3995358Sgblack@eecs.umich.edu 4002292SN/A VectorParam<string> cmd; 4012292SN/A Param<string> executable; 4022292SN/A Param<string> input; 4031684SN/A Param<string> output; 4041684SN/A VectorParam<string> env; 4052292SN/A 4061060SN/AEND_DECLARE_SIM_OBJECT_PARAMS(LiveProcess) 4071060SN/A 4089427SAndreas.Sandberg@ARM.com 4099427SAndreas.Sandberg@ARM.comBEGIN_INIT_SIM_OBJECT_PARAMS(LiveProcess) 4102834Sksewell@umich.edu 4112834Sksewell@umich.edu INIT_PARAM(cmd, "command line (executable plus arguments)"), 4122834Sksewell@umich.edu INIT_PARAM(executable, "executable (overrides cmd[0] if set)"), 4132834Sksewell@umich.edu INIT_PARAM(input, "filename for stdin (dflt: use sim stdin)"), 4142829Sksewell@umich.edu INIT_PARAM(output, "filename for stdout/stderr (dflt: use sim stdout)"), 4156221Snate@binkert.org INIT_PARAM(env, "environment settings") 4162875Sksewell@umich.edu 4172875Sksewell@umich.eduEND_INIT_SIM_OBJECT_PARAMS(LiveProcess) 4186221Snate@binkert.org 4192829Sksewell@umich.edu 4202292SN/ACREATE_SIM_OBJECT(LiveProcess) 4216221Snate@binkert.org{ 4221060SN/A string in = input; 4232292SN/A string out = output; 4246221Snate@binkert.org 4252292SN/A // initialize file descriptors to default: same as simulator 4262292SN/A int stdin_fd, stdout_fd, stderr_fd; 4278834Satgutier@umich.edu 4288834Satgutier@umich.edu if (in == "stdin" || in == "cin") 4298834Satgutier@umich.edu stdin_fd = STDIN_FILENO; 4308834Satgutier@umich.edu else 4312292SN/A stdin_fd = Process::openInputFile(input); 4322292SN/A 4339180Sandreas.hansson@arm.com if (out == "stdout" || out == "cout") 4342292SN/A stdout_fd = STDOUT_FILENO; 4352292SN/A else if (out == "stderr" || out == "cerr") 4366221Snate@binkert.org stdout_fd = STDERR_FILENO; 4372292SN/A else 4382292SN/A stdout_fd = Process::openOutputFile(out); 4393221Sktlim@umich.edu 4402292SN/A stderr_fd = (stdout_fd != STDOUT_FILENO) ? stdout_fd : STDERR_FILENO; 4419180Sandreas.hansson@arm.com 4429180Sandreas.hansson@arm.com return LiveProcess::create(getInstanceName(), 4432292SN/A stdin_fd, stdout_fd, stderr_fd, 4442292SN/A (string)executable == "" ? cmd[0] : executable, 4452292SN/A cmd, env); 4462292SN/A} 4476221Snate@binkert.org 4482292SN/AREGISTER_SIM_OBJECT("LiveProcess", LiveProcess) 4492292SN/A