Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h
35268 views
1
//===-- RuntimeDyldELF.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
// ELF support for MC-JIT runtime dynamic linker.
10
//
11
//===----------------------------------------------------------------------===//
12
13
#ifndef LLVM_LIB_EXECUTIONENGINE_RUNTIMEDYLD_RUNTIMEDYLDELF_H
14
#define LLVM_LIB_EXECUTIONENGINE_RUNTIMEDYLD_RUNTIMEDYLDELF_H
15
16
#include "RuntimeDyldImpl.h"
17
#include "llvm/ADT/DenseMap.h"
18
19
using namespace llvm;
20
21
namespace llvm {
22
namespace object {
23
class ELFObjectFileBase;
24
}
25
26
class RuntimeDyldELF : public RuntimeDyldImpl {
27
28
void resolveRelocation(const SectionEntry &Section, uint64_t Offset,
29
uint64_t Value, uint32_t Type, int64_t Addend,
30
uint64_t SymOffset = 0, SID SectionID = 0);
31
32
void resolveX86_64Relocation(const SectionEntry &Section, uint64_t Offset,
33
uint64_t Value, uint32_t Type, int64_t Addend,
34
uint64_t SymOffset);
35
36
void resolveX86Relocation(const SectionEntry &Section, uint64_t Offset,
37
uint32_t Value, uint32_t Type, int32_t Addend);
38
39
void resolveAArch64Relocation(const SectionEntry &Section, uint64_t Offset,
40
uint64_t Value, uint32_t Type, int64_t Addend);
41
42
bool resolveAArch64ShortBranch(unsigned SectionID, relocation_iterator RelI,
43
const RelocationValueRef &Value);
44
45
void resolveAArch64Branch(unsigned SectionID, const RelocationValueRef &Value,
46
relocation_iterator RelI, StubMap &Stubs);
47
48
void resolveARMRelocation(const SectionEntry &Section, uint64_t Offset,
49
uint32_t Value, uint32_t Type, int32_t Addend);
50
51
void resolvePPC32Relocation(const SectionEntry &Section, uint64_t Offset,
52
uint64_t Value, uint32_t Type, int64_t Addend);
53
54
void resolvePPC64Relocation(const SectionEntry &Section, uint64_t Offset,
55
uint64_t Value, uint32_t Type, int64_t Addend);
56
57
void resolveSystemZRelocation(const SectionEntry &Section, uint64_t Offset,
58
uint64_t Value, uint32_t Type, int64_t Addend);
59
60
void resolveBPFRelocation(const SectionEntry &Section, uint64_t Offset,
61
uint64_t Value, uint32_t Type, int64_t Addend);
62
63
unsigned getMaxStubSize() const override {
64
if (Arch == Triple::aarch64 || Arch == Triple::aarch64_be)
65
return 20; // movz; movk; movk; movk; br
66
if (Arch == Triple::arm || Arch == Triple::thumb)
67
return 8; // 32-bit instruction and 32-bit address
68
else if (IsMipsO32ABI || IsMipsN32ABI)
69
return 16;
70
else if (IsMipsN64ABI)
71
return 32;
72
else if (Arch == Triple::ppc64 || Arch == Triple::ppc64le)
73
return 44;
74
else if (Arch == Triple::x86_64)
75
return 6; // 2-byte jmp instruction + 32-bit relative address
76
else if (Arch == Triple::systemz)
77
return 16;
78
else
79
return 0;
80
}
81
82
Align getStubAlignment() override {
83
if (Arch == Triple::systemz)
84
return Align(8);
85
else
86
return Align(1);
87
}
88
89
void setMipsABI(const ObjectFile &Obj) override;
90
91
Error findPPC64TOCSection(const object::ELFObjectFileBase &Obj,
92
ObjSectionToIDMap &LocalSections,
93
RelocationValueRef &Rel);
94
Error findOPDEntrySection(const object::ELFObjectFileBase &Obj,
95
ObjSectionToIDMap &LocalSections,
96
RelocationValueRef &Rel);
97
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 relative 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 creating the RelocationEntry for when the
125
// relocation requires 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
/// The ID of the current IFunc stub section
162
unsigned IFuncStubSectionID = 0;
163
/// The current offset into the IFunc stub section
164
uint64_t IFuncStubOffset = 0;
165
166
/// A IFunc stub and its original symbol
167
struct IFuncStub {
168
/// The offset of this stub in the IFunc stub section
169
uint64_t StubOffset;
170
/// The symbol table entry of the original symbol
171
SymbolTableEntry OriginalSymbol;
172
};
173
174
/// The IFunc stubs
175
SmallVector<IFuncStub, 2> IFuncStubs;
176
177
/// Create the code for the IFunc resolver at the given address. This code
178
/// works together with the stubs created in createIFuncStub() to call the
179
/// resolver function and then jump to the real function address.
180
/// It must not be larger than 64B.
181
void createIFuncResolver(uint8_t *Addr) const;
182
/// Create the code for an IFunc stub for the IFunc that is defined in
183
/// section IFuncSectionID at offset IFuncOffset. The IFunc resolver created
184
/// by createIFuncResolver() is defined in the section IFuncStubSectionID at
185
/// offset IFuncResolverOffset. The code should be written into the section
186
/// with the id IFuncStubSectionID at the offset IFuncStubOffset.
187
void createIFuncStub(unsigned IFuncStubSectionID,
188
uint64_t IFuncResolverOffset, uint64_t IFuncStubOffset,
189
unsigned IFuncSectionID, uint64_t IFuncOffset);
190
/// Return the maximum size of a stub created by createIFuncStub()
191
unsigned getMaxIFuncStubSize() const;
192
193
void processNewSymbol(const SymbolRef &ObjSymbol,
194
SymbolTableEntry &Entry) override;
195
bool relocationNeedsGot(const RelocationRef &R) const override;
196
bool relocationNeedsStub(const RelocationRef &R) const override;
197
198
// Process a GOTTPOFF TLS relocation for x86-64
199
// NOLINTNEXTLINE(readability-identifier-naming)
200
void processX86_64GOTTPOFFRelocation(unsigned SectionID, uint64_t Offset,
201
RelocationValueRef Value,
202
int64_t Addend);
203
// Process a TLSLD/TLSGD relocation for x86-64
204
// NOLINTNEXTLINE(readability-identifier-naming)
205
void processX86_64TLSRelocation(unsigned SectionID, uint64_t Offset,
206
uint64_t RelType, RelocationValueRef Value,
207
int64_t Addend,
208
const RelocationRef &GetAddrRelocation);
209
210
public:
211
RuntimeDyldELF(RuntimeDyld::MemoryManager &MemMgr,
212
JITSymbolResolver &Resolver);
213
~RuntimeDyldELF() override;
214
215
static std::unique_ptr<RuntimeDyldELF>
216
create(Triple::ArchType Arch, RuntimeDyld::MemoryManager &MemMgr,
217
JITSymbolResolver &Resolver);
218
219
std::unique_ptr<RuntimeDyld::LoadedObjectInfo>
220
loadObject(const object::ObjectFile &O) override;
221
222
void resolveRelocation(const RelocationEntry &RE, uint64_t Value) override;
223
Expected<relocation_iterator>
224
processRelocationRef(unsigned SectionID, relocation_iterator RelI,
225
const ObjectFile &Obj,
226
ObjSectionToIDMap &ObjSectionToID,
227
StubMap &Stubs) override;
228
bool isCompatibleFile(const object::ObjectFile &Obj) const override;
229
void registerEHFrames() override;
230
Error finalizeLoad(const ObjectFile &Obj,
231
ObjSectionToIDMap &SectionMap) override;
232
};
233
234
} // end namespace llvm
235
236
#endif
237
238