Major changes to how SimObjects are created and initialized. Almost all
[gem5.git] / src / sim / process.cc
index 20f7fec2d0d053f8f721ab323b9966967dccf840..c556ade127b09c711d179e2eb4be7966c66a86cf 100644 (file)
@@ -35,6 +35,7 @@
 
 #include <string>
 
+#include "arch/remote_gdb.hh"
 #include "base/intmath.hh"
 #include "base/loader/object_file.hh"
 #include "base/loader/symtab.hh"
@@ -44,8 +45,9 @@
 #include "mem/page_table.hh"
 #include "mem/physical.hh"
 #include "mem/translating_port.hh"
-#include "sim/builder.hh"
+#include "params/LiveProcess.hh"
 #include "sim/process.hh"
+#include "sim/process_impl.hh"
 #include "sim/stats.hh"
 #include "sim/syscall_emul.hh"
 #include "sim/system.hh"
@@ -59,6 +61,8 @@
 #include "arch/sparc/solaris/process.hh"
 #elif THE_ISA == MIPS_ISA
 #include "arch/mips/linux/process.hh"
+#elif THE_ISA == X86_ISA
+#include "arch/x86/linux/process.hh"
 #else
 #error "THE_ISA not set"
 #endif
@@ -154,6 +158,13 @@ Process::registerThreadContext(ThreadContext *tc)
     int myIndex = threadContexts.size();
     threadContexts.push_back(tc);
 
+//    RemoteGDB *rgdb = new RemoteGDB(system, tc);
+//    GDBListener *gdbl = new GDBListener(rgdb, 7000 + myIndex);
+//    gdbl->listen();
+    //gdbl->accept();
+
+//    remoteGDB.push_back(rgdb);
+
     // return CPU number to caller
     return myIndex;
 }
@@ -172,7 +183,8 @@ Process::startup()
 
     Port *mem_port;
     mem_port = system->physmem->getPort("functional");
-    initVirtMem = new TranslatingPort("process init port", pTable, true);
+    initVirtMem = new TranslatingPort("process init port", this,
+            TranslatingPort::Always);
     mem_port->setPeer(initVirtMem);
     initVirtMem->setPeer(mem_port);
 }
@@ -240,14 +252,64 @@ Process::sim_fd(int tgt_fd)
     return fd_map[tgt_fd];
 }
 
+bool
+Process::checkAndAllocNextPage(Addr vaddr)
+{
+    // if this is an initial write we might not have
+    if (vaddr >= stack_min && vaddr < stack_base) {
+        pTable->allocate(roundDown(vaddr, VMPageSize), VMPageSize);
+        return true;
+    }
 
+    // We've accessed the next page of the stack, so extend the stack
+    // to cover it.
+    if(vaddr < stack_min && vaddr >= stack_min - TheISA::PageBytes)
+    {
+        stack_min -= TheISA::PageBytes;
+        if(stack_base - stack_min > 8*1024*1024)
+            fatal("Over max stack size for one thread\n");
+        pTable->allocate(stack_min, TheISA::PageBytes);
+        warn("Increasing stack size by one page.");
+        return true;
+    }
+    return false;
+}
 
-//
-// need to declare these here since there is no concrete Process type
-// that can be constructed (i.e., no REGISTER_SIM_OBJECT() macro call,
-// which is where these get declared for concrete types).
-//
-DEFINE_SIM_OBJECT_CLASS_NAME("Process", Process)
+void
+Process::serialize(std::ostream &os)
+{
+    SERIALIZE_SCALAR(initialContextLoaded);
+    SERIALIZE_SCALAR(brk_point);
+    SERIALIZE_SCALAR(stack_base);
+    SERIALIZE_SCALAR(stack_size);
+    SERIALIZE_SCALAR(stack_min);
+    SERIALIZE_SCALAR(next_thread_stack_base);
+    SERIALIZE_SCALAR(mmap_start);
+    SERIALIZE_SCALAR(mmap_end);
+    SERIALIZE_SCALAR(nxm_start);
+    SERIALIZE_SCALAR(nxm_end);
+    SERIALIZE_ARRAY(fd_map, MAX_FD);
+
+    pTable->serialize(os);
+}
+
+void
+Process::unserialize(Checkpoint *cp, const std::string &section)
+{
+    UNSERIALIZE_SCALAR(initialContextLoaded);
+    UNSERIALIZE_SCALAR(brk_point);
+    UNSERIALIZE_SCALAR(stack_base);
+    UNSERIALIZE_SCALAR(stack_size);
+    UNSERIALIZE_SCALAR(stack_min);
+    UNSERIALIZE_SCALAR(next_thread_stack_base);
+    UNSERIALIZE_SCALAR(mmap_start);
+    UNSERIALIZE_SCALAR(mmap_end);
+    UNSERIALIZE_SCALAR(nxm_start);
+    UNSERIALIZE_SCALAR(nxm_end);
+    UNSERIALIZE_ARRAY(fd_map, MAX_FD);
+
+    pTable->unserialize(cp, section);
+}
 
 
 ////////////////////////////////////////////////////////////////////////
