Switched over to using machine numbers to distinguish v850 architecture variants.
authorNick Clifton <nickc@redhat.com>
Mon, 25 Aug 1997 23:00:29 +0000 (23:00 +0000)
committerNick Clifton <nickc@redhat.com>
Mon, 25 Aug 1997 23:00:29 +0000 (23:00 +0000)
bfd/.Sanitize
bfd/ChangeLog
bfd/Makefile.in
bfd/archures.c
bfd/bfd-in2.h
bfd/config.bfd
bfd/cpu-v850.c [new file with mode: 0644]
bfd/cpu-v850e.c [deleted file]
bfd/cpu-v850eq.c [deleted file]
bfd/elf.c
bfd/elf32-v850.c

index 6678ae8..a6c4592 100644 (file)
@@ -27,17 +27,14 @@ v850_files="elf32-v850.c"
 
 if ( echo $* | grep keep\-v850 > /dev/null ) ; then
        keep_these_too="cpu-v850.c ${v850_files} ${keep_these_too}"
-       lose_these_too="cpu-v850e.c cpu-v850eq.c ${lose_these_too}"
 else
  if ( echo $* | grep keep\-v850e > /dev/null ) ; then
-       keep_these_too="cpu-v850e.c ${v850_files} ${keep_these_too}"
-       lose_these_too="cpu-v850.c cpu-v850eq.c ${lose_these_too}"
+       keep_these_too="cpu-v850.c ${v850_files} ${keep_these_too}"
  else
   if ( echo $* | grep keep\-v850eq > /dev/null ) ; then
-       keep_these_too="cpu-v850eq.c ${v850_files} ${keep_these_too}"
-       lose_these_too="cpu-v850.c cpu-v850e.c ${lose_these_too}"
+       keep_these_too="cpu-v850.c ${v850_files} ${keep_these_too}"
   else
-       lose_these_too="cpu-v850.c cpu-v850e.c cpu-v850eq.c ${v850_files} ${lose_these_too}"
+       lose_these_too="cpu-v850.c ${v850_files} ${lose_these_too}"
   fi
  fi
 fi
@@ -336,28 +333,22 @@ fi
 
 v850_files="ChangeLog ChangeLog.2 Makefile.in Makefile.am archures.c reloc.c targets.c config.bfd configure.in configure bfd-in2.h elf.c libbfd.h elf32-v850.c"
 v850e_files="ChangeLog ChangeLog.2 Makefile.in Makefile.am archures.c reloc.c targets.c config.bfd configure.in configure bfd-in2.h elf.c libbfd.h"
-if ( echo $* | grep keep\-v850 > /dev/null ) ; then
+if ( echo $* | grep keep\-v850eq > /dev/null ) ; then
        for i in $v850_files ; do
-               if test ! -d $i && (grep sanitize-v850 $i > /dev/null) ; then
+               if test -r $i && (grep sanitize-v850eq $i > /dev/null) ; then
                        if [ -n "${verbose}" ] ; then
-                               echo Keeping v850 stuff in $i
+                               echo Keeping v850eq stuff in $i
                        fi
                fi
        done
 else
-  if ( echo $* | grep keep\-v850e > /dev/null ) ; then
-    true
-  else
-    if ( echo $* | grep keep\-v850eq > /dev/null ) ; then
-      true
-    else
-       for i in $v850e_files ; do
-               if test ! -d $i && (grep sanitize-v850 $i > /dev/null) ; then
+       for i in $v850_files ; do
+               if test -f $i && (grep sanitize-v850eq $i > /dev/null) ; then
                        if [ -n "${verbose}" ] ; then
-                               echo Removing traces of \"v850\" from $i...
+                               echo Removing traces of \"v850eq\" from $i...
                        fi
                        cp $i new
-                       sed '/start\-sanitize\-v850/,/end-\sanitize\-v850/d' < $i > new
+                       sed '/start\-sanitize\-v850eq/,/end\-sanitize\-v850eq/d' < $i > new
                        if [ -n "${safe}" -a ! -f .Recover/$i ] ; then
                                if [ -n "${verbose}" ] ; then
                                        echo Caching $i in .Recover...
@@ -367,10 +358,7 @@ else
                        mv new $i
                fi
        done
-    fi
-  fi
 fi
-
 if ( echo $* | grep keep\-v850e > /dev/null ) ; then
        for i in $v850_files ; do
                if test -r $i && (grep sanitize-v850e $i > /dev/null) ; then
@@ -386,7 +374,7 @@ else
                                echo Removing traces of \"v850e\" from $i...
                        fi
                        cp $i new
