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 37static 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 840struct elf_reloc_map 841{ 842 bfd_reloc_code_real_type bfd_val; 843 enum elf_riscv_reloc_type elf_val; 844}; 845 846static 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 901reloc_howto_type * 902riscv_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 915reloc_howto_type * 916riscv_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 927reloc_howto_type * 928riscv_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