RISC-V/bfd: Fix bitsize of R_RISCV_ADD8.
[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 0xffffffff, /* 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 0xffffffff, /* 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 0x0, /* src_mask */
110 0x0, /* 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 0x0, /* src_mask */
124 0x0, /* 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 MINUS_ONE, /* 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 MINUS_ONE, /* 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 MINUS_ONE, /* 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 MINUS_ONE, /* 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 MINUS_ONE, /* 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 MINUS_ONE, /* 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 /* 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 */
247 0, /* src_mask */
248 ENCODE_UJTYPE_IMM (-1U), /* dst_mask */
249 TRUE), /* pcrel_offset */
250
251 /* 32-bit PC-relative function call (AUIPC/JALR). */
252 HOWTO (R_RISCV_CALL, /* type */
253 0, /* rightshift */
254 2, /* size */
255 64, /* bitsize */
256 TRUE, /* pc_relative */
257 0, /* bitpos */
258 complain_overflow_dont, /* complain_on_overflow */
259 bfd_elf_generic_reloc, /* special_function */
260 "R_RISCV_CALL", /* name */
261 FALSE, /* partial_inplace */
262 0, /* src_mask */
263 ENCODE_UTYPE_IMM (-1U) | ((bfd_vma) ENCODE_ITYPE_IMM (-1U) << 32),
264 /* dst_mask */
265 TRUE), /* pcrel_offset */
266
267 /* 32-bit PC-relative function call (AUIPC/JALR). */
268 HOWTO (R_RISCV_CALL_PLT, /* type */
269 0, /* rightshift */
270 2, /* size */
271 64, /* bitsize */
272 TRUE, /* pc_relative */
273 0, /* bitpos */
274 complain_overflow_dont, /* complain_on_overflow */
275 bfd_elf_generic_reloc, /* special_function */
276 "R_RISCV_CALL_PLT", /* name */
277 FALSE, /* partial_inplace */
278 0, /* src_mask */
279 ENCODE_UTYPE_IMM (-1U) | ((bfd_vma) ENCODE_ITYPE_IMM (-1U) << 32),
280 /* dst_mask */
281 TRUE), /* pcrel_offset */
282
283 /* High 20 bits of 32-bit PC-relative GOT access. */
284 HOWTO (R_RISCV_GOT_HI20, /* type */
285 0, /* rightshift */
286 2, /* size */
287 32, /* bitsize */
288 TRUE, /* pc_relative */
289 0, /* bitpos */
290 complain_overflow_dont, /* complain_on_overflow */
291 bfd_elf_generic_reloc, /* special_function */
292 "R_RISCV_GOT_HI20", /* name */
293 FALSE, /* partial_inplace */
294 0, /* src_mask */
295 ENCODE_UTYPE_IMM (-1U), /* dst_mask */
296 FALSE), /* pcrel_offset */
297
298 /* High 20 bits of 32-bit PC-relative TLS IE GOT access. */
299 HOWTO (R_RISCV_TLS_GOT_HI20, /* type */
300 0, /* rightshift */
301 2, /* size */
302 32, /* bitsize */
303 TRUE, /* pc_relative */
304 0, /* bitpos */
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 */
309 0, /* src_mask */
310 ENCODE_UTYPE_IMM (-1U), /* dst_mask */
311 FALSE), /* pcrel_offset */
312
313 /* High 20 bits of 32-bit PC-relative TLS GD GOT reference. */
314 HOWTO (R_RISCV_TLS_GD_HI20, /* type */
315 0, /* rightshift */
316 2, /* size */
317 32, /* bitsize */
318 TRUE, /* pc_relative */
319 0, /* bitpos */
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 */
324 0, /* src_mask */
325 ENCODE_UTYPE_IMM (-1U), /* dst_mask */
326 FALSE), /* pcrel_offset */
327
328 /* High 20 bits of 32-bit PC-relative reference. */
329 HOWTO (R_RISCV_PCREL_HI20, /* type */
330 0, /* rightshift */
331 2, /* size */
332 32, /* bitsize */
333 TRUE, /* pc_relative */
334 0, /* bitpos */
335 complain_overflow_dont, /* complain_on_overflow */
336 bfd_elf_generic_reloc, /* special_function */
337 "R_RISCV_PCREL_HI20", /* name */
338 FALSE, /* partial_inplace */
339 0, /* src_mask */
340 ENCODE_UTYPE_IMM (-1U), /* dst_mask */
341 TRUE), /* pcrel_offset */
342
343 /* Low 12 bits of a 32-bit PC-relative load or add. */
344 HOWTO (R_RISCV_PCREL_LO12_I, /* type */
345 0, /* rightshift */
346 2, /* size */
347 32, /* bitsize */
348 FALSE, /* pc_relative */
349 0, /* bitpos */
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 */
354 0, /* src_mask */
355 ENCODE_ITYPE_IMM (-1U), /* dst_mask */
356 FALSE), /* pcrel_offset */
357
358 /* Low 12 bits of a 32-bit PC-relative store. */
359 HOWTO (R_RISCV_PCREL_LO12_S, /* type */
360 0, /* rightshift */
361 2, /* size */
362 32, /* bitsize */
363 FALSE, /* pc_relative */
364 0, /* bitpos */
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 */
369 0, /* src_mask */
370 ENCODE_STYPE_IMM (-1U), /* dst_mask */
371 FALSE), /* pcrel_offset */
372
373 /* High 20 bits of 32-bit absolute address. */
374 HOWTO (R_RISCV_HI20, /* type */
375 0, /* rightshift */
376 2, /* size */
377 32, /* bitsize */
378 FALSE, /* pc_relative */
379 0, /* bitpos */
380 complain_overflow_dont, /* complain_on_overflow */
381 bfd_elf_generic_reloc, /* special_function */
382 "R_RISCV_HI20", /* name */
383 FALSE, /* partial_inplace */
384 0, /* src_mask */
385 ENCODE_UTYPE_IMM (-1U), /* dst_mask */
386 FALSE), /* pcrel_offset */
387
388 /* High 12 bits of 32-bit load or add. */
389 HOWTO (R_RISCV_LO12_I, /* type */
390 0, /* rightshift */
391 2, /* size */
392 32, /* bitsize */
393 FALSE, /* pc_relative */
394 0, /* bitpos */
395 complain_overflow_dont, /* complain_on_overflow */
396 bfd_elf_generic_reloc, /* special_function */
397 "R_RISCV_LO12_I", /* name */
398 FALSE, /* partial_inplace */
399 0, /* src_mask */
400 ENCODE_ITYPE_IMM (-1U), /* dst_mask */
401 FALSE), /* pcrel_offset */
402
403 /* High 12 bits of 32-bit store. */
404 HOWTO (R_RISCV_LO12_S, /* type */
405 0, /* rightshift */
406 2, /* size */
407 32, /* bitsize */
408 FALSE, /* pc_relative */
409 0, /* bitpos */
410 complain_overflow_dont, /* complain_on_overflow */
411 bfd_elf_generic_reloc, /* special_function */
412 "R_RISCV_LO12_S", /* name */
413 FALSE, /* partial_inplace */
414 0, /* src_mask */
415 ENCODE_STYPE_IMM (-1U), /* dst_mask */
416 FALSE), /* pcrel_offset */
417
418 /* High 20 bits of TLS LE thread pointer offset. */
419 HOWTO (R_RISCV_TPREL_HI20, /* type */
420 0, /* rightshift */
421 2, /* size */
422 32, /* bitsize */
423 FALSE, /* pc_relative */
424 0, /* bitpos */
425 complain_overflow_signed, /* complain_on_overflow */
426 bfd_elf_generic_reloc, /* special_function */
427 "R_RISCV_TPREL_HI20", /* name */
428 TRUE, /* partial_inplace */
429 0, /* src_mask */
430 ENCODE_UTYPE_IMM (-1U), /* dst_mask */
431 FALSE), /* pcrel_offset */
432
433 /* Low 12 bits of TLS LE thread pointer offset for loads and adds. */
434 HOWTO (R_RISCV_TPREL_LO12_I, /* type */
435 0, /* rightshift */
436 2, /* size */
437 32, /* bitsize */
438 FALSE, /* pc_relative */
439 0, /* bitpos */
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 */
444 0, /* src_mask */
445 ENCODE_ITYPE_IMM (-1U), /* dst_mask */
446 FALSE), /* pcrel_offset */
447
448 /* Low 12 bits of TLS LE thread pointer offset for stores. */
449 HOWTO (R_RISCV_TPREL_LO12_S, /* type */
450 0, /* rightshift */
451 2, /* size */
452 32, /* bitsize */
453 FALSE, /* pc_relative */
454 0, /* bitpos */
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 */
459 0, /* src_mask */
460 ENCODE_STYPE_IMM (-1U), /* dst_mask */
461 FALSE), /* pcrel_offset */
462
463 /* TLS LE thread pointer usage. */
464 HOWTO (R_RISCV_TPREL_ADD, /* type */
465 0, /* rightshift */
466 2, /* size */
467 32, /* bitsize */
468 FALSE, /* pc_relative */
469 0, /* bitpos */
470 complain_overflow_dont, /* complain_on_overflow */
471 bfd_elf_generic_reloc, /* special_function */
472 "R_RISCV_TPREL_ADD", /* name */
473 TRUE, /* partial_inplace */
474 0, /* src_mask */
475 0, /* dst_mask */
476 FALSE), /* pcrel_offset */
477
478 /* 8-bit in-place addition, for local label subtraction. */
479 HOWTO (R_RISCV_ADD8, /* type */
480 0, /* rightshift */
481 0, /* size */
482 8, /* bitsize */
483 FALSE, /* pc_relative */
484 0, /* bitpos */
485 complain_overflow_dont, /* complain_on_overflow */
486 bfd_elf_generic_reloc, /* special_function */
487 "R_RISCV_ADD8", /* name */
488 FALSE, /* partial_inplace */
489 0, /* src_mask */
490 MINUS_ONE, /* dst_mask */
491 FALSE), /* pcrel_offset */
492
493 /* 16-bit in-place addition, for local label subtraction. */
494 HOWTO (R_RISCV_ADD16, /* type */
495 0, /* rightshift */
496 1, /* size */
497 16, /* bitsize */
498 FALSE, /* pc_relative */
499 0, /* bitpos */
500 complain_overflow_dont, /* complain_on_overflow */
501 bfd_elf_generic_reloc, /* special_function */
502 "R_RISCV_ADD16", /* name */
503 FALSE, /* partial_inplace */
504 0, /* src_mask */
505 MINUS_ONE, /* dst_mask */
506 FALSE), /* pcrel_offset */
507
508 /* 32-bit in-place addition, for local label subtraction. */
509 HOWTO (R_RISCV_ADD32, /* type */
510 0, /* rightshift */
511 2, /* size */
512 32, /* bitsize */
513 FALSE, /* pc_relative */
514 0, /* bitpos */
515 complain_overflow_dont, /* complain_on_overflow */
516 bfd_elf_generic_reloc, /* special_function */
517 "R_RISCV_ADD32", /* name */
518 FALSE, /* partial_inplace */
519 0, /* src_mask */
520 MINUS_ONE, /* dst_mask */
521 FALSE), /* pcrel_offset */
522
523 /* 64-bit in-place addition, for local label subtraction. */
524 HOWTO (R_RISCV_ADD64, /* type */
525 0, /* rightshift */
526 4, /* size */
527 64, /* bitsize */
528 FALSE, /* pc_relative */
529 0, /* bitpos */
530 complain_overflow_dont, /* complain_on_overflow */
531 bfd_elf_generic_reloc, /* special_function */
532 "R_RISCV_ADD64", /* name */
533 FALSE, /* partial_inplace */
534 0, /* src_mask */
535 MINUS_ONE, /* dst_mask */
536 FALSE), /* pcrel_offset */
537
538 /* 8-bit in-place addition, for local label subtraction. */
539 HOWTO (R_RISCV_SUB8, /* type */
540 0, /* rightshift */
541 0, /* size */
542 8, /* bitsize */
543 FALSE, /* pc_relative */
544 0, /* bitpos */
545 complain_overflow_dont, /* complain_on_overflow */
546 bfd_elf_generic_reloc, /* special_function */
547 "R_RISCV_SUB8", /* name */
548 FALSE, /* partial_inplace */
549 0, /* src_mask */
550 MINUS_ONE, /* dst_mask */
551 FALSE), /* pcrel_offset */
552
553 /* 16-bit in-place addition, for local label subtraction. */
554 HOWTO (R_RISCV_SUB16, /* type */
555 0, /* rightshift */
556 1, /* size */
557 16, /* bitsize */
558 FALSE, /* pc_relative */
559 0, /* bitpos */
560 complain_overflow_dont, /* complain_on_overflow */
561 bfd_elf_generic_reloc, /* special_function */
562 "R_RISCV_SUB16", /* name */
563 FALSE, /* partial_inplace */
564 0, /* src_mask */
565 MINUS_ONE, /* dst_mask */
566 FALSE), /* pcrel_offset */
567
568 /* 32-bit in-place addition, for local label subtraction. */
569 HOWTO (R_RISCV_SUB32, /* type */
570 0, /* rightshift */
571 2, /* size */
572 32, /* bitsize */
573 FALSE, /* pc_relative */
574 0, /* bitpos */
575 complain_overflow_dont, /* complain_on_overflow */
576 bfd_elf_generic_reloc, /* special_function */
577 "R_RISCV_SUB32", /* name */
578 FALSE, /* partial_inplace */
579 0, /* src_mask */
580 MINUS_ONE, /* dst_mask */
581 FALSE), /* pcrel_offset */
582
583 /* 64-bit in-place addition, for local label subtraction. */
584 HOWTO (R_RISCV_SUB64, /* type */
585 0, /* rightshift */
586 4, /* size */
587 64, /* bitsize */
588 FALSE, /* pc_relative */
589 0, /* bitpos */
590 complain_overflow_dont, /* complain_on_overflow */
591 bfd_elf_generic_reloc, /* special_function */
592 "R_RISCV_SUB64", /* name */
593 FALSE, /* partial_inplace */
594 0, /* src_mask */
595 MINUS_ONE, /* dst_mask */
596 FALSE), /* pcrel_offset */
597
598 /* GNU extension to record C++ vtable hierarchy */
599 HOWTO (R_RISCV_GNU_VTINHERIT, /* type */
600 0, /* rightshift */
601 4, /* size */
602 0, /* bitsize */
603 FALSE, /* pc_relative */
604 0, /* bitpos */
605 complain_overflow_dont, /* complain_on_overflow */
606 NULL, /* special_function */
607 "R_RISCV_GNU_VTINHERIT", /* name */
608 FALSE, /* partial_inplace */
609 0, /* src_mask */
610 0, /* dst_mask */
611 FALSE), /* pcrel_offset */
612
613 /* GNU extension to record C++ vtable member usage */
614 HOWTO (R_RISCV_GNU_VTENTRY, /* type */
615 0, /* rightshift */
616 4, /* size */
617 0, /* bitsize */
618 FALSE, /* pc_relative */
619 0, /* bitpos */
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 */
624 0, /* src_mask */
625 0, /* dst_mask */
626 FALSE), /* pcrel_offset */
627
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 */
632 0, /* rightshift */
633 2, /* size */
634 0, /* bitsize */
635 FALSE, /* pc_relative */
636 0, /* bitpos */
637 complain_overflow_dont, /* complain_on_overflow */
638 bfd_elf_generic_reloc, /* special_function */
639 "R_RISCV_ALIGN", /* name */
640 FALSE, /* partial_inplace */
641 0, /* src_mask */
642 0, /* dst_mask */
643 TRUE), /* pcrel_offset */
644
645 /* 8-bit PC-relative branch offset. */
646 HOWTO (R_RISCV_RVC_BRANCH, /* type */
647 0, /* rightshift */
648 2, /* size */
649 32, /* bitsize */
650 TRUE, /* pc_relative */
651 0, /* bitpos */
652 complain_overflow_signed, /* complain_on_overflow */
653 bfd_elf_generic_reloc, /* special_function */
654 "R_RISCV_RVC_BRANCH", /* name */
655 FALSE, /* partial_inplace */
656 0, /* src_mask */
657 ENCODE_RVC_B_IMM (-1U), /* dst_mask */
658 TRUE), /* pcrel_offset */
659
660 /* 11-bit PC-relative jump offset. */
661 HOWTO (R_RISCV_RVC_JUMP, /* type */
662 0, /* rightshift */
663 2, /* size */
664 32, /* bitsize */
665 TRUE, /* pc_relative */
666 0, /* bitpos */
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 */
674 0, /* src_mask */
675 ENCODE_RVC_J_IMM (-1U), /* dst_mask */
676 TRUE), /* pcrel_offset */
677
678 /* High 6 bits of 18-bit absolute address. */
679 HOWTO (R_RISCV_RVC_LUI, /* type */
680 0, /* rightshift */
681 2, /* size */
682 32, /* bitsize */
683 FALSE, /* pc_relative */
684 0, /* bitpos */
685 complain_overflow_dont, /* complain_on_overflow */
686 bfd_elf_generic_reloc, /* special_function */
687 "R_RISCV_RVC_LUI", /* name */
688 FALSE, /* partial_inplace */
689 0, /* src_mask */
690 ENCODE_RVC_IMM (-1U), /* dst_mask */
691 FALSE), /* pcrel_offset */
692
693 /* High 12 bits of 32-bit load or add. */
694 HOWTO (R_RISCV_GPREL_I, /* type */
695 0, /* rightshift */
696 2, /* size */
697 32, /* bitsize */
698 FALSE, /* pc_relative */
699 0, /* bitpos */
700 complain_overflow_dont, /* complain_on_overflow */
701 bfd_elf_generic_reloc, /* special_function */
702 "R_RISCV_GPREL_I", /* name */
703 FALSE, /* partial_inplace */
704 0, /* src_mask */
705 ENCODE_ITYPE_IMM (-1U), /* dst_mask */
706 FALSE), /* pcrel_offset */
707
708 /* High 12 bits of 32-bit store. */
709 HOWTO (R_RISCV_GPREL_S, /* type */
710 0, /* rightshift */
711 2, /* size */
712 32, /* bitsize */
713 FALSE, /* pc_relative */
714 0, /* bitpos */
715 complain_overflow_dont, /* complain_on_overflow */
716 bfd_elf_generic_reloc, /* special_function */
717 "R_RISCV_GPREL_S", /* name */
718 FALSE, /* partial_inplace */
719 0, /* src_mask */
720 ENCODE_STYPE_IMM (-1U), /* dst_mask */
721 FALSE), /* pcrel_offset */
722 };
723
724 /* A mapping from BFD reloc types to RISC-V ELF reloc types. */
725
726 struct elf_reloc_map
727 {
728 bfd_reloc_code_real_type bfd_val;
729 enum elf_riscv_reloc_type elf_val;
730 };
731
732 static const struct elf_reloc_map riscv_reloc_map[] =
733 {
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 },
775 };
776
777 /* Given a BFD reloc type, return a howto structure. */
778
779 reloc_howto_type *
780 riscv_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
781 bfd_reloc_code_real_type code)
782 {
783 unsigned int i;
784
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];
788
789 bfd_set_error (bfd_error_bad_value);
790 return NULL;
791 }
792
793 reloc_howto_type *
794 riscv_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name)
795 {
796 unsigned int i;
797
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];
801
802 return NULL;
803 }
804
805 reloc_howto_type *
806 riscv_elf_rtype_to_howto (unsigned int r_type)
807 {
808 if (r_type >= ARRAY_SIZE (howto_table))
809 {
810 (*_bfd_error_handler) (_("unrecognized relocation (0x%x)"), r_type);
811 bfd_set_error (bfd_error_bad_value);
812 return NULL;
813 }
814 return &howto_table[r_type];
815 }
This page took 0.061386 seconds and 5 git commands to generate.