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