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