OSDN Git Service

bfd/
[pf3gnuchains/pf3gnuchains4x.git] / bfd / cofflink.c
index 32200a8..1ebdfdd 100644 (file)
@@ -1,52 +1,45 @@
 /* COFF specific linker code.
-   Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
-   Free Software Foundation, Inc.
+   Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
+   2004, 2005, 2006, 2007, 2008, 2009, 2011 Free Software Foundation, Inc.
    Written by Ian Lance Taylor, Cygnus Support.
 
-This file is part of BFD, the Binary File Descriptor library.
+   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 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 3 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.
+   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.  */
+   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.  */
 
 /* This file contains the COFF backend linker code.  */
 
-#include "bfd.h"
 #include "sysdep.h"
+#include "bfd.h"
 #include "bfdlink.h"
 #include "libbfd.h"
 #include "coff/internal.h"
 #include "libcoff.h"
+#include "safe-ctype.h"
+
+static bfd_boolean coff_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info);
+static bfd_boolean coff_link_check_archive_element (bfd *abfd, struct bfd_link_info *info, bfd_boolean *pneeded);
+static bfd_boolean coff_link_add_symbols (bfd *abfd, struct bfd_link_info *info);
 
-static boolean coff_link_add_object_symbols
-  PARAMS ((bfd *, struct bfd_link_info *));
-static boolean coff_link_check_archive_element
-  PARAMS ((bfd *, struct bfd_link_info *, boolean *));
-static boolean coff_link_check_ar_symbols
-  PARAMS ((bfd *, struct bfd_link_info *, boolean *));
-static boolean coff_link_add_symbols PARAMS ((bfd *, struct bfd_link_info *));
-static char *dores_com PARAMS ((char *, bfd *, int));
-static char *get_name PARAMS ((char *, char **));
-static int process_embedded_commands
-  PARAMS ((bfd *, struct bfd_link_info *, bfd *));
-static void mark_relocs PARAMS ((struct coff_final_link_info *, bfd *));
-
-/* Return true if SYM is a weak, external symbol.  */
+/* Return TRUE if SYM is a weak, external symbol.  */
 #define IS_WEAK_EXTERNAL(abfd, sym)                    \
   ((sym).n_sclass == C_WEAKEXT                         \
    || (obj_pe (abfd) && (sym).n_sclass == C_NT_WEAK))
 
-/* Return true if SYM is an external symbol.  */
+/* Return TRUE if SYM is an external symbol.  */
 #define IS_EXTERNAL(abfd, sym)                         \
   ((sym).n_sclass == C_EXT || IS_WEAK_EXTERNAL (abfd, sym))
 
@@ -63,10 +56,9 @@ static void mark_relocs PARAMS ((struct coff_final_link_info *, bfd *));
 /* Create an entry in a COFF linker hash table.  */
 
 struct bfd_hash_entry *
