diff options
author | Nelson Chu <nelson@rivosinc.com> | 2024-05-28 01:22:13 +0800 |
---|---|---|
committer | Nelson Chu <nelson@rivosinc.com> | 2024-05-28 01:38:26 +0800 |
commit | e8c26825728385e24990bb7c2968e79908b02410 (patch) | |
tree | a70952d3eac58c803524746645232c34837a6e50 | |
parent | 1d7a877a0f74a7b90d70ca8cc3c0db9461619b1a (diff) | |
download | gdb-e8c26825728385e24990bb7c2968e79908b02410.zip gdb-e8c26825728385e24990bb7c2968e79908b02410.tar.gz gdb-e8c26825728385e24990bb7c2968e79908b02410.tar.bz2 |
RISC-V: Fixed overwritten IRELATIVE relocs in the .rel.iplt for data reloc.
This was originally reported by Hau Hsu <hau.hsu@sifive.com>.
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.
-rw-r--r-- | bfd/elfnn-riscv.c | 22 | ||||
-rw-r--r-- | ld/testsuite/ld-riscv-elf/ifunc-overwrite-exe.rd (renamed from ld/testsuite/ld-riscv-elf/ifunc-plt-got-overwrite-exe.rd) | 1 | ||||
-rw-r--r-- | ld/testsuite/ld-riscv-elf/ifunc-overwrite-pic.rd (renamed from ld/testsuite/ld-riscv-elf/ifunc-plt-got-overwrite-pic.rd) | 6 | ||||
-rw-r--r-- | ld/testsuite/ld-riscv-elf/ifunc-overwrite-pie.rd (renamed from ld/testsuite/ld-riscv-elf/ifunc-plt-got-overwrite-pie.rd) | 4 | ||||
-rw-r--r-- | ld/testsuite/ld-riscv-elf/ifunc-overwrite.d (renamed from ld/testsuite/ld-riscv-elf/ifunc-plt-got-overwrite.d) | 0 | ||||
-rw-r--r-- | ld/testsuite/ld-riscv-elf/ifunc-overwrite.s (renamed from ld/testsuite/ld-riscv-elf/ifunc-plt-got-overwrite.s) | 12 | ||||
-rw-r--r-- | ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp | 12 |
7 files changed, 44 insertions, 13 deletions
diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c index 3fc8726..7591968 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 index 0de47a4..a99170c 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 index f65d789..85fbb4f 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 index 32e66f0..3c0b06e 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 index 333dea3..333dea3 100644 --- a/ld/testsuite/ld-riscv-elf/ifunc-plt-got-overwrite.d +++ b/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 index 6c2f8e8..fd83ae8 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 a1dd0e5..669ac5d 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-*-*"] { |