summaryrefslogtreecommitdiff
path: root/sim/syscall_emul.hh
diff options
context:
space:
mode:
Diffstat (limited to 'sim/syscall_emul.hh')
-rw-r--r--sim/syscall_emul.hh177
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