]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blobdiff - bfd/xcofflink.c
Automatic date update in version.in
[thirdparty/binutils-gdb.git] / bfd / xcofflink.c
index 7ff920aeaaf0a6d441722f310d65510bff3c4194..e7f50d169069477278e9316b561f875a9ff356bb 100644 (file)
@@ -1,6 +1,5 @@
 /* POWER/PowerPC XCOFF linker support.
-   Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-   2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+   Copyright (C) 1995-2019 Free Software Foundation, Inc.
    Written by Ian Lance Taylor <ian@cygnus.com>, Cygnus Support.
 
    This file is part of BFD, the Binary File Descriptor library.
@@ -148,7 +147,7 @@ struct xcoff_link_hash_table
     struct xcoff_link_size_list *next;
     struct xcoff_link_hash_entry *h;
     bfd_size_type size;
-  } 
+  }
   *size_list;
 
   /* Information about archives.  */
@@ -572,7 +571,22 @@ xcoff_link_hash_newfunc (struct bfd_hash_entry *entry,
   return (struct bfd_hash_entry *) ret;
 }
 
-/* Create a XCOFF link hash table.  */
+/* Destroy an XCOFF link hash table.  */
+
+static void
+_bfd_xcoff_bfd_link_hash_table_free (bfd *obfd)
+{
+  struct xcoff_link_hash_table *ret;
+
+  ret = (struct xcoff_link_hash_table *) obfd->link.hash;
+  if (ret->archive_info)
+    htab_delete (ret->archive_info);
+  if (ret->debug_strtab)
+    _bfd_stringtab_free (ret->debug_strtab);
+  _bfd_generic_link_hash_table_free (obfd);
+}
+
+/* Create an XCOFF link hash table.  */
 
 struct bfd_link_hash_table *
 _bfd_xcoff_bfd_link_hash_table_create (bfd *abfd)
@@ -580,7 +594,7 @@ _bfd_xcoff_bfd_link_hash_table_create (bfd *abfd)
   struct xcoff_link_hash_table *ret;
   bfd_size_type amt = sizeof (* ret);
 