-_bfd_coff_link_hash_newfunc (entry, table, string)
-     struct bfd_hash_entry *entry;
-     struct bfd_hash_table *table;
-     const char *string;
+_bfd_coff_link_hash_newfunc (struct bfd_hash_entry *entry,
+                            struct bfd_hash_table *table,
+                            const char *string)
 {
   struct coff_link_hash_entry *ret = (struct coff_link_hash_entry *) entry;
 
@@ -87,7 +79,7 @@ _bfd_coff_link_hash_newfunc (entry, table, string)
       /* Set local fields.  */
       ret->indx = -1;
       ret->type = T_NULL;
-      ret->class = C_NULL;
+      ret->symbol_class = C_NULL;
       ret->numaux = 0;
       ret->auxbfd = NULL;
       ret->aux = NULL;
@@ -98,23 +90,22 @@ _bfd_coff_link_hash_newfunc (entry, table, string)
 
 /* Initialize a COFF linker hash table.  */
 
-boolean
-_bfd_coff_link_hash_table_init (table, abfd, newfunc)
-     struct coff_link_hash_table *table;
-     bfd *abfd;
-     struct bfd_hash_entry *(*newfunc) PARAMS ((struct bfd_hash_entry *,
-                                               struct bfd_hash_table *,
-                                               const char *));
+bfd_boolean
+_bfd_coff_link_hash_table_init (struct coff_link_hash_table *table,
+                               bfd *abfd,
+                               struct bfd_hash_entry *(*newfunc) (struct bfd_hash_entry *,
+                                                                  struct bfd_hash_table *,
+                                                                  const char *),
+                               unsigned int entsize)
 {
-  table->stab_info = NULL;
-  return _bfd_link_hash_table_init (&table->root, abfd, newfunc);
+  memset (&table->stab_info, 0, sizeof (table->stab_info));
+  return _bfd_link_hash_table_init (&table->root, abfd, newfunc, entsize);
 }
 
 /* Create a COFF linker hash table.  */
 
 struct bfd_link_hash_table *
-_bfd_coff_link_hash_table_create (abfd)
-     bfd *abfd;
+_bfd_coff_link_hash_table_create (bfd *abfd)
 {
   struct coff_link_hash_table *ret;
   bfd_size_type amt = sizeof (struct coff_link_hash_table);
@@ -122,8 +113,10 @@ _bfd_coff_link_hash_table_create (abfd)
   ret = (struct coff_link_hash_table *) bfd_malloc (amt);
   if (ret == NULL)
     return NULL;
+
   if (! _bfd_coff_link_hash_table_init (ret, abfd,
-                                       _bfd_coff_link_hash_newfunc))
+                                       _bfd_coff_link_hash_newfunc,
+                                       sizeof (struct coff_link_hash_entry)))
     {
       free (ret);
       return (struct bfd_link_hash_table *) NULL;
@@ -134,10 +127,9 @@ _bfd_coff_link_hash_table_create (abfd)
 /* Create an entry in a COFF debug merge hash table.  */
 
 struct bfd_hash_entry *
-_bfd_coff_debug_merge_hash_newfunc (entry, table, string)
-     struct bfd_hash_entry *entry;
-     struct bfd_hash_table *table;
-     const char *string;
+_bfd_coff_debug_merge_hash_newfunc (struct bfd_hash_entry *entry,
+                                   struct bfd_hash_table *table,
+                                   const char *string)
 {
   struct coff_debug_merge_hash_entry *ret =
     (struct coff_debug_merge_hash_entry *) entry;
@@ -166,90 +158,53 @@ _bfd_coff_debug_merge_hash_newfunc (entry, table, string)
 /* Given a COFF BFD, add symbols to the global hash table as
    appropriate.  */
 
-boolean
-_bfd_coff_link_add_symbols (abfd, info)
-     bfd *abfd;
-     struct bfd_link_info *info;
+bfd_boolean
+_bfd_coff_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
 {
   switch (bfd_get_format (abfd))
     {
     case bfd_object:
       return coff_link_add_object_symbols (abfd, info);
     case bfd_archive:
-      return (_bfd_generic_link_add_archive_symbols
-             (abfd, info, coff_link_check_archive_element));
+      return _bfd_generic_link_add_archive_symbols
+       (abfd, info, coff_link_check_archive_element);
     default:
       bfd_set_error (bfd_error_wrong_format);
-      return false;
+      return FALSE;
     }
 }
 
 /* Add symbols from a COFF object file.  */
 
-static boolean
-coff_link_add_object_symbols (abfd, info)
-     bfd *abfd;
-     struct bfd_link_info *info;
+static bfd_boolean
+coff_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
 {
   if (! _bfd_coff_get_external_symbols (abfd))
-    return false;
+    return FALSE;
   if (! coff_link_add_symbols (abfd, info))
-    return false;
+    return FALSE;
 
-  if (! info->keep_memory)
-    {
-      if (! _bfd_coff_free_symbols (abfd))
-       return false;
-    }
-  return true;
-}
+  if (! info->keep_memory
+      && ! _bfd_coff_free_symbols (abfd))
+    return FALSE;
 
-/* Check a single archive element to see if we need to include it in
-   the link.  *PNEEDED is set according to whether this element is
-   needed in the link or not.  This is called via
-   _bfd_generic_link_add_archive_symbols.  */
-
-static boolean
-coff_link_check_archive_element (abfd, info, pneeded)
-     bfd *abfd;
-     struct bfd_link_info *info;
-     boolean *pneeded;
-{
-  if (! _bfd_coff_get_external_symbols (abfd))
-    return false;
-
-  if (! coff_link_check_ar_symbols (abfd, info, pneeded))
-    return false;
-
-  if (*pneeded)
-    {
-      if (! coff_link_add_symbols (abfd, info))
-       return false;
-    }
-
-  if (! info->keep_memory || ! *pneeded)
-    {
-      if (! _bfd_coff_free_symbols (abfd))
-       return false;
-    }
-
-  return true;
+  return TRUE;
 }
 
 /* Look through the symbols to see if this object file should be
    included in the link.  */
 
-static boolean
-coff_link_check_ar_symbols (abfd, info, pneeded)
-     bfd *abfd;
-     struct bfd_link_info *info;
-     boolean *pneeded;
+static bfd_boolean
+coff_link_check_ar_symbols (bfd *abfd,
+                           struct bfd_link_info *info,
+                           bfd_boolean *pneeded,
+                           bfd **subsbfd)
 {
   bfd_size_type symesz;
   bfd_byte *esym;
   bfd_byte *esym_end;
 
-  *pneeded = false;
+  *pneeded = FALSE;
 
   symesz = bfd_coff_symesz (abfd);
   esym = (bfd_byte *) obj_coff_external_syms (abfd);
@@ -259,7 +214,7 @@ coff_link_check_ar_symbols (abfd, info, pneeded)
       struct internal_syment sym;
       enum coff_symbol_classification classification;
 
-      bfd_coff_swap_sym_in (abfd, (PTR) esym, (PTR) &sym);
+      bfd_coff_swap_sym_in (abfd, esym, &sym);
 
       classification = bfd_coff_classify_symbol (abfd, &sym);
       if (classification == COFF_SYMBOL_GLOBAL
@@ -271,22 +226,17 @@ coff_link_check_ar_symbols (abfd, info, pneeded)
 
          /* This symbol is externally visible, and is defined by this
              object file.  */
-
          name = _bfd_coff_internal_syment_name (abfd, &sym, buf);
          if (name == NULL)
-           return false;
-         h = bfd_link_hash_lookup (info->hash, name, false, false, true);
+           return FALSE;
+         h = bfd_link_hash_lookup (info->hash, name, FALSE, FALSE, TRUE);
+
+         /* Auto import.  */
+         if (!h
+             && info->pei386_auto_import
+             && CONST_STRNEQ (name, "__imp_"))
+           h = bfd_link_hash_lookup (info->hash, name + 6, FALSE, FALSE, TRUE);
 
-         /* auto import */
-         if (!h && info->pei386_auto_import)
-           {
-             if (!strncmp (name,"__imp_", 6))
-               {
-                 h =
-                    bfd_link_hash_lookup (info->hash, name + 6, false, false,
-                                          true);
-               }
-           }
          /* We are only interested in symbols that are currently
             undefined.  If a symbol is currently known to be common,
             COFF linkers do not bring in an object file which defines
@@ -294,10 +244,11 @@ coff_link_check_ar_symbols (abfd, info, pneeded)
          if (h != (struct bfd_link_hash_entry *) NULL
              && h->type == bfd_link_hash_undefined)
            {
-             if (! (*info->callbacks->add_archive_element) (info, abfd, name))
-               return false;
-             *pneeded = true;
-             return true;
+             if (!(*info->callbacks
+                   ->add_archive_element) (info, abfd, name, subsbfd))
+               return FALSE;
+             *pneeded = TRUE;
+             return TRUE;
            }
        }
 
@@ -305,21 +256,65 @@ coff_link_check_ar_symbols (abfd, info, pneeded)
     }
 
   /* We do not need this object file.  */
-  return true;
+  return TRUE;
+}
+
+/* Check a single archive element to see if we need to include it in
+   the link.  *PNEEDED is set according to whether this element is
+   needed in the link or not.  This is called via
+   _bfd_generic_link_add_archive_symbols.  */
+
+static bfd_boolean
+coff_link_check_archive_element (bfd *abfd,
+                                struct bfd_link_info *info,
+                                bfd_boolean *pneeded)
+{
+  bfd *oldbfd;
+  bfd_boolean needed;
+
+  if (!_bfd_coff_get_external_symbols (abfd))
+    return FALSE;
+
+  oldbfd = abfd;
+  if (!coff_link_check_ar_symbols (abfd, info, pneeded, &abfd))
+    return FALSE;
+
+  needed = *pneeded;
+  if (needed)
+    {
+      /* Potentially, the add_archive_element hook may have set a
+        substitute BFD for us.  */
+      if (abfd != oldbfd)
+       {
+         if (!info->keep_memory
+             && !_bfd_coff_free_symbols (oldbfd))
+           return FALSE;
+         if (!_bfd_coff_get_external_symbols (abfd))
+           return FALSE;
+       }
+      if (!coff_link_add_symbols (abfd, info))
+       return FALSE;
+    }
+
+  if (!info->keep_memory || !needed)
+    {
+      if (!_bfd_coff_free_symbols (abfd))
+       return FALSE;
+    }
+  return TRUE;
 }
 
 /* Add all the symbols from an object file to the hash table.  */
 
-static boolean
-coff_link_add_symbols (abfd, info)
-     bfd *abfd;
-     struct bfd_link_info *info;
+static bfd_boolean
+coff_link_add_symbols (bfd *abfd,
+                      struct bfd_link_info *info)
 {
   unsigned int n_tmask = coff_data (abfd)->local_n_tmask;
   unsigned int n_btshft = coff_data (abfd)->local_n_btshft;
   unsigned int n_btmask = coff_data (abfd)->local_n_btmask;
-  boolean keep_syms;
-  boolean default_copy;
+  bfd_boolean keep_syms;
+  bfd_boolean default_copy;
   bfd_size_type symcount;
   struct coff_link_hash_entry **sym_hash;
   bfd_size_type symesz;
@@ -327,23 +322,26 @@ coff_link_add_symbols (abfd, info)
   bfd_byte *esym_end;
   bfd_size_type amt;
 
+  symcount = obj_raw_syment_count (abfd);
+
+  if (symcount == 0)
+    return TRUE;               /* Nothing to do.  */
+
   /* Keep the symbols during this function, in case the linker needs
      to read the generic symbols in order to report an error message.  */
   keep_syms = obj_coff_keep_syms (abfd);
-  obj_coff_keep_syms (abfd) = true;
+  obj_coff_keep_syms (abfd) = TRUE;
 
   if (info->keep_memory)
-    default_copy = false;
+    default_copy = FALSE;
   else
-    default_copy = true;
-
-  symcount = obj_raw_syment_count (abfd);
+    default_copy = TRUE;
 
   /* We keep a list of the linker hash table entries that correspond
      to particular symbols.  */
   amt = symcount * sizeof (struct coff_link_hash_entry *);
   sym_hash = (struct coff_link_hash_entry **) bfd_zalloc (abfd, amt);
-  if (sym_hash == NULL && symcount != 0)
+  if (sym_hash == NULL)
     goto error_return;
   obj_coff_sym_hashes (abfd) = sym_hash;
 
@@ -355,9 +353,9 @@ coff_link_add_symbols (abfd, info)
     {
       struct internal_syment sym;
       enum coff_symbol_classification classification;
-      boolean copy;
+      bfd_boolean copy;
 
-      bfd_coff_swap_sym_in (abfd, (PTR) esym, (PTR) &sym);
+      bfd_coff_swap_sym_in (abfd, esym, &sym);
 
       classification = bfd_coff_classify_symbol (abfd, &sym);
       if (classification != COFF_SYMBOL_LOCAL)
@@ -367,7 +365,7 @@ coff_link_add_symbols (abfd, info)
          flagword flags;
          asection *section;
          bfd_vma value;
-         boolean addit;
+         bfd_boolean addit;
 
          /* This symbol is externally visible.  */
 
@@ -380,7 +378,7 @@ coff_link_add_symbols (abfd, info)
          copy = default_copy;
          if (sym._n._n_n._n_zeroes != 0
              || sym._n._n_n._n_offset == 0)
-           copy = true;
+           copy = TRUE;
 
          value = sym.n_value;
 
@@ -415,7 +413,7 @@ coff_link_add_symbols (abfd, info)
          if (IS_WEAK_EXTERNAL (abfd, sym))
            flags = BSF_WEAK;
 
-         addit = true;
+         addit = TRUE;
 
          /* In the PE format, section symbols actually refer to the
              start of the output section.  We handle them specially
@@ -423,7 +421,7 @@ coff_link_add_symbols (abfd, info)
          if (obj_pe (abfd) && (flags & BSF_SECTION_SYM) != 0)
            {
              *sym_hash = coff_link_hash_lookup (coff_hash_table (info),
-                                                name, false, copy, false);
+                                                name, FALSE, copy, FALSE);
              if (*sym_hash != NULL)
                {
                  if (((*sym_hash)->coff_link_hash_flags
@@ -434,7 +432,7 @@ coff_link_add_symbols (abfd, info)
                      ("Warning: symbol `%s' is both section and non-section",
                       name);
 
-                 addit = false;
+                 addit = FALSE;
                }
            }
 
@@ -463,26 +461,27 @@ coff_link_add_symbols (abfd, info)
          if (obj_pe (abfd)
              && (classification == COFF_SYMBOL_GLOBAL
                  || classification == COFF_SYMBOL_PE_SECTION)
-             && section->comdat != NULL
-             && strncmp (name, "??_", 3) == 0
-             && strcmp (name, section->comdat->name) == 0)
+             && coff_section_data (abfd, section) != NULL
+             && coff_section_data (abfd, section)->comdat != NULL
+             && CONST_STRNEQ (name, "??_")
+             && strcmp (name, coff_section_data (abfd, section)->comdat->name) == 0)
            {
              if (*sym_hash == NULL)
                *sym_hash = coff_link_hash_lookup (coff_hash_table (info),
-                                                  name, false, copy, false);
+                                                  name, FALSE, copy, FALSE);
              if (*sym_hash != NULL
                  && (*sym_hash)->root.type == bfd_link_hash_defined
-                 && (*sym_hash)->root.u.def.section->comdat != NULL
-                 && strcmp ((*sym_hash)->root.u.def.section->comdat->name,
-                            section->comdat->name) == 0)
-               addit = false;
+                 && coff_section_data (abfd, (*sym_hash)->root.u.def.section)->comdat != NULL
+                 && strcmp (coff_section_data (abfd, (*sym_hash)->root.u.def.section)->comdat->name,
+                            coff_section_data (abfd, section)->comdat->name) == 0)
+               addit = FALSE;
            }
 
          if (addit)
            {
              if (! (bfd_coff_link_add_one_symbol
                     (info, abfd, name, flags, section, value,
-                     (const char *) NULL, copy, false,
+                     (const char *) NULL, copy, FALSE,
                      (struct bfd_link_hash_entry **) sym_hash)))
                goto error_return;
            }
@@ -503,20 +502,20 @@ coff_link_add_symbols (abfd, info)
            (*sym_hash)->root.u.c.p->alignment_power
              = bfd_coff_default_section_alignment_power (abfd);
 
-         if (info->hash->creator->flavour == bfd_get_flavour (abfd))
+         if (bfd_get_flavour (info->output_bfd) == bfd_get_flavour (abfd))
            {
              /* If we don't have any symbol information currently in
                  the hash table, or if we are looking at a symbol
                  definition, then update the symbol class and type in
                  the hash table.  */
-             if (((*sym_hash)->class == C_NULL
+             if (((*sym_hash)->symbol_class == C_NULL
                   && (*sym_hash)->type == T_NULL)
                  || sym.n_scnum != 0
                  || (sym.n_value != 0
                      && (*sym_hash)->root.type != bfd_link_hash_defined
                      && (*sym_hash)->root.type != bfd_link_hash_defweak))
                {
-                 (*sym_hash)->class = sym.n_sclass;
+                 (*sym_hash)->symbol_class = sym.n_sclass;
                  if (sym.n_type != T_NULL)
                    {
                      /* We want to warn if the type changed, but not
@@ -531,9 +530,8 @@ coff_link_add_symbols (abfd, info)
                               && (BTYPE ((*sym_hash)->type) == T_NULL
                                   || BTYPE (sym.n_type) == T_NULL)))
                        (*_bfd_error_handler)
-                         (_("Warning: type of symbol `%s' changed from %d to %d in %s"),
-                          name, (*sym_hash)->type, sym.n_type,
-                          bfd_archive_filename (abfd));
+                         (_("Warning: type of symbol `%s' changed from %d to %d in %B"),
+                          abfd, name, (*sym_hash)->type, sym.n_type);
 
                      /* We don't want to change from a meaningful
                         base type to a null one, but if we know
@@ -560,9 +558,9 @@ coff_link_add_symbols (abfd, info)
                      for (i = 0, eaux = esym + symesz, iaux = alloc;
                           i < sym.n_numaux;
                           i++, eaux += symesz, iaux++)
-                       bfd_coff_swap_aux_in (abfd, (PTR) eaux, sym.n_type,
+                       bfd_coff_swap_aux_in (abfd, eaux, sym.n_type,
                                              sym.n_sclass, (int) i,
-                                             sym.n_numaux, (PTR) iaux);
+                                             sym.n_numaux, iaux);
                      (*sym_hash)->aux = alloc;
                    }
                }
@@ -578,10 +576,9 @@ coff_link_add_symbols (abfd, info)
                 FIXME: This is not at all the right place to do this.
                 For example, it won't help objdump.  This needs to be
                 done when we swap in the section header.  */
-
              BFD_ASSERT ((*sym_hash)->numaux == 1);
-             if (section->_raw_size == 0)
-               section->_raw_size = (*sym_hash)->aux[0].x_scn.x_scnlen;
+             if (section->size == 0)
+               section->size = (*sym_hash)->aux[0].x_scn.x_scnlen;
 
              /* FIXME: We could test whether the section sizes
                  matches the size in the aux entry, but apparently
@@ -593,30 +590,35 @@ coff_link_add_symbols (abfd, info)
       sym_hash += sym.n_numaux + 1;
     }
 
-  /* If this is a non-traditional, non-relocateable link, try to
+  /* If this is a non-traditional, non-relocatable link, try to
      optimize the handling of any .stab/.stabstr sections.  */
-  if (! info->relocateable
+  if (! info->relocatable
       && ! info->traditional_format
-      && info->hash->creator->flavour == bfd_get_flavour (abfd)
+      && bfd_get_flavour (info->output_bfd) == bfd_get_flavour (abfd)
       && (info->strip != strip_all && info->strip != strip_debugger))
     {
-      asection *stab, *stabstr;
+      asection *stabstr;
 
-      stab = bfd_get_section_by_name (abfd, ".stab");
-      if (stab != NULL)
-       {
-         stabstr = bfd_get_section_by_name (abfd, ".stabstr");
+      stabstr = bfd_get_section_by_name (abfd, ".stabstr");
 
-         if (stabstr != NULL)
+      if (stabstr != NULL)
+       {
+         bfd_size_type string_offset = 0;
+         asection *stab;
+         
+         for (stab = abfd->sections; stab; stab = stab->next)
+           if (CONST_STRNEQ (stab->name, ".stab")
+               && (!stab->name[5]
+                   || (stab->name[5] == '.' && ISDIGIT (stab->name[6]))))
            {
              struct coff_link_hash_table *table;
-             struct coff_section_tdata *secdata;
-
-             secdata = coff_section_data (abfd, stab);
+             struct coff_section_tdata *secdata
+               = coff_section_data (abfd, stab);
+             
              if (secdata == NULL)
                {
                  amt = sizeof (struct coff_section_tdata);
-                 stab->used_by_bfd = (PTR) bfd_zalloc (abfd, amt);
+                 stab->used_by_bfd = bfd_zalloc (abfd, amt);
                  if (stab->used_by_bfd == NULL)
                    goto error_return;
                  secdata = coff_section_data (abfd, stab);
@@ -626,7 +628,8 @@ coff_link_add_symbols (abfd, info)
 
              if (! _bfd_link_section_stabs (abfd, &table->stab_info,
                                             stab, stabstr,
-                                            &secdata->stab_info))
+                                            &secdata->stab_info,
+                                            &string_offset))
                goto error_return;
            }
        }
@@ -634,24 +637,23 @@ coff_link_add_symbols (abfd, info)
 
   obj_coff_keep_syms (abfd) = keep_syms;
 
-  return true;
+  return TRUE;
 
  error_return:
   obj_coff_keep_syms (abfd) = keep_syms;
-  return false;
+  return FALSE;
 }
 \f
 /* Do the final link step.  */
 
-boolean
-_bfd_coff_final_link (abfd, info)
-     bfd *abfd;
-     struct bfd_link_info *info;
+bfd_boolean
+_bfd_coff_final_link (bfd *abfd,
+                     struct bfd_link_info *info)
 {
   bfd_size_type symesz;
   struct coff_final_link_info finfo;
-  boolean debug_merge_allocated;
-  boolean long_section_names;
+  bfd_boolean debug_merge_allocated;
+  bfd_boolean long_section_names;
   asection *o;
   struct bfd_link_order *p;
   bfd_size_type max_sym_count;
@@ -684,8 +686,8 @@ _bfd_coff_final_link (abfd, info)
   finfo.contents = NULL;
   finfo.external_relocs = NULL;
   finfo.internal_relocs = NULL;
-  finfo.global_to_static = false;
-  debug_merge_allocated = false;
+  finfo.global_to_static = FALSE;
+  debug_merge_allocated = FALSE;
 
   coff_data (abfd)->link_info = info;
 
@@ -695,7 +697,7 @@ _bfd_coff_final_link (abfd, info)
 
   if (! coff_debug_merge_hash_table_init (&finfo.debug_merge))
     goto error_return;
-  debug_merge_allocated = true;
+  debug_merge_allocated = TRUE;
 
   /* Compute the file positions for all the sections.  */
   if (! abfd->output_has_begun)
@@ -712,12 +714,12 @@ _bfd_coff_final_link (abfd, info)
   max_lineno_count = 0;
   max_reloc_count = 0;
 
-  long_section_names = false;
+  long_section_names = FALSE;
   for (o = abfd->sections; o != NULL; o = o->next)
     {
       o->reloc_count = 0;
       o->lineno_count = 0;
-      for (p = o->link_order_head; p != NULL; p = p->next)
+      for (p = o->map_head.link_order; p != NULL; p = p->next)
        {
          if (p->type == bfd_indirect_link_order)
            {
@@ -729,23 +731,25 @@ _bfd_coff_final_link (abfd, info)
                 link.  This will normally be every section.  We need
                 to do this so that we can identify any sections which
                 the linker has decided to not include.  */
-             sec->linker_mark = true;
+             sec->linker_mark = TRUE;
 
              if (info->strip == strip_none
                  || info->strip == strip_some)
                o->lineno_count += sec->lineno_count;
 
-             if (info->relocateable)
+             if (info->relocatable)
                o->reloc_count += sec->reloc_count;
 
-             if (sec->_raw_size > max_contents_size)
-               max_contents_size = sec->_raw_size;
+             if (sec->rawsize > max_contents_size)
+               max_contents_size = sec->rawsize;
+             if (sec->size > max_contents_size)
+               max_contents_size = sec->size;
              if (sec->lineno_count > max_lineno_count)
                max_lineno_count = sec->lineno_count;
              if (sec->reloc_count > max_reloc_count)
                max_reloc_count = sec->reloc_count;
            }
-         else if (info->relocateable
+         else if (info->relocatable
                   && (p->type == bfd_section_reloc_link_order
                       || p->type == bfd_symbol_reloc_link_order))
            ++o->reloc_count;
@@ -757,6 +761,10 @@ _bfd_coff_final_link (abfd, info)
          o->flags |= SEC_RELOC;
          o->rel_filepos = rel_filepos;
          rel_filepos += o->reloc_count * relsz;
+         /* In PE COFF, if there are at least 0xffff relocations an
+            extra relocation will be written out to encode the count.  */
+         if (obj_pe (abfd) && o->reloc_count >= 0xffff)
+           rel_filepos += relsz;
        }
 
       if (bfd_coff_long_section_names (abfd)
@@ -766,17 +774,17 @@ _bfd_coff_final_link (abfd, info)
              table.  This must correspond to the code in
              coff_write_object_contents which puts the string index
              into the s_name field of the section header.  That is why
-             we pass hash as false.  */
-         if (_bfd_stringtab_add (finfo.strtab, o->name, false, false)
+             we pass hash as FALSE.  */
+         if (_bfd_stringtab_add (finfo.strtab, o->name, FALSE, FALSE)
              == (bfd_size_type) -1)
            goto error_return;
-         long_section_names = true;
+         long_section_names = TRUE;
        }
     }
 
-  /* If doing a relocateable link, allocate space for the pointers we
+  /* If doing a relocatable link, allocate space for the pointers we
      need to keep.  */
-  if (info->relocateable)
+  if (info->relocatable)
     {
       unsigned int i;
 
@@ -822,17 +830,17 @@ _bfd_coff_final_link (abfd, info)
 
             Because of this problem, we also keep the relocs in
             memory until the end of the link.  This wastes memory,
-            but only when doing a relocateable link, which is not the
+            but only when doing a relocatable link, which is not the
             common case.  */
-         BFD_ASSERT (info->relocateable);
+         BFD_ASSERT (info->relocatable);
          amt = o->reloc_count;
          amt *= sizeof (struct internal_reloc);
          finfo.section_info[o->target_index].relocs =
-           (struct internal_reloc *) bfd_malloc (amt);
+              (struct internal_reloc *) bfd_malloc (amt);
          amt = o->reloc_count;
          amt *= sizeof (struct coff_link_hash_entry *);
          finfo.section_info[o->target_index].rel_hashes =
-           (struct coff_link_hash_entry **) bfd_malloc (amt);
+              (struct coff_link_hash_entry **) bfd_malloc (amt);
          if (finfo.section_info[o->target_index].relocs == NULL
              || finfo.section_info[o->target_index].rel_hashes == NULL)
            goto error_return;
@@ -857,8 +865,8 @@ _bfd_coff_final_link (abfd, info)
     {
       size_t sz;
 
-      sub->output_has_begun = false;
-      sz = obj_raw_syment_count (sub);
+      sub->output_has_begun = FALSE;
+      sz = bfd_family_coff (sub) ? obj_raw_syment_count (sub) : 2;
       if (sz > max_sym_count)
        max_sym_count = sz;
     }
@@ -869,14 +877,14 @@ _bfd_coff_final_link (abfd, info)
   amt = max_sym_count * sizeof (asection *);
   finfo.sec_ptrs = (asection **) bfd_malloc (amt);
   amt = max_sym_count * sizeof (long);
-  finfo.sym_indices = (long *) bfd_malloc (amt);
+  finfo.sym_indices = (long int *) bfd_malloc (amt);
   finfo.outsyms = (bfd_byte *) bfd_malloc ((max_sym_count + 1) * symesz);
   amt = max_lineno_count * bfd_coff_linesz (abfd);
   finfo.linenos = (bfd_byte *) bfd_malloc (amt);
   finfo.contents = (bfd_byte *) bfd_malloc (max_contents_size);
   amt = max_reloc_count * relsz;
   finfo.external_relocs = (bfd_byte *) bfd_malloc (amt);
-  if (! info->relocateable)
+  if (! info->relocatable)
     {
       amt = max_reloc_count * sizeof (struct internal_reloc);
       finfo.internal_relocs = (struct internal_reloc *) bfd_malloc (amt);
@@ -888,7 +896,7 @@ _bfd_coff_final_link (abfd, info)
       || (finfo.linenos == NULL && max_lineno_count > 0)
       || (finfo.contents == NULL && max_contents_size > 0)
       || (finfo.external_relocs == NULL && max_reloc_count > 0)
-      || (! info->relocateable
+      || (! info->relocatable
          && finfo.internal_relocs == NULL
          && max_reloc_count > 0))
     goto error_return;
@@ -908,7 +916,7 @@ _bfd_coff_final_link (abfd, info)
 
   for (o = abfd->sections; o != NULL; o = o->next)
     {
-      for (p = o->link_order_head; p != NULL; p = p->next)
+      for (p = o->map_head.link_order; p != NULL; p = p->next)
        {
          if (p->type == bfd_indirect_link_order
              && bfd_family_coff (p->u.indirect.section->owner))
@@ -918,7 +926,7 @@ _bfd_coff_final_link (abfd, info)
                {
                  if (! _bfd_coff_link_input_bfd (&finfo, sub))
                    goto error_return;
-                 sub->output_has_begun = true;
+                 sub->output_has_begun = TRUE;
                }
            }
          else if (p->type == bfd_section_reloc_link_order
@@ -935,13 +943,99 @@ _bfd_coff_final_link (abfd, info)
        }
     }
 
+  if (finfo.info->strip != strip_all && finfo.info->discard != discard_all)
+    {
+      /* Add local symbols from foreign inputs.  */
+      for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
+       {
+         unsigned int i;
+
+         if (bfd_family_coff (sub) || ! bfd_get_outsymbols (sub))
+           continue;
+         for (i = 0; i < bfd_get_symcount (sub); ++i)
+           {
+             asymbol *sym = bfd_get_outsymbols (sub) [i];
+             file_ptr pos;
+             struct internal_syment isym;
+             bfd_size_type string_size = 0;
+             bfd_vma written = 0;
+             bfd_boolean rewrite = FALSE;
+
+             if (! (sym->flags & BSF_LOCAL)
+                 || (sym->flags & (BSF_SECTION_SYM | BSF_DEBUGGING_RELOC
+                                   | BSF_THREAD_LOCAL | BSF_RELC | BSF_SRELC
+                                   | BSF_SYNTHETIC))
+                 || ((sym->flags & BSF_DEBUGGING)
+                     && ! (sym->flags & BSF_FILE)))
+               continue;
+
+             /* See if we are discarding symbols with this name.  */
+             if ((finfo.info->strip == strip_some
+                  && (bfd_hash_lookup (finfo.info->keep_hash,
+                                       bfd_asymbol_name(sym), FALSE, FALSE)
+                      == NULL))
+                 || (((finfo.info->discard == discard_sec_merge
+                       && (bfd_get_section (sym)->flags & SEC_MERGE)
+                       && ! finfo.info->relocatable)
+                      || finfo.info->discard == discard_l)
+                     && bfd_is_local_label_name (sub, bfd_asymbol_name(sym))))
+               continue;
+
+             pos = obj_sym_filepos (abfd) + obj_raw_syment_count (abfd)
+                                            * symesz;
+             if (bfd_seek (abfd, pos, SEEK_SET) != 0)
+               goto error_return;
+             if (! coff_write_alien_symbol(abfd, sym, &isym, &written,
+                                           &string_size, NULL, NULL))
+               goto error_return;
+
+             if (string_size)
+               {
+                 bfd_boolean hash = ! (abfd->flags & BFD_TRADITIONAL_FORMAT);
+                 bfd_size_type indx;
+
+                 indx = _bfd_stringtab_add (finfo.strtab,
+                                            bfd_asymbol_name (sym), hash,
+                                            FALSE);
+                 if (indx == (bfd_size_type) -1)
+                   goto error_return;
+                 isym._n._n_n._n_offset = STRING_SIZE_SIZE + indx;
+                 bfd_coff_swap_sym_out (abfd, &isym, finfo.outsyms);
+                 rewrite = TRUE;
+               }
+
+             if (isym.n_sclass == C_FILE)
+               {
+                 if (finfo.last_file_index != -1)
+                   {
+                     finfo.last_file.n_value = obj_raw_syment_count (abfd);
+                     bfd_coff_swap_sym_out (abfd, &finfo.last_file,
+                                            finfo.outsyms);
+                     pos = obj_sym_filepos (abfd) + finfo.last_file_index
+                                                    * symesz;
+                     rewrite = TRUE;
+                   }
+                 finfo.last_file_index = obj_raw_syment_count (abfd);
+                 finfo.last_file = isym;
+               }
+
+             if (rewrite
+                 && (bfd_seek (abfd, pos, SEEK_SET) != 0
+                     || bfd_bwrite (finfo.outsyms, symesz, abfd) != symesz))
+               goto error_return;
+
+             obj_raw_syment_count (abfd) += written;
+           }
+       }
+    }
+
   if (! bfd_coff_final_link_postscript (abfd, & finfo))
     goto error_return;
 
   /* Free up the buffers used by _bfd_coff_link_input_bfd.  */
 
   coff_debug_merge_hash_table_free (&finfo.debug_merge);
-  debug_merge_allocated = false;
+  debug_merge_allocated = FALSE;
 
   if (finfo.internal_syms != NULL)
     {
@@ -988,13 +1082,13 @@ _bfd_coff_final_link (abfd, info)
       file_ptr pos;
 
       finfo.last_file.n_value = obj_raw_syment_count (abfd);
-      bfd_coff_swap_sym_out (abfd, (PTR) &finfo.last_file,
-                            (PTR) finfo.outsyms);
+      bfd_coff_swap_sym_out (abfd, &finfo.last_file,
+                            finfo.outsyms);
 
       pos = obj_sym_filepos (abfd) + finfo.last_file_index * symesz;
       if (bfd_seek (abfd, pos, SEEK_SET) != 0
          || bfd_bwrite (finfo.outsyms, symesz, abfd) != symesz)
-       return false;
+       return FALSE;
     }
 
   /* If doing task linking (ld --task-link) then make a pass through the
@@ -1002,19 +1096,16 @@ _bfd_coff_final_link (abfd, info)
      static.  */
   if (info->task_link)
     {
-      finfo.failed = false;
+      finfo.failed = FALSE;
       coff_link_hash_traverse (coff_hash_table (info),
-                              _bfd_coff_write_task_globals,
-                              (PTR) &finfo);
+                              _bfd_coff_write_task_globals, &finfo);
       if (finfo.failed)
        goto error_return;
     }
 
   /* Write out the global symbols.  */
-  finfo.failed = false;
-  coff_link_hash_traverse (coff_hash_table (info),
-                          _bfd_coff_write_global_sym,
-                          (PTR) &finfo);
+  finfo.failed = FALSE;
+  bfd_hash_traverse (&info->hash->table, _bfd_coff_write_global_sym, &finfo);
   if (finfo.failed)
     goto error_return;
 
@@ -1025,7 +1116,7 @@ _bfd_coff_final_link (abfd, info)
       finfo.outsyms = NULL;
     }
 
-  if (info->relocateable && max_output_reloc_count > 0)
+  if (info->relocatable && max_output_reloc_count > 0)
     {
       /* Now that we have written out all the global symbols, we know
         the symbol indices to use for relocs against them, and we can
@@ -1056,13 +1147,30 @@ _bfd_coff_final_link (abfd, info)
                  BFD_ASSERT ((*rel_hash)->indx >= 0);
                  irel->r_symndx = (*rel_hash)->indx;
                }
-             bfd_coff_swap_reloc_out (abfd, (PTR) irel, (PTR) erel);
+             bfd_coff_swap_reloc_out (abfd, irel, erel);
            }
 
-         if (bfd_seek (abfd, o->rel_filepos, SEEK_SET) != 0
-             || (bfd_bwrite ((PTR) external_relocs,
-                            (bfd_size_type) relsz * o->reloc_count, abfd)
-                 != (bfd_size_type) relsz * o->reloc_count))
+         if (bfd_seek (abfd, o->rel_filepos, SEEK_SET) != 0)
+           goto error_return;
+         if (obj_pe (abfd) && o->reloc_count >= 0xffff)
+           {
+             /* In PE COFF, write the count of relocs as the first
+                reloc.  The header overflow bit will be set
+                elsewhere. */
+             struct internal_reloc incount;
+             bfd_byte *excount = (bfd_byte *)bfd_malloc (relsz);
+             
+             memset (&incount, 0, sizeof (incount));
+             incount.r_vaddr = o->reloc_count + 1;
+             bfd_coff_swap_reloc_out (abfd, (PTR) &incount, (PTR) excount);
+             if (bfd_bwrite (excount, relsz, abfd) != relsz)
+               /* We'll leak, but it's an error anyway. */
+               goto error_return;
+             free (excount);
+           }
+         if (bfd_bwrite (external_relocs,
+                         (bfd_size_type) relsz * o->reloc_count, abfd)
+             != (bfd_size_type) relsz * o->reloc_count)
            goto error_return;
        }
 
@@ -1087,10 +1195,10 @@ _bfd_coff_final_link (abfd, info)
     }
 
   /* If we have optimized stabs strings, output them.  */
-  if (coff_hash_table (info)->stab_info != NULL)
+  if (coff_hash_table (info)->stab_info.stabstr != NULL)
     {
       if (! _bfd_write_stab_strings (abfd, &coff_hash_table (info)->stab_info))
-       return false;
+       return FALSE;
     }
 
   /* Write out the string table.  */
@@ -1100,7 +1208,7 @@ _bfd_coff_final_link (abfd, info)
 
       pos = obj_sym_filepos (abfd) + obj_raw_syment_count (abfd) * symesz;
       if (bfd_seek (abfd, pos, SEEK_SET) != 0)
-       return false;
+       return FALSE;
 
 #if STRING_SIZE_SIZE == 4
       H_PUT_32 (abfd,
@@ -1112,12 +1220,12 @@ _bfd_coff_final_link (abfd, info)
 
       if (bfd_bwrite (strbuf, (bfd_size_type) STRING_SIZE_SIZE, abfd)
          != STRING_SIZE_SIZE)
-       return false;
+       return FALSE;
 
       if (! _bfd_stringtab_emit (abfd, finfo.strtab))
-       return false;
+       return FALSE;
 
-      obj_coff_strings_written (abfd) = true;
+      obj_coff_strings_written (abfd) = TRUE;
     }
 
   _bfd_stringtab_free (finfo.strtab);
@@ -1126,7 +1234,7 @@ _bfd_coff_final_link (abfd, info)
      not try to write out the symbols.  */
   bfd_get_symcount (abfd) = 0;
 
-  return true;
+  return TRUE;
 
  error_return:
   if (debug_merge_allocated)
@@ -1164,20 +1272,18 @@ _bfd_coff_final_link (abfd, info)
     free (finfo.internal_relocs);
   if (external_relocs != NULL)
     free (external_relocs);
-  return false;
+  return FALSE;
 }
 
-/* parse out a -heap <reserved>,<commit> line */
+/* Parse out a -heap <reserved>,<commit> line.  */
 
 static char *
-dores_com (ptr, output_bfd, heap)
-     char *ptr;
-     bfd *output_bfd;
-     int heap;
+dores_com (char *ptr, bfd *output_bfd, int heap)
 {
   if (coff_data(output_bfd)->pe)
     {
       int val = strtoul (ptr, &ptr, 0);
+
       if (heap)
        pe_data(output_bfd)->pe_opthdr.SizeOfHeapReserve = val;
       else
@@ -1195,9 +1301,8 @@ dores_com (ptr, output_bfd, heap)
   return ptr;
 }
 
-static char *get_name(ptr, dst)
-char *ptr;
-char **dst;
+static char *
+get_name (char *ptr, char **dst)
 {
   while (*ptr == ' ')
     ptr++;
@@ -1208,85 +1313,91 @@ char **dst;
   return ptr+1;
 }
 
-/* Process any magic embedded commands in a section called .drectve */
+/* Process any magic embedded commands in a section called .drectve */
 
 static int
-process_embedded_commands (output_bfd, info,  abfd)
-     bfd *output_bfd;
-     struct bfd_link_info *info ATTRIBUTE_UNUSED;
-     bfd *abfd;
+process_embedded_commands (bfd *output_bfd,
+                          struct bfd_link_info *info ATTRIBUTE_UNUSED,
+                          bfd *abfd)
 {
   asection *sec = bfd_get_section_by_name (abfd, ".drectve");
   char *s;
   char *e;
-  char *copy;
+  bfd_byte *copy;
+
   if (!sec)
     return 1;
 
-  copy = bfd_malloc (sec->_raw_size);
-  if (!copy)
-    return 0;
-  if (! bfd_get_section_contents(abfd, sec, copy, (bfd_vma) 0, sec->_raw_size))
+  if (!bfd_malloc_and_get_section (abfd, sec, &copy))
     {
-      free (copy);
+      if (copy != NULL)
+       free (copy);
       return 0;
     }
-  e = copy + sec->_raw_size;
-  for (s = copy;  s < e ; )
+  e = (char *) copy + sec->size;
+
+  for (s = (char *) copy; s < e ; )
     {
-      if (s[0]!= '-') {
-       s++;
-       continue;
-      }
-      if (strncmp (s,"-attr", 5) == 0)
+      if (s[0] != '-')
+       {
+         s++;
+         continue;
+       }
+      if (CONST_STRNEQ (s, "-attr"))
        {
          char *name;
          char *attribs;
          asection *asec;
-
          int loop = 1;
          int had_write = 0;
-         int had_read = 0;
          int had_exec= 0;
-         int had_shared= 0;
+
          s += 5;
-         s = get_name(s, &name);
-         s = get_name(s, &attribs);
-         while (loop) {
-           switch (*attribs++)
-             {
-             case 'W':
-               had_write = 1;
-               break;
-             case 'R':
-               had_read = 1;
-               break;
-             case 'S':
-               had_shared = 1;
-               break;
-             case 'X':
-               had_exec = 1;
-               break;
-             default:
-               loop = 0;
-             }
-         }
+         s = get_name (s, &name);
+         s = get_name (s, &attribs);
+
+         while (loop)
+           {
+             switch (*attribs++)
+               {
+               case 'W':
+                 had_write = 1;
+                 break;
+               case 'R':
+                 break;
+               case 'S':
+                 break;
+               case 'X':
+                 had_exec = 1;
+                 break;
+               default:
+                 loop = 0;
+               }
+           }
          asec = bfd_get_section_by_name (abfd, name);
-         if (asec) {
-           if (had_exec)
-             asec->flags |= SEC_CODE;
-           if (!had_write)
-             asec->flags |= SEC_READONLY;
-         }
-       }
-      else if (strncmp (s,"-heap", 5) == 0)
-       {
-         s = dores_com (s+5, output_bfd, 1);
+         if (asec)
+           {
+             if (had_exec)
+               asec->flags |= SEC_CODE;
+             if (!had_write)
+               asec->flags |= SEC_READONLY;
+           }
        }
-      else if (strncmp (s,"-stack", 6) == 0)
+      else if (CONST_STRNEQ (s, "-heap"))
+       s = dores_com (s + 5, output_bfd, 1);
+
+      else if (CONST_STRNEQ (s, "-stack"))
+       s = dores_com (s + 6, output_bfd, 0);
+
+      /* GNU extension for aligned commons.  */
+      else if (CONST_STRNEQ (s, "-aligncomm:"))
        {
-         s = dores_com (s+6, output_bfd, 0);
+         /* Common symbols must be aligned on reading, as it
+         is too late to do anything here, after they have
+         already been allocated, so just skip the directive.  */
+         s += 11;
        }
+
       else
        s++;
     }
@@ -1297,13 +1408,10 @@ process_embedded_commands (output_bfd, info,  abfd)
 /* Place a marker against all symbols which are used by relocations.
    This marker can be picked up by the 'do we skip this symbol ?'
    loop in _bfd_coff_link_input_bfd() and used to prevent skipping
-   that symbol.
-   */
+   that symbol.  */
 
 static void
-mark_relocs (finfo, input_bfd)
-     struct coff_final_link_info *     finfo;
-     bfd *                             input_bfd;
+mark_relocs (struct coff_final_link_info *finfo, bfd *input_bfd)
 {
   asection * a;
 
@@ -1318,13 +1426,16 @@ mark_relocs (finfo, input_bfd)
 
       if ((a->flags & SEC_RELOC) == 0 || a->reloc_count  < 1)
        continue;
+      /* Don't mark relocs in excluded sections.  */
+      if (a->output_section == bfd_abs_section_ptr)
+       continue;
 
       /* Read in the relocs.  */
       internal_relocs = _bfd_coff_read_internal_relocs
-       (input_bfd, a, false,
+       (input_bfd, a, FALSE,
         finfo->external_relocs,
-        finfo->info->relocateable,
-        (finfo->info->relocateable
+        finfo->info->relocatable,
+        (finfo->info->relocatable
          ? (finfo->section_info[ a->output_section->target_index ].relocs + a->output_section->reloc_count)
          : finfo->internal_relocs)
        );
@@ -1338,35 +1449,27 @@ mark_relocs (finfo, input_bfd)
       /* Place a mark in the sym_indices array (whose entries have
         been initialised to 0) for all of the symbols that are used
         in the relocation table.  This will then be picked up in the
-        skip/don't pass */
-
+        skip/don't-skip pass.  */
       for (; irel < irelend; irel++)
-       {
-         finfo->sym_indices[ irel->r_symndx ] = -1;
-       }
+       finfo->sym_indices[ irel->r_symndx ] = -1;
     }
 }
 
 /* Link an input file into the linker output file.  This function
    handles all the sections and relocations of the input file at once.  */
 
-boolean
-_bfd_coff_link_input_bfd (finfo, input_bfd)
-     struct coff_final_link_info *finfo;
-     bfd *input_bfd;
+bfd_boolean
+_bfd_coff_link_input_bfd (struct coff_final_link_info *finfo, bfd *input_bfd)
 {
   unsigned int n_tmask = coff_data (input_bfd)->local_n_tmask;
   unsigned int n_btshft = coff_data (input_bfd)->local_n_btshft;
-#if 0
-  unsigned int n_btmask = coff_data (input_bfd)->local_n_btmask;
-#endif
-  boolean (*adjust_symndx) PARAMS ((bfd *, struct bfd_link_info *, bfd *,
-                                   asection *, struct internal_reloc *,
-                                   boolean *));
+  bfd_boolean (*adjust_symndx)
+    (bfd *, struct bfd_link_info *, bfd *, asection *,
+     struct internal_reloc *, bfd_boolean *);
   bfd *output_bfd;
   const char *strings;
   bfd_size_type syment_base;
-  boolean copy, hash;
+  bfd_boolean copy, hash;
   bfd_size_type isymesz;
   bfd_size_type osymesz;
   bfd_size_type linesz;
@@ -1390,15 +1493,15 @@ _bfd_coff_link_input_bfd (finfo, input_bfd)
   linesz = bfd_coff_linesz (input_bfd);
   BFD_ASSERT (linesz == bfd_coff_linesz (output_bfd));
 
-  copy = false;
+  copy = FALSE;
   if (! finfo->info->keep_memory)
-    copy = true;
-  hash = true;
+    copy = TRUE;
+  hash = TRUE;
   if ((output_bfd->flags & BFD_TRADITIONAL_FORMAT) != 0)
-    hash = false;
+    hash = FALSE;
 
   if (! _bfd_coff_get_external_symbols (input_bfd))
-    return false;
+    return FALSE;
 
   esym = (bfd_byte *) obj_coff_external_syms (input_bfd);
   esym_end = esym + obj_raw_syment_count (input_bfd) * isymesz;
@@ -1408,20 +1511,18 @@ _bfd_coff_link_input_bfd (finfo, input_bfd)
   output_index = syment_base;
   outsym = finfo->outsyms;
 
-  if (coff_data (output_bfd)->pe)
-    {
-      if (! process_embedded_commands (output_bfd, finfo->info, input_bfd))
-       return false;
-    }
+  if (coff_data (output_bfd)->pe
+      && ! process_embedded_commands (output_bfd, finfo->info, input_bfd))
+    return FALSE;
 
-  /* If we are going to perform relocations and also strip/discard some symbols
-     then we must make sure that we do not strip/discard those symbols that are
-     going to be involved in the relocations */
+  /* If we are going to perform relocations and also strip/discard some
+     symbols then we must make sure that we do not strip/discard those
+     symbols that are going to be involved in the relocations.  */
   if ((   finfo->info->strip   != strip_none
        || finfo->info->discard != discard_none)
-      && finfo->info->relocateable)
+      && finfo->info->relocatable)
     {
-      /* mark the symbol array as 'not-used' */
+      /* Mark the symbol array as 'not-used'.  */
       memset (indexp, 0, obj_raw_syment_count (input_bfd) * sizeof * indexp);
 
       mark_relocs (finfo, input_bfd);
@@ -1431,12 +1532,12 @@ _bfd_coff_link_input_bfd (finfo, input_bfd)
     {
       struct internal_syment isym;
       enum coff_symbol_classification classification;
-      boolean skip;
-      boolean global;
-      boolean dont_skip_symbol;
+      bfd_boolean skip;
+      bfd_boolean global;
+      bfd_boolean dont_skip_symbol;
       int add;
 
-      bfd_coff_swap_sym_in (input_bfd, (PTR) esym, (PTR) isymp);
+      bfd_coff_swap_sym_in (input_bfd, esym, isymp);
 
       /* Make a copy of *isymp so that the relocate_section function
         always sees the original values.  This is more reliable than
@@ -1466,20 +1567,20 @@ _bfd_coff_link_input_bfd (finfo, input_bfd)
          relocation.  */
       if ((finfo->info->strip != strip_none
           || finfo->info->discard != discard_none)
-         && finfo->info->relocateable)
+         && finfo->info->relocatable)
        dont_skip_symbol = *indexp;
       else
-       dont_skip_symbol = false;
+       dont_skip_symbol = FALSE;
 
       *indexp = -1;
 
-      skip = false;
-      global = false;
+      skip = FALSE;
+      global = FALSE;
       add = 1 + isym.n_numaux;
 
       /* If we are stripping all symbols, we want to skip this one.  */
       if (finfo->info->strip == strip_all && ! dont_skip_symbol)
-       skip = true;
+       skip = TRUE;
 
       if (! skip)
        {
@@ -1494,22 +1595,22 @@ _bfd_coff_link_input_bfd (finfo, input_bfd)
                 end of the symbol table, so skip them for now.
                 Locally defined function symbols, however, are an
                 exception, and are not moved to the end.  */
-             global = true;
+             global = TRUE;
              if (! ISFCN (isym.n_type))
-               skip = true;
+               skip = TRUE;
              break;
 
            case COFF_SYMBOL_UNDEFINED:
              /* Undefined symbols are left for the end.  */
-             global = true;
-             skip = true;
+             global = TRUE;
+             skip = TRUE;
              break;
 
            case COFF_SYMBOL_LOCAL:
              /* This is a local symbol.  Skip it if we are discarding
                  local symbols.  */
              if (finfo->info->discard == discard_all && ! dont_skip_symbol)
-               skip = true;
+               skip = TRUE;
              break;
            }
        }
@@ -1518,13 +1619,14 @@ _bfd_coff_link_input_bfd (finfo, input_bfd)
       /* Skip section symbols for sections which are not going to be
         emitted.  */
       if (!skip
+         && !dont_skip_symbol
          && isym.n_sclass == C_STAT
          && isym.n_type == T_NULL
-          && isym.n_numaux > 0)
-        {
-          if ((*secpp)->output_section == bfd_abs_section_ptr)
-            skip = true;
-        }
+         && isym.n_numaux > 0
+         && ((*secpp)->output_section == bfd_abs_section_ptr
+             || bfd_section_removed_from_list (output_bfd,
+                                               (*secpp)->output_section)))
+       skip = TRUE;
 #endif
 
       /* If we stripping debugging symbols, and this is a debugging
@@ -1545,7 +1647,7 @@ _bfd_coff_link_input_bfd (finfo, input_bfd)
                      || isym.n_sclass == C_REGPARM
                      || isym.n_sclass == C_FIELD
                      || isym.n_sclass == C_EOS))))
-       skip = true;
+       skip = TRUE;
 
       /* If some symbols are stripped based on the name, work out the
         name and decide whether to skip this symbol.  */
@@ -1558,16 +1660,16 @@ _bfd_coff_link_input_bfd (finfo, input_bfd)
 
          name = _bfd_coff_internal_syment_name (input_bfd, &isym, buf);
          if (name == NULL)
-           return false;
+           return FALSE;
 
          if (! dont_skip_symbol
              && ((finfo->info->strip == strip_some
-                  && (bfd_hash_lookup (finfo->info->keep_hash, name, false,
-                                   false) == NULL))
+                  && (bfd_hash_lookup (finfo->info->keep_hash, name, FALSE,
+                                   FALSE) == NULL))
                   || (! global
                       && finfo->info->discard == discard_l
                       && bfd_is_local_label_name (input_bfd, name))))
-           skip = true;
+           skip = TRUE;
        }
 
       /* If this is an enum, struct, or union tag, see if we have
@@ -1591,7 +1693,7 @@ _bfd_coff_link_input_bfd (finfo, input_bfd)
 
          name = _bfd_coff_internal_syment_name (input_bfd, &isym, buf);
          if (name == NULL)
-           return false;
+           return FALSE;
 
          /* Ignore fake names invented by compiler; treat them all as
              the same name.  */
@@ -1601,9 +1703,9 @@ _bfd_coff_link_input_bfd (finfo, input_bfd)
            name = "";
 
          mh = coff_debug_merge_hash_lookup (&finfo->debug_merge, name,
-                                            true, true);
+                                            TRUE, TRUE);
          if (mh == NULL)
-           return false;
+           return FALSE;
 
          /* Allocate memory to hold type information.  If this turns
              out to be a duplicate, we pass this address to
@@ -1611,14 +1713,14 @@ _bfd_coff_link_input_bfd (finfo, input_bfd)
          amt = sizeof (struct coff_debug_merge_type);
          mt = (struct coff_debug_merge_type *) bfd_alloc (input_bfd, amt);
          if (mt == NULL)
-           return false;
-         mt->class = isym.n_sclass;
+           return FALSE;
+         mt->type_class = isym.n_sclass;
 
          /* Pick up the aux entry, which points to the end of the tag
              entries.  */
-         bfd_coff_swap_aux_in (input_bfd, (PTR) (esym + isymesz),
+         bfd_coff_swap_aux_in (input_bfd, (esym + isymesz),
                                isym.n_type, isym.n_sclass, 0, isym.n_numaux,
-                               (PTR) &aux);
+                               &aux);
 
          /* Gather the elements.  */
          epp = &mt->elements;
@@ -1633,23 +1735,23 @@ _bfd_coff_link_input_bfd (finfo, input_bfd)
              char elebuf[SYMNMLEN + 1];
              char *name_copy;
 
-             bfd_coff_swap_sym_in (input_bfd, (PTR) esl, (PTR) islp);
+             bfd_coff_swap_sym_in (input_bfd, esl, islp);
 
              amt = sizeof (struct coff_debug_merge_element);
-             *epp = ((struct coff_debug_merge_element *)
-                     bfd_alloc (input_bfd, amt));
+             *epp = (struct coff_debug_merge_element *)
+                  bfd_alloc (input_bfd, amt);
              if (*epp == NULL)
-               return false;
+               return FALSE;
 
              elename = _bfd_coff_internal_syment_name (input_bfd, islp,
                                                        elebuf);
              if (elename == NULL)
-               return false;
+               return FALSE;
 
              amt = strlen (elename) + 1;
              name_copy = (char *) bfd_alloc (input_bfd, amt);
              if (name_copy == NULL)
-               return false;
+               return FALSE;
              strcpy (name_copy, elename);
 
              (*epp)->name = name_copy;
@@ -1662,16 +1764,15 @@ _bfd_coff_link_input_bfd (finfo, input_bfd)
                  union internal_auxent eleaux;
                  long indx;
 
-                 bfd_coff_swap_aux_in (input_bfd, (PTR) (esl + isymesz),
+                 bfd_coff_swap_aux_in (input_bfd, (esl + isymesz),
                                        islp->n_type, islp->n_sclass, 0,
-                                       islp->n_numaux, (PTR) &eleaux);
+                                       islp->n_numaux, &eleaux);
                  indx = eleaux.x_sym.x_tagndx.l;
 
                  /* FIXME: If this tagndx entry refers to a symbol
                     defined later in this file, we just ignore it.
                     Handling this correctly would be tedious, and may
                     not be required.  */
-
                  if (indx > 0
                      && (indx
                          < ((esym -
@@ -1694,7 +1795,7 @@ _bfd_coff_link_input_bfd (finfo, input_bfd)
              type.  We always output the type if it has no elements,
              for simplicity.  */
          if (mt->elements == NULL)
-           bfd_release (input_bfd, (PTR) mt);
+           bfd_release (input_bfd, mt);
          else
            {
              struct coff_debug_merge_type *mtl;
@@ -1703,7 +1804,7 @@ _bfd_coff_link_input_bfd (finfo, input_bfd)
                {
                  struct coff_debug_merge_element *me, *mel;
 
-                 if (mtl->class != mt->class)
+                 if (mtl->type_class != mt->type_class)
                    continue;
 
                  for (me = mt->elements, mel = mtl->elements;
@@ -1730,10 +1831,10 @@ _bfd_coff_link_input_bfd (finfo, input_bfd)
              else
                {
                  /* This is a redefinition which can be merged.  */
-                 bfd_release (input_bfd, (PTR) mt);
+                 bfd_release (input_bfd, mt);
                  *indexp = mtl->indx;
                  add = (eslend - esym) / isymesz;
-                 skip = true;
+                 skip = TRUE;
                }
            }
        }
@@ -1754,13 +1855,12 @@ _bfd_coff_link_input_bfd (finfo, input_bfd)
                 bfd_coff_symname_in_debug.  That is only true for
                 XCOFF, and XCOFF requires different linking code
                 anyhow.  */
-             name = _bfd_coff_internal_syment_name (input_bfd, &isym,
-                                                    (char *) NULL);
+             name = _bfd_coff_internal_syment_name (input_bfd, &isym, NULL);
              if (name == NULL)
-               return false;
+               return FALSE;
              indx = _bfd_stringtab_add (finfo->strtab, name, hash, copy);
              if (indx == (bfd_size_type) -1)
-               return false;
+               return FALSE;
              isym._n._n_n._n_offset = STRING_SIZE_SIZE + indx;
            }
 
@@ -1828,7 +1928,6 @@ _bfd_coff_link_input_bfd (finfo, input_bfd)
                 it).  We try to get this right, below, just before we
                 write the symbols out, but in the general case we may
                 have to write the symbol out twice.  */
-
              if (finfo->last_file_index != -1
                  && finfo->last_file.n_value != (bfd_vma) output_index)
                {
@@ -1839,11 +1938,11 @@ _bfd_coff_link_input_bfd (finfo, input_bfd)
                    {
                      /* The last C_FILE symbol is in this input file.  */
                      bfd_coff_swap_sym_out (output_bfd,
-                                            (PTR) &finfo->last_file,
-                                            (PTR) (finfo->outsyms
-                                                   + ((finfo->last_file_index
-                                                       - syment_base)
-                                                      * osymesz)));
+                                            &finfo->last_file,
+                                            (finfo->outsyms
+                                             + ((finfo->last_file_index
+                                                 - syment_base)
+                                                * osymesz)));
                    }
                  else
                    {
@@ -1853,13 +1952,12 @@ _bfd_coff_link_input_bfd (finfo, input_bfd)
                         symbol.  We need to write it out again.  We
                         borrow *outsym temporarily.  */
                      bfd_coff_swap_sym_out (output_bfd,
-                                            (PTR) &finfo->last_file,
-                                            (PTR) outsym);
+                                            &finfo->last_file, outsym);
                      pos = obj_sym_filepos (output_bfd);
                      pos += finfo->last_file_index * osymesz;
                      if (bfd_seek (output_bfd, pos, SEEK_SET) != 0
                          || bfd_bwrite (outsym, osymesz, output_bfd) != osymesz)
-                       return false;
+                       return FALSE;
                    }
                }
 
@@ -1874,8 +1972,7 @@ _bfd_coff_link_input_bfd (finfo, input_bfd)
            isym.n_sclass = C_STAT;
 
          /* Output the symbol.  */
-
-         bfd_coff_swap_sym_out (output_bfd, (PTR) &isym, (PTR) outsym);
+         bfd_coff_swap_sym_out (output_bfd, &isym, outsym);
 
          *indexp = output_index;
 
@@ -1892,7 +1989,7 @@ _bfd_coff_link_input_bfd (finfo, input_bfd)
                  /* This can happen if there were errors earlier in
                      the link.  */
                  bfd_set_error (bfd_error_bad_value);
-                 return false;
+                 return FALSE;
                }
              h->indx = output_index;
            }
@@ -1915,13 +2012,13 @@ _bfd_coff_link_input_bfd (finfo, input_bfd)
   /* Fix up the aux entries.  This must be done in a separate pass,
      because we don't know the correct symbol indices until we have
      already decided which symbols we are going to keep.  */
-
   esym = (bfd_byte *) obj_coff_external_syms (input_bfd);
   esym_end = esym + obj_raw_syment_count (input_bfd) * isymesz;
   isymp = finfo->internal_syms;
   indexp = finfo->sym_indices;
   sym_hash = obj_coff_sym_hashes (input_bfd);
   outsym = finfo->outsyms;
+
   while (esym < esym_end)
     {
       int add;
@@ -1947,6 +2044,7 @@ _bfd_coff_link_input_bfd (finfo, input_bfd)
                  generate two symbols with the same name, but only one
                  will have aux entries.  */
              BFD_ASSERT (isymp->n_numaux == 0
+                         || h->numaux == 0
                          || h->numaux == isymp->n_numaux);
            }
 
@@ -1962,13 +2060,12 @@ _bfd_coff_link_input_bfd (finfo, input_bfd)
              union internal_auxent aux;
              union internal_auxent *auxp;
 
-             if (h != NULL)
+             if (h != NULL && h->aux != NULL && (h->numaux > i))
                auxp = h->aux + i;
              else
                {
-                 bfd_coff_swap_aux_in (input_bfd, (PTR) esym, isymp->n_type,
-                                       isymp->n_sclass, i, isymp->n_numaux,
-                                       (PTR) &aux);
+                 bfd_coff_swap_aux_in (input_bfd, esym, isymp->n_type,
+                                       isymp->n_sclass, i, isymp->n_numaux, &aux);
                  auxp = &aux;
                }
 
@@ -1988,17 +2085,18 @@ _bfd_coff_link_input_bfd (finfo, input_bfd)
                        {
                          strings = _bfd_coff_read_string_table (input_bfd);
                          if (strings == NULL)
-                           return false;
+                           return FALSE;
                        }
                      filename = strings + auxp->x_file.x_n.x_offset;
                      indx = _bfd_stringtab_add (finfo->strtab, filename,
                                                 hash, copy);
                      if (indx == (bfd_size_type) -1)
-                       return false;
+                       return FALSE;
                      auxp->x_file.x_n.x_offset = STRING_SIZE_SIZE + indx;
                    }
                }
-             else if (isymp->n_sclass != C_STAT || isymp->n_type != T_NULL)
+             else if ((isymp->n_sclass != C_STAT || isymp->n_type != T_NULL)
+                      && isymp->n_sclass != C_NT_WEAK)
                {
                  unsigned long indx;
 
@@ -2061,18 +2159,19 @@ _bfd_coff_link_input_bfd (finfo, input_bfd)
                          if ((bfd_size_type) finfo->last_bf_index
                              >= syment_base)
                            {
-                             PTR auxout;
+                             void *auxout;
 
                              /* The last .bf symbol is in this input
                                 file.  This will only happen if the
                                 assembler did not set up the .bf
                                 endndx symbols correctly.  */
-                             auxout = (PTR) (finfo->outsyms
-                                             + ((finfo->last_bf_index
-                                                 - syment_base)
-                                                * osymesz));
+                             auxout = (finfo->outsyms
+                                       + ((finfo->last_bf_index
+                                           - syment_base)
+                                          * osymesz));
+
                              bfd_coff_swap_aux_out (output_bfd,
-                                                    (PTR) &finfo->last_bf,
+                                                    &finfo->last_bf,
                                                     isymp->n_type,
                                                     isymp->n_sclass,
                                                     0, isymp->n_numaux,
@@ -2088,17 +2187,17 @@ _bfd_coff_link_input_bfd (finfo, input_bfd)
                                  temporarily.  FIXME: This case should
                                  be made faster.  */
                              bfd_coff_swap_aux_out (output_bfd,
-                                                    (PTR) &finfo->last_bf,
+                                                    &finfo->last_bf,
                                                     isymp->n_type,
                                                     isymp->n_sclass,
                                                     0, isymp->n_numaux,
-                                                    (PTR) outsym);
+                                                    outsym);
                              pos = obj_sym_filepos (output_bfd);
                              pos += finfo->last_bf_index * osymesz;
                              if (bfd_seek (output_bfd, pos, SEEK_SET) != 0
                                  || (bfd_bwrite (outsym, osymesz, output_bfd)
                                      != osymesz))
-                               return false;
+                               return FALSE;
                            }
                        }
 
@@ -2119,9 +2218,9 @@ _bfd_coff_link_input_bfd (finfo, input_bfd)
 
              if (h == NULL)
                {
-                 bfd_coff_swap_aux_out (output_bfd, (PTR) auxp, isymp->n_type,
+                 bfd_coff_swap_aux_out (output_bfd, auxp, isymp->n_type,
                                         isymp->n_sclass, i, isymp->n_numaux,
-                                        (PTR) outsym);
+                                        outsym);
                  outsym += osymesz;
                }
 
@@ -2144,7 +2243,7 @@ _bfd_coff_link_input_bfd (finfo, input_bfd)
          bfd_byte *eline;
          bfd_byte *elineend;
          bfd_byte *oeline;
-         boolean skipping;
+         bfd_boolean skipping;
          file_ptr pos;
          bfd_size_type amt;
 
@@ -2164,18 +2263,18 @@ _bfd_coff_link_input_bfd (finfo, input_bfd)
          if (bfd_seek (input_bfd, o->line_filepos, SEEK_SET) != 0
              || bfd_bread (finfo->linenos, linesz * o->lineno_count,
                           input_bfd) != linesz * o->lineno_count)
-           return false;
+           return FALSE;
 
          offset = o->output_section->vma + o->output_offset - o->vma;
          eline = finfo->linenos;
          oeline = finfo->linenos;
          elineend = eline + linesz * o->lineno_count;
-         skipping = false;
+         skipping = FALSE;
          for (; eline < elineend; eline += linesz)
            {
              struct internal_lineno iline;
 
-             bfd_coff_swap_lineno_in (input_bfd, (PTR) eline, (PTR) &iline);
+             bfd_coff_swap_lineno_in (input_bfd, eline, &iline);
 
              if (iline.l_lnno != 0)
                iline.l_addr.l_paddr += offset;
@@ -2196,7 +2295,7 @@ _bfd_coff_link_input_bfd (finfo, input_bfd)
                         with symbol #0) will fail.  We can't regain
                         the space in the output file, but at least
                         they're dense.  */
-                     skipping = true;
+                     skipping = TRUE;
                    }
                  else
                    {
@@ -2211,32 +2310,31 @@ _bfd_coff_link_input_bfd (finfo, input_bfd)
                         of the line numbers rather than an absolute
                         file index.  */
                      bfd_coff_swap_sym_in (output_bfd,
-                                           (PTR) (finfo->outsyms
-                                                  + ((indx - syment_base)
-                                                     * osymesz)),
-                                           (PTR) &is);
+                                           (finfo->outsyms
+                                            + ((indx - syment_base)
+                                               * osymesz)), &is);
                      if ((ISFCN (is.n_type)
                           || is.n_sclass == C_BLOCK)
                          && is.n_numaux >= 1)
                        {
-                         PTR auxptr;
+                         void *auxptr;
 
-                         auxptr = (PTR) (finfo->outsyms
-                                         + ((indx - syment_base + 1)
-                                            * osymesz));
+                         auxptr = (finfo->outsyms
+                                   + ((indx - syment_base + 1)
+                                      * osymesz));
                          bfd_coff_swap_aux_in (output_bfd, auxptr,
                                                is.n_type, is.n_sclass,
-                                               0, is.n_numaux, (PTR) &ia);
+                                               0, is.n_numaux, &ia);
                          ia.x_sym.x_fcnary.x_fcn.x_lnnoptr =
                            (o->output_section->line_filepos
                             + o->output_section->lineno_count * linesz
                             + eline - finfo->linenos);
-                         bfd_coff_swap_aux_out (output_bfd, (PTR) &ia,
+                         bfd_coff_swap_aux_out (output_bfd, &ia,
                                                 is.n_type, is.n_sclass, 0,
                                                 is.n_numaux, auxptr);
                        }
 
-                     skipping = false;
+                     skipping = FALSE;
                    }
 
                  iline.l_addr.l_symndx = indx;
@@ -2244,8 +2342,7 @@ _bfd_coff_link_input_bfd (finfo, input_bfd)
 
              if (!skipping)
                {
-                 bfd_coff_swap_lineno_out (output_bfd, (PTR) &iline,
-                                           (PTR) oeline);
+                 bfd_coff_swap_lineno_out (output_bfd, &iline, oeline);
                  oeline += linesz;
                }
            }
@@ -2255,7 +2352,7 @@ _bfd_coff_link_input_bfd (finfo, input_bfd)
          amt = oeline - finfo->linenos;
          if (bfd_seek (output_bfd, pos, SEEK_SET) != 0
              || bfd_bwrite (finfo->linenos, amt, output_bfd) != amt)
-           return false;
+           return FALSE;
 
          o->output_section->lineno_count += amt / linesz;
        }
@@ -2269,10 +2366,10 @@ _bfd_coff_link_input_bfd (finfo, input_bfd)
       && (bfd_size_type) finfo->last_file_index >= syment_base)
     {
       finfo->last_file.n_value = output_index;
-      bfd_coff_swap_sym_out (output_bfd, (PTR) &finfo->last_file,
-                            (PTR) (finfo->outsyms
-                                   + ((finfo->last_file_index - syment_base)
-                                      * osymesz)));
+      bfd_coff_swap_sym_out (output_bfd, &finfo->last_file,
+                            (finfo->outsyms
+                             + ((finfo->last_file_index - syment_base)
+                                * osymesz)));
     }
 
   /* Write the modified symbols to the output file.  */
@@ -2285,7 +2382,7 @@ _bfd_coff_link_input_bfd (finfo, input_bfd)
       amt = outsym - finfo->outsyms;
       if (bfd_seek (output_bfd, pos, SEEK_SET) != 0
          || bfd_bwrite (finfo->outsyms, amt, output_bfd) != amt)
-       return false;
+       return FALSE;
 
       BFD_ASSERT ((obj_raw_syment_count (output_bfd)
                   + (outsym - finfo->outsyms) / osymesz)
@@ -2302,23 +2399,23 @@ _bfd_coff_link_input_bfd (finfo, input_bfd)
       struct coff_section_tdata *secdata;
 
       if (! o->linker_mark)
-       {
-         /* This section was omitted from the link.  */
-         continue;
-       }
+       /* This section was omitted from the link.  */
+       continue;
+
+      if ((o->flags & SEC_LINKER_CREATED) != 0)
+       continue;
 
       if ((o->flags & SEC_HAS_CONTENTS) == 0
-         || (o->_raw_size == 0 && (o->flags & SEC_RELOC) == 0))
+         || (o->size == 0 && (o->flags & SEC_RELOC) == 0))
        {
          if ((o->flags & SEC_RELOC) != 0
              && o->reloc_count != 0)
            {
-             ((*_bfd_error_handler)
-              (_("%s: relocs in section `%s', but it has no contents"),
-               bfd_archive_filename (input_bfd),
-               bfd_get_section_name (input_bfd, o)));
+             (*_bfd_error_handler)
+               (_("%B: relocs in section `%A', but it has no contents"),
+                input_bfd, o);
              bfd_set_error (bfd_error_no_contents);
-             return false;
+             return FALSE;
            }
 
          continue;
@@ -2329,9 +2426,9 @@ _bfd_coff_link_input_bfd (finfo, input_bfd)
        contents = secdata->contents;
       else
        {
-         if (! bfd_get_section_contents (input_bfd, o, finfo->contents,
-                                         (file_ptr) 0, o->_raw_size))
-           return false;
+         bfd_size_type x = o->rawsize ? o->rawsize : o->size;
+         if (! bfd_get_section_contents (input_bfd, o, finfo->contents, 0, x))
+           return FALSE;
          contents = finfo->contents;
        }
 
@@ -2344,14 +2441,43 @@ _bfd_coff_link_input_bfd (finfo, input_bfd)
          /* Read in the relocs.  */
          target_index = o->output_section->target_index;
          internal_relocs = (_bfd_coff_read_internal_relocs
-                            (input_bfd, o, false, finfo->external_relocs,
-                             finfo->info->relocateable,
-                             (finfo->info->relocateable
+                            (input_bfd, o, FALSE, finfo->external_relocs,
+                             finfo->info->relocatable,
+                             (finfo->info->relocatable
                               ? (finfo->section_info[target_index].relocs
                                  + o->output_section->reloc_count)
                               : finfo->internal_relocs)));
          if (internal_relocs == NULL)
-           return false;
+           return FALSE;
+
+         /* Run through the relocs looking for relocs against symbols
+            coming from discarded sections and complain about them.  */
+         irel = internal_relocs;
+         for (; irel < &internal_relocs[o->reloc_count]; irel++)
+           {
+             struct coff_link_hash_entry *h;
+             asection *ps = NULL;
+             long symndx = irel->r_symndx;
+             if (symndx < 0)
+               continue;
+             h = obj_coff_sym_hashes (input_bfd)[symndx];
+             if (h == NULL)
+               continue;
+             while (h->root.type == bfd_link_hash_indirect
+                    || h->root.type == bfd_link_hash_warning)
+               h = (struct coff_link_hash_entry *) h->root.u.i.link;
+             if (h->root.type == bfd_link_hash_defined
+                 || h->root.type == bfd_link_hash_defweak)
+               ps = h->root.u.def.section;
+             if (ps == NULL)
+               continue;
+             /* Complain if definition comes from an excluded section.  */
+             if (ps->flags & SEC_EXCLUDE)
+               (*finfo->info->callbacks->einfo)
+                 (_("%X`%s' referenced in section `%A' of %B: "
+                    "defined in discarded section `%A' of %B\n"),
+                  h->root.root.string, o, input_bfd, ps, ps->owner);
+           }
 
          /* Call processor specific code to relocate the section
              contents.  */
@@ -2361,9 +2487,9 @@ _bfd_coff_link_input_bfd (finfo, input_bfd)
                                           internal_relocs,
                                           finfo->internal_syms,
                                           finfo->sec_ptrs))
-           return false;
+           return FALSE;
 
-         if (finfo->info->relocateable)
+         if (finfo->info->relocatable)
            {
              bfd_vma offset;
              struct internal_reloc *irelend;
@@ -2377,12 +2503,11 @@ _bfd_coff_link_input_bfd (finfo, input_bfd)
              for (; irel < irelend; irel++, rel_hash++)
                {
                  struct coff_link_hash_entry *h;
-                 boolean adjusted;
+                 bfd_boolean adjusted;
 
                  *rel_hash = NULL;
 
                  /* Adjust the reloc address and symbol index.  */
-
                  irel->r_vaddr += offset;
 
                  if (irel->r_symndx == -1)
@@ -2393,7 +2518,7 @@ _bfd_coff_link_input_bfd (finfo, input_bfd)
                      if (! (*adjust_symndx) (output_bfd, finfo->info,
                                              input_bfd, o, irel,
                                              &adjusted))
-                       return false;
+                       return FALSE;
                      if (adjusted)
                        continue;
                    }
@@ -2433,18 +2558,17 @@ _bfd_coff_link_input_bfd (finfo, input_bfd)
                              stripping.  This should have been handled
                             by the 'dont_skip_symbol' code in the while
                             loop at the top of this function.  */
-
                          is = finfo->internal_syms + irel->r_symndx;
 
                          name = (_bfd_coff_internal_syment_name
                                  (input_bfd, is, buf));
                          if (name == NULL)
-                           return false;
+                           return FALSE;
 
                          if (! ((*finfo->info->callbacks->unattached_reloc)
                                 (finfo->info, name, input_bfd, o,
                                  irel->r_vaddr)))
-                           return false;
+                           return FALSE;
                        }
                    }
                }
@@ -2457,37 +2581,32 @@ _bfd_coff_link_input_bfd (finfo, input_bfd)
       if (secdata == NULL || secdata->stab_info == NULL)
        {
          file_ptr loc = o->output_offset * bfd_octets_per_byte (output_bfd);
-         bfd_size_type amt = (o->_cooked_size != 0
-                              ? o->_cooked_size : o->_raw_size);
          if (! bfd_set_section_contents (output_bfd, o->output_section,
-                                         contents, loc, amt))
-           return false;
+                                         contents, loc, o->size))
+           return FALSE;
        }
       else
        {
          if (! (_bfd_write_section_stabs
                 (output_bfd, &coff_hash_table (finfo->info)->stab_info,
                  o, &secdata->stab_info, contents)))
-           return false;
+           return FALSE;
        }
     }
 
