* elf32-mn10300.c (bfd_elf32_mn10300_reloc): New function.
authorJeff Law <law@redhat.com>
Mon, 25 Nov 1996 15:59:07 +0000 (15:59 +0000)
committerJeff Law <law@redhat.com>
Mon, 25 Nov 1996 15:59:07 +0000 (15:59 +0000)
        (enum reloc_type): Add more reloc types.
        (elf32_mn10300_howto_table): Update for new reloc types.
        (elf32_mn10300_reloc_map): Update for new reloc types.
        * reloc.c: Add some new relocs for the mn10300 series.
        * bfd-in2.h, libbfd.h: Rebuilt.
Last week's reloc work.

bfd/ChangeLog
bfd/elf32-mn10300.c

index 2b5439e8af6519fbf41b23eefbcd00c81d473c5a..a96d00cac96317b7874f4970752353ed10bbe7b3 100644 (file)
@@ -1,3 +1,12 @@
+Mon Nov 25 08:52:29 1996  Jeffrey A Law  (law@cygnus.com)
+
+       * elf32-mn10300.c (bfd_elf32_mn10300_reloc): New function.
+       (enum reloc_type): Add more reloc types.
+       (elf32_mn10300_howto_table): Update for new reloc types.
+       (elf32_mn10300_reloc_map): Update for new reloc types.
+       * reloc.c: Add some new relocs for the mn10300 series.
+       * bfd-in2.h, libbfd.h: Rebuilt.
+       
 Sat Nov 23 13:26:18 1996  Jeffrey A Law  (law@cygnus.com)
 
        * som.c (setup_sections): Don't lose for a space which has
index 4fe8f7a94300076aebdccb7991d2269aae8b258a..659a11dae045272aad617769cf77c8a8219a5bf2 100644 (file)
@@ -26,6 +26,9 @@ static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup
   PARAMS ((bfd *abfd, bfd_reloc_code_real_type code));
 static void mn10300_info_to_howto_rel
   PARAMS ((bfd *, arelent *, Elf32_Internal_Rel *));
+static bfd_reloc_status_type bfd_elf32_mn10300_reloc
+  PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
+
 
 /* Try to minimize the amount of space occupied by relocation tables
    on the ROM (not that the ROM won't be swamped by other ELF overhead).  */
@@ -37,9 +40,13 @@ enum reloc_type
   R_MN10300_32,
   R_MN10300_16,
   R_MN10300_8,
-  R_MN10300_PCREL32,
-  R_MN10300_PCREL16,
-  R_MN10300_PCREL8,
+  R_MN10300_32B,
+  R_MN10300_16B,
+  R_MN10300_PCREL32_1BYTE,
+  R_MN10300_PCREL16_1BYTE,
+  R_MN10300_PCREL8_1BYTE,
+  R_MN10300_PCREL32_2BYTE,
+  R_MN10300_PCREL16_2BYTE,
   R_MN10300_MAX
 };
 
@@ -98,45 +105,97 @@ static reloc_howto_type elf_mn10300_howto_table[] =
         0xff,
         0xff,
         false),
-  HOWTO (R_MN10300_PCREL32,
+  HOWTO (R_MN10300_32B,
         0,
         2,
         32,
+        false,
+        0,
+        complain_overflow_bitfield,
+        bfd_elf32_mn10300_reloc,
+        "R_MN10300_32B",
         true,
+        0xffffffff,
+        0xffffffff,
+        false),
+  HOWTO (R_MN10300_16B,
+        0,
+        1,
+        16,
+        false,
         0,
         complain_overflow_bitfield,
-        bfd_elf_generic_reloc,
-        "R_MN10300_PCREL32",
+        bfd_elf32_mn10300_reloc,
+        "R_MN10300_16B",
+        true,
+        0xffff,
+        0xffff,
+        false),
+  HOWTO (R_MN10300_PCREL32_1BYTE,
+        0,
+        2,
+        32,
+        true,
+        0,
+        complain_overflow_bitfield,
+        bfd_elf32_mn10300_reloc,
+        "R_MN10300_PCREL32_1BYTE",
         true,
         0xffffffff,
         0xffffffff,
         false),
-  HOWTO (R_MN10300_PCREL16,
+  HOWTO (R_MN10300_PCREL16_1BYTE,
         0,
         1,
         16,
         true,
         0,
         complain_overflow_bitfield,
-        bfd_elf_generic_reloc,
-        "R_MN10300_PCREL16",
+        bfd_elf32_mn10300_reloc,
+        "R_MN10300_PCREL16_1BYTE",
         true,
         0xffff,
         0xffff,
         false),
-  HOWTO (R_MN10300_PCREL8,
+  HOWTO (R_MN10300_PCREL8_1BYTE,
         0,
         0,
         8,
         true,
         0,
         complain_overflow_bitfield,
-        bfd_elf_generic_reloc,
-        "R_MN10300_PCREL8",
+        bfd_elf32_mn10300_reloc,
+        "R_MN10300_PCREL8_1BYTE",
         true,
         0xff,
         0xff,
-        false),
+        true),
+  HOWTO (R_MN10300_PCREL32_2BYTE,
+        0,
+        2,
+        32,
+        true,
+        0,
+        complain_overflow_bitfield,
+        bfd_elf32_mn10300_reloc,
+        "R_MN10300_PCREL32_2BYTE",
+        true,
+        0xffffffff,
+        0xffffffff,
+        true),
+  HOWTO (R_MN10300_PCREL16_2BYTE,
+        0,
+        1,
+        16,
+        true,
+        0,
+        complain_overflow_bitfield,
+        bfd_elf32_mn10300_reloc,
+        "R_MN10300_PCREL16_2BYTE",
+        true,
+        0xffff,
+        0xffff,
+        true),
 };
 
 struct mn10300_reloc_map
@@ -151,9 +210,13 @@ static const struct mn10300_reloc_map mn10300_reloc_map[] =
   { BFD_RELOC_32, R_MN10300_32, },
   { BFD_RELOC_16, R_MN10300_16, },
   { BFD_RELOC_8, R_MN10300_8, },
-  { BFD_RELOC_32_PCREL, R_MN10300_PCREL32, },
-  { BFD_RELOC_16_PCREL, R_MN10300_PCREL16, },
-  { BFD_RELOC_8_PCREL, R_MN10300_PCREL8, },
+  { BFD_RELOC_MN10300_32B, R_MN10300_32B, },
+  { BFD_RELOC_MN10300_16B, R_MN10300_16B, },
+  { BFD_RELOC_32_PCREL, R_MN10300_PCREL32_1BYTE, },
+  { BFD_RELOC_16_PCREL, R_MN10300_PCREL16_1BYTE, },
+  { BFD_RELOC_8_PCREL, R_MN10300_PCREL8_1BYTE, },
+  { BFD_RELOC_MN10300_32_PCREL, R_MN10300_PCREL32_2BYTE, },
+  { BFD_RELOC_MN10300_16_PCREL, R_MN10300_PCREL16_2BYTE, },
 };
 
 static reloc_howto_type *
