summaryrefslogtreecommitdiff
path: root/src/base/loader
diff options
context:
space:
mode:
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__