syscalls: fix latent brk/obreak bug.
authorSteve Reinhardt <Steve.Reinhardt@amd.com>
Sat, 15 Nov 2008 17:30:10 +0000 (09:30 -0800)
committerSteve Reinhardt <Steve.Reinhardt@amd.com>
Sat, 15 Nov 2008 17:30:10 +0000 (09:30 -0800)
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
src/arch/alpha/tru64/process.cc
src/arch/mips/linux/process.cc
src/arch/sparc/linux/syscalls.cc
src/arch/sparc/solaris/process.cc
src/arch/x86/linux/syscalls.cc
src/mem/page_table.hh
src/sim/syscall_emul.cc
src/sim/syscall_emul.hh

index 9527759ed80e42859f0008e690492ea8dc4d15cd..efcd6623e63ca3ec90afab94049a706cd3518821 100644 (file)
@@ -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),
index 645cc6cf9f73514fa208c8e7f8f8d372d0446d75..b84dfb286d7bbf87120230f3dd152f25bce1379e 100644 (file)
@@ -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),
index 8a13d0f183c9f8714dcd018a71dd2578f4c42a4d..56413484b83efa01ceadb875258ac3294fbc2711 100644 (file)
@@ -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),
index 2964b3c1a75e4f9816fa8e5db2ca028065f85efc..2845f7bec653a122f97901c2b314e444b8af942c 100644 (file)
@@ -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),
index e0c3eaa4b108fb5d31abc35bf9c4c0d2a0419e06..e4f6b23c892bd5dbbe7a7475b8fc148e79e3ff47 100644 (file)
@@ -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),
index ae2ac243baaf70c2e737b4d8327bbb678b55923d..754fb2eaf6c01798d630860d698761653e9e4fab 100644 (file)
@@ -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),
index b8b52174c81380f3e4a1fe010bb0fd6d1a496289..6ff0be082060a713e1cd225df9801611bed70e5d 100644 (file)
@@ -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.
index e0e7038156612efdd3a07a51094862a6ada75d9d..fb6af0b0c337d572c4de238ee0b47f68c018bcf7 100644 (file)
@@ -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;
 }
index 2e8071196d5dbd05408564a62133e4850445d3ee..57403ab27ba9b5519d8fb77b11b089712e28cc41 100644 (file)
@@ -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,