summaryrefslogtreecommitdiff
path: root/src/sim/syscall_emul.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/sim/syscall_emul.cc')
-rw-r--r--src/sim/syscall_emul.cc182
1 files changed, 106 insertions, 76 deletions
diff --git a/src/sim/syscall_emul.cc b/src/sim/syscall_emul.cc
index bc33625af..848b6f869 100644
--- a/src/sim/syscall_emul.cc
+++ b/src/sim/syscall_emul.cc
@@ -27,6 +27,7 @@
*
* Authors: Steve Reinhardt
* Ali Saidi
+ * Korey Sewell
*/
#include <fcntl.h>
@@ -38,7 +39,7 @@
#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"
@@ -49,26 +50,26 @@ using namespace std;
using namespace TheISA;
void
-SyscallDesc::doSyscall(int callnum, Process *process, ExecContext *xc)
+SyscallDesc::doSyscall(int callnum, Process *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)
+ ThreadContext *tc)
{
fatal("syscall %s (#%d) unimplemented.", desc->name, callnum);
@@ -78,10 +79,10 @@ unimplementedFunc(SyscallDesc *desc, int callnum, Process *process,
SyscallReturn
ignoreFunc(SyscallDesc *desc, int callnum, Process *process,
- ExecContext *xc)
+ ThreadContext *tc)
{
warn("ignoring syscall %s(%d, %d, ...)", desc->name,
- xc->getSyscallArg(0), xc->getSyscallArg(1));
+ tc->getSyscallArg(0), tc->getSyscallArg(1));
return 0;
}
@@ -89,28 +90,28 @@ ignoreFunc(SyscallDesc *desc, int callnum, Process *process,
SyscallReturn
exitFunc(SyscallDesc *desc, int callnum, Process *process,
- ExecContext *xc)
+ ThreadContext *tc)
{
- exitSimLoop("target called exit()", xc->getSyscallArg(0) & 0xff);
+ 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, Process *p, ThreadContext *tc)
{
return (int)VMPageSize;
}
SyscallReturn
-obreakFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
+obreakFunc(SyscallDesc *desc, int num, Process *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 +127,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, Process *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 +138,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, Process *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, Process *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 +170,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, Process *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 +183,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, Process *p, ThreadContext *tc)
{
// given that we don't really implement mmap, munmap is really easy
return 0;
@@ -192,24 +193,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, Process *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, Process *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 +218,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, Process *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 +235,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, Process *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, Process *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, Process *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 +281,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, Process *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);
@@ -300,14 +301,14 @@ fchownFunc(SyscallDesc *desc, int num, Process *process, ExecContext *xc)
SyscallReturn
fcntlFunc(SyscallDesc *desc, int num, Process *process,
- ExecContext *xc)
+ ThreadContext *tc)
{
- int fd = xc->getSyscallArg(0);
+ 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 +342,37 @@ fcntlFunc(SyscallDesc *desc, int num, Process *process,
}
SyscallReturn
+fcntl64Func(SyscallDesc *desc, int num, Process *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, Process *process,
- ExecContext *xc)
+ ThreadContext *tc)
{
int fds[2], sim_fds[2];
int pipe_retval = pipe(fds);
@@ -357,99 +387,99 @@ 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)
+ 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);
+ tc->setIntReg(SyscallPseudoReturnReg, 99);
return 100;
}
SyscallReturn
getuidPseudoFunc(SyscallDesc *desc, int callnum, Process *process,
- ExecContext *xc)
+ 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
+ tc->setIntReg(SyscallPseudoReturnReg, 100); //EUID
return 100; // UID
}
SyscallReturn
getgidPseudoFunc(SyscallDesc *desc, int callnum, Process *process,
- ExecContext *xc)
+ ThreadContext *tc)
{
// Get current group ID. EGID goes in r20.
- xc->setIntReg(SyscallPseudoReturnReg, 100); //EGID
+ tc->setIntReg(SyscallPseudoReturnReg, 100); //EGID
return 100;
}
SyscallReturn
setuidFunc(SyscallDesc *desc, int callnum, Process *process,
- ExecContext *xc)
+ 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)
+ 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
+ tc->setIntReg(SyscallPseudoReturnReg, 99); //PID
return 100;
}
SyscallReturn
getppidFunc(SyscallDesc *desc, int callnum, Process *process,
- ExecContext *xc)
+ ThreadContext *tc)
{
return 99;
}
SyscallReturn
getuidFunc(SyscallDesc *desc, int callnum, Process *process,
- ExecContext *xc)
+ ThreadContext *tc)
{
return 100; // UID
}
SyscallReturn
geteuidFunc(SyscallDesc *desc, int callnum, Process *process,
- ExecContext *xc)
+ ThreadContext *tc)
{
return 100; // UID
}
SyscallReturn
getgidFunc(SyscallDesc *desc, int callnum, Process *process,
- ExecContext *xc)
+ ThreadContext *tc)
{
return 100;
}
SyscallReturn
getegidFunc(SyscallDesc *desc, int callnum, Process *process,
- ExecContext *xc)
+ ThreadContext *tc)
{
return 100;
}