* Makefile.in (SFILES): Add cp-names.y.
[deliverable/binutils-gdb.git] / bfd / elflink.c
index 9d07c4c1619ad6e349a4fde6ad02637757a8f482..1721f3f8a3c478a55cf1bf60dd6d5605032ec393 100644 (file)
@@ -386,7 +386,8 @@ bfd_elf_link_record_dynamic_symbol (struct bfd_link_info *info,
              && h->root.type != bfd_link_hash_undefweak)
            {
              h->forced_local = 1;
-             return TRUE;
+             if (!elf_hash_table (info)->is_relocatable_executable)
+               return TRUE;
            }
 
        default:
@@ -440,13 +441,15 @@ bfd_elf_record_link_assignment (bfd *output_bfd ATTRIBUTE_UNUSED,
                                bfd_boolean provide)
 {
   struct elf_link_hash_entry *h;
+  struct elf_link_hash_table *htab;
 
   if (!is_elf_hash_table (info->hash))
     return TRUE;
 
-  h = elf_link_hash_lookup (elf_hash_table (info), name, TRUE, TRUE, FALSE);
+  htab = elf_hash_table (info);
+  h = elf_link_hash_lookup (htab, name, !provide, TRUE, FALSE);
   if (h == NULL)
-    return FALSE;
+    return provide;
 
   /* Since we're defining the symbol, don't let it seem to have not
      been defined.  record_dynamic_symbol and size_dynamic_sections
@@ -454,11 +457,9 @@ bfd_elf_record_link_assignment (bfd *output_bfd ATTRIBUTE_UNUSED,
   if (h->root.type == bfd_link_hash_undefweak
       || h->root.type == bfd_link_hash_undefined)
     {
-      struct elf_link_hash_table *htab = elf_hash_table (info);
-
+      h->root.type = bfd_link_hash_new;
       if (h->root.u.undef.next != NULL || htab->root.undefs_tail == &h->root)
        bfd_link_repair_undef_list (&htab->root);
-      h->root.type = bfd_link_hash_new;
     }
 
   if (h->root.type == bfd_link_hash_new)
@@ -484,9 +485,18 @@ bfd_elf_record_link_assignment (bfd *output_bfd ATTRIBUTE_UNUSED,
 
   h->def_regular = 1;
 
+  /* STV_HIDDEN and STV_INTERNAL symbols must be STB_LOCAL in shared objects
+     and executables.  */
+  if (!info->relocatable
+      && h->dynindx != -1
+      && (ELF_ST_VISIBILITY (h->other) == STV_HIDDEN
+         || ELF_ST_VISIBILITY (h->other) == STV_INTERNAL))
+    h->forced_local = 1;
+
   if ((h->def_dynamic
        || h->ref_dynamic
-       || info->shared)
+       || info->shared
+       || (info->executable && elf_hash_table (info)->is_relocatable_executable))
       && h->dynindx == -1)
     {
       if (! bfd_elf_link_record_dynamic_symbol (info, h))
@@ -624,6 +634,31 @@ elf_link_renumber_hash_table_dynsyms (struct elf_link_hash_entry *h,
   if (h->root.type == bfd_link_hash_warning)
     h = (struct elf_link_hash_entry *) h->root.u.i.link;
 
+  if (h->forced_local)
+    return TRUE;
+
+  if (h->dynindx != -1)
+    h->dynindx = ++(*count);
+
+  return TRUE;
+}
+
+
+/* Like elf_link_renumber_hash_table_dynsyms, but just number symbols with
+   STB_LOCAL binding.  */
+
+static bfd_boolean
+elf_link_renumber_local_hash_table_dynsyms (struct elf_link_hash_entry *h,
+                                           void *data)
+{
+  size_t *count = data;
+
+  if (h->root.type == bfd_link_hash_warning)
+    h = (struct elf_link_hash_entry *) h->root.u.i.link;
+
+  if (!h->forced_local)
+    return TRUE;
+
   if (h->dynindx != -1)
     h->dynindx = ++(*count);
 
@@ -667,16 +702,17 @@ _bfd_elf_link_omit_section_dynsym (bfd *output_bfd ATTRIBUTE_UNUSED,
 }
 
 /* Assign dynsym indices.  In a shared library we generate a section
-   symbol for each output section, which come first.  Next come all of
-   the back-end allocated local dynamic syms, followed by the rest of
-   the global symbols.  */
+   symbol for each output section, which come first.  Next come symbols
+   which have been forced to local binding.  Then all of the back-end
+   allocated local dynamic syms, followed by the rest of the global
+   symbols.  */
 
 unsigned long
 _bfd_elf_link_renumber_dynsyms (bfd *output_bfd, struct bfd_link_info *info)
 {
   unsigned long dynsymcount = 0;
 
-  if (info->shared)
+  if (info->shared || elf_hash_table (info)->is_relocatable_executable)
     {
       const struct elf_backend_data *bed = get_elf_backend_data (output_bfd);
       asection *p;
@@ -687,6 +723,10 @@ _bfd_elf_link_renumber_dynsyms (bfd *output_bfd, struct bfd_link_info *info)
          elf_section_data (p)->dynindx = ++dynsymcount;
     }
 
+  elf_link_hash_traverse (elf_hash_table (info),
+                         elf_link_renumber_local_hash_table_dynsyms,
+                         &dynsymcount);
+
   if (elf_hash_table (info)->dynlocal)
     {
       struct elf_link_local_dynamic_entry *p;
@@ -716,7 +756,8 @@ _bfd_elf_link_renumber_dynsyms (bfd *output_bfd, struct bfd_link_info *info)
    TYPE_CHANGE_OK if it is OK for the type to change.  We set
    SIZE_CHANGE_OK if it is OK for the size to change.  By OK to
    change, we mean that we shouldn't warn if the type or size does
-   change.  */
+   change.  We set POLD_ALIGNMENT if an old common symbol in a dynamic
+   object is overridden by a regular object.  */
 
 bfd_boolean
 _bfd_elf_merge_symbol (bfd *abfd,
@@ -725,6 +766,7 @@ _bfd_elf_merge_symbol (bfd *abfd,
                       Elf_Internal_Sym *sym,
                       asection **psec,
                       bfd_vma *pvalue,
+                      unsigned int *pold_alignment,
                       struct elf_link_hash_entry **sym_hash,
                       bfd_boolean *skip,
                       bfd_boolean *override,
@@ -1229,9 +1271,10 @@ _bfd_elf_merge_symbol (bfd *abfd,
       if (h->size > *pvalue)
        *pvalue = h->size;
 
-      /* FIXME: We no longer know the alignment required by the symbol
-        in the dynamic object, so we just wind up using the one from
-        the regular object.  */
+      /* We need to remember the alignment required by the symbol
+        in the dynamic object.  */
+      BFD_ASSERT (pold_alignment);
+      *pold_alignment = h->root.u.def.section->alignment_power;
 
       olddef = FALSE;
       olddyncommon = FALSE;
@@ -1343,8 +1386,8 @@ _bfd_elf_add_default_symbol (bfd *abfd,
   size_change_ok = FALSE;
   sec = *psec;
   if (!_bfd_elf_merge_symbol (abfd, info, shortname, sym, &sec, value,
-                             &hi, &skip, &override, &type_change_ok,
-                             &size_change_ok))
+                             NULL, &hi, &skip, &override,
+                             &type_change_ok, &size_change_ok))
     return FALSE;
 
   if (skip)
@@ -1447,8 +1490,8 @@ nondefault:
   size_change_ok = FALSE;
   sec = *psec;
   if (!_bfd_elf_merge_symbol (abfd, info, shortname, sym, &sec, value,
-                             &hi, &skip, &override, &type_change_ok,
-                             &size_change_ok))
+                             NULL, &hi, &skip, &override,
+                             &type_change_ok, &size_change_ok))
     return FALSE;
 
   if (skip)
@@ -2815,7 +2858,12 @@ elf_add_dt_needed_tag (bfd *abfd,
 
 /* Called via elf_link_hash_traverse, elf_smash_syms sets all symbols
    belonging to NOT_NEEDED to bfd_link_hash_new.  We know there are no
-   references to these symbols.  */
+   references from regular objects to these symbols.
+
+   ??? Should we do something about references from other dynamic
+   obects?  If not, we potentially lose some warnings about undefined
+   symbols.  But how can we recover the initial undefined / undefweak
+   state?  */
 
 struct elf_smash_syms_data
 {
@@ -2837,6 +2885,22 @@ elf_smash_syms (struct elf_link_hash_entry *h, void *data)
       return TRUE;
 
     case bfd_link_hash_undefined:
+      if (h->root.u.undef.abfd != inf->not_needed)
+       return TRUE;
+      if (h->root.u.undef.weak != NULL
+         && h->root.u.undef.weak != inf->not_needed)
+       {
+         /* Symbol was undefweak in u.undef.weak bfd, and has become
+            undefined in as-needed lib.  Restore weak.  */
+         h->root.type = bfd_link_hash_undefweak;
+         h->root.u.undef.abfd = h->root.u.undef.weak;
+         if (h->root.u.undef.next != NULL
+             || inf->htab->root.undefs_tail == &h->root)
+           inf->twiddled = TRUE;
+         return TRUE;
+       }
+      break;
+
     case bfd_link_hash_undefweak:
       if (h->root.u.undef.abfd != inf->not_needed)
        return TRUE;
@@ -2863,6 +2927,11 @@ elf_smash_syms (struct elf_link_hash_entry *h, void *data)
       break;
     }
 
+  /* There is no way we can undo symbol table state from defined or
+     defweak back to undefined.  */
+  if (h->ref_regular)
+    abort ();
+
   /* Set sym back to newly created state, but keep undefs list pointer.  */
   bh = h->root.u.undef.next;
   if (bh != NULL || inf->htab->root.undefs_tail == &h->root)
@@ -3116,8 +3185,6 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
            {
              char *msg;
              bfd_size_type sz;
-             bfd_size_type prefix_len;
-             const char * gnu_warning_prefix = _("warning: ");
 
              name += sizeof ".gnu.warning." - 1;
 
@@ -3151,16 +3218,14 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
                }
 
              sz = s->size;
-             prefix_len = strlen (gnu_warning_prefix);
-             msg = bfd_alloc (abfd, prefix_len + sz + 1);
+             msg = bfd_alloc (abfd, sz + 1);
              if (msg == NULL)
                goto error_return;
 
-             strcpy (msg, gnu_warning_prefix);
-             if (! bfd_get_section_contents (abfd, s, msg + prefix_len, 0, sz))
+             if (! bfd_get_section_contents (abfd, s, msg, 0, sz))
                goto error_return;
 
-             msg[prefix_len + sz] = '\0';
+             msg[sz] = '\0';
 
              if (! (_bfd_generic_link_add_one_symbol
                     (info, abfd, name, BSF_WARNING, s, 0, msg,
@@ -3463,7 +3528,7 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
     {
       int bind;
       bfd_vma value;
-      asection *sec;
+      asection *sec, *new_sec;
       flagword flags;
       const char *name;
       struct elf_link_hash_entry *h;
@@ -3513,9 +3578,12 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
            sec = bfd_abs_section_ptr;
          else if (sec->kept_section)
            {
-             /* Symbols from discarded section are undefined.  */
+             /* Symbols from discarded section are undefined, and have
+                default visibility.  */
              sec = bfd_und_section_ptr;
              isym->st_shndx = SHN_UNDEF;
+             isym->st_other = STV_DEFAULT
+                              | (isym->st_other & ~ ELF_ST_VISIBILITY(-1));
            }
          else if ((abfd->flags & (EXEC_P | DYNAMIC)) != 0)
            value -= sec->vma;
@@ -3585,6 +3653,7 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
       type_change_ok = get_elf_backend_data (abfd)->type_change_ok;
       old_alignment = 0;
       old_bfd = NULL;
+      new_sec = sec;
 
       if (is_elf_hash_table (hash_table))
        {
@@ -3697,7 +3766,8 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
              name = newname;
            }
 
-         if (!_bfd_elf_merge_symbol (abfd, info, name, isym, &sec, &value,
+         if (!_bfd_elf_merge_symbol (abfd, info, name, isym, &sec,
+                                     &value, &old_alignment,
                                      sym_hash, &skip, &override,
                                      &type_change_ok, &size_change_ok))
            goto error_free_vers;
@@ -3779,12 +3849,20 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
        }
 
       /* Set the alignment of a common symbol.  */
-      if (isym->st_shndx == SHN_COMMON
+      if ((isym->st_shndx == SHN_COMMON
+          || bfd_is_com_section (sec))
          && h->root.type == bfd_link_hash_common)
        {
          unsigned int align;
 
-         align = bfd_log2 (isym->st_value);
+         if (isym->st_shndx == SHN_COMMON)
+           align = bfd_log2 (isym->st_value);
+         else
+           {
+             /* The new symbol is a common symbol in a shared object.
+                We need to get the alignment from the section.  */
+             align = new_sec->alignment_power;
+           }
          if (align > old_alignment
              /* Permit an alignment power of zero if an alignment of one
                 is specified and no other alignments have been specified.  */
@@ -4094,8 +4172,11 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
     free (isymbuf);
   isymbuf = NULL;
 
-  if (!add_needed)
+  if (!add_needed
+      && (elf_dyn_lib_class (abfd) & DYN_AS_NEEDED) != 0)
     {
+      /* Remove symbols defined in an as-needed shared lib that wasn't
+        needed.  */
       struct elf_smash_syms_data inf;
       inf.not_needed = abfd;
       inf.htab = hash_table;
@@ -4870,7 +4951,7 @@ bfd_elf_size_dynamic_sections (bfd *output_bfd,
        {
          asection *s;
 
-         if (inputobj->flags & DYNAMIC)
+         if (inputobj->flags & (DYNAMIC | BFD_LINKER_CREATED))
            continue;
          s = bfd_get_section_by_name (inputobj, ".note.GNU-stack");
          if (s)
@@ -6757,8 +6838,8 @@ elf_link_input_bfd (struct elf_final_link_info *finfo, bfd *input_bfd)
         For the benefit of the MIPS ELF linker, we check SEC_EXCLUDE
         as well as linker_mark.  */
       if ((isym->st_shndx < SHN_LORESERVE || isym->st_shndx > SHN_HIRESERVE)
-         && isec != NULL
-         && ((! isec->linker_mark && (isec->flags & SEC_HAS_CONTENTS) != 0)
+         && (isec == NULL
+             || (! isec->linker_mark && (isec->flags & SEC_HAS_CONTENTS) != 0)
              || (! finfo->info->relocatable
                  && (isec->flags & SEC_EXCLUDE) != 0)))
        continue;
@@ -8104,7 +8185,7 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
       long last_local = 0;
 
       /* Write out the section symbols for the output sections.  */
-      if (info->shared)
+      if (info->shared || elf_hash_table (info)->is_relocatable_executable)
        {
          asection *s;
 
This page took 0.02881 seconds and 4 git commands to generate.