syscall emul: fix Power Linux mmap constant, plus other cleanup

We were getting a spurious warning in the regressions that turned
out to be due to having the wrong value for TGT_MAP_ANONYMOUS for
Power Linux, but in the process of tracking it down I ended up
doing some cleanup of the mmap handling in general.
This commit is contained in:
Steve Reinhardt 2011-05-23 14:29:23 -07:00
parent 19bb896bfe
commit 8d29bda742
3 changed files with 22 additions and 17 deletions

View file

@ -126,7 +126,7 @@ class PowerLinux : public Linux
//@}
/// For mmap().
static const unsigned TGT_MAP_ANONYMOUS = 0x800;
static const unsigned TGT_MAP_ANONYMOUS = 0x20;
//@{
/// ioctl() command codes.

View file

@ -313,7 +313,7 @@ Process::free_fd(int tgt_fd)
int
Process::sim_fd(int tgt_fd)
{
if (tgt_fd > MAX_FD)
if (tgt_fd < 0 || tgt_fd > MAX_FD)
return -1;
return fd_map[tgt_fd].fd;
@ -322,8 +322,8 @@ Process::sim_fd(int tgt_fd)
Process::FdMap *
Process::sim_fd_obj(int tgt_fd)
{
if (tgt_fd > MAX_FD)
panic("sim_fd_obj called in fd out of range.");
if (tgt_fd < 0 || tgt_fd > MAX_FD)
return NULL;
return &fd_map[tgt_fd];
}

View file

@ -989,13 +989,8 @@ writevFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
/// We don't really handle mmap(). If the target is mmaping an
/// anonymous region or /dev/zero, we can get away with doing basically
/// nothing (since memory is initialized to zero and the simulator
/// doesn't really check addresses anyway). Always print a warning,
/// since this could be seriously broken if we're not mapping
/// /dev/zero.
//
/// Someday we should explicitly check for /dev/zero in open, flag the
/// file descriptor, and fail (or implement!) a non-anonymous mmap to
/// anything else.
/// doesn't really check addresses anyway).
///
template <class OS>
SyscallReturn
mmapFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
@ -1005,9 +1000,24 @@ mmapFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
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 tgt_fd = p->getSyscallArg(tc, index);
// int offset = p->getSyscallArg(tc, index);
if (!(flags & OS::TGT_MAP_ANONYMOUS)) {
Process::FdMap *fd_map = p->sim_fd_obj(tgt_fd);
if (!fd_map || fd_map->fd < 0) {
warn("mmap failing: target fd %d is not valid\n", tgt_fd);
return -EBADF;
}
if (fd_map->filename != "/dev/zero") {
// This is very likely broken, but leave a warning here
// (rather than panic) in case /dev/zero is known by
// another name on some platform
warn("allowing mmap of file %s; mmap not supported on files"
" other than /dev/zero\n", fd_map->filename);
}
}
if ((start % TheISA::VMPageSize) != 0 ||
(length % TheISA::VMPageSize) != 0) {
@ -1032,11 +1042,6 @@ mmapFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
}
p->pTable->allocate(start, length);
if (!(flags & OS::TGT_MAP_ANONYMOUS)) {
warn("allowing mmap of file @ fd %d. "
"This will break if not /dev/zero.", fd);
}
return start;
}