forked from Imagelibrary/binutils-gdb
LoongArch: overflow and underflow checks for R_LARCH_32_PCREL
Relocation overflows can silently write incorrect value to the file, so overflow checks are added to avoid this.
This commit is contained in:
@@ -2933,11 +2933,21 @@ perform_relocation (const Elf_Internal_Rela *rel, asection *input_section,
|
|||||||
{
|
{
|
||||||
value -= sec_addr (input_section) + rel->r_offset;
|
value -= sec_addr (input_section) + rel->r_offset;
|
||||||
value += rel->r_addend;
|
value += rel->r_addend;
|
||||||
bfd_vma word = bfd_get (howto->bitsize, input_bfd,
|
/* Check overflow. */
|
||||||
contents + rel->r_offset);
|
if (ELFNN_R_TYPE (rel->r_info) == R_LARCH_32_PCREL)
|
||||||
word = (word & ~howto->dst_mask) | (value & howto->dst_mask);
|
{
|
||||||
bfd_put (howto->bitsize, input_bfd, word, contents + rel->r_offset);
|
r = loongarch_reloc_rewrite_imm_insn (rel, input_section,
|
||||||
r = bfd_reloc_ok;
|
howto, input_bfd,
|
||||||
|
contents, value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bfd_vma word = bfd_get (howto->bitsize, input_bfd,
|
||||||
|
contents + rel->r_offset);
|
||||||
|
word = (word & ~howto->dst_mask) | (value & howto->dst_mask);
|
||||||
|
bfd_put (howto->bitsize, input_bfd, word, contents + rel->r_offset);
|
||||||
|
r = bfd_reloc_ok;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1390,7 +1390,7 @@ static loongarch_reloc_howto_type loongarch_howto_table[] =
|
|||||||
0xffffffff, /* dst_mask */
|
0xffffffff, /* dst_mask */
|
||||||
false, /* pcrel_offset */
|
false, /* pcrel_offset */
|
||||||
BFD_RELOC_LARCH_32_PCREL, /* bfd_reloc_code_real_type */
|
BFD_RELOC_LARCH_32_PCREL, /* bfd_reloc_code_real_type */
|
||||||
NULL, /* adjust_reloc_bits */
|
reloc_sign_bits, /* adjust_reloc_bits */
|
||||||
NULL), /* larch_reloc_type_name */
|
NULL), /* larch_reloc_type_name */
|
||||||
|
|
||||||
/* The paired relocation may be relaxed. */
|
/* The paired relocation may be relaxed. */
|
||||||
|
|||||||
6
ld/testsuite/ld-loongarch-elf/32_pcrel.s
Normal file
6
ld/testsuite/ld-loongarch-elf/32_pcrel.s
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
.section sx,"a"
|
||||||
|
x:
|
||||||
|
nop
|
||||||
|
|
||||||
|
.section sy,"a"
|
||||||
|
.4byte x-.
|
||||||
@@ -200,6 +200,8 @@ if [istarget "loongarch64-*-*"] {
|
|||||||
run_dump_test "bad_pcrel20_s2_global"
|
run_dump_test "bad_pcrel20_s2_global"
|
||||||
run_dump_test "bad_pcrel20_s2_weak"
|
run_dump_test "bad_pcrel20_s2_weak"
|
||||||
run_dump_test "weak-undef-hidden-shared"
|
run_dump_test "weak-undef-hidden-shared"
|
||||||
|
run_dump_test "overflow_32_pcrel"
|
||||||
|
run_dump_test "underflow_32_pcrel"
|
||||||
}
|
}
|
||||||
|
|
||||||
if [check_pie_support] {
|
if [check_pie_support] {
|
||||||
|
|||||||
4
ld/testsuite/ld-loongarch-elf/overflow_32_pcrel.d
Normal file
4
ld/testsuite/ld-loongarch-elf/overflow_32_pcrel.d
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
#source: 32_pcrel.s
|
||||||
|
#as: -mthin-add-sub
|
||||||
|
#ld: -shared --section-start=sx=0x80001000 --section-start=sy=0x1000
|
||||||
|
#error: .*relocation truncated to fit: R_LARCH_32_PCREL against `x'
|
||||||
4
ld/testsuite/ld-loongarch-elf/underflow_32_pcrel.d
Normal file
4
ld/testsuite/ld-loongarch-elf/underflow_32_pcrel.d
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
#source: 32_pcrel.s
|
||||||
|
#as: -mthin-add-sub
|
||||||
|
#ld: -shared --section-start=sx=0x1000 --section-start=sy=0x80001001
|
||||||
|
#error: .*relocation truncated to fit: R_LARCH_32_PCREL against `x'
|
||||||
Reference in New Issue
Block a user