diff options
author | Steve Reinhardt <steve.reinhardt@amd.com> | 2011-10-22 22:30:07 -0700 |
---|---|---|
committer | Steve Reinhardt <steve.reinhardt@amd.com> | 2011-10-22 22:30:07 -0700 |
commit | 4d5f2c28a88f83d390e80407f55a8a02ead33878 (patch) | |
tree | 59f8aca2bd6995a396aade765156272998fc8bbf /src/sim | |
parent | c6dd122feef8cfb4785b8d45f40907bd6c73e04a (diff) | |
download | gem5-4d5f2c28a88f83d390e80407f55a8a02ead33878.tar.xz |
syscall_emul: implement MAP_FIXED option to mmap()
Diffstat (limited to 'src/sim')
-rw-r--r-- | src/sim/syscall_emul.hh | 47 |
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; } |