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