From e14af8fc413ad29a7943e68cbb2cb79c79916221 Mon Sep 17 00:00:00 2001
From: Jeff Law <law@redhat.com>
Date: Wed, 11 Dec 1996 06:31:23 +0000
Subject: [PATCH]         * elf32-mn10300.c (reloc_type): Remove big endian
 mn10300 reloc         variants.         (elf32_mn10300_howto_table,
 mn10300_reloc_map): Likewise.         (bfd_elf32_mn10300_reloc): Write data
 in little endian format.         * reloc.c: Remove mn10300 big endian relocs.
         * bfd-in2.h, libbfd.h: Rebuilt.

        * elf32-mn10200.c: Update from elf32-mn10300.c.
---
 bfd/elf32-mn10200.c | 295 ++++++++++++++++++++++++++++++++++++++++++--
 bfd/elf32-mn10300.c |  37 +-----
 2 files changed, 287 insertions(+), 45 deletions(-)

diff --git a/bfd/elf32-mn10200.c b/bfd/elf32-mn10200.c
index 88c3cbecb84..7c2431733fd 100644
--- a/bfd/elf32-mn10200.c
+++ b/bfd/elf32-mn10200.c
@@ -24,22 +24,37 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
 static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup
   PARAMS ((bfd *abfd, bfd_reloc_code_real_type code));
-static void mn10200_info_to_howto_rel
-  PARAMS ((bfd *, arelent *, Elf32_Internal_Rel *));
+static void mn10200_info_to_howto
+  PARAMS ((bfd *, arelent *, Elf32_Internal_Rela *));
+static bfd_reloc_status_type bfd_elf32_mn10200_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).  */
-#define USE_REL
+
+/* We have to use RELA instructions since md_apply_fix3 in the assembler
+   does absolutely nothing.  */
+#define USE_RELA
 
 enum reloc_type
 {
   R_MN10200_NONE = 0,
+#if 0
+  R_MN10200_32,
+  R_MN10200_16,
+  R_MN10200_8,
+  R_MN10200_32B,
+  R_MN10200_16B,
+  R_MN10200_PCREL32_1BYTE,
+  R_MN10200_PCREL16_1BYTE,
+  R_MN10200_PCREL8_1BYTE,
+  R_MN10200_PCREL32_2BYTE,
+  R_MN10200_PCREL16_2BYTE,
+#endif
   R_MN10200_MAX
 };
 
 static reloc_howto_type elf_mn10200_howto_table[] =
 {
-  /* */
+  /* Dummy relocation.  Does nothing.  */
   HOWTO (R_MN10200_NONE,
 	 0,
 	 2,
@@ -53,6 +68,153 @@ static reloc_howto_type elf_mn10200_howto_table[] =
 	 0,
 	 0,
 	 false),
+#if 0
+  /* Standard 32 bit reloc.  */
+  HOWTO (R_MN10200_32,
+	 0,
+	 2,
+	 32,
+	 false,
+	 0,
+	 complain_overflow_bitfield,
+	 bfd_elf_generic_reloc,
+	 "R_MN10200_32",
+	 false,
+	 0xffffffff,
+	 0xffffffff,
+	 false),
+  /* Standard 16 bit reloc.  */
+  HOWTO (R_MN10200_16,
+	 0,
+	 1,
+	 16,
+	 false,
+	 0,
+	 complain_overflow_bitfield,
+	 bfd_elf_generic_reloc,
+	 "R_MN10200_16",
+	 false,
+	 0xffff,
+	 0xffff,
+	 false),
+  /* Standard 8 bit reloc.  */
+  HOWTO (R_MN10200_8,
+	 0,
+	 0,
+	 8,
+	 false,
+	 0,
+	 complain_overflow_bitfield,
+	 bfd_elf_generic_reloc,
+	 "R_MN10200_8",
+	 false,
+	 0xff,
+	 0xff,
+	 false),
+  /* Standard 32 bit reloc, except it explicitly writes big-endian format.  */
+  HOWTO (R_MN10200_32B,
+	 0,
+	 2,
+	 32,
+	 false,
+	 0,
+	 complain_overflow_bitfield,
+	 bfd_elf32_mn10200_reloc,
+	 "R_MN10200_32B",
+	 false,
+	 0xffffffff,
+	 0xffffffff,
+	 false),
+  /* Standard 16 bit reloc, except it explicitly writes big-endian format.  */
+  HOWTO (R_MN10200_16B,
+	 0,
+	 1,
+	 16,
+	 false,
+	 0,
+	 complain_overflow_bitfield,
+	 bfd_elf32_mn10200_reloc,
+	 "R_MN10200_16B",
+	 false,
+	 0xffff,
+	 0xffff,
+	 false),
+  /* Simple 32bit pc-relative reloc with a 1 byte adjustment
+     to get the pc-relative offset correct.  */
+  HOWTO (R_MN10200_PCREL32_1BYTE,
+	 0,
+	 2,
+	 32,
+	 true,
+	 0,
+	 complain_overflow_bitfield,
+	 bfd_elf32_mn10200_reloc,
+	 "R_MN10200_PCREL32_1BYTE",
+	 true,
+	 0xffffffff,
+	 0xffffffff,
+	 false),
+  /* Simple 16bit pc-relative reloc with a 1 byte adjustment
+     to get the pc-relative offset correct.  */
+  HOWTO (R_MN10200_PCREL16_1BYTE,
+	 0,
+	 1,
+	 16,
+	 true,
+	 0,
+	 complain_overflow_bitfield,
+	 bfd_elf32_mn10200_reloc,
+	 "R_MN10200_PCREL16_1BYTE",
+	 true,
+	 0xffff,
+	 0xffff,
+	 false),
+  /* Simple 8 pc-relative reloc with a 1 byte adjustment
+     to get the pc-relative offset correct.  */
+  HOWTO (R_MN10200_PCREL8_1BYTE,
+	 0,
+	 0,
+	 8,
+	 true,
+	 0,
+	 complain_overflow_bitfield,
+	 bfd_elf32_mn10200_reloc,
+	 "R_MN10200_PCREL8_1BYTE",
+	 true,
+	 0xff,
+	 0xff,
+	 true),
+  /* Simple 32 pc-relative reloc with a 2 byte adjustment
+     to get the pc-relative offset correct.  */
+  HOWTO (R_MN10200_PCREL32_2BYTE,
+	 0,
+	 2,
+	 32,
+	 true,
+	 0,
+	 complain_overflow_bitfield,
+	 bfd_elf32_mn10200_reloc,
+	 "R_MN10200_PCREL32_2BYTE",
+	 true,
+	 0xffffffff,
+	 0xffffffff,
+	 true),
+  /* Simple 16 pc-relative reloc with a 2 byte adjustment
+     to get the pc-relative offset correct.  */
+  HOWTO (R_MN10200_PCREL16_2BYTE,
+	 0,
+	 1,
+	 16,
+	 true,
+	 0,
+	 complain_overflow_bitfield,
+	 bfd_elf32_mn10200_reloc,
+	 "R_MN10200_PCREL16_2BYTE",
+	 true,
+	 0xffff,
+	 0xffff,
+	 true),
+#endif
 };
 
 struct mn10200_reloc_map
