xref: /netbsd-src/external/apache2/llvm/dist/llvm/lib/Object/RelocationResolver.cpp (revision 82d56013d7b633d116a93943de88e08335357a7c)
17330f729Sjoerg //===- RelocationResolver.cpp ------------------------------------*- C++ -*-===//
27330f729Sjoerg //
37330f729Sjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
47330f729Sjoerg // See https://llvm.org/LICENSE.txt for license information.
57330f729Sjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
67330f729Sjoerg //
77330f729Sjoerg //===----------------------------------------------------------------------===//
87330f729Sjoerg //
97330f729Sjoerg // This file defines utilities to resolve relocations in object files.
107330f729Sjoerg //
117330f729Sjoerg //===----------------------------------------------------------------------===//
127330f729Sjoerg 
137330f729Sjoerg #include "llvm/Object/RelocationResolver.h"
147330f729Sjoerg 
157330f729Sjoerg namespace llvm {
167330f729Sjoerg namespace object {
177330f729Sjoerg 
getELFAddend(RelocationRef R)187330f729Sjoerg static int64_t getELFAddend(RelocationRef R) {
197330f729Sjoerg   Expected<int64_t> AddendOrErr = ELFRelocationRef(R).getAddend();
207330f729Sjoerg   handleAllErrors(AddendOrErr.takeError(), [](const ErrorInfoBase &EI) {
217330f729Sjoerg     report_fatal_error(EI.message());
227330f729Sjoerg   });
237330f729Sjoerg   return *AddendOrErr;
247330f729Sjoerg }
257330f729Sjoerg 
supportsX86_64(uint64_t Type)267330f729Sjoerg static bool supportsX86_64(uint64_t Type) {
277330f729Sjoerg   switch (Type) {
287330f729Sjoerg   case ELF::R_X86_64_NONE:
297330f729Sjoerg   case ELF::R_X86_64_64:
307330f729Sjoerg   case ELF::R_X86_64_DTPOFF32:
317330f729Sjoerg   case ELF::R_X86_64_DTPOFF64:
327330f729Sjoerg   case ELF::R_X86_64_PC32:
337330f729Sjoerg   case ELF::R_X86_64_PC64:
347330f729Sjoerg   case ELF::R_X86_64_32:
357330f729Sjoerg   case ELF::R_X86_64_32S:
367330f729Sjoerg     return true;
377330f729Sjoerg   default:
387330f729Sjoerg     return false;
397330f729Sjoerg   }
407330f729Sjoerg }
417330f729Sjoerg 
resolveX86_64(uint64_t Type,uint64_t Offset,uint64_t S,uint64_t LocData,int64_t Addend)42*82d56013Sjoerg static uint64_t resolveX86_64(uint64_t Type, uint64_t Offset, uint64_t S,
43*82d56013Sjoerg                               uint64_t LocData, int64_t Addend) {
44*82d56013Sjoerg   switch (Type) {
457330f729Sjoerg   case ELF::R_X86_64_NONE:
46*82d56013Sjoerg     return LocData;
477330f729Sjoerg   case ELF::R_X86_64_64:
487330f729Sjoerg   case ELF::R_X86_64_DTPOFF32:
497330f729Sjoerg   case ELF::R_X86_64_DTPOFF64:
50*82d56013Sjoerg     return S + Addend;
517330f729Sjoerg   case ELF::R_X86_64_PC32:
527330f729Sjoerg   case ELF::R_X86_64_PC64:
53*82d56013Sjoerg     return S + Addend - Offset;
547330f729Sjoerg   case ELF::R_X86_64_32:
557330f729Sjoerg   case ELF::R_X86_64_32S:
56*82d56013Sjoerg     return (S + Addend) & 0xFFFFFFFF;
577330f729Sjoerg   default:
587330f729Sjoerg     llvm_unreachable("Invalid relocation type");
597330f729Sjoerg   }
607330f729Sjoerg }
617330f729Sjoerg 
supportsAArch64(uint64_t Type)627330f729Sjoerg static bool supportsAArch64(uint64_t Type) {
637330f729Sjoerg   switch (Type) {
647330f729Sjoerg   case ELF::R_AARCH64_ABS32:
657330f729Sjoerg   case ELF::R_AARCH64_ABS64:
66*82d56013Sjoerg   case ELF::R_AARCH64_PREL32:
67*82d56013Sjoerg   case ELF::R_AARCH64_PREL64:
687330f729Sjoerg     return true;
697330f729Sjoerg   default:
707330f729Sjoerg     return false;
717330f729Sjoerg   }
727330f729Sjoerg }
737330f729Sjoerg 
resolveAArch64(uint64_t Type,uint64_t Offset,uint64_t S,uint64_t,int64_t Addend)74*82d56013Sjoerg static uint64_t resolveAArch64(uint64_t Type, uint64_t Offset, uint64_t S,
75*82d56013Sjoerg                                uint64_t /*LocData*/, int64_t Addend) {
76*82d56013Sjoerg   switch (Type) {
777330f729Sjoerg   case ELF::R_AARCH64_ABS32:
78*82d56013Sjoerg     return (S + Addend) & 0xFFFFFFFF;
797330f729Sjoerg   case ELF::R_AARCH64_ABS64:
80*82d56013Sjoerg     return S + Addend;
81*82d56013Sjoerg   case ELF::R_AARCH64_PREL32:
82*82d56013Sjoerg     return (S + Addend - Offset) & 0xFFFFFFFF;
83*82d56013Sjoerg   case ELF::R_AARCH64_PREL64:
84*82d56013Sjoerg     return S + Addend - Offset;
857330f729Sjoerg   default:
867330f729Sjoerg     llvm_unreachable("Invalid relocation type");
877330f729Sjoerg   }
887330f729Sjoerg }
897330f729Sjoerg 
supportsBPF(uint64_t Type)907330f729Sjoerg static bool supportsBPF(uint64_t Type) {
917330f729Sjoerg   switch (Type) {
927330f729Sjoerg   case ELF::R_BPF_64_32:
937330f729Sjoerg   case ELF::R_BPF_64_64:
947330f729Sjoerg     return true;
957330f729Sjoerg   default:
967330f729Sjoerg     return false;
977330f729Sjoerg   }
987330f729Sjoerg }
997330f729Sjoerg 
resolveBPF(uint64_t Type,uint64_t Offset,uint64_t S,uint64_t LocData,int64_t)100*82d56013Sjoerg static uint64_t resolveBPF(uint64_t Type, uint64_t Offset, uint64_t S,
101*82d56013Sjoerg                            uint64_t LocData, int64_t /*Addend*/) {
102*82d56013Sjoerg   switch (Type) {
1037330f729Sjoerg   case ELF::R_BPF_64_32:
104*82d56013Sjoerg     return (S + LocData) & 0xFFFFFFFF;
1057330f729Sjoerg   case ELF::R_BPF_64_64:
106*82d56013Sjoerg     return S + LocData;
1077330f729Sjoerg   default:
1087330f729Sjoerg     llvm_unreachable("Invalid relocation type");
1097330f729Sjoerg   }
1107330f729Sjoerg }
1117330f729Sjoerg 
supportsMips64(uint64_t Type)1127330f729Sjoerg static bool supportsMips64(uint64_t Type) {
1137330f729Sjoerg   switch (Type) {
1147330f729Sjoerg   case ELF::R_MIPS_32:
1157330f729Sjoerg   case ELF::R_MIPS_64:
1167330f729Sjoerg   case ELF::R_MIPS_TLS_DTPREL64:
117*82d56013Sjoerg   case ELF::R_MIPS_PC32:
1187330f729Sjoerg     return true;
1197330f729Sjoerg   default:
1207330f729Sjoerg     return false;
1217330f729Sjoerg   }
1227330f729Sjoerg }
1237330f729Sjoerg 
resolveMips64(uint64_t Type,uint64_t Offset,uint64_t S,uint64_t,int64_t Addend)124*82d56013Sjoerg static uint64_t resolveMips64(uint64_t Type, uint64_t Offset, uint64_t S,
125*82d56013Sjoerg                               uint64_t /*LocData*/, int64_t Addend) {
126*82d56013Sjoerg   switch (Type) {
1277330f729Sjoerg   case ELF::R_MIPS_32:
128*82d56013Sjoerg     return (S + Addend) & 0xFFFFFFFF;
1297330f729Sjoerg   case ELF::R_MIPS_64:
130*82d56013Sjoerg     return S + Addend;
1317330f729Sjoerg   case ELF::R_MIPS_TLS_DTPREL64:
132*82d56013Sjoerg     return S + Addend - 0x8000;
133*82d56013Sjoerg   case ELF::R_MIPS_PC32:
134*82d56013Sjoerg     return S + Addend - Offset;
135*82d56013Sjoerg   default:
136*82d56013Sjoerg     llvm_unreachable("Invalid relocation type");
137*82d56013Sjoerg   }
138*82d56013Sjoerg }
139*82d56013Sjoerg 
supportsMSP430(uint64_t Type)140*82d56013Sjoerg static bool supportsMSP430(uint64_t Type) {
141*82d56013Sjoerg   switch (Type) {
142*82d56013Sjoerg   case ELF::R_MSP430_32:
143*82d56013Sjoerg   case ELF::R_MSP430_16_BYTE:
144*82d56013Sjoerg     return true;
145*82d56013Sjoerg   default:
146*82d56013Sjoerg     return false;
147*82d56013Sjoerg   }
148*82d56013Sjoerg }
149*82d56013Sjoerg 
resolveMSP430(uint64_t Type,uint64_t Offset,uint64_t S,uint64_t,int64_t Addend)150*82d56013Sjoerg static uint64_t resolveMSP430(uint64_t Type, uint64_t Offset, uint64_t S,
151*82d56013Sjoerg                               uint64_t /*LocData*/, int64_t Addend) {
152*82d56013Sjoerg   switch (Type) {
153*82d56013Sjoerg   case ELF::R_MSP430_32:
154*82d56013Sjoerg     return (S + Addend) & 0xFFFFFFFF;
155*82d56013Sjoerg   case ELF::R_MSP430_16_BYTE:
156*82d56013Sjoerg     return (S + Addend) & 0xFFFF;
1577330f729Sjoerg   default:
1587330f729Sjoerg     llvm_unreachable("Invalid relocation type");
1597330f729Sjoerg   }
1607330f729Sjoerg }
1617330f729Sjoerg 
supportsPPC64(uint64_t Type)1627330f729Sjoerg static bool supportsPPC64(uint64_t Type) {
1637330f729Sjoerg   switch (Type) {
1647330f729Sjoerg   case ELF::R_PPC64_ADDR32:
1657330f729Sjoerg   case ELF::R_PPC64_ADDR64:
166*82d56013Sjoerg   case ELF::R_PPC64_REL32:
167*82d56013Sjoerg   case ELF::R_PPC64_REL64:
1687330f729Sjoerg     return true;
1697330f729Sjoerg   default:
1707330f729Sjoerg     return false;
1717330f729Sjoerg   }
1727330f729Sjoerg }
1737330f729Sjoerg 
resolvePPC64(uint64_t Type,uint64_t Offset,uint64_t S,uint64_t,int64_t Addend)174*82d56013Sjoerg static uint64_t resolvePPC64(uint64_t Type, uint64_t Offset, uint64_t S,
175*82d56013Sjoerg                              uint64_t /*LocData*/, int64_t Addend) {
176*82d56013Sjoerg   switch (Type) {
1777330f729Sjoerg   case ELF::R_PPC64_ADDR32:
178*82d56013Sjoerg     return (S + Addend) & 0xFFFFFFFF;
1797330f729Sjoerg   case ELF::R_PPC64_ADDR64:
180*82d56013Sjoerg     return S + Addend;
181*82d56013Sjoerg   case ELF::R_PPC64_REL32:
182*82d56013Sjoerg     return (S + Addend - Offset) & 0xFFFFFFFF;
183*82d56013Sjoerg   case ELF::R_PPC64_REL64:
184*82d56013Sjoerg     return S + Addend - Offset;
1857330f729Sjoerg   default:
1867330f729Sjoerg     llvm_unreachable("Invalid relocation type");
1877330f729Sjoerg   }
1887330f729Sjoerg }
1897330f729Sjoerg 
supportsSystemZ(uint64_t Type)1907330f729Sjoerg static bool supportsSystemZ(uint64_t Type) {
1917330f729Sjoerg   switch (Type) {
1927330f729Sjoerg   case ELF::R_390_32:
1937330f729Sjoerg   case ELF::R_390_64:
1947330f729Sjoerg     return true;
1957330f729Sjoerg   default:
1967330f729Sjoerg     return false;
1977330f729Sjoerg   }
1987330f729Sjoerg }
1997330f729Sjoerg 
resolveSystemZ(uint64_t Type,uint64_t Offset,uint64_t S,uint64_t,int64_t Addend)200*82d56013Sjoerg static uint64_t resolveSystemZ(uint64_t Type, uint64_t Offset, uint64_t S,
201*82d56013Sjoerg                                uint64_t /*LocData*/, int64_t Addend) {
202*82d56013Sjoerg   switch (Type) {
2037330f729Sjoerg   case ELF::R_390_32:
204*82d56013Sjoerg     return (S + Addend) & 0xFFFFFFFF;
2057330f729Sjoerg   case ELF::R_390_64:
206*82d56013Sjoerg     return S + Addend;
2077330f729Sjoerg   default:
2087330f729Sjoerg     llvm_unreachable("Invalid relocation type");
2097330f729Sjoerg   }
2107330f729Sjoerg }
2117330f729Sjoerg 
supportsSparc64(uint64_t Type)2127330f729Sjoerg static bool supportsSparc64(uint64_t Type) {
2137330f729Sjoerg   switch (Type) {
2147330f729Sjoerg   case ELF::R_SPARC_32:
2157330f729Sjoerg   case ELF::R_SPARC_64:
2167330f729Sjoerg   case ELF::R_SPARC_UA32:
2177330f729Sjoerg   case ELF::R_SPARC_UA64:
2187330f729Sjoerg     return true;
2197330f729Sjoerg   default:
2207330f729Sjoerg     return false;
2217330f729Sjoerg   }
2227330f729Sjoerg }
2237330f729Sjoerg 
resolveSparc64(uint64_t Type,uint64_t Offset,uint64_t S,uint64_t,int64_t Addend)224*82d56013Sjoerg static uint64_t resolveSparc64(uint64_t Type, uint64_t Offset, uint64_t S,
225*82d56013Sjoerg                                uint64_t /*LocData*/, int64_t Addend) {
226*82d56013Sjoerg   switch (Type) {
2277330f729Sjoerg   case ELF::R_SPARC_32:
2287330f729Sjoerg   case ELF::R_SPARC_64:
2297330f729Sjoerg   case ELF::R_SPARC_UA32:
2307330f729Sjoerg   case ELF::R_SPARC_UA64:
231*82d56013Sjoerg     return S + Addend;
2327330f729Sjoerg   default:
2337330f729Sjoerg     llvm_unreachable("Invalid relocation type");
2347330f729Sjoerg   }
2357330f729Sjoerg }
2367330f729Sjoerg 
supportsAmdgpu(uint64_t Type)2377330f729Sjoerg static bool supportsAmdgpu(uint64_t Type) {
2387330f729Sjoerg   switch (Type) {
2397330f729Sjoerg   case ELF::R_AMDGPU_ABS32:
2407330f729Sjoerg   case ELF::R_AMDGPU_ABS64:
2417330f729Sjoerg     return true;
2427330f729Sjoerg   default:
2437330f729Sjoerg     return false;
2447330f729Sjoerg   }
2457330f729Sjoerg }
2467330f729Sjoerg 
resolveAmdgpu(uint64_t Type,uint64_t Offset,uint64_t S,uint64_t,int64_t Addend)247*82d56013Sjoerg static uint64_t resolveAmdgpu(uint64_t Type, uint64_t Offset, uint64_t S,
248*82d56013Sjoerg                               uint64_t /*LocData*/, int64_t Addend) {
249*82d56013Sjoerg   switch (Type) {
2507330f729Sjoerg   case ELF::R_AMDGPU_ABS32:
2517330f729Sjoerg   case ELF::R_AMDGPU_ABS64:
252*82d56013Sjoerg     return S + Addend;
2537330f729Sjoerg   default:
2547330f729Sjoerg     llvm_unreachable("Invalid relocation type");
2557330f729Sjoerg   }
2567330f729Sjoerg }
2577330f729Sjoerg 
supportsX86(uint64_t Type)2587330f729Sjoerg static bool supportsX86(uint64_t Type) {
2597330f729Sjoerg   switch (Type) {
2607330f729Sjoerg   case ELF::R_386_NONE:
2617330f729Sjoerg   case ELF::R_386_32:
2627330f729Sjoerg   case ELF::R_386_PC32:
2637330f729Sjoerg     return true;
2647330f729Sjoerg   default:
2657330f729Sjoerg     return false;
2667330f729Sjoerg   }
2677330f729Sjoerg }
2687330f729Sjoerg 
resolveX86(uint64_t Type,uint64_t Offset,uint64_t S,uint64_t LocData,int64_t)269*82d56013Sjoerg static uint64_t resolveX86(uint64_t Type, uint64_t Offset, uint64_t S,
270*82d56013Sjoerg                            uint64_t LocData, int64_t /*Addend*/) {
271*82d56013Sjoerg   switch (Type) {
2727330f729Sjoerg   case ELF::R_386_NONE:
273*82d56013Sjoerg     return LocData;
2747330f729Sjoerg   case ELF::R_386_32:
275*82d56013Sjoerg     return S + LocData;
2767330f729Sjoerg   case ELF::R_386_PC32:
277*82d56013Sjoerg     return S - Offset + LocData;
2787330f729Sjoerg   default:
2797330f729Sjoerg     llvm_unreachable("Invalid relocation type");
2807330f729Sjoerg   }
2817330f729Sjoerg }
2827330f729Sjoerg 
supportsPPC32(uint64_t Type)2837330f729Sjoerg static bool supportsPPC32(uint64_t Type) {
284*82d56013Sjoerg   switch (Type) {
285*82d56013Sjoerg   case ELF::R_PPC_ADDR32:
286*82d56013Sjoerg   case ELF::R_PPC_REL32:
287*82d56013Sjoerg     return true;
288*82d56013Sjoerg   default:
289*82d56013Sjoerg     return false;
290*82d56013Sjoerg   }
2917330f729Sjoerg }
2927330f729Sjoerg 
resolvePPC32(uint64_t Type,uint64_t Offset,uint64_t S,uint64_t,int64_t Addend)293*82d56013Sjoerg static uint64_t resolvePPC32(uint64_t Type, uint64_t Offset, uint64_t S,
294*82d56013Sjoerg                              uint64_t /*LocData*/, int64_t Addend) {
295*82d56013Sjoerg   switch (Type) {
296*82d56013Sjoerg   case ELF::R_PPC_ADDR32:
297*82d56013Sjoerg     return (S + Addend) & 0xFFFFFFFF;
298*82d56013Sjoerg   case ELF::R_PPC_REL32:
299*82d56013Sjoerg     return (S + Addend - Offset) & 0xFFFFFFFF;
300*82d56013Sjoerg   }
3017330f729Sjoerg   llvm_unreachable("Invalid relocation type");
3027330f729Sjoerg }
3037330f729Sjoerg 
supportsARM(uint64_t Type)3047330f729Sjoerg static bool supportsARM(uint64_t Type) {
305*82d56013Sjoerg   switch (Type) {
306*82d56013Sjoerg   case ELF::R_ARM_ABS32:
307*82d56013Sjoerg   case ELF::R_ARM_REL32:
308*82d56013Sjoerg     return true;
309*82d56013Sjoerg   default:
310*82d56013Sjoerg     return false;
311*82d56013Sjoerg   }
3127330f729Sjoerg }
3137330f729Sjoerg 
resolveARM(uint64_t Type,uint64_t Offset,uint64_t S,uint64_t LocData,int64_t)314*82d56013Sjoerg static uint64_t resolveARM(uint64_t Type, uint64_t Offset, uint64_t S,
315*82d56013Sjoerg                            uint64_t LocData, int64_t /*Addend*/) {
316*82d56013Sjoerg   switch (Type) {
317*82d56013Sjoerg   case ELF::R_ARM_ABS32:
318*82d56013Sjoerg     return (S + LocData) & 0xFFFFFFFF;
319*82d56013Sjoerg   case ELF::R_ARM_REL32:
320*82d56013Sjoerg     return (S + LocData - Offset) & 0xFFFFFFFF;
321*82d56013Sjoerg   }
3227330f729Sjoerg   llvm_unreachable("Invalid relocation type");
3237330f729Sjoerg }
3247330f729Sjoerg 
supportsAVR(uint64_t Type)3257330f729Sjoerg static bool supportsAVR(uint64_t Type) {
3267330f729Sjoerg   switch (Type) {
3277330f729Sjoerg   case ELF::R_AVR_16:
3287330f729Sjoerg   case ELF::R_AVR_32:
3297330f729Sjoerg     return true;
3307330f729Sjoerg   default:
3317330f729Sjoerg     return false;
3327330f729Sjoerg   }
3337330f729Sjoerg }
3347330f729Sjoerg 
resolveAVR(uint64_t Type,uint64_t Offset,uint64_t S,uint64_t,int64_t Addend)335*82d56013Sjoerg static uint64_t resolveAVR(uint64_t Type, uint64_t Offset, uint64_t S,
336*82d56013Sjoerg                            uint64_t /*LocData*/, int64_t Addend) {
337*82d56013Sjoerg   switch (Type) {
3387330f729Sjoerg   case ELF::R_AVR_16:
339*82d56013Sjoerg     return (S + Addend) & 0xFFFF;
3407330f729Sjoerg   case ELF::R_AVR_32:
341*82d56013Sjoerg     return (S + Addend) & 0xFFFFFFFF;
3427330f729Sjoerg   default:
3437330f729Sjoerg     llvm_unreachable("Invalid relocation type");
3447330f729Sjoerg   }
3457330f729Sjoerg }
3467330f729Sjoerg 
supportsLanai(uint64_t Type)3477330f729Sjoerg static bool supportsLanai(uint64_t Type) {
3487330f729Sjoerg   return Type == ELF::R_LANAI_32;
3497330f729Sjoerg }
3507330f729Sjoerg 
resolveLanai(uint64_t Type,uint64_t Offset,uint64_t S,uint64_t,int64_t Addend)351*82d56013Sjoerg static uint64_t resolveLanai(uint64_t Type, uint64_t Offset, uint64_t S,
352*82d56013Sjoerg                              uint64_t /*LocData*/, int64_t Addend) {
353*82d56013Sjoerg   if (Type == ELF::R_LANAI_32)
354*82d56013Sjoerg     return (S + Addend) & 0xFFFFFFFF;
3557330f729Sjoerg   llvm_unreachable("Invalid relocation type");
3567330f729Sjoerg }
3577330f729Sjoerg 
supportsMips32(uint64_t Type)3587330f729Sjoerg static bool supportsMips32(uint64_t Type) {
3597330f729Sjoerg   switch (Type) {
3607330f729Sjoerg   case ELF::R_MIPS_32:
3617330f729Sjoerg   case ELF::R_MIPS_TLS_DTPREL32:
3627330f729Sjoerg     return true;
3637330f729Sjoerg   default:
3647330f729Sjoerg     return false;
3657330f729Sjoerg   }
3667330f729Sjoerg }
3677330f729Sjoerg 
resolveMips32(uint64_t Type,uint64_t Offset,uint64_t S,uint64_t LocData,int64_t)368*82d56013Sjoerg static uint64_t resolveMips32(uint64_t Type, uint64_t Offset, uint64_t S,
369*82d56013Sjoerg                               uint64_t LocData, int64_t /*Addend*/) {
3707330f729Sjoerg   // FIXME: Take in account implicit addends to get correct results.
371*82d56013Sjoerg   if (Type == ELF::R_MIPS_32)
372*82d56013Sjoerg     return (S + LocData) & 0xFFFFFFFF;
373*82d56013Sjoerg   if (Type == ELF::R_MIPS_TLS_DTPREL32)
374*82d56013Sjoerg     return (S + LocData) & 0xFFFFFFFF;
3757330f729Sjoerg   llvm_unreachable("Invalid relocation type");
3767330f729Sjoerg }
3777330f729Sjoerg 
supportsSparc32(uint64_t Type)3787330f729Sjoerg static bool supportsSparc32(uint64_t Type) {
3797330f729Sjoerg   switch (Type) {
3807330f729Sjoerg   case ELF::R_SPARC_32:
3817330f729Sjoerg   case ELF::R_SPARC_UA32:
3827330f729Sjoerg     return true;
3837330f729Sjoerg   default:
3847330f729Sjoerg     return false;
3857330f729Sjoerg   }
3867330f729Sjoerg }
3877330f729Sjoerg 
resolveSparc32(uint64_t Type,uint64_t Offset,uint64_t S,uint64_t LocData,int64_t Addend)388*82d56013Sjoerg static uint64_t resolveSparc32(uint64_t Type, uint64_t Offset, uint64_t S,
389*82d56013Sjoerg                                uint64_t LocData, int64_t Addend) {
390*82d56013Sjoerg   if (Type == ELF::R_SPARC_32 || Type == ELF::R_SPARC_UA32)
391*82d56013Sjoerg     return S + Addend;
392*82d56013Sjoerg   return LocData;
3937330f729Sjoerg }
3947330f729Sjoerg 
supportsHexagon(uint64_t Type)3957330f729Sjoerg static bool supportsHexagon(uint64_t Type) {
3967330f729Sjoerg   return Type == ELF::R_HEX_32;
3977330f729Sjoerg }
3987330f729Sjoerg 
resolveHexagon(uint64_t Type,uint64_t Offset,uint64_t S,uint64_t,int64_t Addend)399*82d56013Sjoerg static uint64_t resolveHexagon(uint64_t Type, uint64_t Offset, uint64_t S,
400*82d56013Sjoerg                                uint64_t /*LocData*/, int64_t Addend) {
401*82d56013Sjoerg   if (Type == ELF::R_HEX_32)
402*82d56013Sjoerg     return S + Addend;
4037330f729Sjoerg   llvm_unreachable("Invalid relocation type");
4047330f729Sjoerg }
4057330f729Sjoerg 
supportsRISCV(uint64_t Type)4067330f729Sjoerg static bool supportsRISCV(uint64_t Type) {
4077330f729Sjoerg   switch (Type) {
4087330f729Sjoerg   case ELF::R_RISCV_NONE:
4097330f729Sjoerg   case ELF::R_RISCV_32:
410*82d56013Sjoerg   case ELF::R_RISCV_32_PCREL:
4117330f729Sjoerg   case ELF::R_RISCV_64:
4127330f729Sjoerg   case ELF::R_RISCV_SET6:
4137330f729Sjoerg   case ELF::R_RISCV_SUB6:
4147330f729Sjoerg   case ELF::R_RISCV_ADD8:
4157330f729Sjoerg   case ELF::R_RISCV_SUB8:
4167330f729Sjoerg   case ELF::R_RISCV_ADD16:
4177330f729Sjoerg   case ELF::R_RISCV_SUB16:
4187330f729Sjoerg   case ELF::R_RISCV_ADD32:
4197330f729Sjoerg   case ELF::R_RISCV_SUB32:
4207330f729Sjoerg   case ELF::R_RISCV_ADD64:
4217330f729Sjoerg   case ELF::R_RISCV_SUB64:
4227330f729Sjoerg     return true;
4237330f729Sjoerg   default:
4247330f729Sjoerg     return false;
4257330f729Sjoerg   }
4267330f729Sjoerg }
4277330f729Sjoerg 
resolveRISCV(uint64_t Type,uint64_t Offset,uint64_t S,uint64_t LocData,int64_t Addend)428*82d56013Sjoerg static uint64_t resolveRISCV(uint64_t Type, uint64_t Offset, uint64_t S,
429*82d56013Sjoerg                              uint64_t LocData, int64_t Addend) {
430*82d56013Sjoerg   int64_t RA = Addend;
431*82d56013Sjoerg   uint64_t A = LocData;
432*82d56013Sjoerg   switch (Type) {
4337330f729Sjoerg   case ELF::R_RISCV_NONE:
434*82d56013Sjoerg     return LocData;
4357330f729Sjoerg   case ELF::R_RISCV_32:
4367330f729Sjoerg     return (S + RA) & 0xFFFFFFFF;
437*82d56013Sjoerg   case ELF::R_RISCV_32_PCREL:
438*82d56013Sjoerg     return (S + RA - Offset) & 0xFFFFFFFF;
4397330f729Sjoerg   case ELF::R_RISCV_64:
4407330f729Sjoerg     return S + RA;
4417330f729Sjoerg   case ELF::R_RISCV_SET6:
442*82d56013Sjoerg     return (A & 0xC0) | ((S + RA) & 0x3F);
4437330f729Sjoerg   case ELF::R_RISCV_SUB6:
444*82d56013Sjoerg     return (A & 0xC0) | (((A & 0x3F) - (S + RA)) & 0x3F);
4457330f729Sjoerg   case ELF::R_RISCV_ADD8:
4467330f729Sjoerg     return (A + (S + RA)) & 0xFF;
4477330f729Sjoerg   case ELF::R_RISCV_SUB8:
4487330f729Sjoerg     return (A - (S + RA)) & 0xFF;
4497330f729Sjoerg   case ELF::R_RISCV_ADD16:
4507330f729Sjoerg     return (A + (S + RA)) & 0xFFFF;
4517330f729Sjoerg   case ELF::R_RISCV_SUB16:
4527330f729Sjoerg     return (A - (S + RA)) & 0xFFFF;
4537330f729Sjoerg   case ELF::R_RISCV_ADD32:
4547330f729Sjoerg     return (A + (S + RA)) & 0xFFFFFFFF;
4557330f729Sjoerg   case ELF::R_RISCV_SUB32:
4567330f729Sjoerg     return (A - (S + RA)) & 0xFFFFFFFF;
4577330f729Sjoerg   case ELF::R_RISCV_ADD64:
4587330f729Sjoerg     return (A + (S + RA));
4597330f729Sjoerg   case ELF::R_RISCV_SUB64:
4607330f729Sjoerg     return (A - (S + RA));
4617330f729Sjoerg   default:
4627330f729Sjoerg     llvm_unreachable("Invalid relocation type");
4637330f729Sjoerg   }
4647330f729Sjoerg }
4657330f729Sjoerg 
supportsCOFFX86(uint64_t Type)4667330f729Sjoerg static bool supportsCOFFX86(uint64_t Type) {
4677330f729Sjoerg   switch (Type) {
4687330f729Sjoerg   case COFF::IMAGE_REL_I386_SECREL:
4697330f729Sjoerg   case COFF::IMAGE_REL_I386_DIR32:
4707330f729Sjoerg     return true;
4717330f729Sjoerg   default:
4727330f729Sjoerg     return false;
4737330f729Sjoerg   }
4747330f729Sjoerg }
4757330f729Sjoerg 
resolveCOFFX86(uint64_t Type,uint64_t Offset,uint64_t S,uint64_t LocData,int64_t)476*82d56013Sjoerg static uint64_t resolveCOFFX86(uint64_t Type, uint64_t Offset, uint64_t S,
477*82d56013Sjoerg                                uint64_t LocData, int64_t /*Addend*/) {
478*82d56013Sjoerg   switch (Type) {
4797330f729Sjoerg   case COFF::IMAGE_REL_I386_SECREL:
4807330f729Sjoerg   case COFF::IMAGE_REL_I386_DIR32:
481*82d56013Sjoerg     return (S + LocData) & 0xFFFFFFFF;
4827330f729Sjoerg   default:
4837330f729Sjoerg     llvm_unreachable("Invalid relocation type");
4847330f729Sjoerg   }
4857330f729Sjoerg }
4867330f729Sjoerg 
supportsCOFFX86_64(uint64_t Type)4877330f729Sjoerg static bool supportsCOFFX86_64(uint64_t Type) {
4887330f729Sjoerg   switch (Type) {
4897330f729Sjoerg   case COFF::IMAGE_REL_AMD64_SECREL:
4907330f729Sjoerg   case COFF::IMAGE_REL_AMD64_ADDR64:
4917330f729Sjoerg     return true;
4927330f729Sjoerg   default:
4937330f729Sjoerg     return false;
4947330f729Sjoerg   }
4957330f729Sjoerg }
4967330f729Sjoerg 
resolveCOFFX86_64(uint64_t Type,uint64_t Offset,uint64_t S,uint64_t LocData,int64_t)497*82d56013Sjoerg static uint64_t resolveCOFFX86_64(uint64_t Type, uint64_t Offset, uint64_t S,
498*82d56013Sjoerg                                   uint64_t LocData, int64_t /*Addend*/) {
499*82d56013Sjoerg   switch (Type) {
5007330f729Sjoerg   case COFF::IMAGE_REL_AMD64_SECREL:
501*82d56013Sjoerg     return (S + LocData) & 0xFFFFFFFF;
5027330f729Sjoerg   case COFF::IMAGE_REL_AMD64_ADDR64:
503*82d56013Sjoerg     return S + LocData;
5047330f729Sjoerg   default:
5057330f729Sjoerg     llvm_unreachable("Invalid relocation type");
5067330f729Sjoerg   }
5077330f729Sjoerg }
5087330f729Sjoerg 
supportsCOFFARM(uint64_t Type)5097330f729Sjoerg static bool supportsCOFFARM(uint64_t Type) {
5107330f729Sjoerg   switch (Type) {
5117330f729Sjoerg   case COFF::IMAGE_REL_ARM_SECREL:
5127330f729Sjoerg   case COFF::IMAGE_REL_ARM_ADDR32:
5137330f729Sjoerg     return true;
5147330f729Sjoerg   default:
5157330f729Sjoerg     return false;
5167330f729Sjoerg   }
5177330f729Sjoerg }
5187330f729Sjoerg 
resolveCOFFARM(uint64_t Type,uint64_t Offset,uint64_t S,uint64_t LocData,int64_t)519*82d56013Sjoerg static uint64_t resolveCOFFARM(uint64_t Type, uint64_t Offset, uint64_t S,
520*82d56013Sjoerg                                uint64_t LocData, int64_t /*Addend*/) {
521*82d56013Sjoerg   switch (Type) {
5227330f729Sjoerg   case COFF::IMAGE_REL_ARM_SECREL:
5237330f729Sjoerg   case COFF::IMAGE_REL_ARM_ADDR32:
524*82d56013Sjoerg     return (S + LocData) & 0xFFFFFFFF;
5257330f729Sjoerg   default:
5267330f729Sjoerg     llvm_unreachable("Invalid relocation type");
5277330f729Sjoerg   }
5287330f729Sjoerg }
5297330f729Sjoerg 
supportsCOFFARM64(uint64_t Type)5307330f729Sjoerg static bool supportsCOFFARM64(uint64_t Type) {
5317330f729Sjoerg   switch (Type) {
5327330f729Sjoerg   case COFF::IMAGE_REL_ARM64_SECREL:
5337330f729Sjoerg   case COFF::IMAGE_REL_ARM64_ADDR64:
5347330f729Sjoerg     return true;
5357330f729Sjoerg   default:
5367330f729Sjoerg     return false;
5377330f729Sjoerg   }
5387330f729Sjoerg }
5397330f729Sjoerg 
resolveCOFFARM64(uint64_t Type,uint64_t Offset,uint64_t S,uint64_t LocData,int64_t)540*82d56013Sjoerg static uint64_t resolveCOFFARM64(uint64_t Type, uint64_t Offset, uint64_t S,
541*82d56013Sjoerg                                  uint64_t LocData, int64_t /*Addend*/) {
542*82d56013Sjoerg   switch (Type) {
5437330f729Sjoerg   case COFF::IMAGE_REL_ARM64_SECREL:
544*82d56013Sjoerg     return (S + LocData) & 0xFFFFFFFF;
5457330f729Sjoerg   case COFF::IMAGE_REL_ARM64_ADDR64:
546*82d56013Sjoerg     return S + LocData;
5477330f729Sjoerg   default:
5487330f729Sjoerg     llvm_unreachable("Invalid relocation type");
5497330f729Sjoerg   }
5507330f729Sjoerg }
5517330f729Sjoerg 
supportsMachOX86_64(uint64_t Type)5527330f729Sjoerg static bool supportsMachOX86_64(uint64_t Type) {
5537330f729Sjoerg   return Type == MachO::X86_64_RELOC_UNSIGNED;
5547330f729Sjoerg }
5557330f729Sjoerg 
resolveMachOX86_64(uint64_t Type,uint64_t Offset,uint64_t S,uint64_t LocData,int64_t)556*82d56013Sjoerg static uint64_t resolveMachOX86_64(uint64_t Type, uint64_t Offset, uint64_t S,
557*82d56013Sjoerg                                    uint64_t LocData, int64_t /*Addend*/) {
558*82d56013Sjoerg   if (Type == MachO::X86_64_RELOC_UNSIGNED)
5597330f729Sjoerg     return S;
5607330f729Sjoerg   llvm_unreachable("Invalid relocation type");
5617330f729Sjoerg }
5627330f729Sjoerg 
supportsWasm32(uint64_t Type)5637330f729Sjoerg static bool supportsWasm32(uint64_t Type) {
5647330f729Sjoerg   switch (Type) {
5657330f729Sjoerg   case wasm::R_WASM_FUNCTION_INDEX_LEB:
5667330f729Sjoerg   case wasm::R_WASM_TABLE_INDEX_SLEB:
5677330f729Sjoerg   case wasm::R_WASM_TABLE_INDEX_I32:
5687330f729Sjoerg   case wasm::R_WASM_MEMORY_ADDR_LEB:
5697330f729Sjoerg   case wasm::R_WASM_MEMORY_ADDR_SLEB:
5707330f729Sjoerg   case wasm::R_WASM_MEMORY_ADDR_I32:
5717330f729Sjoerg   case wasm::R_WASM_TYPE_INDEX_LEB:
5727330f729Sjoerg   case wasm::R_WASM_GLOBAL_INDEX_LEB:
5737330f729Sjoerg   case wasm::R_WASM_FUNCTION_OFFSET_I32:
5747330f729Sjoerg   case wasm::R_WASM_SECTION_OFFSET_I32:
5757330f729Sjoerg   case wasm::R_WASM_EVENT_INDEX_LEB:
576*82d56013Sjoerg   case wasm::R_WASM_GLOBAL_INDEX_I32:
577*82d56013Sjoerg   case wasm::R_WASM_TABLE_NUMBER_LEB:
578*82d56013Sjoerg   case wasm::R_WASM_MEMORY_ADDR_LOCREL_I32:
5797330f729Sjoerg     return true;
5807330f729Sjoerg   default:
5817330f729Sjoerg     return false;
5827330f729Sjoerg   }
5837330f729Sjoerg }
5847330f729Sjoerg 
supportsWasm64(uint64_t Type)585*82d56013Sjoerg static bool supportsWasm64(uint64_t Type) {
586*82d56013Sjoerg   switch (Type) {
587*82d56013Sjoerg   case wasm::R_WASM_MEMORY_ADDR_LEB64:
588*82d56013Sjoerg   case wasm::R_WASM_MEMORY_ADDR_SLEB64:
589*82d56013Sjoerg   case wasm::R_WASM_MEMORY_ADDR_I64:
590*82d56013Sjoerg   case wasm::R_WASM_TABLE_INDEX_SLEB64:
591*82d56013Sjoerg   case wasm::R_WASM_TABLE_INDEX_I64:
592*82d56013Sjoerg   case wasm::R_WASM_FUNCTION_OFFSET_I64:
593*82d56013Sjoerg     return true;
594*82d56013Sjoerg   default:
595*82d56013Sjoerg     return supportsWasm32(Type);
596*82d56013Sjoerg   }
597*82d56013Sjoerg }
598*82d56013Sjoerg 
resolveWasm32(uint64_t Type,uint64_t Offset,uint64_t S,uint64_t LocData,int64_t)599*82d56013Sjoerg static uint64_t resolveWasm32(uint64_t Type, uint64_t Offset, uint64_t S,
600*82d56013Sjoerg                               uint64_t LocData, int64_t /*Addend*/) {
601*82d56013Sjoerg   switch (Type) {
6027330f729Sjoerg   case wasm::R_WASM_FUNCTION_INDEX_LEB:
6037330f729Sjoerg   case wasm::R_WASM_TABLE_INDEX_SLEB:
6047330f729Sjoerg   case wasm::R_WASM_TABLE_INDEX_I32:
6057330f729Sjoerg   case wasm::R_WASM_MEMORY_ADDR_LEB:
6067330f729Sjoerg   case wasm::R_WASM_MEMORY_ADDR_SLEB:
6077330f729Sjoerg   case wasm::R_WASM_MEMORY_ADDR_I32:
6087330f729Sjoerg   case wasm::R_WASM_TYPE_INDEX_LEB:
6097330f729Sjoerg   case wasm::R_WASM_GLOBAL_INDEX_LEB:
6107330f729Sjoerg   case wasm::R_WASM_FUNCTION_OFFSET_I32:
6117330f729Sjoerg   case wasm::R_WASM_SECTION_OFFSET_I32:
6127330f729Sjoerg   case wasm::R_WASM_EVENT_INDEX_LEB:
613*82d56013Sjoerg   case wasm::R_WASM_GLOBAL_INDEX_I32:
614*82d56013Sjoerg   case wasm::R_WASM_TABLE_NUMBER_LEB:
615*82d56013Sjoerg   case wasm::R_WASM_MEMORY_ADDR_LOCREL_I32:
6167330f729Sjoerg     // For wasm section, its offset at 0 -- ignoring Value
617*82d56013Sjoerg     return LocData;
6187330f729Sjoerg   default:
6197330f729Sjoerg     llvm_unreachable("Invalid relocation type");
6207330f729Sjoerg   }
6217330f729Sjoerg }
6227330f729Sjoerg 
resolveWasm64(uint64_t Type,uint64_t Offset,uint64_t S,uint64_t LocData,int64_t Addend)623*82d56013Sjoerg static uint64_t resolveWasm64(uint64_t Type, uint64_t Offset, uint64_t S,
624*82d56013Sjoerg                               uint64_t LocData, int64_t Addend) {
625*82d56013Sjoerg   switch (Type) {
626*82d56013Sjoerg   case wasm::R_WASM_MEMORY_ADDR_LEB64:
627*82d56013Sjoerg   case wasm::R_WASM_MEMORY_ADDR_SLEB64:
628*82d56013Sjoerg   case wasm::R_WASM_MEMORY_ADDR_I64:
629*82d56013Sjoerg   case wasm::R_WASM_TABLE_INDEX_SLEB64:
630*82d56013Sjoerg   case wasm::R_WASM_TABLE_INDEX_I64:
631*82d56013Sjoerg   case wasm::R_WASM_FUNCTION_OFFSET_I64:
632*82d56013Sjoerg     // For wasm section, its offset at 0 -- ignoring Value
633*82d56013Sjoerg     return LocData;
634*82d56013Sjoerg   default:
635*82d56013Sjoerg     return resolveWasm32(Type, Offset, S, LocData, Addend);
636*82d56013Sjoerg   }
637*82d56013Sjoerg }
638*82d56013Sjoerg 
639*82d56013Sjoerg std::pair<SupportsRelocation, RelocationResolver>
getRelocationResolver(const ObjectFile & Obj)6407330f729Sjoerg getRelocationResolver(const ObjectFile &Obj) {
6417330f729Sjoerg   if (Obj.isCOFF()) {
6427330f729Sjoerg     switch (Obj.getArch()) {
6437330f729Sjoerg     case Triple::x86_64:
6447330f729Sjoerg       return {supportsCOFFX86_64, resolveCOFFX86_64};
6457330f729Sjoerg     case Triple::x86:
6467330f729Sjoerg       return {supportsCOFFX86, resolveCOFFX86};
6477330f729Sjoerg     case Triple::arm:
6487330f729Sjoerg     case Triple::thumb:
6497330f729Sjoerg       return {supportsCOFFARM, resolveCOFFARM};
6507330f729Sjoerg     case Triple::aarch64:
6517330f729Sjoerg       return {supportsCOFFARM64, resolveCOFFARM64};
6527330f729Sjoerg     default:
6537330f729Sjoerg       return {nullptr, nullptr};
6547330f729Sjoerg     }
6557330f729Sjoerg   } else if (Obj.isELF()) {
6567330f729Sjoerg     if (Obj.getBytesInAddress() == 8) {
6577330f729Sjoerg       switch (Obj.getArch()) {
6587330f729Sjoerg       case Triple::x86_64:
6597330f729Sjoerg         return {supportsX86_64, resolveX86_64};
6607330f729Sjoerg       case Triple::aarch64:
6617330f729Sjoerg       case Triple::aarch64_be:
6627330f729Sjoerg         return {supportsAArch64, resolveAArch64};
6637330f729Sjoerg       case Triple::bpfel:
6647330f729Sjoerg       case Triple::bpfeb:
6657330f729Sjoerg         return {supportsBPF, resolveBPF};
6667330f729Sjoerg       case Triple::mips64el:
6677330f729Sjoerg       case Triple::mips64:
6687330f729Sjoerg         return {supportsMips64, resolveMips64};
6697330f729Sjoerg       case Triple::ppc64le:
6707330f729Sjoerg       case Triple::ppc64:
6717330f729Sjoerg         return {supportsPPC64, resolvePPC64};
6727330f729Sjoerg       case Triple::systemz:
6737330f729Sjoerg         return {supportsSystemZ, resolveSystemZ};
6747330f729Sjoerg       case Triple::sparcv9:
6757330f729Sjoerg         return {supportsSparc64, resolveSparc64};
6767330f729Sjoerg       case Triple::amdgcn:
6777330f729Sjoerg         return {supportsAmdgpu, resolveAmdgpu};
6787330f729Sjoerg       case Triple::riscv64:
6797330f729Sjoerg         return {supportsRISCV, resolveRISCV};
6807330f729Sjoerg       default:
6817330f729Sjoerg         return {nullptr, nullptr};
6827330f729Sjoerg       }
6837330f729Sjoerg     }
6847330f729Sjoerg 
6857330f729Sjoerg     // 32-bit object file
6867330f729Sjoerg     assert(Obj.getBytesInAddress() == 4 &&
6877330f729Sjoerg            "Invalid word size in object file");
6887330f729Sjoerg 
6897330f729Sjoerg     switch (Obj.getArch()) {
6907330f729Sjoerg     case Triple::x86:
6917330f729Sjoerg       return {supportsX86, resolveX86};
692*82d56013Sjoerg     case Triple::ppcle:
6937330f729Sjoerg     case Triple::ppc:
6947330f729Sjoerg       return {supportsPPC32, resolvePPC32};
6957330f729Sjoerg     case Triple::arm:
6967330f729Sjoerg     case Triple::armeb:
6977330f729Sjoerg       return {supportsARM, resolveARM};
6987330f729Sjoerg     case Triple::avr:
6997330f729Sjoerg       return {supportsAVR, resolveAVR};
7007330f729Sjoerg     case Triple::lanai:
7017330f729Sjoerg       return {supportsLanai, resolveLanai};
7027330f729Sjoerg     case Triple::mipsel:
7037330f729Sjoerg     case Triple::mips:
7047330f729Sjoerg       return {supportsMips32, resolveMips32};
705*82d56013Sjoerg     case Triple::msp430:
706*82d56013Sjoerg       return {supportsMSP430, resolveMSP430};
7077330f729Sjoerg     case Triple::sparc:
7087330f729Sjoerg       return {supportsSparc32, resolveSparc32};
7097330f729Sjoerg     case Triple::hexagon:
7107330f729Sjoerg       return {supportsHexagon, resolveHexagon};
7117330f729Sjoerg     case Triple::riscv32:
7127330f729Sjoerg       return {supportsRISCV, resolveRISCV};
7137330f729Sjoerg     default:
7147330f729Sjoerg       return {nullptr, nullptr};
7157330f729Sjoerg     }
7167330f729Sjoerg   } else if (Obj.isMachO()) {
7177330f729Sjoerg     if (Obj.getArch() == Triple::x86_64)
7187330f729Sjoerg       return {supportsMachOX86_64, resolveMachOX86_64};
7197330f729Sjoerg     return {nullptr, nullptr};
7207330f729Sjoerg   } else if (Obj.isWasm()) {
7217330f729Sjoerg     if (Obj.getArch() == Triple::wasm32)
7227330f729Sjoerg       return {supportsWasm32, resolveWasm32};
723*82d56013Sjoerg     if (Obj.getArch() == Triple::wasm64)
724*82d56013Sjoerg       return {supportsWasm64, resolveWasm64};
7257330f729Sjoerg     return {nullptr, nullptr};
7267330f729Sjoerg   }
7277330f729Sjoerg 
7287330f729Sjoerg   llvm_unreachable("Invalid object file");
7297330f729Sjoerg }
7307330f729Sjoerg 
resolveRelocation(RelocationResolver Resolver,const RelocationRef & R,uint64_t S,uint64_t LocData)731*82d56013Sjoerg uint64_t resolveRelocation(RelocationResolver Resolver, const RelocationRef &R,
732*82d56013Sjoerg                            uint64_t S, uint64_t LocData) {
733*82d56013Sjoerg   if (const ObjectFile *Obj = R.getObject()) {
734*82d56013Sjoerg     int64_t Addend = 0;
735*82d56013Sjoerg     if (Obj->isELF()) {
736*82d56013Sjoerg       auto GetRelSectionType = [&]() -> unsigned {
737*82d56013Sjoerg         if (auto *Elf32LEObj = dyn_cast<ELF32LEObjectFile>(Obj))
738*82d56013Sjoerg           return Elf32LEObj->getRelSection(R.getRawDataRefImpl())->sh_type;
739*82d56013Sjoerg         if (auto *Elf64LEObj = dyn_cast<ELF64LEObjectFile>(Obj))
740*82d56013Sjoerg           return Elf64LEObj->getRelSection(R.getRawDataRefImpl())->sh_type;
741*82d56013Sjoerg         if (auto *Elf32BEObj = dyn_cast<ELF32BEObjectFile>(Obj))
742*82d56013Sjoerg           return Elf32BEObj->getRelSection(R.getRawDataRefImpl())->sh_type;
743*82d56013Sjoerg         auto *Elf64BEObj = cast<ELF64BEObjectFile>(Obj);
744*82d56013Sjoerg         return Elf64BEObj->getRelSection(R.getRawDataRefImpl())->sh_type;
745*82d56013Sjoerg       };
746*82d56013Sjoerg 
747*82d56013Sjoerg       if (GetRelSectionType() == ELF::SHT_RELA)
748*82d56013Sjoerg         Addend = getELFAddend(R);
749*82d56013Sjoerg     }
750*82d56013Sjoerg 
751*82d56013Sjoerg     return Resolver(R.getType(), R.getOffset(), S, LocData, Addend);
752*82d56013Sjoerg   }
753*82d56013Sjoerg 
754*82d56013Sjoerg   // Sometimes the caller might want to use its own specific implementation of
755*82d56013Sjoerg   // the resolver function. E.g. this is used by LLD when it resolves debug
756*82d56013Sjoerg   // relocations and assumes that all of them have the same computation (S + A).
757*82d56013Sjoerg   // The relocation R has no owner object in this case and we don't need to
758*82d56013Sjoerg   // provide Type and Offset fields. It is also assumed the DataRefImpl.p
759*82d56013Sjoerg   // contains the addend, provided by the caller.
760*82d56013Sjoerg   return Resolver(/*Type=*/0, /*Offset=*/0, S, LocData,
761*82d56013Sjoerg                   R.getRawDataRefImpl().p);
762*82d56013Sjoerg }
763*82d56013Sjoerg 
7647330f729Sjoerg } // namespace object
7657330f729Sjoerg } // namespace llvm
766