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