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 /src/sim | |
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.
Diffstat (limited to 'src/sim')
-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); + } + } } } |