-                       sed '/start\-sanitize\-v850e/,/end-\sanitize\-v850e/d' < $i > new
+                       sed '/start\-sanitize\-v850e/,/end\-sanitize\-v850e/d' < $i > new
                        if [ -n "${safe}" -a ! -f .Recover/$i ] ; then
                                if [ -n "${verbose}" ] ; then
                                        echo Caching $i in .Recover...
@@ -397,22 +385,29 @@ else
                fi
        done
 fi
-if ( echo $* | grep keep\-v850eq > /dev/null ) ; then
+
+if ( echo $* | grep keep\-v850 > /dev/null ) ; then
        for i in $v850_files ; do
-               if test -r $i && (grep sanitize-v850eq $i > /dev/null) ; then
+               if test ! -d $i && (grep sanitize-v850 $i > /dev/null) ; then
                        if [ -n "${verbose}" ] ; then
-                               echo Keeping v850eq stuff in $i
+                               echo Keeping v850 stuff in $i
                        fi
                fi
        done
 else
-       for i in $v850_files ; do
-               if test -f $i && (grep sanitize-v850eq $i > /dev/null) ; then
+  if ( echo $* | grep keep\-v850e > /dev/null ) ; then
+    true
+  else
+    if ( echo $* | grep keep\-v850eq > /dev/null ) ; then
+      true
+    else
+       for i in $v850e_files ; do
+               if test ! -d $i && (grep sanitize-v850 $i > /dev/null) ; then
                        if [ -n "${verbose}" ] ; then
-                               echo Removing traces of \"v850eq\" from $i...
+                               echo Removing traces of \"v850\" from $i...
                        fi
                        cp $i new
-                       sed '/start\-sanitize\-v850eq/,/end-\sanitize\-v850eq/d' < $i > new
+                       sed '/start\-sanitize\-v850/,/end\-sanitize\-v850/d' < $i > new
                        if [ -n "${safe}" -a ! -f .Recover/$i ] ; then
                                if [ -n "${verbose}" ] ; then
                                        echo Caching $i in .Recover...
@@ -422,6 +417,8 @@ else
                        mv new $i
                fi
        done
+    fi
+  fi
 fi
 
 r5900_files="ChangeLog config.bfd"
index a373ddb..f354473 100644 (file)
@@ -1,16 +1,42 @@
-Mon Aug 25 14:07:33 1997  Ian Lance Taylor  <ian@cygnus.com>
+start-sanitize-v850
+Mon Aug 25 15:35:46 1997  Nick Clifton  <nickc@cygnus.com>
 
-       * syms.c (_bfd_stab_section_find_nearest_line): Clear the
-       cached_stab field if the offset prevents us from using the cache.
+       * cpu-v850.c (scan): New function.
+       (arch_info_struct): New structure.
+       (bfd_v850_arch): Add link into arch_info_structure.
 
-start-sanitize-v850e
-Mon Aug 25 10:04:35 1997  Nick Clifton  <nickc@cygnus.com>
+       * config.bfd (targ_cpu): All v850 variants use the bfd_arch_v850
+       architecture. 
+
+       * elf32-v850.c (v850_elf_object_p): New function.
 
-       * Makefile.in: Add rule to build cpu-v850e.lo object file.
+start-sanitize-v850e
+       * archures.c (bfd_mach_v850e): Machine value for v850e.
+       
+       * bfd-in2.h (bfd_mach_v850e): Machine value for v850e.
+       
+       * elf32-v850.c (ELF_MACHINE_CODE): Default to v850e machine     
+       number.
+       
+       * elf.c (prep_headers): Add support for v850e machine number. 
+end-sanitize-v850e
+       
 start-sanitize-v850eq
-       * Makefile.in: Add rule to build cpu-v850eq.lo object file.
+       * archures.c (bfd_mach_v850eq): Machine value for v850eq.
+       
+       * bfd-in2.h (bfd_mach_v850eq): Machine value for v850eq.
+       
+       * elf32-v850.c (ELF_MACHINE_CODE): Default to v850eq machine
+       number.
+       
+       * elf.c (prep_headers): Add support for v850eq machine number. 
 end-sanitize-v850eq
-end-sanitize-v850e
+end-sanitize-v850
+
+Mon Aug 25 14:07:33 1997  Ian Lance Taylor  <ian@cygnus.com>
+
+       * syms.c (_bfd_stab_section_find_nearest_line): Clear the
+       cached_stab field if the offset prevents us from using the cache.
 
 Mon Aug 25 12:08:13 1997  Ian Lance Taylor  <ian@cygnus.com>
 
index 16d7609..ed9cb04 100644 (file)
@@ -153,12 +153,6 @@ ALL_MACHINES = \
        $(start-sanitize-v850) \
        cpu-v850.lo \
        $(end-sanitize-v850) \
