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]

Needless relocations in mn10300-elf


When we have something like this in AM33 assembly:

.long .Lfoo - .Lbar
[...] # no .section changes here
.Lbar:
[...] # there may be .section changes here
.Lfoo:
[...]

We emit the difference between .Lfoo and .Lbar as an adjusted PCREL32
relocation, so that, if there are linker relaxations between the two
labels, we still have a chance to adjust the offset.

However, if the difference is in a difference section, say:

.section .rodata
.long .Lfoo - .Lbar
.text
.Lbar:
[...]
.Lfoo:
[...]

A PC-relative relocation doesn't work, so we end up computing the
offset between the symbols and emitting an *ABS*+offset 32-bit
relocation.  It's pointless to emit such a relocation, though: it will
not help linker relaxations, which was the reason we emitted them in
the first place, so we may as well just apply the relocation
immediately and be done with it.  This is what this patch
accomplishes.  I'm checking it in, approved by Nick Clifton.

Index: gas/ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>

	* config/tc-mn10300.c (tc_gen_reloc): Don't emit an *ABS*
	relocation for differences between symbols in a section other
	than the one in which the difference is to be placed; apply
	the relocation instead.

Index: gas/config/tc-mn10300.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-mn10300.c,v
retrieving revision 1.29
diff -u -p -r1.29 tc-mn10300.c
--- gas/config/tc-mn10300.c 2001/09/19 05:33:28 1.29
+++ gas/config/tc-mn10300.c 2001/09/25 08:47:02
@@ -1824,12 +1824,41 @@ tc_gen_reloc (seg, fixp)
 	{
 	  as_bad_where (fixp->fx_file, fixp->fx_line,
 			"Difference of symbols in different sections is not supported");
-	  return NULL;
 	}
+      else
+	{
+	  char *fixpos = fixp->fx_where + fixp->fx_frag->fr_literal;
 
-      reloc->sym_ptr_ptr = (asymbol **) &bfd_abs_symbol;
-      reloc->addend = (S_GET_VALUE (fixp->fx_addsy)
-		       - S_GET_VALUE (fixp->fx_subsy) + fixp->fx_offset);
+	  reloc->addend = (S_GET_VALUE (fixp->fx_addsy)
+			   - S_GET_VALUE (fixp->fx_subsy) + fixp->fx_offset);
+
+	  switch (fixp->fx_r_type)
+	    {
+	    case BFD_RELOC_8:
+	      md_number_to_chars (fixpos, reloc->addend, 1);
+	      break;
+	      
+	    case BFD_RELOC_16:
+	      md_number_to_chars (fixpos, reloc->addend, 2);
+	      break;
+
+	    case BFD_RELOC_24:
+	      md_number_to_chars (fixpos, reloc->addend, 3);
+	      break;
+
+	    case BFD_RELOC_32:
+	      md_number_to_chars (fixpos, reloc->addend, 4);
+	      break;
+
+	    default:
+	      reloc->sym_ptr_ptr = (asymbol **) &bfd_abs_symbol;
+	      return reloc;
+	    }
+	}
+
+      free (reloc->sym_ptr_ptr);
+      free (reloc);
+      return NULL;
     }
   else
     {

-- 
Alexandre Oliva   Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/
Red Hat GCC Developer                  aoliva@{cygnus.com, redhat.com}
CS PhD student at IC-Unicamp        oliva@{lsd.ic.unicamp.br, gnu.org}
Free Software Evangelist    *Please* write to mailing lists, not to me

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