From: Nelson Chu Date: Mon, 27 May 2024 17:22:13 +0000 (+0800) Subject: RISC-V: Fixed overwritten IRELATIVE relocs in the .rel.iplt for data reloc. X-Git-Tag: binutils-2_43~606 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=e8c26825728385e24990bb7c2968e79908b02410;p=thirdparty%2Fbinutils-gdb.git RISC-V: Fixed overwritten IRELATIVE relocs in the .rel.iplt for data reloc. This was originally reported by Hau Hsu . Similar to commit 51a8a7c2e3cc0730831963651a55d23d1fae624d We shouldn't use riscv_elf_append_rela to add dynamic relocs into .rela.iplt in the riscv_elf_relocate_section when handling ifunc data reloc R_RISCV_32/64. This just like what did in the riscv_elf_finish_dynamic_symbol. bfd/ * elfnn-riscv.c (riscv_elf_relocate_section): We shouldn't use riscv_elf_append_rela to add dynamic relocs into .rela.iplt in the riscv_elf_relocate_section when handling ifunc data reloc. ld/ * testsuite/ld-riscv-elf/ifunc-overwrite.s: Updated and renamed. * testsuite/ld-riscv-elf/ifunc-overwrite-exe.rd: Likewise. * testsuite/ld-riscv-elf/ifunc-overwrite-pic.rd: Likewise. * testsuite/ld-riscv-elf/ifunc-overwrite-pie.rd: Likewise. * testsuite/ld-riscv-elf/ifunc-overwrite.d: Renamed. --- diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c index 3fc87267f30..7591968ca9c 100644 --- a/bfd/elfnn-riscv.c +++ b/bfd/elfnn-riscv.c @@ -2358,7 +2358,6 @@ riscv_elf_relocate_section (bfd *output_bfd, || h->plt.offset == (bfd_vma) -1) { Elf_Internal_Rela outrel; - asection *sreloc; /* Need a dynamic relocation to get the real function address. */ @@ -2399,13 +2398,24 @@ riscv_elf_relocate_section (bfd *output_bfd, 2. .rela.got section in dynamic executable. 3. .rela.iplt section in static executable. */ if (bfd_link_pic (info)) - sreloc = htab->elf.irelifunc; + riscv_elf_append_rela (output_bfd, htab->elf.irelifunc, + &outrel); else if (htab->elf.splt != NULL) - sreloc = htab->elf.srelgot; + riscv_elf_append_rela (output_bfd, htab->elf.srelgot, + &outrel); else - sreloc = htab->elf.irelplt; - - riscv_elf_append_rela (output_bfd, sreloc, &outrel); + { + /* Do not use riscv_elf_append_rela to add dynamic + relocs into .rela.iplt, since it may cause the + overwrite problems. This is same as what we did + in the riscv_elf_finish_dynamic_symbol. */ + const struct elf_backend_data *bed = + get_elf_backend_data (output_bfd); + bfd_vma iplt_idx = htab->last_iplt_index--; + bfd_byte *loc = htab->elf.irelplt->contents + + iplt_idx * sizeof (ElfNN_External_Rela); + bed->s->swap_reloca_out (output_bfd, &outrel, loc); + } /* If this reloc is against an external symbol, we do not want to fiddle with the addend. Otherwise, diff --git a/ld/testsuite/ld-riscv-elf/ifunc-plt-got-overwrite-exe.rd b/ld/testsuite/ld-riscv-elf/ifunc-overwrite-exe.rd similarity index 76% rename from ld/testsuite/ld-riscv-elf/ifunc-plt-got-overwrite-exe.rd rename to ld/testsuite/ld-riscv-elf/ifunc-overwrite-exe.rd index 0de47a4009f..a99170c1720 100644 --- a/ld/testsuite/ld-riscv-elf/ifunc-plt-got-overwrite-exe.rd +++ b/ld/testsuite/ld-riscv-elf/ifunc-overwrite-exe.rd @@ -2,3 +2,4 @@ Relocation section '.rela.plt' at .* [ ]+Offset[ ]+Info[ ]+Type[ ]+.* [0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_IRELATIVE[ ]+[0-9a-f]* [0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_IRELATIVE[ ]+[0-9a-f]* +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_IRELATIVE[ ]+[0-9a-f]* diff --git a/ld/testsuite/ld-riscv-elf/ifunc-plt-got-overwrite-pic.rd b/ld/testsuite/ld-riscv-elf/ifunc-overwrite-pic.rd similarity index 71% rename from ld/testsuite/ld-riscv-elf/ifunc-plt-got-overwrite-pic.rd rename to ld/testsuite/ld-riscv-elf/ifunc-overwrite-pic.rd index f65d789b0b8..85fbb4f4247 100644 --- a/ld/testsuite/ld-riscv-elf/ifunc-plt-got-overwrite-pic.rd +++ b/ld/testsuite/ld-riscv-elf/ifunc-overwrite-pic.rd @@ -2,7 +2,11 @@ Relocation section '.rela.got' at .* [ ]+Offset[ ]+Info[ ]+Type[ ]+.* [0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_(32|64)[ ]+foo2\(\)[ ]+foo2 \+ 0 [0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_(32|64)[ ]+foo1\(\)[ ]+foo1 \+ 0 -#... + +Relocation section '.rela.ifunc' at .* +[ ]+Offset[ ]+Info[ ]+Type[ ]+.* +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_(32|64)[ ]+foo3\(\)[ ]+foo3 \+ 0 + Relocation section '.rela.plt' at .* [ ]+Offset[ ]+Info[ ]+Type[ ]+.* [0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_JUMP_SLOT[ ]+foo1\(\)[ ]+foo1 \+ 0 diff --git a/ld/testsuite/ld-riscv-elf/ifunc-plt-got-overwrite-pie.rd b/ld/testsuite/ld-riscv-elf/ifunc-overwrite-pie.rd similarity index 66% rename from ld/testsuite/ld-riscv-elf/ifunc-plt-got-overwrite-pie.rd rename to ld/testsuite/ld-riscv-elf/ifunc-overwrite-pie.rd index 32e66f0bd37..3c0b06ea04e 100644 --- a/ld/testsuite/ld-riscv-elf/ifunc-plt-got-overwrite-pie.rd +++ b/ld/testsuite/ld-riscv-elf/ifunc-overwrite-pie.rd @@ -2,6 +2,10 @@ Relocation section '.rela.got' at .* [ ]+Offset[ ]+Info[ ]+Type[ ]+.* [0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_IRELATIVE[ ]+[0-9a-f]* +Relocation section '.rela.ifunc' at .* +[ ]+Offset[ ]+Info[ ]+Type[ ]+.* +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_IRELATIVE[ ]+[0-9a-f]* + Relocation section '.rela.plt' at .* [ ]+Offset[ ]+Info[ ]+Type[ ]+.* [0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_IRELATIVE[ ]+[0-9a-f]* diff --git a/ld/testsuite/ld-riscv-elf/ifunc-plt-got-overwrite.d b/ld/testsuite/ld-riscv-elf/ifunc-overwrite.d similarity index 100% rename from ld/testsuite/ld-riscv-elf/ifunc-plt-got-overwrite.d rename to ld/testsuite/ld-riscv-elf/ifunc-overwrite.d diff --git a/ld/testsuite/ld-riscv-elf/ifunc-plt-got-overwrite.s b/ld/testsuite/ld-riscv-elf/ifunc-overwrite.s similarity index 79% rename from ld/testsuite/ld-riscv-elf/ifunc-plt-got-overwrite.s rename to ld/testsuite/ld-riscv-elf/ifunc-overwrite.s index 6c2f8e8c42e..fd83ae836b6 100644 --- a/ld/testsuite/ld-riscv-elf/ifunc-plt-got-overwrite.s +++ b/ld/testsuite/ld-riscv-elf/ifunc-overwrite.s @@ -13,6 +13,10 @@ foo_resolver: .type foo2, %gnu_indirect_function .set foo2, foo_resolver + .globl foo3 + .type foo3, %gnu_indirect_function + .set foo3, foo_resolver + .globl bar .type bar, @function bar: @@ -36,3 +40,11 @@ bar: .endif ret .size bar, .-bar + + .data +foo3_addr: +.ifdef __64_bit__ + .quad foo3 +.else + .long foo3 +.endif diff --git a/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp b/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp index a1dd0e5e37e..669ac5d506d 100644 --- a/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp +++ b/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp @@ -277,12 +277,12 @@ if [istarget "riscv*-*-*"] { run_dump_test_ifunc "ifunc-plt-02" rv64 pie run_dump_test_ifunc "ifunc-plt-02" rv64 pic # Check the .rela.iplt overwrite issue. - run_dump_test_ifunc "ifunc-plt-got-overwrite" rv32 exe - run_dump_test_ifunc "ifunc-plt-got-overwrite" rv32 pie - run_dump_test_ifunc "ifunc-plt-got-overwrite" rv32 pic - run_dump_test_ifunc "ifunc-plt-got-overwrite" rv64 exe - run_dump_test_ifunc "ifunc-plt-got-overwrite" rv64 pie - run_dump_test_ifunc "ifunc-plt-got-overwrite" rv64 pic + run_dump_test_ifunc "ifunc-overwrite" rv32 exe + run_dump_test_ifunc "ifunc-overwrite" rv32 pie + run_dump_test_ifunc "ifunc-overwrite" rv32 pic + run_dump_test_ifunc "ifunc-overwrite" rv64 exe + run_dump_test_ifunc "ifunc-overwrite" rv64 pie + run_dump_test_ifunc "ifunc-overwrite" rv64 pic # TODO: Make the following tests work under RV32. if [istarget "riscv32-*-*"] {