1 //===- RelocationResolver.cpp ------------------------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file defines utilities to resolve relocations in object files. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "llvm/Object/RelocationResolver.h" 14 15 namespace llvm { 16 namespace object { 17 18 static int64_t getELFAddend(RelocationRef R) { 19 Expected<int64_t> AddendOrErr = ELFRelocationRef(R).getAddend(); 20 handleAllErrors(AddendOrErr.takeError(), [](const ErrorInfoBase &EI) { 21 report_fatal_error(EI.message()); 22 }); 23 return *AddendOrErr; 24 } 25 26 static bool supportsX86_64(uint64_t Type) { 27 switch (Type) { 28 case ELF::R_X86_64_NONE: 29 case ELF::R_X86_64_64: 30 case ELF::R_X86_64_DTPOFF32: 31 case ELF::R_X86_64_DTPOFF64: 32 case ELF::R_X86_64_PC32: 33 case ELF::R_X86_64_PC64: 34 case ELF::R_X86_64_32: 35 case ELF::R_X86_64_32S: 36 return true; 37 default: 38 return false; 39 } 40 } 41 42 static uint64_t resolveX86_64(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) { 468 case COFF::IMAGE_REL_I386_SECREL: 469 case COFF::IMAGE_REL_I386_DIR32: 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) { 479 case COFF::IMAGE_REL_I386_SECREL: 480 case COFF::IMAGE_REL_I386_DIR32: 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) { 489 case COFF::IMAGE_REL_AMD64_SECREL: 490 case COFF::IMAGE_REL_AMD64_ADDR64: 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) { 500 case COFF::IMAGE_REL_AMD64_SECREL: 501 return (S + LocData) & 0xFFFFFFFF; 502 case COFF::IMAGE_REL_AMD64_ADDR64: 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) { 511 case COFF::IMAGE_REL_ARM_SECREL: 512 case COFF::IMAGE_REL_ARM_ADDR32: 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) { 522 case COFF::IMAGE_REL_ARM_SECREL: 523 case COFF::IMAGE_REL_ARM_ADDR32: 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) { 532 case COFF::IMAGE_REL_ARM64_SECREL: 533 case COFF::IMAGE_REL_ARM64_ADDR64: 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) { 543 case COFF::IMAGE_REL_ARM64_SECREL: 544 return (S + LocData) & 0xFFFFFFFF; 545 case COFF::IMAGE_REL_ARM64_ADDR64: 546 return S + LocData; 547 default: 548 llvm_unreachable("Invalid relocation type"); 549 } 550 } 551 552 static bool supportsMachOX86_64(uint64_t Type) { 553 return Type == MachO::X86_64_RELOC_UNSIGNED; 554 } 555 556 static uint64_t resolveMachOX86_64(uint64_t Type, uint64_t Offset, uint64_t S, 557 uint64_t LocData, int64_t /*Addend*/) { 558 if (Type == MachO::X86_64_RELOC_UNSIGNED) 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 return true; 579 default: 580 return false; 581 } 582 } 583 584 static bool supportsWasm64(uint64_t Type) { 585 switch (Type) { 586 case wasm::R_WASM_MEMORY_ADDR_LEB64: 587 case wasm::R_WASM_MEMORY_ADDR_SLEB64: 588 case wasm::R_WASM_MEMORY_ADDR_I64: 589 case wasm::R_WASM_TABLE_INDEX_SLEB64: 590 case wasm::R_WASM_TABLE_INDEX_I64: 591 case wasm::R_WASM_FUNCTION_OFFSET_I64: 592 return true; 593 default: 594 return supportsWasm32(Type); 595 } 596 } 597 598 static uint64_t resolveWasm32(uint64_t Type, uint64_t Offset, uint64_t S, 599 uint64_t LocData, int64_t /*Addend*/) { 600 switch (Type) { 601 case wasm::R_WASM_FUNCTION_INDEX_LEB: 602 case wasm::R_WASM_TABLE_INDEX_SLEB: 603 case wasm::R_WASM_TABLE_INDEX_I32: 604 case wasm::R_WASM_MEMORY_ADDR_LEB: 605 case wasm::R_WASM_MEMORY_ADDR_SLEB: 606 case wasm::R_WASM_MEMORY_ADDR_I32: 607 case wasm::R_WASM_TYPE_INDEX_LEB: 608 case wasm::R_WASM_GLOBAL_INDEX_LEB: 609 case wasm::R_WASM_FUNCTION_OFFSET_I32: 610 case wasm::R_WASM_SECTION_OFFSET_I32: 611 case wasm::R_WASM_EVENT_INDEX_LEB: 612 case wasm::R_WASM_GLOBAL_INDEX_I32: 613 case wasm::R_WASM_TABLE_NUMBER_LEB: 614 // For wasm section, its offset at 0 -- ignoring Value 615 return LocData; 616 default: 617 llvm_unreachable("Invalid relocation type"); 618 } 619 } 620 621 static uint64_t resolveWasm64(uint64_t Type, uint64_t Offset, uint64_t S, 622 uint64_t LocData, int64_t Addend) { 623 switch (Type) { 624 case wasm::R_WASM_MEMORY_ADDR_LEB64: 625 case wasm::R_WASM_MEMORY_ADDR_SLEB64: 626 case wasm::R_WASM_MEMORY_ADDR_I64: 627 case wasm::R_WASM_TABLE_INDEX_SLEB64: 628 case wasm::R_WASM_TABLE_INDEX_I64: 629 case wasm::R_WASM_FUNCTION_OFFSET_I64: 630 // For wasm section, its offset at 0 -- ignoring Value 631 return LocData; 632 default: 633 return resolveWasm32(Type, Offset, S, LocData, Addend); 634 } 635 } 636 637 std::pair<SupportsRelocation, RelocationResolver> 638 getRelocationResolver(const ObjectFile &Obj) { 639 if (Obj.isCOFF()) { 640 switch (Obj.getArch()) { 641 case Triple::x86_64: 642 return {supportsCOFFX86_64, resolveCOFFX86_64}; 643 case Triple::x86: 644 return {supportsCOFFX86, resolveCOFFX86}; 645 case Triple::arm: 646 case Triple::thumb: 647 return {supportsCOFFARM, resolveCOFFARM}; 648 case Triple::aarch64: 649 return {supportsCOFFARM64, resolveCOFFARM64}; 650 default: 651 return {nullptr, nullptr}; 652 } 653 } else if (Obj.isELF()) { 654 if (Obj.getBytesInAddress() == 8) { 655 switch (Obj.getArch()) { 656 case Triple::x86_64: 657 return {supportsX86_64, resolveX86_64}; 658 case Triple::aarch64: 659 case Triple::aarch64_be: 660 return {supportsAArch64, resolveAArch64}; 661 case Triple::bpfel: 662 case Triple::bpfeb: 663 return {supportsBPF, resolveBPF}; 664 case Triple::mips64el: 665 case Triple::mips64: 666 return {supportsMips64, resolveMips64}; 667 case Triple::ppc64le: 668 case Triple::ppc64: 669 return {supportsPPC64, resolvePPC64}; 670 case Triple::systemz: 671 return {supportsSystemZ, resolveSystemZ}; 672 case Triple::sparcv9: 673 return {supportsSparc64, resolveSparc64}; 674 case Triple::amdgcn: 675 return {supportsAmdgpu, resolveAmdgpu}; 676 case Triple::riscv64: 677 return {supportsRISCV, resolveRISCV}; 678 default: 679 return {nullptr, nullptr}; 680 } 681 } 682 683 // 32-bit object file 684 assert(Obj.getBytesInAddress() == 4 && 685 "Invalid word size in object file"); 686 687 switch (Obj.getArch()) { 688 case Triple::x86: 689 return {supportsX86, resolveX86}; 690 case Triple::ppcle: 691 case Triple::ppc: 692 return {supportsPPC32, resolvePPC32}; 693 case Triple::arm: 694 case Triple::armeb: 695 return {supportsARM, resolveARM}; 696 case Triple::avr: 697 return {supportsAVR, resolveAVR}; 698 case Triple::lanai: 699 return {supportsLanai, resolveLanai}; 700 case Triple::mipsel: 701 case Triple::mips: 702 return {supportsMips32, resolveMips32}; 703 case Triple::msp430: 704 return {supportsMSP430, resolveMSP430}; 705 case Triple::sparc: 706 return {supportsSparc32, resolveSparc32}; 707 case Triple::hexagon: 708 return {supportsHexagon, resolveHexagon}; 709 case Triple::riscv32: 710 return {supportsRISCV, resolveRISCV}; 711 default: 712 return {nullptr, nullptr}; 713 } 714 } else if (Obj.isMachO()) { 715 if (Obj.getArch() == Triple::x86_64) 716 return {supportsMachOX86_64, resolveMachOX86_64}; 717 return {nullptr, nullptr}; 718 } else if (Obj.isWasm()) { 719 if (Obj.getArch() == Triple::wasm32) 720 return {supportsWasm32, resolveWasm32}; 721 if (Obj.getArch() == Triple::wasm64) 722 return {supportsWasm64, resolveWasm64}; 723 return {nullptr, nullptr}; 724 } 725 726 llvm_unreachable("Invalid object file"); 727 } 728 729 uint64_t resolveRelocation(RelocationResolver Resolver, const RelocationRef &R, 730 uint64_t S, uint64_t LocData) { 731 if (const ObjectFile *Obj = R.getObject()) { 732 int64_t Addend = 0; 733 if (Obj->isELF()) { 734 auto GetRelSectionType = [&]() -> unsigned { 735 if (auto *Elf32LEObj = dyn_cast<ELF32LEObjectFile>(Obj)) 736 return Elf32LEObj->getRelSection(R.getRawDataRefImpl())->sh_type; 737 if (auto *Elf64LEObj = dyn_cast<ELF64LEObjectFile>(Obj)) 738 return Elf64LEObj->getRelSection(R.getRawDataRefImpl())->sh_type; 739 if (auto *Elf32BEObj = dyn_cast<ELF32BEObjectFile>(Obj)) 740 return Elf32BEObj->getRelSection(R.getRawDataRefImpl())->sh_type; 741 auto *Elf64BEObj = cast<ELF64BEObjectFile>(Obj); 742 return Elf64BEObj->getRelSection(R.getRawDataRefImpl())->sh_type; 743 }; 744 745 if (GetRelSectionType() == ELF::SHT_RELA) 746 Addend = getELFAddend(R); 747 } 748 749 return Resolver(R.getType(), R.getOffset(), S, LocData, Addend); 750 } 751 752 // Sometimes the caller might want to use its own specific implementation of 753 // the resolver function. E.g. this is used by LLD when it resolves debug 754 // relocations and assumes that all of them have the same computation (S + A). 755 // The relocation R has no owner object in this case and we don't need to 756 // provide Type and Offset fields. It is also assumed the DataRefImpl.p 757 // contains the addend, provided by the caller. 758 return Resolver(/*Type=*/0, /*Offset=*/0, S, LocData, 759 R.getRawDataRefImpl().p); 760 } 761 762 } // namespace object 763 } // namespace llvm 764