* Makefile.am: Bfin support.
authorCatherine Moore <clm@redhat.com>
Fri, 30 Sep 2005 15:36:41 +0000 (15:36 +0000)
committerCatherine Moore <clm@redhat.com>
Fri, 30 Sep 2005 15:36:41 +0000 (15:36 +0000)
* Makefile.in: Regenerated.
* aclocal.m4: Regenerated.
* archures.c (bfd_mach_bfin): New.
(bfd_arch_bfin): New.
bfd-in.h (bfd_bfin_elf32_create_embedded_relocs): New.
* bfd-in2.h: Regenerated.
* config.bfd: Bfin support.
* configure: Regenerated.
* configure.in: Bfin support.
* libbfd.h: Regenerated.
* reloc.c: Add BFD relocations for Bfin.
* targets.c (bfd_elf32_bfin_vec): New.
* cpu-bfin.c: New file.
* elf32-bfin.c: New file.

15 files changed:
bfd/ChangeLog
bfd/Makefile.am
bfd/Makefile.in
bfd/aclocal.m4
bfd/archures.c
bfd/bfd-in.h
bfd/bfd-in2.h
bfd/config.bfd
bfd/configure
bfd/configure.in
bfd/cpu-bfin.c [new file with mode: 0644]
bfd/elf32-bfin.c [new file with mode: 0644]
bfd/libbfd.h
bfd/reloc.c
bfd/targets.c

index fb8d2d0965cff297cbcf0c96bb03c93cc2547c2b..da30d7e3e0438429ed3c103a17d0a8b759398453 100644 (file)
@@ -1,3 +1,21 @@
+2005-09-30  Catherine Moore  <clm@cm00re.com>
+
+       * Makefile.am: Bfin support.
+       * Makefile.in: Regenerated.
+       * aclocal.m4: Regenerated.
+       * archures.c (bfd_mach_bfin): New.
+       (bfd_arch_bfin): New.
+       bfd-in.h (bfd_bfin_elf32_create_embedded_relocs): New.
+       * bfd-in2.h: Regenerated.
+       * config.bfd: Bfin support.
+       * configure: Regenerated.
+       * configure.in: Bfin support.
+       * libbfd.h: Regenerated.
+       * reloc.c: Add BFD relocations for Bfin.
+       * targets.c (bfd_elf32_bfin_vec): New.
+       * cpu-bfin.c: New file.
+       * elf32-bfin.c: New file.
+
 2005-09-30  Alan Modra  <amodra@bigpond.net.au>
 
        * elf64-ppc.c (ppc_type_of_stub): Check both func desc and func
index a4fcc64a6e1ef791b94b938bcd04b264edde053c..a3a2427441e551553c023e0d43051cd8fe7ba4fd 100644 (file)
@@ -58,6 +58,7 @@ ALL_MACHINES = \
        cpu-arc.lo \
        cpu-arm.lo \
        cpu-avr.lo \
+       cpu-bfin.lo \
        cpu-cr16c.lo \
        cpu-cris.lo \
        cpu-crx.lo \
@@ -117,6 +118,7 @@ ALL_MACHINES_CFILES = \
        cpu-arc.c \
        cpu-arm.c \
        cpu-avr.c \
+       cpu-bfin.c \
        cpu-cris.c \
        cpu-cr16c.c \
        cpu-crx.c \
@@ -223,6 +225,7 @@ BFD32_BACKENDS = \
        elf32-arc.lo \
        elf32-arm.lo \
        elf32-avr.lo \
+       elf32-bfin.lo \
        elf32-cr16c.lo \
        elf32-cris.lo \
        elf32-crx.lo \
@@ -392,6 +395,7 @@ BFD32_BACKENDS_CFILES = \
        elf32-arc.c \
        elf32-arm.c \
        elf32-avr.c \
+       elf32-bfin.c \
        elf32-cr16c.c \
        elf32-cris.c \
        elf32-crx.c \
@@ -962,6 +966,7 @@ cpu-arc.lo: cpu-arc.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h
 cpu-arm.lo: cpu-arm.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h \
   $(INCDIR)/libiberty.h
 cpu-avr.lo: cpu-avr.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h
+cpu-bfin.lo: cpu-bfin.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h
 cpu-cris.lo: cpu-cris.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h
 cpu-cr16c.lo: cpu-cr16c.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h
 cpu-crx.lo: cpu-crx.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h
@@ -1208,6 +1213,10 @@ elf32-avr.lo: elf32-avr.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h \
   elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
   $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(INCDIR)/elf/avr.h \
   $(INCDIR)/elf/reloc-macros.h elf32-target.h
+elf32-bfin.lo: elf32-bfin.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h \
+  elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+  $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(INCDIR)/elf/bfin.h \
+  $(INCDIR)/elf/reloc-macros.h elf32-target.h
 elf32-cr16c.lo: elf32-cr16c.c $(INCDIR)/filenames.h \
   $(INCDIR)/hashtab.h $(INCDIR)/bfdlink.h $(INCDIR)/elf/cr16c.h \
   $(INCDIR)/elf/reloc-macros.h elf-bfd.h $(INCDIR)/elf/common.h \
index ff66e3c8bf8ce94b0256916647f15e9f2c5f3c63..342b9a0340f55a6c86c8233e112779515f6af475 100644 (file)
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.9.5 from Makefile.am.
+# Makefile.in generated by automake 1.9.2 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -40,8 +40,9 @@ POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
 target_triplet = @target@
-DIST_COMMON = $(srcdir)/../config.guess $(srcdir)/../config.sub README \
-       ChangeLog $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+DIST_COMMON = $(srcdir)/../config.guess $(srcdir)/../config.sub \
+       INSTALL NEWS README AUTHORS ChangeLog THANKS \
+       $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
        $(top_srcdir)/configure $(am__configure_deps) \
        $(srcdir)/config.in $(srcdir)/../mkinstalldirs \
        $(srcdir)/bfd-in2.h $(top_srcdir)/po/Make-in \
@@ -295,6 +296,7 @@ ALL_MACHINES = \
        cpu-arc.lo \
        cpu-arm.lo \
        cpu-avr.lo \
+       cpu-bfin.lo \
        cpu-cr16c.lo \
        cpu-cris.lo \
        cpu-crx.lo \
@@ -354,6 +356,7 @@ ALL_MACHINES_CFILES = \
        cpu-arc.c \
        cpu-arm.c \
        cpu-avr.c \
+       cpu-bfin.c \
        cpu-cris.c \
        cpu-cr16c.c \
        cpu-crx.c \
@@ -461,6 +464,7 @@ BFD32_BACKENDS = \
        elf32-arc.lo \
        elf32-arm.lo \
        elf32-avr.lo \
+       elf32-bfin.lo \
        elf32-cr16c.lo \
        elf32-cris.lo \
        elf32-crx.lo \
@@ -630,6 +634,7 @@ BFD32_BACKENDS_CFILES = \
        elf32-arc.c \
        elf32-arm.c \
        elf32-avr.c \
+       elf32-bfin.c \
        elf32-cr16c.c \
        elf32-cris.c \
        elf32-crx.c \
@@ -1011,13 +1016,7 @@ uninstall-info-am:
 #     (which will cause the Makefiles to be regenerated when you run `make');
 # (2) otherwise, pass the desired values on the `make' command line.
 $(RECURSIVE_TARGETS):
-       @failcom='exit 1'; \
-       for f in x $$MAKEFLAGS; do \
-         case $$f in \
-           *=* | --[!k]*);; \
-           *k*) failcom='fail=yes';; \
-         esac; \
-       done; \
+       @set fnord $$MAKEFLAGS; amf=$$2; \
        dot_seen=no; \
        target=`echo $@ | sed s/-recursive//`; \
        list='$(SUBDIRS)'; for subdir in $$list; do \
@@ -1029,7 +1028,7 @@ $(RECURSIVE_TARGETS):
            local_target="$$target"; \
          fi; \
          (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
-         || eval $$failcom; \
+          || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
        done; \
        if test "$$dot_seen" = "no"; then \
          $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
@@ -1037,13 +1036,7 @@ $(RECURSIVE_TARGETS):
 
 mostlyclean-recursive clean-recursive distclean-recursive \
 maintainer-clean-recursive:
-       @failcom='exit 1'; \
-       for f in x $$MAKEFLAGS; do \
-         case $$f in \
-           *=* | --[!k]*);; \
-           *k*) failcom='fail=yes';; \
-         esac; \
-       done; \
+       @set fnord $$MAKEFLAGS; amf=$$2; \
        dot_seen=no; \
        case "$@" in \
          distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
@@ -1064,7 +1057,7 @@ maintainer-clean-recursive:
            local_target="$$target"; \
          fi; \
          (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
-         || eval $$failcom; \
+          || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
        done && test -z "$$fail"
 tags-recursive:
        list='$(SUBDIRS)'; for subdir in $$list; do \
@@ -1529,6 +1522,7 @@ cpu-arc.lo: cpu-arc.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h
 cpu-arm.lo: cpu-arm.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h \
   $(INCDIR)/libiberty.h
 cpu-avr.lo: cpu-avr.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h
+cpu-bfin.lo: cpu-bfin.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h
 cpu-cris.lo: cpu-cris.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h
 cpu-cr16c.lo: cpu-cr16c.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h
 cpu-crx.lo: cpu-crx.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h
@@ -1775,6 +1769,10 @@ elf32-avr.lo: elf32-avr.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h \
   elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
   $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(INCDIR)/elf/avr.h \
   $(INCDIR)/elf/reloc-macros.h elf32-target.h
+elf32-bfin.lo: elf32-bfin.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h \
+  elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+  $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(INCDIR)/elf/bfin.h \
+  $(INCDIR)/elf/reloc-macros.h elf32-target.h
 elf32-cr16c.lo: elf32-cr16c.c $(INCDIR)/filenames.h \
   $(INCDIR)/hashtab.h $(INCDIR)/bfdlink.h $(INCDIR)/elf/cr16c.h \
   $(INCDIR)/elf/reloc-macros.h elf-bfd.h $(INCDIR)/elf/common.h \
index d5f315805a9cd6d9eb14c97d95e8bd56434b675d..0f72fdf65a90a32e06747c2924e9a8842a4f8156 100644 (file)
@@ -1,4 +1,4 @@
-# generated automatically by aclocal 1.9.5 -*- Autoconf -*-
+# generated automatically by aclocal 1.9.2 -*- Autoconf -*-
 
 # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
 # 2005  Free Software Foundation, Inc.
 # even the implied warranty of MERCHANTABILITY or FITNESS FOR A
 # PARTICULAR PURPOSE.
 
-# Copyright (C) 2002, 2003, 2005  Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
+#                                                        -*- Autoconf -*-
+# Copyright (C) 2002, 2003  Free Software Foundation, Inc.
+# Generated from amversion.in; do not edit by hand.
+
+# 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, 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
 
 # AM_AUTOMAKE_VERSION(VERSION)
 # ----------------------------
@@ -28,15 +40,26 @@ AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version="1.9"])
 # Call AM_AUTOMAKE_VERSION so it can be traced.
 # This function is AC_REQUIREd by AC_INIT_AUTOMAKE.
 AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
-        [AM_AUTOMAKE_VERSION([1.9.5])])
+        [AM_AUTOMAKE_VERSION([1.9.2])])
 
-# AM_AUX_DIR_EXPAND                                         -*- Autoconf -*-
+# AM_AUX_DIR_EXPAND
 
-# Copyright (C) 2001, 2003, 2005  Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
+# Copyright (C) 2001, 2003 Free Software Foundation, Inc.
+
+# 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, 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.
 
 # For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
 # $ac_aux_dir to `$srcdir/foo'.  In other projects, it is set to
@@ -83,16 +106,26 @@ AC_PREREQ([2.50])dnl
 am_aux_dir=`cd $ac_aux_dir && pwd`
 ])
 
-# AM_CONDITIONAL                                            -*- Autoconf -*-
+# AM_CONDITIONAL                                              -*- Autoconf -*-
 
-# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005
-# Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
+# Copyright (C) 1997, 2000, 2001, 2003, 2004 Free Software Foundation, Inc.
 
-# serial 7
+# 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, 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.
+
+# serial 6
 
 # AM_CONDITIONAL(NAME, SHELL-CONDITION)
 # -------------------------------------
@@ -116,15 +149,26 @@ AC_CONFIG_COMMANDS_PRE(
 Usually this means the macro was only invoked conditionally.]])
 fi])])
 
+# serial 7                                             -*- Autoconf -*-
 
-# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
+# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
 # Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
 
-# serial 8
+# 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, 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.
+
 
 # There are a few dirty hacks below to avoid letting `AC_PROG_CC' be
 # written in clear, in which case automake, when reading aclocal.m4,
@@ -133,6 +177,7 @@ fi])])
 # CC etc. in the Makefile, will ask for an AC_PROG_CC use...
 
 
+
 # _AM_DEPENDENCIES(NAME)
 # ----------------------
 # See how the compiler implements dependency checking.
@@ -272,16 +317,27 @@ AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
 AC_SUBST([AMDEPBACKSLASH])
 ])
 
-# Generate code to set up dependency tracking.              -*- Autoconf -*-
+# Generate code to set up dependency tracking.   -*- Autoconf -*-
 
-# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
-# Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
+# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
+#   Free Software Foundation, Inc.
+
+# 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, 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.
 
-#serial 3
+# 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.
+
+#serial 2
 
 # _AM_OUTPUT_DEPENDENCY_COMMANDS
 # ------------------------------
@@ -340,31 +396,54 @@ AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
      [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"])
 ])
 
-# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005
-# Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
+# Like AC_CONFIG_HEADER, but automatically create stamp file. -*- Autoconf -*-
 
-# serial 8
+# Copyright (C) 1996, 1997, 2000, 2001, 2003 Free Software Foundation, Inc.
+
+# 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, 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.
+
+# serial 7
 
 # AM_CONFIG_HEADER is obsolete.  It has been replaced by AC_CONFIG_HEADERS.
 AU_DEFUN([AM_CONFIG_HEADER], [AC_CONFIG_HEADERS($@)])
 
-# Do all the work for Automake.                             -*- Autoconf -*-
+# Do all the work for Automake.                            -*- Autoconf -*-
+
+# This macro actually does too much some checks are only needed if
+# your package does certain things.  But this isn't really a big deal.
 
-# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
 # Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
 
-# serial 12
+# 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, or (at your option)
+# any later version.
 
-# This macro actually does too much.  Some checks are only needed if
-# your package does certain things.  But this isn't really a big deal.
+# 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.
+
+# serial 11
 
 # AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
 # AM_INIT_AUTOMAKE([OPTIONS])
@@ -466,27 +545,51 @@ for _am_header in $config_headers :; do
 done
 echo "timestamp for $1" >`AS_DIRNAME([$1])`/stamp-h[]$_am_stamp_count])
 
-# Copyright (C) 2001, 2003, 2005  Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
 # AM_PROG_INSTALL_SH
 # ------------------
 # Define $install_sh.
+
+# Copyright (C) 2001, 2003 Free Software Foundation, Inc.
+
+# 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, 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.
+
 AC_DEFUN([AM_PROG_INSTALL_SH],
 [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
 install_sh=${install_sh-"$am_aux_dir/install-sh"}
 AC_SUBST(install_sh)])
 
-# Copyright (C) 2003, 2005  Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
+#                                                          -*- Autoconf -*-
+# Copyright (C) 2003  Free Software Foundation, Inc.
 
-# serial 2
+# 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, 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.
+
+# serial 1
 
 # Check whether the underlying file-system supports filenames
 # with a leading dot.  For instance MS-DOS doesn't.
@@ -501,17 +604,28 @@ fi
 rmdir .tst 2>/dev/null
 AC_SUBST([am__leading_dot])])
 
-# Add --enable-maintainer-mode option to configure.         -*- Autoconf -*-
+# Add --enable-maintainer-mode option to configure.
 # From Jim Meyering
 
-# Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004, 2005
+# Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004
 # Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
 
-# serial 4
+# 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, 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.
+
+# serial 3
 
 AC_DEFUN([AM_MAINTAINER_MODE],
 [AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles])
@@ -530,15 +644,26 @@ AC_DEFUN([AM_MAINTAINER_MODE],
 
 AU_DEFUN([jm_MAINTAINER_MODE], [AM_MAINTAINER_MODE])
 
-# Check to see how 'make' treats includes.                 -*- Autoconf -*-
+# Check to see how 'make' treats includes.     -*- Autoconf -*-
 
-# Copyright (C) 2001, 2002, 2003, 2005  Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
+# Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
 
-# serial 3
+# 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, 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.
+
+# serial 2
 
 # AM_MAKE_INCLUDE()
 # -----------------
@@ -582,16 +707,27 @@ AC_MSG_RESULT([$_am_result])
 rm -f confinc confmf
 ])
 
-# Fake the existence of programs that GNU maintainers use.  -*- Autoconf -*-
+#  -*- Autoconf -*-
 
-# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2005
-# Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
 
-# serial 4
+# Copyright (C) 1997, 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
+
+# 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, 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.
+
+# serial 3
 
 # AM_MISSING_PROG(NAME, PROGRAM)
 # ------------------------------
@@ -617,16 +753,27 @@ else
 fi
 ])
 
-# Copyright (C) 2003, 2004, 2005  Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
 # AM_PROG_MKDIR_P
 # ---------------
 # Check whether `mkdir -p' is supported, fallback to mkinstalldirs otherwise.
-#
+
+# Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+
+# 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, 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.
+
 # Automake 1.8 used `mkdir -m 0755 -p --' to ensure that directories
 # created by `make install' are always world readable, even if the
 # installer happens to have an overly restrictive umask (e.g. 077).
