summaryrefslogtreecommitdiff
path: root/src/base/loader
diff options
context:
space:
mode:
authorGiacomo Travaglini <giacomo.travaglini@arm.com>2019-11-25 14:03:46 +0000
committerGiacomo Travaglini <giacomo.travaglini@arm.com>2019-11-27 23:30:05 +0000
commit2a0140593f652f446464be1f0e01e5c1f9069a4b (patch)
tree88ce2c3966b70d50a09987fa4ebeb2ed2c6771c9 /src/base/loader
parent8e493b5fd275cdb15513dc3466ca4b108ab688e2 (diff)
downloadgem5-2a0140593f652f446464be1f0e01e5c1f9069a4b.tar.xz
base, python: Allow dirname selection for the interpreter
This is the second step towards being able to run dynamically linked applications when the guest ISA != than host ISA. Once the guest interpreter is loaded to memory, we are able to redirect shared object loads through the redirectPath interface. How do we load the guest interpreter? The elf file is for example asking for the /lib/ld-linux-aarch64.so interpreter. That would point to a valid dynamic linker/loader if guest ISA == host ISA, but if we are running on X86 we should point to the guest (aarch64 in the example) toolchain wherever it is installed. This patch is adding the --interp-dir option to point to the parent folder of the guest /lib in the host fs. Change-Id: Id27b97c060008d2e847776a49323d45c8809a27f Signed-off-by: Giacomo Travaglini <giacomo.travaglini@arm.com> Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/23066 Reviewed-by: Jason Lowe-Power <jason@lowepower.com> Maintainer: Jason Lowe-Power <jason@lowepower.com> Tested-by: kokoro <noreply+kokoro@google.com>
Diffstat (limited to 'src/base/loader')
-rw-r--r--src/base/loader/elf_object.cc22
-rw-r--r--src/base/loader/elf_object.hh11
2 files changed, 32 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__