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(Twine(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_ABS32: 93 case ELF::R_BPF_64_ABS64: 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_ABS32: 104 return (S + LocData) & 0xFFFFFFFF; 105 case ELF::R_BPF_64_ABS64: 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 // Support both RELA and REL relocations. The caller is responsible 317 // for supplying the correct values for LocData and Addend, i.e. 318 // Addend == 0 for REL and LocData == 0 for RELA. 319 assert((LocData == 0 || Addend == 0) && 320 "one of LocData and Addend must be 0"); 321 switch (Type) { 322 case ELF::R_ARM_ABS32: 323 return (S + LocData + Addend) & 0xFFFFFFFF; 324 case ELF::R_ARM_REL32: 325 return (S + LocData + Addend - Offset) & 0xFFFFFFFF; 326 } 327 llvm_unreachable("Invalid relocation type"); 328 } 329 330 static bool supportsAVR(uint64_t Type) { 331 switch (Type) { 332 case ELF::R_AVR_16: 333 case ELF::R_AVR_32: 334 return true; 335 default: 336 return false; 337 } 338 } 339 340 static uint64_t resolveAVR(uint64_t Type, uint64_t Offset, uint64_t S, 341 uint64_t /*LocData*/, int64_t Addend) { 342 switch (Type) { 343 case ELF::R_AVR_16: 344 return (S + Addend) & 0xFFFF; 345 case ELF::R_AVR_32: 346 return (S + Addend) & 0xFFFFFFFF; 347 default: 348 llvm_unreachable("Invalid relocation type"); 349 } 350 } 351 352 static bool supportsLanai(uint64_t Type) { 353 return Type == ELF::R_LANAI_32; 354 } 355 356 static uint64_t resolveLanai(uint64_t Type, uint64_t Offset, uint64_t S, 357 uint64_t /*LocData*/, int64_t Addend) { 358 if (Type == ELF::R_LANAI_32) 359 return (S + Addend) & 0xFFFFFFFF; 360 llvm_unreachable("Invalid relocation type"); 361 } 362 363 static bool supportsMips32(uint64_t Type) { 364 switch (Type) { 365 case ELF::R_MIPS_32: 366 case ELF::R_MIPS_TLS_DTPREL32: 367 return true; 368 default: 369 return false; 370 } 371 } 372 373 static uint64_t resolveMips32(uint64_t Type, uint64_t Offset, uint64_t S, 374 uint64_t LocData, int64_t /*Addend*/) { 375 // FIXME: Take in account implicit addends to get correct results. 376 if (Type == ELF::R_MIPS_32) 377 return (S + LocData) & 0xFFFFFFFF; 378 if (Type == ELF::R_MIPS_TLS_DTPREL32) 379 return (S + LocData) & 0xFFFFFFFF; 380 llvm_unreachable("Invalid relocation type"); 381 } 382 383 static bool supportsSparc32(uint64_t Type) { 384 switch (Type) { 385 case ELF::R_SPARC_32: 386 case ELF::R_SPARC_UA32: 387 return true; 388 default: 389 return false; 390 } 391 } 392 393 static uint64_t resolveSparc32(uint64_t Type, uint64_t Offset, uint64_t S, 394 uint64_t LocData, int64_t Addend) { 395 if (Type == ELF::R_SPARC_32 || Type == ELF::R_SPARC_UA32) 396 return S + Addend; 397 return LocData; 398 } 399 400 static bool supportsHexagon(uint64_t Type) { 401 return Type == ELF::R_HEX_32; 402 } 403 404 static uint64_t resolveHexagon(uint64_t Type, uint64_t Offset, uint64_t S, 405 uint64_t /*LocData*/, int64_t Addend) { 406 if (Type == ELF::R_HEX_32) 407 return S + Addend; 408 llvm_unreachable("Invalid relocation type"); 409 } 410 411 static bool supportsRISCV(uint64_t Type) { 412 switch (Type) { 413 case ELF::R_RISCV_NONE: 414 case ELF::R_RISCV_32: 415 case ELF::R_RISCV_32_PCREL: 416 case ELF::R_RISCV_64: 417 case ELF::R_RISCV_SET6: 418 case ELF::R_RISCV_SUB6: 419 case ELF::R_RISCV_ADD8: 420 case ELF::R_RISCV_SUB8: 421 case ELF::R_RISCV_ADD16: 422 case ELF::R_RISCV_SUB16: 423 case ELF::R_RISCV_ADD32: 424 case ELF::R_RISCV_SUB32: 425 case ELF::R_RISCV_ADD64: 426 case ELF::R_RISCV_SUB64: 427 return true; 428 default: 429 return false; 430 } 431 } 432 433 static uint64_t resolveRISCV(uint64_t Type, uint64_t Offset, uint64_t S, 434 uint64_t LocData, int64_t Addend) { 435 int64_t RA = Addend; 436 uint64_t A = LocData; 437 switch (Type) { 438 case ELF::R_RISCV_NONE: 439 return LocData; 440 case ELF::R_RISCV_32: 441 return (S + RA) & 0xFFFFFFFF; 442 case ELF::R_RISCV_32_PCREL: 443 return (S + RA - Offset) & 0xFFFFFFFF; 444 case ELF::R_RISCV_64: 445 return S + RA; 446 case ELF::R_RISCV_SET6: 447 return (A & 0xC0) | ((S + RA) & 0x3F); 448 case ELF::R_RISCV_SUB6: 449 return (A & 0xC0) | (((A & 0x3F) - (S + RA)) & 0x3F); 450 case ELF::R_RISCV_ADD8: 451 return (A + (S + RA)) & 0xFF; 452 case ELF::R_RISCV_SUB8: 453 return (A - (S + RA)) & 0xFF; 454 case ELF::R_RISCV_ADD16: 455 return (A + (S + RA)) & 0xFFFF; 456 case ELF::R_RISCV_SUB16: 457 return (A - (S + RA)) & 0xFFFF; 458 case ELF::R_RISCV_ADD32: 459 return (A + (S + RA)) & 0xFFFFFFFF; 460 case ELF::R_RISCV_SUB32: 461 return (A - (S + RA)) & 0xFFFFFFFF; 462 case ELF::R_RISCV_ADD64: 463 return (A + (S + RA)); 464 case ELF::R_RISCV_SUB64: 465 return (A - (S + RA)); 466 default: 467 llvm_unreachable("Invalid relocation type"); 468 } 469 } 470 471 static bool supportsCOFFX86(uint64_t Type) { 472 switch (Type) { 473 case COFF::IMAGE_REL_I386_SECREL: 474 case COFF::IMAGE_REL_I386_DIR32: 475 return true; 476 default: 477 return false; 478 } 479 } 480 481 static uint64_t resolveCOFFX86(uint64_t Type, uint64_t Offset, uint64_t S, 482 uint64_t LocData, int64_t /*Addend*/) { 483 switch (Type) { 484 case COFF::IMAGE_REL_I386_SECREL: 485 case COFF::IMAGE_REL_I386_DIR32: 486 return (S + LocData) & 0xFFFFFFFF; 487 default: 488 llvm_unreachable("Invalid relocation type"); 489 } 490 } 491 492 static bool supportsCOFFX86_64(uint64_t Type) { 493 switch (Type) { 494 case COFF::IMAGE_REL_AMD64_SECREL: 495 case COFF::IMAGE_REL_AMD64_ADDR64: 496 return true; 497 default: 498 return false; 499 } 500 } 501 502 static uint64_t resolveCOFFX86_64(uint64_t Type, uint64_t Offset, uint64_t S, 503 uint64_t LocData, int64_t /*Addend*/) { 504 switch (Type) { 505 case COFF::IMAGE_REL_AMD64_SECREL: 506 return (S + LocData) & 0xFFFFFFFF; 507 case COFF::IMAGE_REL_AMD64_ADDR64: 508 return S + LocData; 509 default: 510 llvm_unreachable("Invalid relocation type"); 511 } 512 } 513 514 static bool supportsCOFFARM(uint64_t Type) { 515 switch (Type) { 516 case COFF::IMAGE_REL_ARM_SECREL: 517 case COFF::IMAGE_REL_ARM_ADDR32: 518 return true; 519 default: 520 return false; 521 } 522 } 523 524 static uint64_t resolveCOFFARM(uint64_t Type, uint64_t Offset, uint64_t S, 525 uint64_t LocData, int64_t /*Addend*/) { 526 switch (Type) { 527 case COFF::IMAGE_REL_ARM_SECREL: 528 case COFF::IMAGE_REL_ARM_ADDR32: 529 return (S + LocData) & 0xFFFFFFFF; 530 default: 531 llvm_unreachable("Invalid relocation type"); 532 } 533 } 534 535 static bool supportsCOFFARM64(uint64_t Type) { 536 switch (Type) { 537 case COFF::IMAGE_REL_ARM64_SECREL: 538 case COFF::IMAGE_REL_ARM64_ADDR64: 539 return true; 540 default: 541 return false; 542 } 543 } 544 545 static uint64_t resolveCOFFARM64(uint64_t Type, uint64_t Offset, uint64_t S, 546 uint64_t LocData, int64_t /*Addend*/) { 547 switch (Type) { 548 case COFF::IMAGE_REL_ARM64_SECREL: 549 return (S + LocData) & 0xFFFFFFFF; 550 case COFF::IMAGE_REL_ARM64_ADDR64: 551 return S + LocData; 552 default: 553 llvm_unreachable("Invalid relocation type"); 554 } 555 } 556 557 static bool supportsMachOX86_64(uint64_t Type) { 558 return Type == MachO::X86_64_RELOC_UNSIGNED; 559 } 560 561 static uint64_t resolveMachOX86_64(uint64_t Type, uint64_t Offset, uint64_t S, 562 uint64_t LocData, int64_t /*Addend*/) { 563 if (Type == MachO::X86_64_RELOC_UNSIGNED) 564 return S; 565 llvm_unreachable("Invalid relocation type"); 566 } 567 568 static bool supportsWasm32(uint64_t Type) { 569 switch (Type) { 570 case wasm::R_WASM_FUNCTION_INDEX_LEB: 571 case wasm::R_WASM_TABLE_INDEX_SLEB: 572 case wasm::R_WASM_TABLE_INDEX_I32: 573 case wasm::R_WASM_MEMORY_ADDR_LEB: 574 case wasm::R_WASM_MEMORY_ADDR_SLEB: 575 case wasm::R_WASM_MEMORY_ADDR_I32: 576 case wasm::R_WASM_TYPE_INDEX_LEB: 577 case wasm::R_WASM_GLOBAL_INDEX_LEB: 578 case wasm::R_WASM_FUNCTION_OFFSET_I32: 579 case wasm::R_WASM_SECTION_OFFSET_I32: 580 case wasm::R_WASM_TAG_INDEX_LEB: 581 case wasm::R_WASM_GLOBAL_INDEX_I32: 582 case wasm::R_WASM_TABLE_NUMBER_LEB: 583 case wasm::R_WASM_MEMORY_ADDR_LOCREL_I32: 584 return true; 585 default: 586 return false; 587 } 588 } 589 590 static bool supportsWasm64(uint64_t Type) { 591 switch (Type) { 592 case wasm::R_WASM_MEMORY_ADDR_LEB64: 593 case wasm::R_WASM_MEMORY_ADDR_SLEB64: 594 case wasm::R_WASM_MEMORY_ADDR_I64: 595 case wasm::R_WASM_TABLE_INDEX_SLEB64: 596 case wasm::R_WASM_TABLE_INDEX_I64: 597 case wasm::R_WASM_FUNCTION_OFFSET_I64: 598 return true; 599 default: 600 return supportsWasm32(Type); 601 } 602 } 603 604 static uint64_t resolveWasm32(uint64_t Type, uint64_t Offset, uint64_t S, 605 uint64_t LocData, int64_t /*Addend*/) { 606 switch (Type) { 607 case wasm::R_WASM_FUNCTION_INDEX_LEB: 608 case wasm::R_WASM_TABLE_INDEX_SLEB: 609 case wasm::R_WASM_TABLE_INDEX_I32: 610 case wasm::R_WASM_MEMORY_ADDR_LEB: 611 case wasm::R_WASM_MEMORY_ADDR_SLEB: 612 case wasm::R_WASM_MEMORY_ADDR_I32: 613 case wasm::R_WASM_TYPE_INDEX_LEB: 614 case wasm::R_WASM_GLOBAL_INDEX_LEB: 615 case wasm::R_WASM_FUNCTION_OFFSET_I32: 616 case wasm::R_WASM_SECTION_OFFSET_I32: 617 case wasm::R_WASM_TAG_INDEX_LEB: 618 case wasm::R_WASM_GLOBAL_INDEX_I32: 619 case wasm::R_WASM_TABLE_NUMBER_LEB: 620 case wasm::R_WASM_MEMORY_ADDR_LOCREL_I32: 621 // For wasm section, its offset at 0 -- ignoring Value 622 return LocData; 623 default: 624 llvm_unreachable("Invalid relocation type"); 625 } 626 } 627 628 static uint64_t resolveWasm64(uint64_t Type, uint64_t Offset, uint64_t S, 629 uint64_t LocData, int64_t Addend) { 630 switch (Type) { 631 case wasm::R_WASM_MEMORY_ADDR_LEB64: 632 case wasm::R_WASM_MEMORY_ADDR_SLEB64: 633 case wasm::R_WASM_MEMORY_ADDR_I64: 634 case wasm::R_WASM_TABLE_INDEX_SLEB64: 635 case wasm::R_WASM_TABLE_INDEX_I64: 636 case wasm::R_WASM_FUNCTION_OFFSET_I64: 637 // For wasm section, its offset at 0 -- ignoring Value 638 return LocData; 639 default: 640 return resolveWasm32(Type, Offset, S, LocData, Addend); 641 } 642 } 643 644 std::pair<SupportsRelocation, RelocationResolver> 645 getRelocationResolver(const ObjectFile &Obj) { 646 if (Obj.isCOFF()) { 647 switch (Obj.getArch()) { 648 case Triple::x86_64: 649 return {supportsCOFFX86_64, resolveCOFFX86_64}; 650 case Triple::x86: 651 return {supportsCOFFX86, resolveCOFFX86}; 652 case Triple::arm: 653 case Triple::thumb: 654 return {supportsCOFFARM, resolveCOFFARM}; 655 case Triple::aarch64: 656 return {supportsCOFFARM64, resolveCOFFARM64}; 657 default: 658 return {nullptr, nullptr}; 659 } 660 } else if (Obj.isELF()) { 661 if (Obj.getBytesInAddress() == 8) { 662 switch (Obj.getArch()) { 663 case Triple::x86_64: 664 return {supportsX86_64, resolveX86_64}; 665 case Triple::aarch64: 666 case Triple::aarch64_be: 667 return {supportsAArch64, resolveAArch64}; 668 case Triple::bpfel: 669 case Triple::bpfeb: 670 return {supportsBPF, resolveBPF}; 671 case Triple::mips64el: 672 case Triple::mips64: 673 return {supportsMips64, resolveMips64}; 674 case Triple::ppc64le: 675 case Triple::ppc64: 676 return {supportsPPC64, resolvePPC64}; 677 case Triple::systemz: 678 return {supportsSystemZ, resolveSystemZ}; 679 case Triple::sparcv9: 680 return {supportsSparc64, resolveSparc64}; 681 case Triple::amdgcn: 682 return {supportsAmdgpu, resolveAmdgpu}; 683 case Triple::riscv64: 684 return {supportsRISCV, resolveRISCV}; 685 default: 686 return {nullptr, nullptr}; 687 } 688 } 689 690 // 32-bit object file 691 assert(Obj.getBytesInAddress() == 4 && 692 "Invalid word size in object file"); 693 694 switch (Obj.getArch()) { 695 case Triple::x86: 696 return {supportsX86, resolveX86}; 697 case Triple::ppcle: 698 case Triple::ppc: 699 return {supportsPPC32, resolvePPC32}; 700 case Triple::arm: 701 case Triple::armeb: 702 return {supportsARM, resolveARM}; 703 case Triple::avr: 704 return {supportsAVR, resolveAVR}; 705 case Triple::lanai: 706 return {supportsLanai, resolveLanai}; 707 case Triple::mipsel: 708 case Triple::mips: 709 return {supportsMips32, resolveMips32}; 710 case Triple::msp430: 711 return {supportsMSP430, resolveMSP430}; 712 case Triple::sparc: 713 return {supportsSparc32, resolveSparc32}; 714 case Triple::hexagon: 715 return {supportsHexagon, resolveHexagon}; 716 case Triple::riscv32: 717 return {supportsRISCV, resolveRISCV}; 718 default: 719 return {nullptr, nullptr}; 720 } 721 } else if (Obj.isMachO()) { 722 if (Obj.getArch() == Triple::x86_64) 723 return {supportsMachOX86_64, resolveMachOX86_64}; 724 return {nullptr, nullptr}; 725 } else if (Obj.isWasm()) { 726 if (Obj.getArch() == Triple::wasm32) 727 return {supportsWasm32, resolveWasm32}; 728 if (Obj.getArch() == Triple::wasm64) 729 return {supportsWasm64, resolveWasm64}; 730 return {nullptr, nullptr}; 731 } 732 733 llvm_unreachable("Invalid object file"); 734 } 735 736 uint64_t resolveRelocation(RelocationResolver Resolver, const RelocationRef &R, 737 uint64_t S, uint64_t LocData) { 738 if (const ObjectFile *Obj = R.getObject()) { 739 int64_t Addend = 0; 740 if (Obj->isELF()) { 741 auto GetRelSectionType = [&]() -> unsigned { 742 if (auto *Elf32LEObj = dyn_cast<ELF32LEObjectFile>(Obj)) 743 return Elf32LEObj->getRelSection(R.getRawDataRefImpl())->sh_type; 744 if (auto *Elf64LEObj = dyn_cast<ELF64LEObjectFile>(Obj)) 745 return Elf64LEObj->getRelSection(R.getRawDataRefImpl())->sh_type; 746 if (auto *Elf32BEObj = dyn_cast<ELF32BEObjectFile>(Obj)) 747 return Elf32BEObj->getRelSection(R.getRawDataRefImpl())->sh_type; 748 auto *Elf64BEObj = cast<ELF64BEObjectFile>(Obj); 749 return Elf64BEObj->getRelSection(R.getRawDataRefImpl())->sh_type; 750 }; 751 752 if (GetRelSectionType() == ELF::SHT_RELA) { 753 Addend = getELFAddend(R); 754 // RISCV relocations use both LocData and Addend. 755 if (Obj->getArch() != Triple::riscv32 && 756 Obj->getArch() != Triple::riscv64) 757 LocData = 0; 758 } 759 } 760 761 return Resolver(R.getType(), R.getOffset(), S, LocData, Addend); 762 } 763 764 // Sometimes the caller might want to use its own specific implementation of 765 // the resolver function. E.g. this is used by LLD when it resolves debug 766 // relocations and assumes that all of them have the same computation (S + A). 767 // The relocation R has no owner object in this case and we don't need to 768 // provide Type and Offset fields. It is also assumed the DataRefImpl.p 769 // contains the addend, provided by the caller. 770 return Resolver(/*Type=*/0, /*Offset=*/0, S, LocData, 771 R.getRawDataRefImpl().p); 772 } 773 774 } // namespace object 775 } // namespace llvm 776