12f09f445SMaksim Panchenko //===- bolt/Core/Relocation.cpp - Object file relocations -----------------===// 2a34c753fSRafael Auler // 3a34c753fSRafael Auler // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4a34c753fSRafael Auler // See https://llvm.org/LICENSE.txt for license information. 5a34c753fSRafael Auler // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6a34c753fSRafael Auler // 7a34c753fSRafael Auler //===----------------------------------------------------------------------===// 8a34c753fSRafael Auler // 92f09f445SMaksim Panchenko // This file implements the Relocation class. 102f09f445SMaksim Panchenko // 11a34c753fSRafael Auler //===----------------------------------------------------------------------===// 12a34c753fSRafael Auler 13a34c753fSRafael Auler #include "bolt/Core/Relocation.h" 14a34c753fSRafael Auler #include "llvm/MC/MCContext.h" 1557f7c7d9Sserge-sans-paille #include "llvm/MC/MCExpr.h" 16a34c753fSRafael Auler #include "llvm/MC/MCStreamer.h" 1757f7c7d9Sserge-sans-paille #include "llvm/MC/MCSymbol.h" 18eb9f4eb6SAmir Ayupov #include "llvm/Object/ELF.h" 19a34c753fSRafael Auler 20a34c753fSRafael Auler using namespace llvm; 21a34c753fSRafael Auler using namespace bolt; 22a34c753fSRafael Auler 23a34c753fSRafael Auler Triple::ArchType Relocation::Arch; 24a34c753fSRafael Auler 25a34c753fSRafael Auler namespace { 26a34c753fSRafael Auler 27a34c753fSRafael Auler bool isSupportedX86(uint64_t Type) { 28a34c753fSRafael Auler switch (Type) { 29a34c753fSRafael Auler default: 30a34c753fSRafael Auler return false; 31a34c753fSRafael Auler case ELF::R_X86_64_8: 32a34c753fSRafael Auler case ELF::R_X86_64_16: 33a34c753fSRafael Auler case ELF::R_X86_64_32: 34a34c753fSRafael Auler case ELF::R_X86_64_32S: 35a34c753fSRafael Auler case ELF::R_X86_64_64: 36a34c753fSRafael Auler case ELF::R_X86_64_PC8: 37a34c753fSRafael Auler case ELF::R_X86_64_PC32: 38a34c753fSRafael Auler case ELF::R_X86_64_PC64: 39a34c753fSRafael Auler case ELF::R_X86_64_PLT32: 40a34c753fSRafael Auler case ELF::R_X86_64_GOTPCREL: 41a34c753fSRafael Auler case ELF::R_X86_64_GOTTPOFF: 42a34c753fSRafael Auler case ELF::R_X86_64_TPOFF32: 43a34c753fSRafael Auler case ELF::R_X86_64_GOTPCRELX: 44a34c753fSRafael Auler case ELF::R_X86_64_REX_GOTPCRELX: 45a34c753fSRafael Auler return true; 46a34c753fSRafael Auler } 47a34c753fSRafael Auler } 48a34c753fSRafael Auler 49a34c753fSRafael Auler bool isSupportedAArch64(uint64_t Type) { 50a34c753fSRafael Auler switch (Type) { 51a34c753fSRafael Auler default: 52a34c753fSRafael Auler return false; 53a34c753fSRafael Auler case ELF::R_AARCH64_CALL26: 54a34c753fSRafael Auler case ELF::R_AARCH64_JUMP26: 55a34c753fSRafael Auler case ELF::R_AARCH64_TSTBR14: 56a34c753fSRafael Auler case ELF::R_AARCH64_CONDBR19: 57a34c753fSRafael Auler case ELF::R_AARCH64_ADR_PREL_LO21: 58a34c753fSRafael Auler case ELF::R_AARCH64_ADR_PREL_PG_HI21: 59a34c753fSRafael Auler case ELF::R_AARCH64_ADR_PREL_PG_HI21_NC: 60a34c753fSRafael Auler case ELF::R_AARCH64_LDST64_ABS_LO12_NC: 61a34c753fSRafael Auler case ELF::R_AARCH64_ADD_ABS_LO12_NC: 62a34c753fSRafael Auler case ELF::R_AARCH64_LDST128_ABS_LO12_NC: 63a34c753fSRafael Auler case ELF::R_AARCH64_LDST32_ABS_LO12_NC: 64a34c753fSRafael Auler case ELF::R_AARCH64_LDST16_ABS_LO12_NC: 65a34c753fSRafael Auler case ELF::R_AARCH64_LDST8_ABS_LO12_NC: 66a34c753fSRafael Auler case ELF::R_AARCH64_ADR_GOT_PAGE: 67a34c753fSRafael Auler case ELF::R_AARCH64_TLSDESC_ADR_PREL21: 68a34c753fSRafael Auler case ELF::R_AARCH64_TLSDESC_ADR_PAGE21: 69a34c753fSRafael Auler case ELF::R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC: 70a34c753fSRafael Auler case ELF::R_AARCH64_TLSLE_ADD_TPREL_HI12: 71a34c753fSRafael Auler case ELF::R_AARCH64_TLSLE_ADD_TPREL_LO12_NC: 72a34c753fSRafael Auler case ELF::R_AARCH64_LD64_GOT_LO12_NC: 73a34c753fSRafael Auler case ELF::R_AARCH64_TLSDESC_LD64_LO12: 74a34c753fSRafael Auler case ELF::R_AARCH64_TLSDESC_ADD_LO12: 75a34c753fSRafael Auler case ELF::R_AARCH64_TLSDESC_CALL: 76a34c753fSRafael Auler case ELF::R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21: 7748e894a5SAlexey Moksyakov case ELF::R_AARCH64_PREL16: 78a34c753fSRafael Auler case ELF::R_AARCH64_PREL32: 7948e894a5SAlexey Moksyakov case ELF::R_AARCH64_PREL64: 80172deb75SVladislav Khmelevsky case ELF::R_AARCH64_ABS16: 81172deb75SVladislav Khmelevsky case ELF::R_AARCH64_ABS32: 82a34c753fSRafael Auler case ELF::R_AARCH64_ABS64: 83a34c753fSRafael Auler case ELF::R_AARCH64_MOVW_UABS_G0: 84a34c753fSRafael Auler case ELF::R_AARCH64_MOVW_UABS_G0_NC: 85a34c753fSRafael Auler case ELF::R_AARCH64_MOVW_UABS_G1: 86a34c753fSRafael Auler case ELF::R_AARCH64_MOVW_UABS_G1_NC: 87a34c753fSRafael Auler case ELF::R_AARCH64_MOVW_UABS_G2: 88a34c753fSRafael Auler case ELF::R_AARCH64_MOVW_UABS_G2_NC: 89a34c753fSRafael Auler case ELF::R_AARCH64_MOVW_UABS_G3: 90a34c753fSRafael Auler return true; 91a34c753fSRafael Auler } 92a34c753fSRafael Auler } 93a34c753fSRafael Auler 94a34c753fSRafael Auler size_t getSizeForTypeX86(uint64_t Type) { 95a34c753fSRafael Auler switch (Type) { 96a34c753fSRafael Auler default: 97eb9f4eb6SAmir Ayupov errs() << object::getELFRelocationTypeName(ELF::EM_X86_64, Type) << '\n'; 98a34c753fSRafael Auler llvm_unreachable("unsupported relocation type"); 99a34c753fSRafael Auler case ELF::R_X86_64_8: 100a34c753fSRafael Auler case ELF::R_X86_64_PC8: 101a34c753fSRafael Auler return 1; 102a34c753fSRafael Auler case ELF::R_X86_64_16: 103a34c753fSRafael Auler return 2; 104a34c753fSRafael Auler case ELF::R_X86_64_PLT32: 105a34c753fSRafael Auler case ELF::R_X86_64_PC32: 106a34c753fSRafael Auler case ELF::R_X86_64_32S: 107a34c753fSRafael Auler case ELF::R_X86_64_32: 108a34c753fSRafael Auler case ELF::R_X86_64_GOTPCREL: 109a34c753fSRafael Auler case ELF::R_X86_64_GOTTPOFF: 110a34c753fSRafael Auler case ELF::R_X86_64_TPOFF32: 111a34c753fSRafael Auler case ELF::R_X86_64_GOTPCRELX: 112a34c753fSRafael Auler case ELF::R_X86_64_REX_GOTPCRELX: 113a34c753fSRafael Auler return 4; 114a34c753fSRafael Auler case ELF::R_X86_64_PC64: 115a34c753fSRafael Auler case ELF::R_X86_64_64: 116a34c753fSRafael Auler return 8; 117a34c753fSRafael Auler } 118a34c753fSRafael Auler } 119a34c753fSRafael Auler 120a34c753fSRafael Auler size_t getSizeForTypeAArch64(uint64_t Type) { 121a34c753fSRafael Auler switch (Type) { 122a34c753fSRafael Auler default: 123eb9f4eb6SAmir Ayupov errs() << object::getELFRelocationTypeName(ELF::EM_AARCH64, Type) << '\n'; 124a34c753fSRafael Auler llvm_unreachable("unsupported relocation type"); 125172deb75SVladislav Khmelevsky case ELF::R_AARCH64_ABS16: 12648e894a5SAlexey Moksyakov case ELF::R_AARCH64_PREL16: 127172deb75SVladislav Khmelevsky return 2; 128a34c753fSRafael Auler case ELF::R_AARCH64_CALL26: 129a34c753fSRafael Auler case ELF::R_AARCH64_JUMP26: 130a34c753fSRafael Auler case ELF::R_AARCH64_TSTBR14: 131a34c753fSRafael Auler case ELF::R_AARCH64_CONDBR19: 132a34c753fSRafael Auler case ELF::R_AARCH64_ADR_PREL_LO21: 133a34c753fSRafael Auler case ELF::R_AARCH64_ADR_PREL_PG_HI21: 134a34c753fSRafael Auler case ELF::R_AARCH64_ADR_PREL_PG_HI21_NC: 135a34c753fSRafael Auler case ELF::R_AARCH64_LDST64_ABS_LO12_NC: 136a34c753fSRafael Auler case ELF::R_AARCH64_ADD_ABS_LO12_NC: 137a34c753fSRafael Auler case ELF::R_AARCH64_LDST128_ABS_LO12_NC: 138a34c753fSRafael Auler case ELF::R_AARCH64_LDST32_ABS_LO12_NC: 139a34c753fSRafael Auler case ELF::R_AARCH64_LDST16_ABS_LO12_NC: 140a34c753fSRafael Auler case ELF::R_AARCH64_LDST8_ABS_LO12_NC: 141a34c753fSRafael Auler case ELF::R_AARCH64_ADR_GOT_PAGE: 142a34c753fSRafael Auler case ELF::R_AARCH64_TLSDESC_ADR_PREL21: 143a34c753fSRafael Auler case ELF::R_AARCH64_TLSDESC_ADR_PAGE21: 144a34c753fSRafael Auler case ELF::R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC: 145a34c753fSRafael Auler case ELF::R_AARCH64_TLSLE_ADD_TPREL_HI12: 146a34c753fSRafael Auler case ELF::R_AARCH64_TLSLE_ADD_TPREL_LO12_NC: 147a34c753fSRafael Auler case ELF::R_AARCH64_LD64_GOT_LO12_NC: 148a34c753fSRafael Auler case ELF::R_AARCH64_TLSDESC_LD64_LO12: 149a34c753fSRafael Auler case ELF::R_AARCH64_TLSDESC_ADD_LO12: 150a34c753fSRafael Auler case ELF::R_AARCH64_TLSDESC_CALL: 151a34c753fSRafael Auler case ELF::R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21: 152a34c753fSRafael Auler case ELF::R_AARCH64_PREL32: 153a34c753fSRafael Auler case ELF::R_AARCH64_MOVW_UABS_G0: 154a34c753fSRafael Auler case ELF::R_AARCH64_MOVW_UABS_G0_NC: 155a34c753fSRafael Auler case ELF::R_AARCH64_MOVW_UABS_G1: 156a34c753fSRafael Auler case ELF::R_AARCH64_MOVW_UABS_G1_NC: 157a34c753fSRafael Auler case ELF::R_AARCH64_MOVW_UABS_G2: 158a34c753fSRafael Auler case ELF::R_AARCH64_MOVW_UABS_G2_NC: 159a34c753fSRafael Auler case ELF::R_AARCH64_MOVW_UABS_G3: 160172deb75SVladislav Khmelevsky case ELF::R_AARCH64_ABS32: 161a34c753fSRafael Auler return 4; 162a34c753fSRafael Auler case ELF::R_AARCH64_ABS64: 16348e894a5SAlexey Moksyakov case ELF::R_AARCH64_PREL64: 164a34c753fSRafael Auler return 8; 165a34c753fSRafael Auler } 166a34c753fSRafael Auler } 167a34c753fSRafael Auler 168a34c753fSRafael Auler bool skipRelocationProcessX86(uint64_t Type, uint64_t Contents) { 169a34c753fSRafael Auler return false; 170a34c753fSRafael Auler } 171a34c753fSRafael Auler 172a34c753fSRafael Auler bool skipRelocationProcessAArch64(uint64_t Type, uint64_t Contents) { 173a34c753fSRafael Auler auto IsMov = [](uint64_t Contents) -> bool { 174a34c753fSRafael Auler // The bits 28-23 are 0b100101 1752f98c5feSVladislav Khmelevsky return (Contents & 0x1f800000) == 0x12800000; 176a34c753fSRafael Auler }; 177a34c753fSRafael Auler 178a34c753fSRafael Auler auto IsB = [](uint64_t Contents) -> bool { 179a34c753fSRafael Auler // The bits 31-26 are 0b000101 1802f98c5feSVladislav Khmelevsky return (Contents & 0xfc000000) == 0x14000000; 1812f98c5feSVladislav Khmelevsky }; 1822f98c5feSVladislav Khmelevsky 1832f98c5feSVladislav Khmelevsky auto IsAdr = [](uint64_t Contents) -> bool { 1842f98c5feSVladislav Khmelevsky // The bits 31-24 are 0b0xx10000 1852f98c5feSVladislav Khmelevsky return (Contents & 0x9f000000) == 0x10000000; 186a34c753fSRafael Auler }; 187a34c753fSRafael Auler 18840c2e0faSMaksim Panchenko auto IsNop = [](uint64_t Contents) -> bool { return Contents == 0xd503201f; }; 189a34c753fSRafael Auler 190a34c753fSRafael Auler // The linker might eliminate the instruction and replace it with NOP, ignore 191a34c753fSRafael Auler if (IsNop(Contents)) 192a34c753fSRafael Auler return true; 193a34c753fSRafael Auler 194a34c753fSRafael Auler // The linker might perform TLS relocations relaxations, such as 195a34c753fSRafael Auler // changed TLS access model (e.g. changed global dynamic model 196a34c753fSRafael Auler // to initial exec), thus changing the instructions. The static 197a34c753fSRafael Auler // relocations might be invalid at this point and we might no 198a34c753fSRafael Auler // need to proccess these relocations anymore. 199a34c753fSRafael Auler // More information could be found by searching 200a34c753fSRafael Auler // elfNN_aarch64_tls_relax in bfd 201a34c753fSRafael Auler switch (Type) { 202a34c753fSRafael Auler default: 203a34c753fSRafael Auler break; 204a34c753fSRafael Auler case ELF::R_AARCH64_TLSDESC_LD64_LO12: 205a34c753fSRafael Auler case ELF::R_AARCH64_TLSDESC_ADR_PAGE21: 206a34c753fSRafael Auler case ELF::R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC: 207a34c753fSRafael Auler case ELF::R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21: { 208a34c753fSRafael Auler if (IsMov(Contents)) 209a34c753fSRafael Auler return true; 210a34c753fSRafael Auler } 211a34c753fSRafael Auler } 212a34c753fSRafael Auler 2132f98c5feSVladislav Khmelevsky // The linker might replace load/store instruction with jump and 214a34c753fSRafael Auler // veneer due to errata 843419 215a34c753fSRafael Auler // https://documentation-service.arm.com/static/5fa29fddb209f547eebd361d 216a34c753fSRafael Auler // Thus load/store relocations for these instructions must be ignored 217a34c753fSRafael Auler // NOTE: We only process GOT and TLS relocations this way since the 218a34c753fSRafael Auler // addend used in load/store instructions won't change after bolt 219a34c753fSRafael Auler // (it is important since the instruction in veneer won't have relocation) 220a34c753fSRafael Auler switch (Type) { 221a34c753fSRafael Auler default: 222a34c753fSRafael Auler break; 223a34c753fSRafael Auler case ELF::R_AARCH64_LD64_GOT_LO12_NC: 224a34c753fSRafael Auler case ELF::R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC: 225a34c753fSRafael Auler case ELF::R_AARCH64_TLSDESC_LD64_LO12: { 226a34c753fSRafael Auler if (IsB(Contents)) 227a34c753fSRafael Auler return true; 228a34c753fSRafael Auler } 229a34c753fSRafael Auler } 230a34c753fSRafael Auler 2312f98c5feSVladislav Khmelevsky // The linker might relax ADRP+ADD or ADRP+LDR sequences to the ADR+NOP 2322f98c5feSVladislav Khmelevsky switch (Type) { 2332f98c5feSVladislav Khmelevsky default: 2342f98c5feSVladislav Khmelevsky break; 2352f98c5feSVladislav Khmelevsky case ELF::R_AARCH64_ADR_PREL_PG_HI21: 2362f98c5feSVladislav Khmelevsky case ELF::R_AARCH64_ADD_ABS_LO12_NC: 2372f98c5feSVladislav Khmelevsky case ELF::R_AARCH64_ADR_GOT_PAGE: 2382f98c5feSVladislav Khmelevsky case ELF::R_AARCH64_LD64_GOT_LO12_NC: 2392f98c5feSVladislav Khmelevsky if (IsAdr(Contents)) 2402f98c5feSVladislav Khmelevsky return true; 2412f98c5feSVladislav Khmelevsky } 2422f98c5feSVladislav Khmelevsky 243a34c753fSRafael Auler return false; 244a34c753fSRafael Auler } 245a34c753fSRafael Auler 2464a4045f7SElvina Yakubova uint64_t adjustValueX86(uint64_t Type, uint64_t Value, uint64_t PC) { 2474a4045f7SElvina Yakubova switch (Type) { 2484a4045f7SElvina Yakubova default: 2494a4045f7SElvina Yakubova llvm_unreachable("not supported relocation"); 2504a4045f7SElvina Yakubova case ELF::R_X86_64_32: 2514a4045f7SElvina Yakubova break; 2524a4045f7SElvina Yakubova case ELF::R_X86_64_PC32: 2534a4045f7SElvina Yakubova Value -= PC; 2544a4045f7SElvina Yakubova break; 2554a4045f7SElvina Yakubova } 2564a4045f7SElvina Yakubova return Value; 2574a4045f7SElvina Yakubova } 2584a4045f7SElvina Yakubova 2594a4045f7SElvina Yakubova uint64_t adjustValueAArch64(uint64_t Type, uint64_t Value, uint64_t PC) { 2604a4045f7SElvina Yakubova switch (Type) { 2614a4045f7SElvina Yakubova default: 2624a4045f7SElvina Yakubova llvm_unreachable("not supported relocation"); 2634a4045f7SElvina Yakubova case ELF::R_AARCH64_ABS32: 2644a4045f7SElvina Yakubova break; 26548e894a5SAlexey Moksyakov case ELF::R_AARCH64_PREL16: 2664a4045f7SElvina Yakubova case ELF::R_AARCH64_PREL32: 26748e894a5SAlexey Moksyakov case ELF::R_AARCH64_PREL64: 2684a4045f7SElvina Yakubova Value -= PC; 2694a4045f7SElvina Yakubova break; 2704a4045f7SElvina Yakubova } 2714a4045f7SElvina Yakubova return Value; 2724a4045f7SElvina Yakubova } 2734a4045f7SElvina Yakubova 274a34c753fSRafael Auler uint64_t extractValueX86(uint64_t Type, uint64_t Contents, uint64_t PC) { 275a34c753fSRafael Auler if (Type == ELF::R_X86_64_32S) 2764101aa13SMaksim Panchenko return SignExtend64<32>(Contents); 2774101aa13SMaksim Panchenko if (Relocation::isPCRelative(Type)) 2784101aa13SMaksim Panchenko return SignExtend64(Contents, 8 * Relocation::getSizeForType(Type)); 279a34c753fSRafael Auler return Contents; 280a34c753fSRafael Auler } 281a34c753fSRafael Auler 282a34c753fSRafael Auler uint64_t extractValueAArch64(uint64_t Type, uint64_t Contents, uint64_t PC) { 283a34c753fSRafael Auler switch (Type) { 284a34c753fSRafael Auler default: 285eb9f4eb6SAmir Ayupov errs() << object::getELFRelocationTypeName(ELF::EM_AARCH64, Type) << '\n'; 286a34c753fSRafael Auler llvm_unreachable("unsupported relocation type"); 287172deb75SVladislav Khmelevsky case ELF::R_AARCH64_ABS16: 288172deb75SVladislav Khmelevsky case ELF::R_AARCH64_ABS32: 289a34c753fSRafael Auler case ELF::R_AARCH64_ABS64: 290a34c753fSRafael Auler return Contents; 29148e894a5SAlexey Moksyakov case ELF::R_AARCH64_PREL16: 29248e894a5SAlexey Moksyakov return static_cast<int64_t>(PC) + SignExtend64<16>(Contents & 0xffff); 293a34c753fSRafael Auler case ELF::R_AARCH64_PREL32: 294a34c753fSRafael Auler return static_cast<int64_t>(PC) + SignExtend64<32>(Contents & 0xffffffff); 29548e894a5SAlexey Moksyakov case ELF::R_AARCH64_PREL64: 29648e894a5SAlexey Moksyakov return static_cast<int64_t>(PC) + Contents; 297a34c753fSRafael Auler case ELF::R_AARCH64_TLSDESC_CALL: 298a34c753fSRafael Auler case ELF::R_AARCH64_JUMP26: 299a34c753fSRafael Auler case ELF::R_AARCH64_CALL26: 300a34c753fSRafael Auler // Immediate goes in bits 25:0 of B and BL. 301a34c753fSRafael Auler Contents &= ~0xfffffffffc000000ULL; 302a34c753fSRafael Auler return static_cast<int64_t>(PC) + SignExtend64<28>(Contents << 2); 303a34c753fSRafael Auler case ELF::R_AARCH64_TSTBR14: 304a34c753fSRafael Auler // Immediate:15:2 goes in bits 18:5 of TBZ, TBNZ 305a34c753fSRafael Auler Contents &= ~0xfffffffffff8001fULL; 306a34c753fSRafael Auler return static_cast<int64_t>(PC) + SignExtend64<16>(Contents >> 3); 307a34c753fSRafael Auler case ELF::R_AARCH64_CONDBR19: 308a34c753fSRafael Auler // Immediate:20:2 goes in bits 23:5 of Bcc, CBZ, CBNZ 309a34c753fSRafael Auler Contents &= ~0xffffffffff00001fULL; 310a34c753fSRafael Auler return static_cast<int64_t>(PC) + SignExtend64<21>(Contents >> 3); 311a34c753fSRafael Auler case ELF::R_AARCH64_ADR_GOT_PAGE: 312a34c753fSRafael Auler case ELF::R_AARCH64_TLSDESC_ADR_PREL21: 313a34c753fSRafael Auler case ELF::R_AARCH64_TLSDESC_ADR_PAGE21: 314a34c753fSRafael Auler case ELF::R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21: 315a34c753fSRafael Auler case ELF::R_AARCH64_ADR_PREL_LO21: 316a34c753fSRafael Auler case ELF::R_AARCH64_ADR_PREL_PG_HI21: 317a34c753fSRafael Auler case ELF::R_AARCH64_ADR_PREL_PG_HI21_NC: { 318a34c753fSRafael Auler // Bits 32:12 of Symbol address goes in bits 30:29 + 23:5 of ADRP 319a34c753fSRafael Auler // and ADR instructions 320a34c753fSRafael Auler bool IsAdr = !!(((Contents >> 31) & 0x1) == 0); 321a34c753fSRafael Auler Contents &= ~0xffffffff9f00001fUll; 322a34c753fSRafael Auler uint64_t LowBits = (Contents >> 29) & 0x3; 323a34c753fSRafael Auler uint64_t HighBits = (Contents >> 5) & 0x7ffff; 324a34c753fSRafael Auler Contents = LowBits | (HighBits << 2); 325a34c753fSRafael Auler if (IsAdr) 326a34c753fSRafael Auler return static_cast<int64_t>(PC) + SignExtend64<21>(Contents); 327a34c753fSRafael Auler 328a34c753fSRafael Auler // ADRP instruction 329a34c753fSRafael Auler Contents = static_cast<int64_t>(PC) + SignExtend64<33>(Contents << 12); 330a34c753fSRafael Auler Contents &= ~0xfffUll; 331a34c753fSRafael Auler return Contents; 332a34c753fSRafael Auler } 333a34c753fSRafael Auler case ELF::R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC: 334a34c753fSRafael Auler case ELF::R_AARCH64_TLSDESC_LD64_LO12: 335a34c753fSRafael Auler case ELF::R_AARCH64_LD64_GOT_LO12_NC: 336a34c753fSRafael Auler case ELF::R_AARCH64_LDST64_ABS_LO12_NC: { 337a34c753fSRafael Auler // Immediate goes in bits 21:10 of LD/ST instruction, taken 338a34c753fSRafael Auler // from bits 11:3 of Symbol address 339a34c753fSRafael Auler Contents &= ~0xffffffffffc003ffU; 340a34c753fSRafael Auler return Contents >> (10 - 3); 341a34c753fSRafael Auler } 342a34c753fSRafael Auler case ELF::R_AARCH64_TLSLE_ADD_TPREL_HI12: 343a34c753fSRafael Auler case ELF::R_AARCH64_TLSLE_ADD_TPREL_LO12_NC: 344a34c753fSRafael Auler case ELF::R_AARCH64_TLSDESC_ADD_LO12: 345a34c753fSRafael Auler case ELF::R_AARCH64_ADD_ABS_LO12_NC: { 346a34c753fSRafael Auler // Immediate goes in bits 21:10 of ADD instruction 347a34c753fSRafael Auler Contents &= ~0xffffffffffc003ffU; 348a34c753fSRafael Auler return Contents >> (10 - 0); 349a34c753fSRafael Auler } 350a34c753fSRafael Auler case ELF::R_AARCH64_LDST128_ABS_LO12_NC: { 351a34c753fSRafael Auler // Immediate goes in bits 21:10 of ADD instruction, taken 352a34c753fSRafael Auler // from bits 11:4 of Symbol address 353a34c753fSRafael Auler Contents &= ~0xffffffffffc003ffU; 354a34c753fSRafael Auler return Contents >> (10 - 4); 355a34c753fSRafael Auler } 356a34c753fSRafael Auler case ELF::R_AARCH64_LDST32_ABS_LO12_NC: { 357a34c753fSRafael Auler // Immediate goes in bits 21:10 of ADD instruction, taken 358a34c753fSRafael Auler // from bits 11:2 of Symbol address 359a34c753fSRafael Auler Contents &= ~0xffffffffffc003ffU; 360a34c753fSRafael Auler return Contents >> (10 - 2); 361a34c753fSRafael Auler } 362a34c753fSRafael Auler case ELF::R_AARCH64_LDST16_ABS_LO12_NC: { 363a34c753fSRafael Auler // Immediate goes in bits 21:10 of ADD instruction, taken 364a34c753fSRafael Auler // from bits 11:1 of Symbol address 365a34c753fSRafael Auler Contents &= ~0xffffffffffc003ffU; 366a34c753fSRafael Auler return Contents >> (10 - 1); 367a34c753fSRafael Auler } 368a34c753fSRafael Auler case ELF::R_AARCH64_LDST8_ABS_LO12_NC: { 369a34c753fSRafael Auler // Immediate goes in bits 21:10 of ADD instruction, taken 370a34c753fSRafael Auler // from bits 11:0 of Symbol address 371a34c753fSRafael Auler Contents &= ~0xffffffffffc003ffU; 372a34c753fSRafael Auler return Contents >> (10 - 0); 373a34c753fSRafael Auler } 374a34c753fSRafael Auler case ELF::R_AARCH64_MOVW_UABS_G3: 375a34c753fSRafael Auler case ELF::R_AARCH64_MOVW_UABS_G2_NC: 376a34c753fSRafael Auler case ELF::R_AARCH64_MOVW_UABS_G2: 377a34c753fSRafael Auler case ELF::R_AARCH64_MOVW_UABS_G1_NC: 378a34c753fSRafael Auler case ELF::R_AARCH64_MOVW_UABS_G1: 379a34c753fSRafael Auler case ELF::R_AARCH64_MOVW_UABS_G0_NC: 380a34c753fSRafael Auler case ELF::R_AARCH64_MOVW_UABS_G0: 381a34c753fSRafael Auler // The shift goest in bits 22:21 of MOV* instructions 382a34c753fSRafael Auler uint8_t Shift = (Contents >> 21) & 0x3; 383a34c753fSRafael Auler // Immediate goes in bits 20:5 384a34c753fSRafael Auler Contents = (Contents >> 5) & 0xffff; 385a34c753fSRafael Auler return Contents << (16 * Shift); 386a34c753fSRafael Auler } 387a34c753fSRafael Auler } 388a34c753fSRafael Auler 389a34c753fSRafael Auler bool isGOTX86(uint64_t Type) { 390a34c753fSRafael Auler switch (Type) { 391a34c753fSRafael Auler default: 392a34c753fSRafael Auler return false; 393a34c753fSRafael Auler case ELF::R_X86_64_GOT32: 394a34c753fSRafael Auler case ELF::R_X86_64_GOTPCREL: 395a34c753fSRafael Auler case ELF::R_X86_64_GOTTPOFF: 396a34c753fSRafael Auler case ELF::R_X86_64_GOTOFF64: 397a34c753fSRafael Auler case ELF::R_X86_64_GOTPC32: 398a34c753fSRafael Auler case ELF::R_X86_64_GOT64: 399a34c753fSRafael Auler case ELF::R_X86_64_GOTPCREL64: 400a34c753fSRafael Auler case ELF::R_X86_64_GOTPC64: 401a34c753fSRafael Auler case ELF::R_X86_64_GOTPLT64: 402a34c753fSRafael Auler case ELF::R_X86_64_GOTPC32_TLSDESC: 403a34c753fSRafael Auler case ELF::R_X86_64_GOTPCRELX: 404a34c753fSRafael Auler case ELF::R_X86_64_REX_GOTPCRELX: 405a34c753fSRafael Auler return true; 406a34c753fSRafael Auler } 407a34c753fSRafael Auler } 408a34c753fSRafael Auler 409a34c753fSRafael Auler bool isGOTAArch64(uint64_t Type) { 410a34c753fSRafael Auler switch (Type) { 411a34c753fSRafael Auler default: 412a34c753fSRafael Auler return false; 413a34c753fSRafael Auler case ELF::R_AARCH64_ADR_GOT_PAGE: 414a34c753fSRafael Auler case ELF::R_AARCH64_LD64_GOT_LO12_NC: 415a34c753fSRafael Auler case ELF::R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC: 416a34c753fSRafael Auler case ELF::R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21: 417a34c753fSRafael Auler case ELF::R_AARCH64_TLSDESC_ADR_PREL21: 418a34c753fSRafael Auler case ELF::R_AARCH64_TLSDESC_ADR_PAGE21: 419a34c753fSRafael Auler case ELF::R_AARCH64_TLSDESC_LD64_LO12: 420a34c753fSRafael Auler case ELF::R_AARCH64_TLSDESC_ADD_LO12: 421a34c753fSRafael Auler case ELF::R_AARCH64_TLSDESC_CALL: 422a34c753fSRafael Auler return true; 423a34c753fSRafael Auler } 424a34c753fSRafael Auler } 425a34c753fSRafael Auler 426a34c753fSRafael Auler bool isTLSX86(uint64_t Type) { 427a34c753fSRafael Auler switch (Type) { 428a34c753fSRafael Auler default: 429a34c753fSRafael Auler return false; 430a34c753fSRafael Auler case ELF::R_X86_64_TPOFF32: 431a34c753fSRafael Auler case ELF::R_X86_64_TPOFF64: 432a34c753fSRafael Auler case ELF::R_X86_64_GOTTPOFF: 433a34c753fSRafael Auler return true; 434a34c753fSRafael Auler } 435a34c753fSRafael Auler } 436a34c753fSRafael Auler 437a34c753fSRafael Auler bool isTLSAArch64(uint64_t Type) { 438a34c753fSRafael Auler switch (Type) { 439a34c753fSRafael Auler default: 440a34c753fSRafael Auler return false; 441a34c753fSRafael Auler case ELF::R_AARCH64_TLSDESC_ADR_PREL21: 442a34c753fSRafael Auler case ELF::R_AARCH64_TLSDESC_ADR_PAGE21: 443a34c753fSRafael Auler case ELF::R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC: 444a34c753fSRafael Auler case ELF::R_AARCH64_TLSLE_ADD_TPREL_HI12: 445a34c753fSRafael Auler case ELF::R_AARCH64_TLSLE_ADD_TPREL_LO12_NC: 446a34c753fSRafael Auler case ELF::R_AARCH64_TLSDESC_LD64_LO12: 447a34c753fSRafael Auler case ELF::R_AARCH64_TLSDESC_ADD_LO12: 448a34c753fSRafael Auler case ELF::R_AARCH64_TLSDESC_CALL: 449a34c753fSRafael Auler case ELF::R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21: 450a34c753fSRafael Auler return true; 451a34c753fSRafael Auler } 452a34c753fSRafael Auler } 453a34c753fSRafael Auler 454a34c753fSRafael Auler bool isPCRelativeX86(uint64_t Type) { 455a34c753fSRafael Auler switch (Type) { 456a34c753fSRafael Auler default: 457a34c753fSRafael Auler llvm_unreachable("Unknown relocation type"); 458a34c753fSRafael Auler case ELF::R_X86_64_64: 459a34c753fSRafael Auler case ELF::R_X86_64_32: 460a34c753fSRafael Auler case ELF::R_X86_64_32S: 461a34c753fSRafael Auler case ELF::R_X86_64_16: 462a34c753fSRafael Auler case ELF::R_X86_64_8: 463a34c753fSRafael Auler case ELF::R_X86_64_TPOFF32: 464a34c753fSRafael Auler return false; 465a34c753fSRafael Auler case ELF::R_X86_64_PC8: 466a34c753fSRafael Auler case ELF::R_X86_64_PC32: 467a34c753fSRafael Auler case ELF::R_X86_64_PC64: 468a34c753fSRafael Auler case ELF::R_X86_64_GOTPCREL: 469a34c753fSRafael Auler case ELF::R_X86_64_PLT32: 4704101aa13SMaksim Panchenko case ELF::R_X86_64_GOTOFF64: 4714101aa13SMaksim Panchenko case ELF::R_X86_64_GOTPC32: 472a34c753fSRafael Auler case ELF::R_X86_64_GOTTPOFF: 473a34c753fSRafael Auler case ELF::R_X86_64_GOTPCRELX: 474a34c753fSRafael Auler case ELF::R_X86_64_REX_GOTPCRELX: 475a34c753fSRafael Auler return true; 476a34c753fSRafael Auler } 477a34c753fSRafael Auler } 478a34c753fSRafael Auler 479a34c753fSRafael Auler bool isPCRelativeAArch64(uint64_t Type) { 480a34c753fSRafael Auler switch (Type) { 481a34c753fSRafael Auler default: 482a34c753fSRafael Auler llvm_unreachable("Unknown relocation type"); 483172deb75SVladislav Khmelevsky case ELF::R_AARCH64_ABS16: 484172deb75SVladislav Khmelevsky case ELF::R_AARCH64_ABS32: 485a34c753fSRafael Auler case ELF::R_AARCH64_ABS64: 486a34c753fSRafael Auler case ELF::R_AARCH64_LDST64_ABS_LO12_NC: 487a34c753fSRafael Auler case ELF::R_AARCH64_ADD_ABS_LO12_NC: 488a34c753fSRafael Auler case ELF::R_AARCH64_LDST128_ABS_LO12_NC: 489a34c753fSRafael Auler case ELF::R_AARCH64_LDST32_ABS_LO12_NC: 490a34c753fSRafael Auler case ELF::R_AARCH64_LDST16_ABS_LO12_NC: 491a34c753fSRafael Auler case ELF::R_AARCH64_LDST8_ABS_LO12_NC: 492a34c753fSRafael Auler case ELF::R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC: 493a34c753fSRafael Auler case ELF::R_AARCH64_TLSLE_ADD_TPREL_HI12: 494a34c753fSRafael Auler case ELF::R_AARCH64_TLSLE_ADD_TPREL_LO12_NC: 495a34c753fSRafael Auler case ELF::R_AARCH64_LD64_GOT_LO12_NC: 496a34c753fSRafael Auler case ELF::R_AARCH64_TLSDESC_LD64_LO12: 497a34c753fSRafael Auler case ELF::R_AARCH64_TLSDESC_ADD_LO12: 498a34c753fSRafael Auler case ELF::R_AARCH64_MOVW_UABS_G0: 499a34c753fSRafael Auler case ELF::R_AARCH64_MOVW_UABS_G0_NC: 500a34c753fSRafael Auler case ELF::R_AARCH64_MOVW_UABS_G1: 501a34c753fSRafael Auler case ELF::R_AARCH64_MOVW_UABS_G1_NC: 502a34c753fSRafael Auler case ELF::R_AARCH64_MOVW_UABS_G2: 503a34c753fSRafael Auler case ELF::R_AARCH64_MOVW_UABS_G2_NC: 504a34c753fSRafael Auler case ELF::R_AARCH64_MOVW_UABS_G3: 505a34c753fSRafael Auler return false; 506a34c753fSRafael Auler case ELF::R_AARCH64_TLSDESC_CALL: 507a34c753fSRafael Auler case ELF::R_AARCH64_CALL26: 508a34c753fSRafael Auler case ELF::R_AARCH64_JUMP26: 509a34c753fSRafael Auler case ELF::R_AARCH64_TSTBR14: 510a34c753fSRafael Auler case ELF::R_AARCH64_CONDBR19: 511a34c753fSRafael Auler case ELF::R_AARCH64_ADR_PREL_LO21: 512a34c753fSRafael Auler case ELF::R_AARCH64_ADR_PREL_PG_HI21: 513a34c753fSRafael Auler case ELF::R_AARCH64_ADR_PREL_PG_HI21_NC: 514a34c753fSRafael Auler case ELF::R_AARCH64_ADR_GOT_PAGE: 515a34c753fSRafael Auler case ELF::R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21: 516a34c753fSRafael Auler case ELF::R_AARCH64_TLSDESC_ADR_PREL21: 517a34c753fSRafael Auler case ELF::R_AARCH64_TLSDESC_ADR_PAGE21: 51848e894a5SAlexey Moksyakov case ELF::R_AARCH64_PREL16: 519a34c753fSRafael Auler case ELF::R_AARCH64_PREL32: 52048e894a5SAlexey Moksyakov case ELF::R_AARCH64_PREL64: 521a34c753fSRafael Auler return true; 522a34c753fSRafael Auler } 523a34c753fSRafael Auler } 524a34c753fSRafael Auler 525a34c753fSRafael Auler } // end anonymous namespace 526a34c753fSRafael Auler 527a34c753fSRafael Auler bool Relocation::isSupported(uint64_t Type) { 528a34c753fSRafael Auler if (Arch == Triple::aarch64) 529a34c753fSRafael Auler return isSupportedAArch64(Type); 530a34c753fSRafael Auler return isSupportedX86(Type); 531a34c753fSRafael Auler } 532a34c753fSRafael Auler 533a34c753fSRafael Auler size_t Relocation::getSizeForType(uint64_t Type) { 534a34c753fSRafael Auler if (Arch == Triple::aarch64) 535a34c753fSRafael Auler return getSizeForTypeAArch64(Type); 536a34c753fSRafael Auler return getSizeForTypeX86(Type); 537a34c753fSRafael Auler } 538a34c753fSRafael Auler 539a34c753fSRafael Auler bool Relocation::skipRelocationProcess(uint64_t Type, uint64_t Contents) { 540a34c753fSRafael Auler if (Arch == Triple::aarch64) 541a34c753fSRafael Auler return skipRelocationProcessAArch64(Type, Contents); 542a34c753fSRafael Auler return skipRelocationProcessX86(Type, Contents); 543a34c753fSRafael Auler } 544a34c753fSRafael Auler 5454a4045f7SElvina Yakubova uint64_t Relocation::adjustValue(uint64_t Type, uint64_t Value, 5464a4045f7SElvina Yakubova uint64_t PC) { 5474a4045f7SElvina Yakubova if (Arch == Triple::aarch64) 5484a4045f7SElvina Yakubova return adjustValueAArch64(Type, Value, PC); 5494a4045f7SElvina Yakubova return adjustValueX86(Type, Value, PC); 5504a4045f7SElvina Yakubova } 5514a4045f7SElvina Yakubova 552a34c753fSRafael Auler uint64_t Relocation::extractValue(uint64_t Type, uint64_t Contents, 553a34c753fSRafael Auler uint64_t PC) { 554a34c753fSRafael Auler if (Arch == Triple::aarch64) 555a34c753fSRafael Auler return extractValueAArch64(Type, Contents, PC); 556a34c753fSRafael Auler return extractValueX86(Type, Contents, PC); 557a34c753fSRafael Auler } 558a34c753fSRafael Auler 559a34c753fSRafael Auler bool Relocation::isGOT(uint64_t Type) { 560a34c753fSRafael Auler if (Arch == Triple::aarch64) 561a34c753fSRafael Auler return isGOTAArch64(Type); 562a34c753fSRafael Auler return isGOTX86(Type); 563a34c753fSRafael Auler } 564a34c753fSRafael Auler 565*18176426SMaksim Panchenko bool Relocation::isX86GOTPCRELX(uint64_t Type) { 566*18176426SMaksim Panchenko if (Arch != Triple::x86_64) 567*18176426SMaksim Panchenko return false; 568*18176426SMaksim Panchenko return Type == ELF::R_X86_64_GOTPCRELX || Type == ELF::R_X86_64_REX_GOTPCRELX; 569*18176426SMaksim Panchenko } 570*18176426SMaksim Panchenko 571729d29e1SVladislav Khmelevsky bool Relocation::isNone(uint64_t Type) { return Type == getNone(); } 572a34c753fSRafael Auler 573a34c753fSRafael Auler bool Relocation::isRelative(uint64_t Type) { 574a34c753fSRafael Auler if (Arch == Triple::aarch64) 575a34c753fSRafael Auler return Type == ELF::R_AARCH64_RELATIVE; 576a34c753fSRafael Auler return Type == ELF::R_X86_64_RELATIVE; 577a34c753fSRafael Auler } 578a34c753fSRafael Auler 579a34c753fSRafael Auler bool Relocation::isIRelative(uint64_t Type) { 580a34c753fSRafael Auler if (Arch == Triple::aarch64) 581a34c753fSRafael Auler return Type == ELF::R_AARCH64_IRELATIVE; 582a34c753fSRafael Auler return Type == ELF::R_X86_64_IRELATIVE; 583a34c753fSRafael Auler } 584a34c753fSRafael Auler 585a34c753fSRafael Auler bool Relocation::isTLS(uint64_t Type) { 586a34c753fSRafael Auler if (Arch == Triple::aarch64) 587a34c753fSRafael Auler return isTLSAArch64(Type); 588a34c753fSRafael Auler return isTLSX86(Type); 589a34c753fSRafael Auler } 590a34c753fSRafael Auler 591729d29e1SVladislav Khmelevsky uint64_t Relocation::getNone() { 592a34c753fSRafael Auler if (Arch == Triple::aarch64) 593729d29e1SVladislav Khmelevsky return ELF::R_AARCH64_NONE; 594729d29e1SVladislav Khmelevsky return ELF::R_X86_64_NONE; 595a34c753fSRafael Auler } 596a34c753fSRafael Auler 597a34c753fSRafael Auler uint64_t Relocation::getPC32() { 598a34c753fSRafael Auler if (Arch == Triple::aarch64) 599a34c753fSRafael Auler return ELF::R_AARCH64_PREL32; 600a34c753fSRafael Auler return ELF::R_X86_64_PC32; 601a34c753fSRafael Auler } 602a34c753fSRafael Auler 603a34c753fSRafael Auler uint64_t Relocation::getPC64() { 604a34c753fSRafael Auler if (Arch == Triple::aarch64) 605a34c753fSRafael Auler return ELF::R_AARCH64_PREL64; 606a34c753fSRafael Auler return ELF::R_X86_64_PC64; 607a34c753fSRafael Auler } 608a34c753fSRafael Auler 609729d29e1SVladislav Khmelevsky bool Relocation::isPCRelative(uint64_t Type) { 610729d29e1SVladislav Khmelevsky if (Arch == Triple::aarch64) 611729d29e1SVladislav Khmelevsky return isPCRelativeAArch64(Type); 612729d29e1SVladislav Khmelevsky return isPCRelativeX86(Type); 613729d29e1SVladislav Khmelevsky } 614729d29e1SVladislav Khmelevsky 615a34c753fSRafael Auler size_t Relocation::emit(MCStreamer *Streamer) const { 616a34c753fSRafael Auler const size_t Size = getSizeForType(Type); 617a34c753fSRafael Auler MCContext &Ctx = Streamer->getContext(); 618a34c753fSRafael Auler if (isPCRelative(Type)) { 619a34c753fSRafael Auler MCSymbol *TempLabel = Ctx.createNamedTempSymbol(); 620a34c753fSRafael Auler Streamer->emitLabel(TempLabel); 621a34c753fSRafael Auler const MCExpr *Value = nullptr; 622a34c753fSRafael Auler if (Symbol) { 623a34c753fSRafael Auler Value = MCSymbolRefExpr::create(Symbol, Ctx); 624a34c753fSRafael Auler if (Addend) { 62540c2e0faSMaksim Panchenko Value = MCBinaryExpr::createAdd( 62640c2e0faSMaksim Panchenko Value, MCConstantExpr::create(Addend, Ctx), Ctx); 627a34c753fSRafael Auler } 628a34c753fSRafael Auler } else { 629a34c753fSRafael Auler Value = MCConstantExpr::create(Addend, Ctx); 630a34c753fSRafael Auler } 63140c2e0faSMaksim Panchenko Value = MCBinaryExpr::createSub( 63240c2e0faSMaksim Panchenko Value, MCSymbolRefExpr::create(TempLabel, Ctx), Ctx); 633a34c753fSRafael Auler Streamer->emitValue(Value, Size); 634a34c753fSRafael Auler 635a34c753fSRafael Auler return Size; 636a34c753fSRafael Auler } 637a34c753fSRafael Auler 638a34c753fSRafael Auler if (Symbol && Addend) { 63940c2e0faSMaksim Panchenko auto Value = 64040c2e0faSMaksim Panchenko MCBinaryExpr::createAdd(MCSymbolRefExpr::create(Symbol, Ctx), 64140c2e0faSMaksim Panchenko MCConstantExpr::create(Addend, Ctx), Ctx); 642a34c753fSRafael Auler Streamer->emitValue(Value, Size); 643a34c753fSRafael Auler } else if (Symbol) { 644a34c753fSRafael Auler Streamer->emitSymbolValue(Symbol, Size); 645a34c753fSRafael Auler } else { 646a34c753fSRafael Auler Streamer->emitIntValue(Addend, Size); 647a34c753fSRafael Auler } 648a34c753fSRafael Auler 649a34c753fSRafael Auler return Size; 650a34c753fSRafael Auler } 651a34c753fSRafael Auler 652a34c753fSRafael Auler #define ELF_RELOC(name, value) #name, 653a34c753fSRafael Auler 654a34c753fSRafael Auler void Relocation::print(raw_ostream &OS) const { 655a34c753fSRafael Auler static const char *X86RelocNames[] = { 656a34c753fSRafael Auler #include "llvm/BinaryFormat/ELFRelocs/x86_64.def" 657a34c753fSRafael Auler }; 658a34c753fSRafael Auler static const char *AArch64RelocNames[] = { 659a34c753fSRafael Auler #include "llvm/BinaryFormat/ELFRelocs/AArch64.def" 660a34c753fSRafael Auler }; 661a34c753fSRafael Auler if (Arch == Triple::aarch64) 662a34c753fSRafael Auler OS << AArch64RelocNames[Type]; 663a34c753fSRafael Auler else 664a34c753fSRafael Auler OS << X86RelocNames[Type]; 665a34c753fSRafael Auler OS << ", 0x" << Twine::utohexstr(Offset); 666a34c753fSRafael Auler if (Symbol) { 667a34c753fSRafael Auler OS << ", " << Symbol->getName(); 668a34c753fSRafael Auler } 669a34c753fSRafael Auler if (int64_t(Addend) < 0) 670a34c753fSRafael Auler OS << ", -0x" << Twine::utohexstr(-int64_t(Addend)); 671a34c753fSRafael Auler else 672a34c753fSRafael Auler OS << ", 0x" << Twine::utohexstr(Addend); 673a34c753fSRafael Auler OS << ", 0x" << Twine::utohexstr(Value); 674a34c753fSRafael Auler } 675