From 951b235be21c7dad91f5036f330560a9a0807c17 Mon Sep 17 00:00:00 2001 From: Lang Hames Date: Sat, 8 Mar 2014 18:45:12 +0000 Subject: [PATCH] Make createObjectImage and createObjectImageFromFile static methods on the relevant subclasses of RuntimeDyldImpl. This allows construction of RuntimeDyldImpl instances to be deferred until after the target architecture is known. llvm-svn: 203352 --- .../RuntimeDyld/RuntimeDyld.cpp | 124 ++++++++---------- .../RuntimeDyld/RuntimeDyldELF.h | 5 +- .../RuntimeDyld/RuntimeDyldImpl.h | 9 +- .../RuntimeDyld/RuntimeDyldMachO.h | 10 ++ 4 files changed, 72 insertions(+), 76 deletions(-) diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp index d45b47218ae7..723a790b87e0 100644 --- a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp +++ b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp @@ -75,25 +75,7 @@ void RuntimeDyldImpl::mapSectionAddress(const void *LocalAddress, llvm_unreachable("Attempting to remap address of unknown section!"); } -// Subclasses can implement this method to create specialized image instances. -// The caller owns the pointer that is returned. -ObjectImage *RuntimeDyldImpl::createObjectImage(ObjectBuffer *InputBuffer) { - return new ObjectImageCommon(InputBuffer); -} - -ObjectImage *RuntimeDyldImpl::createObjectImageFromFile(ObjectFile *InputObject) { - return new ObjectImageCommon(InputObject); -} - -ObjectImage *RuntimeDyldImpl::loadObject(ObjectFile *InputObject) { - return loadObject(createObjectImageFromFile(InputObject)); -} - -ObjectImage *RuntimeDyldImpl::loadObject(ObjectBuffer *InputBuffer) { - return loadObject(createObjectImage(InputBuffer)); -} - -ObjectImage *RuntimeDyldImpl::loadObject(ObjectImage *InputObject) { +ObjectImage* RuntimeDyldImpl::loadObject(ObjectImage *InputObject) { MutexGuard locked(lock); std::unique_ptr Obj(InputObject); @@ -155,7 +137,7 @@ ObjectImage *RuntimeDyldImpl::loadObject(ObjectImage *InputObject) { if (SI == Obj->end_sections()) continue; Check(SI->getContents(SectionData)); Check(SI->isText(IsCode)); - const uint8_t* SymPtr = (const uint8_t*)InputObject->getData().data() + + const uint8_t* SymPtr = (const uint8_t*)Obj->getData().data() + (uintptr_t)FileOffset; uintptr_t SectOffset = (uintptr_t)(SymPtr - (const uint8_t*)SectionData.begin()); @@ -693,60 +675,70 @@ RuntimeDyld::~RuntimeDyld() { } ObjectImage *RuntimeDyld::loadObject(ObjectFile *InputObject) { - if (!Dyld) { - if (InputObject->isELF()) - Dyld = new RuntimeDyldELF(MM); - else if (InputObject->isMachO()) - Dyld = new RuntimeDyldMachO(MM); - else - report_fatal_error("Incompatible object format!"); - } else { - if (!Dyld->isCompatibleFile(InputObject)) - report_fatal_error("Incompatible object format!"); - } + std::unique_ptr InputImage; - return Dyld->loadObject(InputObject); + if (InputObject->isELF()) { + InputImage.reset(RuntimeDyldELF::createObjectImageFromFile(InputObject)); + if (!Dyld) + Dyld = new RuntimeDyldELF(MM); + } else if (InputObject->isMachO()) { + InputImage.reset(RuntimeDyldMachO::createObjectImageFromFile(InputObject)); + if (!Dyld) + Dyld = new RuntimeDyldMachO(MM); + } else + report_fatal_error("Incompatible object format!"); + + if (!Dyld->isCompatibleFile(InputObject)) + report_fatal_error("Incompatible object format!"); + + Dyld->loadObject(InputImage.get()); + return InputImage.release(); } ObjectImage *RuntimeDyld::loadObject(ObjectBuffer *InputBuffer) { - if (!Dyld) { - sys::fs::file_magic Type = - sys::fs::identify_magic(InputBuffer->getBuffer()); - switch (Type) { - case sys::fs::file_magic::elf_relocatable: - case sys::fs::file_magic::elf_executable: - case sys::fs::file_magic::elf_shared_object: - case sys::fs::file_magic::elf_core: + std::unique_ptr InputImage; + sys::fs::file_magic Type = + sys::fs::identify_magic(InputBuffer->getBuffer()); + + switch (Type) { + case sys::fs::file_magic::elf_relocatable: + case sys::fs::file_magic::elf_executable: + case sys::fs::file_magic::elf_shared_object: + case sys::fs::file_magic::elf_core: + InputImage.reset(RuntimeDyldELF::createObjectImage(InputBuffer)); + if (!Dyld) Dyld = new RuntimeDyldELF(MM); - break; - case sys::fs::file_magic::macho_object: - case sys::fs::file_magic::macho_executable: - case sys::fs::file_magic::macho_fixed_virtual_memory_shared_lib: - case sys::fs::file_magic::macho_core: - case sys::fs::file_magic::macho_preload_executable: - case sys::fs::file_magic::macho_dynamically_linked_shared_lib: - case sys::fs::file_magic::macho_dynamic_linker: - case sys::fs::file_magic::macho_bundle: - case sys::fs::file_magic::macho_dynamically_linked_shared_lib_stub: - case sys::fs::file_magic::macho_dsym_companion: + break; + case sys::fs::file_magic::macho_object: + case sys::fs::file_magic::macho_executable: + case sys::fs::file_magic::macho_fixed_virtual_memory_shared_lib: + case sys::fs::file_magic::macho_core: + case sys::fs::file_magic::macho_preload_executable: + case sys::fs::file_magic::macho_dynamically_linked_shared_lib: + case sys::fs::file_magic::macho_dynamic_linker: + case sys::fs::file_magic::macho_bundle: + case sys::fs::file_magic::macho_dynamically_linked_shared_lib_stub: + case sys::fs::file_magic::macho_dsym_companion: + InputImage.reset(RuntimeDyldMachO::createObjectImage(InputBuffer)); + if (!Dyld) Dyld = new RuntimeDyldMachO(MM); - break; - case sys::fs::file_magic::unknown: - case sys::fs::file_magic::bitcode: - case sys::fs::file_magic::archive: - case sys::fs::file_magic::coff_object: - case sys::fs::file_magic::coff_import_library: - case sys::fs::file_magic::pecoff_executable: - case sys::fs::file_magic::macho_universal_binary: - case sys::fs::file_magic::windows_resource: - report_fatal_error("Incompatible object format!"); - } - } else { - if (!Dyld->isCompatibleFormat(InputBuffer)) - report_fatal_error("Incompatible object format!"); + break; + case sys::fs::file_magic::unknown: + case sys::fs::file_magic::bitcode: + case sys::fs::file_magic::archive: + case sys::fs::file_magic::coff_object: + case sys::fs::file_magic::coff_import_library: + case sys::fs::file_magic::pecoff_executable: + case sys::fs::file_magic::macho_universal_binary: + case sys::fs::file_magic::windows_resource: + report_fatal_error("Incompatible object format!"); } - return Dyld->loadObject(InputBuffer); + if (!Dyld->isCompatibleFormat(InputBuffer)) + report_fatal_error("Incompatible object format!"); + + Dyld->loadObject(InputImage.get()); + return InputImage.release(); } void *RuntimeDyld::getSymbolAddress(StringRef Name) { diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h index 707940ec33ef..f7f43b4069be 100644 --- a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h +++ b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h @@ -139,12 +139,13 @@ public: StubMap &Stubs) override; bool isCompatibleFormat(const ObjectBuffer *Buffer) const override; bool isCompatibleFile(const object::ObjectFile *Buffer) const override; - ObjectImage *createObjectImage(ObjectBuffer *InputBuffer) override; - ObjectImage *createObjectImageFromFile(object::ObjectFile *Obj) override; void registerEHFrames() override; void deregisterEHFrames() override; void finalizeLoad(ObjSectionToIDMap &SectionMap) override; virtual ~RuntimeDyldELF(); + + static ObjectImage *createObjectImage(ObjectBuffer *InputBuffer); + static ObjectImage *createObjectImageFromFile(object::ObjectFile *Obj); }; } // end namespace llvm diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h index 9a9e360d4ff1..8fd55920f2e5 100644 --- a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h +++ b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h @@ -310,9 +310,6 @@ protected: // The base class does nothing. ELF overrides this. virtual void updateGOTEntries(StringRef Name, uint64_t Addr) {} - virtual ObjectImage *createObjectImage(ObjectBuffer *InputBuffer); - virtual ObjectImage *createObjectImageFromFile(object::ObjectFile *InputObject); - // \brief Compute an upper bound of the memory that is required to load all sections void computeTotalAllocSize(ObjectImage &Obj, uint64_t& CodeSize, @@ -322,16 +319,12 @@ protected: // \brief Compute the stub buffer size required for a section unsigned computeSectionStubBufSize(ObjectImage &Obj, const SectionRef &Section); - // This is the implementation for the two public overloads - ObjectImage *loadObject(ObjectImage *InputObject); - public: RuntimeDyldImpl(RTDyldMemoryManager *mm) : MemMgr(mm), HasError(false) {} virtual ~RuntimeDyldImpl(); - ObjectImage *loadObject(ObjectBuffer *InputBuffer); - ObjectImage *loadObject(object::ObjectFile *InputObject); + ObjectImage* loadObject(ObjectImage* InputObject); void *getSymbolAddress(StringRef Name) { // FIXME: Just look up as a function for now. Overly simple of course. diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h index bddf37958f5e..1a285ffbfbdd 100644 --- a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h +++ b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h @@ -14,6 +14,7 @@ #ifndef LLVM_RUNTIME_DYLD_MACHO_H #define LLVM_RUNTIME_DYLD_MACHO_H +#include "ObjectImageCommon.h" #include "RuntimeDyldImpl.h" #include "llvm/ADT/IndexedMap.h" #include "llvm/Object/MachO.h" @@ -95,6 +96,15 @@ public: bool isCompatibleFile(const object::ObjectFile *Obj) const override; void registerEHFrames() override; void finalizeLoad(ObjSectionToIDMap &SectionMap) override; + + + static ObjectImage *createObjectImage(ObjectBuffer *InputBuffer) { + return new ObjectImageCommon(InputBuffer); + } + + static ObjectImage *createObjectImageFromFile(object::ObjectFile *InputObject) { + return new ObjectImageCommon(InputObject); + } }; } // end namespace llvm