mirror of
https://github.com/bminor/binutils-gdb.git
synced 2025-12-26 17:18:55 +00:00
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 51a8a7c2e3
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.
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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]*
|
||||
@@ -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
|
||||
@@ -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]*
|
||||
@@ -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
|
||||
@@ -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-*-*"] {
|
||||
|
||||
Reference in New Issue
Block a user