Rework RISC-V relocations
[deliverable/binutils-gdb.git] / bfd / elfxx-riscv.c
1 /* RISC-V-specific support for ELF.
2 Copyright 2011-2016 Free Software Foundation, Inc.
3
4 Contributed by Andrew Waterman (andrew@sifive.com).
5 Based on TILE-Gx and MIPS targets.
6
7 This file is part of BFD, the Binary File Descriptor library.
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; see the file COPYING3. If not,
21 see <http://www.gnu.org/licenses/>. */
22
23 #include "sysdep.h"
24 #include "bfd.h"
25 #include "libbfd.h"
26 #include "elf-bfd.h"
27 #include "elf/riscv.h"
28 #include "opcode/riscv.h"
29 #include "libiberty.h"
30 #include "elfxx-riscv.h"
31 #include <stdint.h>
32
33 #define MINUS_ONE ((bfd_vma)0 - 1)
34
35 /* The relocation table used for SHT_RELA sections. */
36
37 static reloc_howto_type howto_table[] =
38 {
39 /* No relocation. */
40 HOWTO (R_RISCV_NONE, /* type */
41 0, /* rightshift */
42 3, /* size */
43 0, /* bitsize */
44 FALSE, /* pc_relative */
45 0, /* bitpos */
46 complain_overflow_dont, /* complain_on_overflow */
47 bfd_elf_generic_reloc, /* special_function */
48 "R_RISCV_NONE", /* name */
49 FALSE, /* partial_inplace */
50 0, /* src_mask */
51 0, /* dst_mask */
52 FALSE), /* pcrel_offset */
53
54 /* 32 bit relocation. */
55 HOWTO (R_RISCV_32, /* type */
56 0, /* rightshift */
57 2, /* size */
58 32, /* bitsize */
59 FALSE, /* pc_relative */
60 0, /* bitpos */
61 complain_overflow_dont, /* complain_on_overflow */
62 bfd_elf_generic_reloc, /* special_function */
63 "R_RISCV_32", /* name */
64 FALSE, /* partial_inplace */
65 0, /* src_mask */
66 MINUS_ONE, /* dst_mask */
67 FALSE), /* pcrel_offset */
68
69 /* 64 bit relocation. */
70 HOWTO (R_RISCV_64, /* type */
71 0, /* rightshift */
72 4, /* size */
73 64, /* bitsize */
74 FALSE, /* pc_relative */
75 0, /* bitpos */
76 complain_overflow_dont, /* complain_on_overflow */
77 bfd_elf_generic_reloc, /* special_function */
78 "R_RISCV_64", /* name */
79 FALSE, /* partial_inplace */
80 0, /* src_mask */
81 MINUS_ONE, /* dst_mask */
82 FALSE), /* pcrel_offset */
83
84 /* Relocation against a local symbol in a shared object. */
85 HOWTO (R_RISCV_RELATIVE, /* type */
86 0, /* rightshift */
87 2, /* size */
88 32, /* bitsize */
89 FALSE, /* pc_relative */
90 0, /* bitpos */
91 complain_overflow_dont, /* complain_on_overflow */
92 bfd_elf_generic_reloc, /* special_function */
93 "R_RISCV_RELATIVE", /* name */
94 FALSE, /* partial_inplace */
95 0, /* src_mask */
96 MINUS_ONE, /* dst_mask */
97 FALSE), /* pcrel_offset */
98
99 HOWTO (R_RISCV_COPY, /* type */
100 0, /* rightshift */
101 0, /* this one is variable size */
102 0, /* bitsize */
103 FALSE, /* pc_relative */
104 0, /* bitpos */
105 complain_overflow_bitfield, /* complain_on_overflow */
106 bfd_elf_generic_reloc, /* special_function */
107 "R_RISCV_COPY", /* name */
108 FALSE, /* partial_inplace */
109 0, /* src_mask */
110 0, /* dst_mask */
111 FALSE), /* pcrel_offset */
112
113 HOWTO (R_RISCV_JUMP_SLOT, /* type */
114 0, /* rightshift */
115 4, /* size */
116 64, /* bitsize */
117 FALSE, /* pc_relative */
118 0, /* bitpos */
119 complain_overflow_bitfield, /* complain_on_overflow */
120 bfd_elf_generic_reloc, /* special_function */
121 "R_RISCV_JUMP_SLOT", /* name */
122 FALSE, /* partial_inplace */
123 0, /* src_mask */
124 0, /* dst_mask */
125 FALSE), /* pcrel_offset */
126
127 /* Dynamic TLS relocations. */
128 HOWTO (R_RISCV_TLS_DTPMOD32, /* type */
129 0, /* rightshift */
130 4, /* size */
131 32, /* bitsize */
132 FALSE, /* pc_relative */
133 0, /* bitpos */
134 complain_overflow_dont, /* complain_on_overflow */
135 bfd_elf_generic_reloc, /* special_function */
136 "R_RISCV_TLS_DTPMOD32", /* name */
137 FALSE, /* partial_inplace */
138 0, /* src_mask */
139 MINUS_ONE, /* dst_mask */
140 FALSE), /* pcrel_offset */
141
142 HOWTO (R_RISCV_TLS_DTPMOD64, /* type */
143 0, /* rightshift */
144 4, /* size */
145 64, /* bitsize */
146 FALSE, /* pc_relative */
147 0, /* bitpos */
148 complain_overflow_dont, /* complain_on_overflow */
149 bfd_elf_generic_reloc, /* special_function */
150 "R_RISCV_TLS_DTPMOD64", /* name */
151 FALSE, /* partial_inplace */
152 0, /* src_mask */
153 MINUS_ONE, /* dst_mask */
154 FALSE), /* pcrel_offset */
155
156 HOWTO (R_RISCV_TLS_DTPREL32, /* type */
157 0, /* rightshift */
158 4, /* size */
159 32, /* bitsize */
160 FALSE, /* pc_relative */
161 0, /* bitpos */
162 complain_overflow_dont, /* complain_on_overflow */
163 bfd_elf_generic_reloc, /* special_function */
164 "R_RISCV_TLS_DTPREL32", /* name */
165 TRUE, /* partial_inplace */
166 0, /* src_mask */
167 MINUS_ONE, /* dst_mask */
168 FALSE), /* pcrel_offset */
169
170 HOWTO (R_RISCV_TLS_DTPREL64, /* type */
171 0, /* rightshift */
172 4, /* size */
173 64, /* bitsize */
174 FALSE, /* pc_relative */
175 0, /* bitpos */
176 complain_overflow_dont, /* complain_on_overflow */
177 bfd_elf_generic_reloc, /* special_function */
178 "R_RISCV_TLS_DTPREL64", /* name */
179 TRUE, /* partial_inplace */
180 0, /* src_mask */
181 MINUS_ONE, /* dst_mask */
182 FALSE), /* pcrel_offset */
183
184 HOWTO (R_RISCV_TLS_TPREL32, /* type */
185 0, /* rightshift */
186 2, /* size */
187 32, /* bitsize */
188 FALSE, /* pc_relative */
189 0, /* bitpos */
190 complain_overflow_dont, /* complain_on_overflow */
191 bfd_elf_generic_reloc, /* special_function */
192 "R_RISCV_TLS_TPREL32", /* name */
193 FALSE, /* partial_inplace */
194 0, /* src_mask */
195 MINUS_ONE, /* dst_mask */
196 FALSE), /* pcrel_offset */
197
198 HOWTO (R_RISCV_TLS_TPREL64, /* type */
199 0, /* rightshift */
200 4, /* size */
201 64, /* bitsize */
202 FALSE, /* pc_relative */
203 0, /* bitpos */
204 complain_overflow_dont, /* complain_on_overflow */
205 bfd_elf_generic_reloc, /* special_function */
206 "R_RISCV_TLS_TPREL64", /* name */
207 FALSE, /* partial_inplace */
208 0, /* src_mask */
209 MINUS_ONE, /* dst_mask */
210 FALSE), /* pcrel_offset */
211
212 /* Reserved for future relocs that the dynamic linker must understand. */
213 EMPTY_HOWTO (12),
214 EMPTY_HOWTO (13),
215 EMPTY_HOWTO (14),
216 EMPTY_HOWTO (15),
217
218 /* 12-bit PC-relative branch offset. */
219 HOWTO (R_RISCV_BRANCH, /* type */
220 0, /* rightshift */
221 2, /* size */
222 32, /* bitsize */
223 TRUE, /* pc_relative */
224 0, /* bitpos */
225 complain_overflow_signed, /* complain_on_overflow */
226 bfd_elf_generic_reloc, /* special_function */
227 "R_RISCV_BRANCH", /* name */
228 FALSE, /* partial_inplace */
229 0, /* src_mask */
230 ENCODE_SBTYPE_IMM (-1U), /* dst_mask */
231 TRUE), /* pcrel_offset */
232
233 /* 20-bit PC-relative jump offset. */
234 HOWTO (R_RISCV_JAL, /* type */
235 0, /* rightshift */
236 2, /* size */
237 32, /* bitsize */
238 TRUE, /* pc_relative */
239 0, /* bitpos */
240 complain_overflow_dont, /* complain_on_overflow */
241 bfd_elf_generic_reloc, /* special_function */
242 "R_RISCV_JAL", /* name */
243 FALSE, /* partial_inplace */
244 0, /* src_mask */
245 ENCODE_UJTYPE_IMM (-1U), /* dst_mask */
246 TRUE), /* pcrel_offset */
247
248 /* 32-bit PC-relative function call (AUIPC/JALR). */
249 HOWTO (R_RISCV_CALL, /* type */
250 0, /* rightshift */
251 2, /* size */
252 64, /* bitsize */
253 TRUE, /* pc_relative */
254 0, /* bitpos */
255 complain_overflow_dont, /* complain_on_overflow */
256 bfd_elf_generic_reloc, /* special_function */
257 "R_RISCV_CALL", /* name */
258 FALSE, /* partial_inplace */
259 0, /* src_mask */
260 ENCODE_UTYPE_IMM (-1U) | ((bfd_vma) ENCODE_ITYPE_IMM (-1U) << 32),
261 /* dst_mask */
262 TRUE), /* pcrel_offset */
263
264 /* Like R_RISCV_CALL, but not locally binding. */
265 HOWTO (R_RISCV_CALL_PLT, /* type */
266 0, /* rightshift */
267 2, /* size */
268 64, /* bitsize */
269 TRUE, /* pc_relative */
270 0, /* bitpos */
271 complain_overflow_dont, /* complain_on_overflow */
272 bfd_elf_generic_reloc, /* special_function */
273 "R_RISCV_CALL_PLT", /* name */
274 FALSE, /* partial_inplace */
275 0, /* src_mask */
276 ENCODE_UTYPE_IMM (-1U) | ((bfd_vma) ENCODE_ITYPE_IMM (-1U) << 32),
277 /* dst_mask */
278 TRUE), /* pcrel_offset */
279
280 /* High 20 bits of 32-bit PC-relative GOT access. */
281 HOWTO (R_RISCV_GOT_HI20, /* type */
282 0, /* rightshift */
283 2, /* size */
284 32, /* bitsize */
285 TRUE, /* pc_relative */
286 0, /* bitpos */
287 complain_overflow_dont, /* complain_on_overflow */
288 bfd_elf_generic_reloc, /* special_function */
289 "R_RISCV_GOT_HI20", /* name */
290 FALSE, /* partial_inplace */
291 0, /* src_mask */
292 ENCODE_UTYPE_IMM (-1U), /* dst_mask */
293 FALSE), /* pcrel_offset */
294
295 /* High 20 bits of 32-bit PC-relative TLS IE GOT access. */
296 HOWTO (R_RISCV_TLS_GOT_HI20, /* type */
297 0, /* rightshift */
298 2, /* size */
299 32, /* bitsize */
300 TRUE, /* pc_relative */
301 0, /* bitpos */
302 complain_overflow_dont, /* complain_on_overflow */
303 bfd_elf_generic_reloc, /* special_function */
304 "R_RISCV_TLS_GOT_HI20", /* name */
305 FALSE, /* partial_inplace */
306 0, /* src_mask */
307 ENCODE_UTYPE_IMM (-1U), /* dst_mask */
308 FALSE), /* pcrel_offset */
309
310 /* High 20 bits of 32-bit PC-relative TLS GD GOT reference. */
311 HOWTO (R_RISCV_TLS_GD_HI20, /* type */
312 0, /* rightshift */
313 2, /* size */
314 32, /* bitsize */
315 TRUE, /* pc_relative */
316 0, /* bitpos */
317 complain_overflow_dont, /* complain_on_overflow */
318 bfd_elf_generic_reloc, /* special_function */
319 "R_RISCV_TLS_GD_HI20", /* name */
320 FALSE, /* partial_inplace */
321 0, /* src_mask */
322 ENCODE_UTYPE_IMM (-1U), /* dst_mask */
323 FALSE), /* pcrel_offset */
324
325 /* High 20 bits of 32-bit PC-relative reference. */
326 HOWTO (R_RISCV_PCREL_HI20, /* type */
327 0, /* rightshift */
328 2, /* size */
329 32, /* bitsize */
330 TRUE, /* pc_relative */
331 0, /* bitpos */
332 complain_overflow_dont, /* complain_on_overflow */
333 bfd_elf_generic_reloc, /* special_function */
334 "R_RISCV_PCREL_HI20", /* name */
335 FALSE, /* partial_inplace */
336 0, /* src_mask */
337 ENCODE_UTYPE_IMM (-1U), /* dst_mask */
338 TRUE), /* pcrel_offset */
339
340 /* Low 12 bits of a 32-bit PC-relative load or add. */
341 HOWTO (R_RISCV_PCREL_LO12_I, /* type */
342 0, /* rightshift */
343 2, /* size */
344 32, /* bitsize */
345 FALSE, /* pc_relative */
346 0, /* bitpos */
347 complain_overflow_dont, /* complain_on_overflow */
348 bfd_elf_generic_reloc, /* special_function */
349 "R_RISCV_PCREL_LO12_I", /* name */
350 FALSE, /* partial_inplace */
351 0, /* src_mask */
352 ENCODE_ITYPE_IMM (-1U), /* dst_mask */
353 FALSE), /* pcrel_offset */
354
355 /* Low 12 bits of a 32-bit PC-relative store. */
356 HOWTO (R_RISCV_PCREL_LO12_S, /* type */
357 0, /* rightshift */
358 2, /* size */
359 32, /* bitsize */
360 FALSE, /* pc_relative */
361 0, /* bitpos */
362 complain_overflow_dont, /* complain_on_overflow */
363 bfd_elf_generic_reloc, /* special_function */
364 "R_RISCV_PCREL_LO12_S", /* name */
365 FALSE, /* partial_inplace */
366 0, /* src_mask */
367 ENCODE_STYPE_IMM (-1U), /* dst_mask */
368 FALSE), /* pcrel_offset */
369
370 /* High 20 bits of 32-bit absolute address. */
371 HOWTO (R_RISCV_HI20, /* type */
372 0, /* rightshift */
373 2, /* size */
374 32, /* bitsize */
375 FALSE, /* pc_relative */
376 0, /* bitpos */
377 complain_overflow_dont, /* complain_on_overflow */
378 bfd_elf_generic_reloc, /* special_function */
379 "R_RISCV_HI20", /* name */
380 FALSE, /* partial_inplace */
381 0, /* src_mask */
382 ENCODE_UTYPE_IMM (-1U), /* dst_mask */
383 FALSE), /* pcrel_offset */
384
385 /* High 12 bits of 32-bit load or add. */
386 HOWTO (R_RISCV_LO12_I, /* type */
387 0, /* rightshift */
388 2, /* size */
389 32, /* bitsize */
390 FALSE, /* pc_relative */
391 0, /* bitpos */
392 complain_overflow_dont, /* complain_on_overflow */
393 bfd_elf_generic_reloc, /* special_function */
394 "R_RISCV_LO12_I", /* name */
395 FALSE, /* partial_inplace */
396 0, /* src_mask */
397 ENCODE_ITYPE_IMM (-1U), /* dst_mask */
398 FALSE), /* pcrel_offset */
399
400 /* High 12 bits of 32-bit store. */
401 HOWTO (R_RISCV_LO12_S, /* type */
402 0, /* rightshift */
403 2, /* size */
404 32, /* bitsize */
405 FALSE, /* pc_relative */
406 0, /* bitpos */
407 complain_overflow_dont, /* complain_on_overflow */
408 bfd_elf_generic_reloc, /* special_function */
409 "R_RISCV_LO12_S", /* name */
410 FALSE, /* partial_inplace */
411 0, /* src_mask */
412 ENCODE_STYPE_IMM (-1U), /* dst_mask */
413 FALSE), /* pcrel_offset */
414
415 /* High 20 bits of TLS LE thread pointer offset. */
416 HOWTO (R_RISCV_TPREL_HI20, /* type */
417 0, /* rightshift */
418 2, /* size */
419 32, /* bitsize */
420 FALSE, /* pc_relative */
421 0, /* bitpos */
422 complain_overflow_signed, /* complain_on_overflow */
423 bfd_elf_generic_reloc, /* special_function */
424 "R_RISCV_TPREL_HI20", /* name */
425 TRUE, /* partial_inplace */
426 0, /* src_mask */
427 ENCODE_UTYPE_IMM (-1U), /* dst_mask */
428 FALSE), /* pcrel_offset */
429
430 /* Low 12 bits of TLS LE thread pointer offset for loads and adds. */
431 HOWTO (R_RISCV_TPREL_LO12_I, /* type */
432 0, /* rightshift */
433 2, /* size */
434 32, /* bitsize */
435 FALSE, /* pc_relative */
436 0, /* bitpos */
437 complain_overflow_signed, /* complain_on_overflow */
438 bfd_elf_generic_reloc, /* special_function */
439 "R_RISCV_TPREL_LO12_I", /* name */
440 FALSE, /* partial_inplace */
441 0, /* src_mask */
442 ENCODE_ITYPE_IMM (-1U), /* dst_mask */
443 FALSE), /* pcrel_offset */
444
445 /* Low 12 bits of TLS LE thread pointer offset for stores. */
446 HOWTO (R_RISCV_TPREL_LO12_S, /* type */
447 0, /* rightshift */
448 2, /* size */
449 32, /* bitsize */
450 FALSE, /* pc_relative */
451 0, /* bitpos */
452 complain_overflow_signed, /* complain_on_overflow */
453 bfd_elf_generic_reloc, /* special_function */
454 "R_RISCV_TPREL_LO12_S", /* name */
455 FALSE, /* partial_inplace */
456 0, /* src_mask */
457 ENCODE_STYPE_IMM (-1U), /* dst_mask */
458 FALSE), /* pcrel_offset */
459
460 /* TLS LE thread pointer usage. May be relaxed. */
461 HOWTO (R_RISCV_TPREL_ADD, /* type */
462 0, /* rightshift */
463 2, /* size */
464 32, /* bitsize */
465 FALSE, /* pc_relative */
466 0, /* bitpos */
467 complain_overflow_dont, /* complain_on_overflow */
468 bfd_elf_generic_reloc, /* special_function */
469 "R_RISCV_TPREL_ADD", /* name */
470 TRUE, /* partial_inplace */
471 0, /* src_mask */
472 0, /* dst_mask */
473 FALSE), /* pcrel_offset */
474
475 /* 8-bit in-place addition, for local label subtraction. */
476 HOWTO (R_RISCV_ADD8, /* type */
477 0, /* rightshift */
478 0, /* size */
479 8, /* bitsize */
480 FALSE, /* pc_relative */
481 0, /* bitpos */
482 complain_overflow_dont, /* complain_on_overflow */
483 bfd_elf_generic_reloc, /* special_function */
484 "R_RISCV_ADD8", /* name */
485 FALSE, /* partial_inplace */
486 0, /* src_mask */
487 MINUS_ONE, /* dst_mask */
488 FALSE), /* pcrel_offset */
489
490 /* 16-bit in-place addition, for local label subtraction. */
491 HOWTO (R_RISCV_ADD16, /* type */
492 0, /* rightshift */
493 1, /* size */
494 16, /* bitsize */
495 FALSE, /* pc_relative */
496 0, /* bitpos */
497 complain_overflow_dont, /* complain_on_overflow */
498 bfd_elf_generic_reloc, /* special_function */
499 "R_RISCV_ADD16", /* name */
500 FALSE, /* partial_inplace */
501 0, /* src_mask */
502 MINUS_ONE, /* dst_mask */
503 FALSE), /* pcrel_offset */
504
505 /* 32-bit in-place addition, for local label subtraction. */
506 HOWTO (R_RISCV_ADD32, /* type */
507 0, /* rightshift */
508 2, /* size */
509 32, /* bitsize */
510 FALSE, /* pc_relative */
511 0, /* bitpos */
512 complain_overflow_dont, /* complain_on_overflow */
513 bfd_elf_generic_reloc, /* special_function */
514 "R_RISCV_ADD32", /* name */
515 FALSE, /* partial_inplace */
516 0, /* src_mask */
517 MINUS_ONE, /* dst_mask */
518 FALSE), /* pcrel_offset */
519
520 /* 64-bit in-place addition, for local label subtraction. */
521 HOWTO (R_RISCV_ADD64, /* type */
522 0, /* rightshift */
523 4, /* size */
524 64, /* bitsize */
525 FALSE, /* pc_relative */
526 0, /* bitpos */
527 complain_overflow_dont, /* complain_on_overflow */
528 bfd_elf_generic_reloc, /* special_function */
529 "R_RISCV_ADD64", /* name */
530 FALSE, /* partial_inplace */
531 0, /* src_mask */
532 MINUS_ONE, /* dst_mask */
533 FALSE), /* pcrel_offset */
534
535 /* 8-bit in-place addition, for local label subtraction. */
536 HOWTO (R_RISCV_SUB8, /* type */
537 0, /* rightshift */
538 0, /* size */
539 8, /* bitsize */
540 FALSE, /* pc_relative */
541 0, /* bitpos */
542 complain_overflow_dont, /* complain_on_overflow */
543 bfd_elf_generic_reloc, /* special_function */
544 "R_RISCV_SUB8", /* name */
545 FALSE, /* partial_inplace */
546 0, /* src_mask */
547 MINUS_ONE, /* dst_mask */
548 FALSE), /* pcrel_offset */
549
550 /* 16-bit in-place addition, for local label subtraction. */
551 HOWTO (R_RISCV_SUB16, /* type */
552 0, /* rightshift */
553 1, /* size */
554 16, /* bitsize */
555 FALSE, /* pc_relative */
556 0, /* bitpos */
557 complain_overflow_dont, /* complain_on_overflow */
558 bfd_elf_generic_reloc, /* special_function */
559 "R_RISCV_SUB16", /* name */
560 FALSE, /* partial_inplace */
561 0, /* src_mask */
562 MINUS_ONE, /* dst_mask */
563 FALSE), /* pcrel_offset */
564
565 /* 32-bit in-place addition, for local label subtraction. */
566 HOWTO (R_RISCV_SUB32, /* type */
567 0, /* rightshift */
568 2, /* size */
569 32, /* bitsize */
570 FALSE, /* pc_relative */
571 0, /* bitpos */
572 complain_overflow_dont, /* complain_on_overflow */
573 bfd_elf_generic_reloc, /* special_function */
574 "R_RISCV_SUB32", /* name */
575 FALSE, /* partial_inplace */
576 0, /* src_mask */
577 MINUS_ONE, /* dst_mask */
578 FALSE), /* pcrel_offset */
579
580 /* 64-bit in-place addition, for local label subtraction. */
581 HOWTO (R_RISCV_SUB64, /* type */
582 0, /* rightshift */
583 4, /* size */
584 64, /* bitsize */
585 FALSE, /* pc_relative */
586 0, /* bitpos */
587 complain_overflow_dont, /* complain_on_overflow */
588 bfd_elf_generic_reloc, /* special_function */
589 "R_RISCV_SUB64", /* name */
590 FALSE, /* partial_inplace */
591 0, /* src_mask */
592 MINUS_ONE, /* dst_mask */
593 FALSE), /* pcrel_offset */
594
595 /* GNU extension to record C++ vtable hierarchy */
596 HOWTO (R_RISCV_GNU_VTINHERIT, /* type */
597 0, /* rightshift */
598 4, /* size */
599 0, /* bitsize */
600 FALSE, /* pc_relative */
601 0, /* bitpos */
602 complain_overflow_dont, /* complain_on_overflow */
603 NULL, /* special_function */
604 "R_RISCV_GNU_VTINHERIT", /* name */
605 FALSE, /* partial_inplace */
606 0, /* src_mask */
607 0, /* dst_mask */
608 FALSE), /* pcrel_offset */
609
610 /* GNU extension to record C++ vtable member usage */
611 HOWTO (R_RISCV_GNU_VTENTRY, /* type */
612 0, /* rightshift */
613 4, /* size */
614 0, /* bitsize */
615 FALSE, /* pc_relative */
616 0, /* bitpos */
617 complain_overflow_dont, /* complain_on_overflow */
618 _bfd_elf_rel_vtable_reloc_fn, /* special_function */
619 "R_RISCV_GNU_VTENTRY", /* name */
620 FALSE, /* partial_inplace */
621 0, /* src_mask */
622 0, /* dst_mask */
623 FALSE), /* pcrel_offset */
624
625 /* Indicates an alignment statement. The addend field encodes how many
626 bytes of NOPs follow the statement. The desired alignment is the
627 addend rounded up to the next power of two. */
628 HOWTO (R_RISCV_ALIGN, /* type */
629 0, /* rightshift */
630 2, /* size */
631 0, /* bitsize */
632 FALSE, /* pc_relative */
633 0, /* bitpos */
634 complain_overflow_dont, /* complain_on_overflow */
635 bfd_elf_generic_reloc, /* special_function */
636 "R_RISCV_ALIGN", /* name */
637 FALSE, /* partial_inplace */
638 0, /* src_mask */
639 0, /* dst_mask */
640 TRUE), /* pcrel_offset */
641
642 /* 8-bit PC-relative branch offset. */
643 HOWTO (R_RISCV_RVC_BRANCH, /* type */
644 0, /* rightshift */
645 2, /* size */
646 32, /* bitsize */
647 TRUE, /* pc_relative */
648 0, /* bitpos */
649 complain_overflow_signed, /* complain_on_overflow */
650 bfd_elf_generic_reloc, /* special_function */
651 "R_RISCV_RVC_BRANCH", /* name */
652 FALSE, /* partial_inplace */
653 0, /* src_mask */
654 ENCODE_RVC_B_IMM (-1U), /* dst_mask */
655 TRUE), /* pcrel_offset */
656
657 /* 11-bit PC-relative jump offset. */
658 HOWTO (R_RISCV_RVC_JUMP, /* type */
659 0, /* rightshift */
660 2, /* size */
661 32, /* bitsize */
662 TRUE, /* pc_relative */
663 0, /* bitpos */
664 complain_overflow_dont, /* complain_on_overflow */
665 bfd_elf_generic_reloc, /* special_function */
666 "R_RISCV_RVC_JUMP", /* name */
667 FALSE, /* partial_inplace */
668 0, /* src_mask */
669 ENCODE_RVC_J_IMM (-1U), /* dst_mask */
670 TRUE), /* pcrel_offset */
671
672 /* High 6 bits of 18-bit absolute address. */
673 HOWTO (R_RISCV_RVC_LUI, /* type */
674 0, /* rightshift */
675 2, /* size */
676 32, /* bitsize */
677 FALSE, /* pc_relative */
678 0, /* bitpos */
679 complain_overflow_dont, /* complain_on_overflow */
680 bfd_elf_generic_reloc, /* special_function */
681 "R_RISCV_RVC_LUI", /* name */
682 FALSE, /* partial_inplace */
683 0, /* src_mask */
684 ENCODE_RVC_IMM (-1U), /* dst_mask */
685 FALSE), /* pcrel_offset */
686
687 /* GP-relative load. */
688 HOWTO (R_RISCV_GPREL_I, /* type */
689 0, /* rightshift */
690 2, /* size */
691 32, /* bitsize */
692 FALSE, /* pc_relative */
693 0, /* bitpos */
694 complain_overflow_dont, /* complain_on_overflow */
695 bfd_elf_generic_reloc, /* special_function */
696 "R_RISCV_GPREL_I", /* name */
697 FALSE, /* partial_inplace */
698 0, /* src_mask */
699 ENCODE_ITYPE_IMM (-1U), /* dst_mask */
700 FALSE), /* pcrel_offset */
701
702 /* GP-relative store. */
703 HOWTO (R_RISCV_GPREL_S, /* type */
704 0, /* rightshift */
705 2, /* size */
706 32, /* bitsize */
707 FALSE, /* pc_relative */
708 0, /* bitpos */
709 complain_overflow_dont, /* complain_on_overflow */
710 bfd_elf_generic_reloc, /* special_function */
711 "R_RISCV_GPREL_S", /* name */
712 FALSE, /* partial_inplace */
713 0, /* src_mask */
714 ENCODE_STYPE_IMM (-1U), /* dst_mask */
715 FALSE), /* pcrel_offset */
716
717 /* TP-relative TLS LE load. */
718 HOWTO (R_RISCV_TPREL_I, /* type */
719 0, /* rightshift */
720 2, /* size */
721 32, /* bitsize */
722 FALSE, /* pc_relative */
723 0, /* bitpos */
724 complain_overflow_signed, /* complain_on_overflow */
725 bfd_elf_generic_reloc, /* special_function */
726 "R_RISCV_TPREL_I", /* name */
727 FALSE, /* partial_inplace */
728 0, /* src_mask */
729 ENCODE_ITYPE_IMM (-1U), /* dst_mask */
730 FALSE), /* pcrel_offset */
731
732 /* TP-relative TLS LE store. */
733 HOWTO (R_RISCV_TPREL_S, /* type */
734 0, /* rightshift */
735 2, /* size */
736 32, /* bitsize */
737 FALSE, /* pc_relative */
738 0, /* bitpos */
739 complain_overflow_signed, /* complain_on_overflow */
740 bfd_elf_generic_reloc, /* special_function */
741 "R_RISCV_TPREL_S", /* name */
742 FALSE, /* partial_inplace */
743 0, /* src_mask */
744 ENCODE_STYPE_IMM (-1U), /* dst_mask */
745 FALSE), /* pcrel_offset */
746
747 /* The paired relocation may be relaxed. */
748 HOWTO (R_RISCV_RELAX, /* type */
749 0, /* rightshift */
750 3, /* size */
751 0, /* bitsize */
752 FALSE, /* pc_relative */
753 0, /* bitpos */
754 complain_overflow_dont, /* complain_on_overflow */
755 bfd_elf_generic_reloc, /* special_function */
756 "R_RISCV_RELAX", /* name */
757 FALSE, /* partial_inplace */
758 0, /* src_mask */
759 0, /* dst_mask */
760 FALSE), /* pcrel_offset */
761
762 /* 6-bit in-place addition, for local label subtraction. */
763 HOWTO (R_RISCV_SUB6, /* type */
764 0, /* rightshift */
765 0, /* size */
766 8, /* bitsize */
767 FALSE, /* pc_relative */
768 0, /* bitpos */
769 complain_overflow_dont, /* complain_on_overflow */
770 bfd_elf_generic_reloc, /* special_function */
771 "R_RISCV_SUB6", /* name */
772 FALSE, /* partial_inplace */
773 0, /* src_mask */
774 0x3f, /* dst_mask */
775 FALSE), /* pcrel_offset */
776
777 /* 6-bit in-place setting, for local label subtraction. */
778 HOWTO (R_RISCV_SET6, /* type */
779 0, /* rightshift */
780 0, /* size */
781 8, /* bitsize */
782 FALSE, /* pc_relative */
783 0, /* bitpos */
784 complain_overflow_dont, /* complain_on_overflow */
785 bfd_elf_generic_reloc, /* special_function */
786 "R_RISCV_SET6", /* name */
787 FALSE, /* partial_inplace */
788 0, /* src_mask */
789 0x3f, /* dst_mask */
790 FALSE), /* pcrel_offset */
791
792 /* 8-bit in-place setting, for local label subtraction. */
793 HOWTO (R_RISCV_SET8, /* type */
794 0, /* rightshift */
795 0, /* size */
796 8, /* bitsize */
797 FALSE, /* pc_relative */
798 0, /* bitpos */
799 complain_overflow_dont, /* complain_on_overflow */
800 bfd_elf_generic_reloc, /* special_function */
801 "R_RISCV_SET8", /* name */
802 FALSE, /* partial_inplace */
803 0, /* src_mask */
804 MINUS_ONE, /* dst_mask */
805 FALSE), /* pcrel_offset */
806
807 /* 16-bit in-place setting, for local label subtraction. */
808 HOWTO (R_RISCV_SET16, /* type */
809 0, /* rightshift */
810 1, /* size */
811 16, /* bitsize */
812 FALSE, /* pc_relative */
813 0, /* bitpos */
814 complain_overflow_dont, /* complain_on_overflow */
815 bfd_elf_generic_reloc, /* special_function */
816 "R_RISCV_SET16", /* name */
817 FALSE, /* partial_inplace */
818 0, /* src_mask */
819 MINUS_ONE, /* dst_mask */
820 FALSE), /* pcrel_offset */
821
822 /* 32-bit in-place setting, for local label subtraction. */
823 HOWTO (R_RISCV_SET32, /* type */
824 0, /* rightshift */
825 2, /* size */
826 32, /* bitsize */
827 FALSE, /* pc_relative */
828 0, /* bitpos */
829 complain_overflow_dont, /* complain_on_overflow */
830 bfd_elf_generic_reloc, /* special_function */
831 "R_RISCV_SET32", /* name */
832 FALSE, /* partial_inplace */
833 0, /* src_mask */
834 MINUS_ONE, /* dst_mask */
835 FALSE), /* pcrel_offset */
836 };
837
838 /* A mapping from BFD reloc types to RISC-V ELF reloc types. */
839
840 struct elf_reloc_map
841 {
842 bfd_reloc_code_real_type bfd_val;
843 enum elf_riscv_reloc_type elf_val;
844 };
845
846 static const struct elf_reloc_map riscv_reloc_map[] =
847 {
848 { BFD_RELOC_NONE, R_RISCV_NONE },
849 { BFD_RELOC_32, R_RISCV_32 },
850 { BFD_RELOC_64, R_RISCV_64 },
851 { BFD_RELOC_RISCV_ADD8, R_RISCV_ADD8 },
852 { BFD_RELOC_RISCV_ADD16, R_RISCV_ADD16 },
853 { BFD_RELOC_RISCV_ADD32, R_RISCV_ADD32 },
854 { BFD_RELOC_RISCV_ADD64, R_RISCV_ADD64 },
855 { BFD_RELOC_RISCV_SUB8, R_RISCV_SUB8 },
856 { BFD_RELOC_RISCV_SUB16, R_RISCV_SUB16 },
857 { BFD_RELOC_RISCV_SUB32, R_RISCV_SUB32 },
858 { BFD_RELOC_RISCV_SUB64, R_RISCV_SUB64 },
859 { BFD_RELOC_CTOR, R_RISCV_64 },
860 { BFD_RELOC_12_PCREL, R_RISCV_BRANCH },
861 { BFD_RELOC_RISCV_HI20, R_RISCV_HI20 },
862 { BFD_RELOC_RISCV_LO12_I, R_RISCV_LO12_I },
863 { BFD_RELOC_RISCV_LO12_S, R_RISCV_LO12_S },
864 { BFD_RELOC_RISCV_PCREL_LO12_I, R_RISCV_PCREL_LO12_I },
865 { BFD_RELOC_RISCV_PCREL_LO12_S, R_RISCV_PCREL_LO12_S },
866 { BFD_RELOC_RISCV_CALL, R_RISCV_CALL },
867 { BFD_RELOC_RISCV_CALL_PLT, R_RISCV_CALL_PLT },
868 { BFD_RELOC_RISCV_PCREL_HI20, R_RISCV_PCREL_HI20 },
869 { BFD_RELOC_RISCV_JMP, R_RISCV_JAL },
870 { BFD_RELOC_RISCV_GOT_HI20, R_RISCV_GOT_HI20 },
871 { BFD_RELOC_RISCV_TLS_DTPMOD32, R_RISCV_TLS_DTPMOD32 },
872 { BFD_RELOC_RISCV_TLS_DTPREL32, R_RISCV_TLS_DTPREL32 },
873 { BFD_RELOC_RISCV_TLS_DTPMOD64, R_RISCV_TLS_DTPMOD64 },
874 { BFD_RELOC_RISCV_TLS_DTPREL64, R_RISCV_TLS_DTPREL64 },
875 { BFD_RELOC_RISCV_TLS_TPREL32, R_RISCV_TLS_TPREL32 },
876 { BFD_RELOC_RISCV_TLS_TPREL64, R_RISCV_TLS_TPREL64 },
877 { BFD_RELOC_RISCV_TPREL_HI20, R_RISCV_TPREL_HI20 },
878 { BFD_RELOC_RISCV_TPREL_ADD, R_RISCV_TPREL_ADD },
879 { BFD_RELOC_RISCV_TPREL_LO12_S, R_RISCV_TPREL_LO12_S },
880 { BFD_RELOC_RISCV_TPREL_LO12_I, R_RISCV_TPREL_LO12_I },
881 { BFD_RELOC_RISCV_TLS_GOT_HI20, R_RISCV_TLS_GOT_HI20 },
882 { BFD_RELOC_RISCV_TLS_GD_HI20, R_RISCV_TLS_GD_HI20 },
883 { BFD_RELOC_RISCV_ALIGN, R_RISCV_ALIGN },
884 { BFD_RELOC_RISCV_RVC_BRANCH, R_RISCV_RVC_BRANCH },
885 { BFD_RELOC_RISCV_RVC_JUMP, R_RISCV_RVC_JUMP },
886 { BFD_RELOC_RISCV_RVC_LUI, R_RISCV_RVC_LUI },
887 { BFD_RELOC_RISCV_GPREL_I, R_RISCV_GPREL_I },
888 { BFD_RELOC_RISCV_GPREL_S, R_RISCV_GPREL_S },
889 { BFD_RELOC_RISCV_TPREL_I, R_RISCV_TPREL_I },
890 { BFD_RELOC_RISCV_TPREL_S, R_RISCV_TPREL_S },
891 { BFD_RELOC_RISCV_RELAX, R_RISCV_RELAX },
892 { BFD_RELOC_RISCV_SUB6, R_RISCV_SUB6 },
893 { BFD_RELOC_RISCV_SET6, R_RISCV_SET6 },
894 { BFD_RELOC_RISCV_SET8, R_RISCV_SET8 },
895 { BFD_RELOC_RISCV_SET16, R_RISCV_SET16 },
896 { BFD_RELOC_RISCV_SET32, R_RISCV_SET32 },
897 };
898
899 /* Given a BFD reloc type, return a howto structure. */
900
901 reloc_howto_type *
902 riscv_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
903 bfd_reloc_code_real_type code)
904 {
905 unsigned int i;
906
907 for (i = 0; i < ARRAY_SIZE (riscv_reloc_map); i++)
908 if (riscv_reloc_map[i].bfd_val == code)
909 return &howto_table[(int) riscv_reloc_map[i].elf_val];
910
911 bfd_set_error (bfd_error_bad_value);
912 return NULL;
913 }
914
915 reloc_howto_type *
916 riscv_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name)
917 {
918 unsigned int i;
919
920 for (i = 0; i < ARRAY_SIZE (howto_table); i++)
921 if (howto_table[i].name && strcasecmp (howto_table[i].name, r_name) == 0)
922 return &howto_table[i];
923
924 return NULL;
925 }
926
927 reloc_howto_type *
928 riscv_elf_rtype_to_howto (unsigned int r_type)
929 {
930 if (r_type >= ARRAY_SIZE (howto_table))
931 {
932 (*_bfd_error_handler) (_("unrecognized relocation (0x%x)"), r_type);
933 bfd_set_error (bfd_error_bad_value);
934 return NULL;
935 }
936 return &howto_table[r_type];
937 }
This page took 0.0499 seconds and 5 git commands to generate.