diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp index 7884f46a378..d843e9a7430 100644 --- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp +++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp @@ -391,26 +391,14 @@ void RuntimeDyldImpl::reassignSectionAddress(unsigned SectionID, Sections[SectionID].LoadAddress = Addr; } -void RuntimeDyldImpl::resolveRelocationEntry(const RelocationEntry &RE, - uint64_t Value) { - // Ignore relocations for sections that were not loaded - if (Sections[RE.SectionID].Address != 0) { - DEBUG(dbgs() << "\tSectionID: " << RE.SectionID - << " + " << RE.Offset << " (" - << format("%p", Sections[RE.SectionID].Address + RE.Offset) << ")" - << " RelType: " << RE.RelType - << " Addend: " << RE.Addend - << "\n"); - - resolveRelocation(Sections[RE.SectionID], RE.Offset, - Value, RE.RelType, RE.Addend); - } -} - void RuntimeDyldImpl::resolveRelocationList(const RelocationList &Relocs, uint64_t Value) { for (unsigned i = 0, e = Relocs.size(); i != e; ++i) { - resolveRelocationEntry(Relocs[i], Value); + const RelocationEntry &RE = Relocs[i]; + // Ignore relocations for sections that were not loaded + if (Sections[RE.SectionID].Address == 0) + continue; + resolveRelocation(RE, Value); } } diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp index bb5f84e4b6b..d52bcadd208 100644 --- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp +++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp @@ -560,6 +560,12 @@ void RuntimeDyldELF::resolvePPC64Relocation(const SectionEntry &Section, } } +void RuntimeDyldELF::resolveRelocation(const RelocationEntry &RE, + uint64_t Value) { + const SectionEntry &Section = Sections[RE.SectionID]; + return resolveRelocation(Section, RE.Offset, Value, RE.RelType, RE.Addend); +} + void RuntimeDyldELF::resolveRelocation(const SectionEntry &Section, uint64_t Offset, uint64_t Value, diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h index d71e8b70307..835b66fb516 100644 --- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h +++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h @@ -31,6 +31,12 @@ namespace { } // end anonymous namespace class RuntimeDyldELF : public RuntimeDyldImpl { + void resolveRelocation(const SectionEntry &Section, + uint64_t Offset, + uint64_t Value, + uint32_t Type, + int64_t Addend); + protected: void resolveX86_64Relocation(const SectionEntry &Section, uint64_t Offset, @@ -62,11 +68,7 @@ protected: uint32_t Type, int64_t Addend); - virtual void resolveRelocation(const SectionEntry &Section, - uint64_t Offset, - uint64_t Value, - uint32_t Type, - int64_t Addend); + virtual void resolveRelocation(const RelocationEntry &RE, uint64_t Value); virtual void processRelocationRef(unsigned SectionID, relocation_iterator RelI, diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h index 46771d05a33..d0022c196d6 100644 --- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h +++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h @@ -89,8 +89,20 @@ public: /// used to make a relocation section relative instead of symbol relative. intptr_t Addend; + /// True if this is a PCRel relocation (MachO specific). + bool IsPCRel; + + /// The size of this relocation (MachO specific). + unsigned Size; + RelocationEntry(unsigned id, uint64_t offset, uint32_t type, int64_t addend) - : SectionID(id), Offset(offset), RelType(type), Addend(addend) {} + : SectionID(id), Offset(offset), RelType(type), Addend(addend), + IsPCRel(false), Size(0) {} + + RelocationEntry(unsigned id, uint64_t offset, uint32_t type, int64_t addend, + bool IsPCRel, unsigned Size) + : SectionID(id), Offset(offset), RelType(type), Addend(addend), + IsPCRel(IsPCRel), Size(Size) {} }; class RelocationValueRef { @@ -257,7 +269,6 @@ protected: /// \brief Resolves relocations from Relocs list with address from Value. void resolveRelocationList(const RelocationList &Relocs, uint64_t Value); - void resolveRelocationEntry(const RelocationEntry &RE, uint64_t Value); /// \brief A object file specific relocation resolver /// \param Section The section where the relocation is being applied @@ -266,11 +277,7 @@ protected: /// \param Type object file specific relocation type /// \param Addend A constant addend used to compute the value to be stored /// into the relocatable field - virtual void resolveRelocation(const SectionEntry &Section, - uint64_t Offset, - uint64_t Value, - uint32_t Type, - int64_t Addend) = 0; + virtual void resolveRelocation(const RelocationEntry &RE, uint64_t Value) = 0; /// \brief Parses the object file relocation and stores it to Relocations /// or SymbolRelocations (this depends on the object file type). diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp index af55ed34a94..9a6048c410c 100644 --- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp +++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp @@ -21,16 +21,24 @@ using namespace llvm::object; namespace llvm { +void RuntimeDyldMachO::resolveRelocation(const RelocationEntry &RE, + uint64_t Value) { + const SectionEntry &Section = Sections[RE.SectionID]; + return resolveRelocation(Section, RE.Offset, Value, RE.RelType, RE.Addend, + RE.IsPCRel, RE.Size); +} + void RuntimeDyldMachO::resolveRelocation(const SectionEntry &Section, uint64_t Offset, uint64_t Value, uint32_t Type, - int64_t Addend) { + int64_t Addend, + bool isPCRel, + unsigned LogSize) { uint8_t *LocalAddress = Section.Address + Offset; uint64_t FinalAddress = Section.LoadAddress + Offset; - bool isPCRel = (Type >> 24) & 1; - unsigned MachoType = (Type >> 28) & 0xf; - unsigned Size = 1 << ((Type >> 25) & 3); + unsigned MachoType = Type; + unsigned Size = 1 << LogSize; DEBUG(dbgs() << "resolveRelocation LocalAddress: " << format("%p", LocalAddress) @@ -220,6 +228,8 @@ void RuntimeDyldMachO::processRelocationRef(unsigned SectionID, SectionEntry &Section = Sections[SectionID]; bool isExtern = MachO->getPlainRelocationExternal(RE); + bool IsPCRel = MachO->getAnyRelocationPCRel(RE); + unsigned Size = MachO->getAnyRelocationLength(RE); if (isExtern) { // Obtain the symbol name which is referenced in the relocation SymbolRef Symbol; @@ -276,7 +286,7 @@ void RuntimeDyldMachO::processRelocationRef(unsigned SectionID, if (i != Stubs.end()) resolveRelocation(Section, Offset, (uint64_t)Section.Address + i->second, - RelType, 0); + RelType, 0, IsPCRel, Size); else { // Create a new stub function. Stubs[Value] = Section.StubOffset; @@ -290,11 +300,12 @@ void RuntimeDyldMachO::processRelocationRef(unsigned SectionID, addRelocationForSection(RE, Value.SectionID); resolveRelocation(Section, Offset, (uint64_t)Section.Address + Section.StubOffset, - RelType, 0); + RelType, 0, IsPCRel, Size); Section.StubOffset += getMaxStubSize(); } } else { - RelocationEntry RE(SectionID, Offset, RelType, Value.Addend); + RelocationEntry RE(SectionID, Offset, RelType, Value.Addend, + IsPCRel, Size); if (Value.SymbolName) addRelocationForSymbol(RE, Value.SymbolName); else diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h index 8f1658cbdf5..c82b2f93ced 100644 --- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h +++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h @@ -55,12 +55,15 @@ protected: const SymbolTableMap &Symbols, StubMap &Stubs); + void resolveRelocation(const SectionEntry &Section, + uint64_t Offset, + uint64_t Value, + uint32_t Type, + int64_t Addend, + bool isPCRel, + unsigned Size); public: - virtual void resolveRelocation(const SectionEntry &Section, - uint64_t Offset, - uint64_t Value, - uint32_t Type, - int64_t Addend); + virtual void resolveRelocation(const RelocationEntry &RE, uint64_t Value); RuntimeDyldMachO(RTDyldMemoryManager *mm) : RuntimeDyldImpl(mm) {} diff --git a/test/ExecutionEngine/MCJIT/2013-04-04-RelocAddend.ll b/test/ExecutionEngine/MCJIT/2013-04-04-RelocAddend.ll index 3f402c59311..d2f31bb33ca 100644 --- a/test/ExecutionEngine/MCJIT/2013-04-04-RelocAddend.ll +++ b/test/ExecutionEngine/MCJIT/2013-04-04-RelocAddend.ll @@ -1,4 +1,5 @@ ; RUN: %lli_mcjit %s +; XFAIL: darwin ; ; Verify relocations to global symbols with addend work correctly. ; diff --git a/test/ExecutionEngine/MCJIT/lit.local.cfg b/test/ExecutionEngine/MCJIT/lit.local.cfg index fc29f651aa1..7bf401b7d43 100644 --- a/test/ExecutionEngine/MCJIT/lit.local.cfg +++ b/test/ExecutionEngine/MCJIT/lit.local.cfg @@ -14,10 +14,7 @@ if ('X86' in targets) | ('ARM' in targets) | ('Mips' in targets) | \ else: config.unsupported = True -if root.host_arch not in ['x86', 'x86_64', 'ARM', 'Mips', 'PowerPC']: - config.unsupported = True - -if root.host_os in ['Darwin']: +if root.host_arch not in ['i386', 'x86', 'x86_64', 'ARM', 'Mips', 'PowerPC']: config.unsupported = True if 'powerpc' in root.target_triple and not 'powerpc64' in root.target_triple: diff --git a/test/ExecutionEngine/MCJIT/test-common-symbols-alignment.ll b/test/ExecutionEngine/MCJIT/test-common-symbols-alignment.ll index 989a4734233..43256c4492c 100644 --- a/test/ExecutionEngine/MCJIT/test-common-symbols-alignment.ll +++ b/test/ExecutionEngine/MCJIT/test-common-symbols-alignment.ll @@ -1,4 +1,5 @@ ; RUN: %lli_mcjit -O0 %s +; XFAIL: darwin ; This test checks that common symbols have been allocated addresses honouring ; the alignment requirement. diff --git a/test/ExecutionEngine/MCJIT/test-global-ctors.ll b/test/ExecutionEngine/MCJIT/test-global-ctors.ll index 4510d9b6a49..947d8f5d423 100644 --- a/test/ExecutionEngine/MCJIT/test-global-ctors.ll +++ b/test/ExecutionEngine/MCJIT/test-global-ctors.ll @@ -1,4 +1,5 @@ ; RUN: %lli_mcjit %s > /dev/null +; XFAIL: darwin @var = global i32 1, align 4 @llvm.global_ctors = appending global [1 x { i32, void ()* }] [{ i32, void ()* } { i32 65535, void ()* @ctor_func }] @llvm.global_dtors = appending global [1 x { i32, void ()* }] [{ i32, void ()* } { i32 65535, void ()* @dtor_func }]