daily update
[deliverable/binutils-gdb.git] / bfd / linker.c
index 04044743f263bc7207eecd89dba17de9cd27f4ed..f6ae4e2c6264b07e7042507f0641c37644a96dcf 100644 (file)
@@ -1,7 +1,5 @@
 /* linker.c -- BFD linker routines
-   Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-   2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
-   Free Software Foundation, Inc.
+   Copyright (C) 1993-2014 Free Software Foundation, Inc.
    Written by Steve Chamberlain and Ian Lance Taylor, Cygnus Support
 
    This file is part of BFD, the Binary File Descriptor library.
@@ -315,7 +313,7 @@ SUBSUBSECTION
 
        The <<input_bfds>> field of the <<bfd_link_info>> structure
        will point to a list of all the input files included in the
-       link.  These files are linked through the <<link_next>> field
+       link.  These files are linked through the <<link.next>> field
        of the <<bfd>> structure.
 
        Each section in the output file will have a list of
@@ -484,11 +482,22 @@ _bfd_link_hash_table_init
                                      const char *),
    unsigned int entsize)
 {
+  bfd_boolean ret;
+
+  BFD_ASSERT (!abfd->is_linker_output && !abfd->link.hash);
   table->undefs = NULL;
   table->undefs_tail = NULL;
   table->type = bfd_link_generic_hash_table;
 
-  return bfd_hash_table_init (&table->table, newfunc, entsize);
+  ret = bfd_hash_table_init (&table->table, newfunc, entsize);
+  if (ret)
+    {
+      /* Arrange for destruction of this hash table on closing ABFD.  */
+      table->hash_table_free = _bfd_generic_link_hash_table_free;
+      abfd->link.hash = table;
+      abfd->is_linker_output = TRUE;
+    }
+  return ret;
 }
 
 /* Look up a symbol in a link hash table.  If follow is TRUE, we
@@ -568,8 +577,6 @@ bfd_wrapped_link_hash_lookup (bfd *abfd,
          return h;
        }
 
-#undef WRAP
-
 #undef  REAL
 #define REAL "__real_"
 
@@ -604,6 +611,42 @@ bfd_wrapped_link_hash_lookup (bfd *abfd,
   return bfd_link_hash_lookup (info->hash, string, create, copy, follow);
 }
 
+/* If H is a wrapped symbol, ie. the symbol name starts with "__wrap_"
+   and the remainder is found in wrap_hash, return the real symbol.  */
+
+struct bfd_link_hash_entry *
+unwrap_hash_lookup (struct bfd_link_info *info,
+                   bfd *input_bfd,
+                   struct bfd_link_hash_entry *h)
+{
+  const char *l = h->root.string;
+
+  if (*l == bfd_get_symbol_leading_char (input_bfd)
+      || *l == info->wrap_char)
+    ++l;
+
+  if (CONST_STRNEQ (l, WRAP))
+    {
+      l += sizeof WRAP - 1;
+
+      if (bfd_hash_lookup (info->wrap_hash, l, FALSE, FALSE) != NULL)
+       {
+         char save = 0;
+         if (l - (sizeof WRAP - 1) != h->root.string)
+           {
+             --l;
+             save = *l;
+             *(char *) l = *h->root.string;
+           }
+         h = bfd_link_hash_lookup (info->hash, l, FALSE, FALSE, FALSE);
+         if (save)
+           *(char *) l = save;
+       }
+    }
+  return h;
+}
+#undef WRAP
+
 /* Traverse a generic link hash table.  Differs from bfd_hash_traverse
    in the treatment of warning symbols.  When warning symbols are
    created they replace the real symbol, so you don't get to see the
@@ -739,13 +782,16 @@ _bfd_generic_link_hash_table_create (bfd *abfd)
 }
 
 void
-_bfd_generic_link_hash_table_free (struct bfd_link_hash_table *hash)
+_bfd_generic_link_hash_table_free (bfd *obfd)
 {
-  struct generic_link_hash_table *ret
-    = (struct generic_link_hash_table *) hash;
+  struct generic_link_hash_table *ret;
 
+  BFD_ASSERT (obfd->is_linker_output && obfd->link.hash);
+  ret = (struct generic_link_hash_table *) obfd->link.hash;
   bfd_hash_table_free (&ret->root.table);
   free (ret);
+  obfd->link.hash = NULL;
+  obfd->is_linker_output = FALSE;
 }
 
 /* Grab the symbols for an object file when doing a generic link.  We
@@ -810,18 +856,18 @@ void
 _bfd_generic_link_just_syms (asection *sec,
                             struct bfd_link_info *info ATTRIBUTE_UNUSED)
 {
+  sec->sec_info_type = SEC_INFO_TYPE_JUST_SYMS;
   sec->output_section = bfd_abs_section_ptr;
   sec->output_offset = sec->vma;
 }
 
-/* Copy the type of a symbol assiciated with a linker hast table entry.
-   Override this so that symbols created in linker scripts get their
-   type from the RHS of the assignment.
+/* Copy the symbol type and other attributes for a linker script
+   assignment from HSRC to HDEST.
    The default implementation does nothing.  */
 void
 _bfd_generic_copy_link_hash_symbol_type (bfd *abfd ATTRIBUTE_UNUSED,
-    struct bfd_link_hash_entry * hdest ATTRIBUTE_UNUSED,
-    struct bfd_link_hash_entry * hsrc ATTRIBUTE_UNUSED)
+    struct bfd_link_hash_entry *hdest ATTRIBUTE_UNUSED,
+    struct bfd_link_hash_entry *hsrc ATTRIBUTE_UNUSED)
 {
 }
 
