From 2cd04fd6da67d874fd4e563ed05707a42ff0598f Mon Sep 17 00:00:00 2001 From: Michael Adler Date: Wed, 23 Jul 2008 14:41:33 -0700 Subject: [PATCH] syscalls: Add a bunch of missing system calls. readlink, umask, truncate, ftruncate, mkdir, and getcwd. --- src/arch/alpha/linux/process.cc | 12 ++--- src/arch/alpha/tru64/process.cc | 6 +-- src/arch/mips/linux/process.cc | 8 +-- src/arch/sparc/linux/syscalls.cc | 10 ++-- src/arch/sparc/solaris/process.cc | 4 +- src/sim/process.hh | 2 + src/sim/syscall_emul.cc | 82 +++++++++++++++++++++++++++++++ src/sim/syscall_emul.hh | 17 +++++++ 8 files changed, 121 insertions(+), 20 deletions(-) diff --git a/src/arch/alpha/linux/process.cc b/src/arch/alpha/linux/process.cc index ec47992bd..0a9d2f1a3 100644 --- a/src/arch/alpha/linux/process.cc +++ b/src/arch/alpha/linux/process.cc @@ -179,9 +179,9 @@ SyscallDesc AlphaLinuxProcess::syscallDescs[] = { /* 55 */ SyscallDesc("osf_reboot", unimplementedFunc), /* 56 */ SyscallDesc("osf_revoke", unimplementedFunc), /* 57 */ SyscallDesc("symlink", unimplementedFunc), - /* 58 */ SyscallDesc("readlink", unimplementedFunc), + /* 58 */ SyscallDesc("readlink", readlinkFunc), /* 59 */ SyscallDesc("execve", unimplementedFunc), - /* 60 */ SyscallDesc("umask", unimplementedFunc), + /* 60 */ SyscallDesc("umask", umaskFunc), /* 61 */ SyscallDesc("chroot", unimplementedFunc), /* 62 */ SyscallDesc("osf_old_fstat", unimplementedFunc), /* 63 */ SyscallDesc("getpgrp", unimplementedFunc), @@ -250,14 +250,14 @@ SyscallDesc AlphaLinuxProcess::syscallDescs[] = { /* 126 */ SyscallDesc("setreuid", unimplementedFunc), /* 127 */ SyscallDesc("setregid", unimplementedFunc), /* 128 */ SyscallDesc("rename", renameFunc), - /* 129 */ SyscallDesc("truncate", unimplementedFunc), - /* 130 */ SyscallDesc("ftruncate", unimplementedFunc), + /* 129 */ SyscallDesc("truncate", truncateFunc), + /* 130 */ SyscallDesc("ftruncate", ftruncateFunc), /* 131 */ SyscallDesc("flock", unimplementedFunc), /* 132 */ SyscallDesc("setgid", unimplementedFunc), /* 133 */ SyscallDesc("sendto", unimplementedFunc), /* 134 */ SyscallDesc("shutdown", unimplementedFunc), /* 135 */ SyscallDesc("socketpair", unimplementedFunc), - /* 136 */ SyscallDesc("mkdir", unimplementedFunc), + /* 136 */ SyscallDesc("mkdir", mkdirFunc), /* 137 */ SyscallDesc("rmdir", unimplementedFunc), /* 138 */ SyscallDesc("osf_utimes", unimplementedFunc), /* 139 */ SyscallDesc("osf_old_sigreturn", unimplementedFunc), @@ -491,7 +491,7 @@ SyscallDesc AlphaLinuxProcess::syscallDescs[] = { /* 364 */ SyscallDesc("getrusage", getrusageFunc), /* 365 */ SyscallDesc("wait4", unimplementedFunc), /* 366 */ SyscallDesc("adjtimex", unimplementedFunc), - /* 367 */ SyscallDesc("getcwd", unimplementedFunc), + /* 367 */ SyscallDesc("getcwd", getcwdFunc), /* 368 */ SyscallDesc("capget", unimplementedFunc), /* 369 */ SyscallDesc("capset", unimplementedFunc), /* 370 */ SyscallDesc("sendfile", unimplementedFunc), diff --git a/src/arch/alpha/tru64/process.cc b/src/arch/alpha/tru64/process.cc index 6823d820a..e9f7b6be1 100644 --- a/src/arch/alpha/tru64/process.cc +++ b/src/arch/alpha/tru64/process.cc @@ -260,9 +260,9 @@ SyscallDesc AlphaTru64Process::syscallDescs[] = { /* 55 */ SyscallDesc("reboot", unimplementedFunc), /* 56 */ SyscallDesc("revoke", unimplementedFunc), /* 57 */ SyscallDesc("symlink", unimplementedFunc), - /* 58 */ SyscallDesc("readlink", unimplementedFunc), + /* 58 */ SyscallDesc("readlink", readlinkFunc), /* 59 */ SyscallDesc("execve", unimplementedFunc), - /* 60 */ SyscallDesc("umask", unimplementedFunc), + /* 60 */ SyscallDesc("umask", umaskFunc), /* 61 */ SyscallDesc("chroot", unimplementedFunc), /* 62 */ SyscallDesc("old_fstat", unimplementedFunc), /* 63 */ SyscallDesc("getpgrp", unimplementedFunc), @@ -339,7 +339,7 @@ SyscallDesc AlphaTru64Process::syscallDescs[] = { /* 133 */ SyscallDesc("sendto", unimplementedFunc), /* 134 */ SyscallDesc("shutdown", unimplementedFunc), /* 135 */ SyscallDesc("socketpair", unimplementedFunc), - /* 136 */ SyscallDesc("mkdir", unimplementedFunc), + /* 136 */ SyscallDesc("mkdir", mkdirFunc), /* 137 */ SyscallDesc("rmdir", unimplementedFunc), /* 138 */ SyscallDesc("utimes", unimplementedFunc), /* 139 */ SyscallDesc("obsolete 4.2 sigreturn", unimplementedFunc), diff --git a/src/arch/mips/linux/process.cc b/src/arch/mips/linux/process.cc index 06e6e2cf4..8a13d0f18 100644 --- a/src/arch/mips/linux/process.cc +++ b/src/arch/mips/linux/process.cc @@ -160,7 +160,7 @@ SyscallDesc MipsLinuxProcess::syscallDescs[] = { /* 36 */ SyscallDesc("sync", unimplementedFunc), /* 37 */ SyscallDesc("kill", unimplementedFunc), /* 38 */ SyscallDesc("rename", unimplementedFunc), - /* 39 */ SyscallDesc("mkdir", unimplementedFunc), + /* 39 */ SyscallDesc("mkdir", mkdirFunc), /* 40 */ SyscallDesc("rmdir", unimplementedFunc), /* 41 */ SyscallDesc("dup", unimplementedFunc), /* 42 */ SyscallDesc("pipe", pipePseudoFunc), @@ -181,7 +181,7 @@ SyscallDesc MipsLinuxProcess::syscallDescs[] = { /* 57 */ SyscallDesc("setpgid", unimplementedFunc), /* 58 */ SyscallDesc("ulimit", unimplementedFunc), /* 59 */ SyscallDesc("unused#59", unimplementedFunc), - /* 60 */ SyscallDesc("umask", unimplementedFunc), + /* 60 */ SyscallDesc("umask", umaskFunc), /* 61 */ SyscallDesc("chroot", unimplementedFunc), /* 62 */ SyscallDesc("ustat", unimplementedFunc), /* 63 */ SyscallDesc("dup2", unimplementedFunc), @@ -206,7 +206,7 @@ SyscallDesc MipsLinuxProcess::syscallDescs[] = { /* 82 */ SyscallDesc("reserved#82", unimplementedFunc), /* 83 */ SyscallDesc("symlink", unimplementedFunc), /* 84 */ SyscallDesc("unused#84", unimplementedFunc), - /* 85 */ SyscallDesc("readlink", unimplementedFunc), + /* 85 */ SyscallDesc("readlink", readlinkFunc), /* 86 */ SyscallDesc("uselib", unimplementedFunc), /* 87 */ SyscallDesc("swapon", gethostnameFunc), /* 88 */ SyscallDesc("reboot", unimplementedFunc), @@ -324,7 +324,7 @@ SyscallDesc MipsLinuxProcess::syscallDescs[] = { /* 200 */ SyscallDesc("pread64", unimplementedFunc), /* 201 */ SyscallDesc("pwrite64", unimplementedFunc), /* 202 */ SyscallDesc("chown", unimplementedFunc), - /* 203 */ SyscallDesc("getcwd", unimplementedFunc), + /* 203 */ SyscallDesc("getcwd", getcwdFunc), /* 204 */ SyscallDesc("capget", unimplementedFunc), /* 205 */ SyscallDesc("capset", unimplementedFunc), /* 206 */ SyscallDesc("sigalstack", unimplementedFunc), diff --git a/src/arch/sparc/linux/syscalls.cc b/src/arch/sparc/linux/syscalls.cc index 03c8bafe2..2964b3c1a 100644 --- a/src/arch/sparc/linux/syscalls.cc +++ b/src/arch/sparc/linux/syscalls.cc @@ -147,7 +147,7 @@ SyscallDesc SparcLinuxProcess::syscall32Descs[] = { /* 55 */ SyscallDesc("reboot", unimplementedFunc), //32 bit /* 56 */ SyscallDesc("mmap2", unimplementedFunc), //32 bit /* 57 */ SyscallDesc("symlink", unimplementedFunc), - /* 58 */ SyscallDesc("readlink", unimplementedFunc), //32 bit + /* 58 */ SyscallDesc("readlink", readlinkFunc), //32 bit /* 59 */ SyscallDesc("execve", unimplementedFunc), //32 bit /* 60 */ SyscallDesc("umask", unimplementedFunc), //32 bit /* 61 */ SyscallDesc("chroot", unimplementedFunc), @@ -208,7 +208,7 @@ SyscallDesc SparcLinuxProcess::syscall32Descs[] = { /* 116 */ SyscallDesc("gettimeofday", unimplementedFunc), //32 bit /* 117 */ SyscallDesc("getrusage", unimplementedFunc), //32 bit /* 118 */ SyscallDesc("getsockopt", unimplementedFunc), - /* 119 */ SyscallDesc("getcwd", unimplementedFunc), + /* 119 */ SyscallDesc("getcwd", getcwdFunc), /* 120 */ SyscallDesc("readv", unimplementedFunc), /* 121 */ SyscallDesc("writev", unimplementedFunc), /* 122 */ SyscallDesc("settimeofday", unimplementedFunc), //32 bit @@ -225,7 +225,7 @@ SyscallDesc SparcLinuxProcess::syscall32Descs[] = { /* 133 */ SyscallDesc("sendto", unimplementedFunc), /* 134 */ SyscallDesc("shutdown", unimplementedFunc), /* 135 */ SyscallDesc("socketpair", unimplementedFunc), - /* 136 */ SyscallDesc("mkdir", unimplementedFunc), //32 bit + /* 136 */ SyscallDesc("mkdir", mkdirFunc), //32 bit /* 137 */ SyscallDesc("rmdir", unimplementedFunc), /* 138 */ SyscallDesc("utimes", unimplementedFunc), //32 bit /* 139 */ SyscallDesc("stat64", unimplementedFunc), @@ -450,7 +450,7 @@ SyscallDesc SparcLinuxProcess::syscallDescs[] = { /* 55 */ SyscallDesc("reboot", unimplementedFunc), /* 56 */ SyscallDesc("mmap2", unimplementedFunc), /* 57 */ SyscallDesc("symlink", unimplementedFunc), - /* 58 */ SyscallDesc("readlink", unimplementedFunc), + /* 58 */ SyscallDesc("readlink", readlinkFunc), /* 59 */ SyscallDesc("execve", unimplementedFunc), /* 60 */ SyscallDesc("umask", unimplementedFunc), /* 61 */ SyscallDesc("chroot", unimplementedFunc), @@ -528,7 +528,7 @@ SyscallDesc SparcLinuxProcess::syscallDescs[] = { /* 133 */ SyscallDesc("sendto", unimplementedFunc), /* 134 */ SyscallDesc("shutdown", unimplementedFunc), /* 135 */ SyscallDesc("socketpair", unimplementedFunc), - /* 136 */ SyscallDesc("mkdir", unimplementedFunc), + /* 136 */ SyscallDesc("mkdir", mkdirFunc), /* 137 */ SyscallDesc("rmdir", unimplementedFunc), /* 138 */ SyscallDesc("utimes", unimplementedFunc), /* 139 */ SyscallDesc("stat64", unimplementedFunc), diff --git a/src/arch/sparc/solaris/process.cc b/src/arch/sparc/solaris/process.cc index 40d172690..e0c3eaa4b 100644 --- a/src/arch/sparc/solaris/process.cc +++ b/src/arch/sparc/solaris/process.cc @@ -123,7 +123,7 @@ SyscallDesc SparcSolarisProcess::syscallDescs[] = { /* 57 */ SyscallDesc("utssys", unimplementedFunc), /* 58 */ SyscallDesc("fdsync", unimplementedFunc), /* 59 */ SyscallDesc("execve", unimplementedFunc), - /* 60 */ SyscallDesc("umask", unimplementedFunc), + /* 60 */ SyscallDesc("umask", umaskFunc), /* 61 */ SyscallDesc("chroot", unimplementedFunc), /* 62 */ SyscallDesc("fcntl", unimplementedFunc), /* 63 */ SyscallDesc("ulimit", unimplementedFunc), @@ -153,7 +153,7 @@ SyscallDesc SparcSolarisProcess::syscallDescs[] = { /* 87 */ SyscallDesc("poll", unimplementedFunc), /* 88 */ SyscallDesc("lstat", unimplementedFunc), /* 89 */ SyscallDesc("symlink", unimplementedFunc), - /* 90 */ SyscallDesc("readlink", unimplementedFunc), + /* 90 */ SyscallDesc("readlink", readlinkFunc), /* 91 */ SyscallDesc("setgroups", unimplementedFunc), /* 92 */ SyscallDesc("getgroups", unimplementedFunc), /* 93 */ SyscallDesc("fchmod", unimplementedFunc), diff --git a/src/sim/process.hh b/src/sim/process.hh index 29d6e5aae..55bae2542 100644 --- a/src/sim/process.hh +++ b/src/sim/process.hh @@ -303,6 +303,8 @@ class LiveProcess : public Process return full + filename; } + std::string getcwd() const { return cwd; } + virtual void syscall(int64_t callnum, ThreadContext *tc); virtual SyscallDesc* getDesc(int callnum) = 0; diff --git a/src/sim/syscall_emul.cc b/src/sim/syscall_emul.cc index f4b9b7ae3..3a0db1016 100644 --- a/src/sim/syscall_emul.cc +++ b/src/sim/syscall_emul.cc @@ -239,6 +239,59 @@ gethostnameFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) return 0; } +SyscallReturn +getcwdFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) +{ + int result = 0; + unsigned long size = tc->getSyscallArg(1); + BufferArg buf(tc->getSyscallArg(0), size); + + // Is current working directory defined? + string cwd = p->getcwd(); + if (!cwd.empty()) { + if (cwd.length() >= size) { + // Buffer too small + return -ERANGE; + } + strncpy((char *)buf.bufferPtr(), cwd.c_str(), size); + result = cwd.length(); + } + else { + if (getcwd((char *)buf.bufferPtr(), size) != NULL) { + result = strlen((char *)buf.bufferPtr()); + } + else { + result = -1; + } + } + + buf.copyOut(tc->getMemPort()); + + return (result == -1) ? -errno : result; +} + + +SyscallReturn +readlinkFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) +{ + string path; + + if (!tc->getMemPort()->tryReadString(path, tc->getSyscallArg(0))) + return (TheISA::IntReg)-EFAULT; + + // Adjust path for current working directory + path = p->fullPath(path); + + size_t bufsiz = tc->getSyscallArg(2); + BufferArg buf(tc->getSyscallArg(1), bufsiz); + + int result = readlink(path.c_str(), (char *)buf.bufferPtr(), bufsiz); + + buf.copyOut(tc->getMemPort()); + + return (result == -1) ? -errno : result; +} + SyscallReturn unlinkFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) { @@ -254,6 +307,24 @@ unlinkFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) return (result == -1) ? -errno : result; } + +SyscallReturn +mkdirFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) +{ + string path; + + if (!tc->getMemPort()->tryReadString(path, tc->getSyscallArg(0))) + return (TheISA::IntReg)-EFAULT; + + // Adjust path for current working directory + path = p->fullPath(path); + + mode_t mode = tc->getSyscallArg(1); + + int result = mkdir(path.c_str(), mode); + return (result == -1) ? -errno : result; +} + SyscallReturn renameFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) { @@ -306,6 +377,17 @@ ftruncateFunc(SyscallDesc *desc, int num, LiveProcess *process, ThreadContext *t return (result == -1) ? -errno : result; } +SyscallReturn +umaskFunc(SyscallDesc *desc, int num, LiveProcess *process, ThreadContext *tc) +{ + // Letting the simulated program change the simulator's umask seems like + // a bad idea. Compromise by just returning the current umask but not + // changing anything. + mode_t oldMask = umask(0); + umask(oldMask); + return oldMask; +} + SyscallReturn chownFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) { diff --git a/src/sim/syscall_emul.hh b/src/sim/syscall_emul.hh index e35b0a75b..6dafee34c 100644 --- a/src/sim/syscall_emul.hh +++ b/src/sim/syscall_emul.hh @@ -223,10 +223,22 @@ SyscallReturn munmapFunc(SyscallDesc *desc, int num, SyscallReturn gethostnameFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc); +/// Target getcwd() handler. +SyscallReturn getcwdFunc(SyscallDesc *desc, int num, + LiveProcess *p, ThreadContext *tc); + +/// Target unlink() handler. +SyscallReturn readlinkFunc(SyscallDesc *desc, int num, + LiveProcess *p, ThreadContext *tc); + /// Target unlink() handler. SyscallReturn unlinkFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc); +/// Target mkdir() handler. +SyscallReturn mkdirFunc(SyscallDesc *desc, int num, + LiveProcess *p, ThreadContext *tc); + /// Target rename() handler. SyscallReturn renameFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc); @@ -242,6 +254,11 @@ SyscallReturn ftruncateFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc); +/// Target umask() handler. +SyscallReturn umaskFunc(SyscallDesc *desc, int num, + LiveProcess *p, ThreadContext *tc); + + /// Target chown() handler. SyscallReturn chownFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc);