summaryrefslogtreecommitdiff
path: root/src/sim/syscall_emul.cc
diff options
context:
space:
mode:
authorDavid Hashe <david.hashe@amd.com>2015-07-20 09:15:18 -0500
committerDavid Hashe <david.hashe@amd.com>2015-07-20 09:15:18 -0500
commitd0f6aad3c6709d2ef686dbf3f0c60ac6cbfb7b5a (patch)
treeb52b5bed4a53a30c1e32b40ca1ed59b8f2df50c2 /src/sim/syscall_emul.cc
parent4710eba588cdfe059ab984ec78ff9e49bd7cbe69 (diff)
downloadgem5-d0f6aad3c6709d2ef686dbf3f0c60ac6cbfb7b5a.tar.xz
syscall: Add readlink to x86 with special case /proc/self/exe
This patch implements the correct behavior.
Diffstat (limited to 'src/sim/syscall_emul.cc')
-rw-r--r--src/sim/syscall_emul.cc31
1 files changed, 26 insertions, 5 deletions
diff --git a/src/sim/syscall_emul.cc b/src/sim/syscall_emul.cc
index d62836532..f5b273202 100644
--- a/src/sim/syscall_emul.cc
+++ b/src/sim/syscall_emul.cc
@@ -365,12 +365,10 @@ getcwdFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
}
strncpy((char *)buf.bufferPtr(), cwd.c_str(), size);
result = cwd.length();
- }
- else {
+ } else {
if (getcwd((char *)buf.bufferPtr(), size) != NULL) {
result = strlen((char *)buf.bufferPtr());
- }
- else {
+ } else {
result = -1;
}
}
@@ -405,7 +403,30 @@ readlinkFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc,
BufferArg buf(bufPtr, bufsiz);
- int result = readlink(path.c_str(), (char *)buf.bufferPtr(), bufsiz);
+ int result = -1;
+ if (path != "/proc/self/exe") {
+ result = readlink(path.c_str(), (char *)buf.bufferPtr(), bufsiz);
+ } else {
+ // readlink() will return the path of the binary given
+ // with the -c option, however it is possible that this
+ // will still result in incorrect behavior if one binary
+ // runs another, e.g., -c time -o "my_binary" where
+ // my_binary calls readlink(). this is a very unlikely case,
+ // so we issue a warning.
+ warn_once("readlink may yield unexpected results if multiple "
+ "binaries are used\n");
+ if (strlen(p->progName()) > bufsiz) {
+ // readlink will truncate the contents of the
+ // path to ensure it is no more than bufsiz
+ strncpy((char*)buf.bufferPtr(), p->progName(), bufsiz);
+ result = bufsiz;
+ } else {
+ // return the program's working path rather
+ // than the one for the gem5 binary itself.
+ strcpy((char*)buf.bufferPtr(), p->progName());
+ result = strlen((char*)buf.bufferPtr());
+ }
+ }
buf.copyOut(tc->getMemProxy());