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 <jason@lowepower.com>
Maintainer: Anthony Gutierrez <anthony.gutierrez@amd.com>
This commit is contained in:
Brandon Potter
2018-04-18 14:45:37 -04:00
committed by Anthony Gutierrez
parent bed9460aaa
commit f2abc6bb9e
3 changed files with 122 additions and 12 deletions

View 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),

View File

@@ -32,10 +32,12 @@
#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;
}

View 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);