-  if (! finfo->info->keep_memory)
-    {
-      if (! _bfd_coff_free_symbols (input_bfd))
-       return false;
-    }
+  if (! finfo->info->keep_memory
+      && ! _bfd_coff_free_symbols (input_bfd))
+    return FALSE;
 
-  return true;
+  return TRUE;
 }
 
-/* Write out a global symbol.  Called via coff_link_hash_traverse.  */
+/* Write out a global symbol.  Called via bfd_hash_traverse.  */
 
-boolean
-_bfd_coff_write_global_sym (h, data)
-     struct coff_link_hash_entry *h;
-     PTR data;
+bfd_boolean
+_bfd_coff_write_global_sym (struct bfd_hash_entry *bh, void *data)
 {
+  struct coff_link_hash_entry *h = (struct coff_link_hash_entry *) bh;
   struct coff_final_link_info *finfo = (struct coff_final_link_info *) data;
   bfd *output_bfd;
   struct internal_syment isym;
@@ -2501,19 +2620,19 @@ _bfd_coff_write_global_sym (h, data)
     {
       h = (struct coff_link_hash_entry *) h->root.u.i.link;
       if (h->root.type == bfd_link_hash_new)
-       return true;
+       return TRUE;
     }
 
   if (h->indx >= 0)
-    return true;
+    return TRUE;
 
   if (h->indx != -2
       && (finfo->info->strip == strip_all
          || (finfo->info->strip == strip_some
              && (bfd_hash_lookup (finfo->info->keep_hash,
-                                  h->root.root.string, false, false)
+                                  h->root.root.string, FALSE, FALSE)
                  == NULL))))
