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