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