riscv: [Patch 6/5] Improve Linux emulation for RISC-V
authorAlec Roelke <ar4jc@virginia.edu>
Wed, 30 Nov 2016 22:10:28 +0000 (17:10 -0500)
committerAlec Roelke <ar4jc@virginia.edu>
Wed, 30 Nov 2016 22:10:28 +0000 (17:10 -0500)
This is an add-on patch for the original series that implemented RISC-V
that improves the implementation of Linux emulation for SE mode. Basically
it cleans up linux/linux.hh by removing constants that haven't been
defined for the RISC-V Linux proxy kernel and rearranging the stat
struct so it aligns with RISC-V's implementation of it. It also adds
placeholders for system calls that have been given numbers in RISC-V
but haven't been given implementations yet. These system calls are
as follows:
- readlinkat
- sigprocmask
- ioctl
- clock_gettime
- getrusage
- getrlimit
- setrlimit

The first five patches implemented RISC-V with the base ISA and multiply,
floating point, and atomic extensions and added support for detailed
CPU models with memory timing.

[Fixed incompatibility with changes made from patch 1.]
Signed-off by: Alec Roelke

Signed-off by: Jason Lowe-Power <jason@lowepower.com>

src/arch/riscv/linux/linux.hh
src/arch/riscv/linux/process.cc

