diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index e6ed9609fccaa66709cd7bc67e94108c7f3e31b5..52b26fcd5936fb86a82d0c77c8c9b3b272f51e3a 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 3c4725566c7252e4b78a7ca74110793ef45fabe7..63558c7f55597aecec41b1ae54e5fc7c17bb9e50 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 0bf521ddde9ff77d9d906a433f730d1b042424a5..1a52b850dbc983157017880592fca7072abd8048 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 10a503153e78181618499a4259f221e80c2bdba3..dc4612dc2a1093afba2e2512267a15d3a3a72bf8 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 79c495d1c7d4434fbf2be091d958c1833239222e..9b6ff77afb1a58664d780dd03e147e0da1861e25 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 174e76fb0f5f0b284e1641713342434f3ac948ea..3d31f8f72b261dcc8f534dc76bfe165e253acf88 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