1*0b57cec5SDimitry Andric //===-- RuntimeDyldMachO.h - 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 // MachO support for MC-JIT runtime dynamic linker. 10*0b57cec5SDimitry Andric // 11*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 12*0b57cec5SDimitry Andric 13*0b57cec5SDimitry Andric #ifndef LLVM_LIB_EXECUTIONENGINE_RUNTIMEDYLD_RUNTIMEDYLDMACHO_H 14*0b57cec5SDimitry Andric #define LLVM_LIB_EXECUTIONENGINE_RUNTIMEDYLD_RUNTIMEDYLDMACHO_H 15*0b57cec5SDimitry Andric 16*0b57cec5SDimitry Andric #include "RuntimeDyldImpl.h" 17*0b57cec5SDimitry Andric #include "llvm/Object/MachO.h" 18*0b57cec5SDimitry Andric #include "llvm/Support/Format.h" 19*0b57cec5SDimitry Andric 20*0b57cec5SDimitry Andric #define DEBUG_TYPE "dyld" 21*0b57cec5SDimitry Andric 22*0b57cec5SDimitry Andric using namespace llvm; 23*0b57cec5SDimitry Andric using namespace llvm::object; 24*0b57cec5SDimitry Andric 25*0b57cec5SDimitry Andric namespace llvm { 26*0b57cec5SDimitry Andric class RuntimeDyldMachO : public RuntimeDyldImpl { 27*0b57cec5SDimitry Andric protected: 28*0b57cec5SDimitry Andric struct SectionOffsetPair { 29*0b57cec5SDimitry Andric unsigned SectionID; 30*0b57cec5SDimitry Andric uint64_t Offset; 31*0b57cec5SDimitry Andric }; 32*0b57cec5SDimitry Andric 33*0b57cec5SDimitry Andric struct EHFrameRelatedSections { EHFrameRelatedSectionsEHFrameRelatedSections34*0b57cec5SDimitry Andric EHFrameRelatedSections() 35*0b57cec5SDimitry Andric : EHFrameSID(RTDYLD_INVALID_SECTION_ID), 36*0b57cec5SDimitry Andric TextSID(RTDYLD_INVALID_SECTION_ID), 37*0b57cec5SDimitry Andric ExceptTabSID(RTDYLD_INVALID_SECTION_ID) {} 38*0b57cec5SDimitry Andric EHFrameRelatedSectionsEHFrameRelatedSections39*0b57cec5SDimitry Andric EHFrameRelatedSections(SID EH, SID T, SID Ex) 40*0b57cec5SDimitry Andric : EHFrameSID(EH), TextSID(T), ExceptTabSID(Ex) {} 41*0b57cec5SDimitry Andric SID EHFrameSID; 42*0b57cec5SDimitry Andric SID TextSID; 43*0b57cec5SDimitry Andric SID ExceptTabSID; 44*0b57cec5SDimitry Andric }; 45*0b57cec5SDimitry Andric 46*0b57cec5SDimitry Andric // When a module is loaded we save the SectionID of the EH frame section 47*0b57cec5SDimitry Andric // in a table until we receive a request to register all unregistered 48*0b57cec5SDimitry Andric // EH frame sections with the memory manager. 49*0b57cec5SDimitry Andric SmallVector<EHFrameRelatedSections, 2> UnregisteredEHFrameSections; 50*0b57cec5SDimitry Andric RuntimeDyldMachO(RuntimeDyld::MemoryManager & MemMgr,JITSymbolResolver & Resolver)51*0b57cec5SDimitry Andric RuntimeDyldMachO(RuntimeDyld::MemoryManager &MemMgr, 52*0b57cec5SDimitry Andric JITSymbolResolver &Resolver) 53*0b57cec5SDimitry Andric : RuntimeDyldImpl(MemMgr, Resolver) {} 54*0b57cec5SDimitry Andric 55*0b57cec5SDimitry Andric /// This convenience method uses memcpy to extract a contiguous addend (the 56*0b57cec5SDimitry Andric /// addend size and offset are taken from the corresponding fields of the RE). 57*0b57cec5SDimitry Andric int64_t memcpyAddend(const RelocationEntry &RE) const; 58*0b57cec5SDimitry Andric 59*0b57cec5SDimitry Andric /// Given a relocation_iterator for a non-scattered relocation, construct a 60*0b57cec5SDimitry Andric /// RelocationEntry and fill in the common fields. The 'Addend' field is *not* 61*0b57cec5SDimitry Andric /// filled in, since immediate encodings are highly target/opcode specific. 62*0b57cec5SDimitry Andric /// For targets/opcodes with simple, contiguous immediates (e.g. X86) the 63*0b57cec5SDimitry Andric /// memcpyAddend method can be used to read the immediate. getRelocationEntry(unsigned SectionID,const ObjectFile & BaseTObj,const relocation_iterator & RI)64*0b57cec5SDimitry Andric RelocationEntry getRelocationEntry(unsigned SectionID, 65*0b57cec5SDimitry Andric const ObjectFile &BaseTObj, 66*0b57cec5SDimitry Andric const relocation_iterator &RI) const { 67*0b57cec5SDimitry Andric const MachOObjectFile &Obj = 68*0b57cec5SDimitry Andric static_cast<const MachOObjectFile &>(BaseTObj); 69*0b57cec5SDimitry Andric MachO::any_relocation_info RelInfo = 70*0b57cec5SDimitry Andric Obj.getRelocation(RI->getRawDataRefImpl()); 71*0b57cec5SDimitry Andric 72*0b57cec5SDimitry Andric bool IsPCRel = Obj.getAnyRelocationPCRel(RelInfo); 73*0b57cec5SDimitry Andric unsigned Size = Obj.getAnyRelocationLength(RelInfo); 74*0b57cec5SDimitry Andric uint64_t Offset = RI->getOffset(); 75*0b57cec5SDimitry Andric MachO::RelocationInfoType RelType = 76*0b57cec5SDimitry Andric static_cast<MachO::RelocationInfoType>(Obj.getAnyRelocationType(RelInfo)); 77*0b57cec5SDimitry Andric 78*0b57cec5SDimitry Andric return RelocationEntry(SectionID, Offset, RelType, 0, IsPCRel, Size); 79*0b57cec5SDimitry Andric } 80*0b57cec5SDimitry Andric 81*0b57cec5SDimitry Andric /// Process a scattered vanilla relocation. 82*0b57cec5SDimitry Andric Expected<relocation_iterator> 83*0b57cec5SDimitry Andric processScatteredVANILLA(unsigned SectionID, relocation_iterator RelI, 84*0b57cec5SDimitry Andric const ObjectFile &BaseObjT, 85*0b57cec5SDimitry Andric RuntimeDyldMachO::ObjSectionToIDMap &ObjSectionToID, 86*0b57cec5SDimitry Andric bool TargetIsLocalThumbFunc = false); 87*0b57cec5SDimitry Andric 88*0b57cec5SDimitry Andric /// Construct a RelocationValueRef representing the relocation target. 89*0b57cec5SDimitry Andric /// For Symbols in known sections, this will return a RelocationValueRef 90*0b57cec5SDimitry Andric /// representing a (SectionID, Offset) pair. 91*0b57cec5SDimitry Andric /// For Symbols whose section is not known, this will return a 92*0b57cec5SDimitry Andric /// (SymbolName, Offset) pair, where the Offset is taken from the instruction 93*0b57cec5SDimitry Andric /// immediate (held in RE.Addend). 94*0b57cec5SDimitry Andric /// In both cases the Addend field is *NOT* fixed up to be PC-relative. That 95*0b57cec5SDimitry Andric /// should be done by the caller where appropriate by calling makePCRel on 96*0b57cec5SDimitry Andric /// the RelocationValueRef. 97*0b57cec5SDimitry Andric Expected<RelocationValueRef> 98*0b57cec5SDimitry Andric getRelocationValueRef(const ObjectFile &BaseTObj, 99*0b57cec5SDimitry Andric const relocation_iterator &RI, 100*0b57cec5SDimitry Andric const RelocationEntry &RE, 101*0b57cec5SDimitry Andric ObjSectionToIDMap &ObjSectionToID); 102*0b57cec5SDimitry Andric 103*0b57cec5SDimitry Andric /// Make the RelocationValueRef addend PC-relative. 104*0b57cec5SDimitry Andric void makeValueAddendPCRel(RelocationValueRef &Value, 105*0b57cec5SDimitry Andric const relocation_iterator &RI, 106*0b57cec5SDimitry Andric unsigned OffsetToNextPC); 107*0b57cec5SDimitry Andric 108*0b57cec5SDimitry Andric /// Dump information about the relocation entry (RE) and resolved value. 109*0b57cec5SDimitry Andric void dumpRelocationToResolve(const RelocationEntry &RE, uint64_t Value) const; 110*0b57cec5SDimitry Andric 111*0b57cec5SDimitry Andric // Return a section iterator for the section containing the given address. 112*0b57cec5SDimitry Andric static section_iterator getSectionByAddress(const MachOObjectFile &Obj, 113*0b57cec5SDimitry Andric uint64_t Addr); 114*0b57cec5SDimitry Andric 115*0b57cec5SDimitry Andric 116*0b57cec5SDimitry Andric // Populate __pointers section. 117*0b57cec5SDimitry Andric Error populateIndirectSymbolPointersSection(const MachOObjectFile &Obj, 118*0b57cec5SDimitry Andric const SectionRef &PTSection, 119*0b57cec5SDimitry Andric unsigned PTSectionID); 120*0b57cec5SDimitry Andric 121*0b57cec5SDimitry Andric public: 122*0b57cec5SDimitry Andric 123*0b57cec5SDimitry Andric /// Create a RuntimeDyldMachO instance for the given target architecture. 124*0b57cec5SDimitry Andric static std::unique_ptr<RuntimeDyldMachO> 125*0b57cec5SDimitry Andric create(Triple::ArchType Arch, 126*0b57cec5SDimitry Andric RuntimeDyld::MemoryManager &MemMgr, 127*0b57cec5SDimitry Andric JITSymbolResolver &Resolver); 128*0b57cec5SDimitry Andric 129*0b57cec5SDimitry Andric std::unique_ptr<RuntimeDyld::LoadedObjectInfo> 130*0b57cec5SDimitry Andric loadObject(const object::ObjectFile &O) override; 131*0b57cec5SDimitry Andric getSection(unsigned SectionID)132*0b57cec5SDimitry Andric SectionEntry &getSection(unsigned SectionID) { return Sections[SectionID]; } 133*0b57cec5SDimitry Andric 134*0b57cec5SDimitry Andric bool isCompatibleFile(const object::ObjectFile &Obj) const override; 135*0b57cec5SDimitry Andric }; 136*0b57cec5SDimitry Andric 137*0b57cec5SDimitry Andric /// RuntimeDyldMachOTarget - Templated base class for generic MachO linker 138*0b57cec5SDimitry Andric /// algorithms and data structures. 139*0b57cec5SDimitry Andric /// 140*0b57cec5SDimitry Andric /// Concrete, target specific sub-classes can be accessed via the impl() 141*0b57cec5SDimitry Andric /// methods. (i.e. the RuntimeDyldMachO hierarchy uses the Curiously 142*0b57cec5SDimitry Andric /// Recurring Template Idiom). Concrete subclasses for each target 143*0b57cec5SDimitry Andric /// can be found in ./Targets. 144*0b57cec5SDimitry Andric template <typename Impl> 145*0b57cec5SDimitry Andric class RuntimeDyldMachOCRTPBase : public RuntimeDyldMachO { 146*0b57cec5SDimitry Andric private: impl()147*0b57cec5SDimitry Andric Impl &impl() { return static_cast<Impl &>(*this); } impl()148*0b57cec5SDimitry Andric const Impl &impl() const { return static_cast<const Impl &>(*this); } 149*0b57cec5SDimitry Andric 150*0b57cec5SDimitry Andric unsigned char *processFDE(uint8_t *P, int64_t DeltaForText, 151*0b57cec5SDimitry Andric int64_t DeltaForEH); 152*0b57cec5SDimitry Andric 153*0b57cec5SDimitry Andric public: RuntimeDyldMachOCRTPBase(RuntimeDyld::MemoryManager & MemMgr,JITSymbolResolver & Resolver)154*0b57cec5SDimitry Andric RuntimeDyldMachOCRTPBase(RuntimeDyld::MemoryManager &MemMgr, 155*0b57cec5SDimitry Andric JITSymbolResolver &Resolver) 156*0b57cec5SDimitry Andric : RuntimeDyldMachO(MemMgr, Resolver) {} 157*0b57cec5SDimitry Andric 158*0b57cec5SDimitry Andric Error finalizeLoad(const ObjectFile &Obj, 159*0b57cec5SDimitry Andric ObjSectionToIDMap &SectionMap) override; 160*0b57cec5SDimitry Andric void registerEHFrames() override; 161*0b57cec5SDimitry Andric }; 162*0b57cec5SDimitry Andric 163*0b57cec5SDimitry Andric } // end namespace llvm 164*0b57cec5SDimitry Andric 165*0b57cec5SDimitry Andric #undef DEBUG_TYPE 166*0b57cec5SDimitry Andric 167*0b57cec5SDimitry Andric #endif 168