@@ -2013,7 +2059,7 @@ _bfd_generic_final_link (bfd *abfd, struct bfd_link_info *info)
        p->u.indirect.section->linker_mark = TRUE;
 
   /* Build the output symbol table.  */
-  for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
+  for (sub = info->input_bfds; sub != NULL; sub = sub->link.next)
     if (! _bfd_generic_link_output_symbols (abfd, sub, info, &outsymalloc))
       return FALSE;
 
@@ -2358,6 +2404,12 @@ _bfd_generic_link_output_symbols (bfd *output_bfd,
          else
            output = FALSE;
        }
+      else if (sym->flags == 0
+              && (sym->section->owner->flags & BFD_PLUGIN) != 0)
+       /* LTO doesn't set symbol information.  We get here with the
+          generic linker for a symbol that was "common" but no longer
+          needs to be global.  */
+       output = FALSE;
       else
        abort ();
 
@@ -2912,7 +2964,7 @@ DESCRIPTION
 /* Sections marked with the SEC_LINK_ONCE flag should only be linked
    once into the output.  This routine checks each section, and
    arrange to discard it if a section of the same name has already
-   been linked.  This code assumes that all relevant sections have the 
+   been linked.  This code assumes that all relevant sections have the
    SEC_LINK_ONCE flag set; that is, it does not depend solely upon the
    section name.  bfd_section_already_linked is called via
    bfd_map_over_sections.  */
@@ -3130,6 +3182,76 @@ _bfd_generic_section_already_linked (bfd *abfd ATTRIBUTE_UNUSED,
   return FALSE;
 }
 
+/* Choose a neighbouring section to S in OBFD that will be output, or
+   the absolute section if ADDR is out of bounds of the neighbours.  */
+
+asection *
+_bfd_nearby_section (bfd *obfd, asection *s, bfd_vma addr)
+{
+  asection *next, *prev, *best;
+
+  /* Find preceding kept section.  */
+  for (prev = s->prev; prev != NULL; prev = prev->prev)
+    if ((prev->flags & SEC_EXCLUDE) == 0
+       && !bfd_section_removed_from_list (obfd, prev))
+      break;
+
+  /* Find following kept section.  Start at prev->next because
+     other sections may have been added after S was removed.  */
+  if (s->prev != NULL)
+    next = s->prev->next;
+  else
+    next = s->owner->sections;
+  for (; next != NULL; next = next->next)
+    if ((next->flags & SEC_EXCLUDE) == 0
+       && !bfd_section_removed_from_list (obfd, next))
+      break;
+
+  /* Choose better of two sections, based on flags.  The idea
+     is to choose a section that will be in the same segment
+     as S would have been if it was kept.  */
+  best = next;
+  if (prev == NULL)
+    {
+      if (next == NULL)
+       best = bfd_abs_section_ptr;
+    }
+  else if (next == NULL)
+    best = prev;
+  else if (((prev->flags ^ next->flags)
+           & (SEC_ALLOC | SEC_THREAD_LOCAL | SEC_LOAD)) != 0)
+    {
+      if (((next->flags ^ s->flags)
+          & (SEC_ALLOC | SEC_THREAD_LOCAL)) != 0
+         /* We prefer to choose a loaded section.  Section S
+            doesn't have SEC_LOAD set (it being excluded, that
+            part of the flag processing didn't happen) so we
+            can't compare that flag to those of NEXT and PREV.  */
+         || ((prev->flags & SEC_LOAD) != 0
+             && (next->flags & SEC_LOAD) == 0))
+       best = prev;
+    }
+  else if (((prev->flags ^ next->flags) & SEC_READONLY) != 0)
+    {
+      if (((next->flags ^ s->flags) & SEC_READONLY) != 0)
+       best = prev;
+    }
+  else if (((prev->flags ^ next->flags) & SEC_CODE) != 0)
+    {
+      if (((next->flags ^ s->flags) & SEC_CODE) != 0)
+       best = prev;
+    }
+  else
+    {
+      /* Flags we care about are the same.  Prefer the following
+        section if that will result in a positive valued sym.  */
+      if (addr < next->vma)
+       best = prev;
+    }
+
+  return best;
+}
+
 /* Convert symbols in excluded output sections to use a kept section.  */
 
 static bfd_boolean
