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