xref: /openbsd-src/gnu/llvm/llvm/lib/Object/RelocationResolver.cpp (revision d415bd752c734aee168c4ee86ff32e8cc249eb16)
109467b48Spatrick //===- RelocationResolver.cpp ------------------------------------*- C++ -*-===//
209467b48Spatrick //
309467b48Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
409467b48Spatrick // See https://llvm.org/LICENSE.txt for license information.
509467b48Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
609467b48Spatrick //
709467b48Spatrick //===----------------------------------------------------------------------===//
809467b48Spatrick //
909467b48Spatrick // This file defines utilities to resolve relocations in object files.
1009467b48Spatrick //
1109467b48Spatrick //===----------------------------------------------------------------------===//
1209467b48Spatrick 
1309467b48Spatrick #include "llvm/Object/RelocationResolver.h"
14*d415bd75Srobert #include "llvm/ADT/Triple.h"
15*d415bd75Srobert #include "llvm/ADT/Twine.h"
16*d415bd75Srobert #include "llvm/BinaryFormat/COFF.h"
17*d415bd75Srobert #include "llvm/BinaryFormat/ELF.h"
18*d415bd75Srobert #include "llvm/BinaryFormat/MachO.h"
19*d415bd75Srobert #include "llvm/BinaryFormat/Wasm.h"
20*d415bd75Srobert #include "llvm/Object/ELFObjectFile.h"
21*d415bd75Srobert #include "llvm/Object/ELFTypes.h"
22*d415bd75Srobert #include "llvm/Object/ObjectFile.h"
23*d415bd75Srobert #include "llvm/Object/SymbolicFile.h"
24*d415bd75Srobert #include "llvm/Support/Casting.h"
25*d415bd75Srobert #include "llvm/Support/Error.h"
26*d415bd75Srobert #include "llvm/Support/ErrorHandling.h"
27*d415bd75Srobert #include <cassert>
28*d415bd75Srobert #include <vector>
2909467b48Spatrick 
3009467b48Spatrick namespace llvm {
3109467b48Spatrick namespace object {
3209467b48Spatrick 
getELFAddend(RelocationRef R)3309467b48Spatrick static int64_t getELFAddend(RelocationRef R) {
3409467b48Spatrick   Expected<int64_t> AddendOrErr = ELFRelocationRef(R).getAddend();
3509467b48Spatrick   handleAllErrors(AddendOrErr.takeError(), [](const ErrorInfoBase &EI) {
36*d415bd75Srobert     report_fatal_error(Twine(EI.message()));
3709467b48Spatrick   });
3809467b48Spatrick   return *AddendOrErr;
3909467b48Spatrick }
4009467b48Spatrick 
supportsX86_64(uint64_t Type)4109467b48Spatrick static bool supportsX86_64(uint64_t Type) {
4209467b48Spatrick   switch (Type) {
4309467b48Spatrick   case ELF::R_X86_64_NONE:
4409467b48Spatrick   case ELF::R_X86_64_64:
4509467b48Spatrick   case ELF::R_X86_64_DTPOFF32:
4609467b48Spatrick   case ELF::R_X86_64_DTPOFF64:
4709467b48Spatrick   case ELF::R_X86_64_PC32:
4809467b48Spatrick   case ELF::R_X86_64_PC64:
4909467b48Spatrick   case ELF::R_X86_64_32:
5009467b48Spatrick   case ELF::R_X86_64_32S:
5109467b48Spatrick     return true;
5209467b48Spatrick   default:
5309467b48Spatrick     return false;
5409467b48Spatrick   }
5509467b48Spatrick }
5609467b48Spatrick 
resolveX86_64(uint64_t Type,uint64_t Offset,uint64_t S,uint64_t LocData,int64_t Addend)5773471bf0Spatrick static uint64_t resolveX86_64(uint64_t Type, uint64_t Offset, uint64_t S,
5873471bf0Spatrick                               uint64_t LocData, int64_t Addend) {
5973471bf0Spatrick   switch (Type) {
6009467b48Spatrick   case ELF::R_X86_64_NONE:
6173471bf0Spatrick     return LocData;
6209467b48Spatrick   case ELF::R_X86_64_64:
6309467b48Spatrick   case ELF::R_X86_64_DTPOFF32:
6409467b48Spatrick   case ELF::R_X86_64_DTPOFF64:
6573471bf0Spatrick     return S + Addend;
6609467b48Spatrick   case ELF::R_X86_64_PC32:
6709467b48Spatrick   case ELF::R_X86_64_PC64:
6873471bf0Spatrick     return S + Addend - Offset;
6909467b48Spatrick   case ELF::R_X86_64_32:
7009467b48Spatrick   case ELF::R_X86_64_32S:
7173471bf0Spatrick     return (S + Addend) & 0xFFFFFFFF;
7209467b48Spatrick   default:
7309467b48Spatrick     llvm_unreachable("Invalid relocation type");
7409467b48Spatrick   }
7509467b48Spatrick }
7609467b48Spatrick 
supportsAArch64(uint64_t Type)7709467b48Spatrick static bool supportsAArch64(uint64_t Type) {
7809467b48Spatrick   switch (Type) {
7909467b48Spatrick   case ELF::R_AARCH64_ABS32:
8009467b48Spatrick   case ELF::R_AARCH64_ABS64:
81*d415bd75Srobert   case ELF::R_AARCH64_PREL16:
82097a140dSpatrick   case ELF::R_AARCH64_PREL32:
83097a140dSpatrick   case ELF::R_AARCH64_PREL64:
8409467b48Spatrick     return true;
8509467b48Spatrick   default:
8609467b48Spatrick     return false;
8709467b48Spatrick   }
8809467b48Spatrick }
8909467b48Spatrick 
resolveAArch64(uint64_t Type,uint64_t Offset,uint64_t S,uint64_t,int64_t Addend)9073471bf0Spatrick static uint64_t resolveAArch64(uint64_t Type, uint64_t Offset, uint64_t S,
9173471bf0Spatrick                                uint64_t /*LocData*/, int64_t Addend) {
9273471bf0Spatrick   switch (Type) {
9309467b48Spatrick   case ELF::R_AARCH64_ABS32:
9473471bf0Spatrick     return (S + Addend) & 0xFFFFFFFF;
9509467b48Spatrick   case ELF::R_AARCH64_ABS64:
9673471bf0Spatrick     return S + Addend;
97*d415bd75Srobert   case ELF::R_AARCH64_PREL16:
98*d415bd75Srobert     return (S + Addend - Offset) & 0xFFFF;
99097a140dSpatrick   case ELF::R_AARCH64_PREL32:
10073471bf0Spatrick     return (S + Addend - Offset) & 0xFFFFFFFF;
101097a140dSpatrick   case ELF::R_AARCH64_PREL64:
10273471bf0Spatrick     return S + Addend - Offset;
10309467b48Spatrick   default:
10409467b48Spatrick     llvm_unreachable("Invalid relocation type");
10509467b48Spatrick   }
10609467b48Spatrick }
10709467b48Spatrick 
supportsBPF(uint64_t Type)10809467b48Spatrick static bool supportsBPF(uint64_t Type) {
10909467b48Spatrick   switch (Type) {
11073471bf0Spatrick   case ELF::R_BPF_64_ABS32:
11173471bf0Spatrick   case ELF::R_BPF_64_ABS64:
11209467b48Spatrick     return true;
11309467b48Spatrick   default:
11409467b48Spatrick     return false;
11509467b48Spatrick   }
11609467b48Spatrick }
11709467b48Spatrick 
resolveBPF(uint64_t Type,uint64_t Offset,uint64_t S,uint64_t LocData,int64_t)11873471bf0Spatrick static uint64_t resolveBPF(uint64_t Type, uint64_t Offset, uint64_t S,
11973471bf0Spatrick                            uint64_t LocData, int64_t /*Addend*/) {
12073471bf0Spatrick   switch (Type) {
12173471bf0Spatrick   case ELF::R_BPF_64_ABS32:
12273471bf0Spatrick     return (S + LocData) & 0xFFFFFFFF;
12373471bf0Spatrick   case ELF::R_BPF_64_ABS64:
12473471bf0Spatrick     return S + LocData;
12509467b48Spatrick   default:
12609467b48Spatrick     llvm_unreachable("Invalid relocation type");
12709467b48Spatrick   }
12809467b48Spatrick }
12909467b48Spatrick 
supportsMips64(uint64_t Type)13009467b48Spatrick static bool supportsMips64(uint64_t Type) {
13109467b48Spatrick   switch (Type) {
13209467b48Spatrick   case ELF::R_MIPS_32:
13309467b48Spatrick   case ELF::R_MIPS_64:
13409467b48Spatrick   case ELF::R_MIPS_TLS_DTPREL64:
13509467b48Spatrick   case ELF::R_MIPS_PC32:
13609467b48Spatrick     return true;
13709467b48Spatrick   default:
13809467b48Spatrick     return false;
13909467b48Spatrick   }
14009467b48Spatrick }
14109467b48Spatrick 
resolveMips64(uint64_t Type,uint64_t Offset,uint64_t S,uint64_t,int64_t Addend)14273471bf0Spatrick static uint64_t resolveMips64(uint64_t Type, uint64_t Offset, uint64_t S,
14373471bf0Spatrick                               uint64_t /*LocData*/, int64_t Addend) {
14473471bf0Spatrick   switch (Type) {
14509467b48Spatrick   case ELF::R_MIPS_32:
14673471bf0Spatrick     return (S + Addend) & 0xFFFFFFFF;
14709467b48Spatrick   case ELF::R_MIPS_64:
14873471bf0Spatrick     return S + Addend;
14909467b48Spatrick   case ELF::R_MIPS_TLS_DTPREL64:
15073471bf0Spatrick     return S + Addend - 0x8000;
15109467b48Spatrick   case ELF::R_MIPS_PC32:
15273471bf0Spatrick     return S + Addend - Offset;
15309467b48Spatrick   default:
15409467b48Spatrick     llvm_unreachable("Invalid relocation type");
15509467b48Spatrick   }
15609467b48Spatrick }
15709467b48Spatrick 
supportsMSP430(uint64_t Type)158097a140dSpatrick static bool supportsMSP430(uint64_t Type) {
159097a140dSpatrick   switch (Type) {
160097a140dSpatrick   case ELF::R_MSP430_32:
161097a140dSpatrick   case ELF::R_MSP430_16_BYTE:
162097a140dSpatrick     return true;
163097a140dSpatrick   default:
164097a140dSpatrick     return false;
165097a140dSpatrick   }
166097a140dSpatrick }
167097a140dSpatrick 
resolveMSP430(uint64_t Type,uint64_t Offset,uint64_t S,uint64_t,int64_t Addend)16873471bf0Spatrick static uint64_t resolveMSP430(uint64_t Type, uint64_t Offset, uint64_t S,
16973471bf0Spatrick                               uint64_t /*LocData*/, int64_t Addend) {
17073471bf0Spatrick   switch (Type) {
171097a140dSpatrick   case ELF::R_MSP430_32:
17273471bf0Spatrick     return (S + Addend) & 0xFFFFFFFF;
173097a140dSpatrick   case ELF::R_MSP430_16_BYTE:
17473471bf0Spatrick     return (S + Addend) & 0xFFFF;
175097a140dSpatrick   default:
176097a140dSpatrick     llvm_unreachable("Invalid relocation type");
177097a140dSpatrick   }
178097a140dSpatrick }
179097a140dSpatrick 
supportsPPC64(uint64_t Type)18009467b48Spatrick static bool supportsPPC64(uint64_t Type) {
18109467b48Spatrick   switch (Type) {
18209467b48Spatrick   case ELF::R_PPC64_ADDR32:
18309467b48Spatrick   case ELF::R_PPC64_ADDR64:
184097a140dSpatrick   case ELF::R_PPC64_REL32:
185097a140dSpatrick   case ELF::R_PPC64_REL64:
18609467b48Spatrick     return true;
18709467b48Spatrick   default:
18809467b48Spatrick     return false;
18909467b48Spatrick   }
19009467b48Spatrick }
19109467b48Spatrick 
resolvePPC64(uint64_t Type,uint64_t Offset,uint64_t S,uint64_t,int64_t Addend)19273471bf0Spatrick static uint64_t resolvePPC64(uint64_t Type, uint64_t Offset, uint64_t S,
19373471bf0Spatrick                              uint64_t /*LocData*/, int64_t Addend) {
19473471bf0Spatrick   switch (Type) {
19509467b48Spatrick   case ELF::R_PPC64_ADDR32:
19673471bf0Spatrick     return (S + Addend) & 0xFFFFFFFF;
19709467b48Spatrick   case ELF::R_PPC64_ADDR64:
19873471bf0Spatrick     return S + Addend;
199097a140dSpatrick   case ELF::R_PPC64_REL32:
20073471bf0Spatrick     return (S + Addend - Offset) & 0xFFFFFFFF;
201097a140dSpatrick   case ELF::R_PPC64_REL64:
20273471bf0Spatrick     return S + Addend - Offset;
20309467b48Spatrick   default:
20409467b48Spatrick     llvm_unreachable("Invalid relocation type");
20509467b48Spatrick   }
20609467b48Spatrick }
20709467b48Spatrick 
supportsSystemZ(uint64_t Type)20809467b48Spatrick static bool supportsSystemZ(uint64_t Type) {
20909467b48Spatrick   switch (Type) {
21009467b48Spatrick   case ELF::R_390_32:
21109467b48Spatrick   case ELF::R_390_64:
21209467b48Spatrick     return true;
21309467b48Spatrick   default:
21409467b48Spatrick     return false;
21509467b48Spatrick   }
21609467b48Spatrick }
21709467b48Spatrick 
resolveSystemZ(uint64_t Type,uint64_t Offset,uint64_t S,uint64_t,int64_t Addend)21873471bf0Spatrick static uint64_t resolveSystemZ(uint64_t Type, uint64_t Offset, uint64_t S,
21973471bf0Spatrick                                uint64_t /*LocData*/, int64_t Addend) {
22073471bf0Spatrick   switch (Type) {
22109467b48Spatrick   case ELF::R_390_32:
22273471bf0Spatrick     return (S + Addend) & 0xFFFFFFFF;
22309467b48Spatrick   case ELF::R_390_64:
22473471bf0Spatrick     return S + Addend;
22509467b48Spatrick   default:
22609467b48Spatrick     llvm_unreachable("Invalid relocation type");
22709467b48Spatrick   }
22809467b48Spatrick }
22909467b48Spatrick 
supportsSparc64(uint64_t Type)23009467b48Spatrick static bool supportsSparc64(uint64_t Type) {
23109467b48Spatrick   switch (Type) {
23209467b48Spatrick   case ELF::R_SPARC_32:
23309467b48Spatrick   case ELF::R_SPARC_64:
23409467b48Spatrick   case ELF::R_SPARC_UA32:
23509467b48Spatrick   case ELF::R_SPARC_UA64:
23609467b48Spatrick     return true;
23709467b48Spatrick   default:
23809467b48Spatrick     return false;
23909467b48Spatrick   }
24009467b48Spatrick }
24109467b48Spatrick 
resolveSparc64(uint64_t Type,uint64_t Offset,uint64_t S,uint64_t,int64_t Addend)24273471bf0Spatrick static uint64_t resolveSparc64(uint64_t Type, uint64_t Offset, uint64_t S,
24373471bf0Spatrick                                uint64_t /*LocData*/, int64_t Addend) {
24473471bf0Spatrick   switch (Type) {
24509467b48Spatrick   case ELF::R_SPARC_32:
24609467b48Spatrick   case ELF::R_SPARC_64:
24709467b48Spatrick   case ELF::R_SPARC_UA32:
24809467b48Spatrick   case ELF::R_SPARC_UA64:
24973471bf0Spatrick     return S + Addend;
25009467b48Spatrick   default:
25109467b48Spatrick     llvm_unreachable("Invalid relocation type");
25209467b48Spatrick   }
25309467b48Spatrick }
25409467b48Spatrick 
supportsAmdgpu(uint64_t Type)25509467b48Spatrick static bool supportsAmdgpu(uint64_t Type) {
25609467b48Spatrick   switch (Type) {
25709467b48Spatrick   case ELF::R_AMDGPU_ABS32:
25809467b48Spatrick   case ELF::R_AMDGPU_ABS64:
25909467b48Spatrick     return true;
26009467b48Spatrick   default:
26109467b48Spatrick     return false;
26209467b48Spatrick   }
26309467b48Spatrick }
26409467b48Spatrick 
resolveAmdgpu(uint64_t Type,uint64_t Offset,uint64_t S,uint64_t,int64_t Addend)26573471bf0Spatrick static uint64_t resolveAmdgpu(uint64_t Type, uint64_t Offset, uint64_t S,
26673471bf0Spatrick                               uint64_t /*LocData*/, int64_t Addend) {
26773471bf0Spatrick   switch (Type) {
26809467b48Spatrick   case ELF::R_AMDGPU_ABS32:
26909467b48Spatrick   case ELF::R_AMDGPU_ABS64:
27073471bf0Spatrick     return S + Addend;
27109467b48Spatrick   default:
27209467b48Spatrick     llvm_unreachable("Invalid relocation type");
27309467b48Spatrick   }
27409467b48Spatrick }
27509467b48Spatrick 
supportsX86(uint64_t Type)27609467b48Spatrick static bool supportsX86(uint64_t Type) {
27709467b48Spatrick   switch (Type) {
27809467b48Spatrick   case ELF::R_386_NONE:
27909467b48Spatrick   case ELF::R_386_32:
28009467b48Spatrick   case ELF::R_386_PC32:
28109467b48Spatrick     return true;
28209467b48Spatrick   default:
28309467b48Spatrick     return false;
28409467b48Spatrick   }
28509467b48Spatrick }
28609467b48Spatrick 
resolveX86(uint64_t Type,uint64_t Offset,uint64_t S,uint64_t LocData,int64_t)28773471bf0Spatrick static uint64_t resolveX86(uint64_t Type, uint64_t Offset, uint64_t S,
28873471bf0Spatrick                            uint64_t LocData, int64_t /*Addend*/) {
28973471bf0Spatrick   switch (Type) {
29009467b48Spatrick   case ELF::R_386_NONE:
29173471bf0Spatrick     return LocData;
29209467b48Spatrick   case ELF::R_386_32:
29373471bf0Spatrick     return S + LocData;
29409467b48Spatrick   case ELF::R_386_PC32:
29573471bf0Spatrick     return S - Offset + LocData;
29609467b48Spatrick   default:
29709467b48Spatrick     llvm_unreachable("Invalid relocation type");
29809467b48Spatrick   }
29909467b48Spatrick }
30009467b48Spatrick 
supportsPPC32(uint64_t Type)30109467b48Spatrick static bool supportsPPC32(uint64_t Type) {
302097a140dSpatrick   switch (Type) {
303097a140dSpatrick   case ELF::R_PPC_ADDR32:
304097a140dSpatrick   case ELF::R_PPC_REL32:
305097a140dSpatrick     return true;
306097a140dSpatrick   default:
307097a140dSpatrick     return false;
308097a140dSpatrick   }
30909467b48Spatrick }
31009467b48Spatrick 
resolvePPC32(uint64_t Type,uint64_t Offset,uint64_t S,uint64_t,int64_t Addend)31173471bf0Spatrick static uint64_t resolvePPC32(uint64_t Type, uint64_t Offset, uint64_t S,
31273471bf0Spatrick                              uint64_t /*LocData*/, int64_t Addend) {
31373471bf0Spatrick   switch (Type) {
314097a140dSpatrick   case ELF::R_PPC_ADDR32:
31573471bf0Spatrick     return (S + Addend) & 0xFFFFFFFF;
316097a140dSpatrick   case ELF::R_PPC_REL32:
31773471bf0Spatrick     return (S + Addend - Offset) & 0xFFFFFFFF;
318097a140dSpatrick   }
31909467b48Spatrick   llvm_unreachable("Invalid relocation type");
32009467b48Spatrick }
32109467b48Spatrick 
supportsARM(uint64_t Type)32209467b48Spatrick static bool supportsARM(uint64_t Type) {
32373471bf0Spatrick   switch (Type) {
32473471bf0Spatrick   case ELF::R_ARM_ABS32:
32573471bf0Spatrick   case ELF::R_ARM_REL32:
32673471bf0Spatrick     return true;
32773471bf0Spatrick   default:
32873471bf0Spatrick     return false;
32973471bf0Spatrick   }
33009467b48Spatrick }
33109467b48Spatrick 
resolveARM(uint64_t Type,uint64_t Offset,uint64_t S,uint64_t LocData,int64_t Addend)33273471bf0Spatrick static uint64_t resolveARM(uint64_t Type, uint64_t Offset, uint64_t S,
33373471bf0Spatrick                            uint64_t LocData, int64_t Addend) {
33473471bf0Spatrick   // Support both RELA and REL relocations. The caller is responsible
33573471bf0Spatrick   // for supplying the correct values for LocData and Addend, i.e.
33673471bf0Spatrick   // Addend == 0 for REL and LocData == 0 for RELA.
33773471bf0Spatrick   assert((LocData == 0 || Addend == 0) &&
33873471bf0Spatrick          "one of LocData and Addend must be 0");
33973471bf0Spatrick   switch (Type) {
34073471bf0Spatrick   case ELF::R_ARM_ABS32:
34173471bf0Spatrick     return (S + LocData + Addend) & 0xFFFFFFFF;
34273471bf0Spatrick   case ELF::R_ARM_REL32:
34373471bf0Spatrick     return (S + LocData + Addend - Offset) & 0xFFFFFFFF;
34473471bf0Spatrick   }
34509467b48Spatrick   llvm_unreachable("Invalid relocation type");
34609467b48Spatrick }
34709467b48Spatrick 
supportsAVR(uint64_t Type)34809467b48Spatrick static bool supportsAVR(uint64_t Type) {
34909467b48Spatrick   switch (Type) {
35009467b48Spatrick   case ELF::R_AVR_16:
35109467b48Spatrick   case ELF::R_AVR_32:
35209467b48Spatrick     return true;
35309467b48Spatrick   default:
35409467b48Spatrick     return false;
35509467b48Spatrick   }
35609467b48Spatrick }
35709467b48Spatrick 
resolveAVR(uint64_t Type,uint64_t Offset,uint64_t S,uint64_t,int64_t Addend)35873471bf0Spatrick static uint64_t resolveAVR(uint64_t Type, uint64_t Offset, uint64_t S,
35973471bf0Spatrick                            uint64_t /*LocData*/, int64_t Addend) {
36073471bf0Spatrick   switch (Type) {
36109467b48Spatrick   case ELF::R_AVR_16:
36273471bf0Spatrick     return (S + Addend) & 0xFFFF;
36309467b48Spatrick   case ELF::R_AVR_32:
36473471bf0Spatrick     return (S + Addend) & 0xFFFFFFFF;
36509467b48Spatrick   default:
36609467b48Spatrick     llvm_unreachable("Invalid relocation type");
36709467b48Spatrick   }
36809467b48Spatrick }
36909467b48Spatrick 
supportsLanai(uint64_t Type)37009467b48Spatrick static bool supportsLanai(uint64_t Type) {
37109467b48Spatrick   return Type == ELF::R_LANAI_32;
37209467b48Spatrick }
37309467b48Spatrick 
resolveLanai(uint64_t Type,uint64_t Offset,uint64_t S,uint64_t,int64_t Addend)37473471bf0Spatrick static uint64_t resolveLanai(uint64_t Type, uint64_t Offset, uint64_t S,
37573471bf0Spatrick                              uint64_t /*LocData*/, int64_t Addend) {
37673471bf0Spatrick   if (Type == ELF::R_LANAI_32)
37773471bf0Spatrick     return (S + Addend) & 0xFFFFFFFF;
37809467b48Spatrick   llvm_unreachable("Invalid relocation type");
37909467b48Spatrick }
38009467b48Spatrick 
supportsMips32(uint64_t Type)38109467b48Spatrick static bool supportsMips32(uint64_t Type) {
38209467b48Spatrick   switch (Type) {
38309467b48Spatrick   case ELF::R_MIPS_32:
38409467b48Spatrick   case ELF::R_MIPS_TLS_DTPREL32:
38509467b48Spatrick     return true;
38609467b48Spatrick   default:
38709467b48Spatrick     return false;
38809467b48Spatrick   }
38909467b48Spatrick }
39009467b48Spatrick 
resolveMips32(uint64_t Type,uint64_t Offset,uint64_t S,uint64_t LocData,int64_t)39173471bf0Spatrick static uint64_t resolveMips32(uint64_t Type, uint64_t Offset, uint64_t S,
39273471bf0Spatrick                               uint64_t LocData, int64_t /*Addend*/) {
39309467b48Spatrick   // FIXME: Take in account implicit addends to get correct results.
39473471bf0Spatrick   if (Type == ELF::R_MIPS_32)
39573471bf0Spatrick     return (S + LocData) & 0xFFFFFFFF;
39673471bf0Spatrick   if (Type == ELF::R_MIPS_TLS_DTPREL32)
39773471bf0Spatrick     return (S + LocData) & 0xFFFFFFFF;
39809467b48Spatrick   llvm_unreachable("Invalid relocation type");
39909467b48Spatrick }
40009467b48Spatrick 
supportsSparc32(uint64_t Type)40109467b48Spatrick static bool supportsSparc32(uint64_t Type) {
40209467b48Spatrick   switch (Type) {
40309467b48Spatrick   case ELF::R_SPARC_32:
40409467b48Spatrick   case ELF::R_SPARC_UA32:
40509467b48Spatrick     return true;
40609467b48Spatrick   default:
40709467b48Spatrick     return false;
40809467b48Spatrick   }
40909467b48Spatrick }
41009467b48Spatrick 
resolveSparc32(uint64_t Type,uint64_t Offset,uint64_t S,uint64_t LocData,int64_t Addend)41173471bf0Spatrick static uint64_t resolveSparc32(uint64_t Type, uint64_t Offset, uint64_t S,
41273471bf0Spatrick                                uint64_t LocData, int64_t Addend) {
41373471bf0Spatrick   if (Type == ELF::R_SPARC_32 || Type == ELF::R_SPARC_UA32)
41473471bf0Spatrick     return S + Addend;
41573471bf0Spatrick   return LocData;
41609467b48Spatrick }
41709467b48Spatrick 
supportsHexagon(uint64_t Type)41809467b48Spatrick static bool supportsHexagon(uint64_t Type) {
41909467b48Spatrick   return Type == ELF::R_HEX_32;
42009467b48Spatrick }
42109467b48Spatrick 
resolveHexagon(uint64_t Type,uint64_t Offset,uint64_t S,uint64_t,int64_t Addend)42273471bf0Spatrick static uint64_t resolveHexagon(uint64_t Type, uint64_t Offset, uint64_t S,
42373471bf0Spatrick                                uint64_t /*LocData*/, int64_t Addend) {
42473471bf0Spatrick   if (Type == ELF::R_HEX_32)
42573471bf0Spatrick     return S + Addend;
42609467b48Spatrick   llvm_unreachable("Invalid relocation type");
42709467b48Spatrick }
42809467b48Spatrick 
supportsRISCV(uint64_t Type)42909467b48Spatrick static bool supportsRISCV(uint64_t Type) {
43009467b48Spatrick   switch (Type) {
43109467b48Spatrick   case ELF::R_RISCV_NONE:
43209467b48Spatrick   case ELF::R_RISCV_32:
43309467b48Spatrick   case ELF::R_RISCV_32_PCREL:
43409467b48Spatrick   case ELF::R_RISCV_64:
43509467b48Spatrick   case ELF::R_RISCV_SET6:
436*d415bd75Srobert   case ELF::R_RISCV_SET8:
43709467b48Spatrick   case ELF::R_RISCV_SUB6:
43809467b48Spatrick   case ELF::R_RISCV_ADD8:
43909467b48Spatrick   case ELF::R_RISCV_SUB8:
440*d415bd75Srobert   case ELF::R_RISCV_SET16:
44109467b48Spatrick   case ELF::R_RISCV_ADD16:
44209467b48Spatrick   case ELF::R_RISCV_SUB16:
443*d415bd75Srobert   case ELF::R_RISCV_SET32:
44409467b48Spatrick   case ELF::R_RISCV_ADD32:
44509467b48Spatrick   case ELF::R_RISCV_SUB32:
44609467b48Spatrick   case ELF::R_RISCV_ADD64:
44709467b48Spatrick   case ELF::R_RISCV_SUB64:
44809467b48Spatrick     return true;
44909467b48Spatrick   default:
45009467b48Spatrick     return false;
45109467b48Spatrick   }
45209467b48Spatrick }
45309467b48Spatrick 
resolveRISCV(uint64_t Type,uint64_t Offset,uint64_t S,uint64_t LocData,int64_t Addend)45473471bf0Spatrick static uint64_t resolveRISCV(uint64_t Type, uint64_t Offset, uint64_t S,
45573471bf0Spatrick                              uint64_t LocData, int64_t Addend) {
45673471bf0Spatrick   int64_t RA = Addend;
45773471bf0Spatrick   uint64_t A = LocData;
45873471bf0Spatrick   switch (Type) {
45909467b48Spatrick   case ELF::R_RISCV_NONE:
46073471bf0Spatrick     return LocData;
46109467b48Spatrick   case ELF::R_RISCV_32:
46209467b48Spatrick     return (S + RA) & 0xFFFFFFFF;
46309467b48Spatrick   case ELF::R_RISCV_32_PCREL:
46473471bf0Spatrick     return (S + RA - Offset) & 0xFFFFFFFF;
46509467b48Spatrick   case ELF::R_RISCV_64:
46609467b48Spatrick     return S + RA;
46709467b48Spatrick   case ELF::R_RISCV_SET6:
46809467b48Spatrick     return (A & 0xC0) | ((S + RA) & 0x3F);
46909467b48Spatrick   case ELF::R_RISCV_SUB6:
47009467b48Spatrick     return (A & 0xC0) | (((A & 0x3F) - (S + RA)) & 0x3F);
471*d415bd75Srobert   case ELF::R_RISCV_SET8:
472*d415bd75Srobert     return (S + RA) & 0xFF;
47309467b48Spatrick   case ELF::R_RISCV_ADD8:
47409467b48Spatrick     return (A + (S + RA)) & 0xFF;
47509467b48Spatrick   case ELF::R_RISCV_SUB8:
47609467b48Spatrick     return (A - (S + RA)) & 0xFF;
477*d415bd75Srobert   case ELF::R_RISCV_SET16:
478*d415bd75Srobert     return (S + RA) & 0xFFFF;
47909467b48Spatrick   case ELF::R_RISCV_ADD16:
48009467b48Spatrick     return (A + (S + RA)) & 0xFFFF;
48109467b48Spatrick   case ELF::R_RISCV_SUB16:
48209467b48Spatrick     return (A - (S + RA)) & 0xFFFF;
483*d415bd75Srobert   case ELF::R_RISCV_SET32:
484*d415bd75Srobert     return (S + RA) & 0xFFFFFFFF;
48509467b48Spatrick   case ELF::R_RISCV_ADD32:
48609467b48Spatrick     return (A + (S + RA)) & 0xFFFFFFFF;
48709467b48Spatrick   case ELF::R_RISCV_SUB32:
48809467b48Spatrick     return (A - (S + RA)) & 0xFFFFFFFF;
48909467b48Spatrick   case ELF::R_RISCV_ADD64:
49009467b48Spatrick     return (A + (S + RA));
49109467b48Spatrick   case ELF::R_RISCV_SUB64:
49209467b48Spatrick     return (A - (S + RA));
49309467b48Spatrick   default:
49409467b48Spatrick     llvm_unreachable("Invalid relocation type");
49509467b48Spatrick   }
49609467b48Spatrick }
49709467b48Spatrick 
supportsCSKY(uint64_t Type)498*d415bd75Srobert static bool supportsCSKY(uint64_t Type) {
499*d415bd75Srobert   switch (Type) {
500*d415bd75Srobert   case ELF::R_CKCORE_NONE:
501*d415bd75Srobert   case ELF::R_CKCORE_ADDR32:
502*d415bd75Srobert   case ELF::R_CKCORE_PCREL32:
503*d415bd75Srobert     return true;
504*d415bd75Srobert   default:
505*d415bd75Srobert     return false;
506*d415bd75Srobert   }
507*d415bd75Srobert }
508*d415bd75Srobert 
resolveCSKY(uint64_t Type,uint64_t Offset,uint64_t S,uint64_t LocData,int64_t Addend)509*d415bd75Srobert static uint64_t resolveCSKY(uint64_t Type, uint64_t Offset, uint64_t S,
510*d415bd75Srobert                             uint64_t LocData, int64_t Addend) {
511*d415bd75Srobert   switch (Type) {
512*d415bd75Srobert   case ELF::R_CKCORE_NONE:
513*d415bd75Srobert     return LocData;
514*d415bd75Srobert   case ELF::R_CKCORE_ADDR32:
515*d415bd75Srobert     return (S + Addend) & 0xFFFFFFFF;
516*d415bd75Srobert   case ELF::R_CKCORE_PCREL32:
517*d415bd75Srobert     return (S + Addend - Offset) & 0xFFFFFFFF;
518*d415bd75Srobert   default:
519*d415bd75Srobert     llvm_unreachable("Invalid relocation type");
520*d415bd75Srobert   }
521*d415bd75Srobert }
522*d415bd75Srobert 
supportsLoongArch(uint64_t Type)523*d415bd75Srobert static bool supportsLoongArch(uint64_t Type) {
524*d415bd75Srobert   switch (Type) {
525*d415bd75Srobert   case ELF::R_LARCH_NONE:
526*d415bd75Srobert   case ELF::R_LARCH_32:
527*d415bd75Srobert   case ELF::R_LARCH_32_PCREL:
528*d415bd75Srobert   case ELF::R_LARCH_64:
529*d415bd75Srobert   case ELF::R_LARCH_ADD8:
530*d415bd75Srobert   case ELF::R_LARCH_SUB8:
531*d415bd75Srobert   case ELF::R_LARCH_ADD16:
532*d415bd75Srobert   case ELF::R_LARCH_SUB16:
533*d415bd75Srobert   case ELF::R_LARCH_ADD32:
534*d415bd75Srobert   case ELF::R_LARCH_SUB32:
535*d415bd75Srobert   case ELF::R_LARCH_ADD64:
536*d415bd75Srobert   case ELF::R_LARCH_SUB64:
537*d415bd75Srobert     return true;
538*d415bd75Srobert   default:
539*d415bd75Srobert     return false;
540*d415bd75Srobert   }
541*d415bd75Srobert }
542*d415bd75Srobert 
resolveLoongArch(uint64_t Type,uint64_t Offset,uint64_t S,uint64_t LocData,int64_t Addend)543*d415bd75Srobert static uint64_t resolveLoongArch(uint64_t Type, uint64_t Offset, uint64_t S,
544*d415bd75Srobert                                  uint64_t LocData, int64_t Addend) {
545*d415bd75Srobert   switch (Type) {
546*d415bd75Srobert   case ELF::R_LARCH_NONE:
547*d415bd75Srobert     return LocData;
548*d415bd75Srobert   case ELF::R_LARCH_32:
549*d415bd75Srobert     return (S + Addend) & 0xFFFFFFFF;
550*d415bd75Srobert   case ELF::R_LARCH_32_PCREL:
551*d415bd75Srobert     return (S + Addend - Offset) & 0xFFFFFFFF;
552*d415bd75Srobert   case ELF::R_LARCH_64:
553*d415bd75Srobert     return S + Addend;
554*d415bd75Srobert   case ELF::R_LARCH_ADD8:
555*d415bd75Srobert     return (LocData + (S + Addend)) & 0xFF;
556*d415bd75Srobert   case ELF::R_LARCH_SUB8:
557*d415bd75Srobert     return (LocData - (S + Addend)) & 0xFF;
558*d415bd75Srobert   case ELF::R_LARCH_ADD16:
559*d415bd75Srobert     return (LocData + (S + Addend)) & 0xFFFF;
560*d415bd75Srobert   case ELF::R_LARCH_SUB16:
561*d415bd75Srobert     return (LocData - (S + Addend)) & 0xFFFF;
562*d415bd75Srobert   case ELF::R_LARCH_ADD32:
563*d415bd75Srobert     return (LocData + (S + Addend)) & 0xFFFFFFFF;
564*d415bd75Srobert   case ELF::R_LARCH_SUB32:
565*d415bd75Srobert     return (LocData - (S + Addend)) & 0xFFFFFFFF;
566*d415bd75Srobert   case ELF::R_LARCH_ADD64:
567*d415bd75Srobert     return (LocData + (S + Addend));
568*d415bd75Srobert   case ELF::R_LARCH_SUB64:
569*d415bd75Srobert     return (LocData - (S + Addend));
570*d415bd75Srobert   default:
571*d415bd75Srobert     llvm_unreachable("Invalid relocation type");
572*d415bd75Srobert   }
573*d415bd75Srobert }
574*d415bd75Srobert 
supportsCOFFX86(uint64_t Type)57509467b48Spatrick static bool supportsCOFFX86(uint64_t Type) {
57609467b48Spatrick   switch (Type) {
57709467b48Spatrick   case COFF::IMAGE_REL_I386_SECREL:
57809467b48Spatrick   case COFF::IMAGE_REL_I386_DIR32:
57909467b48Spatrick     return true;
58009467b48Spatrick   default:
58109467b48Spatrick     return false;
58209467b48Spatrick   }
58309467b48Spatrick }
58409467b48Spatrick 
resolveCOFFX86(uint64_t Type,uint64_t Offset,uint64_t S,uint64_t LocData,int64_t)58573471bf0Spatrick static uint64_t resolveCOFFX86(uint64_t Type, uint64_t Offset, uint64_t S,
58673471bf0Spatrick                                uint64_t LocData, int64_t /*Addend*/) {
58773471bf0Spatrick   switch (Type) {
58809467b48Spatrick   case COFF::IMAGE_REL_I386_SECREL:
58909467b48Spatrick   case COFF::IMAGE_REL_I386_DIR32:
59073471bf0Spatrick     return (S + LocData) & 0xFFFFFFFF;
59109467b48Spatrick   default:
59209467b48Spatrick     llvm_unreachable("Invalid relocation type");
59309467b48Spatrick   }
59409467b48Spatrick }
59509467b48Spatrick 
supportsCOFFX86_64(uint64_t Type)59609467b48Spatrick static bool supportsCOFFX86_64(uint64_t Type) {
59709467b48Spatrick   switch (Type) {
59809467b48Spatrick   case COFF::IMAGE_REL_AMD64_SECREL:
59909467b48Spatrick   case COFF::IMAGE_REL_AMD64_ADDR64:
60009467b48Spatrick     return true;
60109467b48Spatrick   default:
60209467b48Spatrick     return false;
60309467b48Spatrick   }
60409467b48Spatrick }
60509467b48Spatrick 
resolveCOFFX86_64(uint64_t Type,uint64_t Offset,uint64_t S,uint64_t LocData,int64_t)60673471bf0Spatrick static uint64_t resolveCOFFX86_64(uint64_t Type, uint64_t Offset, uint64_t S,
60773471bf0Spatrick                                   uint64_t LocData, int64_t /*Addend*/) {
60873471bf0Spatrick   switch (Type) {
60909467b48Spatrick   case COFF::IMAGE_REL_AMD64_SECREL:
61073471bf0Spatrick     return (S + LocData) & 0xFFFFFFFF;
61109467b48Spatrick   case COFF::IMAGE_REL_AMD64_ADDR64:
61273471bf0Spatrick     return S + LocData;
61309467b48Spatrick   default:
61409467b48Spatrick     llvm_unreachable("Invalid relocation type");
61509467b48Spatrick   }
61609467b48Spatrick }
61709467b48Spatrick 
supportsCOFFARM(uint64_t Type)61809467b48Spatrick static bool supportsCOFFARM(uint64_t Type) {
61909467b48Spatrick   switch (Type) {
62009467b48Spatrick   case COFF::IMAGE_REL_ARM_SECREL:
62109467b48Spatrick   case COFF::IMAGE_REL_ARM_ADDR32:
62209467b48Spatrick     return true;
62309467b48Spatrick   default:
62409467b48Spatrick     return false;
62509467b48Spatrick   }
62609467b48Spatrick }
62709467b48Spatrick 
resolveCOFFARM(uint64_t Type,uint64_t Offset,uint64_t S,uint64_t LocData,int64_t)62873471bf0Spatrick static uint64_t resolveCOFFARM(uint64_t Type, uint64_t Offset, uint64_t S,
62973471bf0Spatrick                                uint64_t LocData, int64_t /*Addend*/) {
63073471bf0Spatrick   switch (Type) {
63109467b48Spatrick   case COFF::IMAGE_REL_ARM_SECREL:
63209467b48Spatrick   case COFF::IMAGE_REL_ARM_ADDR32:
63373471bf0Spatrick     return (S + LocData) & 0xFFFFFFFF;
63409467b48Spatrick   default:
63509467b48Spatrick     llvm_unreachable("Invalid relocation type");
63609467b48Spatrick   }
63709467b48Spatrick }
63809467b48Spatrick 
supportsCOFFARM64(uint64_t Type)63909467b48Spatrick static bool supportsCOFFARM64(uint64_t Type) {
64009467b48Spatrick   switch (Type) {
64109467b48Spatrick   case COFF::IMAGE_REL_ARM64_SECREL:
64209467b48Spatrick   case COFF::IMAGE_REL_ARM64_ADDR64:
64309467b48Spatrick     return true;
64409467b48Spatrick   default:
64509467b48Spatrick     return false;
64609467b48Spatrick   }
64709467b48Spatrick }
64809467b48Spatrick 
resolveCOFFARM64(uint64_t Type,uint64_t Offset,uint64_t S,uint64_t LocData,int64_t)64973471bf0Spatrick static uint64_t resolveCOFFARM64(uint64_t Type, uint64_t Offset, uint64_t S,
65073471bf0Spatrick                                  uint64_t LocData, int64_t /*Addend*/) {
65173471bf0Spatrick   switch (Type) {
65209467b48Spatrick   case COFF::IMAGE_REL_ARM64_SECREL:
65373471bf0Spatrick     return (S + LocData) & 0xFFFFFFFF;
65409467b48Spatrick   case COFF::IMAGE_REL_ARM64_ADDR64:
65573471bf0Spatrick     return S + LocData;
65609467b48Spatrick   default:
65709467b48Spatrick     llvm_unreachable("Invalid relocation type");
65809467b48Spatrick   }
65909467b48Spatrick }
66009467b48Spatrick 
supportsMachOX86_64(uint64_t Type)66109467b48Spatrick static bool supportsMachOX86_64(uint64_t Type) {
66209467b48Spatrick   return Type == MachO::X86_64_RELOC_UNSIGNED;
66309467b48Spatrick }
66409467b48Spatrick 
resolveMachOX86_64(uint64_t Type,uint64_t Offset,uint64_t S,uint64_t LocData,int64_t)66573471bf0Spatrick static uint64_t resolveMachOX86_64(uint64_t Type, uint64_t Offset, uint64_t S,
66673471bf0Spatrick                                    uint64_t LocData, int64_t /*Addend*/) {
66773471bf0Spatrick   if (Type == MachO::X86_64_RELOC_UNSIGNED)
66809467b48Spatrick     return S;
66909467b48Spatrick   llvm_unreachable("Invalid relocation type");
67009467b48Spatrick }
67109467b48Spatrick 
supportsWasm32(uint64_t Type)67209467b48Spatrick static bool supportsWasm32(uint64_t Type) {
67309467b48Spatrick   switch (Type) {
67409467b48Spatrick   case wasm::R_WASM_FUNCTION_INDEX_LEB:
67509467b48Spatrick   case wasm::R_WASM_TABLE_INDEX_SLEB:
67609467b48Spatrick   case wasm::R_WASM_TABLE_INDEX_I32:
67709467b48Spatrick   case wasm::R_WASM_MEMORY_ADDR_LEB:
67809467b48Spatrick   case wasm::R_WASM_MEMORY_ADDR_SLEB:
67909467b48Spatrick   case wasm::R_WASM_MEMORY_ADDR_I32:
68009467b48Spatrick   case wasm::R_WASM_TYPE_INDEX_LEB:
68109467b48Spatrick   case wasm::R_WASM_GLOBAL_INDEX_LEB:
68209467b48Spatrick   case wasm::R_WASM_FUNCTION_OFFSET_I32:
68309467b48Spatrick   case wasm::R_WASM_SECTION_OFFSET_I32:
68473471bf0Spatrick   case wasm::R_WASM_TAG_INDEX_LEB:
685097a140dSpatrick   case wasm::R_WASM_GLOBAL_INDEX_I32:
68673471bf0Spatrick   case wasm::R_WASM_TABLE_NUMBER_LEB:
68773471bf0Spatrick   case wasm::R_WASM_MEMORY_ADDR_LOCREL_I32:
68809467b48Spatrick     return true;
68909467b48Spatrick   default:
69009467b48Spatrick     return false;
69109467b48Spatrick   }
69209467b48Spatrick }
69309467b48Spatrick 
supportsWasm64(uint64_t Type)694097a140dSpatrick static bool supportsWasm64(uint64_t Type) {
695097a140dSpatrick   switch (Type) {
696097a140dSpatrick   case wasm::R_WASM_MEMORY_ADDR_LEB64:
697097a140dSpatrick   case wasm::R_WASM_MEMORY_ADDR_SLEB64:
698097a140dSpatrick   case wasm::R_WASM_MEMORY_ADDR_I64:
69973471bf0Spatrick   case wasm::R_WASM_TABLE_INDEX_SLEB64:
70073471bf0Spatrick   case wasm::R_WASM_TABLE_INDEX_I64:
70173471bf0Spatrick   case wasm::R_WASM_FUNCTION_OFFSET_I64:
702097a140dSpatrick     return true;
703097a140dSpatrick   default:
704097a140dSpatrick     return supportsWasm32(Type);
705097a140dSpatrick   }
706097a140dSpatrick }
707097a140dSpatrick 
resolveWasm32(uint64_t Type,uint64_t Offset,uint64_t S,uint64_t LocData,int64_t)70873471bf0Spatrick static uint64_t resolveWasm32(uint64_t Type, uint64_t Offset, uint64_t S,
70973471bf0Spatrick                               uint64_t LocData, int64_t /*Addend*/) {
71073471bf0Spatrick   switch (Type) {
71109467b48Spatrick   case wasm::R_WASM_FUNCTION_INDEX_LEB:
71209467b48Spatrick   case wasm::R_WASM_TABLE_INDEX_SLEB:
71309467b48Spatrick   case wasm::R_WASM_TABLE_INDEX_I32:
71409467b48Spatrick   case wasm::R_WASM_MEMORY_ADDR_LEB:
71509467b48Spatrick   case wasm::R_WASM_MEMORY_ADDR_SLEB:
71609467b48Spatrick   case wasm::R_WASM_MEMORY_ADDR_I32:
71709467b48Spatrick   case wasm::R_WASM_TYPE_INDEX_LEB:
71809467b48Spatrick   case wasm::R_WASM_GLOBAL_INDEX_LEB:
71909467b48Spatrick   case wasm::R_WASM_FUNCTION_OFFSET_I32:
72009467b48Spatrick   case wasm::R_WASM_SECTION_OFFSET_I32:
72173471bf0Spatrick   case wasm::R_WASM_TAG_INDEX_LEB:
722097a140dSpatrick   case wasm::R_WASM_GLOBAL_INDEX_I32:
72373471bf0Spatrick   case wasm::R_WASM_TABLE_NUMBER_LEB:
72473471bf0Spatrick   case wasm::R_WASM_MEMORY_ADDR_LOCREL_I32:
72509467b48Spatrick     // For wasm section, its offset at 0 -- ignoring Value
72673471bf0Spatrick     return LocData;
72709467b48Spatrick   default:
72809467b48Spatrick     llvm_unreachable("Invalid relocation type");
72909467b48Spatrick   }
73009467b48Spatrick }
73109467b48Spatrick 
resolveWasm64(uint64_t Type,uint64_t Offset,uint64_t S,uint64_t LocData,int64_t Addend)73273471bf0Spatrick static uint64_t resolveWasm64(uint64_t Type, uint64_t Offset, uint64_t S,
73373471bf0Spatrick                               uint64_t LocData, int64_t Addend) {
73473471bf0Spatrick   switch (Type) {
735097a140dSpatrick   case wasm::R_WASM_MEMORY_ADDR_LEB64:
736097a140dSpatrick   case wasm::R_WASM_MEMORY_ADDR_SLEB64:
737097a140dSpatrick   case wasm::R_WASM_MEMORY_ADDR_I64:
73873471bf0Spatrick   case wasm::R_WASM_TABLE_INDEX_SLEB64:
73973471bf0Spatrick   case wasm::R_WASM_TABLE_INDEX_I64:
74073471bf0Spatrick   case wasm::R_WASM_FUNCTION_OFFSET_I64:
741097a140dSpatrick     // For wasm section, its offset at 0 -- ignoring Value
74273471bf0Spatrick     return LocData;
743097a140dSpatrick   default:
74473471bf0Spatrick     return resolveWasm32(Type, Offset, S, LocData, Addend);
745097a140dSpatrick   }
746097a140dSpatrick }
747097a140dSpatrick 
74873471bf0Spatrick std::pair<SupportsRelocation, RelocationResolver>
getRelocationResolver(const ObjectFile & Obj)74909467b48Spatrick getRelocationResolver(const ObjectFile &Obj) {
75009467b48Spatrick   if (Obj.isCOFF()) {
75109467b48Spatrick     switch (Obj.getArch()) {
75209467b48Spatrick     case Triple::x86_64:
75309467b48Spatrick       return {supportsCOFFX86_64, resolveCOFFX86_64};
75409467b48Spatrick     case Triple::x86:
75509467b48Spatrick       return {supportsCOFFX86, resolveCOFFX86};
75609467b48Spatrick     case Triple::arm:
75709467b48Spatrick     case Triple::thumb:
75809467b48Spatrick       return {supportsCOFFARM, resolveCOFFARM};
75909467b48Spatrick     case Triple::aarch64:
76009467b48Spatrick       return {supportsCOFFARM64, resolveCOFFARM64};
76109467b48Spatrick     default:
76209467b48Spatrick       return {nullptr, nullptr};
76309467b48Spatrick     }
76409467b48Spatrick   } else if (Obj.isELF()) {
76509467b48Spatrick     if (Obj.getBytesInAddress() == 8) {
76609467b48Spatrick       switch (Obj.getArch()) {
76709467b48Spatrick       case Triple::x86_64:
76809467b48Spatrick         return {supportsX86_64, resolveX86_64};
76909467b48Spatrick       case Triple::aarch64:
77009467b48Spatrick       case Triple::aarch64_be:
77109467b48Spatrick         return {supportsAArch64, resolveAArch64};
77209467b48Spatrick       case Triple::bpfel:
77309467b48Spatrick       case Triple::bpfeb:
77409467b48Spatrick         return {supportsBPF, resolveBPF};
775*d415bd75Srobert       case Triple::loongarch64:
776*d415bd75Srobert         return {supportsLoongArch, resolveLoongArch};
77709467b48Spatrick       case Triple::mips64el:
77809467b48Spatrick       case Triple::mips64:
77909467b48Spatrick         return {supportsMips64, resolveMips64};
78009467b48Spatrick       case Triple::ppc64le:
78109467b48Spatrick       case Triple::ppc64:
78209467b48Spatrick         return {supportsPPC64, resolvePPC64};
78309467b48Spatrick       case Triple::systemz:
78409467b48Spatrick         return {supportsSystemZ, resolveSystemZ};
78509467b48Spatrick       case Triple::sparcv9:
78609467b48Spatrick         return {supportsSparc64, resolveSparc64};
78709467b48Spatrick       case Triple::amdgcn:
78809467b48Spatrick         return {supportsAmdgpu, resolveAmdgpu};
78909467b48Spatrick       case Triple::riscv64:
79009467b48Spatrick         return {supportsRISCV, resolveRISCV};
79109467b48Spatrick       default:
79209467b48Spatrick         return {nullptr, nullptr};
79309467b48Spatrick       }
79409467b48Spatrick     }
79509467b48Spatrick 
79609467b48Spatrick     // 32-bit object file
79709467b48Spatrick     assert(Obj.getBytesInAddress() == 4 &&
79809467b48Spatrick            "Invalid word size in object file");
79909467b48Spatrick 
80009467b48Spatrick     switch (Obj.getArch()) {
80109467b48Spatrick     case Triple::x86:
80209467b48Spatrick       return {supportsX86, resolveX86};
80373471bf0Spatrick     case Triple::ppcle:
80409467b48Spatrick     case Triple::ppc:
80509467b48Spatrick       return {supportsPPC32, resolvePPC32};
80609467b48Spatrick     case Triple::arm:
80709467b48Spatrick     case Triple::armeb:
80809467b48Spatrick       return {supportsARM, resolveARM};
80909467b48Spatrick     case Triple::avr:
81009467b48Spatrick       return {supportsAVR, resolveAVR};
81109467b48Spatrick     case Triple::lanai:
81209467b48Spatrick       return {supportsLanai, resolveLanai};
813*d415bd75Srobert     case Triple::loongarch32:
814*d415bd75Srobert       return {supportsLoongArch, resolveLoongArch};
81509467b48Spatrick     case Triple::mipsel:
81609467b48Spatrick     case Triple::mips:
81709467b48Spatrick       return {supportsMips32, resolveMips32};
818097a140dSpatrick     case Triple::msp430:
819097a140dSpatrick       return {supportsMSP430, resolveMSP430};
82009467b48Spatrick     case Triple::sparc:
82109467b48Spatrick       return {supportsSparc32, resolveSparc32};
82209467b48Spatrick     case Triple::hexagon:
82309467b48Spatrick       return {supportsHexagon, resolveHexagon};
82409467b48Spatrick     case Triple::riscv32:
82509467b48Spatrick       return {supportsRISCV, resolveRISCV};
826*d415bd75Srobert     case Triple::csky:
827*d415bd75Srobert       return {supportsCSKY, resolveCSKY};
82809467b48Spatrick     default:
82909467b48Spatrick       return {nullptr, nullptr};
83009467b48Spatrick     }
83109467b48Spatrick   } else if (Obj.isMachO()) {
83209467b48Spatrick     if (Obj.getArch() == Triple::x86_64)
83309467b48Spatrick       return {supportsMachOX86_64, resolveMachOX86_64};
83409467b48Spatrick     return {nullptr, nullptr};
83509467b48Spatrick   } else if (Obj.isWasm()) {
83609467b48Spatrick     if (Obj.getArch() == Triple::wasm32)
83709467b48Spatrick       return {supportsWasm32, resolveWasm32};
838097a140dSpatrick     if (Obj.getArch() == Triple::wasm64)
839097a140dSpatrick       return {supportsWasm64, resolveWasm64};
84009467b48Spatrick     return {nullptr, nullptr};
84109467b48Spatrick   }
84209467b48Spatrick 
84309467b48Spatrick   llvm_unreachable("Invalid object file");
84409467b48Spatrick }
84509467b48Spatrick 
resolveRelocation(RelocationResolver Resolver,const RelocationRef & R,uint64_t S,uint64_t LocData)84673471bf0Spatrick uint64_t resolveRelocation(RelocationResolver Resolver, const RelocationRef &R,
84773471bf0Spatrick                            uint64_t S, uint64_t LocData) {
84873471bf0Spatrick   if (const ObjectFile *Obj = R.getObject()) {
84973471bf0Spatrick     int64_t Addend = 0;
85073471bf0Spatrick     if (Obj->isELF()) {
85173471bf0Spatrick       auto GetRelSectionType = [&]() -> unsigned {
85273471bf0Spatrick         if (auto *Elf32LEObj = dyn_cast<ELF32LEObjectFile>(Obj))
85373471bf0Spatrick           return Elf32LEObj->getRelSection(R.getRawDataRefImpl())->sh_type;
85473471bf0Spatrick         if (auto *Elf64LEObj = dyn_cast<ELF64LEObjectFile>(Obj))
85573471bf0Spatrick           return Elf64LEObj->getRelSection(R.getRawDataRefImpl())->sh_type;
85673471bf0Spatrick         if (auto *Elf32BEObj = dyn_cast<ELF32BEObjectFile>(Obj))
85773471bf0Spatrick           return Elf32BEObj->getRelSection(R.getRawDataRefImpl())->sh_type;
85873471bf0Spatrick         auto *Elf64BEObj = cast<ELF64BEObjectFile>(Obj);
85973471bf0Spatrick         return Elf64BEObj->getRelSection(R.getRawDataRefImpl())->sh_type;
86073471bf0Spatrick       };
86173471bf0Spatrick 
86273471bf0Spatrick       if (GetRelSectionType() == ELF::SHT_RELA) {
86373471bf0Spatrick         Addend = getELFAddend(R);
86473471bf0Spatrick         // RISCV relocations use both LocData and Addend.
86573471bf0Spatrick         if (Obj->getArch() != Triple::riscv32 &&
86673471bf0Spatrick             Obj->getArch() != Triple::riscv64)
86773471bf0Spatrick           LocData = 0;
86873471bf0Spatrick       }
86973471bf0Spatrick     }
87073471bf0Spatrick 
87173471bf0Spatrick     return Resolver(R.getType(), R.getOffset(), S, LocData, Addend);
87273471bf0Spatrick   }
87373471bf0Spatrick 
87473471bf0Spatrick   // Sometimes the caller might want to use its own specific implementation of
87573471bf0Spatrick   // the resolver function. E.g. this is used by LLD when it resolves debug
87673471bf0Spatrick   // relocations and assumes that all of them have the same computation (S + A).
87773471bf0Spatrick   // The relocation R has no owner object in this case and we don't need to
87873471bf0Spatrick   // provide Type and Offset fields. It is also assumed the DataRefImpl.p
87973471bf0Spatrick   // contains the addend, provided by the caller.
88073471bf0Spatrick   return Resolver(/*Type=*/0, /*Offset=*/0, S, LocData,
88173471bf0Spatrick                   R.getRawDataRefImpl().p);
88273471bf0Spatrick }
88373471bf0Spatrick 
88409467b48Spatrick } // namespace object
88509467b48Spatrick } // namespace llvm
886