diff options
Diffstat (limited to 'sim/syscall_emul.hh')
-rw-r--r-- | sim/syscall_emul.hh | 177 |
1 files changed, 177 insertions, 0 deletions
diff --git a/sim/syscall_emul.hh b/sim/syscall_emul.hh index f22b6dcb7..2bd8969d7 100644 --- a/sim/syscall_emul.hh +++ b/sim/syscall_emul.hh @@ -40,6 +40,7 @@ #ifdef __CYGWIN32__ #include <sys/fcntl.h> // for O_BINARY #endif +#include <sys/uio.h> #include "base/intmath.hh" // for RoundUp #include "mem/functional/functional.hh" @@ -226,6 +227,15 @@ SyscallReturn ftruncateFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc); +/// Target chown() handler. +SyscallReturn chownFunc(SyscallDesc *desc, int num, + Process *p, ExecContext *xc); + + +/// Target fchown() handler. +SyscallReturn fchownFunc(SyscallDesc *desc, int num, + Process *p, ExecContext *xc); + /// This struct is used to build an target-OS-dependent table that /// maps the target's open() flags to the host open() flags. struct OpenFlagTransTable { @@ -343,6 +353,59 @@ openFunc(SyscallDesc *desc, int callnum, Process *process, } +/// Target chmod() handler. +template <class OS> +SyscallReturn +chmodFunc(SyscallDesc *desc, int callnum, Process *process, + ExecContext *xc) +{ + std::string path; + + if (xc->mem->readString(path, xc->getSyscallArg(0)) != No_Fault) + return -EFAULT; + + uint32_t mode = xc->getSyscallArg(1); + mode_t hostMode = 0; + + // XXX translate mode flags via OS::something??? + hostMode = mode; + + // do the chmod + int result = chmod(path.c_str(), hostMode); + if (result < 0) + return errno; + + return 0; +} + + +/// Target fchmod() handler. +template <class OS> +SyscallReturn +fchmodFunc(SyscallDesc *desc, int callnum, Process *process, + ExecContext *xc) +{ + int fd = xc->getSyscallArg(0); + if (fd < 0 || process->sim_fd(fd) < 0) { + // doesn't map to any simulator fd: not a valid target fd + return -EBADF; + } + + uint32_t mode = xc->getSyscallArg(1); + mode_t hostMode = 0; + + // XXX translate mode flags via OS::someting??? + hostMode = mode; + + // do the fchmod + int result = fchmod(process->sim_fd(fd), hostMode); + if (result < 0) + return errno; + + return 0; +} + + /// Target stat() handler. template <class OS> SyscallReturn @@ -366,6 +429,30 @@ statFunc(SyscallDesc *desc, int callnum, Process *process, } +/// Target fstat64() handler. +template <class OS> +SyscallReturn +fstat64Func(SyscallDesc *desc, int callnum, Process *process, + ExecContext *xc) +{ + int fd = xc->getSyscallArg(0); + if (fd < 0 || process->sim_fd(fd) < 0) { + // doesn't map to any simulator fd: not a valid target fd + return -EBADF; + } + + struct stat64 hostBuf; + int result = fstat64(process->sim_fd(fd), &hostBuf); + + if (result < 0) + return errno; + + OS::copyOutStat64Buf(xc->mem, xc->getSyscallArg(1), &hostBuf); + + return 0; +} + + /// Target lstat() handler. template <class OS> SyscallReturn @@ -388,6 +475,28 @@ lstatFunc(SyscallDesc *desc, int callnum, Process *process, return 0; } +/// Target lstat64() handler. +template <class OS> +SyscallReturn +lstat64Func(SyscallDesc *desc, int callnum, Process *process, + ExecContext *xc) +{ + std::string path; + + if (xc->mem->readString(path, xc->getSyscallArg(0)) != No_Fault) + return -EFAULT; + + struct stat64 hostBuf; + int result = lstat64(path.c_str(), &hostBuf); + + if (result < 0) + return -errno; + + OS::copyOutStat64Buf(xc->mem, xc->getSyscallArg(1), &hostBuf); + + return 0; +} + /// Target fstat() handler. template <class OS> SyscallReturn @@ -459,6 +568,46 @@ fstatfsFunc(SyscallDesc *desc, int callnum, Process *process, } +/// Target writev() handler. +template <class OS> +SyscallReturn +writevFunc(SyscallDesc *desc, int callnum, Process *process, + ExecContext *xc) +{ + int fd = xc->getSyscallArg(0); + if (fd < 0 || process->sim_fd(fd) < 0) { + // doesn't map to any simulator fd: not a valid target fd + return -EBADF; + } + + uint64_t tiov_base = xc->getSyscallArg(1); + size_t count = xc->getSyscallArg(2); + struct iovec hiov[count]; + for (int i = 0; i < count; ++i) + { + typename OS::tgt_iovec tiov; + xc->mem->access(Read, tiov_base + i*sizeof(typename OS::tgt_iovec), + &tiov, sizeof(typename OS::tgt_iovec)); + hiov[i].iov_len = tiov.iov_len; + hiov[i].iov_base = new char [hiov[i].iov_len]; + xc->mem->access(Read, tiov.iov_base, + hiov[i].iov_base, hiov[i].iov_len); + } + + int result = writev(process->sim_fd(fd), hiov, count); + + for (int i = 0; i < count; ++i) + { + delete [] (char *)hiov[i].iov_base; + } + + if (result < 0) + return errno; + + return 0; +} + + /// Target mmap() handler. /// /// We don't really handle mmap(). If the target is mmaping an @@ -543,6 +692,34 @@ gettimeofdayFunc(SyscallDesc *desc, int callnum, Process *process, } +/// Target utimes() handler. +template <class OS> +SyscallReturn +utimesFunc(SyscallDesc *desc, int callnum, Process *process, + ExecContext *xc) +{ + std::string path; + + if (xc->mem->readString(path, xc->getSyscallArg(0)) != No_Fault) + return -EFAULT; + + TypedBufferArg<typename OS::timeval [2]> tp(xc->getSyscallArg(1)); + tp.copyIn(xc->mem); + + struct timeval hostTimeval[2]; + for (int i = 0; i < 2; ++i) + { + hostTimeval[i].tv_sec = (*tp)[i].tv_sec; + hostTimeval[i].tv_usec = (*tp)[i].tv_usec; + } + int result = utimes(path.c_str(), hostTimeval); + + if (result < 0) + return -errno; + + return 0; +} + /// Target getrusage() function. template <class OS> SyscallReturn |