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