@@ -680,15 +827,26 @@ else
 fi
 AC_SUBST([mkdir_p])])
 
-# Helper functions for option handling.                     -*- Autoconf -*-
+# Helper functions for option handling.                    -*- Autoconf -*-
 
-# Copyright (C) 2001, 2002, 2003, 2005  Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
+# Copyright (C) 2001, 2002, 2003  Free Software Foundation, Inc.
 
-# serial 3
+# 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, 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.
+
+# serial 2
 
 # _AM_MANGLE_OPTION(NAME)
 # -----------------------
@@ -713,16 +871,28 @@ AC_DEFUN([_AM_SET_OPTIONS],
 AC_DEFUN([_AM_IF_OPTION],
 [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
 
-# Check to make sure that the build environment is sane.    -*- Autoconf -*-
-
-# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005
-# Free Software Foundation, Inc.
 #
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
+# Check to make sure that the build environment is sane.
+#
+
+# Copyright (C) 1996, 1997, 2000, 2001, 2003 Free Software Foundation, Inc.
 
-# serial 4
+# 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, 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.
+
+# serial 3
 
 # AM_SANITY_CHECK
 # ---------------
@@ -765,14 +935,25 @@ Check your system clock])
 fi
 AC_MSG_RESULT(yes)])
 
-# Copyright (C) 2001, 2003, 2005  Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
 # AM_PROG_INSTALL_STRIP
-# ---------------------
+
+# Copyright (C) 2001, 2003 Free Software Foundation, Inc.
+
+# 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, 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.
+
 # One issue with vendor `install' (even GNU) is that you can't
 # specify the program used to strip binaries.  This is especially
 # annoying in cross-compiling environments, where the build's strip
@@ -795,13 +976,25 @@ AC_SUBST([INSTALL_STRIP_PROGRAM])])
 
 # Check how to create a tarball.                            -*- Autoconf -*-
 
-# Copyright (C) 2004, 2005  Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
+# Copyright (C) 2004  Free Software Foundation, Inc.
+
+# 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, 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.
+
+# serial 1
 
-# serial 2
 
 # _AM_PROG_TAR(FORMAT)
 # --------------------
index a6d96541e9067847d58b76c293e5d3c4dd3e9c1a..74d2b712ed54fd40297d3fd2ffe3509698c3715c 100644 (file)
@@ -327,6 +327,8 @@ DESCRIPTION
 .#define bfd_mach_avr3         3
 .#define bfd_mach_avr4         4
 .#define bfd_mach_avr5         5
+.  bfd_arch_bfin,        {* ADI Blackfin *}
+.#define bfd_mach_bfin          1
 .  bfd_arch_cr16c,       {* National Semiconductor CompactRISC. *}
 .#define bfd_mach_cr16c                1
 .  bfd_arch_crx,       {*  National Semiconductor CRX.  *}
@@ -405,6 +407,7 @@ extern const bfd_arch_info_type bfd_alpha_arch;
 extern const bfd_arch_info_type bfd_arc_arch;
 extern const bfd_arch_info_type bfd_arm_arch;
 extern const bfd_arch_info_type bfd_avr_arch;
+extern const bfd_arch_info_type bfd_bfin_arch;
 extern const bfd_arch_info_type bfd_cr16c_arch;
 extern const bfd_arch_info_type bfd_cris_arch;
 extern const bfd_arch_info_type bfd_crx_arch;
@@ -469,6 +472,7 @@ static const bfd_arch_info_type * const bfd_archures_list[] =
     &bfd_arc_arch,
     &bfd_arm_arch,
     &bfd_avr_arch,
+    &bfd_bfin_arch,
     &bfd_cr16c_arch,
     &bfd_cris_arch,
     &bfd_crx_arch,
index cd3bc7678ef2eaad3d0a223e098783dec1a5923a..eaecb920047b1fc0accb0c9372ad1ae11c580089 100644 (file)
@@ -709,6 +709,10 @@ extern bfd_boolean bfd_m68k_elf32_create_embedded_relocs
   (bfd *, struct bfd_link_info *, struct bfd_section *, struct bfd_section *,
    char **);
 
+extern bfd_boolean bfd_bfin_elf32_create_embedded_relocs
+  (bfd *, struct bfd_link_info *, struct bfd_section *, struct bfd_section *,
+   char **);
+
 /* SunOS shared library support routines for the linker.  */
 
 extern struct bfd_link_needed_list *bfd_sunos_get_needed_list
index 807c229df61b4811f4c84685de65a3cc9effb275..347108157a7ba25cbabf5e0c6e3ab58d871437a6 100644 (file)
@@ -716,6 +716,10 @@ extern bfd_boolean bfd_m68k_elf32_create_embedded_relocs
   (bfd *, struct bfd_link_info *, struct bfd_section *, struct bfd_section *,
    char **);
 
+extern bfd_boolean bfd_bfin_elf32_create_embedded_relocs
+  (bfd *, struct bfd_link_info *, struct bfd_section *, struct bfd_section *,
+   char **);
+
 /* SunOS shared library support routines for the linker.  */
 
 extern struct bfd_link_needed_list *bfd_sunos_get_needed_list
@@ -1911,6 +1915,8 @@ enum bfd_architecture
 #define bfd_mach_avr3          3
 #define bfd_mach_avr4          4
 #define bfd_mach_avr5          5
+  bfd_arch_bfin,        /* ADI Blackfin */
+#define bfd_mach_bfin          1
   bfd_arch_cr16c,       /* National Semiconductor CompactRISC. */
 #define bfd_mach_cr16c         1
   bfd_arch_crx,       /*  National Semiconductor CRX.  */
@@ -2998,6 +3004,105 @@ stored in the instruction.  The high 24 bits are installed in bits 23
 through 0.  */
   BFD_RELOC_ARC_B26,
 
+/* ADI Blackfin 16 bit immediate absolute reloc.  */
+  BFD_RELOC_BFIN_16_IMM,
+
+/* ADI Blackfin 16 bit immediate absolute reloc higher 16 bits.  */
+  BFD_RELOC_BFIN_16_HIGH,
+
+/* ADI Blackfin 'a' part of LSETUP.  */
+  BFD_RELOC_BFIN_4_PCREL,
+
+/* ADI Blackfin.  */
+  BFD_RELOC_BFIN_5_PCREL,
+
+/* ADI Blackfin 16 bit immediate absolute reloc lower 16 bits.  */
+  BFD_RELOC_BFIN_16_LOW,
+
+/* ADI Blackfin.  */
+  BFD_RELOC_BFIN_10_PCREL,
+
+/* ADI Blackfin 'b' part of LSETUP.  */
+  BFD_RELOC_BFIN_11_PCREL,
+
+/* ADI Blackfin.  */
+  BFD_RELOC_BFIN_12_PCREL_JUMP,
+
+/* ADI Blackfin Short jump, pcrel.  */
+  BFD_RELOC_BFIN_12_PCREL_JUMP_S,
+
+/* ADI Blackfin Call.x not implemented.  */
+  BFD_RELOC_BFIN_24_PCREL_CALL_X,
+
+/* ADI Blackfin Long Jump pcrel.  */
+  BFD_RELOC_BFIN_24_PCREL_JUMP_L,
+
+/* ADI Blackfin GOT relocation.  */
+  BFD_RELOC_BFIN_GOT,
+
+/* ADI Blackfin PLTPC relocation.  */
+  BFD_RELOC_BFIN_PLTPC,
+
+/* ADI Blackfin arithmetic relocation.  */
+  BFD_ARELOC_BFIN_PUSH,
+
+/* ADI Blackfin arithmetic relocation.  */
+  BFD_ARELOC_BFIN_CONST,
+
+/* ADI Blackfin arithmetic relocation.  */
+  BFD_ARELOC_BFIN_ADD,
+
+/* ADI Blackfin arithmetic relocation.  */
+  BFD_ARELOC_BFIN_SUB,
+
+/* ADI Blackfin arithmetic relocation.  */
+  BFD_ARELOC_BFIN_MULT,
+
+/* ADI Blackfin arithmetic relocation.  */
+  BFD_ARELOC_BFIN_DIV,
+
+/* ADI Blackfin arithmetic relocation.  */
+  BFD_ARELOC_BFIN_MOD,
+
+/* ADI Blackfin arithmetic relocation.  */
+  BFD_ARELOC_BFIN_LSHIFT,
+
+/* ADI Blackfin arithmetic relocation.  */
+  BFD_ARELOC_BFIN_RSHIFT,
+
+/* ADI Blackfin arithmetic relocation.  */
+  BFD_ARELOC_BFIN_AND,
+
+/* ADI Blackfin arithmetic relocation.  */
+  BFD_ARELOC_BFIN_OR,
+
+/* ADI Blackfin arithmetic relocation.  */
+  BFD_ARELOC_BFIN_XOR,
+
+/* ADI Blackfin arithmetic relocation.  */
+  BFD_ARELOC_BFIN_LAND,
+
+/* ADI Blackfin arithmetic relocation.  */
+  BFD_ARELOC_BFIN_LOR,
+
+/* ADI Blackfin arithmetic relocation.  */
+  BFD_ARELOC_BFIN_LEN,
+
+/* ADI Blackfin arithmetic relocation.  */
+  BFD_ARELOC_BFIN_NEG,
+
+/* ADI Blackfin arithmetic relocation.  */
+  BFD_ARELOC_BFIN_COMP,
+
+/* ADI Blackfin arithmetic relocation.  */
+  BFD_ARELOC_BFIN_PAGE,
+
+/* ADI Blackfin arithmetic relocation.  */
+  BFD_ARELOC_BFIN_HWPAGE,
+
+/* ADI Blackfin arithmetic relocation.  */
+  BFD_ARELOC_BFIN_ADDR,
+
 /* Mitsubishi D10V relocs.
 This is a 10-bit reloc with the right 2 bits
 assumed to be 0.  */
