[PATCH]: gold sparc unaligned...

David Miller davem@davemloft.net
Mon Feb 8 23:13:00 GMT 2010


With gcc-4.4, or I guess any gcc emitting .cfi_personality directives,
we get a SIGBUS on sparc in gold during the testsuite.

The reason is that the dwarf2 emitter in gas is emitting R_SPARC_32
relocs on unaligned offsets.

This never gets noticed with the BFD linker because the sparc BFD
backend looks for unaligned relocation offsets and handles them
like R_SPARC_UA* relocs when it finds such unaligned relocs.

The PowerPC BFD linker backends do something similar.

I could hack the sparc GAS target code to change which reloc
it emits, as needed, but who knows how many objects out there
already have this unaligned R_SPARC_32 reloc and gold should
be able to link against existing objects.

BTW, when playing around with fixing this in GAS I noticed that the
gold testsuite doesn't use GAS from the build tree.

Ok to commit?

gold/

2010-02-08  David S. Miller  <davem@davemloft.net>

	* sparc.cc (Target_sparc::Relocate::relocate): If relocation offset is
	unaligned for R_SPARC_16, R_SPARC_32, or R_SPARC_64, use the unaligned
	relocation helper function.

diff --git a/gold/sparc.cc b/gold/sparc.cc
index c5ce06a..fee9554 100644
--- a/gold/sparc.cc
+++ b/gold/sparc.cc
@@ -2447,14 +2447,22 @@ Target_sparc<size, big_endian>::Relocate::relocate(
       break;
 
     case elfcpp::R_SPARC_16:
-      Relocate_functions<size, big_endian>::rela16(view, object,
-						   psymval, addend);
+      if (rela.get_r_offset() & 0x1)
+	Reloc::ua16(view, object, psymval, addend);
+      else
+	Relocate_functions<size, big_endian>::rela16(view, object,
+						     psymval, addend);
       break;
 
     case elfcpp::R_SPARC_32:
       if (!parameters->options().output_is_position_independent())
-	Relocate_functions<size, big_endian>::rela32(view, object,
-						     psymval, addend);
+	{
+	  if (rela.get_r_offset() & 0x3)
+	    Reloc::ua32(view, object, psymval, addend);
+	  else
+	    Relocate_functions<size, big_endian>::rela32(view, object,
+							 psymval, addend);
+	}
       break;
 
     case elfcpp::R_SPARC_DISP8:
@@ -2563,8 +2571,13 @@ Target_sparc<size, big_endian>::Relocate::relocate(
 
     case elfcpp::R_SPARC_64:
       if (!parameters->options().output_is_position_independent())
-	      Relocate_functions<size, big_endian>::rela64(view, object,
-							   psymval, addend);
+	{
+	  if (rela.get_r_offset() & 0x7)
+	    Reloc::ua64(view, object, psymval, addend);
+	  else
+	    Relocate_functions<size, big_endian>::rela64(view, object,
+							 psymval, addend);
+	}
       break;
 
     case elfcpp::R_SPARC_OLO10:



More information about the Binutils mailing list