sim-se, arch-arm: Add support for getdents64
authorJavier Setoain <javier.setoain@arm.com>
Wed, 9 Jan 2019 14:24:31 +0000 (14:24 +0000)
committerAndreas Sandberg <andreas.sandberg@arm.com>
Thu, 10 Jan 2019 17:56:24 +0000 (17:56 +0000)
Change-Id: Ib27950144d4c9802ffb842db98aec9e433ccbfc5
Signed-off-by: Andreas Sandberg <andreas.sandberg@arm.com>
Cc: Giacomo Travaglini <giacomo.travaglini@arm.com>
Cc: Javier Setoain <javier.setoain@arm.com>
Cc: Brandon Potter <Brandon.Potter@amd.com>
Reviewed-on: https://gem5-review.googlesource.com/c/15438
Maintainer: Brandon Potter <Brandon.Potter@amd.com>
Reviewed-by: Jason Lowe-Power <jason@lowepower.com>
src/arch/arm/linux/process.cc
src/sim/syscall_emul.cc
src/sim/syscall_emul.hh

index cb62e6ee7490066ed3b93b113f308ae17670a845..61caa456b407af5be541ff0a982cda96502e9a3b 100644 (file)
@@ -46,6 +46,8 @@
 
 #include "arch/arm/linux/process.hh"
 
+#include <sys/syscall.h>
+
 #include "arch/arm/isa_traits.hh"
 #include "arch/arm/linux/linux.hh"
 #include "base/trace.hh"
@@ -342,7 +344,11 @@ static SyscallDesc syscallDescs32[] = {
     /* 214 */ SyscallDesc("setgid", unimplementedFunc),
     /* 215 */ SyscallDesc("setfsuid", unimplementedFunc),
     /* 216 */ SyscallDesc("setfsgid", unimplementedFunc),
+#if defined(SYS_getdents64)
+    /* 217 */ SyscallDesc("getdents64", getdents64Func),
+#else
     /* 217 */ SyscallDesc("getdents64", unimplementedFunc),
+#endif
     /* 218 */ SyscallDesc("pivot_root", unimplementedFunc),
     /* 219 */ SyscallDesc("mincore", unimplementedFunc),
     /* 220 */ SyscallDesc("madvise", ignoreFunc),
@@ -555,7 +561,11 @@ static SyscallDesc syscallDescs64[] = {
     /*   58 */ SyscallDesc("vhangup", unimplementedFunc),
     /*   59 */ SyscallDesc("pipe2", unimplementedFunc),
     /*   60 */ SyscallDesc("quotactl", unimplementedFunc),
+#if defined(SYS_getdents64)
+    /*   61 */ SyscallDesc("getdents64", getdents64Func),
+#else
     /*   61 */ SyscallDesc("getdents64", unimplementedFunc),
+#endif
     /*   62 */ SyscallDesc("llseek", lseekFunc),
     /*   63 */ SyscallDesc("read", readFunc),
     /*   64 */ SyscallDesc("write", writeFunc),
index 3d17b5d758127c90430e85c1eb5b95261839b9ef..e79e79c6281cd163c6863d8a2d143e8e2c18c2c6 100644 (file)
@@ -1151,9 +1151,10 @@ rmdirFunc(SyscallDesc *desc, int num, Process *p, ThreadContext *tc)
     return (result == -1) ? -errno : result;
 }
 
-#if defined(SYS_getdents)
-SyscallReturn
-getdentsFunc(SyscallDesc *desc, int callnum, Process *p, ThreadContext *tc)
+#if defined(SYS_getdents) || defined(SYS_getdents64)
+template<typename DE, int SYS_NUM>
+static SyscallReturn
+getdentsImpl(SyscallDesc *desc, int callnum, Process *p, ThreadContext *tc)
 {
     int index = 0;
     int tgt_fd = p->getSyscallArg(tc, index);
@@ -1166,21 +1167,14 @@ getdentsFunc(SyscallDesc *desc, int callnum, Process *p, ThreadContext *tc)
     int sim_fd = hbfdp->getSimFD();
 
     BufferArg buf_arg(buf_ptr, count);
-    auto status = syscall(SYS_getdents, sim_fd, buf_arg.bufferPtr(), count);
+    auto status = syscall(SYS_NUM, sim_fd, buf_arg.bufferPtr(), count);
 
     if (status == -1)
         return -errno;
 
-    typedef struct linux_dirent {
-        unsigned long d_ino;
-        unsigned long d_off;
-        unsigned short d_reclen;
-        char dname[];
-    } LinDent;
-
     unsigned traversed = 0;
     while (traversed < status) {
-        LinDent *buffer = (LinDent*)((Addr)buf_arg.bufferPtr() + traversed);
+        DE *buffer = (DE*)((Addr)buf_arg.bufferPtr() + traversed);
 
         auto host_reclen = buffer->d_reclen;
 
@@ -1200,3 +1194,33 @@ getdentsFunc(SyscallDesc *desc, int callnum, Process *p, ThreadContext *tc)
     return status;
 }
 #endif
+
+#if defined(SYS_getdents)
+SyscallReturn
+getdentsFunc(SyscallDesc *desc, int callnum, Process *p, ThreadContext *tc)
+{
+    typedef struct linux_dirent {
+        unsigned long d_ino;
+        unsigned long d_off;
+        unsigned short d_reclen;
+        char dname[];
+    } LinDent;
+
+    return getdentsImpl<LinDent, SYS_getdents>(desc, callnum, p, tc);
+}
+#endif
+
+#if defined(SYS_getdents64)
+SyscallReturn
+getdents64Func(SyscallDesc *desc, int callnum, Process *p, ThreadContext *tc)
+{
+    typedef struct linux_dirent64 {
+        ino64_t d_ino;
+        off64_t d_off;
+        unsigned short d_reclen;
+        char dname[];
+    } LinDent64;
+
+    return getdentsImpl<LinDent64, SYS_getdents64>(desc, callnum, p, tc);
+}
+#endif
index 343fb2731930503b3112da0e9f0e007570a4ec4d..91e115de0b31ab1904cbf06000dc919e6875739a 100644 (file)
@@ -309,6 +309,12 @@ SyscallReturn getdentsFunc(SyscallDesc *desc, int num,
                            Process *p, ThreadContext *tc);
 #endif
 
+#if defined(SYS_getdents64)
+// Target getdents() handler.
+SyscallReturn getdents64Func(SyscallDesc *desc, int num,
+                           Process *p, ThreadContext *tc);
+#endif
+
 // Target getuid() handler.
 SyscallReturn getuidFunc(SyscallDesc *desc, int num,
                          Process *p, ThreadContext *tc);