add some comments.
[gem5.git] / sim / process.cc
index 28d59e22c19269fd16c4c27c28453ca0094dcd37..acc6762f8598b6239914c33e3183e0f2d08721d3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003 The Regents of The University of Michigan
+ * Copyright (c) 2001-2004 The Regents of The University of Michigan
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -34,6 +34,7 @@
 
 #include "base/intmath.hh"
 #include "base/loader/object_file.hh"
+#include "base/loader/symtab.hh"
 #include "base/statistics.hh"
 #include "cpu/exec_context.hh"
 #include "cpu/full_cpu/smt.hh"
@@ -43,7 +44,7 @@
 #include "sim/builder.hh"
 #include "sim/fake_syscall.hh"
 #include "sim/process.hh"
-#include "sim/sim_stats.hh"
+#include "sim/stats.hh"
 
 #ifdef TARGET_ALPHA
 #include "arch/alpha/alpha_tru64_process.hh"
@@ -87,15 +88,13 @@ Process::Process(const string &name,
         fd_map[i] = -1;
     }
 
-    num_syscalls = 0;
-
     // other parameters will be initialized when the program is loaded
 }
 
 void
 Process::regStats()
 {
-    using namespace Statistics;
+    using namespace Stats;
 
     num_syscalls
         .name(name() + ".PROG:num_syscalls")
@@ -144,24 +143,31 @@ Process::registerExecContext(ExecContext *xc)
     execContexts.push_back(xc);
 
     if (myIndex == 0) {
-        // first exec context for this process... initialize & enable
-
         // copy process's initial regs struct
         xc->regs = *init_regs;
-
-        // mark this context as active.
-        // activate with zero delay so that we start ticking right
-        // away on cycle 0
-        xc->activate(0);
     }
 
     // return CPU number to caller and increment available CPU count
     return myIndex;
 }
 
+void
+Process::startup()
+{
+    if (execContexts.empty())
+        return;
+
+    // first exec context for this process... initialize & enable
+    ExecContext *xc = execContexts[0];
+
+    // mark this context as active.
+    // activate with zero delay so that we start ticking right
+    // away on cycle 0
+    xc->activate(0);
+}
 
 void
-Process::replaceExecContext(int xcIndex, ExecContext *xc)
+Process::replaceExecContext(ExecContext *xc, int xcIndex)
 {
     if (xcIndex >= execContexts.size()) {
         panic("replaceExecContext: bad xcIndex, %d >= %d\n",
@@ -221,7 +227,7 @@ Process::sim_fd(int tgt_fd)
 // 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 object", Process)
+DEFINE_SIM_OBJECT_CLASS_NAME("Process", Process)
 
 
 ////////////////////////////////////////////////////////////////////////
@@ -263,13 +269,25 @@ LiveProcess::LiveProcess(const string &name, ObjectFile *objFile,
     // load object file into target memory
     objFile->loadSections(memory);
 
+    // load up symbols, if any... these may be used for debugging or
+    // profiling.
+    if (!debugSymbolTable) {
+        debugSymbolTable = new SymbolTable();
+        if (!objFile->loadGlobalSymbols(debugSymbolTable) ||
+            !objFile->loadLocalSymbols(debugSymbolTable)) {
+            // didn't load any symbols
+            delete debugSymbolTable;
+            debugSymbolTable = NULL;
+        }
+    }
+
     // Set up stack.  On Alpha, stack goes below text section.  This
     // code should get moved to some architecture-specific spot.
     stack_base = text_base - (409600+4096);
 
     // Set up region for mmaps.  Tru64 seems to start just above 0 and
     // grow up from there.
-    mmap_base = 0x10000;
+    mmap_start = mmap_end = 0x10000;
 
     // Set pointer for next thread stack.  Reserve 8M for main stack.
     next_thread_stack_base = stack_base - (8 * 1024 * 1024);
@@ -384,23 +402,29 @@ END_INIT_SIM_OBJECT_PARAMS(LiveProcess)
 
 CREATE_SIM_OBJECT(LiveProcess)
 {
+    string in = input;
+    string out = output;
+
     // initialize file descriptors to default: same as simulator
-    int stdin_fd = input.isValid() ? Process::openInputFile(input) : 0;
-    int stdout_fd = output.isValid() ? Process::openOutputFile(output) : 1;
-    int stderr_fd = output.isValid() ? stdout_fd : 2;
+    int stdin_fd, stdout_fd, stderr_fd;
 
-    // dummy for default env
-    vector<string> null_vec;
+    if (in == "stdin" || in == "cin")
+        stdin_fd = STDIN_FILENO;
+    else
+        stdin_fd = Process::openInputFile(input);
 
-    //  We do this with "temp" because of the bogus compiler warning
-    //  you get with g++ 2.95 -O if you just "return new LiveProcess(..."
-    LiveProcess *temp = LiveProcess::create(getInstanceName(),
-                                            stdin_fd, stdout_fd, stderr_fd,
-                                            cmd,
-                                            env.isValid() ? env : null_vec);
+    if (out == "stdout" || out == "cout")
+        stdout_fd = STDOUT_FILENO;
+    else if (out == "stderr" || out == "cerr")
+        stdout_fd = STDERR_FILENO;
+    else
+        stdout_fd = Process::openOutputFile(out);
 
-    return temp;
-}
+    stderr_fd = (stdout_fd != STDOUT_FILENO) ? stdout_fd : STDERR_FILENO;
 
+    return LiveProcess::create(getInstanceName(),
+                               stdin_fd, stdout_fd, stderr_fd,
+                               cmd, env);
+}
 
 REGISTER_SIM_OBJECT("LiveProcess", LiveProcess)