diff options
Diffstat (limited to 'src/base/loader')
-rw-r--r-- | src/base/loader/elf_object.cc | 22 | ||||
-rw-r--r-- | src/base/loader/elf_object.hh | 11 |
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__ |