This is the mail archive of the binutils@sources.redhat.com 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]

[PATCH] Use R_SPARC_UA32 for unaligned data relocs


Beginning with the new EH ABI, GCC regularly emits unaligned relocations
in dwarf sections.  On sparc, GNU as incorrectly emits R_SPARC_32 relocs
for these, causing a SIGBUS in ld.so.  This breaks programs built with the
GCC 3.0 branch or mainline and GNU binutils on sparc-solaris.

Below is my attempt at fixing gas.  The easy path would have been
using R_SPARC_UA32 in place of R_SPARC_32 everywhere, which is just what
the native assembler appears to do.  I've chosen to be conservative,
emitting R_SPARC_UA32 only for unaligned directives (e.g. uaword).
Dynamic linking will be faster that way (in theory).

I've tested this on the 010521 snapshot and sparc-sun-solaris2.7 with no
regressions.


2001-05-22  Jeff Sturm  <jsturm@one-point.com>

	* elf32-sparc.c: Enable BFD_RELOC_SPARC_UA32 mapping.
	* elf64-sparc.c: Likewise.

diff -rup binutils-010521/bfd/elf32-sparc.c binutils-new/bfd/elf32-sparc.c
--- binutils-010521/bfd/elf32-sparc.c	Thu Mar  8 16:04:00 2001
+++ binutils-new/bfd/elf32-sparc.c	Tue May 22 14:29:43 2001
@@ -159,8 +159,7 @@ static CONST struct elf_reloc_map sparc_
   { BFD_RELOC_SPARC_JMP_SLOT, R_SPARC_JMP_SLOT },
   { BFD_RELOC_SPARC_RELATIVE, R_SPARC_RELATIVE },
   { BFD_RELOC_SPARC_WDISP22, R_SPARC_WDISP22 },
-  /* ??? Doesn't dwarf use this?  */
-/*{ BFD_RELOC_SPARC_UA32, R_SPARC_UA32 }, not used?? */
+  { BFD_RELOC_SPARC_UA32, R_SPARC_UA32 },
   {BFD_RELOC_SPARC_10, R_SPARC_10},
   {BFD_RELOC_SPARC_11, R_SPARC_11},
   {BFD_RELOC_SPARC_64, R_SPARC_64},
diff -rup binutils-010521/bfd/elf64-sparc.c binutils-new/bfd/elf64-sparc.c
--- binutils-010521/bfd/elf64-sparc.c	Thu Mar  8 16:04:01 2001
+++ binutils-new/bfd/elf64-sparc.c	Tue May 22 14:29:58 2001
@@ -188,8 +188,7 @@ static CONST struct elf_reloc_map sparc_
   { BFD_RELOC_SPARC_JMP_SLOT, R_SPARC_JMP_SLOT },
   { BFD_RELOC_SPARC_RELATIVE, R_SPARC_RELATIVE },
   { BFD_RELOC_SPARC_WDISP22, R_SPARC_WDISP22 },
-  /* ??? Doesn't dwarf use this?  */
-/*{ BFD_RELOC_SPARC_UA32, R_SPARC_UA32 }, not used?? */
+  { BFD_RELOC_SPARC_UA32, R_SPARC_UA32 },
   {BFD_RELOC_SPARC_10, R_SPARC_10},
   {BFD_RELOC_SPARC_11, R_SPARC_11},
   {BFD_RELOC_SPARC_64, R_SPARC_64},

2001-05-22  Jeff Sturm  <jsturm@one-point.com>

	* config/tc-sparc.c (md_apply_fix3): Handle BFD_RELOC_SPARC_UA32
	as BFD_RELOC_32.
	(tc_gen_reloc): Likewise.
	(sparc_cons_align): Don't clear sparc_no_align_cons.
	(cons_fix_new_sparc): Substitute BFD_RELOC_SPARC_UA32 for
	BFD_RELOC_32 iff sparc_no_align_cons is set.

diff -rup binutils-010521/gas/config/tc-sparc.c binutils-new/gas/config/tc-sparc.c
--- binutils-010521/gas/config/tc-sparc.c	Thu Mar  8 18:24:25 2001
+++ binutils-new/gas/config/tc-sparc.c	Wed May 23 00:24:39 2001
@@ -2976,6 +2976,7 @@ md_apply_fix3 (fixP, value, segment)
       md_number_to_chars (buf, val, 2);
     }
   else if (fixP->fx_r_type == BFD_RELOC_32
+	   || fixP->fx_r_type == BFD_RELOC_SPARC_UA32
 	   || fixP->fx_r_type == BFD_RELOC_SPARC_REV32)
     {
       md_number_to_chars (buf, val, 4);
@@ -3316,6 +3317,7 @@ tc_gen_reloc (section, fixp)
     case BFD_RELOC_SPARC_LOX10:
     case BFD_RELOC_SPARC_REV32:
     case BFD_RELOC_SPARC_OLO10:
+    case BFD_RELOC_SPARC_UA32:
     case BFD_RELOC_VTABLE_ENTRY:
     case BFD_RELOC_VTABLE_INHERIT:
       code = fixp->fx_r_type;
@@ -4066,12 +4068,9 @@ sparc_cons_align (nbytes)
   if (! enforce_aligned_data)
     return;
 
+  /* Don't align if this is an unaligned pseudo-op.  */
   if (sparc_no_align_cons)
-    {
-      /* This is an unaligned pseudo-op.  */
-      sparc_no_align_cons = 0;
-      return;
-    }
+    return;
 
   nalign = log2 (nbytes);
   if (nalign == 0)
@@ -4199,6 +4198,11 @@ cons_fix_new_sparc (frag, where, nbytes,
   if (target_little_endian_data && nbytes == 4
       && now_seg->flags & SEC_ALLOC)
     r = BFD_RELOC_SPARC_REV32;
+
+  if (sparc_no_align_cons && nbytes == 4)
+    r = BFD_RELOC_SPARC_UA32;
+  sparc_no_align_cons = 0;
+
   fix_new_exp (frag, where, (int) nbytes, exp, 0, r);
 }
 




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