process.hh revision 6329:5d8b91875859
111308Santhony.gutierrez@amd.com/* 211308Santhony.gutierrez@amd.com * Copyright (c) 2001-2005 The Regents of The University of Michigan 311308Santhony.gutierrez@amd.com * All rights reserved. 411308Santhony.gutierrez@amd.com * 511308Santhony.gutierrez@amd.com * Redistribution and use in source and binary forms, with or without 611308Santhony.gutierrez@amd.com * modification, are permitted provided that the following conditions are 711308Santhony.gutierrez@amd.com * met: redistributions of source code must retain the above copyright 811308Santhony.gutierrez@amd.com * notice, this list of conditions and the following disclaimer; 911308Santhony.gutierrez@amd.com * redistributions in binary form must reproduce the above copyright 1011308Santhony.gutierrez@amd.com * notice, this list of conditions and the following disclaimer in the 1111308Santhony.gutierrez@amd.com * documentation and/or other materials provided with the distribution; 1211308Santhony.gutierrez@amd.com * neither the name of the copyright holders nor the names of its 1311308Santhony.gutierrez@amd.com * contributors may be used to endorse or promote products derived from 1411308Santhony.gutierrez@amd.com * this software without specific prior written permission. 1511308Santhony.gutierrez@amd.com * 1611308Santhony.gutierrez@amd.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1711308Santhony.gutierrez@amd.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1811308Santhony.gutierrez@amd.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1911308Santhony.gutierrez@amd.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2011308Santhony.gutierrez@amd.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2111308Santhony.gutierrez@amd.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2211308Santhony.gutierrez@amd.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2311308Santhony.gutierrez@amd.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2411308Santhony.gutierrez@amd.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2511308Santhony.gutierrez@amd.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2611308Santhony.gutierrez@amd.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2711308Santhony.gutierrez@amd.com * 2811308Santhony.gutierrez@amd.com * Authors: Nathan Binkert 2911308Santhony.gutierrez@amd.com * Steve Reinhardt 3011308Santhony.gutierrez@amd.com */ 3111308Santhony.gutierrez@amd.com 3211308Santhony.gutierrez@amd.com#ifndef __PROCESS_HH__ 3311308Santhony.gutierrez@amd.com#define __PROCESS_HH__ 3411308Santhony.gutierrez@amd.com 3511308Santhony.gutierrez@amd.com// 3611308Santhony.gutierrez@amd.com// The purpose of this code is to fake the loader & syscall mechanism 3711308Santhony.gutierrez@amd.com// when there's no OS: thus there's no reason to use it in FULL_SYSTEM 3811308Santhony.gutierrez@amd.com// mode when we do have an OS. 3911308Santhony.gutierrez@amd.com// 4011308Santhony.gutierrez@amd.com#include "config/full_system.hh" 4111308Santhony.gutierrez@amd.com 4211308Santhony.gutierrez@amd.com#if !FULL_SYSTEM 4311308Santhony.gutierrez@amd.com 4411308Santhony.gutierrez@amd.com#include <string> 4511308Santhony.gutierrez@amd.com#include <vector> 4611308Santhony.gutierrez@amd.com 4711308Santhony.gutierrez@amd.com#include "arch/registers.hh" 4811308Santhony.gutierrez@amd.com#include "base/statistics.hh" 4911308Santhony.gutierrez@amd.com#include "base/types.hh" 5011308Santhony.gutierrez@amd.com#include "sim/sim_object.hh" 5111308Santhony.gutierrez@amd.com#include "sim/syscallreturn.hh" 5211308Santhony.gutierrez@amd.com 5311308Santhony.gutierrez@amd.comclass GDBListener; 5411308Santhony.gutierrez@amd.comclass PageTable; 5511308Santhony.gutierrez@amd.comclass ProcessParams; 5611308Santhony.gutierrez@amd.comclass LiveProcessParams; 5711308Santhony.gutierrez@amd.comclass SyscallDesc; 5811308Santhony.gutierrez@amd.comclass System; 5911308Santhony.gutierrez@amd.comclass ThreadContext; 6011308Santhony.gutierrez@amd.comclass TranslatingPort; 6111308Santhony.gutierrez@amd.comnamespace TheISA 6211308Santhony.gutierrez@amd.com{ 6311308Santhony.gutierrez@amd.com class RemoteGDB; 6411308Santhony.gutierrez@amd.com} 6511308Santhony.gutierrez@amd.com 6611308Santhony.gutierrez@amd.comtemplate<class IntType> 6711308Santhony.gutierrez@amd.comstruct AuxVector 6811308Santhony.gutierrez@amd.com{ 6911308Santhony.gutierrez@amd.com IntType a_type; 7011308Santhony.gutierrez@amd.com IntType a_val; 7111308Santhony.gutierrez@amd.com 7211308Santhony.gutierrez@amd.com AuxVector() 7311308Santhony.gutierrez@amd.com {} 7411308Santhony.gutierrez@amd.com 7511308Santhony.gutierrez@amd.com AuxVector(IntType type, IntType val); 7611308Santhony.gutierrez@amd.com}; 7711308Santhony.gutierrez@amd.com 7811308Santhony.gutierrez@amd.comclass Process : public SimObject 7911308Santhony.gutierrez@amd.com{ 8011308Santhony.gutierrez@amd.com public: 8111308Santhony.gutierrez@amd.com 8211308Santhony.gutierrez@amd.com /// Pointer to object representing the system this process is 8311308Santhony.gutierrez@amd.com /// running on. 8411308Santhony.gutierrez@amd.com System *system; 8511308Santhony.gutierrez@amd.com 8611308Santhony.gutierrez@amd.com // have we initialized a thread context from this process? If 8711308Santhony.gutierrez@amd.com // yes, subsequent contexts are assumed to be for dynamically 8811308Santhony.gutierrez@amd.com // created threads and are not initialized. 8911308Santhony.gutierrez@amd.com bool initialContextLoaded; 9011308Santhony.gutierrez@amd.com 9111308Santhony.gutierrez@amd.com bool checkpointRestored; 9211308Santhony.gutierrez@amd.com 9311308Santhony.gutierrez@amd.com // thread contexts associated with this process 9411308Santhony.gutierrez@amd.com std::vector<int> contextIds; 9511308Santhony.gutierrez@amd.com 9611308Santhony.gutierrez@amd.com // remote gdb objects 9711308Santhony.gutierrez@amd.com std::vector<TheISA::RemoteGDB *> remoteGDB; 9811308Santhony.gutierrez@amd.com std::vector<GDBListener *> gdbListen; 9911308Santhony.gutierrez@amd.com bool breakpoint(); 10011308Santhony.gutierrez@amd.com 10111308Santhony.gutierrez@amd.com // number of CPUs (esxec contexts, really) assigned to this process. 10211308Santhony.gutierrez@amd.com unsigned int numCpus() { return contextIds.size(); } 10311308Santhony.gutierrez@amd.com 10411308Santhony.gutierrez@amd.com // record of blocked context 10511308Santhony.gutierrez@amd.com struct WaitRec 10611308Santhony.gutierrez@amd.com { 10711308Santhony.gutierrez@amd.com Addr waitChan; 10811308Santhony.gutierrez@amd.com ThreadContext *waitingContext; 10911308Santhony.gutierrez@amd.com 11011308Santhony.gutierrez@amd.com WaitRec(Addr chan, ThreadContext *ctx) 11111308Santhony.gutierrez@amd.com : waitChan(chan), waitingContext(ctx) 11211308Santhony.gutierrez@amd.com { } 11311308Santhony.gutierrez@amd.com }; 11411308Santhony.gutierrez@amd.com 11511308Santhony.gutierrez@amd.com // list of all blocked contexts 11611308Santhony.gutierrez@amd.com std::list<WaitRec> waitList; 11711308Santhony.gutierrez@amd.com 11811308Santhony.gutierrez@amd.com Addr brk_point; // top of the data segment 11911308Santhony.gutierrez@amd.com 12011308Santhony.gutierrez@amd.com Addr stack_base; // stack segment base (highest address) 12111308Santhony.gutierrez@amd.com unsigned stack_size; // initial stack size 12211308Santhony.gutierrez@amd.com Addr stack_min; // lowest address accessed on the stack 12311308Santhony.gutierrez@amd.com 12411308Santhony.gutierrez@amd.com // The maximum size allowed for the stack. 12511308Santhony.gutierrez@amd.com Addr max_stack_size; 12611308Santhony.gutierrez@amd.com 12711308Santhony.gutierrez@amd.com // addr to use for next stack region (for multithreaded apps) 12811308Santhony.gutierrez@amd.com Addr next_thread_stack_base; 12911308Santhony.gutierrez@amd.com 13011308Santhony.gutierrez@amd.com // Base of region for mmaps (when user doesn't specify an address). 13111308Santhony.gutierrez@amd.com Addr mmap_start; 13211308Santhony.gutierrez@amd.com Addr mmap_end; 13311308Santhony.gutierrez@amd.com 13411308Santhony.gutierrez@amd.com // Base of region for nxm data 13511308Santhony.gutierrez@amd.com Addr nxm_start; 13611308Santhony.gutierrez@amd.com Addr nxm_end; 13711308Santhony.gutierrez@amd.com 13811308Santhony.gutierrez@amd.com std::string prog_fname; // file name 13911308Santhony.gutierrez@amd.com 14011308Santhony.gutierrez@amd.com Stats::Scalar num_syscalls; // number of syscalls executed 14111308Santhony.gutierrez@amd.com 14211308Santhony.gutierrez@amd.com 14311308Santhony.gutierrez@amd.com protected: 14411308Santhony.gutierrez@amd.com // constructor 14511308Santhony.gutierrez@amd.com Process(ProcessParams * params); 14611308Santhony.gutierrez@amd.com 14711308Santhony.gutierrez@amd.com // post initialization startup 14811308Santhony.gutierrez@amd.com virtual void startup(); 14911308Santhony.gutierrez@amd.com 15011308Santhony.gutierrez@amd.com protected: 15111308Santhony.gutierrez@amd.com /// Memory object for initialization (image loading) 15211308Santhony.gutierrez@amd.com TranslatingPort *initVirtMem; 15311308Santhony.gutierrez@amd.com 15411308Santhony.gutierrez@amd.com public: 15511308Santhony.gutierrez@amd.com PageTable *pTable; 15611308Santhony.gutierrez@amd.com 15711308Santhony.gutierrez@amd.com //This id is assigned by m5 and is used to keep process' tlb entries 15811308Santhony.gutierrez@amd.com //separated. 15911308Santhony.gutierrez@amd.com uint64_t M5_pid; 16011308Santhony.gutierrez@amd.com 16111308Santhony.gutierrez@amd.com class FdMap 16211308Santhony.gutierrez@amd.com { 16311308Santhony.gutierrez@amd.com public: 16411308Santhony.gutierrez@amd.com int fd; 16511308Santhony.gutierrez@amd.com std::string filename; 16611308Santhony.gutierrez@amd.com int mode; 16711308Santhony.gutierrez@amd.com int flags; 16811308Santhony.gutierrez@amd.com bool isPipe; 16911308Santhony.gutierrez@amd.com int readPipeSource; 17011308Santhony.gutierrez@amd.com uint64_t fileOffset; 17111308Santhony.gutierrez@amd.com 17211308Santhony.gutierrez@amd.com 17311308Santhony.gutierrez@amd.com FdMap() 17411308Santhony.gutierrez@amd.com { 17511308Santhony.gutierrez@amd.com fd = -1; 17611308Santhony.gutierrez@amd.com filename = "NULL"; 17711308Santhony.gutierrez@amd.com mode = 0; 17811308Santhony.gutierrez@amd.com flags = 0; 17911308Santhony.gutierrez@amd.com isPipe = false; 18011308Santhony.gutierrez@amd.com readPipeSource = 0; 18111308Santhony.gutierrez@amd.com fileOffset = 0; 18211308Santhony.gutierrez@amd.com 18311308Santhony.gutierrez@amd.com } 18411308Santhony.gutierrez@amd.com 18511308Santhony.gutierrez@amd.com void serialize(std::ostream &os); 18611308Santhony.gutierrez@amd.com void unserialize(Checkpoint *cp, const std::string §ion); 18711308Santhony.gutierrez@amd.com 18811308Santhony.gutierrez@amd.com }; 18911308Santhony.gutierrez@amd.com 19011308Santhony.gutierrez@amd.com private: 19111308Santhony.gutierrez@amd.com // file descriptor remapping support 19211308Santhony.gutierrez@amd.com static const int MAX_FD = 256; // max legal fd value 19311308Santhony.gutierrez@amd.com FdMap fd_map[MAX_FD+1]; 19411308Santhony.gutierrez@amd.com 19511308Santhony.gutierrez@amd.com 19611308Santhony.gutierrez@amd.com public: 19711308Santhony.gutierrez@amd.com // static helper functions to generate file descriptors for constructor 19811308Santhony.gutierrez@amd.com static int openInputFile(const std::string &filename); 19911308Santhony.gutierrez@amd.com static int openOutputFile(const std::string &filename); 20011308Santhony.gutierrez@amd.com 20111308Santhony.gutierrez@amd.com // override of virtual SimObject method: register statistics 20211308Santhony.gutierrez@amd.com virtual void regStats(); 20311308Santhony.gutierrez@amd.com 20411308Santhony.gutierrez@amd.com // After getting registered with system object, tell process which 20511308Santhony.gutierrez@amd.com // system-wide context id it is assigned. 20611308Santhony.gutierrez@amd.com void assignThreadContext(int context_id) 20711308Santhony.gutierrez@amd.com { 20811308Santhony.gutierrez@amd.com contextIds.push_back(context_id); 20911308Santhony.gutierrez@amd.com } 21011308Santhony.gutierrez@amd.com 21111308Santhony.gutierrez@amd.com // Find a free context to use 21211308Santhony.gutierrez@amd.com ThreadContext * findFreeContext(); 21311308Santhony.gutierrez@amd.com 21411308Santhony.gutierrez@amd.com // map simulator fd sim_fd to target fd tgt_fd 21511308Santhony.gutierrez@amd.com void dup_fd(int sim_fd, int tgt_fd); 21611308Santhony.gutierrez@amd.com 21711308Santhony.gutierrez@amd.com // generate new target fd for sim_fd 21811308Santhony.gutierrez@amd.com int alloc_fd(int sim_fd, std::string filename, int flags, int mode, bool pipe); 21911308Santhony.gutierrez@amd.com 22011308Santhony.gutierrez@amd.com // free target fd (e.g., after close) 22111308Santhony.gutierrez@amd.com void free_fd(int tgt_fd); 22211308Santhony.gutierrez@amd.com 22311308Santhony.gutierrez@amd.com // look up simulator fd for given target fd 22411308Santhony.gutierrez@amd.com int sim_fd(int tgt_fd); 22511308Santhony.gutierrez@amd.com 22611308Santhony.gutierrez@amd.com // look up simulator fd_map object for a given target fd 22711308Santhony.gutierrez@amd.com FdMap * sim_fd_obj(int tgt_fd); 22811308Santhony.gutierrez@amd.com 22911308Santhony.gutierrez@amd.com // fix all offsets for currently open files and save them 23011308Santhony.gutierrez@amd.com void fix_file_offsets(); 23111308Santhony.gutierrez@amd.com 23211308Santhony.gutierrez@amd.com // find all offsets for currently open files and save them 23311308Santhony.gutierrez@amd.com void find_file_offsets(); 23411308Santhony.gutierrez@amd.com 23511308Santhony.gutierrez@amd.com // set the source of this read pipe for a checkpoint resume 23611308Santhony.gutierrez@amd.com void setReadPipeSource(int read_pipe_fd, int source_fd); 23711308Santhony.gutierrez@amd.com 23811308Santhony.gutierrez@amd.com virtual void syscall(int64_t callnum, ThreadContext *tc) = 0; 23911308Santhony.gutierrez@amd.com 24011308Santhony.gutierrez@amd.com // check if the this addr is on the next available page and allocate it 24111308Santhony.gutierrez@amd.com // if it's not we'll panic 24211308Santhony.gutierrez@amd.com bool checkAndAllocNextPage(Addr vaddr); 24311308Santhony.gutierrez@amd.com 24411308Santhony.gutierrez@amd.com void serialize(std::ostream &os); 24511308Santhony.gutierrez@amd.com void unserialize(Checkpoint *cp, const std::string §ion); 24611308Santhony.gutierrez@amd.com}; 24711308Santhony.gutierrez@amd.com 24811308Santhony.gutierrez@amd.com// 24911308Santhony.gutierrez@amd.com// "Live" process with system calls redirected to host system 25011308Santhony.gutierrez@amd.com// 25111308Santhony.gutierrez@amd.comclass ObjectFile; 25211308Santhony.gutierrez@amd.comclass LiveProcess : public Process 25311308Santhony.gutierrez@amd.com{ 25411308Santhony.gutierrez@amd.com protected: 25511308Santhony.gutierrez@amd.com ObjectFile *objFile; 25611308Santhony.gutierrez@amd.com std::vector<std::string> argv; 25711308Santhony.gutierrez@amd.com std::vector<std::string> envp; 25811308Santhony.gutierrez@amd.com std::string cwd; 25911308Santhony.gutierrez@amd.com 26011308Santhony.gutierrez@amd.com LiveProcess(LiveProcessParams * params, ObjectFile *objFile); 26111308Santhony.gutierrez@amd.com 26211308Santhony.gutierrez@amd.com virtual void argsInit(int intSize, int pageSize); 26311308Santhony.gutierrez@amd.com 26411308Santhony.gutierrez@amd.com // Id of the owner of the process 26511308Santhony.gutierrez@amd.com uint64_t __uid; 26611308Santhony.gutierrez@amd.com uint64_t __euid; 26711308Santhony.gutierrez@amd.com uint64_t __gid; 26811308Santhony.gutierrez@amd.com uint64_t __egid; 26911308Santhony.gutierrez@amd.com 27011308Santhony.gutierrez@amd.com // pid of the process and it's parent 27111308Santhony.gutierrez@amd.com uint64_t __pid; 27211308Santhony.gutierrez@amd.com uint64_t __ppid; 27311308Santhony.gutierrez@amd.com 27411308Santhony.gutierrez@amd.com public: 27511308Santhony.gutierrez@amd.com 27611308Santhony.gutierrez@amd.com enum AuxiliaryVectorType { 27711308Santhony.gutierrez@amd.com M5_AT_NULL = 0, 27811308Santhony.gutierrez@amd.com M5_AT_IGNORE = 1, 27911308Santhony.gutierrez@amd.com M5_AT_EXECFD = 2, 28011308Santhony.gutierrez@amd.com M5_AT_PHDR = 3, 28111308Santhony.gutierrez@amd.com M5_AT_PHENT = 4, 28211308Santhony.gutierrez@amd.com M5_AT_PHNUM = 5, 28311308Santhony.gutierrez@amd.com M5_AT_PAGESZ = 6, 28411308Santhony.gutierrez@amd.com M5_AT_BASE = 7, 28511308Santhony.gutierrez@amd.com M5_AT_FLAGS = 8, 28611308Santhony.gutierrez@amd.com M5_AT_ENTRY = 9, 28711308Santhony.gutierrez@amd.com M5_AT_NOTELF = 10, 28811308Santhony.gutierrez@amd.com M5_AT_UID = 11, 28911308Santhony.gutierrez@amd.com M5_AT_EUID = 12, 29011308Santhony.gutierrez@amd.com M5_AT_GID = 13, 29111308Santhony.gutierrez@amd.com M5_AT_EGID = 14, 29211308Santhony.gutierrez@amd.com // The following may be specific to Linux 29311308Santhony.gutierrez@amd.com M5_AT_PLATFORM = 15, 29411308Santhony.gutierrez@amd.com M5_AT_HWCAP = 16, 29511308Santhony.gutierrez@amd.com M5_AT_CLKTCK = 17, 29611308Santhony.gutierrez@amd.com 29711308Santhony.gutierrez@amd.com M5_AT_SECURE = 23, 29811308Santhony.gutierrez@amd.com 29911308Santhony.gutierrez@amd.com M5_AT_VECTOR_SIZE = 44 30011308Santhony.gutierrez@amd.com }; 30111308Santhony.gutierrez@amd.com 30211308Santhony.gutierrez@amd.com inline uint64_t uid() {return __uid;} 30311308Santhony.gutierrez@amd.com inline uint64_t euid() {return __euid;} 30411308Santhony.gutierrez@amd.com inline uint64_t gid() {return __gid;} 30511308Santhony.gutierrez@amd.com inline uint64_t egid() {return __egid;} 30611308Santhony.gutierrez@amd.com inline uint64_t pid() {return __pid;} 30711308Santhony.gutierrez@amd.com inline uint64_t ppid() {return __ppid;} 30811308Santhony.gutierrez@amd.com 30911308Santhony.gutierrez@amd.com std::string 31011308Santhony.gutierrez@amd.com fullPath(const std::string &filename) 31111308Santhony.gutierrez@amd.com { 31211308Santhony.gutierrez@amd.com if (filename[0] == '/' || cwd.empty()) 31311308Santhony.gutierrez@amd.com return filename; 31411308Santhony.gutierrez@amd.com 31511308Santhony.gutierrez@amd.com std::string full = cwd; 31611308Santhony.gutierrez@amd.com 31711308Santhony.gutierrez@amd.com if (cwd[cwd.size() - 1] != '/') 31811308Santhony.gutierrez@amd.com full += '/'; 31911308Santhony.gutierrez@amd.com 32011308Santhony.gutierrez@amd.com return full + filename; 32111308Santhony.gutierrez@amd.com } 32211308Santhony.gutierrez@amd.com 32311308Santhony.gutierrez@amd.com std::string getcwd() const { return cwd; } 32411308Santhony.gutierrez@amd.com 32511308Santhony.gutierrez@amd.com virtual void syscall(int64_t callnum, ThreadContext *tc); 32611308Santhony.gutierrez@amd.com virtual TheISA::IntReg getSyscallArg(ThreadContext *tc, int i) = 0; 32711308Santhony.gutierrez@amd.com virtual void setSyscallArg(ThreadContext *tc, 32811308Santhony.gutierrez@amd.com int i, TheISA::IntReg val) = 0; 32911308Santhony.gutierrez@amd.com virtual void setSyscallReturn(ThreadContext *tc, 33011308Santhony.gutierrez@amd.com SyscallReturn return_value) = 0; 33111308Santhony.gutierrez@amd.com 33211308Santhony.gutierrez@amd.com virtual SyscallDesc* getDesc(int callnum) = 0; 33311308Santhony.gutierrez@amd.com 33411308Santhony.gutierrez@amd.com // this function is used to create the LiveProcess object, since 33511308Santhony.gutierrez@amd.com // we can't tell which subclass of LiveProcess to use until we 33611308Santhony.gutierrez@amd.com // open and look at the object file. 33711308Santhony.gutierrez@amd.com static LiveProcess *create(LiveProcessParams * params); 33811308Santhony.gutierrez@amd.com}; 33911308Santhony.gutierrez@amd.com 34011308Santhony.gutierrez@amd.com 34111308Santhony.gutierrez@amd.com#endif // !FULL_SYSTEM 34211308Santhony.gutierrez@amd.com 34311308Santhony.gutierrez@amd.com#endif // __PROCESS_HH__ 34411308Santhony.gutierrez@amd.com