Line data Source code
1 : //===-- RuntimeDyldELF.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 : // ELF support for MC-JIT runtime dynamic linker.
11 : //
12 : //===----------------------------------------------------------------------===//
13 :
14 : #ifndef LLVM_LIB_EXECUTIONENGINE_RUNTIMEDYLD_RUNTIMEDYLDELF_H
15 : #define LLVM_LIB_EXECUTIONENGINE_RUNTIMEDYLD_RUNTIMEDYLDELF_H
16 :
17 : #include "RuntimeDyldImpl.h"
18 : #include "llvm/ADT/DenseMap.h"
19 :
20 : using namespace llvm;
21 :
22 : namespace llvm {
23 : namespace object {
24 : class ELFObjectFileBase;
25 : }
26 :
27 : class RuntimeDyldELF : public RuntimeDyldImpl {
28 :
29 : void resolveRelocation(const SectionEntry &Section, uint64_t Offset,
30 : uint64_t Value, uint32_t Type, int64_t Addend,
31 : uint64_t SymOffset = 0, SID SectionID = 0);
32 :
33 : void resolveX86_64Relocation(const SectionEntry &Section, uint64_t Offset,
34 : uint64_t Value, uint32_t Type, int64_t Addend,
35 : uint64_t SymOffset);
36 :
37 : void resolveX86Relocation(const SectionEntry &Section, uint64_t Offset,
38 : uint32_t Value, uint32_t Type, int32_t Addend);
39 :
40 : void resolveAArch64Relocation(const SectionEntry &Section, uint64_t Offset,
41 : uint64_t Value, uint32_t Type, int64_t Addend);
42 :
43 : bool resolveAArch64ShortBranch(unsigned SectionID, relocation_iterator RelI,
44 : const RelocationValueRef &Value);
45 :
46 : void resolveAArch64Branch(unsigned SectionID, const RelocationValueRef &Value,
47 : relocation_iterator RelI, StubMap &Stubs);
48 :
49 : void resolveARMRelocation(const SectionEntry &Section, uint64_t Offset,
50 : uint32_t Value, uint32_t Type, int32_t Addend);
51 :
52 : void resolvePPC32Relocation(const SectionEntry &Section, uint64_t Offset,
53 : uint64_t Value, uint32_t Type, int64_t Addend);
54 :
55 : void resolvePPC64Relocation(const SectionEntry &Section, uint64_t Offset,
56 : uint64_t Value, uint32_t Type, int64_t Addend);
57 :
58 : void resolveSystemZRelocation(const SectionEntry &Section, uint64_t Offset,
59 : uint64_t Value, uint32_t Type, int64_t Addend);
60 :
61 : void resolveBPFRelocation(const SectionEntry &Section, uint64_t Offset,
62 : uint64_t Value, uint32_t Type, int64_t Addend);
63 :
64 843 : unsigned getMaxStubSize() override {
65 843 : if (Arch == Triple::aarch64 || Arch == Triple::aarch64_be)
66 : return 20; // movz; movk; movk; movk; br
67 835 : if (Arch == Triple::arm || Arch == Triple::thumb)
68 : return 8; // 32-bit instruction and 32-bit address
69 833 : else if (IsMipsO32ABI || IsMipsN32ABI)
70 : return 16;
71 797 : else if (IsMipsN64ABI)
72 : return 32;
73 773 : else if (Arch == Triple::ppc64 || Arch == Triple::ppc64le)
74 : return 44;
75 754 : else if (Arch == Triple::x86_64)
76 : return 6; // 2-byte jmp instruction + 32-bit relative address
77 5 : else if (Arch == Triple::systemz)
78 : return 16;
79 : else
80 2 : return 0;
81 : }
82 :
83 1212 : unsigned getStubAlignment() override {
84 1212 : if (Arch == Triple::systemz)
85 : return 8;
86 : else
87 1205 : return 1;
88 : }
89 :
90 : void setMipsABI(const ObjectFile &Obj) override;
91 :
92 : Error findPPC64TOCSection(const ELFObjectFileBase &Obj,
93 : ObjSectionToIDMap &LocalSections,
94 : RelocationValueRef &Rel);
95 : Error findOPDEntrySection(const ELFObjectFileBase &Obj,
96 : ObjSectionToIDMap &LocalSections,
97 : RelocationValueRef &Rel);
98 : protected:
99 : size_t getGOTEntrySize() override;
100 :
101 : private:
102 : SectionEntry &getSection(unsigned SectionID) { return Sections[SectionID]; }
103 :
104 : // Allocate no GOT entries for use in the given section.
105 : uint64_t allocateGOTEntries(unsigned no);
106 :
107 : // Find GOT entry corresponding to relocation or create new one.
108 : uint64_t findOrAllocGOTEntry(const RelocationValueRef &Value,
109 : unsigned GOTRelType);
110 :
111 : // Resolve the relvative address of GOTOffset in Section ID and place
112 : // it at the given Offset
113 : void resolveGOTOffsetRelocation(unsigned SectionID, uint64_t Offset,
114 : uint64_t GOTOffset, uint32_t Type);
115 :
116 : // For a GOT entry referenced from SectionID, compute a relocation entry
117 : // that will place the final resolved value in the GOT slot
118 : RelocationEntry computeGOTOffsetRE(uint64_t GOTOffset, uint64_t SymbolOffset,
119 : unsigned Type);
120 :
121 : // Compute the address in memory where we can find the placeholder
122 : void *computePlaceholderAddress(unsigned SectionID, uint64_t Offset) const;
123 :
124 : // Split out common case for createing the RelocationEntry for when the relocation requires
125 : // no particular advanced processing.
126 : void processSimpleRelocation(unsigned SectionID, uint64_t Offset, unsigned RelType, RelocationValueRef Value);
127 :
128 : // Return matching *LO16 relocation (Mips specific)
129 : uint32_t getMatchingLoRelocation(uint32_t RelType,
130 : bool IsLocal = false) const;
131 :
132 : // The tentative ID for the GOT section
133 : unsigned GOTSectionID;
134 :
135 : // Records the current number of allocated slots in the GOT
136 : // (This would be equivalent to GOTEntries.size() were it not for relocations
137 : // that consume more than one slot)
138 : unsigned CurrentGOTIndex;
139 :
140 : protected:
141 : // A map from section to a GOT section that has entries for section's GOT
142 : // relocations. (Mips64 specific)
143 : DenseMap<SID, SID> SectionToGOTMap;
144 :
145 : private:
146 : // A map to avoid duplicate got entries (Mips64 specific)
147 : StringMap<uint64_t> GOTSymbolOffsets;
148 :
149 : // *HI16 relocations will be added for resolving when we find matching
150 : // *LO16 part. (Mips specific)
151 : SmallVector<std::pair<RelocationValueRef, RelocationEntry>, 8> PendingRelocs;
152 :
153 : // When a module is loaded we save the SectionID of the EH frame section
154 : // in a table until we receive a request to register all unregistered
155 : // EH frame sections with the memory manager.
156 : SmallVector<SID, 2> UnregisteredEHFrameSections;
157 :
158 : // Map between GOT relocation value and corresponding GOT offset
159 : std::map<RelocationValueRef, uint64_t> GOTOffsetMap;
160 :
161 : bool relocationNeedsGot(const RelocationRef &R) const override;
162 : bool relocationNeedsStub(const RelocationRef &R) const override;
163 :
164 : public:
165 : RuntimeDyldELF(RuntimeDyld::MemoryManager &MemMgr,
166 : JITSymbolResolver &Resolver);
167 : ~RuntimeDyldELF() override;
168 :
169 : static std::unique_ptr<RuntimeDyldELF>
170 : create(Triple::ArchType Arch, RuntimeDyld::MemoryManager &MemMgr,
171 : JITSymbolResolver &Resolver);
172 :
173 : std::unique_ptr<RuntimeDyld::LoadedObjectInfo>
174 : loadObject(const object::ObjectFile &O) override;
175 :
176 : void resolveRelocation(const RelocationEntry &RE, uint64_t Value) override;
177 : Expected<relocation_iterator>
178 : processRelocationRef(unsigned SectionID, relocation_iterator RelI,
179 : const ObjectFile &Obj,
180 : ObjSectionToIDMap &ObjSectionToID,
181 : StubMap &Stubs) override;
182 : bool isCompatibleFile(const object::ObjectFile &Obj) const override;
183 : void registerEHFrames() override;
184 : Error finalizeLoad(const ObjectFile &Obj,
185 : ObjSectionToIDMap &SectionMap) override;
186 : };
187 :
188 : } // end namespace llvm
189 :
190 : #endif
|