syscall_emul: implement dir-related syscalls
authorBrandon Potter <brandon.potter@amd.com>
Wed, 18 Apr 2018 18:45:37 +0000 (14:45 -0400)
committerAnthony Gutierrez <anthony.gutierrez@amd.com>
Wed, 19 Sep 2018 20:54:04 +0000 (20:54 +0000)
Add getdents, rmdir, chdir, and mknod to SE mode for x86.

Change-Id: I387ea3066869e8999bc0064f74070f4e47c1e9a1
Reviewed-on: https://gem5-review.googlesource.com/12112
Reviewed-by: Jason Lowe-Power <jason@lowepower.com>
Maintainer: Anthony Gutierrez <anthony.gutierrez@amd.com>

src/arch/x86/linux/process.cc
src/sim/syscall_emul.cc
src/sim/syscall_emul.hh

index 51512fdda83b2067fff8523793ddd0144d91493f..9ec4ca040f4592c4d128136af51d9bb8c6a1260f 100644 (file)
@@ -298,13 +298,13 @@ static SyscallDesc syscallDescs64[] = {
     /*  75 */ SyscallDesc("fdatasync", unimplementedFunc),
     /*  76 */ SyscallDesc("truncate", truncateFunc),
     /*  77 */ SyscallDesc("ftruncate", ftruncateFunc),
-    /*  78 */ SyscallDesc("getdents", unimplementedFunc),
+    /*  78 */ SyscallDesc("getdents", getdentsFunc),
     /*  79 */ SyscallDesc("getcwd", getcwdFunc),
-    /*  80 */ SyscallDesc("chdir", unimplementedFunc),
+    /*  80 */ SyscallDesc("chdir", chdirFunc),
     /*  81 */ SyscallDesc("fchdir", unimplementedFunc),
     /*  82 */ SyscallDesc("rename", renameFunc),
-    /*  83 */ SyscallDesc("mkdir", unimplementedFunc),
-    /*  84 */ SyscallDesc("rmdir", unimplementedFunc),
+    /*  83 */ SyscallDesc("mkdir", mkdirFunc),
+    /*  84 */ SyscallDesc("rmdir", rmdirFunc),
     /*  85 */ SyscallDesc("creat", unimplementedFunc),
     /*  86 */ SyscallDesc("link", linkFunc),
     /*  87 */ SyscallDesc("unlink", unlinkFunc),
@@ -353,7 +353,7 @@ static SyscallDesc syscallDescs64[] = {
     /* 130 */ SyscallDesc("rt_sigsuspend", unimplementedFunc),
     /* 131 */ SyscallDesc("sigaltstack", unimplementedFunc),
     /* 132 */ SyscallDesc("utime", unimplementedFunc),
-    /* 133 */ SyscallDesc("mknod", unimplementedFunc),
+    /* 133 */ SyscallDesc("mknod", mknodFunc),
     /* 134 */ SyscallDesc("uselib", unimplementedFunc),
     /* 135 */ SyscallDesc("personality", unimplementedFunc),
     /* 136 */ SyscallDesc("ustat", unimplementedFunc),
@@ -561,9 +561,9 @@ static SyscallDesc syscallDescs32[] = {
     /*   9 */ SyscallDesc("link", unimplementedFunc),
     /*  10 */ SyscallDesc("unlink", unimplementedFunc),
     /*  11 */ SyscallDesc("execve", execveFunc<X86Linux32>),
-    /*  12 */ SyscallDesc("chdir", unimplementedFunc),
+    /*  12 */ SyscallDesc("chdir", chdirFunc),
     /*  13 */ SyscallDesc("time", timeFunc<X86Linux32>),
-    /*  14 */ SyscallDesc("mknod", unimplementedFunc),
+    /*  14 */ SyscallDesc("mknod", mknodFunc),
     /*  15 */ SyscallDesc("chmod", unimplementedFunc),
     /*  16 */ SyscallDesc("lchown", unimplementedFunc),
     /*  17 */ SyscallDesc("break", unimplementedFunc),
@@ -588,8 +588,8 @@ static SyscallDesc syscallDescs32[] = {
     /*  36 */ SyscallDesc("sync", unimplementedFunc),
     /*  37 */ SyscallDesc("kill", unimplementedFunc),
     /*  38 */ SyscallDesc("rename", unimplementedFunc),
-    /*  39 */ SyscallDesc("mkdir", unimplementedFunc),
-    /*  40 */ SyscallDesc("rmdir", unimplementedFunc),
+    /*  39 */ SyscallDesc("mkdir", mkdirFunc),
+    /*  40 */ SyscallDesc("rmdir", mkdirFunc),
     /*  41 */ SyscallDesc("dup", dupFunc),
     /*  42 */ SyscallDesc("pipe", pipeFunc),
     /*  43 */ SyscallDesc("times", timesFunc<X86Linux32>),
@@ -690,7 +690,7 @@ static SyscallDesc syscallDescs32[] = {
     /* 138 */ SyscallDesc("setfsuid", unimplementedFunc),
     /* 139 */ SyscallDesc("setfsgid", unimplementedFunc),
     /* 140 */ SyscallDesc("_llseek", _llseekFunc),
-    /* 141 */ SyscallDesc("getdents", unimplementedFunc),
+    /* 141 */ SyscallDesc("getdents", getdentsFunc),
     /* 142 */ SyscallDesc("_newselect", unimplementedFunc),
     /* 143 */ SyscallDesc("flock", unimplementedFunc),
     /* 144 */ SyscallDesc("msync", unimplementedFunc),
index dd2323eaaed379096d3ffd683dd2bd84aaf05a96..794b0bc2c1cb82a4ffd953da2c2202a36e1f0674 100644 (file)
 #include "sim/syscall_emul.hh"
 
 #include <fcntl.h>
+#include <syscall.h>
 #include <unistd.h>
 
 #include <csignal>
 #include <iostream>
+#include <mutex>
 #include <string>
 
 #include "arch/utility.hh"
@@ -45,6 +47,7 @@
 #include "cpu/thread_context.hh"
 #include "dev/net/dist_iface.hh"
 #include "mem/page_table.hh"
+#include "sim/byteswap.hh"
 #include "sim/process.hh"
 #include "sim/sim_exit.hh"
 #include "sim/syscall_debug_macros.hh"
@@ -512,7 +515,6 @@ unlinkHelper(SyscallDesc *desc, int num, Process *p, ThreadContext *tc,
     if (!tc->getMemProxy().tryReadString(path, p->getSyscallArg(tc, index)))
         return -EFAULT;
 
-    // Adjust path for current working directory
     path = p->fullPath(path);
 
     int result = unlink(path.c_str());
@@ -1105,3 +1107,95 @@ accessFunc(SyscallDesc *desc, int callnum, Process *p, ThreadContext *tc)
     return accessFunc(desc, callnum, p, tc, 0);
 }
 
+SyscallReturn
+mknodFunc(SyscallDesc *desc, int num, Process *p, ThreadContext *tc)
+{
+    int index = 0;
+    std::string path;
+    if (!tc->getMemProxy().tryReadString(path, p->getSyscallArg(tc, index)))
+        return -EFAULT;
+
+    path = p->fullPath(path);
+    mode_t mode = p->getSyscallArg(tc, index);
+    dev_t dev = p->getSyscallArg(tc, index);
+
+    auto result = mknod(path.c_str(), mode, dev);
+    return (result == -1) ? -errno : result;
+}
+
+SyscallReturn
+chdirFunc(SyscallDesc *desc, int num, Process *p, ThreadContext *tc)
+{
+    int index = 0;
+    std::string path;
+    if (!tc->getMemProxy().tryReadString(path, p->getSyscallArg(tc, index)))
+        return -EFAULT;
+
+    path = p->fullPath(path);
+
+    auto result = chdir(path.c_str());
+    return (result == -1) ? -errno : result;
+}
+
+SyscallReturn
+rmdirFunc(SyscallDesc *desc, int num, Process *p, ThreadContext *tc)
+{
+    int index = 0;
+    std::string path;
+    if (!tc->getMemProxy().tryReadString(path, p->getSyscallArg(tc, index)))
+        return -EFAULT;
+
+    path = p->fullPath(path);
+
+    auto result = rmdir(path.c_str());
+    return (result == -1) ? -errno : result;
+}
+
+SyscallReturn
+getdentsFunc(SyscallDesc *desc, int callnum, Process *p, ThreadContext *tc)
+{
+    int index = 0;
+    int tgt_fd = p->getSyscallArg(tc, index);
+    Addr buf_ptr = p->getSyscallArg(tc, index);
+    unsigned count = p->getSyscallArg(tc, index);
+
+    auto hbfdp = std::dynamic_pointer_cast<HBFDEntry>((*p->fds)[tgt_fd]);
+    if (!hbfdp)
+        return -EBADF;
+    int sim_fd = hbfdp->getSimFD();
+
+    BufferArg buf_arg(buf_ptr, count);
+    auto status = syscall(SYS_getdents, 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);
+
+        auto host_reclen = buffer->d_reclen;
+
+        /**
+         * Convert the byte ordering from the host to the target before
+         * passing the data back into the target's address space to preserve
+         * endianness.
+         */
+        buffer->d_ino = htog(buffer->d_ino);
+        buffer->d_off = htog(buffer->d_off);
+        buffer->d_reclen = htog(buffer->d_reclen);
+
+        traversed += host_reclen;
+    }
+
+    buf_arg.copyOut(tc->getMemProxy());
+    return status;
+}
+
index 1f4233aa889d9bb9d6ac12b39271f4f6b450fd46..c7818b6c65919def03fdecb673dbd026e3cf961c 100644 (file)
@@ -215,6 +215,18 @@ SyscallReturn symlinkFunc(SyscallDesc *desc, int num, Process *p,
 SyscallReturn mkdirFunc(SyscallDesc *desc, int num,
                         Process *p, ThreadContext *tc);
 
+/// Target mknod() handler.
+SyscallReturn mknodFunc(SyscallDesc *desc, int num,
+                        Process *p, ThreadContext *tc);
+
+/// Target chdir() handler.
+SyscallReturn chdirFunc(SyscallDesc *desc, int num,
+                        Process *p, ThreadContext *tc);
+
+// Target rmdir() handler.
+SyscallReturn rmdirFunc(SyscallDesc *desc, int num,
+                        Process *p, ThreadContext *tc);
+
 /// Target rename() handler.
 SyscallReturn renameFunc(SyscallDesc *desc, int num,
                          Process *p, ThreadContext *tc);
@@ -291,7 +303,11 @@ SyscallReturn pipeImpl(SyscallDesc *desc, int num, Process *p,
 SyscallReturn getpidFunc(SyscallDesc *desc, int num,
                          Process *p, ThreadContext *tc);
 
-/// Target getuid() handler.
+// Target getdents() handler.
+SyscallReturn getdentsFunc(SyscallDesc *desc, int num,
+                           Process *p, ThreadContext *tc);
+
+// Target getuid() handler.
 SyscallReturn getuidFunc(SyscallDesc *desc, int num,
                          Process *p, ThreadContext *tc);