LLVM 18.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"
24#include "llvm/Support/Error.h"
27#include <cassert>
28#include <vector>
29
30namespace llvm {
31namespace object {
32
33static int64_t getELFAddend(RelocationRef R) {
35 handleAllErrors(AddendOrErr.takeError(), [](const ErrorInfoBase &EI) {
36 report_fatal_error(Twine(EI.message()));
37 });
38 return *AddendOrErr;
39}
40
42 switch (Type) {
43 case ELF::R_X86_64_NONE:
44 case ELF::R_X86_64_64:
45 case ELF::R_X86_64_DTPOFF32:
46 case ELF::R_X86_64_DTPOFF64:
47 case ELF::R_X86_64_PC32:
48 case ELF::R_X86_64_PC64:
49 case ELF::R_X86_64_32:
50 case ELF::R_X86_64_32S:
51 return true;
52 default:
53 return false;
54 }
55}
56
58 uint64_t LocData, int64_t Addend) {
59 switch (Type) {
60 case ELF::R_X86_64_NONE:
61 return LocData;
62 case ELF::R_X86_64_64:
63 case ELF::R_X86_64_DTPOFF32:
64 case ELF::R_X86_64_DTPOFF64:
65 return S + Addend;
66 case ELF::R_X86_64_PC32:
67 case ELF::R_X86_64_PC64:
68 return S + Addend - Offset;
69 case ELF::R_X86_64_32:
70 case ELF::R_X86_64_32S:
71 return (S + Addend) & 0xFFFFFFFF;
72 default:
73 llvm_unreachable("Invalid relocation type");
74 }
75}
76
78 switch (Type) {
79 case ELF::R_AARCH64_ABS32:
80 case ELF::R_AARCH64_ABS64:
81 case ELF::R_AARCH64_PREL16:
82 case ELF::R_AARCH64_PREL32:
83 case ELF::R_AARCH64_PREL64:
84 return true;
85 default:
86 return false;
87 }
88}
89
91 uint64_t /*LocData*/, int64_t Addend) {
92 switch (Type) {
93 case ELF::R_AARCH64_ABS32:
94 return (S + Addend) & 0xFFFFFFFF;
95 case ELF::R_AARCH64_ABS64:
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 switch (Type) {
281 case ELF::R_AMDGPU_ABS32:
282 case ELF::R_AMDGPU_ABS64:
283 return S + Addend;
284 default:
285 llvm_unreachable("Invalid relocation type");
286 }
287}
288
290 switch (Type) {
291 case ELF::R_386_NONE:
292 case ELF::R_386_32:
293 case ELF::R_386_PC32:
294 return true;
295 default:
296 return false;
297 }
298}
299
301 uint64_t LocData, int64_t /*Addend*/) {
302 switch (Type) {
303 case ELF::R_386_NONE:
304 return LocData;
305 case ELF::R_386_32:
306 return S + LocData;
307 case ELF::R_386_PC32:
308 return S - Offset + LocData;
309 default:
310 llvm_unreachable("Invalid relocation type");
311 }
312}
313
315 switch (Type) {
316 case ELF::R_PPC_ADDR32:
317 case ELF::R_PPC_REL32:
318 return true;
319 default:
320 return false;
321 }
322}
323
325 uint64_t /*LocData*/, int64_t Addend) {
326 switch (Type) {
327 case ELF::R_PPC_ADDR32:
328 return (S + Addend) & 0xFFFFFFFF;
329 case ELF::R_PPC_REL32:
330 return (S + Addend - Offset) & 0xFFFFFFFF;
331 }
332 llvm_unreachable("Invalid relocation type");
333}
334
336 switch (Type) {
337 case ELF::R_ARM_ABS32:
338 case ELF::R_ARM_REL32:
339 return true;
340 default:
341 return false;
342 }
343}
344
346 uint64_t LocData, int64_t Addend) {
347 // Support both RELA and REL relocations. The caller is responsible
348 // for supplying the correct values for LocData and Addend, i.e.
349 // Addend == 0 for REL and LocData == 0 for RELA.
350 assert((LocData == 0 || Addend == 0) &&
351 "one of LocData and Addend must be 0");
352 switch (Type) {
353 case ELF::R_ARM_ABS32:
354 return (S + LocData + Addend) & 0xFFFFFFFF;
355 case ELF::R_ARM_REL32:
356 return (S + LocData + Addend - Offset) & 0xFFFFFFFF;
357 }
358 llvm_unreachable("Invalid relocation type");
359}
360
362 switch (Type) {
363 case ELF::R_AVR_16:
364 case ELF::R_AVR_32:
365 return true;
366 default:
367 return false;
368 }
369}
370
372 uint64_t /*LocData*/, int64_t Addend) {
373 switch (Type) {
374 case ELF::R_AVR_16:
375 return (S + Addend) & 0xFFFF;
376 case ELF::R_AVR_32:
377 return (S + Addend) & 0xFFFFFFFF;
378 default:
379 llvm_unreachable("Invalid relocation type");
380 }
381}
382
384 return Type == ELF::R_LANAI_32;
385}
386
388 uint64_t /*LocData*/, int64_t Addend) {
389 if (Type == ELF::R_LANAI_32)
390 return (S + Addend) & 0xFFFFFFFF;
391 llvm_unreachable("Invalid relocation type");
392}
393
395 switch (Type) {
396 case ELF::R_MIPS_32:
397 case ELF::R_MIPS_TLS_DTPREL32:
398 return true;
399 default:
400 return false;
401 }
402}
403
405 uint64_t LocData, int64_t /*Addend*/) {
406 // FIXME: Take in account implicit addends to get correct results.
407 if (Type == ELF::R_MIPS_32)
408 return (S + LocData) & 0xFFFFFFFF;
409 if (Type == ELF::R_MIPS_TLS_DTPREL32)
410 return (S + LocData) & 0xFFFFFFFF;
411 llvm_unreachable("Invalid relocation type");
412}
413
415 switch (Type) {
416 case ELF::R_SPARC_32:
417 case ELF::R_SPARC_UA32:
418 return true;
419 default:
420 return false;
421 }
422}
423
425 uint64_t LocData, int64_t Addend) {
426 if (Type == ELF::R_SPARC_32 || Type == ELF::R_SPARC_UA32)
427 return S + Addend;
428 return LocData;
429}
430
432 return Type == ELF::R_HEX_32;
433}
434
436 uint64_t /*LocData*/, int64_t Addend) {
437 if (Type == ELF::R_HEX_32)
438 return S + Addend;
439 llvm_unreachable("Invalid relocation type");
440}
441
443 switch (Type) {
444 case ELF::R_RISCV_NONE:
445 case ELF::R_RISCV_32:
446 case ELF::R_RISCV_32_PCREL:
447 case ELF::R_RISCV_64:
448 case ELF::R_RISCV_SET6:
449 case ELF::R_RISCV_SET8:
450 case ELF::R_RISCV_SUB6:
451 case ELF::R_RISCV_ADD8:
452 case ELF::R_RISCV_SUB8:
453 case ELF::R_RISCV_SET16:
454 case ELF::R_RISCV_ADD16:
455 case ELF::R_RISCV_SUB16:
456 case ELF::R_RISCV_SET32:
457 case ELF::R_RISCV_ADD32:
458 case ELF::R_RISCV_SUB32:
459 case ELF::R_RISCV_ADD64:
460 case ELF::R_RISCV_SUB64:
461 return true;
462 default:
463 return false;
464 }
465}
466
468 uint64_t LocData, int64_t Addend) {
469 int64_t RA = Addend;
470 uint64_t A = LocData;
471 switch (Type) {
472 case ELF::R_RISCV_NONE:
473 return LocData;
474 case ELF::R_RISCV_32:
475 return (S + RA) & 0xFFFFFFFF;
476 case ELF::R_RISCV_32_PCREL:
477 return (S + RA - Offset) & 0xFFFFFFFF;
478 case ELF::R_RISCV_64:
479 return S + RA;
480 case ELF::R_RISCV_SET6:
481 return (A & 0xC0) | ((S + RA) & 0x3F);
482 case ELF::R_RISCV_SUB6:
483 return (A & 0xC0) | (((A & 0x3F) - (S + RA)) & 0x3F);
484 case ELF::R_RISCV_SET8:
485 return (S + RA) & 0xFF;
486 case ELF::R_RISCV_ADD8:
487 return (A + (S + RA)) & 0xFF;
488 case ELF::R_RISCV_SUB8:
489 return (A - (S + RA)) & 0xFF;
490 case ELF::R_RISCV_SET16:
491 return (S + RA) & 0xFFFF;
492 case ELF::R_RISCV_ADD16:
493 return (A + (S + RA)) & 0xFFFF;
494 case ELF::R_RISCV_SUB16:
495 return (A - (S + RA)) & 0xFFFF;
496 case ELF::R_RISCV_SET32:
497 return (S + RA) & 0xFFFFFFFF;
498 case ELF::R_RISCV_ADD32:
499 return (A + (S + RA)) & 0xFFFFFFFF;
500 case ELF::R_RISCV_SUB32:
501 return (A - (S + RA)) & 0xFFFFFFFF;
502 case ELF::R_RISCV_ADD64:
503 return (A + (S + RA));
504 case ELF::R_RISCV_SUB64:
505 return (A - (S + RA));
506 default:
507 llvm_unreachable("Invalid relocation type");
508 }
509}
510
512 switch (Type) {
513 case ELF::R_CKCORE_NONE:
514 case ELF::R_CKCORE_ADDR32:
515 case ELF::R_CKCORE_PCREL32:
516 return true;
517 default:
518 return false;
519 }
520}
521
523 uint64_t LocData, int64_t Addend) {
524 switch (Type) {
525 case ELF::R_CKCORE_NONE:
526 return LocData;
527 case ELF::R_CKCORE_ADDR32:
528 return (S + Addend) & 0xFFFFFFFF;
529 case ELF::R_CKCORE_PCREL32:
530 return (S + Addend - Offset) & 0xFFFFFFFF;
531 default:
532 llvm_unreachable("Invalid relocation type");
533 }
534}
535
537 switch (Type) {
538 case ELF::R_LARCH_NONE:
539 case ELF::R_LARCH_32:
540 case ELF::R_LARCH_32_PCREL:
541 case ELF::R_LARCH_64:
542 case ELF::R_LARCH_ADD8:
543 case ELF::R_LARCH_SUB8:
544 case ELF::R_LARCH_ADD16:
545 case ELF::R_LARCH_SUB16:
546 case ELF::R_LARCH_ADD32:
547 case ELF::R_LARCH_SUB32:
548 case ELF::R_LARCH_ADD64:
549 case ELF::R_LARCH_SUB64:
550 return true;
551 default:
552 return false;
553 }
554}
555
557 uint64_t LocData, int64_t Addend) {
558 switch (Type) {
559 case ELF::R_LARCH_NONE:
560 return LocData;
561 case ELF::R_LARCH_32:
562 return (S + Addend) & 0xFFFFFFFF;
563 case ELF::R_LARCH_32_PCREL:
564 return (S + Addend - Offset) & 0xFFFFFFFF;
565 case ELF::R_LARCH_64:
566 return S + Addend;
567 case ELF::R_LARCH_ADD8:
568 return (LocData + (S + Addend)) & 0xFF;
569 case ELF::R_LARCH_SUB8:
570 return (LocData - (S + Addend)) & 0xFF;
571 case ELF::R_LARCH_ADD16:
572 return (LocData + (S + Addend)) & 0xFFFF;
573 case ELF::R_LARCH_SUB16:
574 return (LocData - (S + Addend)) & 0xFFFF;
575 case ELF::R_LARCH_ADD32:
576 return (LocData + (S + Addend)) & 0xFFFFFFFF;
577 case ELF::R_LARCH_SUB32:
578 return (LocData - (S + Addend)) & 0xFFFFFFFF;
579 case ELF::R_LARCH_ADD64:
580 return (LocData + (S + Addend));
581 case ELF::R_LARCH_SUB64:
582 return (LocData - (S + Addend));
583 default:
584 llvm_unreachable("Invalid relocation type");
585 }
586}
587
589 switch (Type) {
592 return true;
593 default:
594 return false;
595 }
596}
597
599 uint64_t LocData, int64_t /*Addend*/) {
600 switch (Type) {
603 return (S + LocData) & 0xFFFFFFFF;
604 default:
605 llvm_unreachable("Invalid relocation type");
606 }
607}
608
610 switch (Type) {
613 return true;
614 default:
615 return false;
616 }
617}
618
620 uint64_t LocData, int64_t /*Addend*/) {
621 switch (Type) {
623 return (S + LocData) & 0xFFFFFFFF;
625 return S + LocData;
626 default:
627 llvm_unreachable("Invalid relocation type");
628 }
629}
630
632 switch (Type) {
635 return true;
636 default:
637 return false;
638 }
639}
640
642 uint64_t LocData, int64_t /*Addend*/) {
643 switch (Type) {
646 return (S + LocData) & 0xFFFFFFFF;
647 default:
648 llvm_unreachable("Invalid relocation type");
649 }
650}
651
653 switch (Type) {
656 return true;
657 default:
658 return false;
659 }
660}
661
663 uint64_t LocData, int64_t /*Addend*/) {
664 switch (Type) {
666 return (S + LocData) & 0xFFFFFFFF;
668 return S + LocData;
669 default:
670 llvm_unreachable("Invalid relocation type");
671 }
672}
673
676}
677
679 uint64_t LocData, int64_t /*Addend*/) {
681 return S;
682 llvm_unreachable("Invalid relocation type");
683}
684
686 switch (Type) {
687 case wasm::R_WASM_FUNCTION_INDEX_LEB:
688 case wasm::R_WASM_TABLE_INDEX_SLEB:
689 case wasm::R_WASM_TABLE_INDEX_I32:
690 case wasm::R_WASM_MEMORY_ADDR_LEB:
691 case wasm::R_WASM_MEMORY_ADDR_SLEB:
692 case wasm::R_WASM_MEMORY_ADDR_I32:
693 case wasm::R_WASM_TYPE_INDEX_LEB:
694 case wasm::R_WASM_GLOBAL_INDEX_LEB:
695 case wasm::R_WASM_FUNCTION_OFFSET_I32:
696 case wasm::R_WASM_SECTION_OFFSET_I32:
697 case wasm::R_WASM_TAG_INDEX_LEB:
698 case wasm::R_WASM_GLOBAL_INDEX_I32:
699 case wasm::R_WASM_TABLE_NUMBER_LEB:
700 case wasm::R_WASM_MEMORY_ADDR_LOCREL_I32:
701 return true;
702 default:
703 return false;
704 }
705}
706
708 switch (Type) {
709 case wasm::R_WASM_MEMORY_ADDR_LEB64:
710 case wasm::R_WASM_MEMORY_ADDR_SLEB64:
711 case wasm::R_WASM_MEMORY_ADDR_I64:
712 case wasm::R_WASM_TABLE_INDEX_SLEB64:
713 case wasm::R_WASM_TABLE_INDEX_I64:
714 case wasm::R_WASM_FUNCTION_OFFSET_I64:
715 return true;
716 default:
717 return supportsWasm32(Type);
718 }
719}
720
722 uint64_t LocData, int64_t /*Addend*/) {
723 switch (Type) {
724 case wasm::R_WASM_FUNCTION_INDEX_LEB:
725 case wasm::R_WASM_TABLE_INDEX_SLEB:
726 case wasm::R_WASM_TABLE_INDEX_I32:
727 case wasm::R_WASM_MEMORY_ADDR_LEB:
728 case wasm::R_WASM_MEMORY_ADDR_SLEB:
729 case wasm::R_WASM_MEMORY_ADDR_I32:
730 case wasm::R_WASM_TYPE_INDEX_LEB:
731 case wasm::R_WASM_GLOBAL_INDEX_LEB:
732 case wasm::R_WASM_FUNCTION_OFFSET_I32:
733 case wasm::R_WASM_SECTION_OFFSET_I32:
734 case wasm::R_WASM_TAG_INDEX_LEB:
735 case wasm::R_WASM_GLOBAL_INDEX_I32:
736 case wasm::R_WASM_TABLE_NUMBER_LEB:
737 case wasm::R_WASM_MEMORY_ADDR_LOCREL_I32:
738 // For wasm section, its offset at 0 -- ignoring Value
739 return LocData;
740 default:
741 llvm_unreachable("Invalid relocation type");
742 }
743}
744
746 uint64_t LocData, int64_t Addend) {
747 switch (Type) {
748 case wasm::R_WASM_MEMORY_ADDR_LEB64:
749 case wasm::R_WASM_MEMORY_ADDR_SLEB64:
750 case wasm::R_WASM_MEMORY_ADDR_I64:
751 case wasm::R_WASM_TABLE_INDEX_SLEB64:
752 case wasm::R_WASM_TABLE_INDEX_I64:
753 case wasm::R_WASM_FUNCTION_OFFSET_I64:
754 // For wasm section, its offset at 0 -- ignoring Value
755 return LocData;
756 default:
757 return resolveWasm32(Type, Offset, S, LocData, Addend);
758 }
759}
760
761std::pair<SupportsRelocation, RelocationResolver>
763 if (Obj.isCOFF()) {
764 switch (Obj.getArch()) {
765 case Triple::x86_64:
767 case Triple::x86:
769 case Triple::arm:
770 case Triple::thumb:
772 case Triple::aarch64:
774 default:
775 return {nullptr, nullptr};
776 }
777 } else if (Obj.isELF()) {
778 if (Obj.getBytesInAddress() == 8) {
779 switch (Obj.getArch()) {
780 case Triple::x86_64:
782 case Triple::aarch64:
785 case Triple::bpfel:
786 case Triple::bpfeb:
787 return {supportsBPF, resolveBPF};
790 case Triple::mips64el:
791 case Triple::mips64:
793 case Triple::ppc64le:
794 case Triple::ppc64:
795 return {supportsPPC64, resolvePPC64};
796 case Triple::systemz:
798 case Triple::sparcv9:
800 case Triple::amdgcn:
802 case Triple::riscv64:
803 return {supportsRISCV, resolveRISCV};
804 default:
805 if (isAMDGPU(Obj))
807 return {nullptr, nullptr};
808 }
809 }
810
811 // 32-bit object file
812 assert(Obj.getBytesInAddress() == 4 &&
813 "Invalid word size in object file");
814
815 switch (Obj.getArch()) {
816 case Triple::x86:
817 return {supportsX86, resolveX86};
818 case Triple::ppcle:
819 case Triple::ppc:
820 return {supportsPPC32, resolvePPC32};
821 case Triple::arm:
822 case Triple::armeb:
823 return {supportsARM, resolveARM};
824 case Triple::avr:
825 return {supportsAVR, resolveAVR};
826 case Triple::lanai:
827 return {supportsLanai, resolveLanai};
830 case Triple::mipsel:
831 case Triple::mips:
833 case Triple::msp430:
835 case Triple::sparc:
837 case Triple::hexagon:
839 case Triple::r600:
841 case Triple::riscv32:
842 return {supportsRISCV, resolveRISCV};
843 case Triple::csky:
844 return {supportsCSKY, resolveCSKY};
845 default:
846 if (isAMDGPU(Obj))
848 return {nullptr, nullptr};
849 }
850 } else if (Obj.isMachO()) {
851 if (Obj.getArch() == Triple::x86_64)
853 return {nullptr, nullptr};
854 } else if (Obj.isWasm()) {
855 if (Obj.getArch() == Triple::wasm32)
857 if (Obj.getArch() == Triple::wasm64)
859 return {nullptr, nullptr};
860 }
861
862 llvm_unreachable("Invalid object file");
863}
864
866 uint64_t S, uint64_t LocData) {
867 if (const ObjectFile *Obj = R.getObject()) {
868 int64_t Addend = 0;
869 if (Obj->isELF()) {
870 auto GetRelSectionType = [&]() -> unsigned {
871 if (auto *Elf32LEObj = dyn_cast<ELF32LEObjectFile>(Obj))
872 return Elf32LEObj->getRelSection(R.getRawDataRefImpl())->sh_type;
873 if (auto *Elf64LEObj = dyn_cast<ELF64LEObjectFile>(Obj))
874 return Elf64LEObj->getRelSection(R.getRawDataRefImpl())->sh_type;
875 if (auto *Elf32BEObj = dyn_cast<ELF32BEObjectFile>(Obj))
876 return Elf32BEObj->getRelSection(R.getRawDataRefImpl())->sh_type;
877 auto *Elf64BEObj = cast<ELF64BEObjectFile>(Obj);
878 return Elf64BEObj->getRelSection(R.getRawDataRefImpl())->sh_type;
879 };
880
881 if (GetRelSectionType() == ELF::SHT_RELA) {
882 Addend = getELFAddend(R);
883 // RISCV relocations use both LocData and Addend.
884 if (Obj->getArch() != Triple::riscv32 &&
885 Obj->getArch() != Triple::riscv64)
886 LocData = 0;
887 }
888 }
889
890 return Resolver(R.getType(), R.getOffset(), S, LocData, Addend);
891 }
892
893 // Sometimes the caller might want to use its own specific implementation of
894 // the resolver function. E.g. this is used by LLD when it resolves debug
895 // relocations and assumes that all of them have the same computation (S + A).
896 // The relocation R has no owner object in this case and we don't need to
897 // provide Type and Offset fields. It is also assumed the DataRefImpl.p
898 // contains the addend, provided by the caller.
899 return Resolver(/*Type=*/0, /*Offset=*/0, S, LocData,
900 R.getRawDataRefImpl().p);
901}
902
903} // namespace object
904} // namespace llvm
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
SI optimize exec mask operations pre RA
Base class for error info classes.
Definition: Error.h:45
Tagged union holding either a T or a Error.
Definition: Error.h:474
Error takeError()
Take ownership of the stored error.
Definition: Error.h:601
Interface for looking up the initializer for a variable name, used by Init::resolveReferences.
Definition: Record.h:2190
@ loongarch32
Definition: Triple.h:61
@ aarch64_be
Definition: Triple.h:52
@ loongarch64
Definition: Triple.h:62
@ mips64el
Definition: Triple.h:67
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
bool isWasm() const
Definition: Binary.h:137
bool isMachO() const
Definition: Binary.h:127
bool isCOFF() const
Definition: Binary.h:131
bool isELF() const
Definition: Binary.h:123
Expected< int64_t > getAddend() const
This class is the base class for all object file types.
Definition: ObjectFile.h:229
virtual uint8_t getBytesInAddress() const =0
The number of bytes used to represent an address in this object file format.
virtual Triple::ArchType getArch() const =0
This is a value type class that represents a single relocation in the list of relocations in the obje...
Definition: ObjectFile.h:52
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ IMAGE_REL_ARM64_SECREL
Definition: COFF.h:408
@ IMAGE_REL_ARM64_ADDR64
Definition: COFF.h:414
@ IMAGE_REL_AMD64_ADDR64
Definition: COFF.h:361
@ IMAGE_REL_AMD64_SECREL
Definition: COFF.h:371
@ IMAGE_REL_ARM_ADDR32
Definition: COFF.h:381
@ IMAGE_REL_ARM_SECREL
Definition: COFF.h:390
@ IMAGE_REL_I386_SECREL
Definition: COFF.h:353
@ IMAGE_REL_I386_DIR32
Definition: COFF.h:349
@ EM_AMDGPU
Definition: ELF.h:316
@ SHT_RELA
Definition: ELF.h:1003
@ X86_64_RELOC_UNSIGNED
Definition: MachO.h:482
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)
uint64_t(*)(uint64_t Type, uint64_t Offset, uint64_t S, uint64_t LocData, int64_t Addend) RelocationResolver
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 uint64_t resolveAmdgpu(uint64_t Type, uint64_t Offset, uint64_t S, uint64_t, int64_t Addend)
static bool supportsWasm32(uint64_t Type)
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)
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 resolveHexagon(uint64_t Type, uint64_t Offset, uint64_t S, uint64_t, int64_t Addend)
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.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:440
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:970