summaryrefslogtreecommitdiff
path: root/src/sim/syscall_emul.cc
diff options
context:
space:
mode:
authorBrandon Potter <brandon.potter@amd.com>2016-11-09 14:27:42 -0600
committerBrandon Potter <brandon.potter@amd.com>2016-11-09 14:27:42 -0600
commitd3d983caf94375b992940b017aeb4a73da28833c (patch)
tree7e6bf4226c9235ad187c0137c6518b3897b64752 /src/sim/syscall_emul.cc
parent6c41181b8e39e776ea2f018bf383fed2782c3d4a (diff)
downloadgem5-d3d983caf94375b992940b017aeb4a73da28833c.tar.xz
syscall_emul: [patch 10/22] refactor fdentry and add fdarray class
Several large changes happen in this patch. The FDEntry class is rewritten so that file descriptors now correspond to types: 'File' which is normal file-backed file with the file open on the host machine, 'Pipe' which is a pipe that has been opened on the host machine, and 'Device' which does not have an open file on the host yet acts as a pseudo device with which to issue ioctls. Other types which might be added in the future are directory entries and sockets (off the top of my head). The FDArray class was create to hold most of the file descriptor handling that was stuffed into the Process class. It uses shared pointers and the std::array type to hold the FDEntries mentioned above. The changes to these two classes needed to be propagated out to the rest of the code so there were quite a few changes for that. Also, comments were added where I thought they were needed to help others and extend our DOxygen coverage.
Diffstat (limited to 'src/sim/syscall_emul.cc')
-rw-r--r--src/sim/syscall_emul.cc176
1 files changed, 97 insertions, 79 deletions
diff --git a/src/sim/syscall_emul.cc b/src/sim/syscall_emul.cc
index d77901fa7..f4bfca6c2 100644
--- a/src/sim/syscall_emul.cc
+++ b/src/sim/syscall_emul.cc
@@ -172,16 +172,7 @@ closeFunc(SyscallDesc *desc, int num, Process *p, ThreadContext *tc)
int index = 0;
int tgt_fd = p->getSyscallArg(tc, index);
- int sim_fd = p->getSimFD(tgt_fd);
- if (sim_fd < 0)
- return -EBADF;
-
- int status = 0;
- if (sim_fd > 2)
- status = close(sim_fd);
- if (status >= 0)
- p->resetFDEntry(tgt_fd);
- return status;
+ return p->fds->closeFDEntry(tgt_fd);
}
@@ -192,12 +183,13 @@ readFunc(SyscallDesc *desc, int num, Process *p, ThreadContext *tc)
int tgt_fd = p->getSyscallArg(tc, index);
Addr bufPtr = p->getSyscallArg(tc, index);
int nbytes = p->getSyscallArg(tc, index);
- BufferArg bufArg(bufPtr, nbytes);
- int sim_fd = p->getSimFD(tgt_fd);
- if (sim_fd < 0)
+ auto hbfdp = std::dynamic_pointer_cast<HBFDEntry>((*p->fds)[tgt_fd]);
+ if (!hbfdp)
return -EBADF;
+ int sim_fd = hbfdp->getSimFD();
+ BufferArg bufArg(bufPtr, nbytes);
int bytes_read = read(sim_fd, bufArg.bufferPtr(), nbytes);
if (bytes_read > 0)
@@ -213,12 +205,13 @@ writeFunc(SyscallDesc *desc, int num, Process *p, ThreadContext *tc)
int tgt_fd = p->getSyscallArg(tc, index);
Addr bufPtr = p->getSyscallArg(tc, index);
int nbytes = p->getSyscallArg(tc, index);
- BufferArg bufArg(bufPtr, nbytes);
- int sim_fd = p->getSimFD(tgt_fd);
- if (sim_fd < 0)
+ auto hbfdp = std::dynamic_pointer_cast<HBFDEntry>((*p->fds)[tgt_fd]);
+ if (!hbfdp)
return -EBADF;
+ int sim_fd = hbfdp->getSimFD();
+ BufferArg bufArg(bufPtr, nbytes);
bufArg.copyIn(tc->getMemProxy());
int bytes_written = write(sim_fd, bufArg.bufferPtr(), nbytes);
@@ -237,9 +230,10 @@ lseekFunc(SyscallDesc *desc, int num, Process *p, ThreadContext *tc)
uint64_t offs = p->getSyscallArg(tc, index);
int whence = p->getSyscallArg(tc, index);
- int sim_fd = p->getSimFD(tgt_fd);
- if (sim_fd < 0)
+ auto ffdp = std::dynamic_pointer_cast<FileFDEntry>((*p->fds)[tgt_fd]);
+ if (!ffdp)
return -EBADF;
+ int sim_fd = ffdp->getSimFD();
off_t result = lseek(sim_fd, offs, whence);
@@ -257,9 +251,10 @@ _llseekFunc(SyscallDesc *desc, int num, Process *p, ThreadContext *tc)
Addr result_ptr = p->getSyscallArg(tc, index);
int whence = p->getSyscallArg(tc, index);
- int sim_fd = p->getSimFD(tgt_fd);
- if (sim_fd < 0)
+ auto ffdp = std::dynamic_pointer_cast<FileFDEntry>((*p->fds)[tgt_fd]);
+ if (!ffdp)
return -EBADF;
+ int sim_fd = ffdp->getSimFD();
uint64_t offset = (offset_high << 32) | offset_low;
@@ -322,7 +317,7 @@ getcwdFunc(SyscallDesc *desc, int num, Process *p, ThreadContext *tc)
strncpy((char *)buf.bufferPtr(), cwd.c_str(), size);
result = cwd.length();
} else {
- if (getcwd((char *)buf.bufferPtr(), size) != NULL) {
+ if (getcwd((char *)buf.bufferPtr(), size)) {
result = strlen((char *)buf.bufferPtr());
} else {
result = -1;
@@ -484,16 +479,16 @@ truncateFunc(SyscallDesc *desc, int num, Process *p, ThreadContext *tc)
}
SyscallReturn
-ftruncateFunc(SyscallDesc *desc, int num,
- Process *process, ThreadContext *tc)
+ftruncateFunc(SyscallDesc *desc, int num, Process *p, ThreadContext *tc)
{
int index = 0;
- int tgt_fd = process->getSyscallArg(tc, index);
- off_t length = process->getSyscallArg(tc, index);
+ int tgt_fd = p->getSyscallArg(tc, index);
+ off_t length = p->getSyscallArg(tc, index);
- int sim_fd = process->getSimFD(tgt_fd);
- if (sim_fd < 0)
+ auto ffdp = std::dynamic_pointer_cast<FileFDEntry>((*p->fds)[tgt_fd]);
+ if (!ffdp)
return -EBADF;
+ int sim_fd = ffdp->getSimFD();
int result = ftruncate(sim_fd, length);
return (result == -1) ? -errno : result;
@@ -523,16 +518,16 @@ truncate64Func(SyscallDesc *desc, int num,
}
SyscallReturn
-ftruncate64Func(SyscallDesc *desc, int num,
- Process *process, ThreadContext *tc)
+ftruncate64Func(SyscallDesc *desc, int num, Process *p, ThreadContext *tc)
{
int index = 0;
- int tgt_fd = process->getSyscallArg(tc, index);
- int64_t length = process->getSyscallArg(tc, index, 64);
+ int tgt_fd = p->getSyscallArg(tc, index);
+ int64_t length = p->getSyscallArg(tc, index, 64);
- int sim_fd = process->getSimFD(tgt_fd);
- if (sim_fd < 0)
+ auto ffdp = std::dynamic_pointer_cast<FileFDEntry>((*p->fds)[tgt_fd]);
+ if (!ffdp)
return -EBADF;
+ int sim_fd = ffdp->getSimFD();
#if NO_STAT64
int result = ftruncate(sim_fd, length);
@@ -576,19 +571,20 @@ chownFunc(SyscallDesc *desc, int num, Process *p, ThreadContext *tc)
}
SyscallReturn
-fchownFunc(SyscallDesc *desc, int num, Process *process, ThreadContext *tc)
+fchownFunc(SyscallDesc *desc, int num, Process *p, ThreadContext *tc)
{
int index = 0;
- int tgt_fd = process->getSyscallArg(tc, index);
+ int tgt_fd = p->getSyscallArg(tc, index);
- int sim_fd = process->getSimFD(tgt_fd);
- if (sim_fd < 0)
+ auto ffdp = std::dynamic_pointer_cast<FileFDEntry>((*p->fds)[tgt_fd]);
+ if (!ffdp)
return -EBADF;
+ int sim_fd = ffdp->getSimFD();
/* XXX endianess */
- uint32_t owner = process->getSyscallArg(tc, index);
+ uint32_t owner = p->getSyscallArg(tc, index);
uid_t hostOwner = owner;
- uint32_t group = process->getSyscallArg(tc, index);
+ uint32_t group = p->getSyscallArg(tc, index);
gid_t hostGroup = group;
int result = fchown(sim_fd, hostOwner, hostGroup);
@@ -596,36 +592,47 @@ fchownFunc(SyscallDesc *desc, int num, Process *process, ThreadContext *tc)
}
+/**
+ * TODO: there's a bit more involved here since file descriptors created with
+ * dup are supposed to share a file description. So, there is a problem with
+ * maintaining fields like file offset or flags since an update to such a
+ * field won't be reflected in the metadata for the fd entries that we
+ * maintain to hold metadata for checkpoint restoration.
+ */
SyscallReturn
-dupFunc(SyscallDesc *desc, int num, Process *process, ThreadContext *tc)
+dupFunc(SyscallDesc *desc, int num, Process *p, ThreadContext *tc)
{
int index = 0;
- int tgt_fd = process->getSyscallArg(tc, index);
+ int tgt_fd = p->getSyscallArg(tc, index);
- int sim_fd = process->getSimFD(tgt_fd);
- if (sim_fd < 0)
+ auto old_hbfdp = std::dynamic_pointer_cast<HBFDEntry>((*p->fds)[tgt_fd]);
+ if (!old_hbfdp)
return -EBADF;
-
- FDEntry *fde = process->getFDEntry(tgt_fd);
+ int sim_fd = old_hbfdp->getSimFD();
int result = dup(sim_fd);
- return (result == -1) ? -errno :
- process->allocFD(result, fde->filename, fde->flags, fde->mode, false);
+ int local_errno = errno;
+
+ std::shared_ptr<FDEntry> new_fdep = old_hbfdp->clone();
+ auto new_hbfdp = std::dynamic_pointer_cast<HBFDEntry>(new_fdep);
+ new_hbfdp->setSimFD(result);
+
+ return (result == -1) ? -local_errno : p->fds->allocFD(new_fdep);
}
SyscallReturn
-fcntlFunc(SyscallDesc *desc, int num, Process *process,
- ThreadContext *tc)
+fcntlFunc(SyscallDesc *desc, int num, Process *p, ThreadContext *tc)
{
int index = 0;
- int tgt_fd = process->getSyscallArg(tc, index);
+ int tgt_fd = p->getSyscallArg(tc, index);
- int sim_fd = process->getSimFD(tgt_fd);
- if (sim_fd < 0)
+ auto hbfdp = std::dynamic_pointer_cast<HBFDEntry>((*p->fds)[tgt_fd]);
+ if (!hbfdp)
return -EBADF;
+ int sim_fd = hbfdp->getSimFD();
- int cmd = process->getSyscallArg(tc, index);
+ int cmd = p->getSyscallArg(tc, index);
switch (cmd) {
case 0: // F_DUPFD
// if we really wanted to support this, we'd need to do it
@@ -659,17 +666,17 @@ fcntlFunc(SyscallDesc *desc, int num, Process *process,
}
SyscallReturn
-fcntl64Func(SyscallDesc *desc, int num, Process *process,
- ThreadContext *tc)
+fcntl64Func(SyscallDesc *desc, int num, Process *p, ThreadContext *tc)
{
int index = 0;
- int tgt_fd = process->getSyscallArg(tc, index);
+ int tgt_fd = p->getSyscallArg(tc, index);
- int sim_fd = process->getSimFD(tgt_fd);
- if (sim_fd < 0)
+ auto hbfdp = std::dynamic_pointer_cast<HBFDEntry>((*p->fds)[tgt_fd]);
+ if (!hbfdp)
return -EBADF;
+ int sim_fd = hbfdp->getSimFD();
- int cmd = process->getSyscallArg(tc, index);
+ int cmd = p->getSyscallArg(tc, index);
switch (cmd) {
case 33: //F_GETLK64
warn("fcntl64(%d, F_GETLK64) not supported, error returned\n", tgt_fd);
@@ -694,21 +701,32 @@ SyscallReturn
pipePseudoFunc(SyscallDesc *desc, int callnum, Process *process,
ThreadContext *tc)
{
- int fds[2], sim_fds[2];
- int pipe_retval = pipe(fds);
+ int sim_fds[2], tgt_fds[2];
- if (pipe_retval < 0) {
- // error
+ int pipe_retval = pipe(sim_fds);
+ if (pipe_retval < 0)
return pipe_retval;
- }
- sim_fds[0] = process->allocFD(fds[0], "PIPE-READ", O_WRONLY, -1, true);
- sim_fds[1] = process->allocFD(fds[1], "PIPE-WRITE", O_RDONLY, -1, true);
+ auto rend = PipeFDEntry::EndType::read;
+ auto rpfd = std::make_shared<PipeFDEntry>(sim_fds[0], O_WRONLY, rend);
+
+ auto wend = PipeFDEntry::EndType::write;
+ auto wpfd = std::make_shared<PipeFDEntry>(sim_fds[1], O_RDONLY, wend);
+
+ tgt_fds[0] = process->fds->allocFD(rpfd);
+ tgt_fds[1] = process->fds->allocFD(wpfd);
- process->setReadPipeSource(sim_fds[0], sim_fds[1]);
- // Alpha Linux convention for pipe() is that fd[0] is returned as
- // the return value of the function, and fd[1] is returned in r20.
- tc->setIntReg(SyscallPseudoReturnReg, sim_fds[1]);
+ /**
+ * Now patch the read object to record the target file descriptor chosen
+ * as the write end of the pipe.
+ */
+ rpfd->setPipeReadSource(tgt_fds[1]);
+
+ /**
+ * Alpha Linux convention for pipe() is that fd[0] is returned as
+ * the return value of the function, and fd[1] is returned in r20.
+ */
+ tc->setIntReg(SyscallPseudoReturnReg, tgt_fds[1]);
return sim_fds[0];
}
@@ -828,7 +846,7 @@ cloneFunc(SyscallDesc *desc, int callnum, Process *process,
}
ThreadContext* ctc; // child thread context
- if ( ( ctc = process->findFreeContext() ) != NULL ) {
+ if ((ctc = process->findFreeContext())) {
DPRINTF(SyscallVerbose, " Found unallocated thread context\n");
ctc->clearArchRegs();
@@ -890,21 +908,21 @@ cloneFunc(SyscallDesc *desc, int callnum, Process *process,
}
SyscallReturn
-fallocateFunc(SyscallDesc *desc, int callnum, Process *process,
- ThreadContext *tc)
+fallocateFunc(SyscallDesc *desc, int callnum, Process *p, ThreadContext *tc)
{
#if NO_FALLOCATE
warn("Host OS cannot support calls to fallocate. Ignoring syscall");
#else
int index = 0;
- int tgt_fd = process->getSyscallArg(tc, index);
- int mode = process->getSyscallArg(tc, index);
- off_t offset = process->getSyscallArg(tc, index);
- off_t len = process->getSyscallArg(tc, index);
+ int tgt_fd = p->getSyscallArg(tc, index);
+ int mode = p->getSyscallArg(tc, index);
+ off_t offset = p->getSyscallArg(tc, index);
+ off_t len = p->getSyscallArg(tc, index);
- int sim_fd = process->getSimFD(tgt_fd);
- if (sim_fd < 0)
+ auto ffdp = std::dynamic_pointer_cast<FileFDEntry>((*p->fds)[tgt_fd]);
+ if (!ffdp)
return -EBADF;
+ int sim_fd = ffdp->getSimFD();
int result = fallocate(sim_fd, mode, offset, len);
if (result < 0)