This is the mail archive of the binutils@sourceware.org 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]
Other format: [Raw text]

[patch] sh relaxing


A couple of patches to fix ld's sh-relax failures.  The BFD bug caused
relaxed jumps to jump to the wrong place.  The GAS one caused offset
tables to be deleted while they were still in use.  Ok?

bfd/ChangeLog
2006-07-25  DJ Delorie  <dj@redhat.com>

	* elf32-sh.c (sh_elf_relax_section): Allow for branches across
	non-moving .align directives.  Preserve any DIR32 offset when
	converting bsr's to jsr's.
	
gas/ChangeLog
2006-07-25  DJ Delorie  <dj@redhat.com>

	* config/tc-sh.c (sh_frob_section): Canonicalize pointers to local
	vs full symbols so that we never have more than one pointer value
	for any given symbol in our symbol table.

Index: bfd/elf32-sh.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-sh.c,v
retrieving revision 1.138
diff -p -U3 -r1.138  bfd/elf32-sh.c
--- bfd/elf32-sh.c	23 Jun 2006 02:58:00 -0000	1.138
+++ bfd/elf32-sh.c	25 Jul 2006 21:22:30 -0000
@@ -2284,7 +2284,11 @@ sh_elf_relax_section (bfd *abfd, asectio
 		 + sec->output_section->vma
 		 + sec->output_offset
 		 + 4));
-      if (foff < -0x1000 || foff >= 0x1000)
+      /* A branch to an address beyond ours might be increased by an
+	 .align that doesn't move when bytes behind us are deleted.
+	 So, we add some slop in this calculation to allow for
+	 that.  */
+      if (foff < -0x1000 || foff >= 0x1000 - 8)
 	{
 	  /* After all that work, we can't shorten this function call.  */
 	  continue;
@@ -2322,6 +2326,12 @@ sh_elf_relax_section (bfd *abfd, asectio
 
       irel->r_addend = -4;
 
+      /* When we calculated the symbol "value" we had an offset in the
+	 DIR32's word in memory (we read and add it above).  However,
+	 the jsr we create does NOT have this offset encoded, so we
+	 have to add it to the addend to preserve it.  */
+      irel->r_addend += bfd_get_32 (abfd, contents + paddr);
+
       /* See if there is another R_SH_USES reloc referring to the same
 	 register load.  */
       for (irelscan = internal_relocs; irelscan < irelend; irelscan++)

Index: gas/config/tc-sh.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-sh.c,v
retrieving revision 1.119
diff -p -U3 -r1.119  gas/config/tc-sh.c
--- gas/config/tc-sh.c	21 Jul 2006 09:46:15 -0000	1.119
+++ gas/config/tc-sh.c	25 Jul 2006 21:22:32 -0000
@@ -3318,6 +3318,21 @@ sh_frob_section (bfd *abfd ATTRIBUTE_UNU
   for (fix = seginfo->fix_root; fix != NULL; fix = fix->fx_next)
     {
       symbolS *sym;
+
+      sym = fix->fx_addsy;
+      /* Check for a local_symbol.  */
+      if (sym && sym->bsym == NULL)
+	{
+	  struct local_symbol *ls = (struct local_symbol *)sym;
+	  /* See if it's been converted.  If so, canonicalize.  */
+	  if (local_symbol_converted_p (ls))
+	    fix->fx_addsy = local_symbol_get_real_symbol (ls);
+	}
+    }
+
+  for (fix = seginfo->fix_root; fix != NULL; fix = fix->fx_next)
+    {
+      symbolS *sym;
       bfd_vma val;
       fixS *fscan;
       struct sh_count_relocs info;


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