summaryrefslogtreecommitdiff
path: root/src/sim/syscall_emul.cc
diff options
context:
space:
mode:
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)