Clang] Fix expansion of response files in -Wp after integrated-cc1 change
[llvm-project.git] / llvm / lib / Object / RelocationResolver.cpp
blob31478be7899ed0531d1b81208dbfe894b9163bc9
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.
11 //===----------------------------------------------------------------------===//
13 #include "llvm/Object/RelocationResolver.h"
15 namespace llvm {
16 namespace object {
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;
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;
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");
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;
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");
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;
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");
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;
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");
130 static bool supportsPPC64(uint64_t Type) {
131 switch (Type) {
132 case ELF::R_PPC64_ADDR32:
133 case ELF::R_PPC64_ADDR64:
134 return true;
135 default:
136 return false;
140 static uint64_t resolvePPC64(RelocationRef R, uint64_t S, uint64_t A) {
141 switch (R.getType()) {
142 case ELF::R_PPC64_ADDR32:
143 return (S + getELFAddend(R)) & 0xFFFFFFFF;
144 case ELF::R_PPC64_ADDR64:
145 return S + getELFAddend(R);
146 default:
147 llvm_unreachable("Invalid relocation type");
151 static bool supportsSystemZ(uint64_t Type) {
152 switch (Type) {
153 case ELF::R_390_32:
154 case ELF::R_390_64:
155 return true;
156 default:
157 return false;
161 static uint64_t resolveSystemZ(RelocationRef R, uint64_t S, uint64_t A) {
162 switch (R.getType()) {
163 case ELF::R_390_32:
164 return (S + getELFAddend(R)) & 0xFFFFFFFF;
165 case ELF::R_390_64:
166 return S + getELFAddend(R);
167 default:
168 llvm_unreachable("Invalid relocation type");
172 static bool supportsSparc64(uint64_t Type) {
173 switch (Type) {
174 case ELF::R_SPARC_32:
175 case ELF::R_SPARC_64:
176 case ELF::R_SPARC_UA32:
177 case ELF::R_SPARC_UA64:
178 return true;
179 default:
180 return false;
184 static uint64_t resolveSparc64(RelocationRef R, uint64_t S, uint64_t A) {
185 switch (R.getType()) {
186 case ELF::R_SPARC_32:
187 case ELF::R_SPARC_64:
188 case ELF::R_SPARC_UA32:
189 case ELF::R_SPARC_UA64:
190 return S + getELFAddend(R);
191 default:
192 llvm_unreachable("Invalid relocation type");
196 static bool supportsAmdgpu(uint64_t Type) {
197 switch (Type) {
198 case ELF::R_AMDGPU_ABS32:
199 case ELF::R_AMDGPU_ABS64:
200 return true;
201 default:
202 return false;
206 static uint64_t resolveAmdgpu(RelocationRef R, uint64_t S, uint64_t A) {
207 switch (R.getType()) {
208 case ELF::R_AMDGPU_ABS32:
209 case ELF::R_AMDGPU_ABS64:
210 return S + getELFAddend(R);
211 default:
212 llvm_unreachable("Invalid relocation type");
216 static bool supportsX86(uint64_t Type) {
217 switch (Type) {
218 case ELF::R_386_NONE:
219 case ELF::R_386_32:
220 case ELF::R_386_PC32:
221 return true;
222 default:
223 return false;
227 static uint64_t resolveX86(RelocationRef R, uint64_t S, uint64_t A) {
228 switch (R.getType()) {
229 case ELF::R_386_NONE:
230 return A;
231 case ELF::R_386_32:
232 return S + A;
233 case ELF::R_386_PC32:
234 return S - R.getOffset() + A;
235 default:
236 llvm_unreachable("Invalid relocation type");
240 static bool supportsPPC32(uint64_t Type) {
241 return Type == ELF::R_PPC_ADDR32;
244 static uint64_t resolvePPC32(RelocationRef R, uint64_t S, uint64_t A) {
245 if (R.getType() == ELF::R_PPC_ADDR32)
246 return (S + getELFAddend(R)) & 0xFFFFFFFF;
247 llvm_unreachable("Invalid relocation type");
250 static bool supportsARM(uint64_t Type) {
251 return Type == ELF::R_ARM_ABS32;
254 static uint64_t resolveARM(RelocationRef R, uint64_t S, uint64_t A) {
255 if (R.getType() == ELF::R_ARM_ABS32)
256 return (S + A) & 0xFFFFFFFF;
257 llvm_unreachable("Invalid relocation type");
260 static bool supportsAVR(uint64_t Type) {
261 switch (Type) {
262 case ELF::R_AVR_16:
263 case ELF::R_AVR_32:
264 return true;
265 default:
266 return false;
270 static uint64_t resolveAVR(RelocationRef R, uint64_t S, uint64_t A) {
271 switch (R.getType()) {
272 case ELF::R_AVR_16:
273 return (S + getELFAddend(R)) & 0xFFFF;
274 case ELF::R_AVR_32:
275 return (S + getELFAddend(R)) & 0xFFFFFFFF;
276 default:
277 llvm_unreachable("Invalid relocation type");
281 static bool supportsLanai(uint64_t Type) {
282 return Type == ELF::R_LANAI_32;
285 static uint64_t resolveLanai(RelocationRef R, uint64_t S, uint64_t A) {
286 if (R.getType() == ELF::R_LANAI_32)
287 return (S + getELFAddend(R)) & 0xFFFFFFFF;
288 llvm_unreachable("Invalid relocation type");
291 static bool supportsMips32(uint64_t Type) {
292 switch (Type) {
293 case ELF::R_MIPS_32:
294 case ELF::R_MIPS_TLS_DTPREL32:
295 return true;
296 default:
297 return false;
301 static uint64_t resolveMips32(RelocationRef R, uint64_t S, uint64_t A) {
302 // FIXME: Take in account implicit addends to get correct results.
303 uint32_t Rel = R.getType();
304 if (Rel == ELF::R_MIPS_32)
305 return (S + A) & 0xFFFFFFFF;
306 if (Rel == ELF::R_MIPS_TLS_DTPREL32)
307 return (S + A) & 0xFFFFFFFF;
308 llvm_unreachable("Invalid relocation type");
311 static bool supportsSparc32(uint64_t Type) {
312 switch (Type) {
313 case ELF::R_SPARC_32:
314 case ELF::R_SPARC_UA32:
315 return true;
316 default:
317 return false;
321 static uint64_t resolveSparc32(RelocationRef R, uint64_t S, uint64_t A) {
322 uint32_t Rel = R.getType();
323 if (Rel == ELF::R_SPARC_32 || Rel == ELF::R_SPARC_UA32)
324 return S + getELFAddend(R);
325 return A;
328 static bool supportsHexagon(uint64_t Type) {
329 return Type == ELF::R_HEX_32;
332 static uint64_t resolveHexagon(RelocationRef R, uint64_t S, uint64_t A) {
333 if (R.getType() == ELF::R_HEX_32)
334 return S + getELFAddend(R);
335 llvm_unreachable("Invalid relocation type");
338 static bool supportsRISCV(uint64_t Type) {
339 switch (Type) {
340 case ELF::R_RISCV_NONE:
341 case ELF::R_RISCV_32:
342 case ELF::R_RISCV_32_PCREL:
343 case ELF::R_RISCV_64:
344 case ELF::R_RISCV_SET6:
345 case ELF::R_RISCV_SUB6:
346 case ELF::R_RISCV_ADD8:
347 case ELF::R_RISCV_SUB8:
348 case ELF::R_RISCV_ADD16:
349 case ELF::R_RISCV_SUB16:
350 case ELF::R_RISCV_ADD32:
351 case ELF::R_RISCV_SUB32:
352 case ELF::R_RISCV_ADD64:
353 case ELF::R_RISCV_SUB64:
354 return true;
355 default:
356 return false;
360 static uint64_t resolveRISCV(RelocationRef R, uint64_t S, uint64_t A) {
361 int64_t RA = getELFAddend(R);
362 switch (R.getType()) {
363 case ELF::R_RISCV_NONE:
364 return A;
365 case ELF::R_RISCV_32:
366 return (S + RA) & 0xFFFFFFFF;
367 case ELF::R_RISCV_32_PCREL:
368 return (S + RA - R.getOffset()) & 0xFFFFFFFF;
369 case ELF::R_RISCV_64:
370 return S + RA;
371 case ELF::R_RISCV_SET6:
372 return (A & 0xC0) | ((S + RA) & 0x3F);
373 case ELF::R_RISCV_SUB6:
374 return (A & 0xC0) | (((A & 0x3F) - (S + RA)) & 0x3F);
375 case ELF::R_RISCV_ADD8:
376 return (A + (S + RA)) & 0xFF;
377 case ELF::R_RISCV_SUB8:
378 return (A - (S + RA)) & 0xFF;
379 case ELF::R_RISCV_ADD16:
380 return (A + (S + RA)) & 0xFFFF;
381 case ELF::R_RISCV_SUB16:
382 return (A - (S + RA)) & 0xFFFF;
383 case ELF::R_RISCV_ADD32:
384 return (A + (S + RA)) & 0xFFFFFFFF;
385 case ELF::R_RISCV_SUB32:
386 return (A - (S + RA)) & 0xFFFFFFFF;
387 case ELF::R_RISCV_ADD64:
388 return (A + (S + RA));
389 case ELF::R_RISCV_SUB64:
390 return (A - (S + RA));
391 default:
392 llvm_unreachable("Invalid relocation type");
396 static bool supportsCOFFX86(uint64_t Type) {
397 switch (Type) {
398 case COFF::IMAGE_REL_I386_SECREL:
399 case COFF::IMAGE_REL_I386_DIR32:
400 return true;
401 default:
402 return false;
406 static uint64_t resolveCOFFX86(RelocationRef R, uint64_t S, uint64_t A) {
407 switch (R.getType()) {
408 case COFF::IMAGE_REL_I386_SECREL:
409 case COFF::IMAGE_REL_I386_DIR32:
410 return (S + A) & 0xFFFFFFFF;
411 default:
412 llvm_unreachable("Invalid relocation type");
416 static bool supportsCOFFX86_64(uint64_t Type) {
417 switch (Type) {
418 case COFF::IMAGE_REL_AMD64_SECREL:
419 case COFF::IMAGE_REL_AMD64_ADDR64:
420 return true;
421 default:
422 return false;
426 static uint64_t resolveCOFFX86_64(RelocationRef R, uint64_t S, uint64_t A) {
427 switch (R.getType()) {
428 case COFF::IMAGE_REL_AMD64_SECREL:
429 return (S + A) & 0xFFFFFFFF;
430 case COFF::IMAGE_REL_AMD64_ADDR64:
431 return S + A;
432 default:
433 llvm_unreachable("Invalid relocation type");
437 static bool supportsCOFFARM(uint64_t Type) {
438 switch (Type) {
439 case COFF::IMAGE_REL_ARM_SECREL:
440 case COFF::IMAGE_REL_ARM_ADDR32:
441 return true;
442 default:
443 return false;
447 static uint64_t resolveCOFFARM(RelocationRef R, uint64_t S, uint64_t A) {
448 switch (R.getType()) {
449 case COFF::IMAGE_REL_ARM_SECREL:
450 case COFF::IMAGE_REL_ARM_ADDR32:
451 return (S + A) & 0xFFFFFFFF;
452 default:
453 llvm_unreachable("Invalid relocation type");
457 static bool supportsCOFFARM64(uint64_t Type) {
458 switch (Type) {
459 case COFF::IMAGE_REL_ARM64_SECREL:
460 case COFF::IMAGE_REL_ARM64_ADDR64:
461 return true;
462 default:
463 return false;
467 static uint64_t resolveCOFFARM64(RelocationRef R, uint64_t S, uint64_t A) {
468 switch (R.getType()) {
469 case COFF::IMAGE_REL_ARM64_SECREL:
470 return (S + A) & 0xFFFFFFFF;
471 case COFF::IMAGE_REL_ARM64_ADDR64:
472 return S + A;
473 default:
474 llvm_unreachable("Invalid relocation type");
478 static bool supportsMachOX86_64(uint64_t Type) {
479 return Type == MachO::X86_64_RELOC_UNSIGNED;
482 static uint64_t resolveMachOX86_64(RelocationRef R, uint64_t S, uint64_t A) {
483 if (R.getType() == MachO::X86_64_RELOC_UNSIGNED)
484 return S;
485 llvm_unreachable("Invalid relocation type");
488 static bool supportsWasm32(uint64_t Type) {
489 switch (Type) {
490 case wasm::R_WASM_FUNCTION_INDEX_LEB:
491 case wasm::R_WASM_TABLE_INDEX_SLEB:
492 case wasm::R_WASM_TABLE_INDEX_I32:
493 case wasm::R_WASM_MEMORY_ADDR_LEB:
494 case wasm::R_WASM_MEMORY_ADDR_SLEB:
495 case wasm::R_WASM_MEMORY_ADDR_I32:
496 case wasm::R_WASM_TYPE_INDEX_LEB:
497 case wasm::R_WASM_GLOBAL_INDEX_LEB:
498 case wasm::R_WASM_FUNCTION_OFFSET_I32:
499 case wasm::R_WASM_SECTION_OFFSET_I32:
500 case wasm::R_WASM_EVENT_INDEX_LEB:
501 return true;
502 default:
503 return false;
507 static uint64_t resolveWasm32(RelocationRef R, uint64_t S, uint64_t A) {
508 switch (R.getType()) {
509 case wasm::R_WASM_FUNCTION_INDEX_LEB:
510 case wasm::R_WASM_TABLE_INDEX_SLEB:
511 case wasm::R_WASM_TABLE_INDEX_I32:
512 case wasm::R_WASM_MEMORY_ADDR_LEB:
513 case wasm::R_WASM_MEMORY_ADDR_SLEB:
514 case wasm::R_WASM_MEMORY_ADDR_I32:
515 case wasm::R_WASM_TYPE_INDEX_LEB:
516 case wasm::R_WASM_GLOBAL_INDEX_LEB:
517 case wasm::R_WASM_FUNCTION_OFFSET_I32:
518 case wasm::R_WASM_SECTION_OFFSET_I32:
519 case wasm::R_WASM_EVENT_INDEX_LEB:
520 // For wasm section, its offset at 0 -- ignoring Value
521 return A;
522 default:
523 llvm_unreachable("Invalid relocation type");
527 std::pair<bool (*)(uint64_t), RelocationResolver>
528 getRelocationResolver(const ObjectFile &Obj) {
529 if (Obj.isCOFF()) {
530 switch (Obj.getArch()) {
531 case Triple::x86_64:
532 return {supportsCOFFX86_64, resolveCOFFX86_64};
533 case Triple::x86:
534 return {supportsCOFFX86, resolveCOFFX86};
535 case Triple::arm:
536 case Triple::thumb:
537 return {supportsCOFFARM, resolveCOFFARM};
538 case Triple::aarch64:
539 return {supportsCOFFARM64, resolveCOFFARM64};
540 default:
541 return {nullptr, nullptr};
543 } else if (Obj.isELF()) {
544 if (Obj.getBytesInAddress() == 8) {
545 switch (Obj.getArch()) {
546 case Triple::x86_64:
547 return {supportsX86_64, resolveX86_64};
548 case Triple::aarch64:
549 case Triple::aarch64_be:
550 return {supportsAArch64, resolveAArch64};
551 case Triple::bpfel:
552 case Triple::bpfeb:
553 return {supportsBPF, resolveBPF};
554 case Triple::mips64el:
555 case Triple::mips64:
556 return {supportsMips64, resolveMips64};
557 case Triple::ppc64le:
558 case Triple::ppc64:
559 return {supportsPPC64, resolvePPC64};
560 case Triple::systemz:
561 return {supportsSystemZ, resolveSystemZ};
562 case Triple::sparcv9:
563 return {supportsSparc64, resolveSparc64};
564 case Triple::amdgcn:
565 return {supportsAmdgpu, resolveAmdgpu};
566 case Triple::riscv64:
567 return {supportsRISCV, resolveRISCV};
568 default:
569 return {nullptr, nullptr};
573 // 32-bit object file
574 assert(Obj.getBytesInAddress() == 4 &&
575 "Invalid word size in object file");
577 switch (Obj.getArch()) {
578 case Triple::x86:
579 return {supportsX86, resolveX86};
580 case Triple::ppc:
581 return {supportsPPC32, resolvePPC32};
582 case Triple::arm:
583 case Triple::armeb:
584 return {supportsARM, resolveARM};
585 case Triple::avr:
586 return {supportsAVR, resolveAVR};
587 case Triple::lanai:
588 return {supportsLanai, resolveLanai};
589 case Triple::mipsel:
590 case Triple::mips:
591 return {supportsMips32, resolveMips32};
592 case Triple::sparc:
593 return {supportsSparc32, resolveSparc32};
594 case Triple::hexagon:
595 return {supportsHexagon, resolveHexagon};
596 case Triple::riscv32:
597 return {supportsRISCV, resolveRISCV};
598 default:
599 return {nullptr, nullptr};
601 } else if (Obj.isMachO()) {
602 if (Obj.getArch() == Triple::x86_64)
603 return {supportsMachOX86_64, resolveMachOX86_64};
604 return {nullptr, nullptr};
605 } else if (Obj.isWasm()) {
606 if (Obj.getArch() == Triple::wasm32)
607 return {supportsWasm32, resolveWasm32};
608 return {nullptr, nullptr};
611 llvm_unreachable("Invalid object file");
614 } // namespace object
615 } // namespace llvm