[binutils-gdb/binutils-2_37-branch] elf/riscv: Fix relaxation with aliases [PR28021]

Michael Matz matz@sourceware.org
Wed Jul 7 16:06:04 GMT 2021


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=7764dd1f5fdc9a4d6d6233b35bbb14ab161df299

commit 7764dd1f5fdc9a4d6d6233b35bbb14ab161df299
Author: Michael Matz <matz@suse.de>
Date:   Mon Jun 28 17:57:17 2021 +0200

    elf/riscv: Fix relaxation with aliases [PR28021]
    
    the fix for PR22756 only changed behaviour for hidden aliases,
    but the same situation exists for non-hidden aliases: sym_hashes[]
    can contain multiple entries pointing to the same symbol structure
    leading to relaxation adjustment to be applied twice.
    
    Fix this by testing for duplicates for everything that looks like it
    has a version.
    
    PR ld/28021
    
    bfd/
            * elfnn-riscv.c (riscv_relax_delete_bytes): Check for any
            versioning.
    
    ld/
            * testsuite/ld-riscv-elf/relax-twice.ver: New.
            * testsuite/ld-riscv-elf/relax-twice-1.s: New.
            * testsuite/ld-riscv-elf/relax-twice-2.s: New.
            * testsuite/ld-riscv-elf/ld-riscv-elf.exp
            (run_relax_twice_test): New, and call it.
    
    (cherry picked from commit 235f5ef4a6b8fbdcfaea8b629f7c6a9792a789de)

Diff:
---
 bfd/ChangeLog                              |  6 ++++
 bfd/elfnn-riscv.c                          |  2 +-
 ld/ChangeLog                               |  9 ++++++
 ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp | 41 ++++++++++++++++++++++++++++
 ld/testsuite/ld-riscv-elf/relax-twice-1.s  | 12 ++++++++
 ld/testsuite/ld-riscv-elf/relax-twice-2.s  | 44 ++++++++++++++++++++++++++++++
 ld/testsuite/ld-riscv-elf/relax-twice.ver  | 11 ++++++++
 7 files changed, 124 insertions(+), 1 deletion(-)

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 39c7fd73f92..5a1efd7425c 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,9 @@
+2021-07-07  Michael Matz  <matz@suse.de>
+
+	PR ld/28021
+	* elfnn-riscv.c (riscv_relax_delete_bytes): Check for any
+	versioning.
+
 2021-07-07  H.J. Lu  <hongjiu.lu@intel.com>
 
 	PR ld/18028
diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c
index f206708a9f3..a02f1af02bd 100644
--- a/bfd/elfnn-riscv.c
+++ b/bfd/elfnn-riscv.c
@@ -3993,7 +3993,7 @@ riscv_relax_delete_bytes (bfd *abfd, asection *sec, bfd_vma addr, size_t count,
 	 foo becomes an alias for foo@BAR, and hence they need the same
 	 treatment.  */
       if (link_info->wrap_hash != NULL
-	  || sym_hash->versioned == versioned_hidden)
+	  || sym_hash->versioned != unversioned)
 	{
 	  struct elf_link_hash_entry **cur_sym_hashes;
 
diff --git a/ld/ChangeLog b/ld/ChangeLog
index b7d9656d5d4..fa8cd35d22f 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,3 +1,12 @@
+2021-07-07  Michael Matz  <matz@suse.de>
+
+	PR ld/28021
+	* testsuite/ld-riscv-elf/relax-twice.ver: New.
+	* testsuite/ld-riscv-elf/relax-twice-1.s: New.
+	* testsuite/ld-riscv-elf/relax-twice-2.s: New.
+	* testsuite/ld-riscv-elf/ld-riscv-elf.exp
+	(run_relax_twice_test): New, and call it.
+
 2021-07-07  H.J. Lu  <hongjiu.lu@intel.com>
 
 	PR ld/18028
diff --git a/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp b/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp
index 1f1245af707..c1418aa4076 100644
--- a/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp
+++ b/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp
@@ -78,6 +78,46 @@ proc run_dump_test_ifunc { name target output} {
 	      "$name-$target.$ext"]]
 }
 