@@ -64,6 +226,18 @@ struct mn10200_reloc_map
 static const struct mn10200_reloc_map mn10200_reloc_map[] =
 {
   { BFD_RELOC_NONE, R_MN10200_NONE, },
+#if 0
+  { BFD_RELOC_32, R_MN10200_32, },
+  { BFD_RELOC_16, R_MN10200_16, },
+  { BFD_RELOC_8, R_MN10200_8, },
+  { BFD_RELOC_MN10200_32B, R_MN10200_32B, },
+  { BFD_RELOC_MN10200_16B, R_MN10200_16B, },
+  { BFD_RELOC_32_PCREL, R_MN10200_PCREL32_1BYTE, },
+  { BFD_RELOC_16_PCREL, R_MN10200_PCREL16_1BYTE, },
+  { BFD_RELOC_8_PCREL, R_MN10200_PCREL8_1BYTE, },
+  { BFD_RELOC_MN10200_32_PCREL, R_MN10200_PCREL32_2BYTE, },
+  { BFD_RELOC_MN10200_16_PCREL, R_MN10200_PCREL16_2BYTE, },
+#endif
 };
 
 static reloc_howto_type *
@@ -84,13 +258,13 @@ 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 MN10200 ELF reloc.  */
 
 static void
-mn10200_info_to_howto_rel (abfd, cache_ptr, dst)
+mn10200_info_to_howto (abfd, cache_ptr, dst)
      bfd *abfd;
      arelent *cache_ptr;
