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