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#include "llvm/Object/ObjectFile.h"
20
21using namespace llvm;
22using namespace bolt;
23
24namespace ELFReserved {
25enum {
26 R_RISCV_TPREL_I = 49,
27 R_RISCV_TPREL_S = 50,
28};
29} // namespace ELFReserved
30
31Triple::ArchType Relocation::Arch;
32
33static bool isSupportedX86(uint32_t Type) {
34 switch (Type) {
35 default:
36 return false;
37 case ELF::R_X86_64_8:
38 case ELF::R_X86_64_16:
39 case ELF::R_X86_64_32:
40 case ELF::R_X86_64_32S:
41 case ELF::R_X86_64_64:
42 case ELF::R_X86_64_PC8:
43 case ELF::R_X86_64_PC32:
44 case ELF::R_X86_64_PC64:
45 case ELF::R_X86_64_PLT32:
46 case ELF::R_X86_64_GOTPC64:
47 case ELF::R_X86_64_GOTPCREL:
48 case ELF::R_X86_64_GOTTPOFF:
49 case ELF::R_X86_64_TPOFF32:
50 case ELF::R_X86_64_GOTPCRELX:
51 case ELF::R_X86_64_REX_GOTPCRELX:
52 return true;
53 }
54}
55
56static bool isSupportedAArch64(uint32_t Type) {
57 switch (Type) {
58 default:
59 return false;
60 case ELF::R_AARCH64_CALL26:
61 case ELF::R_AARCH64_JUMP26:
62 case ELF::R_AARCH64_TSTBR14:
63 case ELF::R_AARCH64_CONDBR19:
64 case ELF::R_AARCH64_ADR_PREL_LO21:
65 case ELF::R_AARCH64_ADR_PREL_PG_HI21:
66 case ELF::R_AARCH64_ADR_PREL_PG_HI21_NC:
67 case ELF::R_AARCH64_LDST64_ABS_LO12_NC:
68 case ELF::R_AARCH64_ADD_ABS_LO12_NC:
69 case ELF::R_AARCH64_LDST128_ABS_LO12_NC:
70 case ELF::R_AARCH64_LDST32_ABS_LO12_NC:
71 case ELF::R_AARCH64_LDST16_ABS_LO12_NC:
72 case ELF::R_AARCH64_LDST8_ABS_LO12_NC:
73 case ELF::R_AARCH64_ADR_GOT_PAGE:
74 case ELF::R_AARCH64_TLSDESC_ADR_PREL21:
75 case ELF::R_AARCH64_TLSDESC_ADR_PAGE21:
76 case ELF::R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:
77 case ELF::R_AARCH64_TLSLE_ADD_TPREL_HI12:
78 case ELF::R_AARCH64_TLSLE_ADD_TPREL_LO12_NC:
79 case ELF::R_AARCH64_TLSLE_MOVW_TPREL_G0:
80 case ELF::R_AARCH64_TLSLE_MOVW_TPREL_G0_NC:
81 case ELF::R_AARCH64_LD64_GOT_LO12_NC:
82 case ELF::R_AARCH64_TLSDESC_LD64_LO12:
83 case ELF::R_AARCH64_TLSDESC_ADD_LO12:
84 case ELF::R_AARCH64_TLSDESC_CALL:
85 case ELF::R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
86 case ELF::R_AARCH64_PREL16:
87 case ELF::R_AARCH64_PREL32:
88 case ELF::R_AARCH64_PREL64:
89 case ELF::R_AARCH64_ABS16:
90 case ELF::R_AARCH64_ABS32:
91 case ELF::R_AARCH64_ABS64:
92 case ELF::R_AARCH64_MOVW_UABS_G0:
93 case ELF::R_AARCH64_MOVW_UABS_G0_NC:
94 case ELF::R_AARCH64_MOVW_UABS_G1:
95 case ELF::R_AARCH64_MOVW_UABS_G1_NC:
96 case ELF::R_AARCH64_MOVW_UABS_G2:
97 case ELF::R_AARCH64_MOVW_UABS_G2_NC:
98 case ELF::R_AARCH64_MOVW_UABS_G3:
99 case ELF::R_AARCH64_PLT32:
100 return true;
101 }
102}
103
104static bool isSupportedRISCV(uint32_t Type) {
105 switch (Type) {
106 default:
107 return false;
108 case ELF::R_RISCV_JAL:
109 case ELF::R_RISCV_CALL:
110 case ELF::R_RISCV_CALL_PLT:
111 case ELF::R_RISCV_BRANCH:
112 case ELF::R_RISCV_RELAX:
113 case ELF::R_RISCV_GOT_HI20:
114 case ELF::R_RISCV_PCREL_HI20:
115 case ELF::R_RISCV_PCREL_LO12_I:
116 case ELF::R_RISCV_PCREL_LO12_S:
117 case ELF::R_RISCV_RVC_JUMP:
118 case ELF::R_RISCV_RVC_BRANCH:
119 case ELF::R_RISCV_ADD32:
120 case ELF::R_RISCV_SUB32:
121 case ELF::R_RISCV_HI20:
122 case ELF::R_RISCV_LO12_I:
123 case ELF::R_RISCV_LO12_S:
124 case ELF::R_RISCV_64:
125 case ELF::R_RISCV_TLS_GOT_HI20:
126 case ELF::R_RISCV_TLS_GD_HI20:
127 case ELF::R_RISCV_TPREL_HI20:
128 case ELF::R_RISCV_TPREL_ADD:
129 case ELF::R_RISCV_TPREL_LO12_I:
130 case ELF::R_RISCV_TPREL_LO12_S:
131 case ELFReserved::R_RISCV_TPREL_I:
132 case ELFReserved::R_RISCV_TPREL_S:
133 return true;
134 }
135}
136
137static size_t getSizeForTypeX86(uint32_t Type) {
138 switch (Type) {
139 default:
140 errs() << object::getELFRelocationTypeName(Machine: ELF::EM_X86_64, Type) << '\n';
141 llvm_unreachable("unsupported relocation type");
142 case ELF::R_X86_64_8:
143 case ELF::R_X86_64_PC8:
144 return 1;
145 case ELF::R_X86_64_16:
146 return 2;
147 case ELF::R_X86_64_PLT32:
148 case ELF::R_X86_64_PC32:
149 case ELF::R_X86_64_32S:
150 case ELF::R_X86_64_32:
151 case ELF::R_X86_64_GOTPCREL:
152 case ELF::R_X86_64_GOTTPOFF:
153 case ELF::R_X86_64_TPOFF32:
154 case ELF::R_X86_64_GOTPCRELX:
155 case ELF::R_X86_64_REX_GOTPCRELX:
156 return 4;
157 case ELF::R_X86_64_PC64:
158 case ELF::R_X86_64_64:
159 case ELF::R_X86_64_GOTPC64:
160 return 8;
161 }
162}
163
164static size_t getSizeForTypeAArch64(uint32_t Type) {
165 switch (Type) {
166 default:
167 errs() << object::getELFRelocationTypeName(Machine: ELF::EM_AARCH64, Type) << '\n';
168 llvm_unreachable("unsupported relocation type");
169 case ELF::R_AARCH64_ABS16:
170 case ELF::R_AARCH64_PREL16:
171 return 2;
172 case ELF::R_AARCH64_CALL26:
173 case ELF::R_AARCH64_JUMP26:
174 case ELF::R_AARCH64_TSTBR14:
175 case ELF::R_AARCH64_CONDBR19:
176 case ELF::R_AARCH64_ADR_PREL_LO21:
177 case ELF::R_AARCH64_ADR_PREL_PG_HI21:
178 case ELF::R_AARCH64_ADR_PREL_PG_HI21_NC:
179 case ELF::R_AARCH64_LDST64_ABS_LO12_NC:
180 case ELF::R_AARCH64_ADD_ABS_LO12_NC:
181 case ELF::R_AARCH64_LDST128_ABS_LO12_NC:
182 case ELF::R_AARCH64_LDST32_ABS_LO12_NC:
183 case ELF::R_AARCH64_LDST16_ABS_LO12_NC:
184 case ELF::R_AARCH64_LDST8_ABS_LO12_NC:
185 case ELF::R_AARCH64_ADR_GOT_PAGE:
186 case ELF::R_AARCH64_TLSDESC_ADR_PREL21:
187 case ELF::R_AARCH64_TLSDESC_ADR_PAGE21:
188 case ELF::R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:
189 case ELF::R_AARCH64_TLSLE_ADD_TPREL_HI12:
190 case ELF::R_AARCH64_TLSLE_ADD_TPREL_LO12_NC:
191 case ELF::R_AARCH64_TLSLE_MOVW_TPREL_G0:
192 case ELF::R_AARCH64_TLSLE_MOVW_TPREL_G0_NC:
193 case ELF::R_AARCH64_LD64_GOT_LO12_NC:
194 case ELF::R_AARCH64_TLSDESC_LD64_LO12:
195 case ELF::R_AARCH64_TLSDESC_ADD_LO12:
196 case ELF::R_AARCH64_TLSDESC_CALL:
197 case ELF::R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
198 case ELF::R_AARCH64_PREL32:
199 case ELF::R_AARCH64_MOVW_UABS_G0:
200 case ELF::R_AARCH64_MOVW_UABS_G0_NC:
201 case ELF::R_AARCH64_MOVW_UABS_G1:
202 case ELF::R_AARCH64_MOVW_UABS_G1_NC:
203 case ELF::R_AARCH64_MOVW_UABS_G2:
204 case ELF::R_AARCH64_MOVW_UABS_G2_NC:
205 case ELF::R_AARCH64_MOVW_UABS_G3:
206 case ELF::R_AARCH64_ABS32:
207 case ELF::R_AARCH64_PLT32:
208 return 4;
209 case ELF::R_AARCH64_ABS64:
210 case ELF::R_AARCH64_PREL64:
211 return 8;
212 }
213}
214
215static size_t getSizeForTypeRISCV(uint32_t Type) {
216 switch (Type) {
217 default:
218 errs() << object::getELFRelocationTypeName(Machine: ELF::EM_RISCV, Type) << '\n';
219 llvm_unreachable("unsupported relocation type");
220 case ELF::R_RISCV_RVC_JUMP:
221 case ELF::R_RISCV_RVC_BRANCH:
222 return 2;
223 case ELF::R_RISCV_JAL:
224 case ELF::R_RISCV_BRANCH:
225 case ELF::R_RISCV_PCREL_HI20:
226 case ELF::R_RISCV_PCREL_LO12_I:
227 case ELF::R_RISCV_PCREL_LO12_S:
228 case ELF::R_RISCV_32_PCREL:
229 case ELF::R_RISCV_CALL:
230 case ELF::R_RISCV_CALL_PLT:
231 case ELF::R_RISCV_ADD32:
232 case ELF::R_RISCV_SUB32:
233 case ELF::R_RISCV_HI20:
234 case ELF::R_RISCV_LO12_I:
235 case ELF::R_RISCV_LO12_S:
236 return 4;
237 case ELF::R_RISCV_64:
238 case ELF::R_RISCV_GOT_HI20:
239 case ELF::R_RISCV_TLS_GOT_HI20:
240 case ELF::R_RISCV_TLS_GD_HI20:
241 // See extractValueRISCV for why this is necessary.
242 return 8;
243 }
244}
245
246static bool skipRelocationTypeX86(uint32_t Type) {
247 return Type == ELF::R_X86_64_NONE;
248}
249
250static bool skipRelocationTypeAArch64(uint32_t Type) {
251 return Type == ELF::R_AARCH64_NONE || Type == ELF::R_AARCH64_LD_PREL_LO19;
252}
253
254static bool skipRelocationTypeRISCV(uint32_t Type) {
255 switch (Type) {
256 default:
257 return false;
258 case ELF::R_RISCV_NONE:
259 case ELF::R_RISCV_RELAX:
260 return true;
261 }
262}
263
264static uint64_t encodeValueX86(uint32_t Type, uint64_t Value, uint64_t PC) {
265 switch (Type) {
266 default:
267 llvm_unreachable("unsupported relocation");
268 case ELF::R_X86_64_64:
269 case ELF::R_X86_64_32:
270 break;
271 case ELF::R_X86_64_PC32:
272 Value -= PC;
273 break;
274 }
275 return Value;
276}
277
278static bool canEncodeValueAArch64(uint32_t Type, uint64_t Value, uint64_t PC) {
279 switch (Type) {
280 default:
281 llvm_unreachable("unsupported relocation");
282 case ELF::R_AARCH64_CALL26:
283 case ELF::R_AARCH64_JUMP26:
284 return isInt<28>(x: Value - PC);
285 }
286}
287
288static uint64_t encodeValueAArch64(uint32_t Type, uint64_t Value, uint64_t PC) {
289 switch (Type) {
290 default:
291 llvm_unreachable("unsupported relocation");
292 case ELF::R_AARCH64_ABS16:
293 case ELF::R_AARCH64_ABS32:
294 case ELF::R_AARCH64_ABS64:
295 break;
296 case ELF::R_AARCH64_PREL16:
297 case ELF::R_AARCH64_PREL32:
298 case ELF::R_AARCH64_PREL64:
299 Value -= PC;
300 break;
301 case ELF::R_AARCH64_CALL26:
302 Value -= PC;
303 assert(isInt<28>(Value) && "only PC +/- 128MB is allowed for direct call");
304 // Immediate goes in bits 25:0 of BL.
305 // OP 1001_01 goes in bits 31:26 of BL.
306 Value = ((Value >> 2) & 0x3ffffff) | 0x94000000ULL;
307 break;
308 case ELF::R_AARCH64_JUMP26:
309 Value -= PC;
310 assert(isInt<28>(Value) &&
311 "only PC +/- 128MB is allowed for direct branch");
312 // Immediate goes in bits 25:0 of B.
313 // OP 0001_01 goes in bits 31:26 of B.
314 Value = ((Value >> 2) & 0x3ffffff) | 0x14000000ULL;
315 break;
316 }
317 return Value;
318}
319
320static uint64_t canEncodeValueRISCV(uint32_t Type, uint64_t Value,
321 uint64_t PC) {
322 switch (Type) {
323 default:
324 llvm_unreachable("unsupported relocation");
325 case ELF::R_RISCV_64:
326 return true;
327 }
328}
329
330static uint64_t encodeValueRISCV(uint32_t Type, uint64_t Value, uint64_t PC) {
331 switch (Type) {
332 default:
333 llvm_unreachable("unsupported relocation");
334 case ELF::R_RISCV_64:
335 break;
336 }
337 return Value;
338}
339
340static uint64_t extractValueX86(uint32_t Type, uint64_t Contents, uint64_t PC) {
341 if (Type == ELF::R_X86_64_32S)
342 return SignExtend64<32>(x: Contents);
343 if (Relocation::isPCRelative(Type))
344 return SignExtend64(X: Contents, B: 8 * Relocation::getSizeForType(Type));
345 return Contents;
346}
347
348static uint64_t extractValueAArch64(uint32_t Type, uint64_t Contents,
349 uint64_t PC) {
350 switch (Type) {
351 default:
352 errs() << object::getELFRelocationTypeName(Machine: ELF::EM_AARCH64, Type) << '\n';
353 llvm_unreachable("unsupported relocation type");
354 case ELF::R_AARCH64_ABS16:
355 case ELF::R_AARCH64_ABS32:
356 case ELF::R_AARCH64_ABS64:
357 return Contents;
358 case ELF::R_AARCH64_PREL16:
359 return static_cast<int64_t>(PC) + SignExtend64<16>(x: Contents & 0xffff);
360 case ELF::R_AARCH64_PREL32:
361 case ELF::R_AARCH64_PLT32:
362 return static_cast<int64_t>(PC) + SignExtend64<32>(x: Contents & 0xffffffff);
363 case ELF::R_AARCH64_PREL64:
364 return static_cast<int64_t>(PC) + Contents;
365 case ELF::R_AARCH64_TLSDESC_CALL:
366 case ELF::R_AARCH64_JUMP26:
367 case ELF::R_AARCH64_CALL26:
368 // Immediate goes in bits 25:0 of B and BL.
369 Contents &= ~0xfffffffffc000000ULL;
370 return static_cast<int64_t>(PC) + SignExtend64<28>(x: Contents << 2);
371 case ELF::R_AARCH64_TSTBR14:
372 // Immediate:15:2 goes in bits 18:5 of TBZ, TBNZ
373 Contents &= ~0xfffffffffff8001fULL;
374 return static_cast<int64_t>(PC) + SignExtend64<16>(x: Contents >> 3);
375 case ELF::R_AARCH64_CONDBR19:
376 // Immediate:20:2 goes in bits 23:5 of Bcc, CBZ, CBNZ
377 Contents &= ~0xffffffffff00001fULL;
378 return static_cast<int64_t>(PC) + SignExtend64<21>(x: Contents >> 3);
379 case ELF::R_AARCH64_ADR_GOT_PAGE:
380 case ELF::R_AARCH64_TLSDESC_ADR_PREL21:
381 case ELF::R_AARCH64_TLSDESC_ADR_PAGE21:
382 case ELF::R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
383 case ELF::R_AARCH64_ADR_PREL_LO21:
384 case ELF::R_AARCH64_ADR_PREL_PG_HI21:
385 case ELF::R_AARCH64_ADR_PREL_PG_HI21_NC: {
386 // Bits 32:12 of Symbol address goes in bits 30:29 + 23:5 of ADRP
387 // and ADR instructions
388 bool IsAdr = !!(((Contents >> 31) & 0x1) == 0);
389 Contents &= ~0xffffffff9f00001fUll;
390 uint64_t LowBits = (Contents >> 29) & 0x3;
391 uint64_t HighBits = (Contents >> 5) & 0x7ffff;
392 Contents = LowBits | (HighBits << 2);
393 if (IsAdr)
394 return static_cast<int64_t>(PC) + SignExtend64<21>(x: Contents);
395
396 // ADRP instruction
397 Contents = static_cast<int64_t>(PC) + SignExtend64<33>(x: Contents << 12);
398 Contents &= ~0xfffUll;
399 return Contents;
400 }
401 case ELF::R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:
402 case ELF::R_AARCH64_TLSDESC_LD64_LO12:
403 case ELF::R_AARCH64_LD64_GOT_LO12_NC:
404 case ELF::R_AARCH64_LDST64_ABS_LO12_NC: {
405 // Immediate goes in bits 21:10 of LD/ST instruction, taken
406 // from bits 11:3 of Symbol address
407 Contents &= ~0xffffffffffc003ffU;
408 return Contents >> (10 - 3);
409 }
410 case ELF::R_AARCH64_TLSLE_ADD_TPREL_HI12:
411 case ELF::R_AARCH64_TLSLE_ADD_TPREL_LO12_NC:
412 case ELF::R_AARCH64_TLSDESC_ADD_LO12:
413 case ELF::R_AARCH64_ADD_ABS_LO12_NC: {
414 // Immediate goes in bits 21:10 of ADD instruction
415 Contents &= ~0xffffffffffc003ffU;
416 return Contents >> (10 - 0);
417 }
418 case ELF::R_AARCH64_LDST128_ABS_LO12_NC: {
419 // Immediate goes in bits 21:10 of ADD instruction, taken
420 // from bits 11:4 of Symbol address
421 Contents &= ~0xffffffffffc003ffU;
422 return Contents >> (10 - 4);
423 }
424 case ELF::R_AARCH64_LDST32_ABS_LO12_NC: {
425 // Immediate goes in bits 21:10 of ADD instruction, taken
426 // from bits 11:2 of Symbol address
427 Contents &= ~0xffffffffffc003ffU;
428 return Contents >> (10 - 2);
429 }
430 case ELF::R_AARCH64_LDST16_ABS_LO12_NC: {
431 // Immediate goes in bits 21:10 of ADD instruction, taken
432 // from bits 11:1 of Symbol address
433 Contents &= ~0xffffffffffc003ffU;
434 return Contents >> (10 - 1);
435 }
436 case ELF::R_AARCH64_LDST8_ABS_LO12_NC: {
437 // Immediate goes in bits 21:10 of ADD instruction, taken
438 // from bits 11:0 of Symbol address
439 Contents &= ~0xffffffffffc003ffU;
440 return Contents >> (10 - 0);
441 }
442 case ELF::R_AARCH64_MOVW_UABS_G3:
443 case ELF::R_AARCH64_MOVW_UABS_G2_NC:
444 case ELF::R_AARCH64_MOVW_UABS_G2:
445 case ELF::R_AARCH64_MOVW_UABS_G1_NC:
446 case ELF::R_AARCH64_MOVW_UABS_G1:
447 case ELF::R_AARCH64_MOVW_UABS_G0_NC:
448 case ELF::R_AARCH64_MOVW_UABS_G0:
449 // The shift goes in bits 22:21 of MOV* instructions
450 uint8_t Shift = (Contents >> 21) & 0x3;
451 // Immediate goes in bits 20:5
452 Contents = (Contents >> 5) & 0xffff;
453 return Contents << (16 * Shift);
454 }
455}
456
457static uint64_t extractUImmRISCV(uint32_t Contents) {
458 return SignExtend64<32>(x: Contents & 0xfffff000);
459}
460
461static uint64_t extractIImmRISCV(uint32_t Contents) {
462 return SignExtend64<12>(x: Contents >> 20);
463}
464
465static uint64_t extractSImmRISCV(uint32_t Contents) {
466 return SignExtend64<12>(x: ((Contents >> 7) & 0x1f) | ((Contents >> 25) << 5));
467}
468
469static uint64_t extractJImmRISCV(uint32_t Contents) {
470 return SignExtend64<21>(
471 x: (((Contents >> 21) & 0x3ff) << 1) | (((Contents >> 20) & 0x1) << 11) |
472 (((Contents >> 12) & 0xff) << 12) | (((Contents >> 31) & 0x1) << 20));
473}
474
475static uint64_t extractBImmRISCV(uint32_t Contents) {
476 return SignExtend64<13>(
477 x: (((Contents >> 8) & 0xf) << 1) | (((Contents >> 25) & 0x3f) << 5) |
478 (((Contents >> 7) & 0x1) << 11) | (((Contents >> 31) & 0x1) << 12));
479}
480
481static uint64_t extractValueRISCV(uint32_t Type, uint64_t Contents,
482 uint64_t PC) {
483 switch (Type) {
484 default:
485 errs() << object::getELFRelocationTypeName(Machine: ELF::EM_RISCV, Type) << '\n';
486 llvm_unreachable("unsupported relocation type");
487 case ELF::R_RISCV_JAL:
488 return extractJImmRISCV(Contents);
489 case ELF::R_RISCV_CALL:
490 case ELF::R_RISCV_CALL_PLT:
491 return extractUImmRISCV(Contents);
492 case ELF::R_RISCV_BRANCH:
493 return extractBImmRISCV(Contents);
494 case ELF::R_RISCV_GOT_HI20:
495 case ELF::R_RISCV_TLS_GOT_HI20:
496 case ELF::R_RISCV_TLS_GD_HI20:
497 // We need to know the exact address of the GOT entry so we extract the
498 // value from both the AUIPC and L[D|W]. We cannot rely on the symbol in the
499 // relocation for this since it simply refers to the object that is stored
500 // in the GOT entry, not to the entry itself.
501 return extractUImmRISCV(Contents: Contents & 0xffffffff) +
502 extractIImmRISCV(Contents: Contents >> 32);
503 case ELF::R_RISCV_PCREL_HI20:
504 case ELF::R_RISCV_HI20:
505 return extractUImmRISCV(Contents);
506 case ELF::R_RISCV_PCREL_LO12_I:
507 case ELF::R_RISCV_LO12_I:
508 return extractIImmRISCV(Contents);
509 case ELF::R_RISCV_PCREL_LO12_S:
510 case ELF::R_RISCV_LO12_S:
511 return extractSImmRISCV(Contents);
512 case ELF::R_RISCV_RVC_JUMP:
513 return SignExtend64<11>(x: Contents >> 2);
514 case ELF::R_RISCV_RVC_BRANCH:
515 return SignExtend64<8>(x: ((Contents >> 2) & 0x1f) | ((Contents >> 5) & 0xe0));
516 case ELF::R_RISCV_ADD32:
517 case ELF::R_RISCV_SUB32:
518 case ELF::R_RISCV_64:
519 return Contents;
520 }
521}
522
523static bool isGOTX86(uint32_t Type) {
524 switch (Type) {
525 default:
526 return false;
527 case ELF::R_X86_64_GOT32:
528 case ELF::R_X86_64_GOTPCREL:
529 case ELF::R_X86_64_GOTTPOFF:
530 case ELF::R_X86_64_GOTOFF64:
531 case ELF::R_X86_64_GOTPC32:
532 case ELF::R_X86_64_GOT64:
533 case ELF::R_X86_64_GOTPCREL64:
534 case ELF::R_X86_64_GOTPC64:
535 case ELF::R_X86_64_GOTPLT64:
536 case ELF::R_X86_64_GOTPC32_TLSDESC:
537 case ELF::R_X86_64_GOTPCRELX:
538 case ELF::R_X86_64_REX_GOTPCRELX:
539 return true;
540 }
541}
542
543static bool isGOTAArch64(uint32_t Type) {
544 switch (Type) {
545 default:
546 return false;
547 case ELF::R_AARCH64_ADR_GOT_PAGE:
548 case ELF::R_AARCH64_LD64_GOT_LO12_NC:
549 case ELF::R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:
550 case ELF::R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
551 case ELF::R_AARCH64_TLSDESC_ADR_PREL21:
552 case ELF::R_AARCH64_TLSDESC_ADR_PAGE21:
553 case ELF::R_AARCH64_TLSDESC_LD64_LO12:
554 case ELF::R_AARCH64_TLSDESC_ADD_LO12:
555 case ELF::R_AARCH64_TLSDESC_CALL:
556 return true;
557 }
558}
559
560static bool isGOTRISCV(uint32_t Type) {
561 switch (Type) {
562 default:
563 return false;
564 case ELF::R_RISCV_GOT_HI20:
565 case ELF::R_RISCV_TLS_GOT_HI20:
566 return true;
567 }
568}
569
570static bool isTLSX86(uint32_t Type) {
571 switch (Type) {
572 default:
573 return false;
574 case ELF::R_X86_64_TPOFF32:
575 case ELF::R_X86_64_TPOFF64:
576 case ELF::R_X86_64_GOTTPOFF:
577 return true;
578 }
579}
580
581static bool isTLSAArch64(uint32_t Type) {
582 switch (Type) {
583 default:
584 return false;
585 case ELF::R_AARCH64_TLSDESC_ADR_PREL21:
586 case ELF::R_AARCH64_TLSDESC_ADR_PAGE21:
587 case ELF::R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:
588 case ELF::R_AARCH64_TLSLE_ADD_TPREL_HI12:
589 case ELF::R_AARCH64_TLSLE_ADD_TPREL_LO12_NC:
590 case ELF::R_AARCH64_TLSLE_MOVW_TPREL_G0:
591 case ELF::R_AARCH64_TLSLE_MOVW_TPREL_G0_NC:
592 case ELF::R_AARCH64_TLSDESC_LD64_LO12:
593 case ELF::R_AARCH64_TLSDESC_ADD_LO12:
594 case ELF::R_AARCH64_TLSDESC_CALL:
595 case ELF::R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
596 return true;
597 }
598}
599
600static bool isTLSRISCV(uint32_t Type) {
601 switch (Type) {
602 default:
603 return false;
604 case ELF::R_RISCV_TLS_GOT_HI20:
605 case ELF::R_RISCV_TPREL_HI20:
606 case ELF::R_RISCV_TPREL_ADD:
607 case ELF::R_RISCV_TPREL_LO12_I:
608 case ELF::R_RISCV_TPREL_LO12_S:
609 case ELFReserved::R_RISCV_TPREL_I:
610 case ELFReserved::R_RISCV_TPREL_S:
611 return true;
612 }
613}
614
615static bool isPCRelativeX86(uint32_t Type) {
616 switch (Type) {
617 default:
618 llvm_unreachable("Unknown relocation type");
619 case ELF::R_X86_64_64:
620 case ELF::R_X86_64_32:
621 case ELF::R_X86_64_32S:
622 case ELF::R_X86_64_16:
623 case ELF::R_X86_64_8:
624 case ELF::R_X86_64_TPOFF32:
625 return false;
626 case ELF::R_X86_64_PC8:
627 case ELF::R_X86_64_PC32:
628 case ELF::R_X86_64_PC64:
629 case ELF::R_X86_64_GOTPCREL:
630 case ELF::R_X86_64_PLT32:
631 case ELF::R_X86_64_GOTOFF64:
632 case ELF::R_X86_64_GOTPC32:
633 case ELF::R_X86_64_GOTPC64:
634 case ELF::R_X86_64_GOTTPOFF:
635 case ELF::R_X86_64_GOTPCRELX:
636 case ELF::R_X86_64_REX_GOTPCRELX:
637 return true;
638 }
639}
640
641static bool isPCRelativeAArch64(uint32_t Type) {
642 switch (Type) {
643 default:
644 llvm_unreachable("Unknown relocation type");
645 case ELF::R_AARCH64_ABS16:
646 case ELF::R_AARCH64_ABS32:
647 case ELF::R_AARCH64_ABS64:
648 case ELF::R_AARCH64_LDST64_ABS_LO12_NC:
649 case ELF::R_AARCH64_ADD_ABS_LO12_NC:
650 case ELF::R_AARCH64_LDST128_ABS_LO12_NC:
651 case ELF::R_AARCH64_LDST32_ABS_LO12_NC:
652 case ELF::R_AARCH64_LDST16_ABS_LO12_NC:
653 case ELF::R_AARCH64_LDST8_ABS_LO12_NC:
654 case ELF::R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:
655 case ELF::R_AARCH64_TLSLE_ADD_TPREL_HI12:
656 case ELF::R_AARCH64_TLSLE_ADD_TPREL_LO12_NC:
657 case ELF::R_AARCH64_TLSLE_MOVW_TPREL_G0:
658 case ELF::R_AARCH64_TLSLE_MOVW_TPREL_G0_NC:
659 case ELF::R_AARCH64_LD64_GOT_LO12_NC:
660 case ELF::R_AARCH64_TLSDESC_LD64_LO12:
661 case ELF::R_AARCH64_TLSDESC_ADD_LO12:
662 case ELF::R_AARCH64_MOVW_UABS_G0:
663 case ELF::R_AARCH64_MOVW_UABS_G0_NC:
664 case ELF::R_AARCH64_MOVW_UABS_G1:
665 case ELF::R_AARCH64_MOVW_UABS_G1_NC:
666 case ELF::R_AARCH64_MOVW_UABS_G2:
667 case ELF::R_AARCH64_MOVW_UABS_G2_NC:
668 case ELF::R_AARCH64_MOVW_UABS_G3:
669 return false;
670 case ELF::R_AARCH64_TLSDESC_CALL:
671 case ELF::R_AARCH64_CALL26:
672 case ELF::R_AARCH64_JUMP26:
673 case ELF::R_AARCH64_TSTBR14:
674 case ELF::R_AARCH64_CONDBR19:
675 case ELF::R_AARCH64_ADR_PREL_LO21:
676 case ELF::R_AARCH64_ADR_PREL_PG_HI21:
677 case ELF::R_AARCH64_ADR_PREL_PG_HI21_NC:
678 case ELF::R_AARCH64_ADR_GOT_PAGE:
679 case ELF::R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
680 case ELF::R_AARCH64_TLSDESC_ADR_PREL21:
681 case ELF::R_AARCH64_TLSDESC_ADR_PAGE21:
682 case ELF::R_AARCH64_PREL16:
683 case ELF::R_AARCH64_PREL32:
684 case ELF::R_AARCH64_PREL64:
685 case ELF::R_AARCH64_PLT32:
686 return true;
687 }
688}
689
690static bool isPCRelativeRISCV(uint32_t Type) {
691 switch (Type) {
692 default:
693 llvm_unreachable("Unknown relocation type");
694 case ELF::R_RISCV_ADD32:
695 case ELF::R_RISCV_SUB32:
696 case ELF::R_RISCV_HI20:
697 case ELF::R_RISCV_LO12_I:
698 case ELF::R_RISCV_LO12_S:
699 case ELF::R_RISCV_64:
700 return false;
701 case ELF::R_RISCV_JAL:
702 case ELF::R_RISCV_CALL:
703 case ELF::R_RISCV_CALL_PLT:
704 case ELF::R_RISCV_BRANCH:
705 case ELF::R_RISCV_GOT_HI20:
706 case ELF::R_RISCV_PCREL_HI20:
707 case ELF::R_RISCV_PCREL_LO12_I:
708 case ELF::R_RISCV_PCREL_LO12_S:
709 case ELF::R_RISCV_RVC_JUMP:
710 case ELF::R_RISCV_RVC_BRANCH:
711 case ELF::R_RISCV_32_PCREL:
712 case ELF::R_RISCV_TLS_GOT_HI20:
713 case ELF::R_RISCV_TLS_GD_HI20:
714 return true;
715 }
716}
717
718bool Relocation::isSupported(uint32_t Type) {
719 switch (Arch) {
720 default:
721 return false;
722 case Triple::aarch64:
723 return isSupportedAArch64(Type);
724 case Triple::riscv64:
725 return isSupportedRISCV(Type);
726 case Triple::x86_64:
727 return isSupportedX86(Type);
728 }
729}
730
731size_t Relocation::getSizeForType(uint32_t Type) {
732 switch (Arch) {
733 default:
734 llvm_unreachable("Unsupported architecture");
735 case Triple::aarch64:
736 return getSizeForTypeAArch64(Type);
737 case Triple::riscv64:
738 return getSizeForTypeRISCV(Type);
739 case Triple::x86_64:
740 return getSizeForTypeX86(Type);
741 }
742}
743
744bool Relocation::skipRelocationType(uint32_t Type) {
745 switch (Arch) {
746 default:
747 llvm_unreachable("Unsupported architecture");
748 case Triple::aarch64:
749 return skipRelocationTypeAArch64(Type);
750 case Triple::riscv64:
751 return skipRelocationTypeRISCV(Type);
752 case Triple::x86_64:
753 return skipRelocationTypeX86(Type);
754 }
755}
756
757uint64_t Relocation::encodeValue(uint32_t Type, uint64_t Value, uint64_t PC) {
758 switch (Arch) {
759 default:
760 llvm_unreachable("Unsupported architecture");
761 case Triple::aarch64:
762 return encodeValueAArch64(Type, Value, PC);
763 case Triple::riscv64:
764 return encodeValueRISCV(Type, Value, PC);
765 case Triple::x86_64:
766 return encodeValueX86(Type, Value, PC);
767 }
768}
769
770bool Relocation::canEncodeValue(uint32_t Type, uint64_t Value, uint64_t PC) {
771 switch (Arch) {
772 default:
773 llvm_unreachable("Unsupported architecture");
774 case Triple::aarch64:
775 return canEncodeValueAArch64(Type, Value, PC);
776 case Triple::riscv64:
777 return canEncodeValueRISCV(Type, Value, PC);
778 case Triple::x86_64:
779 return true;
780 }
781}
782
783uint64_t Relocation::extractValue(uint32_t Type, uint64_t Contents,
784 uint64_t PC) {
785 switch (Arch) {
786 default:
787 llvm_unreachable("Unsupported architecture");
788 case Triple::aarch64:
789 return extractValueAArch64(Type, Contents, PC);
790 case Triple::riscv64:
791 return extractValueRISCV(Type, Contents, PC);
792 case Triple::x86_64:
793 return extractValueX86(Type, Contents, PC);
794 }
795}
796
797bool Relocation::isGOT(uint32_t Type) {
798 switch (Arch) {
799 default:
800 llvm_unreachable("Unsupported architecture");
801 case Triple::aarch64:
802 return isGOTAArch64(Type);
803 case Triple::riscv64:
804 return isGOTRISCV(Type);
805 case Triple::x86_64:
806 return isGOTX86(Type);
807 }
808}
809
810bool Relocation::isX86GOTPCRELX(uint32_t Type) {
811 if (Arch != Triple::x86_64)
812 return false;
813 return Type == ELF::R_X86_64_GOTPCRELX || Type == ELF::R_X86_64_REX_GOTPCRELX;
814}
815
816bool Relocation::isX86GOTPC64(uint32_t Type) {
817 if (Arch != Triple::x86_64)
818 return false;
819 return Type == ELF::R_X86_64_GOTPC64;
820}
821
822bool Relocation::isNone(uint32_t Type) { return Type == getNone(); }
823
824bool Relocation::isRelative(uint32_t Type) {
825 switch (Arch) {
826 default:
827 llvm_unreachable("Unsupported architecture");
828 case Triple::aarch64:
829 return Type == ELF::R_AARCH64_RELATIVE;
830 case Triple::riscv64:
831 return Type == ELF::R_RISCV_RELATIVE;
832 case Triple::x86_64:
833 return Type == ELF::R_X86_64_RELATIVE;
834 }
835}
836
837bool Relocation::isIRelative(uint32_t Type) {
838 switch (Arch) {
839 default:
840 llvm_unreachable("Unsupported architecture");
841 case Triple::aarch64:
842 return Type == ELF::R_AARCH64_IRELATIVE;
843 case Triple::riscv64:
844 llvm_unreachable("not implemented");
845 case Triple::x86_64:
846 return Type == ELF::R_X86_64_IRELATIVE;
847 }
848}
849
850bool Relocation::isTLS(uint32_t Type) {
851 switch (Arch) {
852 default:
853 llvm_unreachable("Unsupported architecture");
854 case Triple::aarch64:
855 return isTLSAArch64(Type);
856 case Triple::riscv64:
857 return isTLSRISCV(Type);
858 case Triple::x86_64:
859 return isTLSX86(Type);
860 }
861}
862
863bool Relocation::isInstructionReference(uint32_t Type) {
864 if (Arch != Triple::riscv64)
865 return false;
866
867 switch (Type) {
868 default:
869 return false;
870 case ELF::R_RISCV_PCREL_LO12_I:
871 case ELF::R_RISCV_PCREL_LO12_S:
872 return true;
873 }
874}
875
876uint32_t Relocation::getNone() {
877 switch (Arch) {
878 default:
879 llvm_unreachable("Unsupported architecture");
880 case Triple::aarch64:
881 return ELF::R_AARCH64_NONE;
882 case Triple::riscv64:
883 return ELF::R_RISCV_NONE;
884 case Triple::x86_64:
885 return ELF::R_X86_64_NONE;
886 }
887}
888
889uint32_t Relocation::getPC32() {
890 switch (Arch) {
891 default:
892 llvm_unreachable("Unsupported architecture");
893 case Triple::aarch64:
894 return ELF::R_AARCH64_PREL32;
895 case Triple::riscv64:
896 return ELF::R_RISCV_32_PCREL;
897 case Triple::x86_64:
898 return ELF::R_X86_64_PC32;
899 }
900}
901
902uint32_t Relocation::getPC64() {
903 switch (Arch) {
904 default:
905 llvm_unreachable("Unsupported architecture");
906 case Triple::aarch64:
907 return ELF::R_AARCH64_PREL64;
908 case Triple::riscv64:
909 llvm_unreachable("not implemented");
910 case Triple::x86_64:
911 return ELF::R_X86_64_PC64;
912 }
913}
914
915uint32_t Relocation::getType(const object::RelocationRef &Rel) {
916 uint64_t RelType = Rel.getType();
917 assert(isUInt<32>(RelType) && "BOLT relocation types are 32 bits");
918 return static_cast<uint32_t>(RelType);
919}
920
921bool Relocation::isPCRelative(uint32_t Type) {
922 switch (Arch) {
923 default:
924 llvm_unreachable("Unsupported architecture");
925 case Triple::aarch64:
926 return isPCRelativeAArch64(Type);
927 case Triple::riscv64:
928 return isPCRelativeRISCV(Type);
929 case Triple::x86_64:
930 return isPCRelativeX86(Type);
931 }
932}
933
934uint32_t Relocation::getAbs64() {
935 switch (Arch) {
936 default:
937 llvm_unreachable("Unsupported architecture");
938 case Triple::aarch64:
939 return ELF::R_AARCH64_ABS64;
940 case Triple::riscv64:
941 return ELF::R_RISCV_64;
942 case Triple::x86_64:
943 return ELF::R_X86_64_64;
944 }
945}
946
947uint32_t Relocation::getRelative() {
948 switch (Arch) {
949 default:
950 llvm_unreachable("Unsupported architecture");
951 case Triple::aarch64:
952 return ELF::R_AARCH64_RELATIVE;
953 case Triple::riscv64:
954 llvm_unreachable("not implemented");
955 case Triple::x86_64:
956 return ELF::R_X86_64_RELATIVE;
957 }
958}
959
960size_t Relocation::emit(MCStreamer *Streamer) const {
961 const size_t Size = getSizeForType(Type);
962 const auto *Value = createExpr(Streamer);
963 Streamer->emitValue(Value, Size);
964 return Size;
965}
966
967const MCExpr *Relocation::createExpr(MCStreamer *Streamer) const {
968 MCContext &Ctx = Streamer->getContext();
969 const MCExpr *Value = nullptr;
970
971 if (Symbol && Addend) {
972 Value = MCBinaryExpr::createAdd(LHS: MCSymbolRefExpr::create(Symbol, Ctx),
973 RHS: MCConstantExpr::create(Value: Addend, Ctx), Ctx);
974 } else if (Symbol) {
975 Value = MCSymbolRefExpr::create(Symbol, Ctx);
976 } else {
977 Value = MCConstantExpr::create(Value: Addend, Ctx);
978 }
979
980 if (isPCRelative(Type)) {
981 MCSymbol *TempLabel = Ctx.createNamedTempSymbol();
982 Streamer->emitLabel(Symbol: TempLabel);
983 Value = MCBinaryExpr::createSub(
984 LHS: Value, RHS: MCSymbolRefExpr::create(Symbol: TempLabel, Ctx), Ctx);
985 }
986
987 return Value;
988}
989
990const MCExpr *Relocation::createExpr(MCStreamer *Streamer,
991 const MCExpr *RetainedValue) const {
992 const auto *Value = createExpr(Streamer);
993
994 if (RetainedValue) {
995 Value = MCBinaryExpr::create(Op: getComposeOpcodeFor(Type), LHS: RetainedValue,
996 RHS: Value, Ctx&: Streamer->getContext());
997 }
998
999 return Value;
1000}
1001
1002MCBinaryExpr::Opcode Relocation::getComposeOpcodeFor(uint32_t Type) {
1003 assert(Arch == Triple::riscv64 && "only implemented for RISC-V");
1004
1005 switch (Type) {
1006 default:
1007 llvm_unreachable("not implemented");
1008 case ELF::R_RISCV_ADD32:
1009 return MCBinaryExpr::Add;
1010 case ELF::R_RISCV_SUB32:
1011 return MCBinaryExpr::Sub;
1012 }
1013}
1014
1015void Relocation::print(raw_ostream &OS) const {
1016 switch (Arch) {
1017 default:
1018 OS << "RType:" << Twine::utohexstr(Val: Type);
1019 break;
1020
1021 case Triple::aarch64:
1022 static const char *const AArch64RelocNames[] = {
1023#define ELF_RELOC(name, value) #name,
1024#include "llvm/BinaryFormat/ELFRelocs/AArch64.def"
1025#undef ELF_RELOC
1026 };
1027 assert(Type < ArrayRef(AArch64RelocNames).size());
1028 OS << AArch64RelocNames[Type];
1029 break;
1030
1031 case Triple::riscv64:
1032 // RISC-V relocations are not sequentially numbered so we cannot use an
1033 // array
1034 switch (Type) {
1035 default:
1036 llvm_unreachable("illegal RISC-V relocation");
1037#define ELF_RELOC(name, value) \
1038 case value: \
1039 OS << #name; \
1040 break;
1041#include "llvm/BinaryFormat/ELFRelocs/RISCV.def"
1042#undef ELF_RELOC
1043 }
1044 break;
1045
1046 case Triple::x86_64:
1047 static const char *const X86RelocNames[] = {
1048#define ELF_RELOC(name, value) #name,
1049#include "llvm/BinaryFormat/ELFRelocs/x86_64.def"
1050#undef ELF_RELOC
1051 };
1052 assert(Type < ArrayRef(X86RelocNames).size());
1053 OS << X86RelocNames[Type];
1054 break;
1055 }
1056 OS << ", 0x" << Twine::utohexstr(Val: Offset);
1057 if (Symbol) {
1058 OS << ", " << Symbol->getName();
1059 }
1060 if (int64_t(Addend) < 0)
1061 OS << ", -0x" << Twine::utohexstr(Val: -int64_t(Addend));
1062 else
1063 OS << ", 0x" << Twine::utohexstr(Val: Addend);
1064 OS << ", 0x" << Twine::utohexstr(Val: Value);
1065}
1066

Provided by KDAB

Privacy Policy
Improve your Profiling and Debugging skills
Find out more

source code of bolt/lib/Core/Relocation.cpp