-    return true;
+    return TRUE;
 
   switch (h->root.type)
     {
@@ -2521,7 +2640,7 @@ _bfd_coff_write_global_sym (h, data)
     case bfd_link_hash_new:
     case bfd_link_hash_warning:
       abort ();
-      return false;
+      return FALSE;
 
     case bfd_link_hash_undefined:
     case bfd_link_hash_undefweak:
@@ -2553,31 +2672,31 @@ _bfd_coff_write_global_sym (h, data)
 
     case bfd_link_hash_indirect:
       /* Just ignore these.  They can't be handled anyhow.  */
-      return true;
+      return TRUE;
     }
 
   if (strlen (h->root.root.string) <= SYMNMLEN)
     strncpy (isym._n._n_name, h->root.root.string, SYMNMLEN);
   else
     {
-      boolean hash;
+      bfd_boolean hash;
       bfd_size_type indx;
 
-      hash = true;
+      hash = TRUE;
       if ((output_bfd->flags & BFD_TRADITIONAL_FORMAT) != 0)
-       hash = false;
+       hash = FALSE;
       indx = _bfd_stringtab_add (finfo->strtab, h->root.root.string, hash,
-                                false);
+                                FALSE);
       if (indx == (bfd_size_type) -1)
        {
-         finfo->failed = true;
-         return false;
+         finfo->failed = TRUE;
+         return FALSE;
        }
       isym._n._n_n._n_zeroes = 0;
       isym._n._n_n._n_offset = STRING_SIZE_SIZE + indx;
     }
 
