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