process.hh revision 5543
12SN/A/*
21762SN/A * Copyright (c) 2001-2005 The Regents of The University of Michigan
32SN/A * All rights reserved.
42SN/A *
52SN/A * Redistribution and use in source and binary forms, with or without
62SN/A * modification, are permitted provided that the following conditions are
72SN/A * met: redistributions of source code must retain the above copyright
82SN/A * notice, this list of conditions and the following disclaimer;
92SN/A * redistributions in binary form must reproduce the above copyright
102SN/A * notice, this list of conditions and the following disclaimer in the
112SN/A * documentation and/or other materials provided with the distribution;
122SN/A * neither the name of the copyright holders nor the names of its
132SN/A * contributors may be used to endorse or promote products derived from
142SN/A * this software without specific prior written permission.
152SN/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.
272665Ssaidi@eecs.umich.edu *
282665Ssaidi@eecs.umich.edu * Authors: Nathan Binkert
292665Ssaidi@eecs.umich.edu *          Steve Reinhardt
302SN/A */
312SN/A
32360SN/A#ifndef __PROCESS_HH__
33360SN/A#define __PROCESS_HH__
342SN/A
352SN/A//
362SN/A// The purpose of this code is to fake the loader & syscall mechanism
372SN/A// when there's no OS: thus there's no reason to use it in FULL_SYSTEM
382SN/A// mode when we do have an OS.
392SN/A//
401858SN/A#include "config/full_system.hh"
411858SN/A
421858SN/A#if !FULL_SYSTEM
432SN/A
444117Sgblack@eecs.umich.edu#include <string>
45180SN/A#include <vector>
462SN/A
472378SN/A#include "base/statistics.hh"
484111Sgblack@eecs.umich.edu#include "sim/host.hh"
4956SN/A#include "sim/sim_object.hh"
502SN/A
515154Sgblack@eecs.umich.educlass GDBListener;
525154Sgblack@eecs.umich.educlass PageTable;
535154Sgblack@eecs.umich.educlass ProcessParams;
545154Sgblack@eecs.umich.educlass LiveProcessParams;
555154Sgblack@eecs.umich.educlass SyscallDesc;
565154Sgblack@eecs.umich.educlass System;
572680Sktlim@umich.educlass ThreadContext;
582401SN/Aclass TranslatingPort;
593971Sgblack@eecs.umich.edunamespace TheISA
603971Sgblack@eecs.umich.edu{
613971Sgblack@eecs.umich.edu    class RemoteGDB;
623971Sgblack@eecs.umich.edu}
632378SN/A
642SN/Aclass Process : public SimObject
652SN/A{
662SN/A  public:
672SN/A
682378SN/A    /// Pointer to object representing the system this process is
692378SN/A    /// running on.
702378SN/A    System *system;
712378SN/A
722680Sktlim@umich.edu    // have we initialized a thread context from this process?  If
732SN/A    // yes, subsequent contexts are assumed to be for dynamically
742SN/A    // created threads and are not initialized.
752SN/A    bool initialContextLoaded;
762SN/A
775183Ssaidi@eecs.umich.edu    bool checkpointRestored;
785183Ssaidi@eecs.umich.edu
792680Sktlim@umich.edu    // thread contexts associated with this process
802680Sktlim@umich.edu    std::vector<ThreadContext *> threadContexts;
81180SN/A
823971Sgblack@eecs.umich.edu    // remote gdb objects
833971Sgblack@eecs.umich.edu    std::vector<TheISA::RemoteGDB *> remoteGDB;
843971Sgblack@eecs.umich.edu    std::vector<GDBListener *> gdbListen;
853971Sgblack@eecs.umich.edu    bool breakpoint();
863971Sgblack@eecs.umich.edu
87180SN/A    // number of CPUs (esxec contexts, really) assigned to this process.
882680Sktlim@umich.edu    unsigned int numCpus() { return threadContexts.size(); }
892SN/A
902SN/A    // record of blocked context
912SN/A    struct WaitRec
922SN/A    {
932SN/A        Addr waitChan;
942680Sktlim@umich.edu        ThreadContext *waitingContext;
952SN/A
962680Sktlim@umich.edu        WaitRec(Addr chan, ThreadContext *ctx)
972SN/A            : waitChan(chan), waitingContext(ctx)
985543Ssaidi@eecs.umich.edu        {       }
992SN/A    };
1002SN/A
1012SN/A    // list of all blocked contexts
1022SN/A    std::list<WaitRec> waitList;
1032SN/A
1045543Ssaidi@eecs.umich.edu    Addr brk_point;             // top of the data segment
1052SN/A
1065543Ssaidi@eecs.umich.edu    Addr stack_base;            // stack segment base (highest address)
1075543Ssaidi@eecs.umich.edu    unsigned stack_size;        // initial stack size
1085543Ssaidi@eecs.umich.edu    Addr stack_min;             // lowest address accessed on the stack
1092SN/A
1105154Sgblack@eecs.umich.edu    // The maximum size allowed for the stack.
1115154Sgblack@eecs.umich.edu    Addr max_stack_size;
1125154Sgblack@eecs.umich.edu
1132SN/A    // addr to use for next stack region (for multithreaded apps)
1142SN/A    Addr next_thread_stack_base;
1152SN/A
116360SN/A    // Base of region for mmaps (when user doesn't specify an address).
1171408SN/A    Addr mmap_start;
1181408SN/A    Addr mmap_end;
119360SN/A
1201514SN/A    // Base of region for nxm data
1211514SN/A    Addr nxm_start;
1221514SN/A    Addr nxm_end;
1231514SN/A
1245543Ssaidi@eecs.umich.edu    std::string prog_fname;     // file name
1252SN/A
1265543Ssaidi@eecs.umich.edu    Stats::Scalar<> num_syscalls;       // number of syscalls executed
1272SN/A
1282SN/A
1292SN/A  protected:
1302SN/A    // constructor
1315154Sgblack@eecs.umich.edu    Process(ProcessParams * params);
1322SN/A
1331395SN/A    // post initialization startup
1341395SN/A    virtual void startup();
1352SN/A
1362SN/A  protected:
1372378SN/A    /// Memory object for initialization (image loading)
1382401SN/A    TranslatingPort *initVirtMem;
1392378SN/A
1402378SN/A  public:
1412378SN/A    PageTable *pTable;
1422SN/A
1434997Sgblack@eecs.umich.edu    //This id is assigned by m5 and is used to keep process' tlb entries
1444997Sgblack@eecs.umich.edu    //separated.
1454997Sgblack@eecs.umich.edu    uint64_t M5_pid;
1464997Sgblack@eecs.umich.edu
1475282Srstrong@cs.ucsd.edu    class FdMap
1485282Srstrong@cs.ucsd.edu    {
1495282Srstrong@cs.ucsd.edu      public:
1505282Srstrong@cs.ucsd.edu            int fd;
1515282Srstrong@cs.ucsd.edu            std::string filename;
1525282Srstrong@cs.ucsd.edu            int mode;
1535282Srstrong@cs.ucsd.edu            int flags;
1545282Srstrong@cs.ucsd.edu            bool isPipe;
1555282Srstrong@cs.ucsd.edu            int readPipeSource;
1565282Srstrong@cs.ucsd.edu            uint64_t fileOffset;
1575282Srstrong@cs.ucsd.edu
1585282Srstrong@cs.ucsd.edu
1595282Srstrong@cs.ucsd.edu            FdMap()
1605282Srstrong@cs.ucsd.edu            {
1615282Srstrong@cs.ucsd.edu                    fd = -1;
1625282Srstrong@cs.ucsd.edu                    filename = "NULL";
1635282Srstrong@cs.ucsd.edu                    mode = 0;
1645282Srstrong@cs.ucsd.edu                    flags = 0;
1655282Srstrong@cs.ucsd.edu                    isPipe = false;
1665282Srstrong@cs.ucsd.edu                    readPipeSource = 0;
1675282Srstrong@cs.ucsd.edu                    fileOffset = 0;
1685282Srstrong@cs.ucsd.edu
1695282Srstrong@cs.ucsd.edu            }
1705282Srstrong@cs.ucsd.edu
1715282Srstrong@cs.ucsd.edu        void serialize(std::ostream &os);
1725282Srstrong@cs.ucsd.edu        void unserialize(Checkpoint *cp, const std::string &section);
1735282Srstrong@cs.ucsd.edu
1745282Srstrong@cs.ucsd.edu    };
1755282Srstrong@cs.ucsd.edu
1762SN/A  private:
1772SN/A    // file descriptor remapping support
1785282Srstrong@cs.ucsd.edu    static const int MAX_FD = 256;    // max legal fd value
1795282Srstrong@cs.ucsd.edu    FdMap fd_map[MAX_FD+1];
1805282Srstrong@cs.ucsd.edu
1812SN/A
1822SN/A  public:
1832SN/A    // static helper functions to generate file descriptors for constructor
1842SN/A    static int openInputFile(const std::string &filename);
1852SN/A    static int openOutputFile(const std::string &filename);
1862SN/A
1872SN/A    // override of virtual SimObject method: register statistics
1882SN/A    virtual void regStats();
1892SN/A
1902680Sktlim@umich.edu    // register a thread context for this process.
1912680Sktlim@umich.edu    // returns tc's cpu number (index into threadContexts[])
1922680Sktlim@umich.edu    int registerThreadContext(ThreadContext *tc);
193180SN/A
194180SN/A
1952680Sktlim@umich.edu    void replaceThreadContext(ThreadContext *tc, int tcIndex);
1962SN/A
1972SN/A    // map simulator fd sim_fd to target fd tgt_fd
1982SN/A    void dup_fd(int sim_fd, int tgt_fd);
1992SN/A
2002SN/A    // generate new target fd for sim_fd
2015282Srstrong@cs.ucsd.edu    int alloc_fd(int sim_fd, std::string filename, int flags, int mode, bool pipe);
2021970SN/A
2031970SN/A    // free target fd (e.g., after close)
2041970SN/A    void free_fd(int tgt_fd);
2052SN/A
2062SN/A    // look up simulator fd for given target fd
2072SN/A    int sim_fd(int tgt_fd);
2082SN/A
2095282Srstrong@cs.ucsd.edu    // look up simulator fd_map object for a given target fd
2105282Srstrong@cs.ucsd.edu    FdMap * sim_fd_obj(int tgt_fd);
2115282Srstrong@cs.ucsd.edu
2125282Srstrong@cs.ucsd.edu    // fix all offsets for currently open files and save them
2135282Srstrong@cs.ucsd.edu    void fix_file_offsets();
2145282Srstrong@cs.ucsd.edu
2155282Srstrong@cs.ucsd.edu    // find all offsets for currently open files and save them
2165282Srstrong@cs.ucsd.edu    void find_file_offsets();
2175282Srstrong@cs.ucsd.edu
2185282Srstrong@cs.ucsd.edu    // set the source of this read pipe for a checkpoint resume
2195282Srstrong@cs.ucsd.edu    void setReadPipeSource(int read_pipe_fd, int source_fd);
2205282Srstrong@cs.ucsd.edu
2212680Sktlim@umich.edu    virtual void syscall(int64_t callnum, ThreadContext *tc) = 0;
2223311Ssaidi@eecs.umich.edu
2234434Ssaidi@eecs.umich.edu    // check if the this addr is on the next available page and allocate it
2244434Ssaidi@eecs.umich.edu    // if it's not we'll panic
2254434Ssaidi@eecs.umich.edu    bool checkAndAllocNextPage(Addr vaddr);
2264434Ssaidi@eecs.umich.edu
2273311Ssaidi@eecs.umich.edu    void serialize(std::ostream &os);
2283311Ssaidi@eecs.umich.edu    void unserialize(Checkpoint *cp, const std::string &section);
2292SN/A};
2302SN/A
2312SN/A//
2322SN/A// "Live" process with system calls redirected to host system
2332SN/A//
234360SN/Aclass ObjectFile;
2352SN/Aclass LiveProcess : public Process
2362SN/A{
237360SN/A  protected:
2382378SN/A    ObjectFile *objFile;
2392378SN/A    std::vector<std::string> argv;
2402378SN/A    std::vector<std::string> envp;
2413669Sbinkertn@umich.edu    std::string cwd;
2422378SN/A
2435154Sgblack@eecs.umich.edu    LiveProcess(LiveProcessParams * params, ObjectFile *objFile);
2442SN/A
2452561SN/A    virtual void argsInit(int intSize, int pageSize);
2462378SN/A
2473114Sgblack@eecs.umich.edu    // Id of the owner of the process
2483114Sgblack@eecs.umich.edu    uint64_t __uid;
2493114Sgblack@eecs.umich.edu    uint64_t __euid;
2503114Sgblack@eecs.umich.edu    uint64_t __gid;
2513114Sgblack@eecs.umich.edu    uint64_t __egid;
2523114Sgblack@eecs.umich.edu
2533114Sgblack@eecs.umich.edu    // pid of the process and it's parent
2543114Sgblack@eecs.umich.edu    uint64_t __pid;
2553114Sgblack@eecs.umich.edu    uint64_t __ppid;
2563114Sgblack@eecs.umich.edu
257360SN/A  public:
2583114Sgblack@eecs.umich.edu
2594793Sgblack@eecs.umich.edu    enum AuxiliaryVectorType {
2604793Sgblack@eecs.umich.edu        M5_AT_NULL = 0,
2614793Sgblack@eecs.umich.edu        M5_AT_IGNORE = 1,
2624793Sgblack@eecs.umich.edu        M5_AT_EXECFD = 2,
2634793Sgblack@eecs.umich.edu        M5_AT_PHDR = 3,
2644793Sgblack@eecs.umich.edu        M5_AT_PHENT = 4,
2654793Sgblack@eecs.umich.edu        M5_AT_PHNUM = 5,
2664793Sgblack@eecs.umich.edu        M5_AT_PAGESZ = 6,
2674793Sgblack@eecs.umich.edu        M5_AT_BASE = 7,
2684793Sgblack@eecs.umich.edu        M5_AT_FLAGS = 8,
2694793Sgblack@eecs.umich.edu        M5_AT_ENTRY = 9,
2704793Sgblack@eecs.umich.edu        M5_AT_NOTELF = 10,
2714793Sgblack@eecs.umich.edu        M5_AT_UID = 11,
2724793Sgblack@eecs.umich.edu        M5_AT_EUID = 12,
2734793Sgblack@eecs.umich.edu        M5_AT_GID = 13,
2744793Sgblack@eecs.umich.edu        M5_AT_EGID = 14,
2754793Sgblack@eecs.umich.edu        // The following may be specific to Linux
2764793Sgblack@eecs.umich.edu        M5_AT_PLATFORM = 15,
2774793Sgblack@eecs.umich.edu        M5_AT_HWCAP = 16,
2784793Sgblack@eecs.umich.edu        M5_AT_CLKTCK = 17,
2794793Sgblack@eecs.umich.edu
2804793Sgblack@eecs.umich.edu        M5_AT_SECURE = 23,
2814793Sgblack@eecs.umich.edu
2824793Sgblack@eecs.umich.edu        M5_AT_VECTOR_SIZE = 44
2834793Sgblack@eecs.umich.edu    };
2844793Sgblack@eecs.umich.edu
2853114Sgblack@eecs.umich.edu    inline uint64_t uid() {return __uid;}
2863114Sgblack@eecs.umich.edu    inline uint64_t euid() {return __euid;}
2873114Sgblack@eecs.umich.edu    inline uint64_t gid() {return __gid;}
2883114Sgblack@eecs.umich.edu    inline uint64_t egid() {return __egid;}
2893114Sgblack@eecs.umich.edu    inline uint64_t pid() {return __pid;}
2903114Sgblack@eecs.umich.edu    inline uint64_t ppid() {return __ppid;}
2913114Sgblack@eecs.umich.edu
2923669Sbinkertn@umich.edu    std::string
2933669Sbinkertn@umich.edu    fullPath(const std::string &filename)
2943669Sbinkertn@umich.edu    {
2953669Sbinkertn@umich.edu        if (filename[0] == '/' || cwd.empty())
2963669Sbinkertn@umich.edu            return filename;
2973669Sbinkertn@umich.edu
2983669Sbinkertn@umich.edu        std::string full = cwd;
2993669Sbinkertn@umich.edu
3003669Sbinkertn@umich.edu        if (cwd[cwd.size() - 1] != '/')
3013669Sbinkertn@umich.edu            full += '/';
3023669Sbinkertn@umich.edu
3033669Sbinkertn@umich.edu        return full + filename;
3043669Sbinkertn@umich.edu    }
3053669Sbinkertn@umich.edu
3065513SMichael.Adler@intel.com    std::string getcwd() const { return cwd; }
3075513SMichael.Adler@intel.com
3082680Sktlim@umich.edu    virtual void syscall(int64_t callnum, ThreadContext *tc);
3092093SN/A
3102462SN/A    virtual SyscallDesc* getDesc(int callnum) = 0;
3112715Sstever@eecs.umich.edu
3122715Sstever@eecs.umich.edu    // this function is used to create the LiveProcess object, since
3132715Sstever@eecs.umich.edu    // we can't tell which subclass of LiveProcess to use until we
3142715Sstever@eecs.umich.edu    // open and look at the object file.
3155154Sgblack@eecs.umich.edu    static LiveProcess *create(LiveProcessParams * params);
3162SN/A};
3172SN/A
318360SN/A
3192SN/A#endif // !FULL_SYSTEM
3202SN/A
321360SN/A#endif // __PROCESS_HH__
322