summaryrefslogtreecommitdiff
path: root/src/sim
diff options
context:
space:
mode:
Diffstat (limited to 'src/sim')
-rw-r--r--src/sim/process.cc6
-rw-r--r--src/sim/syscall_emul.hh31
2 files changed, 21 insertions, 16 deletions
diff --git a/src/sim/process.cc b/src/sim/process.cc
index 9a9527664..28142d731 100644
--- a/src/sim/process.cc
+++ b/src/sim/process.cc
@@ -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];
}
diff --git a/src/sim/syscall_emul.hh b/src/sim/syscall_emul.hh
index e685a0f30..d119adc24 100644
--- a/src/sim/syscall_emul.hh
+++ b/src/sim/syscall_emul.hh
@@ -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;
}