index 8b6e72c6cae61caf5170e9df1a2395074216295f..aec10e182339ebf566fca8dd7c3686d07c8ba6f1 100644 (file)
@@ -71,6 +71,7 @@ targ_cpu=`echo $targ | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
 case "${targ_cpu}" in
 alpha*)                 targ_archs=bfd_alpha_arch ;;
 arm*)           targ_archs=bfd_arm_arch ;;
+bfin*)          targ_archs=bfd_bfin_arch ;;
 c30*)           targ_archs=bfd_tic30_arch ;;
 c4x*)           targ_archs=bfd_tic4x_arch ;;
 c54x*)          targ_archs=bfd_tic54x_arch ;;
@@ -309,6 +310,11 @@ case "${targ}" in
     targ_defvec=bfd_elf32_avr_vec
     ;;
 
+  bfin-*-*)
+    targ_defvec=bfd_elf32_bfin_vec
+    tar_underscore=yes
+    ;;
+
   c30-*-*aout* | tic30-*-*aout*)
     targ_defvec=tic30_aout_vec
     ;;
index 03f04777f9328837e52b9ba9ab9a25754478e059..179967607f617dd19be2c59f4112b2d6bd7b9cbe 100755 (executable)
@@ -12962,6 +12962,7 @@ do
     bfd_efi_app_ia64_vec)      tb="$tb efi-app-ia64.lo pepigen.lo cofflink.lo"; target_size=64 ;;
     bfd_elf32_am33lin_vec)     tb="$tb elf32-am33lin.lo elf32.lo $elf" ;;
     bfd_elf32_avr_vec)         tb="$tb elf32-avr.lo elf32.lo $elf" ;;
+    bfd_elf32_bfin_vec)                tb="$tb elf32-bfin.lo elf32.lo $elf" ;;
     bfd_elf32_big_generic_vec)         tb="$tb elf32-gen.lo elf32.lo $elf" ;;
     bfd_elf32_bigarc_vec)      tb="$tb elf32-arc.lo elf32.lo $elf" ;;
     bfd_elf32_bigarm_vec)      tb="$tb elf32-arm.lo elf32.lo $elf" ;;
index 40da6d83ebac898778269d2f7673f5bb8b2a32da..7ace2196d06850d0108865effc272154c011467b 100644 (file)
@@ -583,6 +583,7 @@ do
     bfd_efi_app_ia64_vec)      tb="$tb efi-app-ia64.lo pepigen.lo cofflink.lo"; target_size=64 ;;
     bfd_elf32_am33lin_vec)     tb="$tb elf32-am33lin.lo elf32.lo $elf" ;;
     bfd_elf32_avr_vec)         tb="$tb elf32-avr.lo elf32.lo $elf" ;;
+    bfd_elf32_bfin_vec)                tb="$tb elf32-bfin.lo elf32.lo $elf" ;;
     bfd_elf32_big_generic_vec)         tb="$tb elf32-gen.lo elf32.lo $elf" ;;
     bfd_elf32_bigarc_vec)      tb="$tb elf32-arc.lo elf32.lo $elf" ;;
     bfd_elf32_bigarm_vec)      tb="$tb elf32-arm.lo elf32.lo $elf" ;;
diff --git a/bfd/cpu-bfin.c b/bfd/cpu-bfin.c
new file mode 100644 (file)
index 0000000..6de6757
--- /dev/null
@@ -0,0 +1,40 @@
+/* BFD Support for the ADI Blackfin processor.
+
+   Copyright 2005 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., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301,
+   USA.  */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+
+const bfd_arch_info_type bfd_bfin_arch =
+  {
+    16,                /* Bits in a word.  */
+    32,                /* Bits in an address.  */
+    8,                 /* Bits in a byte.  */
+    bfd_arch_bfin,
+    0,                 /* Only one machine.  */
+    "bfin",            /* Arch name.  */
+    "bfin",            /* Arch printable name.  */
+    4,                 /* Section align power.  */
+    TRUE,              /* The one and only.  */
+    bfd_default_compatible, 
+    bfd_default_scan ,
+    0,
+  };
diff --git a/bfd/elf32-bfin.c b/bfd/elf32-bfin.c
new file mode 100644 (file)
index 0000000..72f8aee
--- /dev/null
@@ -0,0 +1,2830 @@
+/* ADI Blackfin BFD support for 32-bit ELF. 
+   Copyright 2005 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., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301,
+   USA.  */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "elf/bfin.h"
+
+/* Handling expression relocations for blackfin.  Blackfin
+   will generate relocations in an expression form with a stack.
+   A relocation such as P1.H  = _typenames-4000000;
+   will generate the following relocs at offset 4:
+00000004 R_expst_push      _typenames
+00000004 R_expst_const     .__constant
+00000004 R_expst_sub       .__operator
+00000006 R_huimm16         .__operator
+
+   The .__constant and .__operator symbol names are fake.
+   Special case is a single relocation
+     P1.L  = _typenames; generates
+00000002 R_luimm16         _typenames
+
+   Thus, if you get a R_luimm16, R_huimm16, R_imm16,
+   if the stack is not empty, pop the stack and
+   put the value, else do the normal thing
+   We will currently assume that the max the stack
+   would grow to is 100. .  */
+
+#define RELOC_STACK_SIZE 100
+static bfd_vma reloc_stack[RELOC_STACK_SIZE];
+static unsigned int reloc_stack_tos = 0;
+
+#define is_reloc_stack_empty() ((reloc_stack_tos > 0) ? 0 : 1)
+
+static void
+reloc_stack_push (bfd_vma value)
+{
+  reloc_stack[reloc_stack_tos++] = value;
+}
+
+static bfd_vma
+reloc_stack_pop (void)
+{
+  return reloc_stack[--reloc_stack_tos];
+}
+
+static bfd_vma
+reloc_stack_operate (unsigned int oper)
+{
+  bfd_vma value;
+  switch (oper)
+    {
+    case R_add:
+      {
+       value =
+         reloc_stack[reloc_stack_tos - 2] + reloc_stack[reloc_stack_tos - 1];
+       reloc_stack_tos -= 2;
+       break;
+      }
+    case R_sub:
+      {
+       value =
+         reloc_stack[reloc_stack_tos - 2] - reloc_stack[reloc_stack_tos - 1];
+       reloc_stack_tos -= 2;
+       break;
+      }
+    case R_mult:
+      {
+       value =
+         reloc_stack[reloc_stack_tos - 2] * reloc_stack[reloc_stack_tos - 1];
+       reloc_stack_tos -= 2;
+       break;
+      }
+    case R_div:
+      {
+       if (reloc_stack[reloc_stack_tos - 1] == 0)
+         {
+           _bfd_abort (__FILE__, __LINE__, _("Division by zero. "));
+         }
+       else
+         {
+           value =
+             reloc_stack[reloc_stack_tos - 2] / reloc_stack[reloc_stack_tos - 1];
+           reloc_stack_tos -= 2;
+         }
+       break;
+      }
+    case R_mod:
+      {
+       value =
+         reloc_stack[reloc_stack_tos - 2] % reloc_stack[reloc_stack_tos - 1];
+       reloc_stack_tos -= 2;
+       break;
+      }
+    case R_lshift:
+      {
+       value =
+         reloc_stack[reloc_stack_tos - 2] << reloc_stack[reloc_stack_tos -
+                                                         1];
+       reloc_stack_tos -= 2;
+       break;
+      }
+    case R_rshift:
+      {
+       value =
+         reloc_stack[reloc_stack_tos - 2] >> reloc_stack[reloc_stack_tos -
+                                                         1];
+       reloc_stack_tos -= 2;
+       break;
+      }
+    case R_and:
+      {
+       value =
+         reloc_stack[reloc_stack_tos - 2] & reloc_stack[reloc_stack_tos - 1];
+       reloc_stack_tos -= 2;
+       break;
+      }
+    case R_or:
+      {
+       value =
+         reloc_stack[reloc_stack_tos - 2] | reloc_stack[reloc_stack_tos - 1];
+       reloc_stack_tos -= 2;
+       break;
+      }
+    case R_xor:
+      {
+       value =
+         reloc_stack[reloc_stack_tos - 2] ^ reloc_stack[reloc_stack_tos - 1];
+       reloc_stack_tos -= 2;
+       break;
+      }
+    case R_land:
+      {
+       value = reloc_stack[reloc_stack_tos - 2]
+         && reloc_stack[reloc_stack_tos - 1];
+       reloc_stack_tos -= 2;
+       break;
+      }
+    case R_lor:
+      {
+       value = reloc_stack[reloc_stack_tos - 2]
+         || reloc_stack[reloc_stack_tos - 1];
+       reloc_stack_tos -= 2;
+       break;
+      }
+    case R_neg:
+      {
+       value = -reloc_stack[reloc_stack_tos - 1];
+       reloc_stack_tos--;
+       break;
+      }
+    case R_comp:
+      {
+       value = ~reloc_stack[reloc_stack_tos - 1];
+       reloc_stack_tos -= 1;
+       break;
+      }
+    default:
+      {
+       fprintf (stderr, "bfin relocation : Internal bug\n");
+       return 0;
+      }
+    }
+
+  reloc_stack_push (value);
+
+  return value;
+}
+
+/* FUNCTION : bfin_pltpc_reloc
+   ABSTRACT : TODO : figure out how to handle pltpc relocs.  */
+static bfd_reloc_status_type
+bfin_pltpc_reloc (
+     bfd *abfd ATTRIBUTE_UNUSED,
+     arelent *reloc_entry ATTRIBUTE_UNUSED,
+     asymbol *symbol ATTRIBUTE_UNUSED,
+     PTR data ATTRIBUTE_UNUSED,
+     asection *input_section ATTRIBUTE_UNUSED,
+     bfd *output_bfd ATTRIBUTE_UNUSED,
+     char **error_message ATTRIBUTE_UNUSED) 
+{
+  bfd_reloc_status_type flag = bfd_reloc_ok;
+  return flag; 
+}
+\f
+
+static bfd_reloc_status_type
+bfin_pcrel24_reloc (bfd *abfd,
+                    arelent *reloc_entry,
+                    asymbol *symbol,
+                    PTR data,
+                    asection *input_section,
+                    bfd *output_bfd,
+                    char **error_message ATTRIBUTE_UNUSED)
+{
+  bfd_vma relocation;
+  bfd_size_type addr = reloc_entry->address;
+  bfd_vma output_base = 0;
+  reloc_howto_type *howto = reloc_entry->howto;
+  asection *output_section;
+  bfd_boolean relocatable = (output_bfd != NULL);
+
+  if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
+    return bfd_reloc_outofrange;
+
+  if (!is_reloc_stack_empty ())
+    relocation = reloc_stack_pop();
+  else
+    {
+      if (bfd_is_und_section (symbol->section)
+          && (symbol->flags & BSF_WEAK) == 0
+          && !relocatable)
+        return bfd_reloc_undefined;
+
+      if (bfd_is_com_section (symbol->section))
+       relocation = 0;
+      else
+       relocation = symbol->value;       
+
+      output_section = symbol->section->output_section;
+
+      if (relocatable)
+       output_base = 0;
+      else
+       output_base = output_section->vma;
+      
+      if (!relocatable || !strcmp (symbol->name, symbol->section->name))
+       relocation += output_base + symbol->section->output_offset;
+        
+      if (!relocatable && !strcmp (symbol->name, symbol->section->name))
+        relocation += reloc_entry->addend;
+    }
+      
+  relocation -= input_section->output_section->vma + input_section->output_offset;
+  relocation -= reloc_entry->address;
+
+  if (howto->complain_on_overflow != complain_overflow_dont)
+    {
+      bfd_reloc_status_type status;
+      status= bfd_check_overflow (howto->complain_on_overflow, 
+                                  howto->bitsize,
+                                  howto->rightshift, 
+                                  bfd_arch_bits_per_address(abfd),
+                                  relocation);      
+      if (status != bfd_reloc_ok)
+       return status;
+    }
+      
+  /* if rightshift is 1 and the number odd, return error.  */
+  if (howto->rightshift && (relocation & 0x01))
+    {
+      fprintf(stderr, "relocation should be even number\n");
+      return bfd_reloc_overflow;
+    }
+
+  relocation >>= (bfd_vma) howto->rightshift;
+  /* Shift everything up to where it's going to be used.  */
+
+  relocation <<= (bfd_vma) howto->bitpos;
+
+  if (relocatable)
+    {
+      reloc_entry->address += input_section->output_offset;
+      reloc_entry->addend += symbol->section->output_offset;
+    }
+
+  {
+    short x;
+
+    /* We are getting reloc_entry->address 2 byte off from
+    the start of instruction. Assuming absolute postion
+    of the reloc data. But, following code had been written assuming 
+    reloc address is starting at begining of instruction.
+    To compensate that I have increased the value of 
+    relocation by 1 (effectively 2) and used the addr -2 instead of addr.  */ 
+
+    relocation += 1;
+    x = bfd_get_16 (abfd, (bfd_byte *) data + addr - 2);
+    x = (x & 0xff00) | ((relocation >> 16) & 0xff);
+    bfd_put_16 (abfd, x, (unsigned char *) data + addr - 2);
+
+    x = bfd_get_16 (abfd, (bfd_byte *) data + addr);
+    x = relocation & 0xFFFF;
+    bfd_put_16 (abfd, x, (unsigned char *) data + addr );
+  }
+  return bfd_reloc_ok;
+}
+
+static bfd_reloc_status_type
+bfin_push_reloc (bfd *abfd ATTRIBUTE_UNUSED,
+                arelent *reloc_entry,
+                asymbol *symbol,
+                PTR data ATTRIBUTE_UNUSED,
+                asection *input_section,
+                bfd *output_bfd,
+                char **error_message ATTRIBUTE_UNUSED) 
+{
+  bfd_vma relocation;
+  bfd_vma output_base = 0;
+  asection *output_section;
+  bfd_boolean relocatable = (output_bfd != NULL);
+
+  if (bfd_is_und_section (symbol->section)
+      && (symbol->flags & BSF_WEAK) == 0
+      && !relocatable)
+    return bfd_reloc_undefined;
+
+  /* Is the address of the relocation really within the section?  */
+  if (reloc_entry->address > bfd_get_section_limit(abfd, input_section))
+     return bfd_reloc_outofrange;
+      
+  output_section = symbol->section->output_section;
+  relocation = symbol->value;      
+
+  /* Convert input-section-relative symbol value to absolute.  */
+  if (relocatable)
+    output_base = 0;
+  else
+    output_base = output_section->vma;
+
+  if (!relocatable || !strcmp(symbol->name, symbol->section->name))
+    relocation += output_base + symbol->section->output_offset;
+
+  /* Add in supplied addend.  */
+  relocation += reloc_entry->addend;
+
+  if (relocatable)
+    {
+      reloc_entry->address += input_section->output_offset;
+      reloc_entry->addend += symbol->section->output_offset;
+    }
+
+  /* Now that we have the value, push it. */
+  reloc_stack_push (relocation);
+  
+  return bfd_reloc_ok;
+}
+
+static bfd_reloc_status_type
+bfin_oper_reloc (bfd *abfd ATTRIBUTE_UNUSED,
+                arelent *reloc_entry,
+                asymbol *symbol ATTRIBUTE_UNUSED,
+                PTR data ATTRIBUTE_UNUSED,
+                asection *input_section,
+                bfd *output_bfd,
+                char **error_message ATTRIBUTE_UNUSED) 
+{
+  bfd_boolean relocatable = (output_bfd != NULL);
+
+  /* Just call the operation based on the reloc_type.  */
+  reloc_stack_operate (reloc_entry->howto->type);
+  
+  if (relocatable)
+    reloc_entry->address += input_section->output_offset;
+
+  return bfd_reloc_ok;
+}
+
+static bfd_reloc_status_type
+bfin_const_reloc (bfd *abfd ATTRIBUTE_UNUSED,
+                 arelent *reloc_entry,
+                 asymbol *symbol ATTRIBUTE_UNUSED,
+                 PTR data ATTRIBUTE_UNUSED,
+                 asection *input_section,
+                 bfd *output_bfd,
+                 char **error_message ATTRIBUTE_UNUSED) 
+{
+  bfd_boolean relocatable = (output_bfd != NULL);
+
+  /* Push the addend portion of the relocation.  */
+  reloc_stack_push (reloc_entry->addend);
+
+  if (relocatable)
+    reloc_entry->address += input_section->output_offset;
+  
+  return bfd_reloc_ok;
+}
+
+static bfd_reloc_status_type
+bfin_imm16_reloc (bfd *abfd,
+                 arelent *reloc_entry,
+                 asymbol *symbol,
+                 PTR data,
+                 asection *input_section,
+                 bfd *output_bfd,
+                 char **error_message ATTRIBUTE_UNUSED) 
+{
+  bfd_vma relocation, x;
+  bfd_size_type reloc_addr = reloc_entry->address;
+  bfd_vma output_base = 0;
+  reloc_howto_type *howto = reloc_entry->howto;
+  asection *output_section;
+  bfd_boolean relocatable = (output_bfd != NULL);
+
+  /* Is the address of the relocation really within the section?  */
+  if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
+    return bfd_reloc_outofrange;
+
+  if (is_reloc_stack_empty ())
+    {
+      if (bfd_is_und_section (symbol->section)
+          && (symbol->flags & BSF_WEAK) == 0
+          && !relocatable)
+        return bfd_reloc_undefined;
+
+      output_section = symbol->section->output_section;
+      relocation = symbol->value;      
+
+      /* Convert input-section-relative symbol value to absolute.  */
+      if (relocatable)
+        output_base = 0;
+      else
+       output_base = output_section->vma;
+  
+      if (!relocatable || !strcmp (symbol->name, symbol->section->name))
+       relocation += output_base + symbol->section->output_offset;
+
+      if (symbol->flags & BSF_SECTION_SYM)
+       {
+         /* Add in supplied addend.  */
+         relocation += reloc_entry->addend;
+       }
+    }
+  else
+    {
+      relocation = reloc_stack_pop ();
+    }
+
+  if (relocatable)
+    {                
+      reloc_entry->address += input_section->output_offset;
+      reloc_entry->addend += symbol->section->output_offset;
+    }
+  else
+    {
+      reloc_entry->addend = 0;
+    }
+
+  if (howto->complain_on_overflow != complain_overflow_dont)
+    {
+      bfd_reloc_status_type flag;
+      flag = bfd_check_overflow (howto->complain_on_overflow,
+                                 howto->bitsize,
+                                 howto->rightshift,
+                                 bfd_arch_bits_per_address(abfd),
+                                 relocation);
+      if (flag != bfd_reloc_ok)
+        return flag;
+    }
+
+
+  /* Here the variable relocation holds the final address of the
+     symbol we are relocating against, plus any addend.  */
+
+  x = bfd_get_16 (abfd, (bfd_byte *) data + reloc_addr);
+  relocation >>= (bfd_vma) howto->rightshift;
+  x = relocation;
+  bfd_put_16 (abfd, x, (unsigned char *) data + reloc_addr);
+  return bfd_reloc_ok;
+}
+
+
+static bfd_reloc_status_type
+bfin_byte4_reloc (bfd *abfd,
+                  arelent *reloc_entry,
+                  asymbol *symbol,
+                  PTR data,
+                  asection *input_section,
+                  bfd *output_bfd,
+                  char **error_message ATTRIBUTE_UNUSED) 
+{
+  bfd_vma relocation, x;
+  bfd_size_type addr = reloc_entry->address;
+  bfd_vma output_base = 0;
+  asection *output_section;
+  bfd_boolean relocatable = (output_bfd != NULL);
+
+  /* Is the address of the relocation really within the section?  */
+  if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
+    return bfd_reloc_outofrange;
+
+  if (is_reloc_stack_empty ())
+    {
+      if (bfd_is_und_section (symbol->section)
+          && (symbol->flags & BSF_WEAK) == 0
+          && !relocatable)
+        return bfd_reloc_undefined;
+
+      output_section = symbol->section->output_section;
+      relocation = symbol->value;      
+      /* Convert input-section-relative symbol value to absolute.  */
+      if (relocatable)
+       output_base = 0;
+      else
+       output_base = output_section->vma;
+  
+      if ((symbol->name 
+         && symbol->section->name
+          && !strcmp (symbol->name, symbol->section->name))
+          || !relocatable)
+        {
+         relocation += output_base + symbol->section->output_offset;
+       }
+
+      relocation += reloc_entry->addend;
+    }
+  else
+    {
+      relocation = reloc_stack_pop();
+      relocation += reloc_entry->addend;
+    }
+
+  if (relocatable)
+    { 
+      /* This output will be relocatable ... like ld -r. */
+      reloc_entry->address += input_section->output_offset;
+      reloc_entry->addend += symbol->section->output_offset;
+    }
+  else
+    {
+      reloc_entry->addend = 0;
+    }
+
+  /* Here the variable relocation holds the final address of the
+     symbol we are relocating against, plus any addend.  */
+  x = relocation & 0xFFFF0000;
+  x >>=16;
+  bfd_put_16 (abfd, x, (unsigned char *) data + addr + 2);
+            
+  x = relocation & 0x0000FFFF;
+  bfd_put_16 (abfd, x, (unsigned char *) data + addr);
+  return bfd_reloc_ok;
+}
+
+/* bfin_bfd_reloc handles the blackfin arithmetic relocations.
+   Use this instead of bfd_perform_relocation.  */
+static bfd_reloc_status_type
+bfin_bfd_reloc (bfd *abfd,
+               arelent *reloc_entry,
+               asymbol *symbol,
+               PTR data,
+               asection *input_section,
+               bfd *output_bfd,
+               char **error_message ATTRIBUTE_UNUSED)
+{
+  bfd_vma relocation;
+  bfd_size_type addr = reloc_entry->address;
+  bfd_vma output_base = 0;
+  reloc_howto_type *howto = reloc_entry->howto;
+  asection *output_section;
+  bfd_boolean relocatable = (output_bfd != NULL);
+
+  /* Is the address of the relocation really within the section?  */
+  if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
+    return bfd_reloc_outofrange;
+
+  if (is_reloc_stack_empty())
+    {
+      if (bfd_is_und_section (symbol->section)
+          && (symbol->flags & BSF_WEAK) == 0
+          && !relocatable)
+        return bfd_reloc_undefined;
+
+      /* Get symbol value.  (Common symbols are special.)  */
+      if (bfd_is_com_section (symbol->section))
+        relocation = 0;
+      else
+        relocation = symbol->value;       
+  
+      output_section = symbol->section->output_section;
+        
+      /* Convert input-section-relative symbol value to absolute.  */
+      if (relocatable)
+       output_base = 0;
+      else
+       output_base = output_section->vma;
+        
+      if (!relocatable || !strcmp (symbol->name, symbol->section->name))
+        relocation += output_base + symbol->section->output_offset;
+
+     if (!relocatable && !strcmp (symbol->name, symbol->section->name))
+       {
+         /* Add in supplied addend.  */
+         relocation += reloc_entry->addend;
+       }
+        
+    }
+  else
+    {
+      relocation = reloc_stack_pop();
+    }
+      
+  /* Here the variable relocation holds the final address of the
+     symbol we are relocating against, plus any addend.  */
+
+  if (howto->pc_relative == TRUE)
+    {
+      relocation -= input_section->output_section->vma + input_section->output_offset;
+
+      if (howto->pcrel_offset == TRUE)
+        relocation -= reloc_entry->address;
+    }
+
+  if (relocatable)
+    {
+      reloc_entry->address += input_section->output_offset;
+      reloc_entry->addend += symbol->section->output_offset;
+    }
+
+  if (howto->complain_on_overflow != complain_overflow_dont)
+    {
+      bfd_reloc_status_type status;
+
+      status = bfd_check_overflow (howto->complain_on_overflow, 
+                                  howto->bitsize,
+                                  howto->rightshift, 
+                                  bfd_arch_bits_per_address(abfd),
+                                  relocation);
+      if (status != bfd_reloc_ok)
+       return status;
+    }
+      
+  /* If rightshift is 1 and the number odd, return error.  */
+  if (howto->rightshift && (relocation & 0x01))
+    {
+      fprintf(stderr, "relocation should be even number\n");
+      return bfd_reloc_overflow;
+    }
+
+  relocation >>= (bfd_vma) howto->rightshift;
+
+  /* Shift everything up to where it's going to be used.  */
+
+  relocation <<= (bfd_vma) howto->bitpos;
+
+#define DOIT(x) \
+  x = ( (x & ~howto->dst_mask) | (relocation & howto->dst_mask))
+
+  /* handle 8 and 16 bit relocations here. */
+  switch (howto->size)
+    {
+    case 0:
+      {
+        char x = bfd_get_8 (abfd, (char *) data + addr);
+        DOIT (x);
+        bfd_put_8 (abfd, x, (unsigned char *) data + addr);
+      }
+      break;
+
+    case 1:
+      {
+        unsigned short x = bfd_get_16 (abfd, (bfd_byte *) data + addr);
+        DOIT (x);
+        bfd_put_16 (abfd, (bfd_vma) x, (unsigned char *) data + addr);
+      }
+      break;
+
+    default:
+      return bfd_reloc_other;
+    }
+
+   return bfd_reloc_ok;
+}
+
+#if 0
+static bfd_reloc_status_type bfin_bfd_reloc
+  PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
+
+static bfd_reloc_status_type bfin_imm16_reloc
+  PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
+
+static bfd_reloc_status_type bfin_pcrel24_reloc
+  PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
+
+static bfd_reloc_status_type bfin_pltpc_reloc
+  PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
+
+static bfd_reloc_status_type bfin_const_reloc
+  PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
+
+static bfd_reloc_status_type bfin_oper_reloc
+  PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
+
+static bfd_reloc_status_type bfin_byte4_reloc
+  PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
+
+static bfd_reloc_status_type bfin_push_reloc
+  PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
+
+static bfd_boolean bfin_is_local_label_name
+  PARAMS ((bfd *, const char *));
+#endif
+bfd_boolean bfd_bfin_elf32_create_embedded_relocs
+  PARAMS ((bfd *, struct bfd_link_info *, asection *, asection *, char **));
+
+
+/* HOWTO Table for blackfin.
+   Blackfin relocations are fairly complicated.
+   Some of the salient features are
+   a. Even numbered offsets. A number of (not all) relocations are
+      even numbered. This means that the rightmost bit is not stored.
+      Needs to right shift by 1 and check to see if value is not odd
+   b. A relocation can be an expression. An expression takes on
+      a variety of relocations arranged in a stack.
+   As a result, we cannot use the standard generic function as special
+   function. We will have our own, which is very similar to the standard
+   generic function except that it understands how to get the value from
+   the relocation stack. .  */
+
+#define BFIN_RELOC_MIN 0
+#define BFIN_RELOC_MAX 0x13
+#define BFIN_GNUEXT_RELOC_MIN 0x40
+#define BFIN_GNUEXT_RELOC_MAX 0x43
+#define BFIN_ARELOC_MIN 0xE0
+#define BFIN_ARELOC_MAX 0xF3
+
+static reloc_howto_type bfin_howto_table [] =
+{
+  /* This reloc does nothing. .  */
+  HOWTO (R_unused0,            /* type.  */
+        0,                     /* rightshift.  */
+        2,                     /* size (0 = byte, 1 = short, 2 = long).  */
+        32,                    /* bitsize.  */
+        FALSE,                 /* pc_relative.  */
+        0,                     /* bitpos.  */
+        complain_overflow_bitfield, /* complain_on_overflow.  */
+        bfd_elf_generic_reloc, /* special_function.  */
+        "R_unused0",           /* name.  */
+        FALSE,                 /* partial_inplace.  */
+        0,                     /* src_mask.  */
+        0,                     /* dst_mask.  */
+        FALSE),                /* pcrel_offset.  */
+
+  HOWTO (R_pcrel5m2,           /* type.  */
+        1,                     /* rightshift.  */
+        1,                     /* size (0 = byte, 1 = short, 2 = long)..  */
+        4,                     /* bitsize.  */
+        TRUE,                  /* pc_relative.  */
+        0,                     /* bitpos.  */
+        complain_overflow_unsigned, /* complain_on_overflow.  */
+        bfin_bfd_reloc,        /* special_function.  */
+        "R_pcrel5m2",          /* name.  */
+        FALSE,                 /* partial_inplace.  */
+        0x0000000F,            /* src_mask.  */
+        0x0000000F,            /* dst_mask.  */
+        FALSE),                /* pcrel_offset.  */
+
+  HOWTO (R_unused1,            /* type.  */
+        0,                     /* rightshift.  */
+        2,                     /* size (0 = byte, 1 = short, 2 = long).  */
+        32,                    /* bitsize.  */
+        FALSE,                 /* pc_relative.  */
+        0,                     /* bitpos.  */
+        complain_overflow_bitfield, /* complain_on_overflow.  */
+        bfd_elf_generic_reloc, /* special_function.  */
+        "R_unused1",           /* name.  */
+        FALSE,                 /* partial_inplace.  */
+        0,                     /* src_mask.  */
+        0,                     /* dst_mask.  */
+        FALSE),                /* pcrel_offset.  */
+
+  HOWTO (R_pcrel10,            /* type.  */
+        1,                     /* rightshift.  */
+        1,                     /* size (0 = byte, 1 = short, 2 = long).  */
+        10,                    /* bitsize.  */
+        TRUE,                  /* pc_relative.  */
+        0,                     /* bitpos.  */
+        complain_overflow_signed, /* complain_on_overflow.  */
+        bfin_bfd_reloc,        /* special_function.  */
+        "R_pcrel10",           /* name.  */
+        FALSE,                 /* partial_inplace.  */
+        0x000003FF,            /* src_mask.  */
+        0x000003FF,            /* dst_mask.  */
+        TRUE),                 /* pcrel_offset.  */
+  HOWTO (R_pcrel12_jump,       /* type.  */
+        1,                     /* rightshift.  */
+                               /* the offset is actually 13 bit
+                                  aligned on a word boundary so
+                                  only 12 bits have to be used.
+                                  Right shift the rightmost bit..  */
+        1,                     /* size (0 = byte, 1 = short, 2 = long).  */
+        12,                    /* bitsize.  */
+        TRUE,                  /* pc_relative.  */
+        0,                     /* bitpos.  */
+        complain_overflow_signed, /* complain_on_overflow.  */
+        bfin_bfd_reloc,        /* special_function.  */
+        "R_pcrel12_jump",      /* name.  */
+        FALSE,                 /* partial_inplace.  */
+        0x0FFF,                /* src_mask.  */
+        0x0FFF,                /* dst_mask.  */
+        TRUE),                 /* pcrel_offset.  */
+
+  HOWTO (R_rimm16,             /* type.  */
+        0,                     /* rightshift.  */
+        1,                     /* size (0 = byte, 1 = short, 2 = long).  */
+        16,                    /* bitsize.  */
+        FALSE,                 /* pc_relative.  */
+        0,                     /* bitpos.  */
+        complain_overflow_signed, /* complain_on_overflow.  */
+        bfin_imm16_reloc,      /* special_function.  */
+        "R_rimm16",            /* name.  */
+        FALSE,                 /* partial_inplace.  */
+        0x0000FFFF,            /* src_mask.  */
+        0x0000FFFF,            /* dst_mask.  */
+        TRUE),                 /* pcrel_offset.  */
+
+  HOWTO (R_luimm16,            /* type.  */
+        0,                     /* rightshift.  */
+        1,                     /* size (0 = byte, 1 = short, 2 = long).  */
+        16,                    /* bitsize.  */
+        FALSE,                 /* pc_relative.  */
+        0,                     /* bitpos.  */
+        complain_overflow_dont, /* complain_on_overflow.  */
+        bfin_imm16_reloc,      /* special_function.  */
+        "R_luimm16",           /* name.  */
+        FALSE,                 /* partial_inplace.  */
+        0x0000FFFF,            /* src_mask.  */
+        0x0000FFFF,            /* dst_mask.  */
+        TRUE),                 /* pcrel_offset.  */
+  HOWTO (R_huimm16,            /* type.  */
+        16,                    /* rightshift.  */
+        1,                     /* size (0 = byte, 1 = short, 2 = long).  */
+        16,                    /* bitsize.  */
+        FALSE,                 /* pc_relative.  */
+        0,                     /* bitpos.  */
+        complain_overflow_unsigned, /* complain_on_overflow.  */
+        bfin_imm16_reloc,      /* special_function.  */
+        "R_huimm16",           /* name.  */
+        FALSE,                 /* partial_inplace.  */
+        0x0000FFFF,            /* src_mask.  */
+        0x0000FFFF,            /* dst_mask.  */
+        TRUE),                 /* pcrel_offset.  */
+
+  HOWTO (R_pcrel12_jump_s,     /* type.  */
+        1,                     /* rightshift.  */
+        1,                     /* size (0 = byte, 1 = short, 2 = long).  */
+        12,                    /* bitsize.  */
+        TRUE,                  /* pc_relative.  */
+        0,                     /* bitpos.  */
+        complain_overflow_signed, /* complain_on_overflow.  */
+        bfin_bfd_reloc,        /* special_function.  */
+        "R_pcrel12_jump_s",    /* name.  */
+        FALSE,                 /* partial_inplace.  */
+        0x00000FFF,            /* src_mask.  */
+        0x00000FFF,            /* dst_mask.  */
+        TRUE),                 /* pcrel_offset.  */
+
+  HOWTO (R_pcrel24_jump_x,     /* type.  */
+         1,                    /* rightshift.  */
+         2,                    /* size (0 = byte, 1 = short, 2 = long).  */
+         24,                   /* bitsize.  */
+         TRUE,                 /* pc_relative.  */
+         0,                    /* bitpos.  */
+         complain_overflow_signed, /* complain_on_overflow.  */
+         bfin_pcrel24_reloc,   /* special_function.  */
+         "R_pcrel24_jump_x",   /* name.  */
+        FALSE,                 /* partial_inplace.  */
+        0x00FFFFFF,            /* src_mask.  */
+        0x00FFFFFF,            /* dst_mask.  */
+        TRUE),                 /* pcrel_offset.  */
+
+  HOWTO (R_pcrel24,            /* type.  */
+        1,                     /* rightshift.  */
+        2,                     /* size (0 = byte, 1 = short, 2 = long).  */
+        24,                    /* bitsize.  */
+        TRUE,                  /* pc_relative.  */
+        0,                     /* bitpos.  */
+        complain_overflow_signed, /* complain_on_overflow.  */
+        bfin_pcrel24_reloc,    /* special_function.  */
+        "R_pcrel24",           /* name.  */
+        FALSE,                 /* partial_inplace.  */
+        0x00FFFFFF,            /* src_mask.  */
+        0x00FFFFFF,            /* dst_mask.  */
+        TRUE),                 /* pcrel_offset.  */
+
+  HOWTO (R_unusedb,            /* type.  */
+        0,                     /* rightshift.  */
+        2,                     /* size (0 = byte, 1 = short, 2 = long).  */
+        32,                    /* bitsize.  */
+        FALSE,                 /* pc_relative.  */
+        0,                     /* bitpos.  */
+        complain_overflow_dont, /* complain_on_overflow.  */
+        bfd_elf_generic_reloc, /* special_function.  */
+        "R_unusedb",           /* name.  */
+        FALSE,                 /* partial_inplace.  */
+        0,                     /* src_mask.  */
+        0,                     /* dst_mask.  */
+        FALSE),                /* pcrel_offset.  */
+
+  HOWTO (R_unusedc,            /* type.  */
+        0,                     /* rightshift.  */
+        2,                     /* size (0 = byte, 1 = short, 2 = long).  */
+        32,                    /* bitsize.  */
+        FALSE,                 /* pc_relative.  */
+        0,                     /* bitpos.  */
+        complain_overflow_dont, /* complain_on_overflow.  */
+        bfd_elf_generic_reloc, /* special_function.  */
+        "R_unusedc",           /* name.  */
+        FALSE,                 /* partial_inplace.  */
+        0,                     /* src_mask.  */
+        0,                     /* dst_mask.  */
+        FALSE),                /* pcrel_offset.  */
+
+  HOWTO (R_pcrel24_jump_l,     /* type.  */
+        1,                     /* rightshift.  */
+        2,                     /* size (0 = byte, 1 = short, 2 = long).  */
+        24,                    /* bitsize.  */
+        TRUE,                  /* pc_relative.  */
+        0,                     /* bitpos.  */
+        complain_overflow_signed, /* complain_on_overflow.  */
+        bfin_pcrel24_reloc,    /* special_function.  */
+        "R_pcrel24_jump_l",    /* name.  */
+        FALSE,                 /* partial_inplace.  */
+        0x00FFFFFF,            /* src_mask.  */
+        0x00FFFFFF,            /* dst_mask.  */
+        TRUE),                 /* pcrel_offset.  */
+
+  HOWTO (R_pcrel24_call_x,     /* type.  */
+        1,                     /* rightshift.  */
+        2,                     /* size (0 = byte, 1 = short, 2 = long).  */
+        24,                    /* bitsize.  */
+        TRUE,                  /* pc_relative.  */
+        0,                     /* bitpos.  */
+        complain_overflow_signed, /* complain_on_overflow.  */
+        bfin_pcrel24_reloc,    /* special_function.  */
+        "R_pcrel24_call_x",    /* name.  */
+        FALSE,                 /* partial_inplace.  */
+        0x00FFFFFF,            /* src_mask.  */
+        0x00FFFFFF,            /* dst_mask.  */
+        TRUE),                 /* pcrel_offset.  */
+
+  HOWTO (R_var_eq_symb,                /* type.  */
+        0,                     /* rightshift.  */
+        2,                     /* size (0 = byte, 1 = short, 2 = long).  */
+        32,                    /* bitsize.  */
+        FALSE,                 /* pc_relative.  */
+        0,                     /* bitpos.  */
+        complain_overflow_bitfield, /* complain_on_overflow.  */
+        bfin_bfd_reloc,        /* special_function.  */
+        "R_var_eq_symb",               /* name.  */
+        FALSE,                 /* partial_inplace.  */
+        0,                     /* src_mask.  */
+        0,                     /* dst_mask.  */
+        FALSE),                /* pcrel_offset.  */
+
+  HOWTO (R_byte_data,          /* type.  */
+        0,                     /* rightshift.  */
+        0,                     /* size (0 = byte, 1 = short, 2 = long).  */
+        8,                     /* bitsize.  */
+        FALSE,                 /* pc_relative.  */
+        0,                     /* bitpos.  */
+        complain_overflow_unsigned, /* complain_on_overflow.  */
+        bfin_bfd_reloc,        /* special_function.  */
+        "R_byte_data",         /* name.  */
+        FALSE,                 /* partial_inplace.  */
+        0xFF,                  /* src_mask.  */
+        0xFF,                  /* dst_mask.  */
+        TRUE),                 /* pcrel_offset.  */
+
+  HOWTO (R_byte2_data,         /* type.  */
+        0,                     /* rightshift.  */
+        1,                     /* size (0 = byte, 1 = short, 2 = long).  */
+        16,                    /* bitsize.  */
+        FALSE,                 /* pc_relative.  */
+        0,                     /* bitpos.  */
+        complain_overflow_signed, /* complain_on_overflow.  */
+        bfin_bfd_reloc,        /* special_function.  */
+        "R_byte2_data",        /* name.  */
+        FALSE,                 /* partial_inplace.  */
+        0xFFFF,                /* src_mask.  */
+        0xFFFF,                /* dst_mask.  */
+        TRUE),                 /* pcrel_offset.  */
+
+  HOWTO (R_byte4_data,         /* type.  */
+        0,                     /* rightshift.  */
+        2,                     /* size (0 = byte, 1 = short, 2 = long).  */
+        32,                    /* bitsize.  */
+        FALSE,                 /* pc_relative.  */
+        0,                     /* bitpos.  */
+        complain_overflow_unsigned, /* complain_on_overflow.  */
+        bfin_byte4_reloc,      /* special_function.  */
+        "R_byte4_data",        /* name.  */
+        FALSE,                 /* partial_inplace.  */
+        0xFFFFFFFF,            /* src_mask.  */
+        0xFFFFFFFF,            /* dst_mask.  */
+        TRUE),                 /* pcrel_offset.  */
+
+  HOWTO (R_pcrel11,            /* type.  */
+        1,                     /* rightshift.  */
+        1,                     /* size (0 = byte, 1 = short, 2 = long).  */
+        10,                    /* bitsize.  */
+        TRUE,                  /* pc_relative.  */
+        0,                     /* bitpos.  */
+        complain_overflow_unsigned, /* complain_on_overflow.  */
+        bfin_bfd_reloc,        /* special_function.  */
+        "R_pcrel11",           /* name.  */
+        FALSE,                 /* partial_inplace.  */
+        0x000003FF,            /* src_mask.  */
+        0x000003FF,            /* dst_mask.  */
+        FALSE),                /* pcrel_offset.  */
+};
+
+static reloc_howto_type bfin_areloc_howto_table [] =
+{
+  HOWTO (R_push,
+        0,
+        2,
+        0,
+        FALSE,
+        0,
+        complain_overflow_dont,
+        bfin_push_reloc,
+        "R_expst_push",
+        FALSE,
+        0,
+        0,
+        FALSE),
+
+  HOWTO (R_const,
+        0,
+        2,
+        0,
+        FALSE,
+        0,
+        complain_overflow_dont,
+        bfin_const_reloc,
+        "R_expst_const",
+        FALSE,
+        0,
+        0,
+        FALSE),
+
+  HOWTO (R_add,
+        0,
+        0,
+        0,
+        FALSE,
+        0,
+        complain_overflow_dont,
+        bfin_oper_reloc,
+        "R_expst_add",
+        FALSE,
+        0,
+        0,
+        FALSE),
+
+  HOWTO (R_sub,
+        0,
+        0,
+        0,
+        FALSE,
+        0,
+        complain_overflow_dont,
+        bfin_oper_reloc,
+        "R_expst_sub",
+        FALSE,
+        0,
+        0,
+        FALSE),
+
+  HOWTO (R_mult,
+        0,
+        0,
+        0,
+        FALSE,
+        0,
+        complain_overflow_dont,
+        bfin_oper_reloc,
+        "R_expst_mult",
+        FALSE,
+        0,
+        0,
+        FALSE),
+
+  HOWTO (R_div,                        /* type.  */
+        0,                     /* rightshift.  */
+        0,                     /* size (0 = byte, 1 = short, 2 = long).  */
+        0,                     /* bitsize.  */
+        FALSE,                 /* pc_relative.  */
+        0,                     /* bitpos.  */
+        complain_overflow_dont, /* complain_on_overflow.  */
+        bfin_oper_reloc,       /* special_function.  */
+        "R_expst_div",         /* name.  */
+        FALSE,                 /* partial_inplace.  */
+        0,                     /* src_mask.  */
+        0,                     /* dst_mask.  */
+        FALSE),                /* pcrel_offset.  */
+
+  HOWTO (R_mod,                        /* type.  */
+        0,                     /* rightshift.  */
+        0,                     /* size (0 = byte, 1 = short, 2 = long).  */
+        0,                     /* bitsize.  */
+        FALSE,                 /* pc_relative.  */
+        0,                     /* bitpos.  */
+        complain_overflow_dont, /* complain_on_overflow.  */
+        bfin_oper_reloc,       /* special_function.  */
+        "R_expst_mod",         /* name.  */
+        FALSE,                 /* partial_inplace.  */
+        0,                     /* src_mask.  */
+        0,                     /* dst_mask.  */
+        FALSE),                /* pcrel_offset.  */
+
+  HOWTO (R_lshift,             /* type.  */
+        0,                     /* rightshift.  */
+        0,                     /* size (0 = byte, 1 = short, 2 = long).  */
+        0,                     /* bitsize.  */
+        FALSE,                 /* pc_relative.  */
+        0,                     /* bitpos.  */
+        complain_overflow_dont, /* complain_on_overflow.  */
+        bfin_oper_reloc,       /* special_function.  */
+        "R_expst_lshift",      /* name.  */
+        FALSE,                 /* partial_inplace.  */
+        0,                     /* src_mask.  */
+        0,                     /* dst_mask.  */
+        FALSE),                /* pcrel_offset.  */
+
+  HOWTO (R_rshift,             /* type.  */
+        0,                     /* rightshift.  */
+        0,                     /* size (0 = byte, 1 = short, 2 = long).  */
+        0,                     /* bitsize.  */
+        FALSE,                 /* pc_relative.  */
+        0,                     /* bitpos.  */
+        complain_overflow_dont, /* complain_on_overflow.  */
+        bfin_oper_reloc,       /* special_function.  */
+        "R_expst_rshift",      /* name.  */
+        FALSE,                 /* partial_inplace.  */
+        0,                     /* src_mask.  */
+        0,                     /* dst_mask.  */
+        FALSE),                /* pcrel_offset.  */
+
+  HOWTO (R_and,                        /* type.  */
+        0,                     /* rightshift.  */
+        0,                     /* size (0 = byte, 1 = short, 2 = long).  */
+        0,                     /* bitsize.  */
+        FALSE,                 /* pc_relative.  */
+        0,                     /* bitpos.  */
+        complain_overflow_dont, /* complain_on_overflow.  */
+        bfin_oper_reloc,       /* special_function.  */
+        "R_expst_and",         /* name.  */
+        FALSE,                 /* partial_inplace.  */
+        0,                     /* src_mask.  */
+        0,                     /* dst_mask.  */
+        FALSE),                /* pcrel_offset.  */
+
+  HOWTO (R_or,                 /* type.  */
+        0,                     /* rightshift.  */
+        0,                     /* size (0 = byte, 1 = short, 2 = long).  */
+        0,                     /* bitsize.  */
+        FALSE,                 /* pc_relative.  */
+        0,                     /* bitpos.  */
+        complain_overflow_dont, /* complain_on_overflow.  */
+        bfin_oper_reloc,       /* special_function.  */
+        "R_expst_or",          /* name.  */
+        FALSE,                 /* partial_inplace.  */
+        0,                     /* src_mask.  */
+        0,                     /* dst_mask.  */
+        FALSE),                /* pcrel_offset.  */
+
+  HOWTO (R_xor,                        /* type.  */
+        0,                     /* rightshift.  */
+        0,                     /* size (0 = byte, 1 = short, 2 = long).  */
+        0,                     /* bitsize.  */
+        FALSE,                 /* pc_relative.  */
+        0,                     /* bitpos.  */
+        complain_overflow_dont, /* complain_on_overflow.  */
+        bfin_oper_reloc,       /* special_function.  */
+        "R_expst_xor",         /* name.  */
+        FALSE,                 /* partial_inplace.  */
+        0,                     /* src_mask.  */
+        0,                     /* dst_mask.  */
+        FALSE),                /* pcrel_offset.  */
+
+  HOWTO (R_land,               /* type.  */
+        0,                     /* rightshift.  */
+        0,                     /* size (0 = byte, 1 = short, 2 = long).  */
+        0,                     /* bitsize.  */
+        FALSE,                 /* pc_relative.  */
+        0,                     /* bitpos.  */
+        complain_overflow_dont, /* complain_on_overflow.  */
+        bfin_oper_reloc,       /* special_function.  */
+        "R_expst_land",        /* name.  */
+        FALSE,                 /* partial_inplace.  */
+        0,                     /* src_mask.  */
+        0,                     /* dst_mask.  */
+        FALSE),                /* pcrel_offset.  */
+
+  HOWTO (R_lor,                        /* type.  */
+        0,                     /* rightshift.  */
+        0,                     /* size (0 = byte, 1 = short, 2 = long).  */
+        0,                     /* bitsize.  */
+        FALSE,                 /* pc_relative.  */
+        0,                     /* bitpos.  */
+        complain_overflow_dont, /* complain_on_overflow.  */
+        bfin_oper_reloc,       /* special_function.  */
+        "R_expst_lor",         /* name.  */
+        FALSE,                 /* partial_inplace.  */
+        0,                     /* src_mask.  */
+        0,                     /* dst_mask.  */
+        FALSE),                /* pcrel_offset.  */
+
+  HOWTO (R_len,                        /* type.  */
+        0,                     /* rightshift.  */
+        0,                     /* size (0 = byte, 1 = short, 2 = long).  */
+        0,                     /* bitsize.  */
+        FALSE,                 /* pc_relative.  */
+        0,                     /* bitpos.  */
+        complain_overflow_dont, /* complain_on_overflow.  */
+        bfin_oper_reloc,       /* special_function.  */
+        "R_expst_len",         /* name.  */
+        FALSE,                 /* partial_inplace.  */
+        0,                     /* src_mask.  */
+        0,                     /* dst_mask.  */
+        FALSE),                /* pcrel_offset.  */
+
+  HOWTO (R_neg,                        /* type.  */
+        0,                     /* rightshift.  */
+        0,                     /* size (0 = byte, 1 = short, 2 = long).  */
+        0,                     /* bitsize.  */
+        FALSE,                 /* pc_relative.  */
+        0,                     /* bitpos.  */
+        complain_overflow_dont, /* complain_on_overflow.  */
+        bfin_oper_reloc,       /* special_function.  */
+        "R_expst_neg",         /* name.  */
+        FALSE,                 /* partial_inplace.  */
+        0,                     /* src_mask.  */
+        0,                     /* dst_mask.  */
+        FALSE),                /* pcrel_offset.  */
+
+  HOWTO (R_comp,               /* type.  */
+        0,                     /* rightshift.  */
+        0,                     /* size (0 = byte, 1 = short, 2 = long).  */
+        0,                     /* bitsize.  */
+        FALSE,                 /* pc_relative.  */
+        0,                     /* bitpos.  */
+        complain_overflow_dont, /* complain_on_overflow.  */
+        bfin_oper_reloc,       /* special_function.  */
+        "R_expst_comp",        /* name.  */
+        FALSE,                 /* partial_inplace.  */
+        0,                     /* src_mask.  */
+        0,                     /* dst_mask.  */
+        FALSE),                /* pcrel_offset.  */
+  
+  HOWTO (R_page,               /* type.  */
+        0,                     /* rightshift.  */
+        0,                     /* size (0 = byte, 1 = short, 2 = long).  */
+        0,                     /* bitsize.  */
+        FALSE,                 /* pc_relative.  */
+        0,                     /* bitpos.  */
+        complain_overflow_dont, /* complain_on_overflow.  */
+        bfin_oper_reloc,       /* special_function.  */
+        "R_expst_page",        /* name.  */
+        FALSE,                 /* partial_inplace.  */
+        0,                     /* src_mask.  */
+        0,                     /* dst_mask.  */
+        FALSE),                /* pcrel_offset.  */
+  
+  HOWTO (R_hwpage,             /* type.  */
+        0,                     /* rightshift.  */
+        0,                     /* size (0 = byte, 1 = short, 2 = long).  */
+        0,                     /* bitsize.  */
+        FALSE,                 /* pc_relative.  */
+        0,                     /* bitpos.  */
+        complain_overflow_dont, /* complain_on_overflow.  */
+        bfin_oper_reloc,       /* special_function.  */
+        "R_expst_hwpage",      /* name.  */
+        FALSE,                 /* partial_inplace.  */
+        0,                     /* src_mask.  */
+        0,                     /* dst_mask.  */
+        FALSE),                /* pcrel_offset.  */
+  
+  HOWTO (R_addr,               /* type.  */
+        0,                     /* rightshift.  */
+        0,                     /* size (0 = byte, 1 = short, 2 = long).  */
+        0,                     /* bitsize.  */
+        FALSE,                 /* pc_relative.  */
+        0,                     /* bitpos.  */
+        complain_overflow_dont, /* complain_on_overflow.  */
+        bfin_oper_reloc,       /* special_function.  */
+        "R_expst_addr",        /* name.  */
+        FALSE,                 /* partial_inplace.  */
+        0,                     /* src_mask.  */
+        0,                     /* dst_mask.  */
+        FALSE),                /* pcrel_offset.  */
+};
+
+static reloc_howto_type bfin_gnuext_howto_table [] =
+{
+  HOWTO (R_pltpc,              /* type.  */
+        0,                     /* rightshift.  */
+        1,                     /* size (0 = byte, 1 = short, 2 = long).  */
+        16,                    /* bitsize.  */
+        FALSE,                 /* pc_relative.  */
+        0,                     /* bitpos.  */
+        complain_overflow_bitfield, /* complain_on_overflow.  */
+        bfin_pltpc_reloc,      /* special_function.  */
+        "R_pltpc",             /* name.  */
+        FALSE,                 /* partial_inplace.  */
+        0xffff,                /* src_mask.  */
+        0xffff,                /* dst_mask.  */
+        FALSE),                /* pcrel_offset.  */
+
+  HOWTO (R_got,                        /* type.  */
+        0,                     /* rightshift.  */
+        1,                     /* size (0 = byte, 1 = short, 2 = long).  */
+        16,                    /* bitsize.  */
+        FALSE,                 /* pc_relative.  */
+        0,                     /* bitpos.  */
+        complain_overflow_bitfield, /* complain_on_overflow.  */
+        bfd_elf_generic_reloc, /* special_function.  */
+        "R_got",               /* name.  */
+        FALSE,                 /* partial_inplace.  */
+        0x7fff,                /* src_mask.  */
+        0x7fff,                /* dst_mask.  */
+        FALSE),                /* pcrel_offset.  */
+
+/* GNU extension to record C++ vtable hierarchy.  */
+  HOWTO (R_BFIN_GNU_VTINHERIT, /* type.  */
+         0,                     /* rightshift.  */
+         2,                     /* size (0 = byte, 1 = short, 2 = long).  */
+         0,                     /* bitsize.  */
+         FALSE,                 /* pc_relative.  */
+         0,                     /* bitpos.  */
+         complain_overflow_dont, /* complain_on_overflow.  */
+         NULL,                  /* special_function.  */
+         "R_BFIN_GNU_VTINHERIT", /* name.  */
+         FALSE,                 /* partial_inplace.  */
+         0,                     /* src_mask.  */
+         0,                     /* dst_mask.  */
+         FALSE),                /* pcrel_offset.  */
+
+/* GNU extension to record C++ vtable member usage.  */
+  HOWTO (R_BFIN_GNU_VTENTRY,   /* type.  */
+         0,                     /* rightshift.  */
+         2,                     /* size (0 = byte, 1 = short, 2 = long).  */
+         0,                     /* bitsize.  */
+         FALSE,                 /* pc_relative.  */
+         0,                    /* bitpos.  */
+         complain_overflow_dont, /* complain_on_overflow.  */
+         _bfd_elf_rel_vtable_reloc_fn, /* special_function.  */
+         "R_BFIN_GNU_VTENTRY", /* name.  */
+         FALSE,                 /* partial_inplace.  */
+         0,                     /* src_mask.  */
+         0,                     /* dst_mask.  */
+         FALSE)                 /* pcrel_offset.  */
+};
+
+struct bfin_reloc_map
+{
+  bfd_reloc_code_real_type     bfd_reloc_val;
+  unsigned int                 bfin_reloc_val;
+};
+
+static const struct bfin_reloc_map bfin_reloc_map [] =
+{
+  { BFD_RELOC_NONE,                    R_unused0 },
+  { BFD_RELOC_BFIN_5_PCREL,            R_pcrel5m2 },
+  { BFD_RELOC_NONE,                    R_unused1 },
+  { BFD_RELOC_BFIN_10_PCREL,           R_pcrel10 },
+  { BFD_RELOC_BFIN_12_PCREL_JUMP,      R_pcrel12_jump },
+  { BFD_RELOC_BFIN_16_IMM,             R_rimm16 },
+  { BFD_RELOC_BFIN_16_LOW,             R_luimm16 },
+  { BFD_RELOC_BFIN_16_HIGH,            R_huimm16 },
+  { BFD_RELOC_BFIN_12_PCREL_JUMP_S,    R_pcrel12_jump_s },
+  { BFD_RELOC_24_PCREL,                        R_pcrel24 },
+  { BFD_RELOC_24_PCREL,                        R_pcrel24 },
+  { BFD_RELOC_BFIN_24_PCREL_JUMP_L,    R_pcrel24_jump_l },
+  { BFD_RELOC_NONE,                    R_unusedb },
+  { BFD_RELOC_NONE,                    R_unusedc },
+  { BFD_RELOC_BFIN_24_PCREL_CALL_X,    R_pcrel24_call_x },
+  { BFD_RELOC_8,                       R_byte_data },
+  { BFD_RELOC_16,                      R_byte2_data },
+  { BFD_RELOC_32,                      R_byte4_data },
+  { BFD_RELOC_BFIN_11_PCREL,           R_pcrel11 },
+  { BFD_RELOC_BFIN_GOT,                        R_got },
+  { BFD_RELOC_BFIN_PLTPC,              R_pltpc },
+  { BFD_RELOC_VTABLE_INHERIT,          R_BFIN_GNU_VTINHERIT },
+  { BFD_RELOC_VTABLE_ENTRY,            R_BFIN_GNU_VTENTRY },
+  { BFD_ARELOC_BFIN_PUSH,              R_push },
+  { BFD_ARELOC_BFIN_CONST,             R_const },
+  { BFD_ARELOC_BFIN_ADD,               R_add },
+  { BFD_ARELOC_BFIN_SUB,               R_sub },
+  { BFD_ARELOC_BFIN_MULT,              R_mult },
+  { BFD_ARELOC_BFIN_DIV,               R_div },
+  { BFD_ARELOC_BFIN_MOD,               R_mod },
+  { BFD_ARELOC_BFIN_LSHIFT,            R_lshift },
+  { BFD_ARELOC_BFIN_RSHIFT,            R_rshift },
+  { BFD_ARELOC_BFIN_AND,               R_and },
+  { BFD_ARELOC_BFIN_OR,                        R_or },
+  { BFD_ARELOC_BFIN_XOR,               R_xor },
+  { BFD_ARELOC_BFIN_LAND,              R_land },
+  { BFD_ARELOC_BFIN_LOR,               R_lor },
+  { BFD_ARELOC_BFIN_LEN,               R_len },
+  { BFD_ARELOC_BFIN_NEG,               R_neg },
+  { BFD_ARELOC_BFIN_COMP,              R_comp },
+  { BFD_ARELOC_BFIN_PAGE,              R_page },
+  { BFD_ARELOC_BFIN_HWPAGE,            R_hwpage },
+  { BFD_ARELOC_BFIN_ADDR,              R_addr }
+
+};
+
+
+static void
+bfin_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
+                    arelent *cache_ptr,
+                    Elf_Internal_Rela *dst)
+{
+  unsigned int r_type;
+
+  r_type = ELF32_R_TYPE (dst->r_info);
+
+  if (r_type <= BFIN_RELOC_MAX)
+    cache_ptr->howto = &bfin_howto_table [r_type];
+
+  else if (r_type >= BFIN_ARELOC_MIN && r_type <= BFIN_ARELOC_MAX)
+    cache_ptr->howto = &bfin_areloc_howto_table [r_type - BFIN_ARELOC_MIN];
+
+  else if (r_type >= BFIN_GNUEXT_RELOC_MIN && r_type <= BFIN_GNUEXT_RELOC_MAX)
+    cache_ptr->howto = &bfin_gnuext_howto_table [r_type - BFIN_GNUEXT_RELOC_MIN];
+
+  else
+    cache_ptr->howto = (reloc_howto_type *) NULL;
+
+}
+/* Given a BFD reloc type, return the howto.  */
+static reloc_howto_type *
+bfin_bfd_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
+                           bfd_reloc_code_real_type code)
+{
+  unsigned int i;
+  unsigned int r_type = BFIN_RELOC_MIN;
+
+  for (i = sizeof (bfin_reloc_map) / sizeof (bfin_reloc_map[0]); --i;)
+    if (bfin_reloc_map[i].bfd_reloc_val == code)
+      r_type = bfin_reloc_map[i].bfin_reloc_val;
+
+  if (r_type <= BFIN_RELOC_MAX && r_type > BFIN_RELOC_MIN)
+    return &bfin_howto_table [r_type];
+
+  else if (r_type >= BFIN_ARELOC_MIN && r_type <= BFIN_ARELOC_MAX)
+   return &bfin_areloc_howto_table [r_type - BFIN_ARELOC_MIN];
+
+  else if (r_type >= BFIN_GNUEXT_RELOC_MIN && r_type <= BFIN_GNUEXT_RELOC_MAX)
+   return &bfin_gnuext_howto_table [r_type - BFIN_GNUEXT_RELOC_MIN];
+
+  return (reloc_howto_type *) NULL;
+
+}
+/* Given a bfin relocation type, return the howto.  */
+static reloc_howto_type *
+bfin_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
+                           unsigned int r_type)
+{
+  if (r_type <= BFIN_RELOC_MAX)
+    return &bfin_howto_table [r_type];
+
+  else if (r_type >= BFIN_ARELOC_MIN && r_type <= BFIN_ARELOC_MAX)
+   return &bfin_areloc_howto_table [r_type - BFIN_ARELOC_MIN];
+
+  else if (r_type >= BFIN_GNUEXT_RELOC_MIN && r_type <= BFIN_GNUEXT_RELOC_MAX)
+   return &bfin_gnuext_howto_table [r_type - BFIN_GNUEXT_RELOC_MIN];
+
+  return (reloc_howto_type *) NULL;
+
+}
+
+/* Return TRUE if the name is a local label.
+   bfin local labels begin with L$.  */
+static bfd_boolean
+bfin_is_local_label_name (
+     bfd *abfd ATTRIBUTE_UNUSED,
+     const char *label)
+{
+  if (label[0] == 'L' && label[1] == '$' )
+    return TRUE;
+
+  return _bfd_elf_is_local_label_name (abfd, label);
+}
+
+
+/* Look through the relocs for a section during the first phase, and
+   allocate space in the global offset table or procedure linkage
+   table.  */
+
+static bfd_boolean
+bfin_check_relocs (bfd * abfd,
+                  struct bfd_link_info *info,
+                  asection *sec,
+                   const Elf_Internal_Rela *relocs)
+{
+  bfd *dynobj;
+  Elf_Internal_Shdr *symtab_hdr;
+  struct elf_link_hash_entry **sym_hashes;
+  bfd_signed_vma *local_got_refcounts;
+  const Elf_Internal_Rela *rel;
+  const Elf_Internal_Rela *rel_end;
+  asection *sgot;
+  asection *srelgot;
+  asection *sreloc;
+  if (info->relocatable)
+    return TRUE;
+
+  dynobj = elf_hash_table (info)->dynobj;
+  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+  sym_hashes = elf_sym_hashes (abfd);
+  local_got_refcounts = elf_local_got_refcounts (abfd);
+
+  sgot = NULL;
+  srelgot = NULL;
+  sreloc = NULL;
+
+  rel_end = relocs + sec->reloc_count;
+  for (rel = relocs; rel < rel_end; rel++)
+    {
+      unsigned long r_symndx;
+      struct elf_link_hash_entry *h;
+
+      r_symndx = ELF32_R_SYM (rel->r_info);
+      if (r_symndx < symtab_hdr->sh_info)
+       h = NULL;
+      else
+       h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+
+      switch (ELF32_R_TYPE (rel->r_info))
+       {
+       /* This relocation describes the C++ object vtable hierarchy.
+           Reconstruct it for later use during GC.  */
+        case R_BFIN_GNU_VTINHERIT:
+          if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
+            return FALSE;
+          break;
+
+        /* This relocation describes which C++ vtable entries
+           are actually used.  Record for later use during GC.  */
+        case R_BFIN_GNU_VTENTRY:
+          if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
+            return FALSE;
+          break;
+
+       case R_got:
+         if (h != NULL
+             && strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
+           break;
+         /* Fall through.  */
+
+         if (dynobj == NULL)
+           {
+             /* Create the .got section.  */
+             elf_hash_table (info)->dynobj = dynobj = abfd;
+             if (!_bfd_elf_create_got_section (dynobj, info))
+               return FALSE;
+           }
+
+         if (sgot == NULL)
+           {
+             sgot = bfd_get_section_by_name (dynobj, ".got");
+             BFD_ASSERT (sgot != NULL);
+           }
+
+         if (srelgot == NULL && (h != NULL || info->shared))
+           {
+             srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
+             if (srelgot == NULL)
+               {
+                 srelgot = bfd_make_section (dynobj, ".rela.got");
+                 if (srelgot == NULL
+                     || !bfd_set_section_flags (dynobj, srelgot,
+                                                (SEC_ALLOC
+                                                 | SEC_LOAD
+                                                 | SEC_HAS_CONTENTS
+                                                 | SEC_IN_MEMORY
+                                                 | SEC_LINKER_CREATED
+                                                 | SEC_READONLY))
+                     || !bfd_set_section_alignment (dynobj, srelgot, 2))
+                   return FALSE;
+               }
+           }
+
+         if (h != NULL)
+           {
+             if (h->got.refcount == 0)
+               {
+                 /* Make sure this symbol is output as a dynamic symbol.  */
+                 if (h->dynindx == -1 && !h->forced_local)
+                   {
+                     if (!bfd_elf_link_record_dynamic_symbol (info, h))
+                       return FALSE;
+                   }
+
+                 /* Allocate space in the .got section.  */
+                 sgot->size += 4;
+                 /* Allocate relocation space.  */
+                 srelgot->size += sizeof (Elf32_External_Rela);
+               }
+             h->got.refcount++;
+           }
+         else
+           {
+             /* This is a global offset table entry for a local symbol.  */
+             if (local_got_refcounts == NULL)
+               {
+                 bfd_size_type size;
+
+                 size = symtab_hdr->sh_info;
+                 size *= sizeof (bfd_signed_vma);
+                 local_got_refcounts = ((bfd_signed_vma *)
+                                        bfd_zalloc (abfd, size));
+                 if (local_got_refcounts == NULL)
+                   return FALSE;
+                 elf_local_got_refcounts (abfd) = local_got_refcounts;
+               }
+             if (local_got_refcounts[r_symndx] == 0)
+               {
+                 sgot->size += 4;
+                 if (info->shared)
+                   {
+                     /* If we are generating a shared object, we need to
+                        output a R_68K_RELATIVE reloc so that the dynamic
+                        linker can adjust this GOT entry.  */
+                     srelgot->size += sizeof (Elf32_External_Rela);
+                   }
+               }
+             local_got_refcounts[r_symndx]++;
+           }
+         break;
+
+       default:
+         break;
+       }
+    }
+
+  return TRUE;
+}
+
+static enum elf_reloc_type_class
+elf32_bfin_reloc_type_class (const Elf_Internal_Rela * rela)
+{
+  switch ((int) ELF32_R_TYPE (rela->r_info))
+    {
+    default:
+      return reloc_class_normal;
+    }
+}
+static bfd_boolean
+bfin_relocate_section (bfd * output_bfd,
+                      struct bfd_link_info *info,
+                      bfd * input_bfd,
+                      asection * input_section,
+                      bfd_byte * contents,
+                      Elf_Internal_Rela * relocs,
+                      Elf_Internal_Sym * local_syms,
+                      asection ** local_sections)
+{
+  bfd *dynobj;
+  Elf_Internal_Shdr *symtab_hdr;
+  struct elf_link_hash_entry **sym_hashes;
+  bfd_vma *local_got_offsets;
+  asection *sgot;
+  asection *sreloc;
+  Elf_Internal_Rela *rel;
+  Elf_Internal_Rela *relend;
+  char *error_msg = NULL;
+  int i = 0;
+
+  if (info->relocatable)
+    return TRUE;
+
+  dynobj = elf_hash_table (info)->dynobj;
+  symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
+  sym_hashes = elf_sym_hashes (input_bfd);
+  local_got_offsets = elf_local_got_offsets (input_bfd);
+
+  sgot = NULL;
+  sreloc = NULL;
+
+  rel = relocs;
+  relend = relocs + input_section->reloc_count;
+  for (; rel < relend; rel++, i++)
+    {
+      int r_type;
+      reloc_howto_type *howto;
+      unsigned long r_symndx;
+      struct elf_link_hash_entry *h;
+      Elf_Internal_Sym *sym;
+      asection *sec;
+      bfd_vma relocation = 0;
+      bfd_boolean unresolved_reloc;
+      bfd_reloc_status_type r;
+
+      r_type = ELF32_R_TYPE (rel->r_info);
+      if (r_type < 0 || r_type >= 243)
+       {
+         bfd_set_error (bfd_error_bad_value);
+         return FALSE;
+       }
+
+      if (r_type == R_BFIN_GNU_VTENTRY
+          || r_type == R_BFIN_GNU_VTINHERIT)
+       continue;
+
+      howto = bfin_reloc_type_lookup (input_bfd, r_type);
+      if (howto == NULL)
+       {
+         bfd_set_error (bfd_error_bad_value);
+         return FALSE;
+       }
+      r_symndx = ELF32_R_SYM (rel->r_info);
+
+      h = NULL;
+      sym = NULL;
+      sec = NULL;
+      unresolved_reloc = FALSE;
+
+      if (r_symndx < symtab_hdr->sh_info)
+       {
+         sym = local_syms + r_symndx;
+         sec = local_sections[r_symndx];
+         relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
+         /* Call to bfd_elf_rela_local_sym would have CHANGED the sec
+             as well as updated relocation. The value returned is
+             w.r.t the original section.  */
+         sec = local_sections[r_symndx];
+       }
+      else
+       {
+         h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+
+         while (h->root.type == bfd_link_hash_indirect
+                || h->root.type == bfd_link_hash_warning)
+           h = (struct elf_link_hash_entry *) h->root.u.i.link;
+
+         if (!
+             (!strcmp (h->root.root.string, ".__constant")
+              || !strcmp (h->root.root.string, ".__operator")))
+           {
+             bfd_boolean warned;
+             h = NULL;
+             RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+                                      r_symndx, symtab_hdr, sym_hashes,
+                                      h, sec, relocation,
+                                      unresolved_reloc, warned);
+
+           }
+       }
+
+      switch (r_type)
+       {
+       case R_BFIN_GNU_VTINHERIT:
+       case R_BFIN_GNU_VTENTRY:
+         return bfd_reloc_ok;
+
+       case R_got:
+         /* Relocation is to the address of the entry for this symbol
+            in the global offset table.  */
+         if (h != NULL
+             && strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
+           break;
+         /* Fall through.  */
+         /* Relocation is the offset of the entry for this symbol in
+            the global offset table.  */
+
+         {
+           bfd_vma off;
+
+           if (sgot == NULL)
+             {
+               sgot = bfd_get_section_by_name (dynobj, ".got");
+               BFD_ASSERT (sgot != NULL);
+             }
+
+           if (h != NULL)
+             {
+               bfd_boolean dyn;
+
+               off = h->got.offset;
+               BFD_ASSERT (off != (bfd_vma) - 1);
+
+               dyn = elf_hash_table (info)->dynamic_sections_created;
+               if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h)
+                   || (info->shared
+                       && (info->symbolic
+                           || h->dynindx == -1
+                           || h->forced_local) && h->def_regular))
+                 {
+                   /* This is actually a static link, or it is a
+                      -Bsymbolic link and the symbol is defined
+                      locally, or the symbol was forced to be local
+                      because of a version file..  We must initialize
+                      this entry in the global offset table.  Since
+                      the offset must always be a multiple of 4, we
+                      use the least significant bit to record whether
+                      we have initialized it already.
+
+                      When doing a dynamic link, we create a .rela.got
+                      relocation entry to initialize the value.  This
+                      is done in the finish_dynamic_symbol routine.  */
+                   if ((off & 1) != 0)
+                     off &= ~1;
+                   else
+                     {
+                       bfd_put_32 (output_bfd, relocation,
+                                   sgot->contents + off);
+                       h->got.offset |= 1;
+                     }
+                 }
+               else
+                 unresolved_reloc = FALSE;
+             }
+           else
+             {
+               BFD_ASSERT (local_got_offsets != NULL
+                           && local_got_offsets[r_symndx] != (bfd_vma) - 1);
+
+               off = local_got_offsets[r_symndx];
+
+               /* The offset must always be a multiple of 4.  We use
+                  the least significant bit to record whether we have
+                  already generated the necessary reloc.  */
+               if ((off & 1) != 0)
+                 off &= ~1;
+               else
+                 {
+
+                   bfd_put_32 (output_bfd, relocation, sgot->contents + off);
+
+                   if (info->shared)
+                     {
+                       asection *s;
+                       Elf_Internal_Rela outrel;
+                       bfd_byte *loc;
+
+                       s = bfd_get_section_by_name (dynobj, ".rela.got");
+                       BFD_ASSERT (s != NULL);
+
+                       outrel.r_offset = (sgot->output_section->vma
+                                          + sgot->output_offset + off);
+                       outrel.r_info =
+                         ELF32_R_INFO (0, R_pcrel24);
+                       outrel.r_addend = relocation;
+                       loc = s->contents;
+                       loc +=
+                         s->reloc_count++ * sizeof (Elf32_External_Rela);
+                       bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
+                     }
+
+                   local_got_offsets[r_symndx] |= 1;
+                 }
+             }
+
+           relocation = sgot->output_offset + off;
+           rel->r_addend = 0;
+            /* bfin : preg = [preg + 17bitdiv4offset] relocation is div by 4.  */
+            relocation /= 4;
+         }
+         break;
+
+       default:
+         if (howto->special_function)
+           {
+             bfd_reloc_status_type cont;
+             arelent reloc_ent;
+             asymbol symbol;
+             asymbol *symbol1;
+             symbol.flags = 0;
+             symbol.section = bfd_und_section_ptr;
+             symbol.value = 0;
+
+             if (h != NULL)
+               {
+                 if (unresolved_reloc)
+                   {
+                     break;
+                   }
+                 if (h->root.type != bfd_link_hash_undefweak
+                     && h->root.type != bfd_link_hash_undefined)
+                   {
+                     symbol.the_bfd = input_bfd;
+                     symbol.section = h->root.u.def.section;
+                     symbol.name = h->root.root.string;
+                     symbol.value = h->root.u.def.value;
+                   }
+                 if (h->root.type == bfd_link_hash_defweak
+                      || h->root.type == bfd_link_hash_undefweak)
+                   {
+                     symbol.name = h->root.root.string;
+                     symbol.flags |= BSF_WEAK;
+                   }
+               }
+             else
+               {
+                 symbol = *sec->symbol;
+               }
+             reloc_ent.address = rel->r_offset;
+             reloc_ent.howto = howto;
+             reloc_ent.addend = rel->r_addend;
+             symbol1 = &symbol;
+             reloc_ent.sym_ptr_ptr = &symbol1;
+
+             cont =
+               howto->special_function (input_bfd, &reloc_ent, &symbol,
+                                        contents, input_section,
+                                        info->
+                                        relocatable ? output_bfd : NULL,
+                                        &error_msg);
+             if (cont == bfd_reloc_ok)
+               {
+                 continue;
+               }
+           }
+         else
+           {
+             fprintf (stderr, "%s no special func r_type is %d\n",
+                      input_bfd->filename, r_type);
+             bfd_set_error (bfd_error_bad_value);
+             return FALSE;
+           }
+         break;
+       }
+
+      /* Dynamic relocs are not propagated for SEC_DEBUGGING sections
+         because such sections are not SEC_ALLOC and thus ld.so will
+         not process them.  */
+      if (unresolved_reloc
+         && !((input_section->flags & SEC_DEBUGGING) != 0 && h->def_dynamic))
+       {
+         (*_bfd_error_handler)
+           (_("%B(%A+0x%lx): unresolvable relocation against symbol `%s'"),
+            input_bfd,
+            input_section, (long) rel->r_offset, h->root.root.string);
+         return FALSE;
+       }
+
+      r = _bfd_final_link_relocate (howto, input_bfd, input_section,
+                                   contents, rel->r_offset,
+                                   relocation, rel->r_addend);
+
+      if (r != bfd_reloc_ok)
+       {
+         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 (r == bfd_reloc_overflow)
+           {
+             if (!(info->callbacks->reloc_overflow
+                   (info, (h ? &h->root : NULL), name, howto->name,
+                    (bfd_vma) 0, input_bfd, input_section, rel->r_offset)))
+               return FALSE;
+           }
+         else
+           {
+             (*_bfd_error_handler)
+               (_("%B(%A+0x%lx): reloc against `%s': error %d"),
+                input_bfd, input_section,
+                (long) rel->r_offset, name, (int) r);
+             return FALSE;
+           }
+       }
+    }
+
+  return TRUE;
+}
+
+static asection *
+bfin_gc_mark_hook (asection * sec,
+                  struct bfd_link_info *info ATTRIBUTE_UNUSED,
+                  Elf_Internal_Rela * rel,
+                  struct elf_link_hash_entry *h,
+                   Elf_Internal_Sym * sym)
+{
+  if (h != NULL)
+    {
+      switch (ELF32_R_TYPE (rel->r_info))
+       {
+
+       case R_BFIN_GNU_VTINHERIT:
+       case R_BFIN_GNU_VTENTRY:
+         break;
+
+       default:
+         switch (h->root.type)
+           {
+           default:
+             break;
+
+           case bfd_link_hash_defined:
+           case bfd_link_hash_defweak:
+             return h->root.u.def.section;
+
+           case bfd_link_hash_common:
+             return h->root.u.c.p->section;
+           }
+       }
+    }
+  else
+    return bfd_section_from_elf_index (sec->owner, sym->st_shndx);
+
+  return NULL;
+}
+
+
+/* Update the got entry reference counts for the section being removed.  */
+
+static bfd_boolean
+bfin_gc_sweep_hook (bfd * abfd,
+                   struct bfd_link_info *info,
+                   asection * sec,
+                    const Elf_Internal_Rela * relocs)
+{
+  Elf_Internal_Shdr *symtab_hdr;
+  struct elf_link_hash_entry **sym_hashes;
+  bfd_signed_vma *local_got_refcounts;
+  const Elf_Internal_Rela *rel, *relend;
+  bfd *dynobj;
+  asection *sgot;
+  asection *srelgot;
+
+  dynobj = elf_hash_table (info)->dynobj;
+  if (dynobj == NULL)
+    return TRUE;
+
+  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+  sym_hashes = elf_sym_hashes (abfd);
+  local_got_refcounts = elf_local_got_refcounts (abfd);
+
+  sgot = bfd_get_section_by_name (dynobj, ".got");
+  srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
+
+  relend = relocs + sec->reloc_count;
+  for (rel = relocs; rel < relend; rel++)
+    {
+      unsigned long r_symndx;
+      struct elf_link_hash_entry *h;
+
+      switch (ELF32_R_TYPE (rel->r_info))
+       {
+       case R_got:
+         r_symndx = ELF32_R_SYM (rel->r_info);
+         if (r_symndx >= symtab_hdr->sh_info)
+           {
+             h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+             if (h->got.refcount > 0)
+               {
+                 --h->got.refcount;
+                 if (h->got.refcount == 0)
+                   {
+                     /* We don't need the .got entry any more.  */
+                     sgot->size -= 4;
+                     srelgot->size -= sizeof (Elf32_External_Rela);
+                   }
+               }
+           }
+         else if (local_got_refcounts != NULL)
+           {
+             if (local_got_refcounts[r_symndx] > 0)
+               {
+                 --local_got_refcounts[r_symndx];
+                 if (local_got_refcounts[r_symndx] == 0)
+                   {
+                     /* We don't need the .got entry any more.  */
+                     sgot->size -= 4;
+                     if (info->shared)
+                       srelgot->size -= sizeof (Elf32_External_Rela);
+                   }
+               }
+           }
+         break;
+       default:
+         break;
+       }
+    }
+
+  return TRUE;
+}
+
+
+/* Merge backend specific data from an object file to the output
+   object file when linking.  */
+static bfd_boolean
+elf32_bfin_merge_private_bfd_data (bfd * ibfd, bfd * obfd)
+{
+  flagword out_flags;
+  flagword in_flags;
+
+  if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
+      || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
+    return TRUE;
+
+  in_flags = elf_elfheader (ibfd)->e_flags;
+  out_flags = elf_elfheader (obfd)->e_flags;
+
+  if (!elf_flags_init (obfd))
+    {
+      elf_flags_init (obfd) = TRUE;
+      elf_elfheader (obfd)->e_flags = in_flags;
+    }
+
+  return TRUE;
+}
+
+
+static bfd_boolean
+elf32_bfin_set_private_flags (bfd * abfd, flagword flags)
+{
+  elf_elfheader (abfd)->e_flags = flags;
+  elf_flags_init (abfd) = TRUE;
+  return TRUE;
+}
+
+
+/* Display the flags field.  */
+static bfd_boolean
+elf32_bfin_print_private_bfd_data (bfd * abfd, PTR ptr)
+{
+  FILE *file = (FILE *) ptr;
+
+  BFD_ASSERT (abfd != NULL && ptr != NULL);
+
+  /* Print normal ELF private data.  */
+  _bfd_elf_print_private_bfd_data (abfd, ptr);
+
+  /* Ignore init flag - it may not be set, despite the flags field
+     containing valid data.  */
+
+  /* xgettext:c-format */
+  fprintf (file, _("private flags = %lx:"), elf_elfheader (abfd)->e_flags);
+
+  fputc ('\n', file);
+
+  return TRUE;
+}
+
+/* bfin ELF linker hash entry.  */
+
+struct bfin_link_hash_entry
+{
+  struct elf_link_hash_entry root;
+
+  /* Number of PC relative relocs copied for this symbol.  */
+  struct bfin_pcrel_relocs_copied *pcrel_relocs_copied;
+};
+
+/* bfin ELF linker hash table.  */
+
+struct bfin_link_hash_table
+{
+  struct elf_link_hash_table root;
+
+  /* Small local sym to section mapping cache.  */
+  struct sym_sec_cache sym_sec;
+};
+
+#define bfin_hash_entry(ent) ((struct bfin_link_hash_entry *) (ent))
+
+static struct bfd_hash_entry *
+bfin_link_hash_newfunc (struct bfd_hash_entry *entry,
+                           struct bfd_hash_table *table, const char *string)
+{
+  struct bfd_hash_entry *ret = entry;
+
+  /* Allocate the structure if it has not already been allocated by a
+     subclass.  */
+  if (ret == NULL)
+    ret = bfd_hash_allocate (table, sizeof (struct bfin_link_hash_entry));
+  if (ret == NULL)
+    return ret;
+
+  /* Call the allocation method of the superclass.  */
+  ret = _bfd_elf_link_hash_newfunc (ret, table, string);
+  if (ret != NULL)
+    bfin_hash_entry (ret)->pcrel_relocs_copied = NULL;
+
+  return ret;
+}
+
+/* Create an bfin ELF linker hash table.  */
+
+static struct bfd_link_hash_table *
+bfin_link_hash_table_create (bfd * abfd)
+{
+  struct bfin_link_hash_table *ret;
+  bfd_size_type amt = sizeof (struct bfin_link_hash_table);
+
+  ret = (struct bfin_link_hash_table *) bfd_malloc (amt);
+  if (ret == (struct bfin_link_hash_table *) NULL)
+    return NULL;
+
+  if (!_bfd_elf_link_hash_table_init (&ret->root, abfd,
+                                     bfin_link_hash_newfunc))
+    {
+      free (ret);
+      return NULL;
+    }
+
+  ret->sym_sec.abfd = NULL;
+
+  return &ret->root.root;
+}
+
+/* The size in bytes of an entry in the procedure linkage table.  */
+
+/* Finish up the dynamic sections.  */
+
+static bfd_boolean
+bfin_finish_dynamic_sections (bfd * output_bfd ATTRIBUTE_UNUSED,
+                                 struct bfd_link_info *info)
+{
+  bfd *dynobj;
+  asection *sdyn;
+
+  dynobj = elf_hash_table (info)->dynobj;
+
+  sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
+
+  if (elf_hash_table (info)->dynamic_sections_created)
+    {
+      Elf32_External_Dyn *dyncon, *dynconend;
+
+      BFD_ASSERT (sdyn != NULL);
+
+      dyncon = (Elf32_External_Dyn *) sdyn->contents;
+      dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size);
+      for (; dyncon < dynconend; dyncon++)
+       {
+         Elf_Internal_Dyn dyn;
+
+         bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn);
+
+       }
+
+    }
+  return TRUE;
+}
+
+/* Finish up dynamic symbol handling.  We set the contents of various
+   dynamic sections here.  */
+
+static bfd_boolean
+bfin_finish_dynamic_symbol (bfd * output_bfd,
+                               struct bfd_link_info *info,
+                               struct elf_link_hash_entry *h,
+                               Elf_Internal_Sym * sym)
+{
+  bfd *dynobj;
+
+  dynobj = elf_hash_table (info)->dynobj;
+
+  if (h->got.offset != (bfd_vma) - 1)
+    {
+      asection *sgot;
+      asection *srela;
+      Elf_Internal_Rela rela;
+      bfd_byte *loc;
+
+      /* This symbol has an entry in the global offset table.
+         Set it up.  */
+
+      sgot = bfd_get_section_by_name (dynobj, ".got");
+      srela = bfd_get_section_by_name (dynobj, ".rela.got");
+      BFD_ASSERT (sgot != NULL && srela != NULL);
+
+      rela.r_offset = (sgot->output_section->vma
+                      + sgot->output_offset
+                      + (h->got.offset & ~(bfd_vma) 1));
+
+      /* If this is a -Bsymbolic link, and the symbol is defined
+         locally, we just want to emit a RELATIVE reloc.  Likewise if
+         the symbol was forced to be local because of a version file.
+         The entry in the global offset table will already have been
+         initialized in the relocate_section function.  */
+      if (info->shared
+         && (info->symbolic
+             || h->dynindx == -1 || h->forced_local) && h->def_regular)
+       {
+fprintf(stderr, "*** check this relocation %s\n", __FUNCTION__);
+         rela.r_info = ELF32_R_INFO (0, R_pcrel24);
+         rela.r_addend = bfd_get_signed_32 (output_bfd,
+                                            (sgot->contents
+                                             +
+                                             (h->got.
+                                              offset & ~(bfd_vma) 1)));
+       }
+      else
+       {
+         bfd_put_32 (output_bfd, (bfd_vma) 0,
+                     sgot->contents + (h->got.offset & ~(bfd_vma) 1));
+         rela.r_info = ELF32_R_INFO (h->dynindx, R_got);
+         rela.r_addend = 0;
+       }
+
+      loc = srela->contents;
+      loc += srela->reloc_count++ * sizeof (Elf32_External_Rela);
+      bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
+    }
+
+  if (h->needs_copy)
+    {
+      BFD_ASSERT (0);
+    }
+  /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute.  */
+  if (strcmp (h->root.root.string, "_DYNAMIC") == 0
+      || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
+    sym->st_shndx = SHN_ABS;
+
+  return TRUE;
+}
+
+/* Adjust a symbol defined by a dynamic object and referenced by a
+   regular object.  The current definition is in some section of the
+   dynamic object, but we're not including those sections.  We have to
+   change the definition to something the rest of the link can
+   understand.  */
+
+static bfd_boolean
+bfin_adjust_dynamic_symbol (struct bfd_link_info *info,
+                               struct elf_link_hash_entry *h)
+{
+  bfd *dynobj;
+  asection *s;
+  unsigned int power_of_two;
+
+  dynobj = elf_hash_table (info)->dynobj;
+
+  /* Make sure we know what is going on here.  */
+  BFD_ASSERT (dynobj != NULL
+             && (h->needs_plt
+                 || h->u.weakdef != NULL
+                 || (h->def_dynamic && h->ref_regular && !h->def_regular)));
+
+  /* If this is a function, put it in the procedure linkage table.  We
+     will fill in the contents of the procedure linkage table later,
+     when we know the address of the .got section.  */
+  if (h->type == STT_FUNC || h->needs_plt)
+    {
+      BFD_ASSERT(0);
+    }
+
+  /* If this is a weak symbol, and there is a real definition, the
+     processor independent code will have arranged for us to see the
+     real definition first, and we can just use the same value.  */
+  if (h->u.weakdef != NULL)
+    {
+      BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
+                 || h->u.weakdef->root.type == bfd_link_hash_defweak);
+      h->root.u.def.section = h->u.weakdef->root.u.def.section;
+      h->root.u.def.value = h->u.weakdef->root.u.def.value;
+      return TRUE;
+    }
+
+  /* This is a reference to a symbol defined by a dynamic object which
+     is not a function.  */
+
+  /* If we are creating a shared library, we must presume that the
+     only references to the symbol are via the global offset table.
+     For such cases we need not do anything here; the relocations will
+     be handled correctly by relocate_section.  */
+  if (info->shared)
+    return TRUE;
+
+  /* We must allocate the symbol in our .dynbss section, which will
+     become part of the .bss section of the executable.  There will be
+     an entry for this symbol in the .dynsym section.  The dynamic
+     object will contain position independent code, so all references
+     from the dynamic object to this symbol will go through the global
+     offset table.  The dynamic linker will use the .dynsym entry to
+     determine the address it must put in the global offset table, so
+     both the dynamic object and the regular object will refer to the
+     same memory location for the variable.  */
+
+  s = bfd_get_section_by_name (dynobj, ".dynbss");
+  BFD_ASSERT (s != NULL);
+
+  /* We must generate a R_68K_COPY reloc to tell the dynamic linker to
+     copy the initial value out of the dynamic object and into the
+     runtime process image.  We need to remember the offset into the
+     .rela.bss section we are going to use.  */
+  if ((h->root.u.def.section->flags & SEC_ALLOC) != 0)
+    {
+      asection *srel;
+
+      srel = bfd_get_section_by_name (dynobj, ".rela.bss");
+      BFD_ASSERT (srel != NULL);
+      srel->size += sizeof (Elf32_External_Rela);
+      h->needs_copy = 1;
+    }
+
+  /* We need to figure out the alignment required for this symbol.  I
+     have no idea how ELF linkers handle this.  */
+  power_of_two = bfd_log2 (h->size);
+  if (power_of_two > 3)
+    power_of_two = 3;
+
+  /* Apply the required alignment.  */
+  s->size = BFD_ALIGN (s->size, (bfd_size_type) (1 << power_of_two));
+  if (power_of_two > bfd_get_section_alignment (dynobj, s))
+    {
+      if (!bfd_set_section_alignment (dynobj, s, power_of_two))
+       return FALSE;
+    }
+
+  /* Define the symbol as being at this point in the section.  */
+  h->root.u.def.section = s;
+  h->root.u.def.value = s->size;
+
+  /* Increment the section size to make room for the symbol.  */
+  s->size += h->size;
+
+  return TRUE;
+}
+
+/* The bfin linker needs to keep track of the number of relocs that it
+   decides to copy in check_relocs for each symbol.  This is so that it
+   can discard PC relative relocs if it doesn't need them when linking
+   with -Bsymbolic.  We store the information in a field extending the
+   regular ELF linker hash table.  */
+
+/* This structure keeps track of the number of PC relative relocs we have
+   copied for a given symbol.  */
+
+struct bfin_pcrel_relocs_copied
+{
+  /* Next section.  */
+  struct bfin_pcrel_relocs_copied *next;
+  /* A section in dynobj.  */
+  asection *section;
+  /* Number of relocs copied in this section.  */
+  bfd_size_type count;
+};
+
+/* This function is called via elf_link_hash_traverse if we are
+   creating a shared object.  In the -Bsymbolic case it discards the
+   space allocated to copy PC relative relocs against symbols which
+   are defined in regular objects.  For the normal shared case, it
+   discards space for pc-relative relocs that have become local due to
+   symbol visibility changes.  We allocated space for them in the
+   check_relocs routine, but we won't fill them in in the
+   relocate_section routine.
+
+   We also check whether any of the remaining relocations apply
+   against a readonly section, and set the DF_TEXTREL flag in this
+   case.  */
+
+static bfd_boolean
+bfin_discard_copies (struct elf_link_hash_entry *h, PTR inf)
+{
+  struct bfd_link_info *info = (struct bfd_link_info *) inf;
+  struct bfin_pcrel_relocs_copied *s;
+
+  if (h->root.type == bfd_link_hash_warning)
+    h = (struct elf_link_hash_entry *) h->root.u.i.link;
+
+  if (!h->def_regular || (!info->symbolic && !h->forced_local))
+    {
+      if ((info->flags & DF_TEXTREL) == 0)
+       {
+         /* Look for relocations against read-only sections.  */
+         for (s = bfin_hash_entry (h)->pcrel_relocs_copied;
+              s != NULL; s = s->next)
+           if ((s->section->flags & SEC_READONLY) != 0)
+             {
+               info->flags |= DF_TEXTREL;
+               break;
+             }
+       }
+
+      return TRUE;
+    }
+
+  for (s = bfin_hash_entry (h)->pcrel_relocs_copied;
+       s != NULL; s = s->next)
+    s->section->size -= s->count * sizeof (Elf32_External_Rela);
+
+  return TRUE;
+}
+
+/* Set the sizes of the dynamic sections.  */
+#define ELF_DYNAMIC_INTERPRETER "/usr/lib/libc.so.1"
+
+static bfd_boolean
+bfin_size_dynamic_sections (bfd * output_bfd ATTRIBUTE_UNUSED,
+                               struct bfd_link_info *info)
+{
+  bfd *dynobj;
+  asection *s;
+  bfd_boolean relocs;
+
+  dynobj = elf_hash_table (info)->dynobj;
+  BFD_ASSERT (dynobj != NULL);
+
+  if (elf_hash_table (info)->dynamic_sections_created)
+    {
+      /* Set the contents of the .interp section to the interpreter.  */
+      if (info->executable)
+       {
+         s = bfd_get_section_by_name (dynobj, ".interp");
+         BFD_ASSERT (s != NULL);
+         s->size = sizeof ELF_DYNAMIC_INTERPRETER;
+         s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
+       }
+    }
+  else
+    {
+      /* We may have created entries in the .rela.got section.
+         However, if we are not creating the dynamic sections, we will
+         not actually use these entries.  Reset the size of .rela.got,
+         which will cause it to get stripped from the output file
+         below.  */
+      s = bfd_get_section_by_name (dynobj, ".rela.got");
+      if (s != NULL)
+       s->size = 0;
+    }
+
+  /* If this is a -Bsymbolic shared link, then we need to discard all
+     PC relative relocs against symbols defined in a regular object.
+     For the normal shared case we discard the PC relative relocs
+     against symbols that have become local due to visibility changes.
+     We allocated space for them in the check_relocs routine, but we
+     will not fill them in in the relocate_section routine.  */
+  if (info->shared)
+    elf_link_hash_traverse (elf_hash_table (info),
+                           bfin_discard_copies, (PTR) info);
+
+  /* The check_relocs and adjust_dynamic_symbol entry points have
+     determined the sizes of the various dynamic sections.  Allocate
+     memory for them.  */
+  relocs = FALSE;
+  for (s = dynobj->sections; s != NULL; s = s->next)
+    {
+      const char *name;
+      bfd_boolean strip;
+
+      if ((s->flags & SEC_LINKER_CREATED) == 0)
+       continue;
+
+      /* It's OK to base decisions on the section name, because none
+         of the dynobj section names depend upon the input files.  */
+      name = bfd_get_section_name (dynobj, s);
+
+      strip = FALSE;
+
+       if (strncmp (name, ".rela", 5) == 0)
+       {
+         if (s->size == 0)
+           {
+             /* If we don't need this section, strip it from the
+                output file.  This is mostly to handle .rela.bss and
+                .rela.plt.  We must create both sections in
+                create_dynamic_sections, because they must be created
+                before the linker maps input sections to output
+                sections.  The linker does that before
+                adjust_dynamic_symbol is called, and it is that
+                function which decides whether anything needs to go
+                into these sections.  */
+             strip = TRUE;
+           }
+         else
+           {
+             relocs = TRUE;
+
+             /* We use the reloc_count field as a counter if we need
+                to copy relocs into the output file.  */
+             s->reloc_count = 0;
+           }
+       }
+      else if (strncmp (name, ".got", 4) != 0)
+       {
+         /* It's not one of our sections, so don't allocate space.  */
+         continue;
+       }
+
+      if (strip)
+       {
+         s->flags |= SEC_EXCLUDE;
+         continue;
+       }
+
+      /* Allocate memory for the section contents.  */
+      /* FIXME: This should be a call to bfd_alloc not bfd_zalloc.
+         Unused entries should be reclaimed before the section's contents
+         are written out, but at the moment this does not happen.  Thus in
+         order to prevent writing out garbage, we initialise the section's
+         contents to zero.  */
+      s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
+      if (s->contents == NULL && s->size != 0)
+       return FALSE;
+    }
+
+  if (elf_hash_table (info)->dynamic_sections_created)
+    {
+      /* Add some entries to the .dynamic section.  We fill in the
+         values later, in bfin_finish_dynamic_sections, but we
+         must add the entries now so that we get the correct size for
+         the .dynamic section.  The DT_DEBUG entry is filled in by the
+         dynamic linker and used by the debugger.  */
+#define add_dynamic_entry(TAG, VAL) \
+  _bfd_elf_add_dynamic_entry (info, TAG, VAL)
+
+      if (!info->shared)
+       {
+         if (!add_dynamic_entry (DT_DEBUG, 0))
+           return FALSE;
+       }
+
+
+      if (relocs)
+       {
+         if (!add_dynamic_entry (DT_RELA, 0)
+             || !add_dynamic_entry (DT_RELASZ, 0)
+             || !add_dynamic_entry (DT_RELAENT,
+                                    sizeof (Elf32_External_Rela)))
+           return FALSE;
+       }
+
+      if ((info->flags & DF_TEXTREL) != 0)
+       {
+         if (!add_dynamic_entry (DT_TEXTREL, 0))
+           return FALSE;
+       }
+    }
+#undef add_dynamic_entry
+
+  return TRUE;
+}
+
+/* Given a .data section and a .emreloc in-memory section, store
+   relocation information into the .emreloc section which can be
+   used at runtime to relocate the section.  This is called by the
+   linker when the --embedded-relocs switch is used.  This is called
+   after the add_symbols entry point has been called for all the
+   objects, and before the final_link entry point is called.  */
+
+bfd_boolean
+bfd_bfin_elf32_create_embedded_relocs (
+     bfd *abfd,
+     struct bfd_link_info *info,
+     asection *datasec,
+     asection *relsec,
+     char **errmsg)
+{
+  Elf_Internal_Shdr *symtab_hdr;
+  Elf_Internal_Sym *isymbuf = NULL;
+  Elf_Internal_Rela *internal_relocs = NULL;
+  Elf_Internal_Rela *irel, *irelend;
+  bfd_byte *p;
+  bfd_size_type amt;
+
+  BFD_ASSERT (! info->relocatable);
+
+  *errmsg = NULL;
+
+  if (datasec->reloc_count == 0)
+    return TRUE;
+
+  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+
+  /* Get a copy of the native relocations.  */
+  internal_relocs = (_bfd_elf_link_read_relocs
+                    (abfd, datasec, (PTR) NULL, (Elf_Internal_Rela *) NULL,
+                     info->keep_memory));
+  if (internal_relocs == NULL)
+    goto error_return;
+
+  amt = (bfd_size_type) datasec->reloc_count * 12;
+  relsec->contents = (bfd_byte *) bfd_alloc (abfd, amt);
+  if (relsec->contents == NULL)
+    goto error_return;
+
+  p = relsec->contents;
+
+  irelend = internal_relocs + datasec->reloc_count;
+  for (irel = internal_relocs; irel < irelend; irel++, p += 12)
+    {
+      asection *targetsec;
+
+      /* We are going to write a four byte longword into the runtime
+       reloc section.  The longword will be the address in the data
+       section which must be relocated.  It is followed by the name
+       of the target section NUL-padded or truncated to 8
+       characters.  */
+
+      /* We can only relocate absolute longword relocs at run time.  */
+      if (ELF32_R_TYPE (irel->r_info) != (int) R_byte4_data)
+       {
+         *errmsg = _("unsupported reloc type");
+         bfd_set_error (bfd_error_bad_value);
+         goto error_return;
+       }
+
+      /* Get the target section referred to by the reloc.  */
+      if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
+       {
+         /* A local symbol.  */
+         Elf_Internal_Sym *isym;
+
+         /* Read this BFD's local symbols if we haven't done so already.  */
+         if (isymbuf == NULL)
+           {
+             isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
+             if (isymbuf == NULL)
+               isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
+                                               symtab_hdr->sh_info, 0,
+                                               NULL, NULL, NULL);
+             if (isymbuf == NULL)
+               goto error_return;
+           }
+
+         isym = isymbuf + ELF32_R_SYM (irel->r_info);
+         targetsec = bfd_section_from_elf_index (abfd, isym->st_shndx);
+       }
+      else
+       {
+         unsigned long indx;
+         struct elf_link_hash_entry *h;
+
+         /* An external symbol.  */
+         indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
+         h = elf_sym_hashes (abfd)[indx];
+         BFD_ASSERT (h != NULL);
+         if (h->root.type == bfd_link_hash_defined
+             || h->root.type == bfd_link_hash_defweak)
+           targetsec = h->root.u.def.section;
+         else
+           targetsec = NULL;
+       }
+
+      bfd_put_32 (abfd, irel->r_offset + datasec->output_offset, p);
+      memset (p + 4, 0, 8);
+      if (targetsec != NULL)
+       strncpy (p + 4, targetsec->output_section->name, 8);
+    }
+
+  if (isymbuf != NULL && symtab_hdr->contents != (unsigned char *) isymbuf)
+    free (isymbuf);
+  if (internal_relocs != NULL
+      && elf_section_data (datasec)->relocs != internal_relocs)
+    free (internal_relocs);
+  return TRUE;
+
+error_return:
+  if (isymbuf != NULL && symtab_hdr->contents != (unsigned char *) isymbuf)
+    free (isymbuf);
+  if (internal_relocs != NULL
+      && elf_section_data (datasec)->relocs != internal_relocs)
+    free (internal_relocs);
+  return FALSE;
+}
+
+#define TARGET_LITTLE_SYM              bfd_elf32_bfin_vec
+#define TARGET_LITTLE_NAME             "elf32-bfin"
+#define ELF_ARCH                       bfd_arch_bfin
+#define ELF_MACHINE_CODE               EM_BLACKFIN     
+#define ELF_MAXPAGESIZE                        0x1000
+#define elf_symbol_leading_char                '_'
+
+#define bfd_elf32_bfd_reloc_type_lookup        bfin_bfd_reloc_type_lookup
+#define elf_info_to_howto              bfin_info_to_howto
+#define elf_info_to_howto_rel          0
+
+#define bfd_elf32_bfd_is_local_label_name \
+                                        bfin_is_local_label_name
+#define bfin_hash_table(p) \
+  ((struct bfin_link_hash_table *) (p)->hash)
+
+
+
+#define elf_backend_create_dynamic_sections \
+                                        _bfd_elf_create_dynamic_sections
+#define bfd_elf32_bfd_link_hash_table_create \
+                                        bfin_link_hash_table_create
+#define bfd_elf32_bfd_final_link        bfd_elf_gc_common_final_link
+
+#define elf_backend_check_relocs   bfin_check_relocs
+#define elf_backend_adjust_dynamic_symbol \
+                                        bfin_adjust_dynamic_symbol
+#define elf_backend_size_dynamic_sections \
+                                        bfin_size_dynamic_sections
+#define elf_backend_relocate_section    bfin_relocate_section
+#define elf_backend_finish_dynamic_symbol \
+                                        bfin_finish_dynamic_symbol
+#define elf_backend_finish_dynamic_sections \
+                                        bfin_finish_dynamic_sections
+#define elf_backend_gc_mark_hook        bfin_gc_mark_hook
+#define elf_backend_gc_sweep_hook       bfin_gc_sweep_hook
+#define bfd_elf32_bfd_merge_private_bfd_data \
+                                        elf32_bfin_merge_private_bfd_data
+#define bfd_elf32_bfd_set_private_flags \
+                                        elf32_bfin_set_private_flags
+#define bfd_elf32_bfd_print_private_bfd_data \
+                                        elf32_bfin_print_private_bfd_data
+#define elf_backend_reloc_type_class    elf32_bfin_reloc_type_class
+#define elf_backend_can_gc_sections 1
+#define elf_backend_can_refcount 1
+#define elf_backend_want_got_plt 0
+#define elf_backend_plt_readonly 1
+#define elf_backend_want_plt_sym 0
+#define elf_backend_got_header_size     12
+#define elf_backend_rela_normal         1
+
+
+#include "elf32-target.h"
index de939ec8c7c8d53347cc180e81b7e1c0dbf166ab..6f3650b30bfdf9af85c52ca6d638ffdccb05e346 100644 (file)
@@ -1324,6 +1324,39 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
   "BFD_RELOC_SH_TLS_TPOFF32",
   "BFD_RELOC_ARC_B22_PCREL",
   "BFD_RELOC_ARC_B26",
