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