Merge gblack@m5.eecs.umich.edu:/bk/multiarch
[gem5.git] / arch / alpha / alpha_linux_process.cc
index 600de4447f11ad466c7958a59f1099d25cf61c27..af4df7c30422138fc40cd06336f28bfe39e59e91 100644 (file)
 #include <sys/types.h>
 #include <unistd.h>
 
-#include "cpu/base_cpu.hh"
+#include "cpu/base.hh"
 #include "cpu/exec_context.hh"
-#include "mem/functional_mem/functional_memory.hh"
+#include "mem/functional/functional.hh"
 #include "sim/fake_syscall.hh"
 #include "sim/host.hh"
 #include "sim/process.hh"
 #include "sim/sim_events.hh"
 
+#include "arch/alpha/isa_traits.hh"
 #include "arch/alpha/alpha_common_syscall_emul.hh"
 #include "sim/syscall_emul.hh"
-#include "sim/universe.hh"     // for curTick & ticksPerSecond
+#include "sim/root.hh" // for curTick & ticksPerSecond
 
 #include "arch/alpha/alpha_linux_process.hh"
 
 #include "base/trace.hh"
 
 using namespace std;
+using namespace AlphaISA;
 
 ///
 /// This class encapsulates the types, structures, constants,
@@ -70,6 +72,15 @@ class Linux {
     typedef uint32_t gid_t;
     //@}
 
+#if BSD_HOST
+    typedef struct stat hst_stat;
+    typedef struct stat hst_stat64;
+#else
+    typedef struct stat hst_stat ;
+    typedef struct stat64 hst_stat64;
+#endif
+
+
     //@{
     /// open(2) flag values.
     static const int TGT_O_RDONLY      = 00000000;     //!< O_RDONLY
@@ -117,6 +128,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;
@@ -146,18 +180,18 @@ class Linux {
 
     /// Resource enumeration for getrlimit().
     enum rlimit_resources {
-        RLIMIT_CPU = 0,
-        RLIMIT_FSIZE = 1,
-        RLIMIT_DATA = 2,
-        RLIMIT_STACK = 3,
-        RLIMIT_CORE = 4,
-        RLIMIT_RSS = 5,
-        RLIMIT_NOFILE = 6,
-        RLIMIT_AS = 7,
-        RLIMIT_VMEM = 7,
-        RLIMIT_NPROC = 8,
-        RLIMIT_MEMLOCK = 9,
-        RLIMIT_LOCKS = 10
+        TGT_RLIMIT_CPU = 0,
+        TGT_RLIMIT_FSIZE = 1,
+        TGT_RLIMIT_DATA = 2,
+        TGT_RLIMIT_STACK = 3,
+        TGT_RLIMIT_CORE = 4,
+        TGT_RLIMIT_RSS = 5,
+        TGT_RLIMIT_NOFILE = 6,
+        TGT_RLIMIT_AS = 7,
+        TGT_RLIMIT_VMEM = 7,
+        TGT_RLIMIT_NPROC = 8,
+        TGT_RLIMIT_MEMLOCK = 9,
+        TGT_RLIMIT_LOCKS = 10
     };
 
     /// Limit struct for getrlimit/setrlimit.
@@ -176,11 +210,17 @@ 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;
-    static const int RUSAGE_CHILDREN = -1;
-    static const int RUSAGE_BOTH = -2;
+    static const int TGT_RUSAGE_SELF = 0;
+    static const int TGT_RUSAGE_CHILDREN = -1;
+    static const int TGT_RUSAGE_BOTH = -2;
     //@}
 
     /// For getrusage().
@@ -205,25 +245,98 @@ 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().
+#if !BSD_HOST
     static void
-    copyOutStatBuf(FunctionalMemory *mem, Addr addr, struct stat *host)
+    copyOutStatBuf(FunctionalMemory *mem, Addr addr, hst_stat *host)
     {
         TypedBufferArg<Linux::tgt_stat> tgt(addr);
 
-        tgt->st_dev = host->st_dev;
-        tgt->st_ino = host->st_ino;
-        tgt->st_mode = host->st_mode;
-        tgt->st_nlink = host->st_nlink;
-        tgt->st_uid = host->st_uid;
-        tgt->st_gid = host->st_gid;
-        tgt->st_rdev = host->st_rdev;
-        tgt->st_size = host->st_size;
-        tgt->st_atimeX = host->st_atime;
-        tgt->st_mtimeX = host->st_mtime;
-        tgt->st_ctimeX = host->st_ctime;
-        tgt->st_blksize = host->st_blksize;
-        tgt->st_blocks = host->st_blocks;
+        tgt->st_dev = htog(host->st_dev);
+        tgt->st_ino = htog(host->st_ino);
+        tgt->st_mode = htog(host->st_mode);
+        tgt->st_nlink = htog(host->st_nlink);
+        tgt->st_uid = htog(host->st_uid);
+        tgt->st_gid = htog(host->st_gid);
+        tgt->st_rdev = htog(host->st_rdev);
+        tgt->st_size = htog(host->st_size);
+        tgt->st_atimeX = htog(host->st_atime);
+        tgt->st_mtimeX = htog(host->st_mtime);
+        tgt->st_ctimeX = htog(host->st_ctime);
+        tgt->st_blksize = htog(host->st_blksize);
+        tgt->st_blocks = htog(host->st_blocks);
+
+        tgt.copyOut(mem);
+    }
+#else
+    // Third version for bsd systems which no longer have any support for
+    // the old stat() call and stat() is actually a stat64()
+    static void
+    copyOutStatBuf(FunctionalMemory *mem, Addr addr, hst_stat64 *host)
+    {
+        TypedBufferArg<Linux::tgt_stat> tgt(addr);
+
+        tgt->st_dev = htog(host->st_dev);
+        tgt->st_ino = htog(host->st_ino);
+        tgt->st_mode = htog(host->st_mode);
+        tgt->st_nlink = htog(host->st_nlink);
+        tgt->st_uid = htog(host->st_uid);
+        tgt->st_gid = htog(host->st_gid);
+        tgt->st_rdev = htog(host->st_rdev);
+        tgt->st_size = htog(host->st_size);
+        tgt->st_atimeX = htog(host->st_atime);
+        tgt->st_mtimeX = htog(host->st_mtime);
+        tgt->st_ctimeX = htog(host->st_ctime);
+        tgt->st_blksize = htog(host->st_blksize);
+        tgt->st_blocks = htog(host->st_blocks);
+
+        tgt.copyOut(mem);
+    }
+#endif
+
+
+    // Same for stat64
+    static void
+    copyOutStat64Buf(FunctionalMemory *mem, int fd, Addr addr, hst_stat64 *host)
+    {
+        TypedBufferArg<Linux::tgt_stat64> tgt(addr);
+
+        // fd == 1 checks are because libc does some checks
+        // that the stdout is interactive vs. a file
+        // this makes it work on non-linux systems
+        if (fd == 1)
+            tgt->st_dev = htog((uint64_t)0xA);
+        else
+            tgt->st_dev = htog((uint64_t)host->st_dev);
+        // XXX What about STAT64_HAS_BROKEN_ST_INO ???
+        tgt->st_ino = htog((uint64_t)host->st_ino);
+        if (fd == 1)
+            tgt->st_rdev = htog((uint64_t)0x880d);
+        else
+            tgt->st_rdev = htog((uint64_t)host->st_rdev);
+        tgt->st_size = htog((int64_t)host->st_size);
+        tgt->st_blocks = htog((uint64_t)host->st_blocks);
+
+        if (fd == 1)
+            tgt->st_mode = htog((uint32_t)0x2190);
+        else
+            tgt->st_mode = htog((uint32_t)host->st_mode);
+        tgt->st_uid = htog((uint32_t)host->st_uid);
+        tgt->st_gid = htog((uint32_t)host->st_gid);
+        tgt->st_blksize = htog((uint32_t)host->st_blksize);
+        tgt->st_nlink = htog((uint32_t)host->st_nlink);
+        tgt->tgt_st_atime = htog((uint64_t)host->st_atime);
+        tgt->tgt_st_mtime = htog((uint64_t)host->st_mtime);
+        tgt->tgt_st_ctime = htog((uint64_t)host->st_ctime);
+#if defined(STAT_HAVE_NSEC)
+        tgt->st_atime_nsec = htog(host->st_atime_nsec);
+        tgt->st_mtime_nsec = htog(host->st_mtime_nsec);
+        tgt->st_ctime_nsec = htog(host->st_ctime_nsec);
+#else
+        tgt->st_atime_nsec = 0;
+        tgt->st_mtime_nsec = 0;
+        tgt->st_ctime_nsec = 0;
+#endif
 
         tgt.copyOut(mem);
     }
@@ -292,12 +405,12 @@ class Linux {
               // I don't think this exactly matches the HW FPCR
               fpcr.copyIn(xc->mem);
               DPRINTFR(SyscallVerbose, "osf_setsysinfo(SSI_IEEE_FP_CONTROL): "
-                       " setting FPCR to 0x%x\n", *(uint64_t*)fpcr);
+                       " setting FPCR to 0x%x\n", gtoh(*(uint64_t*)fpcr));
               return 0;
           }
 
           default:
-            cerr << "osf_getsysinfo: unknown op " << op << endl;
+            cerr << "osf_setsysinfo: unknown op " << op << endl;
             abort();
             break;
         }
@@ -429,8 +542,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 +648,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 +893,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 +954,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 =