From 528f6d787b1a847e61eb2f1114559f423fdeb68c Mon Sep 17 00:00:00 2001 From: Andrew Kaylor Date: Fri, 11 Oct 2013 21:25:48 +0000 Subject: Adding multiple object support to MCJIT EH frame handling git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@192504 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp | 9 ++- lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp | 30 +++++++-- lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h | 10 ++- lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h | 7 +- .../RuntimeDyld/RuntimeDyldMachO.cpp | 75 ++++++++++++++-------- lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h | 19 +++++- 6 files changed, 108 insertions(+), 42 deletions(-) (limited to 'lib/ExecutionEngine/RuntimeDyld') diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp index 077442d8df..1b9e0bf035 100644 --- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp +++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp @@ -29,8 +29,7 @@ RuntimeDyldImpl::~RuntimeDyldImpl() {} namespace llvm { -StringRef RuntimeDyldImpl::getEHFrameSection() { - return StringRef(); +void RuntimeDyldImpl::registerEHFrames() { } // Resolve the relocations for all symbols we currently know about. @@ -171,7 +170,7 @@ ObjectImage *RuntimeDyldImpl::loadObject(ObjectBuffer *InputBuffer) { } // Give the subclasses a chance to tie-up any loose ends. - finalizeLoad(); + finalizeLoad(LocalSections); return obj.take(); } @@ -592,8 +591,8 @@ StringRef RuntimeDyld::getErrorString() { return Dyld->getErrorString(); } -StringRef RuntimeDyld::getEHFrameSection() { - return Dyld->getEHFrameSection(); +void RuntimeDyld::registerEHFrames() { + return Dyld->registerEHFrames(); } } // end namespace llvm diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp index a438dcd879..97e03f0694 100644 --- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp +++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp @@ -151,12 +151,17 @@ void DyldELFObject::updateSymbolAddress(const SymbolRef &SymRef, namespace llvm { -StringRef RuntimeDyldELF::getEHFrameSection() { - for (int i = 0, e = Sections.size(); i != e; ++i) { - if (Sections[i].Name == ".eh_frame") - return StringRef((const char*)Sections[i].Address, Sections[i].Size); +void RuntimeDyldELF::registerEHFrames() { + if (!MemMgr) + return; + for (int i = 0, e = UnregisteredEHFrameSections.size(); i != e; ++i) { + SID EHFrameSID = UnregisteredEHFrameSections[i]; + uint8_t *EHFrameAddr = Sections[EHFrameSID].Address; + uint64_t EHFrameLoadAddr = Sections[EHFrameSID].LoadAddress; + size_t EHFrameSize = Sections[EHFrameSID].Size; + MemMgr->registerEHFrames(EHFrameAddr, EHFrameLoadAddr, EHFrameSize); } - return StringRef(); + UnregisteredEHFrameSections.clear(); } ObjectImage *RuntimeDyldELF::createObjectImage(ObjectBuffer *Buffer) { @@ -1342,7 +1347,8 @@ uint64_t RuntimeDyldELF::findGOTEntry(uint64_t LoadAddress, return 0; } -void RuntimeDyldELF::finalizeLoad() { +void RuntimeDyldELF::finalizeLoad(ObjSectionToIDMap &SectionMap) { + // If necessary, allocate the global offset table if (MemMgr) { // Allocate the GOT if necessary size_t numGOTEntries = GOTEntries.size(); @@ -1365,6 +1371,18 @@ void RuntimeDyldELF::finalizeLoad() { else { report_fatal_error("Unable to allocate memory for GOT!"); } + + // Look for and record the EH frame section. + ObjSectionToIDMap::iterator i, e; + for (i = SectionMap.begin(), e = SectionMap.end(); i != e; ++i) { + const SectionRef &Section = i->first; + StringRef Name; + Section.getName(Name); + if (Name == ".eh_frame") { + UnregisteredEHFrameSections.push_back(i->second); + break; + } + } } bool RuntimeDyldELF::isCompatibleFormat(const ObjectBuffer *Buffer) const { diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h index 67dc693b1b..ab6b8bdaf3 100644 --- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h +++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h @@ -94,11 +94,15 @@ class RuntimeDyldELF : public RuntimeDyldImpl { // Relocation entries for symbols whose position-independant offset is // updated in a global offset table. - typedef unsigned SID; // Type for SectionIDs typedef SmallVector GOTRelocations; GOTRelocations GOTEntries; // List of entries requiring finalization. SmallVector, 8> GOTs; // Allocated tables. + // When a module is loaded we save the SectionID of the EH frame section + // in a table until we receive a request to register all unregistered + // EH frame sections with the memory manager. + SmallVector UnregisteredEHFrameSections; + public: RuntimeDyldELF(RTDyldMemoryManager *mm) : RuntimeDyldImpl(mm) {} @@ -112,8 +116,8 @@ public: StubMap &Stubs); virtual bool isCompatibleFormat(const ObjectBuffer *Buffer) const; virtual ObjectImage *createObjectImage(ObjectBuffer *InputBuffer); - virtual StringRef getEHFrameSection(); - virtual void finalizeLoad(); + virtual void registerEHFrames(); + virtual void finalizeLoad(ObjSectionToIDMap &SectionMap); virtual ~RuntimeDyldELF(); }; diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h index 11f77febd5..5796c7cd39 100644 --- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h +++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h @@ -147,6 +147,9 @@ protected: typedef SmallVector SectionList; SectionList Sections; + typedef unsigned SID; // Type for SectionIDs + #define RTDYLD_INVALID_SECTION_ID ((SID)(-1)) + // Keep a map of sections from object file to the SectionID which // references it. typedef std::map ObjSectionToIDMap; @@ -357,9 +360,9 @@ public: virtual bool isCompatibleFormat(const ObjectBuffer *Buffer) const = 0; - virtual StringRef getEHFrameSection(); + virtual void registerEHFrames(); - virtual void finalizeLoad() {} + virtual void finalizeLoad(ObjSectionToIDMap &SectionMap) {} }; } // end namespace llvm diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp index 1bf47d55a7..5b92867b47 100644 --- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp +++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp @@ -55,33 +55,58 @@ static intptr_t computeDelta(SectionEntry *A, SectionEntry *B) { return ObjDistance - MemDistance; } -StringRef RuntimeDyldMachO::getEHFrameSection() { - SectionEntry *Text = NULL; - SectionEntry *EHFrame = NULL; - SectionEntry *ExceptTab = NULL; - for (int i = 0, e = Sections.size(); i != e; ++i) { - if (Sections[i].Name == "__eh_frame") - EHFrame = &Sections[i]; - else if (Sections[i].Name == "__text") - Text = &Sections[i]; - else if (Sections[i].Name == "__gcc_except_tab") - ExceptTab = &Sections[i]; - } - if (Text == NULL || EHFrame == NULL) - return StringRef(); - - intptr_t DeltaForText = computeDelta(Text, EHFrame); - intptr_t DeltaForEH = 0; - if (ExceptTab) - DeltaForEH = computeDelta(ExceptTab, EHFrame); +void RuntimeDyldMachO::registerEHFrames() { - unsigned char *P = EHFrame->Address; - unsigned char *End = P + EHFrame->Size; - do { - P = processFDE(P, DeltaForText, DeltaForEH); - } while(P != End); + if (!MemMgr) + return; + for (int i = 0, e = UnregisteredEHFrameSections.size(); i != e; ++i) { + EHFrameRelatedSections &SectionInfo = UnregisteredEHFrameSections[i]; + if (SectionInfo.EHFrameSID == RTDYLD_INVALID_SECTION_ID || + SectionInfo.TextSID == RTDYLD_INVALID_SECTION_ID) + continue; + SectionEntry *Text = &Sections[SectionInfo.TextSID]; + SectionEntry *EHFrame = &Sections[SectionInfo.EHFrameSID]; + SectionEntry *ExceptTab = NULL; + if (SectionInfo.ExceptTabSID != RTDYLD_INVALID_SECTION_ID) + ExceptTab = &Sections[SectionInfo.ExceptTabSID]; + + intptr_t DeltaForText = computeDelta(Text, EHFrame); + intptr_t DeltaForEH = 0; + if (ExceptTab) + DeltaForEH = computeDelta(ExceptTab, EHFrame); + + unsigned char *P = EHFrame->Address; + unsigned char *End = P + EHFrame->Size; + do { + P = processFDE(P, DeltaForText, DeltaForEH); + } while(P != End); + + MemMgr->registerEHFrames(EHFrame->Address, + EHFrame->LoadAddress, + EHFrame->Size); + } + UnregisteredEHFrameSections.clear(); +} - return StringRef((char*)EHFrame->Address, EHFrame->Size); +void RuntimeDyldMachO::finalizeLoad(ObjSectionToIDMap &SectionMap) { + unsigned EHFrameSID = RTDYLD_INVALID_SECTION_ID; + unsigned TextSID = RTDYLD_INVALID_SECTION_ID; + unsigned ExceptTabSID = RTDYLD_INVALID_SECTION_ID; + ObjSectionToIDMap::iterator i, e; + for (i = SectionMap.begin(), e = SectionMap.end(); i != e; ++i) { + const SectionRef &Section = i->first; + StringRef Name; + Section.getName(Name); + if (Name == "__eh_frame") + EHFrameSID = i->second; + else if (Name == "__text") + TextSID = i->second; + else if (Name == "__gcc_except_tab") + ExceptTabSID = i->second; + } + UnregisteredEHFrameSections.push_back(EHFrameRelatedSections(EHFrameSID, + TextSID, + ExceptTabSID)); } // The target location for the relocation is described by RE.SectionID and diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h index df8d3bb482..3906c9d56d 100644 --- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h +++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h @@ -54,6 +54,22 @@ class RuntimeDyldMachO : public RuntimeDyldImpl { int64_t Addend, bool isPCRel, unsigned Size); + + struct EHFrameRelatedSections { + EHFrameRelatedSections() : EHFrameSID(RTDYLD_INVALID_SECTION_ID), + TextSID(RTDYLD_INVALID_SECTION_ID), + ExceptTabSID(RTDYLD_INVALID_SECTION_ID) {} + EHFrameRelatedSections(SID EH, SID T, SID Ex) + : EHFrameSID(EH), TextSID(T), ExceptTabSID(Ex) {} + SID EHFrameSID; + SID TextSID; + SID ExceptTabSID; + }; + + // When a module is loaded we save the SectionID of the EH frame section + // in a table until we receive a request to register all unregistered + // EH frame sections with the memory manager. + SmallVector UnregisteredEHFrameSections; public: RuntimeDyldMachO(RTDyldMemoryManager *mm) : RuntimeDyldImpl(mm) {} @@ -65,7 +81,8 @@ public: const SymbolTableMap &Symbols, StubMap &Stubs); virtual bool isCompatibleFormat(const ObjectBuffer *Buffer) const; - virtual StringRef getEHFrameSection(); + virtual void registerEHFrames(); + virtual void finalizeLoad(ObjSectionToIDMap &SectionMap); }; } // end namespace llvm -- cgit v1.2.3