1*0b57cec5SDimitry Andric //===-- RuntimeDyldMachO.cpp - Run-time dynamic linker for MC-JIT -*- C++ -*-=// 2*0b57cec5SDimitry Andric // 3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0b57cec5SDimitry Andric // 7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 8*0b57cec5SDimitry Andric // 9*0b57cec5SDimitry Andric // Implementation of the MC-JIT runtime dynamic linker. 10*0b57cec5SDimitry Andric // 11*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 12*0b57cec5SDimitry Andric 13*0b57cec5SDimitry Andric #include "RuntimeDyldMachO.h" 14*0b57cec5SDimitry Andric #include "Targets/RuntimeDyldMachOAArch64.h" 15*0b57cec5SDimitry Andric #include "Targets/RuntimeDyldMachOARM.h" 16*0b57cec5SDimitry Andric #include "Targets/RuntimeDyldMachOI386.h" 17*0b57cec5SDimitry Andric #include "Targets/RuntimeDyldMachOX86_64.h" 18*0b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h" 19*0b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h" 20*0b57cec5SDimitry Andric 21*0b57cec5SDimitry Andric using namespace llvm; 22*0b57cec5SDimitry Andric using namespace llvm::object; 23*0b57cec5SDimitry Andric 24*0b57cec5SDimitry Andric #define DEBUG_TYPE "dyld" 25*0b57cec5SDimitry Andric 26*0b57cec5SDimitry Andric namespace { 27*0b57cec5SDimitry Andric 28*0b57cec5SDimitry Andric class LoadedMachOObjectInfo final 29*0b57cec5SDimitry Andric : public LoadedObjectInfoHelper<LoadedMachOObjectInfo, 30*0b57cec5SDimitry Andric RuntimeDyld::LoadedObjectInfo> { 31*0b57cec5SDimitry Andric public: 32*0b57cec5SDimitry Andric LoadedMachOObjectInfo(RuntimeDyldImpl &RTDyld, 33*0b57cec5SDimitry Andric ObjSectionToIDMap ObjSecToIDMap) 34*0b57cec5SDimitry Andric : LoadedObjectInfoHelper(RTDyld, std::move(ObjSecToIDMap)) {} 35*0b57cec5SDimitry Andric 36*0b57cec5SDimitry Andric OwningBinary<ObjectFile> 37*0b57cec5SDimitry Andric getObjectForDebug(const ObjectFile &Obj) const override { 38*0b57cec5SDimitry Andric return OwningBinary<ObjectFile>(); 39*0b57cec5SDimitry Andric } 40*0b57cec5SDimitry Andric }; 41*0b57cec5SDimitry Andric 42*0b57cec5SDimitry Andric } 43*0b57cec5SDimitry Andric 44*0b57cec5SDimitry Andric namespace llvm { 45*0b57cec5SDimitry Andric 46*0b57cec5SDimitry Andric int64_t RuntimeDyldMachO::memcpyAddend(const RelocationEntry &RE) const { 47*0b57cec5SDimitry Andric unsigned NumBytes = 1 << RE.Size; 48*0b57cec5SDimitry Andric uint8_t *Src = Sections[RE.SectionID].getAddress() + RE.Offset; 49*0b57cec5SDimitry Andric 50*0b57cec5SDimitry Andric return static_cast<int64_t>(readBytesUnaligned(Src, NumBytes)); 51*0b57cec5SDimitry Andric } 52*0b57cec5SDimitry Andric 53*0b57cec5SDimitry Andric Expected<relocation_iterator> 54*0b57cec5SDimitry Andric RuntimeDyldMachO::processScatteredVANILLA( 55*0b57cec5SDimitry Andric unsigned SectionID, relocation_iterator RelI, 56*0b57cec5SDimitry Andric const ObjectFile &BaseObjT, 57*0b57cec5SDimitry Andric RuntimeDyldMachO::ObjSectionToIDMap &ObjSectionToID, 58*0b57cec5SDimitry Andric bool TargetIsLocalThumbFunc) { 59*0b57cec5SDimitry Andric const MachOObjectFile &Obj = 60*0b57cec5SDimitry Andric static_cast<const MachOObjectFile&>(BaseObjT); 61*0b57cec5SDimitry Andric MachO::any_relocation_info RE = 62*0b57cec5SDimitry Andric Obj.getRelocation(RelI->getRawDataRefImpl()); 63*0b57cec5SDimitry Andric 64*0b57cec5SDimitry Andric SectionEntry &Section = Sections[SectionID]; 65*0b57cec5SDimitry Andric uint32_t RelocType = Obj.getAnyRelocationType(RE); 66*0b57cec5SDimitry Andric bool IsPCRel = Obj.getAnyRelocationPCRel(RE); 67*0b57cec5SDimitry Andric unsigned Size = Obj.getAnyRelocationLength(RE); 68*0b57cec5SDimitry Andric uint64_t Offset = RelI->getOffset(); 69*0b57cec5SDimitry Andric uint8_t *LocalAddress = Section.getAddressWithOffset(Offset); 70*0b57cec5SDimitry Andric unsigned NumBytes = 1 << Size; 71*0b57cec5SDimitry Andric int64_t Addend = readBytesUnaligned(LocalAddress, NumBytes); 72*0b57cec5SDimitry Andric 73*0b57cec5SDimitry Andric unsigned SymbolBaseAddr = Obj.getScatteredRelocationValue(RE); 74*0b57cec5SDimitry Andric section_iterator TargetSI = getSectionByAddress(Obj, SymbolBaseAddr); 75*0b57cec5SDimitry Andric assert(TargetSI != Obj.section_end() && "Can't find section for symbol"); 76*0b57cec5SDimitry Andric uint64_t SectionBaseAddr = TargetSI->getAddress(); 77*0b57cec5SDimitry Andric SectionRef TargetSection = *TargetSI; 78*0b57cec5SDimitry Andric bool IsCode = TargetSection.isText(); 79*0b57cec5SDimitry Andric uint32_t TargetSectionID = ~0U; 80*0b57cec5SDimitry Andric if (auto TargetSectionIDOrErr = 81*0b57cec5SDimitry Andric findOrEmitSection(Obj, TargetSection, IsCode, ObjSectionToID)) 82*0b57cec5SDimitry Andric TargetSectionID = *TargetSectionIDOrErr; 83*0b57cec5SDimitry Andric else 84*0b57cec5SDimitry Andric return TargetSectionIDOrErr.takeError(); 85*0b57cec5SDimitry Andric 86*0b57cec5SDimitry Andric Addend -= SectionBaseAddr; 87*0b57cec5SDimitry Andric RelocationEntry R(SectionID, Offset, RelocType, Addend, IsPCRel, Size); 88*0b57cec5SDimitry Andric R.IsTargetThumbFunc = TargetIsLocalThumbFunc; 89*0b57cec5SDimitry Andric 90*0b57cec5SDimitry Andric addRelocationForSection(R, TargetSectionID); 91*0b57cec5SDimitry Andric 92*0b57cec5SDimitry Andric return ++RelI; 93*0b57cec5SDimitry Andric } 94*0b57cec5SDimitry Andric 95*0b57cec5SDimitry Andric 96*0b57cec5SDimitry Andric Expected<RelocationValueRef> 97*0b57cec5SDimitry Andric RuntimeDyldMachO::getRelocationValueRef( 98*0b57cec5SDimitry Andric const ObjectFile &BaseTObj, const relocation_iterator &RI, 99*0b57cec5SDimitry Andric const RelocationEntry &RE, ObjSectionToIDMap &ObjSectionToID) { 100*0b57cec5SDimitry Andric 101*0b57cec5SDimitry Andric const MachOObjectFile &Obj = 102*0b57cec5SDimitry Andric static_cast<const MachOObjectFile &>(BaseTObj); 103*0b57cec5SDimitry Andric MachO::any_relocation_info RelInfo = 104*0b57cec5SDimitry Andric Obj.getRelocation(RI->getRawDataRefImpl()); 105*0b57cec5SDimitry Andric RelocationValueRef Value; 106*0b57cec5SDimitry Andric 107*0b57cec5SDimitry Andric bool IsExternal = Obj.getPlainRelocationExternal(RelInfo); 108*0b57cec5SDimitry Andric if (IsExternal) { 109*0b57cec5SDimitry Andric symbol_iterator Symbol = RI->getSymbol(); 110*0b57cec5SDimitry Andric StringRef TargetName; 111*0b57cec5SDimitry Andric if (auto TargetNameOrErr = Symbol->getName()) 112*0b57cec5SDimitry Andric TargetName = *TargetNameOrErr; 113*0b57cec5SDimitry Andric else 114*0b57cec5SDimitry Andric return TargetNameOrErr.takeError(); 115*0b57cec5SDimitry Andric RTDyldSymbolTable::const_iterator SI = 116*0b57cec5SDimitry Andric GlobalSymbolTable.find(TargetName.data()); 117*0b57cec5SDimitry Andric if (SI != GlobalSymbolTable.end()) { 118*0b57cec5SDimitry Andric const auto &SymInfo = SI->second; 119*0b57cec5SDimitry Andric Value.SectionID = SymInfo.getSectionID(); 120*0b57cec5SDimitry Andric Value.Offset = SymInfo.getOffset() + RE.Addend; 121*0b57cec5SDimitry Andric } else { 122*0b57cec5SDimitry Andric Value.SymbolName = TargetName.data(); 123*0b57cec5SDimitry Andric Value.Offset = RE.Addend; 124*0b57cec5SDimitry Andric } 125*0b57cec5SDimitry Andric } else { 126*0b57cec5SDimitry Andric SectionRef Sec = Obj.getAnyRelocationSection(RelInfo); 127*0b57cec5SDimitry Andric bool IsCode = Sec.isText(); 128*0b57cec5SDimitry Andric if (auto SectionIDOrErr = findOrEmitSection(Obj, Sec, IsCode, 129*0b57cec5SDimitry Andric ObjSectionToID)) 130*0b57cec5SDimitry Andric Value.SectionID = *SectionIDOrErr; 131*0b57cec5SDimitry Andric else 132*0b57cec5SDimitry Andric return SectionIDOrErr.takeError(); 133*0b57cec5SDimitry Andric uint64_t Addr = Sec.getAddress(); 134*0b57cec5SDimitry Andric Value.Offset = RE.Addend - Addr; 135*0b57cec5SDimitry Andric } 136*0b57cec5SDimitry Andric 137*0b57cec5SDimitry Andric return Value; 138*0b57cec5SDimitry Andric } 139*0b57cec5SDimitry Andric 140*0b57cec5SDimitry Andric void RuntimeDyldMachO::makeValueAddendPCRel(RelocationValueRef &Value, 141*0b57cec5SDimitry Andric const relocation_iterator &RI, 142*0b57cec5SDimitry Andric unsigned OffsetToNextPC) { 143*0b57cec5SDimitry Andric auto &O = *cast<MachOObjectFile>(RI->getObject()); 144*0b57cec5SDimitry Andric section_iterator SecI = O.getRelocationRelocatedSection(RI); 145*0b57cec5SDimitry Andric Value.Offset += RI->getOffset() + OffsetToNextPC + SecI->getAddress(); 146*0b57cec5SDimitry Andric } 147*0b57cec5SDimitry Andric 148*0b57cec5SDimitry Andric void RuntimeDyldMachO::dumpRelocationToResolve(const RelocationEntry &RE, 149*0b57cec5SDimitry Andric uint64_t Value) const { 150*0b57cec5SDimitry Andric const SectionEntry &Section = Sections[RE.SectionID]; 151*0b57cec5SDimitry Andric uint8_t *LocalAddress = Section.getAddress() + RE.Offset; 152*0b57cec5SDimitry Andric uint64_t FinalAddress = Section.getLoadAddress() + RE.Offset; 153*0b57cec5SDimitry Andric 154*0b57cec5SDimitry Andric dbgs() << "resolveRelocation Section: " << RE.SectionID 155*0b57cec5SDimitry Andric << " LocalAddress: " << format("%p", LocalAddress) 156*0b57cec5SDimitry Andric << " FinalAddress: " << format("0x%016" PRIx64, FinalAddress) 157*0b57cec5SDimitry Andric << " Value: " << format("0x%016" PRIx64, Value) << " Addend: " << RE.Addend 158*0b57cec5SDimitry Andric << " isPCRel: " << RE.IsPCRel << " MachoType: " << RE.RelType 159*0b57cec5SDimitry Andric << " Size: " << (1 << RE.Size) << "\n"; 160*0b57cec5SDimitry Andric } 161*0b57cec5SDimitry Andric 162*0b57cec5SDimitry Andric section_iterator 163*0b57cec5SDimitry Andric RuntimeDyldMachO::getSectionByAddress(const MachOObjectFile &Obj, 164*0b57cec5SDimitry Andric uint64_t Addr) { 165*0b57cec5SDimitry Andric section_iterator SI = Obj.section_begin(); 166*0b57cec5SDimitry Andric section_iterator SE = Obj.section_end(); 167*0b57cec5SDimitry Andric 168*0b57cec5SDimitry Andric for (; SI != SE; ++SI) { 169*0b57cec5SDimitry Andric uint64_t SAddr = SI->getAddress(); 170*0b57cec5SDimitry Andric uint64_t SSize = SI->getSize(); 171*0b57cec5SDimitry Andric if ((Addr >= SAddr) && (Addr < SAddr + SSize)) 172*0b57cec5SDimitry Andric return SI; 173*0b57cec5SDimitry Andric } 174*0b57cec5SDimitry Andric 175*0b57cec5SDimitry Andric return SE; 176*0b57cec5SDimitry Andric } 177*0b57cec5SDimitry Andric 178*0b57cec5SDimitry Andric 179*0b57cec5SDimitry Andric // Populate __pointers section. 180*0b57cec5SDimitry Andric Error RuntimeDyldMachO::populateIndirectSymbolPointersSection( 181*0b57cec5SDimitry Andric const MachOObjectFile &Obj, 182*0b57cec5SDimitry Andric const SectionRef &PTSection, 183*0b57cec5SDimitry Andric unsigned PTSectionID) { 184*0b57cec5SDimitry Andric assert(!Obj.is64Bit() && 185*0b57cec5SDimitry Andric "Pointer table section not supported in 64-bit MachO."); 186*0b57cec5SDimitry Andric 187*0b57cec5SDimitry Andric MachO::dysymtab_command DySymTabCmd = Obj.getDysymtabLoadCommand(); 188*0b57cec5SDimitry Andric MachO::section Sec32 = Obj.getSection(PTSection.getRawDataRefImpl()); 189*0b57cec5SDimitry Andric uint32_t PTSectionSize = Sec32.size; 190*0b57cec5SDimitry Andric unsigned FirstIndirectSymbol = Sec32.reserved1; 191*0b57cec5SDimitry Andric const unsigned PTEntrySize = 4; 192*0b57cec5SDimitry Andric unsigned NumPTEntries = PTSectionSize / PTEntrySize; 193*0b57cec5SDimitry Andric unsigned PTEntryOffset = 0; 194*0b57cec5SDimitry Andric 195*0b57cec5SDimitry Andric assert((PTSectionSize % PTEntrySize) == 0 && 196*0b57cec5SDimitry Andric "Pointers section does not contain a whole number of stubs?"); 197*0b57cec5SDimitry Andric 198*0b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Populating pointer table section " 199*0b57cec5SDimitry Andric << Sections[PTSectionID].getName() << ", Section ID " 200*0b57cec5SDimitry Andric << PTSectionID << ", " << NumPTEntries << " entries, " 201*0b57cec5SDimitry Andric << PTEntrySize << " bytes each:\n"); 202*0b57cec5SDimitry Andric 203*0b57cec5SDimitry Andric for (unsigned i = 0; i < NumPTEntries; ++i) { 204*0b57cec5SDimitry Andric unsigned SymbolIndex = 205*0b57cec5SDimitry Andric Obj.getIndirectSymbolTableEntry(DySymTabCmd, FirstIndirectSymbol + i); 206*0b57cec5SDimitry Andric symbol_iterator SI = Obj.getSymbolByIndex(SymbolIndex); 207*0b57cec5SDimitry Andric StringRef IndirectSymbolName; 208*0b57cec5SDimitry Andric if (auto IndirectSymbolNameOrErr = SI->getName()) 209*0b57cec5SDimitry Andric IndirectSymbolName = *IndirectSymbolNameOrErr; 210*0b57cec5SDimitry Andric else 211*0b57cec5SDimitry Andric return IndirectSymbolNameOrErr.takeError(); 212*0b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << " " << IndirectSymbolName << ": index " << SymbolIndex 213*0b57cec5SDimitry Andric << ", PT offset: " << PTEntryOffset << "\n"); 214*0b57cec5SDimitry Andric RelocationEntry RE(PTSectionID, PTEntryOffset, 215*0b57cec5SDimitry Andric MachO::GENERIC_RELOC_VANILLA, 0, false, 2); 216*0b57cec5SDimitry Andric addRelocationForSymbol(RE, IndirectSymbolName); 217*0b57cec5SDimitry Andric PTEntryOffset += PTEntrySize; 218*0b57cec5SDimitry Andric } 219*0b57cec5SDimitry Andric return Error::success(); 220*0b57cec5SDimitry Andric } 221*0b57cec5SDimitry Andric 222*0b57cec5SDimitry Andric bool RuntimeDyldMachO::isCompatibleFile(const object::ObjectFile &Obj) const { 223*0b57cec5SDimitry Andric return Obj.isMachO(); 224*0b57cec5SDimitry Andric } 225*0b57cec5SDimitry Andric 226*0b57cec5SDimitry Andric template <typename Impl> 227*0b57cec5SDimitry Andric Error 228*0b57cec5SDimitry Andric RuntimeDyldMachOCRTPBase<Impl>::finalizeLoad(const ObjectFile &Obj, 229*0b57cec5SDimitry Andric ObjSectionToIDMap &SectionMap) { 230*0b57cec5SDimitry Andric unsigned EHFrameSID = RTDYLD_INVALID_SECTION_ID; 231*0b57cec5SDimitry Andric unsigned TextSID = RTDYLD_INVALID_SECTION_ID; 232*0b57cec5SDimitry Andric unsigned ExceptTabSID = RTDYLD_INVALID_SECTION_ID; 233*0b57cec5SDimitry Andric 234*0b57cec5SDimitry Andric for (const auto &Section : Obj.sections()) { 235*0b57cec5SDimitry Andric StringRef Name; 236*0b57cec5SDimitry Andric Section.getName(Name); 237*0b57cec5SDimitry Andric 238*0b57cec5SDimitry Andric // Force emission of the __text, __eh_frame, and __gcc_except_tab sections 239*0b57cec5SDimitry Andric // if they're present. Otherwise call down to the impl to handle other 240*0b57cec5SDimitry Andric // sections that have already been emitted. 241*0b57cec5SDimitry Andric if (Name == "__text") { 242*0b57cec5SDimitry Andric if (auto TextSIDOrErr = findOrEmitSection(Obj, Section, true, SectionMap)) 243*0b57cec5SDimitry Andric TextSID = *TextSIDOrErr; 244*0b57cec5SDimitry Andric else 245*0b57cec5SDimitry Andric return TextSIDOrErr.takeError(); 246*0b57cec5SDimitry Andric } else if (Name == "__eh_frame") { 247*0b57cec5SDimitry Andric if (auto EHFrameSIDOrErr = findOrEmitSection(Obj, Section, false, 248*0b57cec5SDimitry Andric SectionMap)) 249*0b57cec5SDimitry Andric EHFrameSID = *EHFrameSIDOrErr; 250*0b57cec5SDimitry Andric else 251*0b57cec5SDimitry Andric return EHFrameSIDOrErr.takeError(); 252*0b57cec5SDimitry Andric } else if (Name == "__gcc_except_tab") { 253*0b57cec5SDimitry Andric if (auto ExceptTabSIDOrErr = findOrEmitSection(Obj, Section, true, 254*0b57cec5SDimitry Andric SectionMap)) 255*0b57cec5SDimitry Andric ExceptTabSID = *ExceptTabSIDOrErr; 256*0b57cec5SDimitry Andric else 257*0b57cec5SDimitry Andric return ExceptTabSIDOrErr.takeError(); 258*0b57cec5SDimitry Andric } else { 259*0b57cec5SDimitry Andric auto I = SectionMap.find(Section); 260*0b57cec5SDimitry Andric if (I != SectionMap.end()) 261*0b57cec5SDimitry Andric if (auto Err = impl().finalizeSection(Obj, I->second, Section)) 262*0b57cec5SDimitry Andric return Err; 263*0b57cec5SDimitry Andric } 264*0b57cec5SDimitry Andric } 265*0b57cec5SDimitry Andric UnregisteredEHFrameSections.push_back( 266*0b57cec5SDimitry Andric EHFrameRelatedSections(EHFrameSID, TextSID, ExceptTabSID)); 267*0b57cec5SDimitry Andric 268*0b57cec5SDimitry Andric return Error::success(); 269*0b57cec5SDimitry Andric } 270*0b57cec5SDimitry Andric 271*0b57cec5SDimitry Andric template <typename Impl> 272*0b57cec5SDimitry Andric unsigned char *RuntimeDyldMachOCRTPBase<Impl>::processFDE(uint8_t *P, 273*0b57cec5SDimitry Andric int64_t DeltaForText, 274*0b57cec5SDimitry Andric int64_t DeltaForEH) { 275*0b57cec5SDimitry Andric typedef typename Impl::TargetPtrT TargetPtrT; 276*0b57cec5SDimitry Andric 277*0b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Processing FDE: Delta for text: " << DeltaForText 278*0b57cec5SDimitry Andric << ", Delta for EH: " << DeltaForEH << "\n"); 279*0b57cec5SDimitry Andric uint32_t Length = readBytesUnaligned(P, 4); 280*0b57cec5SDimitry Andric P += 4; 281*0b57cec5SDimitry Andric uint8_t *Ret = P + Length; 282*0b57cec5SDimitry Andric uint32_t Offset = readBytesUnaligned(P, 4); 283*0b57cec5SDimitry Andric if (Offset == 0) // is a CIE 284*0b57cec5SDimitry Andric return Ret; 285*0b57cec5SDimitry Andric 286*0b57cec5SDimitry Andric P += 4; 287*0b57cec5SDimitry Andric TargetPtrT FDELocation = readBytesUnaligned(P, sizeof(TargetPtrT)); 288*0b57cec5SDimitry Andric TargetPtrT NewLocation = FDELocation - DeltaForText; 289*0b57cec5SDimitry Andric writeBytesUnaligned(NewLocation, P, sizeof(TargetPtrT)); 290*0b57cec5SDimitry Andric 291*0b57cec5SDimitry Andric P += sizeof(TargetPtrT); 292*0b57cec5SDimitry Andric 293*0b57cec5SDimitry Andric // Skip the FDE address range 294*0b57cec5SDimitry Andric P += sizeof(TargetPtrT); 295*0b57cec5SDimitry Andric 296*0b57cec5SDimitry Andric uint8_t Augmentationsize = *P; 297*0b57cec5SDimitry Andric P += 1; 298*0b57cec5SDimitry Andric if (Augmentationsize != 0) { 299*0b57cec5SDimitry Andric TargetPtrT LSDA = readBytesUnaligned(P, sizeof(TargetPtrT)); 300*0b57cec5SDimitry Andric TargetPtrT NewLSDA = LSDA - DeltaForEH; 301*0b57cec5SDimitry Andric writeBytesUnaligned(NewLSDA, P, sizeof(TargetPtrT)); 302*0b57cec5SDimitry Andric } 303*0b57cec5SDimitry Andric 304*0b57cec5SDimitry Andric return Ret; 305*0b57cec5SDimitry Andric } 306*0b57cec5SDimitry Andric 307*0b57cec5SDimitry Andric static int64_t computeDelta(SectionEntry *A, SectionEntry *B) { 308*0b57cec5SDimitry Andric int64_t ObjDistance = static_cast<int64_t>(A->getObjAddress()) - 309*0b57cec5SDimitry Andric static_cast<int64_t>(B->getObjAddress()); 310*0b57cec5SDimitry Andric int64_t MemDistance = A->getLoadAddress() - B->getLoadAddress(); 311*0b57cec5SDimitry Andric return ObjDistance - MemDistance; 312*0b57cec5SDimitry Andric } 313*0b57cec5SDimitry Andric 314*0b57cec5SDimitry Andric template <typename Impl> 315*0b57cec5SDimitry Andric void RuntimeDyldMachOCRTPBase<Impl>::registerEHFrames() { 316*0b57cec5SDimitry Andric 317*0b57cec5SDimitry Andric for (int i = 0, e = UnregisteredEHFrameSections.size(); i != e; ++i) { 318*0b57cec5SDimitry Andric EHFrameRelatedSections &SectionInfo = UnregisteredEHFrameSections[i]; 319*0b57cec5SDimitry Andric if (SectionInfo.EHFrameSID == RTDYLD_INVALID_SECTION_ID || 320*0b57cec5SDimitry Andric SectionInfo.TextSID == RTDYLD_INVALID_SECTION_ID) 321*0b57cec5SDimitry Andric continue; 322*0b57cec5SDimitry Andric SectionEntry *Text = &Sections[SectionInfo.TextSID]; 323*0b57cec5SDimitry Andric SectionEntry *EHFrame = &Sections[SectionInfo.EHFrameSID]; 324*0b57cec5SDimitry Andric SectionEntry *ExceptTab = nullptr; 325*0b57cec5SDimitry Andric if (SectionInfo.ExceptTabSID != RTDYLD_INVALID_SECTION_ID) 326*0b57cec5SDimitry Andric ExceptTab = &Sections[SectionInfo.ExceptTabSID]; 327*0b57cec5SDimitry Andric 328*0b57cec5SDimitry Andric int64_t DeltaForText = computeDelta(Text, EHFrame); 329*0b57cec5SDimitry Andric int64_t DeltaForEH = 0; 330*0b57cec5SDimitry Andric if (ExceptTab) 331*0b57cec5SDimitry Andric DeltaForEH = computeDelta(ExceptTab, EHFrame); 332*0b57cec5SDimitry Andric 333*0b57cec5SDimitry Andric uint8_t *P = EHFrame->getAddress(); 334*0b57cec5SDimitry Andric uint8_t *End = P + EHFrame->getSize(); 335*0b57cec5SDimitry Andric while (P != End) { 336*0b57cec5SDimitry Andric P = processFDE(P, DeltaForText, DeltaForEH); 337*0b57cec5SDimitry Andric } 338*0b57cec5SDimitry Andric 339*0b57cec5SDimitry Andric MemMgr.registerEHFrames(EHFrame->getAddress(), EHFrame->getLoadAddress(), 340*0b57cec5SDimitry Andric EHFrame->getSize()); 341*0b57cec5SDimitry Andric } 342*0b57cec5SDimitry Andric UnregisteredEHFrameSections.clear(); 343*0b57cec5SDimitry Andric } 344*0b57cec5SDimitry Andric 345*0b57cec5SDimitry Andric std::unique_ptr<RuntimeDyldMachO> 346*0b57cec5SDimitry Andric RuntimeDyldMachO::create(Triple::ArchType Arch, 347*0b57cec5SDimitry Andric RuntimeDyld::MemoryManager &MemMgr, 348*0b57cec5SDimitry Andric JITSymbolResolver &Resolver) { 349*0b57cec5SDimitry Andric switch (Arch) { 350*0b57cec5SDimitry Andric default: 351*0b57cec5SDimitry Andric llvm_unreachable("Unsupported target for RuntimeDyldMachO."); 352*0b57cec5SDimitry Andric break; 353*0b57cec5SDimitry Andric case Triple::arm: 354*0b57cec5SDimitry Andric return make_unique<RuntimeDyldMachOARM>(MemMgr, Resolver); 355*0b57cec5SDimitry Andric case Triple::aarch64: 356*0b57cec5SDimitry Andric return make_unique<RuntimeDyldMachOAArch64>(MemMgr, Resolver); 357*0b57cec5SDimitry Andric case Triple::x86: 358*0b57cec5SDimitry Andric return make_unique<RuntimeDyldMachOI386>(MemMgr, Resolver); 359*0b57cec5SDimitry Andric case Triple::x86_64: 360*0b57cec5SDimitry Andric return make_unique<RuntimeDyldMachOX86_64>(MemMgr, Resolver); 361*0b57cec5SDimitry Andric } 362*0b57cec5SDimitry Andric } 363*0b57cec5SDimitry Andric 364*0b57cec5SDimitry Andric std::unique_ptr<RuntimeDyld::LoadedObjectInfo> 365*0b57cec5SDimitry Andric RuntimeDyldMachO::loadObject(const object::ObjectFile &O) { 366*0b57cec5SDimitry Andric if (auto ObjSectionToIDOrErr = loadObjectImpl(O)) 367*0b57cec5SDimitry Andric return llvm::make_unique<LoadedMachOObjectInfo>(*this, 368*0b57cec5SDimitry Andric *ObjSectionToIDOrErr); 369*0b57cec5SDimitry Andric else { 370*0b57cec5SDimitry Andric HasError = true; 371*0b57cec5SDimitry Andric raw_string_ostream ErrStream(ErrorStr); 372*0b57cec5SDimitry Andric logAllUnhandledErrors(ObjSectionToIDOrErr.takeError(), ErrStream); 373*0b57cec5SDimitry Andric return nullptr; 374*0b57cec5SDimitry Andric } 375*0b57cec5SDimitry Andric } 376*0b57cec5SDimitry Andric 377*0b57cec5SDimitry Andric } // end namespace llvm 378