diff options
Diffstat (limited to 'src/sim')
-rw-r--r-- | src/sim/syscall_emul.hh | 20 |
1 files changed, 15 insertions, 5 deletions
diff --git a/src/sim/syscall_emul.hh b/src/sim/syscall_emul.hh index 7efd7c7e6..fa0959f0e 100644 --- a/src/sim/syscall_emul.hh +++ b/src/sim/syscall_emul.hh @@ -932,6 +932,8 @@ mremapFunc(SyscallDesc *desc, int callnum, Process *process, ThreadContext *tc) if ((start + old_length) == mmap_end && (!use_provided_address || provided_address == start)) { + // This case cannot occur when growing downward, as + // start is greater than or equal to mmap_end. uint64_t diff = new_length - old_length; process->allocateMem(mmap_end, diff); mem_state->setMmapEnd(mmap_end + diff); @@ -941,8 +943,15 @@ mremapFunc(SyscallDesc *desc, int callnum, Process *process, ThreadContext *tc) warn("can't remap here and MREMAP_MAYMOVE flag not set\n"); return -ENOMEM; } else { - uint64_t new_start = use_provided_address ? - provided_address : mmap_end; + uint64_t new_start = provided_address; + if (!use_provided_address) { + new_start = process->mmapGrowsDown() ? + mmap_end - new_length : mmap_end; + mmap_end = process->mmapGrowsDown() ? + new_start : mmap_end + new_length; + mem_state->setMmapEnd(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, @@ -951,10 +960,11 @@ mremapFunc(SyscallDesc *desc, int callnum, Process *process, ThreadContext *tc) process->allocateMem(new_start + old_length, new_length - old_length, use_provided_address /* clobber */); - if (!use_provided_address) - mem_state->setMmapEnd(mmap_end + new_length); if (use_provided_address && - new_start + new_length > mem_state->getMmapEnd()) { + ((new_start + new_length > mem_state->getMmapEnd() && + !process->mmapGrowsDown()) || + (new_start < mem_state->getMmapEnd() && + process->mmapGrowsDown()))) { // something fishy going on here, at least notify the user // @todo: increase mmap_end? warn("mmap region limit exceeded with MREMAP_FIXED\n"); |