process.hh revision 7447:3fc243687abb
14123Sbinkertn@umich.edu/* 24123Sbinkertn@umich.edu * Copyright (c) 2001-2005 The Regents of The University of Michigan 39983Sstever@gmail.com * All rights reserved. 49983Sstever@gmail.com * 54123Sbinkertn@umich.edu * Redistribution and use in source and binary forms, with or without 64123Sbinkertn@umich.edu * modification, are permitted provided that the following conditions are 74123Sbinkertn@umich.edu * met: redistributions of source code must retain the above copyright 84123Sbinkertn@umich.edu * notice, this list of conditions and the following disclaimer; 94123Sbinkertn@umich.edu * redistributions in binary form must reproduce the above copyright 104123Sbinkertn@umich.edu * notice, this list of conditions and the following disclaimer in the 114123Sbinkertn@umich.edu * documentation and/or other materials provided with the distribution; 124123Sbinkertn@umich.edu * neither the name of the copyright holders nor the names of its 134123Sbinkertn@umich.edu * contributors may be used to endorse or promote products derived from 144123Sbinkertn@umich.edu * this software without specific prior written permission. 154123Sbinkertn@umich.edu * 164123Sbinkertn@umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 174123Sbinkertn@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 184123Sbinkertn@umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 194123Sbinkertn@umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 204123Sbinkertn@umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 214123Sbinkertn@umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 224123Sbinkertn@umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 234123Sbinkertn@umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 244123Sbinkertn@umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 254123Sbinkertn@umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 264123Sbinkertn@umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 274123Sbinkertn@umich.edu * 284123Sbinkertn@umich.edu * Authors: Nathan Binkert 294123Sbinkertn@umich.edu * Steve Reinhardt 304123Sbinkertn@umich.edu */ 314123Sbinkertn@umich.edu 324123Sbinkertn@umich.edu#ifndef __PROCESS_HH__ 334123Sbinkertn@umich.edu#define __PROCESS_HH__ 349983Sstever@gmail.com 359983Sstever@gmail.com// 369983Sstever@gmail.com// The purpose of this code is to fake the loader & syscall mechanism 374123Sbinkertn@umich.edu// when there's no OS: thus there's no reason to use it in FULL_SYSTEM 384123Sbinkertn@umich.edu// mode when we do have an OS. 396216Snate@binkert.org// 404123Sbinkertn@umich.edu#include "config/full_system.hh" 419356Snilay@cs.wisc.edu 424123Sbinkertn@umich.edu#if !FULL_SYSTEM 434123Sbinkertn@umich.edu 444123Sbinkertn@umich.edu#include <string> 456216Snate@binkert.org#include <vector> 464123Sbinkertn@umich.edu 479983Sstever@gmail.com#include "arch/registers.hh" 489983Sstever@gmail.com#include "base/statistics.hh" 499983Sstever@gmail.com#include "base/types.hh" 509983Sstever@gmail.com#include "config/the_isa.hh" 519983Sstever@gmail.com#include "sim/sim_object.hh" 529983Sstever@gmail.com#include "sim/syscallreturn.hh" 539983Sstever@gmail.com 549983Sstever@gmail.comclass PageTable; 559983Sstever@gmail.comclass ProcessParams; 569983Sstever@gmail.comclass LiveProcessParams; 579983Sstever@gmail.comclass SyscallDesc; 589983Sstever@gmail.comclass System; 599983Sstever@gmail.comclass ThreadContext; 609983Sstever@gmail.comclass TranslatingPort; 619983Sstever@gmail.com 629983Sstever@gmail.comtemplate<class IntType> 639983Sstever@gmail.comstruct AuxVector 649983Sstever@gmail.com{ 659983Sstever@gmail.com IntType a_type; 669983Sstever@gmail.com IntType a_val; 679983Sstever@gmail.com 689983Sstever@gmail.com AuxVector() 699983Sstever@gmail.com {} 709983Sstever@gmail.com 719983Sstever@gmail.com AuxVector(IntType type, IntType val); 729983Sstever@gmail.com}; 739983Sstever@gmail.com 7410762SCurtis.Dunham@arm.comclass Process : public SimObject 7510756SCurtis.Dunham@arm.com{ 764123Sbinkertn@umich.edu public: 774123Sbinkertn@umich.edu 784123Sbinkertn@umich.edu /// Pointer to object representing the system this process is 794123Sbinkertn@umich.edu /// running on. 804123Sbinkertn@umich.edu System *system; 819983Sstever@gmail.com 824123Sbinkertn@umich.edu // have we initialized a thread context from this process? If 834123Sbinkertn@umich.edu // yes, subsequent contexts are assumed to be for dynamically 849983Sstever@gmail.com // created threads and are not initialized. 859983Sstever@gmail.com bool initialContextLoaded; 869983Sstever@gmail.com 879983Sstever@gmail.com bool checkpointRestored; 889983Sstever@gmail.com 899983Sstever@gmail.com // thread contexts associated with this process 909983Sstever@gmail.com std::vector<int> contextIds; 919983Sstever@gmail.com 929983Sstever@gmail.com // number of CPUs (esxec contexts, really) assigned to this process. 939983Sstever@gmail.com unsigned int numCpus() { return contextIds.size(); } 949983Sstever@gmail.com 959983Sstever@gmail.com // record of blocked context 969983Sstever@gmail.com struct WaitRec 979983Sstever@gmail.com { 989983Sstever@gmail.com Addr waitChan; 999983Sstever@gmail.com ThreadContext *waitingContext; 1009983Sstever@gmail.com 10110762SCurtis.Dunham@arm.com WaitRec(Addr chan, ThreadContext *ctx) 10210762SCurtis.Dunham@arm.com : waitChan(chan), waitingContext(ctx) 10310762SCurtis.Dunham@arm.com { } 1049983Sstever@gmail.com }; 1059983Sstever@gmail.com 1067823Ssteve.reinhardt@amd.com // list of all blocked contexts 1074123Sbinkertn@umich.edu std::list<WaitRec> waitList; 1089174Satgutier@umich.edu 1099174Satgutier@umich.edu Addr brk_point; // top of the data segment 1109174Satgutier@umich.edu 1114123Sbinkertn@umich.edu Addr stack_base; // stack segment base (highest address) 1124123Sbinkertn@umich.edu unsigned stack_size; // initial stack size 11310762SCurtis.Dunham@arm.com Addr stack_min; // lowest address accessed on the stack 1149983Sstever@gmail.com 1159983Sstever@gmail.com // The maximum size allowed for the stack. 1169983Sstever@gmail.com Addr max_stack_size; 1179983Sstever@gmail.com 1189983Sstever@gmail.com // addr to use for next stack region (for multithreaded apps) 1199983Sstever@gmail.com Addr next_thread_stack_base; 1209983Sstever@gmail.com 12110101Sandreas@sandberg.pp.se // Base of region for mmaps (when user doesn't specify an address). 1229983Sstever@gmail.com Addr mmap_start; 1239983Sstever@gmail.com Addr mmap_end; 1249983Sstever@gmail.com 1259983Sstever@gmail.com // Base of region for nxm data 1269983Sstever@gmail.com Addr nxm_start; 1279983Sstever@gmail.com Addr nxm_end; 1289983Sstever@gmail.com 1299983Sstever@gmail.com std::string prog_fname; // file name 1309983Sstever@gmail.com 1319983Sstever@gmail.com Stats::Scalar num_syscalls; // number of syscalls executed 1329983Sstever@gmail.com 1339983Sstever@gmail.com 1349983Sstever@gmail.com protected: 1359983Sstever@gmail.com // constructor 1369983Sstever@gmail.com Process(ProcessParams * params); 1379983Sstever@gmail.com 1389983Sstever@gmail.com // post initialization startup 1399983Sstever@gmail.com virtual void startup(); 1409983Sstever@gmail.com 1419983Sstever@gmail.com protected: 1429983Sstever@gmail.com /// Memory object for initialization (image loading) 1439983Sstever@gmail.com TranslatingPort *initVirtMem; 1449983Sstever@gmail.com 1459983Sstever@gmail.com public: 1469983Sstever@gmail.com PageTable *pTable; 1479983Sstever@gmail.com 1489983Sstever@gmail.com //This id is assigned by m5 and is used to keep process' tlb entries 1499983Sstever@gmail.com //separated. 1509983Sstever@gmail.com uint64_t M5_pid; 1519983Sstever@gmail.com 1529983Sstever@gmail.com class FdMap 1539983Sstever@gmail.com { 1549983Sstever@gmail.com public: 1559983Sstever@gmail.com int fd; 1569983Sstever@gmail.com std::string filename; 1579983Sstever@gmail.com int mode; 1589983Sstever@gmail.com int flags; 1599983Sstever@gmail.com bool isPipe; 1609983Sstever@gmail.com int readPipeSource; 1619983Sstever@gmail.com uint64_t fileOffset; 1629983Sstever@gmail.com 1639983Sstever@gmail.com 1649983Sstever@gmail.com FdMap() 1659983Sstever@gmail.com { 1669983Sstever@gmail.com fd = -1; 1679983Sstever@gmail.com filename = "NULL"; 1689983Sstever@gmail.com mode = 0; 1699983Sstever@gmail.com flags = 0; 1709983Sstever@gmail.com isPipe = false; 1719983Sstever@gmail.com readPipeSource = 0; 1729983Sstever@gmail.com fileOffset = 0; 1739983Sstever@gmail.com 1749983Sstever@gmail.com } 1759983Sstever@gmail.com 1769983Sstever@gmail.com void serialize(std::ostream &os); 1779983Sstever@gmail.com void unserialize(Checkpoint *cp, const std::string §ion); 1789983Sstever@gmail.com 1799983Sstever@gmail.com }; 1809983Sstever@gmail.com 1819983Sstever@gmail.com private: 1829983Sstever@gmail.com // file descriptor remapping support 1839983Sstever@gmail.com static const int MAX_FD = 256; // max legal fd value 1844123Sbinkertn@umich.edu FdMap fd_map[MAX_FD+1]; 1854123Sbinkertn@umich.edu 1864123Sbinkertn@umich.edu 1874123Sbinkertn@umich.edu public: 1889983Sstever@gmail.com // static helper functions to generate file descriptors for constructor 1899983Sstever@gmail.com static int openInputFile(const std::string &filename); 1904123Sbinkertn@umich.edu static int openOutputFile(const std::string &filename); 1914123Sbinkertn@umich.edu 1929983Sstever@gmail.com // override of virtual SimObject method: register statistics 19310153Sandreas@sandberg.pp.se virtual void regStats(); 19410153Sandreas@sandberg.pp.se 19510153Sandreas@sandberg.pp.se // After getting registered with system object, tell process which 1964123Sbinkertn@umich.edu // system-wide context id it is assigned. 1977822Ssteve.reinhardt@amd.com void assignThreadContext(int context_id) 1984123Sbinkertn@umich.edu { 1994123Sbinkertn@umich.edu contextIds.push_back(context_id); 2004123Sbinkertn@umich.edu } 2014123Sbinkertn@umich.edu 20210670SCurtis.Dunham@arm.com // Find a free context to use 20310670SCurtis.Dunham@arm.com ThreadContext * findFreeContext(); 20410670SCurtis.Dunham@arm.com 20510670SCurtis.Dunham@arm.com // map simulator fd sim_fd to target fd tgt_fd 20610670SCurtis.Dunham@arm.com void dup_fd(int sim_fd, int tgt_fd); 2074123Sbinkertn@umich.edu 2084123Sbinkertn@umich.edu // generate new target fd for sim_fd 2094123Sbinkertn@umich.edu int alloc_fd(int sim_fd, std::string filename, int flags, int mode, bool pipe); 2104123Sbinkertn@umich.edu 2114123Sbinkertn@umich.edu // free target fd (e.g., after close) 2124123Sbinkertn@umich.edu void free_fd(int tgt_fd); 2134123Sbinkertn@umich.edu 2144123Sbinkertn@umich.edu // look up simulator fd for given target fd 2154123Sbinkertn@umich.edu int sim_fd(int tgt_fd); 2164123Sbinkertn@umich.edu 21710670SCurtis.Dunham@arm.com // look up simulator fd_map object for a given target fd 21810670SCurtis.Dunham@arm.com FdMap * sim_fd_obj(int tgt_fd); 21910670SCurtis.Dunham@arm.com 22010670SCurtis.Dunham@arm.com // fix all offsets for currently open files and save them 22110670SCurtis.Dunham@arm.com void fix_file_offsets(); 2224123Sbinkertn@umich.edu 2234123Sbinkertn@umich.edu // find all offsets for currently open files and save them 2244123Sbinkertn@umich.edu void find_file_offsets(); 2254123Sbinkertn@umich.edu 226 // set the source of this read pipe for a checkpoint resume 227 void setReadPipeSource(int read_pipe_fd, int source_fd); 228 229 virtual void syscall(int64_t callnum, ThreadContext *tc) = 0; 230 231 // check if the this addr is on the next available page and allocate it 232 // if it's not we'll panic 233 bool checkAndAllocNextPage(Addr vaddr); 234 235 void serialize(std::ostream &os); 236 void unserialize(Checkpoint *cp, const std::string §ion); 237}; 238 239// 240// "Live" process with system calls redirected to host system 241// 242class ObjectFile; 243class LiveProcess : public Process 244{ 245 protected: 246 ObjectFile *objFile; 247 std::vector<std::string> argv; 248 std::vector<std::string> envp; 249 std::string cwd; 250 251 LiveProcess(LiveProcessParams * params, ObjectFile *objFile); 252 253 virtual void argsInit(int intSize, int pageSize); 254 255 // Id of the owner of the process 256 uint64_t __uid; 257 uint64_t __euid; 258 uint64_t __gid; 259 uint64_t __egid; 260 261 // pid of the process and it's parent 262 uint64_t __pid; 263 uint64_t __ppid; 264 265 public: 266 267 enum AuxiliaryVectorType { 268 M5_AT_NULL = 0, 269 M5_AT_IGNORE = 1, 270 M5_AT_EXECFD = 2, 271 M5_AT_PHDR = 3, 272 M5_AT_PHENT = 4, 273 M5_AT_PHNUM = 5, 274 M5_AT_PAGESZ = 6, 275 M5_AT_BASE = 7, 276 M5_AT_FLAGS = 8, 277 M5_AT_ENTRY = 9, 278 M5_AT_NOTELF = 10, 279 M5_AT_UID = 11, 280 M5_AT_EUID = 12, 281 M5_AT_GID = 13, 282 M5_AT_EGID = 14, 283 // The following may be specific to Linux 284 M5_AT_PLATFORM = 15, 285 M5_AT_HWCAP = 16, 286 M5_AT_CLKTCK = 17, 287 288 M5_AT_SECURE = 23, 289 M5_BASE_PLATFORM = 24, 290 M5_AT_RANDOM = 25, 291 292 M5_AT_EXECFN = 31, 293 294 M5_AT_VECTOR_SIZE = 44 295 }; 296 297 inline uint64_t uid() {return __uid;} 298 inline uint64_t euid() {return __euid;} 299 inline uint64_t gid() {return __gid;} 300 inline uint64_t egid() {return __egid;} 301 inline uint64_t pid() {return __pid;} 302 inline uint64_t ppid() {return __ppid;} 303 304 std::string 305 fullPath(const std::string &filename) 306 { 307 if (filename[0] == '/' || cwd.empty()) 308 return filename; 309 310 std::string full = cwd; 311 312 if (cwd[cwd.size() - 1] != '/') 313 full += '/'; 314 315 return full + filename; 316 } 317 318 std::string getcwd() const { return cwd; } 319 320 virtual void syscall(int64_t callnum, ThreadContext *tc); 321 322 virtual TheISA::IntReg getSyscallArg(ThreadContext *tc, int &i) = 0; 323 virtual TheISA::IntReg getSyscallArg(ThreadContext *tc, int &i, int width); 324 virtual void setSyscallArg(ThreadContext *tc, 325 int i, TheISA::IntReg val) = 0; 326 virtual void setSyscallReturn(ThreadContext *tc, 327 SyscallReturn return_value) = 0; 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