This adjusts equate handling by
[deliverable/binutils-gdb.git] / bfd / elflink.c
index 14096aa0a7a2bf5b3bd501b42480cf43de1c58e6..61676d619f6276824a4a0a7a35475ce577ba6746 100644 (file)
@@ -37,6 +37,7 @@ _bfd_elf_define_linkage_sym (bfd *abfd,
 {
   struct elf_link_hash_entry *h;
   struct bfd_link_hash_entry *bh;
+  const struct elf_backend_data *bed;
 
   h = elf_link_hash_lookup (elf_hash_table (info), name, FALSE, FALSE, FALSE);
   if (h != NULL)
@@ -59,10 +60,8 @@ _bfd_elf_define_linkage_sym (bfd *abfd,
   h->type = STT_OBJECT;
   h->other = (h->other & ~ELF_ST_VISIBILITY (-1)) | STV_HIDDEN;
 
-  if (!info->executable
-      && !bfd_elf_link_record_dynamic_symbol (info, h))
-    return NULL;
-
+  bed = get_elf_backend_data (abfd);
+  (*bed->elf_backend_hide_symbol) (info, h, TRUE);
   return h;
 }
 
@@ -736,7 +735,8 @@ _bfd_elf_link_renumber_dynsyms (bfd *output_bfd,
   if (dynsymcount != 0)
     ++dynsymcount;
 
-  return elf_hash_table (info)->dynsymcount = dynsymcount;
+  elf_hash_table (info)->dynsymcount = dynsymcount;
+  return dynsymcount;
 }
 
 /* This function is called when we want to define a new symbol.  It
@@ -852,59 +852,32 @@ _bfd_elf_merge_symbol (bfd *abfd,
   /* NEWDYN and OLDDYN indicate whether the new or old symbol,
      respectively, is from a dynamic object.  */
 
-  if ((abfd->flags & DYNAMIC) != 0)
-    newdyn = TRUE;
-  else
-    newdyn = FALSE;
+  newdyn = (abfd->flags & DYNAMIC) != 0;
 
+  olddyn = FALSE;
   if (oldbfd != NULL)
     olddyn = (oldbfd->flags & DYNAMIC) != 0;
-  else
+  else if (oldsec != NULL)
     {
-      asection *hsec;
-
-      /* This code handles the special SHN_MIPS_{TEXT,DATA} section
+      /* This handles the special SHN_MIPS_{TEXT,DATA} section
         indices used by MIPS ELF.  */
-      switch (h->root.type)
-       {
-       default:
-         hsec = NULL;
-         break;
-
-       case bfd_link_hash_defined:
-       case bfd_link_hash_defweak:
-         hsec = h->root.u.def.section;
-         break;
-
-       case bfd_link_hash_common:
-         hsec = h->root.u.c.p->section;
-         break;
-       }
-
-      if (hsec == NULL)
-       olddyn = FALSE;
-      else
-       olddyn = (hsec->symbol->flags & BSF_DYNAMIC) != 0;
+      olddyn = (oldsec->symbol->flags & BSF_DYNAMIC) != 0;
     }
 
   /* NEWDEF and OLDDEF indicate whether the new or old symbol,
      respectively, appear to be a definition rather than reference.  */
 
-  if (bfd_is_und_section (sec) || bfd_is_com_section (sec))
-    newdef = FALSE;
-  else
-    newdef = TRUE;
+  newdef = !bfd_is_und_section (sec) && !bfd_is_com_section (sec);
 
-  if (h->root.type == bfd_link_hash_undefined
-      || h->root.type == bfd_link_hash_undefweak
-      || h->root.type == bfd_link_hash_common)
-    olddef = FALSE;
-  else
-    olddef = TRUE;
+  olddef = (h->root.type != bfd_link_hash_undefined
+           && h->root.type != bfd_link_hash_undefweak
+           && h->root.type != bfd_link_hash_common);
 
-  /* Check TLS symbol.  */
+  /* Check TLS symbol.  We don't check undefined symbol introduced by
+     "ld -u".  */
   if ((ELF_ST_TYPE (sym->st_info) == STT_TLS || h->type == STT_TLS)
-      && ELF_ST_TYPE (sym->st_info) != h->type)
+      && ELF_ST_TYPE (sym->st_info) != h->type
+      && oldbfd != NULL)
     {
       bfd *ntbfd, *tbfd;
       bfd_boolean ntdef, tdef;
@@ -3289,11 +3262,10 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
       int ret;
 
       /* ld --just-symbols and dynamic objects don't mix very well.
-        Test for --just-symbols by looking at info set up by
-        _bfd_elf_link_just_syms.  */
+        ld shouldn't allow it.  */
       if ((s = abfd->sections) != NULL
          && s->sec_info_type == ELF_INFO_TYPE_JUST_SYMS)
-       goto error_return;
+       abort ();
 
       /* If this dynamic lib was specified on the command line with
         --as-needed in effect, then we don't want to add a DT_NEEDED
@@ -7610,7 +7582,7 @@ elf_get_linked_section_vma (struct bfd_link_order *p)
   elfsec = elf_shdrp[elfsec]->sh_link;
   /* PR 290:
      The Intel C compiler generates SHT_IA_64_UNWIND with
-     SHF_LINK_ORDER.  But it doesn't set theh sh_link or
+     SHF_LINK_ORDER.  But it doesn't set the sh_link or
      sh_info fields.  Hence we could get the situation
      where elfsec is 0.  */
   if (elfsec == 0)
@@ -7663,41 +7635,54 @@ elf_fixup_link_order (bfd *abfd, asection *o)
   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
   int elfsec;
   struct bfd_link_order **sections;
-  asection *s;
+  asection *s, *other_sec, *linkorder_sec;
   bfd_vma offset;
 
+  other_sec = NULL;
+  linkorder_sec = NULL;
   seen_other = 0;
   seen_linkorder = 0;
   for (p = o->map_head.link_order; p != NULL; p = p->next)
     {
-      if (p->type == bfd_indirect_link_order
-         && (bfd_get_flavour ((sub = p->u.indirect.section->owner))
-             == bfd_target_elf_flavour)
-         && elf_elfheader (sub)->e_ident[EI_CLASS] == bed->s->elfclass)
+      if (p->type == bfd_indirect_link_order)
        {
          s = p->u.indirect.section;
-         elfsec = _bfd_elf_section_from_bfd_section (sub, s);
-         if (elfsec != -1
+         sub = s->owner;
+         if (bfd_get_flavour (sub) == bfd_target_elf_flavour
+             && elf_elfheader (sub)->e_ident[EI_CLASS] == bed->s->elfclass
+             && (elfsec = _bfd_elf_section_from_bfd_section (sub, s)) != -1
              && elf_elfsections (sub)[elfsec]->sh_flags & SHF_LINK_ORDER)
-           seen_linkorder++;
+           {
+             seen_linkorder++;
+             linkorder_sec = s;
+           }
          else
-           seen_other++;
+           {
+             seen_other++;
+             other_sec = s;
+           }
        }
       else
        seen_other++;
+
+      if (seen_other && seen_linkorder)
+       {
+         if (other_sec && linkorder_sec)
+           (*_bfd_error_handler) (_("%A has both ordered [`%A' in %B] and unordered [`%A' in %B] sections"),
+                                  o, linkorder_sec,
+                                  linkorder_sec->owner, other_sec,
+                                  other_sec->owner);
+         else
+           (*_bfd_error_handler) (_("%A has both ordered and unordered sections"),
+                                  o);
+         bfd_set_error (bfd_error_bad_value);
+         return FALSE;
+       }
     }
 
   if (!seen_linkorder)
     return TRUE;
 
-  if (seen_other && seen_linkorder)
-    {
-      (*_bfd_error_handler) (_("%A has both ordered and unordered sections"),
-                            o);
-      bfd_set_error (bfd_error_bad_value);
-      return FALSE;
-    }
-
   sections = (struct bfd_link_order **)
     xmalloc (seen_linkorder * sizeof (struct bfd_link_order *));
   seen_linkorder = 0;
@@ -8852,19 +8837,26 @@ _bfd_elf_gc_mark (struct bfd_link_info *info,
 
 /* Sweep symbols in swept sections.  Called via elf_link_hash_traverse.  */
 
+struct elf_gc_sweep_symbol_info {
+  struct bfd_link_info *info;
+  void (*hide_symbol) (struct bfd_link_info *, struct elf_link_hash_entry *,
+                      bfd_boolean);
+};
+
 static bfd_boolean
-elf_gc_sweep_symbol (struct elf_link_hash_entry *h, void *idxptr)
+elf_gc_sweep_symbol (struct elf_link_hash_entry *h, void *data)
 {
-  int *idx = idxptr;
-
   if (h->root.type == bfd_link_hash_warning)
     h = (struct elf_link_hash_entry *) h->root.u.i.link;
 
-  if (h->dynindx != -1
-      && ((h->root.type != bfd_link_hash_defined
-          && h->root.type != bfd_link_hash_defweak)
-         || h->root.u.def.section->gc_mark))
-    h->dynindx = (*idx)++;
+  if ((h->root.type == bfd_link_hash_defined
+       || h->root.type == bfd_link_hash_defweak)
+      && !h->root.u.def.section->gc_mark
+      && !(h->root.u.def.section->owner->flags & DYNAMIC))
+    {
+      struct elf_gc_sweep_symbol_info *inf = data;
+      (*inf->hide_symbol) (inf->info, h, TRUE);
+    }
 
   return TRUE;
 }
@@ -8875,9 +8867,13 @@ typedef bfd_boolean (*gc_sweep_hook_fn)
   (bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *);
 
 static bfd_boolean
-elf_gc_sweep (struct bfd_link_info *info, gc_sweep_hook_fn gc_sweep_hook)
+elf_gc_sweep (bfd *abfd, struct bfd_link_info *info)
 {
   bfd *sub;
+  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+  gc_sweep_hook_fn gc_sweep_hook = bed->gc_sweep_hook;
+  unsigned long section_sym_count;
+  struct elf_gc_sweep_symbol_info sweep_info;
 
   for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
     {
@@ -8934,20 +8930,12 @@ elf_gc_sweep (struct bfd_link_info *info, gc_sweep_hook_fn gc_sweep_hook)
   /* Remove the symbols that were in the swept sections from the dynamic
      symbol table.  GCFIXME: Anyone know how to get them out of the
      static symbol table as well?  */
-  {
-    int i = 0;
-
-    elf_link_hash_traverse (elf_hash_table (info), elf_gc_sweep_symbol, &i);
-
-    /* There is an unused NULL entry at the head of the table which
-       we must account for in our count.  Unless there weren't any
-       symbols, which means we'll have no table at all.  */
-    if (i != 0)
-      ++i;
-
-    elf_hash_table (info)->dynsymcount = i;
-  }
+  sweep_info.info = info;
+  sweep_info.hide_symbol = bed->elf_backend_hide_symbol;
+  elf_link_hash_traverse (elf_hash_table (info), elf_gc_sweep_symbol,
+                         &sweep_info);
 
+  _bfd_elf_link_renumber_dynsyms (abfd, info, &section_sym_count);
   return TRUE;
 }
 
@@ -9184,10 +9172,7 @@ bfd_elf_gc_sections (bfd *abfd, struct bfd_link_info *info)
     }
 
   /* ... and mark SEC_EXCLUDE for those that go.  */
-  if (!elf_gc_sweep (info, get_elf_backend_data (abfd)->gc_sweep_hook))
-    return FALSE;
-
-  return TRUE;
+  return elf_gc_sweep (abfd, info);
 }
 \f
 /* Called from check_relocs to record the existence of a VTINHERIT reloc.  */
This page took 0.027765 seconds and 4 git commands to generate.