RISC-V: Support to add implicit extensions for G.
[deliverable/binutils-gdb.git] / bfd / elfxx-riscv.c
1 /* RISC-V-specific support for ELF.
2 Copyright (C) 2011-2020 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 "libiberty.h"
29 #include "elfxx-riscv.h"
30 #include "safe-ctype.h"
31
32 #define MINUS_ONE ((bfd_vma)0 - 1)
33
34 /* Special handler for ADD/SUB relocations that allows them to be filled out
35 both in the pre-linked and post-linked file. This is necessary to make
36 pre-linked debug info work, as due to linker relaxations we need to emit
37 relocations for the debug info. */
38 static bfd_reloc_status_type riscv_elf_add_sub_reloc
39 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
40
41 /* The relocation table used for SHT_RELA sections. */
42
43 static reloc_howto_type howto_table[] =
44 {
45 /* No relocation. */
46 HOWTO (R_RISCV_NONE, /* type */
47 0, /* rightshift */
48 3, /* size */
49 0, /* bitsize */
50 FALSE, /* pc_relative */
51 0, /* bitpos */
52 complain_overflow_dont, /* complain_on_overflow */
53 bfd_elf_generic_reloc, /* special_function */
54 "R_RISCV_NONE", /* name */
55 FALSE, /* partial_inplace */
56 0, /* src_mask */
57 0, /* dst_mask */
58 FALSE), /* pcrel_offset */
59
60 /* 32 bit relocation. */
61 HOWTO (R_RISCV_32, /* type */
62 0, /* rightshift */
63 2, /* size */
64 32, /* bitsize */
65 FALSE, /* pc_relative */
66 0, /* bitpos */
67 complain_overflow_dont, /* complain_on_overflow */
68 bfd_elf_generic_reloc, /* special_function */
69 "R_RISCV_32", /* name */
70 FALSE, /* partial_inplace */
71 0, /* src_mask */
72 0xffffffff, /* dst_mask */
73 FALSE), /* pcrel_offset */
74
75 /* 64 bit relocation. */
76 HOWTO (R_RISCV_64, /* type */
77 0, /* rightshift */
78 4, /* size */
79 64, /* bitsize */
80 FALSE, /* pc_relative */
81 0, /* bitpos */
82 complain_overflow_dont, /* complain_on_overflow */
83 bfd_elf_generic_reloc, /* special_function */
84 "R_RISCV_64", /* name */
85 FALSE, /* partial_inplace */
86 0, /* src_mask */
87 MINUS_ONE, /* dst_mask */
88 FALSE), /* pcrel_offset */
89
90 /* Relocation against a local symbol in a shared object. */
91 HOWTO (R_RISCV_RELATIVE, /* type */
92 0, /* rightshift */
93 2, /* size */
94 32, /* bitsize */
95 FALSE, /* pc_relative */
96 0, /* bitpos */
97 complain_overflow_dont, /* complain_on_overflow */
98 bfd_elf_generic_reloc, /* special_function */
99 "R_RISCV_RELATIVE", /* name */
100 FALSE, /* partial_inplace */
101 0, /* src_mask */
102 0xffffffff, /* dst_mask */
103 FALSE), /* pcrel_offset */
104
105 HOWTO (R_RISCV_COPY, /* type */
106 0, /* rightshift */
107 0, /* this one is variable size */
108 0, /* bitsize */
109 FALSE, /* pc_relative */
110 0, /* bitpos */
111 complain_overflow_bitfield, /* complain_on_overflow */
112 bfd_elf_generic_reloc, /* special_function */
113 "R_RISCV_COPY", /* name */
114 FALSE, /* partial_inplace */
115 0, /* src_mask */
116 0, /* dst_mask */
117 FALSE), /* pcrel_offset */
118
119 HOWTO (R_RISCV_JUMP_SLOT, /* type */
120 0, /* rightshift */
121 4, /* size */
122 64, /* bitsize */
123 FALSE, /* pc_relative */
124 0, /* bitpos */
125 complain_overflow_bitfield, /* complain_on_overflow */
126 bfd_elf_generic_reloc, /* special_function */
127 "R_RISCV_JUMP_SLOT", /* name */
128 FALSE, /* partial_inplace */
129 0, /* src_mask */
130 0, /* dst_mask */
131 FALSE), /* pcrel_offset */
132
133 /* Dynamic TLS relocations. */
134 HOWTO (R_RISCV_TLS_DTPMOD32, /* type */
135 0, /* rightshift */
136 2, /* size */
137 32, /* bitsize */
138 FALSE, /* pc_relative */
139 0, /* bitpos */
140 complain_overflow_dont, /* complain_on_overflow */
141 bfd_elf_generic_reloc, /* special_function */
142 "R_RISCV_TLS_DTPMOD32", /* name */
143 FALSE, /* partial_inplace */
144 0, /* src_mask */
145 0xffffffff, /* dst_mask */
146 FALSE), /* pcrel_offset */
147
148 HOWTO (R_RISCV_TLS_DTPMOD64, /* type */
149 0, /* rightshift */
150 4, /* size */
151 64, /* bitsize */
152 FALSE, /* pc_relative */
153 0, /* bitpos */
154 complain_overflow_dont, /* complain_on_overflow */
155 bfd_elf_generic_reloc, /* special_function */
156 "R_RISCV_TLS_DTPMOD64", /* name */
157 FALSE, /* partial_inplace */
158 0, /* src_mask */
159 MINUS_ONE, /* dst_mask */
160 FALSE), /* pcrel_offset */
161
162 HOWTO (R_RISCV_TLS_DTPREL32, /* type */
163 0, /* rightshift */
164 2, /* size */
165 32, /* bitsize */
166 FALSE, /* pc_relative */
167 0, /* bitpos */
168 complain_overflow_dont, /* complain_on_overflow */
169 bfd_elf_generic_reloc, /* special_function */
170 "R_RISCV_TLS_DTPREL32", /* name */
171 TRUE, /* partial_inplace */
172 0, /* src_mask */
173 0xffffffff, /* dst_mask */
174 FALSE), /* pcrel_offset */
175
176 HOWTO (R_RISCV_TLS_DTPREL64, /* type */
177 0, /* rightshift */
178 4, /* size */
179 64, /* bitsize */
180 FALSE, /* pc_relative */
181 0, /* bitpos */
182 complain_overflow_dont, /* complain_on_overflow */
183 bfd_elf_generic_reloc, /* special_function */
184 "R_RISCV_TLS_DTPREL64", /* name */
185 TRUE, /* partial_inplace */
186 0, /* src_mask */
187 MINUS_ONE, /* dst_mask */
188 FALSE), /* pcrel_offset */
189
190 HOWTO (R_RISCV_TLS_TPREL32, /* type */
191 0, /* rightshift */
192 2, /* size */
193 32, /* bitsize */
194 FALSE, /* pc_relative */
195 0, /* bitpos */
196 complain_overflow_dont, /* complain_on_overflow */
197 bfd_elf_generic_reloc, /* special_function */
198 "R_RISCV_TLS_TPREL32", /* name */
199 FALSE, /* partial_inplace */
200 0, /* src_mask */
201 0xffffffff, /* dst_mask */
202 FALSE), /* pcrel_offset */
203
204 HOWTO (R_RISCV_TLS_TPREL64, /* type */
205 0, /* rightshift */
206 4, /* size */
207 64, /* bitsize */
208 FALSE, /* pc_relative */
209 0, /* bitpos */
210 complain_overflow_dont, /* complain_on_overflow */
211 bfd_elf_generic_reloc, /* special_function */
212 "R_RISCV_TLS_TPREL64", /* name */
213 FALSE, /* partial_inplace */
214 0, /* src_mask */
215 MINUS_ONE, /* dst_mask */
216 FALSE), /* pcrel_offset */
217
218 /* Reserved for future relocs that the dynamic linker must understand. */
219 EMPTY_HOWTO (12),
220 EMPTY_HOWTO (13),
221 EMPTY_HOWTO (14),
222 EMPTY_HOWTO (15),
223
224 /* 12-bit PC-relative branch offset. */
225 HOWTO (R_RISCV_BRANCH, /* type */
226 0, /* rightshift */
227 2, /* size */
228 32, /* bitsize */
229 TRUE, /* pc_relative */
230 0, /* bitpos */
231 complain_overflow_signed, /* complain_on_overflow */
232 bfd_elf_generic_reloc, /* special_function */
233 "R_RISCV_BRANCH", /* name */
234 FALSE, /* partial_inplace */
235 0, /* src_mask */
236 ENCODE_SBTYPE_IMM (-1U), /* dst_mask */
237 TRUE), /* pcrel_offset */
238
239 /* 20-bit PC-relative jump offset. */
240 HOWTO (R_RISCV_JAL, /* type */
241 0, /* rightshift */
242 2, /* size */
243 32, /* bitsize */
244 TRUE, /* pc_relative */
245 0, /* bitpos */
246 complain_overflow_dont, /* complain_on_overflow */
247 bfd_elf_generic_reloc, /* special_function */
248 "R_RISCV_JAL", /* name */
249 FALSE, /* partial_inplace */
250 0, /* src_mask */
251 ENCODE_UJTYPE_IMM (-1U), /* dst_mask */
252 TRUE), /* pcrel_offset */
253
254 /* 32-bit PC-relative function call (AUIPC/JALR). */
255 HOWTO (R_RISCV_CALL, /* type */
256 0, /* rightshift */
257 4, /* size */
258 64, /* bitsize */
259 TRUE, /* pc_relative */
260 0, /* bitpos */
261 complain_overflow_dont, /* complain_on_overflow */
262 bfd_elf_generic_reloc, /* special_function */
263 "R_RISCV_CALL", /* name */
264 FALSE, /* partial_inplace */
265 0, /* src_mask */
266 ENCODE_UTYPE_IMM (-1U) | ((bfd_vma) ENCODE_ITYPE_IMM (-1U) << 32),
267 /* dst_mask */
268 TRUE), /* pcrel_offset */
269
270 /* Like R_RISCV_CALL, but not locally binding. */
271 HOWTO (R_RISCV_CALL_PLT, /* type */
272 0, /* rightshift */
273 4, /* size */
274 64, /* bitsize */
275 TRUE, /* pc_relative */
276 0, /* bitpos */
277 complain_overflow_dont, /* complain_on_overflow */
278 bfd_elf_generic_reloc, /* special_function */
279 "R_RISCV_CALL_PLT", /* name */
280 FALSE, /* partial_inplace */
281 0, /* src_mask */
282 ENCODE_UTYPE_IMM (-1U) | ((bfd_vma) ENCODE_ITYPE_IMM (-1U) << 32),
283 /* dst_mask */
284 TRUE), /* pcrel_offset */
285
286 /* High 20 bits of 32-bit PC-relative GOT access. */
287 HOWTO (R_RISCV_GOT_HI20, /* type */
288 0, /* rightshift */
289 2, /* size */
290 32, /* bitsize */
291 TRUE, /* pc_relative */
292 0, /* bitpos */
293 complain_overflow_dont, /* complain_on_overflow */
294 bfd_elf_generic_reloc, /* special_function */
295 "R_RISCV_GOT_HI20", /* name */
296 FALSE, /* partial_inplace */
297 0, /* src_mask */
298 ENCODE_UTYPE_IMM (-1U), /* dst_mask */
299 FALSE), /* pcrel_offset */
300
301 /* High 20 bits of 32-bit PC-relative TLS IE GOT access. */
302 HOWTO (R_RISCV_TLS_GOT_HI20, /* type */
303 0, /* rightshift */
304 2, /* size */
305 32, /* bitsize */
306 TRUE, /* pc_relative */
307 0, /* bitpos */
308 complain_overflow_dont, /* complain_on_overflow */
309 bfd_elf_generic_reloc, /* special_function */
310 "R_RISCV_TLS_GOT_HI20", /* name */
311 FALSE, /* partial_inplace */
312 0, /* src_mask */
313 ENCODE_UTYPE_IMM (-1U), /* dst_mask */
314 FALSE), /* pcrel_offset */
315
316 /* High 20 bits of 32-bit PC-relative TLS GD GOT reference. */
317 HOWTO (R_RISCV_TLS_GD_HI20, /* type */
318 0, /* rightshift */
319 2, /* size */
320 32, /* bitsize */
321 TRUE, /* pc_relative */
322 0, /* bitpos */
323 complain_overflow_dont, /* complain_on_overflow */
324 bfd_elf_generic_reloc, /* special_function */
325 "R_RISCV_TLS_GD_HI20", /* name */
326 FALSE, /* partial_inplace */
327 0, /* src_mask */
328 ENCODE_UTYPE_IMM (-1U), /* dst_mask */
329 FALSE), /* pcrel_offset */
330
331 /* High 20 bits of 32-bit PC-relative reference. */
332 HOWTO (R_RISCV_PCREL_HI20, /* type */
333 0, /* rightshift */
334 2, /* size */
335 32, /* bitsize */
336 TRUE, /* pc_relative */
337 0, /* bitpos */
338 complain_overflow_dont, /* complain_on_overflow */
339 bfd_elf_generic_reloc, /* special_function */
340 "R_RISCV_PCREL_HI20", /* name */
341 FALSE, /* partial_inplace */
342 0, /* src_mask */
343 ENCODE_UTYPE_IMM (-1U), /* dst_mask */
344 TRUE), /* pcrel_offset */
345
346 /* Low 12 bits of a 32-bit PC-relative load or add. */
347 HOWTO (R_RISCV_PCREL_LO12_I, /* type */
348 0, /* rightshift */
349 2, /* size */
350 32, /* bitsize */
351 FALSE, /* pc_relative */
352 0, /* bitpos */
353 complain_overflow_dont, /* complain_on_overflow */
354 bfd_elf_generic_reloc, /* special_function */
355 "R_RISCV_PCREL_LO12_I", /* name */
356 FALSE, /* partial_inplace */
357 0, /* src_mask */
358 ENCODE_ITYPE_IMM (-1U), /* dst_mask */
359 FALSE), /* pcrel_offset */
360
361 /* Low 12 bits of a 32-bit PC-relative store. */
362 HOWTO (R_RISCV_PCREL_LO12_S, /* type */
363 0, /* rightshift */
364 2, /* size */
365 32, /* bitsize */
366 FALSE, /* pc_relative */
367 0, /* bitpos */
368 complain_overflow_dont, /* complain_on_overflow */
369 bfd_elf_generic_reloc, /* special_function */
370 "R_RISCV_PCREL_LO12_S", /* name */
371 FALSE, /* partial_inplace */
372 0, /* src_mask */
373 ENCODE_STYPE_IMM (-1U), /* dst_mask */
374 FALSE), /* pcrel_offset */
375
376 /* High 20 bits of 32-bit absolute address. */
377 HOWTO (R_RISCV_HI20, /* type */
378 0, /* rightshift */
379 2, /* size */
380 32, /* bitsize */
381 FALSE, /* pc_relative */
382 0, /* bitpos */
383 complain_overflow_dont, /* complain_on_overflow */
384 bfd_elf_generic_reloc, /* special_function */
385 "R_RISCV_HI20", /* name */
386 FALSE, /* partial_inplace */
387 0, /* src_mask */
388 ENCODE_UTYPE_IMM (-1U), /* dst_mask */
389 FALSE), /* pcrel_offset */
390
391 /* High 12 bits of 32-bit load or add. */
392 HOWTO (R_RISCV_LO12_I, /* type */
393 0, /* rightshift */
394 2, /* size */
395 32, /* bitsize */
396 FALSE, /* pc_relative */
397 0, /* bitpos */
398 complain_overflow_dont, /* complain_on_overflow */
399 bfd_elf_generic_reloc, /* special_function */
400 "R_RISCV_LO12_I", /* name */
401 FALSE, /* partial_inplace */
402 0, /* src_mask */
403 ENCODE_ITYPE_IMM (-1U), /* dst_mask */
404 FALSE), /* pcrel_offset */
405
406 /* High 12 bits of 32-bit store. */
407 HOWTO (R_RISCV_LO12_S, /* type */
408 0, /* rightshift */
409 2, /* size */
410 32, /* bitsize */
411 FALSE, /* pc_relative */
412 0, /* bitpos */
413 complain_overflow_dont, /* complain_on_overflow */
414 bfd_elf_generic_reloc, /* special_function */
415 "R_RISCV_LO12_S", /* name */
416 FALSE, /* partial_inplace */
417 0, /* src_mask */
418 ENCODE_STYPE_IMM (-1U), /* dst_mask */
419 FALSE), /* pcrel_offset */
420
421 /* High 20 bits of TLS LE thread pointer offset. */
422 HOWTO (R_RISCV_TPREL_HI20, /* type */
423 0, /* rightshift */
424 2, /* size */
425 32, /* bitsize */
426 FALSE, /* pc_relative */
427 0, /* bitpos */
428 complain_overflow_signed, /* complain_on_overflow */
429 bfd_elf_generic_reloc, /* special_function */
430 "R_RISCV_TPREL_HI20", /* name */
431 TRUE, /* partial_inplace */
432 0, /* src_mask */
433 ENCODE_UTYPE_IMM (-1U), /* dst_mask */
434 FALSE), /* pcrel_offset */
435
436 /* Low 12 bits of TLS LE thread pointer offset for loads and adds. */
437 HOWTO (R_RISCV_TPREL_LO12_I, /* type */
438 0, /* rightshift */
439 2, /* size */
440 32, /* bitsize */
441 FALSE, /* pc_relative */
442 0, /* bitpos */
443 complain_overflow_signed, /* complain_on_overflow */
444 bfd_elf_generic_reloc, /* special_function */
445 "R_RISCV_TPREL_LO12_I", /* name */
446 FALSE, /* partial_inplace */
447 0, /* src_mask */
448 ENCODE_ITYPE_IMM (-1U), /* dst_mask */
449 FALSE), /* pcrel_offset */
450
451 /* Low 12 bits of TLS LE thread pointer offset for stores. */
452 HOWTO (R_RISCV_TPREL_LO12_S, /* type */
453 0, /* rightshift */
454 2, /* size */
455 32, /* bitsize */
456 FALSE, /* pc_relative */
457 0, /* bitpos */
458 complain_overflow_signed, /* complain_on_overflow */
459 bfd_elf_generic_reloc, /* special_function */
460 "R_RISCV_TPREL_LO12_S", /* name */
461 FALSE, /* partial_inplace */
462 0, /* src_mask */
463 ENCODE_STYPE_IMM (-1U), /* dst_mask */
464 FALSE), /* pcrel_offset */
465
466 /* TLS LE thread pointer usage. May be relaxed. */
467 HOWTO (R_RISCV_TPREL_ADD, /* type */
468 0, /* rightshift */
469 3, /* size */
470 0, /* bitsize */
471 FALSE, /* pc_relative */
472 0, /* bitpos */
473 complain_overflow_dont, /* complain_on_overflow */
474 bfd_elf_generic_reloc, /* special_function */
475 "R_RISCV_TPREL_ADD", /* name */
476 FALSE, /* partial_inplace */
477 0, /* src_mask */
478 0, /* dst_mask */
479 FALSE), /* pcrel_offset */
480
481 /* 8-bit in-place addition, for local label subtraction. */
482 HOWTO (R_RISCV_ADD8, /* type */
483 0, /* rightshift */
484 0, /* size */
485 8, /* bitsize */
486 FALSE, /* pc_relative */
487 0, /* bitpos */
488 complain_overflow_dont, /* complain_on_overflow */
489 riscv_elf_add_sub_reloc, /* special_function */
490 "R_RISCV_ADD8", /* name */
491 FALSE, /* partial_inplace */
492 0, /* src_mask */
493 0xff, /* dst_mask */
494 FALSE), /* pcrel_offset */
495
496 /* 16-bit in-place addition, for local label subtraction. */
497 HOWTO (R_RISCV_ADD16, /* type */
498 0, /* rightshift */
499 1, /* size */
500 16, /* bitsize */
501 FALSE, /* pc_relative */
502 0, /* bitpos */
503 complain_overflow_dont, /* complain_on_overflow */
504 riscv_elf_add_sub_reloc, /* special_function */
505 "R_RISCV_ADD16", /* name */
506 FALSE, /* partial_inplace */
507 0, /* src_mask */
508 0xffff, /* dst_mask */
509 FALSE), /* pcrel_offset */
510
511 /* 32-bit in-place addition, for local label subtraction. */
512 HOWTO (R_RISCV_ADD32, /* type */
513 0, /* rightshift */
514 2, /* size */
515 32, /* bitsize */
516 FALSE, /* pc_relative */
517 0, /* bitpos */
518 complain_overflow_dont, /* complain_on_overflow */
519 riscv_elf_add_sub_reloc, /* special_function */
520 "R_RISCV_ADD32", /* name */
521 FALSE, /* partial_inplace */
522 0, /* src_mask */
523 0xffffffff, /* dst_mask */
524 FALSE), /* pcrel_offset */
525
526 /* 64-bit in-place addition, for local label subtraction. */
527 HOWTO (R_RISCV_ADD64, /* type */
528 0, /* rightshift */
529 4, /* size */
530 64, /* bitsize */
531 FALSE, /* pc_relative */
532 0, /* bitpos */
533 complain_overflow_dont, /* complain_on_overflow */
534 riscv_elf_add_sub_reloc, /* special_function */
535 "R_RISCV_ADD64", /* name */
536 FALSE, /* partial_inplace */
537 0, /* src_mask */
538 MINUS_ONE, /* dst_mask */
539 FALSE), /* pcrel_offset */
540
541 /* 8-bit in-place addition, for local label subtraction. */
542 HOWTO (R_RISCV_SUB8, /* type */
543 0, /* rightshift */
544 0, /* size */
545 8, /* bitsize */
546 FALSE, /* pc_relative */
547 0, /* bitpos */
548 complain_overflow_dont, /* complain_on_overflow */
549 riscv_elf_add_sub_reloc, /* special_function */
550 "R_RISCV_SUB8", /* name */
551 FALSE, /* partial_inplace */
552 0, /* src_mask */
553 0xff, /* dst_mask */
554 FALSE), /* pcrel_offset */
555
556 /* 16-bit in-place addition, for local label subtraction. */
557 HOWTO (R_RISCV_SUB16, /* type */
558 0, /* rightshift */
559 1, /* size */
560 16, /* bitsize */
561 FALSE, /* pc_relative */
562 0, /* bitpos */
563 complain_overflow_dont, /* complain_on_overflow */
564 riscv_elf_add_sub_reloc, /* special_function */
565 "R_RISCV_SUB16", /* name */
566 FALSE, /* partial_inplace */
567 0, /* src_mask */
568 0xffff, /* dst_mask */
569 FALSE), /* pcrel_offset */
570
571 /* 32-bit in-place addition, for local label subtraction. */
572 HOWTO (R_RISCV_SUB32, /* type */
573 0, /* rightshift */
574 2, /* size */
575 32, /* bitsize */
576 FALSE, /* pc_relative */
577 0, /* bitpos */
578 complain_overflow_dont, /* complain_on_overflow */
579 riscv_elf_add_sub_reloc, /* special_function */
580 "R_RISCV_SUB32", /* name */
581 FALSE, /* partial_inplace */
582 0, /* src_mask */
583 0xffffffff, /* dst_mask */
584 FALSE), /* pcrel_offset */
585
586 /* 64-bit in-place addition, for local label subtraction. */
587 HOWTO (R_RISCV_SUB64, /* type */
588 0, /* rightshift */
589 4, /* size */
590 64, /* bitsize */
591 FALSE, /* pc_relative */
592 0, /* bitpos */
593 complain_overflow_dont, /* complain_on_overflow */
594 riscv_elf_add_sub_reloc, /* special_function */
595 "R_RISCV_SUB64", /* name */
596 FALSE, /* partial_inplace */
597 0, /* src_mask */
598 MINUS_ONE, /* dst_mask */
599 FALSE), /* pcrel_offset */
600
601 /* GNU extension to record C++ vtable hierarchy */
602 HOWTO (R_RISCV_GNU_VTINHERIT, /* type */
603 0, /* rightshift */
604 4, /* size */
605 0, /* bitsize */
606 FALSE, /* pc_relative */
607 0, /* bitpos */
608 complain_overflow_dont, /* complain_on_overflow */
609 NULL, /* special_function */
610 "R_RISCV_GNU_VTINHERIT", /* name */
611 FALSE, /* partial_inplace */
612 0, /* src_mask */
613 0, /* dst_mask */
614 FALSE), /* pcrel_offset */
615
616 /* GNU extension to record C++ vtable member usage */
617 HOWTO (R_RISCV_GNU_VTENTRY, /* type */
618 0, /* rightshift */
619 4, /* size */
620 0, /* bitsize */
621 FALSE, /* pc_relative */
622 0, /* bitpos */
623 complain_overflow_dont, /* complain_on_overflow */
624 _bfd_elf_rel_vtable_reloc_fn, /* special_function */
625 "R_RISCV_GNU_VTENTRY", /* name */
626 FALSE, /* partial_inplace */
627 0, /* src_mask */
628 0, /* dst_mask */
629 FALSE), /* pcrel_offset */
630
631 /* Indicates an alignment statement. The addend field encodes how many
632 bytes of NOPs follow the statement. The desired alignment is the
633 addend rounded up to the next power of two. */
634 HOWTO (R_RISCV_ALIGN, /* type */
635 0, /* rightshift */
636 3, /* size */
637 0, /* bitsize */
638 FALSE, /* pc_relative */
639 0, /* bitpos */
640 complain_overflow_dont, /* complain_on_overflow */
641 bfd_elf_generic_reloc, /* special_function */
642 "R_RISCV_ALIGN", /* name */
643 FALSE, /* partial_inplace */
644 0, /* src_mask */
645 0, /* dst_mask */
646 FALSE), /* pcrel_offset */
647
648 /* 8-bit PC-relative branch offset. */
649 HOWTO (R_RISCV_RVC_BRANCH, /* type */
650 0, /* rightshift */
651 1, /* size */
652 16, /* bitsize */
653 TRUE, /* pc_relative */
654 0, /* bitpos */
655 complain_overflow_signed, /* complain_on_overflow */
656 bfd_elf_generic_reloc, /* special_function */
657 "R_RISCV_RVC_BRANCH", /* name */
658 FALSE, /* partial_inplace */
659 0, /* src_mask */
660 ENCODE_RVC_B_IMM (-1U), /* dst_mask */
661 TRUE), /* pcrel_offset */
662
663 /* 11-bit PC-relative jump offset. */
664 HOWTO (R_RISCV_RVC_JUMP, /* type */
665 0, /* rightshift */
666 1, /* size */
667 16, /* bitsize */
668 TRUE, /* pc_relative */
669 0, /* bitpos */
670 complain_overflow_dont, /* complain_on_overflow */
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 1, /* size */
682 16, /* 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 /* GP-relative load. */
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 /* GP-relative 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 /* TP-relative TLS LE load. */
724 HOWTO (R_RISCV_TPREL_I, /* type */
725 0, /* rightshift */
726 2, /* size */
727 32, /* bitsize */
728 FALSE, /* pc_relative */
729 0, /* bitpos */
730 complain_overflow_signed, /* complain_on_overflow */
731 bfd_elf_generic_reloc, /* special_function */
732 "R_RISCV_TPREL_I", /* name */
733 FALSE, /* partial_inplace */
734 0, /* src_mask */
735 ENCODE_ITYPE_IMM (-1U), /* dst_mask */
736 FALSE), /* pcrel_offset */
737
738 /* TP-relative TLS LE store. */
739 HOWTO (R_RISCV_TPREL_S, /* type */
740 0, /* rightshift */
741 2, /* size */
742 32, /* bitsize */
743 FALSE, /* pc_relative */
744 0, /* bitpos */
745 complain_overflow_signed, /* complain_on_overflow */
746 bfd_elf_generic_reloc, /* special_function */
747 "R_RISCV_TPREL_S", /* name */
748 FALSE, /* partial_inplace */
749 0, /* src_mask */
750 ENCODE_STYPE_IMM (-1U), /* dst_mask */
751 FALSE), /* pcrel_offset */
752
753 /* The paired relocation may be relaxed. */
754 HOWTO (R_RISCV_RELAX, /* type */
755 0, /* rightshift */
756 3, /* size */
757 0, /* bitsize */
758 FALSE, /* pc_relative */
759 0, /* bitpos */
760 complain_overflow_dont, /* complain_on_overflow */
761 bfd_elf_generic_reloc, /* special_function */
762 "R_RISCV_RELAX", /* name */
763 FALSE, /* partial_inplace */
764 0, /* src_mask */
765 0, /* dst_mask */
766 FALSE), /* pcrel_offset */
767
768 /* 6-bit in-place addition, for local label subtraction. */
769 HOWTO (R_RISCV_SUB6, /* type */
770 0, /* rightshift */
771 0, /* size */
772 8, /* bitsize */
773 FALSE, /* pc_relative */
774 0, /* bitpos */
775 complain_overflow_dont, /* complain_on_overflow */
776 riscv_elf_add_sub_reloc, /* special_function */
777 "R_RISCV_SUB6", /* name */
778 FALSE, /* partial_inplace */
779 0, /* src_mask */
780 0x3f, /* dst_mask */
781 FALSE), /* pcrel_offset */
782
783 /* 6-bit in-place setting, for local label subtraction. */
784 HOWTO (R_RISCV_SET6, /* type */
785 0, /* rightshift */
786 0, /* size */
787 8, /* bitsize */
788 FALSE, /* pc_relative */
789 0, /* bitpos */
790 complain_overflow_dont, /* complain_on_overflow */
791 bfd_elf_generic_reloc, /* special_function */
792 "R_RISCV_SET6", /* name */
793 FALSE, /* partial_inplace */
794 0, /* src_mask */
795 0x3f, /* dst_mask */
796 FALSE), /* pcrel_offset */
797
798 /* 8-bit in-place setting, for local label subtraction. */
799 HOWTO (R_RISCV_SET8, /* type */
800 0, /* rightshift */
801 0, /* size */
802 8, /* bitsize */
803 FALSE, /* pc_relative */
804 0, /* bitpos */
805 complain_overflow_dont, /* complain_on_overflow */
806 bfd_elf_generic_reloc, /* special_function */
807 "R_RISCV_SET8", /* name */
808 FALSE, /* partial_inplace */
809 0, /* src_mask */
810 0xff, /* dst_mask */
811 FALSE), /* pcrel_offset */
812
813 /* 16-bit in-place setting, for local label subtraction. */
814 HOWTO (R_RISCV_SET16, /* type */
815 0, /* rightshift */
816 1, /* size */
817 16, /* bitsize */
818 FALSE, /* pc_relative */
819 0, /* bitpos */
820 complain_overflow_dont, /* complain_on_overflow */
821 bfd_elf_generic_reloc, /* special_function */
822 "R_RISCV_SET16", /* name */
823 FALSE, /* partial_inplace */
824 0, /* src_mask */
825 0xffff, /* dst_mask */
826 FALSE), /* pcrel_offset */
827
828 /* 32-bit in-place setting, for local label subtraction. */
829 HOWTO (R_RISCV_SET32, /* type */
830 0, /* rightshift */
831 2, /* size */
832 32, /* bitsize */
833 FALSE, /* pc_relative */
834 0, /* bitpos */
835 complain_overflow_dont, /* complain_on_overflow */
836 bfd_elf_generic_reloc, /* special_function */
837 "R_RISCV_SET32", /* name */
838 FALSE, /* partial_inplace */
839 0, /* src_mask */
840 0xffffffff, /* dst_mask */
841 FALSE), /* pcrel_offset */
842
843 /* 32-bit PC relative. */
844 HOWTO (R_RISCV_32_PCREL, /* type */
845 0, /* rightshift */
846 2, /* size */
847 32, /* bitsize */
848 TRUE, /* pc_relative */
849 0, /* bitpos */
850 complain_overflow_dont, /* complain_on_overflow */
851 bfd_elf_generic_reloc, /* special_function */
852 "R_RISCV_32_PCREL", /* name */
853 FALSE, /* partial_inplace */
854 0, /* src_mask */
855 0xffffffff, /* dst_mask */
856 FALSE), /* pcrel_offset */
857
858 /* Relocation against a local ifunc symbol in a shared object. */
859 HOWTO (R_RISCV_IRELATIVE, /* type */
860 0, /* rightshift */
861 2, /* size */
862 32, /* bitsize */
863 FALSE, /* pc_relative */
864 0, /* bitpos */
865 complain_overflow_dont, /* complain_on_overflow */
866 bfd_elf_generic_reloc, /* special_function */
867 "R_RISCV_IRELATIVE", /* name */
868 FALSE, /* partial_inplace */
869 0, /* src_mask */
870 0xffffffff, /* dst_mask */
871 FALSE), /* pcrel_offset */
872 };
873
874 /* A mapping from BFD reloc types to RISC-V ELF reloc types. */
875
876 struct elf_reloc_map
877 {
878 bfd_reloc_code_real_type bfd_val;
879 enum elf_riscv_reloc_type elf_val;
880 };
881
882 static const struct elf_reloc_map riscv_reloc_map[] =
883 {
884 { BFD_RELOC_NONE, R_RISCV_NONE },
885 { BFD_RELOC_32, R_RISCV_32 },
886 { BFD_RELOC_64, R_RISCV_64 },
887 { BFD_RELOC_RISCV_ADD8, R_RISCV_ADD8 },
888 { BFD_RELOC_RISCV_ADD16, R_RISCV_ADD16 },
889 { BFD_RELOC_RISCV_ADD32, R_RISCV_ADD32 },
890 { BFD_RELOC_RISCV_ADD64, R_RISCV_ADD64 },
891 { BFD_RELOC_RISCV_SUB8, R_RISCV_SUB8 },
892 { BFD_RELOC_RISCV_SUB16, R_RISCV_SUB16 },
893 { BFD_RELOC_RISCV_SUB32, R_RISCV_SUB32 },
894 { BFD_RELOC_RISCV_SUB64, R_RISCV_SUB64 },
895 { BFD_RELOC_CTOR, R_RISCV_64 },
896 { BFD_RELOC_12_PCREL, R_RISCV_BRANCH },
897 { BFD_RELOC_RISCV_HI20, R_RISCV_HI20 },
898 { BFD_RELOC_RISCV_LO12_I, R_RISCV_LO12_I },
899 { BFD_RELOC_RISCV_LO12_S, R_RISCV_LO12_S },
900 { BFD_RELOC_RISCV_PCREL_LO12_I, R_RISCV_PCREL_LO12_I },
901 { BFD_RELOC_RISCV_PCREL_LO12_S, R_RISCV_PCREL_LO12_S },
902 { BFD_RELOC_RISCV_CALL, R_RISCV_CALL },
903 { BFD_RELOC_RISCV_CALL_PLT, R_RISCV_CALL_PLT },
904 { BFD_RELOC_RISCV_PCREL_HI20, R_RISCV_PCREL_HI20 },
905 { BFD_RELOC_RISCV_JMP, R_RISCV_JAL },
906 { BFD_RELOC_RISCV_GOT_HI20, R_RISCV_GOT_HI20 },
907 { BFD_RELOC_RISCV_TLS_DTPMOD32, R_RISCV_TLS_DTPMOD32 },
908 { BFD_RELOC_RISCV_TLS_DTPREL32, R_RISCV_TLS_DTPREL32 },
909 { BFD_RELOC_RISCV_TLS_DTPMOD64, R_RISCV_TLS_DTPMOD64 },
910 { BFD_RELOC_RISCV_TLS_DTPREL64, R_RISCV_TLS_DTPREL64 },
911 { BFD_RELOC_RISCV_TLS_TPREL32, R_RISCV_TLS_TPREL32 },
912 { BFD_RELOC_RISCV_TLS_TPREL64, R_RISCV_TLS_TPREL64 },
913 { BFD_RELOC_RISCV_TPREL_HI20, R_RISCV_TPREL_HI20 },
914 { BFD_RELOC_RISCV_TPREL_ADD, R_RISCV_TPREL_ADD },
915 { BFD_RELOC_RISCV_TPREL_LO12_S, R_RISCV_TPREL_LO12_S },
916 { BFD_RELOC_RISCV_TPREL_LO12_I, R_RISCV_TPREL_LO12_I },
917 { BFD_RELOC_RISCV_TLS_GOT_HI20, R_RISCV_TLS_GOT_HI20 },
918 { BFD_RELOC_RISCV_TLS_GD_HI20, R_RISCV_TLS_GD_HI20 },
919 { BFD_RELOC_RISCV_ALIGN, R_RISCV_ALIGN },
920 { BFD_RELOC_RISCV_RVC_BRANCH, R_RISCV_RVC_BRANCH },
921 { BFD_RELOC_RISCV_RVC_JUMP, R_RISCV_RVC_JUMP },
922 { BFD_RELOC_RISCV_RVC_LUI, R_RISCV_RVC_LUI },
923 { BFD_RELOC_RISCV_GPREL_I, R_RISCV_GPREL_I },
924 { BFD_RELOC_RISCV_GPREL_S, R_RISCV_GPREL_S },
925 { BFD_RELOC_RISCV_TPREL_I, R_RISCV_TPREL_I },
926 { BFD_RELOC_RISCV_TPREL_S, R_RISCV_TPREL_S },
927 { BFD_RELOC_RISCV_RELAX, R_RISCV_RELAX },
928 { BFD_RELOC_RISCV_SUB6, R_RISCV_SUB6 },
929 { BFD_RELOC_RISCV_SET6, R_RISCV_SET6 },
930 { BFD_RELOC_RISCV_SET8, R_RISCV_SET8 },
931 { BFD_RELOC_RISCV_SET16, R_RISCV_SET16 },
932 { BFD_RELOC_RISCV_SET32, R_RISCV_SET32 },
933 { BFD_RELOC_RISCV_32_PCREL, R_RISCV_32_PCREL },
934 };
935
936 /* Given a BFD reloc type, return a howto structure. */
937
938 reloc_howto_type *
939 riscv_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
940 bfd_reloc_code_real_type code)
941 {
942 unsigned int i;
943
944 for (i = 0; i < ARRAY_SIZE (riscv_reloc_map); i++)
945 if (riscv_reloc_map[i].bfd_val == code)
946 return &howto_table[(int) riscv_reloc_map[i].elf_val];
947
948 bfd_set_error (bfd_error_bad_value);
949 return NULL;
950 }
951
952 reloc_howto_type *
953 riscv_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name)
954 {
955 unsigned int i;
956
957 for (i = 0; i < ARRAY_SIZE (howto_table); i++)
958 if (howto_table[i].name && strcasecmp (howto_table[i].name, r_name) == 0)
959 return &howto_table[i];
960
961 return NULL;
962 }
963
964 reloc_howto_type *
965 riscv_elf_rtype_to_howto (bfd *abfd, unsigned int r_type)
966 {
967 if (r_type >= ARRAY_SIZE (howto_table))
968 {
969 (*_bfd_error_handler) (_("%pB: unsupported relocation type %#x"),
970 abfd, r_type);
971 bfd_set_error (bfd_error_bad_value);
972 return NULL;
973 }
974 return &howto_table[r_type];
975 }
976
977 /* Special_function of RISCV_ADD and RISCV_SUB relocations. */
978
979 static bfd_reloc_status_type
980 riscv_elf_add_sub_reloc (bfd *abfd,
981 arelent *reloc_entry,
982 asymbol *symbol,
983 void *data,
984 asection *input_section,
985 bfd *output_bfd,
986 char **error_message ATTRIBUTE_UNUSED)
987 {
988 reloc_howto_type *howto = reloc_entry->howto;
989 bfd_vma relocation;
990
991 if (output_bfd != NULL
992 && (symbol->flags & BSF_SECTION_SYM) == 0
993 && (!reloc_entry->howto->partial_inplace || reloc_entry->addend == 0))
994 {
995 reloc_entry->address += input_section->output_offset;
996 return bfd_reloc_ok;
997 }
998
999 if (output_bfd != NULL)
1000 return bfd_reloc_continue;
1001
1002 relocation = symbol->value + symbol->section->output_section->vma
1003 + symbol->section->output_offset + reloc_entry->addend;
1004 bfd_vma old_value = bfd_get (howto->bitsize, abfd,
1005 data + reloc_entry->address);
1006
1007 switch (howto->type)
1008 {
1009 case R_RISCV_ADD8:
1010 case R_RISCV_ADD16:
1011 case R_RISCV_ADD32:
1012 case R_RISCV_ADD64:
1013 relocation = old_value + relocation;
1014 break;
1015 case R_RISCV_SUB6:
1016 case R_RISCV_SUB8:
1017 case R_RISCV_SUB16:
1018 case R_RISCV_SUB32:
1019 case R_RISCV_SUB64:
1020 relocation = old_value - relocation;
1021 break;
1022 }
1023 bfd_put (howto->bitsize, abfd, relocation, data + reloc_entry->address);
1024
1025 return bfd_reloc_ok;
1026 }
1027
1028 /* Array is used to compare the all extensions' order quickly.
1029
1030 Zero number means it is a preserved keyword.
1031 Negative number means it is a prefix keyword (s, h, x, z).
1032 Positive number means it is a standard extension. */
1033
1034 static int riscv_ext_order[26] = {0};
1035
1036 /* Similar to the strcmp. It returns an integer less than, equal to,
1037 or greater than zero if `subset2` is found, respectively, to be less
1038 than, to match, or be greater than `subset1`. */
1039
1040 static int
1041 riscv_compare_subsets (const char *subset1, const char *subset2)
1042 {
1043 int order1 = riscv_ext_order[(*subset1 - 'a')];
1044 int order2 = riscv_ext_order[(*subset2 - 'a')];
1045
1046 /* Compare the standard extension first. */
1047 if (order1 > 0 && order2 > 0)
1048 return order1 - order2;
1049
1050 if (order1 == order2 && order1 < 0)
1051 {
1052 /* Compare the standard addition z extensions. */
1053 if (*subset1 == 'z')
1054 {
1055 order1 = riscv_ext_order[(*++subset1 - 'a')];
1056 order2 = riscv_ext_order[(*++subset2 - 'a')];
1057 if (order1 != order2)
1058 return order1 - order2;
1059 }
1060 return strcasecmp (++subset1, ++subset2);
1061 }
1062
1063 return order2 - order1;
1064 }
1065
1066 /* Find subset in the list. Return TRUE and set `current` to the subset
1067 if it is found. Otherwise, return FALSE and set `current` to the place
1068 where we should insert the subset. However, return FALSE with the NULL
1069 `current` means we should insert the subset at the head of subset list,
1070 if needed. */
1071
1072 bfd_boolean
1073 riscv_lookup_subset (const riscv_subset_list_t *subset_list,
1074 const char *subset,
1075 riscv_subset_t **current)
1076 {
1077 riscv_subset_t *s, *pre_s = NULL;
1078
1079 for (s = subset_list->head;
1080 s != NULL;
1081 pre_s = s, s = s->next)
1082 {
1083 int cmp = riscv_compare_subsets (s->name, subset);
1084 if (cmp == 0)
1085 {
1086 *current = s;
1087 return TRUE;
1088 }
1089 else if (cmp > 0)
1090 break;
1091 }
1092 *current = pre_s;
1093 return FALSE;
1094 }
1095
1096 /* Add arch string extension to the last of the subset list. */
1097
1098 void
1099 riscv_add_subset (riscv_subset_list_t *subset_list,
1100 const char *subset,
1101 int major,
1102 int minor)
1103 {
1104 riscv_subset_t *s = xmalloc (sizeof *s);
1105
1106 if (subset_list->head == NULL)
1107 subset_list->head = s;
1108
1109 s->name = xstrdup (subset);
1110 s->major_version = major;
1111 s->minor_version = minor;
1112 s->next = NULL;
1113
1114 if (subset_list->tail != NULL)
1115 subset_list->tail->next = s;
1116 subset_list->tail = s;
1117 }
1118
1119 /* Add the implicit extension to the subset list. Search the
1120 list first, and then find the right place to add. */
1121
1122 static void
1123 riscv_add_implicit_subset (riscv_subset_list_t *subset_list,
1124 const char *subset,
1125 int major,
1126 int minor)
1127 {
1128 riscv_subset_t *current, *new;
1129
1130 if (riscv_lookup_subset (subset_list, subset, &current))
1131 return;
1132
1133 new = xmalloc (sizeof *new);
1134 new->name = xstrdup (subset);
1135 new->major_version = major;
1136 new->minor_version = minor;
1137 new->next = NULL;
1138
1139 if (current != NULL)
1140 {
1141 new->next = current->next;
1142 current->next = new;
1143 }
1144 else
1145 {
1146 new->next = subset_list->head;
1147 subset_list->head = new;
1148 }
1149 }
1150
1151 /* We have to add all arch string extensions first, and then start to
1152 add their implicit extensions. The arch string extensions must be
1153 set in order, so we can add them to the last of the subset list
1154 directly, without searching.
1155
1156 Find the default versions for the extension before adding them to
1157 the subset list, if their versions are RISCV_UNKNOWN_VERSION.
1158 Afterwards, report errors if we can not find their default versions. */
1159
1160 static void
1161 riscv_parse_add_subset (riscv_parse_subset_t *rps,
1162 const char *subset,
1163 int major,
1164 int minor,
1165 bfd_boolean implicit)
1166 {
1167 int major_version = major;
1168 int minor_version = minor;
1169
1170 if ((major_version == RISCV_UNKNOWN_VERSION
1171 || minor_version == RISCV_UNKNOWN_VERSION)
1172 && rps->get_default_version != NULL)
1173 rps->get_default_version (subset, &major_version, &minor_version);
1174
1175 if (!implicit
1176 && strcmp (subset, "g") != 0
1177 && (major_version == RISCV_UNKNOWN_VERSION
1178 || minor_version == RISCV_UNKNOWN_VERSION))
1179 {
1180 if (subset[0] == 'x')
1181 rps->error_handler
1182 (_("x ISA extension `%s' must be set with the versions"),
1183 subset);
1184 else
1185 rps->error_handler
1186 (_("cannot find default versions of the ISA extension `%s'"),
1187 subset);
1188 return;
1189 }
1190
1191 if (!implicit)
1192 riscv_add_subset (rps->subset_list, subset,
1193 major_version, minor_version);
1194 else if (major_version != RISCV_UNKNOWN_VERSION
1195 && minor_version != RISCV_UNKNOWN_VERSION)
1196 /* We only add the implicit extension if it is supported in the
1197 chosen ISA spec. */
1198 riscv_add_implicit_subset (rps->subset_list, subset,
1199 major_version, minor_version);
1200 }
1201
1202 /* Release subset list. */
1203
1204 void
1205 riscv_release_subset_list (riscv_subset_list_t *subset_list)
1206 {
1207 while (subset_list->head != NULL)
1208 {
1209 riscv_subset_t *next = subset_list->head->next;
1210 free ((void *)subset_list->head->name);
1211 free (subset_list->head);
1212 subset_list->head = next;
1213 }
1214
1215 subset_list->tail = NULL;
1216 }
1217
1218 /* Parsing extension version.
1219
1220 Return Value:
1221 Points to the end of version
1222
1223 Arguments:
1224 `rps`: Hooks and status for parsing extensions.
1225 `march`: Full arch string.
1226 `p`: Curent parsing position.
1227 `major_version`: Parsed major version.
1228 `minor_version`: Parsed minor version.
1229 `std_ext_p`: True if parsing standard extension. */
1230
1231 static const char *
1232 riscv_parsing_subset_version (riscv_parse_subset_t *rps,
1233 const char *march,
1234 const char *p,
1235 int *major_version,
1236 int *minor_version,
1237 bfd_boolean std_ext_p)
1238 {
1239 bfd_boolean major_p = TRUE;
1240 int version = 0;
1241 char np;
1242
1243 *major_version = 0;
1244 *minor_version = 0;
1245 for (; *p; ++p)
1246 {
1247 if (*p == 'p')
1248 {
1249 np = *(p + 1);
1250
1251 if (!ISDIGIT (np))
1252 {
1253 /* Might be beginning of `p` extension. */
1254 if (std_ext_p)
1255 {
1256 *major_version = version;
1257 *minor_version = 0;
1258 return p;
1259 }
1260 else
1261 {
1262 rps->error_handler
1263 (_("-march=%s: expect number after `%dp'"),
1264 march, version);
1265 return NULL;
1266 }
1267 }
1268
1269 *major_version = version;
1270 major_p = FALSE;
1271 version = 0;
1272 }
1273 else if (ISDIGIT (*p))
1274 version = (version * 10) + (*p - '0');
1275 else
1276 break;
1277 }
1278
1279 if (major_p)
1280 *major_version = version;
1281 else
1282 *minor_version = version;
1283
1284 /* We can not find any version in string. */
1285 if (*major_version == 0 && *minor_version == 0)
1286 {
1287 *major_version = RISCV_UNKNOWN_VERSION;
1288 *minor_version = RISCV_UNKNOWN_VERSION;
1289 }
1290
1291 return p;
1292 }
1293
1294 /* Return string which contain all supported standard extensions in
1295 canonical order. */
1296
1297 const char *
1298 riscv_supported_std_ext (void)
1299 {
1300 return "mafdqlcbjtpvn";
1301 }
1302
1303 /* Parsing function for standard extensions.
1304
1305 Return Value:
1306 Points to the end of extensions.
1307
1308 Arguments:
1309 `rps`: Hooks and status for parsing extensions.
1310 `march`: Full arch string.
1311 `p`: Curent parsing position. */
1312
1313 static const char *
1314 riscv_parse_std_ext (riscv_parse_subset_t *rps,
1315 const char *march,
1316 const char *p)
1317 {
1318 const char *all_std_exts = riscv_supported_std_ext ();
1319 const char *std_exts = all_std_exts;
1320 int major_version;
1321 int minor_version;
1322 char subset[2] = {0, 0};
1323
1324 /* First letter must start with i, e or g. */
1325 switch (*p)
1326 {
1327 case 'i':
1328 p = riscv_parsing_subset_version (rps, march, ++p,
1329 &major_version,
1330 &minor_version, TRUE);
1331 riscv_parse_add_subset (rps, "i",
1332 major_version,
1333 minor_version, FALSE);
1334 break;
1335
1336 case 'e':
1337 p = riscv_parsing_subset_version (rps, march, ++p,
1338 &major_version,
1339 &minor_version, TRUE);
1340 riscv_parse_add_subset (rps, "e",
1341 major_version,
1342 minor_version, FALSE);
1343 /* i-ext must be enabled. */
1344 riscv_parse_add_subset (rps, "i",
1345 RISCV_UNKNOWN_VERSION,
1346 RISCV_UNKNOWN_VERSION, FALSE);
1347
1348 if (*rps->xlen > 32)
1349 {
1350 rps->error_handler
1351 (_("-march=%s: rv%de is not a valid base ISA"),
1352 march, *rps->xlen);
1353 return NULL;
1354 }
1355 break;
1356
1357 case 'g':
1358 p = riscv_parsing_subset_version (rps, march, ++p,
1359 &major_version,
1360 &minor_version, TRUE);
1361 /* i-ext must be enabled. */
1362 riscv_parse_add_subset (rps, "i",
1363 RISCV_UNKNOWN_VERSION,
1364 RISCV_UNKNOWN_VERSION, FALSE);
1365 /* g-ext is used to add the implicit extensions, but will
1366 not be output to the arch string. */
1367 riscv_parse_add_subset (rps, "g",
1368 major_version,
1369 minor_version, FALSE);
1370 for ( ; *std_exts != 'q'; std_exts++)
1371 {
1372 subset[0] = *std_exts;
1373 riscv_parse_add_subset (rps, subset,
1374 RISCV_UNKNOWN_VERSION,
1375 RISCV_UNKNOWN_VERSION, FALSE);
1376 }
1377 break;
1378
1379 default:
1380 rps->error_handler
1381 (_("-march=%s: first ISA extension must be `e', `i' or `g'"),
1382 march);
1383 return NULL;
1384 }
1385
1386 while (p != NULL && *p != '\0')
1387 {
1388 if (*p == 'x' || *p == 's' || *p == 'h' || *p == 'z')
1389 break;
1390
1391 if (*p == '_')
1392 {
1393 p++;
1394 continue;
1395 }
1396
1397 /* Checking canonical order. */
1398 char std_ext = *p;
1399 while (*std_exts && std_ext != *std_exts)
1400 std_exts++;
1401
1402 if (std_ext != *std_exts)
1403 {
1404 if (strchr (all_std_exts, std_ext) == NULL)
1405 rps->error_handler
1406 (_("-march=%s: unknown standard ISA extension `%c'"),
1407 march, std_ext);
1408 else
1409 rps->error_handler
1410 (_("-march=%s: standard ISA extension `%c' is not "
1411 "in canonical order"), march, std_ext);
1412 return NULL;
1413 }
1414
1415 std_exts++;
1416 subset[0] = std_ext;
1417 p = riscv_parsing_subset_version (rps, march, ++p,
1418 &major_version,
1419 &minor_version, TRUE);
1420 riscv_parse_add_subset (rps, subset,
1421 major_version,
1422 minor_version, FALSE);
1423 }
1424
1425 return p;
1426 }
1427
1428 /* Classify the argument 'arch' into one of riscv_isa_ext_class_t. */
1429
1430 riscv_isa_ext_class_t
1431 riscv_get_prefix_class (const char *arch)
1432 {
1433 switch (*arch)
1434 {
1435 case 's': return RV_ISA_CLASS_S;
1436 case 'h': return RV_ISA_CLASS_H;
1437 case 'x': return RV_ISA_CLASS_X;
1438 case 'z': return RV_ISA_CLASS_Z;
1439 default: return RV_ISA_CLASS_UNKNOWN;
1440 }
1441 }
1442
1443 /* Structure describing parameters to use when parsing a particular
1444 riscv_isa_ext_class_t. One of these should be provided for each
1445 possible class, except RV_ISA_CLASS_UNKNOWN. */
1446
1447 typedef struct riscv_parse_config
1448 {
1449 /* Class of the extension. */
1450 riscv_isa_ext_class_t class;
1451
1452 /* Prefix string for error printing and internal parser usage. */
1453 const char *prefix;
1454
1455 /* Predicate which is used for checking whether this is a "known"
1456 extension. For 'x', it always returns true since they are by
1457 definition non-standard and cannot be known. */
1458 bfd_boolean (*ext_valid_p) (const char *);
1459 } riscv_parse_config_t;
1460
1461 /* Parsing function for prefixed extensions.
1462
1463 Return Value:
1464 Points to the end of extension.
1465
1466 Arguments:
1467 `rps`: Hooks and status for parsing extensions.
1468 `march`: Full architecture string.
1469 `p`: Curent parsing position.
1470 `config`: What class and predicate function to use for the
1471 extension. */
1472
1473 static const char *
1474 riscv_parse_prefixed_ext (riscv_parse_subset_t *rps,
1475 const char *march,
1476 const char *p,
1477 const riscv_parse_config_t *config)
1478 {
1479 int major_version;
1480 int minor_version;
1481 const char *last_name;
1482 riscv_isa_ext_class_t class;
1483
1484 while (*p)
1485 {
1486 if (*p == '_')
1487 {
1488 p++;
1489 continue;
1490 }
1491
1492 /* Assert that the current extension specifier matches our parsing
1493 class. */
1494 class = riscv_get_prefix_class (p);
1495 if (class != config->class
1496 || class == RV_ISA_CLASS_UNKNOWN)
1497 break;
1498
1499 char *subset = xstrdup (p);
1500 char *q = subset;
1501 const char *end_of_version;
1502
1503 while (*++q != '\0' && *q != '_' && !ISDIGIT (*q))
1504 ;
1505
1506 end_of_version =
1507 riscv_parsing_subset_version (rps, march, q,
1508 &major_version,
1509 &minor_version, FALSE);
1510 *q = '\0';
1511
1512 if (end_of_version == NULL)
1513 {
1514 free (subset);
1515 return NULL;
1516 }
1517
1518 /* Check that the prefix extension is known.
1519 For 'x', anything goes but it cannot simply be 'x'.
1520 For 's', it must be known from a list and cannot simply be 's'.
1521 For 'h', it must be known from a list and cannot simply be 'h'.
1522 For 'z', it must be known from a list and cannot simply be 'z'. */
1523
1524 /* Check that the extension name is well-formed. */
1525 if (!config->ext_valid_p (subset))
1526 {
1527 rps->error_handler
1528 (_("-march=%s: unknown %s ISA extension `%s'"),
1529 march, config->prefix, subset);
1530 free (subset);
1531 return NULL;
1532 }
1533
1534 /* Check that the extension isn't duplicate. */
1535 last_name = rps->subset_list->tail->name;
1536 if (!strcasecmp (last_name, subset))
1537 {
1538 rps->error_handler
1539 (_("-march=%s: duplicate %s ISA extension `%s'"),
1540 march, config->prefix, subset);
1541 free (subset);
1542 return NULL;
1543 }
1544
1545 /* Check that the extension is in alphabetical order. */
1546 if (!strncasecmp (last_name, config->prefix, 1)
1547 && strcasecmp (last_name, subset) > 0)
1548 {
1549 rps->error_handler
1550 (_("-march=%s: %s ISA extension `%s' is not in alphabetical "
1551 "order. It must come before `%s'"),
1552 march, config->prefix, subset, last_name);
1553 free (subset);
1554 return NULL;
1555 }
1556
1557 riscv_parse_add_subset (rps, subset,
1558 major_version,
1559 minor_version, FALSE);
1560 free (subset);
1561 p += end_of_version - subset;
1562
1563 if (*p != '\0' && *p != '_')
1564 {
1565 rps->error_handler
1566 (_("-march=%s: %s ISA extension must separate with _"),
1567 march, config->prefix);
1568 return NULL;
1569 }
1570 }
1571
1572 return p;
1573 }
1574
1575 /* Lists of prefixed class extensions that binutils should know about.
1576 Whether or not a particular entry is in these lists will dictate if
1577 gas/ld will accept its presence in the architecture string.
1578
1579 Please add the extensions to the lists in lower case. However, keep
1580 these subsets in alphabetical order in these tables is recommended,
1581 although there is no impact on the current implementation. */
1582
1583 static const char * const riscv_std_z_ext_strtab[] =
1584 {
1585 "zicsr", "zifencei", NULL
1586 };
1587
1588 static const char * const riscv_std_s_ext_strtab[] =
1589 {
1590 NULL
1591 };
1592
1593 static const char * const riscv_std_h_ext_strtab[] =
1594 {
1595 NULL
1596 };
1597
1598 /* For the extension `ext`, search through the list of known extensions
1599 `known_exts` for a match, and return TRUE if found. */
1600
1601 static bfd_boolean
1602 riscv_multi_letter_ext_valid_p (const char *ext,
1603 const char *const *known_exts)
1604 {
1605 size_t i;
1606
1607 for (i = 0; known_exts[i]; ++i)
1608 if (!strcmp (ext, known_exts[i]))
1609 return TRUE;
1610
1611 return FALSE;
1612 }
1613
1614 /* Predicator function for x-prefixed extensions.
1615 Anything goes, except the literal 'x'. */
1616
1617 static bfd_boolean
1618 riscv_ext_x_valid_p (const char *arg)
1619 {
1620 if (!strcasecmp (arg, "x"))
1621 return FALSE;
1622
1623 return TRUE;
1624 }
1625
1626 /* Predicator functions for z-prefixed extensions.
1627 Only known z-extensions are permitted. */
1628
1629 static bfd_boolean
1630 riscv_ext_z_valid_p (const char *arg)
1631 {
1632 return riscv_multi_letter_ext_valid_p (arg, riscv_std_z_ext_strtab);
1633 }
1634
1635 /* Predicator function for 's' prefixed extensions.
1636 Only known s-extensions are permitted. */
1637
1638 static bfd_boolean
1639 riscv_ext_s_valid_p (const char *arg)
1640 {
1641 return riscv_multi_letter_ext_valid_p (arg, riscv_std_s_ext_strtab);
1642 }
1643
1644 /* Predicator function for 'h' prefixed extensions.
1645 Only known h-extensions are permitted. */
1646
1647 static bfd_boolean
1648 riscv_ext_h_valid_p (const char *arg)
1649 {
1650 return riscv_multi_letter_ext_valid_p (arg, riscv_std_h_ext_strtab);
1651 }
1652
1653 /* Parsing order of the prefixed extensions that is specified by
1654 the ISA spec. */
1655
1656 static const riscv_parse_config_t parse_config[] =
1657 {
1658 {RV_ISA_CLASS_S, "s", riscv_ext_s_valid_p},
1659 {RV_ISA_CLASS_H, "h", riscv_ext_h_valid_p},
1660 {RV_ISA_CLASS_Z, "z", riscv_ext_z_valid_p},
1661 {RV_ISA_CLASS_X, "x", riscv_ext_x_valid_p},
1662 {RV_ISA_CLASS_UNKNOWN, NULL, NULL}
1663 };
1664
1665 /* Init the riscv_ext_order array. */
1666
1667 static void
1668 riscv_init_ext_order (void)
1669 {
1670 static bfd_boolean inited = FALSE;
1671 const char *std_base_exts = "eig";
1672 const char *std_remain_exts = riscv_supported_std_ext ();
1673 const char *ext;
1674 unsigned int i;
1675 int order;
1676
1677 if (inited)
1678 return;
1679
1680 /* All standard extensions' orders are positive numbers. */
1681 order = 1;
1682
1683 /* Init the standard base extensions first. */
1684 for (ext = std_base_exts; *ext; ext++)
1685 riscv_ext_order[(*ext - 'a')] = order++;
1686
1687 /* Init the standard remaining extensions. */
1688 for (ext = std_remain_exts; *ext; ext++)
1689 riscv_ext_order[(*ext - 'a')] = order++;
1690
1691 /* Init the order for prefixed keywords. The orders are
1692 negative numbers. */
1693 order = -1;
1694 for (i = 0; parse_config[i].class != RV_ISA_CLASS_UNKNOWN; i++)
1695 {
1696 ext = parse_config[i].prefix;
1697 riscv_ext_order[(*ext - 'a')] = order--;
1698 }
1699
1700 inited = TRUE;
1701 }
1702
1703 /* Add the implicit extensions according to the arch string extensions. */
1704
1705 static void
1706 riscv_parse_add_implicit_subsets (riscv_parse_subset_t *rps)
1707 {
1708 riscv_subset_t *subset = NULL;
1709
1710 /* Add the zicsr and zifencei only when the i's version less than 2.1. */
1711 if ((riscv_lookup_subset (rps->subset_list, "i", &subset))
1712 && (subset->major_version < 2
1713 || (subset->major_version == 2
1714 && subset->minor_version < 1)))
1715 {
1716 riscv_parse_add_subset (rps, "zicsr",
1717 RISCV_UNKNOWN_VERSION,
1718 RISCV_UNKNOWN_VERSION, TRUE);
1719 riscv_parse_add_subset (rps, "zifencei",
1720 RISCV_UNKNOWN_VERSION,
1721 RISCV_UNKNOWN_VERSION, TRUE);
1722 }
1723
1724 if ((riscv_lookup_subset (rps->subset_list, "q", &subset)))
1725 {
1726 riscv_parse_add_subset (rps, "d",
1727 RISCV_UNKNOWN_VERSION,
1728 RISCV_UNKNOWN_VERSION, TRUE);
1729 riscv_parse_add_subset (rps, "f",
1730 RISCV_UNKNOWN_VERSION,
1731 RISCV_UNKNOWN_VERSION, TRUE);
1732 riscv_parse_add_subset (rps, "zicsr",
1733 RISCV_UNKNOWN_VERSION,
1734 RISCV_UNKNOWN_VERSION, TRUE);
1735 }
1736 else if ((riscv_lookup_subset (rps->subset_list, "d", &subset)))
1737 {
1738 riscv_parse_add_subset (rps, "f",
1739 RISCV_UNKNOWN_VERSION,
1740 RISCV_UNKNOWN_VERSION, TRUE);
1741 riscv_parse_add_subset (rps, "zicsr",
1742 RISCV_UNKNOWN_VERSION,
1743 RISCV_UNKNOWN_VERSION, TRUE);
1744 }
1745 else if ((riscv_lookup_subset (rps->subset_list, "f", &subset)))
1746 riscv_parse_add_subset (rps, "zicsr",
1747 RISCV_UNKNOWN_VERSION,
1748 RISCV_UNKNOWN_VERSION, TRUE);
1749
1750 if ((riscv_lookup_subset (rps->subset_list, "g", &subset)))
1751 {
1752 riscv_parse_add_subset (rps, "zicsr",
1753 RISCV_UNKNOWN_VERSION,
1754 RISCV_UNKNOWN_VERSION, TRUE);
1755 riscv_parse_add_subset (rps, "zifencei",
1756 RISCV_UNKNOWN_VERSION,
1757 RISCV_UNKNOWN_VERSION, TRUE);
1758 }
1759 }
1760
1761 /* Function for parsing arch string.
1762
1763 Return Value:
1764 Return TRUE on success.
1765
1766 Arguments:
1767 `rps`: Hooks and status for parsing extensions.
1768 `arch`: Full arch string. */
1769
1770 bfd_boolean
1771 riscv_parse_subset (riscv_parse_subset_t *rps,
1772 const char *arch)
1773 {
1774 riscv_subset_t *subset = NULL;
1775 const char *p;
1776 size_t i;
1777 bfd_boolean no_conflict = TRUE;
1778
1779 for (p = arch; *p != '\0'; p++)
1780 {
1781 if (ISUPPER (*p))
1782 {
1783 rps->error_handler
1784 (_("-march=%s: ISA string cannot contain uppercase letters"),
1785 arch);
1786 return FALSE;
1787 }
1788 }
1789
1790 p = arch;
1791 if (strncmp (p, "rv32", 4) == 0)
1792 {
1793 *rps->xlen = 32;
1794 p += 4;
1795 }
1796 else if (strncmp (p, "rv64", 4) == 0)
1797 {
1798 *rps->xlen = 64;
1799 p += 4;
1800 }
1801 else
1802 {
1803 /* Arch string shouldn't be NULL or empty here. However,
1804 it might be empty only when we failed to merge the arch
1805 string in the riscv_merge_attributes. We have already
1806 issued the correct error message in another side, so do
1807 not issue this error when the arch string is empty. */
1808 if (strlen (arch))
1809 rps->error_handler (
1810 _("-march=%s: ISA string must begin with rv32 or rv64"),
1811 arch);
1812 return FALSE;
1813 }
1814
1815 /* Init the riscv_ext_order array to compare the order of extensions
1816 quickly. */
1817 riscv_init_ext_order ();
1818
1819 /* Parsing standard extension. */
1820 p = riscv_parse_std_ext (rps, arch, p);
1821
1822 if (p == NULL)
1823 return FALSE;
1824
1825 /* Parse the different classes of extensions in the specified order. */
1826 for (i = 0; i < ARRAY_SIZE (parse_config); ++i)
1827 {
1828 p = riscv_parse_prefixed_ext (rps, arch, p, &parse_config[i]);
1829
1830 if (p == NULL)
1831 return FALSE;
1832 }
1833
1834 if (*p != '\0')
1835 {
1836 rps->error_handler (_("-march=%s: unexpected ISA string at end: %s"),
1837 arch, p);
1838 return FALSE;
1839 }
1840
1841 /* Finally add implicit extensions according to the current
1842 extensions. */
1843 riscv_parse_add_implicit_subsets (rps);
1844
1845 /* Check the conflicts. */
1846 if (riscv_lookup_subset (rps->subset_list, "e", &subset)
1847 && riscv_lookup_subset (rps->subset_list, "f", &subset))
1848 {
1849 rps->error_handler
1850 (_("-march=%s: rv32e does not support the `f' extension"),
1851 arch);
1852 no_conflict = FALSE;
1853 }
1854 if (riscv_lookup_subset (rps->subset_list, "q", &subset)
1855 && *rps->xlen < 64)
1856 {
1857 rps->error_handler
1858 (_("-march=%s: rv32 does not support the `q' extension"),
1859 arch);
1860 no_conflict = FALSE;
1861 }
1862 return no_conflict;
1863 }
1864
1865 /* Return the number of digits for the input. */
1866
1867 size_t
1868 riscv_estimate_digit (unsigned num)
1869 {
1870 size_t digit = 0;
1871 if (num == 0)
1872 return 1;
1873
1874 for (digit = 0; num ; num /= 10)
1875 digit++;
1876
1877 return digit;
1878 }
1879
1880 /* Auxiliary function to estimate string length of subset list. */
1881
1882 static size_t
1883 riscv_estimate_arch_strlen1 (const riscv_subset_t *subset)
1884 {
1885 if (subset == NULL)
1886 return 6; /* For rv32/rv64/rv128 and string terminator. */
1887
1888 return riscv_estimate_arch_strlen1 (subset->next)
1889 + strlen (subset->name)
1890 + riscv_estimate_digit (subset->major_version)
1891 + 1 /* For version seperator: 'p'. */
1892 + riscv_estimate_digit (subset->minor_version)
1893 + 1 /* For underscore. */;
1894 }
1895
1896 /* Estimate the string length of this subset list. */
1897
1898 static size_t
1899 riscv_estimate_arch_strlen (const riscv_subset_list_t *subset_list)
1900 {
1901 return riscv_estimate_arch_strlen1 (subset_list->head);
1902 }
1903
1904 /* Auxiliary function to convert subset info to string. */
1905
1906 static void
1907 riscv_arch_str1 (riscv_subset_t *subset,
1908 char *attr_str, char *buf, size_t bufsz)
1909 {
1910 const char *underline = "_";
1911
1912 if (subset == NULL)
1913 return;
1914
1915 /* No underline between rvXX and i/e. */
1916 if ((strcasecmp (subset->name, "i") == 0)
1917 || (strcasecmp (subset->name, "e") == 0))
1918 underline = "";
1919
1920 snprintf (buf, bufsz, "%s%s%dp%d",
1921 underline,
1922 subset->name,
1923 subset->major_version,
1924 subset->minor_version);
1925
1926 strncat (attr_str, buf, bufsz);
1927
1928 /* Skip 'i' extension after 'e', and skip 'g' extension. */
1929 if (subset->next
1930 && ((strcmp (subset->name, "e") == 0
1931 && strcmp (subset->next->name, "i") == 0)
1932 || strcmp (subset->next->name, "g") == 0))
1933 riscv_arch_str1 (subset->next->next, attr_str, buf, bufsz);
1934 else
1935 riscv_arch_str1 (subset->next, attr_str, buf, bufsz);
1936 }
1937
1938 /* Convert subset info to string with explicit version info. */
1939
1940 char *
1941 riscv_arch_str (unsigned xlen, const riscv_subset_list_t *subset)
1942 {
1943 size_t arch_str_len = riscv_estimate_arch_strlen (subset);
1944 char *attr_str = xmalloc (arch_str_len);
1945 char *buf = xmalloc (arch_str_len);
1946
1947 snprintf (attr_str, arch_str_len, "rv%u", xlen);
1948
1949 riscv_arch_str1 (subset->head, attr_str, buf, arch_str_len);
1950 free (buf);
1951
1952 return attr_str;
1953 }
This page took 0.097792 seconds and 5 git commands to generate.