Path: blob/main/contrib/llvm-project/llvm/lib/Object/RelocationResolver.cpp
35233 views
//===- RelocationResolver.cpp ------------------------------------*- C++ -*-===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file defines utilities to resolve relocations in object files.9//10//===----------------------------------------------------------------------===//1112#include "llvm/Object/RelocationResolver.h"13#include "llvm/ADT/Twine.h"14#include "llvm/BinaryFormat/COFF.h"15#include "llvm/BinaryFormat/ELF.h"16#include "llvm/BinaryFormat/MachO.h"17#include "llvm/BinaryFormat/Wasm.h"18#include "llvm/Object/ELFObjectFile.h"19#include "llvm/Object/ELFTypes.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>2728namespace llvm {29namespace object {3031static int64_t getELFAddend(RelocationRef R) {32Expected<int64_t> AddendOrErr = ELFRelocationRef(R).getAddend();33handleAllErrors(AddendOrErr.takeError(), [](const ErrorInfoBase &EI) {34report_fatal_error(Twine(EI.message()));35});36return *AddendOrErr;37}3839static bool supportsX86_64(uint64_t Type) {40switch (Type) {41case ELF::R_X86_64_NONE:42case ELF::R_X86_64_64:43case ELF::R_X86_64_DTPOFF32:44case ELF::R_X86_64_DTPOFF64:45case ELF::R_X86_64_PC32:46case ELF::R_X86_64_PC64:47case ELF::R_X86_64_32:48case ELF::R_X86_64_32S:49return true;50default:51return false;52}53}5455static uint64_t resolveX86_64(uint64_t Type, uint64_t Offset, uint64_t S,56uint64_t LocData, int64_t Addend) {57switch (Type) {58case ELF::R_X86_64_NONE:59return LocData;60case ELF::R_X86_64_64:61case ELF::R_X86_64_DTPOFF32:62case ELF::R_X86_64_DTPOFF64:63return S + Addend;64case ELF::R_X86_64_PC32:65case ELF::R_X86_64_PC64:66return S + Addend - Offset;67case ELF::R_X86_64_32:68case ELF::R_X86_64_32S:69return (S + Addend) & 0xFFFFFFFF;70default:71llvm_unreachable("Invalid relocation type");72}73}7475static bool supportsAArch64(uint64_t Type) {76switch (Type) {77case ELF::R_AARCH64_ABS32:78case ELF::R_AARCH64_ABS64:79case ELF::R_AARCH64_PREL16:80case ELF::R_AARCH64_PREL32:81case ELF::R_AARCH64_PREL64:82return true;83default:84return false;85}86}8788static uint64_t resolveAArch64(uint64_t Type, uint64_t Offset, uint64_t S,89uint64_t /*LocData*/, int64_t Addend) {90switch (Type) {91case ELF::R_AARCH64_ABS32:92return (S + Addend) & 0xFFFFFFFF;93case ELF::R_AARCH64_ABS64:94return S + Addend;95case ELF::R_AARCH64_PREL16:96return (S + Addend - Offset) & 0xFFFF;97case ELF::R_AARCH64_PREL32:98return (S + Addend - Offset) & 0xFFFFFFFF;99case ELF::R_AARCH64_PREL64:100return S + Addend - Offset;101default:102llvm_unreachable("Invalid relocation type");103}104}105106static bool supportsBPF(uint64_t Type) {107switch (Type) {108case ELF::R_BPF_64_ABS32:109case ELF::R_BPF_64_ABS64:110return true;111default:112return false;113}114}115116static uint64_t resolveBPF(uint64_t Type, uint64_t Offset, uint64_t S,117uint64_t LocData, int64_t /*Addend*/) {118switch (Type) {119case ELF::R_BPF_64_ABS32:120return (S + LocData) & 0xFFFFFFFF;121case ELF::R_BPF_64_ABS64:122return S + LocData;123default:124llvm_unreachable("Invalid relocation type");125}126}127128static bool supportsMips64(uint64_t Type) {129switch (Type) {130case ELF::R_MIPS_32:131case ELF::R_MIPS_64:132case ELF::R_MIPS_TLS_DTPREL64:133case ELF::R_MIPS_PC32:134return true;135default:136return false;137}138}139140static uint64_t resolveMips64(uint64_t Type, uint64_t Offset, uint64_t S,141uint64_t /*LocData*/, int64_t Addend) {142switch (Type) {143case ELF::R_MIPS_32:144return (S + Addend) & 0xFFFFFFFF;145case ELF::R_MIPS_64:146return S + Addend;147case ELF::R_MIPS_TLS_DTPREL64:148return S + Addend - 0x8000;149case ELF::R_MIPS_PC32:150return S + Addend - Offset;151default:152llvm_unreachable("Invalid relocation type");153}154}155156static bool supportsMSP430(uint64_t Type) {157switch (Type) {158case ELF::R_MSP430_32:159case ELF::R_MSP430_16_BYTE:160return true;161default:162return false;163}164}165166static uint64_t resolveMSP430(uint64_t Type, uint64_t Offset, uint64_t S,167uint64_t /*LocData*/, int64_t Addend) {168switch (Type) {169case ELF::R_MSP430_32:170return (S + Addend) & 0xFFFFFFFF;171case ELF::R_MSP430_16_BYTE:172return (S + Addend) & 0xFFFF;173default:174llvm_unreachable("Invalid relocation type");175}176}177178static bool supportsPPC64(uint64_t Type) {179switch (Type) {180case ELF::R_PPC64_ADDR32:181case ELF::R_PPC64_ADDR64:182case ELF::R_PPC64_REL32:183case ELF::R_PPC64_REL64:184return true;185default:186return false;187}188}189190static uint64_t resolvePPC64(uint64_t Type, uint64_t Offset, uint64_t S,191uint64_t /*LocData*/, int64_t Addend) {192switch (Type) {193case ELF::R_PPC64_ADDR32:194return (S + Addend) & 0xFFFFFFFF;195case ELF::R_PPC64_ADDR64:196return S + Addend;197case ELF::R_PPC64_REL32:198return (S + Addend - Offset) & 0xFFFFFFFF;199case ELF::R_PPC64_REL64:200return S + Addend - Offset;201default:202llvm_unreachable("Invalid relocation type");203}204}205206static bool supportsSystemZ(uint64_t Type) {207switch (Type) {208case ELF::R_390_32:209case ELF::R_390_64:210return true;211default:212return false;213}214}215216static uint64_t resolveSystemZ(uint64_t Type, uint64_t Offset, uint64_t S,217uint64_t /*LocData*/, int64_t Addend) {218switch (Type) {219case ELF::R_390_32:220return (S + Addend) & 0xFFFFFFFF;221case ELF::R_390_64:222return S + Addend;223default:224llvm_unreachable("Invalid relocation type");225}226}227228static bool supportsSparc64(uint64_t Type) {229switch (Type) {230case ELF::R_SPARC_32:231case ELF::R_SPARC_64:232case ELF::R_SPARC_UA32:233case ELF::R_SPARC_UA64:234return true;235default:236return false;237}238}239240static uint64_t resolveSparc64(uint64_t Type, uint64_t Offset, uint64_t S,241uint64_t /*LocData*/, int64_t Addend) {242switch (Type) {243case ELF::R_SPARC_32:244case ELF::R_SPARC_64:245case ELF::R_SPARC_UA32:246case ELF::R_SPARC_UA64:247return S + Addend;248default:249llvm_unreachable("Invalid relocation type");250}251}252253/// 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) {261if (const auto *ELFObj = dyn_cast<ELFObjectFileBase>(&Obj))262return ELFObj->getEMachine() == ELF::EM_AMDGPU;263return false;264}265266static bool supportsAmdgpu(uint64_t Type) {267switch (Type) {268case ELF::R_AMDGPU_ABS32:269case ELF::R_AMDGPU_ABS64:270return true;271default:272return false;273}274}275276static uint64_t resolveAmdgpu(uint64_t Type, uint64_t Offset, uint64_t S,277uint64_t /*LocData*/, int64_t Addend) {278switch (Type) {279case ELF::R_AMDGPU_ABS32:280case ELF::R_AMDGPU_ABS64:281return S + Addend;282default:283llvm_unreachable("Invalid relocation type");284}285}286287static bool supportsX86(uint64_t Type) {288switch (Type) {289case ELF::R_386_NONE:290case ELF::R_386_32:291case ELF::R_386_PC32:292return true;293default:294return false;295}296}297298static uint64_t resolveX86(uint64_t Type, uint64_t Offset, uint64_t S,299uint64_t LocData, int64_t /*Addend*/) {300switch (Type) {301case ELF::R_386_NONE:302return LocData;303case ELF::R_386_32:304return S + LocData;305case ELF::R_386_PC32:306return S - Offset + LocData;307default:308llvm_unreachable("Invalid relocation type");309}310}311312static bool supportsPPC32(uint64_t Type) {313switch (Type) {314case ELF::R_PPC_ADDR32:315case ELF::R_PPC_REL32:316return true;317default:318return false;319}320}321322static uint64_t resolvePPC32(uint64_t Type, uint64_t Offset, uint64_t S,323uint64_t /*LocData*/, int64_t Addend) {324switch (Type) {325case ELF::R_PPC_ADDR32:326return (S + Addend) & 0xFFFFFFFF;327case ELF::R_PPC_REL32:328return (S + Addend - Offset) & 0xFFFFFFFF;329}330llvm_unreachable("Invalid relocation type");331}332333static bool supportsARM(uint64_t Type) {334switch (Type) {335case ELF::R_ARM_ABS32:336case ELF::R_ARM_REL32:337return true;338default:339return false;340}341}342343static uint64_t resolveARM(uint64_t Type, uint64_t Offset, uint64_t S,344uint64_t LocData, int64_t Addend) {345// Support both RELA and REL relocations. The caller is responsible346// for supplying the correct values for LocData and Addend, i.e.347// Addend == 0 for REL and LocData == 0 for RELA.348assert((LocData == 0 || Addend == 0) &&349"one of LocData and Addend must be 0");350switch (Type) {351case ELF::R_ARM_ABS32:352return (S + LocData + Addend) & 0xFFFFFFFF;353case ELF::R_ARM_REL32:354return (S + LocData + Addend - Offset) & 0xFFFFFFFF;355}356llvm_unreachable("Invalid relocation type");357}358359static bool supportsAVR(uint64_t Type) {360switch (Type) {361case ELF::R_AVR_16:362case ELF::R_AVR_32:363return true;364default:365return false;366}367}368369static uint64_t resolveAVR(uint64_t Type, uint64_t Offset, uint64_t S,370uint64_t /*LocData*/, int64_t Addend) {371switch (Type) {372case ELF::R_AVR_16:373return (S + Addend) & 0xFFFF;374case ELF::R_AVR_32:375return (S + Addend) & 0xFFFFFFFF;376default:377llvm_unreachable("Invalid relocation type");378}379}380381static bool supportsLanai(uint64_t Type) {382return Type == ELF::R_LANAI_32;383}384385static uint64_t resolveLanai(uint64_t Type, uint64_t Offset, uint64_t S,386uint64_t /*LocData*/, int64_t Addend) {387if (Type == ELF::R_LANAI_32)388return (S + Addend) & 0xFFFFFFFF;389llvm_unreachable("Invalid relocation type");390}391392static bool supportsMips32(uint64_t Type) {393switch (Type) {394case ELF::R_MIPS_32:395case ELF::R_MIPS_TLS_DTPREL32:396return true;397default:398return false;399}400}401402static uint64_t resolveMips32(uint64_t Type, uint64_t Offset, uint64_t S,403uint64_t LocData, int64_t /*Addend*/) {404// FIXME: Take in account implicit addends to get correct results.405if (Type == ELF::R_MIPS_32)406return (S + LocData) & 0xFFFFFFFF;407if (Type == ELF::R_MIPS_TLS_DTPREL32)408return (S + LocData) & 0xFFFFFFFF;409llvm_unreachable("Invalid relocation type");410}411412static bool supportsSparc32(uint64_t Type) {413switch (Type) {414case ELF::R_SPARC_32:415case ELF::R_SPARC_UA32:416return true;417default:418return false;419}420}421422static uint64_t resolveSparc32(uint64_t Type, uint64_t Offset, uint64_t S,423uint64_t LocData, int64_t Addend) {424if (Type == ELF::R_SPARC_32 || Type == ELF::R_SPARC_UA32)425return S + Addend;426return LocData;427}428429static bool supportsHexagon(uint64_t Type) {430return Type == ELF::R_HEX_32;431}432433static uint64_t resolveHexagon(uint64_t Type, uint64_t Offset, uint64_t S,434uint64_t /*LocData*/, int64_t Addend) {435if (Type == ELF::R_HEX_32)436return S + Addend;437llvm_unreachable("Invalid relocation type");438}439440static bool supportsRISCV(uint64_t Type) {441switch (Type) {442case ELF::R_RISCV_NONE:443case ELF::R_RISCV_32:444case ELF::R_RISCV_32_PCREL:445case ELF::R_RISCV_64:446case ELF::R_RISCV_SET6:447case ELF::R_RISCV_SET8:448case ELF::R_RISCV_SUB6:449case ELF::R_RISCV_ADD8:450case ELF::R_RISCV_SUB8:451case ELF::R_RISCV_SET16:452case ELF::R_RISCV_ADD16:453case ELF::R_RISCV_SUB16:454case ELF::R_RISCV_SET32:455case ELF::R_RISCV_ADD32:456case ELF::R_RISCV_SUB32:457case ELF::R_RISCV_ADD64:458case ELF::R_RISCV_SUB64:459return true;460default:461return false;462}463}464465static uint64_t resolveRISCV(uint64_t Type, uint64_t Offset, uint64_t S,466uint64_t LocData, int64_t Addend) {467int64_t RA = Addend;468uint64_t A = LocData;469switch (Type) {470case ELF::R_RISCV_NONE:471return LocData;472case ELF::R_RISCV_32:473return (S + RA) & 0xFFFFFFFF;474case ELF::R_RISCV_32_PCREL:475return (S + RA - Offset) & 0xFFFFFFFF;476case ELF::R_RISCV_64:477return S + RA;478case ELF::R_RISCV_SET6:479return (A & 0xC0) | ((S + RA) & 0x3F);480case ELF::R_RISCV_SUB6:481return (A & 0xC0) | (((A & 0x3F) - (S + RA)) & 0x3F);482case ELF::R_RISCV_SET8:483return (S + RA) & 0xFF;484case ELF::R_RISCV_ADD8:485return (A + (S + RA)) & 0xFF;486case ELF::R_RISCV_SUB8:487return (A - (S + RA)) & 0xFF;488case ELF::R_RISCV_SET16:489return (S + RA) & 0xFFFF;490case ELF::R_RISCV_ADD16:491return (A + (S + RA)) & 0xFFFF;492case ELF::R_RISCV_SUB16:493return (A - (S + RA)) & 0xFFFF;494case ELF::R_RISCV_SET32:495return (S + RA) & 0xFFFFFFFF;496case ELF::R_RISCV_ADD32:497return (A + (S + RA)) & 0xFFFFFFFF;498case ELF::R_RISCV_SUB32:499return (A - (S + RA)) & 0xFFFFFFFF;500case ELF::R_RISCV_ADD64:501return (A + (S + RA));502case ELF::R_RISCV_SUB64:503return (A - (S + RA));504default:505llvm_unreachable("Invalid relocation type");506}507}508509static bool supportsCSKY(uint64_t Type) {510switch (Type) {511case ELF::R_CKCORE_NONE:512case ELF::R_CKCORE_ADDR32:513case ELF::R_CKCORE_PCREL32:514return true;515default:516return false;517}518}519520static uint64_t resolveCSKY(uint64_t Type, uint64_t Offset, uint64_t S,521uint64_t LocData, int64_t Addend) {522switch (Type) {523case ELF::R_CKCORE_NONE:524return LocData;525case ELF::R_CKCORE_ADDR32:526return (S + Addend) & 0xFFFFFFFF;527case ELF::R_CKCORE_PCREL32:528return (S + Addend - Offset) & 0xFFFFFFFF;529default:530llvm_unreachable("Invalid relocation type");531}532}533534static bool supportsLoongArch(uint64_t Type) {535switch (Type) {536case ELF::R_LARCH_NONE:537case ELF::R_LARCH_32:538case ELF::R_LARCH_32_PCREL:539case ELF::R_LARCH_64:540case ELF::R_LARCH_ADD6:541case ELF::R_LARCH_SUB6:542case ELF::R_LARCH_ADD8:543case ELF::R_LARCH_SUB8:544case ELF::R_LARCH_ADD16:545case ELF::R_LARCH_SUB16:546case ELF::R_LARCH_ADD32:547case ELF::R_LARCH_SUB32:548case ELF::R_LARCH_ADD64:549case ELF::R_LARCH_SUB64:550return true;551default:552return false;553}554}555556static uint64_t resolveLoongArch(uint64_t Type, uint64_t Offset, uint64_t S,557uint64_t LocData, int64_t Addend) {558switch (Type) {559case ELF::R_LARCH_NONE:560return LocData;561case ELF::R_LARCH_32:562return (S + Addend) & 0xFFFFFFFF;563case ELF::R_LARCH_32_PCREL:564return (S + Addend - Offset) & 0xFFFFFFFF;565case ELF::R_LARCH_64:566return S + Addend;567case ELF::R_LARCH_ADD6:568return (LocData & 0xC0) | ((LocData + S + Addend) & 0x3F);569case ELF::R_LARCH_SUB6:570return (LocData & 0xC0) | ((LocData - (S + Addend)) & 0x3F);571case ELF::R_LARCH_ADD8:572return (LocData + (S + Addend)) & 0xFF;573case ELF::R_LARCH_SUB8:574return (LocData - (S + Addend)) & 0xFF;575case ELF::R_LARCH_ADD16:576return (LocData + (S + Addend)) & 0xFFFF;577case ELF::R_LARCH_SUB16:578return (LocData - (S + Addend)) & 0xFFFF;579case ELF::R_LARCH_ADD32:580return (LocData + (S + Addend)) & 0xFFFFFFFF;581case ELF::R_LARCH_SUB32:582return (LocData - (S + Addend)) & 0xFFFFFFFF;583case ELF::R_LARCH_ADD64:584return (LocData + (S + Addend));585case ELF::R_LARCH_SUB64:586return (LocData - (S + Addend));587default:588llvm_unreachable("Invalid relocation type");589}590}591592static bool supportsCOFFX86(uint64_t Type) {593switch (Type) {594case COFF::IMAGE_REL_I386_SECREL:595case COFF::IMAGE_REL_I386_DIR32:596return true;597default:598return false;599}600}601602static uint64_t resolveCOFFX86(uint64_t Type, uint64_t Offset, uint64_t S,603uint64_t LocData, int64_t /*Addend*/) {604switch (Type) {605case COFF::IMAGE_REL_I386_SECREL:606case COFF::IMAGE_REL_I386_DIR32:607return (S + LocData) & 0xFFFFFFFF;608default:609llvm_unreachable("Invalid relocation type");610}611}612613static bool supportsCOFFX86_64(uint64_t Type) {614switch (Type) {615case COFF::IMAGE_REL_AMD64_SECREL:616case COFF::IMAGE_REL_AMD64_ADDR64:617return true;618default:619return false;620}621}622623static uint64_t resolveCOFFX86_64(uint64_t Type, uint64_t Offset, uint64_t S,624uint64_t LocData, int64_t /*Addend*/) {625switch (Type) {626case COFF::IMAGE_REL_AMD64_SECREL:627return (S + LocData) & 0xFFFFFFFF;628case COFF::IMAGE_REL_AMD64_ADDR64:629return S + LocData;630default:631llvm_unreachable("Invalid relocation type");632}633}634635static bool supportsCOFFARM(uint64_t Type) {636switch (Type) {637case COFF::IMAGE_REL_ARM_SECREL:638case COFF::IMAGE_REL_ARM_ADDR32:639return true;640default:641return false;642}643}644645static uint64_t resolveCOFFARM(uint64_t Type, uint64_t Offset, uint64_t S,646uint64_t LocData, int64_t /*Addend*/) {647switch (Type) {648case COFF::IMAGE_REL_ARM_SECREL:649case COFF::IMAGE_REL_ARM_ADDR32:650return (S + LocData) & 0xFFFFFFFF;651default:652llvm_unreachable("Invalid relocation type");653}654}655656static bool supportsCOFFARM64(uint64_t Type) {657switch (Type) {658case COFF::IMAGE_REL_ARM64_SECREL:659case COFF::IMAGE_REL_ARM64_ADDR64:660return true;661default:662return false;663}664}665666static uint64_t resolveCOFFARM64(uint64_t Type, uint64_t Offset, uint64_t S,667uint64_t LocData, int64_t /*Addend*/) {668switch (Type) {669case COFF::IMAGE_REL_ARM64_SECREL:670return (S + LocData) & 0xFFFFFFFF;671case COFF::IMAGE_REL_ARM64_ADDR64:672return S + LocData;673default:674llvm_unreachable("Invalid relocation type");675}676}677678static bool supportsMachOX86_64(uint64_t Type) {679return Type == MachO::X86_64_RELOC_UNSIGNED;680}681682static uint64_t resolveMachOX86_64(uint64_t Type, uint64_t Offset, uint64_t S,683uint64_t LocData, int64_t /*Addend*/) {684if (Type == MachO::X86_64_RELOC_UNSIGNED)685return S;686llvm_unreachable("Invalid relocation type");687}688689static bool supportsWasm32(uint64_t Type) {690switch (Type) {691case wasm::R_WASM_FUNCTION_INDEX_LEB:692case wasm::R_WASM_TABLE_INDEX_SLEB:693case wasm::R_WASM_TABLE_INDEX_I32:694case wasm::R_WASM_MEMORY_ADDR_LEB:695case wasm::R_WASM_MEMORY_ADDR_SLEB:696case wasm::R_WASM_MEMORY_ADDR_I32:697case wasm::R_WASM_TYPE_INDEX_LEB:698case wasm::R_WASM_GLOBAL_INDEX_LEB:699case wasm::R_WASM_FUNCTION_OFFSET_I32:700case wasm::R_WASM_SECTION_OFFSET_I32:701case wasm::R_WASM_TAG_INDEX_LEB:702case wasm::R_WASM_GLOBAL_INDEX_I32:703case wasm::R_WASM_TABLE_NUMBER_LEB:704case wasm::R_WASM_MEMORY_ADDR_LOCREL_I32:705return true;706default:707return false;708}709}710711static bool supportsWasm64(uint64_t Type) {712switch (Type) {713case wasm::R_WASM_MEMORY_ADDR_LEB64:714case wasm::R_WASM_MEMORY_ADDR_SLEB64:715case wasm::R_WASM_MEMORY_ADDR_I64:716case wasm::R_WASM_TABLE_INDEX_SLEB64:717case wasm::R_WASM_TABLE_INDEX_I64:718case wasm::R_WASM_FUNCTION_OFFSET_I64:719return true;720default:721return supportsWasm32(Type);722}723}724725static uint64_t resolveWasm32(uint64_t Type, uint64_t Offset, uint64_t S,726uint64_t LocData, int64_t /*Addend*/) {727switch (Type) {728case wasm::R_WASM_FUNCTION_INDEX_LEB:729case wasm::R_WASM_TABLE_INDEX_SLEB:730case wasm::R_WASM_TABLE_INDEX_I32:731case wasm::R_WASM_MEMORY_ADDR_LEB:732case wasm::R_WASM_MEMORY_ADDR_SLEB:733case wasm::R_WASM_MEMORY_ADDR_I32:734case wasm::R_WASM_TYPE_INDEX_LEB:735case wasm::R_WASM_GLOBAL_INDEX_LEB:736case wasm::R_WASM_FUNCTION_OFFSET_I32:737case wasm::R_WASM_SECTION_OFFSET_I32:738case wasm::R_WASM_TAG_INDEX_LEB:739case wasm::R_WASM_GLOBAL_INDEX_I32:740case wasm::R_WASM_TABLE_NUMBER_LEB:741case wasm::R_WASM_MEMORY_ADDR_LOCREL_I32:742// For wasm section, its offset at 0 -- ignoring Value743return LocData;744default:745llvm_unreachable("Invalid relocation type");746}747}748749static uint64_t resolveWasm64(uint64_t Type, uint64_t Offset, uint64_t S,750uint64_t LocData, int64_t Addend) {751switch (Type) {752case wasm::R_WASM_MEMORY_ADDR_LEB64:753case wasm::R_WASM_MEMORY_ADDR_SLEB64:754case wasm::R_WASM_MEMORY_ADDR_I64:755case wasm::R_WASM_TABLE_INDEX_SLEB64:756case wasm::R_WASM_TABLE_INDEX_I64:757case wasm::R_WASM_FUNCTION_OFFSET_I64:758// For wasm section, its offset at 0 -- ignoring Value759return LocData;760default:761return resolveWasm32(Type, Offset, S, LocData, Addend);762}763}764765std::pair<SupportsRelocation, RelocationResolver>766getRelocationResolver(const ObjectFile &Obj) {767if (Obj.isCOFF()) {768switch (Obj.getArch()) {769case Triple::x86_64:770return {supportsCOFFX86_64, resolveCOFFX86_64};771case Triple::x86:772return {supportsCOFFX86, resolveCOFFX86};773case Triple::arm:774case Triple::thumb:775return {supportsCOFFARM, resolveCOFFARM};776case Triple::aarch64:777return {supportsCOFFARM64, resolveCOFFARM64};778default:779return {nullptr, nullptr};780}781} else if (Obj.isELF()) {782if (Obj.getBytesInAddress() == 8) {783switch (Obj.getArch()) {784case Triple::x86_64:785return {supportsX86_64, resolveX86_64};786case Triple::aarch64:787case Triple::aarch64_be:788return {supportsAArch64, resolveAArch64};789case Triple::bpfel:790case Triple::bpfeb:791return {supportsBPF, resolveBPF};792case Triple::loongarch64:793return {supportsLoongArch, resolveLoongArch};794case Triple::mips64el:795case Triple::mips64:796return {supportsMips64, resolveMips64};797case Triple::ppc64le:798case Triple::ppc64:799return {supportsPPC64, resolvePPC64};800case Triple::systemz:801return {supportsSystemZ, resolveSystemZ};802case Triple::sparcv9:803return {supportsSparc64, resolveSparc64};804case Triple::amdgcn:805return {supportsAmdgpu, resolveAmdgpu};806case Triple::riscv64:807return {supportsRISCV, resolveRISCV};808default:809if (isAMDGPU(Obj))810return {supportsAmdgpu, resolveAmdgpu};811return {nullptr, nullptr};812}813}814815// 32-bit object file816assert(Obj.getBytesInAddress() == 4 &&817"Invalid word size in object file");818819switch (Obj.getArch()) {820case Triple::x86:821return {supportsX86, resolveX86};822case Triple::ppcle:823case Triple::ppc:824return {supportsPPC32, resolvePPC32};825case Triple::arm:826case Triple::armeb:827return {supportsARM, resolveARM};828case Triple::avr:829return {supportsAVR, resolveAVR};830case Triple::lanai:831return {supportsLanai, resolveLanai};832case Triple::loongarch32:833return {supportsLoongArch, resolveLoongArch};834case Triple::mipsel:835case Triple::mips:836return {supportsMips32, resolveMips32};837case Triple::msp430:838return {supportsMSP430, resolveMSP430};839case Triple::sparc:840return {supportsSparc32, resolveSparc32};841case Triple::hexagon:842return {supportsHexagon, resolveHexagon};843case Triple::r600:844return {supportsAmdgpu, resolveAmdgpu};845case Triple::riscv32:846return {supportsRISCV, resolveRISCV};847case Triple::csky:848return {supportsCSKY, resolveCSKY};849default:850if (isAMDGPU(Obj))851return {supportsAmdgpu, resolveAmdgpu};852return {nullptr, nullptr};853}854} else if (Obj.isMachO()) {855if (Obj.getArch() == Triple::x86_64)856return {supportsMachOX86_64, resolveMachOX86_64};857return {nullptr, nullptr};858} else if (Obj.isWasm()) {859if (Obj.getArch() == Triple::wasm32)860return {supportsWasm32, resolveWasm32};861if (Obj.getArch() == Triple::wasm64)862return {supportsWasm64, resolveWasm64};863return {nullptr, nullptr};864}865866llvm_unreachable("Invalid object file");867}868869uint64_t resolveRelocation(RelocationResolver Resolver, const RelocationRef &R,870uint64_t S, uint64_t LocData) {871if (const ObjectFile *Obj = R.getObject()) {872int64_t Addend = 0;873if (Obj->isELF()) {874auto GetRelSectionType = [&]() -> unsigned {875if (auto *Elf32LEObj = dyn_cast<ELF32LEObjectFile>(Obj))876return Elf32LEObj->getRelSection(R.getRawDataRefImpl())->sh_type;877if (auto *Elf64LEObj = dyn_cast<ELF64LEObjectFile>(Obj))878return Elf64LEObj->getRelSection(R.getRawDataRefImpl())->sh_type;879if (auto *Elf32BEObj = dyn_cast<ELF32BEObjectFile>(Obj))880return Elf32BEObj->getRelSection(R.getRawDataRefImpl())->sh_type;881auto *Elf64BEObj = cast<ELF64BEObjectFile>(Obj);882return Elf64BEObj->getRelSection(R.getRawDataRefImpl())->sh_type;883};884885if (GetRelSectionType() == ELF::SHT_RELA) {886Addend = getELFAddend(R);887// LoongArch and RISCV relocations use both LocData and Addend.888if (Obj->getArch() != Triple::loongarch32 &&889Obj->getArch() != Triple::loongarch64 &&890Obj->getArch() != Triple::riscv32 &&891Obj->getArch() != Triple::riscv64)892LocData = 0;893}894}895896return Resolver(R.getType(), R.getOffset(), S, LocData, Addend);897}898899// Sometimes the caller might want to use its own specific implementation of900// the resolver function. E.g. this is used by LLD when it resolves debug901// relocations and assumes that all of them have the same computation (S + A).902// The relocation R has no owner object in this case and we don't need to903// provide Type and Offset fields. It is also assumed the DataRefImpl.p904// contains the addend, provided by the caller.905return Resolver(/*Type=*/0, /*Offset=*/0, S, LocData,906R.getRawDataRefImpl().p);907}908909} // namespace object910} // namespace llvm911912913