-  ret = bfd_malloc (amt);
+  ret = bfd_zmalloc (amt);
   if (ret == NULL)
     return NULL;
   if (!_bfd_link_hash_table_init (&ret->root, abfd, xcoff_link_hash_newfunc,
@@ -591,20 +605,14 @@ _bfd_xcoff_bfd_link_hash_table_create (bfd *abfd)
     }
 
   ret->debug_strtab = _bfd_xcoff_stringtab_init ();
-  ret->debug_section = NULL;
-  ret->loader_section = NULL;
-  ret->ldrel_count = 0;
-  memset (&ret->ldhdr, 0, sizeof (struct internal_ldhdr));
-  ret->linkage_section = NULL;
-  ret->toc_section = NULL;
-  ret->descriptor_section = NULL;
-  ret->imports = NULL;
-  ret->file_align = 0;
-  ret->textro = FALSE;
-  ret->gc = FALSE;
   ret->archive_info = htab_create (37, xcoff_archive_info_hash,
                                   xcoff_archive_info_eq, NULL);
-  memset (ret->special_sections, 0, sizeof ret->special_sections);
+  if (!ret->debug_strtab || !ret->archive_info)
+    {
+      _bfd_xcoff_bfd_link_hash_table_free (abfd);
+      return NULL;
+    }
+  ret->root.hash_table_free = _bfd_xcoff_bfd_link_hash_table_free;
 
   /* The linker will always generate a full a.out header.  We need to
      record that fact now, before the sizeof_headers routine could be
@@ -613,18 +621,6 @@ _bfd_xcoff_bfd_link_hash_table_create (bfd *abfd)
 
   return &ret->root;
 }
-
-/* Free a XCOFF link hash table.  */
-
-void
-_bfd_xcoff_bfd_link_hash_table_free (struct bfd_link_hash_table *hash)
-{
-  struct xcoff_link_hash_table *ret = (struct xcoff_link_hash_table *) hash;
-
-  _bfd_stringtab_free (ret->debug_strtab);
-  bfd_hash_table_free (&ret->root.table);
-  free (ret);
-}
 \f
 /* Read internal relocs for an XCOFF csect.  This is a wrapper around
    _bfd_coff_read_internal_relocs which tries to take advantage of any
@@ -832,9 +828,9 @@ xcoff_link_add_dynamic_symbols (bfd *abfd, struct bfd_link_info *info)
      output file.  */
    if (info->output_bfd->xvec != abfd->xvec)
     {
-      (*_bfd_error_handler)
-       (_("%s: XCOFF shared object when not producing XCOFF output"),
-        bfd_get_filename (abfd));
+      _bfd_error_handler
+       (_("%pB: XCOFF shared object when not producing XCOFF output"),
+        abfd);
       bfd_set_error (bfd_error_invalid_operation);
       return FALSE;
     }
@@ -853,9 +849,9 @@ xcoff_link_add_dynamic_symbols (bfd *abfd, struct bfd_link_info *info)
   lsec = bfd_get_section_by_name (abfd, ".loader");
   if (lsec == NULL)
     {
-      (*_bfd_error_handler)
-       (_("%s: dynamic object with no .loader section"),
-        bfd_get_filename (abfd));
+      _bfd_error_handler
+       (_("%pB: dynamic object with no .loader section"),
+        abfd);
       bfd_set_error (bfd_error_no_symbols);
       return FALSE;
     }
@@ -1001,7 +997,7 @@ xcoff_link_add_dynamic_symbols (bfd *abfd, struct bfd_link_info *info)
     return FALSE;
   n->next = NULL;
 
-  if (abfd->my_archive == NULL)
+  if (abfd->my_archive == NULL || bfd_is_thin_archive (abfd->my_archive))
     {
       if (!bfd_xcoff_split_import_path (abfd, abfd->filename,
                                        &n->path, &n->file))
@@ -1054,7 +1050,7 @@ xcoff_link_create_extra_sections (bfd * abfd, struct bfd_link_info *info)
         won't work if we're producing an XCOFF output file with no
         XCOFF input files.  FIXME.  */
 
-      if (!info->relocatable
+      if (!bfd_link_relocatable (info)
          && xcoff_hash_table (info)->loader_section == NULL)
        {
          asection *lsec;
@@ -1365,11 +1361,12 @@ xcoff_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
             If C_FILE or first time, handle special
 
             Advance esym, sym_hash, csect_hash ptrs.  */
-         if (sym.n_sclass == C_FILE)
+         if (sym.n_sclass == C_FILE || sym.n_sclass == C_DWARF)
            csect = NULL;
          if (csect != NULL)
            *csect_cache = csect;
-         else if (first_csect == NULL || sym.n_sclass == C_FILE)
+         else if (first_csect == NULL
+                  || sym.n_sclass == C_FILE || sym.n_sclass == C_DWARF)
            *csect_cache = coff_section_from_bfd_index (abfd, sym.n_scnum);
          else
            *csect_cache = NULL;
@@ -1411,8 +1408,9 @@ xcoff_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
              enclosing = xcoff_section_data (abfd, csect)->enclosing;
              if (enclosing == NULL)
                {
-                 (*_bfd_error_handler)
-                   (_("%B: `%s' has line numbers but no enclosing section"),
+                 _bfd_error_handler
+                   /* xgettext:c-format */
+                   (_("%pB: `%s' has line numbers but no enclosing section"),
                     abfd, name);
                  bfd_set_error (bfd_error_bad_value);
                  goto error_return;
@@ -1463,8 +1461,9 @@ xcoff_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
       /* Pick up the csect auxiliary information.  */
       if (sym.n_numaux == 0)
        {
-         (*_bfd_error_handler)
-           (_("%B: class %d symbol `%s' has no aux entries"),
+         _bfd_error_handler
+           /* xgettext:c-format */
+           (_("%pB: class %d symbol `%s' has no aux entries"),
             abfd, sym.n_sclass, name);
          bfd_set_error (bfd_error_bad_value);
          goto error_return;
@@ -1485,8 +1484,9 @@ xcoff_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
       switch (smtyp)
        {
        default:
-         (*_bfd_error_handler)
-           (_("%B: symbol `%s' has unrecognized csect type %d"),
+         _bfd_error_handler
+           /* xgettext:c-format */
+           (_("%pB: symbol `%s' has unrecognized csect type %d"),
             abfd, name, smtyp);
          bfd_set_error (bfd_error_bad_value);
          goto error_return;
@@ -1497,10 +1497,12 @@ xcoff_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
              || sym.n_scnum != N_UNDEF
              || aux.x_csect.x_scnlen.l != 0)
            {
-             (*_bfd_error_handler)
-               (_("%B: bad XTY_ER symbol `%s': class %d scnum %d scnlen %d"),
+             _bfd_error_handler
+               /* xgettext:c-format */
+               (_("%pB: bad XTY_ER symbol `%s': class %d scnum %d "
+                  "scnlen %" PRId64),
                 abfd, name, sym.n_sclass, sym.n_scnum,
-                aux.x_csect.x_scnlen.l);
+                (int64_t) aux.x_csect.x_scnlen.l);
              bfd_set_error (bfd_error_bad_value);
              goto error_return;
            }
@@ -1526,9 +1528,10 @@ xcoff_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
              if (sym.n_sclass != C_HIDEXT
                  || aux.x_csect.x_scnlen.l != 0)
                {
-                 (*_bfd_error_handler)
-                   (_("%B: XMC_TC0 symbol `%s' is class %d scnlen %d"),
-                    abfd, name, sym.n_sclass, aux.x_csect.x_scnlen.l);
+                 _bfd_error_handler
+                   /* xgettext:c-format */
+                   (_("%pB: XMC_TC0 symbol `%s' is class %d scnlen %" PRId64),
+                    abfd, name, sym.n_sclass, (int64_t) aux.x_csect.x_scnlen.l);
                  bfd_set_error (bfd_error_bad_value);
                  goto error_return;
                }
@@ -1672,8 +1675,9 @@ xcoff_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
                    || ((bfd_vma) sym.n_value + aux.x_csect.x_scnlen.l
                        > enclosing->vma + enclosing->size)))
              {
-               (*_bfd_error_handler)
-                 (_("%B: csect `%s' not in enclosing section"),
+               _bfd_error_handler
+                 /* xgettext:c-format */
+                 (_("%pB: csect `%s' not in enclosing section"),
                   abfd, name);
                bfd_set_error (bfd_error_bad_value);
                goto error_return;
@@ -1779,13 +1783,14 @@ xcoff_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
              }
            if (bad)
              {
-               (*_bfd_error_handler)
-                 (_("%B: misplaced XTY_LD `%s'"),
+               _bfd_error_handler
+                 /* xgettext:c-format */
+                 (_("%pB: misplaced XTY_LD `%s'"),
                   abfd, name);
                bfd_set_error (bfd_error_bad_value);
                goto error_return;
              }
-           csect = section;
+           csect = section;
            value = sym.n_value - csect->vma;
          }
          break;
@@ -1922,7 +1927,7 @@ xcoff_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
             We also have to handle the case of statically linking a
             shared object, which will cause symbol redefinitions,
             although this is an easier case to detect.  */
-         else if (info->output_bfd->xvec == abfd->xvec)
+         else if (info->output_bfd->xvec == abfd->xvec)
            {
              if (! bfd_is_und_section (section))
                *sym_hash = xcoff_link_hash_lookup (xcoff_hash_table (info),
@@ -1995,13 +2000,10 @@ xcoff_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
                     sure the XCOFF linker is wholly prepared to
                     handle them, and that would only be a warning,
                     not an error.  */
-                 if (! ((*info->callbacks->multiple_definition)
-                        (info, (*sym_hash)->root.root.string,
-                         NULL, NULL, (bfd_vma) 0,
-                         (*sym_hash)->root.u.def.section->owner,
-                         (*sym_hash)->root.u.def.section,
-                         (*sym_hash)->root.u.def.value)))
-                   goto error_return;
+                 (*info->callbacks->multiple_definition) (info,
+                                                          &(*sym_hash)->root,
+                                                          NULL, NULL,
+                                                          (bfd_vma) 0);
                  /* Try not to give this error too many times.  */
                  (*sym_hash)->flags &= ~XCOFF_MULTIPLY_DEFINED;
                }
@@ -2038,7 +2040,7 @@ xcoff_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
                  = csect->alignment_power;
            }
 
-         if (info->output_bfd->xvec == abfd->xvec)
+         if (info->output_bfd->xvec == abfd->xvec)
            {
              int flag;
 
@@ -2077,6 +2079,10 @@ xcoff_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
   /* Make sure that we have seen all the relocs.  */
   for (o = abfd->sections; o != first_csect; o = o->next)
     {
+      /* Debugging sections have no csects.  */
+      if (bfd_get_section_flags (abfd, o) & SEC_DEBUGGING)
+       continue;
+
       /* Reset the section size and the line number count, since the
         data is now attached to the csects.  Don't reset the size of
         the .debug section, since we need to read it below in
@@ -2098,9 +2104,10 @@ xcoff_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
            {
              if (*rel_csect == NULL)
                {
-                 (*_bfd_error_handler)
-                   (_("%B: reloc %s:%d not in csect"),
-                    abfd, o->name, i);
+                 _bfd_error_handler
+                   /* xgettext:c-format */
+                   (_("%pB: reloc %s:%" PRId64 " not in csect"),
+                    abfd, o->name, (int64_t) i);
                  bfd_set_error (bfd_error_bad_value);
                  goto error_return;
                }
@@ -2108,7 +2115,7 @@ xcoff_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
              /* We identify all function symbols that are the target
                 of a relocation, so that we can create glue code for
                 functions imported from dynamic objects.  */
-             if (info->output_bfd->xvec == abfd->xvec
+             if (info->output_bfd->xvec == abfd->xvec
                  && *rel_csect != bfd_und_section_ptr
                  && obj_xcoff_sym_hashes (abfd)[rel->r_symndx] != NULL)
                {
@@ -2294,7 +2301,7 @@ xcoff_link_check_dynamic_ar_symbols (bfd *abfd,
        {
          if (!(*info->callbacks
                ->add_archive_element) (info, abfd, name, subsbfd))
-           return FALSE;
+           continue;
          *pneeded = TRUE;
          return TRUE;
        }
@@ -2360,13 +2367,13 @@ xcoff_link_check_ar_symbols (bfd *abfd,
             undefined references in shared objects.  */
          if (h != NULL
              && h->type == bfd_link_hash_undefined
-             && (info->output_bfd->xvec != abfd->xvec
+             && (info->output_bfd->xvec != abfd->xvec
                  || (((struct xcoff_link_hash_entry *) h)->flags
                      & XCOFF_DEF_DYNAMIC) == 0))
            {
              if (!(*info->callbacks
                    ->add_archive_element) (info, abfd, name, subsbfd))
-               return FALSE;
+               continue;
              *pneeded = TRUE;
              return TRUE;
            }
@@ -2387,6 +2394,8 @@ xcoff_link_check_ar_symbols (bfd *abfd,
 static bfd_boolean
 xcoff_link_check_archive_element (bfd *abfd,
                                  struct bfd_link_info *info,
+                                 struct bfd_link_hash_entry *h ATTRIBUTE_UNUSED,
+                                 const char *name ATTRIBUTE_UNUSED,
                                  bfd_boolean *pneeded)
 {
   bfd_boolean keep_syms_p;
@@ -2466,7 +2475,7 @@ _bfd_xcoff_bfd_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
                bfd_boolean needed;
 
                if (! xcoff_link_check_archive_element (member, info,
-                                                       &needed))
+                                                       NULL, NULL, &needed))
                  return FALSE;
                if (needed)
                  member->archive_pass = -1;
@@ -2678,10 +2687,7 @@ xcoff_need_ldrel_p (struct bfd_link_info *info, struct internal_reloc *rel,
     case R_RLA:
       /* Absolute relocations against absolute symbols can be
         resolved statically.  */
-      if (h != NULL
-         && (h->root.type == bfd_link_hash_defined
-             || h->root.type == bfd_link_hash_defweak)
-         && bfd_is_abs_section (h->root.u.def.section))
+      if (h != NULL && bfd_is_abs_symbol (&h->root))
        return FALSE;
 
       return TRUE;
@@ -2701,7 +2707,7 @@ xcoff_mark_symbol (struct bfd_link_info *info, struct xcoff_link_hash_entry *h)
 
   /* If we're marking an undefined symbol, try find some way of
      defining it.  */
-  if (!info->relocatable
+  if (!bfd_link_relocatable (info)
       && (h->flags & XCOFF_IMPORT) == 0
       && (h->flags & XCOFF_DEF_REGULAR) == 0
       && (h->root.type == bfd_link_hash_undefined
@@ -2997,7 +3003,7 @@ xcoff_sweep (struct bfd_link_info *info)
 {
   bfd *sub;
 
-  for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
+  for (sub = info->input_bfds; sub != NULL; sub = sub->link.next)
     {
       asection *o;
 
@@ -3013,6 +3019,7 @@ xcoff_sweep (struct bfd_link_info *info)
                  || o == xcoff_hash_table (info)->loader_section
                  || o == xcoff_hash_table (info)->linkage_section
                  || o == xcoff_hash_table (info)->descriptor_section
+                 || (bfd_get_section_flags (sub, o) & SEC_DEBUGGING)
                  || strcmp (o->name, ".debug") == 0)
                o->flags |= SEC_MARK;
              else
@@ -3115,15 +3122,10 @@ bfd_xcoff_import_symbol (bfd *output_bfd,
   if (val != (bfd_vma) -1)
     {
       if (h->root.type == bfd_link_hash_defined
-         && (! bfd_is_abs_section (h->root.u.def.section)
+         && (!bfd_is_abs_symbol (&h->root)
              || h->root.u.def.value != val))
-       {
-         if (! ((*info->callbacks->multiple_definition)
-                (info, h->root.root.string, h->root.u.def.section->owner,
-                 h->root.u.def.section, h->root.u.def.value,
-                 output_bfd, bfd_abs_section_ptr, val)))
-           return FALSE;
-       }
+       (*info->callbacks->multiple_definition) (info, &h->root, output_bfd,
+                                                bfd_abs_section_ptr, val);
 
       h->root.type = bfd_link_hash_defined;
       h->root.u.def.section = bfd_abs_section_ptr;
@@ -3191,7 +3193,7 @@ bfd_xcoff_link_count_reloc (bfd *output_bfd,
                                     FALSE));
   if (h == NULL)
     {
-      (*_bfd_error_handler) (_("%s: no such symbol"), name);
+      _bfd_error_handler (_("%s: no such symbol"), name);
       bfd_set_error (bfd_error_no_symbols);
       return FALSE;
     }
@@ -3295,7 +3297,7 @@ xcoff_build_ldsym (struct xcoff_loader_info *ldinfo,
   if ((h->flags & XCOFF_EXPORT) != 0
       && (h->flags & XCOFF_WAS_UNDEFINED) != 0)
     {
-      (*_bfd_error_handler)
+      _bfd_error_handler
        (_("warning: attempt to export undefined symbol `%s'"),
         h->root.root.string);
       return TRUE;
@@ -3354,9 +3356,6 @@ xcoff_post_gc_symbol (struct xcoff_link_hash_entry *h, void * p)
 {
   struct xcoff_loader_info *ldinfo = (struct xcoff_loader_info *) p;
 
-  if (h->root.type == bfd_link_hash_warning)
-    h = (struct xcoff_link_hash_entry *) h->root.u.i.link;
-
   /* __rtinit, this symbol has special handling. */
   if (h->flags & XCOFF_RTINIT)
     return TRUE;
@@ -3677,7 +3676,7 @@ bfd_xcoff_size_dynamic_sections (bfd *output_bfd,
                                     "__rtinit", FALSE, FALSE, TRUE);
       if (hsym == NULL)
        {
-         (*_bfd_error_handler)
+         _bfd_error_handler
            (_("error: undefined symbol __rtinit"));
          return FALSE;
        }
@@ -3719,14 +3718,14 @@ bfd_xcoff_size_dynamic_sections (bfd *output_bfd,
     }
 
   /* Garbage collect unused sections.  */
-  if (info->relocatable || !gc)
+  if (bfd_link_relocatable (info) || !gc)
     {
       gc = FALSE;
       xcoff_hash_table (info)->gc = FALSE;
 
       /* We still need to call xcoff_mark, in order to set ldrel_count
         correctly.  */
-      for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
+      for (sub = info->input_bfds; sub != NULL; sub = sub->link.next)
        {
          asection *o;
 
@@ -3820,7 +3819,7 @@ bfd_xcoff_size_dynamic_sections (bfd *output_bfd,
      and figure out the contents of the .debug section.  */
   debug_strtab = xcoff_hash_table (info)->debug_strtab;
 
-  for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
+  for (sub = info->input_bfds; sub != NULL; sub = sub->link.next)
     {
       asection *subdeb;
       bfd_size_type symcount;
@@ -3989,7 +3988,7 @@ bfd_xcoff_link_generate_rtinit (bfd *abfd,
   bim->size = 0;
   bim->buffer = 0;
 
-  abfd->link_next = 0;
+  abfd->link.next = 0;
   abfd->format = bfd_object;
   abfd->iostream = (void *) bim;
   abfd->flags = BFD_IN_MEMORY;
@@ -4056,8 +4055,9 @@ xcoff_create_ldrel (bfd *output_bfd, struct xcoff_final_link_info *flinfo,
        ldrel.l_symndx = 2;
       else
        {
-         (*_bfd_error_handler)
-           (_("%B: loader reloc in unrecognized section `%s'"),
+         _bfd_error_handler
+           /* xgettext:c-format */
+           (_("%pB: loader reloc in unrecognized section `%s'"),
             reference_bfd, secname);
          bfd_set_error (bfd_error_nonrepresentable_section);
          return FALSE;
@@ -4067,8 +4067,9 @@ xcoff_create_ldrel (bfd *output_bfd, struct xcoff_final_link_info *flinfo,
     {
       if (h->ldindx < 0)
        {
-         (*_bfd_error_handler)
-           (_("%B: `%s' in loader reloc but not loader sym"),
+         _bfd_error_handler
+           /* xgettext:c-format */
+           (_("%pB: `%s' in loader reloc but not loader sym"),
             reference_bfd, h->root.root.string);
          bfd_set_error (bfd_error_bad_value);
          return FALSE;
@@ -4083,8 +4084,9 @@ xcoff_create_ldrel (bfd *output_bfd, struct xcoff_final_link_info *flinfo,
   if (xcoff_hash_table (flinfo->info)->textro
       && strcmp (output_section->name, ".text") == 0)
     {
-      (*_bfd_error_handler)
-       (_("%B: loader reloc in read-only section %A"),
+      _bfd_error_handler
+       /* xgettext:c-format */
+       (_("%pB: loader reloc in read-only section %pA"),
         reference_bfd, output_section);
       bfd_set_error (bfd_error_invalid_operation);
       return FALSE;
@@ -4150,7 +4152,7 @@ xcoff_link_input_bfd (struct xcoff_final_link_info *flinfo,
   if (! flinfo->info->keep_memory)
     copy = TRUE;
   hash = TRUE;
-  if ((output_bfd->flags & BFD_TRADITIONAL_FORMAT) != 0)
+  if (flinfo->info->traditional_format)
     hash = FALSE;
 
   if (! _bfd_coff_get_external_symbols (input_bfd))
@@ -4499,7 +4501,10 @@ xcoff_link_input_bfd (struct xcoff_final_link_info *flinfo,
                          if (strings == NULL)
                            return FALSE;
                        }
-                     filename = strings + aux.x_file.x_n.x_offset;
+                     if ((bfd_size_type) aux.x_file.x_n.x_offset >= obj_coff_strings_len (input_bfd))
+                       filename = _("<corrupt>");
+                     else
+                       filename = strings + aux.x_file.x_n.x_offset;
                      indx = _bfd_stringtab_add (flinfo->strtab, filename,
                                                 hash, copy);
                      if (indx == (bfd_size_type) -1)
@@ -4729,8 +4734,8 @@ xcoff_link_input_bfd (struct xcoff_final_link_info *flinfo,
       flinfo->last_file.n_value = output_index;
       bfd_coff_swap_sym_out (output_bfd, (void *) &flinfo->last_file,
                             (void *) (flinfo->outsyms
-                                   + ((flinfo->last_file_index - syment_base)
-                                      * osymesz)));
+                                   + ((flinfo->last_file_index - syment_base)
+                                      * osymesz)));
     }
 
   /* Write the modified symbols to the output file.  */
@@ -4936,21 +4941,24 @@ xcoff_link_input_bfd (struct xcoff_final_link_info *flinfo,
                             this case, but I don't think it's worth it.  */
                          is = flinfo->internal_syms + r_symndx;
 
-                         name = (_bfd_coff_internal_syment_name
-                                 (input_bfd, is, buf));
+                         if (is->n_sclass != C_DWARF)
+                           {
+                             name = (_bfd_coff_internal_syment_name
+                                     (input_bfd, is, buf));
 
-                         if (name == NULL)
-                           return FALSE;
+                             if (name == NULL)
+                               return FALSE;
 
-                         if (! ((*flinfo->info->callbacks->unattached_reloc)
-                                (flinfo->info, name, input_bfd, o,
-                                 irel->r_vaddr)))
-                           return FALSE;
+                             (*flinfo->info->callbacks->unattached_reloc)
+                               (flinfo->info, name,
+                                input_bfd, o, irel->r_vaddr);
+                           }
                        }
                    }
                }
 
-             if (xcoff_need_ldrel_p (flinfo->info, irel, h))
+             if ((o->flags & SEC_DEBUGGING) == 0
+                 && xcoff_need_ldrel_p (flinfo->info, irel, h))
                {
                  asection *sec;
 
@@ -5053,7 +5061,7 @@ xcoff_find_tc0 (bfd *output_bfd, struct xcoff_final_link_info *flinfo)
   section_index = -1;
   for (input_bfd = flinfo->info->input_bfds;
        input_bfd != NULL;
-       input_bfd = input_bfd->link_next)
+       input_bfd = input_bfd->link.next)
     for (sec = input_bfd->sections; sec != NULL; sec = sec->next)
       if ((sec->flags & SEC_MARK) != 0 && xcoff_toc_section_p (sec))
        {
@@ -5085,7 +5093,7 @@ xcoff_find_tc0 (bfd *output_bfd, struct xcoff_final_link_info *flinfo)
       best_address = toc_end;
       for (input_bfd = flinfo->info->input_bfds;
           input_bfd != NULL;
-          input_bfd = input_bfd->link_next)
+          input_bfd = input_bfd->link.next)
        for (sec = input_bfd->sections; sec != NULL; sec = sec->next)
          if ((sec->flags & SEC_MARK) != 0 && xcoff_toc_section_p (sec))
            {
@@ -5101,10 +5109,10 @@ xcoff_find_tc0 (bfd *output_bfd, struct xcoff_final_link_info *flinfo)
       /* Make sure that the start of the TOC is also within range.  */
       if (best_address > toc_start + 0x8000)
        {
-         (*_bfd_error_handler)
-           (_("TOC overflow: 0x%lx > 0x10000; try -mminimal-toc "
+         _bfd_error_handler
+           (_("TOC overflow: %#" PRIx64 " > 0x10000; try -mminimal-toc "
               "when compiling"),
-            (unsigned long) (toc_end - toc_start));
+            (uint64_t) (toc_end - toc_start));
          bfd_set_error (bfd_error_file_too_big);
          return FALSE;
        }
@@ -5116,7 +5124,8 @@ xcoff_find_tc0 (bfd *output_bfd, struct xcoff_final_link_info *flinfo)
   xcoff_data (output_bfd)->sntoc = section_index;
 
   /* Fill out the TC0 symbol.  */
-  if (!bfd_xcoff_put_symbol_name (output_bfd, flinfo->strtab, &irsym, "TOC"))
+  if (!bfd_xcoff_put_symbol_name (output_bfd, flinfo->info, flinfo->strtab,
+                                 &irsym, "TOC"))
     return FALSE;
   irsym.n_value = best_address;
   irsym.n_scnum = section_index;
@@ -5148,8 +5157,9 @@ xcoff_find_tc0 (bfd *output_bfd, struct xcoff_final_link_info *flinfo)
 /* Write out a non-XCOFF global symbol.  */
 
 static bfd_boolean
-xcoff_write_global_symbol (struct xcoff_link_hash_entry *h, void * inf)
+xcoff_write_global_symbol (struct bfd_hash_entry *bh, void * inf)
 {
+  struct xcoff_link_hash_entry *h = (struct xcoff_link_hash_entry *) bh;
   struct xcoff_final_link_info *flinfo = (struct xcoff_final_link_info *) inf;
   bfd *output_bfd;
   bfd_byte *outsym;
@@ -5298,7 +5308,7 @@ xcoff_write_global_symbol (struct xcoff_link_hash_entry *h, void * inf)
        tocoff += h->descriptor->u.toc_offset;
 
       /* The first instruction in the glink code needs to be
-        cooked to to hold the correct offset in the toc.  The
+        cooked to hold the correct offset in the toc.  The
         rest are just output raw.  */
       bfd_put_32 (output_bfd,
                  bfd_xcoff_glink_code(output_bfd, 0) | (tocoff & 0xffff), p);
@@ -5380,7 +5390,8 @@ xcoff_write_global_symbol (struct xcoff_link_hash_entry *h, void * inf)
         the reloc.  */
       if (flinfo->info->strip != strip_all)
        {
-         result = bfd_xcoff_put_symbol_name (output_bfd, flinfo->strtab,
+         result = bfd_xcoff_put_symbol_name (output_bfd, flinfo->info,
+                                             flinfo->strtab,
                                              &irsym, h->root.root.string);
          if (!result)
            return FALSE;
@@ -5554,8 +5565,8 @@ xcoff_write_global_symbol (struct xcoff_link_hash_entry *h, void * inf)
 
   h->indx = obj_raw_syment_count (output_bfd);
 
-  result = bfd_xcoff_put_symbol_name (output_bfd, flinfo->strtab, &isym,
-                                     h->root.root.string);
+  result = bfd_xcoff_put_symbol_name (output_bfd, flinfo->info, flinfo->strtab,
+                                     &isym, h->root.root.string);
   if (!result)
     return FALSE;
 
@@ -5575,10 +5586,10 @@ xcoff_write_global_symbol (struct xcoff_link_hash_entry *h, void * inf)
            || h->root.type == bfd_link_hash_defweak)
           && h->smclas == XMC_XO)
     {
-      BFD_ASSERT (bfd_is_abs_section (h->root.u.def.section));
+      BFD_ASSERT (bfd_is_abs_symbol (&h->root));
       isym.n_value = h->root.u.def.value;
       isym.n_scnum = N_UNDEF;
-      if (h->root.type == bfd_link_hash_undefweak
+      if (h->root.type == bfd_link_hash_defweak
          && C_WEAKEXT == C_AIX_WEAKEXT)
        isym.n_sclass = C_WEAKEXT;
       else
@@ -5644,7 +5655,7 @@ xcoff_write_global_symbol (struct xcoff_link_hash_entry *h, void * inf)
       /* We just output an SD symbol.  Now output an LD symbol.  */
       h->indx += 2;
 
-      if (h->root.type == bfd_link_hash_undefweak
+      if (h->root.type == bfd_link_hash_defweak
          && C_WEAKEXT == C_AIX_WEAKEXT)
        isym.n_sclass = C_WEAKEXT;
       else
@@ -5707,9 +5718,8 @@ xcoff_reloc_link_order (bfd *output_bfd,
                                     FALSE, FALSE, TRUE));
   if (h == NULL)
     {
-      if (! ((*flinfo->info->callbacks->unattached_reloc)
-            (flinfo->info, link_order->u.reloc.p->u.name, NULL, NULL, (bfd_vma) 0)))
-       return FALSE;
+      (*flinfo->info->callbacks->unattached_reloc)
+       (flinfo->info, link_order->u.reloc.p->u.name, NULL, NULL, (bfd_vma) 0);
       return TRUE;
     }
 
@@ -5735,7 +5745,7 @@ xcoff_reloc_link_order (bfd *output_bfd,
 
       size = bfd_get_reloc_size (howto);
       buf = bfd_zmalloc (size);
-      if (buf == NULL)
+      if (buf == NULL && size != 0)
        return FALSE;
 
       rstat = _bfd_relocate_contents (howto, output_bfd, addend, buf);
@@ -5747,13 +5757,9 @@ xcoff_reloc_link_order (bfd *output_bfd,
        case bfd_reloc_outofrange:
          abort ();
        case bfd_reloc_overflow:
-         if (! ((*flinfo->info->callbacks->reloc_overflow)
-                (flinfo->info, NULL, link_order->u.reloc.p->u.name,
-                 howto->name, addend, NULL, NULL, (bfd_vma) 0)))
-           {
-             free (buf);
-             return FALSE;
-           }
+         (*flinfo->info->callbacks->reloc_overflow)
+           (flinfo->info, NULL, link_order->u.reloc.p->u.name,
+            howto->name, addend, NULL, NULL, (bfd_vma) 0);
          break;
        }
       ok = bfd_set_section_contents (output_bfd, output_section, (void *) buf,
@@ -5827,7 +5833,7 @@ _bfd_xcoff_bfd_final_link (bfd *abfd, struct bfd_link_info *info)
   file_ptr pos;
   bfd_size_type amt;
 
-  if (info->shared)
+  if (bfd_link_pic (info))
     abfd->flags |= DYNAMIC;
 
   symesz = bfd_coff_symesz (abfd);
@@ -6114,7 +6120,7 @@ _bfd_xcoff_bfd_final_link (bfd *abfd, struct bfd_link_info *info)
      input BFD's.  We want at least 6 symbols, since that is the
      number which xcoff_write_global_symbol may need.  */
   max_sym_count = 6;
-  for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
+  for (sub = info->input_bfds; sub != NULL; sub = sub->link.next)
     {
       bfd_size_type sz;
 
@@ -6233,9 +6239,7 @@ _bfd_xcoff_bfd_final_link (bfd *abfd, struct bfd_link_info *info)
 
   /* Write out all the global symbols which do not come from XCOFF
      input files.  */
-  xcoff_link_hash_traverse (xcoff_hash_table (info),
-                           xcoff_write_global_symbol,
-                           (void *) &flinfo);
+  bfd_hash_traverse (&info->hash->table, xcoff_write_global_symbol, &flinfo);
 
   if (flinfo.outsyms != NULL)
     {
@@ -6273,16 +6277,15 @@ _bfd_xcoff_bfd_final_link (bfd *abfd, struct bfd_link_info *info)
       irel = flinfo.section_info[o->target_index].relocs;
       irelend = irel + o->reloc_count;
       rel_hash = flinfo.section_info[o->target_index].rel_hashes;
-      for (; irel < irelend; irel++, rel_hash++, erel += relsz)
+      for (; irel < irelend; irel++, rel_hash++)
        {
          if (*rel_hash != NULL)
            {
              if ((*rel_hash)->indx < 0)
                {
-                 if (! ((*info->callbacks->unattached_reloc)
-                        (info, (*rel_hash)->root.root.string,
-                         NULL, o, irel->r_vaddr)))
-                   goto error_return;
+                 (*info->callbacks->unattached_reloc)
+                   (info, (*rel_hash)->root.root.string,
+                    NULL, o, irel->r_vaddr);
                  (*rel_hash)->indx = 0;
                }
              irel->r_symndx = (*rel_hash)->indx;
@@ -6295,10 +6298,9 @@ _bfd_xcoff_bfd_final_link (bfd *abfd, struct bfd_link_info *info)
        {
          if (toc_rel_hash->h->u.toc_indx < 0)
            {
-             if (! ((*info->callbacks->unattached_reloc)
-                    (info, toc_rel_hash->h->root.root.string,
-                     NULL, o, toc_rel_hash->rel->r_vaddr)))
-               goto error_return;
+             (*info->callbacks->unattached_reloc)
+               (info, toc_rel_hash->h->root.root.string,
+                NULL, o, toc_rel_hash->rel->r_vaddr);
              toc_rel_hash->h->u.toc_indx = 0;
            }
          toc_rel_hash->rel->r_symndx = toc_rel_hash->h->u.toc_indx;