diff --git a/include/llvm/Object/COFF.h b/include/llvm/Object/COFF.h index c2e7d52b919..af2eb6826ee 100644 --- a/include/llvm/Object/COFF.h +++ b/include/llvm/Object/COFF.h @@ -390,6 +390,7 @@ protected: bool &Result) const override; relocation_iterator section_rel_begin(DataRefImpl Sec) const override; relocation_iterator section_rel_end(DataRefImpl Sec) const override; + bool section_rel_empty(DataRefImpl Sec) const override; void moveRelocationNext(DataRefImpl &Rel) const override; error_code getRelocationAddress(DataRefImpl Rel, diff --git a/include/llvm/Object/ELFObjectFile.h b/include/llvm/Object/ELFObjectFile.h index e6752b3d904..7dcd4cf08cf 100644 --- a/include/llvm/Object/ELFObjectFile.h +++ b/include/llvm/Object/ELFObjectFile.h @@ -91,6 +91,7 @@ protected: bool &Result) const override; relocation_iterator section_rel_begin(DataRefImpl Sec) const override; relocation_iterator section_rel_end(DataRefImpl Sec) const override; + bool section_rel_empty(DataRefImpl Sec) const override; section_iterator getRelocatedSection(DataRefImpl Sec) const override; void moveRelocationNext(DataRefImpl &Rel) const override; @@ -557,6 +558,12 @@ ELFObjectFile::section_rel_end(DataRefImpl Sec) const { return relocation_iterator(RelocationRef(RelData, this)); } +template +bool ELFObjectFile::section_rel_empty(DataRefImpl Sec) const { + const Elf_Shdr *S = reinterpret_cast(Sec.p); + return S->sh_size == 0; +} + template section_iterator ELFObjectFile::getRelocatedSection(DataRefImpl Sec) const { diff --git a/include/llvm/Object/MachO.h b/include/llvm/Object/MachO.h index 34edec3ebfd..acd391ba330 100644 --- a/include/llvm/Object/MachO.h +++ b/include/llvm/Object/MachO.h @@ -91,6 +91,7 @@ public: bool &Result) const override; relocation_iterator section_rel_begin(DataRefImpl Sec) const override; relocation_iterator section_rel_end(DataRefImpl Sec) const override; + bool section_rel_empty(DataRefImpl Sec) const override; void moveRelocationNext(DataRefImpl &Rel) const override; error_code getRelocationAddress(DataRefImpl Rel, diff --git a/include/llvm/Object/ObjectFile.h b/include/llvm/Object/ObjectFile.h index 790257cdc23..1fdfbe81b24 100644 --- a/include/llvm/Object/ObjectFile.h +++ b/include/llvm/Object/ObjectFile.h @@ -87,6 +87,7 @@ public: SectionRef(DataRefImpl SectionP, const ObjectFile *Owner); bool operator==(const SectionRef &Other) const; + bool operator!=(const SectionRef &Other) const; bool operator<(const SectionRef &Other) const; void moveNext(); @@ -116,6 +117,7 @@ public: relocation_iterator_range relocations() const { return relocation_iterator_range(relocation_begin(), relocation_end()); } + bool relocation_empty() const; section_iterator getRelocatedSection() const; DataRefImpl getRawDataRefImpl() const; @@ -259,6 +261,7 @@ protected: bool &Result) const = 0; virtual relocation_iterator section_rel_begin(DataRefImpl Sec) const = 0; virtual relocation_iterator section_rel_end(DataRefImpl Sec) const = 0; + virtual bool section_rel_empty(DataRefImpl Sec) const = 0; virtual section_iterator getRelocatedSection(DataRefImpl Sec) const; // Same as above for RelocationRef. @@ -392,6 +395,10 @@ inline bool SectionRef::operator==(const SectionRef &Other) const { return SectionPimpl == Other.SectionPimpl; } +inline bool SectionRef::operator!=(const SectionRef &Other) const { + return SectionPimpl != Other.SectionPimpl; +} + inline bool SectionRef::operator<(const SectionRef &Other) const { return SectionPimpl < Other.SectionPimpl; } @@ -461,6 +468,10 @@ inline relocation_iterator SectionRef::relocation_end() const { return OwningObject->section_rel_end(SectionPimpl); } +inline bool SectionRef::relocation_empty() const { + return OwningObject->section_rel_empty(SectionPimpl); +} + inline section_iterator SectionRef::getRelocatedSection() const { return OwningObject->getRelocatedSection(SectionPimpl); } diff --git a/include/llvm/Object/SymbolicFile.h b/include/llvm/Object/SymbolicFile.h index 8b94c49359a..bead2c33ab9 100644 --- a/include/llvm/Object/SymbolicFile.h +++ b/include/llvm/Object/SymbolicFile.h @@ -35,6 +35,10 @@ inline bool operator==(const DataRefImpl &a, const DataRefImpl &b) { return std::memcmp(&a, &b, sizeof(DataRefImpl)) == 0; } +inline bool operator!=(const DataRefImpl &a, const DataRefImpl &b) { + return !operator==(a, b); +} + inline bool operator<(const DataRefImpl &a, const DataRefImpl &b) { // Check bitwise identical. This is the only legal way to compare a union w/o // knowing which member is in use. diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp index 310b206a067..5c3cc008e3a 100644 --- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp +++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp @@ -165,18 +165,19 @@ ObjectImage* RuntimeDyldImpl::loadObject(ObjectImage *InputObject) { StubMap Stubs; section_iterator RelocatedSection = SI->getRelocatedSection(); - if ((SI->relocation_begin() != SI->relocation_end()) || - ProcessAllSections) { - bool IsCode = false; - Check(RelocatedSection->isText(IsCode)); - SectionID = - findOrEmitSection(*Obj, *RelocatedSection, IsCode, LocalSections); - DEBUG(dbgs() << "\tSectionID: " << SectionID << "\n"); - } + if (SI->relocation_empty() && !ProcessAllSections) + continue; - for (const RelocationRef &Reloc : SI->relocations()) - processRelocationRef(SectionID, Reloc, *Obj, LocalSections, LocalSymbols, - Stubs); + bool IsCode = false; + Check(RelocatedSection->isText(IsCode)); + SectionID = + findOrEmitSection(*Obj, *RelocatedSection, IsCode, LocalSections); + DEBUG(dbgs() << "\tSectionID: " << SectionID << "\n"); + + for (relocation_iterator I = SI->relocation_begin(), + E = SI->relocation_end(); I != E;) + I = processRelocationRef(SectionID, I, *Obj, LocalSections, LocalSymbols, + Stubs); } // Give the subclasses a chance to tie-up any loose ends. diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp index 96b4e127aa6..6510bd0a2e3 100644 --- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp +++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp @@ -919,17 +919,18 @@ void RuntimeDyldELF::resolveRelocation(const SectionEntry &Section, } } -void RuntimeDyldELF::processRelocationRef(unsigned SectionID, - RelocationRef RelI, - ObjectImage &Obj, - ObjSectionToIDMap &ObjSectionToID, - const SymbolTableMap &Symbols, - StubMap &Stubs) { +relocation_iterator +RuntimeDyldELF::processRelocationRef(unsigned SectionID, + relocation_iterator RelI, + ObjectImage &Obj, + ObjSectionToIDMap &ObjSectionToID, + const SymbolTableMap &Symbols, + StubMap &Stubs) { uint64_t RelType; - Check(RelI.getType(RelType)); + Check(RelI->getType(RelType)); int64_t Addend; - Check(getELFRelocationAddend(RelI, Addend)); - symbol_iterator Symbol = RelI.getSymbol(); + Check(getELFRelocationAddend(*RelI, Addend)); + symbol_iterator Symbol = RelI->getSymbol(); // Obtain the symbol name which is referenced in the relocation StringRef TargetName; @@ -1001,7 +1002,7 @@ void RuntimeDyldELF::processRelocationRef(unsigned SectionID, } } uint64_t Offset; - Check(RelI.getOffset(Offset)); + Check(RelI->getOffset(Offset)); DEBUG(dbgs() << "\t\tSectionID: " << SectionID << " Offset: " << Offset @@ -1337,6 +1338,7 @@ void RuntimeDyldELF::processRelocationRef(unsigned SectionID, else addRelocationForSection(RE, Value.SectionID); } + return ++RelI; } void RuntimeDyldELF::updateGOTEntries(StringRef Name, uint64_t Addr) { diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h index f7f43b4069b..9c81d071d2f 100644 --- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h +++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h @@ -133,10 +133,10 @@ public: {} void resolveRelocation(const RelocationEntry &RE, uint64_t Value) override; - void processRelocationRef(unsigned SectionID, RelocationRef RelI, - ObjectImage &Obj, ObjSectionToIDMap &ObjSectionToID, - const SymbolTableMap &Symbols, - StubMap &Stubs) override; + relocation_iterator + processRelocationRef(unsigned SectionID, relocation_iterator RelI, + ObjectImage &Obj, ObjSectionToIDMap &ObjSectionToID, + const SymbolTableMap &Symbols, StubMap &Stubs) override; bool isCompatibleFormat(const ObjectBuffer *Buffer) const override; bool isCompatibleFile(const object::ObjectFile *Buffer) const override; void registerEHFrames() override; diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h index 0b7de17a6e9..504a3ff6703 100644 --- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h +++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h @@ -300,12 +300,10 @@ protected: /// \brief Parses the object file relocation and stores it to Relocations /// or SymbolRelocations (this depends on the object file type). - virtual void processRelocationRef(unsigned SectionID, - RelocationRef RelI, - ObjectImage &Obj, - ObjSectionToIDMap &ObjSectionToID, - const SymbolTableMap &Symbols, - StubMap &Stubs) = 0; + virtual relocation_iterator + processRelocationRef(unsigned SectionID, relocation_iterator RelI, + ObjectImage &Obj, ObjSectionToIDMap &ObjSectionToID, + const SymbolTableMap &Symbols, StubMap &Stubs) = 0; /// \brief Resolve relocations to external symbols. void resolveExternalSymbols(); @@ -321,7 +319,8 @@ protected: uint64_t& DataSizeRW); // \brief Compute the stub buffer size required for a section - unsigned computeSectionStubBufSize(ObjectImage &Obj, const SectionRef &Section); + unsigned computeSectionStubBufSize(ObjectImage &Obj, + const SectionRef &Section); public: RuntimeDyldImpl(RTDyldMemoryManager *mm) diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp index 62de7b707cd..0f9fc9169db 100644 --- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp +++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp @@ -320,15 +320,17 @@ bool RuntimeDyldMachO::resolveARMRelocation(uint8_t *LocalAddress, return false; } -void RuntimeDyldMachO::processRelocationRef(unsigned SectionID, - RelocationRef RelI, - ObjectImage &Obj, - ObjSectionToIDMap &ObjSectionToID, - const SymbolTableMap &Symbols, - StubMap &Stubs) { +relocation_iterator +RuntimeDyldMachO::processRelocationRef(unsigned SectionID, + relocation_iterator RelI, + ObjectImage &Obj, + ObjSectionToIDMap &ObjSectionToID, + const SymbolTableMap &Symbols, + StubMap &Stubs) { const ObjectFile *OF = Obj.getObjectFile(); const MachOObjectFile *MachO = static_cast(OF); - MachO::any_relocation_info RE= MachO->getRelocation(RelI.getRawDataRefImpl()); + MachO::any_relocation_info RE = + MachO->getRelocation(RelI->getRawDataRefImpl()); uint32_t RelType = MachO->getAnyRelocationType(RE); @@ -339,7 +341,7 @@ void RuntimeDyldMachO::processRelocationRef(unsigned SectionID, // Note: This will fail horribly where the relocations *do* need to be // applied, but that was already the case. if (MachO->isRelocationScattered(RE)) - return; + return ++RelI; RelocationValueRef Value; SectionEntry &Section = Sections[SectionID]; @@ -348,7 +350,7 @@ void RuntimeDyldMachO::processRelocationRef(unsigned SectionID, bool IsPCRel = MachO->getAnyRelocationPCRel(RE); unsigned Size = MachO->getAnyRelocationLength(RE); uint64_t Offset; - RelI.getOffset(Offset); + RelI->getOffset(Offset); uint8_t *LocalAddress = Section.Address + Offset; unsigned NumBytes = 1 << Size; uint64_t Addend = 0; @@ -356,7 +358,7 @@ void RuntimeDyldMachO::processRelocationRef(unsigned SectionID, if (isExtern) { // Obtain the symbol name which is referenced in the relocation - symbol_iterator Symbol = RelI.getSymbol(); + symbol_iterator Symbol = RelI->getSymbol(); StringRef TargetName; Symbol->getName(TargetName); // First search for the symbol in the local symbol table @@ -443,6 +445,7 @@ void RuntimeDyldMachO::processRelocationRef(unsigned SectionID, else addRelocationForSection(RE, Value.SectionID); } + return ++RelI; } diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h index 1a285ffbfbd..48b0481ce58 100644 --- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h +++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h @@ -88,10 +88,10 @@ public: RuntimeDyldMachO(RTDyldMemoryManager *mm) : RuntimeDyldImpl(mm) {} void resolveRelocation(const RelocationEntry &RE, uint64_t Value) override; - void processRelocationRef(unsigned SectionID, RelocationRef RelI, - ObjectImage &Obj, ObjSectionToIDMap &ObjSectionToID, - const SymbolTableMap &Symbols, - StubMap &Stubs) override; + relocation_iterator + processRelocationRef(unsigned SectionID, relocation_iterator RelI, + ObjectImage &Obj, ObjSectionToIDMap &ObjSectionToID, + const SymbolTableMap &Symbols, StubMap &Stubs) override; bool isCompatibleFormat(const ObjectBuffer *Buffer) const override; bool isCompatibleFile(const object::ObjectFile *Obj) const override; void registerEHFrames() override; diff --git a/lib/Object/COFFObjectFile.cpp b/lib/Object/COFFObjectFile.cpp index 5ad8f8443f7..43913e44857 100644 --- a/lib/Object/COFFObjectFile.cpp +++ b/lib/Object/COFFObjectFile.cpp @@ -410,6 +410,11 @@ relocation_iterator COFFObjectFile::section_rel_end(DataRefImpl Ref) const { return relocation_iterator(RelocationRef(Ret, this)); } +bool COFFObjectFile::section_rel_empty(DataRefImpl Ref) const { + const coff_section *Sec = toSec(Ref); + return Sec->NumberOfRelocations == 0; +} + // Initialize the pointer to the symbol table. error_code COFFObjectFile::initSymbolTablePtr() { if (error_code EC = getObject( diff --git a/lib/Object/MachOObjectFile.cpp b/lib/Object/MachOObjectFile.cpp index 6b1dd875958..b75b3e33b07 100644 --- a/lib/Object/MachOObjectFile.cpp +++ b/lib/Object/MachOObjectFile.cpp @@ -818,6 +818,16 @@ MachOObjectFile::section_rel_end(DataRefImpl Sec) const { return relocation_iterator(RelocationRef(Ret, this)); } +bool MachOObjectFile::section_rel_empty(DataRefImpl Sec) const { + if (is64Bit()) { + MachO::section_64 Sect = getSection64(Sec); + return Sect.nreloc == 0; + } else { + MachO::section Sect = getSection(Sec); + return Sect.nreloc == 0; + } +} + void MachOObjectFile::moveRelocationNext(DataRefImpl &Rel) const { const MachO::any_relocation_info *P = reinterpret_cast(Rel.p);