sim: Add openat/fstatat syscalls and fix mremap

This patch adds support for the openat and fstatat syscalls and
broadens the support for mremap to make it work on OS X.
This commit is contained in:
Chris Adeniyi-Jones 2014-01-24 15:29:30 -06:00
parent 904872a01a
commit 7f835a59f1
2 changed files with 111 additions and 18 deletions

View file

@ -227,6 +227,12 @@ class Linux : public OperatingSystem
static const unsigned TGT_EWOULDBLOCK = TGT_EAGAIN;
static const unsigned TGT_FUTEX_PRIVATE_FLAG = 128;
// for *at syscalls
static const int TGT_AT_FDCWD = -100;
// for MREMAP
static const unsigned TGT_MREMAP_MAYMOVE = 0x1;
static const unsigned TGT_MREMAP_FIXED = 0x2;
}; // class Linux
#endif // __LINUX_HH__

View file

@ -1,4 +1,16 @@
/*
* Copyright (c) 2012-2013 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
* not be construed as granting a license to any other intellectual
* property including but not limited to intellectual property relating
* to a hardware implementation of the functionality of the software
* licensed hereunder. You may use the software subject to the license
* terms below provided that you ensure that this notice is replicated
* unmodified and in its entirety in all distributions of the software,
* modified or unmodified, in source code or in binary form.
*
* Copyright (c) 2003-2005 The Regents of The University of Michigan
* All rights reserved.
*
@ -600,15 +612,13 @@ ioctlFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
return -ENOTTY;
}
/// Target open() handler.
template <class OS>
SyscallReturn
static SyscallReturn
openFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
ThreadContext *tc)
ThreadContext *tc, int index)
{
std::string path;
int index = 0;
if (!tc->getMemProxy().tryReadString(path,
process->getSyscallArg(tc, index)))
return -EFAULT;
@ -664,6 +674,28 @@ openFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
return process->alloc_fd(fd, path.c_str(), hostFlags, mode, false);
}
/// Target open() handler.
template <class OS>
SyscallReturn
openFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
ThreadContext *tc)
{
return openFunc<OS>(desc, callnum, process, tc, 0);
}
/// Target openat() handler.
template <class OS>
SyscallReturn
openatFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
ThreadContext *tc)
{
int index = 0;
int dirfd = process->getSyscallArg(tc, index);
if (dirfd != OS::TGT_AT_FDCWD)
warn("openat: first argument not AT_FDCWD; unlikely to work");
return openFunc<OS>(desc, callnum, process, tc, 1);
}
/// Target sysinfo() handler.
template <class OS>
SyscallReturn
@ -752,40 +784,58 @@ mremapFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *
uint64_t old_length = process->getSyscallArg(tc, index);
uint64_t new_length = process->getSyscallArg(tc, index);
uint64_t flags = process->getSyscallArg(tc, index);
uint64_t provided_address = 0;
bool use_provided_address = flags & OS::TGT_MREMAP_FIXED;
if (use_provided_address)
provided_address = process->getSyscallArg(tc, index);
if ((start % TheISA::VMPageSize != 0) ||
(new_length % TheISA::VMPageSize != 0)) {
(new_length % TheISA::VMPageSize != 0) ||
(provided_address % TheISA::VMPageSize != 0)) {
warn("mremap failing: arguments not page aligned");
return -EINVAL;
}
if (new_length > old_length) {
if ((start + old_length) == process->mmap_end) {
if ((start + old_length) == process->mmap_end &&
(!use_provided_address || provided_address == start)) {
uint64_t diff = new_length - old_length;
process->allocateMem(process->mmap_end, diff);
process->mmap_end += diff;
return start;
} else {
// sys/mman.h defined MREMAP_MAYMOVE
if (!(flags & 1)) {
if (!use_provided_address && !(flags & OS::TGT_MREMAP_MAYMOVE)) {
warn("can't remap here and MREMAP_MAYMOVE flag not set\n");
return -ENOMEM;
} else {
process->pTable->remap(start, old_length, process->mmap_end);
warn("mremapping to totally new vaddr %08p-%08p, adding %d\n",
process->mmap_end, process->mmap_end + new_length, new_length);
start = process->mmap_end;
uint64_t new_start = use_provided_address ?
provided_address : process->mmap_end;
process->pTable->remap(start, old_length, new_start);
warn("mremapping to new vaddr %08p-%08p, adding %d\n",
new_start, new_start + new_length,
new_length - old_length);
// add on the remaining unallocated pages
process->allocateMem(start + old_length,
new_length - old_length);
process->mmap_end += new_length;
warn("returning %08p as start\n", start);
return start;
process->allocateMem(new_start + old_length,
new_length - old_length,
use_provided_address /* clobber */);
if (!use_provided_address)
process->mmap_end += new_length;
if (use_provided_address &&
new_start + new_length > process->mmap_end) {
// something fishy going on here, at least notify the user
// @todo: increase mmap_end?
warn("mmap region limit exceeded with MREMAP_FIXED\n");
}
warn("returning %08p as start\n", new_start);
return new_start;
}
}
} else {
if (use_provided_address && provided_address != start)
process->pTable->remap(start, new_length, provided_address);
process->pTable->unmap(start + new_length, old_length - new_length);
return start;
return use_provided_address ? provided_address : start;
}
}
@ -853,6 +903,43 @@ stat64Func(SyscallDesc *desc, int callnum, LiveProcess *process,
}
/// Target fstatat64() handler.
template <class OS>
SyscallReturn
fstatat64Func(SyscallDesc *desc, int callnum, LiveProcess *process,
ThreadContext *tc)
{
int index = 0;
int dirfd = process->getSyscallArg(tc, index);
if (dirfd != OS::TGT_AT_FDCWD)
warn("openat: first argument not AT_FDCWD; unlikely to work");
std::string path;
if (!tc->getMemProxy().tryReadString(path,
process->getSyscallArg(tc, index)))
return -EFAULT;
Addr bufPtr = process->getSyscallArg(tc, index);
// Adjust path for current working directory
path = process->fullPath(path);
#if NO_STAT64
struct stat hostBuf;
int result = stat(path.c_str(), &hostBuf);
#else
struct stat64 hostBuf;
int result = stat64(path.c_str(), &hostBuf);
#endif
if (result < 0)
return -errno;
copyOutStat64Buf<OS>(tc->getMemProxy(), bufPtr, &hostBuf);
return 0;
}
/// Target fstat64() handler.
template <class OS>
SyscallReturn