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 /bfd | |
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.
Diffstat (limited to 'bfd')
-rw-r--r-- | bfd/elfnn-riscv.c | 22 |
1 files changed, 16 insertions, 6 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, |