-  isym.n_sclass = h->class;
+  isym.n_sclass = h->symbol_class;
   isym.n_type = h->type;
 
   if (isym.n_sclass == C_NULL)
@@ -2590,22 +2709,22 @@ _bfd_coff_write_global_sym (h, data)
   if (finfo->global_to_static)
     {
       if (! IS_EXTERNAL (output_bfd, isym))
-       return true;
+       return TRUE;
 
       isym.n_sclass = C_STAT;
     }
 
-  /* When a weak symbol is not overriden by a strong one,
+  /* When a weak symbol is not overridden by a strong one,
      turn it into an external symbol when not building a
-     shared or relocateable object.  */
+     shared or relocatable object.  */
   if (! finfo->info->shared
-      && ! finfo->info->relocateable
+      && ! finfo->info->relocatable
       && IS_WEAK_EXTERNAL (finfo->output_bfd, isym))
     isym.n_sclass = C_EXT;
 
   isym.n_numaux = h->numaux;
 
-  bfd_coff_swap_sym_out (output_bfd, (PTR) &isym, (PTR) finfo->outsyms);
+  bfd_coff_swap_sym_out (output_bfd, &isym, finfo->outsyms);
 
   symesz = bfd_coff_symesz (output_bfd);
 
@@ -2614,8 +2733,8 @@ _bfd_coff_write_global_sym (h, data)
   if (bfd_seek (output_bfd, pos, SEEK_SET) != 0
       || bfd_bwrite (finfo->outsyms, symesz, output_bfd) != symesz)
     {
-      finfo->failed = true;
-      return false;
+      finfo->failed = TRUE;
+      return FALSE;
     }
 
   h->indx = obj_raw_syment_count (output_bfd);
