Formatting changes for RISC-V
[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
718 /* A mapping from BFD reloc types to RISC-V ELF reloc types. */
719
720 struct elf_reloc_map
721 {
722 bfd_reloc_code_real_type bfd_val;
723 enum elf_riscv_reloc_type elf_val;
724 };
725
726 static const struct elf_reloc_map riscv_reloc_map[] =
727 {
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 },
769 };
770
771 /* Given a BFD reloc type, return a howto structure. */
772
773 reloc_howto_type *
774 riscv_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
775 bfd_reloc_code_real_type code)
776 {
777 unsigned int i;
778
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];
782
783 bfd_set_error (bfd_error_bad_value);
784 return NULL;
785 }
786
787 reloc_howto_type *
788 riscv_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name)
789 {
790 unsigned int i;
791
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];
795
796 return NULL;
797 }
798
799 reloc_howto_type *
800 riscv_elf_rtype_to_howto (unsigned int r_type)
801 {
802 if (r_type >= ARRAY_SIZE (howto_table))
803 {
804 (*_bfd_error_handler) (_("unrecognized relocation (0x%x)"), r_type);
805 bfd_set_error (bfd_error_bad_value);
806 return NULL;
807 }
808 return &howto_table[r_type];
809 }