summaryrefslogtreecommitdiff
path: root/src/sim/syscall_emul.hh
diff options
context:
space:
mode:
authorSteve Reinhardt <steve.reinhardt@amd.com>2011-10-22 22:30:07 -0700
committerSteve Reinhardt <steve.reinhardt@amd.com>2011-10-22 22:30:07 -0700
commit4d5f2c28a88f83d390e80407f55a8a02ead33878 (patch)
tree59f8aca2bd6995a396aade765156272998fc8bbf /src/sim/syscall_emul.hh
parentc6dd122feef8cfb4785b8d45f40907bd6c73e04a (diff)
downloadgem5-4d5f2c28a88f83d390e80407f55a8a02ead33878.tar.xz
syscall_emul: implement MAP_FIXED option to mmap()
Diffstat (limited to 'src/sim/syscall_emul.hh')
-rw-r--r--src/sim/syscall_emul.hh47
1 files changed, 36 insertions, 11 deletions
diff --git a/src/sim/syscall_emul.hh b/src/sim/syscall_emul.hh
index d119adc24..9bcf58844 100644
--- a/src/sim/syscall_emul.hh
+++ b/src/sim/syscall_emul.hh
@@ -1027,20 +1027,45 @@ mmapFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
return -EINVAL;
}
- if (start != 0) {
- warn("mmap: ignoring suggested map address 0x%x, using 0x%x",
- start, p->mmap_end);
+ // are we ok with clobbering existing mappings? only set this to
+ // true if the user has been warned.
+ bool clobber = false;
+
+ // try to use the caller-provided address if there is one
+ bool use_provided_address = (start != 0);
+
+ if (use_provided_address) {
+ // check to see if the desired address is already in use
+ if (!p->pTable->isUnmapped(start, length)) {
+ // there are existing mappings in the desired range
+ // whether we clobber them or not depends on whether the caller
+ // specified MAP_FIXED
+ if (flags & OS::TGT_MAP_FIXED) {
+ // MAP_FIXED specified: clobber existing mappings
+ warn("mmap: MAP_FIXED at 0x%x overwrites existing mappings\n",
+ start);
+ clobber = true;
+ } else {
+ // MAP_FIXED not specified: ignore suggested start address
+ warn("mmap: ignoring suggested map address 0x%x\n", start);
+ use_provided_address = false;
+ }
+ }
}
- // pick next address from our "mmap region"
- if (OS::mmapGrowsDown()) {
- start = p->mmap_end - length;
- p->mmap_end = start;
- } else {
- start = p->mmap_end;
- p->mmap_end += length;
+ if (!use_provided_address) {
+ // no address provided, or provided address unusable:
+ // pick next address from our "mmap region"
+ if (OS::mmapGrowsDown()) {
+ start = p->mmap_end - length;
+ p->mmap_end = start;
+ } else {
+ start = p->mmap_end;
+ p->mmap_end += length;
+ }
}
- p->pTable->allocate(start, length);
+
+ p->pTable->allocate(start, length, clobber);
return start;
}