2010-09-24 Thomas Schwinge <thomas@codesourcery.com>
[deliverable/binutils-gdb.git] / bfd / elflink.c
index f9b577c7738bdb6b15c50ef1b3399ad31da58de3..f4d65991fe55775974a4dcbcb86281d4bafe0c9c 100644 (file)
@@ -1,6 +1,6 @@
 /* ELF linking support for BFD.
    Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
 /* ELF linking support for BFD.
    Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-   2005, 2006, 2007, 2008, 2009
+   2005, 2006, 2007, 2008, 2009, 2010
    Free Software Foundation, Inc.
 
    This file is part of BFD, the Binary File Descriptor library.
    Free Software Foundation, Inc.
 
    This file is part of BFD, the Binary File Descriptor library.
@@ -185,7 +185,7 @@ bfd_boolean
 _bfd_elf_link_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
 {
   flagword flags;
 _bfd_elf_link_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
 {
   flagword flags;
-  register asection *s;
+  asection *s;
   const struct elf_backend_data *bed;
 
   if (! is_elf_hash_table (info->hash))
   const struct elf_backend_data *bed;
 
   if (! is_elf_hash_table (info->hash))
@@ -570,8 +570,7 @@ bfd_elf_record_link_assignment (bfd *output_bfd,
 
   if (provide && hidden)
     {
 
   if (provide && hidden)
     {
-      const struct elf_backend_data *bed = get_elf_backend_data (output_bfd);
-
+      bed = get_elf_backend_data (output_bfd);
       h->other = (h->other & ~ELF_ST_VISIBILITY (-1)) | STV_HIDDEN;
       (*bed->elf_backend_hide_symbol) (info, h, TRUE);
     }
       h->other = (h->other & ~ELF_ST_VISIBILITY (-1)) | STV_HIDDEN;
       (*bed->elf_backend_hide_symbol) (info, h, TRUE);
     }
@@ -634,7 +633,7 @@ bfd_elf_link_record_local_dynamic_symbol (struct bfd_link_info *info,
       return 1;
 
   amt = sizeof (*entry);
       return 1;
 
   amt = sizeof (*entry);
-  entry = bfd_alloc (input_bfd, amt);
+  entry = (struct elf_link_local_dynamic_entry *) bfd_alloc (input_bfd, amt);
   if (entry == NULL)
     return 0;
 
   if (entry == NULL)
     return 0;
 
@@ -719,7 +718,7 @@ static bfd_boolean
 elf_link_renumber_hash_table_dynsyms (struct elf_link_hash_entry *h,
                                      void *data)
 {
 elf_link_renumber_hash_table_dynsyms (struct elf_link_hash_entry *h,
                                      void *data)
 {
-  size_t *count = data;
+  size_t *count = (size_t *) data;
 
   if (h->root.type == bfd_link_hash_warning)
     h = (struct elf_link_hash_entry *) h->root.u.i.link;
 
   if (h->root.type == bfd_link_hash_warning)
     h = (struct elf_link_hash_entry *) h->root.u.i.link;
@@ -741,7 +740,7 @@ static bfd_boolean
 elf_link_renumber_local_hash_table_dynsyms (struct elf_link_hash_entry *h,
                                            void *data)
 {
 elf_link_renumber_local_hash_table_dynsyms (struct elf_link_hash_entry *h,
                                            void *data)
 {
-  size_t *count = data;
+  size_t *count = (size_t *) data;
 
   if (h->root.type == bfd_link_hash_warning)
     h = (struct elf_link_hash_entry *) h->root.u.i.link;
 
   if (h->root.type == bfd_link_hash_warning)
     h = (struct elf_link_hash_entry *) h->root.u.i.link;
@@ -1014,6 +1013,11 @@ _bfd_elf_merge_symbol (bfd *abfd,
       break;
     }
 
       break;
     }
 
+  /* Differentiate strong and weak symbols.  */
+  newweak = bind == STB_WEAK;
+  oldweak = (h->root.type == bfd_link_hash_defweak
+            || h->root.type == bfd_link_hash_undefweak);
+
   /* In cases involving weak versioned symbols, we may wind up trying
      to merge a symbol with itself.  Catch that here, to avoid the
      confusion that results if we try to override a symbol with
   /* In cases involving weak versioned symbols, we may wind up trying
      to merge a symbol with itself.  Catch that here, to avoid the
      confusion that results if we try to override a symbol with
@@ -1021,6 +1025,7 @@ _bfd_elf_merge_symbol (bfd *abfd,
      _GLOBAL_OFFSET_TABLE_, which are regular symbols defined in a
      dynamic object, which we do want to handle here.  */
   if (abfd == oldbfd
      _GLOBAL_OFFSET_TABLE_, which are regular symbols defined in a
      dynamic object, which we do want to handle here.  */
   if (abfd == oldbfd
+      && (newweak || oldweak)
       && ((abfd->flags & DYNAMIC) == 0
          || !h->def_regular))
     return TRUE;
       && ((abfd->flags & DYNAMIC) == 0
          || !h->def_regular))
     return TRUE;
