Home | History | Annotate | Line # | Download | only in bfd
elfxx-riscv.c revision 1.1
      1 /* RISC-V-specific support for ELF.
      2    Copyright (C) 2011-2017 Free Software Foundation, Inc.
      3 
      4    Contributed by Andrew Waterman (andrew (at) 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 }
    938