diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOX86_64.h | 51 |
1 files changed, 50 insertions, 1 deletions
diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOX86_64.h b/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOX86_64.h index dd56e72f914..188e2c65243 100644 --- a/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOX86_64.h +++ b/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOX86_64.h @@ -39,6 +39,10 @@ public: static_cast<const MachOObjectFile &>(BaseObjT); MachO::any_relocation_info RelInfo = Obj.getRelocation(RelI->getRawDataRefImpl()); + uint32_t RelType = Obj.getAnyRelocationType(RelInfo); + + if (RelType == MachO::X86_64_RELOC_SUBTRACTOR) + return processSubtractRelocation(SectionID, RelI, Obj, ObjSectionToID); assert(!Obj.isRelocationScattered(RelInfo) && "Scattered relocations not supported on X86_64"); @@ -91,9 +95,17 @@ public: case MachO::X86_64_RELOC_BRANCH: writeBytesUnaligned(Value + RE.Addend, LocalAddress, 1 << RE.Size); break; + case MachO::X86_64_RELOC_SUBTRACTOR: { + uint64_t SectionABase = Sections[RE.Sections.SectionA].LoadAddress; + uint64_t SectionBBase = Sections[RE.Sections.SectionB].LoadAddress; + assert((Value == SectionABase || Value == SectionBBase) && + "Unexpected SUBTRACTOR relocation value."); + Value = SectionABase - SectionBBase + RE.Addend; + writeBytesUnaligned(Value, LocalAddress, 1 << RE.Size); + break; + } case MachO::X86_64_RELOC_GOT_LOAD: case MachO::X86_64_RELOC_GOT: - case MachO::X86_64_RELOC_SUBTRACTOR: case MachO::X86_64_RELOC_TLV: Error("Relocation type not implemented yet!"); } @@ -130,6 +142,43 @@ private: MachO::X86_64_RELOC_UNSIGNED, RE.Addend, true, 2); resolveRelocation(TargetRE, (uint64_t)Addr); } + + relocation_iterator + processSubtractRelocation(unsigned SectionID, relocation_iterator RelI, + const ObjectFile &BaseObjT, + ObjSectionToIDMap &ObjSectionToID) { + const MachOObjectFile &Obj = + static_cast<const MachOObjectFile&>(BaseObjT); + MachO::any_relocation_info RE = + Obj.getRelocation(RelI->getRawDataRefImpl()); + + unsigned Size = Obj.getAnyRelocationLength(RE); + uint64_t Offset = RelI->getOffset(); + ErrorOr<StringRef> SubtrahendNameOrErr = RelI->getSymbol()->getName(); + if (auto EC = SubtrahendNameOrErr.getError()) + report_fatal_error(EC.message()); + auto SubtrahendI = GlobalSymbolTable.find(*SubtrahendNameOrErr); + unsigned SectionBID = SubtrahendI->second.getSectionID(); + uint64_t SectionBOffset = SubtrahendI->second.getOffset(); + + ++RelI; + ErrorOr<StringRef> MinuendNameOrErr = RelI->getSymbol()->getName(); + if (auto EC = MinuendNameOrErr.getError()) + report_fatal_error(EC.message()); + auto MinuendI = GlobalSymbolTable.find(*MinuendNameOrErr); + unsigned SectionAID = MinuendI->second.getSectionID(); + uint64_t SectionAOffset = MinuendI->second.getOffset(); + + uint64_t Addend = SectionAOffset - SectionBOffset; + RelocationEntry R(SectionID, Offset, MachO::X86_64_RELOC_SUBTRACTOR, Addend, + SectionAID, SectionAOffset, SectionBID, SectionBOffset, + false, Size); + + addRelocationForSection(R, SectionAID); + + return ++RelI; + } + }; } |