summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configs/common/FileSystemConfig.py12
-rw-r--r--configs/common/Options.py9
-rw-r--r--src/base/loader/elf_object.cc22
-rw-r--r--src/base/loader/elf_object.hh11
-rw-r--r--src/python/m5/core.py13
-rw-r--r--src/python/pybind11/core.cc10
6 files changed, 76 insertions, 1 deletions
diff --git a/configs/common/FileSystemConfig.py b/configs/common/FileSystemConfig.py
index 76ea5ffef..33515bca3 100644
--- a/configs/common/FileSystemConfig.py
+++ b/configs/common/FileSystemConfig.py
@@ -154,6 +154,18 @@ def config_filesystem(system, options = None):
system.redirect_paths = _redirect_paths(options)
+ # Setting the interpreter path. This is used to load the
+ # guest dynamic linker itself from the elf file.
+ interp = getattr(options, 'interp_dir', None)
+ if interp:
+ from m5.core import setInterpDir
+ setInterpDir(interp)
+
+ print("Setting the interpreter path to:", interp,
+ "\nFor dynamically linked applications you might still "
+ "need to setup the --redirects so that libraries are "
+ "found\n")
+
def register_node(cpu_list, mem, node_number):
nodebasedir = joinpath(m5.options.outdir, 'fs', 'sys', 'devices',
'system', 'node')
diff --git a/configs/common/Options.py b/configs/common/Options.py
index 855c0063f..c47d4f755 100644
--- a/configs/common/Options.py
+++ b/configs/common/Options.py
@@ -381,6 +381,15 @@ def addSEOptions(parser):
"for information or functionality. Instead of " \
"finding files on the __HOST__ filesystem, the " \
"process will find the user's replacment files.")
+ parser.add_option("--interp-dir", action="store", type="string",
+ default=None,
+ help="The interp-dir option is used for "
+ "setting the interpreter's path. This will "
+ "allow to load the guest dynamic linker/loader "
+ "itself from the elf binary. The option points to "
+ "the parent folder of the guest /lib in the "
+ "host fs")
+
parser.add_option("--redirects", action="append", type="string",
default=[],
help="A collection of one or more redirect paths "
diff --git a/src/base/loader/elf_object.cc b/src/base/loader/elf_object.cc
index bbaa27b70..06cc33bc5 100644
--- a/src/base/loader/elf_object.cc
+++ b/src/base/loader/elf_object.cc
@@ -90,9 +90,18 @@ namespace
{
ElfObjectFormat elfObjectFormat;
+std::string interpDir;
} // anonymous namespace
+void
+setInterpDir(const std::string &dirname)
+{
+ fatal_if(!interpDir.empty(),
+ "Error: setInterpDir has already been called once\n");
+ interpDir = dirname;
+}
+
ElfObject::ElfObject(ImageFileDataPtr ifd) : ObjectFile(ifd)
{
// get a pointer to elf structure
@@ -119,7 +128,7 @@ ElfObject::ElfObject(ImageFileDataPtr ifd) : ObjectFile(ifd)
handleLoadableSegment(phdr, i);
if (phdr.p_type == PT_INTERP) {
// Make sure the interpreter is an valid ELF file.
- char *interp_path = (char *)imageData->data() + phdr.p_offset;
+ auto interp_path = getInterpPath(phdr);
ObjectFile *obj = createObjectFile(interp_path);
interpreter = dynamic_cast<ElfObject *>(obj);
assert(interpreter != nullptr);
@@ -137,6 +146,17 @@ ElfObject::ElfObject(ImageFileDataPtr ifd) : ObjectFile(ifd)
// We will actually read the sections when we need to load them
}
+std::string
+ElfObject::getInterpPath(const GElf_Phdr &phdr) const
+{
+ // This is the interpreter path as specified in the elf file
+ const std::string elf_path = (char *)imageData->data() + phdr.p_offset;
+ if (!interpDir.empty())
+ return interpDir + elf_path;
+ else
+ return elf_path;
+}
+
void
ElfObject::determineArch()
{
diff --git a/src/base/loader/elf_object.hh b/src/base/loader/elf_object.hh
index 2cc2016fd..8b72cee2c 100644
--- a/src/base/loader/elf_object.hh
+++ b/src/base/loader/elf_object.hh
@@ -116,6 +116,8 @@ class ElfObject : public ObjectFile
ObjectFile *getInterpreter() const override { return interpreter; }
+ std::string getInterpPath(const GElf_Phdr &phdr) const;
+
Addr bias() const override { return ldBias; }
bool relocatable() const override { return relocate; }
Addr mapSize() const override { return ldMax - ldMin; }
@@ -128,4 +130,13 @@ class ElfObject : public ObjectFile
uint16_t programHeaderCount() {return _programHeaderCount;}
};
+/**
+ * This is the interface for setting up a base path for the
+ * elf interpreter. This is needed when loading a
+ * cross-compiled (guest ISA != host ISA) dynamically
+ * linked application.
+ * @param dirname base path for the interpreter
+ */
+void setInterpDir(const std::string &dirname);
+
#endif // __BASE_LOADER_ELF_OBJECT_HH__
diff --git a/src/python/m5/core.py b/src/python/m5/core.py
index 4c94353aa..c8c57fcef 100644
--- a/src/python/m5/core.py
+++ b/src/python/m5/core.py
@@ -1,3 +1,15 @@
+# Copyright (c) 2019 ARM Limited
+# All rights reserved.
+#
+# The license below extends only to copyright in the software and shall
+# not be construed as granting a license to any other intellectual
+# property including but not limited to intellectual property relating
+# to a hardware implementation of the functionality of the software
+# licensed hereunder. You may use the software subject to the license
+# terms below provided that you ensure that this notice is replicated
+# unmodified and in its entirety in all distributions of the software,
+# modified or unmodified, in source code or in binary form.
+#
# Copyright (c) 2008 The Hewlett-Packard Development Company
# All rights reserved.
#
@@ -30,3 +42,4 @@ from __future__ import print_function
from __future__ import absolute_import
from _m5.core import setOutputDir
+from _m5.loader import setInterpDir
diff --git a/src/python/pybind11/core.cc b/src/python/pybind11/core.cc
index 3523c0639..2cfaecd45 100644
--- a/src/python/pybind11/core.cc
+++ b/src/python/pybind11/core.cc
@@ -53,6 +53,7 @@
#include "base/addr_range.hh"
#include "base/inet.hh"
+#include "base/loader/elf_object.hh"
#include "base/logging.hh"
#include "base/random.hh"
#include "base/socket.hh"
@@ -202,6 +203,14 @@ init_net(py::module &m_native)
;
}
+static void
+init_loader(py::module &m_native)
+{
+ py::module m = m_native.def_submodule("loader");
+
+ m.def("setInterpDir", &setInterpDir);
+}
+
void
pybind_init_core(py::module &m_native)
{
@@ -281,5 +290,6 @@ pybind_init_core(py::module &m_native)
init_serialize(m_native);
init_range(m_native);
init_net(m_native);
+ init_loader(m_native);
}