LLVM  13.0.0git
RelocationResolver.cpp
Go to the documentation of this file.
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 
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(uint64_t Type, uint64_t Offset, uint64_t S,
43  uint64_t LocData, int64_t Addend) {
44  switch (Type) {
45  case ELF::R_X86_64_NONE:
46  return LocData;
47  case ELF::R_X86_64_64:
48  case ELF::R_X86_64_DTPOFF32:
49  case ELF::R_X86_64_DTPOFF64:
50  return S + Addend;
51  case ELF::R_X86_64_PC32:
52  case ELF::R_X86_64_PC64:
53  return S + Addend - Offset;
54  case ELF::R_X86_64_32:
55  case ELF::R_X86_64_32S:
56  return (S + Addend) & 0xFFFFFFFF;
57  default:
58  llvm_unreachable("Invalid relocation type");
59  }
60 }
61 
62 static bool supportsAArch64(uint64_t Type) {
63  switch (Type) {
64  case ELF::R_AARCH64_ABS32:
65  case ELF::R_AARCH64_ABS64:
66  case ELF::R_AARCH64_PREL32:
67  case ELF::R_AARCH64_PREL64:
68  return true;
69  default:
70  return false;
71  }
72 }
73 
74 static uint64_t resolveAArch64(uint64_t Type, uint64_t Offset, uint64_t S,
75  uint64_t /*LocData*/, int64_t Addend) {
76  switch (Type) {
77  case ELF::R_AARCH64_ABS32:
78  return (S + Addend) & 0xFFFFFFFF;
79  case ELF::R_AARCH64_ABS64:
80  return S + Addend;
81  case ELF::R_AARCH64_PREL32:
82  return (S + Addend - Offset) & 0xFFFFFFFF;
83  case ELF::R_AARCH64_PREL64:
84  return S + Addend - Offset;
85  default:
86  llvm_unreachable("Invalid relocation type");
87  }
88 }
89 
90 static bool supportsBPF(uint64_t Type) {
91  switch (Type) {
92  case ELF::R_BPF_64_32:
93  case ELF::R_BPF_64_64:
94  return true;
95  default:
96  return false;
97  }
98 }
99 
100 static uint64_t resolveBPF(uint64_t Type, uint64_t Offset, uint64_t S,
101  uint64_t LocData, int64_t /*Addend*/) {
102  switch (Type) {
103  case ELF::R_BPF_64_32:
104  return (S + LocData) & 0xFFFFFFFF;
105  case ELF::R_BPF_64_64:
106  return S + LocData;
107  default:
108  llvm_unreachable("Invalid relocation type");
109  }
110 }
111 
112 static bool supportsMips64(uint64_t Type) {
113  switch (Type) {
114  case ELF::R_MIPS_32:
115  case ELF::R_MIPS_64:
116  case ELF::R_MIPS_TLS_DTPREL64:
117  case ELF::R_MIPS_PC32:
118  return true;
119  default:
120  return false;
121  }
122 }
123 
124 static uint64_t resolveMips64(uint64_t Type, uint64_t Offset, uint64_t S,
125  uint64_t /*LocData*/, int64_t Addend) {
126  switch (Type) {
127  case ELF::R_MIPS_32:
128  return (S + Addend) & 0xFFFFFFFF;
129  case ELF::R_MIPS_64:
130  return S + Addend;
131  case ELF::R_MIPS_TLS_DTPREL64:
132  return S + Addend - 0x8000;
133  case ELF::R_MIPS_PC32:
134  return S + Addend - Offset;
135  default:
136  llvm_unreachable("Invalid relocation type");
137  }
138 }
139 
140 static bool supportsMSP430(uint64_t Type) {
141  switch (Type) {
142  case ELF::R_MSP430_32:
143  case ELF::R_MSP430_16_BYTE:
144  return true;
145  default:
146  return false;
147  }
148 }
149 
150 static uint64_t resolveMSP430(uint64_t Type, uint64_t Offset, uint64_t S,
151  uint64_t /*LocData*/, int64_t Addend) {
152  switch (Type) {
153  case ELF::R_MSP430_32:
154  return (S + Addend) & 0xFFFFFFFF;
155  case ELF::R_MSP430_16_BYTE:
156  return (S + Addend) & 0xFFFF;
157  default:
158  llvm_unreachable("Invalid relocation type");
159  }
160 }
161 
162 static bool supportsPPC64(uint64_t Type) {
163  switch (Type) {
164  case ELF::R_PPC64_ADDR32:
165  case ELF::R_PPC64_ADDR64:
166  case ELF::R_PPC64_REL32:
167  case ELF::R_PPC64_REL64:
168  return true;
169  default:
170  return false;
171  }
172 }
173 
174 static uint64_t resolvePPC64(uint64_t Type, uint64_t Offset, uint64_t S,
175  uint64_t /*LocData*/, int64_t Addend) {
176  switch (Type) {
177  case ELF::R_PPC64_ADDR32:
178  return (S + Addend) & 0xFFFFFFFF;
179  case ELF::R_PPC64_ADDR64:
180  return S + Addend;
181  case ELF::R_PPC64_REL32:
182  return (S + Addend - Offset) & 0xFFFFFFFF;
183  case ELF::R_PPC64_REL64:
184  return S + Addend - Offset;
185  default:
186  llvm_unreachable("Invalid relocation type");
187  }
188 }
189 
190 static bool supportsSystemZ(uint64_t Type) {
191  switch (Type) {
192  case ELF::R_390_32:
193  case ELF::R_390_64:
194  return true;
195  default:
196  return false;
197  }
198 }
199 
200 static uint64_t resolveSystemZ(uint64_t Type, uint64_t Offset, uint64_t S,
201  uint64_t /*LocData*/, int64_t Addend) {
202  switch (Type) {
203  case ELF::R_390_32:
204  return (S + Addend) & 0xFFFFFFFF;
205  case ELF::R_390_64:
206  return S + Addend;
207  default:
208  llvm_unreachable("Invalid relocation type");
209  }
210 }
211 
212 static bool supportsSparc64(uint64_t Type) {
213  switch (Type) {
214  case ELF::R_SPARC_32:
215  case ELF::R_SPARC_64:
216  case ELF::R_SPARC_UA32:
217  case ELF::R_SPARC_UA64:
218  return true;
219  default:
220  return false;
221  }
222 }
223 
224 static uint64_t resolveSparc64(uint64_t Type, uint64_t Offset, uint64_t S,
225  uint64_t /*LocData*/, int64_t Addend) {
226  switch (Type) {
227  case ELF::R_SPARC_32:
228  case ELF::R_SPARC_64:
229  case ELF::R_SPARC_UA32:
230  case ELF::R_SPARC_UA64:
231  return S + Addend;
232  default:
233  llvm_unreachable("Invalid relocation type");
234  }
235 }
236 
237 static bool supportsAmdgpu(uint64_t Type) {
238  switch (Type) {
239  case ELF::R_AMDGPU_ABS32:
240  case ELF::R_AMDGPU_ABS64:
241  return true;
242  default:
243  return false;
244  }
245 }
246 
247 static uint64_t resolveAmdgpu(uint64_t Type, uint64_t Offset, uint64_t S,
248  uint64_t /*LocData*/, int64_t Addend) {
249  switch (Type) {
250  case ELF::R_AMDGPU_ABS32:
251  case ELF::R_AMDGPU_ABS64:
252  return S + Addend;
253  default:
254  llvm_unreachable("Invalid relocation type");
255  }
256 }
257 
258 static bool supportsX86(uint64_t Type) {
259  switch (Type) {
260  case ELF::R_386_NONE:
261  case ELF::R_386_32:
262  case ELF::R_386_PC32:
263  return true;
264  default:
265  return false;
266  }
267 }
268 
269 static uint64_t resolveX86(uint64_t Type, uint64_t Offset, uint64_t S,
270  uint64_t LocData, int64_t /*Addend*/) {
271  switch (Type) {
272  case ELF::R_386_NONE:
273  return LocData;
274  case ELF::R_386_32:
275  return S + LocData;
276  case ELF::R_386_PC32:
277  return S - Offset + LocData;
278  default:
279  llvm_unreachable("Invalid relocation type");
280  }
281 }
282 
283 static bool supportsPPC32(uint64_t Type) {
284  switch (Type) {
285  case ELF::R_PPC_ADDR32:
286  case ELF::R_PPC_REL32:
287  return true;
288  default:
289  return false;
290  }
291 }
292 
293 static uint64_t resolvePPC32(uint64_t Type, uint64_t Offset, uint64_t S,
294  uint64_t /*LocData*/, int64_t Addend) {
295  switch (Type) {
296  case ELF::R_PPC_ADDR32:
297  return (S + Addend) & 0xFFFFFFFF;
298  case ELF::R_PPC_REL32:
299  return (S + Addend - Offset) & 0xFFFFFFFF;
300  }
301  llvm_unreachable("Invalid relocation type");
302 }
303 
304 static bool supportsARM(uint64_t Type) {
305  switch (Type) {
306  case ELF::R_ARM_ABS32:
307  case ELF::R_ARM_REL32:
308  return true;
309  default:
310  return false;
311  }
312 }
313 
314 static uint64_t resolveARM(uint64_t Type, uint64_t Offset, uint64_t S,
315  uint64_t LocData, int64_t /*Addend*/) {
316  switch (Type) {
317  case ELF::R_ARM_ABS32:
318  return (S + LocData) & 0xFFFFFFFF;
319  case ELF::R_ARM_REL32:
320  return (S + LocData - Offset) & 0xFFFFFFFF;
321  }
322  llvm_unreachable("Invalid relocation type");
323 }
324 
325 static bool supportsAVR(uint64_t Type) {
326  switch (Type) {
327  case ELF::R_AVR_16:
328  case ELF::R_AVR_32:
329  return true;
330  default:
331  return false;
332  }
333 }
334 
335 static uint64_t resolveAVR(uint64_t Type, uint64_t Offset, uint64_t S,
336  uint64_t /*LocData*/, int64_t Addend) {
337  switch (Type) {
338  case ELF::R_AVR_16:
339  return (S + Addend) & 0xFFFF;
340  case ELF::R_AVR_32:
341  return (S + Addend) & 0xFFFFFFFF;
342  default:
343  llvm_unreachable("Invalid relocation type");
344  }
345 }
346 
347 static bool supportsLanai(uint64_t Type) {
348  return Type == ELF::R_LANAI_32;
349 }
350 
351 static uint64_t resolveLanai(uint64_t Type, uint64_t Offset, uint64_t S,
352  uint64_t /*LocData*/, int64_t Addend) {
353  if (Type == ELF::R_LANAI_32)
354  return (S + Addend) & 0xFFFFFFFF;
355  llvm_unreachable("Invalid relocation type");
356 }
357 
358 static bool supportsMips32(uint64_t Type) {
359  switch (Type) {
360  case ELF::R_MIPS_32:
361  case ELF::R_MIPS_TLS_DTPREL32:
362  return true;
363  default:
364  return false;
365  }
366 }
367 
368 static uint64_t resolveMips32(uint64_t Type, uint64_t Offset, uint64_t S,
369  uint64_t LocData, int64_t /*Addend*/) {
370  // FIXME: Take in account implicit addends to get correct results.
371  if (Type == ELF::R_MIPS_32)
372  return (S + LocData) & 0xFFFFFFFF;
373  if (Type == ELF::R_MIPS_TLS_DTPREL32)
374  return (S + LocData) & 0xFFFFFFFF;
375  llvm_unreachable("Invalid relocation type");
376 }
377 
378 static bool supportsSparc32(uint64_t Type) {
379  switch (Type) {
380  case ELF::R_SPARC_32:
381  case ELF::R_SPARC_UA32:
382  return true;
383  default:
384  return false;
385  }
386 }
387 
388 static uint64_t resolveSparc32(uint64_t Type, uint64_t Offset, uint64_t S,
389  uint64_t LocData, int64_t Addend) {
390  if (Type == ELF::R_SPARC_32 || Type == ELF::R_SPARC_UA32)
391  return S + Addend;
392  return LocData;
393 }
394 
395 static bool supportsHexagon(uint64_t Type) {
396  return Type == ELF::R_HEX_32;
397 }
398 
399 static uint64_t resolveHexagon(uint64_t Type, uint64_t Offset, uint64_t S,
400  uint64_t /*LocData*/, int64_t Addend) {
401  if (Type == ELF::R_HEX_32)
402  return S + Addend;
403  llvm_unreachable("Invalid relocation type");
404 }
405 
406 static bool supportsRISCV(uint64_t Type) {
407  switch (Type) {
408  case ELF::R_RISCV_NONE:
409  case ELF::R_RISCV_32:
410  case ELF::R_RISCV_32_PCREL:
411  case ELF::R_RISCV_64:
412  case ELF::R_RISCV_SET6:
413  case ELF::R_RISCV_SUB6:
414  case ELF::R_RISCV_ADD8:
415  case ELF::R_RISCV_SUB8:
416  case ELF::R_RISCV_ADD16:
417  case ELF::R_RISCV_SUB16:
418  case ELF::R_RISCV_ADD32:
419  case ELF::R_RISCV_SUB32:
420  case ELF::R_RISCV_ADD64:
421  case ELF::R_RISCV_SUB64:
422  return true;
423  default:
424  return false;
425  }
426 }
427 
428 static uint64_t resolveRISCV(uint64_t Type, uint64_t Offset, uint64_t S,
429  uint64_t LocData, int64_t Addend) {
430  int64_t RA = Addend;
431  uint64_t A = LocData;
432  switch (Type) {
433  case ELF::R_RISCV_NONE:
434  return LocData;
435  case ELF::R_RISCV_32:
436  return (S + RA) & 0xFFFFFFFF;
437  case ELF::R_RISCV_32_PCREL:
438  return (S + RA - Offset) & 0xFFFFFFFF;
439  case ELF::R_RISCV_64:
440  return S + RA;
441  case ELF::R_RISCV_SET6:
442  return (A & 0xC0) | ((S + RA) & 0x3F);
443  case ELF::R_RISCV_SUB6:
444  return (A & 0xC0) | (((A & 0x3F) - (S + RA)) & 0x3F);
445  case ELF::R_RISCV_ADD8:
446  return (A + (S + RA)) & 0xFF;
447  case ELF::R_RISCV_SUB8:
448  return (A - (S + RA)) & 0xFF;
449  case ELF::R_RISCV_ADD16:
450  return (A + (S + RA)) & 0xFFFF;
451  case ELF::R_RISCV_SUB16:
452  return (A - (S + RA)) & 0xFFFF;
453  case ELF::R_RISCV_ADD32:
454  return (A + (S + RA)) & 0xFFFFFFFF;
455  case ELF::R_RISCV_SUB32:
456  return (A - (S + RA)) & 0xFFFFFFFF;
457  case ELF::R_RISCV_ADD64:
458  return (A + (S + RA));
459  case ELF::R_RISCV_SUB64:
460  return (A - (S + RA));
461  default:
462  llvm_unreachable("Invalid relocation type");
463  }
464 }
465 
466 static bool supportsCOFFX86(uint64_t Type) {
467  switch (Type) {
470  return true;
471  default:
472  return false;
473  }
474 }
475 
476 static uint64_t resolveCOFFX86(uint64_t Type, uint64_t Offset, uint64_t S,
477  uint64_t LocData, int64_t /*Addend*/) {
478  switch (Type) {
481  return (S + LocData) & 0xFFFFFFFF;
482  default:
483  llvm_unreachable("Invalid relocation type");
484  }
485 }
486 
487 static bool supportsCOFFX86_64(uint64_t Type) {
488  switch (Type) {
491  return true;
492  default:
493  return false;
494  }
495 }
496 
497 static uint64_t resolveCOFFX86_64(uint64_t Type, uint64_t Offset, uint64_t S,
498  uint64_t LocData, int64_t /*Addend*/) {
499  switch (Type) {
501  return (S + LocData) & 0xFFFFFFFF;
503  return S + LocData;
504  default:
505  llvm_unreachable("Invalid relocation type");
506  }
507 }
508 
509 static bool supportsCOFFARM(uint64_t Type) {
510  switch (Type) {
513  return true;
514  default:
515  return false;
516  }
517 }
518 
519 static uint64_t resolveCOFFARM(uint64_t Type, uint64_t Offset, uint64_t S,
520  uint64_t LocData, int64_t /*Addend*/) {
521  switch (Type) {
524  return (S + LocData) & 0xFFFFFFFF;
525  default:
526  llvm_unreachable("Invalid relocation type");
527  }
528 }
529 
530 static bool supportsCOFFARM64(uint64_t Type) {
531  switch (Type) {
534  return true;
535  default:
536  return false;
537  }
538 }
539 
540 static uint64_t resolveCOFFARM64(uint64_t Type, uint64_t Offset, uint64_t S,
541  uint64_t LocData, int64_t /*Addend*/) {
542  switch (Type) {
544  return (S + LocData) & 0xFFFFFFFF;
546  return S + LocData;
547  default:
548  llvm_unreachable("Invalid relocation type");
549  }
550 }
551 
552 static bool supportsMachOX86_64(uint64_t Type) {
554 }
555 
556 static uint64_t resolveMachOX86_64(uint64_t Type, uint64_t Offset, uint64_t S,
557  uint64_t LocData, int64_t /*Addend*/) {
559  return S;
560  llvm_unreachable("Invalid relocation type");
561 }
562 
563 static bool supportsWasm32(uint64_t Type) {
564  switch (Type) {
565  case wasm::R_WASM_FUNCTION_INDEX_LEB:
566  case wasm::R_WASM_TABLE_INDEX_SLEB:
567  case wasm::R_WASM_TABLE_INDEX_I32:
568  case wasm::R_WASM_MEMORY_ADDR_LEB:
569  case wasm::R_WASM_MEMORY_ADDR_SLEB:
570  case wasm::R_WASM_MEMORY_ADDR_I32:
571  case wasm::R_WASM_TYPE_INDEX_LEB:
572  case wasm::R_WASM_GLOBAL_INDEX_LEB:
573  case wasm::R_WASM_FUNCTION_OFFSET_I32:
574  case wasm::R_WASM_SECTION_OFFSET_I32:
575  case wasm::R_WASM_EVENT_INDEX_LEB:
576  case wasm::R_WASM_GLOBAL_INDEX_I32:
577  case wasm::R_WASM_TABLE_NUMBER_LEB:
578  case wasm::R_WASM_MEMORY_ADDR_LOCREL_I32:
579  return true;
580  default:
581  return false;
582  }
583 }
584 
585 static bool supportsWasm64(uint64_t Type) {
586  switch (Type) {
587  case wasm::R_WASM_MEMORY_ADDR_LEB64:
588  case wasm::R_WASM_MEMORY_ADDR_SLEB64:
589  case wasm::R_WASM_MEMORY_ADDR_I64:
590  case wasm::R_WASM_TABLE_INDEX_SLEB64:
591  case wasm::R_WASM_TABLE_INDEX_I64:
592  case wasm::R_WASM_FUNCTION_OFFSET_I64:
593  return true;
594  default:
595  return supportsWasm32(Type);
596  }
597 }
598 
599 static uint64_t resolveWasm32(uint64_t Type, uint64_t Offset, uint64_t S,
600  uint64_t LocData, int64_t /*Addend*/) {
601  switch (Type) {
602  case wasm::R_WASM_FUNCTION_INDEX_LEB:
603  case wasm::R_WASM_TABLE_INDEX_SLEB:
604  case wasm::R_WASM_TABLE_INDEX_I32:
605  case wasm::R_WASM_MEMORY_ADDR_LEB:
606  case wasm::R_WASM_MEMORY_ADDR_SLEB:
607  case wasm::R_WASM_MEMORY_ADDR_I32:
608  case wasm::R_WASM_TYPE_INDEX_LEB:
609  case wasm::R_WASM_GLOBAL_INDEX_LEB:
610  case wasm::R_WASM_FUNCTION_OFFSET_I32:
611  case wasm::R_WASM_SECTION_OFFSET_I32:
612  case wasm::R_WASM_EVENT_INDEX_LEB:
613  case wasm::R_WASM_GLOBAL_INDEX_I32:
614  case wasm::R_WASM_TABLE_NUMBER_LEB:
615  case wasm::R_WASM_MEMORY_ADDR_LOCREL_I32:
616  // For wasm section, its offset at 0 -- ignoring Value
617  return LocData;
618  default:
619  llvm_unreachable("Invalid relocation type");
620  }
621 }
622 
623 static uint64_t resolveWasm64(uint64_t Type, uint64_t Offset, uint64_t S,
624  uint64_t LocData, int64_t Addend) {
625  switch (Type) {
626  case wasm::R_WASM_MEMORY_ADDR_LEB64:
627  case wasm::R_WASM_MEMORY_ADDR_SLEB64:
628  case wasm::R_WASM_MEMORY_ADDR_I64:
629  case wasm::R_WASM_TABLE_INDEX_SLEB64:
630  case wasm::R_WASM_TABLE_INDEX_I64:
631  case wasm::R_WASM_FUNCTION_OFFSET_I64:
632  // For wasm section, its offset at 0 -- ignoring Value
633  return LocData;
634  default:
635  return resolveWasm32(Type, Offset, S, LocData, Addend);
636  }
637 }
638 
639 std::pair<SupportsRelocation, RelocationResolver>
641  if (Obj.isCOFF()) {
642  switch (Obj.getArch()) {
643  case Triple::x86_64:
645  case Triple::x86:
647  case Triple::arm:
648  case Triple::thumb:
650  case Triple::aarch64:
652  default:
653  return {nullptr, nullptr};
654  }
655  } else if (Obj.isELF()) {
656  if (Obj.getBytesInAddress() == 8) {
657  switch (Obj.getArch()) {
658  case Triple::x86_64:
659  return {supportsX86_64, resolveX86_64};
660  case Triple::aarch64:
661  case Triple::aarch64_be:
663  case Triple::bpfel:
664  case Triple::bpfeb:
665  return {supportsBPF, resolveBPF};
666  case Triple::mips64el:
667  case Triple::mips64:
668  return {supportsMips64, resolveMips64};
669  case Triple::ppc64le:
670  case Triple::ppc64:
671  return {supportsPPC64, resolvePPC64};
672  case Triple::systemz:
674  case Triple::sparcv9:
676  case Triple::amdgcn:
677  return {supportsAmdgpu, resolveAmdgpu};
678  case Triple::riscv64:
679  return {supportsRISCV, resolveRISCV};
680  default:
681  return {nullptr, nullptr};
682  }
683  }
684 
685  // 32-bit object file
686  assert(Obj.getBytesInAddress() == 4 &&
687  "Invalid word size in object file");
688 
689  switch (Obj.getArch()) {
690  case Triple::x86:
691  return {supportsX86, resolveX86};
692  case Triple::ppcle:
693  case Triple::ppc:
694  return {supportsPPC32, resolvePPC32};
695  case Triple::arm:
696  case Triple::armeb:
697  return {supportsARM, resolveARM};
698  case Triple::avr:
699  return {supportsAVR, resolveAVR};
700  case Triple::lanai:
701  return {supportsLanai, resolveLanai};
702  case Triple::mipsel:
703  case Triple::mips:
704  return {supportsMips32, resolveMips32};
705  case Triple::msp430:
706  return {supportsMSP430, resolveMSP430};
707  case Triple::sparc:
709  case Triple::hexagon:
711  case Triple::riscv32:
712  return {supportsRISCV, resolveRISCV};
713  default:
714  return {nullptr, nullptr};
715  }
716  } else if (Obj.isMachO()) {
717  if (Obj.getArch() == Triple::x86_64)
719  return {nullptr, nullptr};
720  } else if (Obj.isWasm()) {
721  if (Obj.getArch() == Triple::wasm32)
722  return {supportsWasm32, resolveWasm32};
723  if (Obj.getArch() == Triple::wasm64)
724  return {supportsWasm64, resolveWasm64};
725  return {nullptr, nullptr};
726  }
727 
728  llvm_unreachable("Invalid object file");
729 }
730 
732  uint64_t S, uint64_t LocData) {
733  if (const ObjectFile *Obj = R.getObject()) {
734  int64_t Addend = 0;
735  if (Obj->isELF()) {
736  auto GetRelSectionType = [&]() -> unsigned {
737  if (auto *Elf32LEObj = dyn_cast<ELF32LEObjectFile>(Obj))
738  return Elf32LEObj->getRelSection(R.getRawDataRefImpl())->sh_type;
739  if (auto *Elf64LEObj = dyn_cast<ELF64LEObjectFile>(Obj))
740  return Elf64LEObj->getRelSection(R.getRawDataRefImpl())->sh_type;
741  if (auto *Elf32BEObj = dyn_cast<ELF32BEObjectFile>(Obj))
742  return Elf32BEObj->getRelSection(R.getRawDataRefImpl())->sh_type;
743  auto *Elf64BEObj = cast<ELF64BEObjectFile>(Obj);
744  return Elf64BEObj->getRelSection(R.getRawDataRefImpl())->sh_type;
745  };
746 
747  if (GetRelSectionType() == ELF::SHT_RELA)
748  Addend = getELFAddend(R);
749  }
750 
751  return Resolver(R.getType(), R.getOffset(), S, LocData, Addend);
752  }
753 
754  // Sometimes the caller might want to use its own specific implementation of
755  // the resolver function. E.g. this is used by LLD when it resolves debug
756  // relocations and assumes that all of them have the same computation (S + A).
757  // The relocation R has no owner object in this case and we don't need to
758  // provide Type and Offset fields. It is also assumed the DataRefImpl.p
759  // contains the addend, provided by the caller.
760  return Resolver(/*Type=*/0, /*Offset=*/0, S, LocData,
761  R.getRawDataRefImpl().p);
762 }
763 
764 } // namespace object
765 } // namespace llvm
llvm::object::resolveSystemZ
static uint64_t resolveSystemZ(uint64_t Type, uint64_t Offset, uint64_t S, uint64_t, int64_t Addend)
Definition: RelocationResolver.cpp:200
llvm::Triple::riscv64
@ riscv64
Definition: Triple.h:74
llvm::object::resolveAmdgpu
static uint64_t resolveAmdgpu(uint64_t Type, uint64_t Offset, uint64_t S, uint64_t, int64_t Addend)
Definition: RelocationResolver.cpp:247
llvm::object::supportsRISCV
static bool supportsRISCV(uint64_t Type)
Definition: RelocationResolver.cpp:406
llvm::COFF::IMAGE_REL_ARM64_SECREL
@ IMAGE_REL_ARM64_SECREL
Definition: COFF.h:394
llvm
Definition: AllocatorList.h:23
llvm::object::supportsAVR
static bool supportsAVR(uint64_t Type)
Definition: RelocationResolver.cpp:325
llvm::object::ObjectFile::getBytesInAddress
virtual uint8_t getBytesInAddress() const =0
The number of bytes used to represent an address in this object file format.
llvm::Triple::bpfeb
@ bpfeb
Definition: Triple.h:58
llvm::object::resolveAArch64
static uint64_t resolveAArch64(uint64_t Type, uint64_t Offset, uint64_t S, uint64_t, int64_t Addend)
Definition: RelocationResolver.cpp:74
llvm::object::RelocationResolver
uint64_t(*)(uint64_t Type, uint64_t Offset, uint64_t S, uint64_t LocData, int64_t Addend) RelocationResolver
Definition: RelocationResolver.h:37
llvm::Triple::wasm32
@ wasm32
Definition: Triple.h:99
llvm::Triple::x86
@ x86
Definition: Triple.h:83
llvm::Triple::amdgcn
@ amdgcn
Definition: Triple.h:72
llvm::object::supportsMSP430
static bool supportsMSP430(uint64_t Type)
Definition: RelocationResolver.cpp:140
llvm::object::getELFAddend
static int64_t getELFAddend(RelocationRef R)
Definition: RelocationResolver.cpp:18
llvm::Type
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:46
llvm::Triple::x86_64
@ x86_64
Definition: Triple.h:84
llvm::object::resolveCOFFX86_64
static uint64_t resolveCOFFX86_64(uint64_t Type, uint64_t Offset, uint64_t S, uint64_t LocData, int64_t)
Definition: RelocationResolver.cpp:497
llvm::Triple::ppc
@ ppc
Definition: Triple.h:67
llvm::object::ObjectFile::getArch
virtual Triple::ArchType getArch() const =0
llvm::Triple::hexagon
@ hexagon
Definition: Triple.h:60
Offset
uint64_t Offset
Definition: ELFObjHandler.cpp:81
llvm::object::resolveX86_64
static uint64_t resolveX86_64(uint64_t Type, uint64_t Offset, uint64_t S, uint64_t LocData, int64_t Addend)
Definition: RelocationResolver.cpp:42
llvm::Expected
Tagged union holding either a T or a Error.
Definition: APFloat.h:42
llvm::object::supportsCOFFARM64
static bool supportsCOFFARM64(uint64_t Type)
Definition: RelocationResolver.cpp:530
llvm::Triple::avr
@ avr
Definition: Triple.h:56
llvm::Triple::mips64
@ mips64
Definition: Triple.h:64
llvm::object::supportsMachOX86_64
static bool supportsMachOX86_64(uint64_t Type)
Definition: RelocationResolver.cpp:552
llvm::object::resolveSparc64
static uint64_t resolveSparc64(uint64_t Type, uint64_t Offset, uint64_t S, uint64_t, int64_t Addend)
Definition: RelocationResolver.cpp:224
llvm::object::supportsBPF
static bool supportsBPF(uint64_t Type)
Definition: RelocationResolver.cpp:90
llvm::Resolver
Interface for looking up the initializer for a variable name, used by Init::resolveReferences.
Definition: Record.h:2000
llvm::COFF::IMAGE_REL_ARM_SECREL
@ IMAGE_REL_ARM_SECREL
Definition: COFF.h:376
llvm::Triple::sparc
@ sparc
Definition: Triple.h:75
llvm::object::ELFRelocationRef
Definition: ELFObjectFile.h:191
llvm::object::supportsMips32
static bool supportsMips32(uint64_t Type)
Definition: RelocationResolver.cpp:358
llvm::Triple::sparcv9
@ sparcv9
Definition: Triple.h:76
llvm::object::resolveBPF
static uint64_t resolveBPF(uint64_t Type, uint64_t Offset, uint64_t S, uint64_t LocData, int64_t)
Definition: RelocationResolver.cpp:100
llvm::object::supportsCOFFARM
static bool supportsCOFFARM(uint64_t Type)
Definition: RelocationResolver.cpp:509
llvm::object::supportsSparc64
static bool supportsSparc64(uint64_t Type)
Definition: RelocationResolver.cpp:212
llvm::Triple::mips64el
@ mips64el
Definition: Triple.h:65
llvm::object::resolvePPC32
static uint64_t resolvePPC32(uint64_t Type, uint64_t Offset, uint64_t S, uint64_t, int64_t Addend)
Definition: RelocationResolver.cpp:293
llvm::object::supportsWasm64
static bool supportsWasm64(uint64_t Type)
Definition: RelocationResolver.cpp:585
llvm::object::resolveWasm32
static uint64_t resolveWasm32(uint64_t Type, uint64_t Offset, uint64_t S, uint64_t LocData, int64_t)
Definition: RelocationResolver.cpp:599
llvm::Triple::ppc64
@ ppc64
Definition: Triple.h:69
llvm::object::supportsX86_64
static bool supportsX86_64(uint64_t Type)
Definition: RelocationResolver.cpp:26
llvm::COFF::IMAGE_REL_I386_DIR32
@ IMAGE_REL_I386_DIR32
Definition: COFF.h:335
llvm::object::resolveARM
static uint64_t resolveARM(uint64_t Type, uint64_t Offset, uint64_t S, uint64_t LocData, int64_t)
Definition: RelocationResolver.cpp:314
llvm::Triple::lanai
@ lanai
Definition: Triple.h:98
llvm::object::resolveAVR
static uint64_t resolveAVR(uint64_t Type, uint64_t Offset, uint64_t S, uint64_t, int64_t Addend)
Definition: RelocationResolver.cpp:335
llvm::ErrorInfoBase
Base class for error info classes.
Definition: Error.h:48
llvm::object::resolveMips64
static uint64_t resolveMips64(uint64_t Type, uint64_t Offset, uint64_t S, uint64_t, int64_t Addend)
Definition: RelocationResolver.cpp:124
llvm::object::supportsARM
static bool supportsARM(uint64_t Type)
Definition: RelocationResolver.cpp:304
llvm::object::resolveHexagon
static uint64_t resolveHexagon(uint64_t Type, uint64_t Offset, uint64_t S, uint64_t, int64_t Addend)
Definition: RelocationResolver.cpp:399
llvm::Triple::ppc64le
@ ppc64le
Definition: Triple.h:70
llvm::MachO::X86_64_RELOC_UNSIGNED
@ X86_64_RELOC_UNSIGNED
Definition: MachO.h:474
object
bar al al movzbl eax ret Missed when stored in a memory object
Definition: README.txt:1411
llvm::object::resolveRISCV
static uint64_t resolveRISCV(uint64_t Type, uint64_t Offset, uint64_t S, uint64_t LocData, int64_t Addend)
Definition: RelocationResolver.cpp:428
llvm::object::supportsCOFFX86_64
static bool supportsCOFFX86_64(uint64_t Type)
Definition: RelocationResolver.cpp:487
llvm::ELF::SHT_RELA
@ SHT_RELA
Definition: ELF.h:907
llvm::object::supportsSparc32
static bool supportsSparc32(uint64_t Type)
Definition: RelocationResolver.cpp:378
llvm::COFF::IMAGE_REL_AMD64_ADDR64
@ IMAGE_REL_AMD64_ADDR64
Definition: COFF.h:347
llvm::object::supportsSystemZ
static bool supportsSystemZ(uint64_t Type)
Definition: RelocationResolver.cpp:190
llvm::object::supportsLanai
static bool supportsLanai(uint64_t Type)
Definition: RelocationResolver.cpp:347
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::object::Binary::isELF
bool isELF() const
Definition: Binary.h:120
llvm::object::supportsX86
static bool supportsX86(uint64_t Type)
Definition: RelocationResolver.cpp:258
llvm::Triple::bpfel
@ bpfel
Definition: Triple.h:57
RA
SI optimize exec mask operations pre RA
Definition: SIOptimizeExecMaskingPreRA.cpp:71
llvm::object::getRelocationResolver
std::pair< SupportsRelocation, RelocationResolver > getRelocationResolver(const ObjectFile &Obj)
Definition: RelocationResolver.cpp:640
llvm::Triple::armeb
@ armeb
Definition: Triple.h:51
llvm::object::supportsPPC64
static bool supportsPPC64(uint64_t Type)
Definition: RelocationResolver.cpp:162
RelocationResolver.h
llvm::object::Binary::isCOFF
bool isCOFF() const
Definition: Binary.h:128
llvm::object::resolveMSP430
static uint64_t resolveMSP430(uint64_t Type, uint64_t Offset, uint64_t S, uint64_t, int64_t Addend)
Definition: RelocationResolver.cpp:150
llvm::Triple::arm
@ arm
Definition: Triple.h:50
llvm::object::resolveMips32
static uint64_t resolveMips32(uint64_t Type, uint64_t Offset, uint64_t S, uint64_t LocData, int64_t)
Definition: RelocationResolver.cpp:368
llvm::object::resolveX86
static uint64_t resolveX86(uint64_t Type, uint64_t Offset, uint64_t S, uint64_t LocData, int64_t)
Definition: RelocationResolver.cpp:269
llvm::Triple::aarch64_be
@ aarch64_be
Definition: Triple.h:53
llvm::Triple::msp430
@ msp430
Definition: Triple.h:66
llvm::object::ObjectFile
This class is the base class for all object file types.
Definition: ObjectFile.h:225
llvm::object::Binary::isWasm
bool isWasm() const
Definition: Binary.h:134
llvm::object::supportsPPC32
static bool supportsPPC32(uint64_t Type)
Definition: RelocationResolver.cpp:283
llvm::Triple::ppcle
@ ppcle
Definition: Triple.h:68
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:136
llvm::Triple::thumb
@ thumb
Definition: Triple.h:81
S
add sub stmia L5 ldr r0 bl L_printf $stub Instead of a and a wouldn t it be better to do three moves *Return an aggregate type is even return S
Definition: README.txt:210
llvm::COFF::IMAGE_REL_AMD64_SECREL
@ IMAGE_REL_AMD64_SECREL
Definition: COFF.h:357
llvm::object::supportsMips64
static bool supportsMips64(uint64_t Type)
Definition: RelocationResolver.cpp:112
llvm::object::resolveCOFFARM64
static uint64_t resolveCOFFARM64(uint64_t Type, uint64_t Offset, uint64_t S, uint64_t LocData, int64_t)
Definition: RelocationResolver.cpp:540
llvm::object::resolveMachOX86_64
static uint64_t resolveMachOX86_64(uint64_t Type, uint64_t Offset, uint64_t S, uint64_t LocData, int64_t)
Definition: RelocationResolver.cpp:556
llvm::object::resolveWasm64
static uint64_t resolveWasm64(uint64_t Type, uint64_t Offset, uint64_t S, uint64_t LocData, int64_t Addend)
Definition: RelocationResolver.cpp:623
llvm::object::supportsWasm32
static bool supportsWasm32(uint64_t Type)
Definition: RelocationResolver.cpp:563
llvm::Triple::riscv32
@ riscv32
Definition: Triple.h:73
llvm::object::resolveLanai
static uint64_t resolveLanai(uint64_t Type, uint64_t Offset, uint64_t S, uint64_t, int64_t Addend)
Definition: RelocationResolver.cpp:351
llvm::Triple::mipsel
@ mipsel
Definition: Triple.h:63
llvm::object::resolveCOFFX86
static uint64_t resolveCOFFX86(uint64_t Type, uint64_t Offset, uint64_t S, uint64_t LocData, int64_t)
Definition: RelocationResolver.cpp:476
llvm::object::Binary::isMachO
bool isMachO() const
Definition: Binary.h:124
llvm::Triple::systemz
@ systemz
Definition: Triple.h:78
llvm::object::resolvePPC64
static uint64_t resolvePPC64(uint64_t Type, uint64_t Offset, uint64_t S, uint64_t, int64_t Addend)
Definition: RelocationResolver.cpp:174
llvm::Expected::takeError
Error takeError()
Take ownership of the stored error.
Definition: Error.h:557
llvm::object::supportsAArch64
static bool supportsAArch64(uint64_t Type)
Definition: RelocationResolver.cpp:62
llvm::COFF::IMAGE_REL_I386_SECREL
@ IMAGE_REL_I386_SECREL
Definition: COFF.h:339
llvm::object::resolveSparc32
static uint64_t resolveSparc32(uint64_t Type, uint64_t Offset, uint64_t S, uint64_t LocData, int64_t Addend)
Definition: RelocationResolver.cpp:388
llvm::object::resolveCOFFARM
static uint64_t resolveCOFFARM(uint64_t Type, uint64_t Offset, uint64_t S, uint64_t LocData, int64_t)
Definition: RelocationResolver.cpp:519
llvm::object::RelocationRef
This is a value type class that represents a single relocation in the list of relocations in the obje...
Definition: ObjectFile.h:51
llvm::object::supportsHexagon
static bool supportsHexagon(uint64_t Type)
Definition: RelocationResolver.cpp:395
llvm::COFF::IMAGE_REL_ARM64_ADDR64
@ IMAGE_REL_ARM64_ADDR64
Definition: COFF.h:400
llvm::object::ELFRelocationRef::getAddend
Expected< int64_t > getAddend() const
Definition: ELFObjectFile.h:201
llvm::object::supportsAmdgpu
static bool supportsAmdgpu(uint64_t Type)
Definition: RelocationResolver.cpp:237
llvm::COFF::IMAGE_REL_ARM_ADDR32
@ IMAGE_REL_ARM_ADDR32
Definition: COFF.h:367
llvm::Triple::wasm64
@ wasm64
Definition: Triple.h:100
llvm::handleAllErrors
void handleAllErrors(Error E, HandlerTs &&... Handlers)
Behaves the same as handleErrors, except that by contract all errors must be handled by the given han...
Definition: Error.h:929
llvm::Triple::mips
@ mips
Definition: Triple.h:62
llvm::Triple::aarch64
@ aarch64
Definition: Triple.h:52
llvm::object::supportsCOFFX86
static bool supportsCOFFX86(uint64_t Type)
Definition: RelocationResolver.cpp:466
llvm::object::resolveRelocation
uint64_t resolveRelocation(RelocationResolver Resolver, const RelocationRef &R, uint64_t S, uint64_t LocData)
Definition: RelocationResolver.cpp:731