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: 320b57cec5SDimitry Andric LoadedMachOObjectInfo(RuntimeDyldImpl &RTDyld, 330b57cec5SDimitry Andric ObjSectionToIDMap ObjSecToIDMap) 340b57cec5SDimitry Andric : LoadedObjectInfoHelper(RTDyld, std::move(ObjSecToIDMap)) {} 350b57cec5SDimitry Andric 360b57cec5SDimitry Andric OwningBinary<ObjectFile> 370b57cec5SDimitry 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 460b57cec5SDimitry 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> 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> 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 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 1480b57cec5SDimitry 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 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. 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 2220b57cec5SDimitry 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 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> 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 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> 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> 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> 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