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 MINUS_ONE, /* 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 MINUS_ONE, /* 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 */
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 */
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 */
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 */
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 */
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 */
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 bfd_elf_generic_reloc, /* special_function */
242 "R_RISCV_JAL", /* name */
243 FALSE, /* partial_inplace */
245 ENCODE_UJTYPE_IMM (-1U), /* dst_mask */
246 TRUE), /* pcrel_offset */
248 /* 32-bit PC-relative function call (AUIPC/JALR). */
249 HOWTO (R_RISCV_CALL, /* type */
253 TRUE, /* pc_relative */
255 complain_overflow_dont, /* complain_on_overflow */
256 bfd_elf_generic_reloc, /* special_function */
257 "R_RISCV_CALL", /* name */
258 FALSE, /* partial_inplace */
260 ENCODE_UTYPE_IMM (-1U) | ((bfd_vma) ENCODE_ITYPE_IMM (-1U) << 32),
262 TRUE), /* pcrel_offset */
264 /* Like R_RISCV_CALL, but not locally binding. */
265 HOWTO (R_RISCV_CALL_PLT, /* type */
269 TRUE, /* pc_relative */
271 complain_overflow_dont, /* complain_on_overflow */
272 bfd_elf_generic_reloc, /* special_function */
273 "R_RISCV_CALL_PLT", /* name */
274 FALSE, /* partial_inplace */
276 ENCODE_UTYPE_IMM (-1U) | ((bfd_vma) ENCODE_ITYPE_IMM (-1U) << 32),
278 TRUE), /* pcrel_offset */
280 /* High 20 bits of 32-bit PC-relative GOT access. */
281 HOWTO (R_RISCV_GOT_HI20, /* type */
285 TRUE, /* pc_relative */
287 complain_overflow_dont, /* complain_on_overflow */
288 bfd_elf_generic_reloc, /* special_function */
289 "R_RISCV_GOT_HI20", /* name */
290 FALSE, /* partial_inplace */
292 ENCODE_UTYPE_IMM (-1U), /* dst_mask */
293 FALSE), /* pcrel_offset */
295 /* High 20 bits of 32-bit PC-relative TLS IE GOT access. */
296 HOWTO (R_RISCV_TLS_GOT_HI20, /* type */
300 TRUE, /* pc_relative */
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 */
307 ENCODE_UTYPE_IMM (-1U), /* dst_mask */
308 FALSE), /* pcrel_offset */
310 /* High 20 bits of 32-bit PC-relative TLS GD GOT reference. */
311 HOWTO (R_RISCV_TLS_GD_HI20, /* type */
315 TRUE, /* pc_relative */
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 */
322 ENCODE_UTYPE_IMM (-1U), /* dst_mask */
323 FALSE), /* pcrel_offset */
325 /* High 20 bits of 32-bit PC-relative reference. */
326 HOWTO (R_RISCV_PCREL_HI20, /* type */
330 TRUE, /* pc_relative */
332 complain_overflow_dont, /* complain_on_overflow */
333 bfd_elf_generic_reloc, /* special_function */
334 "R_RISCV_PCREL_HI20", /* name */
335 FALSE, /* partial_inplace */
337 ENCODE_UTYPE_IMM (-1U), /* dst_mask */
338 TRUE), /* pcrel_offset */
340 /* Low 12 bits of a 32-bit PC-relative load or add. */
341 HOWTO (R_RISCV_PCREL_LO12_I, /* type */
345 FALSE, /* pc_relative */
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 */
352 ENCODE_ITYPE_IMM (-1U), /* dst_mask */
353 FALSE), /* pcrel_offset */
355 /* Low 12 bits of a 32-bit PC-relative store. */
356 HOWTO (R_RISCV_PCREL_LO12_S, /* type */
360 FALSE, /* pc_relative */
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 */
367 ENCODE_STYPE_IMM (-1U), /* dst_mask */
368 FALSE), /* pcrel_offset */
370 /* High 20 bits of 32-bit absolute address. */
371 HOWTO (R_RISCV_HI20, /* type */
375 FALSE, /* pc_relative */
377 complain_overflow_dont, /* complain_on_overflow */
378 bfd_elf_generic_reloc, /* special_function */
379 "R_RISCV_HI20", /* name */
380 FALSE, /* partial_inplace */
382 ENCODE_UTYPE_IMM (-1U), /* dst_mask */
383 FALSE), /* pcrel_offset */
385 /* High 12 bits of 32-bit load or add. */
386 HOWTO (R_RISCV_LO12_I, /* type */
390 FALSE, /* pc_relative */
392 complain_overflow_dont, /* complain_on_overflow */
393 bfd_elf_generic_reloc, /* special_function */
394 "R_RISCV_LO12_I", /* name */
395 FALSE, /* partial_inplace */
397 ENCODE_ITYPE_IMM (-1U), /* dst_mask */
398 FALSE), /* pcrel_offset */
400 /* High 12 bits of 32-bit store. */
401 HOWTO (R_RISCV_LO12_S, /* type */
405 FALSE, /* pc_relative */
407 complain_overflow_dont, /* complain_on_overflow */
408 bfd_elf_generic_reloc, /* special_function */
409 "R_RISCV_LO12_S", /* name */
410 FALSE, /* partial_inplace */
412 ENCODE_STYPE_IMM (-1U), /* dst_mask */
413 FALSE), /* pcrel_offset */
415 /* High 20 bits of TLS LE thread pointer offset. */
416 HOWTO (R_RISCV_TPREL_HI20, /* type */
420 FALSE, /* pc_relative */
422 complain_overflow_signed, /* complain_on_overflow */
423 bfd_elf_generic_reloc, /* special_function */
424 "R_RISCV_TPREL_HI20", /* name */
425 TRUE, /* partial_inplace */
427 ENCODE_UTYPE_IMM (-1U), /* dst_mask */
428 FALSE), /* pcrel_offset */
430 /* Low 12 bits of TLS LE thread pointer offset for loads and adds. */
431 HOWTO (R_RISCV_TPREL_LO12_I, /* type */
435 FALSE, /* pc_relative */
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 */
442 ENCODE_ITYPE_IMM (-1U), /* dst_mask */
443 FALSE), /* pcrel_offset */
445 /* Low 12 bits of TLS LE thread pointer offset for stores. */
446 HOWTO (R_RISCV_TPREL_LO12_S, /* type */
450 FALSE, /* pc_relative */
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 */
457 ENCODE_STYPE_IMM (-1U), /* dst_mask */
458 FALSE), /* pcrel_offset */
460 /* TLS LE thread pointer usage. May be relaxed. */
461 HOWTO (R_RISCV_TPREL_ADD, /* type */
465 FALSE, /* pc_relative */
467 complain_overflow_dont, /* complain_on_overflow */
468 bfd_elf_generic_reloc, /* special_function */
469 "R_RISCV_TPREL_ADD", /* name */
470 TRUE, /* partial_inplace */
473 FALSE), /* pcrel_offset */
475 /* 8-bit in-place addition, for local label subtraction. */
476 HOWTO (R_RISCV_ADD8, /* type */
480 FALSE, /* pc_relative */
482 complain_overflow_dont, /* complain_on_overflow */
483 bfd_elf_generic_reloc, /* special_function */
484 "R_RISCV_ADD8", /* name */
485 FALSE, /* partial_inplace */
487 MINUS_ONE, /* dst_mask */
488 FALSE), /* pcrel_offset */
490 /* 16-bit in-place addition, for local label subtraction. */
491 HOWTO (R_RISCV_ADD16, /* type */
495 FALSE, /* pc_relative */
497 complain_overflow_dont, /* complain_on_overflow */
498 bfd_elf_generic_reloc, /* special_function */
499 "R_RISCV_ADD16", /* name */
500 FALSE, /* partial_inplace */
502 MINUS_ONE, /* dst_mask */
503 FALSE), /* pcrel_offset */
505 /* 32-bit in-place addition, for local label subtraction. */
506 HOWTO (R_RISCV_ADD32, /* type */
510 FALSE, /* pc_relative */
512 complain_overflow_dont, /* complain_on_overflow */
513 bfd_elf_generic_reloc, /* special_function */
514 "R_RISCV_ADD32", /* name */
515 FALSE, /* partial_inplace */
517 MINUS_ONE, /* dst_mask */
518 FALSE), /* pcrel_offset */
520 /* 64-bit in-place addition, for local label subtraction. */
521 HOWTO (R_RISCV_ADD64, /* type */
525 FALSE, /* pc_relative */
527 complain_overflow_dont, /* complain_on_overflow */
528 bfd_elf_generic_reloc, /* special_function */
529 "R_RISCV_ADD64", /* name */
530 FALSE, /* partial_inplace */
532 MINUS_ONE, /* dst_mask */
533 FALSE), /* pcrel_offset */
535 /* 8-bit in-place addition, for local label subtraction. */
536 HOWTO (R_RISCV_SUB8, /* type */
540 FALSE, /* pc_relative */
542 complain_overflow_dont, /* complain_on_overflow */
543 bfd_elf_generic_reloc, /* special_function */
544 "R_RISCV_SUB8", /* name */
545 FALSE, /* partial_inplace */
547 MINUS_ONE, /* dst_mask */
548 FALSE), /* pcrel_offset */
550 /* 16-bit in-place addition, for local label subtraction. */
551 HOWTO (R_RISCV_SUB16, /* type */
555 FALSE, /* pc_relative */
557 complain_overflow_dont, /* complain_on_overflow */
558 bfd_elf_generic_reloc, /* special_function */
559 "R_RISCV_SUB16", /* name */
560 FALSE, /* partial_inplace */
562 MINUS_ONE, /* dst_mask */
563 FALSE), /* pcrel_offset */
565 /* 32-bit in-place addition, for local label subtraction. */
566 HOWTO (R_RISCV_SUB32, /* type */
570 FALSE, /* pc_relative */
572 complain_overflow_dont, /* complain_on_overflow */
573 bfd_elf_generic_reloc, /* special_function */
574 "R_RISCV_SUB32", /* name */
575 FALSE, /* partial_inplace */
577 MINUS_ONE, /* dst_mask */
578 FALSE), /* pcrel_offset */
580 /* 64-bit in-place addition, for local label subtraction. */
581 HOWTO (R_RISCV_SUB64, /* type */
585 FALSE, /* pc_relative */
587 complain_overflow_dont, /* complain_on_overflow */
588 bfd_elf_generic_reloc, /* special_function */
589 "R_RISCV_SUB64", /* name */
590 FALSE, /* partial_inplace */
592 MINUS_ONE, /* dst_mask */
593 FALSE), /* pcrel_offset */
595 /* GNU extension to record C++ vtable hierarchy */
596 HOWTO (R_RISCV_GNU_VTINHERIT, /* type */
600 FALSE, /* pc_relative */
602 complain_overflow_dont, /* complain_on_overflow */
603 NULL, /* special_function */
604 "R_RISCV_GNU_VTINHERIT", /* name */
605 FALSE, /* partial_inplace */
608 FALSE), /* pcrel_offset */
610 /* GNU extension to record C++ vtable member usage */
611 HOWTO (R_RISCV_GNU_VTENTRY, /* type */
615 FALSE, /* pc_relative */
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 */
623 FALSE), /* pcrel_offset */
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 */
632 FALSE, /* pc_relative */
634 complain_overflow_dont, /* complain_on_overflow */
635 bfd_elf_generic_reloc, /* special_function */
636 "R_RISCV_ALIGN", /* name */
637 FALSE, /* partial_inplace */
640 TRUE), /* pcrel_offset */
642 /* 8-bit PC-relative branch offset. */
643 HOWTO (R_RISCV_RVC_BRANCH, /* type */
647 TRUE, /* pc_relative */
649 complain_overflow_signed, /* complain_on_overflow */
650 bfd_elf_generic_reloc, /* special_function */
651 "R_RISCV_RVC_BRANCH", /* name */
652 FALSE, /* partial_inplace */
654 ENCODE_RVC_B_IMM (-1U), /* dst_mask */
655 TRUE), /* pcrel_offset */
657 /* 11-bit PC-relative jump offset. */
658 HOWTO (R_RISCV_RVC_JUMP, /* type */
662 TRUE, /* pc_relative */
664 complain_overflow_dont, /* complain_on_overflow */
665 bfd_elf_generic_reloc, /* special_function */
666 "R_RISCV_RVC_JUMP", /* name */
667 FALSE, /* partial_inplace */
669 ENCODE_RVC_J_IMM (-1U), /* dst_mask */
670 TRUE), /* pcrel_offset */
672 /* High 6 bits of 18-bit absolute address. */
673 HOWTO (R_RISCV_RVC_LUI, /* type */
677 FALSE, /* pc_relative */
679 complain_overflow_dont, /* complain_on_overflow */
680 bfd_elf_generic_reloc, /* special_function */
681 "R_RISCV_RVC_LUI", /* name */
682 FALSE, /* partial_inplace */
684 ENCODE_RVC_IMM (-1U), /* dst_mask */
685 FALSE), /* pcrel_offset */
687 /* GP-relative load. */
688 HOWTO (R_RISCV_GPREL_I, /* type */
692 FALSE, /* pc_relative */
694 complain_overflow_dont, /* complain_on_overflow */
695 bfd_elf_generic_reloc, /* special_function */
696 "R_RISCV_GPREL_I", /* name */
697 FALSE, /* partial_inplace */
699 ENCODE_ITYPE_IMM (-1U), /* dst_mask */
700 FALSE), /* pcrel_offset */
702 /* GP-relative store. */
703 HOWTO (R_RISCV_GPREL_S, /* type */
707 FALSE, /* pc_relative */
709 complain_overflow_dont, /* complain_on_overflow */
710 bfd_elf_generic_reloc, /* special_function */
711 "R_RISCV_GPREL_S", /* name */
712 FALSE, /* partial_inplace */
714 ENCODE_STYPE_IMM (-1U), /* dst_mask */
715 FALSE), /* pcrel_offset */
718 /* A mapping from BFD reloc types to RISC-V ELF reloc types. */
722 bfd_reloc_code_real_type bfd_val;
723 enum elf_riscv_reloc_type elf_val;
726 static const struct elf_reloc_map riscv_reloc_map[] =
728 { BFD_RELOC_NONE, R_RISCV_NONE },
729 { BFD_RELOC_32, R_RISCV_32 },
730 { BFD_RELOC_64, R_RISCV_64 },
731 { BFD_RELOC_RISCV_ADD8, R_RISCV_ADD8 },
732 { BFD_RELOC_RISCV_ADD16, R_RISCV_ADD16 },
733 { BFD_RELOC_RISCV_ADD32, R_RISCV_ADD32 },
734 { BFD_RELOC_RISCV_ADD64, R_RISCV_ADD64 },
735 { BFD_RELOC_RISCV_SUB8, R_RISCV_SUB8 },
736 { BFD_RELOC_RISCV_SUB16, R_RISCV_SUB16 },
737 { BFD_RELOC_RISCV_SUB32, R_RISCV_SUB32 },
738 { BFD_RELOC_RISCV_SUB64, R_RISCV_SUB64 },
739 { BFD_RELOC_CTOR, R_RISCV_64 },
740 { BFD_RELOC_12_PCREL, R_RISCV_BRANCH },
741 { BFD_RELOC_RISCV_HI20, R_RISCV_HI20 },
742 { BFD_RELOC_RISCV_LO12_I, R_RISCV_LO12_I },
743 { BFD_RELOC_RISCV_LO12_S, R_RISCV_LO12_S },
744 { BFD_RELOC_RISCV_PCREL_LO12_I, R_RISCV_PCREL_LO12_I },
745 { BFD_RELOC_RISCV_PCREL_LO12_S, R_RISCV_PCREL_LO12_S },
746 { BFD_RELOC_RISCV_CALL, R_RISCV_CALL },
747 { BFD_RELOC_RISCV_CALL_PLT, R_RISCV_CALL_PLT },
748 { BFD_RELOC_RISCV_PCREL_HI20, R_RISCV_PCREL_HI20 },
749 { BFD_RELOC_RISCV_JMP, R_RISCV_JAL },
750 { BFD_RELOC_RISCV_GOT_HI20, R_RISCV_GOT_HI20 },
751 { BFD_RELOC_RISCV_TLS_DTPMOD32, R_RISCV_TLS_DTPMOD32 },
752 { BFD_RELOC_RISCV_TLS_DTPREL32, R_RISCV_TLS_DTPREL32 },
753 { BFD_RELOC_RISCV_TLS_DTPMOD64, R_RISCV_TLS_DTPMOD64 },
754 { BFD_RELOC_RISCV_TLS_DTPREL64, R_RISCV_TLS_DTPREL64 },
755 { BFD_RELOC_RISCV_TLS_TPREL32, R_RISCV_TLS_TPREL32 },
756 { BFD_RELOC_RISCV_TLS_TPREL64, R_RISCV_TLS_TPREL64 },
757 { BFD_RELOC_RISCV_TPREL_HI20, R_RISCV_TPREL_HI20 },
758 { BFD_RELOC_RISCV_TPREL_ADD, R_RISCV_TPREL_ADD },
759 { BFD_RELOC_RISCV_TPREL_LO12_S, R_RISCV_TPREL_LO12_S },
760 { BFD_RELOC_RISCV_TPREL_LO12_I, R_RISCV_TPREL_LO12_I },
761 { BFD_RELOC_RISCV_TLS_GOT_HI20, R_RISCV_TLS_GOT_HI20 },
762 { BFD_RELOC_RISCV_TLS_GD_HI20, R_RISCV_TLS_GD_HI20 },
763 { BFD_RELOC_RISCV_ALIGN, R_RISCV_ALIGN },
764 { BFD_RELOC_RISCV_RVC_BRANCH, R_RISCV_RVC_BRANCH },
765 { BFD_RELOC_RISCV_RVC_JUMP, R_RISCV_RVC_JUMP },
766 { BFD_RELOC_RISCV_RVC_LUI, R_RISCV_RVC_LUI },
767 { BFD_RELOC_RISCV_GPREL_I, R_RISCV_GPREL_I },
768 { BFD_RELOC_RISCV_GPREL_S, R_RISCV_GPREL_S },
771 /* Given a BFD reloc type, return a howto structure. */
774 riscv_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
775 bfd_reloc_code_real_type code)
779 for (i = 0; i < ARRAY_SIZE (riscv_reloc_map); i++)
780 if (riscv_reloc_map[i].bfd_val == code)
781 return &howto_table[(int) riscv_reloc_map[i].elf_val];
783 bfd_set_error (bfd_error_bad_value);
788 riscv_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name)
792 for (i = 0; i < ARRAY_SIZE (howto_table); i++)
793 if (howto_table[i].name && strcasecmp (howto_table[i].name, r_name) == 0)
794 return &howto_table[i];
800 riscv_elf_rtype_to_howto (unsigned int r_type)
802 if (r_type >= ARRAY_SIZE (howto_table))
804 (*_bfd_error_handler) (_("unrecognized relocation (0x%x)"), r_type);
805 bfd_set_error (bfd_error_bad_value);
808 return &howto_table[r_type];