+proc run_relax_twice_test {} {
+    global as
+    global ld
+    global nm
+    global nm_output
+    global srcdir
+    global subdir
+    global runtests
+
+    set testname "relax-twice"
+    if ![runtest_file_p $runtests $testname] then {
+	return
+    }
+
+    # assemble and link the two input files with a version script, then
+    # capture output of nm and compare addresses of the two symbols
+    # 'foobar_new' and 'foobar@@New'.  They must be equal.
+    # Bitness doesn't matter so we simply force 64bit.
+    if { ![ld_assemble_flags $as "-march=rv64i" $srcdir/$subdir/relax-twice-1.s tmpdir/relax-twice-1.o ]
+	|| ![ld_assemble_flags $as "-march=rv64i" $srcdir/$subdir/relax-twice-2.s tmpdir/relax-twice-2.o]
+	|| ![ld_link $ld tmpdir/relax-twice.so "-m[riscv_choose_lp64_emul] -shared --relax --version-script $srcdir/$subdir/relax-twice.ver tmpdir/relax-twice-1.o tmpdir/relax-twice-2.o"] } {
+	fail $testname
+    } elseif { ![ld_nm $nm "" tmpdir/relax-twice.so] } {
+	fail $testname
+    } elseif { ![info exists nm_output(foobar_new)]
+	       || ![info exists nm_output(foobar@@New)]} {
+	send_log "bad output from nm\n"
+	verbose "bad output from nm"
+	fail $testname
+    } elseif {$nm_output(foobar_new) != $nm_output(foobar@@New)} {
+	send_log "foobar_new == $nm_output(foobar_new)\n"
+	verbose "foobar_new == $nm_output(foobar_new)"
+	send_log "foobar@@New == $nm_output(foobar@@New)\n"
+	verbose "foobar@@New == $nm_output(foobar@@New)"
+	fail $testname
+    } else {
+	pass $testname
+    }
+}
+
 if [istarget "riscv*-*-*"] {
     run_dump_test "call-relax"
     run_dump_test "pcgp-relax"
@@ -127,6 +167,7 @@ if [istarget "riscv*-*-*"] {
 
     run_dump_test "relro-relax-lui"
     run_dump_test "relro-relax-pcrel"
+    run_relax_twice_test
 
     set abis [list rv32gc ilp32 [riscv_choose_ilp32_emul] rv64gc lp64 [riscv_choose_lp64_emul]]
     foreach { arch abi emul } $abis {
diff --git a/ld/testsuite/ld-riscv-elf/relax-twice-1.s b/ld/testsuite/ld-riscv-elf/relax-twice-1.s
new file mode 100644
index 00000000000..79f1d942f98
--- /dev/null
+++ b/ld/testsuite/ld-riscv-elf/relax-twice-1.s
@@ -0,0 +1,12 @@
+	.file	"<artificial>"
+	.option pic
+	.text
+	.globl	foobar_new
+	.weak	foobar_new
+	.type	foobar_new, @function
+foobar_new:
+	jr ra
+	.size	foobar_new, .-foobar_new
+	.symver	foobar_new, foobar@@New
+
+	.section	.note.GNU-stack,"",@progbits
diff --git a/ld/testsuite/ld-riscv-elf/relax-twice-2.s b/ld/testsuite/ld-riscv-elf/relax-twice-2.s
new file mode 100644
index 00000000000..39b82b50d19
--- /dev/null
+++ b/ld/testsuite/ld-riscv-elf/relax-twice-2.s
@@ -0,0 +1,44 @@
+	.file	"<artificial>"
+	.option pic
+	.text
+	.section	.rodata.str1.8,"aMS",@progbits,1
+	.align	3
+.LC0:
+	.string	"%u"
+	.text
+	.align	1
+	.globl	relaxme
+	.type	relaxme, @function
+relaxme:
+	addi	sp,sp,-32
+	addi	a2,sp,12
+	lla	a1,.LC0
+	li	a0,0
+	sd	ra,24(sp)
+	call	sscanf@plt
+	ld	ra,24(sp)
+	addi	sp,sp,32
+	jr	ra
+	.size	relaxme, .-relaxme
+	.align	1
+	.globl	foobar_new
+	.type	foobar_new, @function
+foobar_new:
+	li	a0,1
+	ret
+	.size	foobar_new, .-foobar_new
+	.symver	foobar_new, foobar@@New
+	.align	1
+	.globl	foobar_old
+	.type	foobar_old, @function
+foobar_old:
+	addi	sp,sp,-16
+	sd	ra,8(sp)
+	call	foobar@plt
+	ld	ra,8(sp)
+	snez	a0,a0
+	addi	sp,sp,16
+	jr	ra
+	.size	foobar_old, .-foobar_old
+	.symver	foobar_old, foobar@Old
+	.section	.note.GNU-stack,"",@progbits
diff --git a/ld/testsuite/ld-riscv-elf/relax-twice.ver b/ld/testsuite/ld-riscv-elf/relax-twice.ver
new file mode 100644
index 00000000000..a6d80e7b458
--- /dev/null
+++ b/ld/testsuite/ld-riscv-elf/relax-twice.ver
@@ -0,0 +1,11 @@
+Old {
+        global:
+                foobar;
+                relaxme;
+        local:
+                *;
+};
+New {
+        global:
+                foobar;
+} Old;


More information about the Binutils-cvs mailing list