Apply patch for syscall emulation provided by Antti Miettinen (apm@brigitte.dna.fi...
authorKevin Lim <ktlim@umich.edu>
Tue, 22 Nov 2005 17:08:08 +0000 (12:08 -0500)
committerKevin Lim <ktlim@umich.edu>
Tue, 22 Nov 2005 17:08:08 +0000 (12:08 -0500)
arch/alpha/alpha_linux_process.cc:
sim/syscall_emul.cc:
sim/syscall_emul.hh:
    Apply patch for syscall emulation provided by Antti Miettinen (apm@brigitte.dna.fi).

--HG--
extra : convert_revision : 37fbc78a927110b7798343afd2c5f37a269e42b4

arch/alpha/alpha_linux_process.cc
sim/syscall_emul.cc
sim/syscall_emul.hh

index 09039db901fb8982b9c6eca29b9063c0e3d2ce4a..83b0b5e5a11b4bb259ab12f453d1e206a02aa38c 100644 (file)
@@ -117,6 +117,29 @@ class Linux {
         uint32_t       st_gen;         //!< unknown
     };
 
+    // same for stat64
+    struct tgt_stat64 {
+        uint64_t       st_dev;
+        uint64_t       st_ino;
+        uint64_t       st_rdev;
+        int64_t                st_size;
+        uint64_t       st_blocks;
+
+        uint32_t       st_mode;
+        uint32_t       st_uid;
+        uint32_t       st_gid;
+        uint32_t       st_blksize;
+        uint32_t       st_nlink;
+        uint32_t       __pad0;
+
+        uint64_t       tgt_st_atime;
+        uint64_t       st_atime_nsec;
+        uint64_t       tgt_st_mtime;
+        uint64_t       st_mtime_nsec;
+        uint64_t       tgt_st_ctime;
+        uint64_t       st_ctime_nsec;
+        int64_t                __unused[3];
+    };
 
     /// Length of strings in struct utsname (plus 1 for null char).
     static const int _SYS_NMLN = 65;
@@ -176,6 +199,12 @@ class Linux {
         int64_t tv_usec;       //!< microseconds
     };
 
+    // For writev/readv
+    struct tgt_iovec {
+        uint64_t iov_base; // void *
+        uint64_t iov_len;
+    };
+
     //@{
     /// For getrusage().
     static const int RUSAGE_SELF = 0;
@@ -205,7 +234,7 @@ class Linux {
 
     /// Helper function to convert a host stat buffer to a target stat
     /// buffer.  Also copies the target buffer out to the simulated
-    /// memorty space.  Used by stat(), fstat(), and lstat().
+    /// memory space.  Used by stat(), fstat(), and lstat().
     static void
     copyOutStatBuf(FunctionalMemory *mem, Addr addr, struct stat *host)
     {
@@ -228,6 +257,40 @@ class Linux {
         tgt.copyOut(mem);
     }
 
+    // Same for stat64
+    static void
+    copyOutStat64Buf(FunctionalMemory *mem, Addr addr, struct stat64 *host)
+    {
+        TypedBufferArg<Linux::tgt_stat64> tgt(addr);
+
+        // XXX byteswaps
+        tgt->st_dev = host->st_dev;
+        // XXX What about STAT64_HAS_BROKEN_ST_INO ???
+        tgt->st_ino = host->st_ino;
+        tgt->st_rdev = host->st_rdev;
+        tgt->st_size = host->st_size;
+        tgt->st_blocks = host->st_blocks;
+
+        tgt->st_mode = host->st_mode;
+        tgt->st_uid = host->st_uid;
+        tgt->st_gid = host->st_gid;
+        tgt->st_blksize = host->st_blksize;
+        tgt->st_nlink = host->st_nlink;
+        tgt->tgt_st_atime = host->st_atime;
+        tgt->tgt_st_mtime = host->st_mtime;
+        tgt->tgt_st_ctime = host->st_ctime;
+#ifdef STAT_HAVE_NSEC
+        tgt->st_atime_nsec = host->st_atime_nsec;
+        tgt->st_mtime_nsec = host->st_mtime_nsec;
+        tgt->st_ctime_nsec = host->st_ctime_nsec;
+#else
+        tgt->st_atime_nsec = 0;
+        tgt->st_mtime_nsec = 0;
+        tgt->st_ctime_nsec = 0;
+#endif
+        tgt.copyOut(mem);
+    }
+
     /// The target system's hostname.
     static const char *hostname;
 
@@ -297,7 +360,7 @@ class Linux {
           }
 
           default:
-            cerr << "osf_getsysinfo: unknown op " << op << endl;
+            cerr << "osf_setsysinfo: unknown op " << op << endl;
             abort();
             break;
         }
@@ -429,8 +492,8 @@ SyscallDesc Linux::syscallDescs[] = {
     /* 12 */ SyscallDesc("chdir", unimplementedFunc),
     /* 13 */ SyscallDesc("fchdir", unimplementedFunc),
     /* 14 */ SyscallDesc("mknod", unimplementedFunc),
-    /* 15 */ SyscallDesc("chmod", unimplementedFunc),
-    /* 16 */ SyscallDesc("chown", unimplementedFunc),
+    /* 15 */ SyscallDesc("chmod", chmodFunc<Linux>),
+    /* 16 */ SyscallDesc("chown", chownFunc),
     /* 17 */ SyscallDesc("brk", obreakFunc),
     /* 18 */ SyscallDesc("osf_getfsstat", unimplementedFunc),
     /* 19 */ SyscallDesc("lseek", lseekFunc),
@@ -535,10 +598,10 @@ SyscallDesc Linux::syscallDescs[] = {
     /* 118 */ SyscallDesc("getsockopt", unimplementedFunc),
     /* 119 */ SyscallDesc("numa_syscalls", unimplementedFunc),
     /* 120 */ SyscallDesc("readv", unimplementedFunc),
-    /* 121 */ SyscallDesc("writev", unimplementedFunc),
+    /* 121 */ SyscallDesc("writev", writevFunc<Linux>),
     /* 122 */ SyscallDesc("osf_settimeofday", unimplementedFunc),
-    /* 123 */ SyscallDesc("fchown", unimplementedFunc),
-    /* 124 */ SyscallDesc("fchmod", unimplementedFunc),
+    /* 123 */ SyscallDesc("fchown", fchownFunc),
+    /* 124 */ SyscallDesc("fchmod", fchmodFunc<Linux>),
     /* 125 */ SyscallDesc("recvfrom", unimplementedFunc),
     /* 126 */ SyscallDesc("setreuid", unimplementedFunc),
     /* 127 */ SyscallDesc("setregid", unimplementedFunc),
@@ -780,7 +843,7 @@ SyscallDesc Linux::syscallDescs[] = {
     /* 360 */ SyscallDesc("settimeofday", unimplementedFunc),
     /* 361 */ SyscallDesc("getitimer", unimplementedFunc),
     /* 362 */ SyscallDesc("setitimer", unimplementedFunc),
-    /* 363 */ SyscallDesc("utimes", unimplementedFunc),
+    /* 363 */ SyscallDesc("utimes", utimesFunc<Linux>),
     /* 364 */ SyscallDesc("getrusage", getrusageFunc<Linux>),
     /* 365 */ SyscallDesc("wait4", unimplementedFunc),
     /* 366 */ SyscallDesc("adjtimex", unimplementedFunc),
@@ -841,7 +904,24 @@ SyscallDesc Linux::syscallDescs[] = {
     /* 421 */ SyscallDesc("clock_getres", unimplementedFunc),
     /* 422 */ SyscallDesc("clock_nanosleep", unimplementedFunc),
     /* 423 */ SyscallDesc("semtimedop", unimplementedFunc),
-    /* 424 */ SyscallDesc("tgkill", unimplementedFunc)
+    /* 424 */ SyscallDesc("tgkill", unimplementedFunc),
+    /* 425 */ SyscallDesc("stat64", unimplementedFunc),
+    /* 426 */ SyscallDesc("lstat64", lstat64Func<Linux>),
+    /* 427 */ SyscallDesc("fstat64", fstat64Func<Linux>),
+    /* 428 */ SyscallDesc("vserver", unimplementedFunc),
+    /* 429 */ SyscallDesc("mbind", unimplementedFunc),
+    /* 430 */ SyscallDesc("get_mempolicy", unimplementedFunc),
+    /* 431 */ SyscallDesc("set_mempolicy", unimplementedFunc),
+    /* 432 */ SyscallDesc("mq_open", unimplementedFunc),
+    /* 433 */ SyscallDesc("mq_unlink", unimplementedFunc),
+    /* 434 */ SyscallDesc("mq_timedsend", unimplementedFunc),
+    /* 435 */ SyscallDesc("mq_timedreceive", unimplementedFunc),
+    /* 436 */ SyscallDesc("mq_notify", unimplementedFunc),
+    /* 437 */ SyscallDesc("mq_getsetattr", unimplementedFunc),
+    /* 438 */ SyscallDesc("waitid", unimplementedFunc),
+    /* 439 */ SyscallDesc("add_key", unimplementedFunc),
+    /* 440 */ SyscallDesc("request_key", unimplementedFunc),
+    /* 441 */ SyscallDesc("keyctl", unimplementedFunc)
 };
 
 const int Linux::Num_Syscall_Descs =
index 50650018eb54dfbec32baaa153720f6056c067ba..4b6388a41a143fbd6c66a881f01dc8238353fce6 100644 (file)
@@ -242,3 +242,39 @@ ftruncateFunc(SyscallDesc *desc, int num, Process *process, ExecContext *xc)
     int result = ftruncate(fd, length);
     return (result == -1) ? -errno : result;
 }
+
+SyscallReturn
+chownFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
+{
+    string path;
+
+    if (xc->mem->readString(path, xc->getSyscallArg(0)) != No_Fault)
+        return -EFAULT;
+
+    /* XXX endianess */
+    uint32_t owner = xc->getSyscallArg(1);
+    uid_t hostOwner = owner;
+    uint32_t group = xc->getSyscallArg(2);
+    gid_t hostGroup = group;
+
+    int result = chown(path.c_str(), hostOwner, hostGroup);
+    return (result == -1) ? -errno : result;
+}
+
+SyscallReturn
+fchownFunc(SyscallDesc *desc, int num, Process *process, ExecContext *xc)
+{
+    int fd = process->sim_fd(xc->getSyscallArg(0));
+
+    if (fd < 0)
+        return -EBADF;
+
+    /* XXX endianess */
+    uint32_t owner = xc->getSyscallArg(1);
+    uid_t hostOwner = owner;
+    uint32_t group = xc->getSyscallArg(2);
+    gid_t hostGroup = group;
+
+    int result = fchown(fd, hostOwner, hostGroup);
+    return (result == -1) ? -errno : result;
+}
index f22b6dcb76b2cf30b28a25c3cf46b187aa32a721..2bd8969d7b003d986ddf28bcf860b39fe17419df 100644 (file)
@@ -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