xref: /freebsd/contrib/llvm-project/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h (revision 0b57cec536236d46e3dba9bd041533462f33dbb7)
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