@@ -174,7 +237,7 @@ bfd_elf32_bfd_reloc_type_lookup (abfd, code)
   return NULL;
 }
 
-/* Set the howto pointer for an V850 ELF reloc.  */
+/* Set the howto pointer for an MN10300 ELF reloc.  */
 
 static void
 mn10300_info_to_howto_rel (abfd, cache_ptr, dst)
@@ -189,6 +252,101 @@ mn10300_info_to_howto_rel (abfd, cache_ptr, dst)
   cache_ptr->howto = &elf_mn10300_howto_table[r_type];
 }
 
+static bfd_reloc_status_type
+bfd_elf32_mn10300_reloc (abfd, reloc, symbol, data, isection, obfd, err)
+     bfd *abfd;
+     arelent *reloc;
+     asymbol *symbol;
+     PTR data;
+     asection *isection;
+     bfd *obfd;
+     char **err;
+{
+  if (obfd != (bfd *) NULL
+      && (symbol->flags & BSF_SECTION_SYM) == 0
+      && (! reloc->howto->partial_inplace
+         || reloc->addend == 0))
+    {
+      reloc->address += isection->output_offset;
+      return bfd_reloc_ok;
+    }
+  else if (obfd != NULL)
+    {
+      return bfd_reloc_continue;
+    }
+
+  /* Catch relocs involving undefined symbols.  */
+  if (bfd_is_und_section (symbol->section)
+      && (symbol->flags & BSF_WEAK) == 0
+      && obfd == NULL)
+    return bfd_reloc_undefined;
+
+  /* We handle final linking of some relocs ourselves.  */
+    {
+      long relocation, insn;
+
+      /* Is the address of the relocation really within the section?  */
+      if (reloc->address > isection->_cooked_size)
+       return bfd_reloc_outofrange;
+
+      /* Work out which section the relocation is targetted at and the
+        initial relocation command value.  */
+
+      /* Get symbol value.  (Common symbols are special.)  */
+      if (bfd_is_com_section (symbol->section))
+       relocation = 0;
+      else
+       relocation = symbol->value;
+
+      /* Convert input-section-relative symbol value to absolute + addend.  */
+      relocation += symbol->section->output_section->vma;
+      relocation += symbol->section->output_offset;
+      relocation += reloc->addend;
+
+      if (reloc->howto->pc_relative == true)
+       {
+         /* Here the variable relocation holds the final address of the
+            symbol we are relocating against, plus any addend.  */
+         relocation -= isection->output_section->vma + isection->output_offset;
+
+         /* Deal with pcrel_offset */
+         relocation -= reloc->address;
+
+         if (reloc->howto->type == R_MN10300_PCREL32_1BYTE
+             || reloc->howto->type == R_MN10300_PCREL16_1BYTE
+             || reloc->howto->type == R_MN10300_PCREL8_1BYTE)
+            relocation += 1;
+         else if (reloc->howto->type == R_MN10300_PCREL32_2BYTE
+             || reloc->howto->type == R_MN10300_PCREL16_2BYTE)
+            relocation += 2;
+       }
+
+      /* I've got no clue... */
+      reloc->addend = 0;       
+
+      if (reloc->howto->size == 0)
+       {
+         if (relocation > 0x7f || relocation < -0x80)
+           return bfd_reloc_overflow;
+
+         bfd_put_8 (abfd, relocation & 0xff,
+                    (bfd_byte *)data + reloc->address);
+       }
+      else if (reloc->howto->size == 1)
+       {
+         if (relocation > 0x7fff || relocation < -0x8000)
+           return bfd_reloc_overflow;
+
+         bfd_putb16 (relocation & 0xffff, (bfd_byte *)data + reloc->address);
+       }
+      else if (reloc->howto->size == 2)
+       bfd_putb32 (relocation, (bfd_byte *)data + reloc->address);
+      return bfd_reloc_ok;
+    }
+
+  return bfd_reloc_continue;
+}
+
 #define TARGET_LITTLE_SYM      bfd_elf32_mn10300_vec
 #define TARGET_LITTLE_NAME     "elf32-mn10300"
 #define ELF_ARCH               bfd_arch_mn10300