From 7160c10d6530b79ea45d435933b07765f610f54d Mon Sep 17 00:00:00 2001
From: James Clarke <jrtc27@jrtc27.com>
Date: Tue, 28 Jun 2016 12:00:56 +0100
Subject: [PATCH] Don't convert R_SPARC_32 to R_SPARC_RELATIVE if class is
 ELFCLASS64.

bfd	* elfxx-sparc.c (_bfd_sparc_elf_relocate_section): Don't convert
	R_SPARC_32 to R_SPARC_RELATIVE if class is ELFCLASS64.

gold	* sparc.cc (Target_sparc::Scan::local): Don't convert R_SPARC_32
	to R_SPARC_RELATIVE if class is ELFCLASS64.
	(Target_sparc::Scan::global): Likewise.

ld	* testsuite/ld-elf/symbolic-func.r: Allow non-zero offsets from
	.text.
---
 bfd/ChangeLog                       |  5 +++++
 bfd/elfxx-sparc.c                   |  3 ++-
 gold/ChangeLog                      |  6 ++++++
 gold/sparc.cc                       | 11 +++++++----
 ld/ChangeLog                        |  5 +++++
 ld/testsuite/ld-elf/symbolic-func.r |  2 +-
 6 files changed, 26 insertions(+), 6 deletions(-)

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index e6ed9609fcc..52b26fcd593 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,8 @@
+2016-06-28  James Clarke  <jrtc27@jrtc27.com>
+
+	* elfxx-sparc.c (_bfd_sparc_elf_relocate_section): Don't convert
+	R_SPARC_32 to R_SPARC_RELATIVE if class is ELFCLASS64.
+
 2016-06-28  Maciej W. Rozycki  <macro@imgtec.com>
 
 	* elf32-mips.c (elf_mips16_howto_table_rel): Add
diff --git a/bfd/elfxx-sparc.c b/bfd/elfxx-sparc.c
index 3c4725566c7..63558c7f555 100644
--- a/bfd/elfxx-sparc.c
+++ b/bfd/elfxx-sparc.c
@@ -3481,7 +3481,8 @@ _bfd_sparc_elf_relocate_section (bfd *output_bfd,
 		}
 	      else
 		{
-		  if (r_type == R_SPARC_32 || r_type == R_SPARC_64)
+		  if (  (!ABI_64_P (output_bfd) && r_type == R_SPARC_32)
+		      || (ABI_64_P (output_bfd) && r_type == R_SPARC_64))
 		    {
 		      outrel.r_info = SPARC_ELF_R_INFO (htab, NULL,
 							0, R_SPARC_RELATIVE);
diff --git a/gold/ChangeLog b/gold/ChangeLog
index 0bf521ddde9..1a52b850dbc 100644
--- a/gold/ChangeLog
+++ b/gold/ChangeLog
@@ -1,3 +1,9 @@
+2016-06-28  James Clarke  <jrtc27@jrtc27.com>
+
+	* sparc.cc (Target_sparc::Scan::local): Don't convert R_SPARC_32
+	to R_SPARC_RELATIVE if class is ELFCLASS64.
+	(Target_sparc::Scan::global): Likewise.
+
 2016-06-23  Cary Coutant  <ccoutant@gmail.com>
 	    Igor Kudrin  <ikudrin@accesssoftek.com>
 
diff --git a/gold/sparc.cc b/gold/sparc.cc
index 10a503153e7..dc4612dc2a1 100644
--- a/gold/sparc.cc
+++ b/gold/sparc.cc
@@ -2292,7 +2292,9 @@ Target_sparc<size, big_endian>::Scan::local(
       // apply the link-time value, so we flag the location with
       // an R_SPARC_RELATIVE relocation so the dynamic loader can
       // relocate it easily.
-      if (parameters->options().output_is_position_independent())
+      if (parameters->options().output_is_position_independent()
+	  && ((size == 64 && r_type == elfcpp::R_SPARC_64)
+	      || (size == 32 && r_type == elfcpp::R_SPARC_32)))
 	{
 	  Reloc_section* rela_dyn = target->rela_dyn_section(layout);
 	  unsigned int r_sym = elfcpp::elf_r_sym<size>(reloc.get_r_info());
@@ -2300,8 +2302,9 @@ Target_sparc<size, big_endian>::Scan::local(
 				       output_section, data_shndx,
 				       reloc.get_r_offset(),
 				       reloc.get_r_addend(), is_ifunc);
+	  break;
 	}
-      break;
+      /* Fall through.  */
 
     case elfcpp::R_SPARC_HIX22:
     case elfcpp::R_SPARC_LOX10:
@@ -2766,8 +2769,8 @@ Target_sparc<size, big_endian>::Scan::global(
 						       reloc.get_r_offset(),
 						       reloc.get_r_addend());
 	      }
-	    else if ((r_type == elfcpp::R_SPARC_32
-		      || r_type == elfcpp::R_SPARC_64)
+	    else if (((size == 64 && r_type == elfcpp::R_SPARC_64)
+		      || (size == 32 && r_type == elfcpp::R_SPARC_32))
 		     && gsym->can_use_relative_reloc(false))
 	      {
 		Reloc_section* rela_dyn = target->rela_dyn_section(layout);
diff --git a/ld/ChangeLog b/ld/ChangeLog
index 79c495d1c7d..9b6ff77afb1 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,3 +1,8 @@
+2016-06-28  James Clarke  <jrtc27@jrtc27.com>
+
+	* testsuite/ld-elf/symbolic-func.r: Allow non-zero offsets from
+	.text.
+
 2016-06-28  Maciej W. Rozycki  <macro@imgtec.com>
 
 	* testsuite/ld-mips-elf/attr-gnu-4-10.d: Match any UNIX OS/ABI.
diff --git a/ld/testsuite/ld-elf/symbolic-func.r b/ld/testsuite/ld-elf/symbolic-func.r
index 174e76fb0f5..3d31f8f72b2 100644
--- a/ld/testsuite/ld-elf/symbolic-func.r
+++ b/ld/testsuite/ld-elf/symbolic-func.r
@@ -14,5 +14,5 @@
 
 Relocation section.*
  *Offset.*
-0*[1-9a-f][0-9a-f]* +[^ ]+ +[^ ]+ +([0-9a-f]+( +\.text( \+ 0)?)?)?
+0*[1-9a-f][0-9a-f]* +[^ ]+ +[^ ]+ +([0-9a-f]+( +\.text( \+ [0-9a-f]+)?)?)?
 #pass
-- 
GitLab