* reloc.c (BFD_RELOC_RX_ABS16_REV): Add.
authorDJ Delorie <dj@redhat.com>
Fri, 17 Dec 2010 04:17:00 +0000 (04:17 +0000)
committerDJ Delorie <dj@redhat.com>
Fri, 17 Dec 2010 04:17:00 +0000 (04:17 +0000)
(BFD_RELOC_RX_ABS32_REV): Add.
* bfd-in2.h: Regenerate.
* libbfd.h: Regenerate.
* elf32-rx.c (rx_reloc_map): Add them.

* config/tc-rx.c (rx_validate_fix_sub): Permit subtraction in more
cases.
(tc_gen_reloc): Fix handling of subtraction (esp wrt endianness).

bfd/ChangeLog
bfd/bfd-in2.h
bfd/elf32-rx.c
bfd/libbfd.h
bfd/reloc.c
gas/ChangeLog
gas/config/tc-rx.c

index fcf2843..39524f6 100644 (file)
@@ -1,3 +1,11 @@
+2010-12-16  DJ Delorie  <dj@redhat.com>
+
+       * reloc.c (BFD_RELOC_RX_ABS16_REV): Add.
+       (BFD_RELOC_RX_ABS32_REV): Add.
+       * bfd-in2.h: Regenerate.
+       * libbfd.h: Regenerate.
+       * elf32-rx.c (rx_reloc_map): Add them.
+
 2010-12-15  H.J. Lu  <hongjiu.lu@intel.com>
 
        * elf.c (_bfd_elf_new_section_hook): Special handling for
index e7805b6..7cf593b 100644 (file)
@@ -3991,7 +3991,9 @@ instructions  */
   BFD_RELOC_RX_OP_SUBTRACT,
   BFD_RELOC_RX_ABS8,
   BFD_RELOC_RX_ABS16,
+  BFD_RELOC_RX_ABS16_REV,
   BFD_RELOC_RX_ABS32,
+  BFD_RELOC_RX_ABS32_REV,
   BFD_RELOC_RX_ABS16U,
   BFD_RELOC_RX_ABS16UW,
   BFD_RELOC_RX_ABS16UL,
index d7e15a0..ac587ef 100644 (file)
@@ -250,7 +250,9 @@ static const struct rx_reloc_map rx_reloc_map [] =
   { BFD_RELOC_RX_OP_SUBTRACT,  R_RX_OPsub },
   { BFD_RELOC_RX_ABS8,         R_RX_ABS8 },
   { BFD_RELOC_RX_ABS16,                R_RX_ABS16 },
+  { BFD_RELOC_RX_ABS16_REV,    R_RX_ABS16_REV },
   { BFD_RELOC_RX_ABS32,                R_RX_ABS32 },
+  { BFD_RELOC_RX_ABS32_REV,    R_RX_ABS32_REV },
   { BFD_RELOC_RX_ABS16UL,      R_RX_ABS16UL },
   { BFD_RELOC_RX_ABS16UW,      R_RX_ABS16UW },
   { BFD_RELOC_RX_ABS16U,       R_RX_ABS16U }
index e706ce4..5687082 100644 (file)
@@ -1802,7 +1802,9 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
   "BFD_RELOC_RX_OP_SUBTRACT",
   "BFD_RELOC_RX_ABS8",
   "BFD_RELOC_RX_ABS16",
+  "BFD_RELOC_RX_ABS16_REV",
   "BFD_RELOC_RX_ABS32",
+  "BFD_RELOC_RX_ABS32_REV",
   "BFD_RELOC_RX_ABS16U",
   "BFD_RELOC_RX_ABS16UW",
   "BFD_RELOC_RX_ABS16UL",
index 5a428a2..6d4eb85 100644 (file)
@@ -4262,8 +4262,12 @@ ENUMX
 ENUMX
   BFD_RELOC_RX_ABS16
 ENUMX
+  BFD_RELOC_RX_ABS16_REV
+ENUMX
   BFD_RELOC_RX_ABS32
 ENUMX
+  BFD_RELOC_RX_ABS32_REV
+ENUMX
   BFD_RELOC_RX_ABS16U
 ENUMX
   BFD_RELOC_RX_ABS16UW
index f16fbbc..507c046 100644 (file)
@@ -1,3 +1,9 @@
+2010-12-16  DJ Delorie  <dj@redhat.com>
+
+       * config/tc-rx.c (rx_validate_fix_sub): Permit subtraction in more
+       cases.
+       (tc_gen_reloc): Fix handling of subtraction (esp wrt endianness).
+
 2010-12-16  Maciej W. Rozycki  <macro@codesourcery.com>
 
        * symbols.c (symbol_clone_if_forward_ref): Call tc_new_dot_label
index 125686f..aa58286 100644 (file)
@@ -1943,10 +1943,14 @@ md_convert_frag (bfd *   abfd ATTRIBUTE_UNUSED,
 int
 rx_validate_fix_sub (struct fix * f)
 {
-  /* We permit the subtraction of two symbols as a 32-bit relocation.  */
+  /* We permit the subtraction of two symbols in a few cases.  */
+  /* mov #sym1-sym2, R3 */
+  if (f->fx_r_type == BFD_RELOC_RX_32_OP)
+    return 1;
+  /* .long sym1-sym2 */
   if (f->fx_r_type == BFD_RELOC_RX_DIFF
       && ! f->fx_pcrel
-      && f->fx_size == 4)
+      && (f->fx_size == 4 || f->fx_size == 2 || f->fx_size == 1))
     return 1;
   return 0;
 }
@@ -2206,6 +2210,7 @@ arelent **
 tc_gen_reloc (asection * seg ATTRIBUTE_UNUSED, fixS * fixp)
 {
   static arelent * reloc[5];
+  int is_opcode = 0;
 
   if (fixp->fx_r_type == BFD_RELOC_NONE)
     {
@@ -2226,6 +2231,13 @@ tc_gen_reloc (asection * seg ATTRIBUTE_UNUSED, fixS * fixp)
   reloc[0]->address       = fixp->fx_frag->fr_address + fixp->fx_where;
   reloc[0]->addend        = fixp->fx_offset;
 
+  if (fixp->fx_r_type == BFD_RELOC_RX_32_OP
+      && fixp->fx_subsy)
+    {
+      fixp->fx_r_type = BFD_RELOC_RX_DIFF;
+      is_opcode = 1;
+    }
+
   /* Certain BFD relocations cannot be translated directly into
      a single (non-Red Hat) RX relocation, but instead need
      multiple RX relocations - handle them here.  */
@@ -2254,10 +2266,16 @@ tc_gen_reloc (asection * seg ATTRIBUTE_UNUSED, fixS * fixp)
          reloc[3]->howto   = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS8);
          break;
        case 2:
-         reloc[3]->howto   = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS16);
+         if (!is_opcode && target_big_endian)
+           reloc[3]->howto   = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS16_REV);
+         else
+           reloc[3]->howto   = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS16);
          break;
        case 4:
-         reloc[3]->howto   = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS32);
+         if (!is_opcode && target_big_endian)
+           reloc[3]->howto   = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS32_REV);
+         else
+           reloc[3]->howto   = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS32);
          break;
        }
       reloc[3]->addend      = 0;