[committed] RISC-V: Fixed overwritten IRELATIVE relocs in the .rel.iplt for data reloc.
Nelson Chu
nelson@rivosinc.com
Mon May 27 17:44:35 GMT 2024
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.
---
bfd/elfnn-riscv.c | 22 ++++++++++++++-----
...verwrite-exe.rd => ifunc-overwrite-exe.rd} | 1 +
...verwrite-pic.rd => ifunc-overwrite-pic.rd} | 6 ++++-
...verwrite-pie.rd => ifunc-overwrite-pie.rd} | 4 ++++
...-plt-got-overwrite.d => ifunc-overwrite.d} | 0
...-plt-got-overwrite.s => ifunc-overwrite.s} | 12 ++++++++++
ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp | 12 +++++-----
7 files changed, 44 insertions(+), 13 deletions(-)
rename ld/testsuite/ld-riscv-elf/{ifunc-plt-got-overwrite-exe.rd => ifunc-overwrite-exe.rd} (76%)
rename ld/testsuite/ld-riscv-elf/{ifunc-plt-got-overwrite-pic.rd => ifunc-overwrite-pic.rd} (71%)
rename ld/testsuite/ld-riscv-elf/{ifunc-plt-got-overwrite-pie.rd => ifunc-overwrite-pie.rd} (66%)
rename ld/testsuite/ld-riscv-elf/{ifunc-plt-got-overwrite.d => ifunc-overwrite.d} (100%)
rename ld/testsuite/ld-riscv-elf/{ifunc-plt-got-overwrite.s => ifunc-overwrite.s} (79%)
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-*-*"] {
--
2.39.3 (Apple Git-146)
More information about the Binutils
mailing list