+  "BFD_RELOC_BFIN_16_IMM",
+  "BFD_RELOC_BFIN_16_HIGH",
+  "BFD_RELOC_BFIN_4_PCREL",
+  "BFD_RELOC_BFIN_5_PCREL",
+  "BFD_RELOC_BFIN_16_LOW",
+  "BFD_RELOC_BFIN_10_PCREL",
+  "BFD_RELOC_BFIN_11_PCREL",
+  "BFD_RELOC_BFIN_12_PCREL_JUMP",
+  "BFD_RELOC_BFIN_12_PCREL_JUMP_S",
+  "BFD_RELOC_BFIN_24_PCREL_CALL_X",
+  "BFD_RELOC_BFIN_24_PCREL_JUMP_L",
+  "BFD_RELOC_BFIN_GOT",
+  "BFD_RELOC_BFIN_PLTPC",
+  "BFD_ARELOC_BFIN_PUSH",
+  "BFD_ARELOC_BFIN_CONST",
+  "BFD_ARELOC_BFIN_ADD",
+  "BFD_ARELOC_BFIN_SUB",
+  "BFD_ARELOC_BFIN_MULT",
+  "BFD_ARELOC_BFIN_DIV",
+  "BFD_ARELOC_BFIN_MOD",
+  "BFD_ARELOC_BFIN_LSHIFT",
+  "BFD_ARELOC_BFIN_RSHIFT",
+  "BFD_ARELOC_BFIN_AND",
+  "BFD_ARELOC_BFIN_OR",
+  "BFD_ARELOC_BFIN_XOR",
+  "BFD_ARELOC_BFIN_LAND",
+  "BFD_ARELOC_BFIN_LOR",
+  "BFD_ARELOC_BFIN_LEN",
+  "BFD_ARELOC_BFIN_NEG",
+  "BFD_ARELOC_BFIN_COMP",
+  "BFD_ARELOC_BFIN_PAGE",
+  "BFD_ARELOC_BFIN_HWPAGE",
+  "BFD_ARELOC_BFIN_ADDR",
   "BFD_RELOC_D10V_10_PCREL_R",
   "BFD_RELOC_D10V_10_PCREL_L",
   "BFD_RELOC_D10V_18",
