[AArch64][1/3] Add R_AARCH64_P32_TLSLD_ADR_PREL21 in elf header
[deliverable/binutils-gdb.git] / bfd / linker.c
index a31e473417175aa07ac702ec5b42827f8dabc7c2..dec6d1d0ace372ebdb04662139ee16c6a09d4e49 100644 (file)
@@ -1,5 +1,5 @@
 /* linker.c -- BFD linker routines
-   Copyright (C) 1993-2014 Free Software Foundation, Inc.
+   Copyright (C) 1993-2015 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.
@@ -1120,29 +1120,21 @@ generic_link_check_archive_element (bfd *abfd,
 
       /* P is a symbol we are looking for.  */
 
-      if (! bfd_is_com_section (p->section))
+      if (! bfd_is_com_section (p->section)
+         || (h->type == bfd_link_hash_undefined
+             && h->u.undef.abfd == NULL))
        {
-         bfd_size_type symcount;
-         asymbol **symbols;
-         bfd *oldbfd = abfd;
-
-         /* This object file defines this symbol, so pull it in.  */
+         /* P is not a common symbol, or an undefined reference was
+            created from outside BFD such as from a linker -u option.
+            This object file defines the symbol, so pull it in.  */
+         *pneeded = TRUE;
          if (!(*info->callbacks
                ->add_archive_element) (info, abfd, bfd_asymbol_name (p),
                                        &abfd))
            return FALSE;
          /* Potentially, the add_archive_element hook may have set a
             substitute BFD for us.  */
-         if (abfd != oldbfd
-             && !bfd_generic_link_read_symbols (abfd))
-           return FALSE;
-         symcount = _bfd_generic_link_get_symcount (abfd);
-         symbols = _bfd_generic_link_get_symbols (abfd);
-         if (! generic_link_add_symbol_list (abfd, info, symcount,
-                                             symbols, collect))
-           return FALSE;
-         *pneeded = TRUE;
-         return TRUE;
+         return generic_link_add_object_symbols (abfd, info, collect);
        }
 
       /* P is a common symbol.  */
