This is the mail archive of the binutils-cvs@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[binutils-gdb/binutils-2_29-branch] PR ld/22972 on SPARC.


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

commit 3fa1ac0931fcd8a7683e45da6c29b984ec8feeb6
Author: Eric Botcazou <ebotcazou@gcc.gnu.org>
Date:   Wed Mar 28 12:17:15 2018 +0200

    PR ld/22972 on SPARC.
    
    This is a regression for the corner case of a hidden symbol in a PIC/PIE
    binary which is subject to both a new-style GOTDATA relocation and an
    old-style GOT relocation.  In this case, depending  on the link order,
    the R_SPARC_RELATIVE dynamic relocation for the GOT slot needed because
    of the old-style relocation can be replaced with R_SPARC_NONE coming
    from the GOTDATA relocation.
    
    The fix simply records whether an old-style GOT relocation is seen for a
    symbol and prevents the R_SPARC_NONE from being generated in this case.
    
    bfd/
    	* elfxx-sparc.c (struct _bfd_sparc_elf_link_hash_entry): Add new flag
    	has_old_style_got_reloc.
    	(_bfd_sparc_elf_check_relocs) <GOT relocations>: Set it for old-style
    	relocations.  Fix a couple of long lines.
    	(_bfd_sparc_elf_relocate_section) <R_SPARC_GOTDATA_OP>: Do not generate
    	a R_SPARC_NONE for the GOT slot if the symbol is also subject to
    	old-style GOT relocations.
    ld/
    	* testsuite/ld-sparc/sparc.exp: Add test for mixed GOTDATA/GOT relocs.
    	* testsuite/ld-sparc/gotop-hidden.c: New file.
    	* testsuite/ld-sparc/got-hidden32.s: Likewise.
    	* testsuite/ld-sparc/got-hidden64.s: Likewise.
    	* testsuite/ld-sparc/pass.out: Likewise.

Diff:
---
 bfd/ChangeLog                        | 11 +++++++++++
 bfd/elfxx-sparc.c                    | 24 ++++++++++++++++++------
 ld/ChangeLog                         |  9 +++++++++
 ld/testsuite/ld-sparc/got-hidden32.s | 18 ++++++++++++++++++
 ld/testsuite/ld-sparc/got-hidden64.s | 18 ++++++++++++++++++
 ld/testsuite/ld-sparc/gotop-hidden.c | 13 +++++++++++++
 ld/testsuite/ld-sparc/pass.out       |  1 +
 ld/testsuite/ld-sparc/sparc.exp      | 29 +++++++++++++++++++++++++++++
 8 files changed, 117 insertions(+), 6 deletions(-)

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 4bb031c..6e0fdf1 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,14 @@
+2018-03-28  Eric Botcazou  <ebotcazou@adacore.com>
+
+	PR ld/22972
+	* elfxx-sparc.c (struct _bfd_sparc_elf_link_hash_entry): Add new flag
+	has_old_style_got_reloc.
+	(_bfd_sparc_elf_check_relocs) <GOT relocations>: Set it for old-style
+	relocations.  Fix a couple of long lines.
+	(_bfd_sparc_elf_relocate_section) <R_SPARC_GOTDATA_OP>: Do not generate
+	a R_SPARC_NONE for the GOT slot if the symbol is also subject to old-style
+	GOT relocations.
+
 2018-02-09  Eric Botcazou  <ebotcazou@adacore.com>
 
 	* elfxx-sparc.c (UNDEFINED_WEAK_RESOLVED_TO_ZERO): Reorder conditions.
diff --git a/bfd/elfxx-sparc.c b/bfd/elfxx-sparc.c
index 39078f8..86de475 100644
--- a/bfd/elfxx-sparc.c
+++ b/bfd/elfxx-sparc.c
@@ -712,9 +712,12 @@ struct _bfd_sparc_elf_link_hash_entry
 #define GOT_TLS_IE      3
   unsigned char tls_type;
 
-    /* Symbol has GOT or PLT relocations.  */
+  /* Symbol has GOT or PLT relocations.  */
   unsigned int has_got_reloc : 1;
 
+  /* Symbol has old-style, non-relaxable GOT relocations.  */
+  unsigned int has_old_style_got_reloc : 1;
+
   /* Symbol has non-GOT/non-PLT relocations in text sections.  */
   unsigned int has_non_got_reloc : 1;
 
@@ -1607,7 +1610,8 @@ _bfd_sparc_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
 		    local_got_refcounts[r_symndx] += 1;
 		    break;
 		  }
