diff options
author | Timothy M. Jones <tjones1@inf.ed.ac.uk> | 2009-10-24 10:53:58 -0700 |
---|---|---|
committer | Timothy M. Jones <tjones1@inf.ed.ac.uk> | 2009-10-24 10:53:58 -0700 |
commit | 03da1e53c24aa86a3b04216c3d2d002fd9020ea0 (patch) | |
tree | 8b562fe53646a789df61bf514669a1b60bd08777 | |
parent | cc21f862e2d6ad6ba8d5332d6bbc05e58e55bfa0 (diff) | |
download | gem5-03da1e53c24aa86a3b04216c3d2d002fd9020ea0.tar.xz |
syscall: Zero out memory that already exists during the brk system call.
Glibc often assumes that memory it receives from the kernel after a brk
system call will contain only zeros. This is important during a calloc,
because it won't clear the new memory itself. In the simulator, if the
new page exists, it will be cleared using this patch, to mimic the kernel's
functionality.
-rw-r--r-- | src/sim/syscall_emul.cc | 18 |
1 files changed, 18 insertions, 0 deletions
diff --git a/src/sim/syscall_emul.cc b/src/sim/syscall_emul.cc index 9a797bcdb..13ad04311 100644 --- a/src/sim/syscall_emul.cc +++ b/src/sim/syscall_emul.cc @@ -144,6 +144,24 @@ brkFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) if (!p->pTable->translate(gen.addr())) p->pTable->allocate(roundDown(gen.addr(), VMPageSize), VMPageSize); + + // if the address is already there, zero it out + else { + uint8_t zero = 0; + TranslatingPort *tp = tc->getMemPort(); + + // split non-page aligned accesses + Addr next_page = roundUp(gen.addr(), VMPageSize); + uint32_t size_needed = next_page - gen.addr(); + tp->memsetBlob(gen.addr(), zero, size_needed); + if (gen.addr() + VMPageSize > next_page && + next_page < new_brk && + p->pTable->translate(next_page)) + { + size_needed = VMPageSize - size_needed; + tp->memsetBlob(next_page, zero, size_needed); + } + } } } |