brintos

brintos / llvm-project-archived public Read only

0
0
Text · 25.9 KiB · d818993 Raw
924 lines · cpp
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-exception6//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 28namespace llvm {29namespace object {30 31static 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 39static 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 55static 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 75static 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 88static 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 106static 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 116static 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 128static 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 140static 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 156static 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 166static 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 178static 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 190static 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 206static 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 216static 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 228static 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 240static 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 value254/// of e_machine.255///256/// AMDGPU code objects with an e_machine of EF_AMDGPU_MACH_NONE do not257/// identify their arch as either r600 or amdgcn, but we can still handle258/// their relocations. When we identify an ELF object with an UnknownArch,259/// we use isAMDGPU to check for this case.260static 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 266static 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 276static 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 289static 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 300static 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 314static 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 324static 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 335static 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 345static 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 responsible348  // 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 361static 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 371static 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 383static bool supportsLanai(uint64_t Type) {384  return Type == ELF::R_LANAI_32;385}386 387static 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 394static 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 404static 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 414static 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 424static 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 431static bool supportsHexagon(uint64_t Type) {432  return Type == ELF::R_HEX_32;433}434 435static 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 442static 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 by462    // loclists/rnglists) is meaningful, DebugInfoDWARF does not inspect the463    // relocations. We declare support for the two relocation types without an464    // (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 473static 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 517static 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 528static 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 542static 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 564static 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 600static 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 610static 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 621static 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 631static 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 643static 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 653static 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 664static 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 674static 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 686static bool supportsMachOX86_64(uint64_t Type) {687  return Type == MachO::X86_64_RELOC_UNSIGNED;688}689 690static 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 697static 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 719static 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 733static 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 Value751    return LocData;752  default:753    llvm_unreachable("Invalid relocation type");754  }755}756 757static 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 Value767    return LocData;768  default:769    return resolveWasm32(Type, Offset, S, LocData, Addend);770  }771}772 773std::pair<SupportsRelocation, RelocationResolver>774getRelocationResolver(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      case Triple::riscv64be:816        return {supportsRISCV, resolveRISCV};817      default:818        if (isAMDGPU(Obj))819          return {supportsAmdgpu, resolveAmdgpu};820        return {nullptr, nullptr};821      }822    }823 824    // 32-bit object file825    assert(Obj.getBytesInAddress() == 4 &&826           "Invalid word size in object file");827 828    switch (Obj.getArch()) {829    case Triple::x86:830      return {supportsX86, resolveX86};831    case Triple::ppcle:832    case Triple::ppc:833      return {supportsPPC32, resolvePPC32};834    case Triple::arm:835    case Triple::armeb:836      return {supportsARM, resolveARM};837    case Triple::avr:838      return {supportsAVR, resolveAVR};839    case Triple::lanai:840      return {supportsLanai, resolveLanai};841    case Triple::loongarch32:842      return {supportsLoongArch, resolveLoongArch};843    case Triple::mipsel:844    case Triple::mips:845      return {supportsMips32, resolveMips32};846    case Triple::msp430:847      return {supportsMSP430, resolveMSP430};848    case Triple::sparc:849      return {supportsSparc32, resolveSparc32};850    case Triple::hexagon:851      return {supportsHexagon, resolveHexagon};852    case Triple::r600:853      return {supportsAmdgpu, resolveAmdgpu};854    case Triple::riscv32:855    case Triple::riscv32be:856      return {supportsRISCV, resolveRISCV};857    case Triple::csky:858      return {supportsCSKY, resolveCSKY};859    default:860      if (isAMDGPU(Obj))861        return {supportsAmdgpu, resolveAmdgpu};862      return {nullptr, nullptr};863    }864  } else if (Obj.isMachO()) {865    if (Obj.getArch() == Triple::x86_64)866      return {supportsMachOX86_64, resolveMachOX86_64};867    return {nullptr, nullptr};868  } else if (Obj.isWasm()) {869    if (Obj.getArch() == Triple::wasm32)870      return {supportsWasm32, resolveWasm32};871    if (Obj.getArch() == Triple::wasm64)872      return {supportsWasm64, resolveWasm64};873    return {nullptr, nullptr};874  }875 876  llvm_unreachable("Invalid object file");877}878 879uint64_t resolveRelocation(RelocationResolver Resolver, const RelocationRef &R,880                           uint64_t S, uint64_t LocData) {881  if (const ObjectFile *Obj = R.getObject()) {882    int64_t Addend = 0;883    if (Obj->isELF()) {884      auto GetRelSectionType = [&]() -> unsigned {885        if (auto *Elf32LEObj = dyn_cast<ELF32LEObjectFile>(Obj))886          return Elf32LEObj->getRelSection(R.getRawDataRefImpl())->sh_type;887        if (auto *Elf64LEObj = dyn_cast<ELF64LEObjectFile>(Obj))888          return Elf64LEObj->getRelSection(R.getRawDataRefImpl())->sh_type;889        if (auto *Elf32BEObj = dyn_cast<ELF32BEObjectFile>(Obj))890          return Elf32BEObj->getRelSection(R.getRawDataRefImpl())->sh_type;891        auto *Elf64BEObj = cast<ELF64BEObjectFile>(Obj);892        return Elf64BEObj->getRelSection(R.getRawDataRefImpl())->sh_type;893      };894 895      if (GetRelSectionType() == ELF::SHT_RELA ||896          GetRelSectionType() == ELF::SHT_CREL) {897        Addend = getELFAddend(R);898        // LoongArch and RISCV relocations use both LocData and Addend.899        if (Obj->getArch() != Triple::loongarch32 &&900            Obj->getArch() != Triple::loongarch64 &&901            Obj->getArch() != Triple::riscv32 &&902            Obj->getArch() != Triple::riscv64 &&903            Obj->getArch() != Triple::riscv32be &&904            Obj->getArch() != Triple::riscv64be)905          LocData = 0;906      }907    }908 909    return Resolver(R.getType(), R.getOffset(), S, LocData, Addend);910  }911 912  // Sometimes the caller might want to use its own specific implementation of913  // the resolver function. E.g. this is used by LLD when it resolves debug914  // relocations and assumes that all of them have the same computation (S + A).915  // The relocation R has no owner object in this case and we don't need to916  // provide Type and Offset fields. It is also assumed the DataRefImpl.p917  // contains the addend, provided by the caller.918  return Resolver(/*Type=*/0, /*Offset=*/0, S, LocData,919                  R.getRawDataRefImpl().p);920}921 922} // namespace object923} // namespace llvm924