ada-tasks.c::read_atcb: start from a cleared ada_task_info result
[external/binutils.git] / bfd / elfxx-riscv.c
1 /* RISC-V-specific support for ELF.
2    Copyright (C) 2011-2018 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 <stdint.h>
32
33 #define MINUS_ONE ((bfd_vma)0 - 1)
34
35 /* Special handler for ADD/SUB relocations that allows them to be filled out
36    both in the pre-linked and post-linked file.  This is necessary to make
37    pre-linked debug info work, as due to linker relaxations we need to emit
38    relocations for the debug info.  */
39 static bfd_reloc_status_type riscv_elf_add_sub_reloc
40   (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
41
42 /* The relocation table used for SHT_RELA sections.  */
43
44 static reloc_howto_type howto_table[] =
45 {
46   /* No relocation.  */
47   HOWTO (R_RISCV_NONE,                  /* type */
48          0,                             /* rightshift */
49          3,                             /* size */
50          0,                             /* bitsize */
51          FALSE,                         /* pc_relative */
52          0,                             /* bitpos */
53          complain_overflow_dont,        /* complain_on_overflow */
54          bfd_elf_generic_reloc,         /* special_function */
55          "R_RISCV_NONE",                /* name */
56          FALSE,                         /* partial_inplace */
57          0,                             /* src_mask */
58          0,                             /* dst_mask */
59          FALSE),                        /* pcrel_offset */
60
61   /* 32 bit relocation.  */
62   HOWTO (R_RISCV_32,                    /* type */
63          0,                             /* rightshift */
64          2,                             /* size */
65          32,                            /* bitsize */
66          FALSE,                         /* pc_relative */
67          0,                             /* bitpos */
68          complain_overflow_dont,        /* complain_on_overflow */
69          bfd_elf_generic_reloc,         /* special_function */
70          "R_RISCV_32",                  /* name */
71          FALSE,                         /* partial_inplace */
72          0,                             /* src_mask */
73          MINUS_ONE,                     /* dst_mask */
74          FALSE),                        /* pcrel_offset */
75
76   /* 64 bit relocation.  */
77   HOWTO (R_RISCV_64,                    /* type */
78          0,                             /* rightshift */
79          4,                             /* size */
80          64,                            /* bitsize */
81          FALSE,                         /* pc_relative */
82          0,                             /* bitpos */
83          complain_overflow_dont,        /* complain_on_overflow */
84          bfd_elf_generic_reloc,         /* special_function */
85          "R_RISCV_64",                  /* name */
86          FALSE,                         /* partial_inplace */
87          0,                             /* src_mask */
88          MINUS_ONE,                     /* dst_mask */
89          FALSE),                        /* pcrel_offset */
90
91   /* Relocation against a local symbol in a shared object.  */
92   HOWTO (R_RISCV_RELATIVE,              /* type */
93          0,                             /* rightshift */
94          2,                             /* size */
95          32,                            /* bitsize */
96          FALSE,                         /* pc_relative */
97          0,                             /* bitpos */
98          complain_overflow_dont,        /* complain_on_overflow */
99          bfd_elf_generic_reloc,         /* special_function */
100          "R_RISCV_RELATIVE",            /* name */
101          FALSE,                         /* partial_inplace */
102          0,                             /* src_mask */
103          MINUS_ONE,                     /* dst_mask */
104          FALSE),                        /* pcrel_offset */
105
106   HOWTO (R_RISCV_COPY,                  /* type */
107          0,                             /* rightshift */
108          0,                             /* this one is variable size */
109          0,                             /* bitsize */
110          FALSE,                         /* pc_relative */
111          0,                             /* bitpos */
112          complain_overflow_bitfield,    /* complain_on_overflow */
113          bfd_elf_generic_reloc,         /* special_function */
114          "R_RISCV_COPY",                /* name */
115          FALSE,                         /* partial_inplace */
116          0,                             /* src_mask */
117          0,                             /* dst_mask */
118          FALSE),                        /* pcrel_offset */
119
120   HOWTO (R_RISCV_JUMP_SLOT,             /* type */
121          0,                             /* rightshift */
122          4,                             /* size */
123          64,                            /* bitsize */
124          FALSE,                         /* pc_relative */
125          0,                             /* bitpos */
126          complain_overflow_bitfield,    /* complain_on_overflow */
127          bfd_elf_generic_reloc,         /* special_function */
128          "R_RISCV_JUMP_SLOT",           /* name */
129          FALSE,                         /* partial_inplace */
130          0,                             /* src_mask */
131          0,                             /* dst_mask */
132          FALSE),                        /* pcrel_offset */
133
134   /* Dynamic TLS relocations.  */
135   HOWTO (R_RISCV_TLS_DTPMOD32,          /* type */
136          0,                             /* rightshift */
137          4,                             /* size */
138          32,                            /* bitsize */
139          FALSE,                         /* pc_relative */
140          0,                             /* bitpos */
141          complain_overflow_dont,        /* complain_on_overflow */
142          bfd_elf_generic_reloc,         /* special_function */
143          "R_RISCV_TLS_DTPMOD32",        /* name */
144          FALSE,                         /* partial_inplace */
145          0,                             /* src_mask */
146          MINUS_ONE,                     /* dst_mask */
147          FALSE),                        /* pcrel_offset */
148
149   HOWTO (R_RISCV_TLS_DTPMOD64,          /* type */
150          0,                             /* rightshift */
151          4,                             /* size */
152          64,                            /* bitsize */
153          FALSE,                         /* pc_relative */
154          0,                             /* bitpos */
155          complain_overflow_dont,        /* complain_on_overflow */
156          bfd_elf_generic_reloc,         /* special_function */
157          "R_RISCV_TLS_DTPMOD64",        /* name */
158          FALSE,                         /* partial_inplace */
159          0,                             /* src_mask */
160          MINUS_ONE,                     /* dst_mask */
161          FALSE),                        /* pcrel_offset */
162
163   HOWTO (R_RISCV_TLS_DTPREL32,          /* type */
164          0,                             /* rightshift */
165          4,                             /* size */
166          32,                            /* bitsize */
167          FALSE,                         /* pc_relative */
168          0,                             /* bitpos */
169          complain_overflow_dont,        /* complain_on_overflow */
170          bfd_elf_generic_reloc,         /* special_function */
171          "R_RISCV_TLS_DTPREL32",        /* name */
172          TRUE,                          /* partial_inplace */
173          0,                             /* src_mask */
174          MINUS_ONE,                     /* dst_mask */
175          FALSE),                        /* pcrel_offset */
176
177   HOWTO (R_RISCV_TLS_DTPREL64,          /* type */
178          0,                             /* rightshift */
179          4,                             /* size */
180          64,                            /* bitsize */
181          FALSE,                         /* pc_relative */
182          0,                             /* bitpos */
183          complain_overflow_dont,        /* complain_on_overflow */
184          bfd_elf_generic_reloc,         /* special_function */
185          "R_RISCV_TLS_DTPREL64",        /* name */
186          TRUE,                          /* partial_inplace */
187          0,                             /* src_mask */
188          MINUS_ONE,                     /* dst_mask */
189          FALSE),                        /* pcrel_offset */
190
191   HOWTO (R_RISCV_TLS_TPREL32,           /* type */
192          0,                             /* rightshift */
193          2,                             /* size */
194          32,                            /* bitsize */
195          FALSE,                         /* pc_relative */
196          0,                             /* bitpos */
197          complain_overflow_dont,        /* complain_on_overflow */
198          bfd_elf_generic_reloc,         /* special_function */
199          "R_RISCV_TLS_TPREL32",         /* name */
200          FALSE,                         /* partial_inplace */
201          0,                             /* src_mask */
202          MINUS_ONE,                     /* dst_mask */
203          FALSE),                        /* pcrel_offset */
204
205   HOWTO (R_RISCV_TLS_TPREL64,           /* type */
206          0,                             /* rightshift */
207          4,                             /* size */
208          64,                            /* bitsize */
209          FALSE,                         /* pc_relative */
210          0,                             /* bitpos */
211          complain_overflow_dont,        /* complain_on_overflow */
212          bfd_elf_generic_reloc,         /* special_function */
213          "R_RISCV_TLS_TPREL64",         /* name */
214          FALSE,                         /* partial_inplace */
215          0,                             /* src_mask */
216          MINUS_ONE,                     /* dst_mask */
217          FALSE),                        /* pcrel_offset */
218
219   /* Reserved for future relocs that the dynamic linker must understand.  */
220   EMPTY_HOWTO (12),
221   EMPTY_HOWTO (13),
222   EMPTY_HOWTO (14),
223   EMPTY_HOWTO (15),
224
225   /* 12-bit PC-relative branch offset.  */
226   HOWTO (R_RISCV_BRANCH,                /* type */
227          0,                             /* rightshift */
228          2,                             /* size */
229          32,                            /* bitsize */
230          TRUE,                          /* pc_relative */
231          0,                             /* bitpos */
232          complain_overflow_signed,      /* complain_on_overflow */
233          bfd_elf_generic_reloc,         /* special_function */
234          "R_RISCV_BRANCH",              /* name */
235          FALSE,                         /* partial_inplace */
236          0,                             /* src_mask */
237          ENCODE_SBTYPE_IMM (-1U),       /* dst_mask */
238          TRUE),                         /* pcrel_offset */
239
240   /* 20-bit PC-relative jump offset.  */
241   HOWTO (R_RISCV_JAL,                   /* type */
242          0,                             /* rightshift */
243          2,                             /* size */
244          32,                            /* bitsize */
245          TRUE,                          /* pc_relative */
246          0,                             /* bitpos */
247          complain_overflow_dont,        /* complain_on_overflow */
248          bfd_elf_generic_reloc,         /* special_function */
249          "R_RISCV_JAL",                 /* name */
250          FALSE,                         /* partial_inplace */
251          0,                             /* src_mask */
252          ENCODE_UJTYPE_IMM (-1U),       /* dst_mask */
253          TRUE),                         /* pcrel_offset */
254
255   /* 32-bit PC-relative function call (AUIPC/JALR).  */
256   HOWTO (R_RISCV_CALL,                  /* type */
257          0,                             /* rightshift */
258          2,                             /* size */
259          64,                            /* bitsize */
260          TRUE,                          /* pc_relative */
261          0,                             /* bitpos */
262          complain_overflow_dont,        /* complain_on_overflow */
263          bfd_elf_generic_reloc,         /* special_function */
264          "R_RISCV_CALL",                /* name */
265          FALSE,                         /* partial_inplace */
266          0,                             /* src_mask */
267          ENCODE_UTYPE_IMM (-1U) | ((bfd_vma) ENCODE_ITYPE_IMM (-1U) << 32),
268                                         /* dst_mask */
269          TRUE),                         /* pcrel_offset */
270
271   /* Like R_RISCV_CALL, but not locally binding.  */
272   HOWTO (R_RISCV_CALL_PLT,              /* type */
273          0,                             /* rightshift */
274          2,                             /* size */
275          64,                            /* bitsize */
276          TRUE,                          /* pc_relative */
277          0,                             /* bitpos */
278          complain_overflow_dont,        /* complain_on_overflow */
279          bfd_elf_generic_reloc,         /* special_function */
280          "R_RISCV_CALL_PLT",            /* name */
281          FALSE,                         /* partial_inplace */
282          0,                             /* src_mask */
283          ENCODE_UTYPE_IMM (-1U) | ((bfd_vma) ENCODE_ITYPE_IMM (-1U) << 32),
284                                         /* dst_mask */
285          TRUE),                         /* pcrel_offset */
286
287   /* High 20 bits of 32-bit PC-relative GOT access.  */
288   HOWTO (R_RISCV_GOT_HI20,              /* type */
289          0,                             /* rightshift */
290          2,                             /* size */
291          32,                            /* bitsize */
292          TRUE,                          /* pc_relative */
293          0,                             /* bitpos */
294          complain_overflow_dont,        /* complain_on_overflow */
295          bfd_elf_generic_reloc,         /* special_function */
296          "R_RISCV_GOT_HI20",            /* name */
297          FALSE,                         /* partial_inplace */
298          0,                             /* src_mask */
299          ENCODE_UTYPE_IMM (-1U),        /* dst_mask */
300          FALSE),                        /* pcrel_offset */
301
302   /* High 20 bits of 32-bit PC-relative TLS IE GOT access.  */
303   HOWTO (R_RISCV_TLS_GOT_HI20,          /* type */
304          0,                             /* rightshift */
305          2,                             /* size */
306          32,                            /* bitsize */
307          TRUE,                          /* pc_relative */
308          0,                             /* bitpos */
309          complain_overflow_dont,        /* complain_on_overflow */
310          bfd_elf_generic_reloc,         /* special_function */
311          "R_RISCV_TLS_GOT_HI20",        /* name */
312          FALSE,                         /* partial_inplace */
313          0,                             /* src_mask */
314          ENCODE_UTYPE_IMM (-1U),        /* dst_mask */
315          FALSE),                        /* pcrel_offset */
316
317   /* High 20 bits of 32-bit PC-relative TLS GD GOT reference.  */
318   HOWTO (R_RISCV_TLS_GD_HI20,           /* type */
319          0,                             /* rightshift */
320          2,                             /* size */
321          32,                            /* bitsize */
322          TRUE,                          /* pc_relative */
323          0,                             /* bitpos */
324          complain_overflow_dont,        /* complain_on_overflow */
325          bfd_elf_generic_reloc,         /* special_function */
326          "R_RISCV_TLS_GD_HI20",         /* name */
327          FALSE,                         /* partial_inplace */
328          0,                             /* src_mask */
329          ENCODE_UTYPE_IMM (-1U),        /* dst_mask */
330          FALSE),                        /* pcrel_offset */
331
332   /* High 20 bits of 32-bit PC-relative reference.  */
333   HOWTO (R_RISCV_PCREL_HI20,            /* type */
334          0,                             /* rightshift */
335          2,                             /* size */
336          32,                            /* bitsize */
337          TRUE,                          /* pc_relative */
338          0,                             /* bitpos */
339          complain_overflow_dont,        /* complain_on_overflow */
340          bfd_elf_generic_reloc,         /* special_function */
341          "R_RISCV_PCREL_HI20",          /* name */
342          FALSE,                         /* partial_inplace */
343          0,                             /* src_mask */
344          ENCODE_UTYPE_IMM (-1U),        /* dst_mask */
345          TRUE),                         /* pcrel_offset */
346
347   /* Low 12 bits of a 32-bit PC-relative load or add.  */
348   HOWTO (R_RISCV_PCREL_LO12_I,          /* type */
349          0,                             /* rightshift */
350          2,                             /* size */
351          32,                            /* bitsize */
352          FALSE,                         /* pc_relative */
353          0,                             /* bitpos */
354          complain_overflow_dont,        /* complain_on_overflow */
355          bfd_elf_generic_reloc,         /* special_function */
356          "R_RISCV_PCREL_LO12_I",        /* name */
357          FALSE,                         /* partial_inplace */
358          0,                             /* src_mask */
359          ENCODE_ITYPE_IMM (-1U),        /* dst_mask */
360          FALSE),                        /* pcrel_offset */
361
362   /* Low 12 bits of a 32-bit PC-relative store.  */
363   HOWTO (R_RISCV_PCREL_LO12_S,          /* type */
364          0,                             /* rightshift */
365          2,                             /* size */
366          32,                            /* bitsize */
367          FALSE,                         /* pc_relative */
368          0,                             /* bitpos */
369          complain_overflow_dont,        /* complain_on_overflow */
370          bfd_elf_generic_reloc,         /* special_function */
371          "R_RISCV_PCREL_LO12_S",        /* name */
372          FALSE,                         /* partial_inplace */
373          0,                             /* src_mask */
374          ENCODE_STYPE_IMM (-1U),        /* dst_mask */
375          FALSE),                        /* pcrel_offset */
376
377   /* High 20 bits of 32-bit absolute address.  */
378   HOWTO (R_RISCV_HI20,                  /* type */
379          0,                             /* rightshift */
380          2,                             /* size */
381          32,                            /* bitsize */
382          FALSE,                         /* pc_relative */
383          0,                             /* bitpos */
384          complain_overflow_dont,        /* complain_on_overflow */
385          bfd_elf_generic_reloc,         /* special_function */
386          "R_RISCV_HI20",                /* name */
387          FALSE,                         /* partial_inplace */
388          0,                             /* src_mask */
389          ENCODE_UTYPE_IMM (-1U),        /* dst_mask */
390          FALSE),                        /* pcrel_offset */
391
392   /* High 12 bits of 32-bit load or add.  */
393   HOWTO (R_RISCV_LO12_I,                /* type */
394          0,                             /* rightshift */
395          2,                             /* size */
396          32,                            /* bitsize */
397          FALSE,                         /* pc_relative */
398          0,                             /* bitpos */
399          complain_overflow_dont,        /* complain_on_overflow */
400          bfd_elf_generic_reloc,         /* special_function */
401          "R_RISCV_LO12_I",              /* name */
402          FALSE,                         /* partial_inplace */
403          0,                             /* src_mask */
404          ENCODE_ITYPE_IMM (-1U),        /* dst_mask */
405          FALSE),                        /* pcrel_offset */
406
407   /* High 12 bits of 32-bit store.  */
408   HOWTO (R_RISCV_LO12_S,                /* type */
409          0,                             /* rightshift */
410          2,                             /* size */
411          32,                            /* bitsize */
412          FALSE,                         /* pc_relative */
413          0,                             /* bitpos */
414          complain_overflow_dont,        /* complain_on_overflow */
415          bfd_elf_generic_reloc,         /* special_function */
416          "R_RISCV_LO12_S",              /* name */
417          FALSE,                         /* partial_inplace */
418          0,                             /* src_mask */
419          ENCODE_STYPE_IMM (-1U),        /* dst_mask */
420          FALSE),                        /* pcrel_offset */
421
422   /* High 20 bits of TLS LE thread pointer offset.  */
423   HOWTO (R_RISCV_TPREL_HI20,            /* type */
424          0,                             /* rightshift */
425          2,                             /* size */
426          32,                            /* bitsize */
427          FALSE,                         /* pc_relative */
428          0,                             /* bitpos */
429          complain_overflow_signed,      /* complain_on_overflow */
430          bfd_elf_generic_reloc,         /* special_function */
431          "R_RISCV_TPREL_HI20",          /* name */
432          TRUE,                          /* partial_inplace */
433          0,                             /* src_mask */
434          ENCODE_UTYPE_IMM (-1U),        /* dst_mask */
435          FALSE),                        /* pcrel_offset */
436
437   /* Low 12 bits of TLS LE thread pointer offset for loads and adds.  */
438   HOWTO (R_RISCV_TPREL_LO12_I,          /* type */
439          0,                             /* rightshift */
440          2,                             /* size */
441          32,                            /* bitsize */
442          FALSE,                         /* pc_relative */
443          0,                             /* bitpos */
444          complain_overflow_signed,      /* complain_on_overflow */
445          bfd_elf_generic_reloc,         /* special_function */
446          "R_RISCV_TPREL_LO12_I",        /* name */
447          FALSE,                         /* partial_inplace */
448          0,                             /* src_mask */
449          ENCODE_ITYPE_IMM (-1U),        /* dst_mask */
450          FALSE),                        /* pcrel_offset */
451
452   /* Low 12 bits of TLS LE thread pointer offset for stores.  */
453   HOWTO (R_RISCV_TPREL_LO12_S,          /* type */
454          0,                             /* rightshift */
455          2,                             /* size */
456          32,                            /* bitsize */
457          FALSE,                         /* pc_relative */
458          0,                             /* bitpos */
459          complain_overflow_signed,      /* complain_on_overflow */
460          bfd_elf_generic_reloc,         /* special_function */
461          "R_RISCV_TPREL_LO12_S",        /* name */
462          FALSE,                         /* partial_inplace */
463          0,                             /* src_mask */
464          ENCODE_STYPE_IMM (-1U),        /* dst_mask */
465          FALSE),                        /* pcrel_offset */
466
467   /* TLS LE thread pointer usage.  May be relaxed.  */
468   HOWTO (R_RISCV_TPREL_ADD,             /* type */
469          0,                             /* rightshift */
470          2,                             /* size */
471          32,                            /* bitsize */
472          FALSE,                         /* pc_relative */
473          0,                             /* bitpos */
474          complain_overflow_dont,        /* complain_on_overflow */
475          bfd_elf_generic_reloc,         /* special_function */
476          "R_RISCV_TPREL_ADD",           /* name */
477          TRUE,                          /* partial_inplace */
478          0,                             /* src_mask */
479          0,                             /* dst_mask */
480          FALSE),                        /* pcrel_offset */
481
482   /* 8-bit in-place addition, for local label subtraction.  */
483   HOWTO (R_RISCV_ADD8,                  /* type */
484          0,                             /* rightshift */
485          0,                             /* size */
486          8,                             /* bitsize */
487          FALSE,                         /* pc_relative */
488          0,                             /* bitpos */
489          complain_overflow_dont,        /* complain_on_overflow */
490          riscv_elf_add_sub_reloc,       /* special_function */
491          "R_RISCV_ADD8",                /* name */
492          FALSE,                         /* partial_inplace */
493          0,                             /* src_mask */
494          MINUS_ONE,                     /* dst_mask */
495          FALSE),                        /* pcrel_offset */
496
497   /* 16-bit in-place addition, for local label subtraction.  */
498   HOWTO (R_RISCV_ADD16,                 /* type */
499          0,                             /* rightshift */
500          1,                             /* size */
501          16,                            /* bitsize */
502          FALSE,                         /* pc_relative */
503          0,                             /* bitpos */
504          complain_overflow_dont,        /* complain_on_overflow */
505          riscv_elf_add_sub_reloc,       /* special_function */
506          "R_RISCV_ADD16",               /* name */
507          FALSE,                         /* partial_inplace */
508          0,                             /* src_mask */
509          MINUS_ONE,                     /* dst_mask */
510          FALSE),                        /* pcrel_offset */
511
512   /* 32-bit in-place addition, for local label subtraction.  */
513   HOWTO (R_RISCV_ADD32,                 /* type */
514          0,                             /* rightshift */
515          2,                             /* size */
516          32,                            /* bitsize */
517          FALSE,                         /* pc_relative */
518          0,                             /* bitpos */
519          complain_overflow_dont,        /* complain_on_overflow */
520          riscv_elf_add_sub_reloc,       /* special_function */
521          "R_RISCV_ADD32",               /* name */
522          FALSE,                         /* partial_inplace */
523          0,                             /* src_mask */
524          MINUS_ONE,                     /* dst_mask */
525          FALSE),                        /* pcrel_offset */
526
527   /* 64-bit in-place addition, for local label subtraction.  */
528   HOWTO (R_RISCV_ADD64,                 /* type */
529          0,                             /* rightshift */
530          4,                             /* size */
531          64,                            /* bitsize */
532          FALSE,                         /* pc_relative */
533          0,                             /* bitpos */
534          complain_overflow_dont,        /* complain_on_overflow */
535          riscv_elf_add_sub_reloc,       /* special_function */
536          "R_RISCV_ADD64",               /* name */
537          FALSE,                         /* partial_inplace */
538          0,                             /* src_mask */
539          MINUS_ONE,                     /* dst_mask */
540          FALSE),                        /* pcrel_offset */
541
542   /* 8-bit in-place addition, for local label subtraction.  */
543   HOWTO (R_RISCV_SUB8,                  /* type */
544          0,                             /* rightshift */
545          0,                             /* size */
546          8,                             /* bitsize */
547          FALSE,                         /* pc_relative */
548          0,                             /* bitpos */
549          complain_overflow_dont,        /* complain_on_overflow */
550          riscv_elf_add_sub_reloc,       /* special_function */
551          "R_RISCV_SUB8",                /* name */
552          FALSE,                         /* partial_inplace */
553          0,                             /* src_mask */
554          MINUS_ONE,                     /* dst_mask */
555          FALSE),                        /* pcrel_offset */
556
557   /* 16-bit in-place addition, for local label subtraction.  */
558   HOWTO (R_RISCV_SUB16,                 /* type */
559          0,                             /* rightshift */
560          1,                             /* size */
561          16,                            /* bitsize */
562          FALSE,                         /* pc_relative */
563          0,                             /* bitpos */
564          complain_overflow_dont,        /* complain_on_overflow */
565          riscv_elf_add_sub_reloc,       /* special_function */
566          "R_RISCV_SUB16",               /* name */
567          FALSE,                         /* partial_inplace */
568          0,                             /* src_mask */
569          MINUS_ONE,                     /* dst_mask */
570          FALSE),                        /* pcrel_offset */
571
572   /* 32-bit in-place addition, for local label subtraction.  */
573   HOWTO (R_RISCV_SUB32,                 /* type */
574          0,                             /* rightshift */
575          2,                             /* size */
576          32,                            /* bitsize */
577          FALSE,                         /* pc_relative */
578          0,                             /* bitpos */
579          complain_overflow_dont,        /* complain_on_overflow */
580          riscv_elf_add_sub_reloc,       /* special_function */
581          "R_RISCV_SUB32",               /* name */
582          FALSE,                         /* partial_inplace */
583          0,                             /* src_mask */
584          MINUS_ONE,                     /* dst_mask */
585          FALSE),                        /* pcrel_offset */
586
587   /* 64-bit in-place addition, for local label subtraction.  */
588   HOWTO (R_RISCV_SUB64,                 /* type */
589          0,                             /* rightshift */
590          4,                             /* size */
591          64,                            /* bitsize */
592          FALSE,                         /* pc_relative */
593          0,                             /* bitpos */
594          complain_overflow_dont,        /* complain_on_overflow */
595          riscv_elf_add_sub_reloc,       /* special_function */
596          "R_RISCV_SUB64",               /* name */
597          FALSE,                         /* partial_inplace */
598          0,                             /* src_mask */
599          MINUS_ONE,                     /* dst_mask */
600          FALSE),                        /* pcrel_offset */
601
602   /* GNU extension to record C++ vtable hierarchy */
603   HOWTO (R_RISCV_GNU_VTINHERIT,         /* type */
604          0,                             /* rightshift */
605          4,                             /* size */
606          0,                             /* bitsize */
607          FALSE,                         /* pc_relative */
608          0,                             /* bitpos */
609          complain_overflow_dont,        /* complain_on_overflow */
610          NULL,                          /* special_function */
611          "R_RISCV_GNU_VTINHERIT",       /* name */
612          FALSE,                         /* partial_inplace */
613          0,                             /* src_mask */
614          0,                             /* dst_mask */
615          FALSE),                        /* pcrel_offset */
616
617   /* GNU extension to record C++ vtable member usage */
618   HOWTO (R_RISCV_GNU_VTENTRY,           /* type */
619          0,                             /* rightshift */
620          4,                             /* size */
621          0,                             /* bitsize */
622          FALSE,                         /* pc_relative */
623          0,                             /* bitpos */
624          complain_overflow_dont,        /* complain_on_overflow */
625          _bfd_elf_rel_vtable_reloc_fn,  /* special_function */
626          "R_RISCV_GNU_VTENTRY",         /* name */
627          FALSE,                         /* partial_inplace */
628          0,                             /* src_mask */
629          0,                             /* dst_mask */
630          FALSE),                        /* pcrel_offset */
631
632   /* Indicates an alignment statement.  The addend field encodes how many
633      bytes of NOPs follow the statement.  The desired alignment is the
634      addend rounded up to the next power of two.  */
635   HOWTO (R_RISCV_ALIGN,                 /* type */
636          0,                             /* rightshift */
637          2,                             /* size */
638          0,                             /* bitsize */
639          FALSE,                         /* pc_relative */
640          0,                             /* bitpos */
641          complain_overflow_dont,        /* complain_on_overflow */
642          bfd_elf_generic_reloc,         /* special_function */
643          "R_RISCV_ALIGN",               /* name */
644          FALSE,                         /* partial_inplace */
645          0,                             /* src_mask */
646          0,                             /* dst_mask */
647          TRUE),                         /* pcrel_offset */
648
649   /* 8-bit PC-relative branch offset.  */
650   HOWTO (R_RISCV_RVC_BRANCH,            /* type */
651          0,                             /* rightshift */
652          2,                             /* size */
653          32,                            /* bitsize */
654          TRUE,                          /* pc_relative */
655          0,                             /* bitpos */
656          complain_overflow_signed,      /* complain_on_overflow */
657          bfd_elf_generic_reloc,         /* special_function */
658          "R_RISCV_RVC_BRANCH",          /* name */
659          FALSE,                         /* partial_inplace */
660          0,                             /* src_mask */
661          ENCODE_RVC_B_IMM (-1U),        /* dst_mask */
662          TRUE),                         /* pcrel_offset */
663
664   /* 11-bit PC-relative jump offset.  */
665   HOWTO (R_RISCV_RVC_JUMP,              /* type */
666          0,                             /* rightshift */
667          2,                             /* size */
668          32,                            /* bitsize */
669          TRUE,                          /* pc_relative */
670          0,                             /* bitpos */
671          complain_overflow_dont,        /* complain_on_overflow */
672          bfd_elf_generic_reloc,         /* special_function */
673          "R_RISCV_RVC_JUMP",            /* name */
674          FALSE,                         /* partial_inplace */
675          0,                             /* src_mask */
676          ENCODE_RVC_J_IMM (-1U),        /* dst_mask */
677          TRUE),                         /* pcrel_offset */
678
679   /* High 6 bits of 18-bit absolute address.  */
680   HOWTO (R_RISCV_RVC_LUI,               /* type */
681          0,                             /* rightshift */
682          2,                             /* size */
683          32,                            /* bitsize */
684          FALSE,                         /* pc_relative */
685          0,                             /* bitpos */
686          complain_overflow_dont,        /* complain_on_overflow */
687          bfd_elf_generic_reloc,         /* special_function */
688          "R_RISCV_RVC_LUI",             /* name */
689          FALSE,                         /* partial_inplace */
690          0,                             /* src_mask */
691          ENCODE_RVC_IMM (-1U),          /* dst_mask */
692          FALSE),                        /* pcrel_offset */
693
694   /* GP-relative load.  */
695   HOWTO (R_RISCV_GPREL_I,               /* type */
696          0,                             /* rightshift */
697          2,                             /* size */
698          32,                            /* bitsize */
699          FALSE,                         /* pc_relative */
700          0,                             /* bitpos */
701          complain_overflow_dont,        /* complain_on_overflow */
702          bfd_elf_generic_reloc,         /* special_function */
703          "R_RISCV_GPREL_I",             /* name */
704          FALSE,                         /* partial_inplace */
705          0,                             /* src_mask */
706          ENCODE_ITYPE_IMM (-1U),        /* dst_mask */
707          FALSE),                        /* pcrel_offset */
708
709   /* GP-relative store.  */
710   HOWTO (R_RISCV_GPREL_S,               /* type */
711          0,                             /* rightshift */
712          2,                             /* size */
713          32,                            /* bitsize */
714          FALSE,                         /* pc_relative */
715          0,                             /* bitpos */
716          complain_overflow_dont,        /* complain_on_overflow */
717          bfd_elf_generic_reloc,         /* special_function */
718          "R_RISCV_GPREL_S",             /* name */
719          FALSE,                         /* partial_inplace */
720          0,                             /* src_mask */
721          ENCODE_STYPE_IMM (-1U),        /* dst_mask */
722          FALSE),                        /* pcrel_offset */
723
724   /* TP-relative TLS LE load.  */
725   HOWTO (R_RISCV_TPREL_I,               /* type */
726          0,                             /* rightshift */
727          2,                             /* size */
728          32,                            /* bitsize */
729          FALSE,                         /* pc_relative */
730          0,                             /* bitpos */
731          complain_overflow_signed,      /* complain_on_overflow */
732          bfd_elf_generic_reloc,         /* special_function */
733          "R_RISCV_TPREL_I",             /* name */
734          FALSE,                         /* partial_inplace */
735          0,                             /* src_mask */
736          ENCODE_ITYPE_IMM (-1U),        /* dst_mask */
737          FALSE),                        /* pcrel_offset */
738
739   /* TP-relative TLS LE store.  */
740   HOWTO (R_RISCV_TPREL_S,               /* type */
741          0,                             /* rightshift */
742          2,                             /* size */
743          32,                            /* bitsize */
744          FALSE,                         /* pc_relative */
745          0,                             /* bitpos */
746          complain_overflow_signed,      /* complain_on_overflow */
747          bfd_elf_generic_reloc,         /* special_function */
748          "R_RISCV_TPREL_S",             /* name */
749          FALSE,                         /* partial_inplace */
750          0,                             /* src_mask */
751          ENCODE_STYPE_IMM (-1U),        /* dst_mask */
752          FALSE),                        /* pcrel_offset */
753
754   /* The paired relocation may be relaxed.  */
755   HOWTO (R_RISCV_RELAX,                 /* type */
756          0,                             /* rightshift */
757          3,                             /* size */
758          0,                             /* bitsize */
759          FALSE,                         /* pc_relative */
760          0,                             /* bitpos */
761          complain_overflow_dont,        /* complain_on_overflow */
762          bfd_elf_generic_reloc,         /* special_function */
763          "R_RISCV_RELAX",               /* name */
764          FALSE,                         /* partial_inplace */
765          0,                             /* src_mask */
766          0,                             /* dst_mask */
767          FALSE),                        /* pcrel_offset */
768
769   /* 6-bit in-place addition, for local label subtraction.  */
770   HOWTO (R_RISCV_SUB6,                  /* type */
771          0,                             /* rightshift */
772          0,                             /* size */
773          8,                             /* bitsize */
774          FALSE,                         /* pc_relative */
775          0,                             /* bitpos */
776          complain_overflow_dont,        /* complain_on_overflow */
777          riscv_elf_add_sub_reloc,       /* special_function */
778          "R_RISCV_SUB6",                /* name */
779          FALSE,                         /* partial_inplace */
780          0,                             /* src_mask */
781          0x3f,                          /* dst_mask */
782          FALSE),                        /* pcrel_offset */
783
784   /* 6-bit in-place setting, for local label subtraction.  */
785   HOWTO (R_RISCV_SET6,                  /* type */
786          0,                             /* rightshift */
787          0,                             /* size */
788          8,                             /* bitsize */
789          FALSE,                         /* pc_relative */
790          0,                             /* bitpos */
791          complain_overflow_dont,        /* complain_on_overflow */
792          bfd_elf_generic_reloc,         /* special_function */
793          "R_RISCV_SET6",                /* name */
794          FALSE,                         /* partial_inplace */
795          0,                             /* src_mask */
796          0x3f,                          /* dst_mask */
797          FALSE),                        /* pcrel_offset */
798
799   /* 8-bit in-place setting, for local label subtraction.  */
800   HOWTO (R_RISCV_SET8,                  /* type */
801          0,                             /* rightshift */
802          0,                             /* size */
803          8,                             /* bitsize */
804          FALSE,                         /* pc_relative */
805          0,                             /* bitpos */
806          complain_overflow_dont,        /* complain_on_overflow */
807          bfd_elf_generic_reloc,         /* special_function */
808          "R_RISCV_SET8",                /* name */
809          FALSE,                         /* partial_inplace */
810          0,                             /* src_mask */
811          MINUS_ONE,                     /* dst_mask */
812          FALSE),                        /* pcrel_offset */
813
814   /* 16-bit in-place setting, for local label subtraction.  */
815   HOWTO (R_RISCV_SET16,                 /* type */
816          0,                             /* rightshift */
817          1,                             /* size */
818          16,                            /* bitsize */
819          FALSE,                         /* pc_relative */
820          0,                             /* bitpos */
821          complain_overflow_dont,        /* complain_on_overflow */
822          bfd_elf_generic_reloc,         /* special_function */
823          "R_RISCV_SET16",               /* name */
824          FALSE,                         /* partial_inplace */
825          0,                             /* src_mask */
826          MINUS_ONE,                     /* dst_mask */
827          FALSE),                        /* pcrel_offset */
828
829   /* 32-bit in-place setting, for local label subtraction.  */
830   HOWTO (R_RISCV_SET32,                 /* type */
831          0,                             /* rightshift */
832          2,                             /* size */
833          32,                            /* bitsize */
834          FALSE,                         /* pc_relative */
835          0,                             /* bitpos */
836          complain_overflow_dont,        /* complain_on_overflow */
837          bfd_elf_generic_reloc,         /* special_function */
838          "R_RISCV_SET32",               /* name */
839          FALSE,                         /* partial_inplace */
840          0,                             /* src_mask */
841          MINUS_ONE,                     /* dst_mask */
842          FALSE),                        /* pcrel_offset */
843
844   /* 32-bit PC relative.  */
845   HOWTO (R_RISCV_32_PCREL,              /* type */
846          0,                             /* rightshift */
847          2,                             /* size */
848          32,                            /* bitsize */
849          TRUE,                          /* pc_relative */
850          0,                             /* bitpos */
851          complain_overflow_dont,        /* complain_on_overflow */
852          bfd_elf_generic_reloc,         /* special_function */
853          "R_RISCV_32_PCREL",            /* name */
854          FALSE,                         /* partial_inplace */
855          0,                             /* src_mask */
856          MINUS_ONE,                     /* dst_mask */
857          FALSE),                        /* pcrel_offset */
858 };
859
860 /* A mapping from BFD reloc types to RISC-V ELF reloc types.  */
861
862 struct elf_reloc_map
863 {
864   bfd_reloc_code_real_type bfd_val;
865   enum elf_riscv_reloc_type elf_val;
866 };
867
868 static const struct elf_reloc_map riscv_reloc_map[] =
869 {
870   { BFD_RELOC_NONE, R_RISCV_NONE },
871   { BFD_RELOC_32, R_RISCV_32 },
872   { BFD_RELOC_64, R_RISCV_64 },
873   { BFD_RELOC_RISCV_ADD8, R_RISCV_ADD8 },
874   { BFD_RELOC_RISCV_ADD16, R_RISCV_ADD16 },
875   { BFD_RELOC_RISCV_ADD32, R_RISCV_ADD32 },
876   { BFD_RELOC_RISCV_ADD64, R_RISCV_ADD64 },
877   { BFD_RELOC_RISCV_SUB8, R_RISCV_SUB8 },
878   { BFD_RELOC_RISCV_SUB16, R_RISCV_SUB16 },
879   { BFD_RELOC_RISCV_SUB32, R_RISCV_SUB32 },
880   { BFD_RELOC_RISCV_SUB64, R_RISCV_SUB64 },
881   { BFD_RELOC_CTOR, R_RISCV_64 },
882   { BFD_RELOC_12_PCREL, R_RISCV_BRANCH },
883   { BFD_RELOC_RISCV_HI20, R_RISCV_HI20 },
884   { BFD_RELOC_RISCV_LO12_I, R_RISCV_LO12_I },
885   { BFD_RELOC_RISCV_LO12_S, R_RISCV_LO12_S },
886   { BFD_RELOC_RISCV_PCREL_LO12_I, R_RISCV_PCREL_LO12_I },
887   { BFD_RELOC_RISCV_PCREL_LO12_S, R_RISCV_PCREL_LO12_S },
888   { BFD_RELOC_RISCV_CALL, R_RISCV_CALL },
889   { BFD_RELOC_RISCV_CALL_PLT, R_RISCV_CALL_PLT },
890   { BFD_RELOC_RISCV_PCREL_HI20, R_RISCV_PCREL_HI20 },
891   { BFD_RELOC_RISCV_JMP, R_RISCV_JAL },
892   { BFD_RELOC_RISCV_GOT_HI20, R_RISCV_GOT_HI20 },
893   { BFD_RELOC_RISCV_TLS_DTPMOD32, R_RISCV_TLS_DTPMOD32 },
894   { BFD_RELOC_RISCV_TLS_DTPREL32, R_RISCV_TLS_DTPREL32 },
895   { BFD_RELOC_RISCV_TLS_DTPMOD64, R_RISCV_TLS_DTPMOD64 },
896   { BFD_RELOC_RISCV_TLS_DTPREL64, R_RISCV_TLS_DTPREL64 },
897   { BFD_RELOC_RISCV_TLS_TPREL32, R_RISCV_TLS_TPREL32 },
898   { BFD_RELOC_RISCV_TLS_TPREL64, R_RISCV_TLS_TPREL64 },
899   { BFD_RELOC_RISCV_TPREL_HI20, R_RISCV_TPREL_HI20 },
900   { BFD_RELOC_RISCV_TPREL_ADD, R_RISCV_TPREL_ADD },
901   { BFD_RELOC_RISCV_TPREL_LO12_S, R_RISCV_TPREL_LO12_S },
902   { BFD_RELOC_RISCV_TPREL_LO12_I, R_RISCV_TPREL_LO12_I },
903   { BFD_RELOC_RISCV_TLS_GOT_HI20, R_RISCV_TLS_GOT_HI20 },
904   { BFD_RELOC_RISCV_TLS_GD_HI20, R_RISCV_TLS_GD_HI20 },
905   { BFD_RELOC_RISCV_ALIGN, R_RISCV_ALIGN },
906   { BFD_RELOC_RISCV_RVC_BRANCH, R_RISCV_RVC_BRANCH },
907   { BFD_RELOC_RISCV_RVC_JUMP, R_RISCV_RVC_JUMP },
908   { BFD_RELOC_RISCV_RVC_LUI, R_RISCV_RVC_LUI },
909   { BFD_RELOC_RISCV_GPREL_I, R_RISCV_GPREL_I },
910   { BFD_RELOC_RISCV_GPREL_S, R_RISCV_GPREL_S },
911   { BFD_RELOC_RISCV_TPREL_I, R_RISCV_TPREL_I },
912   { BFD_RELOC_RISCV_TPREL_S, R_RISCV_TPREL_S },
913   { BFD_RELOC_RISCV_RELAX, R_RISCV_RELAX },
914   { BFD_RELOC_RISCV_SUB6, R_RISCV_SUB6 },
915   { BFD_RELOC_RISCV_SET6, R_RISCV_SET6 },
916   { BFD_RELOC_RISCV_SET8, R_RISCV_SET8 },
917   { BFD_RELOC_RISCV_SET16, R_RISCV_SET16 },
918   { BFD_RELOC_RISCV_SET32, R_RISCV_SET32 },
919   { BFD_RELOC_RISCV_32_PCREL, R_RISCV_32_PCREL },
920 };
921
922 /* Given a BFD reloc type, return a howto structure.  */
923
924 reloc_howto_type *
925 riscv_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
926                          bfd_reloc_code_real_type code)
927 {
928   unsigned int i;
929
930   for (i = 0; i < ARRAY_SIZE (riscv_reloc_map); i++)
931     if (riscv_reloc_map[i].bfd_val == code)
932       return &howto_table[(int) riscv_reloc_map[i].elf_val];
933
934   bfd_set_error (bfd_error_bad_value);
935   return NULL;
936 }
937
938 reloc_howto_type *
939 riscv_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name)
940 {
941   unsigned int i;
942
943   for (i = 0; i < ARRAY_SIZE (howto_table); i++)
944     if (howto_table[i].name && strcasecmp (howto_table[i].name, r_name) == 0)
945       return &howto_table[i];
946
947   return NULL;
948 }
949
950 reloc_howto_type *
951 riscv_elf_rtype_to_howto (bfd *abfd, unsigned int r_type)
952 {
953   if (r_type >= ARRAY_SIZE (howto_table))
954     {
955       (*_bfd_error_handler) (_("%pB: unsupported relocation type %#x"),
956                              abfd, r_type);
957       bfd_set_error (bfd_error_bad_value);
958       return NULL;
959     }
960   return &howto_table[r_type];
961 }
962
963 /* Special_function of RISCV_ADD and RISCV_SUB relocations.  */
964
965 static bfd_reloc_status_type
966 riscv_elf_add_sub_reloc (bfd *abfd,
967                          arelent *reloc_entry,
968                          asymbol *symbol,
969                          void *data,
970                          asection *input_section,
971                          bfd *output_bfd,
972                          char **error_message ATTRIBUTE_UNUSED)
973 {
974   reloc_howto_type *howto = reloc_entry->howto;
975   bfd_vma relocation;
976
977   if (output_bfd != NULL
978       && (symbol->flags & BSF_SECTION_SYM) == 0
979       && (!reloc_entry->howto->partial_inplace || reloc_entry->addend == 0))
980     {
981       reloc_entry->address += input_section->output_offset;
982       return bfd_reloc_ok;
983     }
984
985   if (output_bfd != NULL)
986     return bfd_reloc_continue;
987
988   relocation = symbol->value + symbol->section->output_section->vma
989     + symbol->section->output_offset + reloc_entry->addend;
990   bfd_vma old_value = bfd_get (howto->bitsize, abfd,
991                                data + reloc_entry->address);
992
993   switch (howto->type)
994     {
995     case R_RISCV_ADD8:
996     case R_RISCV_ADD16:
997     case R_RISCV_ADD32:
998     case R_RISCV_ADD64:
999       relocation = old_value + relocation;
1000       break;
1001     case R_RISCV_SUB6:
1002     case R_RISCV_SUB8:
1003     case R_RISCV_SUB16:
1004     case R_RISCV_SUB32:
1005     case R_RISCV_SUB64:
1006       relocation = old_value - relocation;
1007       break;
1008     }
1009   bfd_put (howto->bitsize, abfd, relocation, data + reloc_entry->address);
1010
1011   return bfd_reloc_ok;
1012 }