-       $(start-sanitize-v850e) \
-       cpu-v850e.lo \
-       $(end-sanitize-v850e) \
-       $(start-sanitize-v850eq) \
-       cpu-v850eq.lo \
-       $(end-sanitize-v850eq) \
        cpu-vax.lo \
        cpu-we32k.lo \
        cpu-w65.lo \
@@ -1017,20 +1011,6 @@ elf32-v850.lo: elf32-v850.c $(INCDIR)/bfdlink.h elf-bfd.h \
   elf32-target.h
 end-sanitize-v850:
 
-start-sanitize-v850e:
-cpu-v850e.lo: cpu-v850e.c
-elf32-v850.lo: elf32-v850.c $(INCDIR)/bfdlink.h elf-bfd.h \
-  $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
-  elf32-target.h
-end-sanitize-v850e:
-
-start-sanitize-v850eq:
-cpu-v850eq.lo: cpu-v850eq.c
-elf32-v850.lo: elf32-v850.c $(INCDIR)/bfdlink.h elf-bfd.h \
-  $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
-  elf32-target.h
-end-sanitize-v850eq:
-
 start-sanitize-tic80:
 cpu-tic80.lo: cpu-tic80.c
 coff-tic80.lo: coff-tic80.c $(INCDIR)/bfdlink.h elf-bfd.h \
index 0582a23..e6d70c0 100644 (file)
@@ -145,6 +145,12 @@ DESCRIPTION
 . {* end-sanitize-tic80 *}
 . {* start-sanitize-v850 *}
 .  bfd_arch_v850,      {* NEC V850 *}
+. {* start-sanitize-v850e *}
+#define bfd_mach_v850e 'E'
+. {* end-sanitize-v850e *}
+. {* start-sanitize-v850eq *}
+#define bfd_mach_v850eq        'Q'
+. {* end-sanitize-v850eq *}
 . {* end-sanitize-v850 *}
 .  bfd_arch_arc,       {* Argonaut RISC Core *}
 .#define bfd_mach_arc_base 0
@@ -265,8 +271,8 @@ static const bfd_arch_info_type * const bfd_archures_list[] =
 /* start-sanitize-v850*/
   &bfd_v850_arch,
 /* end-sanitize-v850 */
-#endif
   0
+#endif
 };
 
 /*
index 33d6aef..d8773a4 100644 (file)
@@ -1238,6 +1238,12 @@ enum bfd_architecture
   /* start-sanitize-v850 */
   bfd_arch_v850,       /* NEC V850 */
   /* end-sanitize-v850 */
+  /* start-sanitize-v850e */
+#define bfd_mach_v850e 'E'
+  /* end-sanitize-v850e */
+  /* start-sanitize-v850eq */
+#define bfd_mach_v850eq        'Q'
+  /* end-sanitize-v850eq */
   bfd_arch_arc,        /* Argonaut RISC Core */
 #define bfd_mach_arc_base 0
   bfd_arch_m32r,       /* Mitsubishi M32R/D */
@@ -1929,6 +1935,9 @@ add3, load, and store instructions. */
 /* This is a 9-bit reloc */
   BFD_RELOC_V850_9_PCREL,
 
+/* This is a 16-bit reloc */
+  BFD_RELOC_V850_16_PCREL,
+
 /* This is a 22-bit reloc */
   BFD_RELOC_V850_22_PCREL,
 
index 8e7ecc5..a0b29a2 100755 (executable)
@@ -37,6 +37,9 @@ mips*)        targ_archs=bfd_mips_arch ;;
 powerpc*) targ_archs="bfd_rs6000_arch bfd_powerpc_arch" ;;
 rs6000)        targ_archs="bfd_rs6000_arch bfd_powerpc_arch" ;;
 sparc*)        targ_archs=bfd_sparc_arch ;;
+# start-sanitize-v850
+v850*) targ_archs=bfd_v850_arch ;;
+# end-sanitize-v850
 z8k*)  targ_archs=bfd_z8k_arch ;;
 *)     targ_archs=bfd_${targ_cpu}_arch ;;
 esac
@@ -551,6 +554,16 @@ case "${targ}" in
     ;;
 
 # end-sanitize-v850
+# start-sanitize-v850e
+  v850e-*-*)
+    targ_defvec=bfd_elf32_v850_vec
+    ;;
+# end-sanitize-v850e
+# start-sanitize-v850eq
+  v850eq-*-*)
+    targ_defvec=bfd_elf32_v850_vec
+    ;;
+# end-sanitize-v850eq
 #if HAVE_host_aout_vec
   vax-*-bsd* | vax-*-ultrix*)
     targ_defvec=host_aout_vec