@@ -257,31 +319,24 @@ DEFINE_SIM_OBJECT_CLASS_NAME("Process", Process)
 ////////////////////////////////////////////////////////////////////////
 
 
-void
-copyStringArray(vector<string> &strings, Addr array_ptr, Addr data_ptr,
-                TranslatingPort* memPort)
-{
-    Addr data_ptr_swap;
-    for (int i = 0; i < strings.size(); ++i) {
-        data_ptr_swap = htog(data_ptr);
-        memPort->writeBlob(array_ptr, (uint8_t*)&data_ptr_swap, sizeof(Addr));
-        memPort->writeString(data_ptr, strings[i].c_str());
-        array_ptr += sizeof(Addr);
-        data_ptr += strings[i].size() + 1;
-    }
-    // add NULL terminator
-    data_ptr = 0;
-
-    memPort->writeBlob(array_ptr, (uint8_t*)&data_ptr, sizeof(Addr));
-}
-
 LiveProcess::LiveProcess(const string &nm, ObjectFile *_objFile,
                          System *_system,
                          int stdin_fd, int stdout_fd, int stderr_fd,
-                         vector<string> &_argv, vector<string> &_envp)
+                         vector<string> &_argv, vector<string> &_envp,
+                         const string &_cwd,
+                         uint64_t _uid, uint64_t _euid,
+                         uint64_t _gid, uint64_t _egid,
+                         uint64_t _pid, uint64_t _ppid)
     : Process(nm, _system, stdin_fd, stdout_fd, stderr_fd),
-      objFile(_objFile), argv(_argv), envp(_envp)
+      objFile(_objFile), argv(_argv), envp(_envp), cwd(_cwd)
 {
+    __uid = _uid;
+    __euid = _euid;
+    __gid = _gid;
+    __egid = _egid;
+    __pid = _pid;
+    __ppid = _ppid;
+
     prog_fname = argv[0];
 
     // load up symbols, if any... these may be used for debugging or
@@ -381,7 +436,11 @@ LiveProcess *
 LiveProcess::create(const std::string &nm, System *system, int stdin_fd,
                     int stdout_fd, int stderr_fd, std::string executable,
                     std::vector<std::string> &argv,
-                    std::vector<std::string> &envp)
+                    std::vector<std::string> &envp,
+                    const std::string &cwd,
+                    uint64_t _uid, uint64_t _euid,
+                    uint64_t _gid, uint64_t _egid,
+                    uint64_t _pid, uint64_t _ppid)
 {
     LiveProcess *process = NULL;
 
@@ -390,6 +449,11 @@ LiveProcess::create(const std::string &nm, System *system, int stdin_fd,
         fatal("Can't load object file %s", executable);
     }
 
+    if (objFile->isDynamic())
+       fatal("Object file is a dynamic executable however only static "
+             "executables are supported!\n        Please recompile your "
+             "executable as a static binary and try again.\n");
+
 #if THE_ISA == ALPHA_ISA
     if (objFile->getArch() != ObjectFile::Alpha)
         fatal("Object file architecture does not match compiled ISA (Alpha).");
@@ -397,33 +461,60 @@ LiveProcess::create(const std::string &nm, System *system, int stdin_fd,
       case ObjectFile::Tru64:
         process = new AlphaTru64Process(nm, objFile, system,
                                         stdin_fd, stdout_fd, stderr_fd,
-                                        argv, envp);
+                                        argv, envp, cwd,
+                                        _uid, _euid, _gid, _egid, _pid, _ppid);
         break;
 
       case ObjectFile::Linux:
         process = new AlphaLinuxProcess(nm, objFile, system,
                                         stdin_fd, stdout_fd, stderr_fd,
-                                        argv, envp);
+                                        argv, envp, cwd,
+                                        _uid, _euid, _gid, _egid, _pid, _ppid);
         break;
 
       default:
         fatal("Unknown/unsupported operating system.");
     }
 #elif THE_ISA == SPARC_ISA
