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]

mn10300 gas: differences between symbols


I've finally got sufficiently annoyed by the inability to assemble
differences between symbols in different sections that I went ahead
and implemented this.  It only works if the base symbol is in the same
section as the relocation being emitted, but it was good enough for
me.  I'm checking this in, approved by Nick Clifton.

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

	* config/tc-mn10300.c (tc_gen_reloc): Don't reject differences
	between symbols if the base symbol is in the current section;
	emit a PC-relative relocation instead.

Index: gas/config/tc-mn10300.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-mn10300.c,v
retrieving revision 1.23
diff -u -p -r1.23 tc-mn10300.c
--- gas/config/tc-mn10300.c 2001/05/09 13:32:01 1.23
+++ gas/config/tc-mn10300.c 2001/05/13 23:15:36
@@ -1798,6 +1798,45 @@ tc_gen_reloc (seg, fixp)
 
   if (fixp->fx_addsy && fixp->fx_subsy)
     {
+      /* If we got a difference between two symbols, and the
+	 subtracted symbol is in the current section, use a
+	 PC-relative relocation.  If both symbols are in the same
+	 section, the difference would have already been simplified
+	 to a constant.  */
+      if (S_GET_SEGMENT (fixp->fx_subsy) == seg)
+	{
+	  reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
+	  *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
+	  reloc->addend = (reloc->address - S_GET_VALUE (fixp->fx_subsy)
+			   + fixp->fx_offset);
+
+	  switch (fixp->fx_r_type)
+	    {
+	    case BFD_RELOC_8:
+	      reloc->howto = bfd_reloc_type_lookup (stdoutput,
+						    BFD_RELOC_8_PCREL);
+	      return reloc;
+	      
+	    case BFD_RELOC_16:
+	      reloc->howto = bfd_reloc_type_lookup (stdoutput,
+						    BFD_RELOC_16_PCREL);
+	      return reloc;
+
+	    case BFD_RELOC_24:
+	      reloc->howto = bfd_reloc_type_lookup (stdoutput,
+						    BFD_RELOC_24_PCREL);
+	      return reloc;
+
+	    case BFD_RELOC_32:
+	      reloc->howto = bfd_reloc_type_lookup (stdoutput,
+						    BFD_RELOC_32_PCREL);
+	      return reloc;
+
+	    default:
+	      /* Try to compute the absolute value below.  */
+	      break;
+	    }
+	}
 
       if ((S_GET_SEGMENT (fixp->fx_addsy) != S_GET_SEGMENT (fixp->fx_subsy))
 	  || S_GET_SEGMENT (fixp->fx_addsy) == undefined_section)

-- 
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]