mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-19 00:59:15 +08:00
LoongArch: Use functions instead of magic numbers.
Replace the magic numbers in gas(tc-loongarch.c) and bfd(elfnn-loongarch.c) with the functions defined in the howto table(elfxx-loongarch.c). gas/ * config/tc-loongarch.c: use functions. bfd/ * elfnn-loongarch.c: use functions. * elfxx-loongarch.c: define functions. * elfxx-loongarch.h
This commit is contained in:
@ -1446,7 +1446,6 @@ loongarch_check_offset (const Elf_Internal_Rela *rel,
|
||||
return bfd_reloc_ok;
|
||||
}
|
||||
|
||||
|
||||
#define LARCH_RELOC_PERFORM_3OP(op1, op2, op3) \
|
||||
({ \
|
||||
bfd_reloc_status_type ret = loongarch_pop (&op2); \
|
||||
@ -1459,50 +1458,21 @@ loongarch_check_offset (const Elf_Internal_Rela *rel,
|
||||
ret; \
|
||||
})
|
||||
|
||||
#define LARCH_RELOC_UINT32_BIT_MASK(bitsize) \
|
||||
(~((0x1U << (bitsize)) - 1))
|
||||
|
||||
static bfd_reloc_status_type
|
||||
loongarch_reloc_rewrite_imm_insn (const Elf_Internal_Rela *rel,
|
||||
const asection *input_section ATTRIBUTE_UNUSED,
|
||||
reloc_howto_type *howto, bfd *input_bfd,
|
||||
bfd_byte *contents, int64_t op,
|
||||
bool is_signed)
|
||||
bfd_byte *contents, bfd_vma reloc_val)
|
||||
{
|
||||
/* Check op low bits if rightshift != 0, before rightshift */
|
||||
if (howto->rightshift
|
||||
&& (((0x1U << howto->rightshift) - 1) & op))
|
||||
return bfd_reloc_overflow;
|
||||
|
||||
uint32_t imm = (uint32_t)(int32_t)(op >> howto->rightshift);
|
||||
|
||||
if (is_signed)
|
||||
{
|
||||
if (op >= 0)
|
||||
{
|
||||
if (LARCH_RELOC_UINT32_BIT_MASK (howto->bitsize - 1) & imm)
|
||||
return bfd_reloc_overflow;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((LARCH_RELOC_UINT32_BIT_MASK (howto->bitsize - 1) & imm)
|
||||
!= LARCH_RELOC_UINT32_BIT_MASK (howto->bitsize - 1))
|
||||
return bfd_reloc_overflow;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (LARCH_RELOC_UINT32_BIT_MASK (howto->bitsize) & imm)
|
||||
return bfd_reloc_overflow;
|
||||
}
|
||||
|
||||
int bits = bfd_get_reloc_size (howto) * 8;
|
||||
uint32_t insn = bfd_get (bits, input_bfd, contents + rel->r_offset);
|
||||
|
||||
imm = imm & ((0x1U << howto->bitsize) - 1);
|
||||
imm <<= howto->bitpos;
|
||||
insn = ((insn & howto->src_mask)
|
||||
| ((insn & (~(uint32_t) howto->dst_mask)) | imm));
|
||||
if (!loongarch_adjust_reloc_bitsfield(howto, &reloc_val))
|
||||
return bfd_reloc_overflow;
|
||||
|
||||
insn = (insn & (uint32_t)howto->src_mask)
|
||||
| ((insn & (~(uint32_t)howto->dst_mask)) | reloc_val);
|
||||
|
||||
bfd_put (bits, input_bfd, insn, contents + rel->r_offset);
|
||||
|
||||
return bfd_reloc_ok;
|
||||
@ -1594,19 +1564,8 @@ perform_relocation (const Elf_Internal_Rela *rel, asection *input_section,
|
||||
case R_LARCH_SOP_POP_32_S_10_16:
|
||||
case R_LARCH_SOP_POP_32_S_10_16_S2:
|
||||
case R_LARCH_SOP_POP_32_S_5_20:
|
||||
r = loongarch_pop (&opr1);
|
||||
if (r != bfd_reloc_ok)
|
||||
break;
|
||||
r = loongarch_check_offset (rel, input_section);
|
||||
if (r != bfd_reloc_ok)
|
||||
break;
|
||||
|
||||
r = loongarch_reloc_rewrite_imm_insn (rel, input_section,
|
||||
howto, input_bfd,
|
||||
contents, opr1, true);
|
||||
break;
|
||||
|
||||
case R_LARCH_SOP_POP_32_U_10_12:
|
||||
case R_LARCH_SOP_POP_32_U:
|
||||
r = loongarch_pop (&opr1);
|
||||
if (r != bfd_reloc_ok)
|
||||
break;
|
||||
@ -1616,7 +1575,7 @@ perform_relocation (const Elf_Internal_Rela *rel, asection *input_section,
|
||||
|
||||
r = loongarch_reloc_rewrite_imm_insn (rel, input_section,
|
||||
howto, input_bfd,
|
||||
contents, opr1, false);
|
||||
contents, (bfd_vma)opr1);
|
||||
break;
|
||||
|
||||
case R_LARCH_SOP_POP_32_S_0_5_10_16_S2:
|
||||
@ -1637,15 +1596,14 @@ perform_relocation (const Elf_Internal_Rela *rel, asection *input_section,
|
||||
r = bfd_reloc_overflow;
|
||||
break;
|
||||
}
|
||||
|
||||
r = loongarch_check_offset (rel, input_section);
|
||||
if (r != bfd_reloc_ok)
|
||||
break;
|
||||
|
||||
insn1 = bfd_get (bits, input_bfd, contents + rel->r_offset);
|
||||
insn1 = ((insn1 & howto->src_mask)
|
||||
insn1 = (insn1 & howto->src_mask)
|
||||
| ((imm & 0xffffU) << 10)
|
||||
| ((imm & 0x1f0000U) >> 16));
|
||||
| ((imm & 0x1f0000U) >> 16);
|
||||
bfd_put (bits, input_bfd, insn1, contents + rel->r_offset);
|
||||
break;
|
||||
}
|
||||
@ -1681,21 +1639,6 @@ perform_relocation (const Elf_Internal_Rela *rel, asection *input_section,
|
||||
break;
|
||||
}
|
||||
|
||||
case R_LARCH_SOP_POP_32_U:
|
||||
r = loongarch_pop (&opr1);
|
||||
if (r != bfd_reloc_ok)
|
||||
break;
|
||||
if ((uint64_t)opr1 & ~(uint64_t) 0xffffffff)
|
||||
r = bfd_reloc_overflow;
|
||||
if (r != bfd_reloc_ok)
|
||||
break;
|
||||
r = loongarch_check_offset (rel, input_section);
|
||||
if (r != bfd_reloc_ok)
|
||||
break;
|
||||
|
||||
bfd_put (bits, input_bfd, opr1, contents + rel->r_offset);
|
||||
break;
|
||||
|
||||
case R_LARCH_TLS_DTPREL32:
|
||||
case R_LARCH_32:
|
||||
case R_LARCH_TLS_DTPREL64:
|
||||
|
@ -29,17 +29,40 @@
|
||||
|
||||
#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). */
|
||||
LOONGARCH_HOWTO (R_LARCH_NONE, /* type (0). */
|
||||
0, /* rightshift */
|
||||
3, /* size */
|
||||
0, /* bitsize */
|
||||
@ -51,10 +74,12 @@ static reloc_howto_type howto_table[] =
|
||||
false, /* partial_inplace */
|
||||
0, /* src_mask */
|
||||
0, /* dst_mask */
|
||||
false), /* pcrel_offset */
|
||||
false, /* pcrel_offset */
|
||||
BFD_RELOC_NONE, /* bfd_reloc_code_real_type */
|
||||
NULL), /* adjust_reloc_bits */
|
||||
|
||||
/* 32 bit relocation. */
|
||||
HOWTO (R_LARCH_32, /* type (1). */
|
||||
LOONGARCH_HOWTO (R_LARCH_32, /* type (1). */
|
||||
0, /* rightshift */
|
||||
2, /* size */
|
||||
32, /* bitsize */
|
||||
@ -65,11 +90,13 @@ static reloc_howto_type howto_table[] =
|
||||
"R_LARCH_32", /* name */
|
||||
false, /* partial_inplace */
|
||||
0, /* src_mask */
|
||||
0xffffffff, /* dst_mask */
|
||||
false), /* pcrel_offset */
|
||||
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). */
|
||||
LOONGARCH_HOWTO (R_LARCH_64, /* type (2). */
|
||||
0, /* rightshift */
|
||||
4, /* size */
|
||||
64, /* bitsize */
|
||||
@ -81,9 +108,11 @@ static reloc_howto_type howto_table[] =
|
||||
false, /* partial_inplace */
|
||||
0, /* src_mask */
|
||||
ALL_ONES, /* dst_mask */
|
||||
false), /* pcrel_offset */
|
||||
false, /* pcrel_offset */
|
||||
BFD_RELOC_64, /* bfd_reloc_code_real_type */
|
||||
NULL), /* adjust_reloc_bits */
|
||||
|
||||
HOWTO (R_LARCH_RELATIVE, /* type (3). */
|
||||
LOONGARCH_HOWTO (R_LARCH_RELATIVE, /* type (3). */
|
||||
0, /* rightshift */
|
||||
2, /* size */
|
||||
32, /* bitsize */
|
||||
@ -94,10 +123,12 @@ static reloc_howto_type howto_table[] =
|
||||
"R_LARCH_RELATIVE", /* name */
|
||||
false, /* partial_inplace */
|
||||
0, /* src_mask */
|
||||
0xffffffff, /* dst_mask */
|
||||
false), /* pcrel_offset */
|
||||
ALL_ONES, /* dst_mask */
|
||||
false, /* pcrel_offset */
|
||||
BFD_RELOC_NONE, /* undefined? */
|
||||
NULL), /* adjust_reloc_bits */
|
||||
|
||||
HOWTO (R_LARCH_COPY, /* type (4). */
|
||||
LOONGARCH_HOWTO (R_LARCH_COPY, /* type (4). */
|
||||
0, /* rightshift */
|
||||
0, /* this one is variable size */
|
||||
0, /* bitsize */
|
||||
@ -109,9 +140,11 @@ static reloc_howto_type howto_table[] =
|
||||
false, /* partial_inplace */
|
||||
0, /* src_mask */
|
||||
0, /* dst_mask */
|
||||
false), /* pcrel_offset */
|
||||
false, /* pcrel_offset */
|
||||
BFD_RELOC_NONE, /* undefined? */
|
||||
NULL), /* adjust_reloc_bits */
|
||||
|
||||
HOWTO (R_LARCH_JUMP_SLOT, /* type (5). */
|
||||
LOONGARCH_HOWTO (R_LARCH_JUMP_SLOT, /* type (5). */
|
||||
0, /* rightshift */
|
||||
4, /* size */
|
||||
64, /* bitsize */
|
||||
@ -123,10 +156,12 @@ static reloc_howto_type howto_table[] =
|
||||
false, /* partial_inplace */
|
||||
0, /* src_mask */
|
||||
0, /* dst_mask */
|
||||
false), /* pcrel_offset */
|
||||
false, /* pcrel_offset */
|
||||
BFD_RELOC_NONE, /* undefined? */
|
||||
NULL), /* adjust_reloc_bits */
|
||||
|
||||
/* Dynamic TLS relocations. */
|
||||
HOWTO (R_LARCH_TLS_DTPMOD32, /* type (6). */
|
||||
LOONGARCH_HOWTO (R_LARCH_TLS_DTPMOD32, /* type (6). */
|
||||
0, /* rightshift */
|
||||
2, /* size */
|
||||
32, /* bitsize */
|
||||
@ -137,10 +172,12 @@ static reloc_howto_type howto_table[] =
|
||||
"R_LARCH_TLS_DTPMOD32", /* name */
|
||||
false, /* partial_inplace */
|
||||
0, /* src_mask */
|
||||
0xffffffff, /* dst_mask */
|
||||
false), /* pcrel_offset */
|
||||
ALL_ONES, /* dst_mask */
|
||||
false, /* pcrel_offset */
|
||||
BFD_RELOC_LARCH_TLS_DTPMOD32, /* bfd_reloc_code_real_type */
|
||||
NULL), /* adjust_reloc_bits */
|
||||
|
||||
HOWTO (R_LARCH_TLS_DTPMOD64, /* type (7). */
|
||||
LOONGARCH_HOWTO (R_LARCH_TLS_DTPMOD64, /* type (7). */
|
||||
0, /* rightshift */
|
||||
4, /* size */
|
||||
64, /* bitsize */
|
||||
@ -152,9 +189,11 @@ static reloc_howto_type howto_table[] =
|
||||
false, /* partial_inplace */
|
||||
0, /* src_mask */
|
||||
ALL_ONES, /* dst_mask */
|
||||
false), /* pcrel_offset */
|
||||
false, /* pcrel_offset */
|
||||
BFD_RELOC_LARCH_TLS_DTPMOD64, /* bfd_reloc_code_real_type */
|
||||
NULL), /* adjust_reloc_bits */
|
||||
|
||||
HOWTO (R_LARCH_TLS_DTPREL32, /* type (8). */
|
||||
LOONGARCH_HOWTO (R_LARCH_TLS_DTPREL32, /* type (8). */
|
||||
0, /* rightshift */
|
||||
2, /* size */
|
||||
32, /* bitsize */
|
||||
@ -165,10 +204,12 @@ static reloc_howto_type howto_table[] =
|
||||
"R_LARCH_TLS_DTPREL32", /* name */
|
||||
true, /* partial_inplace */
|
||||
0, /* src_mask */
|
||||
0xffffffff, /* dst_mask */
|
||||
false), /* pcrel_offset */
|
||||
ALL_ONES, /* dst_mask */
|
||||
false, /* pcrel_offset */
|
||||
BFD_RELOC_LARCH_TLS_DTPREL32, /* bfd_reloc_code_real_type */
|
||||
NULL), /* adjust_reloc_bits */
|
||||
|
||||
HOWTO (R_LARCH_TLS_DTPREL64, /* type (9). */
|
||||
LOONGARCH_HOWTO (R_LARCH_TLS_DTPREL64, /* type (9). */
|
||||
0, /* rightshift */
|
||||
4, /* size */
|
||||
64, /* bitsize */
|
||||
@ -180,9 +221,11 @@ static reloc_howto_type howto_table[] =
|
||||
true, /* partial_inplace */
|
||||
0, /* src_mask */
|
||||
ALL_ONES, /* dst_mask */
|
||||
false), /* pcrel_offset */
|
||||
false, /* pcrel_offset */
|
||||
BFD_RELOC_LARCH_TLS_DTPREL64, /* bfd_reloc_code_real_type */
|
||||
NULL), /* adjust_reloc_bits */
|
||||
|
||||
HOWTO (R_LARCH_TLS_TPREL32, /* type (10). */
|
||||
LOONGARCH_HOWTO (R_LARCH_TLS_TPREL32, /* type (10). */
|
||||
0, /* rightshift */
|
||||
2, /* size */
|
||||
32, /* bitsize */
|
||||
@ -193,10 +236,12 @@ static reloc_howto_type howto_table[] =
|
||||
"R_LARCH_TLS_TPREL32", /* name */
|
||||
false, /* partial_inplace */
|
||||
0, /* src_mask */
|
||||
0xffffffff, /* dst_mask */
|
||||
false), /* pcrel_offset */
|
||||
ALL_ONES, /* dst_mask */
|
||||
false, /* pcrel_offset */
|
||||
BFD_RELOC_LARCH_TLS_TPREL32, /* bfd_reloc_code_real_type */
|
||||
NULL), /* adjust_reloc_bits */
|
||||
|
||||
HOWTO (R_LARCH_TLS_TPREL64, /* type (11). */
|
||||
LOONGARCH_HOWTO (R_LARCH_TLS_TPREL64, /* type (11). */
|
||||
0, /* rightshift */
|
||||
4, /* size */
|
||||
64, /* bitsize */
|
||||
@ -208,9 +253,11 @@ static reloc_howto_type howto_table[] =
|
||||
false, /* partial_inplace */
|
||||
0, /* src_mask */
|
||||
ALL_ONES, /* dst_mask */
|
||||
false), /* pcrel_offset */
|
||||
false, /* pcrel_offset */
|
||||
BFD_RELOC_LARCH_TLS_TPREL64, /* bfd_reloc_code_real_type */
|
||||
NULL), /* adjust_reloc_bits */
|
||||
|
||||
HOWTO (R_LARCH_IRELATIVE, /* type (12). */
|
||||
LOONGARCH_HOWTO (R_LARCH_IRELATIVE, /* type (12). */
|
||||
0, /* rightshift */
|
||||
2, /* size */
|
||||
32, /* bitsize */
|
||||
@ -221,18 +268,20 @@ static reloc_howto_type howto_table[] =
|
||||
"R_LARCH_IRELATIVE", /* name */
|
||||
false, /* partial_inplace */
|
||||
0, /* src_mask */
|
||||
0xffffffff, /* dst_mask */
|
||||
false), /* pcrel_offset */
|
||||
ALL_ONES, /* dst_mask */
|
||||
false, /* pcrel_offset */
|
||||
BFD_RELOC_NONE, /* undefined? */
|
||||
NULL), /* adjust_reloc_bits */
|
||||
|
||||
EMPTY_HOWTO(13),
|
||||
EMPTY_HOWTO(14),
|
||||
EMPTY_HOWTO(15),
|
||||
EMPTY_HOWTO(16),
|
||||
EMPTY_HOWTO(17),
|
||||
EMPTY_HOWTO(18),
|
||||
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),
|
||||
|
||||
HOWTO (R_LARCH_MARK_LA, /* type (20). */
|
||||
LOONGARCH_HOWTO (R_LARCH_MARK_LA, /* type (20). */
|
||||
0, /* rightshift. */
|
||||
3, /* size. */
|
||||
0, /* bitsize. */
|
||||
@ -244,9 +293,11 @@ static reloc_howto_type howto_table[] =
|
||||
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. */
|
||||
@ -258,9 +309,11 @@ static reloc_howto_type howto_table[] =
|
||||
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. */
|
||||
@ -272,26 +325,28 @@ static reloc_howto_type howto_table[] =
|
||||
false, /* partial_inplace. */
|
||||
0x03ffffff, /* src_mask. */
|
||||
0x03ffffff, /* dst_mask. */
|
||||
false), /* pcrel_offset. */
|
||||
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),
|
||||
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),
|
||||
|
||||
HOWTO (R_LARCH_SOP_POP_32_S_10_5, /* type (38). */
|
||||
LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_S_10_5, /* type (38). */
|
||||
0, /* rightshift. */
|
||||
2, /* size. */
|
||||
5, /* bitsize. */
|
||||
@ -303,23 +358,27 @@ static reloc_howto_type howto_table[] =
|
||||
false, /* partial_inplace. */
|
||||
0, /* src_mask */
|
||||
0x7c00, /* dst_mask */
|
||||
false), /* pcrel_offset. */
|
||||
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 */
|
||||
|
||||
HOWTO (R_LARCH_SOP_POP_32_U_10_12, /* type (39). */
|
||||
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_signed, /* complain_on_overflow. */
|
||||
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. */
|
||||
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 */
|
||||
|
||||
HOWTO (R_LARCH_SOP_POP_32_S_10_12, /* type (40). */
|
||||
LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_S_10_12, /* type (40). */
|
||||
0, /* rightshift. */
|
||||
2, /* size. */
|
||||
12, /* bitsize. */
|
||||
@ -331,9 +390,11 @@ static reloc_howto_type howto_table[] =
|
||||
false, /* partial_inplace. */
|
||||
0, /* src_mask */
|
||||
0x3ffc00, /* dst_mask */
|
||||
false), /* pcrel_offset. */
|
||||
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 */
|
||||
|
||||
HOWTO (R_LARCH_SOP_POP_32_S_10_16, /* type (41). */
|
||||
LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_S_10_16, /* type (41). */
|
||||
0, /* rightshift. */
|
||||
2, /* size. */
|
||||
16, /* bitsize. */
|
||||
@ -345,9 +406,11 @@ static reloc_howto_type howto_table[] =
|
||||
false, /* partial_inplace. */
|
||||
0, /* src_mask */
|
||||
0x3fffc00, /* dst_mask */
|
||||
false), /* pcrel_offset. */
|
||||
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 */
|
||||
|
||||
HOWTO (R_LARCH_SOP_POP_32_S_10_16_S2, /* type (42). */
|
||||
LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_S_10_16_S2, /* type (42). */
|
||||
2, /* rightshift. */
|
||||
2, /* size. */
|
||||
16, /* bitsize. */
|
||||
@ -359,9 +422,11 @@ static reloc_howto_type howto_table[] =
|
||||
false, /* partial_inplace. */
|
||||
0, /* src_mask */
|
||||
0x3fffc00, /* dst_mask */
|
||||
false), /* pcrel_offset. */
|
||||
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 */
|
||||
|
||||
HOWTO (R_LARCH_SOP_POP_32_S_5_20, /* type (43). */
|
||||
LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_S_5_20, /* type (43). */
|
||||
0, /* rightshift. */
|
||||
2, /* size. */
|
||||
20, /* bitsize. */
|
||||
@ -372,10 +437,13 @@ static reloc_howto_type howto_table[] =
|
||||
"R_LARCH_SOP_POP_32_S_5_20", /* name. */
|
||||
false, /* partial_inplace. */
|
||||
0, /* src_mask */
|
||||
0x1fffe0, /* dst_mask */
|
||||
false), /* pcrel_offset. */
|
||||
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 */
|
||||
|
||||
HOWTO (R_LARCH_SOP_POP_32_S_0_5_10_16_S2, /* type (44). */
|
||||
LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_S_0_5_10_16_S2,
|
||||
/* type (44). */
|
||||
2, /* rightshift. */
|
||||
2, /* size. */
|
||||
21, /* bitsize. */
|
||||
@ -387,9 +455,12 @@ static reloc_howto_type howto_table[] =
|
||||
false, /* partial_inplace. */
|
||||
0xfc0003e0, /* src_mask */
|
||||
0xfc0003e0, /* dst_mask */
|
||||
false), /* pcrel_offset. */
|
||||
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 */
|
||||
|
||||
HOWTO (R_LARCH_SOP_POP_32_S_0_10_10_16_S2, /* type (45). */
|
||||
LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_S_0_10_10_16_S2, /* type (45). */
|
||||
2, /* rightshift. */
|
||||
2, /* size. */
|
||||
26, /* bitsize. */
|
||||
@ -401,23 +472,28 @@ static reloc_howto_type howto_table[] =
|
||||
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. */
|
||||
@ -428,10 +504,12 @@ static reloc_howto_type howto_table[] =
|
||||
"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. */
|
||||
@ -442,10 +520,12 @@ static reloc_howto_type howto_table[] =
|
||||
"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. */
|
||||
@ -456,10 +536,12 @@ static reloc_howto_type howto_table[] =
|
||||
"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. */
|
||||
@ -470,10 +552,12 @@ static reloc_howto_type howto_table[] =
|
||||
"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. */
|
||||
@ -485,9 +569,11 @@ static reloc_howto_type howto_table[] =
|
||||
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. */
|
||||
@ -498,10 +584,12 @@ static reloc_howto_type howto_table[] =
|
||||
"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. */
|
||||
@ -512,10 +600,12 @@ static reloc_howto_type howto_table[] =
|
||||
"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. */
|
||||
@ -526,10 +616,12 @@ static reloc_howto_type howto_table[] =
|
||||
"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. */
|
||||
@ -540,10 +632,12 @@ static reloc_howto_type howto_table[] =
|
||||
"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. */
|
||||
@ -555,79 +649,60 @@ static reloc_howto_type howto_table[] =
|
||||
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 */
|
||||
|
||||
};
|
||||
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 */
|
||||
|
||||
struct elf_reloc_map
|
||||
{
|
||||
bfd_reloc_code_real_type bfd_val;
|
||||
enum elf_loongarch_reloc_type elf_val;
|
||||
};
|
||||
|
||||
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);
|
||||
@ -635,27 +710,182 @@ loongarch_elf_rtype_to_howto (bfd *abfd, unsigned int r_type)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
reloc_howto_type *
|
||||
loongarch_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name)
|
||||
{
|
||||
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_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
|
||||
bfd_reloc_code_real_type code)
|
||||
{
|
||||
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].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;
|
||||
}
|
||||
|
||||
reloc_howto_type *
|
||||
loongarch_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name)
|
||||
#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)
|
||||
{
|
||||
unsigned int i;
|
||||
bfd_vma val = *fix_val;
|
||||
/* Check val low bits if rightshift != 0, before rightshift */
|
||||
if (howto->rightshift
|
||||
&& (((0x1UL << howto->rightshift) - 1) & val))
|
||||
return false;
|
||||
|
||||
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];
|
||||
int bitsize = howto->bitsize + howto->rightshift;
|
||||
|
||||
return NULL;
|
||||
/* 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);
|
||||
}
|
||||
|
@ -29,3 +29,5 @@ loongarch_reloc_type_lookup (bfd *abfd, bfd_reloc_code_real_type code);
|
||||
|
||||
extern reloc_howto_type *
|
||||
loongarch_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name);
|
||||
|
||||
bool loongarch_adjust_reloc_bitsfield (reloc_howto_type *howto, bfd_vma *fix_val);
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "elf/loongarch.h"
|
||||
#include "opcode/loongarch.h"
|
||||
#include "obj-elf.h"
|
||||
#include "bfd/elfxx-loongarch.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
@ -1068,13 +1069,29 @@ md_pcrel_from (fixS *fixP ATTRIBUTE_UNUSED)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void fix_reloc_insn (fixS *fixP, bfd_vma reloc_val, char *buf)
|
||||
{
|
||||
reloc_howto_type *howto;
|
||||
insn_t insn;
|
||||
howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type);
|
||||
|
||||
insn = bfd_getl32 (buf);
|
||||
|
||||
if (!loongarch_adjust_reloc_bitsfield(howto, &reloc_val))
|
||||
as_warn_where (fixP->fx_file, fixP->fx_line, "Reloc overflow");
|
||||
|
||||
insn = (insn & (insn_t)howto->src_mask)
|
||||
| ((insn & (~(insn_t)howto->dst_mask)) | reloc_val);
|
||||
|
||||
bfd_putl32 (insn, buf);
|
||||
}
|
||||
|
||||
void
|
||||
md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
|
||||
{
|
||||
static int64_t stack_top;
|
||||
static int last_reloc_is_sop_push_pcrel_1 = 0;
|
||||
int last_reloc_is_sop_push_pcrel = last_reloc_is_sop_push_pcrel_1;
|
||||
insn_t insn;
|
||||
last_reloc_is_sop_push_pcrel_1 = 0;
|
||||
|
||||
char *buf = fixP->fx_frag->fr_literal + fixP->fx_where;
|
||||
@ -1083,17 +1100,17 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
|
||||
case BFD_RELOC_LARCH_SOP_PUSH_TLS_TPREL:
|
||||
case BFD_RELOC_LARCH_SOP_PUSH_TLS_GD:
|
||||
case BFD_RELOC_LARCH_SOP_PUSH_TLS_GOT:
|
||||
if (fixP->fx_addsy)
|
||||
S_SET_THREAD_LOCAL (fixP->fx_addsy);
|
||||
else
|
||||
as_bad_where (fixP->fx_file, fixP->fx_line,
|
||||
_("Relocation against a constant"));
|
||||
break;
|
||||
case BFD_RELOC_LARCH_SOP_PUSH_PCREL:
|
||||
case BFD_RELOC_LARCH_SOP_PUSH_PLT_PCREL:
|
||||
if (fixP->fx_addsy == NULL)
|
||||
as_bad_where (fixP->fx_file, fixP->fx_line,
|
||||
_("Relocation against a constant"));
|
||||
|
||||
if (fixP->fx_r_type == BFD_RELOC_LARCH_SOP_PUSH_TLS_TPREL
|
||||
|| fixP->fx_r_type == BFD_RELOC_LARCH_SOP_PUSH_TLS_GD
|
||||
|| fixP->fx_r_type == BFD_RELOC_LARCH_SOP_PUSH_TLS_GOT)
|
||||
S_SET_THREAD_LOCAL (fixP->fx_addsy);
|
||||
|
||||
if (fixP->fx_r_type == BFD_RELOC_LARCH_SOP_PUSH_PCREL)
|
||||
{
|
||||
last_reloc_is_sop_push_pcrel_1 = 1;
|
||||
@ -1106,111 +1123,18 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
|
||||
break;
|
||||
|
||||
case BFD_RELOC_LARCH_SOP_POP_32_S_10_5:
|
||||
if (!last_reloc_is_sop_push_pcrel)
|
||||
break;
|
||||
if ((stack_top & ~(uint64_t) 0xf) != 0x0
|
||||
&& (stack_top & ~(uint64_t) 0xf) != ~(uint64_t) 0xf)
|
||||
as_warn_where (fixP->fx_file, fixP->fx_line, "Reloc overflow");
|
||||
insn = bfd_getl32 (buf);
|
||||
insn = (insn & (~(uint32_t) 0x7c00)) | ((stack_top & 0x1f) << 10);
|
||||
bfd_putl32 (insn, buf);
|
||||
break;
|
||||
|
||||
case BFD_RELOC_LARCH_SOP_POP_32_U_10_12:
|
||||
if (!last_reloc_is_sop_push_pcrel)
|
||||
break;
|
||||
if (stack_top & ~(uint64_t) 0xfff)
|
||||
as_warn_where (fixP->fx_file, fixP->fx_line, "Reloc overflow");
|
||||
insn = bfd_getl32 (buf);
|
||||
insn = (insn & (~(uint32_t) 0x3ffc00)) | ((stack_top & 0xfff) << 10);
|
||||
bfd_putl32 (insn, buf);
|
||||
break;
|
||||
|
||||
case BFD_RELOC_LARCH_SOP_POP_32_S_10_12:
|
||||
if (!last_reloc_is_sop_push_pcrel)
|
||||
break;
|
||||
if ((stack_top & ~(uint64_t) 0x7ff) != 0x0
|
||||
&& (stack_top & ~(uint64_t) 0x7ff) != ~(uint64_t) 0x7ff)
|
||||
as_warn_where (fixP->fx_file, fixP->fx_line, "Reloc overflow");
|
||||
insn = bfd_getl32 (buf);
|
||||
insn = (insn & (~(uint32_t) 0x3ffc00)) | ((stack_top & 0xfff) << 10);
|
||||
bfd_putl32 (insn, buf);
|
||||
break;
|
||||
|
||||
case BFD_RELOC_LARCH_SOP_POP_32_U_10_12:
|
||||
case BFD_RELOC_LARCH_SOP_POP_32_S_10_16:
|
||||
if (!last_reloc_is_sop_push_pcrel)
|
||||
break;
|
||||
if ((stack_top & ~(uint64_t) 0x7fff) != 0x0
|
||||
&& (stack_top & ~(uint64_t) 0x7fff) != ~(uint64_t) 0x7fff)
|
||||
as_warn_where (fixP->fx_file, fixP->fx_line, "Reloc overflow");
|
||||
insn = bfd_getl32 (buf);
|
||||
insn = (insn & 0xfc0003ff) | ((stack_top & 0xffff) << 10);
|
||||
bfd_putl32 (insn, buf);
|
||||
break;
|
||||
|
||||
case BFD_RELOC_LARCH_SOP_POP_32_S_10_16_S2:
|
||||
if (!last_reloc_is_sop_push_pcrel)
|
||||
break;
|
||||
if ((stack_top & 0x3) != 0)
|
||||
as_warn_where (fixP->fx_file, fixP->fx_line, "Reloc overflow");
|
||||
stack_top >>= 2;
|
||||
if ((stack_top & ~(uint64_t) 0x7fff) != 0x0
|
||||
&& (stack_top & ~(uint64_t) 0x7fff) != ~(uint64_t) 0x7fff)
|
||||
as_warn_where (fixP->fx_file, fixP->fx_line, "Reloc overflow");
|
||||
insn = bfd_getl32 (buf);
|
||||
insn = (insn & 0xfc0003ff) | ((stack_top & 0xffff) << 10);
|
||||
bfd_putl32 (insn, buf);
|
||||
break;
|
||||
|
||||
case BFD_RELOC_LARCH_SOP_POP_32_S_0_5_10_16_S2:
|
||||
if (!last_reloc_is_sop_push_pcrel)
|
||||
break;
|
||||
if ((stack_top & 0x3) != 0)
|
||||
break;
|
||||
stack_top >>= 2;
|
||||
if ((stack_top & ~(uint64_t) 0xfffff) != 0x0
|
||||
&& (stack_top & ~(uint64_t) 0xfffff) != ~(uint64_t) 0xfffff)
|
||||
as_warn_where (fixP->fx_file, fixP->fx_line, "Reloc overflow");
|
||||
insn = bfd_getl32 (buf);
|
||||
insn = ((insn & 0xfc0003e0)
|
||||
| ((stack_top & 0xffff) << 10)
|
||||
| ((stack_top & 0x1f0000) >> 16));
|
||||
bfd_putl32 (insn, buf);
|
||||
break;
|
||||
|
||||
case BFD_RELOC_LARCH_SOP_POP_32_S_5_20:
|
||||
if (!last_reloc_is_sop_push_pcrel)
|
||||
break;
|
||||
if ((stack_top & ~(uint64_t) 0x7ffff) != 0x0
|
||||
&& (stack_top & ~(uint64_t) 0x7ffff) != ~(uint64_t) 0x7ffff)
|
||||
as_warn_where (fixP->fx_file, fixP->fx_line, "Reloc overflow");
|
||||
insn = bfd_getl32 (buf);
|
||||
insn = (insn & (~(uint32_t) 0x1ffffe0)) | ((stack_top & 0xfffff) << 5);
|
||||
bfd_putl32 (insn, buf);
|
||||
break;
|
||||
|
||||
case BFD_RELOC_LARCH_SOP_POP_32_U:
|
||||
case BFD_RELOC_LARCH_SOP_POP_32_S_0_5_10_16_S2:
|
||||
case BFD_RELOC_LARCH_SOP_POP_32_S_0_10_10_16_S2:
|
||||
if (!last_reloc_is_sop_push_pcrel)
|
||||
break;
|
||||
if ((stack_top & 0x3) != 0)
|
||||
as_warn_where (fixP->fx_file, fixP->fx_line, "Reloc overflow");
|
||||
stack_top >>= 2;
|
||||
if ((stack_top & ~(uint64_t) 0x1ffffff) != 0x0
|
||||
&& (stack_top & ~(uint64_t) 0x1ffffff) != ~(uint64_t) 0x1ffffff)
|
||||
as_warn_where (fixP->fx_file, fixP->fx_line, "Reloc overflow");
|
||||
insn = bfd_getl32 (buf);
|
||||
insn = ((insn & 0xfc000000)
|
||||
| ((stack_top & 0xffff) << 10)
|
||||
| ((stack_top & 0x3ff0000) >> 16));
|
||||
bfd_putl32 (insn, buf);
|
||||
break;
|
||||
|
||||
case BFD_RELOC_LARCH_SOP_POP_32_U:
|
||||
if (!last_reloc_is_sop_push_pcrel)
|
||||
break;
|
||||
if (stack_top & ~(uint64_t) 0xffffffff)
|
||||
as_warn_where (fixP->fx_file, fixP->fx_line, "Reloc overflow");
|
||||
bfd_putl32 (stack_top, buf);
|
||||
fix_reloc_insn (fixP, (bfd_vma)stack_top, buf);
|
||||
break;
|
||||
|
||||
case BFD_RELOC_64:
|
||||
|
Reference in New Issue
Block a user