-     Elf32_Internal_Rel *dst;
+     Elf32_Internal_Rela *dst;
 {
   unsigned int r_type;
 
@@ -99,13 +273,112 @@ mn10200_info_to_howto_rel (abfd, cache_ptr, dst)
   cache_ptr->howto = &elf_mn10200_howto_table[r_type];
 }
 
+static bfd_reloc_status_type
+bfd_elf32_mn10200_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;
+    }
+
+#if 0
+  /* 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;
+
+      /* 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_MN10200_PCREL32_1BYTE
+	      || reloc->howto->type == R_MN10200_PCREL16_1BYTE
+	      || reloc->howto->type == R_MN10200_PCREL8_1BYTE)
+            relocation += 1;
+	  else if (reloc->howto->type == R_MN10200_PCREL32_2BYTE
+	      || reloc->howto->type == R_MN10200_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;
+    }
+#endif
+
+  return bfd_reloc_continue;
+}
+
 #define TARGET_LITTLE_SYM	bfd_elf32_mn10200_vec
 #define TARGET_LITTLE_NAME	"elf32-mn10200"
 #define ELF_ARCH		bfd_arch_mn10200
 #define ELF_MACHINE_CODE	EM_CYGNUS_MN10200
 #define ELF_MAXPAGESIZE		0x1000
 
-#define elf_info_to_howto	0
-#define elf_info_to_howto_rel	mn10200_info_to_howto_rel
+#define elf_info_to_howto	mn10200_info_to_howto
+#define elf_info_to_howto_rel	0
+
+#define elf_symbol_leading_char '_'
 
 #include "elf32-target.h"
diff --git a/bfd/elf32-mn10300.c b/bfd/elf32-mn10300.c
index c8a764a82bc..d6615c70e41 100644
--- a/bfd/elf32-mn10300.c
+++ b/bfd/elf32-mn10300.c
@@ -40,8 +40,6 @@ enum reloc_type
   R_MN10300_32,
   R_MN10300_16,
   R_MN10300_8,
-  R_MN10300_32B,
-  R_MN10300_16B,
   R_MN10300_PCREL32_1BYTE,
   R_MN10300_PCREL16_1BYTE,
   R_MN10300_PCREL8_1BYTE,
@@ -108,34 +106,6 @@ static reloc_howto_type elf_mn10300_howto_table[] =
 	 0xff,
 	 0xff,
 	 false),
-  /* Standard 32 bit reloc, except it explicitly writes big-endian format.  */
-  HOWTO (R_MN10300_32B,
-	 0,
-	 2,
-	 32,
-	 false,
-	 0,
-	 complain_overflow_bitfield,
-	 bfd_elf32_mn10300_reloc,
-	 "R_MN10300_32B",
-	 false,
-	 0xffffffff,
-	 0xffffffff,
-	 false),
-  /* Standard 16 bit reloc, except it explicitly writes big-endian format.  */
-  HOWTO (R_MN10300_16B,
-	 0,
-	 1,
-	 16,
-	 false,
-	 0,
-	 complain_overflow_bitfield,
-	 bfd_elf32_mn10300_reloc,
-	 "R_MN10300_16B",
-	 false,
-	 0xffff,
-	 0xffff,
-	 false),
   /* Simple 32bit pc-relative reloc with a 1 byte adjustment
      to get the pc-relative offset correct.  */
   HOWTO (R_MN10300_PCREL32_1BYTE,
@@ -225,8 +195,6 @@ 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_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, },
@@ -352,10 +320,11 @@ bfd_elf32_mn10300_reloc (abfd, reloc, symbol, data, isection, obfd, err)
 	  if (relocation > 0x7fff || relocation < -0x8000)
 	    return bfd_reloc_overflow;
 
-	  bfd_putb16 (relocation & 0xffff, (bfd_byte *)data + reloc->address);
+	  bfd_put_16 (abfd, relocation & 0xffff,
+		      (bfd_byte *)data + reloc->address);
  	}
       else if (reloc->howto->size == 2)
-	bfd_putb32 (relocation, (bfd_byte *)data + reloc->address);
+	bfd_put_32 (abfd, relocation, (bfd_byte *)data + reloc->address);
       return bfd_reloc_ok;
     }