| /* LoongArch-specific support for ELF. |
| Copyright (C) 2021-2024 Free Software Foundation, Inc. |
| Contributed by Loongson Ltd. |
| |
| Based on RISC-V target. |
| |
| This file is part of BFD, the Binary File Descriptor library. |
| |
| This program is free software; you can redistribute it and/or modify |
| it under the terms of the GNU General Public License as published by |
| the Free Software Foundation; either version 3 of the License, or |
| (at your option) any later version. |
| |
| This program is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY; without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| GNU General Public License for more details. |
| |
| You should have received a copy of the GNU General Public License |
| along with this program; see the file COPYING3. If not, |
| see <http://www.gnu.org/licenses/>. */ |
| |
| #include "sysdep.h" |
| #include "bfd.h" |
| #include "libbfd.h" |
| #include "elf-bfd.h" |
| #include "elf/loongarch.h" |
| #include "elfxx-loongarch.h" |
| |
| #define ALL_ONES (~ (bfd_vma) 0) |
| |
| typedef struct loongarch_reloc_howto_type_struct |
| { |
| /* The first must be reloc_howto_type! */ |
| reloc_howto_type howto; |
| bfd_reloc_code_real_type bfd_type; |
| bool (*adjust_reloc_bits)(bfd *, reloc_howto_type *, bfd_vma *); |
| const char *larch_reloc_type_name; |
| } loongarch_reloc_howto_type; |
| |
| #define LOONGARCH_DEFAULT_HOWTO(r_name) \ |
| { HOWTO (R_LARCH_##r_name, 0, 4, 32, false, 0, complain_overflow_signed, \ |
| bfd_elf_generic_reloc, "R_LARCH_" #r_name, false, 0, ALL_ONES, \ |
| false), BFD_RELOC_LARCH_##r_name, NULL, NULL } |
| |
| #define LOONGARCH_HOWTO(type, right, size, bits, pcrel, left, ovf, func, \ |
| name, inplace, src_mask, dst_mask, pcrel_off, btype, afunc,lname) \ |
| { HOWTO(type, right, size, bits, pcrel, left, ovf, func, name, \ |
| inplace, src_mask, dst_mask, pcrel_off), btype, afunc, lname } |
| |
| #define LOONGARCH_EMPTY_HOWTO(C) \ |
| { EMPTY_HOWTO (C), BFD_RELOC_NONE, NULL, NULL } |
| |
| static bool |
| reloc_bits (bfd *abfd, reloc_howto_type *howto, bfd_vma *val); |
| static bool |
| reloc_sign_bits (bfd *abfd, reloc_howto_type *howto, bfd_vma *fix_val); |
| static bool |
| reloc_unsign_bits (bfd *abfd, reloc_howto_type *howto, bfd_vma *fix_val); |
| |
| static bfd_reloc_status_type |
| loongarch_elf_add_sub_reloc (bfd *, arelent *, asymbol *, void *, |
| asection *, bfd *, char **); |
| |
| static bfd_reloc_status_type |
| loongarch_elf_add_sub_reloc_uleb128 (bfd *, arelent *, asymbol *, void *, |
| asection *, bfd *, char **); |
| |
| /* This does not include any relocation information, but should be |
| good enough for GDB or objdump to read the file. */ |
| static loongarch_reloc_howto_type loongarch_howto_table[] = |
| { |
| /* No relocation. */ |
| LOONGARCH_HOWTO (R_LARCH_NONE, /* type (0). */ |
| 0, /* rightshift */ |
| 0, /* size */ |
| 0, /* bitsize */ |
| false, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_dont, /* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_LARCH_NONE", /* name */ |
| false, /* partial_inplace */ |
| 0, /* src_mask */ |
| 0, /* dst_mask */ |
| false, /* pcrel_offset */ |
| BFD_RELOC_NONE, /* bfd_reloc_code_real_type */ |
| NULL, /* adjust_reloc_bits */ |
| NULL), /* larch_reloc_type_name */ |
| |
| /* 32 bit relocation. */ |
| LOONGARCH_HOWTO (R_LARCH_32, /* type (1). */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 32, /* bitsize */ |
| false, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_dont, /* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_LARCH_32", /* name */ |
| false, /* partial_inplace */ |
| 0, /* src_mask */ |
| ALL_ONES, /* dst_mask */ |
| false, /* pcrel_offset */ |
| BFD_RELOC_32, /* bfd_reloc_code_real_type */ |
| NULL, /* adjust_reloc_bits */ |
| NULL), /* larch_reloc_type_name */ |
| |
| /* 64 bit relocation. */ |
| LOONGARCH_HOWTO (R_LARCH_64, /* type (2). */ |
| 0, /* rightshift */ |
| 8, /* size */ |
| 64, /* bitsize */ |
| false, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_dont, /* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_LARCH_64", /* name */ |
| false, /* partial_inplace */ |
| 0, /* src_mask */ |
| ALL_ONES, /* dst_mask */ |
| false, /* pcrel_offset */ |
| BFD_RELOC_64, /* bfd_reloc_code_real_type */ |
| NULL, /* adjust_reloc_bits */ |
| NULL), /* larch_reloc_type_name */ |
| |
| LOONGARCH_HOWTO (R_LARCH_RELATIVE, /* type (3). */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 32, /* bitsize */ |
| false, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_dont, /* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_LARCH_RELATIVE", /* name */ |
| false, /* partial_inplace */ |
| 0, /* src_mask */ |
| ALL_ONES, /* dst_mask */ |
| false, /* pcrel_offset */ |
| BFD_RELOC_NONE, /* undefined? */ |
| NULL, /* adjust_reloc_bits */ |
| NULL), /* larch_reloc_type_name */ |
| |
| LOONGARCH_HOWTO (R_LARCH_COPY, /* type (4). */ |
| 0, /* rightshift */ |
| 0, /* this one is variable size */ |
| 0, /* bitsize */ |
| false, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_bitfield, /* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_LARCH_COPY", /* name */ |
| false, /* partial_inplace */ |
| 0, /* src_mask */ |
| 0, /* dst_mask */ |
| false, /* pcrel_offset */ |
| BFD_RELOC_NONE, /* undefined? */ |
| NULL, /* adjust_reloc_bits */ |
| NULL), /* larch_reloc_type_name */ |
| |
| LOONGARCH_HOWTO (R_LARCH_JUMP_SLOT, /* type (5). */ |
| 0, /* rightshift */ |
| 8, /* size */ |
| 64, /* bitsize */ |
| false, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_bitfield, /* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_LARCH_JUMP_SLOT", /* name */ |
| false, /* partial_inplace */ |
| 0, /* src_mask */ |
| 0, /* dst_mask */ |
| false, /* pcrel_offset */ |
| BFD_RELOC_NONE, /* undefined? */ |
| NULL, /* adjust_reloc_bits */ |
| NULL), /* larch_reloc_type_name */ |
| |
| /* Dynamic TLS relocations. */ |
| LOONGARCH_HOWTO (R_LARCH_TLS_DTPMOD32, /* type (6). */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 32, /* bitsize */ |
| false, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_dont, /* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_LARCH_TLS_DTPMOD32", /* name */ |
| false, /* partial_inplace */ |
| 0, /* src_mask */ |
| ALL_ONES, /* dst_mask */ |
| false, /* pcrel_offset */ |
| BFD_RELOC_LARCH_TLS_DTPMOD32, /* bfd_reloc_code_real_type */ |
| NULL, /* adjust_reloc_bits */ |
| NULL), /* larch_reloc_type_name */ |
| |
| LOONGARCH_HOWTO (R_LARCH_TLS_DTPMOD64, /* type (7). */ |
| 0, /* rightshift */ |
| 8, /* size */ |
| 64, /* bitsize */ |
| false, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_dont, /* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_LARCH_TLS_DTPMOD64", /* name */ |
| false, /* partial_inplace */ |
| 0, /* src_mask */ |
| ALL_ONES, /* dst_mask */ |
| false, /* pcrel_offset */ |
| BFD_RELOC_LARCH_TLS_DTPMOD64, /* bfd_reloc_code_real_type */ |
| NULL, /* adjust_reloc_bits */ |
| NULL), /* larch_reloc_type_name */ |
| |
| LOONGARCH_HOWTO (R_LARCH_TLS_DTPREL32, /* type (8). */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 32, /* bitsize */ |
| false, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_dont, /* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_LARCH_TLS_DTPREL32", /* name */ |
| true, /* partial_inplace */ |
| 0, /* src_mask */ |
| ALL_ONES, /* dst_mask */ |
| false, /* pcrel_offset */ |
| BFD_RELOC_LARCH_TLS_DTPREL32, /* bfd_reloc_code_real_type */ |
| NULL, /* adjust_reloc_bits */ |
| NULL), /* larch_reloc_type_name */ |
| |
| LOONGARCH_HOWTO (R_LARCH_TLS_DTPREL64, /* type (9). */ |
| 0, /* rightshift */ |
| 8, /* size */ |
| 64, /* bitsize */ |
| false, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_dont, /* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_LARCH_TLS_DTPREL64", /* name */ |
| true, /* partial_inplace */ |
| 0, /* src_mask */ |
| ALL_ONES, /* dst_mask */ |
| false, /* pcrel_offset */ |
| BFD_RELOC_LARCH_TLS_DTPREL64, /* bfd_reloc_code_real_type */ |
| NULL, /* adjust_reloc_bits */ |
| NULL), /* larch_reloc_type_name */ |
| |
| LOONGARCH_HOWTO (R_LARCH_TLS_TPREL32, /* type (10). */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 32, /* bitsize */ |
| false, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_dont, /* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_LARCH_TLS_TPREL32", /* name */ |
| false, /* partial_inplace */ |
| 0, /* src_mask */ |
| ALL_ONES, /* dst_mask */ |
| false, /* pcrel_offset */ |
| BFD_RELOC_LARCH_TLS_TPREL32, /* bfd_reloc_code_real_type */ |
| NULL, /* adjust_reloc_bits */ |
| NULL), /* larch_reloc_type_name */ |
| |
| LOONGARCH_HOWTO (R_LARCH_TLS_TPREL64, /* type (11). */ |
| 0, /* rightshift */ |
| 8, /* size */ |
| 64, /* bitsize */ |
| false, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_dont, /* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_LARCH_TLS_TPREL64", /* name */ |
| false, /* partial_inplace */ |
| 0, /* src_mask */ |
| ALL_ONES, /* dst_mask */ |
| false, /* pcrel_offset */ |
| BFD_RELOC_LARCH_TLS_TPREL64, /* bfd_reloc_code_real_type */ |
| NULL, /* adjust_reloc_bits */ |
| NULL), /* larch_reloc_type_name */ |
| |
| LOONGARCH_HOWTO (R_LARCH_IRELATIVE, /* type (12). */ |
| 0, /* rightshift */ |
| 8, /* size */ |
| 64, /* bitsize */ |
| false, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_dont, /* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_LARCH_IRELATIVE", /* name */ |
| false, /* partial_inplace */ |
| 0, /* src_mask */ |
| ALL_ONES, /* dst_mask */ |
| false, /* pcrel_offset */ |
| BFD_RELOC_NONE, /* undefined? */ |
| NULL, /* adjust_reloc_bits */ |
| NULL), /* larch_reloc_type_name */ |
| |
| LOONGARCH_HOWTO (R_LARCH_TLS_DESC32, /* type (13). */ |
| 0, /* rightshift. */ |
| 4, /* size. */ |
| 32, /* bitsize. */ |
| false, /* pc_relative. */ |
| 0, /* bitpos. */ |
| complain_overflow_dont, /* complain_on_overflow. */ |
| bfd_elf_generic_reloc, /* special_function. */ |
| "R_LARCH_TLS_DESC32", /* name. */ |
| false, /* partial_inplace. */ |
| 0, /* src_mask. */ |
| ALL_ONES, /* dst_mask. */ |
| false, /* pcrel_offset. */ |
| BFD_RELOC_LARCH_TLS_DESC32, /* bfd_reloc_code_real_type. */ |
| NULL, /* adjust_reloc_bits. */ |
| NULL), /* larch_reloc_type_name. */ |
| |
| LOONGARCH_HOWTO (R_LARCH_TLS_DESC64, /* type (14). */ |
| 0, /* rightshift. */ |
| 8, /* size. */ |
| 64, /* bitsize. */ |
| false, /* pc_relative. */ |
| 0, /* bitpos. */ |
| complain_overflow_dont, /* complain_on_overflow. */ |
| bfd_elf_generic_reloc, /* special_function. */ |
| "R_LARCH_TLS_DESC64", /* name. */ |
| false, /* partial_inplace. */ |
| 0, /* src_mask. */ |
| ALL_ONES, /* dst_mask. */ |
| false, /* pcrel_offset. */ |
| BFD_RELOC_LARCH_TLS_DESC64, /* bfd_reloc_code_real_type. */ |
| NULL, /* adjust_reloc_bits. */ |
| NULL), /* larch_reloc_type_name. */ |
| |
| LOONGARCH_EMPTY_HOWTO (15), |
| LOONGARCH_EMPTY_HOWTO (16), |
| LOONGARCH_EMPTY_HOWTO (17), |
| LOONGARCH_EMPTY_HOWTO (18), |
| LOONGARCH_EMPTY_HOWTO (19), |
| |
| LOONGARCH_HOWTO (R_LARCH_MARK_LA, /* type (20). */ |
| 0, /* rightshift. */ |
| 0, /* size. */ |
| 0, /* bitsize. */ |
| false, /* pc_relative. */ |
| 0, /* bitpos. */ |
| complain_overflow_signed, /* complain_on_overflow. */ |
| bfd_elf_generic_reloc, /* special_function. */ |
| "R_LARCH_MARK_LA", /* name. */ |
| false, /* partial_inplace. */ |
| 0, /* src_mask. */ |
| 0, /* dst_mask. */ |
| false, /* pcrel_offset */ |
| BFD_RELOC_LARCH_MARK_LA, /* bfd_reloc_code_real_type */ |
| NULL, /* adjust_reloc_bits */ |
| NULL), /* larch_reloc_type_name */ |
| |
| LOONGARCH_HOWTO (R_LARCH_MARK_PCREL, /* type (21). */ |
| 0, /* rightshift. */ |
| 0, /* size. */ |
| 0, /* bitsize. */ |
| false, /* pc_relative. */ |
| 0, /* bitpos. */ |
| complain_overflow_signed, /* complain_on_overflow. */ |
| bfd_elf_generic_reloc, /* special_function. */ |
| "R_LARCH_MARK_PCREL", /* name. */ |
| false, /* partial_inplace. */ |
| 0, /* src_mask. */ |
| 0, /* dst_mask. */ |
| false, /* pcrel_offset */ |
| BFD_RELOC_LARCH_MARK_PCREL, /* bfd_reloc_code_real_type */ |
| NULL, /* adjust_reloc_bits */ |
| NULL), /* larch_reloc_type_name */ |
| |
| LOONGARCH_HOWTO (R_LARCH_SOP_PUSH_PCREL, /* type (22). */ |
| 2, /* rightshift. */ |
| 4, /* size. */ |
| 32, /* bitsize. */ |
| true /* FIXME: somewhat use this. */, /* pc_relative. */ |
| 0, /* bitpos. */ |
| complain_overflow_signed, /* complain_on_overflow. */ |
| bfd_elf_generic_reloc, /* special_function. */ |
| "R_LARCH_SOP_PUSH_PCREL", /* name. */ |
| false, /* partial_inplace. */ |
| 0x03ffffff, /* src_mask. */ |
| 0x03ffffff, /* dst_mask. */ |
| false, /* pcrel_offset */ |
| BFD_RELOC_LARCH_SOP_PUSH_PCREL, /* bfd_reloc_code_real_type */ |
| NULL, /* adjust_reloc_bits */ |
| NULL), /* larch_reloc_type_name */ |
| |
| /* type 23-37. */ |
| LOONGARCH_DEFAULT_HOWTO (SOP_PUSH_ABSOLUTE), |
| LOONGARCH_DEFAULT_HOWTO (SOP_PUSH_DUP), |
| LOONGARCH_DEFAULT_HOWTO (SOP_PUSH_GPREL), |
| LOONGARCH_DEFAULT_HOWTO (SOP_PUSH_TLS_TPREL), |
| LOONGARCH_DEFAULT_HOWTO (SOP_PUSH_TLS_GOT), |
| LOONGARCH_DEFAULT_HOWTO (SOP_PUSH_TLS_GD), |
| LOONGARCH_DEFAULT_HOWTO (SOP_PUSH_PLT_PCREL), |
| LOONGARCH_DEFAULT_HOWTO (SOP_ASSERT), |
| LOONGARCH_DEFAULT_HOWTO (SOP_NOT), |
| LOONGARCH_DEFAULT_HOWTO (SOP_SUB), |
| LOONGARCH_DEFAULT_HOWTO (SOP_SL), |
| LOONGARCH_DEFAULT_HOWTO (SOP_SR), |
| LOONGARCH_DEFAULT_HOWTO (SOP_ADD), |
| LOONGARCH_DEFAULT_HOWTO (SOP_AND), |
| LOONGARCH_DEFAULT_HOWTO (SOP_IF_ELSE), |
| |
| LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_S_10_5, /* type (38). */ |
| 0, /* rightshift. */ |
| 4, /* size. */ |
| 5, /* bitsize. */ |
| false, /* pc_relative. */ |
| 10, /* bitpos. */ |
| complain_overflow_signed, /* complain_on_overflow. */ |
| bfd_elf_generic_reloc, /* special_function. */ |
| "R_LARCH_SOP_POP_32_S_10_5", /* name. */ |
| false, /* partial_inplace. */ |
| 0, /* src_mask */ |
| 0x7c00, /* dst_mask */ |
| false, /* pcrel_offset */ |
| BFD_RELOC_LARCH_SOP_POP_32_S_10_5, /* bfd_reloc_code_real_type */ |
| reloc_sign_bits, /* adjust_reloc_bits */ |
| NULL), /* larch_reloc_type_name */ |
| |
| LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_U_10_12, /* type (39). */ |
| 0, /* rightshift. */ |
| 4, /* size. */ |
| 12, /* bitsize. */ |
| false, /* pc_relative. */ |
| 10, /* bitpos. */ |
| complain_overflow_unsigned, /* complain_on_overflow. */ |
| bfd_elf_generic_reloc, /* special_function. */ |
| "R_LARCH_SOP_POP_32_U_10_12", /* name. */ |
| false, /* partial_inplace. */ |
| 0, /* src_mask */ |
| 0x3ffc00, /* dst_mask */ |
| false, /* pcrel_offset */ |
| BFD_RELOC_LARCH_SOP_POP_32_U_10_12, /* bfd_reloc_code_real_type */ |
| reloc_unsign_bits, /* adjust_reloc_bits */ |
| NULL), /* larch_reloc_type_name */ |
| |
| LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_S_10_12, /* type (40). */ |
| 0, /* rightshift. */ |
| 4, /* size. */ |
| 12, /* bitsize. */ |
| false, /* pc_relative. */ |
| 10, /* bitpos. */ |
| complain_overflow_signed, /* complain_on_overflow. */ |
| bfd_elf_generic_reloc, /* special_function. */ |
| "R_LARCH_SOP_POP_32_S_10_12", /* name. */ |
| false, /* partial_inplace. */ |
| 0, /* src_mask */ |
| 0x3ffc00, /* dst_mask */ |
| false, /* pcrel_offset */ |
| BFD_RELOC_LARCH_SOP_POP_32_S_10_12, /* bfd_reloc_code_real_type */ |
| reloc_sign_bits, /* adjust_reloc_bits */ |
| NULL), /* larch_reloc_type_name */ |
| |
| LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_S_10_16, /* type (41). */ |
| 0, /* rightshift. */ |
| 4, /* size. */ |
| 16, /* bitsize. */ |
| false, /* pc_relative. */ |
| 10, /* bitpos. */ |
| complain_overflow_signed, /* complain_on_overflow. */ |
| bfd_elf_generic_reloc, /* special_function. */ |
| "R_LARCH_SOP_POP_32_S_10_16", /* name. */ |
| false, /* partial_inplace. */ |
| 0, /* src_mask */ |
| 0x3fffc00, /* dst_mask */ |
| false, /* pcrel_offset */ |
| BFD_RELOC_LARCH_SOP_POP_32_S_10_16, /* bfd_reloc_code_real_type */ |
| reloc_sign_bits, /* adjust_reloc_bits */ |
| NULL), /* larch_reloc_type_name */ |
| |
| LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_S_10_16_S2, /* type (42). */ |
| 2, /* rightshift. */ |
| 4, /* size. */ |
| 16, /* bitsize. */ |
| false, /* pc_relative. */ |
| 10, /* bitpos. */ |
| complain_overflow_signed, /* complain_on_overflow. */ |
| bfd_elf_generic_reloc, /* special_function. */ |
| "R_LARCH_SOP_POP_32_S_10_16_S2", /* name. */ |
| false, /* partial_inplace. */ |
| 0, /* src_mask */ |
| 0x3fffc00, /* dst_mask */ |
| false, /* pcrel_offset */ |
| BFD_RELOC_LARCH_SOP_POP_32_S_10_16_S2, /* bfd_reloc_code_real_type */ |
| reloc_sign_bits, /* adjust_reloc_bits */ |
| NULL), /* larch_reloc_type_name */ |
| |
| LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_S_5_20, /* type (43). */ |
| 0, /* rightshift. */ |
| 4, /* size. */ |
| 20, /* bitsize. */ |
| false, /* pc_relative. */ |
| 5, /* bitpos. */ |
| complain_overflow_signed, /* complain_on_overflow. */ |
| bfd_elf_generic_reloc, /* special_function. */ |
| "R_LARCH_SOP_POP_32_S_5_20", /* name. */ |
| false, /* partial_inplace. */ |
| 0, /* src_mask */ |
| 0x1ffffe0, /* dst_mask */ |
| false, /* pcrel_offset */ |
| BFD_RELOC_LARCH_SOP_POP_32_S_5_20, /* bfd_reloc_code_real_type */ |
| reloc_sign_bits, /* adjust_reloc_bits */ |
| NULL), /* larch_reloc_type_name */ |
| |
| LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_S_0_5_10_16_S2, |
| /* type (44). */ |
| 2, /* rightshift. */ |
| 4, /* size. */ |
| 21, /* bitsize. */ |
| false, /* pc_relative. */ |
| 0, /* bitpos. */ |
| complain_overflow_signed, /* complain_on_overflow. */ |
| bfd_elf_generic_reloc, /* special_function. */ |
| "R_LARCH_SOP_POP_32_S_0_5_10_16_S2", /* name. */ |
| false, /* partial_inplace. */ |
| 0x0, /* src_mask */ |
| 0x03fffc1f, /* dst_mask */ |
| false, /* pcrel_offset */ |
| BFD_RELOC_LARCH_SOP_POP_32_S_0_5_10_16_S2, |
| /* bfd_reloc_code_real_type */ |
| reloc_sign_bits, /* adjust_reloc_bits */ |
| NULL), /* larch_reloc_type_name */ |
| |
| LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_S_0_10_10_16_S2, /* type (45). */ |
| 2, /* rightshift. */ |
| 4, /* size. */ |
| 26, /* bitsize. */ |
| false, /* pc_relative. */ |
| 0, /* bitpos. */ |
| complain_overflow_signed, /* complain_on_overflow. */ |
| bfd_elf_generic_reloc, /* special_function. */ |
| "R_LARCH_SOP_POP_32_S_0_10_10_16_S2", /* name. */ |
| false, /* partial_inplace. */ |
| 0, /* src_mask */ |
| 0x03ffffff, /* dst_mask */ |
| false, /* pcrel_offset */ |
| BFD_RELOC_LARCH_SOP_POP_32_S_0_10_10_16_S2, |
| /* bfd_reloc_code_real_type */ |
| reloc_sign_bits, /* adjust_reloc_bits */ |
| NULL), /* larch_reloc_type_name */ |
| |
| LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_U, /* type (46). */ |
| 0, /* rightshift. */ |
| 4, /* size. */ |
| 32, /* bitsize. */ |
| false, /* pc_relative. */ |
| 0, /* bitpos. */ |
| complain_overflow_unsigned, /* complain_on_overflow. */ |
| bfd_elf_generic_reloc, /* special_function. */ |
| "R_LARCH_SOP_POP_32_U", /* name. */ |
| false, /* partial_inplace. */ |
| 0xffffffff00000000, /* src_mask */ |
| 0x00000000ffffffff, /* dst_mask */ |
| false, /* pcrel_offset */ |
| BFD_RELOC_LARCH_SOP_POP_32_U, /* bfd_reloc_code_real_type */ |
| reloc_unsign_bits, /* adjust_reloc_bits */ |
| NULL), /* larch_reloc_type_name */ |
| |
| /* 8-bit in-place addition, for local label subtraction. */ |
| LOONGARCH_HOWTO (R_LARCH_ADD8, /* type (47). */ |
| 0, /* rightshift. */ |
| 1, /* size. */ |
| 8, /* bitsize. */ |
| false, /* pc_relative. */ |
| 0, /* bitpos. */ |
| complain_overflow_dont, /* complain_on_overflow. */ |
| loongarch_elf_add_sub_reloc, /* special_function. */ |
| "R_LARCH_ADD8", /* name. */ |
| false, /* partial_inplace. */ |
| 0, /* src_mask. */ |
| 0xff, /* dst_mask. */ |
| false, /* pcrel_offset. */ |
| BFD_RELOC_LARCH_ADD8, /* bfd_reloc_code_real_type. */ |
| NULL, /* adjust_reloc_bits. */ |
| NULL), /* larch_reloc_type_name. */ |
| |
| /* 16-bit in-place addition, for local label subtraction. */ |
| LOONGARCH_HOWTO (R_LARCH_ADD16, /* type (48). */ |
| 0, /* rightshift. */ |
| 2, /* size. */ |
| 16, /* bitsize. */ |
| false, /* pc_relative. */ |
| 0, /* bitpos. */ |
| complain_overflow_dont, /* complain_on_overflow. */ |
| loongarch_elf_add_sub_reloc, /* special_function. */ |
| "R_LARCH_ADD16", /* name. */ |
| false, /* partial_inplace. */ |
| 0, /* src_mask. */ |
| 0xffff, /* dst_mask. */ |
| false, /* pcrel_offset. */ |
| BFD_RELOC_LARCH_ADD16, /* bfd_reloc_code_real_type. */ |
| NULL, /* adjust_reloc_bits. */ |
| NULL), /* larch_reloc_type_name. */ |
| |
| /* 24-bit in-place addition, for local label subtraction. */ |
| LOONGARCH_HOWTO (R_LARCH_ADD24, /* type (49). */ |
| 0, /* rightshift. */ |
| 3, /* size. */ |
| 24, /* bitsize. */ |
| false, /* pc_relative. */ |
| 0, /* bitpos. */ |
| complain_overflow_dont, /* complain_on_overflow. */ |
| loongarch_elf_add_sub_reloc, /* special_function. */ |
| "R_LARCH_ADD24", /* name. */ |
| false, /* partial_inplace. */ |
| 0, /* src_mask. */ |
| 0xffffff, /* dst_mask. */ |
| false, /* pcrel_offset. */ |
| BFD_RELOC_LARCH_ADD24, /* bfd_reloc_code_real_type. */ |
| NULL, /* adjust_reloc_bits. */ |
| NULL), /* larch_reloc_type_name. */ |
| |
| /* 32-bit in-place addition, for local label subtraction. */ |
| LOONGARCH_HOWTO (R_LARCH_ADD32, /* type (50). */ |
| 0, /* rightshift. */ |
| 4, /* size. */ |
| 32, /* bitsize. */ |
| false, /* pc_relative. */ |
| 0, /* bitpos. */ |
| complain_overflow_dont, /* complain_on_overflow. */ |
| loongarch_elf_add_sub_reloc, /* special_function. */ |
| "R_LARCH_ADD32", /* name. */ |
| false, /* partial_inplace. */ |
| 0, /* src_mask. */ |
| 0xffffffff, /* dst_mask. */ |
| false, /* pcrel_offset. */ |
| BFD_RELOC_LARCH_ADD32, /* bfd_reloc_code_real_type. */ |
| NULL, /* adjust_reloc_bits. */ |
| NULL), /* larch_reloc_type_name. */ |
| |
| /* 64-bit in-place addition, for local label subtraction. */ |
| LOONGARCH_HOWTO (R_LARCH_ADD64, /* type (51). */ |
| 0, /* rightshift. */ |
| 8, /* size. */ |
| 64, /* bitsize. */ |
| false, /* pc_relative. */ |
| 0, /* bitpos. */ |
| complain_overflow_dont, /* complain_on_overflow. */ |
| loongarch_elf_add_sub_reloc, /* special_function. */ |
| "R_LARCH_ADD64", /* name. */ |
| false, /* partial_inplace. */ |
| 0, /* src_mask. */ |
| ALL_ONES, /* dst_mask. */ |
| false, /* pcrel_offset. */ |
| BFD_RELOC_LARCH_ADD64, /* bfd_reloc_code_real_type. */ |
| NULL, /* adjust_reloc_bits. */ |
| NULL), /* larch_reloc_type_name. */ |
| |
| /* 8-bit in-place subtraction, for local label subtraction. */ |
| LOONGARCH_HOWTO (R_LARCH_SUB8, /* type (52). */ |
| 0, /* rightshift. */ |
| 1, /* size. */ |
| 8, /* bitsize. */ |
| false, /* pc_relative. */ |
| 0, /* bitpos. */ |
| complain_overflow_dont, /* complain_on_overflow. */ |
| loongarch_elf_add_sub_reloc, /* special_function. */ |
| "R_LARCH_SUB8", /* name. */ |
| false, /* partial_inplace. */ |
| 0, /* src_mask. */ |
| 0xff, /* dst_mask. */ |
| false, /* pcrel_offset. */ |
| BFD_RELOC_LARCH_SUB8, /* bfd_reloc_code_real_type. */ |
| NULL, /* adjust_reloc_bits. */ |
| NULL), /* larch_reloc_type_name. */ |
| |
| /* 16-bit in-place subtraction, for local label subtraction. */ |
| LOONGARCH_HOWTO (R_LARCH_SUB16, /* type (53). */ |
| 0, /* rightshift. */ |
| 2, /* size. */ |
| 16, /* bitsize. */ |
| false, /* pc_relative. */ |
| 0, /* bitpos. */ |
| complain_overflow_dont, /* complain_on_overflow. */ |
| loongarch_elf_add_sub_reloc, /* special_function. */ |
| "R_LARCH_SUB16", /* name. */ |
| false, /* partial_inplace. */ |
| 0, /* src_mask. */ |
| 0xffff, /* dst_mask. */ |
| false, /* pcrel_offset. */ |
| BFD_RELOC_LARCH_SUB16, /* bfd_reloc_code_real_type. */ |
| NULL, /* adjust_reloc_bits. */ |
| NULL), /* larch_reloc_type_name. */ |
| |
| /* 24-bit in-place subtraction, for local label subtraction. */ |
| LOONGARCH_HOWTO (R_LARCH_SUB24, /* type (54). */ |
| 0, /* rightshift. */ |
| 3, /* size. */ |
| 24, /* bitsize. */ |
| false, /* pc_relative. */ |
| 0, /* bitpos. */ |
| complain_overflow_dont, /* complain_on_overflow. */ |
| loongarch_elf_add_sub_reloc, /* special_function. */ |
| "R_LARCH_SUB24", /* name. */ |
| false, /* partial_inplace. */ |
| 0, /* src_mask. */ |
| 0xffffff, /* dst_mask. */ |
| false, /* pcrel_offset. */ |
| BFD_RELOC_LARCH_SUB24, /* bfd_reloc_code_real_type. */ |
| NULL, /* adjust_reloc_bits. */ |
| NULL), /* larch_reloc_type_name. */ |
| |
| /* 32-bit in-place subtraction, for local label subtraction. */ |
| LOONGARCH_HOWTO (R_LARCH_SUB32, /* type (55). */ |
| 0, /* rightshift. */ |
| 4, /* size. */ |
| 32, /* bitsize. */ |
| false, /* pc_relative. */ |
| 0, /* bitpos. */ |
| complain_overflow_dont, /* complain_on_overflow. */ |
| loongarch_elf_add_sub_reloc, /* special_function. */ |
| "R_LARCH_SUB32", /* name. */ |
| false, /* partial_inplace. */ |
| 0, /* src_mask. */ |
| 0xffffffff, /* dst_mask. */ |
| false, /* pcrel_offset. */ |
| BFD_RELOC_LARCH_SUB32, /* bfd_reloc_code_real_type. */ |
| NULL, /* adjust_reloc_bits. */ |
| NULL), /* larch_reloc_type_name. */ |
| |
| /* 64-bit in-place subtraction, for local label subtraction. */ |
| LOONGARCH_HOWTO (R_LARCH_SUB64, /* type (56). */ |
| 0, /* rightshift. */ |
| 8, /* size. */ |
| 64, /* bitsize. */ |
| false, /* pc_relative. */ |
| 0, /* bitpos. */ |
| complain_overflow_dont, /* complain_on_overflow. */ |
| loongarch_elf_add_sub_reloc, /* special_function. */ |
| "R_LARCH_SUB64", /* name. */ |
| false, /* partial_inplace. */ |
| 0, /* src_mask. */ |
| ALL_ONES, /* dst_mask. */ |
| false, /* pcrel_offset. */ |
| BFD_RELOC_LARCH_SUB64, /* bfd_reloc_code_real_type. */ |
| NULL, /* adjust_reloc_bits. */ |
| NULL), /* larch_reloc_type_name. */ |
| |
| LOONGARCH_HOWTO (R_LARCH_GNU_VTINHERIT, /* type (57). */ |
| 0, /* rightshift. */ |
| 0, /* size. */ |
| 0, /* bitsize. */ |
| false, /* pc_relative. */ |
| 0, /* bitpos. */ |
| complain_overflow_signed, /* complain_on_overflow. */ |
| bfd_elf_generic_reloc, /* special_function. */ |
| "R_LARCH_GNU_VTINHERIT", /* name. */ |
| false, /* partial_inplace. */ |
| 0, /* src_mask */ |
| 0, /* dst_mask */ |
| false, /* pcrel_offset */ |
| BFD_RELOC_NONE, /* bfd_reloc_code_real_type */ |
| NULL, /* adjust_reloc_bits */ |
| NULL), /* larch_reloc_type_name */ |
| |
| LOONGARCH_HOWTO (R_LARCH_GNU_VTENTRY, /* type (58). */ |
| 0, /* rightshift. */ |
| 0, /* size. */ |
| 0, /* bitsize. */ |
| false, /* pc_relative. */ |
| 0, /* bitpos. */ |
| complain_overflow_signed, /* complain_on_overflow. */ |
| NULL, /* special_function. */ |
| "R_LARCH_GNU_VTENTRY", /* name. */ |
| false, /* partial_inplace. */ |
| 0, /* src_mask */ |
| 0, /* dst_mask */ |
| false, /* pcrel_offset */ |
| BFD_RELOC_NONE, /* bfd_reloc_code_real_type */ |
| NULL, /* adjust_reloc_bits */ |
| NULL), /* larch_reloc_type_name */ |
| |
| LOONGARCH_EMPTY_HOWTO (59), |
| LOONGARCH_EMPTY_HOWTO (60), |
| LOONGARCH_EMPTY_HOWTO (61), |
| LOONGARCH_EMPTY_HOWTO (62), |
| LOONGARCH_EMPTY_HOWTO (63), |
| |
| /* New reloc types. */ |
| LOONGARCH_HOWTO (R_LARCH_B16, /* type (64). */ |
| 2, /* rightshift. */ |
| 4, /* size. */ |
| 16, /* bitsize. */ |
| false, /* pc_relative. */ |
| 10, /* bitpos. */ |
| complain_overflow_signed, /* complain_on_overflow. */ |
| bfd_elf_generic_reloc, /* special_function. */ |
| "R_LARCH_B16", /* name. */ |
| false, /* partial_inplace. */ |
| 0, /* src_mask. */ |
| 0x3fffc00, /* dst_mask. */ |
| false, /* pcrel_offset. */ |
| BFD_RELOC_LARCH_B16, /* bfd_reloc_code_real_type. */ |
| reloc_sign_bits, /* adjust_reloc_bits. */ |
| "b16"), /* larch_reloc_type_name. */ |
| |
| LOONGARCH_HOWTO (R_LARCH_B21, /* type (65). */ |
| 2, /* rightshift. */ |
| 4, /* size. */ |
| 21, /* bitsize. */ |
| false, /* pc_relative. */ |
| 0, /* bitpos. */ |
| complain_overflow_signed, /* complain_on_overflow. */ |
| bfd_elf_generic_reloc, /* special_function. */ |
| "R_LARCH_B21", /* name. */ |
| false, /* partial_inplace. */ |
| 0, /* src_mask. */ |
| 0x3fffc1f, /* dst_mask. */ |
| false, /* pcrel_offset. */ |
| BFD_RELOC_LARCH_B21, /* bfd_reloc_code_real_type. */ |
| reloc_sign_bits, /* adjust_reloc_bits. */ |
| "b21"), /* larch_reloc_type_name. */ |
| |
| LOONGARCH_HOWTO (R_LARCH_B26, /* type (66). */ |
| 2, /* rightshift. */ |
| 4, /* size. */ |
| 26, /* bitsize. */ |
| false, /* pc_relative. */ |
| 0, /* bitpos. */ |
| complain_overflow_signed, /* complain_on_overflow. */ |
| bfd_elf_generic_reloc, /* special_function. */ |
| "R_LARCH_B26", /* name. */ |
| false, /* partial_inplace. */ |
| 0, /* src_mask. */ |
| 0x03ffffff, /* dst_mask. */ |
| false, /* pcrel_offset. */ |
| BFD_RELOC_LARCH_B26, /* bfd_reloc_code_real_type. */ |
| reloc_sign_bits, /* adjust_reloc_bits. */ |
| "b26"), /* larch_reloc_type_name. */ |
| |
| LOONGARCH_HOWTO (R_LARCH_ABS_HI20, /* type (67). */ |
| 12, /* rightshift. */ |
| 4, /* size. */ |
| 20, /* bitsize. */ |
| false, /* pc_relative. */ |
| 5, /* bitpos. */ |
| complain_overflow_signed, /* complain_on_overflow. */ |
| bfd_elf_generic_reloc, /* special_function. */ |
| "R_LARCH_ABS_HI20", /* name. */ |
| false, /* partial_inplace. */ |
| 0, /* src_mask */ |
| 0x1ffffe0, /* dst_mask */ |
| false, /* pcrel_offset */ |
| BFD_RELOC_LARCH_ABS_HI20, /* bfd_reloc_code_real_type */ |
| reloc_bits, /* adjust_reloc_bits */ |
| "abs_hi20"), /* larch_reloc_type_name */ |
| |
| LOONGARCH_HOWTO (R_LARCH_ABS_LO12, /* type (68). */ |
| 0, /* rightshift. */ |
| 4, /* size. */ |
| 12, /* bitsize. */ |
| false, /* pc_relative. */ |
| 10, /* bitpos. */ |
| complain_overflow_unsigned, /* complain_on_overflow. */ |
| bfd_elf_generic_reloc, /* special_function. */ |
| "R_LARCH_ABS_LO12", /* name. */ |
| false, /* partial_inplace. */ |
| 0, /* src_mask */ |
| 0x3ffc00, /* dst_mask */ |
| false, /* pcrel_offset */ |
| BFD_RELOC_LARCH_ABS_LO12, /* bfd_reloc_code_real_type */ |
| reloc_bits, /* adjust_reloc_bits */ |
| "abs_lo12"), /* larch_reloc_type_name */ |
| |
| LOONGARCH_HOWTO (R_LARCH_ABS64_LO20, /* type (69). */ |
| 32, /* rightshift. */ |
| 4, /* size. */ |
| 20, /* bitsize. */ |
| false, /* pc_relative. */ |
| 5, /* bitpos. */ |
| complain_overflow_signed, /* complain_on_overflow. */ |
| bfd_elf_generic_reloc, /* special_function. */ |
| "R_LARCH_ABS64_LO20", /* name. */ |
| false, /* partial_inplace. */ |
| 0, /* src_mask */ |
| 0x1ffffe0, /* dst_mask */ |
| false, /* pcrel_offset */ |
| BFD_RELOC_LARCH_ABS64_LO20, /* bfd_reloc_code_real_type */ |
| reloc_bits, /* adjust_reloc_bits */ |
| "abs64_lo20"), /* larch_reloc_type_name */ |
| |
| LOONGARCH_HOWTO (R_LARCH_ABS64_HI12, /* type (70). */ |
| 52, /* rightshift. */ |
| 4, /* size. */ |
| 12, /* bitsize. */ |
| false, /* pc_relative. */ |
| 10, /* bitpos. */ |
| complain_overflow_signed, /* complain_on_overflow. */ |
| bfd_elf_generic_reloc, /* special_function. */ |
| "R_LARCH_ABS64_HI12", /* name. */ |
| false, /* partial_inplace. */ |
| 0, /* src_mask */ |
| 0x3ffc00, /* dst_mask */ |
| false, /* pcrel_offset */ |
| BFD_RELOC_LARCH_ABS64_HI12, /* bfd_reloc_code_real_type */ |
| reloc_bits, /* adjust_reloc_bits */ |
| "abs64_hi12"), /* larch_reloc_type_name */ |
| |
| LOONGARCH_HOWTO (R_LARCH_PCALA_HI20, /* type (71). */ |
| 12, /* rightshift. */ |
| 4, /* size. */ |
| 20, /* bitsize. */ |
| false, /* pc_relative. */ |
| 5, /* bitpos. */ |
| complain_overflow_signed, /* complain_on_overflow. */ |
| bfd_elf_generic_reloc, /* special_function. */ |
| "R_LARCH_PCALA_HI20", /* name. */ |
| false, /* partial_inplace. */ |
| 0, /* src_mask */ |
| 0x1ffffe0, /* dst_mask */ |
| false, /* pcrel_offset */ |
| BFD_RELOC_LARCH_PCALA_HI20, /* bfd_reloc_code_real_type */ |
| reloc_bits, /* adjust_reloc_bits */ |
| "pc_hi20"), /* larch_reloc_type_name */ |
| |
| LOONGARCH_HOWTO (R_LARCH_PCALA_LO12, /* type (72). */ |
| 0, /* rightshift. */ |
| 4, /* size. */ |
| 12, /* bitsize. */ |
| false, /* pc_relative. */ |
| 10, /* bitpos. */ |
| complain_overflow_signed, /* complain_on_overflow. */ |
| bfd_elf_generic_reloc, /* special_function. */ |
| "R_LARCH_PCALA_LO12", /* name. */ |
| false, /* partial_inplace. */ |
| 0, /* src_mask */ |
| 0x3ffc00, /* dst_mask */ |
| false, /* pcrel_offset */ |
| BFD_RELOC_LARCH_PCALA_LO12, /* bfd_reloc_code_real_type */ |
| reloc_bits, /* adjust_reloc_bits */ |
| "pc_lo12"), /* larch_reloc_type_name */ |
| |
| LOONGARCH_HOWTO (R_LARCH_PCALA64_LO20, /* type (73). */ |
| 32, /* rightshift. */ |
| 4, /* size. */ |
| 20, /* bitsize. */ |
| false, /* pc_relative. */ |
| 5, /* bitpos. */ |
| complain_overflow_signed, /* complain_on_overflow. */ |
| bfd_elf_generic_reloc, /* special_function. */ |
| "R_LARCH_PCALA64_LO20", /* name. */ |
| false, /* partial_inplace. */ |
| 0, /* src_mask */ |
| 0x1ffffe0, /* dst_mask */ |
| false, /* pcrel_offset */ |
| BFD_RELOC_LARCH_PCALA64_LO20, /* bfd_reloc_code_real_type */ |
| reloc_bits, /* adjust_reloc_bits */ |
| "pc64_lo20"), /* larch_reloc_type_name */ |
| |
| LOONGARCH_HOWTO (R_LARCH_PCALA64_HI12, /* type (74). */ |
| 52, /* rightshift. */ |
| 4, /* size. */ |
| 12, /* bitsize. */ |
| false, /* pc_relative. */ |
| 10, /* bitpos. */ |
| complain_overflow_signed, /* complain_on_overflow. */ |
| bfd_elf_generic_reloc, /* special_function. */ |
| "R_LARCH_PCALA64_HI12", /* name. */ |
| false, /* partial_inplace. */ |
| 0, /* src_mask */ |
| 0x3ffc00, /* dst_mask */ |
| false, /* pcrel_offset */ |
| BFD_RELOC_LARCH_PCALA64_HI12, /* bfd_reloc_code_real_type */ |
| reloc_bits, /* adjust_reloc_bits */ |
| "pc64_hi12"), /* larch_reloc_type_name */ |
| |
| LOONGARCH_HOWTO (R_LARCH_GOT_PC_HI20, /* type (75). */ |
| 12, /* rightshift. */ |
| 4, /* size. */ |
| 20, /* bitsize. */ |
| false, /* pc_relative. */ |
| 5, /* bitpos. */ |
| complain_overflow_signed, /* complain_on_overflow. */ |
| bfd_elf_generic_reloc, /* special_function. */ |
| "R_LARCH_GOT_PC_HI20", /* name. */ |
| false, /* partial_inplace. */ |
| 0, /* src_mask */ |
| 0x1ffffe0, /* dst_mask */ |
| false, /* pcrel_offset */ |
| BFD_RELOC_LARCH_GOT_PC_HI20, /* bfd_reloc_code_real_type */ |
| reloc_bits, /* adjust_reloc_bits */ |
| "got_pc_hi20"), /* larch_reloc_type_name */ |
| |
| LOONGARCH_HOWTO (R_LARCH_GOT_PC_LO12, /* type (76). */ |
| 0, /* rightshift. */ |
| 4, /* size. */ |
| 12, /* bitsize. */ |
| false, /* pc_relative. */ |
| 10, /* bitpos. */ |
| complain_overflow_signed, /* complain_on_overflow. */ |
| bfd_elf_generic_reloc, /* special_function. */ |
| "R_LARCH_GOT_PC_LO12", /* name. */ |
| false, /* partial_inplace. */ |
| 0, /* src_mask */ |
| 0x3ffc00, /* dst_mask */ |
| false, /* pcrel_offset */ |
| BFD_RELOC_LARCH_GOT_PC_LO12, /* bfd_reloc_code_real_type */ |
| reloc_bits, /* adjust_reloc_bits */ |
| "got_pc_lo12"), /* larch_reloc_type_name */ |
| |
| LOONGARCH_HOWTO (R_LARCH_GOT64_PC_LO20, /* type (77). */ |
| 32, /* rightshift. */ |
| 4, /* size. */ |
| 20, /* bitsize. */ |
| false, /* pc_relative. */ |
| 5, /* bitpos. */ |
| complain_overflow_signed, /* complain_on_overflow. */ |
| bfd_elf_generic_reloc, /* special_function. */ |
| "R_LARCH_GOT64_PC_LO20", /* name. */ |
| false, /* partial_inplace. */ |
| 0, /* src_mask */ |
| 0x1ffffe0, /* dst_mask */ |
| false, /* pcrel_offset */ |
| BFD_RELOC_LARCH_GOT64_PC_LO20, /* bfd_reloc_code_real_type */ |
| reloc_bits, /* adjust_reloc_bits */ |
| "got64_pc_lo20"), /* larch_reloc_type_name */ |
| |
| LOONGARCH_HOWTO (R_LARCH_GOT64_PC_HI12, /* type (78). */ |
| 52, /* rightshift. */ |
| 4, /* size. */ |
| 12, /* bitsize. */ |
| false, /* pc_relative. */ |
| 10, /* bitpos. */ |
| complain_overflow_signed, /* complain_on_overflow. */ |
| bfd_elf_generic_reloc, /* special_function. */ |
| "R_LARCH_GOT64_PC_HI12", /* name. */ |
| false, /* partial_inplace. */ |
| 0, /* src_mask */ |
| 0x3ffc00, /* dst_mask */ |
| false, /* pcrel_offset */ |
| BFD_RELOC_LARCH_GOT64_PC_HI12, /* bfd_reloc_code_real_type */ |
| reloc_bits, /* adjust_reloc_bits */ |
| "got64_pc_hi12"), /* larch_reloc_type_name */ |
| |
| LOONGARCH_HOWTO (R_LARCH_GOT_HI20, /* type (79). */ |
| 12, /* rightshift. */ |
| 4, /* size. */ |
| 20, /* bitsize. */ |
| false, /* pc_relative. */ |
| 5, /* bitpos. */ |
| complain_overflow_signed, /* complain_on_overflow. */ |
| bfd_elf_generic_reloc, /* special_function. */ |
| "R_LARCH_GOT_HI20", /* name. */ |
| false, /* partial_inplace. */ |
| 0, /* src_mask */ |
| 0x1ffffe0, /* dst_mask */ |
| false, /* pcrel_offset */ |
| BFD_RELOC_LARCH_GOT_HI20, /* bfd_reloc_code_real_type */ |
| reloc_bits, /* adjust_reloc_bits */ |
| "got_hi20"), /* larch_reloc_type_name */ |
| |
| LOONGARCH_HOWTO (R_LARCH_GOT_LO12, /* type (80). */ |
| 0, /* rightshift. */ |
| 4, /* size. */ |
| 12, /* bitsize. */ |
| false, /* pc_relative. */ |
| 10, /* bitpos. */ |
| complain_overflow_signed, /* complain_on_overflow. */ |
| bfd_elf_generic_reloc, /* special_function. */ |
| "R_LARCH_GOT_LO12", /* name. */ |
| false, /* partial_inplace. */ |
| 0, /* src_mask */ |
| 0x3ffc00, /* dst_mask */ |
| false, /* pcrel_offset */ |
| BFD_RELOC_LARCH_GOT_LO12, /* bfd_reloc_code_real_type */ |
| reloc_bits, /* adjust_reloc_bits */ |
| "got_lo12"), /* larch_reloc_type_name */ |
| |
| LOONGARCH_HOWTO (R_LARCH_GOT64_LO20, /* type (81). */ |
| 32, /* rightshift. */ |
| 4, /* size. */ |
| 20, /* bitsize. */ |
| false, /* pc_relative. */ |
| 5, /* bitpos. */ |
| complain_overflow_signed, /* complain_on_overflow. */ |
| bfd_elf_generic_reloc, /* special_function. */ |
| "R_LARCH_GOT64_LO20", /* name. */ |
| false, /* partial_inplace. */ |
| 0, /* src_mask */ |
| 0x1ffffe0, /* dst_mask */ |
| false, /* pcrel_offset */ |
| BFD_RELOC_LARCH_GOT64_LO20, /* bfd_reloc_code_real_type */ |
| reloc_bits, /* adjust_reloc_bits */ |
| "got64_lo20"), /* larch_reloc_type_name */ |
| |
| LOONGARCH_HOWTO (R_LARCH_GOT64_HI12, /* type (82). */ |
| 52, /* rightshift. */ |
| 4, /* size. */ |
| 12, /* bitsize. */ |
| false, /* pc_relative. */ |
| 10, /* bitpos. */ |
| complain_overflow_signed, /* complain_on_overflow. */ |
| bfd_elf_generic_reloc, /* special_function. */ |
| "R_LARCH_GOT64_HI12", /* name. */ |
| false, /* partial_inplace. */ |
| 0, /* src_mask */ |
| 0x3ffc00, /* dst_mask */ |
| false, /* pcrel_offset */ |
| BFD_RELOC_LARCH_GOT64_HI12, /* bfd_reloc_code_real_type */ |
| reloc_bits, /* adjust_reloc_bits */ |
| "got64_hi12"), /* larch_reloc_type_name */ |
| |
| LOONGARCH_HOWTO (R_LARCH_TLS_LE_HI20, /* type (83). */ |
| 12, /* rightshift. */ |
| 4, /* size. */ |
| 20, /* bitsize. */ |
| false, /* pc_relative. */ |
| 5, /* bitpos. */ |
| complain_overflow_signed, /* complain_on_overflow. */ |
| bfd_elf_generic_reloc, /* special_function. */ |
| "R_LARCH_TLS_LE_HI20", /* name. */ |
| false, /* partial_inplace. */ |
| 0, /* src_mask */ |
| 0x1ffffe0, /* dst_mask */ |
| false, /* pcrel_offset */ |
| BFD_RELOC_LARCH_TLS_LE_HI20, /* bfd_reloc_code_real_type */ |
| reloc_bits, /* adjust_reloc_bits */ |
| "le_hi20"), /* larch_reloc_type_name */ |
| |
| LOONGARCH_HOWTO (R_LARCH_TLS_LE_LO12, /* type (84). */ |
| 0, /* rightshift. */ |
| 4, /* size. */ |
| 12, /* bitsize. */ |
| false, /* pc_relative. */ |
| 10, /* bitpos. */ |
| complain_overflow_unsigned, /* complain_on_overflow. */ |
| bfd_elf_generic_reloc, /* special_function. */ |
| "R_LARCH_TLS_LE_LO12", /* name. */ |
| false, /* partial_inplace. */ |
| 0, /* src_mask */ |
| 0x3ffc00, /* dst_mask */ |
| false, /* pcrel_offset */ |
| BFD_RELOC_LARCH_TLS_LE_LO12, /* bfd_reloc_code_real_type */ |
| reloc_bits, /* adjust_reloc_bits */ |
| "le_lo12"), /* larch_reloc_type_name */ |
| |
| LOONGARCH_HOWTO (R_LARCH_TLS_LE64_LO20, /* type (85). */ |
| 32, /* rightshift. */ |
| 4, /* size. */ |
| 20, /* bitsize. */ |
| false, /* pc_relative. */ |
| 5, /* bitpos. */ |
| complain_overflow_signed, /* complain_on_overflow. */ |
| bfd_elf_generic_reloc, /* special_function. */ |
| "R_LARCH_TLS_LE64_LO20", /* name. */ |
| false, /* partial_inplace. */ |
| 0, /* src_mask */ |
| 0x1ffffe0, /* dst_mask */ |
| false, /* pcrel_offset */ |
| BFD_RELOC_LARCH_TLS_LE64_LO20, /* bfd_reloc_code_real_type */ |
| reloc_bits, /* adjust_reloc_bits */ |
| "le64_lo20"), /* larch_reloc_type_name */ |
| |
| LOONGARCH_HOWTO (R_LARCH_TLS_LE64_HI12, /* type (86). */ |
| 52, /* rightshift. */ |
| 4, /* size. */ |
| 12, /* bitsize. */ |
| false, /* pc_relative. */ |
| 10, /* bitpos. */ |
| complain_overflow_signed, /* complain_on_overflow. */ |
| bfd_elf_generic_reloc, /* special_function. */ |
| "R_LARCH_TLS_LE64_HI12", /* name. */ |
| false, /* partial_inplace. */ |
| 0, /* src_mask */ |
| 0x3ffc00, /* dst_mask */ |
| false, /* pcrel_offset */ |
| BFD_RELOC_LARCH_TLS_LE64_HI12, /* bfd_reloc_code_real_type */ |
| reloc_bits, /* adjust_reloc_bits */ |
| "le64_hi12"), /* larch_reloc_type_name */ |
| |
| LOONGARCH_HOWTO (R_LARCH_TLS_IE_PC_HI20, /* type (87). */ |
| 12, /* rightshift. */ |
| 4, /* size. */ |
| 20, /* bitsize. */ |
| false, /* pc_relative. */ |
| 5, /* bitpos. */ |
| complain_overflow_signed, /* complain_on_overflow. */ |
| bfd_elf_generic_reloc, /* special_function. */ |
| "R_LARCH_TLS_IE_PC_HI20", /* name. */ |
| false, /* partial_inplace. */ |
| 0, /* src_mask */ |
| 0x1ffffe0, /* dst_mask */ |
| false, /* pcrel_offset */ |
| BFD_RELOC_LARCH_TLS_IE_PC_HI20, /* bfd_reloc_code_real_type */ |
| reloc_bits, /* adjust_reloc_bits */ |
| "ie_pc_hi20"), /* larch_reloc_type_name */ |
| |
| LOONGARCH_HOWTO (R_LARCH_TLS_IE_PC_LO12, /* type (88). */ |
| 0, /* rightshift. */ |
| 4, /* size. */ |
| 12, /* bitsize. */ |
| false, /* pc_relative. */ |
| 10, /* bitpos. */ |
| complain_overflow_signed, /* complain_on_overflow. */ |
| bfd_elf_generic_reloc, /* special_function. */ |
| "R_LARCH_TLS_IE_PC_LO12", /* name. */ |
| false, /* partial_inplace. */ |
| 0, /* src_mask */ |
| 0x3ffc00, /* dst_mask */ |
| false, /* pcrel_offset */ |
| BFD_RELOC_LARCH_TLS_IE_PC_LO12, /* bfd_reloc_code_real_type */ |
| reloc_bits, /* adjust_reloc_bits */ |
| "ie_pc_lo12"), /* larch_reloc_type_name */ |
| |
| LOONGARCH_HOWTO (R_LARCH_TLS_IE64_PC_LO20, /* type (89). */ |
| 32, /* rightshift. */ |
| 4, /* size. */ |
| 20, /* bitsize. */ |
| false, /* pc_relative. */ |
| 5, /* bitpos. */ |
| complain_overflow_signed, /* complain_on_overflow. */ |
| bfd_elf_generic_reloc, /* special_function. */ |
| "R_LARCH_TLS_IE64_PC_LO20", /* name. */ |
| false, /* partial_inplace. */ |
| 0, /* src_mask */ |
| 0x1ffffe0, /* dst_mask */ |
| false, /* pcrel_offset */ |
| BFD_RELOC_LARCH_TLS_IE64_PC_LO20, /* bfd_reloc_code_real_type */ |
| reloc_bits, /* adjust_reloc_bits */ |
| "ie64_pc_lo20"), /* larch_reloc_type_name */ |
| |
| LOONGARCH_HOWTO (R_LARCH_TLS_IE64_PC_HI12, /* type (90). */ |
| 52, /* rightshift. */ |
| 4, /* size. */ |
| 12, /* bitsize. */ |
| false, /* pc_relative. */ |
| 10, /* bitpos. */ |
| complain_overflow_signed, /* complain_on_overflow. */ |
| bfd_elf_generic_reloc, /* special_function. */ |
| "R_LARCH_TLS_IE64_PC_HI12", /* name. */ |
| false, /* partial_inplace. */ |
| 0, /* src_mask */ |
| 0x3ffc00, /* dst_mask */ |
| false, /* pcrel_offset */ |
| BFD_RELOC_LARCH_TLS_IE64_PC_HI12, /* bfd_reloc_code_real_type */ |
| reloc_bits, /* adjust_reloc_bits */ |
| "ie64_pc_hi12"), /* larch_reloc_type_name */ |
| |
| LOONGARCH_HOWTO (R_LARCH_TLS_IE_HI20, /* type (91). */ |
| 12, /* rightshift. */ |
| 4, /* size. */ |
| 20, /* bitsize. */ |
| false, /* pc_relative. */ |
| 5, /* bitpos. */ |
| complain_overflow_signed, /* complain_on_overflow. */ |
| bfd_elf_generic_reloc, /* special_function. */ |
| "R_LARCH_TLS_IE_HI20", /* name. */ |
| false, /* partial_inplace. */ |
| 0, /* src_mask */ |
| 0x1ffffe0, /* dst_mask */ |
| false, /* pcrel_offset */ |
| BFD_RELOC_LARCH_TLS_IE_HI20, /* bfd_reloc_code_real_type */ |
| reloc_bits, /* adjust_reloc_bits */ |
| "ie_hi20"), /* larch_reloc_type_name */ |
| |
| LOONGARCH_HOWTO (R_LARCH_TLS_IE_LO12, /* type (92). */ |
| 0, /* rightshift. */ |
| 4, /* size. */ |
| 12, /* bitsize. */ |
| false, /* pc_relative. */ |
| 10, /* bitpos. */ |
| complain_overflow_signed, /* complain_on_overflow. */ |
| bfd_elf_generic_reloc, /* special_function. */ |
| "R_LARCH_TLS_IE_LO12", /* name. */ |
| false, /* partial_inplace. */ |
| 0, /* src_mask */ |
| 0x3ffc00, /* dst_mask */ |
| false, /* pcrel_offset */ |
| BFD_RELOC_LARCH_TLS_IE_LO12, /* bfd_reloc_code_real_type */ |
| reloc_bits, /* adjust_reloc_bits */ |
| "ie_lo12"), /* larch_reloc_type_name */ |
| |
| LOONGARCH_HOWTO (R_LARCH_TLS_IE64_LO20, /* type (93). */ |
| 32, /* rightshift. */ |
| 4, /* size. */ |
| 20, /* bitsize. */ |
| false, /* pc_relative. */ |
| 5, /* bitpos. */ |
| complain_overflow_signed, /* complain_on_overflow. */ |
| bfd_elf_generic_reloc, /* special_function. */ |
| "R_LARCH_TLS_IE64_LO20", /* name. */ |
| false, /* partial_inplace. */ |
| 0, /* src_mask */ |
| 0x1ffffe0, /* dst_mask */ |
| false, /* pcrel_offset */ |
| BFD_RELOC_LARCH_TLS_IE64_LO20, /* bfd_reloc_code_real_type */ |
| reloc_bits, /* adjust_reloc_bits */ |
| "ie64_lo20"), /* larch_reloc_type_name */ |
| |
| LOONGARCH_HOWTO (R_LARCH_TLS_IE64_HI12, /* type (94). */ |
| 52, /* rightshift. */ |
| 4, /* size. */ |
| 12, /* bitsize. */ |
| false, /* pc_relative. */ |
| 10, /* bitpos. */ |
| complain_overflow_signed, /* complain_on_overflow. */ |
| bfd_elf_generic_reloc, /* special_function. */ |
| "R_LARCH_TLS_IE64_HI12", /* name. */ |
| false, /* partial_inplace. */ |
| 0, /* src_mask */ |
| 0x3ffc00, /* dst_mask */ |
| false, /* pcrel_offset */ |
| BFD_RELOC_LARCH_TLS_IE64_HI12, /* bfd_reloc_code_real_type */ |
| reloc_bits, /* adjust_reloc_bits */ |
| "ie64_hi12"), /* larch_reloc_type_name */ |
| |
| LOONGARCH_HOWTO (R_LARCH_TLS_LD_PC_HI20, /* type (95). */ |
| 12, /* rightshift. */ |
| 4, /* size. */ |
| 20, /* bitsize. */ |
| false, /* pc_relative. */ |
| 5, /* bitpos. */ |
| complain_overflow_signed, /* complain_on_overflow. */ |
| bfd_elf_generic_reloc, /* special_function. */ |
| "R_LARCH_TLS_LD_PC_HI20", /* name. */ |
| false, /* partial_inplace. */ |
| 0, /* src_mask */ |
| 0x1ffffe0, /* dst_mask */ |
| false, /* pcrel_offset */ |
| BFD_RELOC_LARCH_TLS_LD_PC_HI20, /* bfd_reloc_code_real_type */ |
| reloc_bits, /* adjust_reloc_bits */ |
| "ld_pc_hi20"), /* larch_reloc_type_name */ |
| |
| LOONGARCH_HOWTO (R_LARCH_TLS_LD_HI20, /* type (96). */ |
| 12, /* rightshift. */ |
| 4, /* size. */ |
| 20, /* bitsize. */ |
| false, /* pc_relative. */ |
| 5, /* bitpos. */ |
| complain_overflow_signed, /* complain_on_overflow. */ |
| bfd_elf_generic_reloc, /* special_function. */ |
| "R_LARCH_TLS_LD_HI20", /* name. */ |
| false, /* partial_inplace. */ |
| 0, /* src_mask */ |
| 0x1ffffe0, /* dst_mask */ |
| false, /* pcrel_offset */ |
| BFD_RELOC_LARCH_TLS_LD_HI20, /* bfd_reloc_code_real_type */ |
| reloc_bits, /* adjust_reloc_bits */ |
| "ld_hi20"), /* larch_reloc_type_name */ |
| |
| LOONGARCH_HOWTO (R_LARCH_TLS_GD_PC_HI20, /* type (97). */ |
| 12, /* rightshift. */ |
| 4, /* size. */ |
| 20, /* bitsize. */ |
| false, /* pc_relative. */ |
| 5, /* bitpos. */ |
| complain_overflow_signed, /* complain_on_overflow. */ |
| bfd_elf_generic_reloc, /* special_function. */ |
| "R_LARCH_TLS_GD_PC_HI20", /* name. */ |
| false, /* partial_inplace. */ |
| 0, /* src_mask */ |
| 0x1ffffe0, /* dst_mask */ |
| false, /* pcrel_offset */ |
| BFD_RELOC_LARCH_TLS_GD_PC_HI20, /* bfd_reloc_code_real_type */ |
| reloc_bits, /* adjust_reloc_bits */ |
| "gd_pc_hi20"), /* larch_reloc_type_name */ |
| |
| LOONGARCH_HOWTO (R_LARCH_TLS_GD_HI20, /* type (98). */ |
| 12, /* rightshift. */ |
| 4, /* size. */ |
| 20, /* bitsize. */ |
| false, /* pc_relative. */ |
| 5, /* bitpos. */ |
| complain_overflow_signed, /* complain_on_overflow. */ |
| bfd_elf_generic_reloc, /* special_function. */ |
| "R_LARCH_TLS_GD_HI20", /* name. */ |
| false, /* partial_inplace. */ |
| 0, /* src_mask */ |
| 0x1ffffe0, /* dst_mask */ |
| false, /* pcrel_offset */ |
| BFD_RELOC_LARCH_TLS_GD_HI20, /* bfd_reloc_code_real_type */ |
| reloc_bits, /* adjust_reloc_bits */ |
| "gd_hi20"), /* larch_reloc_type_name */ |
| |
| /* 32-bit PC relative. */ |
| LOONGARCH_HOWTO (R_LARCH_32_PCREL, /* type (99). */ |
| 0, /* rightshift. */ |
| 4, /* size. */ |
| 32, /* bitsize. */ |
| true, /* pc_relative. */ |
| 0, /* bitpos. */ |
| complain_overflow_signed, /* complain_on_overflow. */ |
| bfd_elf_generic_reloc, /* special_function. */ |
| "R_LARCH_32_PCREL", /* name. */ |
| false, /* partial_inplace. */ |
| 0, /* src_mask */ |
| 0xffffffff, /* dst_mask */ |
| false, /* pcrel_offset */ |
| BFD_RELOC_LARCH_32_PCREL, /* bfd_reloc_code_real_type */ |
| NULL, /* adjust_reloc_bits */ |
| NULL), /* larch_reloc_type_name */ |
| |
| /* The paired relocation may be relaxed. */ |
| LOONGARCH_HOWTO (R_LARCH_RELAX, /* type (100). */ |
| 0, /* rightshift */ |
| 1, /* size */ |
| 0, /* bitsize */ |
| false, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_dont, /* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_LARCH_RELAX", /* name */ |
| false, /* partial_inplace */ |
| 0, /* src_mask */ |
| 0, /* dst_mask */ |
| false, /* pcrel_offset */ |
| BFD_RELOC_LARCH_RELAX, /* bfd_reloc_code_real_type */ |
| NULL, /* adjust_reloc_bits */ |
| NULL), /* larch_reloc_type_name */ |
| |
| /* Delete relaxed instruction. */ |
| LOONGARCH_HOWTO (R_LARCH_DELETE, /* type (101). */ |
| 0, /* rightshift. */ |
| 0, /* size. */ |
| 0, /* bitsize. */ |
| false, /* pc_relative. */ |
| 0, /* bitpos. */ |
| complain_overflow_dont, /* complain_on_overflow. */ |
| bfd_elf_generic_reloc, /* special_function. */ |
| "R_LARCH_DELETE", /* name. */ |
| false, /* partial_inplace. */ |
| 0, /* src_mask. */ |
| 0, /* dst_mask. */ |
| false, /* pcrel_offset. */ |
| BFD_RELOC_LARCH_DELETE, /* bfd_reloc_code_real_type. */ |
| NULL, /* adjust_reloc_bits. */ |
| NULL), /* larch_reloc_type_name. */ |
| |
| /* Indicates an alignment statement. f the symbol index is 0, |
| the addend indicates the number of bytes occupied by nop instructions |
| at the relocation offset. The alignment boundary is specified by the |
| addend rounded up to the next power of two. |
| If the symbol index is not 0, the addend indicates the first and third |
| expressions of .align. The lowest 8 bits are used to represent the first |
| expression, other bits are used to represent the third expression. */ |
| LOONGARCH_HOWTO (R_LARCH_ALIGN, /* type (102). */ |
| 0, /* rightshift. */ |
| 0, /* size. */ |
| 0, /* bitsize. */ |
| false, /* pc_relative. */ |
| 0, /* bitpos. */ |
| complain_overflow_dont, /* complain_on_overflow. */ |
| bfd_elf_generic_reloc, /* special_function. */ |
| "R_LARCH_ALIGN", /* name. */ |
| false, /* partial_inplace. */ |
| 0, /* src_mask. */ |
| 0, /* dst_mask. */ |
| false, /* pcrel_offset. */ |
| BFD_RELOC_LARCH_ALIGN, /* bfd_reloc_code_real_type. */ |
| NULL, /* adjust_reloc_bits. */ |
| NULL), /* larch_reloc_type_name. */ |
| |
| /* For pcaddi and pcala_hi20 + pcala_lo12 can relax to pcrel_20. */ |
| LOONGARCH_HOWTO (R_LARCH_PCREL20_S2, /* type (103). */ |
| 2, /* rightshift. */ |
| 4, /* size. */ |
| 20, /* bitsize. */ |
| false, /* pc_relative. */ |
| 5, /* bitpos. */ |
| complain_overflow_signed, /* complain_on_overflow. */ |
| bfd_elf_generic_reloc, /* special_function. */ |
| "R_LARCH_PCREL20_S2", /* name. */ |
| false, /* partial_inplace. */ |
| 0, /* src_mask. */ |
| 0x1ffffe0, /* dst_mask. */ |
| false, /* pcrel_offset. */ |
| BFD_RELOC_LARCH_PCREL20_S2, /* bfd_reloc_code_real_type. */ |
| reloc_sign_bits, /* adjust_reloc_bits. */ |
| "pcrel_20"), /* larch_reloc_type_name. */ |
| |
| /* Canonical Frame Address. */ |
| LOONGARCH_HOWTO (R_LARCH_CFA, /* type (104). */ |
| 0, /* rightshift. */ |
| 0, /* size. */ |
| 0, /* bitsize. */ |
| false, /* pc_relative. */ |
| 0, /* bitpos. */ |
| complain_overflow_dont, /* complain_on_overflow. */ |
| bfd_elf_generic_reloc, /* special_function. */ |
| "R_LARCH_CFA", /* name. */ |
| false, /* partial_inplace. */ |
| 0, /* src_mask. */ |
| 0, /* dst_mask. */ |
| false, /* pcrel_offset. */ |
| BFD_RELOC_LARCH_CFA, /* bfd_reloc_code_real_type. */ |
| NULL, /* adjust_reloc_bits. */ |
| NULL), /* larch_reloc_type_name. */ |
| |
| /* 6-bit in-place addition, for local label subtraction |
| to calculate DW_CFA_advance_loc. */ |
| LOONGARCH_HOWTO (R_LARCH_ADD6, /* type (105). */ |
| 0, /* rightshift. */ |
| 1, /* size. */ |
| 8, /* bitsize. */ |
| false, /* pc_relative. */ |
| 0, /* bitpos. */ |
| complain_overflow_dont, /* complain_on_overflow. */ |
| loongarch_elf_add_sub_reloc, /* special_function. */ |
| "R_LARCH_ADD6", /* name. */ |
| false, /* partial_inplace. */ |
| 0, /* src_mask. */ |
| 0x3f, /* dst_mask. */ |
| false, /* pcrel_offset. */ |
| BFD_RELOC_LARCH_ADD6, /* bfd_reloc_code_real_type. */ |
| reloc_bits, /* adjust_reloc_bits. */ |
| NULL), /* larch_reloc_type_name. */ |
| |
| /* 6-bit in-place subtraction, for local label subtraction |
| to calculate DW_CFA_advance_loc. */ |
| LOONGARCH_HOWTO (R_LARCH_SUB6, /* type (106). */ |
| 0, /* rightshift. */ |
| 1, /* size. */ |
| 8, /* bitsize. */ |
| false, /* pc_relative. */ |
| 0, /* bitpos. */ |
| complain_overflow_dont, /* complain_on_overflow. */ |
| loongarch_elf_add_sub_reloc, /* special_function. */ |
| "R_LARCH_SUB6", /* name. */ |
| false, /* partial_inplace. */ |
| 0, /* src_mask. */ |
| 0x3f, /* dst_mask. */ |
| false, /* pcrel_offset. */ |
| BFD_RELOC_LARCH_SUB6, /* bfd_reloc_code_real_type. */ |
| reloc_bits, /* adjust_reloc_bits. */ |
| NULL), /* larch_reloc_type_name. */ |
| |
| /* The length of unsigned-leb128 is variable, just assume the |
| size is one byte here. |
| uleb128 in-place addition, for local label subtraction. */ |
| LOONGARCH_HOWTO (R_LARCH_ADD_ULEB128, /* type (107). */ |
| 0, /* rightshift. */ |
| 1, /* size. */ |
| 0, /* bitsize. */ |
| false, /* pc_relative. */ |
| 0, /* bitpos. */ |
| complain_overflow_dont, /* complain_on_overflow. */ |
| loongarch_elf_add_sub_reloc_uleb128, /* special_function. */ |
| "R_LARCH_ADD_ULEB128", /* name. */ |
| false, /* partial_inplace. */ |
| 0, /* src_mask. */ |
| 0, /* dst_mask. */ |
| false, /* pcrel_offset. */ |
| BFD_RELOC_LARCH_ADD_ULEB128, /* bfd_reloc_code_real_type. */ |
| NULL, /* adjust_reloc_bits. */ |
| NULL), /* larch_reloc_type_name. */ |
| |
| /* The length of unsigned-leb128 is variable, just assume the |
| size is one byte here. |
| uleb128 in-place subtraction, for local label subtraction. */ |
| LOONGARCH_HOWTO (R_LARCH_SUB_ULEB128, /* type (108). */ |
| 0, /* rightshift. */ |
| 1, /* size. */ |
| 0, /* bitsize. */ |
| false, /* pc_relative. */ |
| 0, /* bitpos. */ |
| complain_overflow_dont, /* complain_on_overflow. */ |
| loongarch_elf_add_sub_reloc_uleb128, /* special_function. */ |
| "R_LARCH_SUB_ULEB128", /* name. */ |
| false, /* partial_inplace. */ |
| 0, /* src_mask. */ |
| 0, /* dst_mask. */ |
| false, /* pcrel_offset. */ |
| BFD_RELOC_LARCH_SUB_ULEB128, /* bfd_reloc_code_real_type. */ |
| NULL, /* adjust_reloc_bits. */ |
| NULL), /* larch_reloc_type_name. */ |
| |
| /* 64-bit PC relative. */ |
| LOONGARCH_HOWTO (R_LARCH_64_PCREL, /* type (109). */ |
| 0, /* rightshift. */ |
| 8, /* size. */ |
| 64, /* bitsize. */ |
| true, /* pc_relative. */ |
| 0, /* bitpos. */ |
| complain_overflow_signed, /* complain_on_overflow. */ |
| bfd_elf_generic_reloc, /* special_function. */ |
| "R_LARCH_64_PCREL", /* name. */ |
| false, /* partial_inplace. */ |
| 0, /* src_mask */ |
| 0xffffffffffffffff, /* dst_mask */ |
| false, /* pcrel_offset */ |
| BFD_RELOC_LARCH_64_PCREL, /* bfd_reloc_code_real_type */ |
| NULL, /* adjust_reloc_bits */ |
| NULL), /* larch_reloc_type_name */ |
| |
| /* Used for medium code model function call pcaddu18i+jirl, |
| these two instructions must adjacent. */ |
| LOONGARCH_HOWTO (R_LARCH_CALL36, /* type (110). */ |
| 2, /* rightshift. */ |
| 8, /* size. */ |
| 36, /* bitsize. */ |
| true, /* pc_relative. */ |
| 0, /* bitpos. */ |
| complain_overflow_signed, /* complain_on_overflow. */ |
| bfd_elf_generic_reloc, /* special_function. */ |
| "R_LARCH_CALL36", /* name. */ |
| false, /* partial_inplace. */ |
| 0, /* src_mask. */ |
| 0x03fffc0001ffffe0, /* dst_mask. */ |
| false, /* pcrel_offset. */ |
| BFD_RELOC_LARCH_CALL36, /* bfd_reloc_code_real_type. */ |
| reloc_sign_bits, /* adjust_reloc_bits. */ |
| "call36"), /* larch_reloc_type_name. */ |
| |
| /* TLS_DESC PCREL. */ |
| LOONGARCH_HOWTO (R_LARCH_TLS_DESC_PC_HI20, /* type (111). */ |
| 12, /* rightshift. */ |
| 4, /* size. */ |
| 20, /* bitsize. */ |
| true, /* pc_relative. */ |
| 5, /* bitpos. */ |
| complain_overflow_signed, /* complain_on_overflow. */ |
| bfd_elf_generic_reloc, /* special_function. */ |
| "R_LARCH_TLS_DESC_PC_HI20", /* name. */ |
| false, /* partial_inplace. */ |
| 0, /* src_mask. */ |
| 0x1ffffe0, /* dst_mask. */ |
| false, /* pcrel_offset. */ |
| BFD_RELOC_LARCH_TLS_DESC_PC_HI20, /* bfd_reloc_code_real_type. */ |
| reloc_bits, /* adjust_reloc_bits. */ |
| "desc_pc_hi20"), /* larch_reloc_type_name. */ |
| |
| LOONGARCH_HOWTO (R_LARCH_TLS_DESC_PC_LO12, /* type (112). */ |
| 0, /* rightshift. */ |
| 4, /* size. */ |
| 12, /* bitsize. */ |
| true, /* pc_relative. */ |
| 10, /* bitpos. */ |
| complain_overflow_signed, /* complain_on_overflow. */ |
| bfd_elf_generic_reloc, /* special_function. */ |
| "R_LARCH_TLS_DESC_PC_LO12", /* name. */ |
| false, /* partial_inplace. */ |
| 0, /* src_mask. */ |
| 0x3ffc00, /* dst_mask. */ |
| false, /* pcrel_offset. */ |
| BFD_RELOC_LARCH_TLS_DESC_PC_LO12, /* bfd_reloc_code_real_type. */ |
| reloc_bits, /* adjust_reloc_bits. */ |
| "desc_pc_lo12"), /* larch_reloc_type_name. */ |
| |
| /* TLS_DESC64 LARGE PCREL. */ |
| LOONGARCH_HOWTO (R_LARCH_TLS_DESC64_PC_LO20, /* type (113). */ |
| 32, /* rightshift. */ |
| 8, /* size. */ |
| 20, /* bitsize. */ |
| true, /* pc_relative. */ |
| 5, /* bitpos. */ |
| complain_overflow_signed, /* complain_on_overflow. */ |
| bfd_elf_generic_reloc, /* special_function. */ |
| "R_LARCH_TLS_DESC64_PC_LO20", /* name. */ |
| false, /* partial_inplace. */ |
| 0, /* src_mask. */ |
| 0x1ffffe0, /* dst_mask. */ |
| false, /* pcrel_offset. */ |
| BFD_RELOC_LARCH_TLS_DESC64_PC_LO20, /* bfd_reloc_code_real_type. */ |
| reloc_bits, /* adjust_reloc_bits. */ |
| "desc64_pc_lo20"), /* larch_reloc_type_name. */ |
| |
| LOONGARCH_HOWTO (R_LARCH_TLS_DESC64_PC_HI12, /* type (114). */ |
| 52, /* rightshift. */ |
| 8, /* size. */ |
| 12, /* bitsize. */ |
| true, /* pc_relative. */ |
| 10, /* bitpos. */ |
| complain_overflow_signed, /* complain_on_overflow. */ |
| bfd_elf_generic_reloc, /* special_function. */ |
| "R_LARCH_TLS_DESC64_PC_HI12", /* name. */ |
| false, /* partial_inplace. */ |
| 0, /* src_mask. */ |
| 0x3ffc00, /* dst_mask. */ |
| false, /* pcrel_offset. */ |
| BFD_RELOC_LARCH_TLS_DESC64_PC_HI12, /* bfd_reloc_code_real_type. */ |
| reloc_bits, /* adjust_reloc_bits. */ |
| "desc64_pc_hi12"), /* larch_reloc_type_name. */ |
| |
| /* TLS_DESC ABS. */ |
| LOONGARCH_HOWTO (R_LARCH_TLS_DESC_HI20, /* type (115). */ |
| 12, /* rightshift. */ |
| 4, /* size. */ |
| 20, /* bitsize. */ |
| false, /* pc_relative. */ |
| 5, /* bitpos. */ |
| complain_overflow_signed, /* complain_on_overflow. */ |
| bfd_elf_generic_reloc, /* special_function. */ |
| "R_LARCH_TLS_DESC_HI20", /* name. */ |
| false, /* partial_inplace. */ |
| 0, /* src_mask. */ |
| 0x1ffffe0, /* dst_mask. */ |
| false, /* pcrel_offset. */ |
| BFD_RELOC_LARCH_TLS_DESC_HI20, /* bfd_reloc_code_real_type. */ |
| reloc_bits, /* adjust_reloc_bits. */ |
| "desc_hi20"), /* larch_reloc_type_name. */ |
| |
| LOONGARCH_HOWTO (R_LARCH_TLS_DESC_LO12, /* type (116). */ |
| 0, /* rightshift. */ |
| 4, /* size. */ |
| 12, /* bitsize. */ |
| false, /* pc_relative. */ |
| 10, /* bitpos. */ |
| complain_overflow_signed, /* complain_on_overflow. */ |
| bfd_elf_generic_reloc, /* special_function. */ |
| "R_LARCH_TLS_DESC_LO12", /* name. */ |
| false, /* partial_inplace. */ |
| 0, /* src_mask. */ |
| 0x3ffc00, /* dst_mask. */ |
| false, /* pcrel_offset. */ |
| BFD_RELOC_LARCH_TLS_DESC_LO12, /* bfd_reloc_code_real_type. */ |
| reloc_bits, /* adjust_reloc_bits. */ |
| "desc_lo12"), /* larch_reloc_type_name. */ |
| |
| /* TLS_DESC64 LARGE ABS. */ |
| LOONGARCH_HOWTO (R_LARCH_TLS_DESC64_LO20, /* type (117). */ |
| 32, /* rightshift. */ |
| 8, /* size. */ |
| 20, /* bitsize. */ |
| false, /* pc_relative. */ |
| 5, /* bitpos. */ |
| complain_overflow_signed, /* complain_on_overflow. */ |
| bfd_elf_generic_reloc, /* special_function. */ |
| "R_LARCH_TLS_DESC64_LO20", /* name. */ |
| false, /* partial_inplace. */ |
| 0, /* src_mask. */ |
| 0x1ffffe0, /* dst_mask. */ |
| false, /* pcrel_offset. */ |
| BFD_RELOC_LARCH_TLS_DESC64_LO20, /* bfd_reloc_code_real_type. */ |
| reloc_bits, /* adjust_reloc_bits. */ |
| "desc64_lo20"), /* larch_reloc_type_name. */ |
| |
| LOONGARCH_HOWTO (R_LARCH_TLS_DESC64_HI12, /* type (118). */ |
| 52, /* rightshift. */ |
| 8, /* size. */ |
| 12, /* bitsize. */ |
| false, /* pc_relative. */ |
| 10, /* bitpos. */ |
| complain_overflow_signed, /* complain_on_overflow. */ |
| bfd_elf_generic_reloc, /* special_function. */ |
| "R_LARCH_TLS_DESC64_HI12", /* name. */ |
| false, /* partial_inplace. */ |
| 0, /* src_mask. */ |
| 0x3ffc00, /* dst_mask. */ |
| false, /* pcrel_offset. */ |
| BFD_RELOC_LARCH_TLS_DESC64_HI12, /* bfd_reloc_code_real_type. */ |
| reloc_bits, /* adjust_reloc_bits. */ |
| "desc64_hi12"), /* larch_reloc_type_name. */ |
| |
| LOONGARCH_HOWTO (R_LARCH_TLS_DESC_LD, /* type (119). */ |
| 0, /* rightshift. */ |
| 4, /* size. */ |
| 0, /* bitsize. */ |
| true, /* pc_relative. */ |
| 0, /* bitpos. */ |
| complain_overflow_signed, /* complain_on_overflow. */ |
| bfd_elf_generic_reloc, /* special_function. */ |
| "R_LARCH_TLS_DESC_LD", /* name. */ |
| false, /* partial_inplace. */ |
| 0, /* src_mask. */ |
| 0, /* dst_mask. */ |
| false, /* pcrel_offset. */ |
| BFD_RELOC_LARCH_TLS_DESC_LD, /* bfd_reloc_code_real_type. */ |
| NULL, /* adjust_reloc_bits. */ |
| "desc_ld"), /* larch_reloc_type_name. */ |
| |
| LOONGARCH_HOWTO (R_LARCH_TLS_DESC_CALL, /* type (120). */ |
| 0, /* rightshift. */ |
| 4, /* size. */ |
| 0, /* bitsize. */ |
| false, /* pc_relative. */ |
| 0, /* bitpos. */ |
| complain_overflow_dont, /* complain_on_overflow. */ |
| bfd_elf_generic_reloc, /* special_function. */ |
| "R_LARCH_TLS_DESC_CALL", /* name. */ |
| false, /* partial_inplace. */ |
| 0, /* src_mask. */ |
| 0, /* dst_mask. */ |
| false, /* pcrel_offset. */ |
| BFD_RELOC_LARCH_TLS_DESC_CALL, /* bfd_reloc_code_real_type. */ |
| NULL, /* adjust_reloc_bits. */ |
| "desc_call"), /* larch_reloc_type_name. */ |
| |
| LOONGARCH_HOWTO (R_LARCH_TLS_LE_HI20_R, /* type (121). */ |
| 12, /* rightshift. */ |
| 4, /* size. */ |
| 20, /* bitsize. */ |
| false, /* pc_relative. */ |
| 5, /* bitpos. */ |
| complain_overflow_signed, /* complain_on_overflow. */ |
| bfd_elf_generic_reloc, /* special_function. */ |
| "R_LARCH_TLS_LE_HI20_R", /* name. */ |
| false, /* partial_inplace. */ |
| 0, /* src_mask. */ |
| 0x1ffffe0, /* dst_mask. */ |
| false, /* pcrel_offset. */ |
| BFD_RELOC_LARCH_TLS_LE_HI20_R, /* bfd_reloc_code_real_type. */ |
| reloc_bits, /* adjust_reloc_bits. */ |
| "le_hi20_r"), /* larch_reloc_type_name. */ |
| |
| LOONGARCH_HOWTO (R_LARCH_TLS_LE_ADD_R, /* type (122). */ |
| 0, /* rightshift. */ |
| 0, /* size. */ |
| 0, /* bitsize. */ |
| false, /* pc_relative. */ |
| 0, /* bitpos. */ |
| complain_overflow_dont, /* complain_on_overflow. */ |
| bfd_elf_generic_reloc, /* special_function. */ |
| "R_LARCH_TLS_LE_ADD_R", /* name. */ |
| false, /* partial_inplace. */ |
| 0, /* src_mask. */ |
| 0, /* dst_mask. */ |
| false, /* pcrel_offset. */ |
| BFD_RELOC_LARCH_TLS_LE_ADD_R, /* bfd_reloc_code_real_type. */ |
| NULL, /* adjust_reloc_bits. */ |
| "le_add_r"), /* larch_reloc_type_name. */ |
| |
| LOONGARCH_HOWTO (R_LARCH_TLS_LE_LO12_R, /* type (123). */ |
| 0, /* rightshift. */ |
| 4, /* size. */ |
| 12, /* bitsize. */ |
| false, /* pc_relative. */ |
| 10, /* bitpos. */ |
| complain_overflow_signed, /* complain_on_overflow. */ |
| bfd_elf_generic_reloc, /* special_function. */ |
| "R_LARCH_TLS_LE_LO12_R", /* name. */ |
| false, /* partial_inplace. */ |
| 0, /* src_mask. */ |
| 0x3ffc00, /* dst_mask. */ |
| false, /* pcrel_offset. */ |
| BFD_RELOC_LARCH_TLS_LE_LO12_R, /* bfd_reloc_code_real_type. */ |
| reloc_bits, /* adjust_reloc_bits. */ |
| "le_lo12_r"), /* larch_reloc_type_name. */ |
| |
| /* For pcaddi, ld_pc_hi20 + ld_pc_lo12 can relax to ld_pcrel20_s2. */ |
| LOONGARCH_HOWTO (R_LARCH_TLS_LD_PCREL20_S2, /* type (124). */ |
| 2, /* rightshift. */ |
| 4, /* size. */ |
| 20, /* bitsize. */ |
| false, /* pc_relative. */ |
| 5, /* bitpos. */ |
| complain_overflow_signed, /* complain_on_overflow. */ |
| bfd_elf_generic_reloc, /* special_function. */ |
| "R_LARCH_TLS_LD_PCREL20_S2", /* name. */ |
| false, /* partial_inplace. */ |
| 0, /* src_mask. */ |
| 0x1ffffe0, /* dst_mask. */ |
| true, /* pcrel_offset. */ |
| BFD_RELOC_LARCH_TLS_LD_PCREL20_S2, /* bfd_reloc_code_real_type. */ |
| reloc_sign_bits, /* adjust_reloc_bits. */ |
| "ld_pcrel_20"), /* larch_reloc_type_name. */ |
| |
| /* For pcaddi, gd_pc_hi20 + gd_pc_lo12 can relax to gd_pcrel20_s2. */ |
| LOONGARCH_HOWTO (R_LARCH_TLS_GD_PCREL20_S2, /* type (125). */ |
| 2, /* rightshift. */ |
| 4, /* size. */ |
| 20, /* bitsize. */ |
| false, /* pc_relative. */ |
| 5, /* bitpos. */ |
| complain_overflow_signed, /* complain_on_overflow. */ |
| bfd_elf_generic_reloc, /* special_function. */ |
| "R_LARCH_TLS_GD_PCREL20_S2", /* name. */ |
| false, /* partial_inplace. */ |
| 0, /* src_mask. */ |
| 0x1ffffe0, /* dst_mask. */ |
| true, /* pcrel_offset. */ |
| BFD_RELOC_LARCH_TLS_GD_PCREL20_S2, /* bfd_reloc_code_real_type. */ |
| reloc_sign_bits, /* adjust_reloc_bits. */ |
| "gd_pcrel_20"), /* larch_reloc_type_name. */ |
| |
| /* For pcaddi, desc_pc_hi20 + desc_pc_lo12 can relax to desc_pcrel20_s2. */ |
| LOONGARCH_HOWTO (R_LARCH_TLS_DESC_PCREL20_S2, /* type (126). */ |
| 2, /* rightshift. */ |
| 4, /* size. */ |
| 20, /* bitsize. */ |
| false, /* pc_relative. */ |
| 5, /* bitpos. */ |
| complain_overflow_signed, /* complain_on_overflow. */ |
| bfd_elf_generic_reloc, /* special_function. */ |
| "R_LARCH_TLS_DESC_PCREL20_S2", /* name. */ |
| false, /* partial_inplace. */ |
| 0, /* src_mask. */ |
| 0x1ffffe0, /* dst_mask. */ |
| true, /* pcrel_offset. */ |
| BFD_RELOC_LARCH_TLS_DESC_PCREL20_S2, /* bfd_reloc_code_real_type. */ |
| reloc_sign_bits, /* adjust_reloc_bits. */ |
| "desc_pcrel_20"), /* larch_reloc_type_name. */ |
| }; |
| |
| reloc_howto_type * |
| loongarch_elf_rtype_to_howto (bfd *abfd, unsigned int r_type) |
| { |
| if (r_type < R_LARCH_count) |
| { |
| BFD_ASSERT (ARRAY_SIZE (loongarch_howto_table) == R_LARCH_count); |
| BFD_ASSERT (loongarch_howto_table[r_type].howto.type == r_type); |
| return &loongarch_howto_table[r_type].howto; |
| } |
| |
| (*_bfd_error_handler) (_("%pB: unsupported relocation type %#x"), |
| abfd, r_type); |
| bfd_set_error (bfd_error_bad_value); |
| return NULL; |
| } |
| |
| reloc_howto_type * |
| loongarch_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name) |
| { |
| for (size_t i = 0; i < ARRAY_SIZE (loongarch_howto_table); i++) |
| if (loongarch_howto_table[i].howto.name |
| && strcasecmp (loongarch_howto_table[i].howto.name, r_name) == 0) |
| return &loongarch_howto_table[i].howto; |
| |
| (*_bfd_error_handler) (_("%pB: unsupported relocation type %s"), |
| abfd, r_name); |
| bfd_set_error (bfd_error_bad_value); |
| return NULL; |
| } |
| |
| /* Cost so much. */ |
| reloc_howto_type * |
| loongarch_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, |
| bfd_reloc_code_real_type code) |
| { |
| BFD_ASSERT (ARRAY_SIZE (loongarch_howto_table) == R_LARCH_count); |
| |
| /* Fast search for new reloc types. */ |
| if (BFD_RELOC_LARCH_B16 <= code && code < BFD_RELOC_LARCH_RELAX) |
| { |
| BFD_ASSERT (BFD_RELOC_LARCH_RELAX - BFD_RELOC_LARCH_B16 |
| == R_LARCH_RELAX - R_LARCH_B16); |
| loongarch_reloc_howto_type *ht; |
| ht = &loongarch_howto_table[code - BFD_RELOC_LARCH_B16 + R_LARCH_B16]; |
| BFD_ASSERT (ht->bfd_type == code); |
| return &ht->howto; |
| } |
| |
| for (size_t i = 0; i < ARRAY_SIZE (loongarch_howto_table); i++) |
| if (loongarch_howto_table[i].bfd_type == code) |
| return &loongarch_howto_table[i].howto; |
| |
| (*_bfd_error_handler) (_("%pB: unsupported bfd relocation type %#x"), |
| abfd, code); |
| bfd_set_error (bfd_error_bad_value); |
| return NULL; |
| } |
| |
| bfd_reloc_code_real_type |
| loongarch_larch_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, |
| const char *l_r_name) |
| { |
| for (size_t i = 0; i < ARRAY_SIZE (loongarch_howto_table); i++) |
| { |
| loongarch_reloc_howto_type *lht = &loongarch_howto_table[i]; |
| if ((NULL != lht->larch_reloc_type_name) |
| && (0 == strcmp (lht->larch_reloc_type_name, l_r_name))) |
| return lht->bfd_type; |
| } |
| |
| return BFD_RELOC_NONE; |
| } |
| |
| |
| /* Functions for reloc bits field. |
| 1. Signed extend *fix_val. |
| 2. Return false if overflow. */ |
| |
| #define LARCH_RELOC_BFD_VMA_BIT_MASK(bitsize) \ |
| (~((((bfd_vma)0x1) << (bitsize)) - 1)) |
| |
| /* Adjust val to perform insn |
| BFD_RELOC_LARCH_SOP_POP_32_S_10_5 |
| BFD_RELOC_LARCH_SOP_POP_32_S_10_12 |
| BFD_RELOC_LARCH_SOP_POP_32_U_10_12 |
| BFD_RELOC_LARCH_SOP_POP_32_S_10_16 |
| BFD_RELOC_LARCH_SOP_POP_32_S_5_20 |
| BFD_RELOC_LARCH_SOP_POP_32_U. */ |
| |
| static bool |
| reloc_bits (bfd *abfd ATTRIBUTE_UNUSED, |
| reloc_howto_type *howto, |
| bfd_vma *fix_val) |
| { |
| bfd_signed_vma val = (bfd_signed_vma)(*fix_val); |
| bfd_signed_vma mask = ((bfd_signed_vma)0x1 << howto->bitsize) - 1; |
| |
| val = val >> howto->rightshift; |
| |
| /* Perform insn bits field. */ |
| val = val & mask; |
| val <<= howto->bitpos; |
| |
| *fix_val = (bfd_vma)val; |
| |
| return true; |
| } |
| |
| static bool |
| reloc_bits_sanity (bfd *abfd, reloc_howto_type *howto, bfd_vma *fix_val, |
| unsigned int sign) |
| { |
| if ((sign && howto->complain_on_overflow != complain_overflow_signed) |
| || (!sign && howto->complain_on_overflow != complain_overflow_unsigned)) |
| return false; |
| |
| bfd_signed_vma val = (bfd_signed_vma)(*fix_val); |
| |
| /* Check alignment. FIXME: if rightshift is not alingment. */ |
| if (howto->rightshift |
| && (val & ((((bfd_signed_vma) 1) << howto->rightshift) - 1))) |
| { |
| /* The as passes NULL casued internal error, so it can not use _bfd_error_handler |
| output details, ld is not affected. */ |
| if (abfd != NULL) |
| { |
| (*_bfd_error_handler) (_("%pB: relocation %s right shift %d error 0x%lx"), |
| abfd, howto->name, howto->rightshift, (long) val); |
| bfd_set_error (bfd_error_bad_value); |
| } |
| return false; |
| } |
| |
| bfd_signed_vma mask = ((bfd_signed_vma)0x1 << (howto->bitsize |
| + howto->rightshift - sign)) - 1; |
| |
| /* Positive number: high part is all 0; |
| Negative number: if high part is not all 0, high part must be all 1. |
| high part: from sign bit to highest bit. */ |
| if ((val & ~mask) && ((val & ~mask) != ~mask)) |
| { |
| /* The as passes NULL casued internal error, so it can not use _bfd_error_handler |
| output details, ld is not affected. */ |
| if (abfd != NULL) |
| { |
| (*_bfd_error_handler) (_("%pB: relocation %s overflow 0x%lx"), |
| abfd, howto->name, (long) val); |
| bfd_set_error (bfd_error_bad_value); |
| } |
| return false; |
| } |
| |
| val = val >> howto->rightshift; |
| /* can delete? */ |
| mask = ((bfd_signed_vma)0x1 << howto->bitsize) - 1; |
| val = val & mask; |
| |
| switch (howto->type) |
| { |
| case R_LARCH_SOP_POP_32_S_0_10_10_16_S2: |
| case R_LARCH_B26: |
| /* Perform insn bits field. 15:0<<10, 25:16>>16. */ |
| val = ((val & 0xffff) << 10) | ((val >> 16) & 0x3ff); |
| break; |
| case R_LARCH_SOP_POP_32_S_0_5_10_16_S2: |
| case R_LARCH_B21: |
| /* Perform insn bits field. 15:0<<10, 20:16>>16. */ |
| val = ((val & 0xffff) << 10) | ((val >> 16) & 0x1f); |
| break; |
| case R_LARCH_CALL36: |
| /* 0x8000: If low 16-bit immediate greater than 0x7fff, |
| it become to a negative number due to sign-extended, |
| so the high part need to add 0x8000. */ |
| val = (((val + 0x8000) >> 16) << 5) | (((val & 0xffff) << 10) << 32); |
| break; |
| default: |
| val <<= howto->bitpos; |
| break; |
| } |
| |
| *fix_val = val; |
| return true; |
| } |
| |
| static bool |
| reloc_sign_bits (bfd *abfd, reloc_howto_type *howto, bfd_vma *fix_val) |
| { |
| return reloc_bits_sanity (abfd, howto, fix_val, 1); |
| } |
| |
| static bool |
| reloc_unsign_bits (bfd *abfd, reloc_howto_type *howto, bfd_vma *fix_val) |
| { |
| return reloc_bits_sanity (abfd, howto, fix_val, 0); |
| } |
| |
| bool |
| loongarch_adjust_reloc_bitsfield (bfd *abfd, reloc_howto_type *howto, |
| bfd_vma *fix_val) |
| { |
| BFD_ASSERT (((loongarch_reloc_howto_type *)howto)->adjust_reloc_bits); |
| return ((loongarch_reloc_howto_type *) |
| howto)->adjust_reloc_bits (abfd, howto, fix_val); |
| } |
| |
| static bfd_reloc_status_type |
| loongarch_elf_add_sub_reloc (bfd *abfd, |
| arelent *reloc_entry, |
| asymbol *symbol, |
| void *data, |
| asection *input_section, |
| bfd *output_bfd, |
| char **error_message ATTRIBUTE_UNUSED) |
| { |
| reloc_howto_type *howto = reloc_entry->howto; |
| bfd_vma relocation; |
| |
| if (output_bfd != NULL |
| && (symbol->flags & BSF_SECTION_SYM) == 0 |
| && (!reloc_entry->howto->partial_inplace || reloc_entry->addend == 0)) |
| { |
| reloc_entry->address += input_section->output_offset; |
| return bfd_reloc_ok; |
| } |
| |
| if (output_bfd != NULL) |
| return bfd_reloc_continue; |
| |
| relocation = symbol->value + symbol->section->output_section->vma |
| + symbol->section->output_offset + reloc_entry->addend; |
| |
| bfd_size_type octets = reloc_entry->address |
| * bfd_octets_per_byte (abfd, input_section); |
| if (!bfd_reloc_offset_in_range (reloc_entry->howto, abfd, |
| input_section, octets)) |
| return bfd_reloc_outofrange; |
| |
| bfd_vma old_value = bfd_get (howto->bitsize, abfd, |
| data + reloc_entry->address); |
| |
| switch (howto->type) |
| { |
| case R_LARCH_ADD6: |
| case R_LARCH_ADD8: |
| case R_LARCH_ADD16: |
| case R_LARCH_ADD32: |
| case R_LARCH_ADD64: |
| relocation = old_value + relocation; |
| break; |
| |
| case R_LARCH_SUB6: |
| case R_LARCH_SUB8: |
| case R_LARCH_SUB16: |
| case R_LARCH_SUB32: |
| case R_LARCH_SUB64: |
| relocation = old_value - relocation; |
| break; |
| } |
| |
| bfd_put (howto->bitsize, abfd, relocation, data + reloc_entry->address); |
| |
| return bfd_reloc_ok; |
| } |
| |
| static bfd_reloc_status_type |
| loongarch_elf_add_sub_reloc_uleb128 (bfd *abfd, |
| arelent *reloc_entry, |
| asymbol *symbol, |
| void *data, |
| asection *input_section, |
| bfd *output_bfd, |
| char **error_message ATTRIBUTE_UNUSED) |
| { |
| reloc_howto_type *howto = reloc_entry->howto; |
| bfd_vma relocation; |
| |
| if (output_bfd != NULL |
| && (symbol->flags & BSF_SECTION_SYM) == 0 |
| && (!reloc_entry->howto->partial_inplace || reloc_entry->addend == 0)) |
| { |
| reloc_entry->address += input_section->output_offset; |
| return bfd_reloc_ok; |
| } |
| |
| if (output_bfd != NULL) |
| return bfd_reloc_continue; |
| |
| relocation = symbol->value + symbol->section->output_section->vma |
| + symbol->section->output_offset + reloc_entry->addend; |
| |
| bfd_size_type octets = reloc_entry->address |
| * bfd_octets_per_byte (abfd, input_section); |
| if (!bfd_reloc_offset_in_range (reloc_entry->howto, abfd, |
| input_section, octets)) |
| return bfd_reloc_outofrange; |
| |
| unsigned int len = 0; |
| bfd_byte *p = data + reloc_entry->address; |
| bfd_vma old_value = _bfd_read_unsigned_leb128 (abfd, p, &len); |
| |
| switch (howto->type) |
| { |
| case R_LARCH_ADD_ULEB128: |
| relocation = old_value + relocation; |
| break; |
| |
| case R_LARCH_SUB_ULEB128: |
| relocation = old_value - relocation; |
| break; |
| } |
| |
| bfd_vma mask = (1 << (7 * len)) - 1; |
| relocation = relocation & mask; |
| loongarch_write_unsigned_leb128 (p, len, relocation); |
| return bfd_reloc_ok; |
| } |
| |
| /* Write VALUE in uleb128 format to P. |
| LEN is the uleb128 value length. |
| Return a pointer to the byte following the last byte that was written. */ |
| bfd_byte * |
| loongarch_write_unsigned_leb128 (bfd_byte *p, unsigned int len, bfd_vma value) |
| { |
| bfd_byte c; |
| do |
| { |
| c = value & 0x7f; |
| if (len > 1) |
| c |= 0x80; |
| *(p++) = c; |
| value >>= 7; |
| len--; |
| } |
| while (len); |
| return p; |
| } |
| |
| int loongarch_get_uleb128_length (bfd_byte *buf) |
| { |
| unsigned int len = 0; |
| _bfd_read_unsigned_leb128 (NULL, buf, &len); |
| return len; |
| } |