@@ -3146,74 +3268,10 @@ fix_syms (struct bfd_link_hash_entry *h, void *data)
          && (s->output_section->flags & SEC_EXCLUDE) != 0
          && bfd_section_removed_from_list (obfd, s->output_section))
        {
-         asection *op, *op1;
+         asection *op;
 
          h->u.def.value += s->output_offset + s->output_section->vma;
-
-         /* Find preceding kept section.  */
-         for (op1 = s->output_section->prev; op1 != NULL; op1 = op1->prev)
-           if ((op1->flags & SEC_EXCLUDE) == 0
-               && !bfd_section_removed_from_list (obfd, op1))
-             break;
-
-         /* Find following kept section.  Start at prev->next because
-            other sections may have been added after S was removed.  */
-         if (s->output_section->prev != NULL)
-           op = s->output_section->prev->next;
-         else
-           op = s->output_section->owner->sections;
-         for (; op != NULL; op = op->next)
-           if ((op->flags & SEC_EXCLUDE) == 0
-               && !bfd_section_removed_from_list (obfd, op))
-             break;
-
-         /* Choose better of two sections, based on flags.  The idea
-            is to choose a section that will be in the same segment
-            as S would have been if it was kept.  */
-         if (op1 == NULL)
-           {
-             if (op == NULL)
-               op = bfd_abs_section_ptr;
-           }
-         else if (op == NULL)
-           op = op1;
-         else if (((op1->flags ^ op->flags)
-                   & (SEC_ALLOC | SEC_THREAD_LOCAL | SEC_LOAD)) != 0)
-           {
-             if (((op->flags ^ s->flags)
-                  & (SEC_ALLOC | SEC_THREAD_LOCAL)) != 0
-                 /* We prefer to choose a loaded section.  Section S
-                    doesn't have SEC_LOAD set (it being excluded, that
-                    part of the flag processing didn't happen) so we
-                    can't compare that flag to those of OP and OP1.  */
-                 || ((op1->flags & SEC_LOAD) != 0
-                     && (op->flags & SEC_LOAD) == 0))
-               op = op1;
-           }
-         else if (((op1->flags ^ op->flags) & SEC_READONLY) != 0)
-           {
-             if (((op->flags ^ s->flags) & SEC_READONLY) != 0)
-               op = op1;
-           }
-         else if (((op1->flags ^ op->flags) & SEC_CODE) != 0)
-           {
-             if (((op->flags ^ s->flags) & SEC_CODE) != 0)
-               op = op1;
-           }
-         else
-           {
-             /* Flags we care about are the same.  Prefer the following
-                section if that will result in a positive valued sym.  */
-             if (h->u.def.value < op->vma)
-               op = op1;
-           }
-
-         /* Refuse to choose a section for which we are out of bounds.  */
-         /* ??? This may make most of the above moot.  */
-         if (h->u.def.value < op->vma
-             || h->u.def.value > op->vma + op->size)
-           op = bfd_abs_section_ptr;
-
+         op = _bfd_nearby_section (obfd, s->output_section, h->u.def.value);
          h->u.def.value -= op->vma;
          h->u.def.section = op;
        }
@@ -3289,7 +3347,7 @@ bfd_generic_define_common_symbol (bfd *output_bfd,
 
 /*
 FUNCTION
-       bfd_find_version_for_sym 
+       bfd_find_version_for_sym
 
 SYNOPSIS
        struct bfd_elf_version_tree * bfd_find_version_for_sym
This page took 0.028253 seconds and 4 git commands to generate.