1 //===- RelocationResolver.cpp ------------------------------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 // This file defines utilities to resolve relocations in object files.
11 //===----------------------------------------------------------------------===//
13 #include "llvm/Object/RelocationResolver.h"
14 #include "llvm/ADT/Twine.h"
15 #include "llvm/BinaryFormat/COFF.h"
16 #include "llvm/BinaryFormat/ELF.h"
17 #include "llvm/BinaryFormat/MachO.h"
18 #include "llvm/BinaryFormat/Wasm.h"
19 #include "llvm/Object/ELFObjectFile.h"
20 #include "llvm/Object/ELFTypes.h"
21 #include "llvm/Object/ObjectFile.h"
22 #include "llvm/Object/SymbolicFile.h"
23 #include "llvm/Support/Casting.h"
24 #include "llvm/Support/Error.h"
25 #include "llvm/Support/ErrorHandling.h"
26 #include "llvm/TargetParser/Triple.h"
32 static int64_t getELFAddend(RelocationRef R
) {
33 Expected
<int64_t> AddendOrErr
= ELFRelocationRef(R
).getAddend();
34 handleAllErrors(AddendOrErr
.takeError(), [](const ErrorInfoBase
&EI
) {
35 report_fatal_error(Twine(EI
.message()));
40 static bool supportsX86_64(uint64_t Type
) {
42 case ELF::R_X86_64_NONE
:
43 case ELF::R_X86_64_64
:
44 case ELF::R_X86_64_DTPOFF32
:
45 case ELF::R_X86_64_DTPOFF64
:
46 case ELF::R_X86_64_PC32
:
47 case ELF::R_X86_64_PC64
:
48 case ELF::R_X86_64_32
:
49 case ELF::R_X86_64_32S
:
56 static uint64_t resolveX86_64(uint64_t Type
, uint64_t Offset
, uint64_t S
,
57 uint64_t LocData
, int64_t Addend
) {
59 case ELF::R_X86_64_NONE
:
61 case ELF::R_X86_64_64
:
62 case ELF::R_X86_64_DTPOFF32
:
63 case ELF::R_X86_64_DTPOFF64
:
65 case ELF::R_X86_64_PC32
:
66 case ELF::R_X86_64_PC64
:
67 return S
+ Addend
- Offset
;
68 case ELF::R_X86_64_32
:
69 case ELF::R_X86_64_32S
:
70 return (S
+ Addend
) & 0xFFFFFFFF;
72 llvm_unreachable("Invalid relocation type");
76 static bool supportsAArch64(uint64_t Type
) {
78 case ELF::R_AARCH64_ABS32
:
79 case ELF::R_AARCH64_ABS64
:
80 case ELF::R_AARCH64_PREL16
:
81 case ELF::R_AARCH64_PREL32
:
82 case ELF::R_AARCH64_PREL64
:
89 static uint64_t resolveAArch64(uint64_t Type
, uint64_t Offset
, uint64_t S
,
90 uint64_t /*LocData*/, int64_t Addend
) {
92 case ELF::R_AARCH64_ABS32
:
93 return (S
+ Addend
) & 0xFFFFFFFF;
94 case ELF::R_AARCH64_ABS64
:
96 case ELF::R_AARCH64_PREL16
:
97 return (S
+ Addend
- Offset
) & 0xFFFF;
98 case ELF::R_AARCH64_PREL32
:
99 return (S
+ Addend
- Offset
) & 0xFFFFFFFF;
100 case ELF::R_AARCH64_PREL64
:
101 return S
+ Addend
- Offset
;
103 llvm_unreachable("Invalid relocation type");
107 static bool supportsBPF(uint64_t Type
) {
109 case ELF::R_BPF_64_ABS32
:
110 case ELF::R_BPF_64_ABS64
:
117 static uint64_t resolveBPF(uint64_t Type
, uint64_t Offset
, uint64_t S
,
118 uint64_t LocData
, int64_t /*Addend*/) {
120 case ELF::R_BPF_64_ABS32
:
121 return (S
+ LocData
) & 0xFFFFFFFF;
122 case ELF::R_BPF_64_ABS64
:
125 llvm_unreachable("Invalid relocation type");
129 static bool supportsMips64(uint64_t Type
) {
133 case ELF::R_MIPS_TLS_DTPREL64
:
134 case ELF::R_MIPS_PC32
:
141 static uint64_t resolveMips64(uint64_t Type
, uint64_t Offset
, uint64_t S
,
142 uint64_t /*LocData*/, int64_t Addend
) {
145 return (S
+ Addend
) & 0xFFFFFFFF;
148 case ELF::R_MIPS_TLS_DTPREL64
:
149 return S
+ Addend
- 0x8000;
150 case ELF::R_MIPS_PC32
:
151 return S
+ Addend
- Offset
;
153 llvm_unreachable("Invalid relocation type");
157 static bool supportsMSP430(uint64_t Type
) {
159 case ELF::R_MSP430_32
:
160 case ELF::R_MSP430_16_BYTE
:
167 static uint64_t resolveMSP430(uint64_t Type
, uint64_t Offset
, uint64_t S
,
168 uint64_t /*LocData*/, int64_t Addend
) {
170 case ELF::R_MSP430_32
:
171 return (S
+ Addend
) & 0xFFFFFFFF;
172 case ELF::R_MSP430_16_BYTE
:
173 return (S
+ Addend
) & 0xFFFF;
175 llvm_unreachable("Invalid relocation type");
179 static bool supportsPPC64(uint64_t Type
) {
181 case ELF::R_PPC64_ADDR32
:
182 case ELF::R_PPC64_ADDR64
:
183 case ELF::R_PPC64_REL32
:
184 case ELF::R_PPC64_REL64
:
191 static uint64_t resolvePPC64(uint64_t Type
, uint64_t Offset
, uint64_t S
,
192 uint64_t /*LocData*/, int64_t Addend
) {
194 case ELF::R_PPC64_ADDR32
:
195 return (S
+ Addend
) & 0xFFFFFFFF;
196 case ELF::R_PPC64_ADDR64
:
198 case ELF::R_PPC64_REL32
:
199 return (S
+ Addend
- Offset
) & 0xFFFFFFFF;
200 case ELF::R_PPC64_REL64
:
201 return S
+ Addend
- Offset
;
203 llvm_unreachable("Invalid relocation type");
207 static bool supportsSystemZ(uint64_t Type
) {
217 static uint64_t resolveSystemZ(uint64_t Type
, uint64_t Offset
, uint64_t S
,
218 uint64_t /*LocData*/, int64_t Addend
) {
221 return (S
+ Addend
) & 0xFFFFFFFF;
225 llvm_unreachable("Invalid relocation type");
229 static bool supportsSparc64(uint64_t Type
) {
231 case ELF::R_SPARC_32
:
232 case ELF::R_SPARC_64
:
233 case ELF::R_SPARC_UA32
:
234 case ELF::R_SPARC_UA64
:
241 static uint64_t resolveSparc64(uint64_t Type
, uint64_t Offset
, uint64_t S
,
242 uint64_t /*LocData*/, int64_t Addend
) {
244 case ELF::R_SPARC_32
:
245 case ELF::R_SPARC_64
:
246 case ELF::R_SPARC_UA32
:
247 case ELF::R_SPARC_UA64
:
250 llvm_unreachable("Invalid relocation type");
254 /// Returns true if \c Obj is an AMDGPU code object based solely on the value
257 /// AMDGPU code objects with an e_machine of EF_AMDGPU_MACH_NONE do not
258 /// identify their arch as either r600 or amdgcn, but we can still handle
259 /// their relocations. When we identify an ELF object with an UnknownArch,
260 /// we use isAMDGPU to check for this case.
261 static bool isAMDGPU(const ObjectFile
&Obj
) {
262 if (const auto *ELFObj
= dyn_cast
<ELFObjectFileBase
>(&Obj
))
263 return ELFObj
->getEMachine() == ELF::EM_AMDGPU
;
267 static bool supportsAmdgpu(uint64_t Type
) {
269 case ELF::R_AMDGPU_ABS32
:
270 case ELF::R_AMDGPU_ABS64
:
277 static uint64_t resolveAmdgpu(uint64_t Type
, uint64_t Offset
, uint64_t S
,
278 uint64_t /*LocData*/, int64_t Addend
) {
280 case ELF::R_AMDGPU_ABS32
:
281 case ELF::R_AMDGPU_ABS64
:
284 llvm_unreachable("Invalid relocation type");
288 static bool supportsX86(uint64_t Type
) {
290 case ELF::R_386_NONE
:
292 case ELF::R_386_PC32
:
299 static uint64_t resolveX86(uint64_t Type
, uint64_t Offset
, uint64_t S
,
300 uint64_t LocData
, int64_t /*Addend*/) {
302 case ELF::R_386_NONE
:
306 case ELF::R_386_PC32
:
307 return S
- Offset
+ LocData
;
309 llvm_unreachable("Invalid relocation type");
313 static bool supportsPPC32(uint64_t Type
) {
315 case ELF::R_PPC_ADDR32
:
316 case ELF::R_PPC_REL32
:
323 static uint64_t resolvePPC32(uint64_t Type
, uint64_t Offset
, uint64_t S
,
324 uint64_t /*LocData*/, int64_t Addend
) {
326 case ELF::R_PPC_ADDR32
:
327 return (S
+ Addend
) & 0xFFFFFFFF;
328 case ELF::R_PPC_REL32
:
329 return (S
+ Addend
- Offset
) & 0xFFFFFFFF;
331 llvm_unreachable("Invalid relocation type");
334 static bool supportsARM(uint64_t Type
) {
336 case ELF::R_ARM_ABS32
:
337 case ELF::R_ARM_REL32
:
344 static uint64_t resolveARM(uint64_t Type
, uint64_t Offset
, uint64_t S
,
345 uint64_t LocData
, int64_t Addend
) {
346 // Support both RELA and REL relocations. The caller is responsible
347 // for supplying the correct values for LocData and Addend, i.e.
348 // Addend == 0 for REL and LocData == 0 for RELA.
349 assert((LocData
== 0 || Addend
== 0) &&
350 "one of LocData and Addend must be 0");
352 case ELF::R_ARM_ABS32
:
353 return (S
+ LocData
+ Addend
) & 0xFFFFFFFF;
354 case ELF::R_ARM_REL32
:
355 return (S
+ LocData
+ Addend
- Offset
) & 0xFFFFFFFF;
357 llvm_unreachable("Invalid relocation type");
360 static bool supportsAVR(uint64_t Type
) {
370 static uint64_t resolveAVR(uint64_t Type
, uint64_t Offset
, uint64_t S
,
371 uint64_t /*LocData*/, int64_t Addend
) {
374 return (S
+ Addend
) & 0xFFFF;
376 return (S
+ Addend
) & 0xFFFFFFFF;
378 llvm_unreachable("Invalid relocation type");
382 static bool supportsLanai(uint64_t Type
) {
383 return Type
== ELF::R_LANAI_32
;
386 static uint64_t resolveLanai(uint64_t Type
, uint64_t Offset
, uint64_t S
,
387 uint64_t /*LocData*/, int64_t Addend
) {
388 if (Type
== ELF::R_LANAI_32
)
389 return (S
+ Addend
) & 0xFFFFFFFF;
390 llvm_unreachable("Invalid relocation type");
393 static bool supportsMips32(uint64_t Type
) {
396 case ELF::R_MIPS_TLS_DTPREL32
:
403 static uint64_t resolveMips32(uint64_t Type
, uint64_t Offset
, uint64_t S
,
404 uint64_t LocData
, int64_t /*Addend*/) {
405 // FIXME: Take in account implicit addends to get correct results.
406 if (Type
== ELF::R_MIPS_32
)
407 return (S
+ LocData
) & 0xFFFFFFFF;
408 if (Type
== ELF::R_MIPS_TLS_DTPREL32
)
409 return (S
+ LocData
) & 0xFFFFFFFF;
410 llvm_unreachable("Invalid relocation type");
413 static bool supportsSparc32(uint64_t Type
) {
415 case ELF::R_SPARC_32
:
416 case ELF::R_SPARC_UA32
:
423 static uint64_t resolveSparc32(uint64_t Type
, uint64_t Offset
, uint64_t S
,
424 uint64_t LocData
, int64_t Addend
) {
425 if (Type
== ELF::R_SPARC_32
|| Type
== ELF::R_SPARC_UA32
)
430 static bool supportsHexagon(uint64_t Type
) {
431 return Type
== ELF::R_HEX_32
;
434 static uint64_t resolveHexagon(uint64_t Type
, uint64_t Offset
, uint64_t S
,
435 uint64_t /*LocData*/, int64_t Addend
) {
436 if (Type
== ELF::R_HEX_32
)
438 llvm_unreachable("Invalid relocation type");
441 static bool supportsRISCV(uint64_t Type
) {
443 case ELF::R_RISCV_NONE
:
444 case ELF::R_RISCV_32
:
445 case ELF::R_RISCV_32_PCREL
:
446 case ELF::R_RISCV_64
:
447 case ELF::R_RISCV_SET6
:
448 case ELF::R_RISCV_SET8
:
449 case ELF::R_RISCV_SUB6
:
450 case ELF::R_RISCV_ADD8
:
451 case ELF::R_RISCV_SUB8
:
452 case ELF::R_RISCV_SET16
:
453 case ELF::R_RISCV_ADD16
:
454 case ELF::R_RISCV_SUB16
:
455 case ELF::R_RISCV_SET32
:
456 case ELF::R_RISCV_ADD32
:
457 case ELF::R_RISCV_SUB32
:
458 case ELF::R_RISCV_ADD64
:
459 case ELF::R_RISCV_SUB64
:
466 static uint64_t resolveRISCV(uint64_t Type
, uint64_t Offset
, uint64_t S
,
467 uint64_t LocData
, int64_t Addend
) {
469 uint64_t A
= LocData
;
471 case ELF::R_RISCV_NONE
:
473 case ELF::R_RISCV_32
:
474 return (S
+ RA
) & 0xFFFFFFFF;
475 case ELF::R_RISCV_32_PCREL
:
476 return (S
+ RA
- Offset
) & 0xFFFFFFFF;
477 case ELF::R_RISCV_64
:
479 case ELF::R_RISCV_SET6
:
480 return (A
& 0xC0) | ((S
+ RA
) & 0x3F);
481 case ELF::R_RISCV_SUB6
:
482 return (A
& 0xC0) | (((A
& 0x3F) - (S
+ RA
)) & 0x3F);
483 case ELF::R_RISCV_SET8
:
484 return (S
+ RA
) & 0xFF;
485 case ELF::R_RISCV_ADD8
:
486 return (A
+ (S
+ RA
)) & 0xFF;
487 case ELF::R_RISCV_SUB8
:
488 return (A
- (S
+ RA
)) & 0xFF;
489 case ELF::R_RISCV_SET16
:
490 return (S
+ RA
) & 0xFFFF;
491 case ELF::R_RISCV_ADD16
:
492 return (A
+ (S
+ RA
)) & 0xFFFF;
493 case ELF::R_RISCV_SUB16
:
494 return (A
- (S
+ RA
)) & 0xFFFF;
495 case ELF::R_RISCV_SET32
:
496 return (S
+ RA
) & 0xFFFFFFFF;
497 case ELF::R_RISCV_ADD32
:
498 return (A
+ (S
+ RA
)) & 0xFFFFFFFF;
499 case ELF::R_RISCV_SUB32
:
500 return (A
- (S
+ RA
)) & 0xFFFFFFFF;
501 case ELF::R_RISCV_ADD64
:
502 return (A
+ (S
+ RA
));
503 case ELF::R_RISCV_SUB64
:
504 return (A
- (S
+ RA
));
506 llvm_unreachable("Invalid relocation type");
510 static bool supportsCSKY(uint64_t Type
) {
512 case ELF::R_CKCORE_NONE
:
513 case ELF::R_CKCORE_ADDR32
:
514 case ELF::R_CKCORE_PCREL32
:
521 static uint64_t resolveCSKY(uint64_t Type
, uint64_t Offset
, uint64_t S
,
522 uint64_t LocData
, int64_t Addend
) {
524 case ELF::R_CKCORE_NONE
:
526 case ELF::R_CKCORE_ADDR32
:
527 return (S
+ Addend
) & 0xFFFFFFFF;
528 case ELF::R_CKCORE_PCREL32
:
529 return (S
+ Addend
- Offset
) & 0xFFFFFFFF;
531 llvm_unreachable("Invalid relocation type");
535 static bool supportsLoongArch(uint64_t Type
) {
537 case ELF::R_LARCH_NONE
:
538 case ELF::R_LARCH_32
:
539 case ELF::R_LARCH_32_PCREL
:
540 case ELF::R_LARCH_64
:
541 case ELF::R_LARCH_ADD6
:
542 case ELF::R_LARCH_SUB6
:
543 case ELF::R_LARCH_ADD8
:
544 case ELF::R_LARCH_SUB8
:
545 case ELF::R_LARCH_ADD16
:
546 case ELF::R_LARCH_SUB16
:
547 case ELF::R_LARCH_ADD32
:
548 case ELF::R_LARCH_SUB32
:
549 case ELF::R_LARCH_ADD64
:
550 case ELF::R_LARCH_SUB64
:
557 static uint64_t resolveLoongArch(uint64_t Type
, uint64_t Offset
, uint64_t S
,
558 uint64_t LocData
, int64_t Addend
) {
560 case ELF::R_LARCH_NONE
:
562 case ELF::R_LARCH_32
:
563 return (S
+ Addend
) & 0xFFFFFFFF;
564 case ELF::R_LARCH_32_PCREL
:
565 return (S
+ Addend
- Offset
) & 0xFFFFFFFF;
566 case ELF::R_LARCH_64
:
568 case ELF::R_LARCH_ADD6
:
569 return (LocData
& 0xC0) | ((LocData
+ S
+ Addend
) & 0x3F);
570 case ELF::R_LARCH_SUB6
:
571 return (LocData
& 0xC0) | ((LocData
- (S
+ Addend
)) & 0x3F);
572 case ELF::R_LARCH_ADD8
:
573 return (LocData
+ (S
+ Addend
)) & 0xFF;
574 case ELF::R_LARCH_SUB8
:
575 return (LocData
- (S
+ Addend
)) & 0xFF;
576 case ELF::R_LARCH_ADD16
:
577 return (LocData
+ (S
+ Addend
)) & 0xFFFF;
578 case ELF::R_LARCH_SUB16
:
579 return (LocData
- (S
+ Addend
)) & 0xFFFF;
580 case ELF::R_LARCH_ADD32
:
581 return (LocData
+ (S
+ Addend
)) & 0xFFFFFFFF;
582 case ELF::R_LARCH_SUB32
:
583 return (LocData
- (S
+ Addend
)) & 0xFFFFFFFF;
584 case ELF::R_LARCH_ADD64
:
585 return (LocData
+ (S
+ Addend
));
586 case ELF::R_LARCH_SUB64
:
587 return (LocData
- (S
+ Addend
));
589 llvm_unreachable("Invalid relocation type");
593 static bool supportsCOFFX86(uint64_t Type
) {
595 case COFF::IMAGE_REL_I386_SECREL
:
596 case COFF::IMAGE_REL_I386_DIR32
:
603 static uint64_t resolveCOFFX86(uint64_t Type
, uint64_t Offset
, uint64_t S
,
604 uint64_t LocData
, int64_t /*Addend*/) {
606 case COFF::IMAGE_REL_I386_SECREL
:
607 case COFF::IMAGE_REL_I386_DIR32
:
608 return (S
+ LocData
) & 0xFFFFFFFF;
610 llvm_unreachable("Invalid relocation type");
614 static bool supportsCOFFX86_64(uint64_t Type
) {
616 case COFF::IMAGE_REL_AMD64_SECREL
:
617 case COFF::IMAGE_REL_AMD64_ADDR64
:
624 static uint64_t resolveCOFFX86_64(uint64_t Type
, uint64_t Offset
, uint64_t S
,
625 uint64_t LocData
, int64_t /*Addend*/) {
627 case COFF::IMAGE_REL_AMD64_SECREL
:
628 return (S
+ LocData
) & 0xFFFFFFFF;
629 case COFF::IMAGE_REL_AMD64_ADDR64
:
632 llvm_unreachable("Invalid relocation type");
636 static bool supportsCOFFARM(uint64_t Type
) {
638 case COFF::IMAGE_REL_ARM_SECREL
:
639 case COFF::IMAGE_REL_ARM_ADDR32
:
646 static uint64_t resolveCOFFARM(uint64_t Type
, uint64_t Offset
, uint64_t S
,
647 uint64_t LocData
, int64_t /*Addend*/) {
649 case COFF::IMAGE_REL_ARM_SECREL
:
650 case COFF::IMAGE_REL_ARM_ADDR32
:
651 return (S
+ LocData
) & 0xFFFFFFFF;
653 llvm_unreachable("Invalid relocation type");
657 static bool supportsCOFFARM64(uint64_t Type
) {
659 case COFF::IMAGE_REL_ARM64_SECREL
:
660 case COFF::IMAGE_REL_ARM64_ADDR64
:
667 static uint64_t resolveCOFFARM64(uint64_t Type
, uint64_t Offset
, uint64_t S
,
668 uint64_t LocData
, int64_t /*Addend*/) {
670 case COFF::IMAGE_REL_ARM64_SECREL
:
671 return (S
+ LocData
) & 0xFFFFFFFF;
672 case COFF::IMAGE_REL_ARM64_ADDR64
:
675 llvm_unreachable("Invalid relocation type");
679 static bool supportsMachOX86_64(uint64_t Type
) {
680 return Type
== MachO::X86_64_RELOC_UNSIGNED
;
683 static uint64_t resolveMachOX86_64(uint64_t Type
, uint64_t Offset
, uint64_t S
,
684 uint64_t LocData
, int64_t /*Addend*/) {
685 if (Type
== MachO::X86_64_RELOC_UNSIGNED
)
687 llvm_unreachable("Invalid relocation type");
690 static bool supportsWasm32(uint64_t Type
) {
692 case wasm::R_WASM_FUNCTION_INDEX_LEB
:
693 case wasm::R_WASM_TABLE_INDEX_SLEB
:
694 case wasm::R_WASM_TABLE_INDEX_I32
:
695 case wasm::R_WASM_MEMORY_ADDR_LEB
:
696 case wasm::R_WASM_MEMORY_ADDR_SLEB
:
697 case wasm::R_WASM_MEMORY_ADDR_I32
:
698 case wasm::R_WASM_TYPE_INDEX_LEB
:
699 case wasm::R_WASM_GLOBAL_INDEX_LEB
:
700 case wasm::R_WASM_FUNCTION_OFFSET_I32
:
701 case wasm::R_WASM_SECTION_OFFSET_I32
:
702 case wasm::R_WASM_TAG_INDEX_LEB
:
703 case wasm::R_WASM_GLOBAL_INDEX_I32
:
704 case wasm::R_WASM_TABLE_NUMBER_LEB
:
705 case wasm::R_WASM_MEMORY_ADDR_LOCREL_I32
:
712 static bool supportsWasm64(uint64_t Type
) {
714 case wasm::R_WASM_MEMORY_ADDR_LEB64
:
715 case wasm::R_WASM_MEMORY_ADDR_SLEB64
:
716 case wasm::R_WASM_MEMORY_ADDR_I64
:
717 case wasm::R_WASM_TABLE_INDEX_SLEB64
:
718 case wasm::R_WASM_TABLE_INDEX_I64
:
719 case wasm::R_WASM_FUNCTION_OFFSET_I64
:
722 return supportsWasm32(Type
);
726 static uint64_t resolveWasm32(uint64_t Type
, uint64_t Offset
, uint64_t S
,
727 uint64_t LocData
, int64_t /*Addend*/) {
729 case wasm::R_WASM_FUNCTION_INDEX_LEB
:
730 case wasm::R_WASM_TABLE_INDEX_SLEB
:
731 case wasm::R_WASM_TABLE_INDEX_I32
:
732 case wasm::R_WASM_MEMORY_ADDR_LEB
:
733 case wasm::R_WASM_MEMORY_ADDR_SLEB
:
734 case wasm::R_WASM_MEMORY_ADDR_I32
:
735 case wasm::R_WASM_TYPE_INDEX_LEB
:
736 case wasm::R_WASM_GLOBAL_INDEX_LEB
:
737 case wasm::R_WASM_FUNCTION_OFFSET_I32
:
738 case wasm::R_WASM_SECTION_OFFSET_I32
:
739 case wasm::R_WASM_TAG_INDEX_LEB
:
740 case wasm::R_WASM_GLOBAL_INDEX_I32
:
741 case wasm::R_WASM_TABLE_NUMBER_LEB
:
742 case wasm::R_WASM_MEMORY_ADDR_LOCREL_I32
:
743 // For wasm section, its offset at 0 -- ignoring Value
746 llvm_unreachable("Invalid relocation type");
750 static uint64_t resolveWasm64(uint64_t Type
, uint64_t Offset
, uint64_t S
,
751 uint64_t LocData
, int64_t Addend
) {
753 case wasm::R_WASM_MEMORY_ADDR_LEB64
:
754 case wasm::R_WASM_MEMORY_ADDR_SLEB64
:
755 case wasm::R_WASM_MEMORY_ADDR_I64
:
756 case wasm::R_WASM_TABLE_INDEX_SLEB64
:
757 case wasm::R_WASM_TABLE_INDEX_I64
:
758 case wasm::R_WASM_FUNCTION_OFFSET_I64
:
759 // For wasm section, its offset at 0 -- ignoring Value
762 return resolveWasm32(Type
, Offset
, S
, LocData
, Addend
);
766 std::pair
<SupportsRelocation
, RelocationResolver
>
767 getRelocationResolver(const ObjectFile
&Obj
) {
769 switch (Obj
.getArch()) {
771 return {supportsCOFFX86_64
, resolveCOFFX86_64
};
773 return {supportsCOFFX86
, resolveCOFFX86
};
776 return {supportsCOFFARM
, resolveCOFFARM
};
777 case Triple::aarch64
:
778 return {supportsCOFFARM64
, resolveCOFFARM64
};
780 return {nullptr, nullptr};
782 } else if (Obj
.isELF()) {
783 if (Obj
.getBytesInAddress() == 8) {
784 switch (Obj
.getArch()) {
786 return {supportsX86_64
, resolveX86_64
};
787 case Triple::aarch64
:
788 case Triple::aarch64_be
:
789 return {supportsAArch64
, resolveAArch64
};
792 return {supportsBPF
, resolveBPF
};
793 case Triple::loongarch64
:
794 return {supportsLoongArch
, resolveLoongArch
};
795 case Triple::mips64el
:
797 return {supportsMips64
, resolveMips64
};
798 case Triple::ppc64le
:
800 return {supportsPPC64
, resolvePPC64
};
801 case Triple::systemz
:
802 return {supportsSystemZ
, resolveSystemZ
};
803 case Triple::sparcv9
:
804 return {supportsSparc64
, resolveSparc64
};
806 return {supportsAmdgpu
, resolveAmdgpu
};
807 case Triple::riscv64
:
808 return {supportsRISCV
, resolveRISCV
};
811 return {supportsAmdgpu
, resolveAmdgpu
};
812 return {nullptr, nullptr};
816 // 32-bit object file
817 assert(Obj
.getBytesInAddress() == 4 &&
818 "Invalid word size in object file");
820 switch (Obj
.getArch()) {
822 return {supportsX86
, resolveX86
};
825 return {supportsPPC32
, resolvePPC32
};
828 return {supportsARM
, resolveARM
};
830 return {supportsAVR
, resolveAVR
};
832 return {supportsLanai
, resolveLanai
};
833 case Triple::loongarch32
:
834 return {supportsLoongArch
, resolveLoongArch
};
837 return {supportsMips32
, resolveMips32
};
839 return {supportsMSP430
, resolveMSP430
};
841 return {supportsSparc32
, resolveSparc32
};
842 case Triple::hexagon
:
843 return {supportsHexagon
, resolveHexagon
};
845 return {supportsAmdgpu
, resolveAmdgpu
};
846 case Triple::riscv32
:
847 return {supportsRISCV
, resolveRISCV
};
849 return {supportsCSKY
, resolveCSKY
};
852 return {supportsAmdgpu
, resolveAmdgpu
};
853 return {nullptr, nullptr};
855 } else if (Obj
.isMachO()) {
856 if (Obj
.getArch() == Triple::x86_64
)
857 return {supportsMachOX86_64
, resolveMachOX86_64
};
858 return {nullptr, nullptr};
859 } else if (Obj
.isWasm()) {
860 if (Obj
.getArch() == Triple::wasm32
)
861 return {supportsWasm32
, resolveWasm32
};
862 if (Obj
.getArch() == Triple::wasm64
)
863 return {supportsWasm64
, resolveWasm64
};
864 return {nullptr, nullptr};
867 llvm_unreachable("Invalid object file");
870 uint64_t resolveRelocation(RelocationResolver Resolver
, const RelocationRef
&R
,
871 uint64_t S
, uint64_t LocData
) {
872 if (const ObjectFile
*Obj
= R
.getObject()) {
875 auto GetRelSectionType
= [&]() -> unsigned {
876 if (auto *Elf32LEObj
= dyn_cast
<ELF32LEObjectFile
>(Obj
))
877 return Elf32LEObj
->getRelSection(R
.getRawDataRefImpl())->sh_type
;
878 if (auto *Elf64LEObj
= dyn_cast
<ELF64LEObjectFile
>(Obj
))
879 return Elf64LEObj
->getRelSection(R
.getRawDataRefImpl())->sh_type
;
880 if (auto *Elf32BEObj
= dyn_cast
<ELF32BEObjectFile
>(Obj
))
881 return Elf32BEObj
->getRelSection(R
.getRawDataRefImpl())->sh_type
;
882 auto *Elf64BEObj
= cast
<ELF64BEObjectFile
>(Obj
);
883 return Elf64BEObj
->getRelSection(R
.getRawDataRefImpl())->sh_type
;
886 if (GetRelSectionType() == ELF::SHT_RELA
) {
887 Addend
= getELFAddend(R
);
888 // LoongArch and RISCV relocations use both LocData and Addend.
889 if (Obj
->getArch() != Triple::loongarch32
&&
890 Obj
->getArch() != Triple::loongarch64
&&
891 Obj
->getArch() != Triple::riscv32
&&
892 Obj
->getArch() != Triple::riscv64
)
897 return Resolver(R
.getType(), R
.getOffset(), S
, LocData
, Addend
);
900 // Sometimes the caller might want to use its own specific implementation of
901 // the resolver function. E.g. this is used by LLD when it resolves debug
902 // relocations and assumes that all of them have the same computation (S + A).
903 // The relocation R has no owner object in this case and we don't need to
904 // provide Type and Offset fields. It is also assumed the DataRefImpl.p
905 // contains the addend, provided by the caller.
906 return Resolver(/*Type=*/0, /*Offset=*/0, S
, LocData
,
907 R
.getRawDataRefImpl().p
);
910 } // namespace object