From 4514f565e3dfe1de41bbaec05f3f0074e5299bac Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Sat, 15 Nov 2008 09:30:10 -0800 Subject: [PATCH] syscalls: fix latent brk/obreak bug. Bogus calls to ChunkGenerator with negative size were triggering a new assertion that was added there. Also did a little renaming and cleanup in the process. --- src/arch/alpha/linux/process.cc | 2 +- src/arch/alpha/tru64/process.cc | 2 +- src/arch/mips/linux/process.cc | 4 ++-- src/arch/sparc/linux/syscalls.cc | 4 ++-- src/arch/sparc/solaris/process.cc | 2 +- src/arch/x86/linux/syscalls.cc | 2 +- src/mem/page_table.hh | 10 +++++++++- src/sim/syscall_emul.cc | 18 ++++++++++++------ src/sim/syscall_emul.hh | 6 +++--- 9 files changed, 32 insertions(+), 18 deletions(-) diff --git a/src/arch/alpha/linux/process.cc b/src/arch/alpha/linux/process.cc index 9527759ed..efcd6623e 100644 --- a/src/arch/alpha/linux/process.cc +++ b/src/arch/alpha/linux/process.cc @@ -136,7 +136,7 @@ SyscallDesc AlphaLinuxProcess::syscallDescs[] = { /* 14 */ SyscallDesc("mknod", unimplementedFunc), /* 15 */ SyscallDesc("chmod", chmodFunc), /* 16 */ SyscallDesc("chown", chownFunc), - /* 17 */ SyscallDesc("brk", obreakFunc), + /* 17 */ SyscallDesc("brk", brkFunc), /* 18 */ SyscallDesc("osf_getfsstat", unimplementedFunc), /* 19 */ SyscallDesc("lseek", lseekFunc), /* 20 */ SyscallDesc("getxpid", getpidPseudoFunc), diff --git a/src/arch/alpha/tru64/process.cc b/src/arch/alpha/tru64/process.cc index 645cc6cf9..b84dfb286 100644 --- a/src/arch/alpha/tru64/process.cc +++ b/src/arch/alpha/tru64/process.cc @@ -215,7 +215,7 @@ SyscallDesc AlphaTru64Process::syscallDescs[] = { /* 14 */ SyscallDesc("mknod", unimplementedFunc), /* 15 */ SyscallDesc("chmod", unimplementedFunc), /* 16 */ SyscallDesc("chown", unimplementedFunc), - /* 17 */ SyscallDesc("obreak", obreakFunc), + /* 17 */ SyscallDesc("obreak", brkFunc), /* 18 */ SyscallDesc("pre_F64_getfsstat", unimplementedFunc), /* 19 */ SyscallDesc("lseek", lseekFunc), /* 20 */ SyscallDesc("getpid", getpidPseudoFunc), diff --git a/src/arch/mips/linux/process.cc b/src/arch/mips/linux/process.cc index 8a13d0f18..56413484b 100644 --- a/src/arch/mips/linux/process.cc +++ b/src/arch/mips/linux/process.cc @@ -138,7 +138,7 @@ SyscallDesc MipsLinuxProcess::syscallDescs[] = { /* 14 */ SyscallDesc("mknod", unimplementedFunc), /* 15 */ SyscallDesc("chmod", chmodFunc), /* 16 */ SyscallDesc("lchown", chownFunc), - /* 17 */ SyscallDesc("break", obreakFunc), + /* 17 */ SyscallDesc("break", brkFunc), /* 18 */ SyscallDesc("unused#18", unimplementedFunc), /* 19 */ SyscallDesc("lseek", lseekFunc), /* 20 */ SyscallDesc("getpid", getpidFunc), @@ -166,7 +166,7 @@ SyscallDesc MipsLinuxProcess::syscallDescs[] = { /* 42 */ SyscallDesc("pipe", pipePseudoFunc), /* 43 */ SyscallDesc("times", unimplementedFunc), /* 44 */ SyscallDesc("prof", unimplementedFunc), - /* 45 */ SyscallDesc("brk", obreakFunc), + /* 45 */ SyscallDesc("brk", brkFunc), /* 46 */ SyscallDesc("setgid", unimplementedFunc), /* 47 */ SyscallDesc("getgid", getgidFunc), /* 48 */ SyscallDesc("signal", ignoreFunc), diff --git a/src/arch/sparc/linux/syscalls.cc b/src/arch/sparc/linux/syscalls.cc index 2964b3c1a..2845f7bec 100644 --- a/src/arch/sparc/linux/syscalls.cc +++ b/src/arch/sparc/linux/syscalls.cc @@ -106,7 +106,7 @@ SyscallDesc SparcLinuxProcess::syscall32Descs[] = { /* 14 */ SyscallDesc("mknod", unimplementedFunc), /* 15 */ SyscallDesc("chmod", unimplementedFunc), /* 16 */ SyscallDesc("lchown", unimplementedFunc), //32 bit - /* 17 */ SyscallDesc("brk", obreakFunc), + /* 17 */ SyscallDesc("brk", brkFunc), /* 18 */ SyscallDesc("perfctr", unimplementedFunc), //32 bit /* 19 */ SyscallDesc("lseek", lseekFunc), //32 bit /* 20 */ SyscallDesc("getpid", getpidFunc), @@ -409,7 +409,7 @@ SyscallDesc SparcLinuxProcess::syscallDescs[] = { /* 14 */ SyscallDesc("mknod", unimplementedFunc), /* 15 */ SyscallDesc("chmod", chmodFunc), /* 16 */ SyscallDesc("lchown", unimplementedFunc), - /* 17 */ SyscallDesc("brk", obreakFunc), + /* 17 */ SyscallDesc("brk", brkFunc), /* 18 */ SyscallDesc("perfctr", unimplementedFunc), /* 19 */ SyscallDesc("lseek", lseekFunc), /* 20 */ SyscallDesc("getpid", getpidFunc), diff --git a/src/arch/sparc/solaris/process.cc b/src/arch/sparc/solaris/process.cc index e0c3eaa4b..e4f6b23c8 100644 --- a/src/arch/sparc/solaris/process.cc +++ b/src/arch/sparc/solaris/process.cc @@ -80,7 +80,7 @@ SyscallDesc SparcSolarisProcess::syscallDescs[] = { /* 14 */ SyscallDesc("mknod", unimplementedFunc), /* 15 */ SyscallDesc("chmod", chmodFunc), /* 16 */ SyscallDesc("chown", chownFunc), - /* 17 */ SyscallDesc("brk", obreakFunc), + /* 17 */ SyscallDesc("brk", brkFunc), /* 18 */ SyscallDesc("stat", unimplementedFunc), /* 19 */ SyscallDesc("lseek", lseekFunc), /* 20 */ SyscallDesc("getpid", getpidFunc), diff --git a/src/arch/x86/linux/syscalls.cc b/src/arch/x86/linux/syscalls.cc index ae2ac243b..754fb2eaf 100644 --- a/src/arch/x86/linux/syscalls.cc +++ b/src/arch/x86/linux/syscalls.cc @@ -135,7 +135,7 @@ SyscallDesc X86LinuxProcess::syscallDescs[] = { /* 9 */ SyscallDesc("mmap", mmapFunc), /* 10 */ SyscallDesc("mprotect", unimplementedFunc), /* 11 */ SyscallDesc("munmap", munmapFunc), - /* 12 */ SyscallDesc("brk", obreakFunc), + /* 12 */ SyscallDesc("brk", brkFunc), /* 13 */ SyscallDesc("rt_sigaction", unimplementedFunc), /* 14 */ SyscallDesc("rt_sigprocmask", unimplementedFunc), /* 15 */ SyscallDesc("rt_sigreturn", unimplementedFunc), diff --git a/src/mem/page_table.hh b/src/mem/page_table.hh index b8b52174c..6ff0be082 100644 --- a/src/mem/page_table.hh +++ b/src/mem/page_table.hh @@ -91,10 +91,18 @@ class PageTable /** * Translate function * @param vaddr The virtual address. - * @return Physical address from translation. + * @param paddr Physical address from translation. + * @return True if translation exists */ bool translate(Addr vaddr, Addr &paddr); + /** + * Simplified translate function (just check for translation) + * @param vaddr The virtual address. + * @return True if translation exists + */ + bool translate(Addr vaddr) { Addr dummy; return translate(vaddr, dummy); } + /** * Perform a translation on the memory request, fills in paddr * field of req. diff --git a/src/sim/syscall_emul.cc b/src/sim/syscall_emul.cc index e0e703815..fb6af0b0c 100644 --- a/src/sim/syscall_emul.cc +++ b/src/sim/syscall_emul.cc @@ -107,21 +107,27 @@ getpagesizeFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) SyscallReturn -obreakFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) +brkFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) { - Addr junk; - // change brk addr to first arg Addr new_brk = tc->getSyscallArg(0); - if (new_brk != 0) { + + // in Linux at least, brk(0) returns the current break value + // (note that the syscall and the glibc function have different behavior) + if (new_brk == 0) + return p->brk_point; + + if (new_brk > p->brk_point) { + // might need to allocate some new pages for (ChunkGenerator gen(p->brk_point, new_brk - p->brk_point, VMPageSize); !gen.done(); gen.next()) { - if (!p->pTable->translate(gen.addr(), junk)) + if (!p->pTable->translate(gen.addr())) p->pTable->allocate(roundDown(gen.addr(), VMPageSize), VMPageSize); } - p->brk_point = new_brk; } + + p->brk_point = new_brk; DPRINTF(SyscallVerbose, "Break Point changed to: %#X\n", p->brk_point); return p->brk_point; } diff --git a/src/sim/syscall_emul.hh b/src/sim/syscall_emul.hh index 2e8071196..57403ab27 100644 --- a/src/sim/syscall_emul.hh +++ b/src/sim/syscall_emul.hh @@ -191,9 +191,9 @@ SyscallReturn exitFunc(SyscallDesc *desc, int num, SyscallReturn getpagesizeFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc); -/// Target obreak() handler: set brk address. -SyscallReturn obreakFunc(SyscallDesc *desc, int num, - LiveProcess *p, ThreadContext *tc); +/// Target brk() handler: set brk address. +SyscallReturn brkFunc(SyscallDesc *desc, int num, + LiveProcess *p, ThreadContext *tc); /// Target close() handler. SyscallReturn closeFunc(SyscallDesc *desc, int num, -- 2.30.2