[ORC] Add std::tuple support to SimplePackedSerialization.
[llvm-project.git] / llvm / lib / Object / RelocationResolver.cpp
blobab98a2dd2ac1f01625f2da8f5ff68c685b292af2
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.
11 //===----------------------------------------------------------------------===//
13 #include "llvm/Object/RelocationResolver.h"
15 namespace llvm {
16 namespace object {
18 static int64_t getELFAddend(RelocationRef R) {
19 Expected<int64_t> AddendOrErr = ELFRelocationRef(R).getAddend();
20 handleAllErrors(AddendOrErr.takeError(), [](const ErrorInfoBase &EI) {
21 report_fatal_error(EI.message());
22 });
23 return *AddendOrErr;
26 static bool supportsX86_64(uint64_t Type) {
27 switch (Type) {
28 case ELF::R_X86_64_NONE:
29 case ELF::R_X86_64_64:
30 case ELF::R_X86_64_DTPOFF32:
31 case ELF::R_X86_64_DTPOFF64:
32 case ELF::R_X86_64_PC32:
33 case ELF::R_X86_64_PC64:
34 case ELF::R_X86_64_32:
35 case ELF::R_X86_64_32S:
36 return true;
37 default:
38 return false;
42 static uint64_t resolveX86_64(uint64_t Type, uint64_t Offset, uint64_t S,
43 uint64_t LocData, int64_t Addend) {
44 switch (Type) {
45 case ELF::R_X86_64_NONE:
46 return LocData;
47 case ELF::R_X86_64_64:
48 case ELF::R_X86_64_DTPOFF32:
49 case ELF::R_X86_64_DTPOFF64:
50 return S + Addend;
51 case ELF::R_X86_64_PC32:
52 case ELF::R_X86_64_PC64:
53 return S + Addend - Offset;
54 case ELF::R_X86_64_32:
55 case ELF::R_X86_64_32S:
56 return (S + Addend) & 0xFFFFFFFF;
57 default:
58 llvm_unreachable("Invalid relocation type");
62 static bool supportsAArch64(uint64_t Type) {
63 switch (Type) {
64 case ELF::R_AARCH64_ABS32:
65 case ELF::R_AARCH64_ABS64:
66 case ELF::R_AARCH64_PREL32:
67 case ELF::R_AARCH64_PREL64:
68 return true;
69 default:
70 return false;
74 static uint64_t resolveAArch64(uint64_t Type, uint64_t Offset, uint64_t S,
75 uint64_t /*LocData*/, int64_t Addend) {
76 switch (Type) {
77 case ELF::R_AARCH64_ABS32:
78 return (S + Addend) & 0xFFFFFFFF;
79 case ELF::R_AARCH64_ABS64:
80 return S + Addend;
81 case ELF::R_AARCH64_PREL32:
82 return (S + Addend - Offset) & 0xFFFFFFFF;
83 case ELF::R_AARCH64_PREL64:
84 return S + Addend - Offset;
85 default:
86 llvm_unreachable("Invalid relocation type");
90 static bool supportsBPF(uint64_t Type) {
91 switch (Type) {
92 case ELF::R_BPF_64_ABS32:
93 case ELF::R_BPF_64_ABS64:
94 return true;
95 default:
96 return false;
100 static uint64_t resolveBPF(uint64_t Type, uint64_t Offset, uint64_t S,
101 uint64_t LocData, int64_t /*Addend*/) {
102 switch (Type) {
103 case ELF::R_BPF_64_ABS32:
104 return (S + LocData) & 0xFFFFFFFF;
105 case ELF::R_BPF_64_ABS64:
106 return S + LocData;
107 default:
108 llvm_unreachable("Invalid relocation type");
112 static bool supportsMips64(uint64_t Type) {
113 switch (Type) {
114 case ELF::R_MIPS_32:
115 case ELF::R_MIPS_64:
116 case ELF::R_MIPS_TLS_DTPREL64:
117 case ELF::R_MIPS_PC32:
118 return true;
119 default:
120 return false;
124 static uint64_t resolveMips64(uint64_t Type, uint64_t Offset, uint64_t S,
125 uint64_t /*LocData*/, int64_t Addend) {
126 switch (Type) {
127 case ELF::R_MIPS_32:
128 return (S + Addend) & 0xFFFFFFFF;
129 case ELF::R_MIPS_64:
130 return S + Addend;
131 case ELF::R_MIPS_TLS_DTPREL64:
132 return S + Addend - 0x8000;
133 case ELF::R_MIPS_PC32:
134 return S + Addend - Offset;
135 default:
136 llvm_unreachable("Invalid relocation type");
140 static bool supportsMSP430(uint64_t Type) {
141 switch (Type) {
142 case ELF::R_MSP430_32:
143 case ELF::R_MSP430_16_BYTE:
144 return true;
145 default:
146 return false;
150 static uint64_t resolveMSP430(uint64_t Type, uint64_t Offset, uint64_t S,
151 uint64_t /*LocData*/, int64_t Addend) {
152 switch (Type) {
153 case ELF::R_MSP430_32:
154 return (S + Addend) & 0xFFFFFFFF;
155 case ELF::R_MSP430_16_BYTE:
156 return (S + Addend) & 0xFFFF;
157 default:
158 llvm_unreachable("Invalid relocation type");
162 static bool supportsPPC64(uint64_t Type) {
163 switch (Type) {
164 case ELF::R_PPC64_ADDR32:
165 case ELF::R_PPC64_ADDR64:
166 case ELF::R_PPC64_REL32:
167 case ELF::R_PPC64_REL64:
168 return true;
169 default:
170 return false;
174 static uint64_t resolvePPC64(uint64_t Type, uint64_t Offset, uint64_t S,
175 uint64_t /*LocData*/, int64_t Addend) {
176 switch (Type) {
177 case ELF::R_PPC64_ADDR32:
178 return (S + Addend) & 0xFFFFFFFF;
179 case ELF::R_PPC64_ADDR64:
180 return S + Addend;
181 case ELF::R_PPC64_REL32:
182 return (S + Addend - Offset) & 0xFFFFFFFF;
183 case ELF::R_PPC64_REL64:
184 return S + Addend - Offset;
185 default:
186 llvm_unreachable("Invalid relocation type");
190 static bool supportsSystemZ(uint64_t Type) {
191 switch (Type) {
192 case ELF::R_390_32:
193 case ELF::R_390_64:
194 return true;
195 default:
196 return false;
200 static uint64_t resolveSystemZ(uint64_t Type, uint64_t Offset, uint64_t S,
201 uint64_t /*LocData*/, int64_t Addend) {
202 switch (Type) {
203 case ELF::R_390_32:
204 return (S + Addend) & 0xFFFFFFFF;
205 case ELF::R_390_64:
206 return S + Addend;
207 default:
208 llvm_unreachable("Invalid relocation type");
212 static bool supportsSparc64(uint64_t Type) {
213 switch (Type) {
214 case ELF::R_SPARC_32:
215 case ELF::R_SPARC_64:
216 case ELF::R_SPARC_UA32:
217 case ELF::R_SPARC_UA64:
218 return true;
219 default:
220 return false;
224 static uint64_t resolveSparc64(uint64_t Type, uint64_t Offset, uint64_t S,
225 uint64_t /*LocData*/, int64_t Addend) {
226 switch (Type) {
227 case ELF::R_SPARC_32:
228 case ELF::R_SPARC_64:
229 case ELF::R_SPARC_UA32:
230 case ELF::R_SPARC_UA64:
231 return S + Addend;
232 default:
233 llvm_unreachable("Invalid relocation type");
237 static bool supportsAmdgpu(uint64_t Type) {
238 switch (Type) {
239 case ELF::R_AMDGPU_ABS32:
240 case ELF::R_AMDGPU_ABS64:
241 return true;
242 default:
243 return false;
247 static uint64_t resolveAmdgpu(uint64_t Type, uint64_t Offset, uint64_t S,
248 uint64_t /*LocData*/, int64_t Addend) {
249 switch (Type) {
250 case ELF::R_AMDGPU_ABS32:
251 case ELF::R_AMDGPU_ABS64:
252 return S + Addend;
253 default:
254 llvm_unreachable("Invalid relocation type");
258 static bool supportsX86(uint64_t Type) {
259 switch (Type) {
260 case ELF::R_386_NONE:
261 case ELF::R_386_32:
262 case ELF::R_386_PC32:
263 return true;
264 default:
265 return false;
269 static uint64_t resolveX86(uint64_t Type, uint64_t Offset, uint64_t S,
270 uint64_t LocData, int64_t /*Addend*/) {
271 switch (Type) {
272 case ELF::R_386_NONE:
273 return LocData;
274 case ELF::R_386_32:
275 return S + LocData;
276 case ELF::R_386_PC32:
277 return S - Offset + LocData;
278 default:
279 llvm_unreachable("Invalid relocation type");
283 static bool supportsPPC32(uint64_t Type) {
284 switch (Type) {
285 case ELF::R_PPC_ADDR32:
286 case ELF::R_PPC_REL32:
287 return true;
288 default:
289 return false;
293 static uint64_t resolvePPC32(uint64_t Type, uint64_t Offset, uint64_t S,
294 uint64_t /*LocData*/, int64_t Addend) {
295 switch (Type) {
296 case ELF::R_PPC_ADDR32:
297 return (S + Addend) & 0xFFFFFFFF;
298 case ELF::R_PPC_REL32:
299 return (S + Addend - Offset) & 0xFFFFFFFF;
301 llvm_unreachable("Invalid relocation type");
304 static bool supportsARM(uint64_t Type) {
305 switch (Type) {
306 case ELF::R_ARM_ABS32:
307 case ELF::R_ARM_REL32:
308 return true;
309 default:
310 return false;
314 static uint64_t resolveARM(uint64_t Type, uint64_t Offset, uint64_t S,
315 uint64_t LocData, int64_t Addend) {
316 // Support both RELA and REL relocations. The caller is responsible
317 // for supplying the correct values for LocData and Addend, i.e.
318 // Addend == 0 for REL and LocData == 0 for RELA.
319 assert((LocData == 0 || Addend == 0) &&
320 "one of LocData and Addend must be 0");
321 switch (Type) {
322 case ELF::R_ARM_ABS32:
323 return (S + LocData + Addend) & 0xFFFFFFFF;
324 case ELF::R_ARM_REL32:
325 return (S + LocData + Addend - Offset) & 0xFFFFFFFF;
327 llvm_unreachable("Invalid relocation type");
330 static bool supportsAVR(uint64_t Type) {
331 switch (Type) {
332 case ELF::R_AVR_16:
333 case ELF::R_AVR_32:
334 return true;
335 default:
336 return false;
340 static uint64_t resolveAVR(uint64_t Type, uint64_t Offset, uint64_t S,
341 uint64_t /*LocData*/, int64_t Addend) {
342 switch (Type) {
343 case ELF::R_AVR_16:
344 return (S + Addend) & 0xFFFF;
345 case ELF::R_AVR_32:
346 return (S + Addend) & 0xFFFFFFFF;
347 default:
348 llvm_unreachable("Invalid relocation type");
352 static bool supportsLanai(uint64_t Type) {
353 return Type == ELF::R_LANAI_32;
356 static uint64_t resolveLanai(uint64_t Type, uint64_t Offset, uint64_t S,
357 uint64_t /*LocData*/, int64_t Addend) {
358 if (Type == ELF::R_LANAI_32)
359 return (S + Addend) & 0xFFFFFFFF;
360 llvm_unreachable("Invalid relocation type");
363 static bool supportsMips32(uint64_t Type) {
364 switch (Type) {
365 case ELF::R_MIPS_32:
366 case ELF::R_MIPS_TLS_DTPREL32:
367 return true;
368 default:
369 return false;
373 static uint64_t resolveMips32(uint64_t Type, uint64_t Offset, uint64_t S,
374 uint64_t LocData, int64_t /*Addend*/) {
375 // FIXME: Take in account implicit addends to get correct results.
376 if (Type == ELF::R_MIPS_32)
377 return (S + LocData) & 0xFFFFFFFF;
378 if (Type == ELF::R_MIPS_TLS_DTPREL32)
379 return (S + LocData) & 0xFFFFFFFF;
380 llvm_unreachable("Invalid relocation type");
383 static bool supportsSparc32(uint64_t Type) {
384 switch (Type) {
385 case ELF::R_SPARC_32:
386 case ELF::R_SPARC_UA32:
387 return true;
388 default:
389 return false;
393 static uint64_t resolveSparc32(uint64_t Type, uint64_t Offset, uint64_t S,
394 uint64_t LocData, int64_t Addend) {
395 if (Type == ELF::R_SPARC_32 || Type == ELF::R_SPARC_UA32)
396 return S + Addend;
397 return LocData;
400 static bool supportsHexagon(uint64_t Type) {
401 return Type == ELF::R_HEX_32;
404 static uint64_t resolveHexagon(uint64_t Type, uint64_t Offset, uint64_t S,
405 uint64_t /*LocData*/, int64_t Addend) {
406 if (Type == ELF::R_HEX_32)
407 return S + Addend;
408 llvm_unreachable("Invalid relocation type");
411 static bool supportsRISCV(uint64_t Type) {
412 switch (Type) {
413 case ELF::R_RISCV_NONE:
414 case ELF::R_RISCV_32:
415 case ELF::R_RISCV_32_PCREL:
416 case ELF::R_RISCV_64:
417 case ELF::R_RISCV_SET6:
418 case ELF::R_RISCV_SUB6:
419 case ELF::R_RISCV_ADD8:
420 case ELF::R_RISCV_SUB8:
421 case ELF::R_RISCV_ADD16:
422 case ELF::R_RISCV_SUB16:
423 case ELF::R_RISCV_ADD32:
424 case ELF::R_RISCV_SUB32:
425 case ELF::R_RISCV_ADD64:
426 case ELF::R_RISCV_SUB64:
427 return true;
428 default:
429 return false;
433 static uint64_t resolveRISCV(uint64_t Type, uint64_t Offset, uint64_t S,
434 uint64_t LocData, int64_t Addend) {
435 int64_t RA = Addend;
436 uint64_t A = LocData;
437 switch (Type) {
438 case ELF::R_RISCV_NONE:
439 return LocData;
440 case ELF::R_RISCV_32:
441 return (S + RA) & 0xFFFFFFFF;
442 case ELF::R_RISCV_32_PCREL:
443 return (S + RA - Offset) & 0xFFFFFFFF;
444 case ELF::R_RISCV_64:
445 return S + RA;
446 case ELF::R_RISCV_SET6:
447 return (A & 0xC0) | ((S + RA) & 0x3F);
448 case ELF::R_RISCV_SUB6:
449 return (A & 0xC0) | (((A & 0x3F) - (S + RA)) & 0x3F);
450 case ELF::R_RISCV_ADD8:
451 return (A + (S + RA)) & 0xFF;
452 case ELF::R_RISCV_SUB8:
453 return (A - (S + RA)) & 0xFF;
454 case ELF::R_RISCV_ADD16:
455 return (A + (S + RA)) & 0xFFFF;
456 case ELF::R_RISCV_SUB16:
457 return (A - (S + RA)) & 0xFFFF;
458 case ELF::R_RISCV_ADD32:
459 return (A + (S + RA)) & 0xFFFFFFFF;
460 case ELF::R_RISCV_SUB32:
461 return (A - (S + RA)) & 0xFFFFFFFF;
462 case ELF::R_RISCV_ADD64:
463 return (A + (S + RA));
464 case ELF::R_RISCV_SUB64:
465 return (A - (S + RA));
466 default:
467 llvm_unreachable("Invalid relocation type");
471 static bool supportsCOFFX86(uint64_t Type) {
472 switch (Type) {
473 case COFF::IMAGE_REL_I386_SECREL:
474 case COFF::IMAGE_REL_I386_DIR32:
475 return true;
476 default:
477 return false;
481 static uint64_t resolveCOFFX86(uint64_t Type, uint64_t Offset, uint64_t S,
482 uint64_t LocData, int64_t /*Addend*/) {
483 switch (Type) {
484 case COFF::IMAGE_REL_I386_SECREL:
485 case COFF::IMAGE_REL_I386_DIR32:
486 return (S + LocData) & 0xFFFFFFFF;
487 default:
488 llvm_unreachable("Invalid relocation type");
492 static bool supportsCOFFX86_64(uint64_t Type) {
493 switch (Type) {
494 case COFF::IMAGE_REL_AMD64_SECREL:
495 case COFF::IMAGE_REL_AMD64_ADDR64:
496 return true;
497 default:
498 return false;
502 static uint64_t resolveCOFFX86_64(uint64_t Type, uint64_t Offset, uint64_t S,
503 uint64_t LocData, int64_t /*Addend*/) {
504 switch (Type) {
505 case COFF::IMAGE_REL_AMD64_SECREL:
506 return (S + LocData) & 0xFFFFFFFF;
507 case COFF::IMAGE_REL_AMD64_ADDR64:
508 return S + LocData;
509 default:
510 llvm_unreachable("Invalid relocation type");
514 static bool supportsCOFFARM(uint64_t Type) {
515 switch (Type) {
516 case COFF::IMAGE_REL_ARM_SECREL:
517 case COFF::IMAGE_REL_ARM_ADDR32:
518 return true;
519 default:
520 return false;
524 static uint64_t resolveCOFFARM(uint64_t Type, uint64_t Offset, uint64_t S,
525 uint64_t LocData, int64_t /*Addend*/) {
526 switch (Type) {
527 case COFF::IMAGE_REL_ARM_SECREL:
528 case COFF::IMAGE_REL_ARM_ADDR32:
529 return (S + LocData) & 0xFFFFFFFF;
530 default:
531 llvm_unreachable("Invalid relocation type");
535 static bool supportsCOFFARM64(uint64_t Type) {
536 switch (Type) {
537 case COFF::IMAGE_REL_ARM64_SECREL:
538 case COFF::IMAGE_REL_ARM64_ADDR64:
539 return true;
540 default:
541 return false;
545 static uint64_t resolveCOFFARM64(uint64_t Type, uint64_t Offset, uint64_t S,
546 uint64_t LocData, int64_t /*Addend*/) {
547 switch (Type) {
548 case COFF::IMAGE_REL_ARM64_SECREL:
549 return (S + LocData) & 0xFFFFFFFF;
550 case COFF::IMAGE_REL_ARM64_ADDR64:
551 return S + LocData;
552 default:
553 llvm_unreachable("Invalid relocation type");
557 static bool supportsMachOX86_64(uint64_t Type) {
558 return Type == MachO::X86_64_RELOC_UNSIGNED;
561 static uint64_t resolveMachOX86_64(uint64_t Type, uint64_t Offset, uint64_t S,
562 uint64_t LocData, int64_t /*Addend*/) {
563 if (Type == MachO::X86_64_RELOC_UNSIGNED)
564 return S;
565 llvm_unreachable("Invalid relocation type");
568 static bool supportsWasm32(uint64_t Type) {
569 switch (Type) {
570 case wasm::R_WASM_FUNCTION_INDEX_LEB:
571 case wasm::R_WASM_TABLE_INDEX_SLEB:
572 case wasm::R_WASM_TABLE_INDEX_I32:
573 case wasm::R_WASM_MEMORY_ADDR_LEB:
574 case wasm::R_WASM_MEMORY_ADDR_SLEB:
575 case wasm::R_WASM_MEMORY_ADDR_I32:
576 case wasm::R_WASM_TYPE_INDEX_LEB:
577 case wasm::R_WASM_GLOBAL_INDEX_LEB:
578 case wasm::R_WASM_FUNCTION_OFFSET_I32:
579 case wasm::R_WASM_SECTION_OFFSET_I32:
580 case wasm::R_WASM_TAG_INDEX_LEB:
581 case wasm::R_WASM_GLOBAL_INDEX_I32:
582 case wasm::R_WASM_TABLE_NUMBER_LEB:
583 case wasm::R_WASM_MEMORY_ADDR_LOCREL_I32:
584 return true;
585 default:
586 return false;
590 static bool supportsWasm64(uint64_t Type) {
591 switch (Type) {
592 case wasm::R_WASM_MEMORY_ADDR_LEB64:
593 case wasm::R_WASM_MEMORY_ADDR_SLEB64:
594 case wasm::R_WASM_MEMORY_ADDR_I64:
595 case wasm::R_WASM_TABLE_INDEX_SLEB64:
596 case wasm::R_WASM_TABLE_INDEX_I64:
597 case wasm::R_WASM_FUNCTION_OFFSET_I64:
598 return true;
599 default:
600 return supportsWasm32(Type);
604 static uint64_t resolveWasm32(uint64_t Type, uint64_t Offset, uint64_t S,
605 uint64_t LocData, int64_t /*Addend*/) {
606 switch (Type) {
607 case wasm::R_WASM_FUNCTION_INDEX_LEB:
608 case wasm::R_WASM_TABLE_INDEX_SLEB:
609 case wasm::R_WASM_TABLE_INDEX_I32:
610 case wasm::R_WASM_MEMORY_ADDR_LEB:
611 case wasm::R_WASM_MEMORY_ADDR_SLEB:
612 case wasm::R_WASM_MEMORY_ADDR_I32:
613 case wasm::R_WASM_TYPE_INDEX_LEB:
614 case wasm::R_WASM_GLOBAL_INDEX_LEB:
615 case wasm::R_WASM_FUNCTION_OFFSET_I32:
616 case wasm::R_WASM_SECTION_OFFSET_I32:
617 case wasm::R_WASM_TAG_INDEX_LEB:
618 case wasm::R_WASM_GLOBAL_INDEX_I32:
619 case wasm::R_WASM_TABLE_NUMBER_LEB:
620 case wasm::R_WASM_MEMORY_ADDR_LOCREL_I32:
621 // For wasm section, its offset at 0 -- ignoring Value
622 return LocData;
623 default:
624 llvm_unreachable("Invalid relocation type");
628 static uint64_t resolveWasm64(uint64_t Type, uint64_t Offset, uint64_t S,
629 uint64_t LocData, int64_t Addend) {
630 switch (Type) {
631 case wasm::R_WASM_MEMORY_ADDR_LEB64:
632 case wasm::R_WASM_MEMORY_ADDR_SLEB64:
633 case wasm::R_WASM_MEMORY_ADDR_I64:
634 case wasm::R_WASM_TABLE_INDEX_SLEB64:
635 case wasm::R_WASM_TABLE_INDEX_I64:
636 case wasm::R_WASM_FUNCTION_OFFSET_I64:
637 // For wasm section, its offset at 0 -- ignoring Value
638 return LocData;
639 default:
640 return resolveWasm32(Type, Offset, S, LocData, Addend);
644 std::pair<SupportsRelocation, RelocationResolver>
645 getRelocationResolver(const ObjectFile &Obj) {
646 if (Obj.isCOFF()) {
647 switch (Obj.getArch()) {
648 case Triple::x86_64:
649 return {supportsCOFFX86_64, resolveCOFFX86_64};
650 case Triple::x86:
651 return {supportsCOFFX86, resolveCOFFX86};
652 case Triple::arm:
653 case Triple::thumb:
654 return {supportsCOFFARM, resolveCOFFARM};
655 case Triple::aarch64:
656 return {supportsCOFFARM64, resolveCOFFARM64};
657 default:
658 return {nullptr, nullptr};
660 } else if (Obj.isELF()) {
661 if (Obj.getBytesInAddress() == 8) {
662 switch (Obj.getArch()) {
663 case Triple::x86_64:
664 return {supportsX86_64, resolveX86_64};
665 case Triple::aarch64:
666 case Triple::aarch64_be:
667 return {supportsAArch64, resolveAArch64};
668 case Triple::bpfel:
669 case Triple::bpfeb:
670 return {supportsBPF, resolveBPF};
671 case Triple::mips64el:
672 case Triple::mips64:
673 return {supportsMips64, resolveMips64};
674 case Triple::ppc64le:
675 case Triple::ppc64:
676 return {supportsPPC64, resolvePPC64};
677 case Triple::systemz:
678 return {supportsSystemZ, resolveSystemZ};
679 case Triple::sparcv9:
680 return {supportsSparc64, resolveSparc64};
681 case Triple::amdgcn:
682 return {supportsAmdgpu, resolveAmdgpu};
683 case Triple::riscv64:
684 return {supportsRISCV, resolveRISCV};
685 default:
686 return {nullptr, nullptr};
690 // 32-bit object file
691 assert(Obj.getBytesInAddress() == 4 &&
692 "Invalid word size in object file");
694 switch (Obj.getArch()) {
695 case Triple::x86:
696 return {supportsX86, resolveX86};
697 case Triple::ppcle:
698 case Triple::ppc:
699 return {supportsPPC32, resolvePPC32};
700 case Triple::arm:
701 case Triple::armeb:
702 return {supportsARM, resolveARM};
703 case Triple::avr:
704 return {supportsAVR, resolveAVR};
705 case Triple::lanai:
706 return {supportsLanai, resolveLanai};
707 case Triple::mipsel:
708 case Triple::mips:
709 return {supportsMips32, resolveMips32};
710 case Triple::msp430:
711 return {supportsMSP430, resolveMSP430};
712 case Triple::sparc:
713 return {supportsSparc32, resolveSparc32};
714 case Triple::hexagon:
715 return {supportsHexagon, resolveHexagon};
716 case Triple::riscv32:
717 return {supportsRISCV, resolveRISCV};
718 default:
719 return {nullptr, nullptr};
721 } else if (Obj.isMachO()) {
722 if (Obj.getArch() == Triple::x86_64)
723 return {supportsMachOX86_64, resolveMachOX86_64};
724 return {nullptr, nullptr};
725 } else if (Obj.isWasm()) {
726 if (Obj.getArch() == Triple::wasm32)
727 return {supportsWasm32, resolveWasm32};
728 if (Obj.getArch() == Triple::wasm64)
729 return {supportsWasm64, resolveWasm64};
730 return {nullptr, nullptr};
733 llvm_unreachable("Invalid object file");
736 uint64_t resolveRelocation(RelocationResolver Resolver, const RelocationRef &R,
737 uint64_t S, uint64_t LocData) {
738 if (const ObjectFile *Obj = R.getObject()) {
739 int64_t Addend = 0;
740 if (Obj->isELF()) {
741 auto GetRelSectionType = [&]() -> unsigned {
742 if (auto *Elf32LEObj = dyn_cast<ELF32LEObjectFile>(Obj))
743 return Elf32LEObj->getRelSection(R.getRawDataRefImpl())->sh_type;
744 if (auto *Elf64LEObj = dyn_cast<ELF64LEObjectFile>(Obj))
745 return Elf64LEObj->getRelSection(R.getRawDataRefImpl())->sh_type;
746 if (auto *Elf32BEObj = dyn_cast<ELF32BEObjectFile>(Obj))
747 return Elf32BEObj->getRelSection(R.getRawDataRefImpl())->sh_type;
748 auto *Elf64BEObj = cast<ELF64BEObjectFile>(Obj);
749 return Elf64BEObj->getRelSection(R.getRawDataRefImpl())->sh_type;
752 if (GetRelSectionType() == ELF::SHT_RELA) {
753 Addend = getELFAddend(R);
754 // RISCV relocations use both LocData and Addend.
755 if (Obj->getArch() != Triple::riscv32 &&
756 Obj->getArch() != Triple::riscv64)
757 LocData = 0;
761 return Resolver(R.getType(), R.getOffset(), S, LocData, Addend);
764 // Sometimes the caller might want to use its own specific implementation of
765 // the resolver function. E.g. this is used by LLD when it resolves debug
766 // relocations and assumes that all of them have the same computation (S + A).
767 // The relocation R has no owner object in this case and we don't need to
768 // provide Type and Offset fields. It is also assumed the DataRefImpl.p
769 // contains the addend, provided by the caller.
770 return Resolver(/*Type=*/0, /*Offset=*/0, S, LocData,
771 R.getRawDataRefImpl().p);
774 } // namespace object
775 } // namespace llvm