LLVM: lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFAArch64.h Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13#ifndef LLVM_LIB_EXECUTIONENGINE_RUNTIMEDYLD_TARGETS_RUNTIMEDYLDCOFFAARCH64_H
14#define LLVM_LIB_EXECUTIONENGINE_RUNTIMEDYLD_TARGETS_RUNTIMEDYLDCOFFAARCH64_H
15
21
22#define DEBUG_TYPE "dyld"
23
24namespace llvm {
25
26
27
31
36
37static void or32le(void *P, int32_t V) {
39
41}
42
45
47 orig &= ~(0xFFF << 10);
48 write32le(T, orig | ((imm & (0xFFF >> rangeLimit)) << 10));
49}
50
53
56
57
58 if ((orig & 0x04800000) == 0x04800000)
60 if ((imm & ((1 << size) - 1)) != 0)
61 assert(0 && "misaligned ldr/str offset");
63}
64
67
68 uint64_t Imm = (s >> shift) - (p >> shift);
69 uint32_t ImmLo = (Imm & 0x3) << 29;
70 uint32_t ImmHi = (Imm & 0x1FFFFC) << 3;
71 uint64_t Mask = (0x3 << 29) | (0x1FFFFC << 3);
73}
74
76
77private:
78
79
80
84
85
87 if (!ImageBase) {
88 ImageBase = std::numeric_limits<uint64_t>::max();
90
91
92
93
94
95 if (Section.getLoadAddress() != 0)
96 ImageBase = std::min(ImageBase, Section.getLoadAddress());
97 }
98 return ImageBase;
99 }
100
101public:
106
108
110
111 std::tuple<uint64_t, uint64_t, uint64_t>
115 uintptr_t StubOffset;
117
119 OriginalRelValueRef.SectionID = SectionID;
121 OriginalRelValueRef.Addend = Addend;
123
124 auto [Stub, Inserted] = Stubs.try_emplace(OriginalRelValueRef);
125 if (Inserted) {
126 LLVM_DEBUG(dbgs() << " Create a new stub function for "
127 << TargetName.data() << "\n");
128
129 StubOffset = Section.getStubOffset();
130 Stub->second = StubOffset;
133 } else {
134 LLVM_DEBUG(dbgs() << " Stub function found for " << TargetName.data()
135 << "\n");
136 StubOffset = Stub->second;
137 }
138
139
141 resolveRelocation(RE, Section.getLoadAddressWithOffset(StubOffset));
142
143
144
145
146 Addend = 0;
149
150 return std::make_tuple(Offset, RelType, Addend);
151 }
152
157 StubMap &Stubs) override {
159
161 if (Symbol == Obj.symbol_end())
163
165 if (!TargetNameOrErr)
166 return TargetNameOrErr.takeError();
167 StringRef TargetName = *TargetNameOrErr;
168
169 auto SectionOrErr = Symbol->getSection();
170 if (!SectionOrErr)
172 auto Section = *SectionOrErr;
173
176
177
178 bool IsExtern = Section == Obj.section_end();
179
180
185
186 unsigned TargetSectionID = -1;
188
190 TargetSectionID = SectionID;
193 IsExtern = false;
194 } else if (!IsExtern) {
196 Obj, *Section, Section->isText(), ObjSectionToID))
197 TargetSectionID = *TargetSectionIDOrErr;
198 else
199 return TargetSectionIDOrErr.takeError();
200
202 }
203
204 switch (RelType) {
209 Addend = read32le(Displacement);
210 break;
213 Addend = (orig & 0x03FFFFFF) << 2;
214
215 if (IsExtern)
217 SectionID, TargetName, Offset, RelType, Addend, Stubs);
218 break;
219 }
222 Addend = (orig & 0x00FFFFE0) >> 3;
223 break;
224 }
227 Addend = (orig & 0x000FFFE0) >> 3;
228 break;
229 }
233 Addend = ((orig >> 29) & 0x3) | ((orig >> 3) & 0x1FFFFC);
234 break;
235 }
239 Addend = ((orig >> 10) & 0xFFF);
240 break;
241 }
243 Addend = read64le(Displacement);
244 break;
245 }
246 default:
247 break;
248 }
249
250#if !defined(NDEBUG)
253
255 << " RelType: " << RelTypeName << " TargetName: "
256 << TargetName << " Addend " << Addend << "\n");
257#endif
258
259 if (IsExtern) {
262 } else {
265 }
266 return ++RelI;
267 }
268
271
274 uint64_t FinalAddress = Section.getLoadAddressWithOffset(RE.Offset);
275
277 default:
280
281 break;
282 }
284
287 break;
288 }
290
293 break;
294 }
296
297
300 break;
301 }
303
304
307 break;
308 }
310
313 break;
314 }
316
319 break;
320 }
322
327 break;
328 }
330
331
333 assert(isInt<28>(PCRelVal) && "Branch target is out of range.");
335 (PCRelVal & 0x0FFFFFFC) >> 2);
336 break;
337 }
339
340
342 assert(isInt<21>(PCRelVal) && "Branch target is out of range.");
344 (PCRelVal & 0x001FFFFC) << 3);
345 break;
346 }
348
349
351 assert(isInt<16>(PCRelVal) && "Branch target is out of range.");
353 (PCRelVal & 0x0000FFFC) << 3);
354 break;
355 }
357
359 break;
360 }
362
364 "relocation overflow");
366 break;
367 }
369
370 assert(static_cast<int64_t>(RE.Addend) <= INT32_MAX &&
371 "Relocation overflow");
372 assert(static_cast<int64_t>(RE.Addend) >= INT32_MIN &&
373 "Relocation underflow");
375 break;
376 }
378
381 break;
382 }
383 }
384 }
385
387};
388
389}
390
391#undef DEBUG_TYPE
392
393#endif
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file defines the SmallString class.
void write32le(void *P, uint32_t V)
Tagged union holding either a T or a Error.
Error takeError()
Take ownership of the stored error.
Symbol resolution interface.
RelocationEntry - used to represent relocations internally in the dynamic linker.
uint32_t RelType
RelType - relocation type.
uint64_t Offset
Offset - offset into the section.
int64_t Addend
Addend - the relocation addend encoded in the instruction itself.
unsigned SectionID
SectionID - the section this relocation points to.
Interface for looking up the initializer for a variable name, used by Init::resolveReferences.
Align getStubAlignment() override
Definition RuntimeDyldCOFFAArch64.h:107
void resolveRelocation(const RelocationEntry &RE, uint64_t Value) override
A object file specific relocation resolver.
Definition RuntimeDyldCOFFAArch64.h:269
unsigned getMaxStubSize() const override
Definition RuntimeDyldCOFFAArch64.h:109
RuntimeDyldCOFFAArch64(RuntimeDyld::MemoryManager &MM, JITSymbolResolver &Resolver)
Definition RuntimeDyldCOFFAArch64.h:102
void registerEHFrames() override
Definition RuntimeDyldCOFFAArch64.h:386
std::tuple< uint64_t, uint64_t, uint64_t > generateRelocationStub(unsigned SectionID, StringRef TargetName, uint64_t Offset, uint64_t RelType, uint64_t Addend, StubMap &Stubs)
Definition RuntimeDyldCOFFAArch64.h:112
Expected< object::relocation_iterator > processRelocationRef(unsigned SectionID, object::relocation_iterator RelI, const object::ObjectFile &Obj, ObjSectionToIDMap &ObjSectionToID, StubMap &Stubs) override
Parses one or more object file relocations (some object files use relocation pairs) and stores it to ...
Definition RuntimeDyldCOFFAArch64.h:154
uint64_t getSymbolOffset(const SymbolRef &Sym)
static constexpr StringRef getImportSymbolPrefix()
RuntimeDyldCOFF(RuntimeDyld::MemoryManager &MemMgr, JITSymbolResolver &Resolver, unsigned PointerSize, uint32_t PointerReloc)
uint64_t getDLLImportOffset(unsigned SectionID, StubMap &Stubs, StringRef Name, bool SetSectionIDMinus1=false)
std::map< SectionRef, unsigned > ObjSectionToIDMap
std::map< RelocationValueRef, uintptr_t > StubMap
void addRelocationForSymbol(const RelocationEntry &RE, StringRef SymbolName)
void addRelocationForSection(const RelocationEntry &RE, unsigned SectionID)
Expected< unsigned > findOrEmitSection(const ObjectFile &Obj, const SectionRef &Section, bool IsCode, ObjSectionToIDMap &LocalSections)
Find Section in LocalSections.
uint8_t * createStubFunction(uint8_t *Addr, unsigned AbiVariant=0)
Emits long jump instruction to Addr.
SectionEntry - represents a section emitted into memory by the dynamic linker.
uintptr_t getObjAddress() const
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
constexpr const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Target - Wrapper for Target specific information.
LLVM Value Representation.
This class is the base class for all object file types.
uint64_t getOffset() const
symbol_iterator getSymbol() const
void getTypeName(SmallVectorImpl< char > &Result) const
Get a string that represents the type of this relocation.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ IMAGE_REL_ARM64_BRANCH19
@ IMAGE_REL_ARM64_SECTION
@ IMAGE_REL_ARM64_ABSOLUTE
@ IMAGE_REL_ARM64_PAGEOFFSET_12A
@ IMAGE_REL_ARM64_BRANCH14
@ IMAGE_REL_ARM64_BRANCH26
@ IMAGE_REL_ARM64_PAGEOFFSET_12L
@ IMAGE_REL_ARM64_ADDR32NB
@ IMAGE_REL_ARM64_PAGEBASE_REL21
content_iterator< RelocationRef > relocation_iterator
uint64_t read64le(const void *P)
uint16_t read16le(const void *P)
void write64le(void *P, uint64_t V)
void write16le(void *P, uint16_t V)
uint32_t read32le(const void *P)
This is an optimization pass for GlobalISel generic memory operations.
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
InternalRelocationType
Definition RuntimeDyldCOFFAArch64.h:28
@ INTERNAL_REL_ARM64_LONG_BRANCH26
Definition RuntimeDyldCOFFAArch64.h:29
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
static void write32AArch64Ldr(uint8_t *T, uint64_t imm)
Definition RuntimeDyldCOFFAArch64.h:51
static void or32le(void *P, int32_t V)
Definition RuntimeDyldCOFFAArch64.h:37
static void add16(uint8_t *p, int16_t v)
Definition RuntimeDyldCOFFAArch64.h:32
static void write32AArch64Imm(uint8_t *T, uint64_t imm, uint32_t rangeLimit)
Definition RuntimeDyldCOFFAArch64.h:43
static void write32AArch64Addr(void *T, uint64_t s, uint64_t p, int shift)
Definition RuntimeDyldCOFFAArch64.h:65
This struct is a compact representation of a valid (non-zero power of two) alignment.