diff options
Diffstat (limited to 'bfd/elfxx-loongarch.c')
-rw-r--r-- | bfd/elfxx-loongarch.c | 1354 |
1 files changed, 1032 insertions, 322 deletions
diff --git a/bfd/elfxx-loongarch.c b/bfd/elfxx-loongarch.c index 4424969..f059f1a 100644 --- a/bfd/elfxx-loongarch.c +++ b/bfd/elfxx-loongarch.c @@ -35,27 +35,30 @@ typedef struct loongarch_reloc_howto_type_struct reloc_howto_type howto; bfd_reloc_code_real_type bfd_type; bool (*adjust_reloc_bits)(reloc_howto_type *, bfd_vma *); -}loongarch_reloc_howto_type; + 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 } + 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) \ + 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 } + inplace, src_mask, dst_mask, pcrel_off), btype, afunc, lname } #define LOONGARCH_EMPTY_HOWTO(C) \ - { EMPTY_HOWTO(C), BFD_RELOC_NONE, NULL } - -bool loongarch_gen_adjust_reloc_bits (reloc_howto_type *howto, bfd_vma *val); -bool loongarch_adjust_reloc_bits_l16_xx5_h5 (reloc_howto_type *howto, - bfd_vma *fix_val); -bool loongarch_adjust_reloc_bits_l16_h10 (reloc_howto_type *howto, - bfd_vma *val); + { EMPTY_HOWTO (C), BFD_RELOC_NONE, NULL, NULL } +static bool +reloc_bits (reloc_howto_type *howto, bfd_vma *val); +static bool +reloc_bits_b16 (reloc_howto_type *howto, bfd_vma *fix_val); +static bool +reloc_bits_b21 (reloc_howto_type *howto, bfd_vma *fix_val); +static bool +reloc_bits_b26 (reloc_howto_type *howto, bfd_vma *val); /* This does not include any relocation information, but should be good enough for GDB or objdump to read the file. */ @@ -76,7 +79,8 @@ static loongarch_reloc_howto_type loongarch_howto_table[] = 0, /* dst_mask */ false, /* pcrel_offset */ BFD_RELOC_NONE, /* bfd_reloc_code_real_type */ - NULL), /* adjust_reloc_bits */ + NULL, /* adjust_reloc_bits */ + NULL), /* larch_reloc_type_name */ /* 32 bit relocation. */ LOONGARCH_HOWTO (R_LARCH_32, /* type (1). */ @@ -93,7 +97,8 @@ static loongarch_reloc_howto_type loongarch_howto_table[] = ALL_ONES, /* dst_mask */ false, /* pcrel_offset */ BFD_RELOC_32, /* bfd_reloc_code_real_type */ - NULL), /* adjust_reloc_bits */ + NULL, /* adjust_reloc_bits */ + NULL), /* larch_reloc_type_name */ /* 64 bit relocation. */ LOONGARCH_HOWTO (R_LARCH_64, /* type (2). */ @@ -110,7 +115,8 @@ static loongarch_reloc_howto_type loongarch_howto_table[] = ALL_ONES, /* dst_mask */ false, /* pcrel_offset */ BFD_RELOC_64, /* bfd_reloc_code_real_type */ - NULL), /* adjust_reloc_bits */ + NULL, /* adjust_reloc_bits */ + NULL), /* larch_reloc_type_name */ LOONGARCH_HOWTO (R_LARCH_RELATIVE, /* type (3). */ 0, /* rightshift */ @@ -126,7 +132,8 @@ static loongarch_reloc_howto_type loongarch_howto_table[] = ALL_ONES, /* dst_mask */ false, /* pcrel_offset */ BFD_RELOC_NONE, /* undefined? */ - NULL), /* adjust_reloc_bits */ + NULL, /* adjust_reloc_bits */ + NULL), /* larch_reloc_type_name */ LOONGARCH_HOWTO (R_LARCH_COPY, /* type (4). */ 0, /* rightshift */ @@ -141,8 +148,9 @@ static loongarch_reloc_howto_type loongarch_howto_table[] = 0, /* src_mask */ 0, /* dst_mask */ false, /* pcrel_offset */ - BFD_RELOC_NONE, /* undefined? */ - NULL), /* adjust_reloc_bits */ + BFD_RELOC_NONE, /* undefined? */ + NULL, /* adjust_reloc_bits */ + NULL), /* larch_reloc_type_name */ LOONGARCH_HOWTO (R_LARCH_JUMP_SLOT, /* type (5). */ 0, /* rightshift */ @@ -157,8 +165,9 @@ static loongarch_reloc_howto_type loongarch_howto_table[] = 0, /* src_mask */ 0, /* dst_mask */ false, /* pcrel_offset */ - BFD_RELOC_NONE, /* undefined? */ - NULL), /* adjust_reloc_bits */ + BFD_RELOC_NONE, /* undefined? */ + NULL, /* adjust_reloc_bits */ + NULL), /* larch_reloc_type_name */ /* Dynamic TLS relocations. */ LOONGARCH_HOWTO (R_LARCH_TLS_DTPMOD32, /* type (6). */ @@ -175,7 +184,8 @@ static loongarch_reloc_howto_type loongarch_howto_table[] = ALL_ONES, /* dst_mask */ false, /* pcrel_offset */ BFD_RELOC_LARCH_TLS_DTPMOD32, /* bfd_reloc_code_real_type */ - NULL), /* adjust_reloc_bits */ + NULL, /* adjust_reloc_bits */ + NULL), /* larch_reloc_type_name */ LOONGARCH_HOWTO (R_LARCH_TLS_DTPMOD64, /* type (7). */ 0, /* rightshift */ @@ -191,7 +201,8 @@ static loongarch_reloc_howto_type loongarch_howto_table[] = ALL_ONES, /* dst_mask */ false, /* pcrel_offset */ BFD_RELOC_LARCH_TLS_DTPMOD64, /* bfd_reloc_code_real_type */ - NULL), /* adjust_reloc_bits */ + NULL, /* adjust_reloc_bits */ + NULL), /* larch_reloc_type_name */ LOONGARCH_HOWTO (R_LARCH_TLS_DTPREL32, /* type (8). */ 0, /* rightshift */ @@ -207,7 +218,8 @@ static loongarch_reloc_howto_type loongarch_howto_table[] = ALL_ONES, /* dst_mask */ false, /* pcrel_offset */ BFD_RELOC_LARCH_TLS_DTPREL32, /* bfd_reloc_code_real_type */ - NULL), /* adjust_reloc_bits */ + NULL, /* adjust_reloc_bits */ + NULL), /* larch_reloc_type_name */ LOONGARCH_HOWTO (R_LARCH_TLS_DTPREL64, /* type (9). */ 0, /* rightshift */ @@ -223,7 +235,8 @@ static loongarch_reloc_howto_type loongarch_howto_table[] = ALL_ONES, /* dst_mask */ false, /* pcrel_offset */ BFD_RELOC_LARCH_TLS_DTPREL64, /* bfd_reloc_code_real_type */ - NULL), /* adjust_reloc_bits */ + NULL, /* adjust_reloc_bits */ + NULL), /* larch_reloc_type_name */ LOONGARCH_HOWTO (R_LARCH_TLS_TPREL32, /* type (10). */ 0, /* rightshift */ @@ -239,7 +252,8 @@ static loongarch_reloc_howto_type loongarch_howto_table[] = ALL_ONES, /* dst_mask */ false, /* pcrel_offset */ BFD_RELOC_LARCH_TLS_TPREL32, /* bfd_reloc_code_real_type */ - NULL), /* adjust_reloc_bits */ + NULL, /* adjust_reloc_bits */ + NULL), /* larch_reloc_type_name */ LOONGARCH_HOWTO (R_LARCH_TLS_TPREL64, /* type (11). */ 0, /* rightshift */ @@ -255,7 +269,8 @@ static loongarch_reloc_howto_type loongarch_howto_table[] = ALL_ONES, /* dst_mask */ false, /* pcrel_offset */ BFD_RELOC_LARCH_TLS_TPREL64, /* bfd_reloc_code_real_type */ - NULL), /* adjust_reloc_bits */ + NULL, /* adjust_reloc_bits */ + NULL), /* larch_reloc_type_name */ LOONGARCH_HOWTO (R_LARCH_IRELATIVE, /* type (12). */ 0, /* rightshift */ @@ -271,63 +286,67 @@ static loongarch_reloc_howto_type loongarch_howto_table[] = ALL_ONES, /* dst_mask */ false, /* pcrel_offset */ BFD_RELOC_NONE, /* undefined? */ - NULL), /* adjust_reloc_bits */ + NULL, /* adjust_reloc_bits */ + NULL), /* larch_reloc_type_name */ - LOONGARCH_EMPTY_HOWTO(13), - LOONGARCH_EMPTY_HOWTO(14), - LOONGARCH_EMPTY_HOWTO(15), - LOONGARCH_EMPTY_HOWTO(16), - LOONGARCH_EMPTY_HOWTO(17), - LOONGARCH_EMPTY_HOWTO(18), - LOONGARCH_EMPTY_HOWTO(19), + LOONGARCH_EMPTY_HOWTO (13), + LOONGARCH_EMPTY_HOWTO (14), + 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. */ + 0, /* rightshift. */ + 0, /* size. */ + 0, /* bitsize. */ false, /* pc_relative. */ - 0, /* bitpos. */ - complain_overflow_signed, /* complain_on_overflow. */ - bfd_elf_generic_reloc, /* special_function. */ + 0, /* bitpos. */ + complain_overflow_signed, /* complain_on_overflow. */ + bfd_elf_generic_reloc, /* special_function. */ "R_LARCH_MARK_LA", /* name. */ - false, /* partial_inplace. */ + 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, /* adjust_reloc_bits */ + NULL), /* larch_reloc_type_name */ LOONGARCH_HOWTO (R_LARCH_MARK_PCREL, /* type (21). */ - 0, /* rightshift. */ - 0, /* size. */ - 0, /* bitsize. */ + 0, /* rightshift. */ + 0, /* size. */ + 0, /* bitsize. */ false, /* pc_relative. */ - 0, /* bitpos. */ - complain_overflow_signed, /* complain_on_overflow. */ - bfd_elf_generic_reloc, /* special_function. */ + 0, /* bitpos. */ + complain_overflow_signed, /* complain_on_overflow. */ + bfd_elf_generic_reloc, /* special_function. */ "R_LARCH_MARK_PCREL", /* name. */ - false, /* partial_inplace. */ + 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, /* adjust_reloc_bits */ + NULL), /* larch_reloc_type_name */ LOONGARCH_HOWTO (R_LARCH_SOP_PUSH_PCREL, /* type (22). */ - 2, /* rightshift. */ - 4, /* size. */ - 32, /* bitsize. */ + 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. */ + 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, /* adjust_reloc_bits */ + NULL), /* larch_reloc_type_name */ /* type 23-37. */ LOONGARCH_DEFAULT_HOWTO (SOP_PUSH_ABSOLUTE), @@ -347,343 +366,984 @@ static loongarch_reloc_howto_type loongarch_howto_table[] = LOONGARCH_DEFAULT_HOWTO (SOP_IF_ELSE), LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_S_10_5, /* type (38). */ - 0, /* rightshift. */ - 4, /* size. */ - 5, /* bitsize. */ + 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. */ + 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 */ - loongarch_gen_adjust_reloc_bits), /* adjust_reloc_bits */ + reloc_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. */ + 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. */ + 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 */ - loongarch_gen_adjust_reloc_bits), /* adjust_reloc_bits */ + reloc_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. */ + 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. */ + 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 */ - loongarch_gen_adjust_reloc_bits), /* adjust_reloc_bits */ + reloc_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. */ + 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. */ + 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 */ - loongarch_gen_adjust_reloc_bits), /* adjust_reloc_bits */ + reloc_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. */ + 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. */ + 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 */ - loongarch_gen_adjust_reloc_bits), /* adjust_reloc_bits */ + reloc_bits_b16, /* 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. */ + 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. */ + 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 */ - loongarch_gen_adjust_reloc_bits), /* adjust_reloc_bits */ + reloc_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. */ + 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. */ + 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. */ 0xfc0003e0, /* src_mask */ 0xfc0003e0, /* dst_mask */ false, /* pcrel_offset */ BFD_RELOC_LARCH_SOP_POP_32_S_0_5_10_16_S2, /* bfd_reloc_code_real_type */ - loongarch_adjust_reloc_bits_l16_xx5_h5), /* adjust_reloc_bits */ + reloc_bits_b21, /* 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. */ - 0xfc000000, /* src_mask */ - 0xfc000000, /* dst_mask */ + 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 */ - loongarch_adjust_reloc_bits_l16_h10), /* adjust_reloc_bits */ + reloc_bits_b26, /* 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_S_U", /* name. */ - false, /* partial_inplace. */ + 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_S_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 */ - loongarch_gen_adjust_reloc_bits), /* adjust_reloc_bits */ + reloc_bits, /* adjust_reloc_bits */ + NULL), /* larch_reloc_type_name */ - LOONGARCH_HOWTO (R_LARCH_ADD8, /* type (47). */ - 0, /* rightshift. */ - 4, /* size. */ - 8, /* bitsize. */ + LOONGARCH_HOWTO (R_LARCH_ADD8, /* type (47). */ + 0, /* rightshift. */ + 4, /* size. */ + 8, /* bitsize. */ false, /* pc_relative. */ - 0, /* bitpos. */ - complain_overflow_signed, /* complain_on_overflow. */ - bfd_elf_generic_reloc, /* special_function. */ - "R_LARCH_ADD8", /* name. */ - false, /* partial_inplace. */ + 0, /* bitpos. */ + complain_overflow_signed, /* complain_on_overflow. */ + bfd_elf_generic_reloc, /* special_function. */ + "R_LARCH_ADD8", /* name. */ + false, /* partial_inplace. */ 0, /* src_mask */ ALL_ONES, /* dst_mask */ false, /* pcrel_offset */ BFD_RELOC_LARCH_ADD8, /* bfd_reloc_code_real_type */ - NULL), /* adjust_reloc_bits */ + NULL, /* adjust_reloc_bits */ + NULL), /* larch_reloc_type_name */ - LOONGARCH_HOWTO (R_LARCH_ADD16, /* type (48). */ - 0, /* rightshift. */ - 4, /* size. */ - 16, /* bitsize. */ + LOONGARCH_HOWTO (R_LARCH_ADD16, /* type (48). */ + 0, /* rightshift. */ + 4, /* size. */ + 16, /* bitsize. */ false, /* pc_relative. */ - 0, /* bitpos. */ - complain_overflow_signed, /* complain_on_overflow. */ - bfd_elf_generic_reloc, /* special_function. */ - "R_LARCH_ADD16", /* name. */ - false, /* partial_inplace. */ + 0, /* bitpos. */ + complain_overflow_signed, /* complain_on_overflow. */ + bfd_elf_generic_reloc, /* special_function. */ + "R_LARCH_ADD16", /* name. */ + false, /* partial_inplace. */ 0, /* src_mask */ ALL_ONES, /* dst_mask */ false, /* pcrel_offset */ BFD_RELOC_LARCH_ADD16, /* bfd_reloc_code_real_type */ - NULL), /* adjust_reloc_bits */ + NULL, /* adjust_reloc_bits */ + NULL), /* larch_reloc_type_name */ - LOONGARCH_HOWTO (R_LARCH_ADD24, /* type (49). */ - 0, /* rightshift. */ - 4, /* size. */ - 24, /* bitsize. */ + LOONGARCH_HOWTO (R_LARCH_ADD24, /* type (49). */ + 0, /* rightshift. */ + 4, /* size. */ + 24, /* bitsize. */ false, /* pc_relative. */ - 0, /* bitpos. */ - complain_overflow_signed, /* complain_on_overflow. */ - bfd_elf_generic_reloc, /* special_function. */ - "R_LARCH_ADD24", /* name. */ - false, /* partial_inplace. */ + 0, /* bitpos. */ + complain_overflow_signed, /* complain_on_overflow. */ + bfd_elf_generic_reloc, /* special_function. */ + "R_LARCH_ADD24", /* name. */ + false, /* partial_inplace. */ 0, /* src_mask */ ALL_ONES, /* dst_mask */ false, /* pcrel_offset */ BFD_RELOC_LARCH_ADD24, /* bfd_reloc_code_real_type */ - NULL), /* adjust_reloc_bits */ + NULL, /* adjust_reloc_bits */ + NULL), /* larch_reloc_type_name */ - LOONGARCH_HOWTO (R_LARCH_ADD32, /* type (50). */ - 0, /* rightshift. */ - 4, /* size. */ - 32, /* bitsize. */ + LOONGARCH_HOWTO (R_LARCH_ADD32, /* type (50). */ + 0, /* rightshift. */ + 4, /* size. */ + 32, /* bitsize. */ false, /* pc_relative. */ - 0, /* bitpos. */ - complain_overflow_signed, /* complain_on_overflow. */ - bfd_elf_generic_reloc, /* special_function. */ - "R_LARCH_ADD32", /* name. */ - false, /* partial_inplace. */ + 0, /* bitpos. */ + complain_overflow_signed, /* complain_on_overflow. */ + bfd_elf_generic_reloc, /* special_function. */ + "R_LARCH_ADD32", /* name. */ + false, /* partial_inplace. */ 0, /* src_mask */ ALL_ONES, /* dst_mask */ false, /* pcrel_offset */ BFD_RELOC_LARCH_ADD32, /* bfd_reloc_code_real_type */ - NULL), /* adjust_reloc_bits */ + NULL, /* adjust_reloc_bits */ + NULL), /* larch_reloc_type_name */ - LOONGARCH_HOWTO (R_LARCH_ADD64, /* type (51). */ - 0, /* rightshift. */ - 8, /* size. */ - 64, /* bitsize. */ + LOONGARCH_HOWTO (R_LARCH_ADD64, /* type (51). */ + 0, /* rightshift. */ + 8, /* size. */ + 64, /* bitsize. */ false, /* pc_relative. */ - 0, /* bitpos. */ - complain_overflow_signed, /* complain_on_overflow. */ - bfd_elf_generic_reloc, /* special_function. */ - "R_LARCH_ADD64", /* name. */ - false, /* partial_inplace. */ + 0, /* bitpos. */ + complain_overflow_signed, /* complain_on_overflow. */ + bfd_elf_generic_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, /* adjust_reloc_bits */ + NULL), /* larch_reloc_type_name */ - LOONGARCH_HOWTO (R_LARCH_SUB8, /* type (52). */ - 0, /* rightshift. */ - 4, /* size. */ - 8, /* bitsize. */ + LOONGARCH_HOWTO (R_LARCH_SUB8, /* type (52). */ + 0, /* rightshift. */ + 4, /* size. */ + 8, /* bitsize. */ false, /* pc_relative. */ - 0, /* bitpos. */ - complain_overflow_signed, /* complain_on_overflow. */ - bfd_elf_generic_reloc, /* special_function. */ - "R_LARCH_SUB8", /* name. */ - false, /* partial_inplace. */ + 0, /* bitpos. */ + complain_overflow_signed, /* complain_on_overflow. */ + bfd_elf_generic_reloc, /* special_function. */ + "R_LARCH_SUB8", /* name. */ + false, /* partial_inplace. */ 0, /* src_mask */ ALL_ONES, /* dst_mask */ false, /* pcrel_offset */ BFD_RELOC_LARCH_SUB8, /* bfd_reloc_code_real_type */ - NULL), /* adjust_reloc_bits */ + NULL, /* adjust_reloc_bits */ + NULL), /* larch_reloc_type_name */ - LOONGARCH_HOWTO (R_LARCH_SUB16, /* type (53). */ - 0, /* rightshift. */ - 4, /* size. */ - 16, /* bitsize. */ + LOONGARCH_HOWTO (R_LARCH_SUB16, /* type (53). */ + 0, /* rightshift. */ + 4, /* size. */ + 16, /* bitsize. */ false, /* pc_relative. */ - 0, /* bitpos. */ - complain_overflow_signed, /* complain_on_overflow. */ - bfd_elf_generic_reloc, /* special_function. */ - "R_LARCH_SUB16", /* name. */ - false, /* partial_inplace. */ + 0, /* bitpos. */ + complain_overflow_signed, /* complain_on_overflow. */ + bfd_elf_generic_reloc, /* special_function. */ + "R_LARCH_SUB16", /* name. */ + false, /* partial_inplace. */ 0, /* src_mask */ ALL_ONES, /* dst_mask */ false, /* pcrel_offset */ BFD_RELOC_LARCH_SUB16, /* bfd_reloc_code_real_type */ - NULL), /* adjust_reloc_bits */ + NULL, /* adjust_reloc_bits */ + NULL), /* larch_reloc_type_name */ - LOONGARCH_HOWTO (R_LARCH_SUB24, /* type (54). */ - 0, /* rightshift. */ - 4, /* size. */ - 24, /* bitsize. */ + LOONGARCH_HOWTO (R_LARCH_SUB24, /* type (54). */ + 0, /* rightshift. */ + 4, /* size. */ + 24, /* bitsize. */ false, /* pc_relative. */ - 0, /* bitpos. */ - complain_overflow_signed, /* complain_on_overflow. */ - bfd_elf_generic_reloc, /* special_function. */ - "R_LARCH_SUB24", /* name. */ - false, /* partial_inplace. */ + 0, /* bitpos. */ + complain_overflow_signed, /* complain_on_overflow. */ + bfd_elf_generic_reloc, /* special_function. */ + "R_LARCH_SUB24", /* name. */ + false, /* partial_inplace. */ 0, /* src_mask */ ALL_ONES, /* dst_mask */ false, /* pcrel_offset */ BFD_RELOC_LARCH_SUB24, /* bfd_reloc_code_real_type */ - NULL), /* adjust_reloc_bits */ + NULL, /* adjust_reloc_bits */ + NULL), /* larch_reloc_type_name */ - LOONGARCH_HOWTO (R_LARCH_SUB32, /* type (55). */ - 0, /* rightshift. */ - 4, /* size. */ - 32, /* bitsize. */ + LOONGARCH_HOWTO (R_LARCH_SUB32, /* type (55). */ + 0, /* rightshift. */ + 4, /* size. */ + 32, /* bitsize. */ false, /* pc_relative. */ - 0, /* bitpos. */ - complain_overflow_signed, /* complain_on_overflow. */ - bfd_elf_generic_reloc, /* special_function. */ - "R_LARCH_SUB32", /* name. */ - false, /* partial_inplace. */ + 0, /* bitpos. */ + complain_overflow_signed, /* complain_on_overflow. */ + bfd_elf_generic_reloc, /* special_function. */ + "R_LARCH_SUB32", /* name. */ + false, /* partial_inplace. */ 0, /* src_mask */ ALL_ONES, /* dst_mask */ false, /* pcrel_offset */ BFD_RELOC_LARCH_SUB32, /* bfd_reloc_code_real_type */ - NULL), /* adjust_reloc_bits */ + NULL, /* adjust_reloc_bits */ + NULL), /* larch_reloc_type_name */ - LOONGARCH_HOWTO (R_LARCH_SUB64, /* type (56). */ - 0, /* rightshift. */ - 8, /* size. */ - 64, /* bitsize. */ + LOONGARCH_HOWTO (R_LARCH_SUB64, /* type (56). */ + 0, /* rightshift. */ + 8, /* size. */ + 64, /* bitsize. */ false, /* pc_relative. */ - 0, /* bitpos. */ - complain_overflow_signed, /* complain_on_overflow. */ - bfd_elf_generic_reloc, /* special_function. */ - "R_LARCH_SUB64", /* name. */ - false, /* partial_inplace. */ + 0, /* bitpos. */ + complain_overflow_signed, /* complain_on_overflow. */ + bfd_elf_generic_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, /* adjust_reloc_bits */ + NULL), /* larch_reloc_type_name */ - LOONGARCH_HOWTO (R_LARCH_GNU_VTINHERIT, /* type (57). */ - 0, /* rightshift. */ - 0, /* size. */ - 0, /* bitsize. */ + 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, /* 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, /* adjust_reloc_bits */ + NULL), /* larch_reloc_type_name */ - LOONGARCH_HOWTO (R_LARCH_GNU_VTENTRY, /* type (58). */ - 0, /* rightshift. */ - 0, /* size. */ - 0, /* bitsize. */ + 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. */ + 0, /* bitpos. */ + complain_overflow_signed, /* complain_on_overflow. */ NULL, /* special_function. */ - "R_LARCH_GNU_VTENTRY", /* name. */ - false, /* partial_inplace. */ + "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, /* 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. */ + 0x3fffc00, /* src_mask */ + 0x3fffc00, /* dst_mask */ + false, /* pcrel_offset */ + BFD_RELOC_LARCH_B16, /* bfd_reloc_code_real_type */ + reloc_bits_b16, /* 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. */ + 0xfc0003e0, /* src_mask */ + 0xfc0003e0, /* dst_mask */ + false, /* pcrel_offset */ + BFD_RELOC_LARCH_B21, /* bfd_reloc_code_real_type */ + reloc_bits_b21, /* 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_bits_b26, /* 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_signed, /* 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_unsigned, /* 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 */ + + LOONGARCH_HOWTO (R_LARCH_RELAX, /* type (99). */ + 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 */ + }; reloc_howto_type * @@ -697,8 +1357,6 @@ loongarch_elf_rtype_to_howto (bfd *abfd, unsigned int r_type) if (loongarch_howto_table[r_type].howto.type == r_type) return (reloc_howto_type *)&loongarch_howto_table[r_type]; - BFD_ASSERT (loongarch_howto_table[r_type].howto.type == r_type); - for (size_t i = 0; i < ARRAY_SIZE (loongarch_howto_table); i++) if (loongarch_howto_table[i].howto.type == r_type) return (reloc_howto_type *)&loongarch_howto_table[i]; @@ -734,6 +1392,17 @@ loongarch_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, { 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 = NULL; + ht = &loongarch_howto_table[code - BFD_RELOC_LARCH_B16 + R_LARCH_B16]; + BFD_ASSERT (ht->bfd_type == code); + return (reloc_howto_type *)ht; + } + for (size_t i = 0; i < ARRAY_SIZE (loongarch_howto_table); i++) if (loongarch_howto_table[i].bfd_type == code) return (reloc_howto_type *)&loongarch_howto_table[i]; @@ -745,56 +1414,89 @@ loongarch_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, 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; + } + + (*_bfd_error_handler) (_("%pB: unsupported relocation type name %s"), + abfd, l_r_name); + bfd_set_error (bfd_error_bad_value); + 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_10_16_S2 - * BFD_RELOC_LARCH_SOP_POP_32_S_5_20 - * BFD_RELOC_LARCH_SOP_POP_32_U. -*/ - -bool loongarch_gen_adjust_reloc_bits (reloc_howto_type *howto, bfd_vma *fix_val) + 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 (reloc_howto_type *howto, bfd_vma *fix_val) { - bfd_vma val = *fix_val; - /* Check val low bits if rightshift != 0, before rightshift */ - if (howto->rightshift - && (((0x1UL << howto->rightshift) - 1) & val)) + bfd_signed_vma val = ((bfd_signed_vma)(*fix_val)) >> howto->rightshift; + + /* Perform insn bits field. */ + val = val & (((bfd_vma)0x1 << howto->bitsize) - 1); + val <<= howto->bitpos; + + *fix_val = (bfd_vma)val; + + return true; +} + +/* Adjust val to perform insn + R_LARCH_SOP_POP_32_S_10_16_S2 + R_LARCH_B16. */ +static bool +reloc_bits_b16 (reloc_howto_type *howto, bfd_vma *fix_val) +{ + if (howto->complain_on_overflow != complain_overflow_signed) + return false; + + bfd_signed_vma val = *fix_val; + + /* Judge whether 4 bytes align. */ + if (val & ((0x1UL << howto->rightshift) - 1)) return false; int bitsize = howto->bitsize + howto->rightshift; + bfd_signed_vma sig_bit = (val >> (bitsize - 1)) & 0x1; - /* Return false if overflow. */ - if (howto->complain_on_overflow == complain_overflow_signed) + /* If val < 0, sign bit is 1. */ + if (sig_bit) { - bfd_vma sig_bit = (val >> (bitsize - 1)) & 0x1; - /* If val < 0. */ - if (sig_bit) - { - if ((LARCH_RELOC_BFD_VMA_BIT_MASK (bitsize - 1) & val) - != LARCH_RELOC_BFD_VMA_BIT_MASK (bitsize - 1)) - return false; - } - else - { - if (LARCH_RELOC_BFD_VMA_BIT_MASK (bitsize - 1) & val) - return false; - } + /* Signed bits is 1. */ + if ((LARCH_RELOC_BFD_VMA_BIT_MASK (bitsize - 1) & val) + != LARCH_RELOC_BFD_VMA_BIT_MASK (bitsize - 1)) + return false; } - else if (howto->complain_on_overflow == complain_overflow_unsigned) + else { + /* Signed bits is 0. */ if (LARCH_RELOC_BFD_VMA_BIT_MASK (bitsize) & val) return false; } - else - return false; /* Perform insn bits field. */ - val = (val & ((0x1U << bitsize) - 1)) >> howto->rightshift; + val >>= howto->rightshift; + val = val & (((bfd_vma)0x1 << howto->bitsize) - 1); val <<= howto->bitpos; *fix_val = val; @@ -802,22 +1504,24 @@ bool loongarch_gen_adjust_reloc_bits (reloc_howto_type *howto, bfd_vma *fix_val) return true; } -/* Reloc type R_LARCH_SOP_POP_32_S_0_5_10_16_S2. */ -bool loongarch_adjust_reloc_bits_l16_xx5_h5 (reloc_howto_type *howto, - bfd_vma *fix_val) +/* Reloc type : + R_LARCH_SOP_POP_32_S_0_5_10_16_S2 + R_LARCH_B21. */ +static bool +reloc_bits_b21 (reloc_howto_type *howto, + bfd_vma *fix_val) { - bfd_vma val = *fix_val; - /* Check val low bits if rightshift != 0, before rightshift */ - if (howto->rightshift - && (((0x1UL << howto->rightshift) - 1) & val)) + if (howto->complain_on_overflow != complain_overflow_signed) return false; - /* Return false if overflow. */ - if (howto->complain_on_overflow != complain_overflow_signed) + bfd_signed_vma val = *fix_val; + + if (val & ((0x1UL << howto->rightshift) - 1)) return false; int bitsize = howto->bitsize + howto->rightshift; - bfd_vma sig_bit = (val >> (bitsize - 1)) & 0x1; + bfd_signed_vma sig_bit = (val >> (bitsize - 1)) & 0x1; + /* If val < 0. */ if (sig_bit) { @@ -827,14 +1531,15 @@ bool loongarch_adjust_reloc_bits_l16_xx5_h5 (reloc_howto_type *howto, } else { - if (LARCH_RELOC_BFD_VMA_BIT_MASK (bitsize - 1) & val) + if (LARCH_RELOC_BFD_VMA_BIT_MASK (bitsize) & val) return false; } /* Perform insn bits field. */ - val = (val & ((0x1U << bitsize) - 1)) >> howto->rightshift; + val >>= howto->rightshift; + val = val & (((bfd_vma)0x1 << howto->bitsize) - 1); - /* Perform insn bits field. 20:16>>16, 15:0<<10 */ + /* Perform insn bits field. 15:0<<10, 20:16>>16. */ val = ((val & 0xffff) << 10) | ((val >> 16) & 0x1f); *fix_val = val; @@ -842,22 +1547,25 @@ bool loongarch_adjust_reloc_bits_l16_xx5_h5 (reloc_howto_type *howto, return true; } -/* Reloc type R_LARCH_SOP_POP_32_S_0_10_10_16_S2. */ -bool loongarch_adjust_reloc_bits_l16_h10 (reloc_howto_type *howto, - bfd_vma *fix_val) +/* Reloc type: + R_LARCH_SOP_POP_32_S_0_10_10_16_S2 + R_LARCH_B26. */ +static bool +reloc_bits_b26 (reloc_howto_type *howto, + bfd_vma *fix_val) { - bfd_vma val = *fix_val; - /* Check val low bits if rightshift != 0, before rightshift */ - if (howto->rightshift - && (((0x1UL << howto->rightshift) - 1) & val)) - return false; - /* Return false if overflow. */ if (howto->complain_on_overflow != complain_overflow_signed) return false; + bfd_signed_vma val = *fix_val; + + if (val & ((0x1UL << howto->rightshift) - 1)) + return false; + int bitsize = howto->bitsize + howto->rightshift; - bfd_vma sig_bit = (val >> (bitsize - 1)) & 0x1; + bfd_signed_vma sig_bit = (val >> (bitsize - 1)) & 0x1; + /* If val < 0. */ if (sig_bit) { @@ -867,14 +1575,15 @@ bool loongarch_adjust_reloc_bits_l16_h10 (reloc_howto_type *howto, } else { - if (LARCH_RELOC_BFD_VMA_BIT_MASK (bitsize - 1) & val) + if (LARCH_RELOC_BFD_VMA_BIT_MASK (bitsize) & val) return false; } /* Perform insn bits field. */ - val = (val & ((0x1U << bitsize) - 1)) >> howto->rightshift; + val >>= howto->rightshift; + val = val & (((bfd_vma)0x1 << howto->bitsize) - 1); - /* Perform insn bits field. 25:16>>16, 15:0<<10 */ + /* Perform insn bits field. 25:16>>16, 15:0<<10. */ val = ((val & 0xffff) << 10) | ((val >> 16) & 0x3ff); *fix_val = val; @@ -882,8 +1591,9 @@ bool loongarch_adjust_reloc_bits_l16_h10 (reloc_howto_type *howto, return true; } -bool loongarch_adjust_reloc_bitsfield (reloc_howto_type *howto, - bfd_vma *fix_val) +bool +loongarch_adjust_reloc_bitsfield (reloc_howto_type *howto, + bfd_vma *fix_val) { BFD_ASSERT (((loongarch_reloc_howto_type *)howto)->adjust_reloc_bits); return ((loongarch_reloc_howto_type *) |