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