@@ -2646,16 +2765,13 @@ _bfd_coff_write_global_sym (h, data)
          sec = h->root.u.def.section->output_section;
          if (sec != NULL)
            {
-             auxp->x_scn.x_scnlen = (sec->_cooked_size != 0
-                                     ? sec->_cooked_size
-                                     : sec->_raw_size);
+             auxp->x_scn.x_scnlen = sec->size;
 
              /* For PE, an overflow on the final link reportedly does
                  not matter.  FIXME: Why not?  */
-
              if (sec->reloc_count > 0xffff
                  && (! obj_pe (output_bfd)
-                     || finfo->info->relocateable))
+                     || finfo->info->relocatable))
                (*_bfd_error_handler)
                  (_("%s: %s: reloc overflow: 0x%lx > 0xffff"),
                   bfd_get_filename (output_bfd),
@@ -2664,7 +2780,7 @@ _bfd_coff_write_global_sym (h, data)
 
              if (sec->lineno_count > 0xffff
                  && (! obj_pe (output_bfd)
-                     || finfo->info->relocateable))
+                     || finfo->info->relocatable))
                (*_bfd_error_handler)
                  (_("%s: warning: %s: line number overflow: 0x%lx > 0xffff"),
                   bfd_get_filename (output_bfd),
@@ -2679,32 +2795,30 @@ _bfd_coff_write_global_sym (h, data)
            }
        }
 