index ab50c7b83897fbdc258e5e019dea39d604ebe932..8566d59456aa5db0303c5d228d54703095e7fdb9 100644 (file)
@@ -2980,6 +2980,139 @@ ENUMDOC
   stored in the instruction.  The high 24 bits are installed in bits 23
   through 0.
 
+ENUM
+  BFD_RELOC_BFIN_16_IMM
+ENUMDOC
+  ADI Blackfin 16 bit immediate absolute reloc.
+ENUM
+  BFD_RELOC_BFIN_16_HIGH
+ENUMDOC
+  ADI Blackfin 16 bit immediate absolute reloc higher 16 bits.
+ENUM
+  BFD_RELOC_BFIN_4_PCREL
+ENUMDOC
+  ADI Blackfin 'a' part of LSETUP.
+ENUM
+  BFD_RELOC_BFIN_5_PCREL
+ENUMDOC
+  ADI Blackfin.
+ENUM
+  BFD_RELOC_BFIN_16_LOW
+ENUMDOC
+  ADI Blackfin 16 bit immediate absolute reloc lower 16 bits.
+ENUM
+  BFD_RELOC_BFIN_10_PCREL
+ENUMDOC
+  ADI Blackfin.
+ENUM
+  BFD_RELOC_BFIN_11_PCREL
+ENUMDOC
+  ADI Blackfin 'b' part of LSETUP.
+ENUM
+  BFD_RELOC_BFIN_12_PCREL_JUMP
+ENUMDOC
+  ADI Blackfin.
+ENUM
+  BFD_RELOC_BFIN_12_PCREL_JUMP_S
+ENUMDOC
+  ADI Blackfin Short jump, pcrel.
+ENUM
+  BFD_RELOC_BFIN_24_PCREL_CALL_X
+ENUMDOC
+  ADI Blackfin Call.x not implemented.
+ENUM
+  BFD_RELOC_BFIN_24_PCREL_JUMP_L
+ENUMDOC
+  ADI Blackfin Long Jump pcrel.
+ENUM
+  BFD_RELOC_BFIN_GOT
+ENUMDOC
+  ADI Blackfin GOT relocation.
+ENUM
+  BFD_RELOC_BFIN_PLTPC
+ENUMDOC
+  ADI Blackfin PLTPC relocation.
+ENUM
+  BFD_ARELOC_BFIN_PUSH
+ENUMDOC
+  ADI Blackfin arithmetic relocation.
+ENUM
+  BFD_ARELOC_BFIN_CONST
+ENUMDOC
+  ADI Blackfin arithmetic relocation.
+ENUM
+  BFD_ARELOC_BFIN_ADD
+ENUMDOC
+  ADI Blackfin arithmetic relocation.
+ENUM
+  BFD_ARELOC_BFIN_SUB
+ENUMDOC
+  ADI Blackfin arithmetic relocation.
+ENUM
+  BFD_ARELOC_BFIN_MULT
+ENUMDOC
+  ADI Blackfin arithmetic relocation.
+ENUM
+  BFD_ARELOC_BFIN_DIV
+ENUMDOC
+  ADI Blackfin arithmetic relocation.
+ENUM
+  BFD_ARELOC_BFIN_MOD
+ENUMDOC
+  ADI Blackfin arithmetic relocation.
+ENUM
+  BFD_ARELOC_BFIN_LSHIFT
+ENUMDOC
+  ADI Blackfin arithmetic relocation.
+ENUM
+  BFD_ARELOC_BFIN_RSHIFT
+ENUMDOC
+  ADI Blackfin arithmetic relocation.
+ENUM
+  BFD_ARELOC_BFIN_AND
+ENUMDOC
+  ADI Blackfin arithmetic relocation.
+ENUM
+  BFD_ARELOC_BFIN_OR
+ENUMDOC
+  ADI Blackfin arithmetic relocation.
+ENUM
+  BFD_ARELOC_BFIN_XOR
+ENUMDOC
+  ADI Blackfin arithmetic relocation.
+ENUM
+  BFD_ARELOC_BFIN_LAND
+ENUMDOC
+  ADI Blackfin arithmetic relocation.
+ENUM
+  BFD_ARELOC_BFIN_LOR
+ENUMDOC
+  ADI Blackfin arithmetic relocation.
+ENUM
+  BFD_ARELOC_BFIN_LEN
+ENUMDOC
+  ADI Blackfin arithmetic relocation.
+ENUM
+  BFD_ARELOC_BFIN_NEG
+ENUMDOC
+  ADI Blackfin arithmetic relocation.
+ENUM
+  BFD_ARELOC_BFIN_COMP
+ENUMDOC
+  ADI Blackfin arithmetic relocation.
+ENUM
+  BFD_ARELOC_BFIN_PAGE
+ENUMDOC
+  ADI Blackfin arithmetic relocation.
+ENUM
+  BFD_ARELOC_BFIN_HWPAGE
+ENUMDOC
+  ADI Blackfin arithmetic relocation.
+ENUM
+  BFD_ARELOC_BFIN_ADDR
+ENUMDOC
+  ADI Blackfin arithmetic relocation.
+
 ENUM
   BFD_RELOC_D10V_10_PCREL_R
 ENUMDOC
index 009f9066aa00d291ab93969ee6eea0fc151cafb9..dd5e097267690607437436d666d82551302243cd 100644 (file)
@@ -546,6 +546,7 @@ extern const bfd_target b_out_vec_little_host;
 extern const bfd_target bfd_efi_app_ia32_vec;
 extern const bfd_target bfd_efi_app_ia64_vec;
 extern const bfd_target bfd_elf32_avr_vec;
+extern const bfd_target bfd_elf32_bfin_vec;
 extern const bfd_target bfd_elf32_big_generic_vec;
 extern const bfd_target bfd_elf32_bigarc_vec;
 extern const bfd_target bfd_elf32_bigarm_vec;
@@ -841,6 +842,7 @@ static const bfd_target * const _bfd_target_vector[] = {
        &bfd_efi_app_ia64_vec,
 #endif
        &bfd_elf32_avr_vec,
+       &bfd_elf32_bfin_vec,
 
        /* This, and other vectors, may not be used in any *.mt configuration.
           But that does not mean they are unnecessary.  If configured with