changes regarding fs.py
[gem5.git] / src / sim / syscall_emul.cc
index e37fea1b1d0061bd6f215f1b062b9d2fbce417ac..9028d590bd0964312319c326f447c080c7399ddb 100644 (file)
 #include "sim/syscall_emul.hh"
 #include "base/chunk_generator.hh"
 #include "base/trace.hh"
-#include "cpu/exec_context.hh"
+#include "cpu/thread_context.hh"
 #include "cpu/base.hh"
 #include "mem/page_table.hh"
 #include "sim/process.hh"
 
-#include "sim/sim_events.hh"
+#include "sim/sim_exit.hh"
 
 using namespace std;
 using namespace TheISA;
 
 void
-SyscallDesc::doSyscall(int callnum, Process *process, ExecContext *xc)
+SyscallDesc::doSyscall(int callnum, LiveProcess *process, ThreadContext *tc)
 {
     DPRINTFR(SyscallVerbose, "%d: %s: syscall %s called w/arguments %d,%d,%d,%d\n",
-             curTick,xc->getCpuPtr()->name(), name,
-             xc->getSyscallArg(0),xc->getSyscallArg(1),
-             xc->getSyscallArg(2),xc->getSyscallArg(3));
+             curTick,tc->getCpuPtr()->name(), name,
+             tc->getSyscallArg(0),tc->getSyscallArg(1),
+             tc->getSyscallArg(2),tc->getSyscallArg(3));
 
-    SyscallReturn retval = (*funcPtr)(this, callnum, process, xc);
+    SyscallReturn retval = (*funcPtr)(this, callnum, process, tc);
 
     DPRINTFR(SyscallVerbose, "%d: %s: syscall %s returns %d\n",
-             curTick,xc->getCpuPtr()->name(), name, retval.value());
+             curTick,tc->getCpuPtr()->name(), name, retval.value());
 
     if (!(flags & SyscallDesc::SuppressReturnValue))
-        xc->setSyscallReturn(retval);
+        tc->setSyscallReturn(retval);
 }
 
 
 SyscallReturn
-unimplementedFunc(SyscallDesc *desc, int callnum, Process *process,
-                  ExecContext *xc)
+unimplementedFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
+                  ThreadContext *tc)
 {
     fatal("syscall %s (#%d) unimplemented.", desc->name, callnum);
 
@@ -77,40 +77,42 @@ unimplementedFunc(SyscallDesc *desc, int callnum, Process *process,
 
 
 SyscallReturn
-ignoreFunc(SyscallDesc *desc, int callnum, Process *process,
-           ExecContext *xc)
+ignoreFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
+           ThreadContext *tc)
 {
     warn("ignoring syscall %s(%d, %d, ...)", desc->name,
-         xc->getSyscallArg(0), xc->getSyscallArg(1));
+         tc->getSyscallArg(0), tc->getSyscallArg(1));
 
     return 0;
 }
 
 
 SyscallReturn
-exitFunc(SyscallDesc *desc, int callnum, Process *process,
-         ExecContext *xc)
+exitFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
+         ThreadContext *tc)
 {
-    new SimExitEvent("target called exit()", xc->getSyscallArg(0) & 0xff);
+    if (tc->exit()) {
+        exitSimLoop("target called exit()", tc->getSyscallArg(0) & 0xff);
+    }
 
     return 1;
 }
 
 
 SyscallReturn
-getpagesizeFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
+getpagesizeFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
 {
     return (int)VMPageSize;
 }
 
 
 SyscallReturn
-obreakFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
+obreakFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
 {
     Addr junk;
 
     // change brk addr to first arg
-    Addr new_brk = xc->getSyscallArg(0);
+    Addr new_brk = tc->getSyscallArg(0);
     if (new_brk != 0) {
         for (ChunkGenerator gen(p->brk_point, new_brk - p->brk_point,
                                 VMPageSize); !gen.done(); gen.next()) {
@@ -126,9 +128,9 @@ obreakFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
 
 
 SyscallReturn
-closeFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
+closeFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
 {
-    int target_fd = xc->getSyscallArg(0);
+    int target_fd = tc->getSyscallArg(0);
     int status = close(p->sim_fd(target_fd));
     if (status >= 0)
         p->free_fd(target_fd);
@@ -137,28 +139,28 @@ closeFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
 
 
 SyscallReturn
-readFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
+readFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
 {
-    int fd = p->sim_fd(xc->getSyscallArg(0));
-    int nbytes = xc->getSyscallArg(2);
-    BufferArg bufArg(xc->getSyscallArg(1), nbytes);
+    int fd = p->sim_fd(tc->getSyscallArg(0));
+    int nbytes = tc->getSyscallArg(2);
+    BufferArg bufArg(tc->getSyscallArg(1), nbytes);
 
     int bytes_read = read(fd, bufArg.bufferPtr(), nbytes);
 
     if (bytes_read != -1)
-        bufArg.copyOut(xc->getMemPort());
+        bufArg.copyOut(tc->getMemPort());
 
     return bytes_read;
 }
 
 SyscallReturn
-writeFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
+writeFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
 {
-    int fd = p->sim_fd(xc->getSyscallArg(0));
-    int nbytes = xc->getSyscallArg(2);
-    BufferArg bufArg(xc->getSyscallArg(1), nbytes);
+    int fd = p->sim_fd(tc->getSyscallArg(0));
+    int nbytes = tc->getSyscallArg(2);
+    BufferArg bufArg(tc->getSyscallArg(1), nbytes);
 
-    bufArg.copyIn(xc->getMemPort());
+    bufArg.copyIn(tc->getMemPort());
 
     int bytes_written = write(fd, bufArg.bufferPtr(), nbytes);
 
@@ -169,11 +171,11 @@ writeFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
 
 
 SyscallReturn
-lseekFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
+lseekFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
 {
-    int fd = p->sim_fd(xc->getSyscallArg(0));
-    uint64_t offs = xc->getSyscallArg(1);
-    int whence = xc->getSyscallArg(2);
+    int fd = p->sim_fd(tc->getSyscallArg(0));
+    uint64_t offs = tc->getSyscallArg(1);
+    int whence = tc->getSyscallArg(2);
 
     off_t result = lseek(fd, offs, whence);
 
@@ -182,7 +184,7 @@ lseekFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
 
 
 SyscallReturn
-munmapFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
+munmapFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
 {
     // given that we don't really implement mmap, munmap is really easy
     return 0;
@@ -192,24 +194,24 @@ munmapFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
 const char *hostname = "m5.eecs.umich.edu";
 
 SyscallReturn
-gethostnameFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
+gethostnameFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
 {
-    int name_len = xc->getSyscallArg(1);
-    BufferArg name(xc->getSyscallArg(0), name_len);
+    int name_len = tc->getSyscallArg(1);
+    BufferArg name(tc->getSyscallArg(0), name_len);
 
     strncpy((char *)name.bufferPtr(), hostname, name_len);
 
-    name.copyOut(xc->getMemPort());
+    name.copyOut(tc->getMemPort());
 
     return 0;
 }
 
 SyscallReturn
-unlinkFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
+unlinkFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
 {
     string path;
 
-    if (!xc->getMemPort()->tryReadString(path, xc->getSyscallArg(0)))
+    if (!tc->getMemPort()->tryReadString(path, tc->getSyscallArg(0)))
         return (TheISA::IntReg)-EFAULT;
 
     int result = unlink(path.c_str());
@@ -217,16 +219,16 @@ unlinkFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
 }
 
 SyscallReturn
-renameFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
+renameFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
 {
     string old_name;
 
-    if (!xc->getMemPort()->tryReadString(old_name, xc->getSyscallArg(0)))
+    if (!tc->getMemPort()->tryReadString(old_name, tc->getSyscallArg(0)))
         return -EFAULT;
 
     string new_name;
 
-    if (!xc->getMemPort()->tryReadString(new_name, xc->getSyscallArg(1)))
+    if (!tc->getMemPort()->tryReadString(new_name, tc->getSyscallArg(1)))
         return -EFAULT;
 
     int64_t result = rename(old_name.c_str(), new_name.c_str());
@@ -234,45 +236,45 @@ renameFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
 }
 
 SyscallReturn
-truncateFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
+truncateFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
 {
     string path;
 
-    if (!xc->getMemPort()->tryReadString(path, xc->getSyscallArg(0)))
+    if (!tc->getMemPort()->tryReadString(path, tc->getSyscallArg(0)))
         return -EFAULT;
 
-    off_t length = xc->getSyscallArg(1);
+    off_t length = tc->getSyscallArg(1);
 
     int result = truncate(path.c_str(), length);
     return (result == -1) ? -errno : result;
 }
 
 SyscallReturn
-ftruncateFunc(SyscallDesc *desc, int num, Process *process, ExecContext *xc)
+ftruncateFunc(SyscallDesc *desc, int num, LiveProcess *process, ThreadContext *tc)
 {
-    int fd = process->sim_fd(xc->getSyscallArg(0));
+    int fd = process->sim_fd(tc->getSyscallArg(0));
 
     if (fd < 0)
         return -EBADF;
 
-    off_t length = xc->getSyscallArg(1);
+    off_t length = tc->getSyscallArg(1);
 
     int result = ftruncate(fd, length);
     return (result == -1) ? -errno : result;
 }
 
 SyscallReturn
-chownFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
+chownFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
 {
     string path;
 
-    if (!xc->getMemPort()->tryReadString(path, xc->getSyscallArg(0)))
+    if (!tc->getMemPort()->tryReadString(path, tc->getSyscallArg(0)))
         return -EFAULT;
 
     /* XXX endianess */
-    uint32_t owner = xc->getSyscallArg(1);
+    uint32_t owner = tc->getSyscallArg(1);
     uid_t hostOwner = owner;
-    uint32_t group = xc->getSyscallArg(2);
+    uint32_t group = tc->getSyscallArg(2);
     gid_t hostGroup = group;
 
     int result = chown(path.c_str(), hostOwner, hostGroup);
@@ -280,17 +282,17 @@ chownFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
 }
 
 SyscallReturn
-fchownFunc(SyscallDesc *desc, int num, Process *process, ExecContext *xc)
+fchownFunc(SyscallDesc *desc, int num, LiveProcess *process, ThreadContext *tc)
 {
-    int fd = process->sim_fd(xc->getSyscallArg(0));
+    int fd = process->sim_fd(tc->getSyscallArg(0));
 
     if (fd < 0)
         return -EBADF;
 
     /* XXX endianess */
-    uint32_t owner = xc->getSyscallArg(1);
+    uint32_t owner = tc->getSyscallArg(1);
     uid_t hostOwner = owner;
-    uint32_t group = xc->getSyscallArg(2);
+    uint32_t group = tc->getSyscallArg(2);
     gid_t hostGroup = group;
 
     int result = fchown(fd, hostOwner, hostGroup);
@@ -299,15 +301,28 @@ fchownFunc(SyscallDesc *desc, int num, Process *process, ExecContext *xc)
 
 
 SyscallReturn
-fcntlFunc(SyscallDesc *desc, int num, Process *process,
-          ExecContext *xc)
+dupFunc(SyscallDesc *desc, int num, LiveProcess *process, ThreadContext *tc)
 {
-    int fd = xc->getSyscallArg(0);
+    int fd = process->sim_fd(tc->getSyscallArg(0));
+
+    if (fd < 0)
+        return -EBADF;
+
+    int result = dup(fd);
+    return (result == -1) ? -errno : process->alloc_fd(result);
+}
+
+
+SyscallReturn
+fcntlFunc(SyscallDesc *desc, int num, LiveProcess *process,
+          ThreadContext *tc)
+{
+    int fd = tc->getSyscallArg(0);
 
     if (fd < 0 || process->sim_fd(fd) < 0)
         return -EBADF;
 
-    int cmd = xc->getSyscallArg(1);
+    int cmd = tc->getSyscallArg(1);
     switch (cmd) {
       case 0: // F_DUPFD
         // if we really wanted to support this, we'd need to do it
@@ -341,8 +356,37 @@ fcntlFunc(SyscallDesc *desc, int num, Process *process,
 }
 
 SyscallReturn
-pipePseudoFunc(SyscallDesc *desc, int callnum, Process *process,
-         ExecContext *xc)
+fcntl64Func(SyscallDesc *desc, int num, LiveProcess *process,
+            ThreadContext *tc)
+{
+    int fd = tc->getSyscallArg(0);
+
+    if (fd < 0 || process->sim_fd(fd) < 0)
+        return -EBADF;
+
+    int cmd = tc->getSyscallArg(1);
+    switch (cmd) {
+      case 33: //F_GETLK64
+        warn("fcntl64(%d, F_GETLK64) not supported, error returned\n", fd);
+        return -EMFILE;
+
+      case 34: // F_SETLK64
+      case 35: // F_SETLKW64
+        warn("fcntl64(%d, F_SETLK(W)64) not supported, error returned\n", fd);
+        return -EMFILE;
+
+      default:
+        // not sure if this is totally valid, but we'll pass it through
+        // to the underlying OS
+        warn("fcntl64(%d, %d) passed through to host\n", fd, cmd);
+        return fcntl(process->sim_fd(fd), cmd);
+        // return 0;
+    }
+}
+
+SyscallReturn
+pipePseudoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
+         ThreadContext *tc)
 {
     int fds[2], sim_fds[2];
     int pipe_retval = pipe(fds);
@@ -357,101 +401,101 @@ pipePseudoFunc(SyscallDesc *desc, int callnum, Process *process,
 
     // Alpha Linux convention for pipe() is that fd[0] is returned as
     // the return value of the function, and fd[1] is returned in r20.
-    xc->setIntReg(SyscallPseudoReturnReg, sim_fds[1]);
+    tc->setIntReg(SyscallPseudoReturnReg, sim_fds[1]);
     return sim_fds[0];
 }
 
 
 SyscallReturn
-getpidPseudoFunc(SyscallDesc *desc, int callnum, Process *process,
-           ExecContext *xc)
+getpidPseudoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
+           ThreadContext *tc)
 {
     // Make up a PID.  There's no interprocess communication in
     // fake_syscall mode, so there's no way for a process to know it's
     // not getting a unique value.
 
-    xc->setIntReg(SyscallPseudoReturnReg, 99);
-    return 100;
+    tc->setIntReg(SyscallPseudoReturnReg, process->ppid());
+    return process->pid();
 }
 
 
 SyscallReturn
-getuidPseudoFunc(SyscallDesc *desc, int callnum, Process *process,
-           ExecContext *xc)
+getuidPseudoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
+           ThreadContext *tc)
 {
     // Make up a UID and EUID... it shouldn't matter, and we want the
     // simulation to be deterministic.
 
     // EUID goes in r20.
-    xc->setIntReg(SyscallPseudoReturnReg, 100); //EUID
-    return 100;                // UID
+    tc->setIntReg(SyscallPseudoReturnReg, process->euid()); //EUID
+    return process->uid();             // UID
 }
 
 
 SyscallReturn
-getgidPseudoFunc(SyscallDesc *desc, int callnum, Process *process,
-           ExecContext *xc)
+getgidPseudoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
+           ThreadContext *tc)
 {
     // Get current group ID.  EGID goes in r20.
-    xc->setIntReg(SyscallPseudoReturnReg, 100); //EGID
-    return 100;
+    tc->setIntReg(SyscallPseudoReturnReg, process->egid()); //EGID
+    return process->gid();
 }
 
 
 SyscallReturn
-setuidFunc(SyscallDesc *desc, int callnum, Process *process,
-           ExecContext *xc)
+setuidFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
+           ThreadContext *tc)
 {
     // can't fathom why a benchmark would call this.
-    warn("Ignoring call to setuid(%d)\n", xc->getSyscallArg(0));
+    warn("Ignoring call to setuid(%d)\n", tc->getSyscallArg(0));
     return 0;
 }
 
 SyscallReturn
-getpidFunc(SyscallDesc *desc, int callnum, Process *process,
-           ExecContext *xc)
+getpidFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
+           ThreadContext *tc)
 {
     // Make up a PID.  There's no interprocess communication in
     // fake_syscall mode, so there's no way for a process to know it's
     // not getting a unique value.
 
-    xc->setIntReg(SyscallPseudoReturnReg, 99); //PID
-    return 100;
+    tc->setIntReg(SyscallPseudoReturnReg, process->ppid()); //PID
+    return process->pid();
 }
 
 SyscallReturn
-getppidFunc(SyscallDesc *desc, int callnum, Process *process,
-           ExecContext *xc)
+getppidFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
+           ThreadContext *tc)
 {
-    return 99;
+    return process->ppid();
 }
 
 SyscallReturn
-getuidFunc(SyscallDesc *desc, int callnum, Process *process,
-           ExecContext *xc)
+getuidFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
+           ThreadContext *tc)
 {
-    return 100;                // UID
+    return process->uid();             // UID
 }
 
 SyscallReturn
-geteuidFunc(SyscallDesc *desc, int callnum, Process *process,
-           ExecContext *xc)
+geteuidFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
+           ThreadContext *tc)
 {
-    return 100;                // UID
+    return process->euid();            // UID
 }
 
 SyscallReturn
-getgidFunc(SyscallDesc *desc, int callnum, Process *process,
-           ExecContext *xc)
+getgidFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
+           ThreadContext *tc)
 {
-    return 100;
+    return process->gid();
 }
 
 SyscallReturn
-getegidFunc(SyscallDesc *desc, int callnum, Process *process,
-           ExecContext *xc)
+getegidFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
+           ThreadContext *tc)
 {
-    return 100;
+    return process->egid();
 }