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