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