* Makefile.in (SFILES): Add cp-names.y.
[deliverable/binutils-gdb.git] / bfd / elflink.c
index d7c9ded0b18412dfd401b7bc2dea3d5577f742d1..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:
@@ -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)
@@ -3485,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;
@@ -3535,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;
@@ -3607,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))
        {
@@ -3719,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;
@@ -3801,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.  */
@@ -4895,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)
@@ -6782,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;
@@ -8129,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.033241 seconds and 4 git commands to generate.