syscalls: fix latent brk/obreak bug.
[gem5.git] / src / sim / process.cc
index d83b0247e204b7a9c2044d1e7223d53be329419c..50bc5e034b5cabc88372bce939cd1f8d75cf7052 100644 (file)
@@ -46,6 +46,7 @@
 #include "mem/translating_port.hh"
 #include "params/Process.hh"
 #include "params/LiveProcess.hh"
+#include "sim/debug.hh"
 #include "sim/process.hh"
 #include "sim/process_impl.hh"
 #include "sim/stats.hh"
@@ -61,6 +62,8 @@
 #include "arch/sparc/solaris/process.hh"
 #elif THE_ISA == MIPS_ISA
 #include "arch/mips/linux/process.hh"
+#elif THE_ISA == ARM_ISA
+#include "arch/arm/linux/process.hh"
 #elif THE_ISA == X86_ISA
 #include "arch/x86/linux/process.hh"
 #else
@@ -89,6 +92,7 @@ Process::Process(ProcessParams * params)
 {
     string in = params->input;
     string out = params->output;
+    string err = params->errout;
 
     // initialize file descriptors to default: same as simulator
     int stdin_fd, stdout_fd, stderr_fd;
@@ -109,7 +113,16 @@ Process::Process(ProcessParams * params)
     else
         stdout_fd = Process::openOutputFile(out);
 
-    stderr_fd = (stdout_fd != STDOUT_FILENO) ? stdout_fd : STDERR_FILENO;
+    if (err == "stdout" || err == "cout")
+        stderr_fd = STDOUT_FILENO;
+    else if (err == "stderr" || err == "cerr")
+        stderr_fd = STDERR_FILENO;
+    else if (err == "None")
+        stderr_fd = -1;
+    else if (err == out)
+        stderr_fd = stdout_fd;
+    else
+        stderr_fd = Process::openOutputFile(err);
 
     M5_pid = system->allocatePID();
     // initialize first 3 fds (stdin, stdout, stderr)
@@ -129,7 +142,7 @@ Process::Process(ProcessParams * params)
 
     fdo = &fd_map[STDERR_FILENO];
     fdo->fd = stderr_fd;
-    fdo->filename = "STDERR";
+    fdo->filename = err;
     fdo->flags = O_WRONLY;
     fdo->mode = -1;
     fdo->fileOffset = 0;
@@ -180,7 +193,7 @@ Process::openInputFile(const string &filename)
 int
 Process::openOutputFile(const string &filename)
 {
-    int fd = open(filename.c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0774);
+    int fd = open(filename.c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0664);
 
     if (fd == -1) {
         perror(NULL);
@@ -191,33 +204,29 @@ Process::openOutputFile(const string &filename)
     return fd;
 }
 
-
-int
-Process::registerThreadContext(ThreadContext *tc)
+ThreadContext *
+Process::findFreeContext()
 {
-    // add to list
-    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;
+    int size = contextIds.size();
+    ThreadContext *tc;
+    for (int i = 0; i < size; ++i) {
+        tc = system->getThreadContext(contextIds[i]);
+        if (tc->status() == ThreadContext::Unallocated) {
+            // inactive context, free to use
+            return tc;
+        }
+    }
+    return NULL;
 }
 
 void
 Process::startup()
 {
-    if (threadContexts.empty())
-        fatal("Process %s is not associated with any CPUs!\n", name());
+    if (contextIds.empty())
+        fatal("Process %s is not associated with any HW contexts!\n", name());
 
     // first thread context for this process... initialize & enable
-    ThreadContext *tc = threadContexts[0];
+    ThreadContext *tc = system->getThreadContext(contextIds[0]);
 
     // mark this context as active so it will start ticking.
     tc->activate(0);
@@ -230,17 +239,6 @@ Process::startup()
     initVirtMem->setPeer(mem_port);
 }
 
-void
-Process::replaceThreadContext(ThreadContext *tc, int tcIndex)
-{
-    if (tcIndex >= threadContexts.size()) {
-        panic("replaceThreadContext: bad tcIndex, %d >= %d\n",
-              tcIndex, threadContexts.size());
-    }
-
-    threadContexts[tcIndex] = tc;
-}
-
 // map simulator fd sim_fd to target fd tgt_fd
 void
 Process::dup_fd(int sim_fd, int tgt_fd)
@@ -350,6 +348,7 @@ Process::fix_file_offsets() {
     Process::FdMap *fdo_stderr = &fd_map[STDERR_FILENO];
     string in = fdo_stdin->filename;
     string out = fdo_stdout->filename;
+    string err = fdo_stderr->filename;
 
     // initialize file descriptors to default: same as simulator
     int stdin_fd, stdout_fd, stderr_fd;
@@ -373,11 +372,23 @@ Process::fix_file_offsets() {
         stdout_fd = -1;
     else{
         stdout_fd = Process::openOutputFile(out);
-        if (lseek(stdin_fd, fdo_stdout->fileOffset, SEEK_SET) < 0)
-            panic("Unable to seek to correct in file: %s", out);
+        if (lseek(stdout_fd, fdo_stdout->fileOffset, SEEK_SET) < 0)
+            panic("Unable to seek to correct location in file: %s", out);
     }
 
-    stderr_fd = (stdout_fd != STDOUT_FILENO) ? stdout_fd : STDERR_FILENO;
+    if (err == "stdout" || err == "cout")
+        stderr_fd = STDOUT_FILENO;
+    else if (err == "stderr" || err == "cerr")
+        stderr_fd = STDERR_FILENO;
+    else if (err == "None")
+        stderr_fd = -1;
+    else if (err == out)
+        stderr_fd = stdout_fd;
+    else {
+        stderr_fd = Process::openOutputFile(err);
+        if (lseek(stderr_fd, fdo_stderr->fileOffset, SEEK_SET) < 0)
+            panic("Unable to seek to correct location in file: %s", err);
+    }
 
     fdo_stdin->fd = stdin_fd;
     fdo_stdout->fd = stdout_fd;
@@ -596,16 +607,19 @@ LiveProcess::argsInit(int intSize, int pageSize)
     copyStringArray(envp, envp_array_base, env_data_base, initVirtMem);
 
     assert(NumArgumentRegs >= 2);
-    threadContexts[0]->setIntReg(ArgumentReg[0], argc);
-    threadContexts[0]->setIntReg(ArgumentReg[1], argv_array_base);
-    threadContexts[0]->setIntReg(StackPointerReg, stack_min);
+
+    ThreadContext *tc = system->getThreadContext(contextIds[0]);
+
+    tc->setIntReg(ArgumentReg[0], argc);
+    tc->setIntReg(ArgumentReg[1], argv_array_base);
+    tc->setIntReg(StackPointerReg, stack_min);
 
     Addr prog_entry = objFile->entryPoint();
-    threadContexts[0]->setPC(prog_entry);
-    threadContexts[0]->setNextPC(prog_entry + sizeof(MachInst));
+    tc->setPC(prog_entry);
+    tc->setNextPC(prog_entry + sizeof(MachInst));
 
 #if THE_ISA != ALPHA_ISA //e.g. MIPS or Sparc
-    threadContexts[0]->setNextNPC(prog_entry + (2 * sizeof(MachInst)));
+    tc->setNextNPC(prog_entry + (2 * sizeof(MachInst)));
 #endif
 
     num_processes++;
@@ -697,6 +711,17 @@ LiveProcess::create(LiveProcessParams * params)
         process = new MipsLinuxProcess(params, objFile);
         break;
 
+      default:
+        fatal("Unknown/unsupported operating system.");
+    }
+#elif THE_ISA == ARM_ISA
+    if (objFile->getArch() != ObjectFile::Arm)
+        fatal("Object file architecture does not match compiled ISA (ARM).");
+    switch (objFile->getOpSys()) {
+      case ObjectFile::Linux:
+        process = new ArmLinuxProcess(params, objFile);
+        break;
+
       default:
         fatal("Unknown/unsupported operating system.");
     }