diff --git a/bfd/cpu-v850.c b/bfd/cpu-v850.c
new file mode 100644 (file)
index 0000000..aa083fd
--- /dev/null
@@ -0,0 +1,137 @@
+/* BFD support for the NEC V850 processor
+   Copyright 1994, 1995 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+
+static boolean 
+scan (info, string)
+     const struct bfd_arch_info * info;
+     const char * string;
+{
+  const char *ptr_src;
+  const char *ptr_tst;
+  unsigned long number;
+  enum bfd_architecture arch;
+
+  /* First test for an exact match */
+  if (strcmp (string, info->printable_name) == 0)
+    return true;
+
+  /* See how much of the supplied string matches with the
+     architecture, eg the string m68k:68020 would match the m68k entry
+     up to the :, then we get left with the machine number */
+
+  for (ptr_src = string, ptr_tst = info->arch_name; 
+       *ptr_src && *ptr_tst;
+       ptr_src++, ptr_tst++) 
+    {
+      if (*ptr_src != *ptr_tst) break;
+    }
+
+  /* Chewed up as much of the architecture as will match, skip any
+     colons */
+  if (*ptr_src == ':')
+    ptr_src++;
+  
+  if (*ptr_src == 0)
+    {
+      /* nothing more, then only keep this one if it is the default
+        machine for this architecture */
+      return info->the_default;
+    }
+
+  number = 0;
+  while (isdigit (*ptr_src))
+    {
+      number = number * 10 + * ptr_src  - '0';
+      ptr_src++;
+    }
+
+  switch (number) 
+    {
+    case bfd_mach_v850e:  arch = bfd_arch_v850; break;
+    case bfd_mach_v850eq: arch = bfd_arch_v850; break;
+
+    default:  
+      return false;
+    }
+
+  if (arch != info->arch) 
+    return false;
+
+  if (number != info->mach)
+    return false;
+
+  return true;
+}
+
+
+static const bfd_arch_info_type arch_info_struct[2] = 
+{
+/* start-sanitize-v850e */
+  {
+    32,        /* 32 bits in a word */
+    32,        /* 32 bits in an address */
+    8, /* 8 bits in a byte */
+    bfd_arch_v850,
+    bfd_mach_v850e,
+    "v850e",
+    "v850e",
+    2,
+    false,
+    bfd_default_compatible, 
+    scan,
+    & arch_info_struct[ 1 ],
+  },
+/* end-sanitize-v850e */
+/* start-sanitize-v850eq */
+  {
+    32,        /* 32 bits in a word */
+    32,        /* 32 bits in an address */
+    8, /* 8 bits in a byte */
+    bfd_arch_v850,
+    bfd_mach_v850eq,
+    "v850eq",
+    "v850eq",
+    2,
+    false,
+    bfd_default_compatible, 
+    scan,
+    0,
+  }
+/* end-sanitize-v850eq */
+};
+
+const bfd_arch_info_type bfd_v850_arch =
+  {
+    32, /* 32 bits in a word */
+    32, /* 32 bits in an address */
+    8,  /* 8 bits in a byte */
+    bfd_arch_v850,
+    0,  /* only 1 machine */
+    "v850",
+    "plain v850",
+    2,
+    true, /* the default */
+    bfd_default_compatible,
+    scan ,
+    & arch_info_struct[ 0 ],
+  };
diff --git a/bfd/cpu-v850e.c b/bfd/cpu-v850e.c
deleted file mode 100644 (file)
index 803c7b3..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-/* BFD support for the NEC V850E processor
-   Copyright 1994, 1995 Free Software Foundation, Inc.
-
-This file is part of BFD, the Binary File Descriptor library.
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
-
-#include "bfd.h"
-#include "sysdep.h"
-#include "libbfd.h"
-
-const bfd_arch_info_type bfd_v850e_arch =
-  {
-    32, /* 32 bits in a word */
-    32, /* 32 bits in an address */
-    8,  /* 8 bits in a byte */
-    bfd_arch_v850e,
-    0,  /* only 1 machine */
-    "v850e",
-    "v850e",
-    2,
-    true, /* the one and only */
-    bfd_default_compatible,
-    bfd_default_scan ,
-    0,
-  };
-
diff --git a/bfd/cpu-v850eq.c b/bfd/cpu-v850eq.c
deleted file mode 100644 (file)
index a820186..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-/* BFD support for the NEC V850EQ processor
-   Copyright 1994, 1995 Free Software Foundation, Inc.
-
-This file is part of BFD, the Binary File Descriptor library.
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
-
-#include "bfd.h"
-#include "sysdep.h"
-#include "libbfd.h"
-
-const bfd_arch_info_type bfd_v850eq_arch =
-  {
-    32, /* 32 bits in a word */
-    32, /* 32 bits in an address */
-    8,  /* 8 bits in a byte */
-    bfd_arch_v850eq,
-    0,  /* only 1 machine */
-    "v850eq",
-    "v850eq",
-    2,
-    true, /* the one and only */
-    bfd_default_compatible,
-    bfd_default_scan ,
-    0,
-  };
-
index 48ab443..7b1d196 100644 (file)
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -2872,10 +2872,20 @@ prep_headers (abfd)
 /* end-sanitize-d30v */
 /* start-sanitize-v850 */
     case bfd_arch_v850:
