LLVM 23.0.0git
RelocationResolver.cpp
Go to the documentation of this file.
1//===- RelocationResolver.cpp ------------------------------------*- 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// This file defines utilities to resolve relocations in object files.
10//
11//===----------------------------------------------------------------------===//
12
14#include "llvm/ADT/Twine.h"
23#include "llvm/Support/Error.h"
26#include <cassert>
27
28namespace llvm {
29namespace object {
30
31static int64_t getELFAddend(RelocationRef R) {
33 handleAllErrors(AddendOrErr.takeError(), [](const ErrorInfoBase &EI) {
34 report_fatal_error(Twine(EI.message()));
35 });
36 return *AddendOrErr;
37}
38
40 switch (Type) {
41 case ELF::R_X86_64_NONE:
42 case ELF::R_X86_64_64:
43 case ELF::R_X86_64_DTPOFF32:
44 case ELF::R_X86_64_DTPOFF64:
45 case ELF::R_X86_64_PC32:
46 case ELF::R_X86_64_PC64:
47 case ELF::R_X86_64_32:
48 case ELF::R_X86_64_32S:
49 return true;
50 default:
51 return false;
52 }
53}
54
56 uint64_t LocData, int64_t Addend) {
57 switch (Type) {
58 case ELF::R_X86_64_NONE:
59 return LocData;
60 case ELF::R_X86_64_64:
61 case ELF::R_X86_64_DTPOFF32:
62 case ELF::R_X86_64_DTPOFF64:
63 return S + Addend;
64 case ELF::R_X86_64_PC32:
65 case ELF::R_X86_64_PC64:
66 return S + Addend - Offset;
67 case ELF::R_X86_64_32:
68 case ELF::R_X86_64_32S:
69 return (S + Addend) & 0xFFFFFFFF;
70 default:
71 llvm_unreachable("Invalid relocation type");
72 }
73}
74
76 switch (Type) {
77 case ELF::R_AARCH64_ABS32:
78 case ELF::R_AARCH64_ABS64:
79 case ELF::R_AARCH64_PREL16:
80 case ELF::R_AARCH64_PREL32:
81 case ELF::R_AARCH64_PREL64:
82 case ELF::R_AARCH64_TLS_DTPREL64:
83 return true;
84 default:
85 return false;
86 }
87}
88
90 uint64_t /*LocData*/, int64_t Addend) {
91 switch (Type) {
92 case ELF::R_AARCH64_ABS32:
93 return (S + Addend) & 0xFFFFFFFF;
94 case ELF::R_AARCH64_ABS64:
95 case ELF::R_AARCH64_TLS_DTPREL64:
96 return S + Addend;
97 case ELF::R_AARCH64_PREL16:
98 return (S + Addend - Offset) & 0xFFFF;
99 case ELF::R_AARCH64_PREL32:
100 return (S + Addend - Offset) & 0xFFFFFFFF;
101 case ELF::R_AARCH64_PREL64:
102 return S + Addend - Offset;
103 default:
104 llvm_unreachable("Invalid relocation type");
105 }
106}
107
109 switch (Type) {
110 case ELF::R_BPF_64_ABS32:
111 case ELF::R_BPF_64_ABS64:
112 return true;
113 default:
114 return false;
115 }
116}
117
119 uint64_t LocData, int64_t /*Addend*/) {
120 switch (Type) {
121 case ELF::R_BPF_64_ABS32:
122 return (S + LocData) & 0xFFFFFFFF;
123 case ELF::R_BPF_64_ABS64:
124 return S + LocData;
125 default:
126 llvm_unreachable("Invalid relocation type");
127 }
128}
129
131 switch (Type) {
132 case ELF::R_MIPS_32:
133 case ELF::R_MIPS_64:
134 case ELF::R_MIPS_TLS_DTPREL64:
135 case ELF::R_MIPS_PC32:
136 return true;
137 default:
138 return false;
139 }
140}
141
143 uint64_t /*LocData*/, int64_t Addend) {
144 switch (Type) {
145 case ELF::R_MIPS_32:
146 return (S + Addend) & 0xFFFFFFFF;
147 case ELF::R_MIPS_64:
148 return S + Addend;
149 case ELF::R_MIPS_TLS_DTPREL64:
150 return S + Addend - 0x8000;
151 case ELF::R_MIPS_PC32:
152 return S + Addend - Offset;
153 default:
154 llvm_unreachable("Invalid relocation type");
155 }
156}
157
159 switch (Type) {
160 case ELF::R_MSP430_32:
161 case ELF::R_MSP430_16_BYTE:
162 return true;
163 default:
164 return false;
165 }
166}
167
169 uint64_t /*LocData*/, int64_t Addend) {
170 switch (Type) {
171 case ELF::R_MSP430_32:
172 return (S + Addend) & 0xFFFFFFFF;
173 case ELF::R_MSP430_16_BYTE:
174 return (S + Addend) & 0xFFFF;
175 default:
176 llvm_unreachable("Invalid relocation type");
177 }
178}
179
181 switch (Type) {
182 case ELF::R_PPC64_ADDR32:
183 case ELF::R_PPC64_ADDR64:
184 case ELF::R_PPC64_REL32:
185 case ELF::R_PPC64_REL64:
186 return true;
187 default:
188 return false;
189 }
190}
191
193 uint64_t /*LocData*/, int64_t Addend) {
194 switch (Type) {
195 case ELF::R_PPC64_ADDR32:
196 return (S + Addend) & 0xFFFFFFFF;
197 case ELF::R_PPC64_ADDR64:
198 return S + Addend;
199 case ELF::R_PPC64_REL32:
200 return (S + Addend - Offset) & 0xFFFFFFFF;
201 case ELF::R_PPC64_REL64:
202 return S + Addend - Offset;
203 default:
204 llvm_unreachable("Invalid relocation type");
205 }
206}
207
209 switch (Type) {
210 case ELF::R_390_32:
211 case ELF::R_390_64:
212 return true;
213 default:
214 return false;
215 }
216}
217
219 uint64_t /*LocData*/, int64_t Addend) {
220 switch (Type) {
221 case ELF::R_390_32:
222 return (S + Addend) & 0xFFFFFFFF;
223 case ELF::R_390_64:
224 return S + Addend;
225 default:
226 llvm_unreachable("Invalid relocation type");
227 }
228}
229
231 switch (Type) {
232 case ELF::R_SPARC_32:
233 case ELF::R_SPARC_64:
234 case ELF::R_SPARC_UA32:
235 case ELF::R_SPARC_UA64:
236 return true;
237 default:
238 return false;
239 }
240}
241
243 uint64_t /*LocData*/, int64_t Addend) {
244 switch (Type) {
245 case ELF::R_SPARC_32:
246 case ELF::R_SPARC_64:
247 case ELF::R_SPARC_UA32:
248 case ELF::R_SPARC_UA64:
249 return S + Addend;
250 default:
251 llvm_unreachable("Invalid relocation type");
252 }
253}
254
255/// Returns true if \c Obj is an AMDGPU code object based solely on the value
256/// of e_machine.
257///
258/// AMDGPU code objects with an e_machine of EF_AMDGPU_MACH_NONE do not
259/// identify their arch as either r600 or amdgcn, but we can still handle
260/// their relocations. When we identify an ELF object with an UnknownArch,
261/// we use isAMDGPU to check for this case.
262static bool isAMDGPU(const ObjectFile &Obj) {
263 if (const auto *ELFObj = dyn_cast<ELFObjectFileBase>(&Obj))
264 return ELFObj->getEMachine() == ELF::EM_AMDGPU;
265 return false;
266}
267
269 switch (Type) {
270 case ELF::R_AMDGPU_ABS32:
271 case ELF::R_AMDGPU_ABS64:
272 return true;
273 default:
274 return false;
275 }
276}
277
279 uint64_t LocData, int64_t Addend) {
280 assert((LocData == 0 || Addend == 0) &&
281 "one of LocData and Addend must be 0");
282 switch (Type) {
283 case ELF::R_AMDGPU_ABS32:
284 case ELF::R_AMDGPU_ABS64:
285 return S + LocData + Addend;
286 default:
287 llvm_unreachable("Invalid relocation type");
288 }
289}
290
292 switch (Type) {
293 case ELF::R_386_NONE:
294 case ELF::R_386_32:
295 case ELF::R_386_PC32:
296 return true;
297 default:
298 return false;
299 }
300}
301
303 uint64_t LocData, int64_t /*Addend*/) {
304 switch (Type) {
305 case ELF::R_386_NONE:
306 return LocData;
307 case ELF::R_386_32:
308 return S + LocData;
309 case ELF::R_386_PC32:
310 return S - Offset + LocData;
311 default:
312 llvm_unreachable("Invalid relocation type");
313 }
314}
315
317 switch (Type) {
318 case ELF::R_PPC_ADDR32:
319 case ELF::R_PPC_REL32:
320 return true;
321 default:
322 return false;
323 }
324}
325
327 uint64_t /*LocData*/, int64_t Addend) {
328 switch (Type) {
329 case ELF::R_PPC_ADDR32:
330 return (S + Addend) & 0xFFFFFFFF;
331 case ELF::R_PPC_REL32:
332 return (S + Addend - Offset) & 0xFFFFFFFF;
333 }
334 llvm_unreachable("Invalid relocation type");
335}
336
338 switch (Type) {
339 case ELF::R_ARM_ABS32:
340 case ELF::R_ARM_REL32:
341 return true;
342 default:
343 return false;
344 }
345}
346
348 uint64_t LocData, int64_t Addend) {
349 // Support both RELA and REL relocations. The caller is responsible
350 // for supplying the correct values for LocData and Addend, i.e.
351 // Addend == 0 for REL and LocData == 0 for RELA.
352 assert((LocData == 0 || Addend == 0) &&
353 "one of LocData and Addend must be 0");
354 switch (Type) {
355 case ELF::R_ARM_ABS32:
356 return (S + LocData + Addend) & 0xFFFFFFFF;
357 case ELF::R_ARM_REL32:
358 return (S + LocData + Addend - Offset) & 0xFFFFFFFF;
359 }
360 llvm_unreachable("Invalid relocation type");
361}
362
364 switch (Type) {
365 case ELF::R_AVR_16:
366 case ELF::R_AVR_32:
367 return true;
368 default:
369 return false;
370 }
371}
372
374 uint64_t /*LocData*/, int64_t Addend) {
375 switch (Type) {
376 case ELF::R_AVR_16:
377 return (S + Addend) & 0xFFFF;
378 case ELF::R_AVR_32:
379 return (S + Addend) & 0xFFFFFFFF;
380 default:
381 llvm_unreachable("Invalid relocation type");
382 }
383}
384
386 return Type == ELF::R_LANAI_32;
387}
388
390 uint64_t /*LocData*/, int64_t Addend) {
391 if (Type == ELF::R_LANAI_32)
392 return (S + Addend) & 0xFFFFFFFF;
393 llvm_unreachable("Invalid relocation type");
394}
395
397 switch (Type) {
398 case ELF::R_MIPS_32:
399 case ELF::R_MIPS_TLS_DTPREL32:
400 return true;
401 default:
402 return false;
403 }
404}
405
407 uint64_t LocData, int64_t /*Addend*/) {
408 // FIXME: Take in account implicit addends to get correct results.
409 if (Type == ELF::R_MIPS_32)
410 return (S + LocData) & 0xFFFFFFFF;
411 if (Type == ELF::R_MIPS_TLS_DTPREL32)
412 return (S + LocData) & 0xFFFFFFFF;
413 llvm_unreachable("Invalid relocation type");
414}
415
417 switch (Type) {
418 case ELF::R_SPARC_32:
419 case ELF::R_SPARC_UA32:
420 return true;
421 default:
422 return false;
423 }
424}
425
427 uint64_t LocData, int64_t Addend) {
428 if (Type == ELF::R_SPARC_32 || Type == ELF::R_SPARC_UA32)
429 return S + Addend;
430 return LocData;
431}
432
434 return Type == ELF::R_HEX_32;
435}
436
438 uint64_t /*LocData*/, int64_t Addend) {
439 if (Type == ELF::R_HEX_32)
440 return S + Addend;
441 llvm_unreachable("Invalid relocation type");
442}
443
445 switch (Type) {
446 case ELF::R_RISCV_NONE:
447 case ELF::R_RISCV_32:
448 case ELF::R_RISCV_32_PCREL:
449 case ELF::R_RISCV_64:
450 case ELF::R_RISCV_SET6:
451 case ELF::R_RISCV_SET8:
452 case ELF::R_RISCV_SUB6:
453 case ELF::R_RISCV_ADD8:
454 case ELF::R_RISCV_SUB8:
455 case ELF::R_RISCV_SET16:
456 case ELF::R_RISCV_ADD16:
457 case ELF::R_RISCV_SUB16:
458 case ELF::R_RISCV_SET32:
459 case ELF::R_RISCV_ADD32:
460 case ELF::R_RISCV_SUB32:
461 case ELF::R_RISCV_ADD64:
462 case ELF::R_RISCV_SUB64:
463 // Because the unrelocated value generated by .uleb128 A-B (used by
464 // loclists/rnglists) is meaningful, DebugInfoDWARF does not inspect the
465 // relocations. We declare support for the two relocation types without an
466 // (unreachable) implementation.
467 case ELF::R_RISCV_SET_ULEB128:
468 case ELF::R_RISCV_SUB_ULEB128:
469 return true;
470 default:
471 return false;
472 }
473}
474
476 uint64_t LocData, int64_t Addend) {
477 int64_t RA = Addend;
478 uint64_t A = LocData;
479 switch (Type) {
480 case ELF::R_RISCV_NONE:
481 return LocData;
482 case ELF::R_RISCV_32:
483 return (S + RA) & 0xFFFFFFFF;
484 case ELF::R_RISCV_32_PCREL:
485 return (S + RA - Offset) & 0xFFFFFFFF;
486 case ELF::R_RISCV_64:
487 return S + RA;
488 case ELF::R_RISCV_SET6:
489 return (A & 0xC0) | ((S + RA) & 0x3F);
490 case ELF::R_RISCV_SUB6:
491 return (A & 0xC0) | (((A & 0x3F) - (S + RA)) & 0x3F);
492 case ELF::R_RISCV_SET8:
493 return (S + RA) & 0xFF;
494 case ELF::R_RISCV_ADD8:
495 return (A + (S + RA)) & 0xFF;
496 case ELF::R_RISCV_SUB8:
497 return (A - (S + RA)) & 0xFF;
498 case ELF::R_RISCV_SET16:
499 return (S + RA) & 0xFFFF;
500 case ELF::R_RISCV_ADD16:
501 return (A + (S + RA)) & 0xFFFF;
502 case ELF::R_RISCV_SUB16:
503 return (A - (S + RA)) & 0xFFFF;
504 case ELF::R_RISCV_SET32:
505 return (S + RA) & 0xFFFFFFFF;
506 case ELF::R_RISCV_ADD32:
507 return (A + (S + RA)) & 0xFFFFFFFF;
508 case ELF::R_RISCV_SUB32:
509 return (A - (S + RA)) & 0xFFFFFFFF;
510 case ELF::R_RISCV_ADD64:
511 return (A + (S + RA));
512 case ELF::R_RISCV_SUB64:
513 return (A - (S + RA));
514 default:
515 llvm_unreachable("Invalid relocation type");
516 }
517}
518
520 switch (Type) {
521 case ELF::R_CKCORE_NONE:
522 case ELF::R_CKCORE_ADDR32:
523 case ELF::R_CKCORE_PCREL32:
524 return true;
525 default:
526 return false;
527 }
528}
529
531 uint64_t LocData, int64_t Addend) {
532 switch (Type) {
533 case ELF::R_CKCORE_NONE:
534 return LocData;
535 case ELF::R_CKCORE_ADDR32:
536 return (S + Addend) & 0xFFFFFFFF;
537 case ELF::R_CKCORE_PCREL32:
538 return (S + Addend - Offset) & 0xFFFFFFFF;
539 default:
540 llvm_unreachable("Invalid relocation type");
541 }
542}
543
545 switch (Type) {
546 case ELF::R_LARCH_NONE:
547 case ELF::R_LARCH_32:
548 case ELF::R_LARCH_32_PCREL:
549 case ELF::R_LARCH_64:
550 case ELF::R_LARCH_ADD6:
551 case ELF::R_LARCH_SUB6:
552 case ELF::R_LARCH_ADD8:
553 case ELF::R_LARCH_SUB8:
554 case ELF::R_LARCH_ADD16:
555 case ELF::R_LARCH_SUB16:
556 case ELF::R_LARCH_ADD32:
557 case ELF::R_LARCH_SUB32:
558 case ELF::R_LARCH_ADD64:
559 case ELF::R_LARCH_SUB64:
560 return true;
561 default:
562 return false;
563 }
564}
565
567 uint64_t LocData, int64_t Addend) {
568 switch (Type) {
569 case ELF::R_LARCH_NONE:
570 return LocData;
571 case ELF::R_LARCH_32:
572 return (S + Addend) & 0xFFFFFFFF;
573 case ELF::R_LARCH_32_PCREL:
574 return (S + Addend - Offset) & 0xFFFFFFFF;
575 case ELF::R_LARCH_64:
576 return S + Addend;
577 case ELF::R_LARCH_ADD6:
578 return (LocData & 0xC0) | ((LocData + S + Addend) & 0x3F);
579 case ELF::R_LARCH_SUB6:
580 return (LocData & 0xC0) | ((LocData - (S + Addend)) & 0x3F);
581 case ELF::R_LARCH_ADD8:
582 return (LocData + (S + Addend)) & 0xFF;
583 case ELF::R_LARCH_SUB8:
584 return (LocData - (S + Addend)) & 0xFF;
585 case ELF::R_LARCH_ADD16:
586 return (LocData + (S + Addend)) & 0xFFFF;
587 case ELF::R_LARCH_SUB16:
588 return (LocData - (S + Addend)) & 0xFFFF;
589 case ELF::R_LARCH_ADD32:
590 return (LocData + (S + Addend)) & 0xFFFFFFFF;
591 case ELF::R_LARCH_SUB32:
592 return (LocData - (S + Addend)) & 0xFFFFFFFF;
593 case ELF::R_LARCH_ADD64:
594 return (LocData + (S + Addend));
595 case ELF::R_LARCH_SUB64:
596 return (LocData - (S + Addend));
597 default:
598 llvm_unreachable("Invalid relocation type");
599 }
600}
601
603 switch (Type) {
606 return true;
607 default:
608 return false;
609 }
610}
611
613 uint64_t LocData, int64_t /*Addend*/) {
614 switch (Type) {
617 return (S + LocData) & 0xFFFFFFFF;
618 default:
619 llvm_unreachable("Invalid relocation type");
620 }
621}
622
624 switch (Type) {
627 return true;
628 default:
629 return false;
630 }
631}
632
634 uint64_t LocData, int64_t /*Addend*/) {
635 switch (Type) {
637 return (S + LocData) & 0xFFFFFFFF;
639 return S + LocData;
640 default:
641 llvm_unreachable("Invalid relocation type");
642 }
643}
644
646 switch (Type) {
649 return true;
650 default:
651 return false;
652 }
653}
654
656 uint64_t LocData, int64_t /*Addend*/) {
657 switch (Type) {
660 return (S + LocData) & 0xFFFFFFFF;
661 default:
662 llvm_unreachable("Invalid relocation type");
663 }
664}
665
667 switch (Type) {
670 return true;
671 default:
672 return false;
673 }
674}
675
677 uint64_t LocData, int64_t /*Addend*/) {
678 switch (Type) {
680 return (S + LocData) & 0xFFFFFFFF;
682 return S + LocData;
683 default:
684 llvm_unreachable("Invalid relocation type");
685 }
686}
687
691
693 uint64_t LocData, int64_t /*Addend*/) {
695 return S;
696 llvm_unreachable("Invalid relocation type");
697}
698
700 switch (Type) {
701 case wasm::R_WASM_FUNCTION_INDEX_LEB:
702 case wasm::R_WASM_TABLE_INDEX_SLEB:
703 case wasm::R_WASM_TABLE_INDEX_I32:
704 case wasm::R_WASM_MEMORY_ADDR_LEB:
705 case wasm::R_WASM_MEMORY_ADDR_SLEB:
706 case wasm::R_WASM_MEMORY_ADDR_I32:
707 case wasm::R_WASM_TYPE_INDEX_LEB:
708 case wasm::R_WASM_GLOBAL_INDEX_LEB:
709 case wasm::R_WASM_FUNCTION_OFFSET_I32:
710 case wasm::R_WASM_SECTION_OFFSET_I32:
711 case wasm::R_WASM_TAG_INDEX_LEB:
712 case wasm::R_WASM_GLOBAL_INDEX_I32:
713 case wasm::R_WASM_TABLE_NUMBER_LEB:
714 case wasm::R_WASM_MEMORY_ADDR_LOCREL_I32:
715 return true;
716 default:
717 return false;
718 }
719}
720
722 switch (Type) {
723 case wasm::R_WASM_MEMORY_ADDR_LEB64:
724 case wasm::R_WASM_MEMORY_ADDR_SLEB64:
725 case wasm::R_WASM_MEMORY_ADDR_I64:
726 case wasm::R_WASM_TABLE_INDEX_SLEB64:
727 case wasm::R_WASM_TABLE_INDEX_I64:
728 case wasm::R_WASM_FUNCTION_OFFSET_I64:
729 return true;
730 default:
731 return supportsWasm32(Type);
732 }
733}
734
736 uint64_t LocData, int64_t /*Addend*/) {
737 switch (Type) {
738 case wasm::R_WASM_FUNCTION_INDEX_LEB:
739 case wasm::R_WASM_TABLE_INDEX_SLEB:
740 case wasm::R_WASM_TABLE_INDEX_I32:
741 case wasm::R_WASM_MEMORY_ADDR_LEB:
742 case wasm::R_WASM_MEMORY_ADDR_SLEB:
743 case wasm::R_WASM_MEMORY_ADDR_I32:
744 case wasm::R_WASM_TYPE_INDEX_LEB:
745 case wasm::R_WASM_GLOBAL_INDEX_LEB:
746 case wasm::R_WASM_FUNCTION_OFFSET_I32:
747 case wasm::R_WASM_SECTION_OFFSET_I32:
748 case wasm::R_WASM_TAG_INDEX_LEB:
749 case wasm::R_WASM_GLOBAL_INDEX_I32:
750 case wasm::R_WASM_TABLE_NUMBER_LEB:
751 case wasm::R_WASM_MEMORY_ADDR_LOCREL_I32:
752 // For wasm section, its offset at 0 -- ignoring Value
753 return LocData;
754 default:
755 llvm_unreachable("Invalid relocation type");
756 }
757}
758
760 uint64_t LocData, int64_t Addend) {
761 switch (Type) {
762 case wasm::R_WASM_MEMORY_ADDR_LEB64:
763 case wasm::R_WASM_MEMORY_ADDR_SLEB64:
764 case wasm::R_WASM_MEMORY_ADDR_I64:
765 case wasm::R_WASM_TABLE_INDEX_SLEB64:
766 case wasm::R_WASM_TABLE_INDEX_I64:
767 case wasm::R_WASM_FUNCTION_OFFSET_I64:
768 // For wasm section, its offset at 0 -- ignoring Value
769 return LocData;
770 default:
771 return resolveWasm32(Type, Offset, S, LocData, Addend);
772 }
773}
774
775std::pair<SupportsRelocation, RelocationResolver>
777 if (Obj.isCOFF()) {
778 switch (Obj.getArch()) {
779 case Triple::x86_64:
781 case Triple::x86:
783 case Triple::arm:
784 case Triple::thumb:
786 case Triple::aarch64:
788 default:
789 return {nullptr, nullptr};
790 }
791 } else if (Obj.isELF()) {
792 if (Obj.getBytesInAddress() == 8) {
793 switch (Obj.getArch()) {
794 case Triple::x86_64:
796 case Triple::aarch64:
799 case Triple::bpfel:
800 case Triple::bpfeb:
801 return {supportsBPF, resolveBPF};
804 case Triple::mips64el:
805 case Triple::mips64:
807 case Triple::ppc64le:
808 case Triple::ppc64:
809 return {supportsPPC64, resolvePPC64};
810 case Triple::systemz:
812 case Triple::sparcv9:
814 case Triple::amdgcn:
816 case Triple::riscv64:
818 return {supportsRISCV, resolveRISCV};
819 default:
820 if (isAMDGPU(Obj))
822 return {nullptr, nullptr};
823 }
824 }
825
826 // 32-bit object file
827 assert(Obj.getBytesInAddress() == 4 &&
828 "Invalid word size in object file");
829
830 switch (Obj.getArch()) {
831 case Triple::x86:
832 return {supportsX86, resolveX86};
833 case Triple::ppcle:
834 case Triple::ppc:
835 return {supportsPPC32, resolvePPC32};
836 case Triple::arm:
837 case Triple::armeb:
838 return {supportsARM, resolveARM};
839 case Triple::avr:
840 return {supportsAVR, resolveAVR};
841 case Triple::lanai:
842 return {supportsLanai, resolveLanai};
845 case Triple::mipsel:
846 case Triple::mips:
848 case Triple::msp430:
850 case Triple::sparc:
852 case Triple::hexagon:
854 case Triple::r600:
856 case Triple::riscv32:
858 return {supportsRISCV, resolveRISCV};
859 case Triple::csky:
860 return {supportsCSKY, resolveCSKY};
861 default:
862 if (isAMDGPU(Obj))
864 return {nullptr, nullptr};
865 }
866 } else if (Obj.isMachO()) {
867 if (Obj.getArch() == Triple::x86_64)
869 return {nullptr, nullptr};
870 } else if (Obj.isWasm()) {
871 if (Obj.getArch() == Triple::wasm32)
873 if (Obj.getArch() == Triple::wasm64)
875 return {nullptr, nullptr};
876 }
877
878 llvm_unreachable("Invalid object file");
879}
880
882 uint64_t S, uint64_t LocData) {
883 if (const ObjectFile *Obj = R.getObject()) {
884 int64_t Addend = 0;
885 if (Obj->isELF()) {
886 auto GetRelSectionType = [&]() -> unsigned {
887 if (auto *Elf32LEObj = dyn_cast<ELF32LEObjectFile>(Obj))
888 return Elf32LEObj->getRelSection(R.getRawDataRefImpl())->sh_type;
889 if (auto *Elf64LEObj = dyn_cast<ELF64LEObjectFile>(Obj))
890 return Elf64LEObj->getRelSection(R.getRawDataRefImpl())->sh_type;
891 if (auto *Elf32BEObj = dyn_cast<ELF32BEObjectFile>(Obj))
892 return Elf32BEObj->getRelSection(R.getRawDataRefImpl())->sh_type;
893 auto *Elf64BEObj = cast<ELF64BEObjectFile>(Obj);
894 return Elf64BEObj->getRelSection(R.getRawDataRefImpl())->sh_type;
895 };
896
897 if (GetRelSectionType() == ELF::SHT_RELA ||
898 GetRelSectionType() == ELF::SHT_CREL) {
899 Addend = getELFAddend(R);
900 // LoongArch and RISCV relocations use both LocData and Addend.
901 if (Obj->getArch() != Triple::loongarch32 &&
902 Obj->getArch() != Triple::loongarch64 &&
903 Obj->getArch() != Triple::riscv32 &&
904 Obj->getArch() != Triple::riscv64 &&
905 Obj->getArch() != Triple::riscv32be &&
906 Obj->getArch() != Triple::riscv64be)
907 LocData = 0;
908 }
909 }
910
911 return Resolver(R.getType(), R.getOffset(), S, LocData, Addend);
912 }
913
914 // Sometimes the caller might want to use its own specific implementation of
915 // the resolver function. E.g. this is used by LLD when it resolves debug
916 // relocations and assumes that all of them have the same computation (S + A).
917 // The relocation R has no owner object in this case and we don't need to
918 // provide Type and Offset fields. It is also assumed the DataRefImpl.p
919 // contains the addend, provided by the caller.
920 return Resolver(/*Type=*/0, /*Offset=*/0, S, LocData,
921 R.getRawDataRefImpl().p);
922}
923
924} // namespace object
925} // namespace llvm
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
SI optimize exec mask operations pre RA
Base class for error info classes.
Definition Error.h:44
Tagged union holding either a T or a Error.
Definition Error.h:485
Error takeError()
Take ownership of the stored error.
Definition Error.h:612
Interface for looking up the initializer for a variable name, used by Init::resolveReferences.
Definition Record.h:2199
@ loongarch32
Definition Triple.h:64
@ loongarch64
Definition Triple.h:65
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
Expected< int64_t > getAddend() const
This class is the base class for all object file types.
Definition ObjectFile.h:231
This is a value type class that represents a single relocation in the list of relocations in the obje...
Definition ObjectFile.h:54
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ IMAGE_REL_ARM64_SECREL
Definition COFF.h:409
@ IMAGE_REL_ARM64_ADDR64
Definition COFF.h:415
@ IMAGE_REL_AMD64_ADDR64
Definition COFF.h:362
@ IMAGE_REL_AMD64_SECREL
Definition COFF.h:372
@ IMAGE_REL_ARM_ADDR32
Definition COFF.h:382
@ IMAGE_REL_ARM_SECREL
Definition COFF.h:391
@ IMAGE_REL_I386_SECREL
Definition COFF.h:354
@ IMAGE_REL_I386_DIR32
Definition COFF.h:350
@ EM_AMDGPU
Definition ELF.h:321
@ SHT_CREL
Definition ELF.h:1167
@ SHT_RELA
Definition ELF.h:1149
@ X86_64_RELOC_UNSIGNED
Definition MachO.h:540
static uint64_t resolveCOFFARM(uint64_t Type, uint64_t Offset, uint64_t S, uint64_t LocData, int64_t)
static bool supportsRISCV(uint64_t Type)
static bool supportsCOFFARM(uint64_t Type)
static uint64_t resolveCOFFARM64(uint64_t Type, uint64_t Offset, uint64_t S, uint64_t LocData, int64_t)
static uint64_t resolveMips64(uint64_t Type, uint64_t Offset, uint64_t S, uint64_t, int64_t Addend)
static bool supportsCSKY(uint64_t Type)
static bool supportsLanai(uint64_t Type)
static uint64_t resolvePPC64(uint64_t Type, uint64_t Offset, uint64_t S, uint64_t, int64_t Addend)
static bool supportsMSP430(uint64_t Type)
static bool supportsLoongArch(uint64_t Type)
static uint64_t resolveCSKY(uint64_t Type, uint64_t Offset, uint64_t S, uint64_t LocData, int64_t Addend)
static int64_t getELFAddend(RelocationRef R)
static uint64_t resolveAArch64(uint64_t Type, uint64_t Offset, uint64_t S, uint64_t, int64_t Addend)
static bool supportsWasm32(uint64_t Type)
LLVM_ABI uint64_t resolveRelocation(RelocationResolver Resolver, const RelocationRef &R, uint64_t S, uint64_t LocData)
static uint64_t resolveX86(uint64_t Type, uint64_t Offset, uint64_t S, uint64_t LocData, int64_t)
static uint64_t resolveWasm64(uint64_t Type, uint64_t Offset, uint64_t S, uint64_t LocData, int64_t Addend)
static bool supportsSystemZ(uint64_t Type)
static uint64_t resolveARM(uint64_t Type, uint64_t Offset, uint64_t S, uint64_t LocData, int64_t Addend)
static bool supportsWasm64(uint64_t Type)
static bool supportsSparc64(uint64_t Type)
static bool supportsMips64(uint64_t Type)
uint64_t(*)(uint64_t Type, uint64_t Offset, uint64_t S, uint64_t LocData, int64_t Addend) RelocationResolver
static bool supportsMachOX86_64(uint64_t Type)
static uint64_t resolveLanai(uint64_t Type, uint64_t Offset, uint64_t S, uint64_t, int64_t Addend)
static uint64_t resolveCOFFX86(uint64_t Type, uint64_t Offset, uint64_t S, uint64_t LocData, int64_t)
static uint64_t resolveX86_64(uint64_t Type, uint64_t Offset, uint64_t S, uint64_t LocData, int64_t Addend)
static uint64_t resolveMSP430(uint64_t Type, uint64_t Offset, uint64_t S, uint64_t, int64_t Addend)
static bool supportsAmdgpu(uint64_t Type)
static bool supportsMips32(uint64_t Type)
static bool isAMDGPU(const ObjectFile &Obj)
Returns true if Obj is an AMDGPU code object based solely on the value of e_machine.
static bool supportsBPF(uint64_t Type)
static uint64_t resolvePPC32(uint64_t Type, uint64_t Offset, uint64_t S, uint64_t, int64_t Addend)
static uint64_t resolveLoongArch(uint64_t Type, uint64_t Offset, uint64_t S, uint64_t LocData, int64_t Addend)
static uint64_t resolveAmdgpu(uint64_t Type, uint64_t Offset, uint64_t S, uint64_t LocData, int64_t Addend)
static uint64_t resolveHexagon(uint64_t Type, uint64_t Offset, uint64_t S, uint64_t, int64_t Addend)
LLVM_ABI std::pair< SupportsRelocation, RelocationResolver > getRelocationResolver(const ObjectFile &Obj)
static bool supportsPPC32(uint64_t Type)
static uint64_t resolveSparc64(uint64_t Type, uint64_t Offset, uint64_t S, uint64_t, int64_t Addend)
static uint64_t resolveAVR(uint64_t Type, uint64_t Offset, uint64_t S, uint64_t, int64_t Addend)
static bool supportsCOFFX86_64(uint64_t Type)
static bool supportsARM(uint64_t Type)
static uint64_t resolveBPF(uint64_t Type, uint64_t Offset, uint64_t S, uint64_t LocData, int64_t)
static bool supportsAVR(uint64_t Type)
static uint64_t resolveWasm32(uint64_t Type, uint64_t Offset, uint64_t S, uint64_t LocData, int64_t)
static bool supportsX86(uint64_t Type)
static uint64_t resolveCOFFX86_64(uint64_t Type, uint64_t Offset, uint64_t S, uint64_t LocData, int64_t)
static uint64_t resolveRISCV(uint64_t Type, uint64_t Offset, uint64_t S, uint64_t LocData, int64_t Addend)
static bool supportsHexagon(uint64_t Type)
static uint64_t resolveMachOX86_64(uint64_t Type, uint64_t Offset, uint64_t S, uint64_t LocData, int64_t)
static bool supportsAArch64(uint64_t Type)
static bool supportsX86_64(uint64_t Type)
static uint64_t resolveSparc32(uint64_t Type, uint64_t Offset, uint64_t S, uint64_t LocData, int64_t Addend)
static bool supportsPPC64(uint64_t Type)
static bool supportsCOFFARM64(uint64_t Type)
static bool supportsCOFFX86(uint64_t Type)
static uint64_t resolveMips32(uint64_t Type, uint64_t Offset, uint64_t S, uint64_t LocData, int64_t)
static bool supportsSparc32(uint64_t Type)
static uint64_t resolveSystemZ(uint64_t Type, uint64_t Offset, uint64_t S, uint64_t, int64_t Addend)
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:532
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
void handleAllErrors(Error E, HandlerTs &&... Handlers)
Behaves the same as handleErrors, except that by contract all errors must be handled by the given han...
Definition Error.h:990
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559