-      bfd_coff_swap_aux_out (output_bfd, (PTR) auxp, isym.n_type,
+      bfd_coff_swap_aux_out (output_bfd, auxp, isym.n_type,
                             isym.n_sclass, (int) i, isym.n_numaux,
-                            (PTR) finfo->outsyms);
+                            finfo->outsyms);
       if (bfd_bwrite (finfo->outsyms, symesz, output_bfd) != symesz)
        {
-         finfo->failed = true;
-         return false;
+         finfo->failed = TRUE;
+         return FALSE;
        }
       ++obj_raw_syment_count (output_bfd);
     }
 
-  return true;
+  return TRUE;
 }
 
 /* Write out task global symbols, converting them to statics.  Called
    via coff_link_hash_traverse.  Calls bfd_coff_write_global_sym to do
    the dirty work, if the symbol we are processing needs conversion.  */
 
-boolean
-_bfd_coff_write_task_globals (h, data)
-     struct coff_link_hash_entry *h;
-     PTR data;
+bfd_boolean
+_bfd_coff_write_task_globals (struct coff_link_hash_entry *h, void *data)
 {
   struct coff_final_link_info *finfo = (struct coff_final_link_info *) data;
-  boolean rtnval = true;
-  boolean save_global_to_static;
+  bfd_boolean rtnval = TRUE;
+  bfd_boolean save_global_to_static;
 
   if (h->root.type == bfd_link_hash_warning)
     h = (struct coff_link_hash_entry *) h->root.u.i.link;
@@ -2716,8 +2830,8 @@ _bfd_coff_write_task_globals (h, data)
        case bfd_link_hash_defined:
        case bfd_link_hash_defweak:
          save_global_to_static = finfo->global_to_static;
-         finfo->global_to_static = true;
-         rtnval = _bfd_coff_write_global_sym (h, data);
+         finfo->global_to_static = TRUE;
+         rtnval = _bfd_coff_write_global_sym (&h->root.root, data);
          finfo->global_to_static = save_global_to_static;
          break;
        default:
@@ -2729,12 +2843,11 @@ _bfd_coff_write_task_globals (h, data)
 
 /* Handle a link order which is supposed to generate a reloc.  */
 
-boolean
-_bfd_coff_reloc_link_order (output_bfd, finfo, output_section, link_order)
-     bfd *output_bfd;
-     struct coff_final_link_info *finfo;
-     asection *output_section;
-     struct bfd_link_order *link_order;
+bfd_boolean
+_bfd_coff_reloc_link_order (bfd *output_bfd,
+                           struct coff_final_link_info *finfo,
+                           asection *output_section,
+                           struct bfd_link_order *link_order)
 {
   reloc_howto_type *howto;
   struct internal_reloc *irel;
@@ -2744,7 +2857,7 @@ _bfd_coff_reloc_link_order (output_bfd, finfo, output_section, link_order)
   if (howto == NULL)
     {
       bfd_set_error (bfd_error_bad_value);
-      return false;
+      return FALSE;
     }
 
   if (link_order->u.reloc.p->addend != 0)
@@ -2752,13 +2865,13 @@ _bfd_coff_reloc_link_order (output_bfd, finfo, output_section, link_order)
       bfd_size_type size;
       bfd_byte *buf;
       bfd_reloc_status_type rstat;
-      boolean ok;
+      bfd_boolean ok;
       file_ptr loc;
 
       size = bfd_get_reloc_size (howto);
       buf = (bfd_byte *) bfd_zmalloc (size);
       if (buf == NULL)
-       return false;
+       return FALSE;
 
       rstat = _bfd_relocate_contents (howto, output_bfd,
                                      (bfd_vma) link_order->u.reloc.p->addend,\
@@ -2772,7 +2885,7 @@ _bfd_coff_reloc_link_order (output_bfd, finfo, output_section, link_order)
          abort ();
        case bfd_reloc_overflow:
          if (! ((*finfo->info->callbacks->reloc_overflow)
-                (finfo->info,
+                (finfo->info, NULL,
                  (link_order->type == bfd_section_reloc_link_order
                   ? bfd_section_name (output_bfd,
                                       link_order->u.reloc.p->u.section)
@@ -2781,21 +2894,20 @@ _bfd_coff_reloc_link_order (output_bfd, finfo, output_section, link_order)
                  (bfd *) NULL, (asection *) NULL, (bfd_vma) 0)))
            {
              free (buf);
-             return false;
+             return FALSE;
            }
          break;
        }
       loc = link_order->offset * bfd_octets_per_byte (output_bfd);
-      ok = bfd_set_section_contents (output_bfd, output_section, (PTR) buf,
+      ok = bfd_set_section_contents (output_bfd, output_section, buf,
                                      loc, size);
       free (buf);
       if (! ok)
-       return false;
+       return FALSE;
     }
 
   /* Store the reloc information in the right place.  It will get
      swapped and written out at the end of the final_link routine.  */
-
   irel = (finfo->section_info[output_section->target_index].relocs
          + output_section->reloc_count);
   rel_hash_ptr = (finfo->section_info[output_section->target_index].rel_hashes
@@ -2823,7 +2935,7 @@ _bfd_coff_reloc_link_order (output_bfd, finfo, output_section, link_order)
       h = ((struct coff_link_hash_entry *)
           bfd_wrapped_link_hash_lookup (output_bfd, finfo->info,
                                         link_order->u.reloc.p->u.name,
-                                        false, false, true));
+                                        FALSE, FALSE, TRUE));
       if (h != NULL)
        {
          if (h->indx >= 0)
@@ -2842,7 +2954,7 @@ _bfd_coff_reloc_link_order (output_bfd, finfo, output_section, link_order)
          if (! ((*finfo->info->callbacks->unattached_reloc)
                 (finfo->info, link_order->u.reloc.p->u.name, (bfd *) NULL,
                  (asection *) NULL, (bfd_vma) 0)))
-           return false;
+           return FALSE;
          irel->r_symndx = 0;
        }
     }
@@ -2854,27 +2966,23 @@ _bfd_coff_reloc_link_order (output_bfd, finfo, output_section, link_order)
      routines anyhow.  r_extern is only used for ECOFF.  */
 
   /* FIXME: What is the right value for r_offset?  Is zero OK?  */
-
   ++output_section->reloc_count;
 
-  return true;
+  return TRUE;
 }
 
 /* A basic reloc handling routine which may be used by processors with
    simple relocs.  */
 
-boolean
-_bfd_coff_generic_relocate_section (output_bfd, info, input_bfd,
-                                   input_section, contents, relocs, syms,
-                                   sections)
-     bfd *output_bfd;
-     struct bfd_link_info *info;
-     bfd *input_bfd;
-     asection *input_section;
-     bfd_byte *contents;
-     struct internal_reloc *relocs;
-     struct internal_syment *syms;
-     asection **sections;
+bfd_boolean
+_bfd_coff_generic_relocate_section (bfd *output_bfd,
+                                   struct bfd_link_info *info,
+                                   bfd *input_bfd,
+                                   asection *input_section,
+                                   bfd_byte *contents,
+                                   struct internal_reloc *relocs,
+                                   struct internal_syment *syms,
+                                   asection **sections)
 {
   struct internal_reloc *rel;
   struct internal_reloc *relend;
@@ -2902,9 +3010,8 @@ _bfd_coff_generic_relocate_section (output_bfd, info, input_bfd,
               || (unsigned long) symndx >= obj_raw_syment_count (input_bfd))
        {
          (*_bfd_error_handler)
-           ("%s: illegal symbol index %ld in relocs",
-            bfd_archive_filename (input_bfd), symndx);
-         return false;
+           ("%B: illegal symbol index %ld in relocs", input_bfd, symndx);
+         return FALSE;
        }
       else
        {
@@ -2916,7 +3023,6 @@ _bfd_coff_generic_relocate_section (output_bfd, info, input_bfd,
          size of the symbol is included in the section contents, or it
          is not.  We assume that the size is not included, and force
          the rtype_to_howto function to adjust the addend as needed.  */
-
       if (sym != NULL && sym->n_scnum != 0)
        addend = - sym->n_value;
       else
@@ -2925,15 +3031,15 @@ _bfd_coff_generic_relocate_section (output_bfd, info, input_bfd,
       howto = bfd_coff_rtype_to_howto (input_bfd, input_section, rel, h,
                                       sym, &addend);
       if (howto == NULL)
-       return false;
+       return FALSE;
 
-      /* If we are doing a relocateable link, then we can just ignore
+      /* If we are doing a relocatable link, then we can just ignore
          a PC relative reloc that is pcrel_offset.  It will already
-         have the correct value.  If this is not a relocateable link,
+         have the correct value.  If this is not a relocatable link,
          then we should ignore the symbol value.  */
       if (howto->pc_relative && howto->pcrel_offset)
        {
-         if (info->relocateable)
+         if (info->relocatable)
            continue;
          if (sym != NULL && sym->n_scnum != 0)
            addend += sym->n_value;
@@ -2965,23 +3071,57 @@ _bfd_coff_generic_relocate_section (output_bfd, info, input_bfd,
          if (h->root.type == bfd_link_hash_defined
              || h->root.type == bfd_link_hash_defweak)
            {
+             /* Defined weak symbols are a GNU extension. */
              asection *sec;
 
              sec = h->root.u.def.section;
              val = (h->root.u.def.value
                     + sec->output_section->vma
                     + sec->output_offset);
-             }
+           }
 
          else if (h->root.type == bfd_link_hash_undefweak)
-           val = 0;
+           {
+              if (h->symbol_class == C_NT_WEAK && h->numaux == 1)
+               {
+                 /* See _Microsoft Portable Executable and Common Object
+                     File Format Specification_, section 5.5.3.
+                    Note that weak symbols without aux records are a GNU
+                    extension.
+                    FIXME: All weak externals are treated as having
+                    characteristic IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY (1).
+                    These behave as per SVR4 ABI:  A library member
+                    will resolve a weak external only if a normal
+                    external causes the library member to be linked.
+                    See also linker.c: generic_link_check_archive_element. */
+                 asection *sec;
+                 struct coff_link_hash_entry *h2 =
+                   h->auxbfd->tdata.coff_obj_data->sym_hashes[
+                   h->aux->x_sym.x_tagndx.l];
+
+                 if (!h2 || h2->root.type == bfd_link_hash_undefined)
+                   {
+                     sec = bfd_abs_section_ptr;
+                     val = 0;
+                   }
+                 else
+                   {
+                     sec = h2->root.u.def.section;
+                     val = h2->root.u.def.value
+                       + sec->output_section->vma + sec->output_offset;
+                   }
+               }
+             else
+                /* This is a GNU extension.  */
+               val = 0;
+           }
 
-         else if (! info->relocateable)
+         else if (! info->relocatable)
            {
              if (! ((*info->callbacks->undefined_symbol)
                     (info, h->root.root.string, input_bfd, input_section,
-                     rel->r_vaddr - input_section->vma, true)))
-               return false;
+                     rel->r_vaddr - input_section->vma, TRUE)))
+               return FALSE;
            }
        }
 
@@ -2994,19 +3134,19 @@ _bfd_coff_generic_relocate_section (output_bfd, info, input_bfd,
                 absolute.  We output the address here to a file.
                 This file is then read by dlltool when generating the
                 reloc section.  Note that the base file is not
-                portable between systems.  We write out a long here,
-                and dlltool reads in a long.  */
-             long addr = (rel->r_vaddr
+                portable between systems.  We write out a bfd_vma here,
+                and dlltool reads in a bfd_vma.  */
+             bfd_vma addr = (rel->r_vaddr
                           - input_section->vma
                           + input_section->output_offset
                           + input_section->output_section->vma);
              if (coff_data (output_bfd)->pe)
                addr -= pe_data(output_bfd)->pe_opthdr.ImageBase;
-             if (fwrite (&addr, 1, sizeof (long), (FILE *) info->base_file)
-                 != sizeof (long))
+             if (fwrite (&addr, 1, sizeof (bfd_vma), (FILE *) info->base_file)
+                 != sizeof (bfd_vma))
                {
                  bfd_set_error (bfd_error_system_call);
-                 return false;
+                 return FALSE;
                }
            }
        }
@@ -3024,11 +3164,9 @@ _bfd_coff_generic_relocate_section (output_bfd, info, input_bfd,
          break;
        case bfd_reloc_outofrange:
          (*_bfd_error_handler)
-           (_("%s: bad reloc address 0x%lx in section `%s'"),
-            bfd_archive_filename (input_bfd),
-            (unsigned long) rel->r_vaddr,
-            bfd_get_section_name (input_bfd, input_section));
-         return false;
+           (_("%B: bad reloc address 0x%lx in section `%A'"),
+            input_bfd, input_section, (unsigned long) rel->r_vaddr);
+         return FALSE;
        case bfd_reloc_overflow:
          {
            const char *name;
@@ -3037,20 +3175,21 @@ _bfd_coff_generic_relocate_section (output_bfd, info, input_bfd,
            if (symndx == -1)
              name = "*ABS*";
            else if (h != NULL)
-             name = h->root.root.string;
+             name = NULL;
            else
              {
                name = _bfd_coff_internal_syment_name (input_bfd, sym, buf);
                if (name == NULL)
-                 return false;
+                 return FALSE;
              }
 
            if (! ((*info->callbacks->reloc_overflow)
-                  (info, name, howto->name, (bfd_vma) 0, input_bfd,
-                   input_section, rel->r_vaddr - input_section->vma)))
-             return false;
+                  (info, (h ? &h->root : NULL), name, howto->name,
+                   (bfd_vma) 0, input_bfd, input_section,
+                   rel->r_vaddr - input_section->vma)))
+             return FALSE;
          }
        }
     }
-  return true;
+  return TRUE;
 }