Automatic date update in version.in
[binutils-gdb.git] / bfd / elfxx-riscv.c
1 /* RISC-V-specific support for ELF.
2 Copyright (C) 2011-2022 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 {"v", "d", check_implicit_always},
1077 {"v", "zve64d", check_implicit_always},
1078 {"v", "zvl128b", check_implicit_always},
1079 {"zve64d", "d", check_implicit_always},
1080 {"zve64d", "zve64f", check_implicit_always},
1081 {"zve64f", "zve32f", check_implicit_always},
1082 {"zve64f", "zve64x", check_implicit_always},
1083 {"zve64f", "zvl64b", check_implicit_always},
1084 {"zve32f", "f", check_implicit_always},
1085 {"zve32f", "zvl32b", check_implicit_always},
1086 {"zve32f", "zve32x", check_implicit_always},
1087 {"zve64x", "zve32x", check_implicit_always},
1088 {"zve64x", "zvl64b", check_implicit_always},
1089 {"zve32x", "zvl32b", check_implicit_always},
1090 {"zvl65536b", "zvl32768b", check_implicit_always},
1091 {"zvl32768b", "zvl16384b", check_implicit_always},
1092 {"zvl16384b", "zvl8192b", check_implicit_always},
1093 {"zvl8192b", "zvl4096b", check_implicit_always},
1094 {"zvl4096b", "zvl2048b", check_implicit_always},
1095 {"zvl2048b", "zvl1024b", check_implicit_always},
1096 {"zvl1024b", "zvl512b", check_implicit_always},
1097 {"zvl512b", "zvl256b", check_implicit_always},
1098 {"zvl256b", "zvl128b", check_implicit_always},
1099 {"zvl128b", "zvl64b", check_implicit_always},
1100 {"zvl64b", "zvl32b", check_implicit_always},
1101 {"d", "f", check_implicit_always},
1102 {"f", "zicsr", check_implicit_always},
1103 {"zqinx", "zdinx", check_implicit_always},
1104 {"zdinx", "zfinx", check_implicit_always},
1105 {"zk", "zkn", check_implicit_always},
1106 {"zk", "zkr", check_implicit_always},
1107 {"zk", "zkt", check_implicit_always},
1108 {"zkn", "zbkb", check_implicit_always},
1109 {"zkn", "zbkc", check_implicit_always},
1110 {"zkn", "zbkx", check_implicit_always},
1111 {"zkn", "zkne", check_implicit_always},
1112 {"zkn", "zknd", check_implicit_always},
1113 {"zkn", "zknh", check_implicit_always},
1114 {"zks", "zbkb", check_implicit_always},
1115 {"zks", "zbkc", check_implicit_always},
1116 {"zks", "zbkx", check_implicit_always},
1117 {"zks", "zksed", check_implicit_always},
1118 {"zks", "zksh", check_implicit_always},
1119 {NULL, NULL, NULL}
1120 };
1121
1122 /* For default_enable field, decide if the extension should
1123 be enbaled by default. */
1124
1125 #define EXT_DEFAULT 0x1
1126
1127 /* List all extensions that binutils should know about. */
1128
1129 struct riscv_supported_ext
1130 {
1131 const char *name;
1132 enum riscv_spec_class isa_spec_class;
1133 int major_version;
1134 int minor_version;
1135 unsigned long default_enable;
1136 };
1137
1138 /* The standard extensions must be added in canonical order. */
1139
1140 static struct riscv_supported_ext riscv_supported_std_ext[] =
1141 {
1142 {"e", ISA_SPEC_CLASS_20191213, 1, 9, 0 },
1143 {"e", ISA_SPEC_CLASS_20190608, 1, 9, 0 },
1144 {"e", ISA_SPEC_CLASS_2P2, 1, 9, 0 },
1145 {"i", ISA_SPEC_CLASS_20191213, 2, 1, 0 },
1146 {"i", ISA_SPEC_CLASS_20190608, 2, 1, 0 },
1147 {"i", ISA_SPEC_CLASS_2P2, 2, 0, 0 },
1148 /* The g is a special case which we don't want to output it,
1149 but still need it when adding implicit extensions. */
1150 {"g", ISA_SPEC_CLASS_NONE, RISCV_UNKNOWN_VERSION, RISCV_UNKNOWN_VERSION, EXT_DEFAULT },
1151 {"m", ISA_SPEC_CLASS_20191213, 2, 0, 0 },
1152 {"m", ISA_SPEC_CLASS_20190608, 2, 0, 0 },
1153 {"m", ISA_SPEC_CLASS_2P2, 2, 0, 0 },
1154 {"a", ISA_SPEC_CLASS_20191213, 2, 1, 0 },
1155 {"a", ISA_SPEC_CLASS_20190608, 2, 0, 0 },
1156 {"a", ISA_SPEC_CLASS_2P2, 2, 0, 0 },
1157 {"f", ISA_SPEC_CLASS_20191213, 2, 2, 0 },
1158 {"f", ISA_SPEC_CLASS_20190608, 2, 2, 0 },
1159 {"f", ISA_SPEC_CLASS_2P2, 2, 0, 0 },
1160 {"d", ISA_SPEC_CLASS_20191213, 2, 2, 0 },
1161 {"d", ISA_SPEC_CLASS_20190608, 2, 2, 0 },
1162 {"d", ISA_SPEC_CLASS_2P2, 2, 0, 0 },
1163 {"q", ISA_SPEC_CLASS_20191213, 2, 2, 0 },
1164 {"q", ISA_SPEC_CLASS_20190608, 2, 2, 0 },
1165 {"q", ISA_SPEC_CLASS_2P2, 2, 0, 0 },
1166 {"l", ISA_SPEC_CLASS_NONE, RISCV_UNKNOWN_VERSION, RISCV_UNKNOWN_VERSION, 0 },
1167 {"c", ISA_SPEC_CLASS_20191213, 2, 0, 0 },
1168 {"c", ISA_SPEC_CLASS_20190608, 2, 0, 0 },
1169 {"c", ISA_SPEC_CLASS_2P2, 2, 0, 0 },
1170 {"b", ISA_SPEC_CLASS_NONE, RISCV_UNKNOWN_VERSION, RISCV_UNKNOWN_VERSION, 0 },
1171 {"k", ISA_SPEC_CLASS_NONE, RISCV_UNKNOWN_VERSION, RISCV_UNKNOWN_VERSION, 0 },
1172 {"j", ISA_SPEC_CLASS_NONE, RISCV_UNKNOWN_VERSION, RISCV_UNKNOWN_VERSION, 0 },
1173 {"t", ISA_SPEC_CLASS_NONE, RISCV_UNKNOWN_VERSION, RISCV_UNKNOWN_VERSION, 0 },
1174 {"p", ISA_SPEC_CLASS_NONE, RISCV_UNKNOWN_VERSION, RISCV_UNKNOWN_VERSION, 0 },
1175 {"v", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
1176 {"n", ISA_SPEC_CLASS_NONE, RISCV_UNKNOWN_VERSION, RISCV_UNKNOWN_VERSION, 0 },
1177 {NULL, 0, 0, 0, 0}
1178 };
1179
1180 static struct riscv_supported_ext riscv_supported_std_z_ext[] =
1181 {
1182 {"zicsr", ISA_SPEC_CLASS_20191213, 2, 0, 0 },
1183 {"zicsr", ISA_SPEC_CLASS_20190608, 2, 0, 0 },
1184 {"zifencei", ISA_SPEC_CLASS_20191213, 2, 0, 0 },
1185 {"zifencei", ISA_SPEC_CLASS_20190608, 2, 0, 0 },
1186 {"zihintpause", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
1187 {"zfinx", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
1188 {"zdinx", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
1189 {"zqinx", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
1190 {"zbb", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
1191 {"zba", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
1192 {"zbc", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
1193 {"zbs", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
1194 {"zbkb", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
1195 {"zbkc", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
1196 {"zbkx", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
1197 {"zk", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
1198 {"zkn", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
1199 {"zknd", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
1200 {"zkne", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
1201 {"zknh", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
1202 {"zkr", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
1203 {"zks", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
1204 {"zksed", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
1205 {"zksh", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
1206 {"zkt", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
1207 {"zve32x", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
1208 {"zve32f", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
1209 {"zve32d", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
1210 {"zve64x", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
1211 {"zve64f", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
1212 {"zve64d", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
1213 {"zvl32b", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
1214 {"zvl64b", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
1215 {"zvl128b", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
1216 {"zvl256b", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
1217 {"zvl512b", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
1218 {"zvl1024b", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
1219 {"zvl2048b", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
1220 {"zvl4096b", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
1221 {"zvl8192b", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
1222 {"zvl16384b", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
1223 {"zvl32768b", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
1224 {"zvl65536b", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
1225 {NULL, 0, 0, 0, 0}
1226 };
1227
1228 static struct riscv_supported_ext riscv_supported_std_s_ext[] =
1229 {
1230 {"svinval", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
1231 {NULL, 0, 0, 0, 0}
1232 };
1233
1234 static struct riscv_supported_ext riscv_supported_std_h_ext[] =
1235 {
1236 {NULL, 0, 0, 0, 0}
1237 };
1238
1239 static struct riscv_supported_ext riscv_supported_std_zxm_ext[] =
1240 {
1241 {NULL, 0, 0, 0, 0}
1242 };
1243
1244 const struct riscv_supported_ext *riscv_all_supported_ext[] =
1245 {
1246 riscv_supported_std_ext,
1247 riscv_supported_std_z_ext,
1248 riscv_supported_std_s_ext,
1249 riscv_supported_std_h_ext,
1250 riscv_supported_std_zxm_ext,
1251 NULL
1252 };
1253
1254 /* ISA extension prefixed name class. Must define them in parsing order. */
1255 enum riscv_prefix_ext_class
1256 {
1257 RV_ISA_CLASS_Z = 1,
1258 RV_ISA_CLASS_S,
1259 RV_ISA_CLASS_H,
1260 RV_ISA_CLASS_ZXM,
1261 RV_ISA_CLASS_X,
1262 RV_ISA_CLASS_UNKNOWN
1263 };
1264
1265 /* Record the strings of the prefixed extensions, and their corresponding
1266 classes. The more letters of the prefix string, the more forward it must
1267 be defined. Otherwise, the riscv_get_prefix_class will map it to the
1268 wrong classes. */
1269 struct riscv_parse_prefix_config
1270 {
1271 /* Class of the extension. */
1272 enum riscv_prefix_ext_class class;
1273
1274 /* Prefix string for error printing and internal parser usage. */
1275 const char *prefix;
1276 };
1277 static const struct riscv_parse_prefix_config parse_config[] =
1278 {
1279 {RV_ISA_CLASS_ZXM, "zxm"},
1280 {RV_ISA_CLASS_Z, "z"},
1281 {RV_ISA_CLASS_S, "s"},
1282 {RV_ISA_CLASS_H, "h"},
1283 {RV_ISA_CLASS_X, "x"},
1284 {RV_ISA_CLASS_UNKNOWN, NULL}
1285 };
1286
1287 /* Get the prefixed name class for the extensions, the class also
1288 means the order of the prefixed extensions. */
1289
1290 static enum riscv_prefix_ext_class
1291 riscv_get_prefix_class (const char *arch)
1292 {
1293 int i = 0;
1294 while (parse_config[i].class != RV_ISA_CLASS_UNKNOWN)
1295 {
1296 if (strncmp (arch, parse_config[i].prefix,
1297 strlen (parse_config[i].prefix)) == 0)
1298 return parse_config[i].class;
1299 i++;
1300 }
1301 return RV_ISA_CLASS_UNKNOWN;
1302 }
1303
1304 /* Check KNOWN_EXTS to see if the EXT is supported. */
1305
1306 static bool
1307 riscv_known_prefixed_ext (const char *ext,
1308 struct riscv_supported_ext *known_exts)
1309 {
1310 size_t i;
1311 for (i = 0; known_exts[i].name != NULL; ++i)
1312 if (strcmp (ext, known_exts[i].name) == 0)
1313 return true;
1314 return false;
1315 }
1316
1317 /* Check whether the prefixed extension is recognized or not. Return
1318 true if recognized, otehrwise return false. */
1319
1320 static bool
1321 riscv_recognized_prefixed_ext (const char *ext)
1322 {
1323 enum riscv_prefix_ext_class class = riscv_get_prefix_class (ext);
1324 switch (class)
1325 {
1326 case RV_ISA_CLASS_Z:
1327 return riscv_known_prefixed_ext (ext, riscv_supported_std_z_ext);
1328 case RV_ISA_CLASS_ZXM:
1329 return riscv_known_prefixed_ext (ext, riscv_supported_std_zxm_ext);
1330 case RV_ISA_CLASS_S:
1331 return riscv_known_prefixed_ext (ext, riscv_supported_std_s_ext);
1332 case RV_ISA_CLASS_H:
1333 return riscv_known_prefixed_ext (ext, riscv_supported_std_h_ext);
1334 case RV_ISA_CLASS_X:
1335 /* Only the single x is unrecognized. */
1336 if (strcmp (ext, "x") != 0)
1337 return true;
1338 default:
1339 break;
1340 }
1341 return false;
1342 }
1343
1344 /* Array is used to compare the orders of standard extensions quickly. */
1345 static int riscv_ext_order[26] = {0};
1346
1347 /* Init the riscv_ext_order array. */
1348
1349 static void
1350 riscv_init_ext_order (void)
1351 {
1352 static bool inited = false;
1353 if (inited)
1354 return;
1355
1356 /* The orders of all standard extensions are positive. */
1357 int order = 1;
1358
1359 int i = 0;
1360 while (riscv_supported_std_ext[i].name != NULL)
1361 {
1362 const char *ext = riscv_supported_std_ext[i].name;
1363 riscv_ext_order[(*ext - 'a')] = order++;
1364 i++;
1365 while (riscv_supported_std_ext[i].name
1366 && strcmp (ext, riscv_supported_std_ext[i].name) == 0)
1367 i++;
1368 }
1369
1370 /* Some of the prefixed keyword are not single letter, so we set
1371 their prefixed orders in the riscv_compare_subsets directly,
1372 not through the riscv_ext_order. */
1373
1374 inited = true;
1375 }
1376
1377 /* Similar to the strcmp. It returns an integer less than, equal to,
1378 or greater than zero if `subset2` is found, respectively, to be less
1379 than, to match, or be greater than `subset1`.
1380
1381 The order values,
1382 Zero: Preserved keywords.
1383 Positive number: Standard extensions.
1384 Negative number: Prefixed keywords. */
1385
1386 int
1387 riscv_compare_subsets (const char *subset1, const char *subset2)
1388 {
1389 int order1 = riscv_ext_order[(*subset1 - 'a')];
1390 int order2 = riscv_ext_order[(*subset2 - 'a')];
1391
1392 /* Compare the standard extension first. */
1393 if (order1 > 0 && order2 > 0)
1394 return order1 - order2;
1395
1396 /* Set the prefixed orders to negative numbers. */
1397 enum riscv_prefix_ext_class class1 = riscv_get_prefix_class (subset1);
1398 enum riscv_prefix_ext_class class2 = riscv_get_prefix_class (subset2);
1399
1400 if (class1 != RV_ISA_CLASS_UNKNOWN)
1401 order1 = - (int) class1;
1402 if (class2 != RV_ISA_CLASS_UNKNOWN)
1403 order2 = - (int) class2;
1404
1405 if (order1 == order2)
1406 {
1407 /* Compare the standard addition z extensions. */
1408 if (class1 == RV_ISA_CLASS_Z)
1409 {
1410 order1 = riscv_ext_order[(*++subset1 - 'a')];
1411 order2 = riscv_ext_order[(*++subset2 - 'a')];
1412 if (order1 != order2)
1413 return order1 - order2;
1414 }
1415 return strcasecmp (++subset1, ++subset2);
1416 }
1417
1418 return order2 - order1;
1419 }
1420
1421 /* Find subset in the list. Return TRUE and set `current` to the subset
1422 if it is found. Otherwise, return FALSE and set `current` to the place
1423 where we should insert the subset. However, return FALSE with the NULL
1424 `current` means we should insert the subset at the head of subset list,
1425 if needed. */
1426
1427 bool
1428 riscv_lookup_subset (const riscv_subset_list_t *subset_list,
1429 const char *subset,
1430 riscv_subset_t **current)
1431 {
1432 riscv_subset_t *s, *pre_s = NULL;
1433
1434 /* If the subset is added in order, then just add it at the tail. */
1435 if (subset_list->tail != NULL
1436 && riscv_compare_subsets (subset_list->tail->name, subset) < 0)
1437 {
1438 *current = subset_list->tail;
1439 return false;
1440 }
1441
1442 for (s = subset_list->head;
1443 s != NULL;
1444 pre_s = s, s = s->next)
1445 {
1446 int cmp = riscv_compare_subsets (s->name, subset);
1447 if (cmp == 0)
1448 {
1449 *current = s;
1450 return true;
1451 }
1452 else if (cmp > 0)
1453 break;
1454 }
1455 *current = pre_s;
1456
1457 return false;
1458 }
1459
1460 /* Add the extension to the subset list. Search the
1461 list first, and then find the right place to add. */
1462
1463 void
1464 riscv_add_subset (riscv_subset_list_t *subset_list,
1465 const char *subset,
1466 int major,
1467 int minor)
1468 {
1469 riscv_subset_t *current, *new;
1470
1471 if (riscv_lookup_subset (subset_list, subset, &current))
1472 return;
1473
1474 new = xmalloc (sizeof *new);
1475 new->name = xstrdup (subset);
1476 new->major_version = major;
1477 new->minor_version = minor;
1478 new->next = NULL;
1479
1480 if (current != NULL)
1481 {
1482 new->next = current->next;
1483 current->next = new;
1484 }
1485 else
1486 {
1487 new->next = subset_list->head;
1488 subset_list->head = new;
1489 }
1490
1491 if (new->next == NULL)
1492 subset_list->tail = new;
1493 }
1494
1495 /* Get the default versions from the riscv_supported_*ext tables. */
1496
1497 static void
1498 riscv_get_default_ext_version (enum riscv_spec_class *default_isa_spec,
1499 const char *name,
1500 int *major_version,
1501 int *minor_version)
1502 {
1503 if (name == NULL
1504 || default_isa_spec == NULL
1505 || *default_isa_spec == ISA_SPEC_CLASS_NONE)
1506 return;
1507
1508 struct riscv_supported_ext *table = NULL;
1509 enum riscv_prefix_ext_class class = riscv_get_prefix_class (name);
1510 switch (class)
1511 {
1512 case RV_ISA_CLASS_ZXM: table = riscv_supported_std_zxm_ext; break;
1513 case RV_ISA_CLASS_Z: table = riscv_supported_std_z_ext; break;
1514 case RV_ISA_CLASS_S: table = riscv_supported_std_s_ext; break;
1515 case RV_ISA_CLASS_H: table = riscv_supported_std_h_ext; break;
1516 case RV_ISA_CLASS_X:
1517 break;
1518 default:
1519 table = riscv_supported_std_ext;
1520 }
1521
1522 int i = 0;
1523 while (table != NULL && table[i].name != NULL)
1524 {
1525 if (strcmp (table[i].name, name) == 0
1526 && (table[i].isa_spec_class == ISA_SPEC_CLASS_DRAFT
1527 || table[i].isa_spec_class == *default_isa_spec))
1528 {
1529 *major_version = table[i].major_version;
1530 *minor_version = table[i].minor_version;
1531 return;
1532 }
1533 i++;
1534 }
1535 }
1536
1537 /* Find the default versions for the extension before adding them to
1538 the subset list, if their versions are RISCV_UNKNOWN_VERSION.
1539 Afterwards, report errors if we can not find their default versions. */
1540
1541 static void
1542 riscv_parse_add_subset (riscv_parse_subset_t *rps,
1543 const char *subset,
1544 int major,
1545 int minor,
1546 bool implicit)
1547 {
1548 int major_version = major;
1549 int minor_version = minor;
1550
1551 if (major_version == RISCV_UNKNOWN_VERSION
1552 || minor_version == RISCV_UNKNOWN_VERSION)
1553 riscv_get_default_ext_version (rps->isa_spec, subset,
1554 &major_version, &minor_version);
1555
1556 /* We don't care the versions of the implicit extensions. */
1557 if (!implicit
1558 && (major_version == RISCV_UNKNOWN_VERSION
1559 || minor_version == RISCV_UNKNOWN_VERSION))
1560 {
1561 if (subset[0] == 'x')
1562 rps->error_handler
1563 (_("x ISA extension `%s' must be set with the versions"),
1564 subset);
1565 /* Allow old ISA spec can recognize zicsr and zifencei. */
1566 else if (strcmp (subset, "zicsr") != 0
1567 && strcmp (subset, "zifencei") != 0)
1568 rps->error_handler
1569 (_("cannot find default versions of the ISA extension `%s'"),
1570 subset);
1571 return;
1572 }
1573
1574 riscv_add_subset (rps->subset_list, subset,
1575 major_version, minor_version);
1576 }
1577
1578 /* Release subset list. */
1579
1580 void
1581 riscv_release_subset_list (riscv_subset_list_t *subset_list)
1582 {
1583 while (subset_list->head != NULL)
1584 {
1585 riscv_subset_t *next = subset_list->head->next;
1586 free ((void *)subset_list->head->name);
1587 free (subset_list->head);
1588 subset_list->head = next;
1589 }
1590
1591 subset_list->tail = NULL;
1592 }
1593
1594 /* Parsing extension version.
1595
1596 Return Value:
1597 Points to the end of version
1598
1599 Arguments:
1600 `p`: Curent parsing position.
1601 `major_version`: Parsed major version.
1602 `minor_version`: Parsed minor version. */
1603
1604 static const char *
1605 riscv_parsing_subset_version (const char *p,
1606 int *major_version,
1607 int *minor_version)
1608 {
1609 bool major_p = true;
1610 int version = 0;
1611 char np;
1612
1613 *major_version = 0;
1614 *minor_version = 0;
1615 for (; *p; ++p)
1616 {
1617 if (*p == 'p')
1618 {
1619 np = *(p + 1);
1620
1621 /* Might be beginning of `p` extension. */
1622 if (!ISDIGIT (np))
1623 break;
1624
1625 *major_version = version;
1626 major_p = false;
1627 version = 0;
1628 }
1629 else if (ISDIGIT (*p))
1630 version = (version * 10) + (*p - '0');
1631 else
1632 break;
1633 }
1634
1635 if (major_p)
1636 *major_version = version;
1637 else
1638 *minor_version = version;
1639
1640 /* We can not find any version in string. */
1641 if (*major_version == 0 && *minor_version == 0)
1642 {
1643 *major_version = RISCV_UNKNOWN_VERSION;
1644 *minor_version = RISCV_UNKNOWN_VERSION;
1645 }
1646
1647 return p;
1648 }
1649
1650 /* Parsing function for standard extensions.
1651
1652 Return Value:
1653 Points to the end of extensions.
1654
1655 Arguments:
1656 `rps`: Hooks and status for parsing extensions.
1657 `arch`: Full ISA string.
1658 `p`: Curent parsing position. */
1659
1660 static const char *
1661 riscv_parse_std_ext (riscv_parse_subset_t *rps,
1662 const char *arch,
1663 const char *p)
1664 {
1665 /* First letter must start with i, e or g. */
1666 if (*p != 'e' && *p != 'i' && *p != 'g')
1667 {
1668 rps->error_handler
1669 (_("%s: first ISA extension must be `e', `i' or `g'"),
1670 arch);
1671 return NULL;
1672 }
1673
1674 while (p != NULL && *p != '\0')
1675 {
1676 /* Stop when we parsed the known prefix class. */
1677 enum riscv_prefix_ext_class class = riscv_get_prefix_class (p);
1678 if (class != RV_ISA_CLASS_UNKNOWN)
1679 break;
1680
1681 if (*p == '_')
1682 {
1683 p++;
1684 continue;
1685 }
1686
1687 bool implicit = false;
1688 int major = RISCV_UNKNOWN_VERSION;
1689 int minor = RISCV_UNKNOWN_VERSION;
1690 char subset[2] = {0, 0};
1691
1692 subset[0] = *p;
1693
1694 /* Check if the standard extension is supported. */
1695 if (riscv_ext_order[(subset[0] - 'a')] == 0)
1696 {
1697 rps->error_handler
1698 (_("%s: unknown standard ISA extension `%c'"),
1699 arch, subset[0]);
1700 return NULL;
1701 }
1702
1703 /* Checking canonical order. */
1704 if (rps->subset_list->tail != NULL
1705 && riscv_compare_subsets (rps->subset_list->tail->name, subset) > 0)
1706 {
1707 rps->error_handler
1708 (_("%s: standard ISA extension `%c' is not "
1709 "in canonical order"), arch, subset[0]);
1710 return NULL;
1711 }
1712
1713 p = riscv_parsing_subset_version (++p, &major, &minor);
1714 /* Added g as an implicit extension. */
1715 if (subset[0] == 'g')
1716 {
1717 implicit = true;
1718 major = RISCV_UNKNOWN_VERSION;
1719 minor = RISCV_UNKNOWN_VERSION;
1720 }
1721 riscv_parse_add_subset (rps, subset, major, minor, implicit);
1722 }
1723
1724 return p;
1725 }
1726
1727 /* Parsing function for prefixed extensions.
1728
1729 Return Value:
1730 Points to the end of extension.
1731
1732 Arguments:
1733 `rps`: Hooks and status for parsing extensions.
1734 `arch`: Full ISA string.
1735 `p`: Curent parsing position. */
1736
1737 static const char *
1738 riscv_parse_prefixed_ext (riscv_parse_subset_t *rps,
1739 const char *arch,
1740 const char *p)
1741 {
1742 int major_version;
1743 int minor_version;
1744 const char *last_name;
1745 enum riscv_prefix_ext_class class;
1746
1747 while (*p)
1748 {
1749 if (*p == '_')
1750 {
1751 p++;
1752 continue;
1753 }
1754
1755 class = riscv_get_prefix_class (p);
1756 if (class == RV_ISA_CLASS_UNKNOWN)
1757 {
1758 rps->error_handler
1759 (_("%s: unknown prefix class for the ISA extension `%s'"),
1760 arch, p);
1761 return NULL;
1762 }
1763
1764 char *subset = xstrdup (p);
1765 char *q = subset;
1766 const char *end_of_version;
1767
1768 /* Extract the whole prefixed extension by '_'. */
1769 while (*++q != '\0' && *q != '_')
1770 ;
1771 /* Look forward to the first letter which is not <major>p<minor>. */
1772 bool find_any_version = false;
1773 bool find_minor_version = false;
1774 while (1)
1775 {
1776 q--;
1777 if (ISDIGIT (*q))
1778 find_any_version = true;
1779 else if (find_any_version
1780 && !find_minor_version
1781 && *q == 'p'
1782 && ISDIGIT (*(q - 1)))
1783 find_minor_version = true;
1784 else
1785 break;
1786 }
1787 q++;
1788
1789 /* Check if the end of extension is 'p' or not. If yes, then
1790 the second letter from the end cannot be number. */
1791 if (*(q - 1) == 'p' && ISDIGIT (*(q - 2)))
1792 {
1793 *q = '\0';
1794 rps->error_handler
1795 (_("%s: invalid prefixed ISA extension `%s' ends with <number>p"),
1796 arch, subset);
1797 free (subset);
1798 return NULL;
1799 }
1800
1801 end_of_version =
1802 riscv_parsing_subset_version (q, &major_version, &minor_version);
1803 *q = '\0';
1804 if (end_of_version == NULL)
1805 {
1806 free (subset);
1807 return NULL;
1808 }
1809
1810 /* Check that the extension name is well-formed. */
1811 if (rps->check_unknown_prefixed_ext
1812 && !riscv_recognized_prefixed_ext (subset))
1813 {
1814 rps->error_handler
1815 (_("%s: unknown prefixed ISA extension `%s'"),
1816 arch, subset);
1817 free (subset);
1818 return NULL;
1819 }
1820
1821 /* Check that the extension isn't duplicate. */
1822 last_name = rps->subset_list->tail->name;
1823 if (!strcasecmp (last_name, subset))
1824 {
1825 rps->error_handler
1826 (_("%s: duplicate prefixed ISA extension `%s'"),
1827 arch, subset);
1828 free (subset);
1829 return NULL;
1830 }
1831
1832 /* Check that the extension is in expected order. */
1833 if (riscv_compare_subsets (last_name, subset) > 0)
1834 {
1835 rps->error_handler
1836 (_("%s: prefixed ISA extension `%s' is not in expected "
1837 "order. It must come before `%s'"),
1838 arch, subset, last_name);
1839 free (subset);
1840 return NULL;
1841 }
1842
1843 riscv_parse_add_subset (rps, subset,
1844 major_version,
1845 minor_version, false);
1846 p += end_of_version - subset;
1847 free (subset);
1848
1849 if (*p != '\0' && *p != '_')
1850 {
1851 rps->error_handler
1852 (_("%s: prefixed ISA extension must separate with _"),
1853 arch);
1854 return NULL;
1855 }
1856 }
1857
1858 return p;
1859 }
1860
1861 /* Add the implicit extensions. */
1862
1863 static void
1864 riscv_parse_add_implicit_subsets (riscv_parse_subset_t *rps)
1865 {
1866 struct riscv_implicit_subset *t = riscv_implicit_subsets;
1867 for (; t->subset_name; t++)
1868 {
1869 riscv_subset_t *subset = NULL;
1870 if (riscv_lookup_subset (rps->subset_list, t->subset_name, &subset)
1871 && t->check_func (t->implicit_name, subset))
1872 riscv_parse_add_subset (rps, t->implicit_name,
1873 RISCV_UNKNOWN_VERSION,
1874 RISCV_UNKNOWN_VERSION, true);
1875 }
1876 }
1877
1878 /* Check extensions conflicts. */
1879
1880 static bool
1881 riscv_parse_check_conflicts (riscv_parse_subset_t *rps)
1882 {
1883 riscv_subset_t *subset = NULL;
1884 int xlen = *rps->xlen;
1885 bool no_conflict = true;
1886
1887 if (riscv_lookup_subset (rps->subset_list, "e", &subset)
1888 && xlen > 32)
1889 {
1890 rps->error_handler
1891 (_("rv%d does not support the `e' extension"), xlen);
1892 no_conflict = false;
1893 }
1894 if (riscv_lookup_subset (rps->subset_list, "q", &subset)
1895 && xlen < 64)
1896 {
1897 rps->error_handler
1898 (_("rv%d does not support the `q' extension"), xlen);
1899 no_conflict = false;
1900 }
1901 if (riscv_lookup_subset (rps->subset_list, "e", &subset)
1902 && riscv_lookup_subset (rps->subset_list, "f", &subset))
1903 {
1904 rps->error_handler
1905 (_("rv32e does not support the `f' extension"));
1906 no_conflict = false;
1907 }
1908 if (riscv_lookup_subset (rps->subset_list, "zfinx", &subset)
1909 && riscv_lookup_subset (rps->subset_list, "f", &subset))
1910 {
1911 rps->error_handler
1912 (_("`zfinx' is conflict with the `f/d/q' extension"));
1913 no_conflict = false;
1914 }
1915
1916 bool support_zve = false;
1917 bool support_zvl = false;
1918 riscv_subset_t *s = rps->subset_list->head;
1919 for (; s != NULL; s = s->next)
1920 {
1921 if (!support_zve
1922 && strncmp (s->name, "zve", 3) == 0)
1923 support_zve = true;
1924 if (!support_zvl
1925 && strncmp (s->name, "zvl", 3) == 0)
1926 support_zvl = true;
1927 if (support_zve && support_zvl)
1928 break;
1929 }
1930 if (support_zvl && !support_zve)
1931 {
1932 rps->error_handler
1933 (_("zvl*b extensions need to enable either `v' or `zve' extension"));
1934 no_conflict = false;
1935 }
1936
1937 return no_conflict;
1938 }
1939
1940 /* Set the default subset list according to the default_enable field
1941 of riscv_supported_*ext tables. */
1942
1943 static void
1944 riscv_set_default_arch (riscv_parse_subset_t *rps)
1945 {
1946 unsigned long enable = EXT_DEFAULT;
1947 int i, j;
1948 for (i = 0; riscv_all_supported_ext[i] != NULL; i++)
1949 {
1950 const struct riscv_supported_ext *table = riscv_all_supported_ext[i];
1951 for (j = 0; table[j].name != NULL; j++)
1952 {
1953 bool implicit = false;
1954 if (strcmp (table[j].name, "g") == 0)
1955 implicit = true;
1956 if (table[j].default_enable & enable)
1957 riscv_parse_add_subset (rps, table[j].name,
1958 RISCV_UNKNOWN_VERSION,
1959 RISCV_UNKNOWN_VERSION, implicit);
1960 }
1961 }
1962 }
1963
1964 /* Function for parsing ISA string.
1965
1966 Return Value:
1967 Return TRUE on success.
1968
1969 Arguments:
1970 `rps`: Hooks and status for parsing extensions.
1971 `arch`: Full ISA string. */
1972
1973 bool
1974 riscv_parse_subset (riscv_parse_subset_t *rps,
1975 const char *arch)
1976 {
1977 const char *p;
1978
1979 /* Init the riscv_ext_order array to compare the order of extensions
1980 quickly. */
1981 riscv_init_ext_order ();
1982
1983 if (arch == NULL)
1984 {
1985 riscv_set_default_arch (rps);
1986 riscv_parse_add_implicit_subsets (rps);
1987 return riscv_parse_check_conflicts (rps);
1988 }
1989
1990 for (p = arch; *p != '\0'; p++)
1991 {
1992 if (ISUPPER (*p))
1993 {
1994 rps->error_handler
1995 (_("%s: ISA string cannot contain uppercase letters"),
1996 arch);
1997 return false;
1998 }
1999 }
2000
2001 p = arch;
2002 if (startswith (p, "rv32"))
2003 {
2004 *rps->xlen = 32;
2005 p += 4;
2006 }
2007 else if (startswith (p, "rv64"))
2008 {
2009 *rps->xlen = 64;
2010 p += 4;
2011 }
2012 else
2013 {
2014 /* ISA string shouldn't be NULL or empty here. For linker,
2015 it might be empty when we failed to merge the ISA string
2016 in the riscv_merge_attributes. For assembler, we might
2017 give an empty string by .attribute arch, "" or -march=.
2018 However, We have already issued the correct error message
2019 in another side, so do not issue this error when the ISA
2020 string is empty. */
2021 if (strlen (arch))
2022 rps->error_handler (
2023 _("%s: ISA string must begin with rv32 or rv64"),
2024 arch);
2025 return false;
2026 }
2027
2028 /* Parsing standard extension. */
2029 p = riscv_parse_std_ext (rps, arch, p);
2030
2031 if (p == NULL)
2032 return false;
2033
2034 /* Parse the different classes of extensions in the specified order. */
2035 while (*p != '\0')
2036 {
2037 p = riscv_parse_prefixed_ext (rps, arch, p);
2038
2039 if (p == NULL)
2040 return false;
2041 }
2042
2043 /* Finally add implicit extensions according to the current
2044 extensions. */
2045 riscv_parse_add_implicit_subsets (rps);
2046
2047 /* Check the conflicts. */
2048 return riscv_parse_check_conflicts (rps);
2049 }
2050
2051 /* Return the number of digits for the input. */
2052
2053 size_t
2054 riscv_estimate_digit (unsigned num)
2055 {
2056 size_t digit = 0;
2057 if (num == 0)
2058 return 1;
2059
2060 for (digit = 0; num ; num /= 10)
2061 digit++;
2062
2063 return digit;
2064 }
2065
2066 /* Auxiliary function to estimate string length of subset list. */
2067
2068 static size_t
2069 riscv_estimate_arch_strlen1 (const riscv_subset_t *subset)
2070 {
2071 if (subset == NULL)
2072 return 6; /* For rv32/rv64/rv128 and string terminator. */
2073
2074 return riscv_estimate_arch_strlen1 (subset->next)
2075 + strlen (subset->name)
2076 + riscv_estimate_digit (subset->major_version)
2077 + 1 /* For version seperator 'p'. */
2078 + riscv_estimate_digit (subset->minor_version)
2079 + 1 /* For underscore. */;
2080 }
2081
2082 /* Estimate the string length of this subset list. */
2083
2084 static size_t
2085 riscv_estimate_arch_strlen (const riscv_subset_list_t *subset_list)
2086 {
2087 return riscv_estimate_arch_strlen1 (subset_list->head);
2088 }
2089
2090 /* Auxiliary function to convert subset info to string. */
2091
2092 static void
2093 riscv_arch_str1 (riscv_subset_t *subset,
2094 char *attr_str, char *buf, size_t bufsz)
2095 {
2096 const char *underline = "_";
2097 riscv_subset_t *subset_t = subset;
2098
2099 if (subset_t == NULL)
2100 return;
2101
2102 /* No underline between rvXX and i/e. */
2103 if ((strcasecmp (subset_t->name, "i") == 0)
2104 || (strcasecmp (subset_t->name, "e") == 0))
2105 underline = "";
2106
2107 snprintf (buf, bufsz, "%s%s%dp%d",
2108 underline,
2109 subset_t->name,
2110 subset_t->major_version,
2111 subset_t->minor_version);
2112
2113 strncat (attr_str, buf, bufsz);
2114
2115 /* Skip 'i' extension after 'e', or skip extensions which
2116 versions are unknown. */
2117 while (subset_t->next
2118 && ((strcmp (subset_t->name, "e") == 0
2119 && strcmp (subset_t->next->name, "i") == 0)
2120 || subset_t->next->major_version == RISCV_UNKNOWN_VERSION
2121 || subset_t->next->minor_version == RISCV_UNKNOWN_VERSION))
2122 subset_t = subset_t->next;
2123
2124 riscv_arch_str1 (subset_t->next, attr_str, buf, bufsz);
2125 }
2126
2127 /* Convert subset information into string with explicit versions. */
2128
2129 char *
2130 riscv_arch_str (unsigned xlen, const riscv_subset_list_t *subset)
2131 {
2132 size_t arch_str_len = riscv_estimate_arch_strlen (subset);
2133 char *attr_str = xmalloc (arch_str_len);
2134 char *buf = xmalloc (arch_str_len);
2135
2136 snprintf (attr_str, arch_str_len, "rv%u", xlen);
2137
2138 riscv_arch_str1 (subset->head, attr_str, buf, arch_str_len);
2139 free (buf);
2140
2141 return attr_str;
2142 }
2143
2144 /* Copy the subset in the subset list. */
2145
2146 static struct riscv_subset_t *
2147 riscv_copy_subset (riscv_subset_list_t *subset_list,
2148 riscv_subset_t *subset)
2149 {
2150 if (subset == NULL)
2151 return NULL;
2152
2153 riscv_subset_t *new = xmalloc (sizeof *new);
2154 new->name = xstrdup (subset->name);
2155 new->major_version = subset->major_version;
2156 new->minor_version = subset->minor_version;
2157 new->next = riscv_copy_subset (subset_list, subset->next);
2158
2159 if (subset->next == NULL)
2160 subset_list->tail = new;
2161
2162 return new;
2163 }
2164
2165 /* Copy the subset list. */
2166
2167 riscv_subset_list_t *
2168 riscv_copy_subset_list (riscv_subset_list_t *subset_list)
2169 {
2170 riscv_subset_list_t *new = xmalloc (sizeof *new);
2171 new->head = riscv_copy_subset (new, subset_list->head);
2172 return new;
2173 }
2174
2175 /* Remove the SUBSET from the subset list. */
2176
2177 static void
2178 riscv_remove_subset (riscv_subset_list_t *subset_list,
2179 const char *subset)
2180 {
2181 riscv_subset_t *current = subset_list->head;
2182 riscv_subset_t *pre = NULL;
2183 for (; current != NULL; pre = current, current = current->next)
2184 {
2185 if (strcmp (current->name, subset) == 0)
2186 {
2187 if (pre == NULL)
2188 subset_list->head = current->next;
2189 else
2190 pre->next = current->next;
2191 if (current->next == NULL)
2192 subset_list->tail = pre;
2193 free ((void *) current->name);
2194 free (current);
2195 break;
2196 }
2197 }
2198 }
2199
2200 /* Add/Remove an extension to/from the subset list. This is used for
2201 the .option rvc or norvc, and .option arch directives. */
2202
2203 bool
2204 riscv_update_subset (riscv_parse_subset_t *rps,
2205 const char *str)
2206 {
2207 const char *p = str;
2208
2209 do
2210 {
2211 int major_version = RISCV_UNKNOWN_VERSION;
2212 int minor_version = RISCV_UNKNOWN_VERSION;
2213
2214 bool removed = false;
2215 switch (*p)
2216 {
2217 case '+': removed = false; break;
2218 case '-': removed = true; break;
2219 default:
2220 riscv_release_subset_list (rps->subset_list);
2221 return riscv_parse_subset (rps, p);
2222 }
2223 ++p;
2224
2225 char *subset = xstrdup (p);
2226 char *q = subset;
2227 const char *end_of_version;
2228 /* Extract the whole prefixed extension by ','. */
2229 while (*q != '\0' && *q != ',')
2230 q++;
2231
2232 /* Look forward to the first letter which is not <major>p<minor>. */
2233 bool find_any_version = false;
2234 bool find_minor_version = false;
2235 size_t len = q - subset;
2236 size_t i;
2237 for (i = len; i > 0; i--)
2238 {
2239 q--;
2240 if (ISDIGIT (*q))
2241 find_any_version = true;
2242 else if (find_any_version
2243 && !find_minor_version
2244 && *q == 'p'
2245 && ISDIGIT (*(q - 1)))
2246 find_minor_version = true;
2247 else
2248 break;
2249 }
2250 if (len > 0)
2251 q++;
2252
2253 /* Check if the end of extension is 'p' or not. If yes, then
2254 the second letter from the end cannot be number. */
2255 if (len > 1 && *(q - 1) == 'p' && ISDIGIT (*(q - 2)))
2256 {
2257 *q = '\0';
2258 rps->error_handler
2259 (_("invalid ISA extension ends with <number>p "
2260 "in .option arch `%s'"), str);
2261 free (subset);
2262 return false;
2263 }
2264
2265 end_of_version =
2266 riscv_parsing_subset_version (q, &major_version, &minor_version);
2267 *q = '\0';
2268 if (end_of_version == NULL)
2269 {
2270 free (subset);
2271 return false;
2272 }
2273
2274 if (strlen (subset) == 0
2275 || (strlen (subset) == 1
2276 && riscv_ext_order[(*subset - 'a')] == 0)
2277 || (strlen (subset) > 1
2278 && rps->check_unknown_prefixed_ext
2279 && !riscv_recognized_prefixed_ext (subset)))
2280 {
2281 rps->error_handler
2282 (_("unknown ISA extension `%s' in .option arch `%s'"),
2283 subset, str);
2284 free (subset);
2285 return false;
2286 }
2287
2288 if (strcmp (subset, "i") == 0
2289 || strcmp (subset, "e") == 0
2290 || strcmp (subset, "g") == 0)
2291 {
2292 rps->error_handler
2293 (_("cannot + or - base extension `%s' in .option "
2294 "arch `%s'"), subset, str);
2295 free (subset);
2296 return false;
2297 }
2298
2299 if (removed)
2300 riscv_remove_subset (rps->subset_list, subset);
2301 else
2302 riscv_parse_add_subset (rps, subset, major_version, minor_version, true);
2303 p += end_of_version - subset;
2304 free (subset);
2305 }
2306 while (*p++ == ',');
2307
2308 riscv_parse_add_implicit_subsets (rps);
2309 return riscv_parse_check_conflicts (rps);
2310 }
2311
2312 /* Check if the FEATURE subset is supported or not in the subset list.
2313 Return true if it is supported; Otherwise, return false. */
2314
2315 bool
2316 riscv_subset_supports (riscv_parse_subset_t *rps,
2317 const char *feature)
2318 {
2319 struct riscv_subset_t *subset;
2320 return riscv_lookup_subset (rps->subset_list, feature, &subset);
2321 }
2322
2323 /* Each instuction is belonged to an instruction class INSN_CLASS_*.
2324 Call riscv_subset_supports to make sure if the instuction is valid. */
2325
2326 bool
2327 riscv_multi_subset_supports (riscv_parse_subset_t *rps,
2328 enum riscv_insn_class insn_class)
2329 {
2330 switch (insn_class)
2331 {
2332 case INSN_CLASS_I:
2333 return riscv_subset_supports (rps, "i");
2334 case INSN_CLASS_ZICSR:
2335 return riscv_subset_supports (rps, "zicsr");
2336 case INSN_CLASS_ZIFENCEI:
2337 return riscv_subset_supports (rps, "zifencei");
2338 case INSN_CLASS_ZIHINTPAUSE:
2339 return riscv_subset_supports (rps, "zihintpause");
2340 case INSN_CLASS_M:
2341 return riscv_subset_supports (rps, "m");
2342 case INSN_CLASS_A:
2343 return riscv_subset_supports (rps, "a");
2344 case INSN_CLASS_F:
2345 return riscv_subset_supports (rps, "f");
2346 case INSN_CLASS_D:
2347 return riscv_subset_supports (rps, "d");
2348 case INSN_CLASS_Q:
2349 return riscv_subset_supports (rps, "q");
2350 case INSN_CLASS_C:
2351 return riscv_subset_supports (rps, "c");
2352 case INSN_CLASS_F_AND_C:
2353 return (riscv_subset_supports (rps, "f")
2354 && riscv_subset_supports (rps, "c"));
2355 case INSN_CLASS_D_AND_C:
2356 return (riscv_subset_supports (rps, "d")
2357 && riscv_subset_supports (rps, "c"));
2358 case INSN_CLASS_F_OR_ZFINX:
2359 return (riscv_subset_supports (rps, "f")
2360 || riscv_subset_supports (rps, "zfinx"));
2361 case INSN_CLASS_D_OR_ZDINX:
2362 return (riscv_subset_supports (rps, "d")
2363 || riscv_subset_supports (rps, "zdinx"));
2364 case INSN_CLASS_Q_OR_ZQINX:
2365 return (riscv_subset_supports (rps, "q")
2366 || riscv_subset_supports (rps, "zqinx"));
2367 case INSN_CLASS_ZBA:
2368 return riscv_subset_supports (rps, "zba");
2369 case INSN_CLASS_ZBB:
2370 return riscv_subset_supports (rps, "zbb");
2371 case INSN_CLASS_ZBC:
2372 return riscv_subset_supports (rps, "zbc");
2373 case INSN_CLASS_ZBS:
2374 return riscv_subset_supports (rps, "zbs");
2375 case INSN_CLASS_ZBKB:
2376 return riscv_subset_supports (rps, "zbkb");
2377 case INSN_CLASS_ZBKC:
2378 return riscv_subset_supports (rps, "zbkc");
2379 case INSN_CLASS_ZBKX:
2380 return riscv_subset_supports (rps, "zbkx");
2381 case INSN_CLASS_ZBB_OR_ZBKB:
2382 return (riscv_subset_supports (rps, "zbb")
2383 || riscv_subset_supports (rps, "zbkb"));
2384 case INSN_CLASS_ZBC_OR_ZBKC:
2385 return (riscv_subset_supports (rps, "zbc")
2386 || riscv_subset_supports (rps, "zbkc"));
2387 case INSN_CLASS_ZKND:
2388 return riscv_subset_supports (rps, "zknd");
2389 case INSN_CLASS_ZKNE:
2390 return riscv_subset_supports (rps, "zkne");
2391 case INSN_CLASS_ZKNH:
2392 return riscv_subset_supports (rps, "zknh");
2393 case INSN_CLASS_ZKND_OR_ZKNE:
2394 return (riscv_subset_supports (rps, "zknd")
2395 || riscv_subset_supports (rps, "zkne"));
2396 case INSN_CLASS_ZKSED:
2397 return riscv_subset_supports (rps, "zksed");
2398 case INSN_CLASS_ZKSH:
2399 return riscv_subset_supports (rps, "zksh");
2400 case INSN_CLASS_V:
2401 return (riscv_subset_supports (rps, "v")
2402 || riscv_subset_supports (rps, "zve64x")
2403 || riscv_subset_supports (rps, "zve32x"));
2404 case INSN_CLASS_ZVEF:
2405 return (riscv_subset_supports (rps, "v")
2406 || riscv_subset_supports (rps, "zve64d")
2407 || riscv_subset_supports (rps, "zve64f")
2408 || riscv_subset_supports (rps, "zve32f"));
2409 case INSN_CLASS_SVINVAL:
2410 return riscv_subset_supports (rps, "svinval");
2411 default:
2412 rps->error_handler
2413 (_("internal: unreachable INSN_CLASS_*"));
2414 return false;
2415 }
2416 }