[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