Syscalls: Make system calls access arguments like a stack, not an array.
When accessing arguments for a syscall, the position of an argument depends on the policies of the ISA, how much space preceding arguments took up, and the "alignment" of the index for this particular argument into the number of possible storate locations. This change adjusts getSyscallArg to take its index parameter by reference instead of value and to adjust it to point to the possible location of the next argument on the stack, basically just after the current one. This way, the rules for the new argument can be applied locally without knowing about other arguments since those have already been taken into account implicitly. All system calls have also been changed to reflect the new interface. In a number of cases this made the implementation clearer since it encourages arguments to be collected in one place in order and then used as necessary later, as opposed to scattering them throughout the function or using them in place in long expressions. It also discourages using getSyscallArg over and over to retrieve the same value when a temporary would do the job.
This commit is contained in:
@@ -647,6 +647,12 @@ LiveProcess::syscall(int64_t callnum, ThreadContext *tc)
|
||||
desc->doSyscall(callnum, this, tc);
|
||||
}
|
||||
|
||||
IntReg
|
||||
LiveProcess::getSyscallArg(ThreadContext *tc, int &i, int width)
|
||||
{
|
||||
return getSyscallArg(tc, i);
|
||||
}
|
||||
|
||||
LiveProcess *
|
||||
LiveProcess::create(LiveProcessParams * params)
|
||||
{
|
||||
|
||||
@@ -325,7 +325,9 @@ class LiveProcess : public Process
|
||||
std::string getcwd() const { return cwd; }
|
||||
|
||||
virtual void syscall(int64_t callnum, ThreadContext *tc);
|
||||
virtual TheISA::IntReg getSyscallArg(ThreadContext *tc, int i) = 0;
|
||||
|
||||
virtual TheISA::IntReg getSyscallArg(ThreadContext *tc, int &i) = 0;
|
||||
virtual TheISA::IntReg getSyscallArg(ThreadContext *tc, int &i, int width);
|
||||
virtual void setSyscallArg(ThreadContext *tc,
|
||||
int i, TheISA::IntReg val) = 0;
|
||||
virtual void setSyscallReturn(ThreadContext *tc,
|
||||
|
||||
@@ -52,11 +52,14 @@ using namespace TheISA;
|
||||
void
|
||||
SyscallDesc::doSyscall(int callnum, LiveProcess *process, ThreadContext *tc)
|
||||
{
|
||||
int index = 0;
|
||||
DPRINTFR(SyscallVerbose,
|
||||
"%d: %s: syscall %s called w/arguments %d,%d,%d,%d\n",
|
||||
curTick, tc->getCpuPtr()->name(), name,
|
||||
process->getSyscallArg(tc, 0), process->getSyscallArg(tc, 1),
|
||||
process->getSyscallArg(tc, 2), process->getSyscallArg(tc, 3));
|
||||
process->getSyscallArg(tc, index),
|
||||
process->getSyscallArg(tc, index),
|
||||
process->getSyscallArg(tc, index),
|
||||
process->getSyscallArg(tc, index));
|
||||
|
||||
SyscallReturn retval = (*funcPtr)(this, callnum, process, tc);
|
||||
|
||||
@@ -82,8 +85,9 @@ SyscallReturn
|
||||
ignoreFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||
ThreadContext *tc)
|
||||
{
|
||||
int index = 0;
|
||||
warn("ignoring syscall %s(%d, %d, ...)", desc->name,
|
||||
process->getSyscallArg(tc, 0), process->getSyscallArg(tc, 1));
|
||||
process->getSyscallArg(tc, index), process->getSyscallArg(tc, index));
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -95,8 +99,9 @@ exitFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||
{
|
||||
if (process->system->numRunningContexts() == 1) {
|
||||
// Last running context... exit simulator
|
||||
int index = 0;
|
||||
exitSimLoop("target called exit()",
|
||||
process->getSyscallArg(tc, 0) & 0xff);
|
||||
process->getSyscallArg(tc, index) & 0xff);
|
||||
} else {
|
||||
// other running threads... just halt this one
|
||||
tc->halt();
|
||||
@@ -112,8 +117,9 @@ exitGroupFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||
{
|
||||
// really should just halt all thread contexts belonging to this
|
||||
// process in case there's another process running...
|
||||
int index = 0;
|
||||
exitSimLoop("target called exit()",
|
||||
process->getSyscallArg(tc, 0) & 0xff);
|
||||
process->getSyscallArg(tc, index) & 0xff);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -130,7 +136,8 @@ SyscallReturn
|
||||
brkFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
|
||||
{
|
||||
// change brk addr to first arg
|
||||
Addr new_brk = p->getSyscallArg(tc, 0);
|
||||
int index = 0;
|
||||
Addr new_brk = p->getSyscallArg(tc, index);
|
||||
|
||||
// in Linux at least, brk(0) returns the current break value
|
||||
// (note that the syscall and the glibc function have different behavior)
|
||||
@@ -174,7 +181,8 @@ brkFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
|
||||
SyscallReturn
|
||||
closeFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
|
||||
{
|
||||
int target_fd = p->getSyscallArg(tc, 0);
|
||||
int index = 0;
|
||||
int target_fd = p->getSyscallArg(tc, index);
|
||||
int status = close(p->sim_fd(target_fd));
|
||||
if (status >= 0)
|
||||
p->free_fd(target_fd);
|
||||
@@ -185,9 +193,11 @@ closeFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
|
||||
SyscallReturn
|
||||
readFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
|
||||
{
|
||||
int fd = p->sim_fd(p->getSyscallArg(tc, 0));
|
||||
int nbytes = p->getSyscallArg(tc, 2);
|
||||
BufferArg bufArg(p->getSyscallArg(tc, 1), nbytes);
|
||||
int index = 0;
|
||||
int fd = p->sim_fd(p->getSyscallArg(tc, index));
|
||||
Addr bufPtr = p->getSyscallArg(tc, index);
|
||||
int nbytes = p->getSyscallArg(tc, index);
|
||||
BufferArg bufArg(bufPtr, nbytes);
|
||||
|
||||
int bytes_read = read(fd, bufArg.bufferPtr(), nbytes);
|
||||
|
||||
@@ -200,9 +210,11 @@ readFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
|
||||
SyscallReturn
|
||||
writeFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
|
||||
{
|
||||
int fd = p->sim_fd(p->getSyscallArg(tc, 0));
|
||||
int nbytes = p->getSyscallArg(tc, 2);
|
||||
BufferArg bufArg(p->getSyscallArg(tc, 1), nbytes);
|
||||
int index = 0;
|
||||
int fd = p->sim_fd(p->getSyscallArg(tc, index));
|
||||
Addr bufPtr = p->getSyscallArg(tc, index);
|
||||
int nbytes = p->getSyscallArg(tc, index);
|
||||
BufferArg bufArg(bufPtr, nbytes);
|
||||
|
||||
bufArg.copyIn(tc->getMemPort());
|
||||
|
||||
@@ -217,9 +229,10 @@ writeFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
|
||||
SyscallReturn
|
||||
lseekFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
|
||||
{
|
||||
int fd = p->sim_fd(p->getSyscallArg(tc, 0));
|
||||
uint64_t offs = p->getSyscallArg(tc, 1);
|
||||
int whence = p->getSyscallArg(tc, 2);
|
||||
int index = 0;
|
||||
int fd = p->sim_fd(p->getSyscallArg(tc, index));
|
||||
uint64_t offs = p->getSyscallArg(tc, index);
|
||||
int whence = p->getSyscallArg(tc, index);
|
||||
|
||||
off_t result = lseek(fd, offs, whence);
|
||||
|
||||
@@ -230,11 +243,12 @@ lseekFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
|
||||
SyscallReturn
|
||||
_llseekFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
|
||||
{
|
||||
int fd = p->sim_fd(p->getSyscallArg(tc, 0));
|
||||
uint64_t offset_high = p->getSyscallArg(tc, 1);
|
||||
uint32_t offset_low = p->getSyscallArg(tc, 2);
|
||||
Addr result_ptr = p->getSyscallArg(tc, 3);
|
||||
int whence = p->getSyscallArg(tc, 4);
|
||||
int index = 0;
|
||||
int fd = p->sim_fd(p->getSyscallArg(tc, index));
|
||||
uint64_t offset_high = p->getSyscallArg(tc, index);
|
||||
uint32_t offset_low = p->getSyscallArg(tc, index);
|
||||
Addr result_ptr = p->getSyscallArg(tc, index);
|
||||
int whence = p->getSyscallArg(tc, index);
|
||||
|
||||
uint64_t offset = (offset_high << 32) | offset_low;
|
||||
|
||||
@@ -273,8 +287,10 @@ const char *hostname = "m5.eecs.umich.edu";
|
||||
SyscallReturn
|
||||
gethostnameFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
|
||||
{
|
||||
int name_len = p->getSyscallArg(tc, 1);
|
||||
BufferArg name(p->getSyscallArg(tc, 0), name_len);
|
||||
int index = 0;
|
||||
Addr bufPtr = p->getSyscallArg(tc, index);
|
||||
int name_len = p->getSyscallArg(tc, index);
|
||||
BufferArg name(bufPtr, name_len);
|
||||
|
||||
strncpy((char *)name.bufferPtr(), hostname, name_len);
|
||||
|
||||
@@ -287,8 +303,10 @@ SyscallReturn
|
||||
getcwdFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
|
||||
{
|
||||
int result = 0;
|
||||
unsigned long size = p->getSyscallArg(tc, 1);
|
||||
BufferArg buf(p->getSyscallArg(tc, 0), size);
|
||||
int index;
|
||||
Addr bufPtr = p->getSyscallArg(tc, index);
|
||||
unsigned long size = p->getSyscallArg(tc, index);
|
||||
BufferArg buf(bufPtr, size);
|
||||
|
||||
// Is current working directory defined?
|
||||
string cwd = p->getcwd();
|
||||
@@ -320,14 +338,17 @@ readlinkFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
|
||||
{
|
||||
string path;
|
||||
|
||||
if (!tc->getMemPort()->tryReadString(path, p->getSyscallArg(tc, 0)))
|
||||
int index = 0;
|
||||
if (!tc->getMemPort()->tryReadString(path, p->getSyscallArg(tc, index)))
|
||||
return (TheISA::IntReg)-EFAULT;
|
||||
|
||||
// Adjust path for current working directory
|
||||
path = p->fullPath(path);
|
||||
|
||||
size_t bufsiz = p->getSyscallArg(tc, 2);
|
||||
BufferArg buf(p->getSyscallArg(tc, 1), bufsiz);
|
||||
Addr bufPtr = p->getSyscallArg(tc, index);
|
||||
size_t bufsiz = p->getSyscallArg(tc, index);
|
||||
|
||||
BufferArg buf(bufPtr, bufsiz);
|
||||
|
||||
int result = readlink(path.c_str(), (char *)buf.bufferPtr(), bufsiz);
|
||||
|
||||
@@ -341,7 +362,8 @@ unlinkFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
|
||||
{
|
||||
string path;
|
||||
|
||||
if (!tc->getMemPort()->tryReadString(path, p->getSyscallArg(tc, 0)))
|
||||
int index = 0;
|
||||
if (!tc->getMemPort()->tryReadString(path, p->getSyscallArg(tc, index)))
|
||||
return (TheISA::IntReg)-EFAULT;
|
||||
|
||||
// Adjust path for current working directory
|
||||
@@ -357,13 +379,14 @@ mkdirFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
|
||||
{
|
||||
string path;
|
||||
|
||||
if (!tc->getMemPort()->tryReadString(path, p->getSyscallArg(tc, 0)))
|
||||
int index = 0;
|
||||
if (!tc->getMemPort()->tryReadString(path, p->getSyscallArg(tc, index)))
|
||||
return (TheISA::IntReg)-EFAULT;
|
||||
|
||||
// Adjust path for current working directory
|
||||
path = p->fullPath(path);
|
||||
|
||||
mode_t mode = p->getSyscallArg(tc, 1);
|
||||
mode_t mode = p->getSyscallArg(tc, index);
|
||||
|
||||
int result = mkdir(path.c_str(), mode);
|
||||
return (result == -1) ? -errno : result;
|
||||
@@ -374,12 +397,13 @@ renameFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
|
||||
{
|
||||
string old_name;
|
||||
|
||||
if (!tc->getMemPort()->tryReadString(old_name, p->getSyscallArg(tc, 0)))
|
||||
int index = 0;
|
||||
if (!tc->getMemPort()->tryReadString(old_name, p->getSyscallArg(tc, index)))
|
||||
return -EFAULT;
|
||||
|
||||
string new_name;
|
||||
|
||||
if (!tc->getMemPort()->tryReadString(new_name, p->getSyscallArg(tc, 1)))
|
||||
if (!tc->getMemPort()->tryReadString(new_name, p->getSyscallArg(tc, index)))
|
||||
return -EFAULT;
|
||||
|
||||
// Adjust path for current working directory
|
||||
@@ -395,10 +419,11 @@ truncateFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
|
||||
{
|
||||
string path;
|
||||
|
||||
if (!tc->getMemPort()->tryReadString(path, p->getSyscallArg(tc, 0)))
|
||||
int index = 0;
|
||||
if (!tc->getMemPort()->tryReadString(path, p->getSyscallArg(tc, index)))
|
||||
return -EFAULT;
|
||||
|
||||
off_t length = p->getSyscallArg(tc, 1);
|
||||
off_t length = p->getSyscallArg(tc, index);
|
||||
|
||||
// Adjust path for current working directory
|
||||
path = p->fullPath(path);
|
||||
@@ -411,12 +436,13 @@ SyscallReturn
|
||||
ftruncateFunc(SyscallDesc *desc, int num,
|
||||
LiveProcess *process, ThreadContext *tc)
|
||||
{
|
||||
int fd = process->sim_fd(process->getSyscallArg(tc, 0));
|
||||
int index = 0;
|
||||
int fd = process->sim_fd(process->getSyscallArg(tc, index));
|
||||
|
||||
if (fd < 0)
|
||||
return -EBADF;
|
||||
|
||||
off_t length = process->getSyscallArg(tc, 1);
|
||||
off_t length = process->getSyscallArg(tc, index);
|
||||
|
||||
int result = ftruncate(fd, length);
|
||||
return (result == -1) ? -errno : result;
|
||||
@@ -426,13 +452,13 @@ SyscallReturn
|
||||
ftruncate64Func(SyscallDesc *desc, int num,
|
||||
LiveProcess *process, ThreadContext *tc)
|
||||
{
|
||||
int fd = process->sim_fd(process->getSyscallArg(tc, 0));
|
||||
int index = 0;
|
||||
int fd = process->sim_fd(process->getSyscallArg(tc, index));
|
||||
|
||||
if (fd < 0)
|
||||
return -EBADF;
|
||||
|
||||
// I'm not sure why, but the length argument is in arg reg 3
|
||||
loff_t length = process->getSyscallArg(tc, 3);
|
||||
loff_t length = process->getSyscallArg(tc, index, 64);
|
||||
|
||||
int result = ftruncate64(fd, length);
|
||||
return (result == -1) ? -errno : result;
|
||||
@@ -454,13 +480,14 @@ chownFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
|
||||
{
|
||||
string path;
|
||||
|
||||
if (!tc->getMemPort()->tryReadString(path, p->getSyscallArg(tc, 0)))
|
||||
int index = 0;
|
||||
if (!tc->getMemPort()->tryReadString(path, p->getSyscallArg(tc, index)))
|
||||
return -EFAULT;
|
||||
|
||||
/* XXX endianess */
|
||||
uint32_t owner = p->getSyscallArg(tc, 1);
|
||||
uint32_t owner = p->getSyscallArg(tc, index);
|
||||
uid_t hostOwner = owner;
|
||||
uint32_t group = p->getSyscallArg(tc, 2);
|
||||
uint32_t group = p->getSyscallArg(tc, index);
|
||||
gid_t hostGroup = group;
|
||||
|
||||
// Adjust path for current working directory
|
||||
@@ -473,15 +500,16 @@ chownFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
|
||||
SyscallReturn
|
||||
fchownFunc(SyscallDesc *desc, int num, LiveProcess *process, ThreadContext *tc)
|
||||
{
|
||||
int fd = process->sim_fd(process->getSyscallArg(tc, 0));
|
||||
int index = 0;
|
||||
int fd = process->sim_fd(process->getSyscallArg(tc, index));
|
||||
|
||||
if (fd < 0)
|
||||
return -EBADF;
|
||||
|
||||
/* XXX endianess */
|
||||
uint32_t owner = process->getSyscallArg(tc, 1);
|
||||
uint32_t owner = process->getSyscallArg(tc, index);
|
||||
uid_t hostOwner = owner;
|
||||
uint32_t group = process->getSyscallArg(tc, 2);
|
||||
uint32_t group = process->getSyscallArg(tc, index);
|
||||
gid_t hostGroup = group;
|
||||
|
||||
int result = fchown(fd, hostOwner, hostGroup);
|
||||
@@ -492,11 +520,12 @@ fchownFunc(SyscallDesc *desc, int num, LiveProcess *process, ThreadContext *tc)
|
||||
SyscallReturn
|
||||
dupFunc(SyscallDesc *desc, int num, LiveProcess *process, ThreadContext *tc)
|
||||
{
|
||||
int fd = process->sim_fd(process->getSyscallArg(tc, 0));
|
||||
int index = 0;
|
||||
int fd = process->sim_fd(process->getSyscallArg(tc, index));
|
||||
if (fd < 0)
|
||||
return -EBADF;
|
||||
|
||||
Process::FdMap *fdo = process->sim_fd_obj(process->getSyscallArg(tc, 0));
|
||||
Process::FdMap *fdo = process->sim_fd_obj(fd);
|
||||
|
||||
int result = dup(fd);
|
||||
return (result == -1) ? -errno :
|
||||
@@ -508,12 +537,13 @@ SyscallReturn
|
||||
fcntlFunc(SyscallDesc *desc, int num, LiveProcess *process,
|
||||
ThreadContext *tc)
|
||||
{
|
||||
int fd = process->getSyscallArg(tc, 0);
|
||||
int index = 0;
|
||||
int fd = process->getSyscallArg(tc, index);
|
||||
|
||||
if (fd < 0 || process->sim_fd(fd) < 0)
|
||||
return -EBADF;
|
||||
|
||||
int cmd = process->getSyscallArg(tc, 1);
|
||||
int cmd = process->getSyscallArg(tc, index);
|
||||
switch (cmd) {
|
||||
case 0: // F_DUPFD
|
||||
// if we really wanted to support this, we'd need to do it
|
||||
@@ -550,12 +580,13 @@ SyscallReturn
|
||||
fcntl64Func(SyscallDesc *desc, int num, LiveProcess *process,
|
||||
ThreadContext *tc)
|
||||
{
|
||||
int fd = process->getSyscallArg(tc, 0);
|
||||
int index = 0;
|
||||
int fd = process->getSyscallArg(tc, index);
|
||||
|
||||
if (fd < 0 || process->sim_fd(fd) < 0)
|
||||
return -EBADF;
|
||||
|
||||
int cmd = process->getSyscallArg(tc, 1);
|
||||
int cmd = process->getSyscallArg(tc, index);
|
||||
switch (cmd) {
|
||||
case 33: //F_GETLK64
|
||||
warn("fcntl64(%d, F_GETLK64) not supported, error returned\n", fd);
|
||||
@@ -639,7 +670,8 @@ setuidFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||
ThreadContext *tc)
|
||||
{
|
||||
// can't fathom why a benchmark would call this.
|
||||
warn("Ignoring call to setuid(%d)\n", process->getSyscallArg(tc, 0));
|
||||
int index = 0;
|
||||
warn("Ignoring call to setuid(%d)\n", process->getSyscallArg(tc, index));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -695,17 +727,20 @@ SyscallReturn
|
||||
cloneFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||
ThreadContext *tc)
|
||||
{
|
||||
int index = 0;
|
||||
IntReg flags = process->getSyscallArg(tc, index);
|
||||
IntReg newStack = process->getSyscallArg(tc, index);
|
||||
|
||||
DPRINTF(SyscallVerbose, "In sys_clone:\n");
|
||||
DPRINTF(SyscallVerbose, " Flags=%llx\n", process->getSyscallArg(tc, 0));
|
||||
DPRINTF(SyscallVerbose, " Child stack=%llx\n",
|
||||
process->getSyscallArg(tc, 1));
|
||||
DPRINTF(SyscallVerbose, " Flags=%llx\n", flags);
|
||||
DPRINTF(SyscallVerbose, " Child stack=%llx\n", newStack);
|
||||
|
||||
|
||||
if (process->getSyscallArg(tc, 0) != 0x10f00) {
|
||||
if (flags != 0x10f00) {
|
||||
warn("This sys_clone implementation assumes flags "
|
||||
"CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD "
|
||||
"(0x10f00), and may not work correctly with given flags "
|
||||
"0x%llx\n", process->getSyscallArg(tc, 0));
|
||||
"0x%llx\n", flags);
|
||||
}
|
||||
|
||||
ThreadContext* ctc; // child thread context
|
||||
@@ -738,7 +773,7 @@ cloneFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||
#endif
|
||||
|
||||
// Set up stack register
|
||||
ctc->setIntReg(TheISA::StackPointerReg, process->getSyscallArg(tc, 1));
|
||||
ctc->setIntReg(TheISA::StackPointerReg, newStack);
|
||||
|
||||
// Set up syscall return values in parent and child
|
||||
ctc->setIntReg(ReturnValueReg, 0); // return value, child
|
||||
|
||||
@@ -481,8 +481,9 @@ SyscallReturn
|
||||
ioctlFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||
ThreadContext *tc)
|
||||
{
|
||||
int fd = process->getSyscallArg(tc, 0);
|
||||
unsigned req = process->getSyscallArg(tc, 1);
|
||||
int index = 0;
|
||||
int fd = process->getSyscallArg(tc, index);
|
||||
unsigned req = process->getSyscallArg(tc, index);
|
||||
|
||||
DPRINTF(SyscallVerbose, "ioctl(%d, 0x%x, ...)\n", fd, req);
|
||||
|
||||
@@ -517,7 +518,9 @@ openFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||
{
|
||||
std::string path;
|
||||
|
||||
if (!tc->getMemPort()->tryReadString(path, process->getSyscallArg(tc, 0)))
|
||||
int index = 0;
|
||||
if (!tc->getMemPort()->tryReadString(path,
|
||||
process->getSyscallArg(tc, index)))
|
||||
return -EFAULT;
|
||||
|
||||
if (path == "/dev/sysdev0") {
|
||||
@@ -527,8 +530,8 @@ openFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
int tgtFlags = process->getSyscallArg(tc, 1);
|
||||
int mode = process->getSyscallArg(tc, 2);
|
||||
int tgtFlags = process->getSyscallArg(tc, index);
|
||||
int mode = process->getSyscallArg(tc, index);
|
||||
int hostFlags = 0;
|
||||
|
||||
// translate open flags
|
||||
@@ -573,14 +576,16 @@ sysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||
ThreadContext *tc)
|
||||
{
|
||||
|
||||
TypedBufferArg<typename OS::tgt_sysinfo> sysinfo(process->getSyscallArg(tc, 0));
|
||||
int index = 0;
|
||||
TypedBufferArg<typename OS::tgt_sysinfo>
|
||||
sysinfo(process->getSyscallArg(tc, index));
|
||||
|
||||
sysinfo->uptime=seconds_since_epoch;
|
||||
sysinfo->totalram=process->system->memSize();
|
||||
sysinfo->uptime=seconds_since_epoch;
|
||||
sysinfo->totalram=process->system->memSize();
|
||||
|
||||
sysinfo.copyOut(tc->getMemPort());
|
||||
sysinfo.copyOut(tc->getMemPort());
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// Target chmod() handler.
|
||||
@@ -591,10 +596,13 @@ chmodFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||
{
|
||||
std::string path;
|
||||
|
||||
if (!tc->getMemPort()->tryReadString(path, process->getSyscallArg(tc, 0)))
|
||||
int index = 0;
|
||||
if (!tc->getMemPort()->tryReadString(path,
|
||||
process->getSyscallArg(tc, index))) {
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
uint32_t mode = process->getSyscallArg(tc, 1);
|
||||
uint32_t mode = process->getSyscallArg(tc, index);
|
||||
mode_t hostMode = 0;
|
||||
|
||||
// XXX translate mode flags via OS::something???
|
||||
@@ -618,13 +626,14 @@ SyscallReturn
|
||||
fchmodFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||
ThreadContext *tc)
|
||||
{
|
||||
int fd = process->getSyscallArg(tc, 0);
|
||||
int index = 0;
|
||||
int fd = process->getSyscallArg(tc, index);
|
||||
if (fd < 0 || process->sim_fd(fd) < 0) {
|
||||
// doesn't map to any simulator fd: not a valid target fd
|
||||
return -EBADF;
|
||||
}
|
||||
|
||||
uint32_t mode = process->getSyscallArg(tc, 1);
|
||||
uint32_t mode = process->getSyscallArg(tc, index);
|
||||
mode_t hostMode = 0;
|
||||
|
||||
// XXX translate mode flags via OS::someting???
|
||||
@@ -643,10 +652,11 @@ template <class OS>
|
||||
SyscallReturn
|
||||
mremapFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc)
|
||||
{
|
||||
Addr start = process->getSyscallArg(tc, 0);
|
||||
uint64_t old_length = process->getSyscallArg(tc, 1);
|
||||
uint64_t new_length = process->getSyscallArg(tc, 2);
|
||||
uint64_t flags = process->getSyscallArg(tc, 3);
|
||||
int index = 0;
|
||||
Addr start = process->getSyscallArg(tc, index);
|
||||
uint64_t old_length = process->getSyscallArg(tc, index);
|
||||
uint64_t new_length = process->getSyscallArg(tc, index);
|
||||
uint64_t flags = process->getSyscallArg(tc, index);
|
||||
|
||||
if ((start % TheISA::VMPageSize != 0) ||
|
||||
(new_length % TheISA::VMPageSize != 0)) {
|
||||
@@ -692,8 +702,12 @@ statFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||
{
|
||||
std::string path;
|
||||
|
||||
if (!tc->getMemPort()->tryReadString(path, process->getSyscallArg(tc, 0)))
|
||||
return -EFAULT;
|
||||
int index = 0;
|
||||
if (!tc->getMemPort()->tryReadString(path,
|
||||
process->getSyscallArg(tc, index))) {
|
||||
return -EFAULT;
|
||||
}
|
||||
Addr bufPtr = process->getSyscallArg(tc, index);
|
||||
|
||||
// Adjust path for current working directory
|
||||
path = process->fullPath(path);
|
||||
@@ -704,8 +718,7 @@ statFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||
if (result < 0)
|
||||
return -errno;
|
||||
|
||||
copyOutStatBuf<OS>(tc->getMemPort(), process->getSyscallArg(tc, 1),
|
||||
&hostBuf);
|
||||
copyOutStatBuf<OS>(tc->getMemPort(), bufPtr, &hostBuf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -719,8 +732,11 @@ stat64Func(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||
{
|
||||
std::string path;
|
||||
|
||||
if (!tc->getMemPort()->tryReadString(path, process->getSyscallArg(tc, 0)))
|
||||
int index = 0;
|
||||
if (!tc->getMemPort()->tryReadString(path,
|
||||
process->getSyscallArg(tc, index)))
|
||||
return -EFAULT;
|
||||
Addr bufPtr = process->getSyscallArg(tc, index);
|
||||
|
||||
// Adjust path for current working directory
|
||||
path = process->fullPath(path);
|
||||
@@ -736,8 +752,7 @@ stat64Func(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||
if (result < 0)
|
||||
return -errno;
|
||||
|
||||
copyOutStat64Buf<OS>(tc->getMemPort(), process->getSyscallArg(tc, 1),
|
||||
&hostBuf);
|
||||
copyOutStat64Buf<OS>(tc->getMemPort(), bufPtr, &hostBuf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -749,7 +764,9 @@ SyscallReturn
|
||||
fstat64Func(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||
ThreadContext *tc)
|
||||
{
|
||||
int fd = process->getSyscallArg(tc, 0);
|
||||
int index = 0;
|
||||
int fd = process->getSyscallArg(tc, index);
|
||||
Addr bufPtr = process->getSyscallArg(tc, index);
|
||||
if (fd < 0 || process->sim_fd(fd) < 0) {
|
||||
// doesn't map to any simulator fd: not a valid target fd
|
||||
return -EBADF;
|
||||
@@ -766,8 +783,7 @@ fstat64Func(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||
if (result < 0)
|
||||
return -errno;
|
||||
|
||||
copyOutStat64Buf<OS>(tc->getMemPort(), process->getSyscallArg(tc, 1),
|
||||
&hostBuf, (fd == 1));
|
||||
copyOutStat64Buf<OS>(tc->getMemPort(), bufPtr, &hostBuf, (fd == 1));
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -781,8 +797,12 @@ lstatFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||
{
|
||||
std::string path;
|
||||
|
||||
if (!tc->getMemPort()->tryReadString(path, process->getSyscallArg(tc, 0)))
|
||||
return -EFAULT;
|
||||
int index = 0;
|
||||
if (!tc->getMemPort()->tryReadString(path,
|
||||
process->getSyscallArg(tc, index))) {
|
||||
return -EFAULT;
|
||||
}
|
||||
Addr bufPtr = process->getSyscallArg(tc, index);
|
||||
|
||||
// Adjust path for current working directory
|
||||
path = process->fullPath(path);
|
||||
@@ -793,8 +813,7 @@ lstatFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||
if (result < 0)
|
||||
return -errno;
|
||||
|
||||
copyOutStatBuf<OS>(tc->getMemPort(), process->getSyscallArg(tc, 1),
|
||||
&hostBuf);
|
||||
copyOutStatBuf<OS>(tc->getMemPort(), bufPtr, &hostBuf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -807,8 +826,12 @@ lstat64Func(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||
{
|
||||
std::string path;
|
||||
|
||||
if (!tc->getMemPort()->tryReadString(path, process->getSyscallArg(tc, 0)))
|
||||
return -EFAULT;
|
||||
int index = 0;
|
||||
if (!tc->getMemPort()->tryReadString(path,
|
||||
process->getSyscallArg(tc, index))) {
|
||||
return -EFAULT;
|
||||
}
|
||||
Addr bufPtr = process->getSyscallArg(tc, index);
|
||||
|
||||
// Adjust path for current working directory
|
||||
path = process->fullPath(path);
|
||||
@@ -824,8 +847,7 @@ lstat64Func(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||
if (result < 0)
|
||||
return -errno;
|
||||
|
||||
copyOutStat64Buf<OS>(tc->getMemPort(), process->getSyscallArg(tc, 1),
|
||||
&hostBuf);
|
||||
copyOutStat64Buf<OS>(tc->getMemPort(), bufPtr, &hostBuf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -836,7 +858,9 @@ SyscallReturn
|
||||
fstatFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||
ThreadContext *tc)
|
||||
{
|
||||
int fd = process->sim_fd(process->getSyscallArg(tc, 0));
|
||||
int index = 0;
|
||||
int fd = process->sim_fd(process->getSyscallArg(tc, index));
|
||||
Addr bufPtr = process->getSyscallArg(tc, index);
|
||||
|
||||
DPRINTF(SyscallVerbose, "fstat(%d, ...)\n", fd);
|
||||
|
||||
@@ -849,8 +873,7 @@ fstatFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||
if (result < 0)
|
||||
return -errno;
|
||||
|
||||
copyOutStatBuf<OS>(tc->getMemPort(), process->getSyscallArg(tc, 1),
|
||||
&hostBuf, (fd == 1));
|
||||
copyOutStatBuf<OS>(tc->getMemPort(), bufPtr, &hostBuf, (fd == 1));
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -864,8 +887,12 @@ statfsFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||
{
|
||||
std::string path;
|
||||
|
||||
if (!tc->getMemPort()->tryReadString(path, process->getSyscallArg(tc, 0)))
|
||||
return -EFAULT;
|
||||
int index = 0;
|
||||
if (!tc->getMemPort()->tryReadString(path,
|
||||
process->getSyscallArg(tc, index))) {
|
||||
return -EFAULT;
|
||||
}
|
||||
Addr bufPtr = process->getSyscallArg(tc, index);
|
||||
|
||||
// Adjust path for current working directory
|
||||
path = process->fullPath(path);
|
||||
@@ -876,8 +903,7 @@ statfsFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||
if (result < 0)
|
||||
return -errno;
|
||||
|
||||
OS::copyOutStatfsBuf(tc->getMemPort(),
|
||||
(Addr)(process->getSyscallArg(tc, 1)), &hostBuf);
|
||||
OS::copyOutStatfsBuf(tc->getMemPort(), bufPtr, &hostBuf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -889,7 +915,9 @@ SyscallReturn
|
||||
fstatfsFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||
ThreadContext *tc)
|
||||
{
|
||||
int fd = process->sim_fd(process->getSyscallArg(tc, 0));
|
||||
int index = 0;
|
||||
int fd = process->sim_fd(process->getSyscallArg(tc, index));
|
||||
Addr bufPtr = process->getSyscallArg(tc, index);
|
||||
|
||||
if (fd < 0)
|
||||
return -EBADF;
|
||||
@@ -900,8 +928,7 @@ fstatfsFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||
if (result < 0)
|
||||
return -errno;
|
||||
|
||||
OS::copyOutStatfsBuf(tc->getMemPort(), process->getSyscallArg(tc, 1),
|
||||
&hostBuf);
|
||||
OS::copyOutStatfsBuf(tc->getMemPort(), bufPtr, &hostBuf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -913,15 +940,16 @@ SyscallReturn
|
||||
writevFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||
ThreadContext *tc)
|
||||
{
|
||||
int fd = process->getSyscallArg(tc, 0);
|
||||
int index = 0;
|
||||
int fd = process->getSyscallArg(tc, index);
|
||||
if (fd < 0 || process->sim_fd(fd) < 0) {
|
||||
// doesn't map to any simulator fd: not a valid target fd
|
||||
return -EBADF;
|
||||
}
|
||||
|
||||
TranslatingPort *p = tc->getMemPort();
|
||||
uint64_t tiov_base = process->getSyscallArg(tc, 1);
|
||||
size_t count = process->getSyscallArg(tc, 2);
|
||||
uint64_t tiov_base = process->getSyscallArg(tc, index);
|
||||
size_t count = process->getSyscallArg(tc, index);
|
||||
struct iovec hiov[count];
|
||||
for (size_t i = 0; i < count; ++i) {
|
||||
typename OS::tgt_iovec tiov;
|
||||
@@ -962,12 +990,13 @@ template <class OS>
|
||||
SyscallReturn
|
||||
mmapFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
|
||||
{
|
||||
Addr start = p->getSyscallArg(tc, 0);
|
||||
uint64_t length = p->getSyscallArg(tc, 1);
|
||||
// int prot = p->getSyscallArg(tc, 2);
|
||||
int flags = p->getSyscallArg(tc, 3);
|
||||
// int fd = p->sim_fd(p->getSyscallArg(tc, 4));
|
||||
// int offset = p->getSyscallArg(tc, 5);
|
||||
int index = 0;
|
||||
Addr start = p->getSyscallArg(tc, index);
|
||||
uint64_t length = p->getSyscallArg(tc, index);
|
||||
index++; // int prot = p->getSyscallArg(tc, index);
|
||||
int flags = p->getSyscallArg(tc, index);
|
||||
int fd = p->sim_fd(p->getSyscallArg(tc, index));
|
||||
// int offset = p->getSyscallArg(tc, index);
|
||||
|
||||
|
||||
if ((start % TheISA::VMPageSize) != 0 ||
|
||||
@@ -995,7 +1024,7 @@ mmapFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
|
||||
|
||||
if (!(flags & OS::TGT_MAP_ANONYMOUS)) {
|
||||
warn("allowing mmap of file @ fd %d. "
|
||||
"This will break if not /dev/zero.", p->getSyscallArg(tc, 4));
|
||||
"This will break if not /dev/zero.", fd);
|
||||
}
|
||||
|
||||
return start;
|
||||
@@ -1007,8 +1036,9 @@ SyscallReturn
|
||||
getrlimitFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||
ThreadContext *tc)
|
||||
{
|
||||
unsigned resource = process->getSyscallArg(tc, 0);
|
||||
TypedBufferArg<typename OS::rlimit> rlp(process->getSyscallArg(tc, 1));
|
||||
int index = 0;
|
||||
unsigned resource = process->getSyscallArg(tc, index);
|
||||
TypedBufferArg<typename OS::rlimit> rlp(process->getSyscallArg(tc, index));
|
||||
|
||||
switch (resource) {
|
||||
case OS::TGT_RLIMIT_STACK:
|
||||
@@ -1042,7 +1072,8 @@ SyscallReturn
|
||||
gettimeofdayFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||
ThreadContext *tc)
|
||||
{
|
||||
TypedBufferArg<typename OS::timeval> tp(process->getSyscallArg(tc, 0));
|
||||
int index = 0;
|
||||
TypedBufferArg<typename OS::timeval> tp(process->getSyscallArg(tc, index));
|
||||
|
||||
getElapsedTime(tp->tv_sec, tp->tv_usec);
|
||||
tp->tv_sec += seconds_since_epoch;
|
||||
@@ -1063,10 +1094,14 @@ utimesFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||
{
|
||||
std::string path;
|
||||
|
||||
if (!tc->getMemPort()->tryReadString(path, process->getSyscallArg(tc, 0)))
|
||||
return -EFAULT;
|
||||
int index = 0;
|
||||
if (!tc->getMemPort()->tryReadString(path,
|
||||
process->getSyscallArg(tc, index))) {
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
TypedBufferArg<typename OS::timeval [2]> tp(process->getSyscallArg(tc, 1));
|
||||
TypedBufferArg<typename OS::timeval [2]>
|
||||
tp(process->getSyscallArg(tc, index));
|
||||
tp.copyIn(tc->getMemPort());
|
||||
|
||||
struct timeval hostTimeval[2];
|
||||
@@ -1092,8 +1127,9 @@ SyscallReturn
|
||||
getrusageFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||
ThreadContext *tc)
|
||||
{
|
||||
int who = process->getSyscallArg(tc, 0); // THREAD, SELF, or CHILDREN
|
||||
TypedBufferArg<typename OS::rusage> rup(process->getSyscallArg(tc, 1));
|
||||
int index = 0;
|
||||
int who = process->getSyscallArg(tc, index); // THREAD, SELF, or CHILDREN
|
||||
TypedBufferArg<typename OS::rusage> rup(process->getSyscallArg(tc, index));
|
||||
|
||||
rup->ru_utime.tv_sec = 0;
|
||||
rup->ru_utime.tv_usec = 0;
|
||||
@@ -1143,7 +1179,8 @@ SyscallReturn
|
||||
timesFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||
ThreadContext *tc)
|
||||
{
|
||||
TypedBufferArg<typename OS::tms> bufp(process->getSyscallArg(tc, 0));
|
||||
int index = 0;
|
||||
TypedBufferArg<typename OS::tms> bufp(process->getSyscallArg(tc, index));
|
||||
|
||||
// Fill in the time structure (in clocks)
|
||||
int64_t clocks = curTick * OS::_SC_CLK_TCK / Clock::Int::s;
|
||||
@@ -1172,7 +1209,8 @@ timeFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||
getElapsedTime(sec, usec);
|
||||
sec += seconds_since_epoch;
|
||||
|
||||
Addr taddr = (Addr)process->getSyscallArg(tc, 0);
|
||||
int index = 0;
|
||||
Addr taddr = (Addr)process->getSyscallArg(tc, index);
|
||||
if(taddr != 0) {
|
||||
typename OS::time_t t = sec;
|
||||
t = htog(t);
|
||||
|
||||
Reference in New Issue
Block a user