index f1540cdc1ec379375ce52d1d17a27eace70080b4..0c76fa6ede54e554fcdff554c943c2c92ef0dd7e 100644 (file)
 class RiscvLinux : public Linux
 {
   public:
-
-    static const int TGT_SIGHUP         = 0x000001;
-    static const int TGT_SIGINT         = 0x000002;
-    static const int TGT_SIGQUIT        = 0x000003;
-    static const int TGT_SIGILL         = 0x000004;
-    static const int TGT_SIGTRAP        = 0x000005;
-    static const int TGT_SIGIOT         = 0x000006;
-    static const int TGT_SIGABRT        = 0x000006;
-    static const int TGT_SIGEMT         = 0x000007;
-    static const int TGT_SIGFPE         = 0x000008;
-    static const int TGT_SIGKILL        = 0x000009;
-    static const int TGT_SIGBUS         = 0x00000a;
-    static const int TGT_SIGSEGV        = 0x00000b;
-    static const int TGT_SIGSYS         = 0x00000c;
-    static const int TGT_SIGPIPE        = 0x00000d;
-    static const int TGT_SIGALRM        = 0x00000e;
-    static const int TGT_SIGTERM        = 0x00000f;
-    static const int TGT_SIGUSR1        = 0x000010;
-    static const int TGT_SIGUSR2        = 0x000011;
-    static const int TGT_SIGCHLD        = 0x000012;
-    static const int TGT_SIGCLD         = 0x000012;
-    static const int TGT_SIGPWR         = 0x000013;
-    static const int TGT_SIGWINCH       = 0x000014;
-    static const int TGT_SIGURG         = 0x000015;
-    static const int TGT_SIGIO          = 0x000016;
-    static const int TGT_SIGPOLL        = 0x000016;
-    static const int TGT_SIGSTOP        = 0x000017;
-    static const int TGT_SIGTSTP        = 0x000018;
-    static const int TGT_SIGCONT        = 0x000019;
-    static const int TGT_SIGTTIN        = 0x00001a;
-    static const int TGT_SIGTTOU        = 0x00001b;
-    static const int TGT_SIGVTALRM      = 0x00001c;
-    static const int TGT_SIGPROF        = 0x00001d;
-    static const int TGT_SIGXCPU        = 0x00001e;
-    static const int TGT_SIGXFSZ        = 0x00001f;
+    static const int TGT_SIGHUP         =  1;
+    static const int TGT_SIGINT         =  2;
+    static const int TGT_SIGQUIT        =  3;
+    static const int TGT_SIGILL         =  4;
+    static const int TGT_SIGTRAP        =  5;
+    static const int TGT_SIGABRT        =  6;
+    static const int TGT_SIGIOT         =  6;
+    static const int TGT_SIGEMT         =  7;
+    static const int TGT_SIGFPE         =  8;
+    static const int TGT_SIGKILL        =  9;
+    static const int TGT_SIGBUS         = 10;
+    static const int TGT_SIGSEGV        = 11;
+    static const int TGT_SIGSYS         = 12;
+    static const int TGT_SIGPIPE        = 13;
+    static const int TGT_SIGALRM        = 14;
+    static const int TGT_SIGTERM        = 15;
+    static const int TGT_SIGURG         = 16;
+    static const int TGT_SIGSTOP        = 17;
+    static const int TGT_SIGTSTP        = 18;
+    static const int TGT_SIGCONT        = 19;
+    static const int TGT_SIGCHLD        = 20;
+    static const int TGT_SIGCLD         = 20;
+    static const int TGT_SIGTTIN        = 21;
+    static const int TGT_SIGTTOU        = 22;
+    static const int TGT_SIGPOLL        = 23;
+    static const int TGT_SIGIO          = 23;
+    static const int TGT_SIGXCPU        = 24;
+    static const int TGT_SIGXFSZ        = 25;
+    static const int TGT_SIGVTALRM      = 26;
+    static const int TGT_SIGPROF        = 27;
+    static const int TGT_SIGWINCH       = 28;
+    static const int TGT_SIGLOST        = 29;
+    static const int TGT_SIGPWR         = 29;
+    static const int TGT_SIGUSR1        = 30;
+    static const int TGT_SIGUSR2        = 31;
 
     /// This table maps the target open() flags to the corresponding
     /// host open() flags.
@@ -81,119 +81,77 @@ class RiscvLinux : public Linux
 
     //@{
     /// open(2) flag values.
-    static const int TGT_O_RDONLY       = 0x00000000;   //!< O_RDONLY
-    static const int TGT_O_WRONLY       = 0x00000001;   //!< O_WRONLY
-    static const int TGT_O_RDWR         = 0x00000002;   //!< O_RDWR
-    static const int TGT_O_CREAT        = 0x00000100;   //!< O_CREAT
-    static const int TGT_O_EXCL         = 0x00000400;   //!< O_EXCL
-    static const int TGT_O_NOCTTY       = 0x00000800;   //!< O_NOCTTY
-    static const int TGT_O_TRUNC        = 0x00000200;   //!< O_TRUNC
-    static const int TGT_O_APPEND       = 0x00000008;   //!< O_APPEND
-    static const int TGT_O_NONBLOCK     = 0x00000080;   //!< O_NONBLOCK
-    static const int TGT_O_DSYNC        = 0x00000010;   //!< O_DSYNC
-    static const int TGT_FASYNC         = 0x00001000;   //!< O_FASYNC
-    static const int TGT_O_DIRECT       = 0x00008000;   //!< O_DIRECT
-    static const int TGT_O_LARGEFILE    = 0x00002000;   //!< O_LARGEFILE
-    static const int TGT_O_DIRECTORY    = 0x00010000;   //!< O_DIRECTORY
-    static const int TGT_O_NOFOLLOW     = 0x00020000;   //!< O_NOFOLLOW
-    static const int TGT_O_NOATIME      = 0x00040000;   //!< O_NOATIME
-    static const int TGT_O_CLOEXEC      = 0x00080000;   //!< O_CLOEXEC
-    static const int TGT_O_SYNC         = 0x00004010;   //!< O_SYNC
-    static const int TGT_O_PATH         = 0x00200000;   //!< O_PATH
+    static const int TGT_O_RDONLY       = 0x000000; //!< O_RDONLY
+    static const int TGT_O_WRONLY       = 0x000001; //!< O_WRONLY
+    static const int TGT_O_RDWR         = 0x000002; //!< O_RDWR
+    static const int TGT_O_CREAT        = 0x000040; //!< O_CREAT
+    static const int TGT_O_EXCL         = 0x000080; //!< O_EXCL
+    static const int TGT_O_NOCTTY       = 0x000100; //!< O_NOCTTY
+    static const int TGT_O_TRUNC        = 0x000200; //!< O_TRUNC
+    static const int TGT_O_APPEND       = 0x000400; //!< O_APPEND
+    static const int TGT_O_NONBLOCK     = 0x000800; //!< O_NONBLOCK
+    static const int TGT_O_SYNC         = 0x001000; //!< O_SYNC
+    static const int TGT_FSYNC          = 0x001000; //!< FSYNC
+    static const int TGT_FASYNC         = 0x008000; //!< FASYNC
+    // The following are not present in riscv64-unknown-elf <fcntl.h>
+    static const int TGT_O_DSYNC        = 0x010000; //!< O_DSYNC
+    static const int TGT_O_CLOEXEC      = 0x040000; //!< O_CLOEXEC
+    static const int TGT_O_NOINHERIT    = 0x040000; //!< O_NOINHERIT
+    static const int TGT_O_DIRECT       = 0x080000; //!< O_DIRECT
+    static const int TGT_O_NOFOLLOW     = 0x100000; //!< O_NOFOLLOW
+    static const int TGT_O_DIRECTORY    = 0x200000; //!< O_DIRECTORY
+    // The following are not defined by riscv64-unknown-elf
+    static const int TGT_O_LARGEFILE    = 0x020000; //!< O_LARGEFILE
+    static const int TGT_O_NOATIME      = 0x800000; //!< O_NOATIME
+    static const int TGT_O_PATH         = 0x400000; //!< O_PATH
     //@}
 
-    static const unsigned TGT_MAP_SHARED        = 0x00001;
-    static const unsigned TGT_MAP_PRIVATE       = 0x00002;
-    static const unsigned TGT_MAP_ANON          = 0x00800;
-    static const unsigned TGT_MAP_DENYWRITE     = 0x02000;
-    static const unsigned TGT_MAP_EXECUTABLE    = 0x04000;
-    static const unsigned TGT_MAP_FILE          = 0x00000;
-    static const unsigned TGT_MAP_GROWSDOWN     = 0x01000;
-    static const unsigned TGT_MAP_HUGETLB       = 0x80000;
-    static const unsigned TGT_MAP_LOCKED        = 0x08000;
-    static const unsigned TGT_MAP_NONBLOCK      = 0x20000;
-    static const unsigned TGT_MAP_NORESERVE     = 0x00400;
-    static const unsigned TGT_MAP_POPULATE      = 0x10000;
-    static const unsigned TGT_MAP_STACK         = 0x40000;
-    static const unsigned TGT_MAP_ANONYMOUS     = 0x00800;
-    static const unsigned TGT_MAP_FIXED         = 0x00010;
+    // Only defined in riscv-unknown-elf for proxy kernel and not linux kernel
+    static const unsigned TGT_MAP_SHARED        = 0x0001;
+    static const unsigned TGT_MAP_PRIVATE       = 0x0002;
+    static const unsigned TGT_MAP_FIXED         = 0x0010;
+    static const unsigned TGT_MAP_ANONYMOUS     = 0x0020;
+    static const unsigned TGT_MAP_POPULATE      = 0x1000;
+    static const unsigned TGT_MREMAP_FIXED      = 0x0020;
 
     static const unsigned NUM_MMAP_FLAGS;
 
-    //@{
-    /// For getsysinfo().
-    static const unsigned GSI_PLATFORM_NAME = 103; //!< platform name as string
-    static const unsigned GSI_CPU_INFO = 59;       //!< CPU information
-    static const unsigned GSI_PROC_TYPE = 60;      //!< get proc_type
-    static const unsigned GSI_MAX_CPU = 30;        //!< max # cpus
-    static const unsigned GSI_CPUS_IN_BOX = 55;    //!< # of CPUs in system
-    static const unsigned GSI_PHYSMEM = 19;        //!< Physical memory in KB
-    static const unsigned GSI_CLK_TCK = 42;        //!< clock freq in Hz
-    //@}
-
-    //@{
-    /// For setsysinfo().
-    static const unsigned SSI_IEEE_FP_CONTROL = 14; //!< ieee_set_fp_control()
-    //@}
-
-    //@{
-    /// ioctl() command codes.
-    static const unsigned TGT_TCGETA     = 0x5401;
-    static const unsigned TGT_TCSETAW    = 0x5403;
-    static const unsigned TGT_TCGETS     = 0x540d;
-    static const unsigned TGT_FIONREAD   = 0x467f;
-    static const unsigned TGT_TIOCGETP   = 0x7408;
-    static const unsigned TGT_TIOCSETP   = 0x7409;
-    static const unsigned TGT_TIOCSETN   = 0x740a;
-    //@}
-
-    static bool
-    isTtyReq(unsigned req)
-    {
-        switch (req) {
-          case TGT_TIOCGETP:
-          case TGT_TIOCSETP:
-          case TGT_TIOCSETN:
-          case TGT_FIONREAD:
-          case TGT_TCGETS:
-          case TGT_TCGETA:
-          case TGT_TCSETAW:
-            return true;
-          default:
-            return false;
-        }
-    }
-
-    /// For table().
-    static const int TBL_SYSINFO = 12;
-
-    /// Resource constants for getrlimit() (overide some generics).
-    static const unsigned TGT_RLIMIT_NPROC = 8;
-    static const unsigned TGT_RLIMIT_AS = 6;
-    static const unsigned TGT_RLIMIT_RSS = 7;
-    static const unsigned TGT_RLIMIT_NOFILE = 5;
-    static const unsigned TGT_RLIMIT_MEMLOCK = 9;
-
-    /// Offset used to make sure that processes don't
-    /// assign themselves to process IDs reserved for
-    /// the root users.
-    static const int NUM_ROOT_PROCS = 2;
+    typedef int64_t time_t;
+    typedef uint64_t dev_t;
+    typedef uint64_t ino_t;
+    typedef uint32_t mode_t;
+    typedef uint32_t nlink_t;
+    typedef uint32_t uid_t;
+    typedef uint32_t gid_t;
+    typedef int64_t off_t;
+    typedef uint64_t blksize_t;
+    typedef uint64_t blkcnt_t;
+
+    struct timespec {
+        time_t tv_sec;
+        int64_t tv_nsec;
+    };
 
     typedef struct {
-       int32_t  uptime;    /* Seconds since boot */
-       uint32_t loads[3];  /* 1, 5, and 15 minute load averages */
-       uint32_t totalram;  /* Total usable main memory size */
-       uint32_t freeram;   /* Available memory size */
-       uint32_t sharedram; /* Amount of shared memory */
-       uint32_t bufferram; /* Memory used by buffers */
-       uint32_t totalswap; /* Total swap space size */
-       uint32_t freeswap;  /* swap space still available */
-       uint16_t procs;     /* Number of current processes */
-       uint32_t totalhigh; /* Total high memory size */
-       uint32_t freehigh;  /* Available high memory size */
-       uint32_t mem_unit;  /* Memory unit size in bytes */
-    } tgt_sysinfo;
-
+        dev_t st_dev;
+        ino_t st_ino;
+        mode_t st_mode;
+        nlink_t st_nlink;
+        uid_t st_uid;
+        gid_t st_gid;
+        dev_t st_rdev;
+        dev_t __pad1;
+        off_t st_size;
+        blksize_t st_blksize;
+        blkcnt_t st_blocks;
+        uint64_t st_atimeX;
+        uint64_t st_atime_nsec;
+        uint64_t st_mtimeX;
+        uint64_t st_mtime_nsec;
+        uint64_t st_ctimeX;
+        uint64_t st_ctime_nsec;
+        int32_t ___glibc_reserved[2];
+    } tgt_stat64;
 };
 
 #endif
