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