-		old_tls_type = _bfd_sparc_elf_local_got_tls_type (abfd) [r_symndx];
+		old_tls_type
+		  = _bfd_sparc_elf_local_got_tls_type (abfd) [r_symndx];
 	      }
 
 	    /* If a TLS symbol is accessed using IE at least once,
@@ -1643,8 +1647,14 @@ _bfd_sparc_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
 		return FALSE;
 	    }
 
-          if (eh != NULL)
-            eh->has_got_reloc = 1;
+	  if (eh != NULL)
+	    {
+	      eh->has_got_reloc = 1;
+	      if (r_type == R_SPARC_GOT10
+		  || r_type == R_SPARC_GOT13
+		  || r_type == R_SPARC_GOT22)
+		eh->has_old_style_got_reloc = 1;
+	    }
 	  break;
 
 	case R_SPARC_TLS_GD_CALL:
@@ -3335,12 +3345,14 @@ _bfd_sparc_elf_relocate_section (bfd *output_bfd,
 	      bfd_put_32 (output_bfd, relocation, contents + rel->r_offset);
 
 	      /* If the symbol is global but not dynamic, an .rela.* slot has
-		 been allocated for it in the GOT so output R_SPARC_NONE here.
-		 See also the handling of other GOT relocations just below.  */
+		 been allocated for it in the GOT so output R_SPARC_NONE here,
+		 if it isn't also subject to another, old-style GOT relocation.
+		 See also the handling of these GOT relocations just below.  */
 	      if (h != NULL
 		  && h->dynindx == -1
 		  && !h->forced_local
 		  && h->root.type != bfd_link_hash_undefweak
+		  && !eh->has_old_style_got_reloc
 		  && (h->got.offset & 1) == 0
 		  && bfd_link_pic (info))
 		{
diff --git a/ld/ChangeLog b/ld/ChangeLog
index 0415ea9..df42c58 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,3 +1,12 @@
+2018-03-28  Eric Botcazou  <ebotcazou@adacore.com>
+
+	PR ld/22972
+	* testsuite/ld-sparc/sparc.exp: Add test for mixed GOTDATA/GOT relocs.
+	* testsuite/ld-sparc/gotop-hidden.c: New file.
+	* testsuite/ld-sparc/got-hidden32.s: Likewise.
+	* testsuite/ld-sparc/got-hidden64.s: Likewise.
+	* testsuite/ld-sparc/pass.out: Likewise.
+
 2017-11-24  Alan Modra  <amodra@gmail.com>
 
 	Apply from master
diff --git a/ld/testsuite/ld-sparc/got-hidden32.s b/ld/testsuite/ld-sparc/got-hidden32.s
new file mode 100644
index 0000000..cd1ecf2
--- /dev/null
+++ b/ld/testsuite/ld-sparc/got-hidden32.s
@@ -0,0 +1,18 @@
+	.text
+.LLGETPC0:
+	retl
+	 add	%o7, %l7, %l7
+	.global foo
+	.type foo, #function
+	.proc   04
+foo:
+	save    %sp, -104, %sp
+	sethi	%hi(_GLOBAL_OFFSET_TABLE_-4), %l7
+	call	.LLGETPC0
+	 add	%l7, %lo(_GLOBAL_OFFSET_TABLE_+4), %l7
+	sethi 	%hi(var), %g1
+	or 	%g1, %lo(var), %g1
+	ld 	[%l7+%g1], %g1
+	ld 	[%g1], %i0
+	ret
+	 restore
diff --git a/ld/testsuite/ld-sparc/got-hidden64.s b/ld/testsuite/ld-sparc/got-hidden64.s
new file mode 100644
index 0000000..50e75ca
--- /dev/null
+++ b/ld/testsuite/ld-sparc/got-hidden64.s
@@ -0,0 +1,18 @@
+	.text
+.LLGETPC0:
+	retl
+	 add	%o7, %l7, %l7
+	.global foo
+	.type foo, #function
+	.proc   04
+foo:
+	save    %sp, -160, %sp
+	sethi	%hi(_GLOBAL_OFFSET_TABLE_-4), %l7
+	call	.LLGETPC0
+	 add	%l7, %lo(_GLOBAL_OFFSET_TABLE_+4), %l7
+	sethi 	%hi(var), %g1
+	or 	%g1, %lo(var), %g1
+	ldx 	[%l7+%g1], %g1
+	ld 	[%g1], %i0
+	ret
+	 restore
diff --git a/ld/testsuite/ld-sparc/gotop-hidden.c b/ld/testsuite/ld-sparc/gotop-hidden.c
new file mode 100644
index 0000000..d769c6d
--- /dev/null
+++ b/ld/testsuite/ld-sparc/gotop-hidden.c
@@ -0,0 +1,13 @@
+#include <stdio.h>
+
+extern unsigned int foo (void);
+
+__attribute__((visibility("hidden"))) unsigned int var = 0xdeadbeef;
+
+int main (void)
+{
+  if (var == foo ())
+    puts ("PASS");
+
+  return 0;
+}
diff --git a/ld/testsuite/ld-sparc/pass.out b/ld/testsuite/ld-sparc/pass.out
new file mode 100644
index 0000000..7ef22e9
--- /dev/null
+++ b/ld/testsuite/ld-sparc/pass.out
@@ -0,0 +1 @@
+PASS
diff --git a/ld/testsuite/ld-sparc/sparc.exp b/ld/testsuite/ld-sparc/sparc.exp
index 7782900..395c68f 100644
--- a/ld/testsuite/ld-sparc/sparc.exp
+++ b/ld/testsuite/ld-sparc/sparc.exp
@@ -131,8 +131,37 @@ set sparc64tests {
 if { ![istarget "sparc64-*-elf*"] } {
     run_ld_link_tests $sparctests
 }
+
 if { !([istarget "sparc-*-elf*"]
        || [istarget "sparc-sun-solaris2.5*"]
        || [istarget "sparc-sun-solaris2.6"]) } {
     run_ld_link_tests $sparc64tests
 }
+
+if { [istarget "sparc*-*-linux*"] && [isnative] } {
+    run_ld_link_exec_tests [list \
+	[list \
+	    "32-bit: mixed GOTDATA/GOT relocations" \
+	    "-pie -m32" \
+	    "" \
+	    { gotop-hidden.c got-hidden32.s } \
+	    "gotop-hidden32" \
+	    "pass.out" \
+	    "-fPIE -m32" \
+	] \
+    ]
+}
+
+if { [istarget "sparc64-*-linux*"] && [isnative] } {
+    run_ld_link_exec_tests [list \
+	[list \
+	    "64-bit: mixed GOTDATA/GOT relocations" \
+	    "-pie -m64" \
+	    "" \
+	    { gotop-hidden.c got-hidden64.s } \
+	    "gotop-hidden64" \
+	    "pass.out" \
+	    "-fPIE -m64" \
+	] \
+    ]
+}


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]