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