@@ -1153,23 +1145,6 @@ generic_link_check_archive_element (bfd *abfd,
          bfd_vma size;
          unsigned int power;
 
-         symbfd = h->u.undef.abfd;
-         if (symbfd == NULL)
-           {
-             /* This symbol was created as undefined from outside
-                BFD.  We assume that we should link in the object
-                file.  This is for the -u option in the linker.  */
-             if (!(*info->callbacks
-                   ->add_archive_element) (info, abfd, bfd_asymbol_name (p),
-                                           &abfd))
-               return FALSE;
-             /* Potentially, the add_archive_element hook may have set a
-                substitute BFD for us.  But no symbols are going to get
-                registered by anything we're returning to from here.  */
-             *pneeded = TRUE;
-             return TRUE;
-           }
-
          /* Turn the symbol into a common symbol but do not link in
             the object file.  This is how a.out works.  Object
             formats that require different semantics must implement
@@ -1177,6 +1152,7 @@ generic_link_check_archive_element (bfd *abfd,
             undefs list.  We add the section to a common section
             attached to symbfd to ensure that it is in a BFD which
             will be linked in.  */
+         symbfd = h->u.undef.abfd;
          h->type = bfd_link_hash_common;
          h->u.c.p = (struct bfd_link_hash_common_entry *)
            bfd_hash_allocate (&info->hash->table,
@@ -1366,8 +1342,7 @@ enum link_action
   CIND,                /* Make indirect symbol from existing common symbol.  */
   SET,         /* Add value to set.  */
   MWARN,       /* Make warning symbol.  */
-  WARN,                /* Issue warning.  */
-  CWARN,       /* Warn if referenced, else MWARN.  */
+  WARN,                /* Warn if referenced, else MWARN.  */
   CYCLE,       /* Repeat with symbol pointed to.  */
   REFC,                /* Mark indirect symbol referenced and then CYCLE.  */
   WARNC                /* Issue warning and then CYCLE.  */
@@ -1385,7 +1360,7 @@ static const enum link_action link_action[8][8] =
   /* DEFW_ROW  */  {DEFW,  DEFW,  DEFW,  NOACT, NOACT, NOACT, NOACT, CYCLE },
   /* COMMON_ROW        */  {COM,   COM,   COM,   CREF,  COM,   BIG,   REFC,  WARNC },
   /* INDR_ROW  */  {IND,   IND,   IND,   MDEF,  IND,   CIND,  MIND,  CYCLE },
-  /* WARN_ROW   */  {MWARN, WARN,  WARN,  CWARN, CWARN, WARN,  CWARN, NOACT },
+  /* WARN_ROW   */  {MWARN, WARN,  WARN,  WARN,  WARN,  WARN,  WARN,  NOACT },
   /* SET_ROW   */  {SET,   SET,   SET,   SET,   SET,   SET,   CYCLE, CYCLE }
 };
 
@@ -1467,13 +1442,23 @@ _bfd_generic_link_add_one_symbol (struct bfd_link_info *info,
 {
   enum link_row row;
   struct bfd_link_hash_entry *h;
+  struct bfd_link_hash_entry *inh = NULL;
   bfd_boolean cycle;
 
   BFD_ASSERT (section != NULL);
 
   if (bfd_is_ind_section (section)
       || (flags & BSF_INDIRECT) != 0)
-    row = INDR_ROW;
+    {
+      row = INDR_ROW;
+      /* Create the indirect symbol here.  This is for the benefit of
+        the plugin "notice" function.
+        STRING is the name of the symbol we want to indirect to.  */
+      inh = bfd_wrapped_link_hash_lookup (abfd, info, string, TRUE,
+                                         copy, FALSE);
+      if (inh == NULL)
+       return FALSE;
+    }
   else if ((flags & BSF_WARNING) != 0)
     row = WARN_ROW;
   else if ((flags & BSF_CONSTRUCTOR) != 0)
@@ -1518,8 +1503,8 @@ _bfd_generic_link_add_one_symbol (struct bfd_link_info *info,
       || (info->notice_hash != NULL
          && bfd_hash_lookup (info->notice_hash, name, FALSE, FALSE) != NULL))
     {
-      if (! (*info->callbacks->notice) (info, h,
-                                       abfd, section, value, flags, string))
+      if (! (*info->callbacks->notice) (info, h, inh,
+                                       abfd, section, value, flags))
        return FALSE;
     }
 
@@ -1575,6 +1560,7 @@ _bfd_generic_link_add_one_symbol (struct bfd_link_info *info,
              h->type = bfd_link_hash_defined;
            h->u.def.section = section;
            h->u.def.value = value;
+           h->linker_def = 0;
 
            /* If we have been asked to, we act like collect2 and
               identify all functions that might be global
@@ -1674,6 +1660,7 @@ _bfd_generic_link_add_one_symbol (struct bfd_link_info *info,
            }
          else
            h->u.c.p->section = section;
+         h->linker_def = 0;
          break;
 
        case REF:
@@ -1753,44 +1740,40 @@ _bfd_generic_link_add_one_symbol (struct bfd_link_info *info,
            return FALSE;
          /* Fall through.  */
        case IND:
-         /* Create an indirect symbol.  */
-         {
-           struct bfd_link_hash_entry *inh;
-
-           /* STRING is the name of the symbol we want to indirect
-              to.  */
-           inh = bfd_wrapped_link_hash_lookup (abfd, info, string, TRUE,
-                                               copy, FALSE);
-           if (inh == NULL)
+         if (inh->type == bfd_link_hash_indirect
+             && inh->u.i.link == h)
+           {
+             (*_bfd_error_handler)
+               (_("%B: indirect symbol `%s' to `%s' is a loop"),
+                abfd, name, string);
+             bfd_set_error (bfd_error_invalid_operation);
              return FALSE;
-           if (inh->type == bfd_link_hash_indirect
-               && inh->u.i.link == h)
-             {
-               (*_bfd_error_handler)
-                 (_("%B: indirect symbol `%s' to `%s' is a loop"),
-                  abfd, name, string);
-               bfd_set_error (bfd_error_invalid_operation);
-               return FALSE;
-             }
-           if (inh->type == bfd_link_hash_new)
-             {
-               inh->type = bfd_link_hash_undefined;
-               inh->u.undef.abfd = abfd;
-               bfd_link_add_undef (info->hash, inh);
-             }
+           }
+         if (inh->type == bfd_link_hash_new)
+           {
+             inh->type = bfd_link_hash_undefined;
+             inh->u.undef.abfd = abfd;
+             bfd_link_add_undef (info->hash, inh);
+           }
 
-           /* If the indirect symbol has been referenced, we need to
-              push the reference down to the symbol we are
-              referencing.  */
-           if (h->type != bfd_link_hash_new)
-             {
-               row = UNDEF_ROW;
-               cycle = TRUE;
-             }
+         /* If the indirect symbol has been referenced, we need to
+            push the reference down to the symbol we are referencing.  */
+         if (h->type != bfd_link_hash_new)
+           {
+             /* ??? If inh->type == bfd_link_hash_undefweak this
+                converts inh to bfd_link_hash_undefined.  */
+             row = UNDEF_ROW;
+             cycle = TRUE;
+           }
 
-           h->type = bfd_link_hash_indirect;
-           h->u.i.link = inh;
-         }
+         h->type = bfd_link_hash_indirect;
+         h->u.i.link = inh;
+         /* Not setting h = h->u.i.link here means that when cycle is
+            set above we'll always go to REFC, and then cycle again
+            to the indirected symbol.  This means that any successful
+            change of an existing symbol to indirect counts as a
+            reference.  ??? That may not be correct when the existing
+            symbol was defweak.  */
          break;
 
        case SET:
@@ -1801,8 +1784,10 @@ _bfd_generic_link_add_one_symbol (struct bfd_link_info *info,
          break;
 
        case WARNC:
-         /* Issue a warning and cycle.  */
-         if (h->u.i.warning != NULL)
+         /* Issue a warning and cycle, except when the reference is
+            in LTO IR.  */
+         if (h->u.i.warning != NULL
+             && (abfd->flags & BFD_PLUGIN) == 0)
            {
              if (! (*info->callbacks->warning) (info, h->u.i.warning,
                                                 h->root.string, abfd,
@@ -1827,19 +1812,11 @@ _bfd_generic_link_add_one_symbol (struct bfd_link_info *info,
          break;
 
        case WARN:
-         /* Issue a warning.  */
-         if (! (*info->callbacks->warning) (info, string, h->root.string,
-                                            hash_entry_bfd (h), NULL, 0))
-           return FALSE;
-         break;
-
-       case CWARN:
-         /* Warn if this symbol has been referenced already,
-            otherwise add a warning.  A symbol has been referenced if
-            the u.undef.next field is not NULL, or it is the tail of the
-            undefined symbol list.  The REF case above helps to
-            ensure this.  */
-         if (h->u.undef.next != NULL || info->hash->undefs_tail == h)
+         /* Warn if this symbol has been referenced already from non-IR,
+            otherwise add a warning.  */
+         if ((!info->lto_plugin_active
+              && (h->u.undef.next != NULL || info->hash->undefs_tail == h))
+             || h->non_ir_ref)
            {
              if (! (*info->callbacks->warning) (info, string, h->root.string,
                                                 hash_entry_bfd (h), NULL, 0))
@@ -2159,7 +2136,7 @@ _bfd_generic_link_output_symbols (bfd *output_bfd,
                  /* fall through */
                case bfd_link_hash_defined:
                  sym->flags |= BSF_GLOBAL;
-                 sym->flags &=~ BSF_CONSTRUCTOR;
+                 sym->flags &=~ (BSF_WEAK | BSF_CONSTRUCTOR);
                  sym->value = h->root.u.def.value;
                  sym->section = h->root.u.def.section;
                  break;
@@ -2457,7 +2434,7 @@ _bfd_generic_reloc_link_order (bfd *abfd,
 
       size = bfd_get_reloc_size (r->howto);
       buf = (bfd_byte *) bfd_zmalloc (size);
-      if (buf == NULL)
+      if (buf == NULL && size != 0)
        return FALSE;
       rstat = _bfd_relocate_contents (r->howto, abfd,
                                      (bfd_vma) link_order->u.reloc.p->addend,
@@ -2919,7 +2896,7 @@ _bfd_handle_already_linked (asection *sec,
         files over IR because the first pass may contain a
         mix of LTO and normal objects and we must keep the
         first match, be it IR or real.  */
-      if (info->loading_lto_outputs
+      if (sec->owner->lto_output
          && (l->sec->owner->flags & BFD_PLUGIN) != 0)
        {
          l->sec = sec;
This page took 0.036569 seconds and 4 git commands to generate.