summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteve Reinhardt <Steve.Reinhardt@amd.com>2008-11-15 09:30:10 -0800
committerSteve Reinhardt <Steve.Reinhardt@amd.com>2008-11-15 09:30:10 -0800
commit4514f565e3dfe1de41bbaec05f3f0074e5299bac (patch)
treee70dc0c3c09f7b035a7c33c69b98562a6c198a23
parentba8936120e4de7a4cdf6093a0e0cb04e0d1b8a59 (diff)
downloadgem5-4514f565e3dfe1de41bbaec05f3f0074e5299bac.tar.xz
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.
-rw-r--r--src/arch/alpha/linux/process.cc2
-rw-r--r--src/arch/alpha/tru64/process.cc2
-rw-r--r--src/arch/mips/linux/process.cc4
-rw-r--r--src/arch/sparc/linux/syscalls.cc4
-rw-r--r--src/arch/sparc/solaris/process.cc2
-rw-r--r--src/arch/x86/linux/syscalls.cc2
-rw-r--r--src/mem/page_table.hh10
-rw-r--r--src/sim/syscall_emul.cc18
-rw-r--r--src/sim/syscall_emul.hh6
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<AlphaLinux>),
/* 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<MipsLinux>),
/* 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<Linux>),
/* 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<Solaris>),
/* 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<X86Linux64>),
/* 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,11 +91,19 @@ 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.
* @param req The memory request.
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,