From e87dadc44b1544c35e13cf48dfe167109929a944 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Tue, 30 Apr 2013 15:40:54 +0000 Subject: Fix Addend computation for non external relocations on Macho. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@180790 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Object/MachO.h | 1 + .../RuntimeDyld/RuntimeDyldMachO.cpp | 38 ++++++---------------- lib/Object/MachOObjectFile.cpp | 10 ++++++ test/ExecutionEngine/MCJIT/non-extern-addend.ll | 12 +++++++ 4 files changed, 33 insertions(+), 28 deletions(-) create mode 100644 test/ExecutionEngine/MCJIT/non-extern-addend.ll diff --git a/include/llvm/Object/MachO.h b/include/llvm/Object/MachO.h index 17a8fc2bff..14cd4d767d 100644 --- a/include/llvm/Object/MachO.h +++ b/include/llvm/Object/MachO.h @@ -130,6 +130,7 @@ public: unsigned getAnyRelocationPCRel(const macho::RelocationEntry &RE) const; unsigned getAnyRelocationLength(const macho::RelocationEntry &RE) const; unsigned getAnyRelocationType(const macho::RelocationEntry &RE) const; + SectionRef getRelocationSection(const macho::RelocationEntry &RE) const; // Walk load commands. LoadCommandInfo getFirstLoadCommandInfo() const; diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp index 6054b2ab79..b3467a9ab3 100644 --- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp +++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp @@ -232,12 +232,12 @@ void RuntimeDyldMachO::processRelocationRef(unsigned SectionID, unsigned Size = MachO->getAnyRelocationLength(RE); uint64_t Offset; RelI.getOffset(Offset); - if (isExtern) { - uint8_t *LocalAddress = Section.Address + Offset; - unsigned NumBytes = 1 << Size; - uint64_t Addend = 0; - memcpy(&Addend, LocalAddress, NumBytes); + uint8_t *LocalAddress = Section.Address + Offset; + unsigned NumBytes = 1 << Size; + uint64_t Addend = 0; + memcpy(&Addend, LocalAddress, NumBytes); + if (isExtern) { // Obtain the symbol name which is referenced in the relocation SymbolRef Symbol; RelI.getSymbol(Symbol); @@ -260,29 +260,11 @@ void RuntimeDyldMachO::processRelocationRef(unsigned SectionID, } } } else { - error_code err; - uint8_t sectionIndex = static_cast(RelType & 0xFF); - section_iterator si = Obj.begin_sections(), - se = Obj.end_sections(); - for (uint8_t i = 1; i < sectionIndex; i++) { - error_code err; - si.increment(err); - if (si == se) - break; - } - assert(si != se && "No section containing relocation!"); - Value.SectionID = findOrEmitSection(Obj, *si, true, ObjSectionToID); - Value.Addend = 0; - // FIXME: The size and type of the relocation determines if we can - // encode an Addend in the target location itself, and if so, how many - // bytes we should read in order to get it. We don't yet support doing - // that, and just assuming it's sizeof(intptr_t) is blatantly wrong. - //Value.Addend = *(const intptr_t *)Target; - if (Value.Addend) { - // The MachO addend is an offset from the current section. We need it - // to be an offset from the destination section - Value.Addend += Section.ObjAddress - Sections[Value.SectionID].ObjAddress; - } + SectionRef Sec = MachO->getRelocationSection(RE); + Value.SectionID = findOrEmitSection(Obj, Sec, true, ObjSectionToID); + uint64_t Addr; + Sec.getAddress(Addr); + Value.Addend = Addend - Addr; } if (Arch == Triple::arm && (RelType & 0xf) == macho::RIT_ARM_Branch24Bit) { diff --git a/lib/Object/MachOObjectFile.cpp b/lib/Object/MachOObjectFile.cpp index f6840b8c15..dfd8d3d3dd 100644 --- a/lib/Object/MachOObjectFile.cpp +++ b/lib/Object/MachOObjectFile.cpp @@ -1414,6 +1414,16 @@ MachOObjectFile::getAnyRelocationType(const macho::RelocationEntry &RE) const { return getPlainRelocationType(this, RE); } +SectionRef +MachOObjectFile::getRelocationSection(const macho::RelocationEntry &RE) const { + if (isRelocationScattered(RE) || getPlainRelocationExternal(RE)) + return *end_sections(); + unsigned SecNum = getPlainRelocationSymbolNum(RE) - 1; + DataRefImpl DRI; + DRI.d.a = SecNum; + return SectionRef(DRI, this); +} + MachOObjectFile::LoadCommandInfo MachOObjectFile::getFirstLoadCommandInfo() const { MachOObjectFile::LoadCommandInfo Load; diff --git a/test/ExecutionEngine/MCJIT/non-extern-addend.ll b/test/ExecutionEngine/MCJIT/non-extern-addend.ll new file mode 100644 index 0000000000..3a6e634412 --- /dev/null +++ b/test/ExecutionEngine/MCJIT/non-extern-addend.ll @@ -0,0 +1,12 @@ +; RUN: %lli_mcjit %s > /dev/null + +define i32 @foo(i32 %X, i32 %Y, double %A) { + %cond212 = fcmp ueq double %A, 2.000000e+00 ; [#uses=1] + %cast110 = zext i1 %cond212 to i32 ; [#uses=1] + ret i32 %cast110 +} + +define i32 @main() { + %reg212 = call i32 @foo( i32 0, i32 1, double 1.000000e+00 ) ; [#uses=1] + ret i32 %reg212 +} -- cgit v1.2.3