syscall_emul: add support for x86 statfs system calls
authorBrandon Potter <brandon.potter@amd.com>
Thu, 15 Dec 2016 18:16:03 +0000 (13:16 -0500)
committerBrandon Potter <brandon.potter@amd.com>
Thu, 15 Dec 2016 18:16:03 +0000 (13:16 -0500)
src/arch/x86/linux/linux.hh
src/arch/x86/linux/process.cc
src/sim/syscall_emul.hh

index fb8e611cbd5a1956fa5676ae5e4657263b82da5f..ef0715fd6ecc46ca770c4dade2bd6860054ff904 100644 (file)
@@ -67,6 +67,24 @@ class X86Linux64 : public Linux
         int64_t unused0[3];
     } tgt_stat64;
 
+    typedef struct {
+        long val[2];
+    } tgt_fsid;
+
+    typedef struct {
+        long f_type;
+        long f_bsize;
+        long f_blocks;
+        long f_bfree;
+        long f_bavail;
+        long f_files;
+        long f_ffree;
+        tgt_fsid f_fsid;
+        long f_namelen;
+        long f_frsize;
+        long f_spare[5];
+    } tgt_statfs;
+
     static const int TGT_SIGHUP         = 0x000001;
     static const int TGT_SIGINT         = 0x000002;
     static const int TGT_SIGQUIT        = 0x000003;
index f68f1c4c86ec6e630abcb4eaa3b7c91c09dc6b0b..e5db3cb49705d9f5f2df4db069e515e6ad63b877 100644 (file)
@@ -355,7 +355,7 @@ static SyscallDesc syscallDescs64[] = {
     /* 134 */ SyscallDesc("uselib", unimplementedFunc),
     /* 135 */ SyscallDesc("personality", unimplementedFunc),
     /* 136 */ SyscallDesc("ustat", unimplementedFunc),
-    /* 137 */ SyscallDesc("statfs", unimplementedFunc),
+    /* 137 */ SyscallDesc("statfs", statfsFunc<X86Linux64>),
     /* 138 */ SyscallDesc("fstatfs", unimplementedFunc),
     /* 139 */ SyscallDesc("sysfs", unimplementedFunc),
     /* 140 */ SyscallDesc("getpriority", unimplementedFunc),
index 53da9197b7b0c6116fd5e467f9bcc4e22aee420d..bf7ec1ae774f6125c84d39466a7b4f5d73f224ac 100644 (file)
@@ -62,6 +62,7 @@
 #include <fcntl.h>
 #include <sys/mman.h>
 #include <sys/stat.h>
+#include <sys/statfs.h>
 #include <sys/time.h>
 #include <sys/uio.h>
 #include <unistd.h>
@@ -451,6 +452,7 @@ getElapsedTimeNano(T1 &sec, T2 &nsec)
 //
 //////////////////////////////////////////////////////////////////////
 
+    typedef struct statfs hst_statfs;
 #if NO_STAT64
     typedef struct stat hst_stat;
     typedef struct stat hst_stat64;
@@ -556,6 +558,32 @@ copyOutStat64Buf(SETranslatingPortProxy &mem, Addr addr,
     tgt.copyOut(mem);
 }
 
+template <class OS>
+static void
+copyOutStatfsBuf(SETranslatingPortProxy &mem, Addr addr,
+                 hst_statfs *host)
+{
+    TypedBufferArg<typename OS::tgt_statfs> tgt(addr);
+
+#if defined(__OpenBSD__) || defined(__APPLE__) || defined(__FreeBSD__)
+    tgt->f_type = 0;
+#else
+    tgt->f_type = TheISA::htog(host->f_type);
+#endif
+    tgt->f_bsize = TheISA::htog(host->f_bsize);
+    tgt->f_blocks = TheISA::htog(host->f_blocks);
+    tgt->f_bfree = TheISA::htog(host->f_bfree);
+    tgt->f_bavail = TheISA::htog(host->f_bavail);
+    tgt->f_files = TheISA::htog(host->f_files);
+    tgt->f_ffree = TheISA::htog(host->f_ffree);
+    memcpy(&tgt->f_fsid, &host->f_fsid, sizeof(host->f_fsid));
+    tgt->f_namelen = TheISA::htog(host->f_namelen);
+    tgt->f_frsize = TheISA::htog(host->f_frsize);
+    memcpy(&tgt->f_spare, &host->f_spare, sizeof(host->f_spare));
+
+    tgt.copyOut(mem);
+}
+
 /// Target ioctl() handler.  For the most part, programs call ioctl()
 /// only to find out if their stdout is a tty, to determine whether to
 /// do line or block buffering.  We always claim that output fds are
@@ -1156,7 +1184,7 @@ statfsFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
     if (result < 0)
         return -errno;
 
-    OS::copyOutStatfsBuf(tc->getMemProxy(), bufPtr, &hostBuf);
+    copyOutStatfsBuf<OS>(tc->getMemProxy(), bufPtr, &hostBuf);
 
     return 0;
 }
@@ -1182,7 +1210,7 @@ fstatfsFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
     if (result < 0)
         return -errno;
 
-    OS::copyOutStatfsBuf(tc->getMemProxy(), bufPtr, &hostBuf);
+    copyOutStatfsBuf<OS>(tc->getMemProxy(), bufPtr, &hostBuf);
 
     return 0;
 }