xref: /freebsd-src/contrib/llvm-project/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp (revision 5b27928474e6a4103d65b347544705c40c9618fd)
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