xref: /llvm-project/bolt/lib/Core/Relocation.cpp (revision b0d1f87b5943b695be44e7ae186a28e263143a6b)
1 //===- bolt/Core/Relocation.cpp - Object file relocations -----------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file implements the Relocation class.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "bolt/Core/Relocation.h"
14 #include "llvm/MC/MCContext.h"
15 #include "llvm/MC/MCExpr.h"
16 #include "llvm/MC/MCStreamer.h"
17 #include "llvm/MC/MCSymbol.h"
18 #include "llvm/Object/ELF.h"
19 
20 using namespace llvm;
21 using namespace bolt;
22 
23 Triple::ArchType Relocation::Arch;
24 
25 static bool isSupportedX86(uint64_t Type) {
26   switch (Type) {
27   default:
28     return false;
29   case ELF::R_X86_64_8:
30   case ELF::R_X86_64_16:
31   case ELF::R_X86_64_32:
32   case ELF::R_X86_64_32S:
33   case ELF::R_X86_64_64:
34   case ELF::R_X86_64_PC8:
35   case ELF::R_X86_64_PC32:
36   case ELF::R_X86_64_PC64:
37   case ELF::R_X86_64_PLT32:
38   case ELF::R_X86_64_GOTPCREL:
39   case ELF::R_X86_64_GOTTPOFF:
40   case ELF::R_X86_64_TPOFF32:
41   case ELF::R_X86_64_GOTPCRELX:
42   case ELF::R_X86_64_REX_GOTPCRELX:
43     return true;
44   }
45 }
46 
47 static bool isSupportedAArch64(uint64_t Type) {
48   switch (Type) {
49   default:
50     return false;
51   case ELF::R_AARCH64_CALL26:
52   case ELF::R_AARCH64_JUMP26:
53   case ELF::R_AARCH64_TSTBR14:
54   case ELF::R_AARCH64_CONDBR19:
55   case ELF::R_AARCH64_ADR_PREL_LO21:
56   case ELF::R_AARCH64_ADR_PREL_PG_HI21:
57   case ELF::R_AARCH64_ADR_PREL_PG_HI21_NC:
58   case ELF::R_AARCH64_LDST64_ABS_LO12_NC:
59   case ELF::R_AARCH64_ADD_ABS_LO12_NC:
60   case ELF::R_AARCH64_LDST128_ABS_LO12_NC:
61   case ELF::R_AARCH64_LDST32_ABS_LO12_NC:
62   case ELF::R_AARCH64_LDST16_ABS_LO12_NC:
63   case ELF::R_AARCH64_LDST8_ABS_LO12_NC:
64   case ELF::R_AARCH64_ADR_GOT_PAGE:
65   case ELF::R_AARCH64_TLSDESC_ADR_PREL21:
66   case ELF::R_AARCH64_TLSDESC_ADR_PAGE21:
67   case ELF::R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:
68   case ELF::R_AARCH64_TLSLE_ADD_TPREL_HI12:
69   case ELF::R_AARCH64_TLSLE_ADD_TPREL_LO12_NC:
70   case ELF::R_AARCH64_LD64_GOT_LO12_NC:
71   case ELF::R_AARCH64_TLSDESC_LD64_LO12:
72   case ELF::R_AARCH64_TLSDESC_ADD_LO12:
73   case ELF::R_AARCH64_TLSDESC_CALL:
74   case ELF::R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
75   case ELF::R_AARCH64_PREL16:
76   case ELF::R_AARCH64_PREL32:
77   case ELF::R_AARCH64_PREL64:
78   case ELF::R_AARCH64_ABS16:
79   case ELF::R_AARCH64_ABS32:
80   case ELF::R_AARCH64_ABS64:
81   case ELF::R_AARCH64_MOVW_UABS_G0:
82   case ELF::R_AARCH64_MOVW_UABS_G0_NC:
83   case ELF::R_AARCH64_MOVW_UABS_G1:
84   case ELF::R_AARCH64_MOVW_UABS_G1_NC:
85   case ELF::R_AARCH64_MOVW_UABS_G2:
86   case ELF::R_AARCH64_MOVW_UABS_G2_NC:
87   case ELF::R_AARCH64_MOVW_UABS_G3:
88     return true;
89   }
90 }
91 
92 static size_t getSizeForTypeX86(uint64_t Type) {
93   switch (Type) {
94   default:
95     errs() << object::getELFRelocationTypeName(ELF::EM_X86_64, Type) << '\n';
96     llvm_unreachable("unsupported relocation type");
97   case ELF::R_X86_64_8:
98   case ELF::R_X86_64_PC8:
99     return 1;
100   case ELF::R_X86_64_16:
101     return 2;
102   case ELF::R_X86_64_PLT32:
103   case ELF::R_X86_64_PC32:
104   case ELF::R_X86_64_32S:
105   case ELF::R_X86_64_32:
106   case ELF::R_X86_64_GOTPCREL:
107   case ELF::R_X86_64_GOTTPOFF:
108   case ELF::R_X86_64_TPOFF32:
109   case ELF::R_X86_64_GOTPCRELX:
110   case ELF::R_X86_64_REX_GOTPCRELX:
111     return 4;
112   case ELF::R_X86_64_PC64:
113   case ELF::R_X86_64_64:
114     return 8;
115   }
116 }
117 
118 static size_t getSizeForTypeAArch64(uint64_t Type) {
119   switch (Type) {
120   default:
121     errs() << object::getELFRelocationTypeName(ELF::EM_AARCH64, Type) << '\n';
122     llvm_unreachable("unsupported relocation type");
123   case ELF::R_AARCH64_ABS16:
124   case ELF::R_AARCH64_PREL16:
125     return 2;
126   case ELF::R_AARCH64_CALL26:
127   case ELF::R_AARCH64_JUMP26:
128   case ELF::R_AARCH64_TSTBR14:
129   case ELF::R_AARCH64_CONDBR19:
130   case ELF::R_AARCH64_ADR_PREL_LO21:
131   case ELF::R_AARCH64_ADR_PREL_PG_HI21:
132   case ELF::R_AARCH64_ADR_PREL_PG_HI21_NC:
133   case ELF::R_AARCH64_LDST64_ABS_LO12_NC:
134   case ELF::R_AARCH64_ADD_ABS_LO12_NC:
135   case ELF::R_AARCH64_LDST128_ABS_LO12_NC:
136   case ELF::R_AARCH64_LDST32_ABS_LO12_NC:
137   case ELF::R_AARCH64_LDST16_ABS_LO12_NC:
138   case ELF::R_AARCH64_LDST8_ABS_LO12_NC:
139   case ELF::R_AARCH64_ADR_GOT_PAGE:
140   case ELF::R_AARCH64_TLSDESC_ADR_PREL21:
141   case ELF::R_AARCH64_TLSDESC_ADR_PAGE21:
142   case ELF::R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:
143   case ELF::R_AARCH64_TLSLE_ADD_TPREL_HI12:
144   case ELF::R_AARCH64_TLSLE_ADD_TPREL_LO12_NC:
145   case ELF::R_AARCH64_LD64_GOT_LO12_NC:
146   case ELF::R_AARCH64_TLSDESC_LD64_LO12:
147   case ELF::R_AARCH64_TLSDESC_ADD_LO12:
148   case ELF::R_AARCH64_TLSDESC_CALL:
149   case ELF::R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
150   case ELF::R_AARCH64_PREL32:
151   case ELF::R_AARCH64_MOVW_UABS_G0:
152   case ELF::R_AARCH64_MOVW_UABS_G0_NC:
153   case ELF::R_AARCH64_MOVW_UABS_G1:
154   case ELF::R_AARCH64_MOVW_UABS_G1_NC:
155   case ELF::R_AARCH64_MOVW_UABS_G2:
156   case ELF::R_AARCH64_MOVW_UABS_G2_NC:
157   case ELF::R_AARCH64_MOVW_UABS_G3:
158   case ELF::R_AARCH64_ABS32:
159     return 4;
160   case ELF::R_AARCH64_ABS64:
161   case ELF::R_AARCH64_PREL64:
162     return 8;
163   }
164 }
165 
166 static bool skipRelocationTypeX86(uint64_t Type) {
167   return Type == ELF::R_X86_64_NONE;
168 }
169 
170 static bool skipRelocationTypeAArch64(uint64_t Type) {
171   return Type == ELF::R_AARCH64_NONE || Type == ELF::R_AARCH64_LD_PREL_LO19;
172 }
173 
174 static bool skipRelocationProcessX86(uint64_t &Type, uint64_t Contents) {
175   return false;
176 }
177 
178 static bool skipRelocationProcessAArch64(uint64_t &Type, uint64_t Contents) {
179   auto IsMov = [](uint64_t Contents) -> bool {
180     // The bits 28-23 are 0b100101
181     return (Contents & 0x1f800000) == 0x12800000;
182   };
183 
184   auto IsB = [](uint64_t Contents) -> bool {
185     // The bits 31-26 are 0b000101
186     return (Contents & 0xfc000000) == 0x14000000;
187   };
188 
189   auto IsAdr = [](uint64_t Contents) -> bool {
190     // The bits 31-24 are 0b0xx10000
191     return (Contents & 0x9f000000) == 0x10000000;
192   };
193 
194   auto IsAddImm = [](uint64_t Contents) -> bool {
195     // The bits 30-23 are 0b00100010
196     return (Contents & 0x7F800000) == 0x11000000;
197   };
198 
199   auto IsNop = [](uint64_t Contents) -> bool { return Contents == 0xd503201f; };
200 
201   // The linker might eliminate the instruction and replace it with NOP, ignore
202   if (IsNop(Contents))
203     return true;
204 
205   // The linker might relax ADRP+LDR instruction sequence for loading symbol
206   // address from GOT table to ADRP+ADD sequence that would point to the
207   // binary-local symbol. Change relocation type in order to process it right.
208   if (Type == ELF::R_AARCH64_LD64_GOT_LO12_NC && IsAddImm(Contents)) {
209     Type = ELF::R_AARCH64_ADD_ABS_LO12_NC;
210     return false;
211   }
212 
213   // The linker might perform TLS relocations relaxations, such as
214   // changed TLS access model (e.g. changed global dynamic model
215   // to initial exec), thus changing the instructions. The static
216   // relocations might be invalid at this point and we might no
217   // need to proccess these relocations anymore.
218   // More information could be found by searching
219   // elfNN_aarch64_tls_relax in bfd
220   switch (Type) {
221   default:
222     break;
223   case ELF::R_AARCH64_TLSDESC_LD64_LO12:
224   case ELF::R_AARCH64_TLSDESC_ADR_PAGE21:
225   case ELF::R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:
226   case ELF::R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21: {
227     if (IsMov(Contents))
228       return true;
229   }
230   }
231 
232   // The linker might replace load/store instruction with jump and
233   // veneer due to errata 843419
234   // https://documentation-service.arm.com/static/5fa29fddb209f547eebd361d
235   // Thus load/store relocations for these instructions must be ignored
236   // NOTE: We only process GOT and TLS relocations this way since the
237   // addend used in load/store instructions won't change after bolt
238   // (it is important since the instruction in veneer won't have relocation)
239   switch (Type) {
240   default:
241     break;
242   case ELF::R_AARCH64_LD64_GOT_LO12_NC:
243   case ELF::R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:
244   case ELF::R_AARCH64_TLSDESC_LD64_LO12: {
245     if (IsB(Contents))
246       return true;
247   }
248   }
249 
250   // The linker might relax ADRP+ADD or ADRP+LDR sequences to the ADR+NOP
251   switch (Type) {
252   default:
253     break;
254   case ELF::R_AARCH64_ADR_PREL_PG_HI21:
255   case ELF::R_AARCH64_ADD_ABS_LO12_NC:
256   case ELF::R_AARCH64_ADR_GOT_PAGE:
257   case ELF::R_AARCH64_LD64_GOT_LO12_NC:
258     if (IsAdr(Contents))
259       return true;
260   }
261 
262   return false;
263 }
264 
265 static uint64_t adjustValueX86(uint64_t Type, uint64_t Value, uint64_t PC) {
266   switch (Type) {
267   default:
268     llvm_unreachable("not supported relocation");
269   case ELF::R_X86_64_32:
270     break;
271   case ELF::R_X86_64_PC32:
272     Value -= PC;
273     break;
274   }
275   return Value;
276 }
277 
278 static uint64_t adjustValueAArch64(uint64_t Type, uint64_t Value, uint64_t PC) {
279   switch (Type) {
280   default:
281     llvm_unreachable("not supported relocation");
282   case ELF::R_AARCH64_ABS32:
283     break;
284   case ELF::R_AARCH64_PREL16:
285   case ELF::R_AARCH64_PREL32:
286   case ELF::R_AARCH64_PREL64:
287     Value -= PC;
288     break;
289   }
290   return Value;
291 }
292 
293 static uint64_t extractValueX86(uint64_t Type, uint64_t Contents, uint64_t PC) {
294   if (Type == ELF::R_X86_64_32S)
295     return SignExtend64<32>(Contents);
296   if (Relocation::isPCRelative(Type))
297     return SignExtend64(Contents, 8 * Relocation::getSizeForType(Type));
298   return Contents;
299 }
300 
301 static uint64_t extractValueAArch64(uint64_t Type, uint64_t Contents,
302                                     uint64_t PC) {
303   switch (Type) {
304   default:
305     errs() << object::getELFRelocationTypeName(ELF::EM_AARCH64, Type) << '\n';
306     llvm_unreachable("unsupported relocation type");
307   case ELF::R_AARCH64_ABS16:
308   case ELF::R_AARCH64_ABS32:
309   case ELF::R_AARCH64_ABS64:
310     return Contents;
311   case ELF::R_AARCH64_PREL16:
312     return static_cast<int64_t>(PC) + SignExtend64<16>(Contents & 0xffff);
313   case ELF::R_AARCH64_PREL32:
314     return static_cast<int64_t>(PC) + SignExtend64<32>(Contents & 0xffffffff);
315   case ELF::R_AARCH64_PREL64:
316     return static_cast<int64_t>(PC) + Contents;
317   case ELF::R_AARCH64_TLSDESC_CALL:
318   case ELF::R_AARCH64_JUMP26:
319   case ELF::R_AARCH64_CALL26:
320     // Immediate goes in bits 25:0 of B and BL.
321     Contents &= ~0xfffffffffc000000ULL;
322     return static_cast<int64_t>(PC) + SignExtend64<28>(Contents << 2);
323   case ELF::R_AARCH64_TSTBR14:
324     // Immediate:15:2 goes in bits 18:5 of TBZ, TBNZ
325     Contents &= ~0xfffffffffff8001fULL;
326     return static_cast<int64_t>(PC) + SignExtend64<16>(Contents >> 3);
327   case ELF::R_AARCH64_CONDBR19:
328     // Immediate:20:2 goes in bits 23:5 of Bcc, CBZ, CBNZ
329     Contents &= ~0xffffffffff00001fULL;
330     return static_cast<int64_t>(PC) + SignExtend64<21>(Contents >> 3);
331   case ELF::R_AARCH64_ADR_GOT_PAGE:
332   case ELF::R_AARCH64_TLSDESC_ADR_PREL21:
333   case ELF::R_AARCH64_TLSDESC_ADR_PAGE21:
334   case ELF::R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
335   case ELF::R_AARCH64_ADR_PREL_LO21:
336   case ELF::R_AARCH64_ADR_PREL_PG_HI21:
337   case ELF::R_AARCH64_ADR_PREL_PG_HI21_NC: {
338     // Bits 32:12 of Symbol address goes in bits 30:29 + 23:5 of ADRP
339     // and ADR instructions
340     bool IsAdr = !!(((Contents >> 31) & 0x1) == 0);
341     Contents &= ~0xffffffff9f00001fUll;
342     uint64_t LowBits = (Contents >> 29) & 0x3;
343     uint64_t HighBits = (Contents >> 5) & 0x7ffff;
344     Contents = LowBits | (HighBits << 2);
345     if (IsAdr)
346       return static_cast<int64_t>(PC) + SignExtend64<21>(Contents);
347 
348     // ADRP instruction
349     Contents = static_cast<int64_t>(PC) + SignExtend64<33>(Contents << 12);
350     Contents &= ~0xfffUll;
351     return Contents;
352   }
353   case ELF::R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:
354   case ELF::R_AARCH64_TLSDESC_LD64_LO12:
355   case ELF::R_AARCH64_LD64_GOT_LO12_NC:
356   case ELF::R_AARCH64_LDST64_ABS_LO12_NC: {
357     // Immediate goes in bits 21:10 of LD/ST instruction, taken
358     // from bits 11:3 of Symbol address
359     Contents &= ~0xffffffffffc003ffU;
360     return Contents >> (10 - 3);
361   }
362   case ELF::R_AARCH64_TLSLE_ADD_TPREL_HI12:
363   case ELF::R_AARCH64_TLSLE_ADD_TPREL_LO12_NC:
364   case ELF::R_AARCH64_TLSDESC_ADD_LO12:
365   case ELF::R_AARCH64_ADD_ABS_LO12_NC: {
366     // Immediate goes in bits 21:10 of ADD instruction
367     Contents &= ~0xffffffffffc003ffU;
368     return Contents >> (10 - 0);
369   }
370   case ELF::R_AARCH64_LDST128_ABS_LO12_NC: {
371     // Immediate goes in bits 21:10 of ADD instruction, taken
372     // from bits 11:4 of Symbol address
373     Contents &= ~0xffffffffffc003ffU;
374     return Contents >> (10 - 4);
375   }
376   case ELF::R_AARCH64_LDST32_ABS_LO12_NC: {
377     // Immediate goes in bits 21:10 of ADD instruction, taken
378     // from bits 11:2 of Symbol address
379     Contents &= ~0xffffffffffc003ffU;
380     return Contents >> (10 - 2);
381   }
382   case ELF::R_AARCH64_LDST16_ABS_LO12_NC: {
383     // Immediate goes in bits 21:10 of ADD instruction, taken
384     // from bits 11:1 of Symbol address
385     Contents &= ~0xffffffffffc003ffU;
386     return Contents >> (10 - 1);
387   }
388   case ELF::R_AARCH64_LDST8_ABS_LO12_NC: {
389     // Immediate goes in bits 21:10 of ADD instruction, taken
390     // from bits 11:0 of Symbol address
391     Contents &= ~0xffffffffffc003ffU;
392     return Contents >> (10 - 0);
393   }
394   case ELF::R_AARCH64_MOVW_UABS_G3:
395   case ELF::R_AARCH64_MOVW_UABS_G2_NC:
396   case ELF::R_AARCH64_MOVW_UABS_G2:
397   case ELF::R_AARCH64_MOVW_UABS_G1_NC:
398   case ELF::R_AARCH64_MOVW_UABS_G1:
399   case ELF::R_AARCH64_MOVW_UABS_G0_NC:
400   case ELF::R_AARCH64_MOVW_UABS_G0:
401     // The shift goest in bits 22:21 of MOV* instructions
402     uint8_t Shift = (Contents >> 21) & 0x3;
403     // Immediate goes in bits 20:5
404     Contents = (Contents >> 5) & 0xffff;
405     return Contents << (16 * Shift);
406   }
407 }
408 
409 static bool isGOTX86(uint64_t Type) {
410   switch (Type) {
411   default:
412     return false;
413   case ELF::R_X86_64_GOT32:
414   case ELF::R_X86_64_GOTPCREL:
415   case ELF::R_X86_64_GOTTPOFF:
416   case ELF::R_X86_64_GOTOFF64:
417   case ELF::R_X86_64_GOTPC32:
418   case ELF::R_X86_64_GOT64:
419   case ELF::R_X86_64_GOTPCREL64:
420   case ELF::R_X86_64_GOTPC64:
421   case ELF::R_X86_64_GOTPLT64:
422   case ELF::R_X86_64_GOTPC32_TLSDESC:
423   case ELF::R_X86_64_GOTPCRELX:
424   case ELF::R_X86_64_REX_GOTPCRELX:
425     return true;
426   }
427 }
428 
429 static bool isGOTAArch64(uint64_t Type) {
430   switch (Type) {
431   default:
432     return false;
433   case ELF::R_AARCH64_ADR_GOT_PAGE:
434   case ELF::R_AARCH64_LD64_GOT_LO12_NC:
435   case ELF::R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:
436   case ELF::R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
437   case ELF::R_AARCH64_TLSDESC_ADR_PREL21:
438   case ELF::R_AARCH64_TLSDESC_ADR_PAGE21:
439   case ELF::R_AARCH64_TLSDESC_LD64_LO12:
440   case ELF::R_AARCH64_TLSDESC_ADD_LO12:
441   case ELF::R_AARCH64_TLSDESC_CALL:
442     return true;
443   }
444 }
445 
446 static bool isTLSX86(uint64_t Type) {
447   switch (Type) {
448   default:
449     return false;
450   case ELF::R_X86_64_TPOFF32:
451   case ELF::R_X86_64_TPOFF64:
452   case ELF::R_X86_64_GOTTPOFF:
453     return true;
454   }
455 }
456 
457 static bool isTLSAArch64(uint64_t Type) {
458   switch (Type) {
459   default:
460     return false;
461   case ELF::R_AARCH64_TLSDESC_ADR_PREL21:
462   case ELF::R_AARCH64_TLSDESC_ADR_PAGE21:
463   case ELF::R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:
464   case ELF::R_AARCH64_TLSLE_ADD_TPREL_HI12:
465   case ELF::R_AARCH64_TLSLE_ADD_TPREL_LO12_NC:
466   case ELF::R_AARCH64_TLSDESC_LD64_LO12:
467   case ELF::R_AARCH64_TLSDESC_ADD_LO12:
468   case ELF::R_AARCH64_TLSDESC_CALL:
469   case ELF::R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
470     return true;
471   }
472 }
473 
474 static bool isPCRelativeX86(uint64_t Type) {
475   switch (Type) {
476   default:
477     llvm_unreachable("Unknown relocation type");
478   case ELF::R_X86_64_64:
479   case ELF::R_X86_64_32:
480   case ELF::R_X86_64_32S:
481   case ELF::R_X86_64_16:
482   case ELF::R_X86_64_8:
483   case ELF::R_X86_64_TPOFF32:
484     return false;
485   case ELF::R_X86_64_PC8:
486   case ELF::R_X86_64_PC32:
487   case ELF::R_X86_64_PC64:
488   case ELF::R_X86_64_GOTPCREL:
489   case ELF::R_X86_64_PLT32:
490   case ELF::R_X86_64_GOTOFF64:
491   case ELF::R_X86_64_GOTPC32:
492   case ELF::R_X86_64_GOTTPOFF:
493   case ELF::R_X86_64_GOTPCRELX:
494   case ELF::R_X86_64_REX_GOTPCRELX:
495     return true;
496   }
497 }
498 
499 static bool isPCRelativeAArch64(uint64_t Type) {
500   switch (Type) {
501   default:
502     llvm_unreachable("Unknown relocation type");
503   case ELF::R_AARCH64_ABS16:
504   case ELF::R_AARCH64_ABS32:
505   case ELF::R_AARCH64_ABS64:
506   case ELF::R_AARCH64_LDST64_ABS_LO12_NC:
507   case ELF::R_AARCH64_ADD_ABS_LO12_NC:
508   case ELF::R_AARCH64_LDST128_ABS_LO12_NC:
509   case ELF::R_AARCH64_LDST32_ABS_LO12_NC:
510   case ELF::R_AARCH64_LDST16_ABS_LO12_NC:
511   case ELF::R_AARCH64_LDST8_ABS_LO12_NC:
512   case ELF::R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:
513   case ELF::R_AARCH64_TLSLE_ADD_TPREL_HI12:
514   case ELF::R_AARCH64_TLSLE_ADD_TPREL_LO12_NC:
515   case ELF::R_AARCH64_LD64_GOT_LO12_NC:
516   case ELF::R_AARCH64_TLSDESC_LD64_LO12:
517   case ELF::R_AARCH64_TLSDESC_ADD_LO12:
518   case ELF::R_AARCH64_MOVW_UABS_G0:
519   case ELF::R_AARCH64_MOVW_UABS_G0_NC:
520   case ELF::R_AARCH64_MOVW_UABS_G1:
521   case ELF::R_AARCH64_MOVW_UABS_G1_NC:
522   case ELF::R_AARCH64_MOVW_UABS_G2:
523   case ELF::R_AARCH64_MOVW_UABS_G2_NC:
524   case ELF::R_AARCH64_MOVW_UABS_G3:
525     return false;
526   case ELF::R_AARCH64_TLSDESC_CALL:
527   case ELF::R_AARCH64_CALL26:
528   case ELF::R_AARCH64_JUMP26:
529   case ELF::R_AARCH64_TSTBR14:
530   case ELF::R_AARCH64_CONDBR19:
531   case ELF::R_AARCH64_ADR_PREL_LO21:
532   case ELF::R_AARCH64_ADR_PREL_PG_HI21:
533   case ELF::R_AARCH64_ADR_PREL_PG_HI21_NC:
534   case ELF::R_AARCH64_ADR_GOT_PAGE:
535   case ELF::R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
536   case ELF::R_AARCH64_TLSDESC_ADR_PREL21:
537   case ELF::R_AARCH64_TLSDESC_ADR_PAGE21:
538   case ELF::R_AARCH64_PREL16:
539   case ELF::R_AARCH64_PREL32:
540   case ELF::R_AARCH64_PREL64:
541     return true;
542   }
543 }
544 
545 bool Relocation::isSupported(uint64_t Type) {
546   if (Arch == Triple::aarch64)
547     return isSupportedAArch64(Type);
548   return isSupportedX86(Type);
549 }
550 
551 size_t Relocation::getSizeForType(uint64_t Type) {
552   if (Arch == Triple::aarch64)
553     return getSizeForTypeAArch64(Type);
554   return getSizeForTypeX86(Type);
555 }
556 
557 bool Relocation::skipRelocationType(uint64_t Type) {
558   if (Arch == Triple::aarch64)
559     return skipRelocationTypeAArch64(Type);
560   return skipRelocationTypeX86(Type);
561 }
562 
563 bool Relocation::skipRelocationProcess(uint64_t &Type, uint64_t Contents) {
564   if (Arch == Triple::aarch64)
565     return skipRelocationProcessAArch64(Type, Contents);
566   return skipRelocationProcessX86(Type, Contents);
567 }
568 
569 uint64_t Relocation::adjustValue(uint64_t Type, uint64_t Value,
570                                  uint64_t PC) {
571   if (Arch == Triple::aarch64)
572     return adjustValueAArch64(Type, Value, PC);
573   return adjustValueX86(Type, Value, PC);
574 }
575 
576 uint64_t Relocation::extractValue(uint64_t Type, uint64_t Contents,
577                                   uint64_t PC) {
578   if (Arch == Triple::aarch64)
579     return extractValueAArch64(Type, Contents, PC);
580   return extractValueX86(Type, Contents, PC);
581 }
582 
583 bool Relocation::isGOT(uint64_t Type) {
584   if (Arch == Triple::aarch64)
585     return isGOTAArch64(Type);
586   return isGOTX86(Type);
587 }
588 
589 bool Relocation::isX86GOTPCRELX(uint64_t Type) {
590   if (Arch != Triple::x86_64)
591     return false;
592   return Type == ELF::R_X86_64_GOTPCRELX || Type == ELF::R_X86_64_REX_GOTPCRELX;
593 }
594 
595 bool Relocation::isNone(uint64_t Type) { return Type == getNone(); }
596 
597 bool Relocation::isRelative(uint64_t Type) {
598   if (Arch == Triple::aarch64)
599     return Type == ELF::R_AARCH64_RELATIVE;
600   return Type == ELF::R_X86_64_RELATIVE;
601 }
602 
603 bool Relocation::isIRelative(uint64_t Type) {
604   if (Arch == Triple::aarch64)
605     return Type == ELF::R_AARCH64_IRELATIVE;
606   return Type == ELF::R_X86_64_IRELATIVE;
607 }
608 
609 bool Relocation::isTLS(uint64_t Type) {
610   if (Arch == Triple::aarch64)
611     return isTLSAArch64(Type);
612   return isTLSX86(Type);
613 }
614 
615 uint64_t Relocation::getNone() {
616   if (Arch == Triple::aarch64)
617     return ELF::R_AARCH64_NONE;
618   return ELF::R_X86_64_NONE;
619 }
620 
621 uint64_t Relocation::getPC32() {
622   if (Arch == Triple::aarch64)
623     return ELF::R_AARCH64_PREL32;
624   return ELF::R_X86_64_PC32;
625 }
626 
627 uint64_t Relocation::getPC64() {
628   if (Arch == Triple::aarch64)
629     return ELF::R_AARCH64_PREL64;
630   return ELF::R_X86_64_PC64;
631 }
632 
633 bool Relocation::isPCRelative(uint64_t Type) {
634   if (Arch == Triple::aarch64)
635     return isPCRelativeAArch64(Type);
636   return isPCRelativeX86(Type);
637 }
638 
639 uint64_t Relocation::getAbs64() {
640   if (Arch == Triple::aarch64)
641     return ELF::R_AARCH64_ABS64;
642   return ELF::R_X86_64_64;
643 }
644 
645 size_t Relocation::emit(MCStreamer *Streamer) const {
646   const size_t Size = getSizeForType(Type);
647   MCContext &Ctx = Streamer->getContext();
648   if (isPCRelative(Type)) {
649     MCSymbol *TempLabel = Ctx.createNamedTempSymbol();
650     Streamer->emitLabel(TempLabel);
651     const MCExpr *Value = nullptr;
652     if (Symbol) {
653       Value = MCSymbolRefExpr::create(Symbol, Ctx);
654       if (Addend) {
655         Value = MCBinaryExpr::createAdd(
656             Value, MCConstantExpr::create(Addend, Ctx), Ctx);
657       }
658     } else {
659       Value = MCConstantExpr::create(Addend, Ctx);
660     }
661     Value = MCBinaryExpr::createSub(
662         Value, MCSymbolRefExpr::create(TempLabel, Ctx), Ctx);
663     Streamer->emitValue(Value, Size);
664 
665     return Size;
666   }
667 
668   if (Symbol && Addend) {
669     auto Value =
670         MCBinaryExpr::createAdd(MCSymbolRefExpr::create(Symbol, Ctx),
671                                 MCConstantExpr::create(Addend, Ctx), Ctx);
672     Streamer->emitValue(Value, Size);
673   } else if (Symbol) {
674     Streamer->emitSymbolValue(Symbol, Size);
675   } else {
676     Streamer->emitIntValue(Addend, Size);
677   }
678 
679   return Size;
680 }
681 
682 #define ELF_RELOC(name, value) #name,
683 
684 void Relocation::print(raw_ostream &OS) const {
685   static const char *X86RelocNames[] = {
686 #include "llvm/BinaryFormat/ELFRelocs/x86_64.def"
687   };
688   static const char *AArch64RelocNames[] = {
689 #include "llvm/BinaryFormat/ELFRelocs/AArch64.def"
690   };
691   if (Arch == Triple::aarch64)
692     OS << AArch64RelocNames[Type];
693   else
694     OS << X86RelocNames[Type];
695   OS << ", 0x" << Twine::utohexstr(Offset);
696   if (Symbol) {
697     OS << ", " << Symbol->getName();
698   }
699   if (int64_t(Addend) < 0)
700     OS << ", -0x" << Twine::utohexstr(-int64_t(Addend));
701   else
702     OS << ", 0x" << Twine::utohexstr(Addend);
703   OS << ", 0x" << Twine::utohexstr(Value);
704 }
705