xref: /llvm-project/bolt/lib/Core/Relocation.cpp (revision 1817642684c8d7fbe197d27b34df097d4223c23e)
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