diff options
-rw-r--r-- | src/sim/process.cc | 13 | ||||
-rw-r--r-- | src/sim/process.hh | 3 | ||||
-rw-r--r-- | src/sim/syscall_emul.cc | 41 |
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()); |