process.hh revision 5758:9c3edb28db1a
1/* 2 * Copyright (c) 2001-2005 The Regents of The University of Michigan 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer; 9 * redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution; 12 * neither the name of the copyright holders nor the names of its 13 * contributors may be used to endorse or promote products derived from 14 * this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * 28 * Authors: Nathan Binkert 29 * Steve Reinhardt 30 */ 31 32#ifndef __PROCESS_HH__ 33#define __PROCESS_HH__ 34 35// 36// The purpose of this code is to fake the loader & syscall mechanism 37// when there's no OS: thus there's no reason to use it in FULL_SYSTEM 38// mode when we do have an OS. 39// 40#include "config/full_system.hh" 41 42#if !FULL_SYSTEM 43 44#include <string> 45#include <vector> 46 47#include "base/statistics.hh" 48#include "sim/host.hh" 49#include "sim/sim_object.hh" 50 51class GDBListener; 52class PageTable; 53class ProcessParams; 54class LiveProcessParams; 55class SyscallDesc; 56class System; 57class ThreadContext; 58class TranslatingPort; 59namespace TheISA 60{ 61 class RemoteGDB; 62} 63 64template<class IntType> 65struct M5_auxv_t 66{ 67 IntType a_type; 68 union { 69 IntType a_val; 70 IntType a_ptr; 71 IntType a_fcn; 72 }; 73 74 M5_auxv_t() 75 {} 76 77 M5_auxv_t(IntType type, IntType val); 78}; 79 80class Process : public SimObject 81{ 82 public: 83 84 /// Pointer to object representing the system this process is 85 /// running on. 86 System *system; 87 88 // have we initialized a thread context from this process? If 89 // yes, subsequent contexts are assumed to be for dynamically 90 // created threads and are not initialized. 91 bool initialContextLoaded; 92 93 bool checkpointRestored; 94 95 // thread contexts associated with this process 96 std::vector<int> contextIds; 97 98 // remote gdb objects 99 std::vector<TheISA::RemoteGDB *> remoteGDB; 100 std::vector<GDBListener *> gdbListen; 101 bool breakpoint(); 102 103 // number of CPUs (esxec contexts, really) assigned to this process. 104 unsigned int numCpus() { return contextIds.size(); } 105 106 // record of blocked context 107 struct WaitRec 108 { 109 Addr waitChan; 110 ThreadContext *waitingContext; 111 112 WaitRec(Addr chan, ThreadContext *ctx) 113 : waitChan(chan), waitingContext(ctx) 114 { } 115 }; 116 117 // list of all blocked contexts 118 std::list<WaitRec> waitList; 119 120 Addr brk_point; // top of the data segment 121 122 Addr stack_base; // stack segment base (highest address) 123 unsigned stack_size; // initial stack size 124 Addr stack_min; // lowest address accessed on the stack 125 126 // The maximum size allowed for the stack. 127 Addr max_stack_size; 128 129 // addr to use for next stack region (for multithreaded apps) 130 Addr next_thread_stack_base; 131 132 // Base of region for mmaps (when user doesn't specify an address). 133 Addr mmap_start; 134 Addr mmap_end; 135 136 // Base of region for nxm data 137 Addr nxm_start; 138 Addr nxm_end; 139 140 std::string prog_fname; // file name 141 142 Stats::Scalar<> num_syscalls; // number of syscalls executed 143 144 145 protected: 146 // constructor 147 Process(ProcessParams * params); 148 149 // post initialization startup 150 virtual void startup(); 151 152 protected: 153 /// Memory object for initialization (image loading) 154 TranslatingPort *initVirtMem; 155 156 public: 157 PageTable *pTable; 158 159 //This id is assigned by m5 and is used to keep process' tlb entries 160 //separated. 161 uint64_t M5_pid; 162 163 class FdMap 164 { 165 public: 166 int fd; 167 std::string filename; 168 int mode; 169 int flags; 170 bool isPipe; 171 int readPipeSource; 172 uint64_t fileOffset; 173 174 175 FdMap() 176 { 177 fd = -1; 178 filename = "NULL"; 179 mode = 0; 180 flags = 0; 181 isPipe = false; 182 readPipeSource = 0; 183 fileOffset = 0; 184 185 } 186 187 void serialize(std::ostream &os); 188 void unserialize(Checkpoint *cp, const std::string §ion); 189 190 }; 191 192 private: 193 // file descriptor remapping support 194 static const int MAX_FD = 256; // max legal fd value 195 FdMap fd_map[MAX_FD+1]; 196 197 198 public: 199 // static helper functions to generate file descriptors for constructor 200 static int openInputFile(const std::string &filename); 201 static int openOutputFile(const std::string &filename); 202 203 // override of virtual SimObject method: register statistics 204 virtual void regStats(); 205 206 // After getting registered with system object, tell process which 207 // system-wide context id it is assigned. 208 void assignThreadContext(int context_id) 209 { 210 contextIds.push_back(context_id); 211 } 212 213 // Find a free context to use 214 ThreadContext * findFreeContext(); 215 216 // map simulator fd sim_fd to target fd tgt_fd 217 void dup_fd(int sim_fd, int tgt_fd); 218 219 // generate new target fd for sim_fd 220 int alloc_fd(int sim_fd, std::string filename, int flags, int mode, bool pipe); 221 222 // free target fd (e.g., after close) 223 void free_fd(int tgt_fd); 224 225 // look up simulator fd for given target fd 226 int sim_fd(int tgt_fd); 227 228 // look up simulator fd_map object for a given target fd 229 FdMap * sim_fd_obj(int tgt_fd); 230 231 // fix all offsets for currently open files and save them 232 void fix_file_offsets(); 233 234 // find all offsets for currently open files and save them 235 void find_file_offsets(); 236 237 // set the source of this read pipe for a checkpoint resume 238 void setReadPipeSource(int read_pipe_fd, int source_fd); 239 240 virtual void syscall(int64_t callnum, ThreadContext *tc) = 0; 241 242 // check if the this addr is on the next available page and allocate it 243 // if it's not we'll panic 244 bool checkAndAllocNextPage(Addr vaddr); 245 246 void serialize(std::ostream &os); 247 void unserialize(Checkpoint *cp, const std::string §ion); 248}; 249 250// 251// "Live" process with system calls redirected to host system 252// 253class ObjectFile; 254class LiveProcess : public Process 255{ 256 protected: 257 ObjectFile *objFile; 258 std::vector<std::string> argv; 259 std::vector<std::string> envp; 260 std::string cwd; 261 262 LiveProcess(LiveProcessParams * params, ObjectFile *objFile); 263 264 virtual void argsInit(int intSize, int pageSize); 265 266 // Id of the owner of the process 267 uint64_t __uid; 268 uint64_t __euid; 269 uint64_t __gid; 270 uint64_t __egid; 271 272 // pid of the process and it's parent 273 uint64_t __pid; 274 uint64_t __ppid; 275 276 public: 277 278 enum AuxiliaryVectorType { 279 M5_AT_NULL = 0, 280 M5_AT_IGNORE = 1, 281 M5_AT_EXECFD = 2, 282 M5_AT_PHDR = 3, 283 M5_AT_PHENT = 4, 284 M5_AT_PHNUM = 5, 285 M5_AT_PAGESZ = 6, 286 M5_AT_BASE = 7, 287 M5_AT_FLAGS = 8, 288 M5_AT_ENTRY = 9, 289 M5_AT_NOTELF = 10, 290 M5_AT_UID = 11, 291 M5_AT_EUID = 12, 292 M5_AT_GID = 13, 293 M5_AT_EGID = 14, 294 // The following may be specific to Linux 295 M5_AT_PLATFORM = 15, 296 M5_AT_HWCAP = 16, 297 M5_AT_CLKTCK = 17, 298 299 M5_AT_SECURE = 23, 300 301 M5_AT_VECTOR_SIZE = 44 302 }; 303 304 inline uint64_t uid() {return __uid;} 305 inline uint64_t euid() {return __euid;} 306 inline uint64_t gid() {return __gid;} 307 inline uint64_t egid() {return __egid;} 308 inline uint64_t pid() {return __pid;} 309 inline uint64_t ppid() {return __ppid;} 310 311 std::string 312 fullPath(const std::string &filename) 313 { 314 if (filename[0] == '/' || cwd.empty()) 315 return filename; 316 317 std::string full = cwd; 318 319 if (cwd[cwd.size() - 1] != '/') 320 full += '/'; 321 322 return full + filename; 323 } 324 325 std::string getcwd() const { return cwd; } 326 327 virtual void syscall(int64_t callnum, ThreadContext *tc); 328 329 virtual SyscallDesc* getDesc(int callnum) = 0; 330 331 // this function is used to create the LiveProcess object, since 332 // we can't tell which subclass of LiveProcess to use until we 333 // open and look at the object file. 334 static LiveProcess *create(LiveProcessParams * params); 335}; 336 337 338#endif // !FULL_SYSTEM 339 340#endif // __PROCESS_HH__ 341