From f2abc6bb9edbcb23c7e314873b26ca6303a9c1b7 Mon Sep 17 00:00:00 2001 From: Brandon Potter Date: Wed, 18 Apr 2018 14:45:37 -0400 Subject: syscall_emul: implement dir-related syscalls 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 Maintainer: Anthony Gutierrez --- src/arch/x86/linux/process.cc | 20 ++++----- src/sim/syscall_emul.cc | 96 ++++++++++++++++++++++++++++++++++++++++++- src/sim/syscall_emul.hh | 18 +++++++- 3 files changed, 122 insertions(+), 12 deletions(-) diff --git a/src/arch/x86/linux/process.cc b/src/arch/x86/linux/process.cc index 51512fdda..9ec4ca040 100644 --- a/src/arch/x86/linux/process.cc +++ b/src/arch/x86/linux/process.cc @@ -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), - /* 12 */ SyscallDesc("chdir", unimplementedFunc), + /* 12 */ SyscallDesc("chdir", chdirFunc), /* 13 */ SyscallDesc("time", timeFunc), - /* 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), @@ -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), diff --git a/src/sim/syscall_emul.cc b/src/sim/syscall_emul.cc index dd2323eaa..794b0bc2c 100644 --- a/src/sim/syscall_emul.cc +++ b/src/sim/syscall_emul.cc @@ -32,10 +32,12 @@ #include "sim/syscall_emul.hh" #include +#include #include #include #include +#include #include #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((*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; +} + diff --git a/src/sim/syscall_emul.hh b/src/sim/syscall_emul.hh index 1f4233aa8..c7818b6c6 100644 --- a/src/sim/syscall_emul.hh +++ b/src/sim/syscall_emul.hh @@ -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); -- cgit v1.2.3