1*4597dce4SFangrui Song //===- RelocationResolver.cpp ------------------------------------*- C++ -*-===// 2*4597dce4SFangrui Song // 3*4597dce4SFangrui Song // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*4597dce4SFangrui Song // See https://llvm.org/LICENSE.txt for license information. 5*4597dce4SFangrui Song // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*4597dce4SFangrui Song // 7*4597dce4SFangrui Song //===----------------------------------------------------------------------===// 8*4597dce4SFangrui Song // 9*4597dce4SFangrui Song // This file defines utilities to resolve relocations in object files. 10*4597dce4SFangrui Song // 11*4597dce4SFangrui Song //===----------------------------------------------------------------------===// 12*4597dce4SFangrui Song 13*4597dce4SFangrui Song #include "llvm/Object/RelocationResolver.h" 14*4597dce4SFangrui Song 15*4597dce4SFangrui Song namespace llvm { 16*4597dce4SFangrui Song namespace object { 17*4597dce4SFangrui Song 18*4597dce4SFangrui Song static int64_t getELFAddend(RelocationRef R) { 19*4597dce4SFangrui Song Expected<int64_t> AddendOrErr = ELFRelocationRef(R).getAddend(); 20*4597dce4SFangrui Song handleAllErrors(AddendOrErr.takeError(), [](const ErrorInfoBase &EI) { 21*4597dce4SFangrui Song report_fatal_error(EI.message()); 22*4597dce4SFangrui Song }); 23*4597dce4SFangrui Song return *AddendOrErr; 24*4597dce4SFangrui Song } 25*4597dce4SFangrui Song 26*4597dce4SFangrui Song static bool supportsX86_64(uint64_t Type) { 27*4597dce4SFangrui Song switch (Type) { 28*4597dce4SFangrui Song case ELF::R_X86_64_NONE: 29*4597dce4SFangrui Song case ELF::R_X86_64_64: 30*4597dce4SFangrui Song case ELF::R_X86_64_DTPOFF32: 31*4597dce4SFangrui Song case ELF::R_X86_64_DTPOFF64: 32*4597dce4SFangrui Song case ELF::R_X86_64_PC32: 33*4597dce4SFangrui Song case ELF::R_X86_64_32: 34*4597dce4SFangrui Song case ELF::R_X86_64_32S: 35*4597dce4SFangrui Song return true; 36*4597dce4SFangrui Song default: 37*4597dce4SFangrui Song return false; 38*4597dce4SFangrui Song } 39*4597dce4SFangrui Song } 40*4597dce4SFangrui Song 41*4597dce4SFangrui Song static uint64_t resolveX86_64(RelocationRef R, uint64_t S, uint64_t A) { 42*4597dce4SFangrui Song switch (R.getType()) { 43*4597dce4SFangrui Song case ELF::R_X86_64_NONE: 44*4597dce4SFangrui Song return A; 45*4597dce4SFangrui Song case ELF::R_X86_64_64: 46*4597dce4SFangrui Song case ELF::R_X86_64_DTPOFF32: 47*4597dce4SFangrui Song case ELF::R_X86_64_DTPOFF64: 48*4597dce4SFangrui Song return S + getELFAddend(R); 49*4597dce4SFangrui Song case ELF::R_X86_64_PC32: 50*4597dce4SFangrui Song return S + getELFAddend(R) - R.getOffset(); 51*4597dce4SFangrui Song case ELF::R_X86_64_32: 52*4597dce4SFangrui Song case ELF::R_X86_64_32S: 53*4597dce4SFangrui Song return (S + getELFAddend(R)) & 0xFFFFFFFF; 54*4597dce4SFangrui Song default: 55*4597dce4SFangrui Song llvm_unreachable("Invalid relocation type"); 56*4597dce4SFangrui Song } 57*4597dce4SFangrui Song } 58*4597dce4SFangrui Song 59*4597dce4SFangrui Song static bool supportsAArch64(uint64_t Type) { 60*4597dce4SFangrui Song switch (Type) { 61*4597dce4SFangrui Song case ELF::R_AARCH64_ABS32: 62*4597dce4SFangrui Song case ELF::R_AARCH64_ABS64: 63*4597dce4SFangrui Song return true; 64*4597dce4SFangrui Song default: 65*4597dce4SFangrui Song return false; 66*4597dce4SFangrui Song } 67*4597dce4SFangrui Song } 68*4597dce4SFangrui Song 69*4597dce4SFangrui Song static uint64_t resolveAArch64(RelocationRef R, uint64_t S, uint64_t A) { 70*4597dce4SFangrui Song switch (R.getType()) { 71*4597dce4SFangrui Song case ELF::R_AARCH64_ABS32: 72*4597dce4SFangrui Song return (S + getELFAddend(R)) & 0xFFFFFFFF; 73*4597dce4SFangrui Song case ELF::R_AARCH64_ABS64: 74*4597dce4SFangrui Song return S + getELFAddend(R); 75*4597dce4SFangrui Song default: 76*4597dce4SFangrui Song llvm_unreachable("Invalid relocation type"); 77*4597dce4SFangrui Song } 78*4597dce4SFangrui Song } 79*4597dce4SFangrui Song 80*4597dce4SFangrui Song static bool supportsBPF(uint64_t Type) { 81*4597dce4SFangrui Song switch (Type) { 82*4597dce4SFangrui Song case ELF::R_BPF_64_32: 83*4597dce4SFangrui Song case ELF::R_BPF_64_64: 84*4597dce4SFangrui Song return true; 85*4597dce4SFangrui Song default: 86*4597dce4SFangrui Song return false; 87*4597dce4SFangrui Song } 88*4597dce4SFangrui Song } 89*4597dce4SFangrui Song 90*4597dce4SFangrui Song static uint64_t resolveBPF(RelocationRef R, uint64_t S, uint64_t A) { 91*4597dce4SFangrui Song switch (R.getType()) { 92*4597dce4SFangrui Song case ELF::R_BPF_64_32: 93*4597dce4SFangrui Song return S & 0xFFFFFFFF; 94*4597dce4SFangrui Song case ELF::R_BPF_64_64: 95*4597dce4SFangrui Song return S; 96*4597dce4SFangrui Song default: 97*4597dce4SFangrui Song llvm_unreachable("Invalid relocation type"); 98*4597dce4SFangrui Song } 99*4597dce4SFangrui Song } 100*4597dce4SFangrui Song 101*4597dce4SFangrui Song static bool supportsMips64(uint64_t Type) { 102*4597dce4SFangrui Song switch (Type) { 103*4597dce4SFangrui Song case ELF::R_MIPS_32: 104*4597dce4SFangrui Song case ELF::R_MIPS_64: 105*4597dce4SFangrui Song case ELF::R_MIPS_TLS_DTPREL64: 106*4597dce4SFangrui Song return true; 107*4597dce4SFangrui Song default: 108*4597dce4SFangrui Song return false; 109*4597dce4SFangrui Song } 110*4597dce4SFangrui Song } 111*4597dce4SFangrui Song 112*4597dce4SFangrui Song static uint64_t resolveMips64(RelocationRef R, uint64_t S, uint64_t A) { 113*4597dce4SFangrui Song switch (R.getType()) { 114*4597dce4SFangrui Song case ELF::R_MIPS_32: 115*4597dce4SFangrui Song return (S + getELFAddend(R)) & 0xFFFFFFFF; 116*4597dce4SFangrui Song case ELF::R_MIPS_64: 117*4597dce4SFangrui Song return S + getELFAddend(R); 118*4597dce4SFangrui Song case ELF::R_MIPS_TLS_DTPREL64: 119*4597dce4SFangrui Song return S + getELFAddend(R) - 0x8000; 120*4597dce4SFangrui Song default: 121*4597dce4SFangrui Song llvm_unreachable("Invalid relocation type"); 122*4597dce4SFangrui Song } 123*4597dce4SFangrui Song } 124*4597dce4SFangrui Song 125*4597dce4SFangrui Song static bool supportsPPC64(uint64_t Type) { 126*4597dce4SFangrui Song switch (Type) { 127*4597dce4SFangrui Song case ELF::R_PPC64_ADDR32: 128*4597dce4SFangrui Song case ELF::R_PPC64_ADDR64: 129*4597dce4SFangrui Song return true; 130*4597dce4SFangrui Song default: 131*4597dce4SFangrui Song return false; 132*4597dce4SFangrui Song } 133*4597dce4SFangrui Song } 134*4597dce4SFangrui Song 135*4597dce4SFangrui Song static uint64_t resolvePPC64(RelocationRef R, uint64_t S, uint64_t A) { 136*4597dce4SFangrui Song switch (R.getType()) { 137*4597dce4SFangrui Song case ELF::R_PPC64_ADDR32: 138*4597dce4SFangrui Song return (S + getELFAddend(R)) & 0xFFFFFFFF; 139*4597dce4SFangrui Song case ELF::R_PPC64_ADDR64: 140*4597dce4SFangrui Song return S + getELFAddend(R); 141*4597dce4SFangrui Song default: 142*4597dce4SFangrui Song llvm_unreachable("Invalid relocation type"); 143*4597dce4SFangrui Song } 144*4597dce4SFangrui Song } 145*4597dce4SFangrui Song 146*4597dce4SFangrui Song static bool supportsSystemZ(uint64_t Type) { 147*4597dce4SFangrui Song switch (Type) { 148*4597dce4SFangrui Song case ELF::R_390_32: 149*4597dce4SFangrui Song case ELF::R_390_64: 150*4597dce4SFangrui Song return true; 151*4597dce4SFangrui Song default: 152*4597dce4SFangrui Song return false; 153*4597dce4SFangrui Song } 154*4597dce4SFangrui Song } 155*4597dce4SFangrui Song 156*4597dce4SFangrui Song static uint64_t resolveSystemZ(RelocationRef R, uint64_t S, uint64_t A) { 157*4597dce4SFangrui Song switch (R.getType()) { 158*4597dce4SFangrui Song case ELF::R_390_32: 159*4597dce4SFangrui Song return (S + getELFAddend(R)) & 0xFFFFFFFF; 160*4597dce4SFangrui Song case ELF::R_390_64: 161*4597dce4SFangrui Song return S + getELFAddend(R); 162*4597dce4SFangrui Song default: 163*4597dce4SFangrui Song llvm_unreachable("Invalid relocation type"); 164*4597dce4SFangrui Song } 165*4597dce4SFangrui Song } 166*4597dce4SFangrui Song 167*4597dce4SFangrui Song static bool supportsSparc64(uint64_t Type) { 168*4597dce4SFangrui Song switch (Type) { 169*4597dce4SFangrui Song case ELF::R_SPARC_32: 170*4597dce4SFangrui Song case ELF::R_SPARC_64: 171*4597dce4SFangrui Song case ELF::R_SPARC_UA32: 172*4597dce4SFangrui Song case ELF::R_SPARC_UA64: 173*4597dce4SFangrui Song return true; 174*4597dce4SFangrui Song default: 175*4597dce4SFangrui Song return false; 176*4597dce4SFangrui Song } 177*4597dce4SFangrui Song } 178*4597dce4SFangrui Song 179*4597dce4SFangrui Song static uint64_t resolveSparc64(RelocationRef R, uint64_t S, uint64_t A) { 180*4597dce4SFangrui Song switch (R.getType()) { 181*4597dce4SFangrui Song case ELF::R_SPARC_32: 182*4597dce4SFangrui Song case ELF::R_SPARC_64: 183*4597dce4SFangrui Song case ELF::R_SPARC_UA32: 184*4597dce4SFangrui Song case ELF::R_SPARC_UA64: 185*4597dce4SFangrui Song return S + getELFAddend(R); 186*4597dce4SFangrui Song default: 187*4597dce4SFangrui Song llvm_unreachable("Invalid relocation type"); 188*4597dce4SFangrui Song } 189*4597dce4SFangrui Song } 190*4597dce4SFangrui Song 191*4597dce4SFangrui Song static bool supportsAmdgpu(uint64_t Type) { 192*4597dce4SFangrui Song switch (Type) { 193*4597dce4SFangrui Song case ELF::R_AMDGPU_ABS32: 194*4597dce4SFangrui Song case ELF::R_AMDGPU_ABS64: 195*4597dce4SFangrui Song return true; 196*4597dce4SFangrui Song default: 197*4597dce4SFangrui Song return false; 198*4597dce4SFangrui Song } 199*4597dce4SFangrui Song } 200*4597dce4SFangrui Song 201*4597dce4SFangrui Song static uint64_t resolveAmdgpu(RelocationRef R, uint64_t S, uint64_t A) { 202*4597dce4SFangrui Song switch (R.getType()) { 203*4597dce4SFangrui Song case ELF::R_AMDGPU_ABS32: 204*4597dce4SFangrui Song case ELF::R_AMDGPU_ABS64: 205*4597dce4SFangrui Song return S + getELFAddend(R); 206*4597dce4SFangrui Song default: 207*4597dce4SFangrui Song llvm_unreachable("Invalid relocation type"); 208*4597dce4SFangrui Song } 209*4597dce4SFangrui Song } 210*4597dce4SFangrui Song 211*4597dce4SFangrui Song static bool supportsX86(uint64_t Type) { 212*4597dce4SFangrui Song switch (Type) { 213*4597dce4SFangrui Song case ELF::R_386_NONE: 214*4597dce4SFangrui Song case ELF::R_386_32: 215*4597dce4SFangrui Song case ELF::R_386_PC32: 216*4597dce4SFangrui Song return true; 217*4597dce4SFangrui Song default: 218*4597dce4SFangrui Song return false; 219*4597dce4SFangrui Song } 220*4597dce4SFangrui Song } 221*4597dce4SFangrui Song 222*4597dce4SFangrui Song static uint64_t resolveX86(RelocationRef R, uint64_t S, uint64_t A) { 223*4597dce4SFangrui Song switch (R.getType()) { 224*4597dce4SFangrui Song case ELF::R_386_NONE: 225*4597dce4SFangrui Song return A; 226*4597dce4SFangrui Song case ELF::R_386_32: 227*4597dce4SFangrui Song return S + A; 228*4597dce4SFangrui Song case ELF::R_386_PC32: 229*4597dce4SFangrui Song return S - R.getOffset() + A; 230*4597dce4SFangrui Song default: 231*4597dce4SFangrui Song llvm_unreachable("Invalid relocation type"); 232*4597dce4SFangrui Song } 233*4597dce4SFangrui Song } 234*4597dce4SFangrui Song 235*4597dce4SFangrui Song static bool supportsPPC32(uint64_t Type) { 236*4597dce4SFangrui Song return Type == ELF::R_PPC_ADDR32; 237*4597dce4SFangrui Song } 238*4597dce4SFangrui Song 239*4597dce4SFangrui Song static uint64_t resolvePPC32(RelocationRef R, uint64_t S, uint64_t A) { 240*4597dce4SFangrui Song if (R.getType() == ELF::R_PPC_ADDR32) 241*4597dce4SFangrui Song return (S + getELFAddend(R)) & 0xFFFFFFFF; 242*4597dce4SFangrui Song llvm_unreachable("Invalid relocation type"); 243*4597dce4SFangrui Song } 244*4597dce4SFangrui Song 245*4597dce4SFangrui Song static bool supportsARM(uint64_t Type) { 246*4597dce4SFangrui Song return Type == ELF::R_ARM_ABS32; 247*4597dce4SFangrui Song } 248*4597dce4SFangrui Song 249*4597dce4SFangrui Song static uint64_t resolveARM(RelocationRef R, uint64_t S, uint64_t A) { 250*4597dce4SFangrui Song if (R.getType() == ELF::R_ARM_ABS32) 251*4597dce4SFangrui Song return (S + A) & 0xFFFFFFFF; 252*4597dce4SFangrui Song llvm_unreachable("Invalid relocation type"); 253*4597dce4SFangrui Song } 254*4597dce4SFangrui Song 255*4597dce4SFangrui Song static bool supportsAVR(uint64_t Type) { 256*4597dce4SFangrui Song switch (Type) { 257*4597dce4SFangrui Song case ELF::R_AVR_16: 258*4597dce4SFangrui Song case ELF::R_AVR_32: 259*4597dce4SFangrui Song return true; 260*4597dce4SFangrui Song default: 261*4597dce4SFangrui Song return false; 262*4597dce4SFangrui Song } 263*4597dce4SFangrui Song } 264*4597dce4SFangrui Song 265*4597dce4SFangrui Song static uint64_t resolveAVR(RelocationRef R, uint64_t S, uint64_t A) { 266*4597dce4SFangrui Song switch (R.getType()) { 267*4597dce4SFangrui Song case ELF::R_AVR_16: 268*4597dce4SFangrui Song return (S + getELFAddend(R)) & 0xFFFF; 269*4597dce4SFangrui Song case ELF::R_AVR_32: 270*4597dce4SFangrui Song return (S + getELFAddend(R)) & 0xFFFFFFFF; 271*4597dce4SFangrui Song default: 272*4597dce4SFangrui Song llvm_unreachable("Invalid relocation type"); 273*4597dce4SFangrui Song } 274*4597dce4SFangrui Song } 275*4597dce4SFangrui Song 276*4597dce4SFangrui Song static bool supportsLanai(uint64_t Type) { 277*4597dce4SFangrui Song return Type == ELF::R_LANAI_32; 278*4597dce4SFangrui Song } 279*4597dce4SFangrui Song 280*4597dce4SFangrui Song static uint64_t resolveLanai(RelocationRef R, uint64_t S, uint64_t A) { 281*4597dce4SFangrui Song if (R.getType() == ELF::R_LANAI_32) 282*4597dce4SFangrui Song return (S + getELFAddend(R)) & 0xFFFFFFFF; 283*4597dce4SFangrui Song llvm_unreachable("Invalid relocation type"); 284*4597dce4SFangrui Song } 285*4597dce4SFangrui Song 286*4597dce4SFangrui Song static bool supportsMips32(uint64_t Type) { 287*4597dce4SFangrui Song switch (Type) { 288*4597dce4SFangrui Song case ELF::R_MIPS_32: 289*4597dce4SFangrui Song case ELF::R_MIPS_TLS_DTPREL32: 290*4597dce4SFangrui Song return true; 291*4597dce4SFangrui Song default: 292*4597dce4SFangrui Song return false; 293*4597dce4SFangrui Song } 294*4597dce4SFangrui Song } 295*4597dce4SFangrui Song 296*4597dce4SFangrui Song static uint64_t resolveMips32(RelocationRef R, uint64_t S, uint64_t A) { 297*4597dce4SFangrui Song // FIXME: Take in account implicit addends to get correct results. 298*4597dce4SFangrui Song uint32_t Rel = R.getType(); 299*4597dce4SFangrui Song if (Rel == ELF::R_MIPS_32) 300*4597dce4SFangrui Song return (S + A) & 0xFFFFFFFF; 301*4597dce4SFangrui Song if (Rel == ELF::R_MIPS_TLS_DTPREL32) 302*4597dce4SFangrui Song return (S + A) & 0xFFFFFFFF; 303*4597dce4SFangrui Song llvm_unreachable("Invalid relocation type"); 304*4597dce4SFangrui Song } 305*4597dce4SFangrui Song 306*4597dce4SFangrui Song static bool supportsSparc32(uint64_t Type) { 307*4597dce4SFangrui Song switch (Type) { 308*4597dce4SFangrui Song case ELF::R_SPARC_32: 309*4597dce4SFangrui Song case ELF::R_SPARC_UA32: 310*4597dce4SFangrui Song return true; 311*4597dce4SFangrui Song default: 312*4597dce4SFangrui Song return false; 313*4597dce4SFangrui Song } 314*4597dce4SFangrui Song } 315*4597dce4SFangrui Song 316*4597dce4SFangrui Song static uint64_t resolveSparc32(RelocationRef R, uint64_t S, uint64_t A) { 317*4597dce4SFangrui Song uint32_t Rel = R.getType(); 318*4597dce4SFangrui Song if (Rel == ELF::R_SPARC_32 || Rel == ELF::R_SPARC_UA32) 319*4597dce4SFangrui Song return S + getELFAddend(R); 320*4597dce4SFangrui Song return A; 321*4597dce4SFangrui Song } 322*4597dce4SFangrui Song 323*4597dce4SFangrui Song static bool supportsHexagon(uint64_t Type) { 324*4597dce4SFangrui Song return Type == ELF::R_HEX_32; 325*4597dce4SFangrui Song } 326*4597dce4SFangrui Song 327*4597dce4SFangrui Song static uint64_t resolveHexagon(RelocationRef R, uint64_t S, uint64_t A) { 328*4597dce4SFangrui Song if (R.getType() == ELF::R_HEX_32) 329*4597dce4SFangrui Song return S + getELFAddend(R); 330*4597dce4SFangrui Song llvm_unreachable("Invalid relocation type"); 331*4597dce4SFangrui Song } 332*4597dce4SFangrui Song 333*4597dce4SFangrui Song static bool supportsCOFFX86(uint64_t Type) { 334*4597dce4SFangrui Song switch (Type) { 335*4597dce4SFangrui Song case COFF::IMAGE_REL_I386_SECREL: 336*4597dce4SFangrui Song case COFF::IMAGE_REL_I386_DIR32: 337*4597dce4SFangrui Song return true; 338*4597dce4SFangrui Song default: 339*4597dce4SFangrui Song return false; 340*4597dce4SFangrui Song } 341*4597dce4SFangrui Song } 342*4597dce4SFangrui Song 343*4597dce4SFangrui Song static uint64_t resolveCOFFX86(RelocationRef R, uint64_t S, uint64_t A) { 344*4597dce4SFangrui Song switch (R.getType()) { 345*4597dce4SFangrui Song case COFF::IMAGE_REL_I386_SECREL: 346*4597dce4SFangrui Song case COFF::IMAGE_REL_I386_DIR32: 347*4597dce4SFangrui Song return (S + A) & 0xFFFFFFFF; 348*4597dce4SFangrui Song default: 349*4597dce4SFangrui Song llvm_unreachable("Invalid relocation type"); 350*4597dce4SFangrui Song } 351*4597dce4SFangrui Song } 352*4597dce4SFangrui Song 353*4597dce4SFangrui Song static bool supportsCOFFX86_64(uint64_t Type) { 354*4597dce4SFangrui Song switch (Type) { 355*4597dce4SFangrui Song case COFF::IMAGE_REL_AMD64_SECREL: 356*4597dce4SFangrui Song case COFF::IMAGE_REL_AMD64_ADDR64: 357*4597dce4SFangrui Song return true; 358*4597dce4SFangrui Song default: 359*4597dce4SFangrui Song return false; 360*4597dce4SFangrui Song } 361*4597dce4SFangrui Song } 362*4597dce4SFangrui Song 363*4597dce4SFangrui Song static uint64_t resolveCOFFX86_64(RelocationRef R, uint64_t S, uint64_t A) { 364*4597dce4SFangrui Song switch (R.getType()) { 365*4597dce4SFangrui Song case COFF::IMAGE_REL_AMD64_SECREL: 366*4597dce4SFangrui Song return (S + A) & 0xFFFFFFFF; 367*4597dce4SFangrui Song case COFF::IMAGE_REL_AMD64_ADDR64: 368*4597dce4SFangrui Song return S + A; 369*4597dce4SFangrui Song default: 370*4597dce4SFangrui Song llvm_unreachable("Invalid relocation type"); 371*4597dce4SFangrui Song } 372*4597dce4SFangrui Song } 373*4597dce4SFangrui Song 374*4597dce4SFangrui Song static bool supportsMachOX86_64(uint64_t Type) { 375*4597dce4SFangrui Song return Type == MachO::X86_64_RELOC_UNSIGNED; 376*4597dce4SFangrui Song } 377*4597dce4SFangrui Song 378*4597dce4SFangrui Song static uint64_t resolveMachOX86_64(RelocationRef R, uint64_t S, uint64_t A) { 379*4597dce4SFangrui Song if (R.getType() == MachO::X86_64_RELOC_UNSIGNED) 380*4597dce4SFangrui Song return S; 381*4597dce4SFangrui Song llvm_unreachable("Invalid relocation type"); 382*4597dce4SFangrui Song } 383*4597dce4SFangrui Song 384*4597dce4SFangrui Song static bool supportsWasm32(uint64_t Type) { 385*4597dce4SFangrui Song switch (Type) { 386*4597dce4SFangrui Song case wasm::R_WASM_FUNCTION_INDEX_LEB: 387*4597dce4SFangrui Song case wasm::R_WASM_TABLE_INDEX_SLEB: 388*4597dce4SFangrui Song case wasm::R_WASM_TABLE_INDEX_I32: 389*4597dce4SFangrui Song case wasm::R_WASM_MEMORY_ADDR_LEB: 390*4597dce4SFangrui Song case wasm::R_WASM_MEMORY_ADDR_SLEB: 391*4597dce4SFangrui Song case wasm::R_WASM_MEMORY_ADDR_I32: 392*4597dce4SFangrui Song case wasm::R_WASM_TYPE_INDEX_LEB: 393*4597dce4SFangrui Song case wasm::R_WASM_GLOBAL_INDEX_LEB: 394*4597dce4SFangrui Song case wasm::R_WASM_FUNCTION_OFFSET_I32: 395*4597dce4SFangrui Song case wasm::R_WASM_SECTION_OFFSET_I32: 396*4597dce4SFangrui Song case wasm::R_WASM_EVENT_INDEX_LEB: 397*4597dce4SFangrui Song return true; 398*4597dce4SFangrui Song default: 399*4597dce4SFangrui Song return false; 400*4597dce4SFangrui Song } 401*4597dce4SFangrui Song } 402*4597dce4SFangrui Song 403*4597dce4SFangrui Song static uint64_t resolveWasm32(RelocationRef R, uint64_t S, uint64_t A) { 404*4597dce4SFangrui Song switch (R.getType()) { 405*4597dce4SFangrui Song case wasm::R_WASM_FUNCTION_INDEX_LEB: 406*4597dce4SFangrui Song case wasm::R_WASM_TABLE_INDEX_SLEB: 407*4597dce4SFangrui Song case wasm::R_WASM_TABLE_INDEX_I32: 408*4597dce4SFangrui Song case wasm::R_WASM_MEMORY_ADDR_LEB: 409*4597dce4SFangrui Song case wasm::R_WASM_MEMORY_ADDR_SLEB: 410*4597dce4SFangrui Song case wasm::R_WASM_MEMORY_ADDR_I32: 411*4597dce4SFangrui Song case wasm::R_WASM_TYPE_INDEX_LEB: 412*4597dce4SFangrui Song case wasm::R_WASM_GLOBAL_INDEX_LEB: 413*4597dce4SFangrui Song case wasm::R_WASM_FUNCTION_OFFSET_I32: 414*4597dce4SFangrui Song case wasm::R_WASM_SECTION_OFFSET_I32: 415*4597dce4SFangrui Song case wasm::R_WASM_EVENT_INDEX_LEB: 416*4597dce4SFangrui Song // For wasm section, its offset at 0 -- ignoring Value 417*4597dce4SFangrui Song return A; 418*4597dce4SFangrui Song default: 419*4597dce4SFangrui Song llvm_unreachable("Invalid relocation type"); 420*4597dce4SFangrui Song } 421*4597dce4SFangrui Song } 422*4597dce4SFangrui Song 423*4597dce4SFangrui Song std::pair<bool (*)(uint64_t), RelocationResolver> 424*4597dce4SFangrui Song getRelocationResolver(const ObjectFile &Obj) { 425*4597dce4SFangrui Song if (Obj.isCOFF()) { 426*4597dce4SFangrui Song if (Obj.getBytesInAddress() == 8) 427*4597dce4SFangrui Song return {supportsCOFFX86_64, resolveCOFFX86_64}; 428*4597dce4SFangrui Song return {supportsCOFFX86, resolveCOFFX86}; 429*4597dce4SFangrui Song } else if (Obj.isELF()) { 430*4597dce4SFangrui Song if (Obj.getBytesInAddress() == 8) { 431*4597dce4SFangrui Song switch (Obj.getArch()) { 432*4597dce4SFangrui Song case Triple::x86_64: 433*4597dce4SFangrui Song return {supportsX86_64, resolveX86_64}; 434*4597dce4SFangrui Song case Triple::aarch64: 435*4597dce4SFangrui Song case Triple::aarch64_be: 436*4597dce4SFangrui Song return {supportsAArch64, resolveAArch64}; 437*4597dce4SFangrui Song case Triple::bpfel: 438*4597dce4SFangrui Song case Triple::bpfeb: 439*4597dce4SFangrui Song return {supportsBPF, resolveBPF}; 440*4597dce4SFangrui Song case Triple::mips64el: 441*4597dce4SFangrui Song case Triple::mips64: 442*4597dce4SFangrui Song return {supportsMips64, resolveMips64}; 443*4597dce4SFangrui Song case Triple::ppc64le: 444*4597dce4SFangrui Song case Triple::ppc64: 445*4597dce4SFangrui Song return {supportsPPC64, resolvePPC64}; 446*4597dce4SFangrui Song case Triple::systemz: 447*4597dce4SFangrui Song return {supportsSystemZ, resolveSystemZ}; 448*4597dce4SFangrui Song case Triple::sparcv9: 449*4597dce4SFangrui Song return {supportsSparc64, resolveSparc64}; 450*4597dce4SFangrui Song case Triple::amdgcn: 451*4597dce4SFangrui Song return {supportsAmdgpu, resolveAmdgpu}; 452*4597dce4SFangrui Song default: 453*4597dce4SFangrui Song return {nullptr, nullptr}; 454*4597dce4SFangrui Song } 455*4597dce4SFangrui Song } 456*4597dce4SFangrui Song 457*4597dce4SFangrui Song // 32-bit object file 458*4597dce4SFangrui Song assert(Obj.getBytesInAddress() == 4 && 459*4597dce4SFangrui Song "Invalid word size in object file"); 460*4597dce4SFangrui Song 461*4597dce4SFangrui Song switch (Obj.getArch()) { 462*4597dce4SFangrui Song case Triple::x86: 463*4597dce4SFangrui Song return {supportsX86, resolveX86}; 464*4597dce4SFangrui Song case Triple::ppc: 465*4597dce4SFangrui Song return {supportsPPC32, resolvePPC32}; 466*4597dce4SFangrui Song case Triple::arm: 467*4597dce4SFangrui Song case Triple::armeb: 468*4597dce4SFangrui Song return {supportsARM, resolveARM}; 469*4597dce4SFangrui Song case Triple::avr: 470*4597dce4SFangrui Song return {supportsAVR, resolveAVR}; 471*4597dce4SFangrui Song case Triple::lanai: 472*4597dce4SFangrui Song return {supportsLanai, resolveLanai}; 473*4597dce4SFangrui Song case Triple::mipsel: 474*4597dce4SFangrui Song case Triple::mips: 475*4597dce4SFangrui Song return {supportsMips32, resolveMips32}; 476*4597dce4SFangrui Song case Triple::sparc: 477*4597dce4SFangrui Song return {supportsSparc32, resolveSparc32}; 478*4597dce4SFangrui Song case Triple::hexagon: 479*4597dce4SFangrui Song return {supportsHexagon, resolveHexagon}; 480*4597dce4SFangrui Song default: 481*4597dce4SFangrui Song return {nullptr, nullptr}; 482*4597dce4SFangrui Song } 483*4597dce4SFangrui Song } else if (Obj.isMachO()) { 484*4597dce4SFangrui Song if (Obj.getArch() == Triple::x86_64) 485*4597dce4SFangrui Song return {supportsMachOX86_64, resolveMachOX86_64}; 486*4597dce4SFangrui Song return {nullptr, nullptr}; 487*4597dce4SFangrui Song } else if (Obj.isWasm()) { 488*4597dce4SFangrui Song if (Obj.getArch() == Triple::wasm32) 489*4597dce4SFangrui Song return {supportsWasm32, resolveWasm32}; 490*4597dce4SFangrui Song return {nullptr, nullptr}; 491*4597dce4SFangrui Song } 492*4597dce4SFangrui Song 493*4597dce4SFangrui Song llvm_unreachable("Invalid object file"); 494*4597dce4SFangrui Song } 495*4597dce4SFangrui Song 496*4597dce4SFangrui Song } // namespace object 497*4597dce4SFangrui Song } // namespace llvm 498