[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