* config/tc-mn10300.c (tc_gen_reloc): Don't reject differences
authorAlexandre Oliva <aoliva@redhat.com>
Sun, 13 May 2001 23:16:30 +0000 (23:16 +0000)
committerAlexandre Oliva <aoliva@redhat.com>
Sun, 13 May 2001 23:16:30 +0000 (23:16 +0000)
between symbols if the base symbol is in the current section;
emit a PC-relative relocation instead.

gas/ChangeLog
gas/config/tc-mn10300.c

index f0de91334273a587fe876f3a1e9494c92050147b..022709c876f5072058357503a392cd20c8285647 100644 (file)
@@ -1,3 +1,9 @@
+2001-05-13  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.
+
 2001-05-12  Peter Targett  <peter.targett@arccores.com>
 
        * config/tc-arc.c: Update copyright and tidy source comments.
index 5e2ba77b92b6f4828d7b03cdd2d29710d6032136..8bda0649e2dea9a39b81223cb6c8e951a1c1ae66 100644 (file)
@@ -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)