summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/sim/process.cc13
-rw-r--r--src/sim/process.hh3
-rw-r--r--src/sim/syscall_emul.cc41
3 files changed, 38 insertions, 19 deletions
diff --git a/src/sim/process.cc b/src/sim/process.cc
index 575627367..def42c0b2 100644
--- a/src/sim/process.cc
+++ b/src/sim/process.cc
@@ -472,6 +472,7 @@ Process::map(Addr vaddr, Addr paddr, int size, bool cacheable)
LiveProcess::LiveProcess(LiveProcessParams *params, ObjectFile *_objFile)
: Process(params), objFile(_objFile),
argv(params->cmd), envp(params->env), cwd(params->cwd),
+ executable(params->executable),
__uid(params->uid), __euid(params->euid),
__gid(params->gid), __egid(params->egid),
__pid(params->pid), __ppid(params->ppid),
@@ -528,11 +529,15 @@ LiveProcess::create(LiveProcessParams * params)
{
LiveProcess *process = NULL;
- string executable =
- params->executable == "" ? params->cmd[0] : params->executable;
- ObjectFile *objFile = createObjectFile(executable);
+ // If not specified, set the executable parameter equal to the
+ // simulated system's zeroth command line parameter
+ if (params->executable == "") {
+ params->executable = params->cmd[0];
+ }
+
+ ObjectFile *objFile = createObjectFile(params->executable);
if (objFile == NULL) {
- fatal("Can't load object file %s", executable);
+ fatal("Can't load object file %s", params->executable);
}
if (objFile->isDynamic())
diff --git a/src/sim/process.hh b/src/sim/process.hh
index f509b81c7..43d1a4edc 100644
--- a/src/sim/process.hh
+++ b/src/sim/process.hh
@@ -238,6 +238,7 @@ class LiveProcess : public Process
std::vector<std::string> argv;
std::vector<std::string> envp;
std::string cwd;
+ std::string executable;
LiveProcess(LiveProcessParams *params, ObjectFile *objFile);
@@ -294,7 +295,7 @@ class LiveProcess : public Process
inline uint64_t ppid() {return __ppid;}
// provide program name for debug messages
- virtual const char *progName() const { return argv[0].c_str(); }
+ virtual const char *progName() const { return executable.c_str(); }
std::string
fullPath(const std::string &filename)
diff --git a/src/sim/syscall_emul.cc b/src/sim/syscall_emul.cc
index f5b273202..3dda05da7 100644
--- a/src/sim/syscall_emul.cc
+++ b/src/sim/syscall_emul.cc
@@ -407,25 +407,38 @@ readlinkFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc,
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) {
+ // Emulate readlink() called on '/proc/self/exe' should return the
+ // absolute path of the binary running in the simulated system (the
+ // LiveProcess' executable). It is possible that using this path in
+ // the simulated system will result in unexpected behavior if:
+ // 1) One binary runs another (e.g., -c time -o "my_binary"), and
+ // called binary calls readlink().
+ // 2) The host's full path to the running benchmark changes from one
+ // simulation to another. This can result in different simulated
+ // performance since the simulated system will process the binary
+ // path differently, even if the binary itself does not change.
+
+ // Get the absolute canonical path to the running application
+ char real_path[PATH_MAX];
+ char *check_real_path = realpath(p->progName(), real_path);
+ if (!check_real_path) {
+ fatal("readlink('/proc/self/exe') unable to resolve path to "
+ "executable: %s", p->progName());
+ }
+ strncpy((char*)buf.bufferPtr(), real_path, bufsiz);
+ size_t real_path_len = strlen(real_path);
+ if (real_path_len > 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());
+ result = real_path_len;
}
+
+ // Issue a warning about potential unexpected results
+ warn_once("readlink() called on '/proc/self/exe' may yield unexpected "
+ "results in various settings.\n Returning '%s'\n",
+ (char*)buf.bufferPtr());
}
buf.copyOut(tc->getMemProxy());