-      i_ehdrp->e_machine = EM_CYGNUS_V850;
+      switch (bfd_get_mach (abfd))
+       {
+       default:
+       case 0:               i_ehdrp->e_machine = EM_CYGNUS_V850; break;
+/* start-sanitize-v850e */
+       case bfd_mach_v850e:  i_ehdrp->e_machine = EM_CYGNUS_V850E; break;
+/* end-sanitize-v850e */
+/* start-sanitize-v850eq */
+       case bfd_mach_v850eq: i_ehdrp->e_machine = EM_CYGNUS_V850EQ; break;
+/* end-sanitize-v850eq */
+       }
       break;
 /* end-sanitize-v850 */
-    case bfd_arch_arc:
+   case bfd_arch_arc:
       i_ehdrp->e_machine = EM_CYGNUS_ARC;
       break;
     case bfd_arch_m32r:
index d9b1266..0cca799 100644 (file)
@@ -36,7 +36,7 @@ static void v850_elf_info_to_howto_rel
   PARAMS ((bfd *, arelent *, Elf32_Internal_Rel *));
 static bfd_reloc_status_type v850_elf_reloc
   PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
-static boolean v850_elf_is_local_label PARAMS ((bfd *, asymbol *));
+static boolean v850_elf_is_local_label_name PARAMS ((bfd *, const char *));
 static boolean v850_elf_relocate_section PARAMS((bfd *,
                                                 struct bfd_link_info *,
                                                 bfd *,
@@ -82,6 +82,21 @@ static reloc_howto_type v850_elf_howto_table[] =
         0x00ffffff,                    /* dst_mask */
         true),                         /* pcrel_offset */
 
+  /* A PC relative 16 bit load/store. */
+  HOWTO (R_V850_16_PCREL,              /* type */
+        0,                             /* rightshift */
+        2,                             /* size (0 = byte, 1 = short, 2 = long) */
+        15,                            /* bitsize */
+        true,                          /* pc_relative */
+        17,                            /* bitpos */
+        complain_overflow_bitfield,    /* complain_on_overflow */
+        v850_elf_reloc,                /* special_function */
+        "R_V850_16_PCREL",             /* name */
+        false,                         /* partial_inplace */
+        0xfffe0000,                    /* src_mask */
+        0xfffe0000,                    /* dst_mask */
+        true),                         /* pcrel_offset */
+
   /* A PC relative 22 bit branch. */
   HOWTO (R_V850_22_PCREL,              /* type */
         2,                             /* rightshift */
@@ -135,7 +150,7 @@ static reloc_howto_type v850_elf_howto_table[] =
         false,                         /* pc_relative */
         0,                             /* bitpos */
         complain_overflow_dont,        /* complain_on_overflow */
-        bfd_elf_generic_reloc,         /* special_function */
+        v850_elf_reloc,                /* special_function */
         "R_V850_LO16",                 /* name */
         true,                          /* partial_inplace */
         0xffff,                        /* src_mask */
@@ -195,7 +210,7 @@ static reloc_howto_type v850_elf_howto_table[] =
         false,                         /* pc_relative */
         0,                             /* bitpos */
         complain_overflow_dont,        /* complain_on_overflow */
-        bfd_elf_generic_reloc,         /* special_function */
+        v850_elf_reloc,                /* special_function */
         "R_V850_SDA_OFFSET",           /* name */
         true,                          /* partial_inplace */
         0xffff,                        /* src_mask */
@@ -210,7 +225,7 @@ static reloc_howto_type v850_elf_howto_table[] =
         false,                         /* pc_relative */
         0,                             /* bitpos */
         complain_overflow_dont,        /* complain_on_overflow */
-        bfd_elf_generic_reloc,         /* special_function */
+        v850_elf_reloc,                /* special_function */
         "R_V850_ZDA_OFFSET",           /* name */
         true,                          /* partial_inplace */
         0xffff,                        /* src_mask */
@@ -225,7 +240,7 @@ static reloc_howto_type v850_elf_howto_table[] =
         false,                         /* pc_relative */
         0,                             /* bitpos */
         complain_overflow_dont,        /* complain_on_overflow */
-        bfd_elf_generic_reloc,         /* special_function */
+        v850_elf_reloc,                /* special_function */
         "R_V850_TDA_OFFSET",           /* name */
         true,                          /* partial_inplace */
         0xff,                          /* src_mask */
@@ -246,6 +261,7 @@ static const struct v850_elf_reloc_map v850_elf_reloc_map[] =
 {
   { BFD_RELOC_NONE,            R_V850_NONE, },
   { BFD_RELOC_V850_9_PCREL,    R_V850_9_PCREL, },
+  { BFD_RELOC_V850_16_PCREL,   R_V850_16_PCREL, },
   { BFD_RELOC_V850_22_PCREL,   R_V850_22_PCREL, },
   { BFD_RELOC_HI16_S,          R_V850_HI16_S, },
   { BFD_RELOC_HI16,            R_V850_HI16, },
@@ -348,6 +364,7 @@ v850_elf_check_relocs (abfd, info, sec, relocs)
        default:
        case R_V850_NONE:
        case R_V850_9_PCREL:
+       case R_V850_16_PCREL:
        case R_V850_22_PCREL:
        case R_V850_HI16_S:
        case R_V850_HI16:
@@ -411,7 +428,7 @@ v850_elf_check_relocs (abfd, info, sec, relocs)
                }
            }
 
-         if (h->root.type == bfd_link_hash_common
+         if (h && h->root.type == bfd_link_hash_common
              && h->root.u.c.p
              && !strcmp (bfd_get_section_name (abfd, h->root.u.c.p->section), "COMMON"))
            {
@@ -497,8 +514,12 @@ v850_elf_reloc (abfd, reloc, symbol, data, isection, obfd, err)
       /* I've got no clue... */
       reloc->addend = 0;       
 
-      if (reloc->howto->type == R_V850_22_PCREL)
+      switch (reloc->howto->type)
        {
+       default:
+         return bfd_reloc_notsupported;
+
+       case R_V850_22_PCREL:
          if (relocation > 0x1ffff || relocation < -0x200000)
            return bfd_reloc_overflow;
 
@@ -511,9 +532,21 @@ v850_elf_reloc (abfd, reloc, symbol, data, isection, obfd, err)
                   | ((relocation & 0x3f0000) >> 16));
          bfd_put_32 (abfd, insn, (bfd_byte *)data + reloc->address);
          return bfd_reloc_ok;
-       }
-      else if (reloc->howto->type == R_V850_9_PCREL)
-       {
+
+       case R_V850_16_PCREL:
+         if (relocation > 0x7fff || relocation < -0x10000)
+           return bfd_reloc_overflow;
+
+         if ((relocation % 2) != 0)
+           return bfd_reloc_dangerous;
+
+         insn = bfd_get_32 (abfd, (bfd_byte *) data + reloc->address);
+         insn &= 0x1ffff;
+         insn |= ((relocation & 0xfffe) << 16);
+         bfd_put_32 (abfd, insn, (bfd_byte *) data + reloc->address);
+         return bfd_reloc_ok;
+
+       case R_V850_9_PCREL:
          if (relocation > 0xff || relocation < -0x100)
            return bfd_reloc_overflow;
 
@@ -521,27 +554,60 @@ v850_elf_reloc (abfd, reloc, symbol, data, isection, obfd, err)
            return bfd_reloc_dangerous;
 
          insn = bfd_get_16 (abfd, (bfd_byte *) data + reloc->address);
-         insn &= 0xf870;
+         insn &= 0xf870;
          insn |= ((relocation & 0x1f0) << 7) | ((relocation & 0x0e) << 3);
          bfd_put_16 (abfd, insn, (bfd_byte *)data + reloc->address);
          return bfd_reloc_ok;
-       }
-      else if (reloc->howto->type == R_V850_HI16_S)
-       {
+
+       case R_V850_HI16_S:
          relocation += bfd_get_16 (abfd, (bfd_byte *) data + reloc->address);
          relocation = (relocation >> 16) + ((relocation & 0x8000) != 0);
          bfd_put_16 (abfd, relocation, (bfd_byte *)data + reloc->address);
          return bfd_reloc_ok;
-       }
-      else if (reloc->howto->type == R_V850_HI16)
-       {
+
+       case R_V850_HI16:
          relocation += bfd_get_16 (abfd, (bfd_byte *) data + reloc->address);
          relocation = (relocation >> 16);
          bfd_put_16 (abfd, relocation, (bfd_byte *)data + reloc->address);
          return bfd_reloc_ok;
+
+       case R_V850_16:
+       case R_V850_ZDA_OFFSET:
+         relocation += (short)bfd_get_16 (abfd, (bfd_byte *) data + reloc->address);
+
+         if ((long)relocation > 0x7fff || (long)relocation < -0x8000)
+           return bfd_reloc_overflow;
+
+         bfd_put_16 (abfd, relocation, (bfd_byte *)data + reloc->address);
+         return bfd_reloc_ok;
+
+#if 0
+       case R_V850_SDA_OFFSET:
+         {
+           unsigned long gp;
+           struct bfd_link_hash_entry *h;
+
+           relocation += (short)bfd_get_16 (abfd, (bfd_byte *) data + reloc->address);
+
+           /* Get the value of __gp.  */
+           h = bfd_link_hash_lookup (info->hash, "__gp", false, false, true);
+           if (h == (struct bfd_link_hash_entry *) NULL
+               || h->type != bfd_link_hash_defined)
+             return bfd_reloc_undefined;
+
+           gp = (h->u.def.value
+                 + h->u.def.section->output_section->vma
+                 + h->u.def.section->output_offset);
+           relocation -= gp;
+
+           if ((long)relocation > 0x7fff || (long)relocation < -0x8000)
+             return bfd_reloc_overflow;
+
+           bfd_put_16 (abfd, relocation, (bfd_byte *)data + reloc->address);
+           return bfd_reloc_ok;
+         }
+#endif
        }
-      else
-       return bfd_reloc_notsupported;
     }
 
   return bfd_reloc_continue;
@@ -550,13 +616,13 @@ v850_elf_reloc (abfd, reloc, symbol, data, isection, obfd, err)
 \f
 /*ARGSUSED*/
 static boolean
-v850_elf_is_local_label (abfd, symbol)
+v850_elf_is_local_label_name (abfd, name)
      bfd *abfd;
-     asymbol *symbol;
+     const char *name;
 {
-  return ((symbol->name[0] == '.' && (symbol->name[1] == 'L' || symbol->name[1] == '.'))
-         || (symbol->name[0] == '_' && symbol->name[1] == '.' && symbol->name[2] == 'L'
-             && symbol->name[3] == '_'));
+  return ((name[0] == '.' && (name[1] == 'L' || name[1] == '.'))
+         || (name[0] == '_' && name[1] == '.' && name[2] == 'L'
+             && name[3] == '_'));
 }
 
 \f
@@ -579,9 +645,7 @@ v850_elf_final_link_relocate (howto, input_bfd, output_bfd,
 {
   unsigned long insn;
   unsigned long r_type = howto->type;
-  unsigned long r_format = howto->bitsize;
   bfd_byte *hit_data = contents + offset;
-  boolean r_pcrel = howto->pc_relative;
 
   switch (r_type)
     {
@@ -602,6 +666,22 @@ v850_elf_final_link_relocate (howto, input_bfd, output_bfd,
       bfd_put_16 (input_bfd, insn, hit_data);
       return bfd_reloc_ok;
     
+    case R_V850_16_PCREL:
+      value -= (input_section->output_section->vma + input_section->output_offset);
+      value -= offset;
+
+      if ((long)value > 0x7fff || (long)value < -0x10000)
+       return bfd_reloc_overflow;
+      
+      if ((value % 2) != 0)
+       return bfd_reloc_dangerous;
+      
+      insn = bfd_get_32 (input_bfd, hit_data);
+      insn &= 0x1ffff;
+      insn |= ((value & 0xfffe) << 16);
+      bfd_put_32 (input_bfd, insn, hit_data);
+      return bfd_reloc_ok;
+      
     case R_V850_22_PCREL:
       value -= (input_section->output_section->vma
                + input_section->output_offset);
@@ -777,10 +857,11 @@ v850_elf_final_link_relocate (howto, input_bfd, output_bfd,
       }
     
     case R_V850_NONE:
+      return bfd_reloc_ok;
+
     default:
-      break;
+      return bfd_reloc_notsupported;
     }
-
 }
 
 \f
@@ -817,6 +898,10 @@ v850_elf_relocate_section (output_bfd, info, input_bfd, input_section,
       bfd_vma relocation;
       bfd_reloc_status_type r;
 
+      r_symndx = ELF32_R_SYM (rel->r_info);
+      r_type = ELF32_R_TYPE (rel->r_info);
+      howto = v850_elf_howto_table + r_type;
+
       if (info->relocateable)
        {
          /* This is a relocateable link.  We don't have to change
@@ -836,12 +921,6 @@ v850_elf_relocate_section (output_bfd, info, input_bfd, input_section,
          continue;
        }
 
-      r_type = ELF32_R_TYPE (rel->r_info);
-
-      howto = v850_elf_howto_table + r_type;
-
-      r_symndx = ELF32_R_SYM (rel->r_info);
-
       /* This is a final link.  */
       h = NULL;
       sym = NULL;
@@ -890,31 +969,56 @@ v850_elf_relocate_section (output_bfd, info, input_bfd, input_section,
 
       if (r != bfd_reloc_ok)
        {
+         const char *name;
+         const char *msg = (const char *)0;
+
+         if (h != NULL)
+           name = h->root.root.string;
+         else
+           {
+             name = (bfd_elf_string_from_elf_section
+                     (input_bfd, symtab_hdr->sh_link, sym->st_name));
+             if (name == NULL || *name == '\0')
+               name = bfd_section_name (input_bfd, sec);
+           }
+
          switch (r)
            {
-           default:
-           case bfd_reloc_outofrange:
-             abort ();
            case bfd_reloc_overflow:
-             {
-               const char *name;
-
-               if (h != NULL)
-                 name = h->root.root.string;
-               else
-                 {
-                   name = (bfd_elf_string_from_elf_section
-                           (input_bfd, symtab_hdr->sh_link, sym->st_name));
-                   if (name == NULL)
-                     return false;
-                   if (*name == '\0')
-                     name = bfd_section_name (input_bfd, sec);
-                 }
-               if (! ((*info->callbacks->reloc_overflow)
-                      (info, name, howto->name, (bfd_vma) 0,
-                       input_bfd, input_section, rel->r_offset)))
-                 return false;
-             }
+             if (! ((*info->callbacks->reloc_overflow)
+                    (info, name, howto->name, (bfd_vma) 0,
+                     input_bfd, input_section, rel->r_offset)))
+               return false;
+             break;
+
+           case bfd_reloc_undefined:
+             if (! ((*info->callbacks->undefined_symbol)
+                    (info, name, input_bfd, input_section,
+                     rel->r_offset)))
+               return false;
+             break;
+
+           case bfd_reloc_outofrange:
+             msg = "internal error: out of range error";
+             goto common_error;
+
+           case bfd_reloc_notsupported:
+             msg = "internal error: unsupported relocation error";
+             goto common_error;
+
+           case bfd_reloc_dangerous:
+             msg = "internal error: dangerous error";
+             goto common_error;
+
+           default:
+             msg = "internal error: unknown error";
+             /* fall through */
+
+           common_error:
+             if (!((*info->callbacks->warning)
+                   (info, msg, name, input_bfd, input_section,
+                    rel->r_offset)))
+               return false;
              break;
            }
        }
@@ -923,18 +1027,47 @@ v850_elf_relocate_section (output_bfd, info, input_bfd, input_section,
   return true;
 }
 
+/* Set the right machine number.  */
+
+static boolean
+v850_elf_object_p (abfd)
+     bfd *abfd;
+{
+  switch (get_elf_backend_data (abfd) -> elf_machine_code)
+    {
+    default:
+    case EM_CYGNUS_V850:   (void) bfd_default_set_arch_mach (abfd, bfd_arch_v850, 0); break;
+/* start-sanitize-v850e */
+    case EM_CYGNUS_V850E:  (void) bfd_default_set_arch_mach (abfd, bfd_arch_v850, bfd_mach_v850e); break;
+/* end-sanitize-v850e */
+/* start-sanitize-v850eq */
+    case EM_CYGNUS_V850EQ: (void) bfd_default_set_arch_mach (abfd, bfd_arch_v850, bfd_mach_v850eq); break;
+/* start-sanitize-v850eq */
+    }
+}
+
 \f
 #define TARGET_LITTLE_SYM                      bfd_elf32_v850_vec
 #define TARGET_LITTLE_NAME                     "elf32-v850"
 #define ELF_ARCH                               bfd_arch_v850
 #define ELF_MACHINE_CODE                       EM_CYGNUS_V850
+/* start-sanitize-v850e */
+#undef  ELF_MACHINE_CODE
+#define ELF_MACHINE_CODE                       EM_CYGNUS_V850E
+/* end-sanitize-v850e */
+/* start-sanitize-v850eq */
+#undef  ELF_MACHINE_CODE
+#define ELF_MACHINE_CODE                       EM_CYGNUS_V850EQ
+/* end-sanitize-v850eq */
+
 #define ELF_MAXPAGESIZE                                0x1000
        
 #define elf_info_to_howto                      0
 #define elf_info_to_howto_rel                  v850_elf_info_to_howto_rel
 #define elf_backend_check_relocs               v850_elf_check_relocs
 #define elf_backend_relocate_section           v850_elf_relocate_section
-#define bfd_elf32_bfd_is_local_label           v850_elf_is_local_label
+#define elf_backend_object_p                   v850_elf_object_p
+#define bfd_elf32_bfd_is_local_label_name      v850_elf_is_local_label_name
 #define bfd_elf32_bfd_reloc_type_lookup                v850_elf_reloc_type_lookup
 
 #define elf_symbol_leading_char                        '_'