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"
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());
26 static bool supportsX86_64(uint64_t 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
:
42 static uint64_t resolveX86_64(uint64_t Type
, uint64_t Offset
, uint64_t S
,
43 uint64_t LocData
, int64_t Addend
) {
45 case ELF::R_X86_64_NONE
:
47 case ELF::R_X86_64_64
:
48 case ELF::R_X86_64_DTPOFF32
:
49 case ELF::R_X86_64_DTPOFF64
:
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;
58 llvm_unreachable("Invalid relocation type");
62 static bool supportsAArch64(uint64_t 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
:
74 static uint64_t resolveAArch64(uint64_t Type
, uint64_t Offset
, uint64_t S
,
75 uint64_t /*LocData*/, int64_t Addend
) {
77 case ELF::R_AARCH64_ABS32
:
78 return (S
+ Addend
) & 0xFFFFFFFF;
79 case ELF::R_AARCH64_ABS64
:
81 case ELF::R_AARCH64_PREL32
:
82 return (S
+ Addend
- Offset
) & 0xFFFFFFFF;
83 case ELF::R_AARCH64_PREL64
:
84 return S
+ Addend
- Offset
;
86 llvm_unreachable("Invalid relocation type");
90 static bool supportsBPF(uint64_t Type
) {
92 case ELF::R_BPF_64_ABS32
:
93 case ELF::R_BPF_64_ABS64
:
100 static uint64_t resolveBPF(uint64_t Type
, uint64_t Offset
, uint64_t S
,
101 uint64_t LocData
, int64_t /*Addend*/) {
103 case ELF::R_BPF_64_ABS32
:
104 return (S
+ LocData
) & 0xFFFFFFFF;
105 case ELF::R_BPF_64_ABS64
:
108 llvm_unreachable("Invalid relocation type");
112 static bool supportsMips64(uint64_t Type
) {
116 case ELF::R_MIPS_TLS_DTPREL64
:
117 case ELF::R_MIPS_PC32
:
124 static uint64_t resolveMips64(uint64_t Type
, uint64_t Offset
, uint64_t S
,
125 uint64_t /*LocData*/, int64_t Addend
) {
128 return (S
+ Addend
) & 0xFFFFFFFF;
131 case ELF::R_MIPS_TLS_DTPREL64
:
132 return S
+ Addend
- 0x8000;
133 case ELF::R_MIPS_PC32
:
134 return S
+ Addend
- Offset
;
136 llvm_unreachable("Invalid relocation type");
140 static bool supportsMSP430(uint64_t Type
) {
142 case ELF::R_MSP430_32
:
143 case ELF::R_MSP430_16_BYTE
:
150 static uint64_t resolveMSP430(uint64_t Type
, uint64_t Offset
, uint64_t S
,
151 uint64_t /*LocData*/, int64_t Addend
) {
153 case ELF::R_MSP430_32
:
154 return (S
+ Addend
) & 0xFFFFFFFF;
155 case ELF::R_MSP430_16_BYTE
:
156 return (S
+ Addend
) & 0xFFFF;
158 llvm_unreachable("Invalid relocation type");
162 static bool supportsPPC64(uint64_t 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
:
174 static uint64_t resolvePPC64(uint64_t Type
, uint64_t Offset
, uint64_t S
,
175 uint64_t /*LocData*/, int64_t Addend
) {
177 case ELF::R_PPC64_ADDR32
:
178 return (S
+ Addend
) & 0xFFFFFFFF;
179 case ELF::R_PPC64_ADDR64
:
181 case ELF::R_PPC64_REL32
:
182 return (S
+ Addend
- Offset
) & 0xFFFFFFFF;
183 case ELF::R_PPC64_REL64
:
184 return S
+ Addend
- Offset
;
186 llvm_unreachable("Invalid relocation type");
190 static bool supportsSystemZ(uint64_t Type
) {
200 static uint64_t resolveSystemZ(uint64_t Type
, uint64_t Offset
, uint64_t S
,
201 uint64_t /*LocData*/, int64_t Addend
) {
204 return (S
+ Addend
) & 0xFFFFFFFF;
208 llvm_unreachable("Invalid relocation type");
212 static bool supportsSparc64(uint64_t 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
:
224 static uint64_t resolveSparc64(uint64_t Type
, uint64_t Offset
, uint64_t S
,
225 uint64_t /*LocData*/, int64_t Addend
) {
227 case ELF::R_SPARC_32
:
228 case ELF::R_SPARC_64
:
229 case ELF::R_SPARC_UA32
:
230 case ELF::R_SPARC_UA64
:
233 llvm_unreachable("Invalid relocation type");
237 static bool supportsAmdgpu(uint64_t Type
) {
239 case ELF::R_AMDGPU_ABS32
:
240 case ELF::R_AMDGPU_ABS64
:
247 static uint64_t resolveAmdgpu(uint64_t Type
, uint64_t Offset
, uint64_t S
,
248 uint64_t /*LocData*/, int64_t Addend
) {
250 case ELF::R_AMDGPU_ABS32
:
251 case ELF::R_AMDGPU_ABS64
:
254 llvm_unreachable("Invalid relocation type");
258 static bool supportsX86(uint64_t Type
) {
260 case ELF::R_386_NONE
:
262 case ELF::R_386_PC32
:
269 static uint64_t resolveX86(uint64_t Type
, uint64_t Offset
, uint64_t S
,
270 uint64_t LocData
, int64_t /*Addend*/) {
272 case ELF::R_386_NONE
:
276 case ELF::R_386_PC32
:
277 return S
- Offset
+ LocData
;
279 llvm_unreachable("Invalid relocation type");
283 static bool supportsPPC32(uint64_t Type
) {
285 case ELF::R_PPC_ADDR32
:
286 case ELF::R_PPC_REL32
:
293 static uint64_t resolvePPC32(uint64_t Type
, uint64_t Offset
, uint64_t S
,
294 uint64_t /*LocData*/, int64_t Addend
) {
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
) {
306 case ELF::R_ARM_ABS32
:
307 case ELF::R_ARM_REL32
:
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");
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
) {
340 static uint64_t resolveAVR(uint64_t Type
, uint64_t Offset
, uint64_t S
,
341 uint64_t /*LocData*/, int64_t Addend
) {
344 return (S
+ Addend
) & 0xFFFF;
346 return (S
+ Addend
) & 0xFFFFFFFF;
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
) {
366 case ELF::R_MIPS_TLS_DTPREL32
:
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
) {
385 case ELF::R_SPARC_32
:
386 case ELF::R_SPARC_UA32
:
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
)
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
)
408 llvm_unreachable("Invalid relocation type");
411 static bool supportsRISCV(uint64_t 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
:
433 static uint64_t resolveRISCV(uint64_t Type
, uint64_t Offset
, uint64_t S
,
434 uint64_t LocData
, int64_t Addend
) {
436 uint64_t A
= LocData
;
438 case ELF::R_RISCV_NONE
:
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
:
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
));
467 llvm_unreachable("Invalid relocation type");
471 static bool supportsCOFFX86(uint64_t Type
) {
473 case COFF::IMAGE_REL_I386_SECREL
:
474 case COFF::IMAGE_REL_I386_DIR32
:
481 static uint64_t resolveCOFFX86(uint64_t Type
, uint64_t Offset
, uint64_t S
,
482 uint64_t LocData
, int64_t /*Addend*/) {
484 case COFF::IMAGE_REL_I386_SECREL
:
485 case COFF::IMAGE_REL_I386_DIR32
:
486 return (S
+ LocData
) & 0xFFFFFFFF;
488 llvm_unreachable("Invalid relocation type");
492 static bool supportsCOFFX86_64(uint64_t Type
) {
494 case COFF::IMAGE_REL_AMD64_SECREL
:
495 case COFF::IMAGE_REL_AMD64_ADDR64
:
502 static uint64_t resolveCOFFX86_64(uint64_t Type
, uint64_t Offset
, uint64_t S
,
503 uint64_t LocData
, int64_t /*Addend*/) {
505 case COFF::IMAGE_REL_AMD64_SECREL
:
506 return (S
+ LocData
) & 0xFFFFFFFF;
507 case COFF::IMAGE_REL_AMD64_ADDR64
:
510 llvm_unreachable("Invalid relocation type");
514 static bool supportsCOFFARM(uint64_t Type
) {
516 case COFF::IMAGE_REL_ARM_SECREL
:
517 case COFF::IMAGE_REL_ARM_ADDR32
:
524 static uint64_t resolveCOFFARM(uint64_t Type
, uint64_t Offset
, uint64_t S
,
525 uint64_t LocData
, int64_t /*Addend*/) {
527 case COFF::IMAGE_REL_ARM_SECREL
:
528 case COFF::IMAGE_REL_ARM_ADDR32
:
529 return (S
+ LocData
) & 0xFFFFFFFF;
531 llvm_unreachable("Invalid relocation type");
535 static bool supportsCOFFARM64(uint64_t Type
) {
537 case COFF::IMAGE_REL_ARM64_SECREL
:
538 case COFF::IMAGE_REL_ARM64_ADDR64
:
545 static uint64_t resolveCOFFARM64(uint64_t Type
, uint64_t Offset
, uint64_t S
,
546 uint64_t LocData
, int64_t /*Addend*/) {
548 case COFF::IMAGE_REL_ARM64_SECREL
:
549 return (S
+ LocData
) & 0xFFFFFFFF;
550 case COFF::IMAGE_REL_ARM64_ADDR64
:
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
)
565 llvm_unreachable("Invalid relocation type");
568 static bool supportsWasm32(uint64_t 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
:
590 static bool supportsWasm64(uint64_t 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
:
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*/) {
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
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
) {
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
640 return resolveWasm32(Type
, Offset
, S
, LocData
, Addend
);
644 std::pair
<SupportsRelocation
, RelocationResolver
>
645 getRelocationResolver(const ObjectFile
&Obj
) {
647 switch (Obj
.getArch()) {
649 return {supportsCOFFX86_64
, resolveCOFFX86_64
};
651 return {supportsCOFFX86
, resolveCOFFX86
};
654 return {supportsCOFFARM
, resolveCOFFARM
};
655 case Triple::aarch64
:
656 return {supportsCOFFARM64
, resolveCOFFARM64
};
658 return {nullptr, nullptr};
660 } else if (Obj
.isELF()) {
661 if (Obj
.getBytesInAddress() == 8) {
662 switch (Obj
.getArch()) {
664 return {supportsX86_64
, resolveX86_64
};
665 case Triple::aarch64
:
666 case Triple::aarch64_be
:
667 return {supportsAArch64
, resolveAArch64
};
670 return {supportsBPF
, resolveBPF
};
671 case Triple::mips64el
:
673 return {supportsMips64
, resolveMips64
};
674 case Triple::ppc64le
:
676 return {supportsPPC64
, resolvePPC64
};
677 case Triple::systemz
:
678 return {supportsSystemZ
, resolveSystemZ
};
679 case Triple::sparcv9
:
680 return {supportsSparc64
, resolveSparc64
};
682 return {supportsAmdgpu
, resolveAmdgpu
};
683 case Triple::riscv64
:
684 return {supportsRISCV
, resolveRISCV
};
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()) {
696 return {supportsX86
, resolveX86
};
699 return {supportsPPC32
, resolvePPC32
};
702 return {supportsARM
, resolveARM
};
704 return {supportsAVR
, resolveAVR
};
706 return {supportsLanai
, resolveLanai
};
709 return {supportsMips32
, resolveMips32
};
711 return {supportsMSP430
, resolveMSP430
};
713 return {supportsSparc32
, resolveSparc32
};
714 case Triple::hexagon
:
715 return {supportsHexagon
, resolveHexagon
};
716 case Triple::riscv32
:
717 return {supportsRISCV
, resolveRISCV
};
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()) {
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
)
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