diff options
Diffstat (limited to 'src/sim/process.cc')
-rw-r--r-- | src/sim/process.cc | 91 |
1 files changed, 76 insertions, 15 deletions
diff --git a/src/sim/process.cc b/src/sim/process.cc index 5cec2958e..10c68fe6c 100644 --- a/src/sim/process.cc +++ b/src/sim/process.cc @@ -50,6 +50,7 @@ #include <unistd.h> #include <array> +#include <climits> #include <csignal> #include <map> #include <string> @@ -67,6 +68,7 @@ #include "sim/emul_driver.hh" #include "sim/fd_array.hh" #include "sim/fd_entry.hh" +#include "sim/redirect_path.hh" #include "sim/syscall_desc.hh" #include "sim/system.hh" @@ -101,6 +103,14 @@ using namespace std; using namespace TheISA; +static std::string +normalize(std::string& directory) +{ + if (directory.back() != '/') + directory += '/'; + return directory; +} + Process::Process(ProcessParams *params, EmulationPageTable *pTable, ObjectFile *obj_file) : SimObject(params), system(params->system), @@ -111,8 +121,10 @@ Process::Process(ProcessParams *params, EmulationPageTable *pTable, initVirtMem(system->getSystemPort(), this, SETranslatingPortProxy::Always), objFile(obj_file), - argv(params->cmd), envp(params->env), cwd(params->cwd), + argv(params->cmd), envp(params->env), executable(params->executable), + tgtCwd(normalize(params->cwd)), + hostCwd(checkPathRedirect(tgtCwd)), _uid(params->uid), _euid(params->euid), _gid(params->gid), _egid(params->egid), _pid(params->pid), _ppid(params->ppid), @@ -441,6 +453,42 @@ Process::findDriver(std::string filename) return nullptr; } +std::string +Process::checkPathRedirect(const std::string &filename) +{ + // If the input parameter contains a relative path, convert it. Note, + // the return value for this method should always return an absolute + // path on the host filesystem. The return value will be used to + // open and manipulate the path specified by the input parameter. Since + // all filesystem handling in syscall mode is passed through to the host, + // we deal only with host paths. + auto host_fs_abs_path = absolutePath(filename, true); + + for (auto path : system->redirectPaths) { + // Search through the redirect paths to see if a starting substring of + // our path falls into any buckets which need to redirected. + if (startswith(host_fs_abs_path, path->appPath())) { + std::string tail = host_fs_abs_path.substr(path->appPath().size()); + + // If this path needs to be redirected, search through a list + // of targets to see if we can match a valid file (or directory). + for (auto host_path : path->hostPaths()) { + if (access((host_path + tail).c_str(), R_OK) == 0) { + // Return the valid match. + return host_path + tail; + } + } + // The path needs to be redirected, but the file or directory + // does not exist on the host filesystem. Return the first + // host path as a default. + return path->hostPaths()[0] + tail; + } + } + + // The path does not need to be redirected. + return host_fs_abs_path; +} + void Process::updateBias() { @@ -489,6 +537,33 @@ Process::getStartPC() return interp ? interp->entryPoint() : objFile->entryPoint(); } +std::string +Process::absolutePath(const std::string &filename, bool host_filesystem) +{ + if (filename.empty() || startswith(filename, "/")) + return filename; + + // Verify that the current working directories are initialized properly. + // These members should be set initially via params from 'Process.py', + // although they may change over time depending on what the application + // does during simulation. + assert(!tgtCwd.empty()); + assert(!hostCwd.empty()); + + // Construct the absolute path given the current working directory for + // either the host filesystem or target filesystem. The distinction only + // matters if filesystem redirection is utilized in the simulation. + auto path_base = host_filesystem ? hostCwd : tgtCwd; + + // Add a trailing '/' if the current working directory did not have one. + normalize(path_base); + + // Append the filename onto the current working path. + auto absolute_path = path_base + filename; + + return absolute_path; +} + Process * ProcessParams::create() { @@ -649,17 +724,3 @@ ProcessParams::create() fatal("Unknown error creating process object."); return process; } - -std::string -Process::fullPath(const std::string &file_name) -{ - if (file_name[0] == '/' || cwd.empty()) - return file_name; - - std::string full = cwd; - - if (cwd[cwd.size() - 1] != '/') - full += '/'; - - return full + file_name; -} |