diff --git a/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOX86_64.h b/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOX86_64.h index 0f1407dd8de..bc482298324 100644 --- a/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOX86_64.h +++ b/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOX86_64.h @@ -157,10 +157,10 @@ private: Expected processSubtractRelocation(unsigned SectionID, relocation_iterator RelI, - const ObjectFile &BaseObjT, + const MachOObjectFile &BaseObj, ObjSectionToIDMap &ObjSectionToID) { const MachOObjectFile &Obj = - static_cast(BaseObjT); + static_cast(BaseObj); MachO::any_relocation_info RE = Obj.getRelocation(RelI->getRawDataRefImpl()); @@ -168,23 +168,60 @@ private: uint64_t Offset = RelI->getOffset(); uint8_t *LocalAddress = Sections[SectionID].getAddressWithOffset(Offset); unsigned NumBytes = 1 << Size; - - Expected SubtrahendNameOrErr = RelI->getSymbol()->getName(); - if (!SubtrahendNameOrErr) - return SubtrahendNameOrErr.takeError(); - auto SubtrahendI = GlobalSymbolTable.find(*SubtrahendNameOrErr); - unsigned SectionBID = SubtrahendI->second.getSectionID(); - uint64_t SectionBOffset = SubtrahendI->second.getOffset(); int64_t Addend = SignExtend64(readBytesUnaligned(LocalAddress, NumBytes), NumBytes * 8); + unsigned SectionBID = ~0U; + uint64_t SectionBOffset = 0; + + MachO::any_relocation_info RelInfo = + Obj.getRelocation(RelI->getRawDataRefImpl()); + + bool AIsExternal = BaseObj.getPlainRelocationExternal(RelInfo); + + if (AIsExternal) { + Expected SubtrahendNameOrErr = RelI->getSymbol()->getName(); + if (!SubtrahendNameOrErr) + return SubtrahendNameOrErr.takeError(); + auto SubtrahendI = GlobalSymbolTable.find(*SubtrahendNameOrErr); + SectionBID = SubtrahendI->second.getSectionID(); + SectionBOffset = SubtrahendI->second.getOffset(); + } else { + SectionRef SecB = Obj.getAnyRelocationSection(RelInfo); + bool IsCode = SecB.isText(); + Expected SectionBIDOrErr = + findOrEmitSection(Obj, SecB, IsCode, ObjSectionToID); + if (!SectionBIDOrErr) + return SectionBIDOrErr.takeError(); + SectionBID = *SectionBIDOrErr; + Addend += SecB.getAddress(); + } + ++RelI; - Expected MinuendNameOrErr = RelI->getSymbol()->getName(); - if (!MinuendNameOrErr) - return MinuendNameOrErr.takeError(); - auto MinuendI = GlobalSymbolTable.find(*MinuendNameOrErr); - unsigned SectionAID = MinuendI->second.getSectionID(); - uint64_t SectionAOffset = MinuendI->second.getOffset(); + + unsigned SectionAID = ~0U; + uint64_t SectionAOffset = 0; + + RelInfo = Obj.getRelocation(RelI->getRawDataRefImpl()); + + bool BIsExternal = BaseObj.getPlainRelocationExternal(RelInfo); + if (BIsExternal) { + Expected MinuendNameOrErr = RelI->getSymbol()->getName(); + if (!MinuendNameOrErr) + return MinuendNameOrErr.takeError(); + auto MinuendI = GlobalSymbolTable.find(*MinuendNameOrErr); + SectionAID = MinuendI->second.getSectionID(); + SectionAOffset = MinuendI->second.getOffset(); + } else { + SectionRef SecA = Obj.getAnyRelocationSection(RelInfo); + bool IsCode = SecA.isText(); + Expected SectionAIDOrErr = + findOrEmitSection(Obj, SecA, IsCode, ObjSectionToID); + if (!SectionAIDOrErr) + return SectionAIDOrErr.takeError(); + SectionAID = *SectionAIDOrErr; + Addend -= SecA.getAddress(); + } RelocationEntry R(SectionID, Offset, MachO::X86_64_RELOC_SUBTRACTOR, (uint64_t)Addend, SectionAID, SectionAOffset, SectionBID, SectionBOffset, diff --git a/test/ExecutionEngine/RuntimeDyld/X86/MachO_x86-64_PIC_relocations.s b/test/ExecutionEngine/RuntimeDyld/X86/MachO_x86-64_PIC_relocations.s index 8a50ede9027..f050c3d846c 100644 --- a/test/ExecutionEngine/RuntimeDyld/X86/MachO_x86-64_PIC_relocations.s +++ b/test/ExecutionEngine/RuntimeDyld/X86/MachO_x86-64_PIC_relocations.s @@ -62,11 +62,26 @@ z2: .globl abssym abssym = 0xdeadbeef - # Test subtractor relocations. -# rtdyld-check: *{8}z3 = z4 - z5 + 4 -z3: +# Test subtractor relocations between named symbols. +# rtdyld-check: *{8}z3a = z4 - z5 + 4 +z3a: .quad z4 - z5 + 4 +# Test subtractor relocations between anonymous symbols. +# rtdyld-check: *{8}z3b = (section_addr(test_x86-64.o, _tmp3) + 4) - (section_addr(test_x86-64.o, _tmp4)) + 8 +z3b: + .quad Lanondiff_1 - Lanondiff_2 + 8 + +# Test subtractor relocations between named and anonymous symbols. +# rtdyld-check: *{8}z3c = z4 - (section_addr(test_x86-64.o, _tmp4)) + 12 +z3c: + .quad z4 - Lanondiff_2 + 12 + +# Test subtractor relocations between anonymous and named symbols. +# rtdyld-check: *{8}z3d = (section_addr(test_x86-64.o, _tmp3) + 4) - z4 + 16 +z3d: + .quad Lanondiff_1 - z4 + 16 + .section __DATA,_tmp1 z4: .byte 1 @@ -75,4 +90,13 @@ z4: z5: .byte 1 + .section __DATA,_tmp3 + .long 1 # padding to make sure we handle non-zero offsets. +Lanondiff_1: + .byte 1 + + .section __DATA,_tmp4 +Lanondiff_2: + .byte 1 + .subsections_via_symbols