-    if (objFile->getArch() != ObjectFile::SPARC)
+    if (objFile->getArch() != ObjectFile::SPARC64 && objFile->getArch() != ObjectFile::SPARC32)
         fatal("Object file architecture does not match compiled ISA (SPARC).");
     switch (objFile->getOpSys()) {
       case ObjectFile::Linux:
-        process = new SparcLinuxProcess(nm, objFile, system,
-                                        stdin_fd, stdout_fd, stderr_fd,
-                                        argv, envp);
+        if (objFile->getArch() == ObjectFile::SPARC64) {
+            process = new Sparc64LinuxProcess(nm, objFile, system,
+                                              stdin_fd, stdout_fd, stderr_fd,
+                                              argv, envp, cwd,
+                                              _uid, _euid, _gid,
+                                              _egid, _pid, _ppid);
+        } else {
+            process = new Sparc32LinuxProcess(nm, objFile, system,
+                                              stdin_fd, stdout_fd, stderr_fd,
+                                              argv, envp, cwd,
+                                              _uid, _euid, _gid,
+                                              _egid, _pid, _ppid);
+        }
         break;
 
 
       case ObjectFile::Solaris:
         process = new SparcSolarisProcess(nm, objFile, system,
                                         stdin_fd, stdout_fd, stderr_fd,
-                                        argv, envp);
+                                        argv, envp, cwd,
+                                        _uid, _euid, _gid, _egid, _pid, _ppid);
+        break;
+      default:
+        fatal("Unknown/unsupported operating system.");
+    }
+#elif THE_ISA == X86_ISA
+    if (objFile->getArch() != ObjectFile::X86)
+        fatal("Object file architecture does not match compiled ISA (x86).");
+    switch (objFile->getOpSys()) {
+      case ObjectFile::Linux:
+        process = new X86LinuxProcess(nm, objFile, system,
+                                          stdin_fd, stdout_fd, stderr_fd,
+                                          argv, envp, cwd,
+                                          _uid, _euid, _gid,
+                                          _egid, _pid, _ppid);
         break;
       default:
         fatal("Unknown/unsupported operating system.");
@@ -435,7 +526,8 @@ LiveProcess::create(const std::string &nm, System *system, int stdin_fd,
       case ObjectFile::Linux:
         process = new MipsLinuxProcess(nm, objFile, system,
                                         stdin_fd, stdout_fd, stderr_fd,
-                                        argv, envp);
+                                        argv, envp, cwd,
+                                        _uid, _euid, _gid, _egid, _pid, _ppid);
         break;
 
       default:
@@ -451,44 +543,8 @@ LiveProcess::create(const std::string &nm, System *system, int stdin_fd,
     return process;
 }
 
-
-BEGIN_DECLARE_SIM_OBJECT_PARAMS(LiveProcess)
-
-    VectorParam<string> cmd;
-    Param<string> executable;
-    Param<string> input;
-    Param<string> output;
-    VectorParam<string> env;
-    SimObjectParam<System *> system;
-    Param<uint64_t> uid;
-    Param<uint64_t> euid;
-    Param<uint64_t> gid;
-    Param<uint64_t> egid;
-    Param<uint64_t> pid;
-    Param<uint64_t> ppid;
-
-END_DECLARE_SIM_OBJECT_PARAMS(LiveProcess)
-
-
-BEGIN_INIT_SIM_OBJECT_PARAMS(LiveProcess)
-
-    INIT_PARAM(cmd, "command line (executable plus arguments)"),
-    INIT_PARAM(executable, "executable (overrides cmd[0] if set)"),
-    INIT_PARAM(input, "filename for stdin (dflt: use sim stdin)"),
-    INIT_PARAM(output, "filename for stdout/stderr (dflt: use sim stdout)"),
-    INIT_PARAM(env, "environment settings"),
-    INIT_PARAM(system, "system"),
-    INIT_PARAM(uid, "user id"),
-    INIT_PARAM(euid, "effective user id"),
-    INIT_PARAM(gid, "group id"),
-    INIT_PARAM(egid, "effective group id"),
-    INIT_PARAM(pid, "process id"),
-    INIT_PARAM(ppid, "parent process id")
-
-END_INIT_SIM_OBJECT_PARAMS(LiveProcess)
-
-
-CREATE_SIM_OBJECT(LiveProcess)
+LiveProcess *
+LiveProcessParams::create()
 {
     string in = input;
     string out = output;
@@ -510,11 +566,9 @@ CREATE_SIM_OBJECT(LiveProcess)
 
     stderr_fd = (stdout_fd != STDOUT_FILENO) ? stdout_fd : STDERR_FILENO;
 
-    return LiveProcess::create(getInstanceName(), system,
+    return LiveProcess::create(name, system,
                                stdin_fd, stdout_fd, stderr_fd,
                                (string)executable == "" ? cmd[0] : executable,
-                               cmd, env);
+                               cmd, env, cwd,
+                               uid, euid, gid, egid, pid, ppid);
 }
-
-
-REGISTER_SIM_OBJECT("LiveProcess", LiveProcess)