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