summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-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
4 files changed, 55 insertions, 1 deletions
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);
}