RISC-V: Minimal support of scalar crypto extension.
[binutils-gdb.git] / bfd / elfxx-riscv.c
1 /* RISC-V-specific support for ELF.
2 Copyright (C) 2011-2021 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 "safe-ctype.h"
32
33 #define MINUS_ONE ((bfd_vma)0 - 1)
34
35 /* Special handler for ADD/SUB relocations that allows them to be filled out
36 both in the pre-linked and post-linked file. This is necessary to make
37 pre-linked debug info work, as due to linker relaxations we need to emit
38 relocations for the debug info. */
39 static bfd_reloc_status_type riscv_elf_add_sub_reloc
40 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
41
42 /* The relocation table used for SHT_RELA sections. */
43
44 static reloc_howto_type howto_table[] =
45 {
46 /* No relocation. */
47 HOWTO (R_RISCV_NONE, /* type */
48 0, /* rightshift */
49 3, /* size */
50 0, /* bitsize */
51 false, /* pc_relative */
52 0, /* bitpos */
53 complain_overflow_dont, /* complain_on_overflow */
54 bfd_elf_generic_reloc, /* special_function */
55 "R_RISCV_NONE", /* name */
56 false, /* partial_inplace */
57 0, /* src_mask */
58 0, /* dst_mask */
59 false), /* pcrel_offset */
60
61 /* 32 bit relocation. */
62 HOWTO (R_RISCV_32, /* type */
63 0, /* rightshift */
64 2, /* size */
65 32, /* bitsize */
66 false, /* pc_relative */
67 0, /* bitpos */
68 complain_overflow_dont, /* complain_on_overflow */
69 bfd_elf_generic_reloc, /* special_function */
70 "R_RISCV_32", /* name */
71 false, /* partial_inplace */
72 0, /* src_mask */
73 0xffffffff, /* dst_mask */
74 false), /* pcrel_offset */
75
76 /* 64 bit relocation. */
77 HOWTO (R_RISCV_64, /* type */
78 0, /* rightshift */
79 4, /* size */
80 64, /* bitsize */
81 false, /* pc_relative */
82 0, /* bitpos */
83 complain_overflow_dont, /* complain_on_overflow */
84 bfd_elf_generic_reloc, /* special_function */
85 "R_RISCV_64", /* name */
86 false, /* partial_inplace */
87 0, /* src_mask */
88 MINUS_ONE, /* dst_mask */
89 false), /* pcrel_offset */
90
91 /* Relocation against a local symbol in a shared object. */
92 HOWTO (R_RISCV_RELATIVE, /* type */
93 0, /* rightshift */
94 2, /* size */
95 32, /* bitsize */
96 false, /* pc_relative */
97 0, /* bitpos */
98 complain_overflow_dont, /* complain_on_overflow */
99 bfd_elf_generic_reloc, /* special_function */
100 "R_RISCV_RELATIVE", /* name */
101 false, /* partial_inplace */
102 0, /* src_mask */
103 0xffffffff, /* dst_mask */
104 false), /* pcrel_offset */
105
106 HOWTO (R_RISCV_COPY, /* type */
107 0, /* rightshift */
108 0, /* this one is variable size */
109 0, /* bitsize */
110 false, /* pc_relative */
111 0, /* bitpos */
112 complain_overflow_bitfield, /* complain_on_overflow */
113 bfd_elf_generic_reloc, /* special_function */
114 "R_RISCV_COPY", /* name */
115 false, /* partial_inplace */
116 0, /* src_mask */
117 0, /* dst_mask */
118 false), /* pcrel_offset */
119
120 HOWTO (R_RISCV_JUMP_SLOT, /* type */
121 0, /* rightshift */
122 4, /* size */
123 64, /* bitsize */
124 false, /* pc_relative */
125 0, /* bitpos */
126 complain_overflow_bitfield, /* complain_on_overflow */
127 bfd_elf_generic_reloc, /* special_function */
128 "R_RISCV_JUMP_SLOT", /* name */
129 false, /* partial_inplace */
130 0, /* src_mask */
131 0, /* dst_mask */
132 false), /* pcrel_offset */
133
134 /* Dynamic TLS relocations. */
135 HOWTO (R_RISCV_TLS_DTPMOD32, /* type */
136 0, /* rightshift */
137 2, /* size */
138 32, /* bitsize */
139 false, /* pc_relative */
140 0, /* bitpos */
141 complain_overflow_dont, /* complain_on_overflow */
142 bfd_elf_generic_reloc, /* special_function */
143 "R_RISCV_TLS_DTPMOD32", /* name */
144 false, /* partial_inplace */
145 0, /* src_mask */
146 0xffffffff, /* dst_mask */
147 false), /* pcrel_offset */
148
149 HOWTO (R_RISCV_TLS_DTPMOD64, /* type */
150 0, /* rightshift */
151 4, /* size */
152 64, /* bitsize */
153 false, /* pc_relative */
154 0, /* bitpos */
155 complain_overflow_dont, /* complain_on_overflow */
156 bfd_elf_generic_reloc, /* special_function */
157 "R_RISCV_TLS_DTPMOD64", /* name */
158 false, /* partial_inplace */
159 0, /* src_mask */
160 MINUS_ONE, /* dst_mask */
161 false), /* pcrel_offset */
162
163 HOWTO (R_RISCV_TLS_DTPREL32, /* type */
164 0, /* rightshift */
165 2, /* size */
166 32, /* bitsize */
167 false, /* pc_relative */
168 0, /* bitpos */
169 complain_overflow_dont, /* complain_on_overflow */
170 bfd_elf_generic_reloc, /* special_function */
171 "R_RISCV_TLS_DTPREL32", /* name */
172 true, /* partial_inplace */
173 0, /* src_mask */
174 0xffffffff, /* dst_mask */
175 false), /* pcrel_offset */
176
177 HOWTO (R_RISCV_TLS_DTPREL64, /* type */
178 0, /* rightshift */
179 4, /* size */
180 64, /* bitsize */
181 false, /* pc_relative */
182 0, /* bitpos */
183 complain_overflow_dont, /* complain_on_overflow */
184 bfd_elf_generic_reloc, /* special_function */
185 "R_RISCV_TLS_DTPREL64", /* name */
186 true, /* partial_inplace */
187 0, /* src_mask */
188 MINUS_ONE, /* dst_mask */
189 false), /* pcrel_offset */
190
191 HOWTO (R_RISCV_TLS_TPREL32, /* type */
192 0, /* rightshift */
193 2, /* size */
194 32, /* bitsize */
195 false, /* pc_relative */
196 0, /* bitpos */
197 complain_overflow_dont, /* complain_on_overflow */
198 bfd_elf_generic_reloc, /* special_function */
199 "R_RISCV_TLS_TPREL32", /* name */
200 false, /* partial_inplace */
201 0, /* src_mask */
202 0xffffffff, /* dst_mask */
203 false), /* pcrel_offset */
204
205 HOWTO (R_RISCV_TLS_TPREL64, /* type */
206 0, /* rightshift */
207 4, /* size */
208 64, /* bitsize */
209 false, /* pc_relative */
210 0, /* bitpos */
211 complain_overflow_dont, /* complain_on_overflow */
212 bfd_elf_generic_reloc, /* special_function */
213 "R_RISCV_TLS_TPREL64", /* name */
214 false, /* partial_inplace */
215 0, /* src_mask */
216 MINUS_ONE, /* dst_mask */
217 false), /* pcrel_offset */
218
219 /* Reserved for future relocs that the dynamic linker must understand. */
220 EMPTY_HOWTO (12),
221 EMPTY_HOWTO (13),
222 EMPTY_HOWTO (14),
223 EMPTY_HOWTO (15),
224
225 /* 12-bit PC-relative branch offset. */
226 HOWTO (R_RISCV_BRANCH, /* type */
227 0, /* rightshift */
228 2, /* size */
229 32, /* bitsize */
230 true, /* pc_relative */
231 0, /* bitpos */
232 complain_overflow_signed, /* complain_on_overflow */
233 bfd_elf_generic_reloc, /* special_function */
234 "R_RISCV_BRANCH", /* name */
235 false, /* partial_inplace */
236 0, /* src_mask */
237 ENCODE_BTYPE_IMM (-1U), /* dst_mask */
238 true), /* pcrel_offset */
239
240 /* 20-bit PC-relative jump offset. */
241 HOWTO (R_RISCV_JAL, /* type */
242 0, /* rightshift */
243 2, /* size */
244 32, /* bitsize */
245 true, /* pc_relative */
246 0, /* bitpos */
247 complain_overflow_dont, /* complain_on_overflow */
248 bfd_elf_generic_reloc, /* special_function */
249 "R_RISCV_JAL", /* name */
250 false, /* partial_inplace */
251 0, /* src_mask */
252 ENCODE_JTYPE_IMM (-1U), /* dst_mask */
253 true), /* pcrel_offset */
254
255 /* 32-bit PC-relative function call (AUIPC/JALR). */
256 HOWTO (R_RISCV_CALL, /* type */
257 0, /* rightshift */
258 4, /* size */
259 64, /* bitsize */
260 true, /* pc_relative */
261 0, /* bitpos */
262 complain_overflow_dont, /* complain_on_overflow */
263 bfd_elf_generic_reloc, /* special_function */
264 "R_RISCV_CALL", /* name */
265 false, /* partial_inplace */
266 0, /* src_mask */
267 ENCODE_UTYPE_IMM (-1U) | ((bfd_vma) ENCODE_ITYPE_IMM (-1U) << 32),
268 /* dst_mask */
269 true), /* pcrel_offset */
270
271 /* Like R_RISCV_CALL, but not locally binding. */
272 HOWTO (R_RISCV_CALL_PLT, /* type */
273 0, /* rightshift */
274 4, /* size */
275 64, /* bitsize */
276 true, /* pc_relative */
277 0, /* bitpos */
278 complain_overflow_dont, /* complain_on_overflow */
279 bfd_elf_generic_reloc, /* special_function */
280 "R_RISCV_CALL_PLT", /* name */
281 false, /* partial_inplace */
282 0, /* src_mask */
283 ENCODE_UTYPE_IMM (-1U) | ((bfd_vma) ENCODE_ITYPE_IMM (-1U) << 32),
284 /* dst_mask */
285 true), /* pcrel_offset */
286
287 /* High 20 bits of 32-bit PC-relative GOT access. */
288 HOWTO (R_RISCV_GOT_HI20, /* type */
289 0, /* rightshift */
290 2, /* size */
291 32, /* bitsize */
292 true, /* pc_relative */
293 0, /* bitpos */
294 complain_overflow_dont, /* complain_on_overflow */
295 bfd_elf_generic_reloc, /* special_function */
296 "R_RISCV_GOT_HI20", /* name */
297 false, /* partial_inplace */
298 0, /* src_mask */
299 ENCODE_UTYPE_IMM (-1U), /* dst_mask */
300 false), /* pcrel_offset */
301
302 /* High 20 bits of 32-bit PC-relative TLS IE GOT access. */
303 HOWTO (R_RISCV_TLS_GOT_HI20, /* type */
304 0, /* rightshift */
305 2, /* size */
306 32, /* bitsize */
307 true, /* pc_relative */
308 0, /* bitpos */
309 complain_overflow_dont, /* complain_on_overflow */
310 bfd_elf_generic_reloc, /* special_function */
311 "R_RISCV_TLS_GOT_HI20", /* name */
312 false, /* partial_inplace */
313 0, /* src_mask */
314 ENCODE_UTYPE_IMM (-1U), /* dst_mask */
315 false), /* pcrel_offset */
316
317 /* High 20 bits of 32-bit PC-relative TLS GD GOT reference. */
318 HOWTO (R_RISCV_TLS_GD_HI20, /* type */
319 0, /* rightshift */
320 2, /* size */
321 32, /* bitsize */
322 true, /* pc_relative */
323 0, /* bitpos */
324 complain_overflow_dont, /* complain_on_overflow */
325 bfd_elf_generic_reloc, /* special_function */
326 "R_RISCV_TLS_GD_HI20", /* name */
327 false, /* partial_inplace */
328 0, /* src_mask */
329 ENCODE_UTYPE_IMM (-1U), /* dst_mask */
330 false), /* pcrel_offset */
331
332 /* High 20 bits of 32-bit PC-relative reference. */
333 HOWTO (R_RISCV_PCREL_HI20, /* type */
334 0, /* rightshift */
335 2, /* size */
336 32, /* bitsize */
337 true, /* pc_relative */
338 0, /* bitpos */
339 complain_overflow_dont, /* complain_on_overflow */
340 bfd_elf_generic_reloc, /* special_function */
341 "R_RISCV_PCREL_HI20", /* name */
342 false, /* partial_inplace */
343 0, /* src_mask */
344 ENCODE_UTYPE_IMM (-1U), /* dst_mask */
345 true), /* pcrel_offset */
346
347 /* Low 12 bits of a 32-bit PC-relative load or add. */
348 HOWTO (R_RISCV_PCREL_LO12_I, /* type */
349 0, /* rightshift */
350 2, /* size */
351 32, /* bitsize */
352 false, /* pc_relative */
353 0, /* bitpos */
354 complain_overflow_dont, /* complain_on_overflow */
355 bfd_elf_generic_reloc, /* special_function */
356 "R_RISCV_PCREL_LO12_I", /* name */
357 false, /* partial_inplace */
358 0, /* src_mask */
359 ENCODE_ITYPE_IMM (-1U), /* dst_mask */
360 false), /* pcrel_offset */
361
362 /* Low 12 bits of a 32-bit PC-relative store. */
363 HOWTO (R_RISCV_PCREL_LO12_S, /* type */
364 0, /* rightshift */
365 2, /* size */
366 32, /* bitsize */
367 false, /* pc_relative */
368 0, /* bitpos */
369 complain_overflow_dont, /* complain_on_overflow */
370 bfd_elf_generic_reloc, /* special_function */
371 "R_RISCV_PCREL_LO12_S", /* name */
372 false, /* partial_inplace */
373 0, /* src_mask */
374 ENCODE_STYPE_IMM (-1U), /* dst_mask */
375 false), /* pcrel_offset */
376
377 /* High 20 bits of 32-bit absolute address. */
378 HOWTO (R_RISCV_HI20, /* type */
379 0, /* rightshift */
380 2, /* size */
381 32, /* bitsize */
382 false, /* pc_relative */
383 0, /* bitpos */
384 complain_overflow_dont, /* complain_on_overflow */
385 bfd_elf_generic_reloc, /* special_function */
386 "R_RISCV_HI20", /* name */
387 false, /* partial_inplace */
388 0, /* src_mask */
389 ENCODE_UTYPE_IMM (-1U), /* dst_mask */
390 false), /* pcrel_offset */
391
392 /* High 12 bits of 32-bit load or add. */
393 HOWTO (R_RISCV_LO12_I, /* type */
394 0, /* rightshift */
395 2, /* size */
396 32, /* bitsize */
397 false, /* pc_relative */
398 0, /* bitpos */
399 complain_overflow_dont, /* complain_on_overflow */
400 bfd_elf_generic_reloc, /* special_function */
401 "R_RISCV_LO12_I", /* name */
402 false, /* partial_inplace */
403 0, /* src_mask */
404 ENCODE_ITYPE_IMM (-1U), /* dst_mask */
405 false), /* pcrel_offset */
406
407 /* High 12 bits of 32-bit store. */
408 HOWTO (R_RISCV_LO12_S, /* type */
409 0, /* rightshift */
410 2, /* size */
411 32, /* bitsize */
412 false, /* pc_relative */
413 0, /* bitpos */
414 complain_overflow_dont, /* complain_on_overflow */
415 bfd_elf_generic_reloc, /* special_function */
416 "R_RISCV_LO12_S", /* name */
417 false, /* partial_inplace */
418 0, /* src_mask */
419 ENCODE_STYPE_IMM (-1U), /* dst_mask */
420 false), /* pcrel_offset */
421
422 /* High 20 bits of TLS LE thread pointer offset. */
423 HOWTO (R_RISCV_TPREL_HI20, /* type */
424 0, /* rightshift */
425 2, /* size */
426 32, /* bitsize */
427 false, /* pc_relative */
428 0, /* bitpos */
429 complain_overflow_signed, /* complain_on_overflow */
430 bfd_elf_generic_reloc, /* special_function */
431 "R_RISCV_TPREL_HI20", /* name */
432 true, /* partial_inplace */
433 0, /* src_mask */
434 ENCODE_UTYPE_IMM (-1U), /* dst_mask */
435 false), /* pcrel_offset */
436
437 /* Low 12 bits of TLS LE thread pointer offset for loads and adds. */
438 HOWTO (R_RISCV_TPREL_LO12_I, /* type */
439 0, /* rightshift */
440 2, /* size */
441 32, /* bitsize */
442 false, /* pc_relative */
443 0, /* bitpos */
444 complain_overflow_signed, /* complain_on_overflow */
445 bfd_elf_generic_reloc, /* special_function */
446 "R_RISCV_TPREL_LO12_I", /* name */
447 false, /* partial_inplace */
448 0, /* src_mask */
449 ENCODE_ITYPE_IMM (-1U), /* dst_mask */
450 false), /* pcrel_offset */
451
452 /* Low 12 bits of TLS LE thread pointer offset for stores. */
453 HOWTO (R_RISCV_TPREL_LO12_S, /* type */
454 0, /* rightshift */
455 2, /* size */
456 32, /* bitsize */
457 false, /* pc_relative */
458 0, /* bitpos */
459 complain_overflow_signed, /* complain_on_overflow */
460 bfd_elf_generic_reloc, /* special_function */
461 "R_RISCV_TPREL_LO12_S", /* name */
462 false, /* partial_inplace */
463 0, /* src_mask */
464 ENCODE_STYPE_IMM (-1U), /* dst_mask */
465 false), /* pcrel_offset */
466
467 /* TLS LE thread pointer usage. May be relaxed. */
468 HOWTO (R_RISCV_TPREL_ADD, /* type */
469 0, /* rightshift */
470 3, /* size */
471 0, /* bitsize */
472 false, /* pc_relative */
473 0, /* bitpos */
474 complain_overflow_dont, /* complain_on_overflow */
475 bfd_elf_generic_reloc, /* special_function */
476 "R_RISCV_TPREL_ADD", /* name */
477 false, /* partial_inplace */
478 0, /* src_mask */
479 0, /* dst_mask */
480 false), /* pcrel_offset */
481
482 /* 8-bit in-place addition, for local label subtraction. */
483 HOWTO (R_RISCV_ADD8, /* type */
484 0, /* rightshift */
485 0, /* size */
486 8, /* bitsize */
487 false, /* pc_relative */
488 0, /* bitpos */
489 complain_overflow_dont, /* complain_on_overflow */
490 riscv_elf_add_sub_reloc, /* special_function */
491 "R_RISCV_ADD8", /* name */
492 false, /* partial_inplace */
493 0, /* src_mask */
494 0xff, /* dst_mask */
495 false), /* pcrel_offset */
496
497 /* 16-bit in-place addition, for local label subtraction. */
498 HOWTO (R_RISCV_ADD16, /* type */
499 0, /* rightshift */
500 1, /* size */
501 16, /* bitsize */
502 false, /* pc_relative */
503 0, /* bitpos */
504 complain_overflow_dont, /* complain_on_overflow */
505 riscv_elf_add_sub_reloc, /* special_function */
506 "R_RISCV_ADD16", /* name */
507 false, /* partial_inplace */
508 0, /* src_mask */
509 0xffff, /* dst_mask */
510 false), /* pcrel_offset */
511
512 /* 32-bit in-place addition, for local label subtraction. */
513 HOWTO (R_RISCV_ADD32, /* type */
514 0, /* rightshift */
515 2, /* size */
516 32, /* bitsize */
517 false, /* pc_relative */
518 0, /* bitpos */
519 complain_overflow_dont, /* complain_on_overflow */
520 riscv_elf_add_sub_reloc, /* special_function */
521 "R_RISCV_ADD32", /* name */
522 false, /* partial_inplace */
523 0, /* src_mask */
524 0xffffffff, /* dst_mask */
525 false), /* pcrel_offset */
526
527 /* 64-bit in-place addition, for local label subtraction. */
528 HOWTO (R_RISCV_ADD64, /* type */
529 0, /* rightshift */
530 4, /* size */
531 64, /* bitsize */
532 false, /* pc_relative */
533 0, /* bitpos */
534 complain_overflow_dont, /* complain_on_overflow */
535 riscv_elf_add_sub_reloc, /* special_function */
536 "R_RISCV_ADD64", /* name */
537 false, /* partial_inplace */
538 0, /* src_mask */
539 MINUS_ONE, /* dst_mask */
540 false), /* pcrel_offset */
541
542 /* 8-bit in-place addition, for local label subtraction. */
543 HOWTO (R_RISCV_SUB8, /* type */
544 0, /* rightshift */
545 0, /* size */
546 8, /* bitsize */
547 false, /* pc_relative */
548 0, /* bitpos */
549 complain_overflow_dont, /* complain_on_overflow */
550 riscv_elf_add_sub_reloc, /* special_function */
551 "R_RISCV_SUB8", /* name */
552 false, /* partial_inplace */
553 0, /* src_mask */
554 0xff, /* dst_mask */
555 false), /* pcrel_offset */
556
557 /* 16-bit in-place addition, for local label subtraction. */
558 HOWTO (R_RISCV_SUB16, /* type */
559 0, /* rightshift */
560 1, /* size */
561 16, /* bitsize */
562 false, /* pc_relative */
563 0, /* bitpos */
564 complain_overflow_dont, /* complain_on_overflow */
565 riscv_elf_add_sub_reloc, /* special_function */
566 "R_RISCV_SUB16", /* name */
567 false, /* partial_inplace */
568 0, /* src_mask */
569 0xffff, /* dst_mask */
570 false), /* pcrel_offset */
571
572 /* 32-bit in-place addition, for local label subtraction. */
573 HOWTO (R_RISCV_SUB32, /* type */
574 0, /* rightshift */
575 2, /* size */
576 32, /* bitsize */
577 false, /* pc_relative */
578 0, /* bitpos */
579 complain_overflow_dont, /* complain_on_overflow */
580 riscv_elf_add_sub_reloc, /* special_function */
581 "R_RISCV_SUB32", /* name */
582 false, /* partial_inplace */
583 0, /* src_mask */
584 0xffffffff, /* dst_mask */
585 false), /* pcrel_offset */
586
587 /* 64-bit in-place addition, for local label subtraction. */
588 HOWTO (R_RISCV_SUB64, /* type */
589 0, /* rightshift */
590 4, /* size */
591 64, /* bitsize */
592 false, /* pc_relative */
593 0, /* bitpos */
594 complain_overflow_dont, /* complain_on_overflow */
595 riscv_elf_add_sub_reloc, /* special_function */
596 "R_RISCV_SUB64", /* name */
597 false, /* partial_inplace */
598 0, /* src_mask */
599 MINUS_ONE, /* dst_mask */
600 false), /* pcrel_offset */
601
602 /* GNU extension to record C++ vtable hierarchy */
603 HOWTO (R_RISCV_GNU_VTINHERIT, /* type */
604 0, /* rightshift */
605 4, /* size */
606 0, /* bitsize */
607 false, /* pc_relative */
608 0, /* bitpos */
609 complain_overflow_dont, /* complain_on_overflow */
610 NULL, /* special_function */
611 "R_RISCV_GNU_VTINHERIT", /* name */
612 false, /* partial_inplace */
613 0, /* src_mask */
614 0, /* dst_mask */
615 false), /* pcrel_offset */
616
617 /* GNU extension to record C++ vtable member usage */
618 HOWTO (R_RISCV_GNU_VTENTRY, /* type */
619 0, /* rightshift */
620 4, /* size */
621 0, /* bitsize */
622 false, /* pc_relative */
623 0, /* bitpos */
624 complain_overflow_dont, /* complain_on_overflow */
625 _bfd_elf_rel_vtable_reloc_fn, /* special_function */
626 "R_RISCV_GNU_VTENTRY", /* name */
627 false, /* partial_inplace */
628 0, /* src_mask */
629 0, /* dst_mask */
630 false), /* pcrel_offset */
631
632 /* Indicates an alignment statement. The addend field encodes how many
633 bytes of NOPs follow the statement. The desired alignment is the
634 addend rounded up to the next power of two. */
635 HOWTO (R_RISCV_ALIGN, /* type */
636 0, /* rightshift */
637 3, /* size */
638 0, /* bitsize */
639 false, /* pc_relative */
640 0, /* bitpos */
641 complain_overflow_dont, /* complain_on_overflow */
642 bfd_elf_generic_reloc, /* special_function */
643 "R_RISCV_ALIGN", /* name */
644 false, /* partial_inplace */
645 0, /* src_mask */
646 0, /* dst_mask */
647 false), /* pcrel_offset */
648
649 /* 8-bit PC-relative branch offset. */
650 HOWTO (R_RISCV_RVC_BRANCH, /* type */
651 0, /* rightshift */
652 1, /* size */
653 16, /* bitsize */
654 true, /* pc_relative */
655 0, /* bitpos */
656 complain_overflow_signed, /* complain_on_overflow */
657 bfd_elf_generic_reloc, /* special_function */
658 "R_RISCV_RVC_BRANCH", /* name */
659 false, /* partial_inplace */
660 0, /* src_mask */
661 ENCODE_CBTYPE_IMM (-1U), /* dst_mask */
662 true), /* pcrel_offset */
663
664 /* 11-bit PC-relative jump offset. */
665 HOWTO (R_RISCV_RVC_JUMP, /* type */
666 0, /* rightshift */
667 1, /* size */
668 16, /* bitsize */
669 true, /* pc_relative */
670 0, /* bitpos */
671 complain_overflow_dont, /* complain_on_overflow */
672 bfd_elf_generic_reloc, /* special_function */
673 "R_RISCV_RVC_JUMP", /* name */
674 false, /* partial_inplace */
675 0, /* src_mask */
676 ENCODE_CJTYPE_IMM (-1U), /* dst_mask */
677 true), /* pcrel_offset */
678
679 /* High 6 bits of 18-bit absolute address. */
680 HOWTO (R_RISCV_RVC_LUI, /* type */
681 0, /* rightshift */
682 1, /* size */
683 16, /* bitsize */
684 false, /* pc_relative */
685 0, /* bitpos */
686 complain_overflow_dont, /* complain_on_overflow */
687 bfd_elf_generic_reloc, /* special_function */
688 "R_RISCV_RVC_LUI", /* name */
689 false, /* partial_inplace */
690 0, /* src_mask */
691 ENCODE_CITYPE_IMM (-1U), /* dst_mask */
692 false), /* pcrel_offset */
693
694 /* GP-relative load. */
695 HOWTO (R_RISCV_GPREL_I, /* type */
696 0, /* rightshift */
697 2, /* size */
698 32, /* bitsize */
699 false, /* pc_relative */
700 0, /* bitpos */
701 complain_overflow_dont, /* complain_on_overflow */
702 bfd_elf_generic_reloc, /* special_function */
703 "R_RISCV_GPREL_I", /* name */
704 false, /* partial_inplace */
705 0, /* src_mask */
706 ENCODE_ITYPE_IMM (-1U), /* dst_mask */
707 false), /* pcrel_offset */
708
709 /* GP-relative store. */
710 HOWTO (R_RISCV_GPREL_S, /* type */
711 0, /* rightshift */
712 2, /* size */
713 32, /* bitsize */
714 false, /* pc_relative */
715 0, /* bitpos */
716 complain_overflow_dont, /* complain_on_overflow */
717 bfd_elf_generic_reloc, /* special_function */
718 "R_RISCV_GPREL_S", /* name */
719 false, /* partial_inplace */
720 0, /* src_mask */
721 ENCODE_STYPE_IMM (-1U), /* dst_mask */
722 false), /* pcrel_offset */
723
724 /* TP-relative TLS LE load. */
725 HOWTO (R_RISCV_TPREL_I, /* type */
726 0, /* rightshift */
727 2, /* size */
728 32, /* bitsize */
729 false, /* pc_relative */
730 0, /* bitpos */
731 complain_overflow_signed, /* complain_on_overflow */
732 bfd_elf_generic_reloc, /* special_function */
733 "R_RISCV_TPREL_I", /* name */
734 false, /* partial_inplace */
735 0, /* src_mask */
736 ENCODE_ITYPE_IMM (-1U), /* dst_mask */
737 false), /* pcrel_offset */
738
739 /* TP-relative TLS LE store. */
740 HOWTO (R_RISCV_TPREL_S, /* type */
741 0, /* rightshift */
742 2, /* size */
743 32, /* bitsize */
744 false, /* pc_relative */
745 0, /* bitpos */
746 complain_overflow_signed, /* complain_on_overflow */
747 bfd_elf_generic_reloc, /* special_function */
748 "R_RISCV_TPREL_S", /* name */
749 false, /* partial_inplace */
750 0, /* src_mask */
751 ENCODE_STYPE_IMM (-1U), /* dst_mask */
752 false), /* pcrel_offset */
753
754 /* The paired relocation may be relaxed. */
755 HOWTO (R_RISCV_RELAX, /* type */
756 0, /* rightshift */
757 3, /* size */
758 0, /* bitsize */
759 false, /* pc_relative */
760 0, /* bitpos */
761 complain_overflow_dont, /* complain_on_overflow */
762 bfd_elf_generic_reloc, /* special_function */
763 "R_RISCV_RELAX", /* name */
764 false, /* partial_inplace */
765 0, /* src_mask */
766 0, /* dst_mask */
767 false), /* pcrel_offset */
768
769 /* 6-bit in-place addition, for local label subtraction. */
770 HOWTO (R_RISCV_SUB6, /* type */
771 0, /* rightshift */
772 0, /* size */
773 8, /* bitsize */
774 false, /* pc_relative */
775 0, /* bitpos */
776 complain_overflow_dont, /* complain_on_overflow */
777 riscv_elf_add_sub_reloc, /* special_function */
778 "R_RISCV_SUB6", /* name */
779 false, /* partial_inplace */
780 0, /* src_mask */
781 0x3f, /* dst_mask */
782 false), /* pcrel_offset */
783
784 /* 6-bit in-place setting, for local label subtraction. */
785 HOWTO (R_RISCV_SET6, /* type */
786 0, /* rightshift */
787 0, /* size */
788 8, /* bitsize */
789 false, /* pc_relative */
790 0, /* bitpos */
791 complain_overflow_dont, /* complain_on_overflow */
792 bfd_elf_generic_reloc, /* special_function */
793 "R_RISCV_SET6", /* name */
794 false, /* partial_inplace */
795 0, /* src_mask */
796 0x3f, /* dst_mask */
797 false), /* pcrel_offset */
798
799 /* 8-bit in-place setting, for local label subtraction. */
800 HOWTO (R_RISCV_SET8, /* type */
801 0, /* rightshift */
802 0, /* size */
803 8, /* bitsize */
804 false, /* pc_relative */
805 0, /* bitpos */
806 complain_overflow_dont, /* complain_on_overflow */
807 bfd_elf_generic_reloc, /* special_function */
808 "R_RISCV_SET8", /* name */
809 false, /* partial_inplace */
810 0, /* src_mask */
811 0xff, /* dst_mask */
812 false), /* pcrel_offset */
813
814 /* 16-bit in-place setting, for local label subtraction. */
815 HOWTO (R_RISCV_SET16, /* type */
816 0, /* rightshift */
817 1, /* size */
818 16, /* bitsize */
819 false, /* pc_relative */
820 0, /* bitpos */
821 complain_overflow_dont, /* complain_on_overflow */
822 bfd_elf_generic_reloc, /* special_function */
823 "R_RISCV_SET16", /* name */
824 false, /* partial_inplace */
825 0, /* src_mask */
826 0xffff, /* dst_mask */
827 false), /* pcrel_offset */
828
829 /* 32-bit in-place setting, for local label subtraction. */
830 HOWTO (R_RISCV_SET32, /* type */
831 0, /* rightshift */
832 2, /* size */
833 32, /* bitsize */
834 false, /* pc_relative */
835 0, /* bitpos */
836 complain_overflow_dont, /* complain_on_overflow */
837 bfd_elf_generic_reloc, /* special_function */
838 "R_RISCV_SET32", /* name */
839 false, /* partial_inplace */
840 0, /* src_mask */
841 0xffffffff, /* dst_mask */
842 false), /* pcrel_offset */
843
844 /* 32-bit PC relative. */
845 HOWTO (R_RISCV_32_PCREL, /* type */
846 0, /* rightshift */
847 2, /* size */
848 32, /* bitsize */
849 true, /* pc_relative */
850 0, /* bitpos */
851 complain_overflow_dont, /* complain_on_overflow */
852 bfd_elf_generic_reloc, /* special_function */
853 "R_RISCV_32_PCREL", /* name */
854 false, /* partial_inplace */
855 0, /* src_mask */
856 0xffffffff, /* dst_mask */
857 false), /* pcrel_offset */
858
859 /* Relocation against a local ifunc symbol in a shared object. */
860 HOWTO (R_RISCV_IRELATIVE, /* type */
861 0, /* rightshift */
862 2, /* size */
863 32, /* bitsize */
864 false, /* pc_relative */
865 0, /* bitpos */
866 complain_overflow_dont, /* complain_on_overflow */
867 bfd_elf_generic_reloc, /* special_function */
868 "R_RISCV_IRELATIVE", /* name */
869 false, /* partial_inplace */
870 0, /* src_mask */
871 0xffffffff, /* dst_mask */
872 false), /* pcrel_offset */
873 };
874
875 /* A mapping from BFD reloc types to RISC-V ELF reloc types. */
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
1005 bfd_size_type octets = reloc_entry->address
1006 * bfd_octets_per_byte (abfd, input_section);
1007 if (!bfd_reloc_offset_in_range (reloc_entry->howto, abfd,
1008 input_section, octets))
1009 return bfd_reloc_outofrange;
1010
1011 bfd_vma old_value = bfd_get (howto->bitsize, abfd,
1012 data + reloc_entry->address);
1013
1014 switch (howto->type)
1015 {
1016 case R_RISCV_ADD8:
1017 case R_RISCV_ADD16:
1018 case R_RISCV_ADD32:
1019 case R_RISCV_ADD64:
1020 relocation = old_value + relocation;
1021 break;
1022 case R_RISCV_SUB6:
1023 case R_RISCV_SUB8:
1024 case R_RISCV_SUB16:
1025 case R_RISCV_SUB32:
1026 case R_RISCV_SUB64:
1027 relocation = old_value - relocation;
1028 break;
1029 }
1030 bfd_put (howto->bitsize, abfd, relocation, data + reloc_entry->address);
1031
1032 return bfd_reloc_ok;
1033 }
1034
1035 /* Always add the IMPLICIT for the SUBSET. */
1036
1037 static bool
1038 check_implicit_always (const char *implicit ATTRIBUTE_UNUSED,
1039 riscv_subset_t *subset ATTRIBUTE_UNUSED)
1040 {
1041 return true;
1042 }
1043
1044 /* Add the IMPLICIT only when the version of SUBSET less than 2.1. */
1045
1046 static bool
1047 check_implicit_for_i (const char *implicit ATTRIBUTE_UNUSED,
1048 riscv_subset_t *subset)
1049 {
1050 return (subset->major_version < 2
1051 || (subset->major_version == 2
1052 && subset->minor_version < 1));
1053 }
1054
1055 /* Record all implicit information for the subsets. */
1056 struct riscv_implicit_subset
1057 {
1058 const char *subset_name;
1059 const char *implicit_name;
1060 /* A function to determine if we need to add the implicit subset. */
1061 bool (*check_func) (const char *, riscv_subset_t *);
1062 };
1063 static struct riscv_implicit_subset riscv_implicit_subsets[] =
1064 {
1065 {"e", "i", check_implicit_always},
1066 {"i", "zicsr", check_implicit_for_i},
1067 {"i", "zifencei", check_implicit_for_i},
1068 {"g", "i", check_implicit_always},
1069 {"g", "m", check_implicit_always},
1070 {"g", "a", check_implicit_always},
1071 {"g", "f", check_implicit_always},
1072 {"g", "d", check_implicit_always},
1073 {"g", "zicsr", check_implicit_always},
1074 {"g", "zifencei", check_implicit_always},
1075 {"q", "d", check_implicit_always},
1076 {"d", "f", check_implicit_always},
1077 {"f", "zicsr", check_implicit_always},
1078 {"zk", "zkn", check_implicit_always},
1079 {"zk", "zkr", check_implicit_always},
1080 {"zk", "zkt", check_implicit_always},
1081 {"zkn", "zbkb", check_implicit_always},
1082 {"zkn", "zbkc", check_implicit_always},
1083 {"zkn", "zbkx", check_implicit_always},
1084 {"zkn", "zkne", check_implicit_always},
1085 {"zkn", "zknd", check_implicit_always},
1086 {"zkn", "zknh", check_implicit_always},
1087 {"zks", "zbkb", check_implicit_always},
1088 {"zks", "zbkc", check_implicit_always},
1089 {"zks", "zbkx", check_implicit_always},
1090 {"zks", "zksed", check_implicit_always},
1091 {"zks", "zksh", check_implicit_always},
1092 {NULL, NULL, NULL}
1093 };
1094
1095 /* For default_enable field, decide if the extension should
1096 be enbaled by default. */
1097
1098 #define EXT_DEFAULT 0x1
1099
1100 /* List all extensions that binutils should know about. */
1101
1102 struct riscv_supported_ext
1103 {
1104 const char *name;
1105 enum riscv_spec_class isa_spec_class;
1106 int major_version;
1107 int minor_version;
1108 unsigned long default_enable;
1109 };
1110
1111 /* The standard extensions must be added in canonical order. */
1112
1113 static struct riscv_supported_ext riscv_supported_std_ext[] =
1114 {
1115 {"e", ISA_SPEC_CLASS_20191213, 1, 9, 0 },
1116 {"e", ISA_SPEC_CLASS_20190608, 1, 9, 0 },
1117 {"e", ISA_SPEC_CLASS_2P2, 1, 9, 0 },
1118 {"i", ISA_SPEC_CLASS_20191213, 2, 1, 0 },
1119 {"i", ISA_SPEC_CLASS_20190608, 2, 1, 0 },
1120 {"i", ISA_SPEC_CLASS_2P2, 2, 0, 0 },
1121 /* The g is a special case which we don't want to output it,
1122 but still need it when adding implicit extensions. */
1123 {"g", ISA_SPEC_CLASS_NONE, RISCV_UNKNOWN_VERSION, RISCV_UNKNOWN_VERSION, EXT_DEFAULT },
1124 {"m", ISA_SPEC_CLASS_20191213, 2, 0, 0 },
1125 {"m", ISA_SPEC_CLASS_20190608, 2, 0, 0 },
1126 {"m", ISA_SPEC_CLASS_2P2, 2, 0, 0 },
1127 {"a", ISA_SPEC_CLASS_20191213, 2, 1, 0 },
1128 {"a", ISA_SPEC_CLASS_20190608, 2, 0, 0 },
1129 {"a", ISA_SPEC_CLASS_2P2, 2, 0, 0 },
1130 {"f", ISA_SPEC_CLASS_20191213, 2, 2, 0 },
1131 {"f", ISA_SPEC_CLASS_20190608, 2, 2, 0 },
1132 {"f", ISA_SPEC_CLASS_2P2, 2, 0, 0 },
1133 {"d", ISA_SPEC_CLASS_20191213, 2, 2, 0 },
1134 {"d", ISA_SPEC_CLASS_20190608, 2, 2, 0 },
1135 {"d", ISA_SPEC_CLASS_2P2, 2, 0, 0 },
1136 {"q", ISA_SPEC_CLASS_20191213, 2, 2, 0 },
1137 {"q", ISA_SPEC_CLASS_20190608, 2, 2, 0 },
1138 {"q", ISA_SPEC_CLASS_2P2, 2, 0, 0 },
1139 {"l", ISA_SPEC_CLASS_NONE, RISCV_UNKNOWN_VERSION, RISCV_UNKNOWN_VERSION, 0 },
1140 {"c", ISA_SPEC_CLASS_20191213, 2, 0, 0 },
1141 {"c", ISA_SPEC_CLASS_20190608, 2, 0, 0 },
1142 {"c", ISA_SPEC_CLASS_2P2, 2, 0, 0 },
1143 {"b", ISA_SPEC_CLASS_NONE, RISCV_UNKNOWN_VERSION, RISCV_UNKNOWN_VERSION, 0 },
1144 {"k", ISA_SPEC_CLASS_NONE, RISCV_UNKNOWN_VERSION, RISCV_UNKNOWN_VERSION, 0 },
1145 {"j", ISA_SPEC_CLASS_NONE, RISCV_UNKNOWN_VERSION, RISCV_UNKNOWN_VERSION, 0 },
1146 {"t", ISA_SPEC_CLASS_NONE, RISCV_UNKNOWN_VERSION, RISCV_UNKNOWN_VERSION, 0 },
1147 {"p", ISA_SPEC_CLASS_NONE, RISCV_UNKNOWN_VERSION, RISCV_UNKNOWN_VERSION, 0 },
1148 {"v", ISA_SPEC_CLASS_NONE, RISCV_UNKNOWN_VERSION, RISCV_UNKNOWN_VERSION, 0 },
1149 {"n", ISA_SPEC_CLASS_NONE, RISCV_UNKNOWN_VERSION, RISCV_UNKNOWN_VERSION, 0 },
1150 {NULL, 0, 0, 0, 0}
1151 };
1152
1153 static struct riscv_supported_ext riscv_supported_std_z_ext[] =
1154 {
1155 {"zicsr", ISA_SPEC_CLASS_20191213, 2, 0, 0 },
1156 {"zicsr", ISA_SPEC_CLASS_20190608, 2, 0, 0 },
1157 {"zifencei", ISA_SPEC_CLASS_20191213, 2, 0, 0 },
1158 {"zifencei", ISA_SPEC_CLASS_20190608, 2, 0, 0 },
1159 {"zihintpause", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
1160 {"zbb", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
1161 {"zba", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
1162 {"zbc", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
1163 {"zbs", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
1164 {"zbkb", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
1165 {"zbkc", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
1166 {"zbkx", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
1167 {"zk", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
1168 {"zkn", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
1169 {"zknd", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
1170 {"zkne", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
1171 {"zknh", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
1172 {"zkr", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
1173 {"zks", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
1174 {"zksed", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
1175 {"zksh", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
1176 {"zkt", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
1177 {NULL, 0, 0, 0, 0}
1178 };
1179
1180 static struct riscv_supported_ext riscv_supported_std_s_ext[] =
1181 {
1182 {NULL, 0, 0, 0, 0}
1183 };
1184
1185 static struct riscv_supported_ext riscv_supported_std_h_ext[] =
1186 {
1187 {NULL, 0, 0, 0, 0}
1188 };
1189
1190 static struct riscv_supported_ext riscv_supported_std_zxm_ext[] =
1191 {
1192 {NULL, 0, 0, 0, 0}
1193 };
1194
1195 const struct riscv_supported_ext *riscv_all_supported_ext[] =
1196 {
1197 riscv_supported_std_ext,
1198 riscv_supported_std_z_ext,
1199 riscv_supported_std_s_ext,
1200 riscv_supported_std_h_ext,
1201 riscv_supported_std_zxm_ext,
1202 NULL
1203 };
1204
1205 /* ISA extension prefixed name class. Must define them in parsing order. */
1206 enum riscv_prefix_ext_class
1207 {
1208 RV_ISA_CLASS_Z = 1,
1209 RV_ISA_CLASS_S,
1210 RV_ISA_CLASS_H,
1211 RV_ISA_CLASS_ZXM,
1212 RV_ISA_CLASS_X,
1213 RV_ISA_CLASS_UNKNOWN
1214 };
1215
1216 /* Record the strings of the prefixed extensions, and their corresponding
1217 classes. The more letters of the prefix string, the more forward it must
1218 be defined. Otherwise, the riscv_get_prefix_class will map it to the
1219 wrong classes. */
1220 struct riscv_parse_prefix_config
1221 {
1222 /* Class of the extension. */
1223 enum riscv_prefix_ext_class class;
1224
1225 /* Prefix string for error printing and internal parser usage. */
1226 const char *prefix;
1227 };
1228 static const struct riscv_parse_prefix_config parse_config[] =
1229 {
1230 {RV_ISA_CLASS_ZXM, "zxm"},
1231 {RV_ISA_CLASS_Z, "z"},
1232 {RV_ISA_CLASS_S, "s"},
1233 {RV_ISA_CLASS_H, "h"},
1234 {RV_ISA_CLASS_X, "x"},
1235 {RV_ISA_CLASS_UNKNOWN, NULL}
1236 };
1237
1238 /* Get the prefixed name class for the extensions, the class also
1239 means the order of the prefixed extensions. */
1240
1241 static enum riscv_prefix_ext_class
1242 riscv_get_prefix_class (const char *arch)
1243 {
1244 int i = 0;
1245 while (parse_config[i].class != RV_ISA_CLASS_UNKNOWN)
1246 {
1247 if (strncmp (arch, parse_config[i].prefix,
1248 strlen (parse_config[i].prefix)) == 0)
1249 return parse_config[i].class;
1250 i++;
1251 }
1252 return RV_ISA_CLASS_UNKNOWN;
1253 }
1254
1255 /* Check KNOWN_EXTS to see if the EXT is supported. */
1256
1257 static bool
1258 riscv_known_prefixed_ext (const char *ext,
1259 struct riscv_supported_ext *known_exts)
1260 {
1261 size_t i;
1262 for (i = 0; known_exts[i].name != NULL; ++i)
1263 if (strcmp (ext, known_exts[i].name) == 0)
1264 return true;
1265 return false;
1266 }
1267
1268 /* Check whether the prefixed extension is recognized or not. Return
1269 true if recognized, otehrwise return false. */
1270
1271 static bool
1272 riscv_recognized_prefixed_ext (const char *ext)
1273 {
1274 enum riscv_prefix_ext_class class = riscv_get_prefix_class (ext);
1275 switch (class)
1276 {
1277 case RV_ISA_CLASS_Z:
1278 return riscv_known_prefixed_ext (ext, riscv_supported_std_z_ext);
1279 case RV_ISA_CLASS_ZXM:
1280 return riscv_known_prefixed_ext (ext, riscv_supported_std_zxm_ext);
1281 case RV_ISA_CLASS_S:
1282 return riscv_known_prefixed_ext (ext, riscv_supported_std_s_ext);
1283 case RV_ISA_CLASS_H:
1284 return riscv_known_prefixed_ext (ext, riscv_supported_std_h_ext);
1285 case RV_ISA_CLASS_X:
1286 /* Only the single x is unrecognized. */
1287 if (strcmp (ext, "x") != 0)
1288 return true;
1289 default:
1290 break;
1291 }
1292 return false;
1293 }
1294
1295 /* Array is used to compare the orders of standard extensions quickly. */
1296 static int riscv_ext_order[26] = {0};
1297
1298 /* Init the riscv_ext_order array. */
1299
1300 static void
1301 riscv_init_ext_order (void)
1302 {
1303 static bool inited = false;
1304 if (inited)
1305 return;
1306
1307 /* The orders of all standard extensions are positive. */
1308 int order = 1;
1309
1310 int i = 0;
1311 while (riscv_supported_std_ext[i].name != NULL)
1312 {
1313 const char *ext = riscv_supported_std_ext[i].name;
1314 riscv_ext_order[(*ext - 'a')] = order++;
1315 i++;
1316 while (riscv_supported_std_ext[i].name
1317 && strcmp (ext, riscv_supported_std_ext[i].name) == 0)
1318 i++;
1319 }
1320
1321 /* Some of the prefixed keyword are not single letter, so we set
1322 their prefixed orders in the riscv_compare_subsets directly,
1323 not through the riscv_ext_order. */
1324
1325 inited = true;
1326 }
1327
1328 /* Similar to the strcmp. It returns an integer less than, equal to,
1329 or greater than zero if `subset2` is found, respectively, to be less
1330 than, to match, or be greater than `subset1`.
1331
1332 The order values,
1333 Zero: Preserved keywords.
1334 Positive number: Standard extensions.
1335 Negative number: Prefixed keywords. */
1336
1337 int
1338 riscv_compare_subsets (const char *subset1, const char *subset2)
1339 {
1340 int order1 = riscv_ext_order[(*subset1 - 'a')];
1341 int order2 = riscv_ext_order[(*subset2 - 'a')];
1342
1343 /* Compare the standard extension first. */
1344 if (order1 > 0 && order2 > 0)
1345 return order1 - order2;
1346
1347 /* Set the prefixed orders to negative numbers. */
1348 enum riscv_prefix_ext_class class1 = riscv_get_prefix_class (subset1);
1349 enum riscv_prefix_ext_class class2 = riscv_get_prefix_class (subset2);
1350
1351 if (class1 != RV_ISA_CLASS_UNKNOWN)
1352 order1 = - (int) class1;
1353 if (class2 != RV_ISA_CLASS_UNKNOWN)
1354 order2 = - (int) class2;
1355
1356 if (order1 == order2)
1357 {
1358 /* Compare the standard addition z extensions. */
1359 if (class1 == RV_ISA_CLASS_Z)
1360 {
1361 order1 = riscv_ext_order[(*++subset1 - 'a')];
1362 order2 = riscv_ext_order[(*++subset2 - 'a')];
1363 if (order1 != order2)
1364 return order1 - order2;
1365 }
1366 return strcasecmp (++subset1, ++subset2);
1367 }
1368
1369 return order2 - order1;
1370 }
1371
1372 /* Find subset in the list. Return TRUE and set `current` to the subset
1373 if it is found. Otherwise, return FALSE and set `current` to the place
1374 where we should insert the subset. However, return FALSE with the NULL
1375 `current` means we should insert the subset at the head of subset list,
1376 if needed. */
1377
1378 bool
1379 riscv_lookup_subset (const riscv_subset_list_t *subset_list,
1380 const char *subset,
1381 riscv_subset_t **current)
1382 {
1383 riscv_subset_t *s, *pre_s = NULL;
1384
1385 /* If the subset is added in order, then just add it at the tail. */
1386 if (subset_list->tail != NULL
1387 && riscv_compare_subsets (subset_list->tail->name, subset) < 0)
1388 {
1389 *current = subset_list->tail;
1390 return false;
1391 }
1392
1393 for (s = subset_list->head;
1394 s != NULL;
1395 pre_s = s, s = s->next)
1396 {
1397 int cmp = riscv_compare_subsets (s->name, subset);
1398 if (cmp == 0)
1399 {
1400 *current = s;
1401 return true;
1402 }
1403 else if (cmp > 0)
1404 break;
1405 }
1406 *current = pre_s;
1407
1408 return false;
1409 }
1410
1411 /* Add the extension to the subset list. Search the
1412 list first, and then find the right place to add. */
1413
1414 void
1415 riscv_add_subset (riscv_subset_list_t *subset_list,
1416 const char *subset,
1417 int major,
1418 int minor)
1419 {
1420 riscv_subset_t *current, *new;
1421
1422 if (riscv_lookup_subset (subset_list, subset, &current))
1423 return;
1424
1425 new = xmalloc (sizeof *new);
1426 new->name = xstrdup (subset);
1427 new->major_version = major;
1428 new->minor_version = minor;
1429 new->next = NULL;
1430
1431 if (current != NULL)
1432 {
1433 new->next = current->next;
1434 current->next = new;
1435 }
1436 else
1437 {
1438 new->next = subset_list->head;
1439 subset_list->head = new;
1440 }
1441
1442 if (new->next == NULL)
1443 subset_list->tail = new;
1444 }
1445
1446 /* Get the default versions from the riscv_supported_*ext tables. */
1447
1448 static void
1449 riscv_get_default_ext_version (enum riscv_spec_class *default_isa_spec,
1450 const char *name,
1451 int *major_version,
1452 int *minor_version)
1453 {
1454 if (name == NULL
1455 || default_isa_spec == NULL
1456 || *default_isa_spec == ISA_SPEC_CLASS_NONE)
1457 return;
1458
1459 struct riscv_supported_ext *table = NULL;
1460 enum riscv_prefix_ext_class class = riscv_get_prefix_class (name);
1461 switch (class)
1462 {
1463 case RV_ISA_CLASS_ZXM: table = riscv_supported_std_zxm_ext; break;
1464 case RV_ISA_CLASS_Z: table = riscv_supported_std_z_ext; break;
1465 case RV_ISA_CLASS_S: table = riscv_supported_std_s_ext; break;
1466 case RV_ISA_CLASS_H: table = riscv_supported_std_h_ext; break;
1467 case RV_ISA_CLASS_X:
1468 break;
1469 default:
1470 table = riscv_supported_std_ext;
1471 }
1472
1473 int i = 0;
1474 while (table != NULL && table[i].name != NULL)
1475 {
1476 if (strcmp (table[i].name, name) == 0
1477 && (table[i].isa_spec_class == ISA_SPEC_CLASS_DRAFT
1478 || table[i].isa_spec_class == *default_isa_spec))
1479 {
1480 *major_version = table[i].major_version;
1481 *minor_version = table[i].minor_version;
1482 return;
1483 }
1484 i++;
1485 }
1486 }
1487
1488 /* Find the default versions for the extension before adding them to
1489 the subset list, if their versions are RISCV_UNKNOWN_VERSION.
1490 Afterwards, report errors if we can not find their default versions. */
1491
1492 static void
1493 riscv_parse_add_subset (riscv_parse_subset_t *rps,
1494 const char *subset,
1495 int major,
1496 int minor,
1497 bool implicit)
1498 {
1499 int major_version = major;
1500 int minor_version = minor;
1501
1502 if (major_version == RISCV_UNKNOWN_VERSION
1503 || minor_version == RISCV_UNKNOWN_VERSION)
1504 riscv_get_default_ext_version (rps->isa_spec, subset,
1505 &major_version, &minor_version);
1506
1507 /* We don't care the versions of the implicit extensions. */
1508 if (!implicit
1509 && (major_version == RISCV_UNKNOWN_VERSION
1510 || minor_version == RISCV_UNKNOWN_VERSION))
1511 {
1512 if (subset[0] == 'x')
1513 rps->error_handler
1514 (_("x ISA extension `%s' must be set with the versions"),
1515 subset);
1516 else
1517 rps->error_handler
1518 (_("cannot find default versions of the ISA extension `%s'"),
1519 subset);
1520 return;
1521 }
1522
1523 riscv_add_subset (rps->subset_list, subset,
1524 major_version, minor_version);
1525 }
1526
1527 /* Release subset list. */
1528
1529 void
1530 riscv_release_subset_list (riscv_subset_list_t *subset_list)
1531 {
1532 while (subset_list->head != NULL)
1533 {
1534 riscv_subset_t *next = subset_list->head->next;
1535 free ((void *)subset_list->head->name);
1536 free (subset_list->head);
1537 subset_list->head = next;
1538 }
1539
1540 subset_list->tail = NULL;
1541 }
1542
1543 /* Parsing extension version.
1544
1545 Return Value:
1546 Points to the end of version
1547
1548 Arguments:
1549 `p`: Curent parsing position.
1550 `major_version`: Parsed major version.
1551 `minor_version`: Parsed minor version. */
1552
1553 static const char *
1554 riscv_parsing_subset_version (const char *p,
1555 int *major_version,
1556 int *minor_version)
1557 {
1558 bool major_p = true;
1559 int version = 0;
1560 char np;
1561
1562 *major_version = 0;
1563 *minor_version = 0;
1564 for (; *p; ++p)
1565 {
1566 if (*p == 'p')
1567 {
1568 np = *(p + 1);
1569
1570 /* Might be beginning of `p` extension. */
1571 if (!ISDIGIT (np))
1572 break;
1573
1574 *major_version = version;
1575 major_p = false;
1576 version = 0;
1577 }
1578 else if (ISDIGIT (*p))
1579 version = (version * 10) + (*p - '0');
1580 else
1581 break;
1582 }
1583
1584 if (major_p)
1585 *major_version = version;
1586 else
1587 *minor_version = version;
1588
1589 /* We can not find any version in string. */
1590 if (*major_version == 0 && *minor_version == 0)
1591 {
1592 *major_version = RISCV_UNKNOWN_VERSION;
1593 *minor_version = RISCV_UNKNOWN_VERSION;
1594 }
1595
1596 return p;
1597 }
1598
1599 /* Parsing function for standard extensions.
1600
1601 Return Value:
1602 Points to the end of extensions.
1603
1604 Arguments:
1605 `rps`: Hooks and status for parsing extensions.
1606 `arch`: Full ISA string.
1607 `p`: Curent parsing position. */
1608
1609 static const char *
1610 riscv_parse_std_ext (riscv_parse_subset_t *rps,
1611 const char *arch,
1612 const char *p)
1613 {
1614 /* First letter must start with i, e or g. */
1615 if (*p != 'e' && *p != 'i' && *p != 'g')
1616 {
1617 rps->error_handler
1618 (_("%s: first ISA extension must be `e', `i' or `g'"),
1619 arch);
1620 return NULL;
1621 }
1622
1623 while (p != NULL && *p != '\0')
1624 {
1625 /* Stop when we parsed the known prefix class. */
1626 enum riscv_prefix_ext_class class = riscv_get_prefix_class (p);
1627 if (class != RV_ISA_CLASS_UNKNOWN)
1628 break;
1629
1630 if (*p == '_')
1631 {
1632 p++;
1633 continue;
1634 }
1635
1636 bool implicit = false;
1637 int major = RISCV_UNKNOWN_VERSION;
1638 int minor = RISCV_UNKNOWN_VERSION;
1639 char subset[2] = {0, 0};
1640
1641 subset[0] = *p;
1642
1643 /* Check if the standard extension is supported. */
1644 if (riscv_ext_order[(subset[0] - 'a')] == 0)
1645 {
1646 rps->error_handler
1647 (_("%s: unknown standard ISA extension `%c'"),
1648 arch, subset[0]);
1649 return NULL;
1650 }
1651
1652 /* Checking canonical order. */
1653 if (rps->subset_list->tail != NULL
1654 && riscv_compare_subsets (rps->subset_list->tail->name, subset) > 0)
1655 {
1656 rps->error_handler
1657 (_("%s: standard ISA extension `%c' is not "
1658 "in canonical order"), arch, subset[0]);
1659 return NULL;
1660 }
1661
1662 p = riscv_parsing_subset_version (++p, &major, &minor);
1663 /* Added g as an implicit extension. */
1664 if (subset[0] == 'g')
1665 {
1666 implicit = true;
1667 major = RISCV_UNKNOWN_VERSION;
1668 minor = RISCV_UNKNOWN_VERSION;
1669 }
1670 riscv_parse_add_subset (rps, subset, major, minor, implicit);
1671 }
1672
1673 return p;
1674 }
1675
1676 /* Parsing function for prefixed extensions.
1677
1678 Return Value:
1679 Points to the end of extension.
1680
1681 Arguments:
1682 `rps`: Hooks and status for parsing extensions.
1683 `arch`: Full ISA string.
1684 `p`: Curent parsing position. */
1685
1686 static const char *
1687 riscv_parse_prefixed_ext (riscv_parse_subset_t *rps,
1688 const char *arch,
1689 const char *p)
1690 {
1691 int major_version;
1692 int minor_version;
1693 const char *last_name;
1694 enum riscv_prefix_ext_class class;
1695
1696 while (*p)
1697 {
1698 if (*p == '_')
1699 {
1700 p++;
1701 continue;
1702 }
1703
1704 class = riscv_get_prefix_class (p);
1705 if (class == RV_ISA_CLASS_UNKNOWN)
1706 {
1707 rps->error_handler
1708 (_("%s: unknown prefix class for the ISA extension `%s'"),
1709 arch, p);
1710 return NULL;
1711 }
1712
1713 char *subset = xstrdup (p);
1714 char *q = subset;
1715 const char *end_of_version;
1716
1717 /* Extract the whole prefixed extension by '_'. */
1718 while (*++q != '\0' && *q != '_')
1719 ;
1720 /* Look forward to the first letter which is not <major>p<minor>. */
1721 bool find_any_version = false;
1722 bool find_minor_version = false;
1723 while (1)
1724 {
1725 q--;
1726 if (ISDIGIT (*q))
1727 find_any_version = true;
1728 else if (find_any_version
1729 && !find_minor_version
1730 && *q == 'p'
1731 && ISDIGIT (*(q - 1)))
1732 find_minor_version = true;
1733 else
1734 break;
1735 }
1736 q++;
1737
1738 /* Check if the end of extension is 'p' or not. If yes, then
1739 the second letter from the end cannot be number. */
1740 if (*(q - 1) == 'p' && ISDIGIT (*(q - 2)))
1741 {
1742 *q = '\0';
1743 rps->error_handler
1744 (_("%s: invalid prefixed ISA extension `%s' ends with <number>p"),
1745 arch, subset);
1746 free (subset);
1747 return NULL;
1748 }
1749
1750 end_of_version =
1751 riscv_parsing_subset_version (q, &major_version, &minor_version);
1752 *q = '\0';
1753 if (end_of_version == NULL)
1754 {
1755 free (subset);
1756 return NULL;
1757 }
1758
1759 /* Check that the extension name is well-formed. */
1760 if (rps->check_unknown_prefixed_ext
1761 && !riscv_recognized_prefixed_ext (subset))
1762 {
1763 rps->error_handler
1764 (_("%s: unknown prefixed ISA extension `%s'"),
1765 arch, subset);
1766 free (subset);
1767 return NULL;
1768 }
1769
1770 /* Check that the extension isn't duplicate. */
1771 last_name = rps->subset_list->tail->name;
1772 if (!strcasecmp (last_name, subset))
1773 {
1774 rps->error_handler
1775 (_("%s: duplicate prefixed ISA extension `%s'"),
1776 arch, subset);
1777 free (subset);
1778 return NULL;
1779 }
1780
1781 /* Check that the extension is in expected order. */
1782 if (riscv_compare_subsets (last_name, subset) > 0)
1783 {
1784 rps->error_handler
1785 (_("%s: prefixed ISA extension `%s' is not in expected "
1786 "order. It must come before `%s'"),
1787 arch, subset, last_name);
1788 free (subset);
1789 return NULL;
1790 }
1791
1792 riscv_parse_add_subset (rps, subset,
1793 major_version,
1794 minor_version, false);
1795 p += end_of_version - subset;
1796 free (subset);
1797
1798 if (*p != '\0' && *p != '_')
1799 {
1800 rps->error_handler
1801 (_("%s: prefixed ISA extension must separate with _"),
1802 arch);
1803 return NULL;
1804 }
1805 }
1806
1807 return p;
1808 }
1809
1810 /* Add the implicit extensions. */
1811
1812 static void
1813 riscv_parse_add_implicit_subsets (riscv_parse_subset_t *rps)
1814 {
1815 struct riscv_implicit_subset *t = riscv_implicit_subsets;
1816 for (; t->subset_name; t++)
1817 {
1818 riscv_subset_t *subset = NULL;
1819 if (riscv_lookup_subset (rps->subset_list, t->subset_name, &subset)
1820 && t->check_func (t->implicit_name, subset))
1821 riscv_parse_add_subset (rps, t->implicit_name,
1822 RISCV_UNKNOWN_VERSION,
1823 RISCV_UNKNOWN_VERSION, true);
1824 }
1825 }
1826
1827 /* Check extensions conflicts. */
1828
1829 static bool
1830 riscv_parse_check_conflicts (riscv_parse_subset_t *rps)
1831 {
1832 riscv_subset_t *subset = NULL;
1833 int xlen = *rps->xlen;
1834 bool no_conflict = true;
1835
1836 if (riscv_lookup_subset (rps->subset_list, "e", &subset)
1837 && xlen > 32)
1838 {
1839 rps->error_handler
1840 (_("rv%d does not support the `e' extension"), xlen);
1841 no_conflict = false;
1842 }
1843 if (riscv_lookup_subset (rps->subset_list, "q", &subset)
1844 && xlen < 64)
1845 {
1846 rps->error_handler
1847 (_("rv%d does not support the `q' extension"), xlen);
1848 no_conflict = false;
1849 }
1850 if (riscv_lookup_subset (rps->subset_list, "e", &subset)
1851 && riscv_lookup_subset (rps->subset_list, "f", &subset))
1852 {
1853 rps->error_handler
1854 (_("rv32e does not support the `f' extension"));
1855 no_conflict = false;
1856 }
1857 return no_conflict;
1858 }
1859
1860 /* Set the default subset list according to the default_enable field
1861 of riscv_supported_*ext tables. */
1862
1863 static void
1864 riscv_set_default_arch (riscv_parse_subset_t *rps)
1865 {
1866 unsigned long enable = EXT_DEFAULT;
1867 int i, j;
1868 for (i = 0; riscv_all_supported_ext[i] != NULL; i++)
1869 {
1870 const struct riscv_supported_ext *table = riscv_all_supported_ext[i];
1871 for (j = 0; table[j].name != NULL; j++)
1872 {
1873 bool implicit = false;
1874 if (strcmp (table[j].name, "g") == 0)
1875 implicit = true;
1876 if (table[j].default_enable & enable)
1877 riscv_parse_add_subset (rps, table[j].name,
1878 RISCV_UNKNOWN_VERSION,
1879 RISCV_UNKNOWN_VERSION, implicit);
1880 }
1881 }
1882 }
1883
1884 /* Function for parsing ISA string.
1885
1886 Return Value:
1887 Return TRUE on success.
1888
1889 Arguments:
1890 `rps`: Hooks and status for parsing extensions.
1891 `arch`: Full ISA string. */
1892
1893 bool
1894 riscv_parse_subset (riscv_parse_subset_t *rps,
1895 const char *arch)
1896 {
1897 const char *p;
1898
1899 /* Init the riscv_ext_order array to compare the order of extensions
1900 quickly. */
1901 riscv_init_ext_order ();
1902
1903 if (arch == NULL)
1904 {
1905 riscv_set_default_arch (rps);
1906 riscv_parse_add_implicit_subsets (rps);
1907 return riscv_parse_check_conflicts (rps);
1908 }
1909
1910 for (p = arch; *p != '\0'; p++)
1911 {
1912 if (ISUPPER (*p))
1913 {
1914 rps->error_handler
1915 (_("%s: ISA string cannot contain uppercase letters"),
1916 arch);
1917 return false;
1918 }
1919 }
1920
1921 p = arch;
1922 if (startswith (p, "rv32"))
1923 {
1924 *rps->xlen = 32;
1925 p += 4;
1926 }
1927 else if (startswith (p, "rv64"))
1928 {
1929 *rps->xlen = 64;
1930 p += 4;
1931 }
1932 else
1933 {
1934 /* ISA string shouldn't be NULL or empty here. For linker,
1935 it might be empty when we failed to merge the ISA string
1936 in the riscv_merge_attributes. For assembler, we might
1937 give an empty string by .attribute arch, "" or -march=.
1938 However, We have already issued the correct error message
1939 in another side, so do not issue this error when the ISA
1940 string is empty. */
1941 if (strlen (arch))
1942 rps->error_handler (
1943 _("%s: ISA string must begin with rv32 or rv64"),
1944 arch);
1945 return false;
1946 }
1947
1948 /* Parsing standard extension. */
1949 p = riscv_parse_std_ext (rps, arch, p);
1950
1951 if (p == NULL)
1952 return false;
1953
1954 /* Parse the different classes of extensions in the specified order. */
1955 while (*p != '\0')
1956 {
1957 p = riscv_parse_prefixed_ext (rps, arch, p);
1958
1959 if (p == NULL)
1960 return false;
1961 }
1962
1963 /* Finally add implicit extensions according to the current
1964 extensions. */
1965 riscv_parse_add_implicit_subsets (rps);
1966
1967 /* Check the conflicts. */
1968 return riscv_parse_check_conflicts (rps);
1969 }
1970
1971 /* Return the number of digits for the input. */
1972
1973 size_t
1974 riscv_estimate_digit (unsigned num)
1975 {
1976 size_t digit = 0;
1977 if (num == 0)
1978 return 1;
1979
1980 for (digit = 0; num ; num /= 10)
1981 digit++;
1982
1983 return digit;
1984 }
1985
1986 /* Auxiliary function to estimate string length of subset list. */
1987
1988 static size_t
1989 riscv_estimate_arch_strlen1 (const riscv_subset_t *subset)
1990 {
1991 if (subset == NULL)
1992 return 6; /* For rv32/rv64/rv128 and string terminator. */
1993
1994 return riscv_estimate_arch_strlen1 (subset->next)
1995 + strlen (subset->name)
1996 + riscv_estimate_digit (subset->major_version)
1997 + 1 /* For version seperator 'p'. */
1998 + riscv_estimate_digit (subset->minor_version)
1999 + 1 /* For underscore. */;
2000 }
2001
2002 /* Estimate the string length of this subset list. */
2003
2004 static size_t
2005 riscv_estimate_arch_strlen (const riscv_subset_list_t *subset_list)
2006 {
2007 return riscv_estimate_arch_strlen1 (subset_list->head);
2008 }
2009
2010 /* Auxiliary function to convert subset info to string. */
2011
2012 static void
2013 riscv_arch_str1 (riscv_subset_t *subset,
2014 char *attr_str, char *buf, size_t bufsz)
2015 {
2016 const char *underline = "_";
2017 riscv_subset_t *subset_t = subset;
2018
2019 if (subset_t == NULL)
2020 return;
2021
2022 /* No underline between rvXX and i/e. */
2023 if ((strcasecmp (subset_t->name, "i") == 0)
2024 || (strcasecmp (subset_t->name, "e") == 0))
2025 underline = "";
2026
2027 snprintf (buf, bufsz, "%s%s%dp%d",
2028 underline,
2029 subset_t->name,
2030 subset_t->major_version,
2031 subset_t->minor_version);
2032
2033 strncat (attr_str, buf, bufsz);
2034
2035 /* Skip 'i' extension after 'e', or skip extensions which
2036 versions are unknown. */
2037 while (subset_t->next
2038 && ((strcmp (subset_t->name, "e") == 0
2039 && strcmp (subset_t->next->name, "i") == 0)
2040 || subset_t->next->major_version == RISCV_UNKNOWN_VERSION
2041 || subset_t->next->minor_version == RISCV_UNKNOWN_VERSION))
2042 subset_t = subset_t->next;
2043
2044 riscv_arch_str1 (subset_t->next, attr_str, buf, bufsz);
2045 }
2046
2047 /* Convert subset information into string with explicit versions. */
2048
2049 char *
2050 riscv_arch_str (unsigned xlen, const riscv_subset_list_t *subset)
2051 {
2052 size_t arch_str_len = riscv_estimate_arch_strlen (subset);
2053 char *attr_str = xmalloc (arch_str_len);
2054 char *buf = xmalloc (arch_str_len);
2055
2056 snprintf (attr_str, arch_str_len, "rv%u", xlen);
2057
2058 riscv_arch_str1 (subset->head, attr_str, buf, arch_str_len);
2059 free (buf);
2060
2061 return attr_str;
2062 }
2063
2064 /* Remove the SUBSET from the subset list. */
2065
2066 static void
2067 riscv_remove_subset (riscv_subset_list_t *subset_list,
2068 const char *subset)
2069 {
2070 riscv_subset_t *current = subset_list->head;
2071 riscv_subset_t *pre = NULL;
2072 for (; current != NULL; pre = current, current = current->next)
2073 {
2074 if (strcmp (current->name, subset) == 0)
2075 {
2076 if (pre == NULL)
2077 subset_list->head = current->next;
2078 else
2079 pre->next = current->next;
2080 if (current->next == NULL)
2081 subset_list->tail = pre;
2082 free ((void *) current->name);
2083 free (current);
2084 break;
2085 }
2086 }
2087 }
2088
2089 /* Add/Remove an extension to/from the subset list. This is used for
2090 the .option rvc or norvc. */
2091
2092 bool
2093 riscv_update_subset (riscv_parse_subset_t *rps,
2094 const char *subset,
2095 bool removed)
2096 {
2097 if (strlen (subset) == 0
2098 || (strlen (subset) == 1
2099 && riscv_ext_order[(*subset - 'a')] == 0)
2100 || (strlen (subset) > 1
2101 && rps->check_unknown_prefixed_ext
2102 && !riscv_recognized_prefixed_ext (subset)))
2103 {
2104 rps->error_handler
2105 (_("riscv_update_subset: unknown ISA extension `%s'"), subset);
2106 return false;
2107 }
2108
2109 if (removed)
2110 {
2111 if (strcmp (subset, "i") == 0)
2112 {
2113 rps->error_handler
2114 (_("riscv_update_subset: cannot remove extension i from "
2115 "the subset list"));
2116 return false;
2117 }
2118 riscv_remove_subset (rps->subset_list, subset);
2119 }
2120 else
2121 riscv_parse_add_subset (rps, subset,
2122 RISCV_UNKNOWN_VERSION,
2123 RISCV_UNKNOWN_VERSION, true);
2124
2125 riscv_parse_add_implicit_subsets (rps);
2126 return riscv_parse_check_conflicts (rps);
2127 }
2128
2129 /* Check if the FEATURE subset is supported or not in the subset list.
2130 Return true if it is supported; Otherwise, return false. */
2131
2132 bool
2133 riscv_subset_supports (riscv_parse_subset_t *rps,
2134 const char *feature)
2135 {
2136 struct riscv_subset_t *subset;
2137 return riscv_lookup_subset (rps->subset_list, feature, &subset);
2138 }
2139
2140 /* Each instuction is belonged to an instruction class INSN_CLASS_*.
2141 Call riscv_subset_supports to make sure if the instuction is valid. */
2142
2143 bool
2144 riscv_multi_subset_supports (riscv_parse_subset_t *rps,
2145 enum riscv_insn_class insn_class)
2146 {
2147 switch (insn_class)
2148 {
2149 case INSN_CLASS_I:
2150 return riscv_subset_supports (rps, "i");
2151 case INSN_CLASS_ZICSR:
2152 return riscv_subset_supports (rps, "zicsr");
2153 case INSN_CLASS_ZIFENCEI:
2154 return riscv_subset_supports (rps, "zifencei");
2155 case INSN_CLASS_ZIHINTPAUSE:
2156 return riscv_subset_supports (rps, "zihintpause");
2157 case INSN_CLASS_M:
2158 return riscv_subset_supports (rps, "m");
2159 case INSN_CLASS_A:
2160 return riscv_subset_supports (rps, "a");
2161 case INSN_CLASS_F:
2162 return riscv_subset_supports (rps, "f");
2163 case INSN_CLASS_D:
2164 return riscv_subset_supports (rps, "d");
2165 case INSN_CLASS_Q:
2166 return riscv_subset_supports (rps, "q");
2167 case INSN_CLASS_C:
2168 return riscv_subset_supports (rps, "c");
2169 case INSN_CLASS_F_AND_C:
2170 return (riscv_subset_supports (rps, "f")
2171 && riscv_subset_supports (rps, "c"));
2172 case INSN_CLASS_D_AND_C:
2173 return (riscv_subset_supports (rps, "d")
2174 && riscv_subset_supports (rps, "c"));
2175 case INSN_CLASS_ZBA:
2176 return riscv_subset_supports (rps, "zba");
2177 case INSN_CLASS_ZBB:
2178 return riscv_subset_supports (rps, "zbb");
2179 case INSN_CLASS_ZBC:
2180 return riscv_subset_supports (rps, "zbc");
2181 case INSN_CLASS_ZBS:
2182 return riscv_subset_supports (rps, "zbs");
2183 default:
2184 rps->error_handler
2185 (_("internal: unreachable INSN_CLASS_*"));
2186 return false;
2187 }
2188 }