xref: /llvm-project/llvm/lib/Object/RelocationResolver.cpp (revision b922004ea29d54534c4f09b9cfa655bf5f3360f0)
1 //===- RelocationResolver.cpp ------------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file defines utilities to resolve relocations in object files.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "llvm/Object/RelocationResolver.h"
14 
15 namespace llvm {
16 namespace object {
17 
18 static int64_t getELFAddend(RelocationRef R) {
19   Expected<int64_t> AddendOrErr = ELFRelocationRef(R).getAddend();
20   handleAllErrors(AddendOrErr.takeError(), [](const ErrorInfoBase &EI) {
21     report_fatal_error(EI.message());
22   });
23   return *AddendOrErr;
24 }
25 
26 static bool supportsX86_64(uint64_t Type) {
27   switch (Type) {
28   case ELF::R_X86_64_NONE:
29   case ELF::R_X86_64_64:
30   case ELF::R_X86_64_DTPOFF32:
31   case ELF::R_X86_64_DTPOFF64:
32   case ELF::R_X86_64_PC32:
33   case ELF::R_X86_64_PC64:
34   case ELF::R_X86_64_32:
35   case ELF::R_X86_64_32S:
36     return true;
37   default:
38     return false;
39   }
40 }
41 
42 static uint64_t resolveX86_64(RelocationRef R, uint64_t S, uint64_t A) {
43   switch (R.getType()) {
44   case ELF::R_X86_64_NONE:
45     return A;
46   case ELF::R_X86_64_64:
47   case ELF::R_X86_64_DTPOFF32:
48   case ELF::R_X86_64_DTPOFF64:
49     return S + getELFAddend(R);
50   case ELF::R_X86_64_PC32:
51   case ELF::R_X86_64_PC64:
52     return S + getELFAddend(R) - R.getOffset();
53   case ELF::R_X86_64_32:
54   case ELF::R_X86_64_32S:
55     return (S + getELFAddend(R)) & 0xFFFFFFFF;
56   default:
57     llvm_unreachable("Invalid relocation type");
58   }
59 }
60 
61 static bool supportsAArch64(uint64_t Type) {
62   switch (Type) {
63   case ELF::R_AARCH64_ABS32:
64   case ELF::R_AARCH64_ABS64:
65     return true;
66   default:
67     return false;
68   }
69 }
70 
71 static uint64_t resolveAArch64(RelocationRef R, uint64_t S, uint64_t A) {
72   switch (R.getType()) {
73   case ELF::R_AARCH64_ABS32:
74     return (S + getELFAddend(R)) & 0xFFFFFFFF;
75   case ELF::R_AARCH64_ABS64:
76     return S + getELFAddend(R);
77   default:
78     llvm_unreachable("Invalid relocation type");
79   }
80 }
81 
82 static bool supportsBPF(uint64_t Type) {
83   switch (Type) {
84   case ELF::R_BPF_64_32:
85   case ELF::R_BPF_64_64:
86     return true;
87   default:
88     return false;
89   }
90 }
91 
92 static uint64_t resolveBPF(RelocationRef R, uint64_t S, uint64_t A) {
93   switch (R.getType()) {
94   case ELF::R_BPF_64_32:
95     return (S + A) & 0xFFFFFFFF;
96   case ELF::R_BPF_64_64:
97     return S + A;
98   default:
99     llvm_unreachable("Invalid relocation type");
100   }
101 }
102 
103 static bool supportsMips64(uint64_t Type) {
104   switch (Type) {
105   case ELF::R_MIPS_32:
106   case ELF::R_MIPS_64:
107   case ELF::R_MIPS_TLS_DTPREL64:
108   case ELF::R_MIPS_PC32:
109     return true;
110   default:
111     return false;
112   }
113 }
114 
115 static uint64_t resolveMips64(RelocationRef R, uint64_t S, uint64_t A) {
116   switch (R.getType()) {
117   case ELF::R_MIPS_32:
118     return (S + getELFAddend(R)) & 0xFFFFFFFF;
119   case ELF::R_MIPS_64:
120     return S + getELFAddend(R);
121   case ELF::R_MIPS_TLS_DTPREL64:
122     return S + getELFAddend(R) - 0x8000;
123   case ELF::R_MIPS_PC32:
124     return S + getELFAddend(R) - R.getOffset();
125   default:
126     llvm_unreachable("Invalid relocation type");
127   }
128 }
129 
130 static bool supportsMSP430(uint64_t Type) {
131   switch (Type) {
132   case ELF::R_MSP430_32:
133   case ELF::R_MSP430_16_BYTE:
134     return true;
135   default:
136     return false;
137   }
138 }
139 
140 static uint64_t resolveMSP430(RelocationRef R, uint64_t S, uint64_t A) {
141   switch (R.getType()) {
142   case ELF::R_MSP430_32:
143     return (S + getELFAddend(R)) & 0xFFFFFFFF;
144   case ELF::R_MSP430_16_BYTE:
145     return (S + getELFAddend(R)) & 0xFFFF;
146   default:
147     llvm_unreachable("Invalid relocation type");
148   }
149 }
150 
151 static bool supportsPPC64(uint64_t Type) {
152   switch (Type) {
153   case ELF::R_PPC64_ADDR32:
154   case ELF::R_PPC64_ADDR64:
155   case ELF::R_PPC64_REL32:
156   case ELF::R_PPC64_REL64:
157     return true;
158   default:
159     return false;
160   }
161 }
162 
163 static uint64_t resolvePPC64(RelocationRef R, uint64_t S, uint64_t A) {
164   switch (R.getType()) {
165   case ELF::R_PPC64_ADDR32:
166     return (S + getELFAddend(R)) & 0xFFFFFFFF;
167   case ELF::R_PPC64_ADDR64:
168     return S + getELFAddend(R);
169   case ELF::R_PPC64_REL32:
170     return (S + getELFAddend(R) - R.getOffset()) & 0xFFFFFFFF;
171   case ELF::R_PPC64_REL64:
172     return S + getELFAddend(R) - R.getOffset();
173   default:
174     llvm_unreachable("Invalid relocation type");
175   }
176 }
177 
178 static bool supportsSystemZ(uint64_t Type) {
179   switch (Type) {
180   case ELF::R_390_32:
181   case ELF::R_390_64:
182     return true;
183   default:
184     return false;
185   }
186 }
187 
188 static uint64_t resolveSystemZ(RelocationRef R, uint64_t S, uint64_t A) {
189   switch (R.getType()) {
190   case ELF::R_390_32:
191     return (S + getELFAddend(R)) & 0xFFFFFFFF;
192   case ELF::R_390_64:
193     return S + getELFAddend(R);
194   default:
195     llvm_unreachable("Invalid relocation type");
196   }
197 }
198 
199 static bool supportsSparc64(uint64_t Type) {
200   switch (Type) {
201   case ELF::R_SPARC_32:
202   case ELF::R_SPARC_64:
203   case ELF::R_SPARC_UA32:
204   case ELF::R_SPARC_UA64:
205     return true;
206   default:
207     return false;
208   }
209 }
210 
211 static uint64_t resolveSparc64(RelocationRef R, uint64_t S, uint64_t A) {
212   switch (R.getType()) {
213   case ELF::R_SPARC_32:
214   case ELF::R_SPARC_64:
215   case ELF::R_SPARC_UA32:
216   case ELF::R_SPARC_UA64:
217     return S + getELFAddend(R);
218   default:
219     llvm_unreachable("Invalid relocation type");
220   }
221 }
222 
223 static bool supportsAmdgpu(uint64_t Type) {
224   switch (Type) {
225   case ELF::R_AMDGPU_ABS32:
226   case ELF::R_AMDGPU_ABS64:
227     return true;
228   default:
229     return false;
230   }
231 }
232 
233 static uint64_t resolveAmdgpu(RelocationRef R, uint64_t S, uint64_t A) {
234   switch (R.getType()) {
235   case ELF::R_AMDGPU_ABS32:
236   case ELF::R_AMDGPU_ABS64:
237     return S + getELFAddend(R);
238   default:
239     llvm_unreachable("Invalid relocation type");
240   }
241 }
242 
243 static bool supportsX86(uint64_t Type) {
244   switch (Type) {
245   case ELF::R_386_NONE:
246   case ELF::R_386_32:
247   case ELF::R_386_PC32:
248     return true;
249   default:
250     return false;
251   }
252 }
253 
254 static uint64_t resolveX86(RelocationRef R, uint64_t S, uint64_t A) {
255   switch (R.getType()) {
256   case ELF::R_386_NONE:
257     return A;
258   case ELF::R_386_32:
259     return S + A;
260   case ELF::R_386_PC32:
261     return S - R.getOffset() + A;
262   default:
263     llvm_unreachable("Invalid relocation type");
264   }
265 }
266 
267 static bool supportsPPC32(uint64_t Type) {
268   switch (Type) {
269   case ELF::R_PPC_ADDR32:
270   case ELF::R_PPC_REL32:
271     return true;
272   default:
273     return false;
274   }
275 }
276 
277 static uint64_t resolvePPC32(RelocationRef R, uint64_t S, uint64_t A) {
278   switch (R.getType()) {
279   case ELF::R_PPC_ADDR32:
280     return (S + getELFAddend(R)) & 0xFFFFFFFF;
281   case ELF::R_PPC_REL32:
282     return (S + getELFAddend(R) - R.getOffset()) & 0xFFFFFFFF;
283   }
284   llvm_unreachable("Invalid relocation type");
285 }
286 
287 static bool supportsARM(uint64_t Type) {
288   return Type == ELF::R_ARM_ABS32;
289 }
290 
291 static uint64_t resolveARM(RelocationRef R, uint64_t S, uint64_t A) {
292   if (R.getType() == ELF::R_ARM_ABS32)
293     return (S + A) & 0xFFFFFFFF;
294   llvm_unreachable("Invalid relocation type");
295 }
296 
297 static bool supportsAVR(uint64_t Type) {
298   switch (Type) {
299   case ELF::R_AVR_16:
300   case ELF::R_AVR_32:
301     return true;
302   default:
303     return false;
304   }
305 }
306 
307 static uint64_t resolveAVR(RelocationRef R, uint64_t S, uint64_t A) {
308   switch (R.getType()) {
309   case ELF::R_AVR_16:
310     return (S + getELFAddend(R)) & 0xFFFF;
311   case ELF::R_AVR_32:
312     return (S + getELFAddend(R)) & 0xFFFFFFFF;
313   default:
314     llvm_unreachable("Invalid relocation type");
315   }
316 }
317 
318 static bool supportsLanai(uint64_t Type) {
319   return Type == ELF::R_LANAI_32;
320 }
321 
322 static uint64_t resolveLanai(RelocationRef R, uint64_t S, uint64_t A) {
323   if (R.getType() == ELF::R_LANAI_32)
324     return (S + getELFAddend(R)) & 0xFFFFFFFF;
325   llvm_unreachable("Invalid relocation type");
326 }
327 
328 static bool supportsMips32(uint64_t Type) {
329   switch (Type) {
330   case ELF::R_MIPS_32:
331   case ELF::R_MIPS_TLS_DTPREL32:
332     return true;
333   default:
334     return false;
335   }
336 }
337 
338 static uint64_t resolveMips32(RelocationRef R, uint64_t S, uint64_t A) {
339   // FIXME: Take in account implicit addends to get correct results.
340   uint32_t Rel = R.getType();
341   if (Rel == ELF::R_MIPS_32)
342     return (S + A) & 0xFFFFFFFF;
343   if (Rel == ELF::R_MIPS_TLS_DTPREL32)
344     return (S + A) & 0xFFFFFFFF;
345   llvm_unreachable("Invalid relocation type");
346 }
347 
348 static bool supportsSparc32(uint64_t Type) {
349   switch (Type) {
350   case ELF::R_SPARC_32:
351   case ELF::R_SPARC_UA32:
352     return true;
353   default:
354     return false;
355   }
356 }
357 
358 static uint64_t resolveSparc32(RelocationRef R, uint64_t S, uint64_t A) {
359   uint32_t Rel = R.getType();
360   if (Rel == ELF::R_SPARC_32 || Rel == ELF::R_SPARC_UA32)
361     return S + getELFAddend(R);
362   return A;
363 }
364 
365 static bool supportsHexagon(uint64_t Type) {
366   return Type == ELF::R_HEX_32;
367 }
368 
369 static uint64_t resolveHexagon(RelocationRef R, uint64_t S, uint64_t A) {
370   if (R.getType() == ELF::R_HEX_32)
371     return S + getELFAddend(R);
372   llvm_unreachable("Invalid relocation type");
373 }
374 
375 static bool supportsRISCV(uint64_t Type) {
376   switch (Type) {
377   case ELF::R_RISCV_NONE:
378   case ELF::R_RISCV_32:
379   case ELF::R_RISCV_32_PCREL:
380   case ELF::R_RISCV_64:
381   case ELF::R_RISCV_SET6:
382   case ELF::R_RISCV_SUB6:
383   case ELF::R_RISCV_ADD8:
384   case ELF::R_RISCV_SUB8:
385   case ELF::R_RISCV_ADD16:
386   case ELF::R_RISCV_SUB16:
387   case ELF::R_RISCV_ADD32:
388   case ELF::R_RISCV_SUB32:
389   case ELF::R_RISCV_ADD64:
390   case ELF::R_RISCV_SUB64:
391     return true;
392   default:
393     return false;
394   }
395 }
396 
397 static uint64_t resolveRISCV(RelocationRef R, uint64_t S, uint64_t A) {
398   int64_t RA = getELFAddend(R);
399   switch (R.getType()) {
400   case ELF::R_RISCV_NONE:
401     return A;
402   case ELF::R_RISCV_32:
403     return (S + RA) & 0xFFFFFFFF;
404   case ELF::R_RISCV_32_PCREL:
405     return (S + RA - R.getOffset()) & 0xFFFFFFFF;
406   case ELF::R_RISCV_64:
407     return S + RA;
408   case ELF::R_RISCV_SET6:
409     return (A & 0xC0) | ((S + RA) & 0x3F);
410   case ELF::R_RISCV_SUB6:
411     return (A & 0xC0) | (((A & 0x3F) - (S + RA)) & 0x3F);
412   case ELF::R_RISCV_ADD8:
413     return (A + (S + RA)) & 0xFF;
414   case ELF::R_RISCV_SUB8:
415     return (A - (S + RA)) & 0xFF;
416   case ELF::R_RISCV_ADD16:
417     return (A + (S + RA)) & 0xFFFF;
418   case ELF::R_RISCV_SUB16:
419     return (A - (S + RA)) & 0xFFFF;
420   case ELF::R_RISCV_ADD32:
421     return (A + (S + RA)) & 0xFFFFFFFF;
422   case ELF::R_RISCV_SUB32:
423     return (A - (S + RA)) & 0xFFFFFFFF;
424   case ELF::R_RISCV_ADD64:
425     return (A + (S + RA));
426   case ELF::R_RISCV_SUB64:
427     return (A - (S + RA));
428   default:
429     llvm_unreachable("Invalid relocation type");
430   }
431 }
432 
433 static bool supportsCOFFX86(uint64_t Type) {
434   switch (Type) {
435   case COFF::IMAGE_REL_I386_SECREL:
436   case COFF::IMAGE_REL_I386_DIR32:
437     return true;
438   default:
439     return false;
440   }
441 }
442 
443 static uint64_t resolveCOFFX86(RelocationRef R, uint64_t S, uint64_t A) {
444   switch (R.getType()) {
445   case COFF::IMAGE_REL_I386_SECREL:
446   case COFF::IMAGE_REL_I386_DIR32:
447     return (S + A) & 0xFFFFFFFF;
448   default:
449     llvm_unreachable("Invalid relocation type");
450   }
451 }
452 
453 static bool supportsCOFFX86_64(uint64_t Type) {
454   switch (Type) {
455   case COFF::IMAGE_REL_AMD64_SECREL:
456   case COFF::IMAGE_REL_AMD64_ADDR64:
457     return true;
458   default:
459     return false;
460   }
461 }
462 
463 static uint64_t resolveCOFFX86_64(RelocationRef R, uint64_t S, uint64_t A) {
464   switch (R.getType()) {
465   case COFF::IMAGE_REL_AMD64_SECREL:
466     return (S + A) & 0xFFFFFFFF;
467   case COFF::IMAGE_REL_AMD64_ADDR64:
468     return S + A;
469   default:
470     llvm_unreachable("Invalid relocation type");
471   }
472 }
473 
474 static bool supportsCOFFARM(uint64_t Type) {
475   switch (Type) {
476   case COFF::IMAGE_REL_ARM_SECREL:
477   case COFF::IMAGE_REL_ARM_ADDR32:
478     return true;
479   default:
480     return false;
481   }
482 }
483 
484 static uint64_t resolveCOFFARM(RelocationRef R, uint64_t S, uint64_t A) {
485   switch (R.getType()) {
486   case COFF::IMAGE_REL_ARM_SECREL:
487   case COFF::IMAGE_REL_ARM_ADDR32:
488     return (S + A) & 0xFFFFFFFF;
489   default:
490     llvm_unreachable("Invalid relocation type");
491   }
492 }
493 
494 static bool supportsCOFFARM64(uint64_t Type) {
495   switch (Type) {
496   case COFF::IMAGE_REL_ARM64_SECREL:
497   case COFF::IMAGE_REL_ARM64_ADDR64:
498     return true;
499   default:
500     return false;
501   }
502 }
503 
504 static uint64_t resolveCOFFARM64(RelocationRef R, uint64_t S, uint64_t A) {
505   switch (R.getType()) {
506   case COFF::IMAGE_REL_ARM64_SECREL:
507     return (S + A) & 0xFFFFFFFF;
508   case COFF::IMAGE_REL_ARM64_ADDR64:
509     return S + A;
510   default:
511     llvm_unreachable("Invalid relocation type");
512   }
513 }
514 
515 static bool supportsMachOX86_64(uint64_t Type) {
516   return Type == MachO::X86_64_RELOC_UNSIGNED;
517 }
518 
519 static uint64_t resolveMachOX86_64(RelocationRef R, uint64_t S, uint64_t A) {
520   if (R.getType() == MachO::X86_64_RELOC_UNSIGNED)
521     return S;
522   llvm_unreachable("Invalid relocation type");
523 }
524 
525 static bool supportsWasm32(uint64_t Type) {
526   switch (Type) {
527   case wasm::R_WASM_FUNCTION_INDEX_LEB:
528   case wasm::R_WASM_TABLE_INDEX_SLEB:
529   case wasm::R_WASM_TABLE_INDEX_I32:
530   case wasm::R_WASM_MEMORY_ADDR_LEB:
531   case wasm::R_WASM_MEMORY_ADDR_SLEB:
532   case wasm::R_WASM_MEMORY_ADDR_I32:
533   case wasm::R_WASM_TYPE_INDEX_LEB:
534   case wasm::R_WASM_GLOBAL_INDEX_LEB:
535   case wasm::R_WASM_FUNCTION_OFFSET_I32:
536   case wasm::R_WASM_SECTION_OFFSET_I32:
537   case wasm::R_WASM_EVENT_INDEX_LEB:
538   case wasm::R_WASM_GLOBAL_INDEX_I32:
539     return true;
540   default:
541     return false;
542   }
543 }
544 
545 static bool supportsWasm64(uint64_t Type) {
546   switch (Type) {
547   case wasm::R_WASM_MEMORY_ADDR_LEB64:
548   case wasm::R_WASM_MEMORY_ADDR_SLEB64:
549   case wasm::R_WASM_MEMORY_ADDR_I64:
550   case wasm::R_WASM_TABLE_INDEX_SLEB64:
551   case wasm::R_WASM_TABLE_INDEX_I64:
552     return true;
553   default:
554     return supportsWasm32(Type);
555   }
556 }
557 
558 static uint64_t resolveWasm32(RelocationRef R, uint64_t S, uint64_t A) {
559   switch (R.getType()) {
560   case wasm::R_WASM_FUNCTION_INDEX_LEB:
561   case wasm::R_WASM_TABLE_INDEX_SLEB:
562   case wasm::R_WASM_TABLE_INDEX_I32:
563   case wasm::R_WASM_MEMORY_ADDR_LEB:
564   case wasm::R_WASM_MEMORY_ADDR_SLEB:
565   case wasm::R_WASM_MEMORY_ADDR_I32:
566   case wasm::R_WASM_TYPE_INDEX_LEB:
567   case wasm::R_WASM_GLOBAL_INDEX_LEB:
568   case wasm::R_WASM_FUNCTION_OFFSET_I32:
569   case wasm::R_WASM_SECTION_OFFSET_I32:
570   case wasm::R_WASM_EVENT_INDEX_LEB:
571   case wasm::R_WASM_GLOBAL_INDEX_I32:
572     // For wasm section, its offset at 0 -- ignoring Value
573     return A;
574   default:
575     llvm_unreachable("Invalid relocation type");
576   }
577 }
578 
579 static uint64_t resolveWasm64(RelocationRef R, uint64_t S, uint64_t A) {
580   switch (R.getType()) {
581   case wasm::R_WASM_MEMORY_ADDR_LEB64:
582   case wasm::R_WASM_MEMORY_ADDR_SLEB64:
583   case wasm::R_WASM_MEMORY_ADDR_I64:
584   case wasm::R_WASM_TABLE_INDEX_SLEB64:
585   case wasm::R_WASM_TABLE_INDEX_I64:
586     // For wasm section, its offset at 0 -- ignoring Value
587     return A;
588   default:
589     return resolveWasm32(R, S, A);
590   }
591 }
592 
593 std::pair<bool (*)(uint64_t), RelocationResolver>
594 getRelocationResolver(const ObjectFile &Obj) {
595   if (Obj.isCOFF()) {
596     switch (Obj.getArch()) {
597     case Triple::x86_64:
598       return {supportsCOFFX86_64, resolveCOFFX86_64};
599     case Triple::x86:
600       return {supportsCOFFX86, resolveCOFFX86};
601     case Triple::arm:
602     case Triple::thumb:
603       return {supportsCOFFARM, resolveCOFFARM};
604     case Triple::aarch64:
605       return {supportsCOFFARM64, resolveCOFFARM64};
606     default:
607       return {nullptr, nullptr};
608     }
609   } else if (Obj.isELF()) {
610     if (Obj.getBytesInAddress() == 8) {
611       switch (Obj.getArch()) {
612       case Triple::x86_64:
613         return {supportsX86_64, resolveX86_64};
614       case Triple::aarch64:
615       case Triple::aarch64_be:
616         return {supportsAArch64, resolveAArch64};
617       case Triple::bpfel:
618       case Triple::bpfeb:
619         return {supportsBPF, resolveBPF};
620       case Triple::mips64el:
621       case Triple::mips64:
622         return {supportsMips64, resolveMips64};
623       case Triple::ppc64le:
624       case Triple::ppc64:
625         return {supportsPPC64, resolvePPC64};
626       case Triple::systemz:
627         return {supportsSystemZ, resolveSystemZ};
628       case Triple::sparcv9:
629         return {supportsSparc64, resolveSparc64};
630       case Triple::amdgcn:
631         return {supportsAmdgpu, resolveAmdgpu};
632       case Triple::riscv64:
633         return {supportsRISCV, resolveRISCV};
634       default:
635         return {nullptr, nullptr};
636       }
637     }
638 
639     // 32-bit object file
640     assert(Obj.getBytesInAddress() == 4 &&
641            "Invalid word size in object file");
642 
643     switch (Obj.getArch()) {
644     case Triple::x86:
645       return {supportsX86, resolveX86};
646     case Triple::ppc:
647       return {supportsPPC32, resolvePPC32};
648     case Triple::arm:
649     case Triple::armeb:
650       return {supportsARM, resolveARM};
651     case Triple::avr:
652       return {supportsAVR, resolveAVR};
653     case Triple::lanai:
654       return {supportsLanai, resolveLanai};
655     case Triple::mipsel:
656     case Triple::mips:
657       return {supportsMips32, resolveMips32};
658     case Triple::msp430:
659       return {supportsMSP430, resolveMSP430};
660     case Triple::sparc:
661       return {supportsSparc32, resolveSparc32};
662     case Triple::hexagon:
663       return {supportsHexagon, resolveHexagon};
664     case Triple::riscv32:
665       return {supportsRISCV, resolveRISCV};
666     default:
667       return {nullptr, nullptr};
668     }
669   } else if (Obj.isMachO()) {
670     if (Obj.getArch() == Triple::x86_64)
671       return {supportsMachOX86_64, resolveMachOX86_64};
672     return {nullptr, nullptr};
673   } else if (Obj.isWasm()) {
674     if (Obj.getArch() == Triple::wasm32)
675       return {supportsWasm32, resolveWasm32};
676     if (Obj.getArch() == Triple::wasm64)
677       return {supportsWasm64, resolveWasm64};
678     return {nullptr, nullptr};
679   }
680 
681   llvm_unreachable("Invalid object file");
682 }
683 
684 } // namespace object
685 } // namespace llvm
686