@@ -1184,9 +1189,8 @@ _bfd_elf_merge_symbol (bfd *abfd,
             was referenced before.  */
          if (h->ref_regular)
            {
             was referenced before.  */
          if (h->ref_regular)
            {
-             const struct elf_backend_data *bed
-               = get_elf_backend_data (abfd);
              struct elf_link_hash_entry *vh = *sym_hash;
              struct elf_link_hash_entry *vh = *sym_hash;
+
              vh->root.type = h->root.type;
              h->root.type = bfd_link_hash_indirect;
              (*bed->elf_backend_copy_indirect_symbol) (info, vh, h);
              vh->root.type = h->root.type;
              h->root.type = bfd_link_hash_indirect;
              (*bed->elf_backend_copy_indirect_symbol) (info, vh, h);
@@ -1243,10 +1247,8 @@ _bfd_elf_merge_symbol (bfd *abfd,
       return TRUE;
     }
 
       return TRUE;
     }
 
-  /* Differentiate strong and weak symbols.  */
-  newweak = bind == STB_WEAK;
-  oldweak = (h->root.type == bfd_link_hash_defweak
-            || h->root.type == bfd_link_hash_undefweak);
+  if (bind == STB_GNU_UNIQUE)
+    h->unique_global = 1;
 
   /* If a new weak symbol definition comes from a regular file and the
      old symbol comes from a dynamic library, we treat the new one as
 
   /* If a new weak symbol definition comes from a regular file and the
      old symbol comes from a dynamic library, we treat the new one as
@@ -1545,7 +1547,6 @@ _bfd_elf_merge_symbol (bfd *abfd,
       /* Handle the case where we had a versioned symbol in a dynamic
         library and now find a definition in a normal object.  In this
         case, we make the versioned symbol point to the normal one.  */
       /* Handle the case where we had a versioned symbol in a dynamic
         library and now find a definition in a normal object.  In this
         case, we make the versioned symbol point to the normal one.  */
-      const struct elf_backend_data *bed = get_elf_backend_data (abfd);
       flip->root.type = h->root.type;
       flip->root.u.undef.abfd = h->root.u.undef.abfd;
       h->root.type = bfd_link_hash_indirect;
       flip->root.type = h->root.type;
       flip->root.u.undef.abfd = h->root.u.undef.abfd;
       h->root.type = bfd_link_hash_indirect;
@@ -1621,7 +1622,7 @@ _bfd_elf_add_default_symbol (bfd *abfd,
   dynamic = (abfd->flags & DYNAMIC) != 0;
 
   shortlen = p - name;
   dynamic = (abfd->flags & DYNAMIC) != 0;
 
   shortlen = p - name;
-  shortname = bfd_hash_allocate (&info->hash->table, shortlen + 1);
+  shortname = (char *) bfd_hash_allocate (&info->hash->table, shortlen + 1);
   if (shortname == NULL)
     return FALSE;
   memcpy (shortname, name, shortlen);
   if (shortname == NULL)
     return FALSE;
   memcpy (shortname, name, shortlen);
@@ -1715,7 +1716,7 @@ _bfd_elf_add_default_symbol (bfd *abfd,
        {
          if (! dynamic)
            {
        {
          if (! dynamic)
            {
-             if (info->shared
+             if (! info->executable
                  || hi->ref_dynamic)
                *dynsym = TRUE;
            }
                  || hi->ref_dynamic)
                *dynsym = TRUE;
            }
@@ -1732,7 +1733,7 @@ _bfd_elf_add_default_symbol (bfd *abfd,
 
 nondefault:
   len = strlen (name);
 
 nondefault:
   len = strlen (name);
-  shortname = bfd_hash_allocate (&info->hash->table, len);
+  shortname = (char *) bfd_hash_allocate (&info->hash->table, len);
   if (shortname == NULL)
     return FALSE;
   memcpy (shortname, name, shortlen);
   if (shortname == NULL)
     return FALSE;
   memcpy (shortname, name, shortlen);
@@ -1784,7 +1785,7 @@ nondefault:
            {
              if (! dynamic)
                {
            {
              if (! dynamic)
                {
-                 if (info->shared
+                 if (! info->executable
                      || hi->ref_dynamic)
                    *dynsym = TRUE;
                }
                      || hi->ref_dynamic)
                    *dynsym = TRUE;
                }
@@ -1806,7 +1807,7 @@ nondefault:
 static bfd_boolean
 _bfd_elf_export_symbol (struct elf_link_hash_entry *h, void *data)
 {
 static bfd_boolean
 _bfd_elf_export_symbol (struct elf_link_hash_entry *h, void *data)
 {
-  struct elf_info_failed *eif = data;
+  struct elf_info_failed *eif = (struct elf_info_failed *) data;
 
   /* Ignore this if we won't export it.  */
   if (!eif->info->export_dynamic && !h->dynamic)
 
   /* Ignore this if we won't export it.  */
   if (!eif->info->export_dynamic && !h->dynamic)
@@ -1849,7 +1850,7 @@ static bfd_boolean
 _bfd_elf_link_find_version_dependencies (struct elf_link_hash_entry *h,
                                         void *data)
 {
 _bfd_elf_link_find_version_dependencies (struct elf_link_hash_entry *h,
                                         void *data)
 {
-  struct elf_find_verdep_info *rinfo = data;
+  struct elf_find_verdep_info *rinfo = (struct elf_find_verdep_info *) data;
   Elf_Internal_Verneed *t;
   Elf_Internal_Vernaux *a;
   bfd_size_type amt;
   Elf_Internal_Verneed *t;
   Elf_Internal_Vernaux *a;
   bfd_size_type amt;
@@ -1885,7 +1886,7 @@ _bfd_elf_link_find_version_dependencies (struct elf_link_hash_entry *h,
   if (t == NULL)
     {
       amt = sizeof *t;
   if (t == NULL)
     {
       amt = sizeof *t;
-      t = bfd_zalloc (rinfo->info->output_bfd, amt);
+      t = (Elf_Internal_Verneed *) bfd_zalloc (rinfo->info->output_bfd, amt);
       if (t == NULL)
        {
          rinfo->failed = TRUE;
       if (t == NULL)
        {
          rinfo->failed = TRUE;
@@ -1898,7 +1899,7 @@ _bfd_elf_link_find_version_dependencies (struct elf_link_hash_entry *h,
     }
 
   amt = sizeof *a;
     }
 
   amt = sizeof *a;
-  a = bfd_zalloc (rinfo->info->output_bfd, amt);
+  a = (Elf_Internal_Vernaux *) bfd_zalloc (rinfo->info->output_bfd, amt);
   if (a == NULL)
     {
       rinfo->failed = TRUE;
   if (a == NULL)
     {
       rinfo->failed = TRUE;
@@ -1939,7 +1940,7 @@ _bfd_elf_link_assign_sym_version (struct elf_link_hash_entry *h, void *data)
   char *p;
   bfd_size_type amt;
 
   char *p;
   bfd_size_type amt;
 
-  sinfo = data;
+  sinfo = (struct elf_info_failed *) data;
   info = sinfo->info;
 
   if (h->root.type == bfd_link_hash_warning)
   info = sinfo->info;
 
   if (h->root.type == bfd_link_hash_warning)
@@ -1996,7 +1997,7 @@ _bfd_elf_link_assign_sym_version (struct elf_link_hash_entry *h, void *data)
              struct bfd_elf_version_expr *d;
 
              len = p - h->root.root.string;
              struct bfd_elf_version_expr *d;
 
              len = p - h->root.root.string;
-             alc = bfd_malloc (len);
+             alc = (char *) bfd_malloc (len);
              if (alc == NULL)
                {
                  sinfo->failed = TRUE;
              if (alc == NULL)
                {
                  sinfo->failed = TRUE;
@@ -2043,7 +2044,7 @@ _bfd_elf_link_assign_sym_version (struct elf_link_hash_entry *h, void *data)
            return TRUE;
 
          amt = sizeof *t;
            return TRUE;
 
          amt = sizeof *t;
-         t = bfd_zalloc (info->output_bfd, amt);
+         t = (struct bfd_elf_version_tree *) bfd_zalloc (info->output_bfd, amt);
          if (t == NULL)
            {
              sinfo->failed = TRUE;
          if (t == NULL)
            {
              sinfo->failed = TRUE;
@@ -2145,7 +2146,7 @@ elf_link_read_relocs_from_section (bfd *abfd,
       return FALSE;
     }
 
       return FALSE;
     }
 
-  erela = external_relocs;
+  erela = (const bfd_byte *) external_relocs;
   erelaend = erela + shdr->sh_size;
   irela = internal_relocs;
   while (erela < erelaend)
   erelaend = erela + shdr->sh_size;
   irela = internal_relocs;
   while (erela < erelaend)
@@ -2169,7 +2170,7 @@ elf_link_read_relocs_from_section (bfd *abfd,
              return FALSE;
            }
        }
              return FALSE;
            }
        }
-      else if (r_symndx != 0)
+      else if (r_symndx != STN_UNDEF)
        {
          (*_bfd_error_handler)
            (_("%B: non-zero symbol index (0x%lx) for offset 0x%lx in section `%A'"
        {
          (*_bfd_error_handler)
            (_("%B: non-zero symbol index (0x%lx) for offset 0x%lx in section `%A'"
@@ -2223,9 +2224,9 @@ _bfd_elf_link_read_relocs (bfd *abfd,
       size = o->reloc_count;
       size *= bed->s->int_rels_per_ext_rel * sizeof (Elf_Internal_Rela);
       if (keep_memory)
       size = o->reloc_count;
       size *= bed->s->int_rels_per_ext_rel * sizeof (Elf_Internal_Rela);
       if (keep_memory)
-       internal_relocs = alloc2 = bfd_alloc (abfd, size);
+       internal_relocs = alloc2 = (Elf_Internal_Rela *) bfd_alloc (abfd, size);
       else
       else
-       internal_relocs = alloc2 = bfd_malloc (size);
+       internal_relocs = alloc2 = (Elf_Internal_Rela *) bfd_malloc (size);
       if (internal_relocs == NULL)
        goto error_return;
     }
       if (internal_relocs == NULL)
        goto error_return;
     }
@@ -2308,7 +2309,7 @@ _bfd_elf_link_size_reloc_section (bfd *abfd,
      allocate it with bfd_alloc rather than malloc.  Also since we
      cannot be sure that the contents will actually be filled in,
      we zero the allocated space.  */
      allocate it with bfd_alloc rather than malloc.  Also since we
      cannot be sure that the contents will actually be filled in,
      we zero the allocated space.  */
-  rel_hdr->contents = bfd_zalloc (abfd, rel_hdr->sh_size);
+  rel_hdr->contents = (unsigned char *) bfd_zalloc (abfd, rel_hdr->sh_size);
   if (rel_hdr->contents == NULL && rel_hdr->sh_size != 0)
     return FALSE;
 
   if (rel_hdr->contents == NULL && rel_hdr->sh_size != 0)
     return FALSE;
 
@@ -2319,7 +2320,8 @@ _bfd_elf_link_size_reloc_section (bfd *abfd,
     {
       struct elf_link_hash_entry **p;
 
     {
       struct elf_link_hash_entry **p;
 
-      p = bfd_zmalloc (num_rel_hashes * sizeof (struct elf_link_hash_entry *));
+      p = (struct elf_link_hash_entry **)
+          bfd_zmalloc (num_rel_hashes * sizeof (struct elf_link_hash_entry *));
       if (p == NULL)
        return FALSE;
 
       if (p == NULL)
        return FALSE;
 
@@ -2568,7 +2570,7 @@ _bfd_elf_fix_symbol_flags (struct elf_link_hash_entry *h,
 static bfd_boolean
 _bfd_elf_adjust_dynamic_symbol (struct elf_link_hash_entry *h, void *data)
 {
 static bfd_boolean
 _bfd_elf_adjust_dynamic_symbol (struct elf_link_hash_entry *h, void *data)
 {
-  struct elf_info_failed *eif = data;
+  struct elf_info_failed *eif = (struct elf_info_failed *) data;
   bfd *dynobj;
   const struct elf_backend_data *bed;
 
   bfd *dynobj;
   const struct elf_backend_data *bed;
 
@@ -2602,6 +2604,7 @@ _bfd_elf_adjust_dynamic_symbol (struct elf_link_hash_entry *h, void *data)
      about symbols which are defined by one dynamic object and
      referenced by another one?  */
   if (!h->needs_plt
      about symbols which are defined by one dynamic object and
      referenced by another one?  */
   if (!h->needs_plt
+      && h->type != STT_GNU_IFUNC
       && (h->def_regular
          || !h->def_dynamic
          || (!h->ref_regular
       && (h->def_regular
          || !h->def_dynamic
          || (!h->ref_regular
@@ -2748,7 +2751,7 @@ _bfd_elf_link_sec_merge_syms (struct elf_link_hash_entry *h, void *data)
       && ((sec = h->root.u.def.section)->flags & SEC_MERGE)
       && sec->sec_info_type == ELF_INFO_TYPE_MERGE)
     {
       && ((sec = h->root.u.def.section)->flags & SEC_MERGE)
       && sec->sec_info_type == ELF_INFO_TYPE_MERGE)
     {
-      bfd *output_bfd = data;
+      bfd *output_bfd = (bfd *) data;
 
       h->root.u.def.value =
        _bfd_merged_section_offset (output_bfd,
 
       h->root.u.def.value =
        _bfd_merged_section_offset (output_bfd,
@@ -2767,7 +2770,7 @@ _bfd_elf_link_sec_merge_syms (struct elf_link_hash_entry *h, void *data)
 bfd_boolean
 _bfd_elf_dynamic_symbol_p (struct elf_link_hash_entry *h,
                           struct bfd_link_info *info,
 bfd_boolean
 _bfd_elf_dynamic_symbol_p (struct elf_link_hash_entry *h,
                           struct bfd_link_info *info,
-                          bfd_boolean ignore_protected)
+                          bfd_boolean not_local_protected)
 {
   bfd_boolean binding_stays_local_p;
   const struct elf_backend_data *bed;
 {
   bfd_boolean binding_stays_local_p;
   const struct elf_backend_data *bed;
@@ -2806,7 +2809,7 @@ _bfd_elf_dynamic_symbol_p (struct elf_link_hash_entry *h,
       /* Proper resolution for function pointer equality may require
         that these symbols perhaps be resolved dynamically, even though
         we should be resolving them to the current module.  */
       /* Proper resolution for function pointer equality may require
         that these symbols perhaps be resolved dynamically, even though
         we should be resolving them to the current module.  */
-      if (!ignore_protected || !bed->is_function_type (h->type))
+      if (!not_local_protected || !bed->is_function_type (h->type))
        binding_stays_local_p = TRUE;
       break;
 
        binding_stays_local_p = TRUE;
       break;
 
@@ -2815,7 +2818,7 @@ _bfd_elf_dynamic_symbol_p (struct elf_link_hash_entry *h,
     }
 
   /* If it isn't defined locally, then clearly it's dynamic.  */
     }
 
   /* If it isn't defined locally, then clearly it's dynamic.  */
-  if (!h->def_regular)
+  if (!h->def_regular && !ELF_COMMON_DEF_P (h))
     return TRUE;
 
   /* Otherwise, the symbol is dynamic if binding rules don't tell
     return TRUE;
 
   /* Otherwise, the symbol is dynamic if binding rules don't tell
@@ -2826,7 +2829,15 @@ _bfd_elf_dynamic_symbol_p (struct elf_link_hash_entry *h,
 /* Return true if the symbol referred to by H should be considered
    to resolve local to the current module, and false otherwise.  Differs
    from (the inverse of) _bfd_elf_dynamic_symbol_p in the treatment of
 /* Return true if the symbol referred to by H should be considered
    to resolve local to the current module, and false otherwise.  Differs
    from (the inverse of) _bfd_elf_dynamic_symbol_p in the treatment of
-   undefined symbols and weak symbols.  */
+   undefined symbols.  The two functions are virtually identical except
+   for the place where forced_local and dynindx == -1 are tested.  If
+   either of those tests are true, _bfd_elf_dynamic_symbol_p will say
+   the symbol is local, while _bfd_elf_symbol_refs_local_p will say
+   the symbol is local only for defined symbols.
+   It might seem that _bfd_elf_dynamic_symbol_p could be rewritten as
+   !_bfd_elf_symbol_refs_local_p, except that targets differ in their
+   treatment of undefined weak symbols.  For those that do not make
+   undefined weak symbols dynamic, both functions may return false.  */
 
 bfd_boolean
 _bfd_elf_symbol_refs_local_p (struct elf_link_hash_entry *h,
 
 bfd_boolean
 _bfd_elf_symbol_refs_local_p (struct elf_link_hash_entry *h,
@@ -3063,7 +3074,7 @@ _bfd_elf_add_dynamic_entry (struct bfd_link_info *info,
   BFD_ASSERT (s != NULL);
 
   newsize = s->size + bed->s->sizeof_dyn;
   BFD_ASSERT (s != NULL);
 
   newsize = s->size + bed->s->sizeof_dyn;
-  newcontents = bfd_realloc (s->contents, newsize);
+  newcontents = (bfd_byte *) bfd_realloc (s->contents, newsize);
   if (newcontents == NULL)
     return FALSE;
 
   if (newcontents == NULL)
     return FALSE;
 
@@ -3178,7 +3189,7 @@ elf_sort_symbol (const void *arg1, const void *arg2)
 static bfd_boolean
 elf_adjust_dynstr_offsets (struct elf_link_hash_entry *h, void *data)
 {
 static bfd_boolean
 elf_adjust_dynstr_offsets (struct elf_link_hash_entry *h, void *data)
 {
-  struct elf_strtab_hash *dynstr = data;
+  struct elf_strtab_hash *dynstr = (struct elf_strtab_hash *) data;
 
   if (h->root.type == bfd_link_hash_warning)
     h = (struct elf_link_hash_entry *) h->root.u.i.link;
 
   if (h->root.type == bfd_link_hash_warning)
     h = (struct elf_link_hash_entry *) h->root.u.i.link;
@@ -3229,6 +3240,8 @@ elf_finalize_dynstr (bfd *output_bfd, struct bfd_link_info *info)
        case DT_RUNPATH:
        case DT_FILTER:
        case DT_AUXILIARY:
        case DT_RUNPATH:
        case DT_FILTER:
        case DT_AUXILIARY:
+       case DT_AUDIT:
+       case DT_DEPAUDIT:
          dyn.d_un.d_val = _bfd_elf_strtab_offset (dynstr, dyn.d_un.d_val);
          break;
        default:
          dyn.d_un.d_val = _bfd_elf_strtab_offset (dynstr, dyn.d_un.d_val);
          break;
        default:
@@ -3469,7 +3482,7 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
                }
 
              sz = s->size;
                }
 
              sz = s->size;
-             msg = bfd_alloc (abfd, sz + 1);
+             msg = (char *) bfd_alloc (abfd, sz + 1);
              if (msg == NULL)
                goto error_return;
 
              if (msg == NULL)
                goto error_return;
 
@@ -3520,6 +3533,7 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
     {
       asection *s;
       const char *soname = NULL;
     {
       asection *s;
       const char *soname = NULL;
+      char *audit = NULL;
       struct bfd_link_needed_list *rpath = NULL, *runpath = NULL;
       int ret;
 
       struct bfd_link_needed_list *rpath = NULL, *runpath = NULL;
       int ret;
 
@@ -3581,12 +3595,12 @@ error_free_dyn:
                  unsigned int tagv = dyn.d_un.d_val;
 
                  amt = sizeof (struct bfd_link_needed_list);
                  unsigned int tagv = dyn.d_un.d_val;
 
                  amt = sizeof (struct bfd_link_needed_list);
-                 n = bfd_alloc (abfd, amt);
+                 n = (struct bfd_link_needed_list *) bfd_alloc (abfd, amt);
                  fnm = bfd_elf_string_from_elf_section (abfd, shlink, tagv);
                  if (n == NULL || fnm == NULL)
                    goto error_free_dyn;
                  amt = strlen (fnm) + 1;
                  fnm = bfd_elf_string_from_elf_section (abfd, shlink, tagv);
                  if (n == NULL || fnm == NULL)
                    goto error_free_dyn;
                  amt = strlen (fnm) + 1;
-                 anm = bfd_alloc (abfd, amt);
+                 anm = (char *) bfd_alloc (abfd, amt);
                  if (anm == NULL)
                    goto error_free_dyn;
                  memcpy (anm, fnm, amt);
                  if (anm == NULL)
                    goto error_free_dyn;
                  memcpy (anm, fnm, amt);
@@ -3604,12 +3618,12 @@ error_free_dyn:
                  unsigned int tagv = dyn.d_un.d_val;
 
                  amt = sizeof (struct bfd_link_needed_list);
                  unsigned int tagv = dyn.d_un.d_val;
 
                  amt = sizeof (struct bfd_link_needed_list);
-                 n = bfd_alloc (abfd, amt);
+                 n = (struct bfd_link_needed_list *) bfd_alloc (abfd, amt);
                  fnm = bfd_elf_string_from_elf_section (abfd, shlink, tagv);
                  if (n == NULL || fnm == NULL)
                    goto error_free_dyn;
                  amt = strlen (fnm) + 1;
                  fnm = bfd_elf_string_from_elf_section (abfd, shlink, tagv);
                  if (n == NULL || fnm == NULL)
                    goto error_free_dyn;
                  amt = strlen (fnm) + 1;
-                 anm = bfd_alloc (abfd, amt);
+                 anm = (char *) bfd_alloc (abfd, amt);
                  if (anm == NULL)
                    goto error_free_dyn;
                  memcpy (anm, fnm, amt);
                  if (anm == NULL)
                    goto error_free_dyn;
                  memcpy (anm, fnm, amt);
@@ -3630,12 +3644,12 @@ error_free_dyn:
                  unsigned int tagv = dyn.d_un.d_val;
 
                  amt = sizeof (struct bfd_link_needed_list);
                  unsigned int tagv = dyn.d_un.d_val;
 
                  amt = sizeof (struct bfd_link_needed_list);
-                 n = bfd_alloc (abfd, amt);
+                 n = (struct bfd_link_needed_list *) bfd_alloc (abfd, amt);
                  fnm = bfd_elf_string_from_elf_section (abfd, shlink, tagv);
                  if (n == NULL || fnm == NULL)
                    goto error_free_dyn;
                  amt = strlen (fnm) + 1;
                  fnm = bfd_elf_string_from_elf_section (abfd, shlink, tagv);
                  if (n == NULL || fnm == NULL)
                    goto error_free_dyn;
                  amt = strlen (fnm) + 1;
-                 anm = bfd_alloc (abfd, amt);
+                 anm = (char *) bfd_alloc (abfd, amt);
                  if (anm == NULL)
                    goto error_free_dyn;
                  memcpy (anm, fnm, amt);
                  if (anm == NULL)
                    goto error_free_dyn;
                  memcpy (anm, fnm, amt);
@@ -3648,6 +3662,11 @@ error_free_dyn:
                    ;
                  *pn = n;
                }
                    ;
                  *pn = n;
                }
+             if (dyn.d_tag == DT_AUDIT)
+               {
+                 unsigned int tagv = dyn.d_un.d_val;
+                 audit = bfd_elf_string_from_elf_section (abfd, shlink, tagv);
+               }
            }
 
          free (dynbuf);
            }
 
          free (dynbuf);
@@ -3700,6 +3719,9 @@ error_free_dyn:
         particular dynamic object more than once.  */
       if (ret > 0)
        return TRUE;
         particular dynamic object more than once.  */
       if (ret > 0)
        return TRUE;
+
+      /* Save the DT_AUDIT entry for the linker emulation code. */
+      elf_dt_audit (abfd) = audit; 
     }
 
   /* If this is a dynamic object, we always link against the .dynsym
     }
 
   /* If this is a dynamic object, we always link against the .dynsym
@@ -3739,7 +3761,7 @@ error_free_dyn:
       /* We store a pointer to the hash table entry for each external
         symbol.  */
       amt = extsymcount * sizeof (struct elf_link_hash_entry *);
       /* We store a pointer to the hash table entry for each external
         symbol.  */
       amt = extsymcount * sizeof (struct elf_link_hash_entry *);
-      sym_hash = bfd_alloc (abfd, amt);
+      sym_hash = (struct elf_link_hash_entry **) bfd_alloc (abfd, amt);
       if (sym_hash == NULL)
        goto error_free_sym;
       elf_sym_hashes (abfd) = sym_hash;
       if (sym_hash == NULL)
        goto error_free_sym;
       elf_sym_hashes (abfd) = sym_hash;
@@ -3759,7 +3781,7 @@ error_free_dyn:
          Elf_Internal_Shdr *versymhdr;
 
          versymhdr = &elf_tdata (abfd)->dynversym_hdr;
          Elf_Internal_Shdr *versymhdr;
 
          versymhdr = &elf_tdata (abfd)->dynversym_hdr;
-         extversym = bfd_malloc (versymhdr->sh_size);
+         extversym = (Elf_External_Versym *) bfd_malloc (versymhdr->sh_size);
          if (extversym == NULL)
            goto error_free_sym;
          amt = versymhdr->sh_size;
          if (extversym == NULL)
            goto error_free_sym;
          amt = versymhdr->sh_size;
@@ -3861,6 +3883,7 @@ error_free_dyn:
       bfd_boolean common;
       unsigned int old_alignment;
       bfd *old_bfd;
       bfd_boolean common;
       unsigned int old_alignment;
       bfd *old_bfd;
+      bfd * undef_bfd = NULL;
 
       override = FALSE;
 
 
       override = FALSE;
 
@@ -3871,24 +3894,31 @@ error_free_dyn:
       common = bed->common_definition (isym);
 
       bind = ELF_ST_BIND (isym->st_info);
       common = bed->common_definition (isym);
 
       bind = ELF_ST_BIND (isym->st_info);
-      if (bind == STB_LOCAL)
+      switch (bind)
        {
        {
+       case STB_LOCAL:
          /* This should be impossible, since ELF requires that all
             global symbols follow all local symbols, and that sh_info
             point to the first global symbol.  Unfortunately, Irix 5
             screws this up.  */
          continue;
          /* This should be impossible, since ELF requires that all
             global symbols follow all local symbols, and that sh_info
             point to the first global symbol.  Unfortunately, Irix 5
             screws this up.  */
          continue;
-       }
-      else if (bind == STB_GLOBAL)
-       {
+
+       case STB_GLOBAL:
          if (isym->st_shndx != SHN_UNDEF && !common)
            flags = BSF_GLOBAL;
          if (isym->st_shndx != SHN_UNDEF && !common)
            flags = BSF_GLOBAL;
-       }
-      else if (bind == STB_WEAK)
-       flags = BSF_WEAK;
-      else
-       {
+         break;
+
+       case STB_WEAK:
+         flags = BSF_WEAK;
+         break;
+
+       case STB_GNU_UNIQUE:
+         flags = BSF_GNU_UNIQUE;
+         break;
+
+       default:
          /* Leave it up to the processor backend.  */
          /* Leave it up to the processor backend.  */
+         break;
        }
 
       if (isym->st_shndx == SHN_UNDEF)
        }
 
       if (isym->st_shndx == SHN_UNDEF)
@@ -3978,6 +4008,20 @@ error_free_dyn:
          unsigned int vernum = 0;
          bfd_boolean skip;
 
          unsigned int vernum = 0;
          bfd_boolean skip;
 
+         /* If this is a definition of a symbol which was previously
+            referenced in a non-weak manner then make a note of the bfd
+            that contained the reference.  This is used if we need to
+            refer to the source of the reference later on.  */
+         if (! bfd_is_und_section (sec))
+           {
+             h = elf_link_hash_lookup (elf_hash_table (info), name, FALSE, FALSE, FALSE);
+
+             if (h != NULL
+                 && h->root.type == bfd_link_hash_undefined
+                 && h->root.u.undef.abfd)
+               undef_bfd = h->root.u.undef.abfd;
+           }
+         
          if (ever == NULL)
            {
              if (info->default_imported_symver)
          if (ever == NULL)
            {
              if (info->default_imported_symver)
@@ -4068,7 +4112,7 @@ error_free_dyn:
                  && isym->st_shndx != SHN_UNDEF)
                ++newlen;
 
                  && isym->st_shndx != SHN_UNDEF)
                ++newlen;
 
-             newname = bfd_hash_allocate (&htab->root.table, newlen);
+             newname = (char *) bfd_hash_allocate (&htab->root.table, newlen);
              if (newname == NULL)
                goto error_free_vers;
              memcpy (newname, name, namelen);
              if (newname == NULL)
                goto error_free_vers;
              memcpy (newname, name, namelen);
@@ -4085,6 +4129,19 @@ error_free_dyn:
              name = newname;
            }
 
              name = newname;
            }
 
+         /* If necessary, make a second attempt to locate the bfd
+            containing an unresolved, non-weak reference to the
+            current symbol.  */
+         if (! bfd_is_und_section (sec) && undef_bfd == NULL)
+           {
+             h = elf_link_hash_lookup (elf_hash_table (info), name, FALSE, FALSE, FALSE);
+
+             if (h != NULL
+                 && h->root.type == bfd_link_hash_undefined
+                 && h->root.u.undef.abfd)
+               undef_bfd = h->root.u.undef.abfd;
+           }
+
          if (!_bfd_elf_merge_symbol (abfd, info, name, isym, &sec,
                                      &value, &old_alignment,
                                      sym_hash, &skip, &override,
          if (!_bfd_elf_merge_symbol (abfd, info, name, isym, &sec,
                                      &value, &old_alignment,
                                      sym_hash, &skip, &override,
@@ -4140,7 +4197,10 @@ error_free_dyn:
       while (h->root.type == bfd_link_hash_indirect
             || h->root.type == bfd_link_hash_warning)
        h = (struct elf_link_hash_entry *) h->root.u.i.link;
       while (h->root.type == bfd_link_hash_indirect
             || h->root.type == bfd_link_hash_warning)
        h = (struct elf_link_hash_entry *) h->root.u.i.link;
+
       *sym_hash = h;
       *sym_hash = h;
+      if (is_elf_hash_table (htab))
+       h->unique_global = (flags & BSF_GNU_UNIQUE) != 0;
 
       new_weakdef = FALSE;
       if (dynamic
 
       new_weakdef = FALSE;
       if (dynamic
@@ -4348,7 +4408,6 @@ error_free_dyn:
          if (definition && (sec->flags & SEC_DEBUGGING) && !info->relocatable)
            {
              /* We don't want to make debug symbol dynamic.  */
          if (definition && (sec->flags & SEC_DEBUGGING) && !info->relocatable)
            {
              /* We don't want to make debug symbol dynamic.  */
-             (*bed->elf_backend_hide_symbol) (info, h, TRUE);
              dynsym = FALSE;
            }
 
              dynsym = FALSE;
            }
 
@@ -4371,7 +4430,8 @@ error_free_dyn:
                    {
                      amt = ((isymend - isym + 1)
                             * sizeof (struct elf_link_hash_entry *));
                    {
                      amt = ((isymend - isym + 1)
                             * sizeof (struct elf_link_hash_entry *));
-                     nondeflt_vers = bfd_malloc (amt);
+                     nondeflt_vers =
+                          (struct elf_link_hash_entry **) bfd_malloc (amt);
                      if (!nondeflt_vers)
                        goto error_free_vers;
                    }
                      if (!nondeflt_vers)
                        goto error_free_vers;
                    }
@@ -4418,17 +4478,23 @@ error_free_dyn:
              /* A symbol from a library loaded via DT_NEEDED of some
                 other library is referenced by a regular object.
                 Add a DT_NEEDED entry for it.  Issue an error if
              /* A symbol from a library loaded via DT_NEEDED of some
                 other library is referenced by a regular object.
                 Add a DT_NEEDED entry for it.  Issue an error if
-                --no-add-needed is used.  */
-             if ((elf_dyn_lib_class (abfd) & DYN_NO_NEEDED) != 0)
+                --no-add-needed is used and the reference was not
+                a weak one.  */
+             if (undef_bfd != NULL
+                 && (elf_dyn_lib_class (abfd) & DYN_NO_NEEDED) != 0)
                {
                  (*_bfd_error_handler)
                {
                  (*_bfd_error_handler)
-                   (_("%s: invalid DSO for symbol `%s' definition"),
+                   (_("%B: undefined reference to symbol '%s'"),
+                    undef_bfd, name);
+                 (*_bfd_error_handler)
+                   (_("note: '%s' is defined in DSO %B so try adding it to the linker command line"),
                     abfd, name);
                     abfd, name);
-                 bfd_set_error (bfd_error_bad_value);
+                 bfd_set_error (bfd_error_invalid_operation);
                  goto error_free_vers;
                }
 
                  goto error_free_vers;
                }
 
-             elf_dyn_lib_class (abfd) &= ~DYN_AS_NEEDED;
+             elf_dyn_lib_class (abfd) = (enum dynamic_lib_link_class)
+                  (elf_dyn_lib_class (abfd) & ~DYN_AS_NEEDED);
 
              add_needed = TRUE;
              ret = elf_add_dt_needed_tag (abfd, info, soname, add_needed);
 
              add_needed = TRUE;
              ret = elf_add_dt_needed_tag (abfd, info, soname, add_needed);
@@ -4534,7 +4600,7 @@ error_free_dyn:
            continue;
 
          amt = p - h->root.root.string;
            continue;
 
          amt = p - h->root.root.string;
-         shortname = bfd_malloc (amt + 1);
+         shortname = (char *) bfd_malloc (amt + 1);
          if (!shortname)
            goto error_free_vers;
          memcpy (shortname, h->root.root.string, amt);
          if (!shortname)
            goto error_free_vers;
          memcpy (shortname, h->root.root.string, amt);
@@ -4592,7 +4658,7 @@ error_free_dyn:
         defined symbol, search time for N weak defined symbols will be
         O(N^2). Binary search will cut it down to O(NlogN).  */
       amt = extsymcount * sizeof (struct elf_link_hash_entry *);
         defined symbol, search time for N weak defined symbols will be
         O(N^2). Binary search will cut it down to O(NlogN).  */
       amt = extsymcount * sizeof (struct elf_link_hash_entry *);
-      sorted_sym_hash = bfd_malloc (amt);
+      sorted_sym_hash = (struct elf_link_hash_entry **) bfd_malloc (amt);
       if (sorted_sym_hash == NULL)
        goto error_return;
       sym_hash = sorted_sym_hash;
       if (sorted_sym_hash == NULL)
        goto error_return;
       sym_hash = sorted_sym_hash;
@@ -4734,6 +4800,7 @@ error_free_dyn:
   if (! dynamic
       && is_elf_hash_table (htab)
       && bed->check_relocs != NULL
   if (! dynamic
       && is_elf_hash_table (htab)
       && bed->check_relocs != NULL
+      && elf_object_id (abfd) == elf_hash_table_id (htab)
       && (*bed->relocs_compatible) (abfd->xvec, info->output_bfd->xvec))
     {
       asection *o;
       && (*bed->relocs_compatible) (abfd->xvec, info->output_bfd->xvec))
     {
       asection *o;
@@ -4805,7 +4872,8 @@ error_free_dyn:
       /* Add this bfd to the loaded list.  */
       struct elf_link_loaded_list *n;
 
       /* Add this bfd to the loaded list.  */
       struct elf_link_loaded_list *n;
 
-      n = bfd_alloc (abfd, sizeof (struct elf_link_loaded_list));
+      n = (struct elf_link_loaded_list *)
+          bfd_alloc (abfd, sizeof (struct elf_link_loaded_list));
       if (n == NULL)
        goto error_return;
       n->abfd = abfd;
       if (n == NULL)
        goto error_return;
       n->abfd = abfd;
@@ -4856,7 +4924,7 @@ _bfd_elf_archive_symbol_lookup (bfd *abfd,
 
   /* First check with only one `@'.  */
   len = strlen (name);
 
   /* First check with only one `@'.  */
   len = strlen (name);
-  copy = bfd_alloc (abfd, len);
+  copy = (char *) bfd_alloc (abfd, len);
   if (copy == NULL)
     return (struct elf_link_hash_entry *) 0 - 1;
 
   if (copy == NULL)
     return (struct elf_link_hash_entry *) 0 - 1;
 
@@ -4933,8 +5001,8 @@ elf_link_add_archive_symbols (bfd *abfd, struct bfd_link_info *info)
     return TRUE;
   amt = c;
   amt *= sizeof (bfd_boolean);
     return TRUE;
   amt = c;
   amt *= sizeof (bfd_boolean);
-  defined = bfd_zmalloc (amt);
-  included = bfd_zmalloc (amt);
+  defined = (bfd_boolean *) bfd_zmalloc (amt);
+  included = (bfd_boolean *) bfd_zmalloc (amt);
   if (defined == NULL || included == NULL)
     goto error_return;
 
   if (defined == NULL || included == NULL)
     goto error_return;
 
@@ -5098,7 +5166,7 @@ struct hash_codes_info
 static bfd_boolean
 elf_collect_hash_codes (struct elf_link_hash_entry *h, void *data)
 {
 static bfd_boolean
 elf_collect_hash_codes (struct elf_link_hash_entry *h, void *data)
 {
-  struct hash_codes_info *inf = data;
+  struct hash_codes_info *inf = (struct hash_codes_info *) data;
   const char *name;
   char *p;
   unsigned long ha;
   const char *name;
   char *p;
   unsigned long ha;
@@ -5115,7 +5183,7 @@ elf_collect_hash_codes (struct elf_link_hash_entry *h, void *data)
   p = strchr (name, ELF_VER_CHR);
   if (p != NULL)
     {
   p = strchr (name, ELF_VER_CHR);
   if (p != NULL)
     {
-      alc = bfd_malloc (p - name + 1);
+      alc = (char *) bfd_malloc (p - name + 1);
       if (alc == NULL)
        {
          inf->error = TRUE;
       if (alc == NULL)
        {
          inf->error = TRUE;
@@ -5169,7 +5237,7 @@ struct collect_gnu_hash_codes
 static bfd_boolean
 elf_collect_gnu_hash_codes (struct elf_link_hash_entry *h, void *data)
 {
 static bfd_boolean
 elf_collect_gnu_hash_codes (struct elf_link_hash_entry *h, void *data)
 {
-  struct collect_gnu_hash_codes *s = data;
+  struct collect_gnu_hash_codes *s = (struct collect_gnu_hash_codes *) data;
   const char *name;
   char *p;
   unsigned long ha;
   const char *name;
   char *p;
   unsigned long ha;
@@ -5190,7 +5258,7 @@ elf_collect_gnu_hash_codes (struct elf_link_hash_entry *h, void *data)
   p = strchr (name, ELF_VER_CHR);
   if (p != NULL)
     {
   p = strchr (name, ELF_VER_CHR);
   if (p != NULL)
     {
-      alc = bfd_malloc (p - name + 1);
+      alc = (char *) bfd_malloc (p - name + 1);
       if (alc == NULL)
        {
          s->error = TRUE;
       if (alc == NULL)
        {
          s->error = TRUE;
@@ -5224,7 +5292,7 @@ elf_collect_gnu_hash_codes (struct elf_link_hash_entry *h, void *data)
 static bfd_boolean
 elf_renumber_gnu_hash_syms (struct elf_link_hash_entry *h, void *data)
 {
 static bfd_boolean
 elf_renumber_gnu_hash_syms (struct elf_link_hash_entry *h, void *data)
 {
-  struct collect_gnu_hash_codes *s = data;
+  struct collect_gnu_hash_codes *s = (struct collect_gnu_hash_codes *) data;
   unsigned long int bucket;
   unsigned long int val;
 
   unsigned long int bucket;
   unsigned long int val;
 
@@ -5294,7 +5362,7 @@ static const size_t elf_buckets[] =
    Therefore the result is always a good payoff between few collisions
    (= short chain lengths) and table size.  */
 static size_t
    Therefore the result is always a good payoff between few collisions
    (= short chain lengths) and table size.  */
 static size_t
-compute_bucket_count (struct bfd_link_info *info,
+compute_bucket_count (struct bfd_link_info *info ATTRIBUTE_UNUSED,
                      unsigned long int *hashcodes ATTRIBUTE_UNUSED,
                      unsigned long int nsyms,
                      int gnu_hash)
                      unsigned long int *hashcodes ATTRIBUTE_UNUSED,
                      unsigned long int nsyms,
                      int gnu_hash)
@@ -5316,6 +5384,7 @@ compute_bucket_count (struct bfd_link_info *info,
       const struct elf_backend_data *bed = get_elf_backend_data (dynobj);
       unsigned long int *counts;
       bfd_size_type amt;
       const struct elf_backend_data *bed = get_elf_backend_data (dynobj);
       unsigned long int *counts;
       bfd_size_type amt;
+      unsigned int no_improvement_count = 0;
 
       /* Possible optimization parameters: if we have NSYMS symbols we say
         that the hashing table must at least have NSYMS/4 and at most
 
       /* Possible optimization parameters: if we have NSYMS symbols we say
         that the hashing table must at least have NSYMS/4 and at most
@@ -5336,7 +5405,7 @@ compute_bucket_count (struct bfd_link_info *info,
         since the size could be large.  */
       amt = maxsize;
       amt *= sizeof (unsigned long int);
         since the size could be large.  */
       amt = maxsize;
       amt *= sizeof (unsigned long int);
-      counts = bfd_malloc (amt);
+      counts = (unsigned long int *) bfd_malloc (amt);
       if (counts == NULL)
        return 0;
 
       if (counts == NULL)
        return 0;
 
@@ -5400,7 +5469,12 @@ compute_bucket_count (struct bfd_link_info *info,
            {
              best_chlen = max;
              best_size = i;
            {
              best_chlen = max;
              best_size = i;
+              no_improvement_count = 0;
            }
            }
+         /* PR 11843: Avoid futile long searches for the best bucket size
+            when there are a large number of symbols.  */
+         else if (++no_improvement_count == 100)
+           break;
        }
 
       free (counts);
        }
 
       free (counts);
@@ -5424,6 +5498,20 @@ compute_bucket_count (struct bfd_link_info *info,
   return best_size;
 }
 
   return best_size;
 }
 
+/* Size any SHT_GROUP section for ld -r.  */
+
+bfd_boolean
+_bfd_elf_size_group_sections (struct bfd_link_info *info)
+{
+  bfd *ibfd;
+
+  for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
+    if (bfd_get_flavour (ibfd) == bfd_target_elf_flavour
+       && !_bfd_elf_fixup_group_sections (ibfd, bfd_abs_section_ptr))
+      return FALSE;
+  return TRUE;
+}
+
 /* Set up the sizes and contents of the ELF dynamic sections.  This is
    called by the ELF linker emulation before_allocation routine.  We
    must set the sizes of the sections before the linker sets the
 /* Set up the sizes and contents of the ELF dynamic sections.  This is
    called by the ELF linker emulation before_allocation routine.  We
    must set the sizes of the sections before the linker sets the
@@ -5434,6 +5522,8 @@ bfd_elf_size_dynamic_sections (bfd *output_bfd,
                               const char *soname,
                               const char *rpath,
                               const char *filter_shlib,
                               const char *soname,
                               const char *rpath,
                               const char *filter_shlib,
+                              const char *audit,
+                              const char *depaudit,
                               const char * const *auxiliary_filters,
                               struct bfd_link_info *info,
                               asection **sinterpptr,
                               const char * const *auxiliary_filters,
                               struct bfd_link_info *info,
                               asection **sinterpptr,
@@ -5496,6 +5586,10 @@ bfd_elf_size_dynamic_sections (bfd *output_bfd,
   elf_hash_table (info)->init_plt_refcount
     = elf_hash_table (info)->init_plt_offset;
 
   elf_hash_table (info)->init_plt_refcount
     = elf_hash_table (info)->init_plt_offset;
 
+  if (info->relocatable
+      && !_bfd_elf_size_group_sections (info))
+    return FALSE;
+
   /* The backend may have to create some sections regardless of whether
      we're dynamic or not.  */
   if (bed->elf_backend_always_size_sections
   /* The backend may have to create some sections regardless of whether
      we're dynamic or not.  */
   if (bed->elf_backend_always_size_sections
@@ -5586,6 +5680,28 @@ bfd_elf_size_dynamic_sections (bfd *output_bfd,
            }
        }
 
            }
        }
 
+      if (audit != NULL)
+       {
+         bfd_size_type indx;
+
+         indx = _bfd_elf_strtab_add (elf_hash_table (info)->dynstr, audit,
+                                     TRUE);
+         if (indx == (bfd_size_type) -1
+             || !_bfd_elf_add_dynamic_entry (info, DT_AUDIT, indx))
+           return FALSE;
+       }
+
+      if (depaudit != NULL)
+       {
+         bfd_size_type indx;
+
+         indx = _bfd_elf_strtab_add (elf_hash_table (info)->dynstr, depaudit,
+                                     TRUE);
+         if (indx == (bfd_size_type) -1
+             || !_bfd_elf_add_dynamic_entry (info, DT_DEPAUDIT, indx))
+           return FALSE;
+       }
+
       eif.info = info;
       eif.verdefs = verdefs;
       eif.failed = FALSE;
       eif.info = info;
       eif.verdefs = verdefs;
       eif.failed = FALSE;
@@ -5618,7 +5734,7 @@ bfd_elf_size_dynamic_sections (bfd *output_bfd,
              verlen = strlen (verstr);
              newlen = namelen + verlen + 3;
 
              verlen = strlen (verstr);
              newlen = namelen + verlen + 3;
 
-             newname = bfd_malloc (newlen);
+             newname = (char *) bfd_malloc (newlen);
              if (newname == NULL)
                return FALSE;
              memcpy (newname, name, namelen);
              if (newname == NULL)
                return FALSE;
              memcpy (newname, name, namelen);
@@ -5847,6 +5963,10 @@ bfd_elf_size_dynamic_sections (bfd *output_bfd,
            {
              struct bfd_elf_version_deps *n;
 
            {
              struct bfd_elf_version_deps *n;
 
+             /* Don't emit base version twice.  */
+             if (t->vernum == 0)
+               continue;
+
              size += sizeof (Elf_External_Verdef);
              size += sizeof (Elf_External_Verdaux);
              ++cdefs;
              size += sizeof (Elf_External_Verdef);
              size += sizeof (Elf_External_Verdaux);
              ++cdefs;
@@ -5856,7 +5976,7 @@ bfd_elf_size_dynamic_sections (bfd *output_bfd,
            }
 
          s->size = size;
            }
 
          s->size = size;
-         s->contents = bfd_alloc (output_bfd, s->size);
+         s->contents = (unsigned char *) bfd_alloc (output_bfd, s->size);
          if (s->contents == NULL && s->size != 0)
            return FALSE;
 
          if (s->contents == NULL && s->size != 0)
            return FALSE;
 
@@ -5946,6 +6066,10 @@ bfd_elf_size_dynamic_sections (bfd *output_bfd,
              unsigned int cdeps;
              struct bfd_elf_version_deps *n;
 
              unsigned int cdeps;
              struct bfd_elf_version_deps *n;
 
+             /* Don't emit the base version twice.  */
+             if (t->vernum == 0)
+               continue;
+
              cdeps = 0;
              for (n = t->deps; n != NULL; n = n->next)
                ++cdeps;
              cdeps = 0;
              for (n = t->deps; n != NULL; n = n->next)
                ++cdeps;
@@ -5977,7 +6101,13 @@ bfd_elf_size_dynamic_sections (bfd *output_bfd,
              def.vd_hash = bfd_elf_hash (t->name);
              def.vd_aux = sizeof (Elf_External_Verdef);
              def.vd_next = 0;
              def.vd_hash = bfd_elf_hash (t->name);
              def.vd_aux = sizeof (Elf_External_Verdef);
              def.vd_next = 0;
-             if (t->next != NULL)
+
+             /* If a basever node is next, it *must* be the last node in
+                the chain, otherwise Verdef construction breaks.  */
+             if (t->next != NULL && t->next->vernum == 0)
+               BFD_ASSERT (t->next->next == NULL);
+
+             if (t->next != NULL && t->next->vernum != 0)
                def.vd_next = (sizeof (Elf_External_Verdef)
                               + (cdeps + 1) * sizeof (Elf_External_Verdaux));
 
                def.vd_next = (sizeof (Elf_External_Verdef)
                               + (cdeps + 1) * sizeof (Elf_External_Verdaux));
 
@@ -6078,7 +6208,7 @@ bfd_elf_size_dynamic_sections (bfd *output_bfd,
            unsigned int crefs;
            bfd_byte *p;
 
            unsigned int crefs;
            bfd_byte *p;
 
-           /* Build the version definition section.  */
+           /* Build the version dependency section.  */
            size = 0;
            crefs = 0;
            for (t = elf_tdata (output_bfd)->verref;
            size = 0;
            crefs = 0;
            for (t = elf_tdata (output_bfd)->verref;
@@ -6094,7 +6224,7 @@ bfd_elf_size_dynamic_sections (bfd *output_bfd,
              }
 
            s->size = size;
              }
 
            s->size = size;
-           s->contents = bfd_alloc (output_bfd, s->size);
+           s->contents = (unsigned char *) bfd_alloc (output_bfd, s->size);
            if (s->contents == NULL)
              return FALSE;
 
            if (s->contents == NULL)
              return FALSE;
 
@@ -6254,7 +6384,7 @@ bfd_elf_size_dynsym_hash_dynstr (bfd *output_bfd, struct bfd_link_info *info)
          && (s->flags & SEC_EXCLUDE) == 0)
        {
          s->size = dynsymcount * sizeof (Elf_External_Versym);
          && (s->flags & SEC_EXCLUDE) == 0)
        {
          s->size = dynsymcount * sizeof (Elf_External_Versym);
-         s->contents = bfd_zalloc (output_bfd, s->size);
+         s->contents = (unsigned char *) bfd_zalloc (output_bfd, s->size);
          if (s->contents == NULL)
            return FALSE;
 
          if (s->contents == NULL)
            return FALSE;
 
@@ -6274,7 +6404,7 @@ bfd_elf_size_dynsym_hash_dynstr (bfd *output_bfd, struct bfd_link_info *info)
 
       if (dynsymcount != 0)
        {
 
       if (dynsymcount != 0)
        {
-         s->contents = bfd_alloc (output_bfd, s->size);
+         s->contents = (unsigned char *) bfd_alloc (output_bfd, s->size);
          if (s->contents == NULL)
            return FALSE;
 
          if (s->contents == NULL)
            return FALSE;
 
@@ -6301,7 +6431,7 @@ bfd_elf_size_dynsym_hash_dynstr (bfd *output_bfd, struct bfd_link_info *info)
             time store the values in an array so that we could use them for
             optimizations.  */
          amt = dynsymcount * sizeof (unsigned long int);
             time store the values in an array so that we could use them for
             optimizations.  */
          amt = dynsymcount * sizeof (unsigned long int);
-         hashcodes = bfd_malloc (amt);
+         hashcodes = (unsigned long int *) bfd_malloc (amt);
          if (hashcodes == NULL)
            return FALSE;
          hashinf.hashcodes = hashcodes;
          if (hashcodes == NULL)
            return FALSE;
          hashinf.hashcodes = hashcodes;
@@ -6330,7 +6460,7 @@ bfd_elf_size_dynsym_hash_dynstr (bfd *output_bfd, struct bfd_link_info *info)
          BFD_ASSERT (s != NULL);
          hash_entry_size = elf_section_data (s)->this_hdr.sh_entsize;
          s->size = ((2 + bucketcount + dynsymcount) * hash_entry_size);
          BFD_ASSERT (s != NULL);
          hash_entry_size = elf_section_data (s)->this_hdr.sh_entsize;
          s->size = ((2 + bucketcount + dynsymcount) * hash_entry_size);
-         s->contents = bfd_zalloc (output_bfd, s->size);
+         s->contents = (unsigned char *) bfd_zalloc (output_bfd, s->size);
          if (s->contents == NULL)
            return FALSE;
 
          if (s->contents == NULL)
            return FALSE;
 
@@ -6353,7 +6483,7 @@ bfd_elf_size_dynsym_hash_dynstr (bfd *output_bfd, struct bfd_link_info *info)
             time store the values in an array so that we could use them for
             optimizations.  */
          amt = dynsymcount * 2 * sizeof (unsigned long int);
             time store the values in an array so that we could use them for
             optimizations.  */
          amt = dynsymcount * 2 * sizeof (unsigned long int);
-         cinfo.hashcodes = bfd_malloc (amt);
+         cinfo.hashcodes = (long unsigned int *) bfd_malloc (amt);
          if (cinfo.hashcodes == NULL)
            return FALSE;
 
          if (cinfo.hashcodes == NULL)
            return FALSE;
 
@@ -6389,7 +6519,7 @@ bfd_elf_size_dynsym_hash_dynstr (bfd *output_bfd, struct bfd_link_info *info)
              BFD_ASSERT (cinfo.min_dynindx == -1);
              free (cinfo.hashcodes);
              s->size = 5 * 4 + bed->s->arch_size / 8;
              BFD_ASSERT (cinfo.min_dynindx == -1);
              free (cinfo.hashcodes);
              s->size = 5 * 4 + bed->s->arch_size / 8;
-             contents = bfd_zalloc (output_bfd, s->size);
+             contents = (unsigned char *) bfd_zalloc (output_bfd, s->size);
              if (contents == NULL)
                return FALSE;
              s->contents = contents;
              if (contents == NULL)
                return FALSE;
              s->contents = contents;
@@ -6433,14 +6563,14 @@ bfd_elf_size_dynsym_hash_dynstr (bfd *output_bfd, struct bfd_link_info *info)
              maskwords = 1 << (maskbitslog2 - cinfo.shift1);
              amt = bucketcount * sizeof (unsigned long int) * 2;
              amt += maskwords * sizeof (bfd_vma);
              maskwords = 1 << (maskbitslog2 - cinfo.shift1);
              amt = bucketcount * sizeof (unsigned long int) * 2;
              amt += maskwords * sizeof (bfd_vma);
-             cinfo.bitmask = bfd_malloc (amt);
+             cinfo.bitmask = (bfd_vma *) bfd_malloc (amt);
              if (cinfo.bitmask == NULL)
                {
                  free (cinfo.hashcodes);
                  return FALSE;
                }
 
              if (cinfo.bitmask == NULL)
                {
                  free (cinfo.hashcodes);
                  return FALSE;
                }
 
-             cinfo.counts = (void *) (cinfo.bitmask + maskwords);
+             cinfo.counts = (long unsigned int *) (cinfo.bitmask + maskwords);
              cinfo.indx = cinfo.counts + bucketcount;
              cinfo.symindx = dynsymcount - cinfo.nsyms;
              memset (cinfo.bitmask, 0, maskwords * sizeof (bfd_vma));
              cinfo.indx = cinfo.counts + bucketcount;
              cinfo.symindx = dynsymcount - cinfo.nsyms;
              memset (cinfo.bitmask, 0, maskwords * sizeof (bfd_vma));
@@ -6462,7 +6592,7 @@ bfd_elf_size_dynsym_hash_dynstr (bfd *output_bfd, struct bfd_link_info *info)
 
              s->size = (4 + bucketcount + cinfo.nsyms) * 4;
              s->size += cinfo.maskbits / 8;
 
              s->size = (4 + bucketcount + cinfo.nsyms) * 4;
              s->size += cinfo.maskbits / 8;
-             contents = bfd_zalloc (output_bfd, s->size);
+             contents = (unsigned char *) bfd_zalloc (output_bfd, s->size);
              if (contents == NULL)
                {
                  free (cinfo.bitmask);
              if (contents == NULL)
                {
                  free (cinfo.bitmask);
@@ -6586,7 +6716,8 @@ _bfd_elf_link_hash_newfunc (struct bfd_hash_entry *entry,
      subclass.  */
   if (entry == NULL)
     {
      subclass.  */
   if (entry == NULL)
     {
-      entry = bfd_hash_allocate (table, sizeof (struct elf_link_hash_entry));
+      entry = (struct bfd_hash_entry *)
+          bfd_hash_allocate (table, sizeof (struct elf_link_hash_entry));
       if (entry == NULL)
        return entry;
     }
       if (entry == NULL)
        return entry;
     }
@@ -6700,7 +6831,8 @@ _bfd_elf_link_hash_table_init
    struct bfd_hash_entry *(*newfunc) (struct bfd_hash_entry *,
                                      struct bfd_hash_table *,
                                      const char *),
    struct bfd_hash_entry *(*newfunc) (struct bfd_hash_entry *,
                                      struct bfd_hash_table *,
                                      const char *),
-   unsigned int entsize)
+   unsigned int entsize,
+   enum elf_target_id target_id)
 {
   bfd_boolean ret;
   int can_refcount = get_elf_backend_data (abfd)->can_refcount;
 {
   bfd_boolean ret;
   int can_refcount = get_elf_backend_data (abfd)->can_refcount;
@@ -6714,7 +6846,9 @@ _bfd_elf_link_hash_table_init
   table->dynsymcount = 1;
 
   ret = _bfd_link_hash_table_init (&table->root, abfd, newfunc, entsize);
   table->dynsymcount = 1;
 
   ret = _bfd_link_hash_table_init (&table->root, abfd, newfunc, entsize);
+
   table->root.type = bfd_link_elf_hash_table;
   table->root.type = bfd_link_elf_hash_table;
+  table->hash_table_id = target_id;
 
   return ret;
 }
 
   return ret;
 }
@@ -6727,12 +6861,13 @@ _bfd_elf_link_hash_table_create (bfd *abfd)
   struct elf_link_hash_table *ret;
   bfd_size_type amt = sizeof (struct elf_link_hash_table);
 
   struct elf_link_hash_table *ret;
   bfd_size_type amt = sizeof (struct elf_link_hash_table);
 
-  ret = bfd_malloc (amt);
+  ret = (struct elf_link_hash_table *) bfd_malloc (amt);
   if (ret == NULL)
     return NULL;
 
   if (! _bfd_elf_link_hash_table_init (ret, abfd, _bfd_elf_link_hash_newfunc,
   if (ret == NULL)
     return NULL;
 
   if (! _bfd_elf_link_hash_table_init (ret, abfd, _bfd_elf_link_hash_newfunc,
-                                      sizeof (struct elf_link_hash_entry)))
+                                      sizeof (struct elf_link_hash_entry),
+                                      GENERIC_ELF_DATA))
     {
       free (ret);
       return NULL;
     {
       free (ret);
       return NULL;
@@ -6870,7 +7005,7 @@ bfd_elf_get_bfd_needed_list (bfd *abfd,
            goto error_return;
 
          amt = sizeof *l;
            goto error_return;
 
          amt = sizeof *l;
-         l = bfd_alloc (abfd, amt);
+         l = (struct bfd_link_needed_list *) bfd_alloc (abfd, amt);
          if (l == NULL)
            goto error_return;
 
          if (l == NULL)
            goto error_return;
 
@@ -6942,7 +7077,7 @@ elf_create_symbuf (bfd_size_type symcount, Elf_Internal_Sym *isymbuf)
   struct elf_symbuf_head *ssymbuf, *ssymhead;
   bfd_size_type i, shndx_count, total_size;
 
   struct elf_symbuf_head *ssymbuf, *ssymhead;
   bfd_size_type i, shndx_count, total_size;
 
-  indbuf = bfd_malloc2 (symcount, sizeof (*indbuf));
+  indbuf = (Elf_Internal_Sym **) bfd_malloc2 (symcount, sizeof (*indbuf));
   if (indbuf == NULL)
     return NULL;
 
   if (indbuf == NULL)
     return NULL;
 
@@ -6962,7 +7097,7 @@ elf_create_symbuf (bfd_size_type symcount, Elf_Internal_Sym *isymbuf)
 
   total_size = ((shndx_count + 1) * sizeof (*ssymbuf)
                + (indbufend - indbuf) * sizeof (*ssym));
 
   total_size = ((shndx_count + 1) * sizeof (*ssymbuf)
                + (indbufend - indbuf) * sizeof (*ssym));
-  ssymbuf = bfd_malloc (total_size);
+  ssymbuf = (struct elf_symbuf_head *) bfd_malloc (total_size);
   if (ssymbuf == NULL)
     {
       free (indbuf);
   if (ssymbuf == NULL)
     {
       free (indbuf);
@@ -7043,8 +7178,8 @@ bfd_elf_match_symbols_in_sections (asection *sec1, asection *sec2,
   result = FALSE;
   isymbuf1 = NULL;
   isymbuf2 = NULL;
   result = FALSE;
   isymbuf1 = NULL;
   isymbuf2 = NULL;
-  ssymbuf1 = elf_tdata (bfd1)->symbuf;
-  ssymbuf2 = elf_tdata (bfd2)->symbuf;
+  ssymbuf1 = (struct elf_symbuf_head *) elf_tdata (bfd1)->symbuf;
+  ssymbuf2 = (struct elf_symbuf_head *) elf_tdata (bfd2)->symbuf;
 
   if (ssymbuf1 == NULL)
     {
 
   if (ssymbuf1 == NULL)
     {
@@ -7118,8 +7253,10 @@ bfd_elf_match_symbols_in_sections (asection *sec1, asection *sec2,
       if (count1 == 0 || count2 == 0 || count1 != count2)
        goto done;
 
       if (count1 == 0 || count2 == 0 || count1 != count2)
        goto done;
 
-      symtable1 = bfd_malloc (count1 * sizeof (struct elf_symbol));
-      symtable2 = bfd_malloc (count2 * sizeof (struct elf_symbol));
+      symtable1 = (struct elf_symbol *)
+          bfd_malloc (count1 * sizeof (struct elf_symbol));
+      symtable2 = (struct elf_symbol *)
+          bfd_malloc (count2 * sizeof (struct elf_symbol));
       if (symtable1 == NULL || symtable2 == NULL)
        goto done;
 
       if (symtable1 == NULL || symtable2 == NULL)
        goto done;
 
@@ -7160,8 +7297,10 @@ bfd_elf_match_symbols_in_sections (asection *sec1, asection *sec2,
       goto done;
     }
 
       goto done;
     }
 
-  symtable1 = bfd_malloc (symcount1 * sizeof (struct elf_symbol));
-  symtable2 = bfd_malloc (symcount2 * sizeof (struct elf_symbol));
+  symtable1 = (struct elf_symbol *)
+      bfd_malloc (symcount1 * sizeof (struct elf_symbol));
+  symtable2 = (struct elf_symbol *)
+      bfd_malloc (symcount2 * sizeof (struct elf_symbol));
   if (symtable1 == NULL || symtable2 == NULL)
     goto done;
 
   if (symtable1 == NULL || symtable2 == NULL)
     goto done;
 
@@ -7749,6 +7888,7 @@ bfd_elf_perform_complex_relocation (bfd *input_bfd,
   else
     shift = (8 * wordsz) - (start + len);
 
   else
     shift = (8 * wordsz) - (start + len);
 
+  /* FIXME: octets_per_byte.  */
   x = get_value (wordsz, chunksz, input_bfd, contents + rel->r_offset);
 
 #ifdef DEBUG
   x = get_value (wordsz, chunksz, input_bfd, contents + rel->r_offset);
 
 #ifdef DEBUG
@@ -7780,6 +7920,7 @@ bfd_elf_perform_complex_relocation (bfd *input_bfd,
          relocation, (mask << shift),
          ((relocation & mask) << shift), x);
 #endif
          relocation, (mask << shift),
          ((relocation & mask) << shift), x);
 #endif
+  /* FIXME: octets_per_byte.  */
   put_value (wordsz, chunksz, input_bfd, x, contents + rel->r_offset);
   return r;
 }
   put_value (wordsz, chunksz, input_bfd, x, contents + rel->r_offset);
   return r;
 }
@@ -7863,8 +8004,8 @@ struct elf_link_sort_rela
 static int
 elf_link_sort_cmp1 (const void *A, const void *B)
 {
 static int
 elf_link_sort_cmp1 (const void *A, const void *B)
 {
-  const struct elf_link_sort_rela *a = A;
-  const struct elf_link_sort_rela *b = B;
+  const struct elf_link_sort_rela *a = (const struct elf_link_sort_rela *) A;
+  const struct elf_link_sort_rela *b = (const struct elf_link_sort_rela *) B;
   int relativea, relativeb;
 
   relativea = a->type == reloc_class_relative;
   int relativea, relativeb;
 
   relativea = a->type == reloc_class_relative;
@@ -7888,8 +8029,8 @@ elf_link_sort_cmp1 (const void *A, const void *B)
 static int
 elf_link_sort_cmp2 (const void *A, const void *B)
 {
 static int
 elf_link_sort_cmp2 (const void *A, const void *B)
 {
-  const struct elf_link_sort_rela *a = A;
-  const struct elf_link_sort_rela *b = B;
+  const struct elf_link_sort_rela *a = (const struct elf_link_sort_rela *) A;
+  const struct elf_link_sort_rela *b = (const struct elf_link_sort_rela *) B;
   int copya, copyb;
 
   if (a->u.offset < b->u.offset)
   int copya, copyb;
 
   if (a->u.offset < b->u.offset)
@@ -8089,7 +8230,7 @@ elf_link_sort_relocs (bfd *abfd, struct bfd_link_info *info, asection **psec)
   count = dynamic_relocs->size / ext_size;
   if (count == 0)
     return 0;
   count = dynamic_relocs->size / ext_size;
   if (count == 0)
     return 0;
-  sort = bfd_zmalloc (sort_elt * count);
+  sort = (bfd_byte *) bfd_zmalloc (sort_elt * count);
 
   if (sort == NULL)
     {
 
   if (sort == NULL)
     {
@@ -8119,6 +8260,7 @@ elf_link_sort_relocs (bfd *abfd, struct bfd_link_info *info, asection **psec)
          }
        erel = o->contents;
        erelend = o->contents + o->size;
          }
        erel = o->contents;
        erelend = o->contents + o->size;
+       /* FIXME: octets_per_byte.  */
        p = sort + o->output_offset / ext_size * sort_elt;
 
        while (erel < erelend)
        p = sort + o->output_offset / ext_size * sort_elt;
 
        while (erel < erelend)
@@ -8163,6 +8305,7 @@ elf_link_sort_relocs (bfd *abfd, struct bfd_link_info *info, asection **psec)
 
        erel = o->contents;
        erelend = o->contents + o->size;
 
        erel = o->contents;
        erelend = o->contents + o->size;
+       /* FIXME: octets_per_byte.  */
        p = sort + o->output_offset / ext_size * sort_elt;
        while (erel < erelend)
          {
        p = sort + o->output_offset / ext_size * sort_elt;
        while (erel < erelend)
          {
@@ -8256,7 +8399,8 @@ elf_link_output_sym (struct elf_final_link_info *finfo,
          bfd_size_type amt;
 
          amt = finfo->shndxbuf_size * sizeof (Elf_External_Sym_Shndx);
          bfd_size_type amt;
 
          amt = finfo->shndxbuf_size * sizeof (Elf_External_Sym_Shndx);
-         destshndx = bfd_realloc (destshndx, amt * 2);
+         destshndx = (Elf_External_Sym_Shndx *) bfd_realloc (destshndx,
+                                                              amt * 2);
          if (destshndx == NULL)
            return 0;
          finfo->symshndxbuf = destshndx;
          if (destshndx == NULL)
            return 0;
          finfo->symshndxbuf = destshndx;
@@ -8382,7 +8526,7 @@ elf_link_check_versioned_symbol (struct bfd_link_info *info,
 
       /* Read in any version definitions.  */
       versymhdr = &elf_tdata (input)->dynversym_hdr;
 
       /* Read in any version definitions.  */
       versymhdr = &elf_tdata (input)->dynversym_hdr;
-      extversym = bfd_malloc (versymhdr->sh_size);
+      extversym = (Elf_External_Versym *) bfd_malloc (versymhdr->sh_size);
       if (extversym == NULL)
        goto error_ret;
 
       if (extversym == NULL)
        goto error_ret;
 
@@ -8416,10 +8560,14 @@ elf_link_check_versioned_symbol (struct bfd_link_info *info,
 
          _bfd_elf_swap_versym_in (input, ever, &iver);
 
 
          _bfd_elf_swap_versym_in (input, ever, &iver);
 
-         if ((iver.vs_vers & VERSYM_HIDDEN) == 0)
+         if ((iver.vs_vers & VERSYM_HIDDEN) == 0
+             && !(h->def_regular
+                  && h->forced_local))
            {
              /* If we have a non-hidden versioned sym, then it should
            {
              /* If we have a non-hidden versioned sym, then it should
-                have provided a definition for the undefined sym.  */
+                have provided a definition for the undefined sym unless
+                it is defined in a non-shared object and forced local.
+              */
              abort ();
            }
 
              abort ();
            }
 
@@ -8450,7 +8598,7 @@ elf_link_check_versioned_symbol (struct bfd_link_info *info,
 static bfd_boolean
 elf_link_output_extsym (struct elf_link_hash_entry *h, void *data)
 {
 static bfd_boolean
 elf_link_output_extsym (struct elf_link_hash_entry *h, void *data)
 {
-  struct elf_outext_info *eoinfo = data;
+  struct elf_outext_info *eoinfo = (struct elf_outext_info *) data;
   struct elf_final_link_info *finfo = eoinfo->finfo;
   bfd_boolean strip;
   Elf_Internal_Sym sym;
   struct elf_final_link_info *finfo = eoinfo->finfo;
   bfd_boolean strip;
   Elf_Internal_Sym sym;
@@ -8484,7 +8632,9 @@ elf_link_output_extsym (struct elf_link_hash_entry *h, void *data)
     {
       /* If we have an undefined symbol reference here then it must have
         come from a shared library that is being linked in.  (Undefined
     {
       /* If we have an undefined symbol reference here then it must have
         come from a shared library that is being linked in.  (Undefined
-        references in regular files have already been handled).  */
+        references in regular files have already been handled unless
+        they are in unreferenced sections which are removed by garbage
+        collection).  */
       bfd_boolean ignore_undef = FALSE;
 
       /* Some symbols may be special in that the fact that they're
       bfd_boolean ignore_undef = FALSE;
 
       /* Some symbols may be special in that the fact that they're
@@ -8493,14 +8643,15 @@ elf_link_output_extsym (struct elf_link_hash_entry *h, void *data)
        ignore_undef = bed->elf_backend_ignore_undef_symbol (h);
 
       /* If we are reporting errors for this situation then do so now.  */
        ignore_undef = bed->elf_backend_ignore_undef_symbol (h);
 
       /* If we are reporting errors for this situation then do so now.  */
-      if (ignore_undef == FALSE
+      if (!ignore_undef
          && h->ref_dynamic
          && h->ref_dynamic
-         && ! h->ref_regular
+         && (!h->ref_regular || finfo->info->gc_sections)
          && ! elf_link_check_versioned_symbol (finfo->info, bed, h)
          && finfo->info->unresolved_syms_in_shared_libs != RM_IGNORE)
        {
          if (! (finfo->info->callbacks->undefined_symbol
          && ! elf_link_check_versioned_symbol (finfo->info, bed, h)
          && finfo->info->unresolved_syms_in_shared_libs != RM_IGNORE)
        {
          if (! (finfo->info->callbacks->undefined_symbol
-                (finfo->info, h->root.root.string, h->root.u.undef.abfd,
+                (finfo->info, h->root.root.string,
+                 h->ref_regular ? NULL : h->root.u.undef.abfd,
                  NULL, 0, finfo->info->unresolved_syms_in_shared_libs == RM_GENERATE_ERROR)))
            {
              eoinfo->failed = TRUE;
                  NULL, 0, finfo->info->unresolved_syms_in_shared_libs == RM_GENERATE_ERROR)))
            {
              eoinfo->failed = TRUE;
@@ -8560,9 +8711,11 @@ elf_link_output_extsym (struct elf_link_hash_entry *h, void *data)
     strip = FALSE;
 
   /* If we're stripping it, and it's not a dynamic symbol, there's
     strip = FALSE;
 
   /* If we're stripping it, and it's not a dynamic symbol, there's
-     nothing else to do unless it is a forced local symbol.  */
+     nothing else to do unless it is a forced local symbol or a
+     STT_GNU_IFUNC symbol.  */
   if (strip
       && h->dynindx == -1
   if (strip
       && h->dynindx == -1
+      && h->type != STT_GNU_IFUNC
       && !h->forced_local)
     return TRUE;
 
       && !h->forced_local)
     return TRUE;
 
@@ -8570,7 +8723,13 @@ elf_link_output_extsym (struct elf_link_hash_entry *h, void *data)
   sym.st_size = h->size;
   sym.st_other = h->other;
   if (h->forced_local)
   sym.st_size = h->size;
   sym.st_other = h->other;
   if (h->forced_local)
-    sym.st_info = ELF_ST_INFO (STB_LOCAL, h->type);
+    {
+      sym.st_info = ELF_ST_INFO (STB_LOCAL, h->type);
+      /* Turn off visibility on local symbol.  */
+      sym.st_other &= ~ELF_ST_VISIBILITY (-1);
+    }
+  else if (h->unique_global)
+    sym.st_info = ELF_ST_INFO (STB_GNU_UNIQUE, h->type);
   else if (h->root.type == bfd_link_hash_undefweak
           || h->root.type == bfd_link_hash_defweak)
     sym.st_info = ELF_ST_INFO (STB_WEAK, h->type);
   else if (h->root.type == bfd_link_hash_undefweak
           || h->root.type == bfd_link_hash_defweak)
     sym.st_info = ELF_ST_INFO (STB_WEAK, h->type);
@@ -9341,7 +9500,7 @@ elf_link_input_bfd (struct elf_final_link_info *finfo, bfd *input_bfd)
                     discarded section.  */
                  if ((sec = *ps) != NULL && elf_discarded_section (sec))
                    {
                     discarded section.  */
                  if ((sec = *ps) != NULL && elf_discarded_section (sec))
                    {
-                     BFD_ASSERT (r_symndx != 0);
+                     BFD_ASSERT (r_symndx != STN_UNDEF);
                      if (action_discarded & COMPLAIN)
                        (*finfo->info->callbacks->einfo)
                          (_("%X`%s' referenced in section `%A' of %B: "
                      if (action_discarded & COMPLAIN)
                        (*finfo->info->callbacks->einfo)
                          (_("%X`%s' referenced in section `%A' of %B: "
@@ -9508,7 +9667,7 @@ elf_link_input_bfd (struct elf_final_link_info *finfo, bfd *input_bfd)
                      /* I suppose the backend ought to fill in the
                         section of any STT_SECTION symbol against a
                         processor specific section.  */
                      /* I suppose the backend ought to fill in the
                         section of any STT_SECTION symbol against a
                         processor specific section.  */
-                     r_symndx = 0;
+                     r_symndx = STN_UNDEF;
                      if (bfd_is_abs_section (sec))
                        ;
                      else if (sec == NULL || sec->owner == NULL)
                      if (bfd_is_abs_section (sec))
                        ;
                      else if (sec == NULL || sec->owner == NULL)
@@ -9537,7 +9696,7 @@ elf_link_input_bfd (struct elf_final_link_info *finfo, bfd *input_bfd)
                          if (!bfd_is_abs_section (osec))
                            {
                              r_symndx = osec->target_index;
                          if (!bfd_is_abs_section (osec))
                            {
                              r_symndx = osec->target_index;
-                             if (r_symndx == 0)
+                             if (r_symndx == STN_UNDEF)
                                {
                                  struct elf_link_hash_table *htab;
                                  asection *oi;
                                {
                                  struct elf_link_hash_table *htab;
                                  asection *oi;
@@ -9555,7 +9714,7 @@ elf_link_input_bfd (struct elf_final_link_info *finfo, bfd *input_bfd)
                                    }
                                }
 
                                    }
                                }
 
-                             BFD_ASSERT (r_symndx != 0);
+                             BFD_ASSERT (r_symndx != STN_UNDEF);
                            }
                        }
 
                            }
                        }
 
@@ -9682,8 +9841,8 @@ elf_link_input_bfd (struct elf_final_link_info *finfo, bfd *input_bfd)
          break;
        default:
          {
          break;
        default:
          {
+           /* FIXME: octets_per_byte.  */
            if (! (o->flags & SEC_EXCLUDE)
            if (! (o->flags & SEC_EXCLUDE)
-               && ! (o->output_section->flags & SEC_NEVER_LOAD)
                && ! bfd_set_section_contents (output_bfd, o->output_section,
                                               contents,
                                               (file_ptr) o->output_offset,
                && ! bfd_set_section_contents (output_bfd, o->output_section,
                                               contents,
                                               (file_ptr) o->output_offset,
@@ -9789,8 +9948,8 @@ elf_reloc_link_order (bfd *output_bfd,
       bfd_boolean ok;
       const char *sym_name;
 
       bfd_boolean ok;
       const char *sym_name;
 
-      size = bfd_get_reloc_size (howto);
-      buf = bfd_zmalloc (size);
+      size = (bfd_size_type) bfd_get_reloc_size (howto);
+      buf = (bfd_byte *) bfd_zmalloc (size);
       if (buf == NULL)
        return FALSE;
       rstat = _bfd_relocate_contents (howto, output_bfd, addend, buf);
       if (buf == NULL)
        return FALSE;
       rstat = _bfd_relocate_contents (howto, output_bfd, addend, buf);
@@ -10005,6 +10164,7 @@ elf_fixup_link_order (bfd *abfd, asection *o)
       offset &= ~(bfd_vma) 0 << s->alignment_power;
       s->output_offset = offset;
       sections[n]->offset = offset;
       offset &= ~(bfd_vma) 0 << s->alignment_power;
       s->output_offset = offset;
       sections[n]->offset = offset;
+      /* FIXME: octets_per_byte.  */
       offset += sections[n]->size;
     }
 
       offset += sections[n]->size;
     }
 
@@ -10022,9 +10182,9 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
   bfd_boolean emit_relocs;
   bfd *dynobj;
   struct elf_final_link_info finfo;
   bfd_boolean emit_relocs;
   bfd *dynobj;
   struct elf_final_link_info finfo;
-  register asection *o;
-  register struct bfd_link_order *p;
-  register bfd *sub;
+  asection *o;
+  struct bfd_link_order *p;
+  bfd *sub;
   bfd_size_type max_contents_size;
   bfd_size_type max_external_reloc_size;
   bfd_size_type max_internal_reloc_count;
   bfd_size_type max_contents_size;
   bfd_size_type max_external_reloc_size;
   bfd_size_type max_internal_reloc_count;
@@ -10199,7 +10359,10 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
                    {
                      size_t ext_size;
 
                    {
                      size_t ext_size;
 
-                     ext_size = elf_section_data (sec)->rel_hdr.sh_size;
+                     ext_size = esdi->rel_hdr.sh_size;
+                     if (esdi->rel_hdr2 != NULL)
+                       ext_size += esdi->rel_hdr2->sh_size;
+
                      if (ext_size > max_external_reloc_size)
                        max_external_reloc_size = ext_size;
                      if (sec->reloc_count > max_internal_reloc_count)
                      if (ext_size > max_external_reloc_size)
                        max_external_reloc_size = ext_size;
                      if (sec->reloc_count > max_internal_reloc_count)
@@ -10347,7 +10510,7 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
     finfo.symbuf_size = max_sym_count;
   amt = finfo.symbuf_size;
   amt *= bed->s->sizeof_sym;
     finfo.symbuf_size = max_sym_count;
   amt = finfo.symbuf_size;
   amt *= bed->s->sizeof_sym;
-  finfo.symbuf = bfd_malloc (amt);
+  finfo.symbuf = (bfd_byte *) bfd_malloc (amt);
   if (finfo.symbuf == NULL)
     goto error_return;
   if (elf_numsections (abfd) > (SHN_LORESERVE & 0xFFFF))
   if (finfo.symbuf == NULL)
     goto error_return;
   if (elf_numsections (abfd) > (SHN_LORESERVE & 0xFFFF))
@@ -10356,7 +10519,7 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
       amt = 2 * max_sym_count + elf_numsections (abfd) + 1000;
       finfo.shndxbuf_size = amt;
       amt *= sizeof (Elf_External_Sym_Shndx);
       amt = 2 * max_sym_count + elf_numsections (abfd) + 1000;
       finfo.shndxbuf_size = amt;
       amt *= sizeof (Elf_External_Sym_Shndx);
-      finfo.symshndxbuf = bfd_zmalloc (amt);
+      finfo.symshndxbuf = (Elf_External_Sym_Shndx *) bfd_zmalloc (amt);
       if (finfo.symshndxbuf == NULL)
        goto error_return;
     }
       if (finfo.symshndxbuf == NULL)
        goto error_return;
     }
@@ -10407,7 +10570,7 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
      files.  */
   if (max_contents_size != 0)
     {
      files.  */
   if (max_contents_size != 0)
     {
-      finfo.contents = bfd_malloc (max_contents_size);
+      finfo.contents = (bfd_byte *) bfd_malloc (max_contents_size);
       if (finfo.contents == NULL)
        goto error_return;
     }
       if (finfo.contents == NULL)
        goto error_return;
     }
@@ -10423,7 +10586,7 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
     {
       amt = max_internal_reloc_count * bed->s->int_rels_per_ext_rel;
       amt *= sizeof (Elf_Internal_Rela);
     {
       amt = max_internal_reloc_count * bed->s->int_rels_per_ext_rel;
       amt *= sizeof (Elf_Internal_Rela);
-      finfo.internal_relocs = bfd_malloc (amt);
+      finfo.internal_relocs = (Elf_Internal_Rela *) bfd_malloc (amt);
       if (finfo.internal_relocs == NULL)
        goto error_return;
     }
       if (finfo.internal_relocs == NULL)
        goto error_return;
     }
@@ -10431,22 +10594,22 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
   if (max_sym_count != 0)
     {
       amt = max_sym_count * bed->s->sizeof_sym;
   if (max_sym_count != 0)
     {
       amt = max_sym_count * bed->s->sizeof_sym;
-      finfo.external_syms = bfd_malloc (amt);
+      finfo.external_syms = (bfd_byte *) bfd_malloc (amt);
       if (finfo.external_syms == NULL)
        goto error_return;
 
       amt = max_sym_count * sizeof (Elf_Internal_Sym);
       if (finfo.external_syms == NULL)
        goto error_return;
 
       amt = max_sym_count * sizeof (Elf_Internal_Sym);
-      finfo.internal_syms = bfd_malloc (amt);
+      finfo.internal_syms = (Elf_Internal_Sym *) bfd_malloc (amt);
       if (finfo.internal_syms == NULL)
        goto error_return;
 
       amt = max_sym_count * sizeof (long);
       if (finfo.internal_syms == NULL)
        goto error_return;
 
       amt = max_sym_count * sizeof (long);
-      finfo.indices = bfd_malloc (amt);
+      finfo.indices = (long int *) bfd_malloc (amt);
       if (finfo.indices == NULL)
        goto error_return;
 
       amt = max_sym_count * sizeof (asection *);
       if (finfo.indices == NULL)
        goto error_return;
 
       amt = max_sym_count * sizeof (asection *);
-      finfo.sections = bfd_malloc (amt);
+      finfo.sections = (asection **) bfd_malloc (amt);
       if (finfo.sections == NULL)
        goto error_return;
     }
       if (finfo.sections == NULL)
        goto error_return;
     }
@@ -10454,7 +10617,7 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
   if (max_sym_shndx_count != 0)
     {
       amt = max_sym_shndx_count * sizeof (Elf_External_Sym_Shndx);
   if (max_sym_shndx_count != 0)
     {
       amt = max_sym_shndx_count * sizeof (Elf_External_Sym_Shndx);
-      finfo.locsym_shndx = bfd_malloc (amt);
+      finfo.locsym_shndx = (Elf_External_Sym_Shndx *) bfd_malloc (amt);
       if (finfo.locsym_shndx == NULL)
        goto error_return;
     }
       if (finfo.locsym_shndx == NULL)
        goto error_return;
     }
@@ -10473,9 +10636,10 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
          if (size == 0
              && (sec->flags & SEC_HAS_CONTENTS) == 0)
            {
          if (size == 0
              && (sec->flags & SEC_HAS_CONTENTS) == 0)
            {
-             struct bfd_link_order *o = sec->map_tail.link_order;
-             if (o != NULL)
-               size = o->offset + o->size;
+             struct bfd_link_order *ord = sec->map_tail.link_order;
+
+             if (ord != NULL)
+               size = ord->offset + ord->size;
            }
          end = sec->vma + size;
        }
            }
          end = sec->vma + size;
        }
@@ -10638,13 +10802,11 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
              asection *s;
              bfd_byte *dest;
 
              asection *s;
              bfd_byte *dest;
 
-             sym.st_size = e->isym.st_size;
-             sym.st_other = e->isym.st_other;
-
-             /* Copy the internal symbol as is.
+             /* Copy the internal symbol and turn off visibility.
                 Note that we saved a word of storage and overwrote
                 the original st_name with the dynstr_index.  */
              sym = e->isym;
                 Note that we saved a word of storage and overwrote
                 the original st_name with the dynstr_index.  */
              sym = e->isym;
+             sym.st_other &= ~ELF_ST_VISIBILITY (-1);
 
              s = bfd_section_from_elf_index (e->input_bfd,
                                              e->isym.st_shndx);
 
              s = bfd_section_from_elf_index (e->input_bfd,
                                              e->isym.st_shndx);
@@ -10984,6 +11146,7 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
               != SHT_STRTAB)
              || strcmp (bfd_get_section_name (abfd, o), ".dynstr") != 0)
            {
               != SHT_STRTAB)
              || strcmp (bfd_get_section_name (abfd, o), ".dynstr") != 0)
            {
+             /* FIXME: octets_per_byte.  */
              if (! bfd_set_section_contents (abfd, o->output_section,
                                              o->contents,
                                              (file_ptr) o->output_offset,
              if (! bfd_set_section_contents (abfd, o->output_section,
                                              o->contents,
                                              (file_ptr) o->output_offset,
@@ -11058,7 +11221,7 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
 
   if (attr_section)
     {
 
   if (attr_section)
     {
-      bfd_byte *contents = bfd_malloc (attr_size);
+      bfd_byte *contents = (bfd_byte *) bfd_malloc (attr_size);
       if (contents == NULL)
        return FALSE;   /* Bail out and fail.  */
       bfd_elf_set_obj_attr_contents (abfd, contents, attr_size);
       if (contents == NULL)
        return FALSE;   /* Bail out and fail.  */
       bfd_elf_set_obj_attr_contents (abfd, contents, attr_size);
@@ -11245,6 +11408,8 @@ _bfd_elf_gc_mark_hook (asection *sec,
                       struct elf_link_hash_entry *h,
                       Elf_Internal_Sym *sym)
 {
                       struct elf_link_hash_entry *h,
                       Elf_Internal_Sym *sym)
 {
+  const char *sec_name;
+
   if (h != NULL)
     {
       switch (h->root.type)
   if (h != NULL)
     {
       switch (h->root.type)
@@ -11256,6 +11421,33 @@ _bfd_elf_gc_mark_hook (asection *sec,
        case bfd_link_hash_common:
          return h->root.u.c.p->section;
 
        case bfd_link_hash_common:
          return h->root.u.c.p->section;
 
+       case bfd_link_hash_undefined:
+       case bfd_link_hash_undefweak:
+         /* To work around a glibc bug, keep all XXX input sections
+            when there is an as yet undefined reference to __start_XXX
+            or __stop_XXX symbols.  The linker will later define such
+            symbols for orphan input sections that have a name
+            representable as a C identifier.  */
+         if (strncmp (h->root.root.string, "__start_", 8) == 0)
+           sec_name = h->root.root.string + 8;
+         else if (strncmp (h->root.root.string, "__stop_", 7) == 0)
+           sec_name = h->root.root.string + 7;
+         else
+           sec_name = NULL;
+
+         if (sec_name && *sec_name != '\0')
+           {
+             bfd *i;
+             
+             for (i = info->input_bfds; i; i = i->link_next)
+               {
+                 sec = bfd_get_section_by_name (i, sec_name);
+                 if (sec)
+                   sec->flags |= SEC_KEEP;
+               }
+           }
+         break;
+
        default:
          break;
        }
        default:
          break;
        }
@@ -11279,7 +11471,7 @@ _bfd_elf_gc_mark_rsec (struct bfd_link_info *info, asection *sec,
   struct elf_link_hash_entry *h;
 
   r_symndx = cookie->rel->r_info >> cookie->r_sym_shift;
   struct elf_link_hash_entry *h;
 
   r_symndx = cookie->rel->r_info >> cookie->r_sym_shift;
-  if (r_symndx == 0)
+  if (r_symndx == STN_UNDEF)
     return NULL;
 
   if (r_symndx >= cookie->locsymcount
     return NULL;
 
   if (r_symndx >= cookie->locsymcount
@@ -11400,7 +11592,8 @@ elf_gc_sweep_symbol (struct elf_link_hash_entry *h, void *data)
       && !h->root.u.def.section->gc_mark
       && !(h->root.u.def.section->owner->flags & DYNAMIC))
     {
       && !h->root.u.def.section->gc_mark
       && !(h->root.u.def.section->owner->flags & DYNAMIC))
     {
-      struct elf_gc_sweep_symbol_info *inf = data;
+      struct elf_gc_sweep_symbol_info *inf =
+          (struct elf_gc_sweep_symbol_info *) data;
       (*inf->hide_symbol) (inf->info, h, TRUE);
     }
 
       (*inf->hide_symbol) (inf->info, h, TRUE);
     }
 
@@ -11440,9 +11633,10 @@ elf_gc_sweep (bfd *abfd, struct bfd_link_info *info)
              o->gc_mark = first->gc_mark;
            }
          else if ((o->flags & (SEC_DEBUGGING | SEC_LINKER_CREATED)) != 0
              o->gc_mark = first->gc_mark;
            }
          else if ((o->flags & (SEC_DEBUGGING | SEC_LINKER_CREATED)) != 0
-                  || (o->flags & (SEC_ALLOC | SEC_LOAD | SEC_RELOC)) == 0)
+                  || (o->flags & (SEC_ALLOC | SEC_LOAD | SEC_RELOC)) == 0
+                  || elf_section_data (o)->this_hdr.sh_type == SHT_NOTE)
            {
            {
-             /* Keep debug and special sections.  */
+             /* Keep debug, special and SHT_NOTE sections.  */
              o->gc_mark = 1;
            }
 
              o->gc_mark = 1;
            }
 
@@ -11781,7 +11975,8 @@ bfd_elf_gc_record_vtinherit (bfd *abfd,
  win:
   if (!child->vtable)
     {
  win:
   if (!child->vtable)
     {
-      child->vtable = bfd_zalloc (abfd, sizeof (*child->vtable));
+      child->vtable = (struct elf_link_virtual_table_entry *)
+          bfd_zalloc (abfd, sizeof (*child->vtable));
       if (!child->vtable)
        return FALSE;
     }
       if (!child->vtable)
        return FALSE;
     }
@@ -11813,7 +12008,8 @@ bfd_elf_gc_record_vtentry (bfd *abfd ATTRIBUTE_UNUSED,
 
   if (!h->vtable)
     {
 
   if (!h->vtable)
     {
-      h->vtable = bfd_zalloc (abfd, sizeof (*h->vtable));
+      h->vtable = (struct elf_link_virtual_table_entry *)
+          bfd_zalloc (abfd, sizeof (*h->vtable));
       if (!h->vtable)
        return FALSE;
     }
       if (!h->vtable)
        return FALSE;
     }
@@ -11846,7 +12042,7 @@ bfd_elf_gc_record_vtentry (bfd *abfd ATTRIBUTE_UNUSED,
 
       if (ptr)
        {
 
       if (ptr)
        {
-         ptr = bfd_realloc (ptr - 1, bytes);
+         ptr = (bfd_boolean *) bfd_realloc (ptr - 1, bytes);
 
          if (ptr != NULL)
            {
 
          if (ptr != NULL)
            {
@@ -11858,7 +12054,7 @@ bfd_elf_gc_record_vtentry (bfd *abfd ATTRIBUTE_UNUSED,
            }
        }
       else
            }
        }
       else
-       ptr = bfd_zmalloc (bytes);
+       ptr = (bfd_boolean *) bfd_zmalloc (bytes);
 
       if (ptr == NULL)
        return FALSE;
 
       if (ptr == NULL)
        return FALSE;
@@ -11884,7 +12080,7 @@ struct alloc_got_off_arg {
 static bfd_boolean
 elf_gc_allocate_got_offsets (struct elf_link_hash_entry *h, void *arg)
 {
 static bfd_boolean
 elf_gc_allocate_got_offsets (struct elf_link_hash_entry *h, void *arg)
 {
-  struct alloc_got_off_arg *gofarg = arg;
+  struct alloc_got_off_arg *gofarg = (struct alloc_got_off_arg *) arg;
   bfd *obfd = gofarg->info->output_bfd;
   const struct elf_backend_data *bed = get_elf_backend_data (obfd);
 
   bfd *obfd = gofarg->info->output_bfd;
   const struct elf_backend_data *bed = get_elf_backend_data (obfd);
 
@@ -11984,7 +12180,7 @@ bfd_elf_gc_common_final_link (bfd *abfd, struct bfd_link_info *info)
 bfd_boolean
 bfd_elf_reloc_symbol_deleted_p (bfd_vma offset, void *cookie)
 {
 bfd_boolean
 bfd_elf_reloc_symbol_deleted_p (bfd_vma offset, void *cookie)
 {
-  struct elf_reloc_cookie *rcookie = cookie;
+  struct elf_reloc_cookie *rcookie = (struct elf_reloc_cookie *) cookie;
 
   if (rcookie->bad_symtab)
     rcookie->rel = rcookie->rels;
 
   if (rcookie->bad_symtab)
     rcookie->rel = rcookie->rels;
@@ -12000,7 +12196,7 @@ bfd_elf_reloc_symbol_deleted_p (bfd_vma offset, void *cookie)
        continue;
 
       r_symndx = rcookie->rel->r_info >> rcookie->r_sym_shift;
        continue;
 
       r_symndx = rcookie->rel->r_info >> rcookie->r_sym_shift;
-      if (r_symndx == SHN_UNDEF)
+      if (r_symndx == STN_UNDEF)
        return TRUE;
 
       if (r_symndx >= rcookie->locsymcount
        return TRUE;
 
       if (r_symndx >= rcookie->locsymcount
@@ -12460,7 +12656,7 @@ _bfd_elf_get_dynamic_reloc_section (bfd *       abfd,
    section does not exist it is created and attached to the DYNOBJ
    bfd and stored in the SRELOC field of SEC's elf_section_data
    structure.
    section does not exist it is created and attached to the DYNOBJ
    bfd and stored in the SRELOC field of SEC's elf_section_data
    structure.
-   
+
    ALIGNMENT is the alignment for the newly created section and
    IS_RELA defines whether the name should be .rela.<SEC's name>
    or .rel.<SEC's name>.  The section name is looked up in the
    ALIGNMENT is the alignment for the newly created section and
    IS_RELA defines whether the name should be .rela.<SEC's name>
    or .rel.<SEC's name>.  The section name is looked up in the
@@ -12505,3 +12701,15 @@ _bfd_elf_make_dynamic_reloc_section (asection *         sec,
 
   return reloc_sec;
 }
 
   return reloc_sec;
 }
+
+/* Copy the ELF symbol type associated with a linker hash entry.  */
+void
+_bfd_elf_copy_link_hash_symbol_type (bfd *abfd ATTRIBUTE_UNUSED,
+    struct bfd_link_hash_entry * hdest,
+    struct bfd_link_hash_entry * hsrc)
+{
+  struct elf_link_hash_entry *ehdest = (struct elf_link_hash_entry *)hdest;
+  struct elf_link_hash_entry *ehsrc = (struct elf_link_hash_entry *)hsrc;
+
+  ehdest->type = ehsrc->type;
+}
This page took 0.102593 seconds and 4 git commands to generate.