1 /* RISC-V-specific support for ELF.
2 Copyright 2011-2016 Free Software Foundation, Inc.
4 Contributed by Andrew Waterman (andrew@sifive.com).
5 Based on TILE-Gx and MIPS targets.
7 This file is part of BFD, the Binary File Descriptor library.
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.
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.
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/>. */
27 #include "elf/riscv.h"
28 #include "opcode/riscv.h"
29 #include "libiberty.h"
30 #include "elfxx-riscv.h"
33 #define MINUS_ONE ((bfd_vma)0 - 1)
35 /* The relocation table used for SHT_RELA sections. */
37 static reloc_howto_type howto_table[] =
40 HOWTO (R_RISCV_NONE, /* type */
44 FALSE, /* pc_relative */
46 complain_overflow_dont, /* complain_on_overflow */
47 bfd_elf_generic_reloc, /* special_function */
48 "R_RISCV_NONE", /* name */
49 FALSE, /* partial_inplace */
52 FALSE), /* pcrel_offset */
54 /* 32 bit relocation. */
55 HOWTO (R_RISCV_32, /* type */
59 FALSE, /* pc_relative */
61 complain_overflow_dont, /* complain_on_overflow */
62 bfd_elf_generic_reloc, /* special_function */
63 "R_RISCV_32", /* name */
64 FALSE, /* partial_inplace */
66 0xffffffff, /* dst_mask */
67 FALSE), /* pcrel_offset */
69 /* 64 bit relocation. */
70 HOWTO (R_RISCV_64, /* type */
74 FALSE, /* pc_relative */
76 complain_overflow_dont, /* complain_on_overflow */
77 bfd_elf_generic_reloc, /* special_function */
78 "R_RISCV_64", /* name */
79 FALSE, /* partial_inplace */
81 MINUS_ONE, /* dst_mask */
82 FALSE), /* pcrel_offset */
84 /* Relocation against a local symbol in a shared object. */
85 HOWTO (R_RISCV_RELATIVE, /* type */
89 FALSE, /* pc_relative */
91 complain_overflow_dont, /* complain_on_overflow */
92 bfd_elf_generic_reloc, /* special_function */
93 "R_RISCV_RELATIVE", /* name */
94 FALSE, /* partial_inplace */
96 0xffffffff, /* dst_mask */
97 FALSE), /* pcrel_offset */
99 HOWTO (R_RISCV_COPY, /* type */
101 0, /* this one is variable size */
103 FALSE, /* pc_relative */
105 complain_overflow_bitfield, /* complain_on_overflow */
106 bfd_elf_generic_reloc, /* special_function */
107 "R_RISCV_COPY", /* name */
108 FALSE, /* partial_inplace */
111 FALSE), /* pcrel_offset */
113 HOWTO (R_RISCV_JUMP_SLOT, /* type */
117 FALSE, /* pc_relative */
119 complain_overflow_bitfield, /* complain_on_overflow */
120 bfd_elf_generic_reloc, /* special_function */
121 "R_RISCV_JUMP_SLOT", /* name */
122 FALSE, /* partial_inplace */
125 FALSE), /* pcrel_offset */
127 /* Dynamic TLS relocations. */
128 HOWTO (R_RISCV_TLS_DTPMOD32, /* type */
132 FALSE, /* pc_relative */
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 MINUS_ONE, /* src_mask */
139 MINUS_ONE, /* dst_mask */
140 FALSE), /* pcrel_offset */
142 HOWTO (R_RISCV_TLS_DTPMOD64, /* type */
146 FALSE, /* pc_relative */
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 MINUS_ONE, /* src_mask */
153 MINUS_ONE, /* dst_mask */
154 FALSE), /* pcrel_offset */
156 HOWTO (R_RISCV_TLS_DTPREL32, /* type */
160 FALSE, /* pc_relative */
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 MINUS_ONE, /* src_mask */
167 MINUS_ONE, /* dst_mask */
168 FALSE), /* pcrel_offset */
170 HOWTO (R_RISCV_TLS_DTPREL64, /* type */
174 FALSE, /* pc_relative */
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 MINUS_ONE, /* src_mask */
181 MINUS_ONE, /* dst_mask */
182 FALSE), /* pcrel_offset */
184 HOWTO (R_RISCV_TLS_TPREL32, /* type */
188 FALSE, /* pc_relative */
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 MINUS_ONE, /* src_mask */
195 MINUS_ONE, /* dst_mask */
196 FALSE), /* pcrel_offset */
198 HOWTO (R_RISCV_TLS_TPREL64, /* type */
202 FALSE, /* pc_relative */
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 MINUS_ONE, /* src_mask */
209 MINUS_ONE, /* dst_mask */
210 FALSE), /* pcrel_offset */
212 /* Reserved for future relocs that the dynamic linker must understand. */
218 /* 12-bit PC-relative branch offset. */
219 HOWTO (R_RISCV_BRANCH, /* type */
223 TRUE, /* pc_relative */
225 complain_overflow_signed, /* complain_on_overflow */
226 bfd_elf_generic_reloc, /* special_function */
227 "R_RISCV_BRANCH", /* name */
228 FALSE, /* partial_inplace */
230 ENCODE_SBTYPE_IMM (-1U), /* dst_mask */
231 TRUE), /* pcrel_offset */
233 /* 20-bit PC-relative jump offset. */
234 HOWTO (R_RISCV_JAL, /* type */
238 TRUE, /* pc_relative */
240 complain_overflow_dont, /* complain_on_overflow */
241 /* This needs complex overflow
242 detection, because the upper 36
243 bits must match the PC + 4. */
244 bfd_elf_generic_reloc, /* special_function */
245 "R_RISCV_JAL", /* name */
246 FALSE, /* partial_inplace */
248 ENCODE_UJTYPE_IMM (-1U), /* dst_mask */
249 TRUE), /* pcrel_offset */
251 /* 32-bit PC-relative function call (AUIPC/JALR). */
252 HOWTO (R_RISCV_CALL, /* type */
256 TRUE, /* pc_relative */
258 complain_overflow_dont, /* complain_on_overflow */
259 bfd_elf_generic_reloc, /* special_function */
260 "R_RISCV_CALL", /* name */
261 FALSE, /* partial_inplace */
263 ENCODE_UTYPE_IMM (-1U) | ((bfd_vma) ENCODE_ITYPE_IMM (-1U) << 32),
265 TRUE), /* pcrel_offset */
267 /* 32-bit PC-relative function call (AUIPC/JALR). */
268 HOWTO (R_RISCV_CALL_PLT, /* type */
272 TRUE, /* pc_relative */
274 complain_overflow_dont, /* complain_on_overflow */
275 bfd_elf_generic_reloc, /* special_function */
276 "R_RISCV_CALL_PLT", /* name */
277 FALSE, /* partial_inplace */
279 ENCODE_UTYPE_IMM (-1U) | ((bfd_vma) ENCODE_ITYPE_IMM (-1U) << 32),
281 TRUE), /* pcrel_offset */
283 /* High 20 bits of 32-bit PC-relative GOT access. */
284 HOWTO (R_RISCV_GOT_HI20, /* type */
288 TRUE, /* pc_relative */
290 complain_overflow_dont, /* complain_on_overflow */
291 bfd_elf_generic_reloc, /* special_function */
292 "R_RISCV_GOT_HI20", /* name */
293 FALSE, /* partial_inplace */
295 ENCODE_UTYPE_IMM (-1U), /* dst_mask */
296 FALSE), /* pcrel_offset */
298 /* High 20 bits of 32-bit PC-relative TLS IE GOT access. */
299 HOWTO (R_RISCV_TLS_GOT_HI20, /* type */
303 TRUE, /* pc_relative */
305 complain_overflow_dont, /* complain_on_overflow */
306 bfd_elf_generic_reloc, /* special_function */
307 "R_RISCV_TLS_GOT_HI20", /* name */
308 FALSE, /* partial_inplace */
310 ENCODE_UTYPE_IMM (-1U), /* dst_mask */
311 FALSE), /* pcrel_offset */
313 /* High 20 bits of 32-bit PC-relative TLS GD GOT reference. */
314 HOWTO (R_RISCV_TLS_GD_HI20, /* type */
318 TRUE, /* pc_relative */
320 complain_overflow_dont, /* complain_on_overflow */
321 bfd_elf_generic_reloc, /* special_function */
322 "R_RISCV_TLS_GD_HI20", /* name */
323 FALSE, /* partial_inplace */
325 ENCODE_UTYPE_IMM (-1U), /* dst_mask */
326 FALSE), /* pcrel_offset */
328 /* High 20 bits of 32-bit PC-relative reference. */
329 HOWTO (R_RISCV_PCREL_HI20, /* type */
333 TRUE, /* pc_relative */
335 complain_overflow_dont, /* complain_on_overflow */
336 bfd_elf_generic_reloc, /* special_function */
337 "R_RISCV_PCREL_HI20", /* name */
338 FALSE, /* partial_inplace */
340 ENCODE_UTYPE_IMM (-1U), /* dst_mask */
341 TRUE), /* pcrel_offset */
343 /* Low 12 bits of a 32-bit PC-relative load or add. */
344 HOWTO (R_RISCV_PCREL_LO12_I, /* type */
348 FALSE, /* pc_relative */
350 complain_overflow_dont, /* complain_on_overflow */
351 bfd_elf_generic_reloc, /* special_function */
352 "R_RISCV_PCREL_LO12_I", /* name */
353 FALSE, /* partial_inplace */
355 ENCODE_ITYPE_IMM (-1U), /* dst_mask */
356 FALSE), /* pcrel_offset */
358 /* Low 12 bits of a 32-bit PC-relative store. */
359 HOWTO (R_RISCV_PCREL_LO12_S, /* type */
363 FALSE, /* pc_relative */
365 complain_overflow_dont, /* complain_on_overflow */
366 bfd_elf_generic_reloc, /* special_function */
367 "R_RISCV_PCREL_LO12_S", /* name */
368 FALSE, /* partial_inplace */
370 ENCODE_STYPE_IMM (-1U), /* dst_mask */
371 FALSE), /* pcrel_offset */
373 /* High 20 bits of 32-bit absolute address. */
374 HOWTO (R_RISCV_HI20, /* type */
378 FALSE, /* pc_relative */
380 complain_overflow_dont, /* complain_on_overflow */
381 bfd_elf_generic_reloc, /* special_function */
382 "R_RISCV_HI20", /* name */
383 FALSE, /* partial_inplace */
385 ENCODE_UTYPE_IMM (-1U), /* dst_mask */
386 FALSE), /* pcrel_offset */
388 /* High 12 bits of 32-bit load or add. */
389 HOWTO (R_RISCV_LO12_I, /* type */
393 FALSE, /* pc_relative */
395 complain_overflow_dont, /* complain_on_overflow */
396 bfd_elf_generic_reloc, /* special_function */
397 "R_RISCV_LO12_I", /* name */
398 FALSE, /* partial_inplace */
400 ENCODE_ITYPE_IMM (-1U), /* dst_mask */
401 FALSE), /* pcrel_offset */
403 /* High 12 bits of 32-bit store. */
404 HOWTO (R_RISCV_LO12_S, /* type */
408 FALSE, /* pc_relative */
410 complain_overflow_dont, /* complain_on_overflow */
411 bfd_elf_generic_reloc, /* special_function */
412 "R_RISCV_LO12_S", /* name */
413 FALSE, /* partial_inplace */
415 ENCODE_STYPE_IMM (-1U), /* dst_mask */
416 FALSE), /* pcrel_offset */
418 /* High 20 bits of TLS LE thread pointer offset. */
419 HOWTO (R_RISCV_TPREL_HI20, /* type */
423 FALSE, /* pc_relative */
425 complain_overflow_signed, /* complain_on_overflow */
426 bfd_elf_generic_reloc, /* special_function */
427 "R_RISCV_TPREL_HI20", /* name */
428 TRUE, /* partial_inplace */
430 ENCODE_UTYPE_IMM (-1U), /* dst_mask */
431 FALSE), /* pcrel_offset */
433 /* Low 12 bits of TLS LE thread pointer offset for loads and adds. */
434 HOWTO (R_RISCV_TPREL_LO12_I, /* type */
438 FALSE, /* pc_relative */
440 complain_overflow_signed, /* complain_on_overflow */
441 bfd_elf_generic_reloc, /* special_function */
442 "R_RISCV_TPREL_LO12_I", /* name */
443 FALSE, /* partial_inplace */
445 ENCODE_ITYPE_IMM (-1U), /* dst_mask */
446 FALSE), /* pcrel_offset */
448 /* Low 12 bits of TLS LE thread pointer offset for stores. */
449 HOWTO (R_RISCV_TPREL_LO12_S, /* type */
453 FALSE, /* pc_relative */
455 complain_overflow_signed, /* complain_on_overflow */
456 bfd_elf_generic_reloc, /* special_function */
457 "R_RISCV_TPREL_LO12_S", /* name */
458 FALSE, /* partial_inplace */
460 ENCODE_STYPE_IMM (-1U), /* dst_mask */
461 FALSE), /* pcrel_offset */
463 /* TLS LE thread pointer usage. */
464 HOWTO (R_RISCV_TPREL_ADD, /* type */
468 FALSE, /* pc_relative */
470 complain_overflow_dont, /* complain_on_overflow */
471 bfd_elf_generic_reloc, /* special_function */
472 "R_RISCV_TPREL_ADD", /* name */
473 TRUE, /* partial_inplace */
476 FALSE), /* pcrel_offset */
478 /* 8-bit in-place addition, for local label subtraction. */
479 HOWTO (R_RISCV_ADD8, /* type */
483 FALSE, /* pc_relative */
485 complain_overflow_dont, /* complain_on_overflow */
486 bfd_elf_generic_reloc, /* special_function */
487 "R_RISCV_ADD8", /* name */
488 FALSE, /* partial_inplace */
490 MINUS_ONE, /* dst_mask */
491 FALSE), /* pcrel_offset */
493 /* 16-bit in-place addition, for local label subtraction. */
494 HOWTO (R_RISCV_ADD16, /* type */
498 FALSE, /* pc_relative */
500 complain_overflow_dont, /* complain_on_overflow */
501 bfd_elf_generic_reloc, /* special_function */
502 "R_RISCV_ADD16", /* name */
503 FALSE, /* partial_inplace */
505 MINUS_ONE, /* dst_mask */
506 FALSE), /* pcrel_offset */
508 /* 32-bit in-place addition, for local label subtraction. */
509 HOWTO (R_RISCV_ADD32, /* type */
513 FALSE, /* pc_relative */
515 complain_overflow_dont, /* complain_on_overflow */
516 bfd_elf_generic_reloc, /* special_function */
517 "R_RISCV_ADD32", /* name */
518 FALSE, /* partial_inplace */
520 MINUS_ONE, /* dst_mask */
521 FALSE), /* pcrel_offset */
523 /* 64-bit in-place addition, for local label subtraction. */
524 HOWTO (R_RISCV_ADD64, /* type */
528 FALSE, /* pc_relative */
530 complain_overflow_dont, /* complain_on_overflow */
531 bfd_elf_generic_reloc, /* special_function */
532 "R_RISCV_ADD64", /* name */
533 FALSE, /* partial_inplace */
535 MINUS_ONE, /* dst_mask */
536 FALSE), /* pcrel_offset */
538 /* 8-bit in-place addition, for local label subtraction. */
539 HOWTO (R_RISCV_SUB8, /* type */
543 FALSE, /* pc_relative */
545 complain_overflow_dont, /* complain_on_overflow */
546 bfd_elf_generic_reloc, /* special_function */
547 "R_RISCV_SUB8", /* name */
548 FALSE, /* partial_inplace */
550 MINUS_ONE, /* dst_mask */
551 FALSE), /* pcrel_offset */
553 /* 16-bit in-place addition, for local label subtraction. */
554 HOWTO (R_RISCV_SUB16, /* type */
558 FALSE, /* pc_relative */
560 complain_overflow_dont, /* complain_on_overflow */
561 bfd_elf_generic_reloc, /* special_function */
562 "R_RISCV_SUB16", /* name */
563 FALSE, /* partial_inplace */
565 MINUS_ONE, /* dst_mask */
566 FALSE), /* pcrel_offset */
568 /* 32-bit in-place addition, for local label subtraction. */
569 HOWTO (R_RISCV_SUB32, /* type */
573 FALSE, /* pc_relative */
575 complain_overflow_dont, /* complain_on_overflow */
576 bfd_elf_generic_reloc, /* special_function */
577 "R_RISCV_SUB32", /* name */
578 FALSE, /* partial_inplace */
580 MINUS_ONE, /* dst_mask */
581 FALSE), /* pcrel_offset */
583 /* 64-bit in-place addition, for local label subtraction. */
584 HOWTO (R_RISCV_SUB64, /* type */
588 FALSE, /* pc_relative */
590 complain_overflow_dont, /* complain_on_overflow */
591 bfd_elf_generic_reloc, /* special_function */
592 "R_RISCV_SUB64", /* name */
593 FALSE, /* partial_inplace */
595 MINUS_ONE, /* dst_mask */
596 FALSE), /* pcrel_offset */
598 /* GNU extension to record C++ vtable hierarchy */
599 HOWTO (R_RISCV_GNU_VTINHERIT, /* type */
603 FALSE, /* pc_relative */
605 complain_overflow_dont, /* complain_on_overflow */
606 NULL, /* special_function */
607 "R_RISCV_GNU_VTINHERIT", /* name */
608 FALSE, /* partial_inplace */
611 FALSE), /* pcrel_offset */
613 /* GNU extension to record C++ vtable member usage */
614 HOWTO (R_RISCV_GNU_VTENTRY, /* type */
618 FALSE, /* pc_relative */
620 complain_overflow_dont, /* complain_on_overflow */
621 _bfd_elf_rel_vtable_reloc_fn, /* special_function */
622 "R_RISCV_GNU_VTENTRY", /* name */
623 FALSE, /* partial_inplace */
626 FALSE), /* pcrel_offset */
628 /* Indicates an alignment statement. The addend field encodes how many
629 bytes of NOPs follow the statement. The desired alignment is the
630 addend rounded up to the next power of two. */
631 HOWTO (R_RISCV_ALIGN, /* type */
635 FALSE, /* pc_relative */
637 complain_overflow_dont, /* complain_on_overflow */
638 bfd_elf_generic_reloc, /* special_function */
639 "R_RISCV_ALIGN", /* name */
640 FALSE, /* partial_inplace */
643 TRUE), /* pcrel_offset */
645 /* 8-bit PC-relative branch offset. */
646 HOWTO (R_RISCV_RVC_BRANCH, /* type */
650 TRUE, /* pc_relative */
652 complain_overflow_signed, /* complain_on_overflow */
653 bfd_elf_generic_reloc, /* special_function */
654 "R_RISCV_RVC_BRANCH", /* name */
655 FALSE, /* partial_inplace */
657 ENCODE_RVC_B_IMM (-1U), /* dst_mask */
658 TRUE), /* pcrel_offset */
660 /* 11-bit PC-relative jump offset. */
661 HOWTO (R_RISCV_RVC_JUMP, /* type */
665 TRUE, /* pc_relative */
667 complain_overflow_dont, /* complain_on_overflow */
668 /* This needs complex overflow
669 detection, because the upper 36
670 bits must match the PC + 4. */
671 bfd_elf_generic_reloc, /* special_function */
672 "R_RISCV_RVC_JUMP", /* name */
673 FALSE, /* partial_inplace */
675 ENCODE_RVC_J_IMM (-1U), /* dst_mask */
676 TRUE), /* pcrel_offset */
678 /* High 6 bits of 18-bit absolute address. */
679 HOWTO (R_RISCV_RVC_LUI, /* type */
683 FALSE, /* pc_relative */
685 complain_overflow_dont, /* complain_on_overflow */
686 bfd_elf_generic_reloc, /* special_function */
687 "R_RISCV_RVC_LUI", /* name */
688 FALSE, /* partial_inplace */
690 ENCODE_RVC_IMM (-1U), /* dst_mask */
691 FALSE), /* pcrel_offset */
693 /* High 12 bits of 32-bit load or add. */
694 HOWTO (R_RISCV_GPREL_I, /* type */
698 FALSE, /* pc_relative */
700 complain_overflow_dont, /* complain_on_overflow */
701 bfd_elf_generic_reloc, /* special_function */
702 "R_RISCV_GPREL_I", /* name */
703 FALSE, /* partial_inplace */
705 ENCODE_ITYPE_IMM (-1U), /* dst_mask */
706 FALSE), /* pcrel_offset */
708 /* High 12 bits of 32-bit store. */
709 HOWTO (R_RISCV_GPREL_S, /* type */
713 FALSE, /* pc_relative */
715 complain_overflow_dont, /* complain_on_overflow */
716 bfd_elf_generic_reloc, /* special_function */
717 "R_RISCV_GPREL_S", /* name */
718 FALSE, /* partial_inplace */
720 ENCODE_STYPE_IMM (-1U), /* dst_mask */
721 FALSE), /* pcrel_offset */
724 /* A mapping from BFD reloc types to RISC-V ELF reloc types. */
728 bfd_reloc_code_real_type bfd_val;
729 enum elf_riscv_reloc_type elf_val;
732 static const struct elf_reloc_map riscv_reloc_map[] =
734 { BFD_RELOC_NONE, R_RISCV_NONE },
735 { BFD_RELOC_32, R_RISCV_32 },
736 { BFD_RELOC_64, R_RISCV_64 },
737 { BFD_RELOC_RISCV_ADD8, R_RISCV_ADD8 },
738 { BFD_RELOC_RISCV_ADD16, R_RISCV_ADD16 },
739 { BFD_RELOC_RISCV_ADD32, R_RISCV_ADD32 },
740 { BFD_RELOC_RISCV_ADD64, R_RISCV_ADD64 },
741 { BFD_RELOC_RISCV_SUB8, R_RISCV_SUB8 },
742 { BFD_RELOC_RISCV_SUB16, R_RISCV_SUB16 },
743 { BFD_RELOC_RISCV_SUB32, R_RISCV_SUB32 },
744 { BFD_RELOC_RISCV_SUB64, R_RISCV_SUB64 },
745 { BFD_RELOC_CTOR, R_RISCV_64 },
746 { BFD_RELOC_12_PCREL, R_RISCV_BRANCH },
747 { BFD_RELOC_RISCV_HI20, R_RISCV_HI20 },
748 { BFD_RELOC_RISCV_LO12_I, R_RISCV_LO12_I },
749 { BFD_RELOC_RISCV_LO12_S, R_RISCV_LO12_S },
750 { BFD_RELOC_RISCV_PCREL_LO12_I, R_RISCV_PCREL_LO12_I },
751 { BFD_RELOC_RISCV_PCREL_LO12_S, R_RISCV_PCREL_LO12_S },
752 { BFD_RELOC_RISCV_CALL, R_RISCV_CALL },
753 { BFD_RELOC_RISCV_CALL_PLT, R_RISCV_CALL_PLT },
754 { BFD_RELOC_RISCV_PCREL_HI20, R_RISCV_PCREL_HI20 },
755 { BFD_RELOC_RISCV_JMP, R_RISCV_JAL },
756 { BFD_RELOC_RISCV_GOT_HI20, R_RISCV_GOT_HI20 },
757 { BFD_RELOC_RISCV_TLS_DTPMOD32, R_RISCV_TLS_DTPMOD32 },
758 { BFD_RELOC_RISCV_TLS_DTPREL32, R_RISCV_TLS_DTPREL32 },
759 { BFD_RELOC_RISCV_TLS_DTPMOD64, R_RISCV_TLS_DTPMOD64 },
760 { BFD_RELOC_RISCV_TLS_DTPREL64, R_RISCV_TLS_DTPREL64 },
761 { BFD_RELOC_RISCV_TLS_TPREL32, R_RISCV_TLS_TPREL32 },
762 { BFD_RELOC_RISCV_TLS_TPREL64, R_RISCV_TLS_TPREL64 },
763 { BFD_RELOC_RISCV_TPREL_HI20, R_RISCV_TPREL_HI20 },
764 { BFD_RELOC_RISCV_TPREL_ADD, R_RISCV_TPREL_ADD },
765 { BFD_RELOC_RISCV_TPREL_LO12_S, R_RISCV_TPREL_LO12_S },
766 { BFD_RELOC_RISCV_TPREL_LO12_I, R_RISCV_TPREL_LO12_I },
767 { BFD_RELOC_RISCV_TLS_GOT_HI20, R_RISCV_TLS_GOT_HI20 },
768 { BFD_RELOC_RISCV_TLS_GD_HI20, R_RISCV_TLS_GD_HI20 },
769 { BFD_RELOC_RISCV_ALIGN, R_RISCV_ALIGN },
770 { BFD_RELOC_RISCV_RVC_BRANCH, R_RISCV_RVC_BRANCH },
771 { BFD_RELOC_RISCV_RVC_JUMP, R_RISCV_RVC_JUMP },
772 { BFD_RELOC_RISCV_RVC_LUI, R_RISCV_RVC_LUI },
773 { BFD_RELOC_RISCV_GPREL_I, R_RISCV_GPREL_I },
774 { BFD_RELOC_RISCV_GPREL_S, R_RISCV_GPREL_S },
777 /* Given a BFD reloc type, return a howto structure. */
780 riscv_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
781 bfd_reloc_code_real_type code)
785 for (i = 0; i < ARRAY_SIZE (riscv_reloc_map); i++)
786 if (riscv_reloc_map[i].bfd_val == code)
787 return &howto_table[(int) riscv_reloc_map[i].elf_val];
789 bfd_set_error (bfd_error_bad_value);
794 riscv_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name)
798 for (i = 0; i < ARRAY_SIZE (howto_table); i++)
799 if (howto_table[i].name && strcasecmp (howto_table[i].name, r_name) == 0)
800 return &howto_table[i];
806 riscv_elf_rtype_to_howto (unsigned int r_type)
808 if (r_type >= ARRAY_SIZE (howto_table))
810 (*_bfd_error_handler) (_("unrecognized relocation (0x%x)"), r_type);
811 bfd_set_error (bfd_error_bad_value);
814 return &howto_table[r_type];