Automatic date update in version.in
[deliverable/binutils-gdb.git] / bfd / elflink.c
index ddbe80100d747a00949b7dfb452409d939a778d3..07b79013d90c710def29183b29a3b2d3541b8305 100644 (file)
@@ -577,6 +577,9 @@ bfd_elf_record_link_assignment (bfd *output_bfd,
   if (h == NULL)
     return provide;
 
+  if (h->root.type == bfd_link_hash_warning)
+    h = (struct elf_link_hash_entry *) h->root.u.i.link;
+
   if (h->versioned == unknown)
     {
       /* Set versioned if symbol version is unknown.  */
@@ -624,9 +627,9 @@ bfd_elf_record_link_assignment (bfd *output_bfd,
       hv->root.u.i.link = (struct bfd_link_hash_entry *) h;
       (*bed->elf_backend_copy_indirect_symbol) (info, h, hv);
       break;
-    case bfd_link_hash_warning:
-      abort ();
-      break;
+    default:
+      BFD_FAIL ();
+      return FALSE;
     }
 
   /* If this symbol is being provided by the linker script, and it is
@@ -2654,18 +2657,35 @@ _bfd_elf_fix_symbol_flags (struct elf_link_hash_entry *h,
       && (h->root.u.def.section->owner->flags & (DYNAMIC | BFD_PLUGIN)) == 0)
     h->def_regular = 1;
 
+  /* If a weak undefined symbol has non-default visibility, we also
+     hide it from the dynamic linker.  */
+  if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
+      && h->root.type == bfd_link_hash_undefweak)
+    (*bed->elf_backend_hide_symbol) (eif->info, h, TRUE);
+
+  /* A hidden versioned symbol in executable should be forced local if
+     it is is locally defined, not referenced by shared library and not
+     exported.  */
+  else if (bfd_link_executable (eif->info)
+          && h->versioned == versioned_hidden
+          && !eif->info->export_dynamic
+          && !h->dynamic
+          && !h->ref_dynamic
+          && h->def_regular)
+    (*bed->elf_backend_hide_symbol) (eif->info, h, TRUE);
+
   /* If -Bsymbolic was used (which means to bind references to global
      symbols to the definition within the shared object), and this
      symbol was defined in a regular object, then it actually doesn't
      need a PLT entry.  Likewise, if the symbol has non-default
      visibility.  If the symbol has hidden or internal visibility, we
      will force it local.  */
-  if (h->needs_plt
-      && bfd_link_pic (eif->info)
-      && is_elf_hash_table (eif->info->hash)
-      && (SYMBOLIC_BIND (eif->info, h)
-         || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
-      && h->def_regular)
+  else if (h->needs_plt
+          && bfd_link_pic (eif->info)
+          && is_elf_hash_table (eif->info->hash)
+          && (SYMBOLIC_BIND (eif->info, h)
+              || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
+          && h->def_regular)
     {
       bfd_boolean force_local;
 
@@ -2674,12 +2694,6 @@ _bfd_elf_fix_symbol_flags (struct elf_link_hash_entry *h,
       (*bed->elf_backend_hide_symbol) (eif->info, h, force_local);
     }
 
-  /* If a weak undefined symbol has non-default visibility, we also
-     hide it from the dynamic linker.  */
-  if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
-      && h->root.type == bfd_link_hash_undefweak)
-    (*bed->elf_backend_hide_symbol) (eif->info, h, TRUE);
-
   /* If this is a weak defined symbol in a dynamic object, and we know
      the real definition in the dynamic object, copy interesting flags
      over to the real definition.  */
@@ -9249,16 +9263,6 @@ elf_link_output_extsym (struct bfd_hash_entry *bh, void *data)
   long indx;
   int ret;
   unsigned int type;
-  /* A symbol is bound locally if it is forced local or it is locally
-     defined, hidden versioned, not referenced by shared library and
-     not exported when linking executable.  */
-  bfd_boolean local_bind = (h->forced_local
-                           || (bfd_link_executable (flinfo->info)
-                               && !flinfo->info->export_dynamic
-                               && !h->dynamic
-                               && !h->ref_dynamic
-                               && h->def_regular
-                               && h->versioned == versioned_hidden));
 
   if (h->root.type == bfd_link_hash_warning)
     {
@@ -9270,12 +9274,12 @@ elf_link_output_extsym (struct bfd_hash_entry *bh, void *data)
   /* Decide whether to output this symbol in this pass.  */
   if (eoinfo->localsyms)
     {
-      if (!local_bind)
+      if (!h->forced_local)
        return TRUE;
     }
   else
     {
-      if (local_bind)
+      if (h->forced_local)
        return TRUE;
     }
 
@@ -9492,7 +9496,7 @@ elf_link_output_extsym (struct bfd_hash_entry *bh, void *data)
        abort ();
       }
 
-  if (local_bind)
+  if (h->forced_local)
     {
       sym.st_info = ELF_ST_INFO (STB_LOCAL, type);
       /* Turn off visibility on local symbol.  */
@@ -9603,10 +9607,8 @@ elf_link_output_extsym (struct bfd_hash_entry *bh, void *data)
       /* Since there is no version information in the dynamic string,
         if there is no version info in symbol version section, we will
         have a run-time problem if not linking executable, referenced
-        by shared library, not locally defined, or not bound locally.
-      */
+        by shared library, or not bound locally.  */
       if (h->verinfo.verdef == NULL
-         && !local_bind
          && (!bfd_link_executable (flinfo->info)
              || h->ref_dynamic
              || !h->def_regular))
@@ -11343,7 +11345,6 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
              asection *sec;
 
              sec = p->u.indirect.section;
-             esdi = elf_section_data (sec);
 
              /* Mark all sections which are to be included in the
                 link.  This will normally be every section.  We need
@@ -11354,37 +11355,18 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
              if (sec->flags & SEC_MERGE)
                merged = TRUE;
 
-             if (esdo->this_hdr.sh_type == SHT_REL
-                 || esdo->this_hdr.sh_type == SHT_RELA)
-               /* Some backends use reloc_count in relocation sections
-                  to count particular types of relocs.  Of course,
-                  reloc sections themselves can't have relocations.  */
-               reloc_count = 0;
-             else if (emit_relocs)
-               {
-                 reloc_count = sec->reloc_count;
-                 if (bed->elf_backend_count_additional_relocs)
-                   {
-                     int c;
-                     c = (*bed->elf_backend_count_additional_relocs) (sec);
-                     additional_reloc_count += c;
-                   }
-               }
-             else if (bed->elf_backend_count_relocs)
-               reloc_count = (*bed->elf_backend_count_relocs) (info, sec);
-
              if (sec->rawsize > max_contents_size)
                max_contents_size = sec->rawsize;
              if (sec->size > max_contents_size)
                max_contents_size = sec->size;
 
-             /* We are interested in just local symbols, not all
-                symbols.  */
              if (bfd_get_flavour (sec->owner) == bfd_target_elf_flavour
                  && (sec->owner->flags & DYNAMIC) == 0)
                {
                  size_t sym_count;
 
+                 /* We are interested in just local symbols, not all
+                    symbols.  */
                  if (elf_bad_symtab (sec->owner))
                    sym_count = (elf_tdata (sec->owner)->symtab_hdr.sh_size
                                 / bed->s->sizeof_sym);
@@ -11398,6 +11380,27 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
                      && elf_symtab_shndx_list (sec->owner) != NULL)
                    max_sym_shndx_count = sym_count;
 
+                 if (esdo->this_hdr.sh_type == SHT_REL
+                     || esdo->this_hdr.sh_type == SHT_RELA)
+                   /* Some backends use reloc_count in relocation sections
+                      to count particular types of relocs.  Of course,
+                      reloc sections themselves can't have relocations.  */
+                   ;
+                 else if (emit_relocs)
+                   {
+                     reloc_count = sec->reloc_count;
+                     if (bed->elf_backend_count_additional_relocs)
+                       {
+                         int c;
+                         c = (*bed->elf_backend_count_additional_relocs) (sec);
+                         additional_reloc_count += c;
+                       }
+                   }
+                 else if (bed->elf_backend_count_relocs)
+                   reloc_count = (*bed->elf_backend_count_relocs) (info, sec);
+
+                 esdi = elf_section_data (sec);
+
                  if ((sec->flags & SEC_RELOC) != 0)
                    {
                      size_t ext_size = 0;
@@ -13048,6 +13051,7 @@ bfd_elf_gc_mark_dynamic_ref_symbol (struct elf_link_hash_entry *h, void *inf)
              && ELF_ST_VISIBILITY (h->other) != STV_INTERNAL
              && ELF_ST_VISIBILITY (h->other) != STV_HIDDEN
              && (!bfd_link_executable (info)
+                 || info->gc_keep_exported
                  || info->export_dynamic
                  || (h->dynamic
                      && d != NULL
@@ -13167,7 +13171,7 @@ bfd_elf_gc_sections (bfd *abfd, struct bfd_link_info *info)
     return FALSE;
 
   /* Mark dynamically referenced symbols.  */
-  if (htab->dynamic_sections_created)
+  if (htab->dynamic_sections_created || info->gc_keep_exported)
     elf_link_hash_traverse (htab, bed->gc_mark_dynamic_ref, info);
 
   /* Grovel through relocs to find out who stays ...  */
This page took 0.028088 seconds and 4 git commands to generate.