LLVM: lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOAArch64.h Source File (original) (raw)
21public:
22
24
28
30
32
33
36 uint8_t *LocalAddress = Section.getAddressWithOffset(RE.Offset);
37 unsigned NumBytes = 1 << RE.Size;
38 int64_t Addend = 0;
39
41 default: {
42 std::string ErrMsg;
43 {
45 ErrStream << "Unsupported relocation type: "
46 << getRelocName(RE.RelType);
47 }
50 }
53 if (NumBytes != 4 && NumBytes != 8) {
54 std::string ErrMsg;
55 {
57 ErrStream << "Invalid relocation size for relocation "
58 << getRelocName(RE.RelType);
59 }
62 }
63 break;
64 }
70 assert(NumBytes == 4 && "Invalid relocation size.");
71 assert((((uintptr_t)LocalAddress & 0x3) == 0) &&
72 "Instruction address is not aligned to 4 bytes.");
73 break;
74 }
75
77 default:
81
82 if (NumBytes == 4)
84 else
86 break;
88
90 assert(((*p & 0xFC000000) == 0x14000000 ||
91 (*p & 0xFC000000) == 0x94000000) &&
92 "Expected branch instruction.");
93
94
95
96
97 Addend = (*p & 0x03FFFFFF) << 2;
99 break;
100 }
103
105 assert((*p & 0x9F000000) == 0x90000000 && "Expected adrp instruction.");
106
107
108
109
110 Addend = ((*p & 0x60000000) >> 29) | ((*p & 0x01FFFFE0) >> 3) << 12;
112 break;
113 }
115
116
118 (void)p;
119 assert((*p & 0x3B000000) == 0x39000000 &&
120 "Only expected load / store instructions.");
121 [[fallthrough]];
122 }
124
125
127 assert((((*p & 0x3B000000) == 0x39000000) ||
128 ((*p & 0x11C00000) == 0x11000000) ) &&
129 "Expected load / store or add/sub instruction.");
130
131
132 Addend = (*p & 0x003FFC00) >> 10;
133
134
135
136 int ImplicitShift = 0;
137 if ((*p & 0x3B000000) == 0x39000000) {
138
139 ImplicitShift = ((*p >> 30) & 0x3);
140 if (ImplicitShift == 0) {
141
142 if ((*p & 0x04800000) == 0x04800000)
143 ImplicitShift = 4;
144 }
145 }
146
147 Addend <<= ImplicitShift;
148 break;
149 }
150 }
151 return Addend;
152 }
153
154
157
158 switch (RelType) {
159 default:
163 assert((NumBytes == 4 || NumBytes == 8) && "Invalid relocation size.");
164 break;
170 assert(NumBytes == 4 && "Invalid relocation size.");
171 assert((((uintptr_t)LocalAddress & 0x3) == 0) &&
172 "Instruction address is not aligned to 4 bytes.");
173 break;
174 }
175
176 switch (RelType) {
177 default:
181
182 if (NumBytes == 4)
184 else
186 break;
189
190 assert(((*p & 0xFC000000) == 0x14000000 ||
191 (*p & 0xFC000000) == 0x94000000) &&
192 "Expected branch instruction.");
193
194
195 assert((Addend & 0x3) == 0 && "Branch target is not aligned");
196 assert(isInt<28>(Addend) && "Branch target is out of range.");
197
198
199 *p = (*p & 0xFC000000) | ((uint32_t)(Addend >> 2) & 0x03FFFFFF);
200 break;
201 }
204
206 assert((*p & 0x9F000000) == 0x90000000 && "Expected adrp instruction.");
207
208
209 assert((Addend & 0xFFF) == 0 && "ADRP target is not page aligned.");
210 assert(isInt<33>(Addend) && "Invalid page reloc value.");
211
212
215 *p = (*p & 0x9F00001F) | ImmHiValue | ImmLoValue;
216 break;
217 }
219
220
222 assert((*p & 0x3B000000) == 0x39000000 &&
223 "Only expected load / store instructions.");
224 (void)p;
225 [[fallthrough]];
226 }
228
229
231 assert((((*p & 0x3B000000) == 0x39000000) ||
232 ((*p & 0x11C00000) == 0x11000000) ) &&
233 "Expected load / store or add/sub instruction.");
234
235
236
237 int ImplicitShift = 0;
238 if ((*p & 0x3B000000) == 0x39000000) {
239
240 ImplicitShift = ((*p >> 30) & 0x3);
241 switch (ImplicitShift) {
242 case 0:
243
244 if ((*p & 0x04800000) == 0x04800000) {
245 ImplicitShift = 4;
246 assert(((Addend & 0xF) == 0) &&
247 "128-bit LDR/STR not 16-byte aligned.");
248 }
249 break;
250 case 1:
251 assert(((Addend & 0x1) == 0) && "16-bit LDR/STR not 2-byte aligned.");
252 break;
253 case 2:
254 assert(((Addend & 0x3) == 0) && "32-bit LDR/STR not 4-byte aligned.");
255 break;
256 case 3:
257 assert(((Addend & 0x7) == 0) && "64-bit LDR/STR not 8-byte aligned.");
258 break;
259 }
260 }
261
262 Addend >>= ImplicitShift;
264
265
266 *p = (*p & 0xFFC003FF) | ((uint32_t)(Addend << 10) & 0x003FFC00);
267 break;
268 }
269 }
270 }
271
276 StubMap &Stubs) override {
281
282 if (Obj.isRelocationScattered(RelInfo))
284 "for MachO AArch64");
285
286
287
288
289
290 int64_t ExplicitAddend = 0;
292 assert(!Obj.getPlainRelocationExternal(RelInfo));
293 assert(!Obj.getAnyRelocationPCRel(RelInfo));
294 assert(Obj.getAnyRelocationLength(RelInfo) == 2);
295 int64_t RawAddend = Obj.getPlainRelocationSymbolNum(RelInfo);
296
297 ExplicitAddend = SignExtend64(RawAddend, 24);
298 ++RelI;
300 }
301
303 return processSubtractRelocation(SectionID, RelI, Obj, ObjSectionToID);
304
306
308 bool Valid =
310 if (!Valid)
312 "32-bit pc-rel or 64-bit absolute only",
314 }
315
318 else
319 return Addend.takeError();
320
321 assert((ExplicitAddend == 0 || RE.Addend == 0) && "Relocation has "\
322 "ARM64_RELOC_ADDEND and embedded addend in the instruction.");
323 if (ExplicitAddend)
324 RE.Addend = ExplicitAddend;
325
328 Value = *ValueOrErr;
329 else
330 return ValueOrErr.takeError();
331
332 bool IsExtern = Obj.getPlainRelocationExternal(RelInfo);
334
335 Value.Offset = 0;
336 } else if (!IsExtern && RE.IsPCRel)
338
340
344 processGOTRelocation(RE, Value, Stubs);
345 else {
346 if (Value.SymbolName)
348 else
350 }
351
352 return ++RelI;
353 }
354
357
359 uint8_t *LocalAddress = Section.getAddressWithOffset(RE.Offset);
362
363 switch (RelType) {
364 default:
367 assert(!RE.IsPCRel && "PCRel and ARM64_RELOC_UNSIGNED not supported");
368
369
370 if (RE.Size < 2)
372
374 break;
375 }
376
379 "ARM64_RELOC_POINTER_TO_GOT only supports 32-bit pc-rel or 64-bit "
380 "absolute");
381
382
386 break;
387 }
388
390 assert(RE.IsPCRel && "not PCRel and ARM64_RELOC_BRANCH26 not supported");
391
392 uint64_t FinalAddress = Section.getLoadAddressWithOffset(RE.Offset);
393 int64_t PCRelVal = Value - FinalAddress + RE.Addend;
394 encodeAddend(LocalAddress, 4, RelType, PCRelVal);
395 break;
396 }
399 assert(RE.IsPCRel && "not PCRel and ARM64_RELOC_PAGE21 not supported");
400
401 uint64_t FinalAddress = Section.getLoadAddressWithOffset(RE.Offset);
402 int64_t PCRelVal =
403 ((Value + RE.Addend) & (-4096)) - (FinalAddress & (-4096));
404 encodeAddend(LocalAddress, 4, RelType, PCRelVal);
405 break;
406 }
409 assert(!RE.IsPCRel && "PCRel and ARM64_RELOC_PAGEOFF21 not supported");
410
412
415 break;
416 }
421 "Unexpected SUBTRACTOR relocation value.");
422 Value = SectionABase - SectionBBase + RE.Addend;
424 break;
425 }
426
431 llvm_unreachable("ARM64_RELOC_ADDEND should have been handeled by "
432 "processRelocationRef!");
433 }
434 }
435
440
441private:
445 (RE.Size == 2 || RE.Size == 3)) ||
446 RE.Size == 2);
448 auto [It, Inserted] = Stubs.try_emplace(Value);
450 if (!Inserted)
451 Offset = static_cast<int64_t>(It->second);
452 else {
453
454
455 uintptr_t BaseAddress = uintptr_t(Section.getAddress());
457 uintptr_t StubAddress =
458 (BaseAddress + Section.getStubOffset() + StubAlignment - 1) &
459 -StubAlignment;
460 unsigned StubOffset = StubAddress - BaseAddress;
461 It->second = StubOffset;
463 "GOT entry not aligned");
466 false, 3);
467 if (Value.SymbolName)
469 else
472 Offset = static_cast<int64_t>(StubOffset);
473 }
477 }
478
479 Expected<relocation_iterator>
483 const MachOObjectFile &Obj =
484 static_cast<const MachOObjectFile&>(BaseObjT);
485 MachO::any_relocation_info RE =
487
488 unsigned Size = Obj.getAnyRelocationLength(RE);
490 uint8_t *LocalAddress = Sections[SectionID].getAddressWithOffset(Offset);
491 unsigned NumBytes = 1 << Size;
492
493 Expected SubtrahendNameOrErr = RelI->getSymbol()->getName();
494 if (!SubtrahendNameOrErr)
495 return SubtrahendNameOrErr.takeError();
497 unsigned SectionBID = SubtrahendI->second.getSectionID();
498 uint64_t SectionBOffset = SubtrahendI->second.getOffset();
499 int64_t Addend =
501
502 ++RelI;
503 Expected MinuendNameOrErr = RelI->getSymbol()->getName();
504 if (!MinuendNameOrErr)
505 return MinuendNameOrErr.takeError();
507 unsigned SectionAID = MinuendI->second.getSectionID();
508 uint64_t SectionAOffset = MinuendI->second.getOffset();
509
511 SectionAID, SectionAOffset, SectionBID, SectionBOffset,
512 false, Size);
513
515
516 return ++RelI;
517 }
518
519 static const char *getRelocName(uint32_t RelocType) {
520 switch (RelocType) {
532 }
533 return "Unrecognized arm64 addend";
534 }
535
536};