1*4597dce4SFangrui Song //===- RelocationResolver.cpp ------------------------------------*- C++ -*-===//
2*4597dce4SFangrui Song //
3*4597dce4SFangrui Song // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*4597dce4SFangrui Song // See https://llvm.org/LICENSE.txt for license information.
5*4597dce4SFangrui Song // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*4597dce4SFangrui Song //
7*4597dce4SFangrui Song //===----------------------------------------------------------------------===//
8*4597dce4SFangrui Song //
9*4597dce4SFangrui Song // This file defines utilities to resolve relocations in object files.
10*4597dce4SFangrui Song //
11*4597dce4SFangrui Song //===----------------------------------------------------------------------===//
12*4597dce4SFangrui Song 
13*4597dce4SFangrui Song #include "llvm/Object/RelocationResolver.h"
14*4597dce4SFangrui Song 
15*4597dce4SFangrui Song namespace llvm {
16*4597dce4SFangrui Song namespace object {
17*4597dce4SFangrui Song 
18*4597dce4SFangrui Song static int64_t getELFAddend(RelocationRef R) {
19*4597dce4SFangrui Song   Expected<int64_t> AddendOrErr = ELFRelocationRef(R).getAddend();
20*4597dce4SFangrui Song   handleAllErrors(AddendOrErr.takeError(), [](const ErrorInfoBase &EI) {
21*4597dce4SFangrui Song     report_fatal_error(EI.message());
22*4597dce4SFangrui Song   });
23*4597dce4SFangrui Song   return *AddendOrErr;
24*4597dce4SFangrui Song }
25*4597dce4SFangrui Song 
26*4597dce4SFangrui Song static bool supportsX86_64(uint64_t Type) {
27*4597dce4SFangrui Song   switch (Type) {
28*4597dce4SFangrui Song   case ELF::R_X86_64_NONE:
29*4597dce4SFangrui Song   case ELF::R_X86_64_64:
30*4597dce4SFangrui Song   case ELF::R_X86_64_DTPOFF32:
31*4597dce4SFangrui Song   case ELF::R_X86_64_DTPOFF64:
32*4597dce4SFangrui Song   case ELF::R_X86_64_PC32:
33*4597dce4SFangrui Song   case ELF::R_X86_64_32:
34*4597dce4SFangrui Song   case ELF::R_X86_64_32S:
35*4597dce4SFangrui Song     return true;
36*4597dce4SFangrui Song   default:
37*4597dce4SFangrui Song     return false;
38*4597dce4SFangrui Song   }
39*4597dce4SFangrui Song }
40*4597dce4SFangrui Song 
41*4597dce4SFangrui Song static uint64_t resolveX86_64(RelocationRef R, uint64_t S, uint64_t A) {
42*4597dce4SFangrui Song   switch (R.getType()) {
43*4597dce4SFangrui Song   case ELF::R_X86_64_NONE:
44*4597dce4SFangrui Song     return A;
45*4597dce4SFangrui Song   case ELF::R_X86_64_64:
46*4597dce4SFangrui Song   case ELF::R_X86_64_DTPOFF32:
47*4597dce4SFangrui Song   case ELF::R_X86_64_DTPOFF64:
48*4597dce4SFangrui Song     return S + getELFAddend(R);
49*4597dce4SFangrui Song   case ELF::R_X86_64_PC32:
50*4597dce4SFangrui Song     return S + getELFAddend(R) - R.getOffset();
51*4597dce4SFangrui Song   case ELF::R_X86_64_32:
52*4597dce4SFangrui Song   case ELF::R_X86_64_32S:
53*4597dce4SFangrui Song     return (S + getELFAddend(R)) & 0xFFFFFFFF;
54*4597dce4SFangrui Song   default:
55*4597dce4SFangrui Song     llvm_unreachable("Invalid relocation type");
56*4597dce4SFangrui Song   }
57*4597dce4SFangrui Song }
58*4597dce4SFangrui Song 
59*4597dce4SFangrui Song static bool supportsAArch64(uint64_t Type) {
60*4597dce4SFangrui Song   switch (Type) {
61*4597dce4SFangrui Song   case ELF::R_AARCH64_ABS32:
62*4597dce4SFangrui Song   case ELF::R_AARCH64_ABS64:
63*4597dce4SFangrui Song     return true;
64*4597dce4SFangrui Song   default:
65*4597dce4SFangrui Song     return false;
66*4597dce4SFangrui Song   }
67*4597dce4SFangrui Song }
68*4597dce4SFangrui Song 
69*4597dce4SFangrui Song static uint64_t resolveAArch64(RelocationRef R, uint64_t S, uint64_t A) {
70*4597dce4SFangrui Song   switch (R.getType()) {
71*4597dce4SFangrui Song   case ELF::R_AARCH64_ABS32:
72*4597dce4SFangrui Song     return (S + getELFAddend(R)) & 0xFFFFFFFF;
73*4597dce4SFangrui Song   case ELF::R_AARCH64_ABS64:
74*4597dce4SFangrui Song     return S + getELFAddend(R);
75*4597dce4SFangrui Song   default:
76*4597dce4SFangrui Song     llvm_unreachable("Invalid relocation type");
77*4597dce4SFangrui Song   }
78*4597dce4SFangrui Song }
79*4597dce4SFangrui Song 
80*4597dce4SFangrui Song static bool supportsBPF(uint64_t Type) {
81*4597dce4SFangrui Song   switch (Type) {
82*4597dce4SFangrui Song   case ELF::R_BPF_64_32:
83*4597dce4SFangrui Song   case ELF::R_BPF_64_64:
84*4597dce4SFangrui Song     return true;
85*4597dce4SFangrui Song   default:
86*4597dce4SFangrui Song     return false;
87*4597dce4SFangrui Song   }
88*4597dce4SFangrui Song }
89*4597dce4SFangrui Song 
90*4597dce4SFangrui Song static uint64_t resolveBPF(RelocationRef R, uint64_t S, uint64_t A) {
91*4597dce4SFangrui Song   switch (R.getType()) {
92*4597dce4SFangrui Song   case ELF::R_BPF_64_32:
93*4597dce4SFangrui Song     return S & 0xFFFFFFFF;
94*4597dce4SFangrui Song   case ELF::R_BPF_64_64:
95*4597dce4SFangrui Song     return S;
96*4597dce4SFangrui Song   default:
97*4597dce4SFangrui Song     llvm_unreachable("Invalid relocation type");
98*4597dce4SFangrui Song   }
99*4597dce4SFangrui Song }
100*4597dce4SFangrui Song 
101*4597dce4SFangrui Song static bool supportsMips64(uint64_t Type) {
102*4597dce4SFangrui Song   switch (Type) {
103*4597dce4SFangrui Song   case ELF::R_MIPS_32:
104*4597dce4SFangrui Song   case ELF::R_MIPS_64:
105*4597dce4SFangrui Song   case ELF::R_MIPS_TLS_DTPREL64:
106*4597dce4SFangrui Song     return true;
107*4597dce4SFangrui Song   default:
108*4597dce4SFangrui Song     return false;
109*4597dce4SFangrui Song   }
110*4597dce4SFangrui Song }
111*4597dce4SFangrui Song 
112*4597dce4SFangrui Song static uint64_t resolveMips64(RelocationRef R, uint64_t S, uint64_t A) {
113*4597dce4SFangrui Song   switch (R.getType()) {
114*4597dce4SFangrui Song   case ELF::R_MIPS_32:
115*4597dce4SFangrui Song     return (S + getELFAddend(R)) & 0xFFFFFFFF;
116*4597dce4SFangrui Song   case ELF::R_MIPS_64:
117*4597dce4SFangrui Song     return S + getELFAddend(R);
118*4597dce4SFangrui Song   case ELF::R_MIPS_TLS_DTPREL64:
119*4597dce4SFangrui Song     return S + getELFAddend(R) - 0x8000;
120*4597dce4SFangrui Song   default:
121*4597dce4SFangrui Song     llvm_unreachable("Invalid relocation type");
122*4597dce4SFangrui Song   }
123*4597dce4SFangrui Song }
124*4597dce4SFangrui Song 
125*4597dce4SFangrui Song static bool supportsPPC64(uint64_t Type) {
126*4597dce4SFangrui Song   switch (Type) {
127*4597dce4SFangrui Song   case ELF::R_PPC64_ADDR32:
128*4597dce4SFangrui Song   case ELF::R_PPC64_ADDR64:
129*4597dce4SFangrui Song     return true;
130*4597dce4SFangrui Song   default:
131*4597dce4SFangrui Song     return false;
132*4597dce4SFangrui Song   }
133*4597dce4SFangrui Song }
134*4597dce4SFangrui Song 
135*4597dce4SFangrui Song static uint64_t resolvePPC64(RelocationRef R, uint64_t S, uint64_t A) {
136*4597dce4SFangrui Song   switch (R.getType()) {
137*4597dce4SFangrui Song   case ELF::R_PPC64_ADDR32:
138*4597dce4SFangrui Song     return (S + getELFAddend(R)) & 0xFFFFFFFF;
139*4597dce4SFangrui Song   case ELF::R_PPC64_ADDR64:
140*4597dce4SFangrui Song     return S + getELFAddend(R);
141*4597dce4SFangrui Song   default:
142*4597dce4SFangrui Song     llvm_unreachable("Invalid relocation type");
143*4597dce4SFangrui Song   }
144*4597dce4SFangrui Song }
145*4597dce4SFangrui Song 
146*4597dce4SFangrui Song static bool supportsSystemZ(uint64_t Type) {
147*4597dce4SFangrui Song   switch (Type) {
148*4597dce4SFangrui Song   case ELF::R_390_32:
149*4597dce4SFangrui Song   case ELF::R_390_64:
150*4597dce4SFangrui Song     return true;
151*4597dce4SFangrui Song   default:
152*4597dce4SFangrui Song     return false;
153*4597dce4SFangrui Song   }
154*4597dce4SFangrui Song }
155*4597dce4SFangrui Song 
156*4597dce4SFangrui Song static uint64_t resolveSystemZ(RelocationRef R, uint64_t S, uint64_t A) {
157*4597dce4SFangrui Song   switch (R.getType()) {
158*4597dce4SFangrui Song   case ELF::R_390_32:
159*4597dce4SFangrui Song     return (S + getELFAddend(R)) & 0xFFFFFFFF;
160*4597dce4SFangrui Song   case ELF::R_390_64:
161*4597dce4SFangrui Song     return S + getELFAddend(R);
162*4597dce4SFangrui Song   default:
163*4597dce4SFangrui Song     llvm_unreachable("Invalid relocation type");
164*4597dce4SFangrui Song   }
165*4597dce4SFangrui Song }
166*4597dce4SFangrui Song 
167*4597dce4SFangrui Song static bool supportsSparc64(uint64_t Type) {
168*4597dce4SFangrui Song   switch (Type) {
169*4597dce4SFangrui Song   case ELF::R_SPARC_32:
170*4597dce4SFangrui Song   case ELF::R_SPARC_64:
171*4597dce4SFangrui Song   case ELF::R_SPARC_UA32:
172*4597dce4SFangrui Song   case ELF::R_SPARC_UA64:
173*4597dce4SFangrui Song     return true;
174*4597dce4SFangrui Song   default:
175*4597dce4SFangrui Song     return false;
176*4597dce4SFangrui Song   }
177*4597dce4SFangrui Song }
178*4597dce4SFangrui Song 
179*4597dce4SFangrui Song static uint64_t resolveSparc64(RelocationRef R, uint64_t S, uint64_t A) {
180*4597dce4SFangrui Song   switch (R.getType()) {
181*4597dce4SFangrui Song   case ELF::R_SPARC_32:
182*4597dce4SFangrui Song   case ELF::R_SPARC_64:
183*4597dce4SFangrui Song   case ELF::R_SPARC_UA32:
184*4597dce4SFangrui Song   case ELF::R_SPARC_UA64:
185*4597dce4SFangrui Song     return S + getELFAddend(R);
186*4597dce4SFangrui Song   default:
187*4597dce4SFangrui Song     llvm_unreachable("Invalid relocation type");
188*4597dce4SFangrui Song   }
189*4597dce4SFangrui Song }
190*4597dce4SFangrui Song 
191*4597dce4SFangrui Song static bool supportsAmdgpu(uint64_t Type) {
192*4597dce4SFangrui Song   switch (Type) {
193*4597dce4SFangrui Song   case ELF::R_AMDGPU_ABS32:
194*4597dce4SFangrui Song   case ELF::R_AMDGPU_ABS64:
195*4597dce4SFangrui Song     return true;
196*4597dce4SFangrui Song   default:
197*4597dce4SFangrui Song     return false;
198*4597dce4SFangrui Song   }
199*4597dce4SFangrui Song }
200*4597dce4SFangrui Song 
201*4597dce4SFangrui Song static uint64_t resolveAmdgpu(RelocationRef R, uint64_t S, uint64_t A) {
202*4597dce4SFangrui Song   switch (R.getType()) {
203*4597dce4SFangrui Song   case ELF::R_AMDGPU_ABS32:
204*4597dce4SFangrui Song   case ELF::R_AMDGPU_ABS64:
205*4597dce4SFangrui Song     return S + getELFAddend(R);
206*4597dce4SFangrui Song   default:
207*4597dce4SFangrui Song     llvm_unreachable("Invalid relocation type");
208*4597dce4SFangrui Song   }
209*4597dce4SFangrui Song }
210*4597dce4SFangrui Song 
211*4597dce4SFangrui Song static bool supportsX86(uint64_t Type) {
212*4597dce4SFangrui Song   switch (Type) {
213*4597dce4SFangrui Song   case ELF::R_386_NONE:
214*4597dce4SFangrui Song   case ELF::R_386_32:
215*4597dce4SFangrui Song   case ELF::R_386_PC32:
216*4597dce4SFangrui Song     return true;
217*4597dce4SFangrui Song   default:
218*4597dce4SFangrui Song     return false;
219*4597dce4SFangrui Song   }
220*4597dce4SFangrui Song }
221*4597dce4SFangrui Song 
222*4597dce4SFangrui Song static uint64_t resolveX86(RelocationRef R, uint64_t S, uint64_t A) {
223*4597dce4SFangrui Song   switch (R.getType()) {
224*4597dce4SFangrui Song   case ELF::R_386_NONE:
225*4597dce4SFangrui Song     return A;
226*4597dce4SFangrui Song   case ELF::R_386_32:
227*4597dce4SFangrui Song     return S + A;
228*4597dce4SFangrui Song   case ELF::R_386_PC32:
229*4597dce4SFangrui Song     return S - R.getOffset() + A;
230*4597dce4SFangrui Song   default:
231*4597dce4SFangrui Song     llvm_unreachable("Invalid relocation type");
232*4597dce4SFangrui Song   }
233*4597dce4SFangrui Song }
234*4597dce4SFangrui Song 
235*4597dce4SFangrui Song static bool supportsPPC32(uint64_t Type) {
236*4597dce4SFangrui Song   return Type == ELF::R_PPC_ADDR32;
237*4597dce4SFangrui Song }
238*4597dce4SFangrui Song 
239*4597dce4SFangrui Song static uint64_t resolvePPC32(RelocationRef R, uint64_t S, uint64_t A) {
240*4597dce4SFangrui Song   if (R.getType() == ELF::R_PPC_ADDR32)
241*4597dce4SFangrui Song     return (S + getELFAddend(R)) & 0xFFFFFFFF;
242*4597dce4SFangrui Song   llvm_unreachable("Invalid relocation type");
243*4597dce4SFangrui Song }
244*4597dce4SFangrui Song 
245*4597dce4SFangrui Song static bool supportsARM(uint64_t Type) {
246*4597dce4SFangrui Song   return Type == ELF::R_ARM_ABS32;
247*4597dce4SFangrui Song }
248*4597dce4SFangrui Song 
249*4597dce4SFangrui Song static uint64_t resolveARM(RelocationRef R, uint64_t S, uint64_t A) {
250*4597dce4SFangrui Song   if (R.getType() == ELF::R_ARM_ABS32)
251*4597dce4SFangrui Song     return (S + A) & 0xFFFFFFFF;
252*4597dce4SFangrui Song   llvm_unreachable("Invalid relocation type");
253*4597dce4SFangrui Song }
254*4597dce4SFangrui Song 
255*4597dce4SFangrui Song static bool supportsAVR(uint64_t Type) {
256*4597dce4SFangrui Song   switch (Type) {
257*4597dce4SFangrui Song   case ELF::R_AVR_16:
258*4597dce4SFangrui Song   case ELF::R_AVR_32:
259*4597dce4SFangrui Song     return true;
260*4597dce4SFangrui Song   default:
261*4597dce4SFangrui Song     return false;
262*4597dce4SFangrui Song   }
263*4597dce4SFangrui Song }
264*4597dce4SFangrui Song 
265*4597dce4SFangrui Song static uint64_t resolveAVR(RelocationRef R, uint64_t S, uint64_t A) {
266*4597dce4SFangrui Song   switch (R.getType()) {
267*4597dce4SFangrui Song   case ELF::R_AVR_16:
268*4597dce4SFangrui Song     return (S + getELFAddend(R)) & 0xFFFF;
269*4597dce4SFangrui Song   case ELF::R_AVR_32:
270*4597dce4SFangrui Song     return (S + getELFAddend(R)) & 0xFFFFFFFF;
271*4597dce4SFangrui Song   default:
272*4597dce4SFangrui Song     llvm_unreachable("Invalid relocation type");
273*4597dce4SFangrui Song   }
274*4597dce4SFangrui Song }
275*4597dce4SFangrui Song 
276*4597dce4SFangrui Song static bool supportsLanai(uint64_t Type) {
277*4597dce4SFangrui Song   return Type == ELF::R_LANAI_32;
278*4597dce4SFangrui Song }
279*4597dce4SFangrui Song 
280*4597dce4SFangrui Song static uint64_t resolveLanai(RelocationRef R, uint64_t S, uint64_t A) {
281*4597dce4SFangrui Song   if (R.getType() == ELF::R_LANAI_32)
282*4597dce4SFangrui Song     return (S + getELFAddend(R)) & 0xFFFFFFFF;
283*4597dce4SFangrui Song   llvm_unreachable("Invalid relocation type");
284*4597dce4SFangrui Song }
285*4597dce4SFangrui Song 
286*4597dce4SFangrui Song static bool supportsMips32(uint64_t Type) {
287*4597dce4SFangrui Song   switch (Type) {
288*4597dce4SFangrui Song   case ELF::R_MIPS_32:
289*4597dce4SFangrui Song   case ELF::R_MIPS_TLS_DTPREL32:
290*4597dce4SFangrui Song     return true;
291*4597dce4SFangrui Song   default:
292*4597dce4SFangrui Song     return false;
293*4597dce4SFangrui Song   }
294*4597dce4SFangrui Song }
295*4597dce4SFangrui Song 
296*4597dce4SFangrui Song static uint64_t resolveMips32(RelocationRef R, uint64_t S, uint64_t A) {
297*4597dce4SFangrui Song   // FIXME: Take in account implicit addends to get correct results.
298*4597dce4SFangrui Song   uint32_t Rel = R.getType();
299*4597dce4SFangrui Song   if (Rel == ELF::R_MIPS_32)
300*4597dce4SFangrui Song     return (S + A) & 0xFFFFFFFF;
301*4597dce4SFangrui Song   if (Rel == ELF::R_MIPS_TLS_DTPREL32)
302*4597dce4SFangrui Song     return (S + A) & 0xFFFFFFFF;
303*4597dce4SFangrui Song   llvm_unreachable("Invalid relocation type");
304*4597dce4SFangrui Song }
305*4597dce4SFangrui Song 
306*4597dce4SFangrui Song static bool supportsSparc32(uint64_t Type) {
307*4597dce4SFangrui Song   switch (Type) {
308*4597dce4SFangrui Song   case ELF::R_SPARC_32:
309*4597dce4SFangrui Song   case ELF::R_SPARC_UA32:
310*4597dce4SFangrui Song     return true;
311*4597dce4SFangrui Song   default:
312*4597dce4SFangrui Song     return false;
313*4597dce4SFangrui Song   }
314*4597dce4SFangrui Song }
315*4597dce4SFangrui Song 
316*4597dce4SFangrui Song static uint64_t resolveSparc32(RelocationRef R, uint64_t S, uint64_t A) {
317*4597dce4SFangrui Song   uint32_t Rel = R.getType();
318*4597dce4SFangrui Song   if (Rel == ELF::R_SPARC_32 || Rel == ELF::R_SPARC_UA32)
319*4597dce4SFangrui Song     return S + getELFAddend(R);
320*4597dce4SFangrui Song   return A;
321*4597dce4SFangrui Song }
322*4597dce4SFangrui Song 
323*4597dce4SFangrui Song static bool supportsHexagon(uint64_t Type) {
324*4597dce4SFangrui Song   return Type == ELF::R_HEX_32;
325*4597dce4SFangrui Song }
326*4597dce4SFangrui Song 
327*4597dce4SFangrui Song static uint64_t resolveHexagon(RelocationRef R, uint64_t S, uint64_t A) {
328*4597dce4SFangrui Song   if (R.getType() == ELF::R_HEX_32)
329*4597dce4SFangrui Song     return S + getELFAddend(R);
330*4597dce4SFangrui Song   llvm_unreachable("Invalid relocation type");
331*4597dce4SFangrui Song }
332*4597dce4SFangrui Song 
333*4597dce4SFangrui Song static bool supportsCOFFX86(uint64_t Type) {
334*4597dce4SFangrui Song   switch (Type) {
335*4597dce4SFangrui Song   case COFF::IMAGE_REL_I386_SECREL:
336*4597dce4SFangrui Song   case COFF::IMAGE_REL_I386_DIR32:
337*4597dce4SFangrui Song     return true;
338*4597dce4SFangrui Song   default:
339*4597dce4SFangrui Song     return false;
340*4597dce4SFangrui Song   }
341*4597dce4SFangrui Song }
342*4597dce4SFangrui Song 
343*4597dce4SFangrui Song static uint64_t resolveCOFFX86(RelocationRef R, uint64_t S, uint64_t A) {
344*4597dce4SFangrui Song   switch (R.getType()) {
345*4597dce4SFangrui Song   case COFF::IMAGE_REL_I386_SECREL:
346*4597dce4SFangrui Song   case COFF::IMAGE_REL_I386_DIR32:
347*4597dce4SFangrui Song     return (S + A) & 0xFFFFFFFF;
348*4597dce4SFangrui Song   default:
349*4597dce4SFangrui Song     llvm_unreachable("Invalid relocation type");
350*4597dce4SFangrui Song   }
351*4597dce4SFangrui Song }
352*4597dce4SFangrui Song 
353*4597dce4SFangrui Song static bool supportsCOFFX86_64(uint64_t Type) {
354*4597dce4SFangrui Song   switch (Type) {
355*4597dce4SFangrui Song   case COFF::IMAGE_REL_AMD64_SECREL:
356*4597dce4SFangrui Song   case COFF::IMAGE_REL_AMD64_ADDR64:
357*4597dce4SFangrui Song     return true;
358*4597dce4SFangrui Song   default:
359*4597dce4SFangrui Song     return false;
360*4597dce4SFangrui Song   }
361*4597dce4SFangrui Song }
362*4597dce4SFangrui Song 
363*4597dce4SFangrui Song static uint64_t resolveCOFFX86_64(RelocationRef R, uint64_t S, uint64_t A) {
364*4597dce4SFangrui Song   switch (R.getType()) {
365*4597dce4SFangrui Song   case COFF::IMAGE_REL_AMD64_SECREL:
366*4597dce4SFangrui Song     return (S + A) & 0xFFFFFFFF;
367*4597dce4SFangrui Song   case COFF::IMAGE_REL_AMD64_ADDR64:
368*4597dce4SFangrui Song     return S + A;
369*4597dce4SFangrui Song   default:
370*4597dce4SFangrui Song     llvm_unreachable("Invalid relocation type");
371*4597dce4SFangrui Song   }
372*4597dce4SFangrui Song }
373*4597dce4SFangrui Song 
374*4597dce4SFangrui Song static bool supportsMachOX86_64(uint64_t Type) {
375*4597dce4SFangrui Song   return Type == MachO::X86_64_RELOC_UNSIGNED;
376*4597dce4SFangrui Song }
377*4597dce4SFangrui Song 
378*4597dce4SFangrui Song static uint64_t resolveMachOX86_64(RelocationRef R, uint64_t S, uint64_t A) {
379*4597dce4SFangrui Song   if (R.getType() == MachO::X86_64_RELOC_UNSIGNED)
380*4597dce4SFangrui Song     return S;
381*4597dce4SFangrui Song   llvm_unreachable("Invalid relocation type");
382*4597dce4SFangrui Song }
383*4597dce4SFangrui Song 
384*4597dce4SFangrui Song static bool supportsWasm32(uint64_t Type) {
385*4597dce4SFangrui Song   switch (Type) {
386*4597dce4SFangrui Song   case wasm::R_WASM_FUNCTION_INDEX_LEB:
387*4597dce4SFangrui Song   case wasm::R_WASM_TABLE_INDEX_SLEB:
388*4597dce4SFangrui Song   case wasm::R_WASM_TABLE_INDEX_I32:
389*4597dce4SFangrui Song   case wasm::R_WASM_MEMORY_ADDR_LEB:
390*4597dce4SFangrui Song   case wasm::R_WASM_MEMORY_ADDR_SLEB:
391*4597dce4SFangrui Song   case wasm::R_WASM_MEMORY_ADDR_I32:
392*4597dce4SFangrui Song   case wasm::R_WASM_TYPE_INDEX_LEB:
393*4597dce4SFangrui Song   case wasm::R_WASM_GLOBAL_INDEX_LEB:
394*4597dce4SFangrui Song   case wasm::R_WASM_FUNCTION_OFFSET_I32:
395*4597dce4SFangrui Song   case wasm::R_WASM_SECTION_OFFSET_I32:
396*4597dce4SFangrui Song   case wasm::R_WASM_EVENT_INDEX_LEB:
397*4597dce4SFangrui Song     return true;
398*4597dce4SFangrui Song   default:
399*4597dce4SFangrui Song     return false;
400*4597dce4SFangrui Song   }
401*4597dce4SFangrui Song }
402*4597dce4SFangrui Song 
403*4597dce4SFangrui Song static uint64_t resolveWasm32(RelocationRef R, uint64_t S, uint64_t A) {
404*4597dce4SFangrui Song   switch (R.getType()) {
405*4597dce4SFangrui Song   case wasm::R_WASM_FUNCTION_INDEX_LEB:
406*4597dce4SFangrui Song   case wasm::R_WASM_TABLE_INDEX_SLEB:
407*4597dce4SFangrui Song   case wasm::R_WASM_TABLE_INDEX_I32:
408*4597dce4SFangrui Song   case wasm::R_WASM_MEMORY_ADDR_LEB:
409*4597dce4SFangrui Song   case wasm::R_WASM_MEMORY_ADDR_SLEB:
410*4597dce4SFangrui Song   case wasm::R_WASM_MEMORY_ADDR_I32:
411*4597dce4SFangrui Song   case wasm::R_WASM_TYPE_INDEX_LEB:
412*4597dce4SFangrui Song   case wasm::R_WASM_GLOBAL_INDEX_LEB:
413*4597dce4SFangrui Song   case wasm::R_WASM_FUNCTION_OFFSET_I32:
414*4597dce4SFangrui Song   case wasm::R_WASM_SECTION_OFFSET_I32:
415*4597dce4SFangrui Song   case wasm::R_WASM_EVENT_INDEX_LEB:
416*4597dce4SFangrui Song     // For wasm section, its offset at 0 -- ignoring Value
417*4597dce4SFangrui Song     return A;
418*4597dce4SFangrui Song   default:
419*4597dce4SFangrui Song     llvm_unreachable("Invalid relocation type");
420*4597dce4SFangrui Song   }
421*4597dce4SFangrui Song }
422*4597dce4SFangrui Song 
423*4597dce4SFangrui Song std::pair<bool (*)(uint64_t), RelocationResolver>
424*4597dce4SFangrui Song getRelocationResolver(const ObjectFile &Obj) {
425*4597dce4SFangrui Song   if (Obj.isCOFF()) {
426*4597dce4SFangrui Song     if (Obj.getBytesInAddress() == 8)
427*4597dce4SFangrui Song       return {supportsCOFFX86_64, resolveCOFFX86_64};
428*4597dce4SFangrui Song     return {supportsCOFFX86, resolveCOFFX86};
429*4597dce4SFangrui Song   } else if (Obj.isELF()) {
430*4597dce4SFangrui Song     if (Obj.getBytesInAddress() == 8) {
431*4597dce4SFangrui Song       switch (Obj.getArch()) {
432*4597dce4SFangrui Song       case Triple::x86_64:
433*4597dce4SFangrui Song         return {supportsX86_64, resolveX86_64};
434*4597dce4SFangrui Song       case Triple::aarch64:
435*4597dce4SFangrui Song       case Triple::aarch64_be:
436*4597dce4SFangrui Song         return {supportsAArch64, resolveAArch64};
437*4597dce4SFangrui Song       case Triple::bpfel:
438*4597dce4SFangrui Song       case Triple::bpfeb:
439*4597dce4SFangrui Song         return {supportsBPF, resolveBPF};
440*4597dce4SFangrui Song       case Triple::mips64el:
441*4597dce4SFangrui Song       case Triple::mips64:
442*4597dce4SFangrui Song         return {supportsMips64, resolveMips64};
443*4597dce4SFangrui Song       case Triple::ppc64le:
444*4597dce4SFangrui Song       case Triple::ppc64:
445*4597dce4SFangrui Song         return {supportsPPC64, resolvePPC64};
446*4597dce4SFangrui Song       case Triple::systemz:
447*4597dce4SFangrui Song         return {supportsSystemZ, resolveSystemZ};
448*4597dce4SFangrui Song       case Triple::sparcv9:
449*4597dce4SFangrui Song         return {supportsSparc64, resolveSparc64};
450*4597dce4SFangrui Song       case Triple::amdgcn:
451*4597dce4SFangrui Song         return {supportsAmdgpu, resolveAmdgpu};
452*4597dce4SFangrui Song       default:
453*4597dce4SFangrui Song         return {nullptr, nullptr};
454*4597dce4SFangrui Song       }
455*4597dce4SFangrui Song     }
456*4597dce4SFangrui Song 
457*4597dce4SFangrui Song     // 32-bit object file
458*4597dce4SFangrui Song     assert(Obj.getBytesInAddress() == 4 &&
459*4597dce4SFangrui Song            "Invalid word size in object file");
460*4597dce4SFangrui Song 
461*4597dce4SFangrui Song     switch (Obj.getArch()) {
462*4597dce4SFangrui Song     case Triple::x86:
463*4597dce4SFangrui Song       return {supportsX86, resolveX86};
464*4597dce4SFangrui Song     case Triple::ppc:
465*4597dce4SFangrui Song       return {supportsPPC32, resolvePPC32};
466*4597dce4SFangrui Song     case Triple::arm:
467*4597dce4SFangrui Song     case Triple::armeb:
468*4597dce4SFangrui Song       return {supportsARM, resolveARM};
469*4597dce4SFangrui Song     case Triple::avr:
470*4597dce4SFangrui Song       return {supportsAVR, resolveAVR};
471*4597dce4SFangrui Song     case Triple::lanai:
472*4597dce4SFangrui Song       return {supportsLanai, resolveLanai};
473*4597dce4SFangrui Song     case Triple::mipsel:
474*4597dce4SFangrui Song     case Triple::mips:
475*4597dce4SFangrui Song       return {supportsMips32, resolveMips32};
476*4597dce4SFangrui Song     case Triple::sparc:
477*4597dce4SFangrui Song       return {supportsSparc32, resolveSparc32};
478*4597dce4SFangrui Song     case Triple::hexagon:
479*4597dce4SFangrui Song       return {supportsHexagon, resolveHexagon};
480*4597dce4SFangrui Song     default:
481*4597dce4SFangrui Song       return {nullptr, nullptr};
482*4597dce4SFangrui Song     }
483*4597dce4SFangrui Song   } else if (Obj.isMachO()) {
484*4597dce4SFangrui Song     if (Obj.getArch() == Triple::x86_64)
485*4597dce4SFangrui Song       return {supportsMachOX86_64, resolveMachOX86_64};
486*4597dce4SFangrui Song     return {nullptr, nullptr};
487*4597dce4SFangrui Song   } else if (Obj.isWasm()) {
488*4597dce4SFangrui Song     if (Obj.getArch() == Triple::wasm32)
489*4597dce4SFangrui Song       return {supportsWasm32, resolveWasm32};
490*4597dce4SFangrui Song     return {nullptr, nullptr};
491*4597dce4SFangrui Song   }
492*4597dce4SFangrui Song 
493*4597dce4SFangrui Song   llvm_unreachable("Invalid object file");
494*4597dce4SFangrui Song }
495*4597dce4SFangrui Song 
496*4597dce4SFangrui Song } // namespace object
497*4597dce4SFangrui Song } // namespace llvm
498