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.
This commit is contained in:
Steve Reinhardt 2008-11-15 09:30:10 -08:00
parent ba8936120e
commit 4514f565e3
9 changed files with 32 additions and 18 deletions

View file

@ -136,7 +136,7 @@ SyscallDesc AlphaLinuxProcess::syscallDescs[] = {
/* 14 */ SyscallDesc("mknod", unimplementedFunc), /* 14 */ SyscallDesc("mknod", unimplementedFunc),
/* 15 */ SyscallDesc("chmod", chmodFunc<AlphaLinux>), /* 15 */ SyscallDesc("chmod", chmodFunc<AlphaLinux>),
/* 16 */ SyscallDesc("chown", chownFunc), /* 16 */ SyscallDesc("chown", chownFunc),
/* 17 */ SyscallDesc("brk", obreakFunc), /* 17 */ SyscallDesc("brk", brkFunc),
/* 18 */ SyscallDesc("osf_getfsstat", unimplementedFunc), /* 18 */ SyscallDesc("osf_getfsstat", unimplementedFunc),
/* 19 */ SyscallDesc("lseek", lseekFunc), /* 19 */ SyscallDesc("lseek", lseekFunc),
/* 20 */ SyscallDesc("getxpid", getpidPseudoFunc), /* 20 */ SyscallDesc("getxpid", getpidPseudoFunc),

View file

@ -215,7 +215,7 @@ SyscallDesc AlphaTru64Process::syscallDescs[] = {
/* 14 */ SyscallDesc("mknod", unimplementedFunc), /* 14 */ SyscallDesc("mknod", unimplementedFunc),
/* 15 */ SyscallDesc("chmod", unimplementedFunc), /* 15 */ SyscallDesc("chmod", unimplementedFunc),
/* 16 */ SyscallDesc("chown", unimplementedFunc), /* 16 */ SyscallDesc("chown", unimplementedFunc),
/* 17 */ SyscallDesc("obreak", obreakFunc), /* 17 */ SyscallDesc("obreak", brkFunc),
/* 18 */ SyscallDesc("pre_F64_getfsstat", unimplementedFunc), /* 18 */ SyscallDesc("pre_F64_getfsstat", unimplementedFunc),
/* 19 */ SyscallDesc("lseek", lseekFunc), /* 19 */ SyscallDesc("lseek", lseekFunc),
/* 20 */ SyscallDesc("getpid", getpidPseudoFunc), /* 20 */ SyscallDesc("getpid", getpidPseudoFunc),

View file

@ -138,7 +138,7 @@ SyscallDesc MipsLinuxProcess::syscallDescs[] = {
/* 14 */ SyscallDesc("mknod", unimplementedFunc), /* 14 */ SyscallDesc("mknod", unimplementedFunc),
/* 15 */ SyscallDesc("chmod", chmodFunc<MipsLinux>), /* 15 */ SyscallDesc("chmod", chmodFunc<MipsLinux>),
/* 16 */ SyscallDesc("lchown", chownFunc), /* 16 */ SyscallDesc("lchown", chownFunc),
/* 17 */ SyscallDesc("break", obreakFunc), /* 17 */ SyscallDesc("break", brkFunc),
/* 18 */ SyscallDesc("unused#18", unimplementedFunc), /* 18 */ SyscallDesc("unused#18", unimplementedFunc),
/* 19 */ SyscallDesc("lseek", lseekFunc), /* 19 */ SyscallDesc("lseek", lseekFunc),
/* 20 */ SyscallDesc("getpid", getpidFunc), /* 20 */ SyscallDesc("getpid", getpidFunc),
@ -166,7 +166,7 @@ SyscallDesc MipsLinuxProcess::syscallDescs[] = {
/* 42 */ SyscallDesc("pipe", pipePseudoFunc), /* 42 */ SyscallDesc("pipe", pipePseudoFunc),
/* 43 */ SyscallDesc("times", unimplementedFunc), /* 43 */ SyscallDesc("times", unimplementedFunc),
/* 44 */ SyscallDesc("prof", unimplementedFunc), /* 44 */ SyscallDesc("prof", unimplementedFunc),
/* 45 */ SyscallDesc("brk", obreakFunc), /* 45 */ SyscallDesc("brk", brkFunc),
/* 46 */ SyscallDesc("setgid", unimplementedFunc), /* 46 */ SyscallDesc("setgid", unimplementedFunc),
/* 47 */ SyscallDesc("getgid", getgidFunc), /* 47 */ SyscallDesc("getgid", getgidFunc),
/* 48 */ SyscallDesc("signal", ignoreFunc), /* 48 */ SyscallDesc("signal", ignoreFunc),

View file

@ -106,7 +106,7 @@ SyscallDesc SparcLinuxProcess::syscall32Descs[] = {
/* 14 */ SyscallDesc("mknod", unimplementedFunc), /* 14 */ SyscallDesc("mknod", unimplementedFunc),
/* 15 */ SyscallDesc("chmod", unimplementedFunc), /* 15 */ SyscallDesc("chmod", unimplementedFunc),
/* 16 */ SyscallDesc("lchown", unimplementedFunc), //32 bit /* 16 */ SyscallDesc("lchown", unimplementedFunc), //32 bit
/* 17 */ SyscallDesc("brk", obreakFunc), /* 17 */ SyscallDesc("brk", brkFunc),
/* 18 */ SyscallDesc("perfctr", unimplementedFunc), //32 bit /* 18 */ SyscallDesc("perfctr", unimplementedFunc), //32 bit
/* 19 */ SyscallDesc("lseek", lseekFunc), //32 bit /* 19 */ SyscallDesc("lseek", lseekFunc), //32 bit
/* 20 */ SyscallDesc("getpid", getpidFunc), /* 20 */ SyscallDesc("getpid", getpidFunc),
@ -409,7 +409,7 @@ SyscallDesc SparcLinuxProcess::syscallDescs[] = {
/* 14 */ SyscallDesc("mknod", unimplementedFunc), /* 14 */ SyscallDesc("mknod", unimplementedFunc),
/* 15 */ SyscallDesc("chmod", chmodFunc<Linux>), /* 15 */ SyscallDesc("chmod", chmodFunc<Linux>),
/* 16 */ SyscallDesc("lchown", unimplementedFunc), /* 16 */ SyscallDesc("lchown", unimplementedFunc),
/* 17 */ SyscallDesc("brk", obreakFunc), /* 17 */ SyscallDesc("brk", brkFunc),
/* 18 */ SyscallDesc("perfctr", unimplementedFunc), /* 18 */ SyscallDesc("perfctr", unimplementedFunc),
/* 19 */ SyscallDesc("lseek", lseekFunc), /* 19 */ SyscallDesc("lseek", lseekFunc),
/* 20 */ SyscallDesc("getpid", getpidFunc), /* 20 */ SyscallDesc("getpid", getpidFunc),

View file

@ -80,7 +80,7 @@ SyscallDesc SparcSolarisProcess::syscallDescs[] = {
/* 14 */ SyscallDesc("mknod", unimplementedFunc), /* 14 */ SyscallDesc("mknod", unimplementedFunc),
/* 15 */ SyscallDesc("chmod", chmodFunc<Solaris>), /* 15 */ SyscallDesc("chmod", chmodFunc<Solaris>),
/* 16 */ SyscallDesc("chown", chownFunc), /* 16 */ SyscallDesc("chown", chownFunc),
/* 17 */ SyscallDesc("brk", obreakFunc), /* 17 */ SyscallDesc("brk", brkFunc),
/* 18 */ SyscallDesc("stat", unimplementedFunc), /* 18 */ SyscallDesc("stat", unimplementedFunc),
/* 19 */ SyscallDesc("lseek", lseekFunc), /* 19 */ SyscallDesc("lseek", lseekFunc),
/* 20 */ SyscallDesc("getpid", getpidFunc), /* 20 */ SyscallDesc("getpid", getpidFunc),

View file

@ -135,7 +135,7 @@ SyscallDesc X86LinuxProcess::syscallDescs[] = {
/* 9 */ SyscallDesc("mmap", mmapFunc<X86Linux64>), /* 9 */ SyscallDesc("mmap", mmapFunc<X86Linux64>),
/* 10 */ SyscallDesc("mprotect", unimplementedFunc), /* 10 */ SyscallDesc("mprotect", unimplementedFunc),
/* 11 */ SyscallDesc("munmap", munmapFunc), /* 11 */ SyscallDesc("munmap", munmapFunc),
/* 12 */ SyscallDesc("brk", obreakFunc), /* 12 */ SyscallDesc("brk", brkFunc),
/* 13 */ SyscallDesc("rt_sigaction", unimplementedFunc), /* 13 */ SyscallDesc("rt_sigaction", unimplementedFunc),
/* 14 */ SyscallDesc("rt_sigprocmask", unimplementedFunc), /* 14 */ SyscallDesc("rt_sigprocmask", unimplementedFunc),
/* 15 */ SyscallDesc("rt_sigreturn", unimplementedFunc), /* 15 */ SyscallDesc("rt_sigreturn", unimplementedFunc),

View file

@ -91,10 +91,18 @@ class PageTable
/** /**
* Translate function * Translate function
* @param vaddr The virtual address. * @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); 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 * Perform a translation on the memory request, fills in paddr
* field of req. * field of req.

View file

@ -107,21 +107,27 @@ getpagesizeFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
SyscallReturn 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 // change brk addr to first arg
Addr new_brk = tc->getSyscallArg(0); 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, for (ChunkGenerator gen(p->brk_point, new_brk - p->brk_point,
VMPageSize); !gen.done(); gen.next()) { 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), p->pTable->allocate(roundDown(gen.addr(), VMPageSize),
VMPageSize); VMPageSize);
} }
p->brk_point = new_brk;
} }
p->brk_point = new_brk;
DPRINTF(SyscallVerbose, "Break Point changed to: %#X\n", p->brk_point); DPRINTF(SyscallVerbose, "Break Point changed to: %#X\n", p->brk_point);
return p->brk_point; return p->brk_point;
} }

View file

@ -191,8 +191,8 @@ SyscallReturn exitFunc(SyscallDesc *desc, int num,
SyscallReturn getpagesizeFunc(SyscallDesc *desc, int num, SyscallReturn getpagesizeFunc(SyscallDesc *desc, int num,
LiveProcess *p, ThreadContext *tc); LiveProcess *p, ThreadContext *tc);
/// Target obreak() handler: set brk address. /// Target brk() handler: set brk address.
SyscallReturn obreakFunc(SyscallDesc *desc, int num, SyscallReturn brkFunc(SyscallDesc *desc, int num,
LiveProcess *p, ThreadContext *tc); LiveProcess *p, ThreadContext *tc);
/// Target close() handler. /// Target close() handler.