10b57cec5SDimitry Andric //===-- RuntimeDyldMachO.cpp - Run-time dynamic linker for MC-JIT -*- C++ -*-=//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // Implementation of the MC-JIT runtime dynamic linker.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric
130b57cec5SDimitry Andric #include "RuntimeDyldMachO.h"
140b57cec5SDimitry Andric #include "Targets/RuntimeDyldMachOAArch64.h"
150b57cec5SDimitry Andric #include "Targets/RuntimeDyldMachOARM.h"
160b57cec5SDimitry Andric #include "Targets/RuntimeDyldMachOI386.h"
170b57cec5SDimitry Andric #include "Targets/RuntimeDyldMachOX86_64.h"
180b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h"
190b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h"
200b57cec5SDimitry Andric
210b57cec5SDimitry Andric using namespace llvm;
220b57cec5SDimitry Andric using namespace llvm::object;
230b57cec5SDimitry Andric
240b57cec5SDimitry Andric #define DEBUG_TYPE "dyld"
250b57cec5SDimitry Andric
260b57cec5SDimitry Andric namespace {
270b57cec5SDimitry Andric
280b57cec5SDimitry Andric class LoadedMachOObjectInfo final
290b57cec5SDimitry Andric : public LoadedObjectInfoHelper<LoadedMachOObjectInfo,
300b57cec5SDimitry Andric RuntimeDyld::LoadedObjectInfo> {
310b57cec5SDimitry Andric public:
LoadedMachOObjectInfo(RuntimeDyldImpl & RTDyld,ObjSectionToIDMap ObjSecToIDMap)320b57cec5SDimitry Andric LoadedMachOObjectInfo(RuntimeDyldImpl &RTDyld,
330b57cec5SDimitry Andric ObjSectionToIDMap ObjSecToIDMap)
340b57cec5SDimitry Andric : LoadedObjectInfoHelper(RTDyld, std::move(ObjSecToIDMap)) {}
350b57cec5SDimitry Andric
360b57cec5SDimitry Andric OwningBinary<ObjectFile>
getObjectForDebug(const ObjectFile & Obj) const370b57cec5SDimitry Andric getObjectForDebug(const ObjectFile &Obj) const override {
380b57cec5SDimitry Andric return OwningBinary<ObjectFile>();
390b57cec5SDimitry Andric }
400b57cec5SDimitry Andric };
410b57cec5SDimitry Andric
420b57cec5SDimitry Andric }
430b57cec5SDimitry Andric
440b57cec5SDimitry Andric namespace llvm {
450b57cec5SDimitry Andric
memcpyAddend(const RelocationEntry & RE) const460b57cec5SDimitry Andric int64_t RuntimeDyldMachO::memcpyAddend(const RelocationEntry &RE) const {
470b57cec5SDimitry Andric unsigned NumBytes = 1 << RE.Size;
480b57cec5SDimitry Andric uint8_t *Src = Sections[RE.SectionID].getAddress() + RE.Offset;
490b57cec5SDimitry Andric
500b57cec5SDimitry Andric return static_cast<int64_t>(readBytesUnaligned(Src, NumBytes));
510b57cec5SDimitry Andric }
520b57cec5SDimitry Andric
530b57cec5SDimitry Andric Expected<relocation_iterator>
processScatteredVANILLA(unsigned SectionID,relocation_iterator RelI,const ObjectFile & BaseObjT,RuntimeDyldMachO::ObjSectionToIDMap & ObjSectionToID,bool TargetIsLocalThumbFunc)540b57cec5SDimitry Andric RuntimeDyldMachO::processScatteredVANILLA(
550b57cec5SDimitry Andric unsigned SectionID, relocation_iterator RelI,
560b57cec5SDimitry Andric const ObjectFile &BaseObjT,
570b57cec5SDimitry Andric RuntimeDyldMachO::ObjSectionToIDMap &ObjSectionToID,
580b57cec5SDimitry Andric bool TargetIsLocalThumbFunc) {
590b57cec5SDimitry Andric const MachOObjectFile &Obj =
600b57cec5SDimitry Andric static_cast<const MachOObjectFile&>(BaseObjT);
610b57cec5SDimitry Andric MachO::any_relocation_info RE =
620b57cec5SDimitry Andric Obj.getRelocation(RelI->getRawDataRefImpl());
630b57cec5SDimitry Andric
640b57cec5SDimitry Andric SectionEntry &Section = Sections[SectionID];
650b57cec5SDimitry Andric uint32_t RelocType = Obj.getAnyRelocationType(RE);
660b57cec5SDimitry Andric bool IsPCRel = Obj.getAnyRelocationPCRel(RE);
670b57cec5SDimitry Andric unsigned Size = Obj.getAnyRelocationLength(RE);
680b57cec5SDimitry Andric uint64_t Offset = RelI->getOffset();
690b57cec5SDimitry Andric uint8_t *LocalAddress = Section.getAddressWithOffset(Offset);
700b57cec5SDimitry Andric unsigned NumBytes = 1 << Size;
710b57cec5SDimitry Andric int64_t Addend = readBytesUnaligned(LocalAddress, NumBytes);
720b57cec5SDimitry Andric
730b57cec5SDimitry Andric unsigned SymbolBaseAddr = Obj.getScatteredRelocationValue(RE);
740b57cec5SDimitry Andric section_iterator TargetSI = getSectionByAddress(Obj, SymbolBaseAddr);
750b57cec5SDimitry Andric assert(TargetSI != Obj.section_end() && "Can't find section for symbol");
760b57cec5SDimitry Andric uint64_t SectionBaseAddr = TargetSI->getAddress();
770b57cec5SDimitry Andric SectionRef TargetSection = *TargetSI;
780b57cec5SDimitry Andric bool IsCode = TargetSection.isText();
790b57cec5SDimitry Andric uint32_t TargetSectionID = ~0U;
800b57cec5SDimitry Andric if (auto TargetSectionIDOrErr =
810b57cec5SDimitry Andric findOrEmitSection(Obj, TargetSection, IsCode, ObjSectionToID))
820b57cec5SDimitry Andric TargetSectionID = *TargetSectionIDOrErr;
830b57cec5SDimitry Andric else
840b57cec5SDimitry Andric return TargetSectionIDOrErr.takeError();
850b57cec5SDimitry Andric
860b57cec5SDimitry Andric Addend -= SectionBaseAddr;
870b57cec5SDimitry Andric RelocationEntry R(SectionID, Offset, RelocType, Addend, IsPCRel, Size);
880b57cec5SDimitry Andric R.IsTargetThumbFunc = TargetIsLocalThumbFunc;
890b57cec5SDimitry Andric
900b57cec5SDimitry Andric addRelocationForSection(R, TargetSectionID);
910b57cec5SDimitry Andric
920b57cec5SDimitry Andric return ++RelI;
930b57cec5SDimitry Andric }
940b57cec5SDimitry Andric
950b57cec5SDimitry Andric
960b57cec5SDimitry Andric Expected<RelocationValueRef>
getRelocationValueRef(const ObjectFile & BaseTObj,const relocation_iterator & RI,const RelocationEntry & RE,ObjSectionToIDMap & ObjSectionToID)970b57cec5SDimitry Andric RuntimeDyldMachO::getRelocationValueRef(
980b57cec5SDimitry Andric const ObjectFile &BaseTObj, const relocation_iterator &RI,
990b57cec5SDimitry Andric const RelocationEntry &RE, ObjSectionToIDMap &ObjSectionToID) {
1000b57cec5SDimitry Andric
1010b57cec5SDimitry Andric const MachOObjectFile &Obj =
1020b57cec5SDimitry Andric static_cast<const MachOObjectFile &>(BaseTObj);
1030b57cec5SDimitry Andric MachO::any_relocation_info RelInfo =
1040b57cec5SDimitry Andric Obj.getRelocation(RI->getRawDataRefImpl());
1050b57cec5SDimitry Andric RelocationValueRef Value;
1060b57cec5SDimitry Andric
1070b57cec5SDimitry Andric bool IsExternal = Obj.getPlainRelocationExternal(RelInfo);
1080b57cec5SDimitry Andric if (IsExternal) {
1090b57cec5SDimitry Andric symbol_iterator Symbol = RI->getSymbol();
1100b57cec5SDimitry Andric StringRef TargetName;
1110b57cec5SDimitry Andric if (auto TargetNameOrErr = Symbol->getName())
1120b57cec5SDimitry Andric TargetName = *TargetNameOrErr;
1130b57cec5SDimitry Andric else
1140b57cec5SDimitry Andric return TargetNameOrErr.takeError();
1150b57cec5SDimitry Andric RTDyldSymbolTable::const_iterator SI =
1160b57cec5SDimitry Andric GlobalSymbolTable.find(TargetName.data());
1170b57cec5SDimitry Andric if (SI != GlobalSymbolTable.end()) {
1180b57cec5SDimitry Andric const auto &SymInfo = SI->second;
1190b57cec5SDimitry Andric Value.SectionID = SymInfo.getSectionID();
1200b57cec5SDimitry Andric Value.Offset = SymInfo.getOffset() + RE.Addend;
1210b57cec5SDimitry Andric } else {
1220b57cec5SDimitry Andric Value.SymbolName = TargetName.data();
1230b57cec5SDimitry Andric Value.Offset = RE.Addend;
1240b57cec5SDimitry Andric }
1250b57cec5SDimitry Andric } else {
1260b57cec5SDimitry Andric SectionRef Sec = Obj.getAnyRelocationSection(RelInfo);
1270b57cec5SDimitry Andric bool IsCode = Sec.isText();
1280b57cec5SDimitry Andric if (auto SectionIDOrErr = findOrEmitSection(Obj, Sec, IsCode,
1290b57cec5SDimitry Andric ObjSectionToID))
1300b57cec5SDimitry Andric Value.SectionID = *SectionIDOrErr;
1310b57cec5SDimitry Andric else
1320b57cec5SDimitry Andric return SectionIDOrErr.takeError();
1330b57cec5SDimitry Andric uint64_t Addr = Sec.getAddress();
1340b57cec5SDimitry Andric Value.Offset = RE.Addend - Addr;
1350b57cec5SDimitry Andric }
1360b57cec5SDimitry Andric
1370b57cec5SDimitry Andric return Value;
1380b57cec5SDimitry Andric }
1390b57cec5SDimitry Andric
makeValueAddendPCRel(RelocationValueRef & Value,const relocation_iterator & RI,unsigned OffsetToNextPC)1400b57cec5SDimitry Andric void RuntimeDyldMachO::makeValueAddendPCRel(RelocationValueRef &Value,
1410b57cec5SDimitry Andric const relocation_iterator &RI,
1420b57cec5SDimitry Andric unsigned OffsetToNextPC) {
1430b57cec5SDimitry Andric auto &O = *cast<MachOObjectFile>(RI->getObject());
1440b57cec5SDimitry Andric section_iterator SecI = O.getRelocationRelocatedSection(RI);
1450b57cec5SDimitry Andric Value.Offset += RI->getOffset() + OffsetToNextPC + SecI->getAddress();
1460b57cec5SDimitry Andric }
1470b57cec5SDimitry Andric
dumpRelocationToResolve(const RelocationEntry & RE,uint64_t Value) const1480b57cec5SDimitry Andric void RuntimeDyldMachO::dumpRelocationToResolve(const RelocationEntry &RE,
1490b57cec5SDimitry Andric uint64_t Value) const {
1500b57cec5SDimitry Andric const SectionEntry &Section = Sections[RE.SectionID];
1510b57cec5SDimitry Andric uint8_t *LocalAddress = Section.getAddress() + RE.Offset;
1520b57cec5SDimitry Andric uint64_t FinalAddress = Section.getLoadAddress() + RE.Offset;
1530b57cec5SDimitry Andric
1540b57cec5SDimitry Andric dbgs() << "resolveRelocation Section: " << RE.SectionID
1550b57cec5SDimitry Andric << " LocalAddress: " << format("%p", LocalAddress)
1560b57cec5SDimitry Andric << " FinalAddress: " << format("0x%016" PRIx64, FinalAddress)
1570b57cec5SDimitry Andric << " Value: " << format("0x%016" PRIx64, Value) << " Addend: " << RE.Addend
1580b57cec5SDimitry Andric << " isPCRel: " << RE.IsPCRel << " MachoType: " << RE.RelType
1590b57cec5SDimitry Andric << " Size: " << (1 << RE.Size) << "\n";
1600b57cec5SDimitry Andric }
1610b57cec5SDimitry Andric
1620b57cec5SDimitry Andric section_iterator
getSectionByAddress(const MachOObjectFile & Obj,uint64_t Addr)1630b57cec5SDimitry Andric RuntimeDyldMachO::getSectionByAddress(const MachOObjectFile &Obj,
1640b57cec5SDimitry Andric uint64_t Addr) {
1650b57cec5SDimitry Andric section_iterator SI = Obj.section_begin();
1660b57cec5SDimitry Andric section_iterator SE = Obj.section_end();
1670b57cec5SDimitry Andric
1680b57cec5SDimitry Andric for (; SI != SE; ++SI) {
1690b57cec5SDimitry Andric uint64_t SAddr = SI->getAddress();
1700b57cec5SDimitry Andric uint64_t SSize = SI->getSize();
1710b57cec5SDimitry Andric if ((Addr >= SAddr) && (Addr < SAddr + SSize))
1720b57cec5SDimitry Andric return SI;
1730b57cec5SDimitry Andric }
1740b57cec5SDimitry Andric
1750b57cec5SDimitry Andric return SE;
1760b57cec5SDimitry Andric }
1770b57cec5SDimitry Andric
1780b57cec5SDimitry Andric
1790b57cec5SDimitry Andric // Populate __pointers section.
populateIndirectSymbolPointersSection(const MachOObjectFile & Obj,const SectionRef & PTSection,unsigned PTSectionID)1800b57cec5SDimitry Andric Error RuntimeDyldMachO::populateIndirectSymbolPointersSection(
1810b57cec5SDimitry Andric const MachOObjectFile &Obj,
1820b57cec5SDimitry Andric const SectionRef &PTSection,
1830b57cec5SDimitry Andric unsigned PTSectionID) {
1840b57cec5SDimitry Andric assert(!Obj.is64Bit() &&
1850b57cec5SDimitry Andric "Pointer table section not supported in 64-bit MachO.");
1860b57cec5SDimitry Andric
1870b57cec5SDimitry Andric MachO::dysymtab_command DySymTabCmd = Obj.getDysymtabLoadCommand();
1880b57cec5SDimitry Andric MachO::section Sec32 = Obj.getSection(PTSection.getRawDataRefImpl());
1890b57cec5SDimitry Andric uint32_t PTSectionSize = Sec32.size;
1900b57cec5SDimitry Andric unsigned FirstIndirectSymbol = Sec32.reserved1;
1910b57cec5SDimitry Andric const unsigned PTEntrySize = 4;
1920b57cec5SDimitry Andric unsigned NumPTEntries = PTSectionSize / PTEntrySize;
1930b57cec5SDimitry Andric unsigned PTEntryOffset = 0;
1940b57cec5SDimitry Andric
1950b57cec5SDimitry Andric assert((PTSectionSize % PTEntrySize) == 0 &&
1960b57cec5SDimitry Andric "Pointers section does not contain a whole number of stubs?");
1970b57cec5SDimitry Andric
1980b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Populating pointer table section "
1990b57cec5SDimitry Andric << Sections[PTSectionID].getName() << ", Section ID "
2000b57cec5SDimitry Andric << PTSectionID << ", " << NumPTEntries << " entries, "
2010b57cec5SDimitry Andric << PTEntrySize << " bytes each:\n");
2020b57cec5SDimitry Andric
2030b57cec5SDimitry Andric for (unsigned i = 0; i < NumPTEntries; ++i) {
2040b57cec5SDimitry Andric unsigned SymbolIndex =
2050b57cec5SDimitry Andric Obj.getIndirectSymbolTableEntry(DySymTabCmd, FirstIndirectSymbol + i);
2060b57cec5SDimitry Andric symbol_iterator SI = Obj.getSymbolByIndex(SymbolIndex);
2070b57cec5SDimitry Andric StringRef IndirectSymbolName;
2080b57cec5SDimitry Andric if (auto IndirectSymbolNameOrErr = SI->getName())
2090b57cec5SDimitry Andric IndirectSymbolName = *IndirectSymbolNameOrErr;
2100b57cec5SDimitry Andric else
2110b57cec5SDimitry Andric return IndirectSymbolNameOrErr.takeError();
2120b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << " " << IndirectSymbolName << ": index " << SymbolIndex
2130b57cec5SDimitry Andric << ", PT offset: " << PTEntryOffset << "\n");
2140b57cec5SDimitry Andric RelocationEntry RE(PTSectionID, PTEntryOffset,
2150b57cec5SDimitry Andric MachO::GENERIC_RELOC_VANILLA, 0, false, 2);
2160b57cec5SDimitry Andric addRelocationForSymbol(RE, IndirectSymbolName);
2170b57cec5SDimitry Andric PTEntryOffset += PTEntrySize;
2180b57cec5SDimitry Andric }
2190b57cec5SDimitry Andric return Error::success();
2200b57cec5SDimitry Andric }
2210b57cec5SDimitry Andric
isCompatibleFile(const object::ObjectFile & Obj) const2220b57cec5SDimitry Andric bool RuntimeDyldMachO::isCompatibleFile(const object::ObjectFile &Obj) const {
2230b57cec5SDimitry Andric return Obj.isMachO();
2240b57cec5SDimitry Andric }
2250b57cec5SDimitry Andric
2260b57cec5SDimitry Andric template <typename Impl>
2270b57cec5SDimitry Andric Error
finalizeLoad(const ObjectFile & Obj,ObjSectionToIDMap & SectionMap)2280b57cec5SDimitry Andric RuntimeDyldMachOCRTPBase<Impl>::finalizeLoad(const ObjectFile &Obj,
2290b57cec5SDimitry Andric ObjSectionToIDMap &SectionMap) {
2300b57cec5SDimitry Andric unsigned EHFrameSID = RTDYLD_INVALID_SECTION_ID;
2310b57cec5SDimitry Andric unsigned TextSID = RTDYLD_INVALID_SECTION_ID;
2320b57cec5SDimitry Andric unsigned ExceptTabSID = RTDYLD_INVALID_SECTION_ID;
2330b57cec5SDimitry Andric
2340b57cec5SDimitry Andric for (const auto &Section : Obj.sections()) {
2350b57cec5SDimitry Andric StringRef Name;
236*8bcb0991SDimitry Andric if (Expected<StringRef> NameOrErr = Section.getName())
237*8bcb0991SDimitry Andric Name = *NameOrErr;
238*8bcb0991SDimitry Andric else
239*8bcb0991SDimitry Andric consumeError(NameOrErr.takeError());
2400b57cec5SDimitry Andric
2410b57cec5SDimitry Andric // Force emission of the __text, __eh_frame, and __gcc_except_tab sections
2420b57cec5SDimitry Andric // if they're present. Otherwise call down to the impl to handle other
2430b57cec5SDimitry Andric // sections that have already been emitted.
2440b57cec5SDimitry Andric if (Name == "__text") {
2450b57cec5SDimitry Andric if (auto TextSIDOrErr = findOrEmitSection(Obj, Section, true, SectionMap))
2460b57cec5SDimitry Andric TextSID = *TextSIDOrErr;
2470b57cec5SDimitry Andric else
2480b57cec5SDimitry Andric return TextSIDOrErr.takeError();
2490b57cec5SDimitry Andric } else if (Name == "__eh_frame") {
2500b57cec5SDimitry Andric if (auto EHFrameSIDOrErr = findOrEmitSection(Obj, Section, false,
2510b57cec5SDimitry Andric SectionMap))
2520b57cec5SDimitry Andric EHFrameSID = *EHFrameSIDOrErr;
2530b57cec5SDimitry Andric else
2540b57cec5SDimitry Andric return EHFrameSIDOrErr.takeError();
2550b57cec5SDimitry Andric } else if (Name == "__gcc_except_tab") {
2560b57cec5SDimitry Andric if (auto ExceptTabSIDOrErr = findOrEmitSection(Obj, Section, true,
2570b57cec5SDimitry Andric SectionMap))
2580b57cec5SDimitry Andric ExceptTabSID = *ExceptTabSIDOrErr;
2590b57cec5SDimitry Andric else
2600b57cec5SDimitry Andric return ExceptTabSIDOrErr.takeError();
2610b57cec5SDimitry Andric } else {
2620b57cec5SDimitry Andric auto I = SectionMap.find(Section);
2630b57cec5SDimitry Andric if (I != SectionMap.end())
2640b57cec5SDimitry Andric if (auto Err = impl().finalizeSection(Obj, I->second, Section))
2650b57cec5SDimitry Andric return Err;
2660b57cec5SDimitry Andric }
2670b57cec5SDimitry Andric }
2680b57cec5SDimitry Andric UnregisteredEHFrameSections.push_back(
2690b57cec5SDimitry Andric EHFrameRelatedSections(EHFrameSID, TextSID, ExceptTabSID));
2700b57cec5SDimitry Andric
2710b57cec5SDimitry Andric return Error::success();
2720b57cec5SDimitry Andric }
2730b57cec5SDimitry Andric
2740b57cec5SDimitry Andric template <typename Impl>
processFDE(uint8_t * P,int64_t DeltaForText,int64_t DeltaForEH)2750b57cec5SDimitry Andric unsigned char *RuntimeDyldMachOCRTPBase<Impl>::processFDE(uint8_t *P,
2760b57cec5SDimitry Andric int64_t DeltaForText,
2770b57cec5SDimitry Andric int64_t DeltaForEH) {
2780b57cec5SDimitry Andric typedef typename Impl::TargetPtrT TargetPtrT;
2790b57cec5SDimitry Andric
2800b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Processing FDE: Delta for text: " << DeltaForText
2810b57cec5SDimitry Andric << ", Delta for EH: " << DeltaForEH << "\n");
2820b57cec5SDimitry Andric uint32_t Length = readBytesUnaligned(P, 4);
2830b57cec5SDimitry Andric P += 4;
2840b57cec5SDimitry Andric uint8_t *Ret = P + Length;
2850b57cec5SDimitry Andric uint32_t Offset = readBytesUnaligned(P, 4);
2860b57cec5SDimitry Andric if (Offset == 0) // is a CIE
2870b57cec5SDimitry Andric return Ret;
2880b57cec5SDimitry Andric
2890b57cec5SDimitry Andric P += 4;
2900b57cec5SDimitry Andric TargetPtrT FDELocation = readBytesUnaligned(P, sizeof(TargetPtrT));
2910b57cec5SDimitry Andric TargetPtrT NewLocation = FDELocation - DeltaForText;
2920b57cec5SDimitry Andric writeBytesUnaligned(NewLocation, P, sizeof(TargetPtrT));
2930b57cec5SDimitry Andric
2940b57cec5SDimitry Andric P += sizeof(TargetPtrT);
2950b57cec5SDimitry Andric
2960b57cec5SDimitry Andric // Skip the FDE address range
2970b57cec5SDimitry Andric P += sizeof(TargetPtrT);
2980b57cec5SDimitry Andric
2990b57cec5SDimitry Andric uint8_t Augmentationsize = *P;
3000b57cec5SDimitry Andric P += 1;
3010b57cec5SDimitry Andric if (Augmentationsize != 0) {
3020b57cec5SDimitry Andric TargetPtrT LSDA = readBytesUnaligned(P, sizeof(TargetPtrT));
3030b57cec5SDimitry Andric TargetPtrT NewLSDA = LSDA - DeltaForEH;
3040b57cec5SDimitry Andric writeBytesUnaligned(NewLSDA, P, sizeof(TargetPtrT));
3050b57cec5SDimitry Andric }
3060b57cec5SDimitry Andric
3070b57cec5SDimitry Andric return Ret;
3080b57cec5SDimitry Andric }
3090b57cec5SDimitry Andric
computeDelta(SectionEntry * A,SectionEntry * B)3100b57cec5SDimitry Andric static int64_t computeDelta(SectionEntry *A, SectionEntry *B) {
3110b57cec5SDimitry Andric int64_t ObjDistance = static_cast<int64_t>(A->getObjAddress()) -
3120b57cec5SDimitry Andric static_cast<int64_t>(B->getObjAddress());
3130b57cec5SDimitry Andric int64_t MemDistance = A->getLoadAddress() - B->getLoadAddress();
3140b57cec5SDimitry Andric return ObjDistance - MemDistance;
3150b57cec5SDimitry Andric }
3160b57cec5SDimitry Andric
3170b57cec5SDimitry Andric template <typename Impl>
registerEHFrames()3180b57cec5SDimitry Andric void RuntimeDyldMachOCRTPBase<Impl>::registerEHFrames() {
3190b57cec5SDimitry Andric
3200b57cec5SDimitry Andric for (int i = 0, e = UnregisteredEHFrameSections.size(); i != e; ++i) {
3210b57cec5SDimitry Andric EHFrameRelatedSections &SectionInfo = UnregisteredEHFrameSections[i];
3220b57cec5SDimitry Andric if (SectionInfo.EHFrameSID == RTDYLD_INVALID_SECTION_ID ||
3230b57cec5SDimitry Andric SectionInfo.TextSID == RTDYLD_INVALID_SECTION_ID)
3240b57cec5SDimitry Andric continue;
3250b57cec5SDimitry Andric SectionEntry *Text = &Sections[SectionInfo.TextSID];
3260b57cec5SDimitry Andric SectionEntry *EHFrame = &Sections[SectionInfo.EHFrameSID];
3270b57cec5SDimitry Andric SectionEntry *ExceptTab = nullptr;
3280b57cec5SDimitry Andric if (SectionInfo.ExceptTabSID != RTDYLD_INVALID_SECTION_ID)
3290b57cec5SDimitry Andric ExceptTab = &Sections[SectionInfo.ExceptTabSID];
3300b57cec5SDimitry Andric
3310b57cec5SDimitry Andric int64_t DeltaForText = computeDelta(Text, EHFrame);
3320b57cec5SDimitry Andric int64_t DeltaForEH = 0;
3330b57cec5SDimitry Andric if (ExceptTab)
3340b57cec5SDimitry Andric DeltaForEH = computeDelta(ExceptTab, EHFrame);
3350b57cec5SDimitry Andric
3360b57cec5SDimitry Andric uint8_t *P = EHFrame->getAddress();
3370b57cec5SDimitry Andric uint8_t *End = P + EHFrame->getSize();
3380b57cec5SDimitry Andric while (P != End) {
3390b57cec5SDimitry Andric P = processFDE(P, DeltaForText, DeltaForEH);
3400b57cec5SDimitry Andric }
3410b57cec5SDimitry Andric
3420b57cec5SDimitry Andric MemMgr.registerEHFrames(EHFrame->getAddress(), EHFrame->getLoadAddress(),
3430b57cec5SDimitry Andric EHFrame->getSize());
3440b57cec5SDimitry Andric }
3450b57cec5SDimitry Andric UnregisteredEHFrameSections.clear();
3460b57cec5SDimitry Andric }
3470b57cec5SDimitry Andric
3480b57cec5SDimitry Andric std::unique_ptr<RuntimeDyldMachO>
create(Triple::ArchType Arch,RuntimeDyld::MemoryManager & MemMgr,JITSymbolResolver & Resolver)3490b57cec5SDimitry Andric RuntimeDyldMachO::create(Triple::ArchType Arch,
3500b57cec5SDimitry Andric RuntimeDyld::MemoryManager &MemMgr,
3510b57cec5SDimitry Andric JITSymbolResolver &Resolver) {
3520b57cec5SDimitry Andric switch (Arch) {
3530b57cec5SDimitry Andric default:
3540b57cec5SDimitry Andric llvm_unreachable("Unsupported target for RuntimeDyldMachO.");
3550b57cec5SDimitry Andric break;
3560b57cec5SDimitry Andric case Triple::arm:
357*8bcb0991SDimitry Andric return std::make_unique<RuntimeDyldMachOARM>(MemMgr, Resolver);
3580b57cec5SDimitry Andric case Triple::aarch64:
359*8bcb0991SDimitry Andric return std::make_unique<RuntimeDyldMachOAArch64>(MemMgr, Resolver);
360*8bcb0991SDimitry Andric case Triple::aarch64_32:
361*8bcb0991SDimitry Andric return std::make_unique<RuntimeDyldMachOAArch64>(MemMgr, Resolver);
3620b57cec5SDimitry Andric case Triple::x86:
363*8bcb0991SDimitry Andric return std::make_unique<RuntimeDyldMachOI386>(MemMgr, Resolver);
3640b57cec5SDimitry Andric case Triple::x86_64:
365*8bcb0991SDimitry Andric return std::make_unique<RuntimeDyldMachOX86_64>(MemMgr, Resolver);
3660b57cec5SDimitry Andric }
3670b57cec5SDimitry Andric }
3680b57cec5SDimitry Andric
3690b57cec5SDimitry Andric std::unique_ptr<RuntimeDyld::LoadedObjectInfo>
loadObject(const object::ObjectFile & O)3700b57cec5SDimitry Andric RuntimeDyldMachO::loadObject(const object::ObjectFile &O) {
3710b57cec5SDimitry Andric if (auto ObjSectionToIDOrErr = loadObjectImpl(O))
372*8bcb0991SDimitry Andric return std::make_unique<LoadedMachOObjectInfo>(*this,
3730b57cec5SDimitry Andric *ObjSectionToIDOrErr);
3740b57cec5SDimitry Andric else {
3750b57cec5SDimitry Andric HasError = true;
3760b57cec5SDimitry Andric raw_string_ostream ErrStream(ErrorStr);
3770b57cec5SDimitry Andric logAllUnhandledErrors(ObjSectionToIDOrErr.takeError(), ErrStream);
3780b57cec5SDimitry Andric return nullptr;
3790b57cec5SDimitry Andric }
3800b57cec5SDimitry Andric }
3810b57cec5SDimitry Andric
3820b57cec5SDimitry Andric } // end namespace llvm
383