index e1c9ea2a29dd9da733a13426e6a2f47801d42c7b..7884b83b2a009fa3214262a2b1a0d926054178c9 100644 (file)
@@ -71,13 +71,13 @@ unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
 std::map<int, SyscallDesc> RiscvLinuxProcess::syscallDescs = {
     {17, SyscallDesc("getcwd", getcwdFunc)},
     {23, SyscallDesc("dup", dupFunc)},
-    {25, SyscallDesc("fcntl", fcntlFunc)},
+    {25, SyscallDesc("fcntl", fcntl64Func)},
     {29, SyscallDesc("ioctl", ioctlFunc<RiscvLinux>)},
     {34, SyscallDesc("mkdirat", unimplementedFunc)},
     {35, SyscallDesc("unlinkat", unlinkatFunc<RiscvLinux>)},
     {37, SyscallDesc("linkat", unimplementedFunc)},
     {38, SyscallDesc("renameat", renameatFunc<RiscvLinux>)},
-    {46, SyscallDesc("ftruncate", ftruncateFunc)},
+    {46, SyscallDesc("ftruncate", ftruncate64Func)},
     {48, SyscallDesc("faccessat", faccessatFunc<RiscvLinux>)},
     {49, SyscallDesc("chdir", unimplementedFunc)},
     {56, SyscallDesc("openat", openatFunc<RiscvLinux>)},
@@ -88,10 +88,10 @@ std::map<int, SyscallDesc> RiscvLinuxProcess::syscallDescs = {
     {64, SyscallDesc("write", writeFunc)},
     {66, SyscallDesc("writev", writevFunc<RiscvLinux>)},
     {67, SyscallDesc("pread", unimplementedFunc)},
-    {68, SyscallDesc("pwrite", unimplementedFunc)},
+    {68, SyscallDesc("pwrite", pwrite64Func<RiscvLinux>)},
     {78, SyscallDesc("readlinkat", readlinkatFunc<RiscvLinux>)},
-    {79, SyscallDesc("fstatat", unimplementedFunc)},
-    {80, SyscallDesc("fstat", fstatFunc<RiscvLinux>)},
+    {79, SyscallDesc("fstatat", fstatat64Func<RiscvLinux>)},
+    {80, SyscallDesc("fstat", fstat64Func<RiscvLinux>)},
     {93, SyscallDesc("exit", exitFunc)},
     {94, SyscallDesc("exit_group", exitGroupFunc)},
     {113, SyscallDesc("clock_gettime", clock_gettimeFunc<RiscvLinux>)},
@@ -119,8 +119,8 @@ std::map<int, SyscallDesc> RiscvLinuxProcess::syscallDescs = {
     {1026, SyscallDesc("unlink", unlinkFunc)},
     {1030, SyscallDesc("mkdir", mkdirFunc)},
     {1033, SyscallDesc("access", accessFunc)},
-    {1038, SyscallDesc("stat", statFunc<RiscvLinux>)},
-    {1039, SyscallDesc("lstat", lstatFunc<RiscvLinux>)},
+    {1038, SyscallDesc("stat", stat64Func<RiscvLinux>)},
+    {1039, SyscallDesc("lstat", lstat64Func<RiscvLinux>)},
     {1062, SyscallDesc("time", timeFunc<RiscvLinux>)},
     {2011, SyscallDesc("getmainvars", unimplementedFunc)},
 };