14597dce4SFangrui Song //===- RelocationResolver.cpp ------------------------------------*- C++ -*-===// 24597dce4SFangrui Song // 34597dce4SFangrui Song // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 44597dce4SFangrui Song // See https://llvm.org/LICENSE.txt for license information. 54597dce4SFangrui Song // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 64597dce4SFangrui Song // 74597dce4SFangrui Song //===----------------------------------------------------------------------===// 84597dce4SFangrui Song // 94597dce4SFangrui Song // This file defines utilities to resolve relocations in object files. 104597dce4SFangrui Song // 114597dce4SFangrui Song //===----------------------------------------------------------------------===// 124597dce4SFangrui Song 134597dce4SFangrui Song #include "llvm/Object/RelocationResolver.h" 144597dce4SFangrui Song 154597dce4SFangrui Song namespace llvm { 164597dce4SFangrui Song namespace object { 174597dce4SFangrui Song 184597dce4SFangrui Song static int64_t getELFAddend(RelocationRef R) { 194597dce4SFangrui Song Expected<int64_t> AddendOrErr = ELFRelocationRef(R).getAddend(); 204597dce4SFangrui Song handleAllErrors(AddendOrErr.takeError(), [](const ErrorInfoBase &EI) { 214597dce4SFangrui Song report_fatal_error(EI.message()); 224597dce4SFangrui Song }); 234597dce4SFangrui Song return *AddendOrErr; 244597dce4SFangrui Song } 254597dce4SFangrui Song 264597dce4SFangrui Song static bool supportsX86_64(uint64_t Type) { 274597dce4SFangrui Song switch (Type) { 284597dce4SFangrui Song case ELF::R_X86_64_NONE: 294597dce4SFangrui Song case ELF::R_X86_64_64: 304597dce4SFangrui Song case ELF::R_X86_64_DTPOFF32: 314597dce4SFangrui Song case ELF::R_X86_64_DTPOFF64: 324597dce4SFangrui Song case ELF::R_X86_64_PC32: 333e6590c4SArtur Pilipenko case ELF::R_X86_64_PC64: 344597dce4SFangrui Song case ELF::R_X86_64_32: 354597dce4SFangrui Song case ELF::R_X86_64_32S: 364597dce4SFangrui Song return true; 374597dce4SFangrui Song default: 384597dce4SFangrui Song return false; 394597dce4SFangrui Song } 404597dce4SFangrui Song } 414597dce4SFangrui Song 429a99d23aSGeorgii Rymar static uint64_t resolveX86_64(uint64_t Type, uint64_t Offset, uint64_t S, 439a99d23aSGeorgii Rymar uint64_t LocData, int64_t Addend) { 449a99d23aSGeorgii Rymar switch (Type) { 454597dce4SFangrui Song case ELF::R_X86_64_NONE: 469a99d23aSGeorgii Rymar return LocData; 474597dce4SFangrui Song case ELF::R_X86_64_64: 484597dce4SFangrui Song case ELF::R_X86_64_DTPOFF32: 494597dce4SFangrui Song case ELF::R_X86_64_DTPOFF64: 509a99d23aSGeorgii Rymar return S + Addend; 514597dce4SFangrui Song case ELF::R_X86_64_PC32: 523e6590c4SArtur Pilipenko case ELF::R_X86_64_PC64: 539a99d23aSGeorgii Rymar return S + Addend - Offset; 544597dce4SFangrui Song case ELF::R_X86_64_32: 554597dce4SFangrui Song case ELF::R_X86_64_32S: 569a99d23aSGeorgii Rymar return (S + Addend) & 0xFFFFFFFF; 574597dce4SFangrui Song default: 584597dce4SFangrui Song llvm_unreachable("Invalid relocation type"); 594597dce4SFangrui Song } 604597dce4SFangrui Song } 614597dce4SFangrui Song 624597dce4SFangrui Song static bool supportsAArch64(uint64_t Type) { 634597dce4SFangrui Song switch (Type) { 644597dce4SFangrui Song case ELF::R_AARCH64_ABS32: 654597dce4SFangrui Song case ELF::R_AARCH64_ABS64: 663073a3aaSFangrui Song case ELF::R_AARCH64_PREL32: 673073a3aaSFangrui Song case ELF::R_AARCH64_PREL64: 684597dce4SFangrui Song return true; 694597dce4SFangrui Song default: 704597dce4SFangrui Song return false; 714597dce4SFangrui Song } 724597dce4SFangrui Song } 734597dce4SFangrui Song 749a99d23aSGeorgii Rymar static uint64_t resolveAArch64(uint64_t Type, uint64_t Offset, uint64_t S, 759a99d23aSGeorgii Rymar uint64_t /*LocData*/, int64_t Addend) { 769a99d23aSGeorgii Rymar switch (Type) { 774597dce4SFangrui Song case ELF::R_AARCH64_ABS32: 789a99d23aSGeorgii Rymar return (S + Addend) & 0xFFFFFFFF; 794597dce4SFangrui Song case ELF::R_AARCH64_ABS64: 809a99d23aSGeorgii Rymar return S + Addend; 813073a3aaSFangrui Song case ELF::R_AARCH64_PREL32: 829a99d23aSGeorgii Rymar return (S + Addend - Offset) & 0xFFFFFFFF; 833073a3aaSFangrui Song case ELF::R_AARCH64_PREL64: 849a99d23aSGeorgii Rymar return S + Addend - Offset; 854597dce4SFangrui Song default: 864597dce4SFangrui Song llvm_unreachable("Invalid relocation type"); 874597dce4SFangrui Song } 884597dce4SFangrui Song } 894597dce4SFangrui Song 904597dce4SFangrui Song static bool supportsBPF(uint64_t Type) { 914597dce4SFangrui Song switch (Type) { 92*8ce45f97SYonghong Song case ELF::R_BPF_64_ABS32: 93*8ce45f97SYonghong Song case ELF::R_BPF_64_ABS64: 944597dce4SFangrui Song return true; 954597dce4SFangrui Song default: 964597dce4SFangrui Song return false; 974597dce4SFangrui Song } 984597dce4SFangrui Song } 994597dce4SFangrui Song 1009a99d23aSGeorgii Rymar static uint64_t resolveBPF(uint64_t Type, uint64_t Offset, uint64_t S, 1019a99d23aSGeorgii Rymar uint64_t LocData, int64_t /*Addend*/) { 1029a99d23aSGeorgii Rymar switch (Type) { 103*8ce45f97SYonghong Song case ELF::R_BPF_64_ABS32: 1049a99d23aSGeorgii Rymar return (S + LocData) & 0xFFFFFFFF; 105*8ce45f97SYonghong Song case ELF::R_BPF_64_ABS64: 1069a99d23aSGeorgii Rymar return S + LocData; 1074597dce4SFangrui Song default: 1084597dce4SFangrui Song llvm_unreachable("Invalid relocation type"); 1094597dce4SFangrui Song } 1104597dce4SFangrui Song } 1114597dce4SFangrui Song 1124597dce4SFangrui Song static bool supportsMips64(uint64_t Type) { 1134597dce4SFangrui Song switch (Type) { 1144597dce4SFangrui Song case ELF::R_MIPS_32: 1154597dce4SFangrui Song case ELF::R_MIPS_64: 1164597dce4SFangrui Song case ELF::R_MIPS_TLS_DTPREL64: 117894f742aSAlex Richardson case ELF::R_MIPS_PC32: 1184597dce4SFangrui Song return true; 1194597dce4SFangrui Song default: 1204597dce4SFangrui Song return false; 1214597dce4SFangrui Song } 1224597dce4SFangrui Song } 1234597dce4SFangrui Song 1249a99d23aSGeorgii Rymar static uint64_t resolveMips64(uint64_t Type, uint64_t Offset, uint64_t S, 1259a99d23aSGeorgii Rymar uint64_t /*LocData*/, int64_t Addend) { 1269a99d23aSGeorgii Rymar switch (Type) { 1274597dce4SFangrui Song case ELF::R_MIPS_32: 1289a99d23aSGeorgii Rymar return (S + Addend) & 0xFFFFFFFF; 1294597dce4SFangrui Song case ELF::R_MIPS_64: 1309a99d23aSGeorgii Rymar return S + Addend; 1314597dce4SFangrui Song case ELF::R_MIPS_TLS_DTPREL64: 1329a99d23aSGeorgii Rymar return S + Addend - 0x8000; 133894f742aSAlex Richardson case ELF::R_MIPS_PC32: 1349a99d23aSGeorgii Rymar return S + Addend - Offset; 1354597dce4SFangrui Song default: 1364597dce4SFangrui Song llvm_unreachable("Invalid relocation type"); 1374597dce4SFangrui Song } 1384597dce4SFangrui Song } 1394597dce4SFangrui Song 140a5bd75aaSAnatoly Trosinenko static bool supportsMSP430(uint64_t Type) { 141a5bd75aaSAnatoly Trosinenko switch (Type) { 142a5bd75aaSAnatoly Trosinenko case ELF::R_MSP430_32: 143a5bd75aaSAnatoly Trosinenko case ELF::R_MSP430_16_BYTE: 144a5bd75aaSAnatoly Trosinenko return true; 145a5bd75aaSAnatoly Trosinenko default: 146a5bd75aaSAnatoly Trosinenko return false; 147a5bd75aaSAnatoly Trosinenko } 148a5bd75aaSAnatoly Trosinenko } 149a5bd75aaSAnatoly Trosinenko 1509a99d23aSGeorgii Rymar static uint64_t resolveMSP430(uint64_t Type, uint64_t Offset, uint64_t S, 1519a99d23aSGeorgii Rymar uint64_t /*LocData*/, int64_t Addend) { 1529a99d23aSGeorgii Rymar switch (Type) { 153a5bd75aaSAnatoly Trosinenko case ELF::R_MSP430_32: 1549a99d23aSGeorgii Rymar return (S + Addend) & 0xFFFFFFFF; 155a5bd75aaSAnatoly Trosinenko case ELF::R_MSP430_16_BYTE: 1569a99d23aSGeorgii Rymar return (S + Addend) & 0xFFFF; 157a5bd75aaSAnatoly Trosinenko default: 158a5bd75aaSAnatoly Trosinenko llvm_unreachable("Invalid relocation type"); 159a5bd75aaSAnatoly Trosinenko } 160a5bd75aaSAnatoly Trosinenko } 161a5bd75aaSAnatoly Trosinenko 1624597dce4SFangrui Song static bool supportsPPC64(uint64_t Type) { 1634597dce4SFangrui Song switch (Type) { 1644597dce4SFangrui Song case ELF::R_PPC64_ADDR32: 1654597dce4SFangrui Song case ELF::R_PPC64_ADDR64: 166b922004eSFangrui Song case ELF::R_PPC64_REL32: 167b922004eSFangrui Song case ELF::R_PPC64_REL64: 1684597dce4SFangrui Song return true; 1694597dce4SFangrui Song default: 1704597dce4SFangrui Song return false; 1714597dce4SFangrui Song } 1724597dce4SFangrui Song } 1734597dce4SFangrui Song 1749a99d23aSGeorgii Rymar static uint64_t resolvePPC64(uint64_t Type, uint64_t Offset, uint64_t S, 1759a99d23aSGeorgii Rymar uint64_t /*LocData*/, int64_t Addend) { 1769a99d23aSGeorgii Rymar switch (Type) { 1774597dce4SFangrui Song case ELF::R_PPC64_ADDR32: 1789a99d23aSGeorgii Rymar return (S + Addend) & 0xFFFFFFFF; 1794597dce4SFangrui Song case ELF::R_PPC64_ADDR64: 1809a99d23aSGeorgii Rymar return S + Addend; 181b922004eSFangrui Song case ELF::R_PPC64_REL32: 1829a99d23aSGeorgii Rymar return (S + Addend - Offset) & 0xFFFFFFFF; 183b922004eSFangrui Song case ELF::R_PPC64_REL64: 1849a99d23aSGeorgii Rymar return S + Addend - Offset; 1854597dce4SFangrui Song default: 1864597dce4SFangrui Song llvm_unreachable("Invalid relocation type"); 1874597dce4SFangrui Song } 1884597dce4SFangrui Song } 1894597dce4SFangrui Song 1904597dce4SFangrui Song static bool supportsSystemZ(uint64_t Type) { 1914597dce4SFangrui Song switch (Type) { 1924597dce4SFangrui Song case ELF::R_390_32: 1934597dce4SFangrui Song case ELF::R_390_64: 1944597dce4SFangrui Song return true; 1954597dce4SFangrui Song default: 1964597dce4SFangrui Song return false; 1974597dce4SFangrui Song } 1984597dce4SFangrui Song } 1994597dce4SFangrui Song 2009a99d23aSGeorgii Rymar static uint64_t resolveSystemZ(uint64_t Type, uint64_t Offset, uint64_t S, 2019a99d23aSGeorgii Rymar uint64_t /*LocData*/, int64_t Addend) { 2029a99d23aSGeorgii Rymar switch (Type) { 2034597dce4SFangrui Song case ELF::R_390_32: 2049a99d23aSGeorgii Rymar return (S + Addend) & 0xFFFFFFFF; 2054597dce4SFangrui Song case ELF::R_390_64: 2069a99d23aSGeorgii Rymar return S + Addend; 2074597dce4SFangrui Song default: 2084597dce4SFangrui Song llvm_unreachable("Invalid relocation type"); 2094597dce4SFangrui Song } 2104597dce4SFangrui Song } 2114597dce4SFangrui Song 2124597dce4SFangrui Song static bool supportsSparc64(uint64_t Type) { 2134597dce4SFangrui Song switch (Type) { 2144597dce4SFangrui Song case ELF::R_SPARC_32: 2154597dce4SFangrui Song case ELF::R_SPARC_64: 2164597dce4SFangrui Song case ELF::R_SPARC_UA32: 2174597dce4SFangrui Song case ELF::R_SPARC_UA64: 2184597dce4SFangrui Song return true; 2194597dce4SFangrui Song default: 2204597dce4SFangrui Song return false; 2214597dce4SFangrui Song } 2224597dce4SFangrui Song } 2234597dce4SFangrui Song 2249a99d23aSGeorgii Rymar static uint64_t resolveSparc64(uint64_t Type, uint64_t Offset, uint64_t S, 2259a99d23aSGeorgii Rymar uint64_t /*LocData*/, int64_t Addend) { 2269a99d23aSGeorgii Rymar switch (Type) { 2274597dce4SFangrui Song case ELF::R_SPARC_32: 2284597dce4SFangrui Song case ELF::R_SPARC_64: 2294597dce4SFangrui Song case ELF::R_SPARC_UA32: 2304597dce4SFangrui Song case ELF::R_SPARC_UA64: 2319a99d23aSGeorgii Rymar return S + Addend; 2324597dce4SFangrui Song default: 2334597dce4SFangrui Song llvm_unreachable("Invalid relocation type"); 2344597dce4SFangrui Song } 2354597dce4SFangrui Song } 2364597dce4SFangrui Song 2374597dce4SFangrui Song static bool supportsAmdgpu(uint64_t Type) { 2384597dce4SFangrui Song switch (Type) { 2394597dce4SFangrui Song case ELF::R_AMDGPU_ABS32: 2404597dce4SFangrui Song case ELF::R_AMDGPU_ABS64: 2414597dce4SFangrui Song return true; 2424597dce4SFangrui Song default: 2434597dce4SFangrui Song return false; 2444597dce4SFangrui Song } 2454597dce4SFangrui Song } 2464597dce4SFangrui Song 2479a99d23aSGeorgii Rymar static uint64_t resolveAmdgpu(uint64_t Type, uint64_t Offset, uint64_t S, 2489a99d23aSGeorgii Rymar uint64_t /*LocData*/, int64_t Addend) { 2499a99d23aSGeorgii Rymar switch (Type) { 2504597dce4SFangrui Song case ELF::R_AMDGPU_ABS32: 2514597dce4SFangrui Song case ELF::R_AMDGPU_ABS64: 2529a99d23aSGeorgii Rymar return S + Addend; 2534597dce4SFangrui Song default: 2544597dce4SFangrui Song llvm_unreachable("Invalid relocation type"); 2554597dce4SFangrui Song } 2564597dce4SFangrui Song } 2574597dce4SFangrui Song 2584597dce4SFangrui Song static bool supportsX86(uint64_t Type) { 2594597dce4SFangrui Song switch (Type) { 2604597dce4SFangrui Song case ELF::R_386_NONE: 2614597dce4SFangrui Song case ELF::R_386_32: 2624597dce4SFangrui Song case ELF::R_386_PC32: 2634597dce4SFangrui Song return true; 2644597dce4SFangrui Song default: 2654597dce4SFangrui Song return false; 2664597dce4SFangrui Song } 2674597dce4SFangrui Song } 2684597dce4SFangrui Song 2699a99d23aSGeorgii Rymar static uint64_t resolveX86(uint64_t Type, uint64_t Offset, uint64_t S, 2709a99d23aSGeorgii Rymar uint64_t LocData, int64_t /*Addend*/) { 2719a99d23aSGeorgii Rymar switch (Type) { 2724597dce4SFangrui Song case ELF::R_386_NONE: 2739a99d23aSGeorgii Rymar return LocData; 2744597dce4SFangrui Song case ELF::R_386_32: 2759a99d23aSGeorgii Rymar return S + LocData; 2764597dce4SFangrui Song case ELF::R_386_PC32: 2779a99d23aSGeorgii Rymar return S - Offset + LocData; 2784597dce4SFangrui Song default: 2794597dce4SFangrui Song llvm_unreachable("Invalid relocation type"); 2804597dce4SFangrui Song } 2814597dce4SFangrui Song } 2824597dce4SFangrui Song 2834597dce4SFangrui Song static bool supportsPPC32(uint64_t Type) { 284b922004eSFangrui Song switch (Type) { 285b922004eSFangrui Song case ELF::R_PPC_ADDR32: 286b922004eSFangrui Song case ELF::R_PPC_REL32: 287b922004eSFangrui Song return true; 288b922004eSFangrui Song default: 289b922004eSFangrui Song return false; 290b922004eSFangrui Song } 2914597dce4SFangrui Song } 2924597dce4SFangrui Song 2939a99d23aSGeorgii Rymar static uint64_t resolvePPC32(uint64_t Type, uint64_t Offset, uint64_t S, 2949a99d23aSGeorgii Rymar uint64_t /*LocData*/, int64_t Addend) { 2959a99d23aSGeorgii Rymar switch (Type) { 296b922004eSFangrui Song case ELF::R_PPC_ADDR32: 2979a99d23aSGeorgii Rymar return (S + Addend) & 0xFFFFFFFF; 298b922004eSFangrui Song case ELF::R_PPC_REL32: 2999a99d23aSGeorgii Rymar return (S + Addend - Offset) & 0xFFFFFFFF; 300b922004eSFangrui Song } 3014597dce4SFangrui Song llvm_unreachable("Invalid relocation type"); 3024597dce4SFangrui Song } 3034597dce4SFangrui Song 3044597dce4SFangrui Song static bool supportsARM(uint64_t Type) { 3053ab0f53eSFangrui Song switch (Type) { 3063ab0f53eSFangrui Song case ELF::R_ARM_ABS32: 3073ab0f53eSFangrui Song case ELF::R_ARM_REL32: 3083ab0f53eSFangrui Song return true; 3093ab0f53eSFangrui Song default: 3103ab0f53eSFangrui Song return false; 3113ab0f53eSFangrui Song } 3124597dce4SFangrui Song } 3134597dce4SFangrui Song 3149a99d23aSGeorgii Rymar static uint64_t resolveARM(uint64_t Type, uint64_t Offset, uint64_t S, 3159a99d23aSGeorgii Rymar uint64_t LocData, int64_t /*Addend*/) { 3169a99d23aSGeorgii Rymar switch (Type) { 3173ab0f53eSFangrui Song case ELF::R_ARM_ABS32: 3189a99d23aSGeorgii Rymar return (S + LocData) & 0xFFFFFFFF; 3193ab0f53eSFangrui Song case ELF::R_ARM_REL32: 3209a99d23aSGeorgii Rymar return (S + LocData - Offset) & 0xFFFFFFFF; 3213ab0f53eSFangrui Song } 3224597dce4SFangrui Song llvm_unreachable("Invalid relocation type"); 3234597dce4SFangrui Song } 3244597dce4SFangrui Song 3254597dce4SFangrui Song static bool supportsAVR(uint64_t Type) { 3264597dce4SFangrui Song switch (Type) { 3274597dce4SFangrui Song case ELF::R_AVR_16: 3284597dce4SFangrui Song case ELF::R_AVR_32: 3294597dce4SFangrui Song return true; 3304597dce4SFangrui Song default: 3314597dce4SFangrui Song return false; 3324597dce4SFangrui Song } 3334597dce4SFangrui Song } 3344597dce4SFangrui Song 3359a99d23aSGeorgii Rymar static uint64_t resolveAVR(uint64_t Type, uint64_t Offset, uint64_t S, 3369a99d23aSGeorgii Rymar uint64_t /*LocData*/, int64_t Addend) { 3379a99d23aSGeorgii Rymar switch (Type) { 3384597dce4SFangrui Song case ELF::R_AVR_16: 3399a99d23aSGeorgii Rymar return (S + Addend) & 0xFFFF; 3404597dce4SFangrui Song case ELF::R_AVR_32: 3419a99d23aSGeorgii Rymar return (S + Addend) & 0xFFFFFFFF; 3424597dce4SFangrui Song default: 3434597dce4SFangrui Song llvm_unreachable("Invalid relocation type"); 3444597dce4SFangrui Song } 3454597dce4SFangrui Song } 3464597dce4SFangrui Song 3474597dce4SFangrui Song static bool supportsLanai(uint64_t Type) { 3484597dce4SFangrui Song return Type == ELF::R_LANAI_32; 3494597dce4SFangrui Song } 3504597dce4SFangrui Song 3519a99d23aSGeorgii Rymar static uint64_t resolveLanai(uint64_t Type, uint64_t Offset, uint64_t S, 3529a99d23aSGeorgii Rymar uint64_t /*LocData*/, int64_t Addend) { 3539a99d23aSGeorgii Rymar if (Type == ELF::R_LANAI_32) 3549a99d23aSGeorgii Rymar return (S + Addend) & 0xFFFFFFFF; 3554597dce4SFangrui Song llvm_unreachable("Invalid relocation type"); 3564597dce4SFangrui Song } 3574597dce4SFangrui Song 3584597dce4SFangrui Song static bool supportsMips32(uint64_t Type) { 3594597dce4SFangrui Song switch (Type) { 3604597dce4SFangrui Song case ELF::R_MIPS_32: 3614597dce4SFangrui Song case ELF::R_MIPS_TLS_DTPREL32: 3624597dce4SFangrui Song return true; 3634597dce4SFangrui Song default: 3644597dce4SFangrui Song return false; 3654597dce4SFangrui Song } 3664597dce4SFangrui Song } 3674597dce4SFangrui Song 3689a99d23aSGeorgii Rymar static uint64_t resolveMips32(uint64_t Type, uint64_t Offset, uint64_t S, 3699a99d23aSGeorgii Rymar uint64_t LocData, int64_t /*Addend*/) { 3704597dce4SFangrui Song // FIXME: Take in account implicit addends to get correct results. 3719a99d23aSGeorgii Rymar if (Type == ELF::R_MIPS_32) 3729a99d23aSGeorgii Rymar return (S + LocData) & 0xFFFFFFFF; 3739a99d23aSGeorgii Rymar if (Type == ELF::R_MIPS_TLS_DTPREL32) 3749a99d23aSGeorgii Rymar return (S + LocData) & 0xFFFFFFFF; 3754597dce4SFangrui Song llvm_unreachable("Invalid relocation type"); 3764597dce4SFangrui Song } 3774597dce4SFangrui Song 3784597dce4SFangrui Song static bool supportsSparc32(uint64_t Type) { 3794597dce4SFangrui Song switch (Type) { 3804597dce4SFangrui Song case ELF::R_SPARC_32: 3814597dce4SFangrui Song case ELF::R_SPARC_UA32: 3824597dce4SFangrui Song return true; 3834597dce4SFangrui Song default: 3844597dce4SFangrui Song return false; 3854597dce4SFangrui Song } 3864597dce4SFangrui Song } 3874597dce4SFangrui Song 3889a99d23aSGeorgii Rymar static uint64_t resolveSparc32(uint64_t Type, uint64_t Offset, uint64_t S, 3899a99d23aSGeorgii Rymar uint64_t LocData, int64_t Addend) { 3909a99d23aSGeorgii Rymar if (Type == ELF::R_SPARC_32 || Type == ELF::R_SPARC_UA32) 3919a99d23aSGeorgii Rymar return S + Addend; 3929a99d23aSGeorgii Rymar return LocData; 3934597dce4SFangrui Song } 3944597dce4SFangrui Song 3954597dce4SFangrui Song static bool supportsHexagon(uint64_t Type) { 3964597dce4SFangrui Song return Type == ELF::R_HEX_32; 3974597dce4SFangrui Song } 3984597dce4SFangrui Song 3999a99d23aSGeorgii Rymar static uint64_t resolveHexagon(uint64_t Type, uint64_t Offset, uint64_t S, 4009a99d23aSGeorgii Rymar uint64_t /*LocData*/, int64_t Addend) { 4019a99d23aSGeorgii Rymar if (Type == ELF::R_HEX_32) 4029a99d23aSGeorgii Rymar return S + Addend; 4034597dce4SFangrui Song llvm_unreachable("Invalid relocation type"); 4044597dce4SFangrui Song } 4054597dce4SFangrui Song 40644deaf7eSAlex Bradbury static bool supportsRISCV(uint64_t Type) { 40744deaf7eSAlex Bradbury switch (Type) { 40844deaf7eSAlex Bradbury case ELF::R_RISCV_NONE: 40944deaf7eSAlex Bradbury case ELF::R_RISCV_32: 4107bf721e5SLuís Marques case ELF::R_RISCV_32_PCREL: 41144deaf7eSAlex Bradbury case ELF::R_RISCV_64: 41218ccfaddSHsiangkai Wang case ELF::R_RISCV_SET6: 41318ccfaddSHsiangkai Wang case ELF::R_RISCV_SUB6: 41444deaf7eSAlex Bradbury case ELF::R_RISCV_ADD8: 41544deaf7eSAlex Bradbury case ELF::R_RISCV_SUB8: 41644deaf7eSAlex Bradbury case ELF::R_RISCV_ADD16: 41744deaf7eSAlex Bradbury case ELF::R_RISCV_SUB16: 41844deaf7eSAlex Bradbury case ELF::R_RISCV_ADD32: 41944deaf7eSAlex Bradbury case ELF::R_RISCV_SUB32: 42044deaf7eSAlex Bradbury case ELF::R_RISCV_ADD64: 42144deaf7eSAlex Bradbury case ELF::R_RISCV_SUB64: 42244deaf7eSAlex Bradbury return true; 42344deaf7eSAlex Bradbury default: 42444deaf7eSAlex Bradbury return false; 42544deaf7eSAlex Bradbury } 42644deaf7eSAlex Bradbury } 42744deaf7eSAlex Bradbury 4289a99d23aSGeorgii Rymar static uint64_t resolveRISCV(uint64_t Type, uint64_t Offset, uint64_t S, 4299a99d23aSGeorgii Rymar uint64_t LocData, int64_t Addend) { 4309a99d23aSGeorgii Rymar int64_t RA = Addend; 4319a99d23aSGeorgii Rymar uint64_t A = LocData; 4329a99d23aSGeorgii Rymar switch (Type) { 43344deaf7eSAlex Bradbury case ELF::R_RISCV_NONE: 4349a99d23aSGeorgii Rymar return LocData; 43544deaf7eSAlex Bradbury case ELF::R_RISCV_32: 43644deaf7eSAlex Bradbury return (S + RA) & 0xFFFFFFFF; 4377bf721e5SLuís Marques case ELF::R_RISCV_32_PCREL: 4389a99d23aSGeorgii Rymar return (S + RA - Offset) & 0xFFFFFFFF; 43944deaf7eSAlex Bradbury case ELF::R_RISCV_64: 44044deaf7eSAlex Bradbury return S + RA; 44118ccfaddSHsiangkai Wang case ELF::R_RISCV_SET6: 442b8b57087SLuís Marques return (A & 0xC0) | ((S + RA) & 0x3F); 44318ccfaddSHsiangkai Wang case ELF::R_RISCV_SUB6: 444b8b57087SLuís Marques return (A & 0xC0) | (((A & 0x3F) - (S + RA)) & 0x3F); 44544deaf7eSAlex Bradbury case ELF::R_RISCV_ADD8: 44644deaf7eSAlex Bradbury return (A + (S + RA)) & 0xFF; 44744deaf7eSAlex Bradbury case ELF::R_RISCV_SUB8: 44844deaf7eSAlex Bradbury return (A - (S + RA)) & 0xFF; 44944deaf7eSAlex Bradbury case ELF::R_RISCV_ADD16: 45044deaf7eSAlex Bradbury return (A + (S + RA)) & 0xFFFF; 45144deaf7eSAlex Bradbury case ELF::R_RISCV_SUB16: 45244deaf7eSAlex Bradbury return (A - (S + RA)) & 0xFFFF; 45344deaf7eSAlex Bradbury case ELF::R_RISCV_ADD32: 45444deaf7eSAlex Bradbury return (A + (S + RA)) & 0xFFFFFFFF; 45544deaf7eSAlex Bradbury case ELF::R_RISCV_SUB32: 45644deaf7eSAlex Bradbury return (A - (S + RA)) & 0xFFFFFFFF; 45744deaf7eSAlex Bradbury case ELF::R_RISCV_ADD64: 45844deaf7eSAlex Bradbury return (A + (S + RA)); 45944deaf7eSAlex Bradbury case ELF::R_RISCV_SUB64: 46044deaf7eSAlex Bradbury return (A - (S + RA)); 46144deaf7eSAlex Bradbury default: 46244deaf7eSAlex Bradbury llvm_unreachable("Invalid relocation type"); 46344deaf7eSAlex Bradbury } 46444deaf7eSAlex Bradbury } 46544deaf7eSAlex Bradbury 4664597dce4SFangrui Song static bool supportsCOFFX86(uint64_t Type) { 4674597dce4SFangrui Song switch (Type) { 4684597dce4SFangrui Song case COFF::IMAGE_REL_I386_SECREL: 4694597dce4SFangrui Song case COFF::IMAGE_REL_I386_DIR32: 4704597dce4SFangrui Song return true; 4714597dce4SFangrui Song default: 4724597dce4SFangrui Song return false; 4734597dce4SFangrui Song } 4744597dce4SFangrui Song } 4754597dce4SFangrui Song 4769a99d23aSGeorgii Rymar static uint64_t resolveCOFFX86(uint64_t Type, uint64_t Offset, uint64_t S, 4779a99d23aSGeorgii Rymar uint64_t LocData, int64_t /*Addend*/) { 4789a99d23aSGeorgii Rymar switch (Type) { 4794597dce4SFangrui Song case COFF::IMAGE_REL_I386_SECREL: 4804597dce4SFangrui Song case COFF::IMAGE_REL_I386_DIR32: 4819a99d23aSGeorgii Rymar return (S + LocData) & 0xFFFFFFFF; 4824597dce4SFangrui Song default: 4834597dce4SFangrui Song llvm_unreachable("Invalid relocation type"); 4844597dce4SFangrui Song } 4854597dce4SFangrui Song } 4864597dce4SFangrui Song 4874597dce4SFangrui Song static bool supportsCOFFX86_64(uint64_t Type) { 4884597dce4SFangrui Song switch (Type) { 4894597dce4SFangrui Song case COFF::IMAGE_REL_AMD64_SECREL: 4904597dce4SFangrui Song case COFF::IMAGE_REL_AMD64_ADDR64: 4914597dce4SFangrui Song return true; 4924597dce4SFangrui Song default: 4934597dce4SFangrui Song return false; 4944597dce4SFangrui Song } 4954597dce4SFangrui Song } 4964597dce4SFangrui Song 4979a99d23aSGeorgii Rymar static uint64_t resolveCOFFX86_64(uint64_t Type, uint64_t Offset, uint64_t S, 4989a99d23aSGeorgii Rymar uint64_t LocData, int64_t /*Addend*/) { 4999a99d23aSGeorgii Rymar switch (Type) { 5004597dce4SFangrui Song case COFF::IMAGE_REL_AMD64_SECREL: 5019a99d23aSGeorgii Rymar return (S + LocData) & 0xFFFFFFFF; 5024597dce4SFangrui Song case COFF::IMAGE_REL_AMD64_ADDR64: 5039a99d23aSGeorgii Rymar return S + LocData; 5044597dce4SFangrui Song default: 5054597dce4SFangrui Song llvm_unreachable("Invalid relocation type"); 5064597dce4SFangrui Song } 5074597dce4SFangrui Song } 5084597dce4SFangrui Song 5095d269590SMartin Storsjo static bool supportsCOFFARM(uint64_t Type) { 5105d269590SMartin Storsjo switch (Type) { 5115d269590SMartin Storsjo case COFF::IMAGE_REL_ARM_SECREL: 5125d269590SMartin Storsjo case COFF::IMAGE_REL_ARM_ADDR32: 5135d269590SMartin Storsjo return true; 5145d269590SMartin Storsjo default: 5155d269590SMartin Storsjo return false; 5165d269590SMartin Storsjo } 5175d269590SMartin Storsjo } 5185d269590SMartin Storsjo 5199a99d23aSGeorgii Rymar static uint64_t resolveCOFFARM(uint64_t Type, uint64_t Offset, uint64_t S, 5209a99d23aSGeorgii Rymar uint64_t LocData, int64_t /*Addend*/) { 5219a99d23aSGeorgii Rymar switch (Type) { 5225d269590SMartin Storsjo case COFF::IMAGE_REL_ARM_SECREL: 5235d269590SMartin Storsjo case COFF::IMAGE_REL_ARM_ADDR32: 5249a99d23aSGeorgii Rymar return (S + LocData) & 0xFFFFFFFF; 5255d269590SMartin Storsjo default: 5265d269590SMartin Storsjo llvm_unreachable("Invalid relocation type"); 5275d269590SMartin Storsjo } 5285d269590SMartin Storsjo } 5295d269590SMartin Storsjo 5305d269590SMartin Storsjo static bool supportsCOFFARM64(uint64_t Type) { 5315d269590SMartin Storsjo switch (Type) { 5325d269590SMartin Storsjo case COFF::IMAGE_REL_ARM64_SECREL: 5335d269590SMartin Storsjo case COFF::IMAGE_REL_ARM64_ADDR64: 5345d269590SMartin Storsjo return true; 5355d269590SMartin Storsjo default: 5365d269590SMartin Storsjo return false; 5375d269590SMartin Storsjo } 5385d269590SMartin Storsjo } 5395d269590SMartin Storsjo 5409a99d23aSGeorgii Rymar static uint64_t resolveCOFFARM64(uint64_t Type, uint64_t Offset, uint64_t S, 5419a99d23aSGeorgii Rymar uint64_t LocData, int64_t /*Addend*/) { 5429a99d23aSGeorgii Rymar switch (Type) { 5435d269590SMartin Storsjo case COFF::IMAGE_REL_ARM64_SECREL: 5449a99d23aSGeorgii Rymar return (S + LocData) & 0xFFFFFFFF; 5455d269590SMartin Storsjo case COFF::IMAGE_REL_ARM64_ADDR64: 5469a99d23aSGeorgii Rymar return S + LocData; 5475d269590SMartin Storsjo default: 5485d269590SMartin Storsjo llvm_unreachable("Invalid relocation type"); 5495d269590SMartin Storsjo } 5505d269590SMartin Storsjo } 5515d269590SMartin Storsjo 5524597dce4SFangrui Song static bool supportsMachOX86_64(uint64_t Type) { 5534597dce4SFangrui Song return Type == MachO::X86_64_RELOC_UNSIGNED; 5544597dce4SFangrui Song } 5554597dce4SFangrui Song 5569a99d23aSGeorgii Rymar static uint64_t resolveMachOX86_64(uint64_t Type, uint64_t Offset, uint64_t S, 5579a99d23aSGeorgii Rymar uint64_t LocData, int64_t /*Addend*/) { 5589a99d23aSGeorgii Rymar if (Type == MachO::X86_64_RELOC_UNSIGNED) 5594597dce4SFangrui Song return S; 5604597dce4SFangrui Song llvm_unreachable("Invalid relocation type"); 5614597dce4SFangrui Song } 5624597dce4SFangrui Song 5634597dce4SFangrui Song static bool supportsWasm32(uint64_t Type) { 5644597dce4SFangrui Song switch (Type) { 5654597dce4SFangrui Song case wasm::R_WASM_FUNCTION_INDEX_LEB: 5664597dce4SFangrui Song case wasm::R_WASM_TABLE_INDEX_SLEB: 5674597dce4SFangrui Song case wasm::R_WASM_TABLE_INDEX_I32: 5684597dce4SFangrui Song case wasm::R_WASM_MEMORY_ADDR_LEB: 5694597dce4SFangrui Song case wasm::R_WASM_MEMORY_ADDR_SLEB: 5704597dce4SFangrui Song case wasm::R_WASM_MEMORY_ADDR_I32: 5714597dce4SFangrui Song case wasm::R_WASM_TYPE_INDEX_LEB: 5724597dce4SFangrui Song case wasm::R_WASM_GLOBAL_INDEX_LEB: 5734597dce4SFangrui Song case wasm::R_WASM_FUNCTION_OFFSET_I32: 5744597dce4SFangrui Song case wasm::R_WASM_SECTION_OFFSET_I32: 5754597dce4SFangrui Song case wasm::R_WASM_EVENT_INDEX_LEB: 57648139ebcSWouter van Oortmerssen case wasm::R_WASM_GLOBAL_INDEX_I32: 57769e2797eSPaulo Matos case wasm::R_WASM_TABLE_NUMBER_LEB: 578aa0c571aSYuta Saito case wasm::R_WASM_MEMORY_ADDR_LOCREL_I32: 5794597dce4SFangrui Song return true; 5804597dce4SFangrui Song default: 5814597dce4SFangrui Song return false; 5824597dce4SFangrui Song } 5834597dce4SFangrui Song } 5844597dce4SFangrui Song 5853b29376eSWouter van Oortmerssen static bool supportsWasm64(uint64_t Type) { 5863b29376eSWouter van Oortmerssen switch (Type) { 5873b29376eSWouter van Oortmerssen case wasm::R_WASM_MEMORY_ADDR_LEB64: 5883b29376eSWouter van Oortmerssen case wasm::R_WASM_MEMORY_ADDR_SLEB64: 5893b29376eSWouter van Oortmerssen case wasm::R_WASM_MEMORY_ADDR_I64: 590cc1b9b68SWouter van Oortmerssen case wasm::R_WASM_TABLE_INDEX_SLEB64: 591cc1b9b68SWouter van Oortmerssen case wasm::R_WASM_TABLE_INDEX_I64: 59216f02431SWouter van Oortmerssen case wasm::R_WASM_FUNCTION_OFFSET_I64: 5933b29376eSWouter van Oortmerssen return true; 5943b29376eSWouter van Oortmerssen default: 5953b29376eSWouter van Oortmerssen return supportsWasm32(Type); 5963b29376eSWouter van Oortmerssen } 5973b29376eSWouter van Oortmerssen } 5983b29376eSWouter van Oortmerssen 5999a99d23aSGeorgii Rymar static uint64_t resolveWasm32(uint64_t Type, uint64_t Offset, uint64_t S, 6009a99d23aSGeorgii Rymar uint64_t LocData, int64_t /*Addend*/) { 6019a99d23aSGeorgii Rymar switch (Type) { 6024597dce4SFangrui Song case wasm::R_WASM_FUNCTION_INDEX_LEB: 6034597dce4SFangrui Song case wasm::R_WASM_TABLE_INDEX_SLEB: 6044597dce4SFangrui Song case wasm::R_WASM_TABLE_INDEX_I32: 6054597dce4SFangrui Song case wasm::R_WASM_MEMORY_ADDR_LEB: 6064597dce4SFangrui Song case wasm::R_WASM_MEMORY_ADDR_SLEB: 6074597dce4SFangrui Song case wasm::R_WASM_MEMORY_ADDR_I32: 6084597dce4SFangrui Song case wasm::R_WASM_TYPE_INDEX_LEB: 6094597dce4SFangrui Song case wasm::R_WASM_GLOBAL_INDEX_LEB: 6104597dce4SFangrui Song case wasm::R_WASM_FUNCTION_OFFSET_I32: 6114597dce4SFangrui Song case wasm::R_WASM_SECTION_OFFSET_I32: 6124597dce4SFangrui Song case wasm::R_WASM_EVENT_INDEX_LEB: 61348139ebcSWouter van Oortmerssen case wasm::R_WASM_GLOBAL_INDEX_I32: 61469e2797eSPaulo Matos case wasm::R_WASM_TABLE_NUMBER_LEB: 615aa0c571aSYuta Saito case wasm::R_WASM_MEMORY_ADDR_LOCREL_I32: 6164597dce4SFangrui Song // For wasm section, its offset at 0 -- ignoring Value 6179a99d23aSGeorgii Rymar return LocData; 6184597dce4SFangrui Song default: 6194597dce4SFangrui Song llvm_unreachable("Invalid relocation type"); 6204597dce4SFangrui Song } 6214597dce4SFangrui Song } 6224597dce4SFangrui Song 6239a99d23aSGeorgii Rymar static uint64_t resolveWasm64(uint64_t Type, uint64_t Offset, uint64_t S, 6249a99d23aSGeorgii Rymar uint64_t LocData, int64_t Addend) { 6259a99d23aSGeorgii Rymar switch (Type) { 6263b29376eSWouter van Oortmerssen case wasm::R_WASM_MEMORY_ADDR_LEB64: 6273b29376eSWouter van Oortmerssen case wasm::R_WASM_MEMORY_ADDR_SLEB64: 6283b29376eSWouter van Oortmerssen case wasm::R_WASM_MEMORY_ADDR_I64: 629cc1b9b68SWouter van Oortmerssen case wasm::R_WASM_TABLE_INDEX_SLEB64: 630cc1b9b68SWouter van Oortmerssen case wasm::R_WASM_TABLE_INDEX_I64: 63116f02431SWouter van Oortmerssen case wasm::R_WASM_FUNCTION_OFFSET_I64: 6323b29376eSWouter van Oortmerssen // For wasm section, its offset at 0 -- ignoring Value 6339a99d23aSGeorgii Rymar return LocData; 6343b29376eSWouter van Oortmerssen default: 6359a99d23aSGeorgii Rymar return resolveWasm32(Type, Offset, S, LocData, Addend); 6363b29376eSWouter van Oortmerssen } 6373b29376eSWouter van Oortmerssen } 6383b29376eSWouter van Oortmerssen 6399a99d23aSGeorgii Rymar std::pair<SupportsRelocation, RelocationResolver> 6404597dce4SFangrui Song getRelocationResolver(const ObjectFile &Obj) { 6414597dce4SFangrui Song if (Obj.isCOFF()) { 6425d269590SMartin Storsjo switch (Obj.getArch()) { 6435d269590SMartin Storsjo case Triple::x86_64: 6444597dce4SFangrui Song return {supportsCOFFX86_64, resolveCOFFX86_64}; 6455d269590SMartin Storsjo case Triple::x86: 6464597dce4SFangrui Song return {supportsCOFFX86, resolveCOFFX86}; 6475d269590SMartin Storsjo case Triple::arm: 6485d269590SMartin Storsjo case Triple::thumb: 6495d269590SMartin Storsjo return {supportsCOFFARM, resolveCOFFARM}; 6505d269590SMartin Storsjo case Triple::aarch64: 6515d269590SMartin Storsjo return {supportsCOFFARM64, resolveCOFFARM64}; 6525d269590SMartin Storsjo default: 6535d269590SMartin Storsjo return {nullptr, nullptr}; 6545d269590SMartin Storsjo } 6554597dce4SFangrui Song } else if (Obj.isELF()) { 6564597dce4SFangrui Song if (Obj.getBytesInAddress() == 8) { 6574597dce4SFangrui Song switch (Obj.getArch()) { 6584597dce4SFangrui Song case Triple::x86_64: 6594597dce4SFangrui Song return {supportsX86_64, resolveX86_64}; 6604597dce4SFangrui Song case Triple::aarch64: 6614597dce4SFangrui Song case Triple::aarch64_be: 6624597dce4SFangrui Song return {supportsAArch64, resolveAArch64}; 6634597dce4SFangrui Song case Triple::bpfel: 6644597dce4SFangrui Song case Triple::bpfeb: 6654597dce4SFangrui Song return {supportsBPF, resolveBPF}; 6664597dce4SFangrui Song case Triple::mips64el: 6674597dce4SFangrui Song case Triple::mips64: 6684597dce4SFangrui Song return {supportsMips64, resolveMips64}; 6694597dce4SFangrui Song case Triple::ppc64le: 6704597dce4SFangrui Song case Triple::ppc64: 6714597dce4SFangrui Song return {supportsPPC64, resolvePPC64}; 6724597dce4SFangrui Song case Triple::systemz: 6734597dce4SFangrui Song return {supportsSystemZ, resolveSystemZ}; 6744597dce4SFangrui Song case Triple::sparcv9: 6754597dce4SFangrui Song return {supportsSparc64, resolveSparc64}; 6764597dce4SFangrui Song case Triple::amdgcn: 6774597dce4SFangrui Song return {supportsAmdgpu, resolveAmdgpu}; 67844deaf7eSAlex Bradbury case Triple::riscv64: 67944deaf7eSAlex Bradbury return {supportsRISCV, resolveRISCV}; 6804597dce4SFangrui Song default: 6814597dce4SFangrui Song return {nullptr, nullptr}; 6824597dce4SFangrui Song } 6834597dce4SFangrui Song } 6844597dce4SFangrui Song 6854597dce4SFangrui Song // 32-bit object file 6864597dce4SFangrui Song assert(Obj.getBytesInAddress() == 4 && 6874597dce4SFangrui Song "Invalid word size in object file"); 6884597dce4SFangrui Song 6894597dce4SFangrui Song switch (Obj.getArch()) { 6904597dce4SFangrui Song case Triple::x86: 6914597dce4SFangrui Song return {supportsX86, resolveX86}; 692696bd307SBrandon Bergren case Triple::ppcle: 6934597dce4SFangrui Song case Triple::ppc: 6944597dce4SFangrui Song return {supportsPPC32, resolvePPC32}; 6954597dce4SFangrui Song case Triple::arm: 6964597dce4SFangrui Song case Triple::armeb: 6974597dce4SFangrui Song return {supportsARM, resolveARM}; 6984597dce4SFangrui Song case Triple::avr: 6994597dce4SFangrui Song return {supportsAVR, resolveAVR}; 7004597dce4SFangrui Song case Triple::lanai: 7014597dce4SFangrui Song return {supportsLanai, resolveLanai}; 7024597dce4SFangrui Song case Triple::mipsel: 7034597dce4SFangrui Song case Triple::mips: 7044597dce4SFangrui Song return {supportsMips32, resolveMips32}; 705a5bd75aaSAnatoly Trosinenko case Triple::msp430: 706a5bd75aaSAnatoly Trosinenko return {supportsMSP430, resolveMSP430}; 7074597dce4SFangrui Song case Triple::sparc: 7084597dce4SFangrui Song return {supportsSparc32, resolveSparc32}; 7094597dce4SFangrui Song case Triple::hexagon: 7104597dce4SFangrui Song return {supportsHexagon, resolveHexagon}; 71144deaf7eSAlex Bradbury case Triple::riscv32: 71244deaf7eSAlex Bradbury return {supportsRISCV, resolveRISCV}; 7134597dce4SFangrui Song default: 7144597dce4SFangrui Song return {nullptr, nullptr}; 7154597dce4SFangrui Song } 7164597dce4SFangrui Song } else if (Obj.isMachO()) { 7174597dce4SFangrui Song if (Obj.getArch() == Triple::x86_64) 7184597dce4SFangrui Song return {supportsMachOX86_64, resolveMachOX86_64}; 7194597dce4SFangrui Song return {nullptr, nullptr}; 7204597dce4SFangrui Song } else if (Obj.isWasm()) { 7214597dce4SFangrui Song if (Obj.getArch() == Triple::wasm32) 7224597dce4SFangrui Song return {supportsWasm32, resolveWasm32}; 7233b29376eSWouter van Oortmerssen if (Obj.getArch() == Triple::wasm64) 7243b29376eSWouter van Oortmerssen return {supportsWasm64, resolveWasm64}; 7254597dce4SFangrui Song return {nullptr, nullptr}; 7264597dce4SFangrui Song } 7274597dce4SFangrui Song 7284597dce4SFangrui Song llvm_unreachable("Invalid object file"); 7294597dce4SFangrui Song } 7304597dce4SFangrui Song 7319a99d23aSGeorgii Rymar uint64_t resolveRelocation(RelocationResolver Resolver, const RelocationRef &R, 7329a99d23aSGeorgii Rymar uint64_t S, uint64_t LocData) { 7339a99d23aSGeorgii Rymar if (const ObjectFile *Obj = R.getObject()) { 7349a99d23aSGeorgii Rymar int64_t Addend = 0; 7359a99d23aSGeorgii Rymar if (Obj->isELF()) { 7369a99d23aSGeorgii Rymar auto GetRelSectionType = [&]() -> unsigned { 7379a99d23aSGeorgii Rymar if (auto *Elf32LEObj = dyn_cast<ELF32LEObjectFile>(Obj)) 7389a99d23aSGeorgii Rymar return Elf32LEObj->getRelSection(R.getRawDataRefImpl())->sh_type; 7399a99d23aSGeorgii Rymar if (auto *Elf64LEObj = dyn_cast<ELF64LEObjectFile>(Obj)) 7409a99d23aSGeorgii Rymar return Elf64LEObj->getRelSection(R.getRawDataRefImpl())->sh_type; 7419a99d23aSGeorgii Rymar if (auto *Elf32BEObj = dyn_cast<ELF32BEObjectFile>(Obj)) 7429a99d23aSGeorgii Rymar return Elf32BEObj->getRelSection(R.getRawDataRefImpl())->sh_type; 7439a99d23aSGeorgii Rymar auto *Elf64BEObj = cast<ELF64BEObjectFile>(Obj); 7449a99d23aSGeorgii Rymar return Elf64BEObj->getRelSection(R.getRawDataRefImpl())->sh_type; 7459a99d23aSGeorgii Rymar }; 7469a99d23aSGeorgii Rymar 7479a99d23aSGeorgii Rymar if (GetRelSectionType() == ELF::SHT_RELA) 7489a99d23aSGeorgii Rymar Addend = getELFAddend(R); 7499a99d23aSGeorgii Rymar } 7509a99d23aSGeorgii Rymar 7519a99d23aSGeorgii Rymar return Resolver(R.getType(), R.getOffset(), S, LocData, Addend); 7529a99d23aSGeorgii Rymar } 7539a99d23aSGeorgii Rymar 7549a99d23aSGeorgii Rymar // Sometimes the caller might want to use its own specific implementation of 7559a99d23aSGeorgii Rymar // the resolver function. E.g. this is used by LLD when it resolves debug 7569a99d23aSGeorgii Rymar // relocations and assumes that all of them have the same computation (S + A). 7579a99d23aSGeorgii Rymar // The relocation R has no owner object in this case and we don't need to 7589a99d23aSGeorgii Rymar // provide Type and Offset fields. It is also assumed the DataRefImpl.p 7599a99d23aSGeorgii Rymar // contains the addend, provided by the caller. 7609a99d23aSGeorgii Rymar return Resolver(/*Type=*/0, /*Offset=*/0, S, LocData, 7619a99d23aSGeorgii Rymar R.getRawDataRefImpl().p); 7629a99d23aSGeorgii Rymar } 7639a99d23aSGeorgii Rymar 7644597dce4SFangrui Song } // namespace object 7654597dce4SFangrui Song } // namespace llvm 766