#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)(reloc_howto_type *, bfd_vma *);
+}loongarch_reloc_howto_type;
+
+#define LOONGARCH_DEFAULT_HOWTO(r_name) \
+ { HOWTO (R_LARCH_##r_name, 0, 2, 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 }
+
+#define LOONGARCH_HOWTO(type, right, size, bits, pcrel, left, ovf, func, \
+ name, inplace, src_mask, dst_mask, pcrel_off, btype, afunc) \
+ { HOWTO(type, right, size, bits, pcrel, left, ovf, func, name, \
+ inplace, src_mask, dst_mask, pcrel_off), btype, afunc }
+
+#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);
+
+
/* This does not include any relocation information, but should be
good enough for GDB or objdump to read the file. */
-
-static reloc_howto_type howto_table[] =
+static loongarch_reloc_howto_type loongarch_howto_table[] =
{
-#define LOONGARCH_HOWTO(r_name) \
- HOWTO (R_LARCH_##r_name, 0, 2, 32, false, 0, complain_overflow_signed, \
- bfd_elf_generic_reloc, "R_LARCH_" #r_name, false, 0, 0xffffffff, false)
-
/* No relocation. */
- HOWTO (R_LARCH_NONE, /* type (0). */
- 0, /* rightshift */
- 3, /* 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 */
+ LOONGARCH_HOWTO (R_LARCH_NONE, /* type (0). */
+ 0, /* rightshift */
+ 3, /* 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 */
/* 32 bit relocation. */
- HOWTO (R_LARCH_32, /* type (1). */
- 0, /* rightshift */
- 2, /* 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 */
- 0xffffffff, /* dst_mask */
- false), /* pcrel_offset */
+ LOONGARCH_HOWTO (R_LARCH_32, /* type (1). */
+ 0, /* rightshift */
+ 2, /* 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 */
/* 64 bit relocation. */
- HOWTO (R_LARCH_64, /* type (2). */
- 0, /* rightshift */
- 4, /* 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 */
-
- HOWTO (R_LARCH_RELATIVE, /* type (3). */
- 0, /* rightshift */
- 2, /* 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 */
- 0xffffffff, /* dst_mask */
- false), /* pcrel_offset */
-
- 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 */
-
- HOWTO (R_LARCH_JUMP_SLOT, /* type (5). */
- 0, /* rightshift */
- 4, /* 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 */
+ LOONGARCH_HOWTO (R_LARCH_64, /* type (2). */
+ 0, /* rightshift */
+ 4, /* 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 */
+
+ LOONGARCH_HOWTO (R_LARCH_RELATIVE, /* type (3). */
+ 0, /* rightshift */
+ 2, /* 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 */
+
+ 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 */
+
+ LOONGARCH_HOWTO (R_LARCH_JUMP_SLOT, /* type (5). */
+ 0, /* rightshift */
+ 4, /* 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 */
/* Dynamic TLS relocations. */
- HOWTO (R_LARCH_TLS_DTPMOD32, /* type (6). */
- 0, /* rightshift */
- 2, /* 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 */
- 0xffffffff, /* dst_mask */
- false), /* pcrel_offset */
-
- HOWTO (R_LARCH_TLS_DTPMOD64, /* type (7). */
- 0, /* rightshift */
- 4, /* 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 */
-
- HOWTO (R_LARCH_TLS_DTPREL32, /* type (8). */
- 0, /* rightshift */
- 2, /* 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 */
- 0xffffffff, /* dst_mask */
- false), /* pcrel_offset */
-
- HOWTO (R_LARCH_TLS_DTPREL64, /* type (9). */
- 0, /* rightshift */
- 4, /* 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 */
-
- HOWTO (R_LARCH_TLS_TPREL32, /* type (10). */
- 0, /* rightshift */
- 2, /* 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 */
- 0xffffffff, /* dst_mask */
- false), /* pcrel_offset */
-
- HOWTO (R_LARCH_TLS_TPREL64, /* type (11). */
- 0, /* rightshift */
- 4, /* 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 */
-
- HOWTO (R_LARCH_IRELATIVE, /* type (12). */
- 0, /* rightshift */
- 2, /* size */
- 32, /* 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 */
- 0xffffffff, /* dst_mask */
- false), /* pcrel_offset */
-
- EMPTY_HOWTO(13),
- EMPTY_HOWTO(14),
- EMPTY_HOWTO(15),
- EMPTY_HOWTO(16),
- EMPTY_HOWTO(17),
- EMPTY_HOWTO(18),
- EMPTY_HOWTO(19),
-
- HOWTO (R_LARCH_MARK_LA, /* type (20). */
+ LOONGARCH_HOWTO (R_LARCH_TLS_DTPMOD32, /* type (6). */
+ 0, /* rightshift */
+ 2, /* 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 */
+
+ LOONGARCH_HOWTO (R_LARCH_TLS_DTPMOD64, /* type (7). */
+ 0, /* rightshift */
+ 4, /* 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 */
+
+ LOONGARCH_HOWTO (R_LARCH_TLS_DTPREL32, /* type (8). */
+ 0, /* rightshift */
+ 2, /* 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 */
+
+ LOONGARCH_HOWTO (R_LARCH_TLS_DTPREL64, /* type (9). */
+ 0, /* rightshift */
+ 4, /* 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 */
+
+ LOONGARCH_HOWTO (R_LARCH_TLS_TPREL32, /* type (10). */
+ 0, /* rightshift */
+ 2, /* 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 */
+
+ LOONGARCH_HOWTO (R_LARCH_TLS_TPREL64, /* type (11). */
+ 0, /* rightshift */
+ 4, /* 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 */
+
+ LOONGARCH_HOWTO (R_LARCH_IRELATIVE, /* type (12). */
+ 0, /* rightshift */
+ 2, /* size */
+ 32, /* 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 */
+
+ 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. */
3, /* size. */
0, /* bitsize. */
false, /* partial_inplace. */
0, /* src_mask. */
0, /* dst_mask. */
- false), /* pcrel_offset. */
+ false, /* pcrel_offset */
+ BFD_RELOC_LARCH_MARK_LA, /* bfd_reloc_code_real_type */
+ NULL), /* adjust_reloc_bits */
- HOWTO (R_LARCH_MARK_PCREL, /* type (21). */
+ LOONGARCH_HOWTO (R_LARCH_MARK_PCREL, /* type (21). */
0, /* rightshift. */
3, /* size. */
0, /* bitsize. */
false, /* partial_inplace. */
0, /* src_mask. */
0, /* dst_mask. */
- false), /* pcrel_offset. */
+ false, /* pcrel_offset */
+ BFD_RELOC_LARCH_MARK_PCREL, /* bfd_reloc_code_real_type */
+ NULL), /* adjust_reloc_bits */
- HOWTO (R_LARCH_SOP_PUSH_PCREL, /* type (22). */
+ LOONGARCH_HOWTO (R_LARCH_SOP_PUSH_PCREL, /* type (22). */
2, /* rightshift. */
2, /* size. */
32, /* bitsize. */
bfd_elf_generic_reloc, /* special_function. */
"R_LARCH_SOP_PUSH_PCREL", /* name. */
false, /* partial_inplace. */
- 0x03ffffff, /* src_mask. */
- 0x03ffffff, /* dst_mask. */
- false), /* pcrel_offset. */
+ 0x03ffffff, /* src_mask. */
+ 0x03ffffff, /* dst_mask. */
+ false, /* pcrel_offset */
+ BFD_RELOC_LARCH_SOP_PUSH_PCREL, /* bfd_reloc_code_real_type */
+ NULL), /* adjust_reloc_bits */
/* type 23-37. */
- LOONGARCH_HOWTO (SOP_PUSH_ABSOLUTE),
- LOONGARCH_HOWTO (SOP_PUSH_DUP),
- LOONGARCH_HOWTO (SOP_PUSH_GPREL),
- LOONGARCH_HOWTO (SOP_PUSH_TLS_TPREL),
- LOONGARCH_HOWTO (SOP_PUSH_TLS_GOT),
- LOONGARCH_HOWTO (SOP_PUSH_TLS_GD),
- LOONGARCH_HOWTO (SOP_PUSH_PLT_PCREL),
- LOONGARCH_HOWTO (SOP_ASSERT),
- LOONGARCH_HOWTO (SOP_NOT),
- LOONGARCH_HOWTO (SOP_SUB),
- LOONGARCH_HOWTO (SOP_SL),
- LOONGARCH_HOWTO (SOP_SR),
- LOONGARCH_HOWTO (SOP_ADD),
- LOONGARCH_HOWTO (SOP_AND),
- LOONGARCH_HOWTO (SOP_IF_ELSE),
-
- HOWTO (R_LARCH_SOP_POP_32_S_10_5, /* type (38). */
- 0, /* rightshift. */
- 2, /* 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. */
-
- HOWTO (R_LARCH_SOP_POP_32_U_10_12, /* type (39). */
- 0, /* rightshift. */
- 2, /* 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_U_10_12", /* name. */
- false, /* partial_inplace. */
- 0, /* src_mask */
- 0x3ffc00, /* dst_mask */
- false), /* pcrel_offset. */
-
- HOWTO (R_LARCH_SOP_POP_32_S_10_12, /* type (40). */
- 0, /* rightshift. */
- 2, /* 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. */
-
- HOWTO (R_LARCH_SOP_POP_32_S_10_16, /* type (41). */
- 0, /* rightshift. */
- 2, /* 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. */
-
- HOWTO (R_LARCH_SOP_POP_32_S_10_16_S2, /* type (42). */
- 2, /* rightshift. */
- 2, /* 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. */
-
- HOWTO (R_LARCH_SOP_POP_32_S_5_20, /* type (43). */
- 0, /* rightshift. */
- 2, /* 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 */
- 0x1fffe0, /* dst_mask */
- false), /* pcrel_offset. */
-
- HOWTO (R_LARCH_SOP_POP_32_S_0_5_10_16_S2, /* type (44). */
- 2, /* rightshift. */
- 2, /* 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. */
- 0xfc0003e0, /* src_mask */
- 0xfc0003e0, /* dst_mask */
- false), /* pcrel_offset. */
-
- HOWTO (R_LARCH_SOP_POP_32_S_0_10_10_16_S2, /* type (45). */
+ 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. */
+ 2, /* 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 */
+ loongarch_gen_adjust_reloc_bits), /* adjust_reloc_bits */
+
+ LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_U_10_12, /* type (39). */
+ 0, /* rightshift. */
+ 2, /* 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 */
+ loongarch_gen_adjust_reloc_bits), /* adjust_reloc_bits */
+
+ LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_S_10_12, /* type (40). */
+ 0, /* rightshift. */
+ 2, /* 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 */
+ loongarch_gen_adjust_reloc_bits), /* adjust_reloc_bits */
+
+ LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_S_10_16, /* type (41). */
+ 0, /* rightshift. */
+ 2, /* 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 */
+ loongarch_gen_adjust_reloc_bits), /* adjust_reloc_bits */
+
+ LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_S_10_16_S2, /* type (42). */
+ 2, /* rightshift. */
+ 2, /* 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 */
+ loongarch_gen_adjust_reloc_bits), /* adjust_reloc_bits */
+
+ LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_S_5_20, /* type (43). */
+ 0, /* rightshift. */
+ 2, /* 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 */
+ loongarch_gen_adjust_reloc_bits), /* adjust_reloc_bits */
+
+ LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_S_0_5_10_16_S2,
+ /* type (44). */
+ 2, /* rightshift. */
+ 2, /* 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. */
+ 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 */
+
+ LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_S_0_10_10_16_S2, /* type (45). */
2, /* rightshift. */
2, /* size. */
26, /* bitsize. */
false, /* partial_inplace. */
0xfc000000, /* src_mask */
0xfc000000, /* dst_mask */
- false), /* pcrel_offset. */
+ 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 */
- HOWTO (R_LARCH_SOP_POP_32_U, /* type (46). */
+ LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_U, /* type (46). */
0, /* rightshift. */
2, /* size. */
32, /* bitsize. */
false, /* pc_relative. */
0, /* bitpos. */
- complain_overflow_signed, /* complain_on_overflow. */
+ complain_overflow_unsigned, /* complain_on_overflow. */
bfd_elf_generic_reloc, /* special_function. */
"R_LARCH_SOP_POP_32_S_U", /* name. */
false, /* partial_inplace. */
- 0, /* src_mask */
- 0, /* dst_mask */
- false), /* pcrel_offset. */
+ 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 */
- HOWTO (R_LARCH_ADD8, /* type (47). */
+ LOONGARCH_HOWTO (R_LARCH_ADD8, /* type (47). */
0, /* rightshift. */
2, /* size. */
8, /* bitsize. */
"R_LARCH_ADD8", /* name. */
false, /* partial_inplace. */
0, /* src_mask */
- 0xffffffff, /* dst_mask */
- false), /* pcrel_offset. */
+ ALL_ONES, /* dst_mask */
+ false, /* pcrel_offset */
+ BFD_RELOC_LARCH_ADD8, /* bfd_reloc_code_real_type */
+ NULL), /* adjust_reloc_bits */
- HOWTO (R_LARCH_ADD16, /* type (48). */
+ LOONGARCH_HOWTO (R_LARCH_ADD16, /* type (48). */
0, /* rightshift. */
2, /* size. */
16, /* bitsize. */
"R_LARCH_ADD16", /* name. */
false, /* partial_inplace. */
0, /* src_mask */
- 0xffffffff, /* dst_mask */
- false), /* pcrel_offset. */
+ ALL_ONES, /* dst_mask */
+ false, /* pcrel_offset */
+ BFD_RELOC_LARCH_ADD16, /* bfd_reloc_code_real_type */
+ NULL), /* adjust_reloc_bits */
- HOWTO (R_LARCH_ADD24, /* type (49). */
+ LOONGARCH_HOWTO (R_LARCH_ADD24, /* type (49). */
0, /* rightshift. */
2, /* size. */
24, /* bitsize. */
"R_LARCH_ADD24", /* name. */
false, /* partial_inplace. */
0, /* src_mask */
- 0xffffffff, /* dst_mask */
- false), /* pcrel_offset. */
+ ALL_ONES, /* dst_mask */
+ false, /* pcrel_offset */
+ BFD_RELOC_LARCH_ADD24, /* bfd_reloc_code_real_type */
+ NULL), /* adjust_reloc_bits */
- HOWTO (R_LARCH_ADD32, /* type (50). */
+ LOONGARCH_HOWTO (R_LARCH_ADD32, /* type (50). */
0, /* rightshift. */
2, /* size. */
32, /* bitsize. */
"R_LARCH_ADD32", /* name. */
false, /* partial_inplace. */
0, /* src_mask */
- 0xffffffff, /* dst_mask */
- false), /* pcrel_offset. */
+ ALL_ONES, /* dst_mask */
+ false, /* pcrel_offset */
+ BFD_RELOC_LARCH_ADD32, /* bfd_reloc_code_real_type */
+ NULL), /* adjust_reloc_bits */
- HOWTO (R_LARCH_ADD64, /* type (51). */
+ LOONGARCH_HOWTO (R_LARCH_ADD64, /* type (51). */
0, /* rightshift. */
4, /* size. */
64, /* bitsize. */
false, /* partial_inplace. */
0, /* src_mask */
ALL_ONES, /* dst_mask */
- false), /* pcrel_offset. */
+ false, /* pcrel_offset */
+ BFD_RELOC_LARCH_ADD64, /* bfd_reloc_code_real_type */
+ NULL), /* adjust_reloc_bits */
- HOWTO (R_LARCH_SUB8, /* type (52). */
+ LOONGARCH_HOWTO (R_LARCH_SUB8, /* type (52). */
0, /* rightshift. */
2, /* size. */
8, /* bitsize. */
"R_LARCH_SUB8", /* name. */
false, /* partial_inplace. */
0, /* src_mask */
- 0xffffffff, /* dst_mask */
- false), /* pcrel_offset. */
+ ALL_ONES, /* dst_mask */
+ false, /* pcrel_offset */
+ BFD_RELOC_LARCH_SUB8, /* bfd_reloc_code_real_type */
+ NULL), /* adjust_reloc_bits */
- HOWTO (R_LARCH_SUB16, /* type (53). */
+ LOONGARCH_HOWTO (R_LARCH_SUB16, /* type (53). */
0, /* rightshift. */
2, /* size. */
16, /* bitsize. */
"R_LARCH_SUB16", /* name. */
false, /* partial_inplace. */
0, /* src_mask */
- 0xffffffff, /* dst_mask */
- false), /* pcrel_offset. */
+ ALL_ONES, /* dst_mask */
+ false, /* pcrel_offset */
+ BFD_RELOC_LARCH_SUB16, /* bfd_reloc_code_real_type */
+ NULL), /* adjust_reloc_bits */
- HOWTO (R_LARCH_SUB24, /* type (54). */
+ LOONGARCH_HOWTO (R_LARCH_SUB24, /* type (54). */
0, /* rightshift. */
2, /* size. */
24, /* bitsize. */
"R_LARCH_SUB24", /* name. */
false, /* partial_inplace. */
0, /* src_mask */
- 0xffffffff, /* dst_mask */
- false), /* pcrel_offset. */
+ ALL_ONES, /* dst_mask */
+ false, /* pcrel_offset */
+ BFD_RELOC_LARCH_SUB24, /* bfd_reloc_code_real_type */
+ NULL), /* adjust_reloc_bits */
- HOWTO (R_LARCH_SUB32, /* type (55). */
+ LOONGARCH_HOWTO (R_LARCH_SUB32, /* type (55). */
0, /* rightshift. */
2, /* size. */
32, /* bitsize. */
"R_LARCH_SUB32", /* name. */
false, /* partial_inplace. */
0, /* src_mask */
- 0xffffffff, /* dst_mask */
- false), /* pcrel_offset. */
+ ALL_ONES, /* dst_mask */
+ false, /* pcrel_offset */
+ BFD_RELOC_LARCH_SUB32, /* bfd_reloc_code_real_type */
+ NULL), /* adjust_reloc_bits */
- HOWTO (R_LARCH_SUB64, /* type (56). */
+ LOONGARCH_HOWTO (R_LARCH_SUB64, /* type (56). */
0, /* rightshift. */
4, /* size. */
64, /* bitsize. */
false, /* partial_inplace. */
0, /* src_mask */
ALL_ONES, /* dst_mask */
- false), /* pcrel_offset. */
-
-};
+ false, /* pcrel_offset */
+ BFD_RELOC_LARCH_SUB64, /* bfd_reloc_code_real_type */
+ NULL), /* adjust_reloc_bits */
-struct elf_reloc_map
-{
- bfd_reloc_code_real_type bfd_val;
- enum elf_loongarch_reloc_type elf_val;
-};
+ 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 */
-static const struct elf_reloc_map larch_reloc_map[] =
-{
- { BFD_RELOC_NONE, R_LARCH_NONE },
- { BFD_RELOC_32, R_LARCH_32 },
- { BFD_RELOC_64, R_LARCH_64 },
-
-#define LOONGARCH_reloc_map(r_name) \
- { \
- BFD_RELOC_LARCH_##r_name, R_LARCH_##r_name \
- }
- LOONGARCH_reloc_map (TLS_DTPMOD32),
- LOONGARCH_reloc_map (TLS_DTPMOD64),
- LOONGARCH_reloc_map (TLS_DTPREL32),
- LOONGARCH_reloc_map (TLS_DTPREL64),
- LOONGARCH_reloc_map (TLS_TPREL32),
- LOONGARCH_reloc_map (TLS_TPREL64),
-
- LOONGARCH_reloc_map (MARK_LA),
- LOONGARCH_reloc_map (MARK_PCREL),
- LOONGARCH_reloc_map (SOP_PUSH_PCREL),
- LOONGARCH_reloc_map (SOP_PUSH_ABSOLUTE),
- LOONGARCH_reloc_map (SOP_PUSH_DUP),
- LOONGARCH_reloc_map (SOP_PUSH_GPREL),
- LOONGARCH_reloc_map (SOP_PUSH_TLS_TPREL),
- LOONGARCH_reloc_map (SOP_PUSH_TLS_GOT),
- LOONGARCH_reloc_map (SOP_PUSH_TLS_GD),
- LOONGARCH_reloc_map (SOP_PUSH_PLT_PCREL),
- LOONGARCH_reloc_map (SOP_ASSERT),
- LOONGARCH_reloc_map (SOP_NOT),
- LOONGARCH_reloc_map (SOP_SUB),
- LOONGARCH_reloc_map (SOP_SL),
- LOONGARCH_reloc_map (SOP_SR),
- LOONGARCH_reloc_map (SOP_ADD),
- LOONGARCH_reloc_map (SOP_AND),
- LOONGARCH_reloc_map (SOP_IF_ELSE),
- LOONGARCH_reloc_map (SOP_POP_32_S_10_5),
- LOONGARCH_reloc_map (SOP_POP_32_U_10_12),
- LOONGARCH_reloc_map (SOP_POP_32_S_10_12),
- LOONGARCH_reloc_map (SOP_POP_32_S_10_16),
- LOONGARCH_reloc_map (SOP_POP_32_S_10_16_S2),
- LOONGARCH_reloc_map (SOP_POP_32_S_5_20),
- LOONGARCH_reloc_map (SOP_POP_32_S_0_5_10_16_S2),
- LOONGARCH_reloc_map (SOP_POP_32_S_0_10_10_16_S2),
- LOONGARCH_reloc_map (SOP_POP_32_U),
- LOONGARCH_reloc_map (ADD8),
- LOONGARCH_reloc_map (ADD16),
- LOONGARCH_reloc_map (ADD24),
- LOONGARCH_reloc_map (ADD32),
- LOONGARCH_reloc_map (ADD64),
- LOONGARCH_reloc_map (SUB8),
- LOONGARCH_reloc_map (SUB16),
- LOONGARCH_reloc_map (SUB24),
- LOONGARCH_reloc_map (SUB32),
- LOONGARCH_reloc_map (SUB64),
+ 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 */
};
reloc_howto_type *
loongarch_elf_rtype_to_howto (bfd *abfd, unsigned int r_type)
{
- size_t i;
- for (i = 0; i < ARRAY_SIZE (howto_table); i++)
- if (howto_table[i].type == r_type)
- return &howto_table[i];
+ if(r_type < R_LARCH_count)
+ {
+ /* For search table fast. */
+ BFD_ASSERT (ARRAY_SIZE (loongarch_howto_table) == R_LARCH_count);
+
+ 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];
+ }
(*_bfd_error_handler) (_("%pB: unsupported relocation type %#x"),
abfd, r_type);
}
reloc_howto_type *
-loongarch_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
- bfd_reloc_code_real_type code)
+loongarch_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name)
{
- unsigned int i;
- for (i = 0; i < ARRAY_SIZE (larch_reloc_map); i++)
- if (larch_reloc_map[i].bfd_val == code)
- return loongarch_elf_rtype_to_howto (abfd,
- (int) larch_reloc_map[i].elf_val);
+ BFD_ASSERT (ARRAY_SIZE (loongarch_howto_table) == R_LARCH_count);
+
+ 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 (reloc_howto_type *)&loongarch_howto_table[i];
+
+ (*_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_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name)
+loongarch_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ bfd_reloc_code_real_type code)
{
- unsigned int i;
+ BFD_ASSERT (ARRAY_SIZE (loongarch_howto_table) == R_LARCH_count);
- for (i = 0; i < ARRAY_SIZE (howto_table); i++)
- if (howto_table[i].name && strcasecmp (howto_table[i].name, r_name) == 0)
- return &howto_table[i];
+ 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];
+
+ (*_bfd_error_handler) (_("%pB: unsupported bfd relocation type %#x"),
+ abfd, code);
+ bfd_set_error (bfd_error_bad_value);
return NULL;
}
+
+#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_vma val = *fix_val;
+ /* Check val low bits if rightshift != 0, before rightshift */
+ if (howto->rightshift
+ && (((0x1UL << howto->rightshift) - 1) & val))
+ return false;
+
+ int bitsize = howto->bitsize + howto->rightshift;
+
+ /* Return false if overflow. */
+ if (howto->complain_on_overflow == complain_overflow_signed)
+ {
+ 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;
+ }
+ }
+ else if (howto->complain_on_overflow == complain_overflow_unsigned)
+ {
+ 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->bitpos;
+
+ *fix_val = 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)
+{
+ 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;
+
+ int bitsize = howto->bitsize + howto->rightshift;
+ 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;
+ }
+
+ /* Perform insn bits field. */
+ val = (val & ((0x1U << bitsize) - 1)) >> howto->rightshift;
+
+ /* Perform insn bits field. 20:16>>16, 15:0<<10 */
+ val = ((val & 0xffff) << 10) | ((val >> 16) & 0x1f);
+
+ *fix_val = val;
+
+ 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)
+{
+ 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;
+
+ int bitsize = howto->bitsize + howto->rightshift;
+ 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;
+ }
+
+ /* Perform insn bits field. */
+ val = (val & ((0x1U << bitsize) - 1)) >> howto->rightshift;
+
+ /* Perform insn bits field. 25:16>>16, 15:0<<10 */
+ val = ((val & 0xffff) << 10) | ((val >> 16) & 0x3ff);
+
+ *fix_val = val;
+
+ return true;
+}
+
+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 *)
+ howto)->adjust_reloc_bits(howto, fix_val);
+}