non_ir_ref_dynamic
authorAlan Modra <amodra@gmail.com>
Mon, 15 May 2017 22:26:41 +0000 (07:56 +0930)
committerAlan Modra <amodra@gmail.com>
Tue, 16 May 2017 01:05:02 +0000 (10:35 +0930)
dynamic_ref_after_ir_def is a little odd compared to other symbol
flags in that as the name suggests, it is set only for certain
references after a definition.  It turns out that setting a flag for
any non-ir reference from a dynamic object can be used to solve the
problem for which this flag was invented, which I think is a cleaner.
This patch does that, and sets non_ir_ref only for regular object
references.

include/
* bfdlink.h (struct bfd_link_hash_entry): Update non_ir_ref
comment.  Rename dynamic_ref_after_ir_def to non_ir_ref_dynamic.
ld/
* plugin.c (is_visible_from_outside): Use non_ir_ref_dynamic.
(plugin_notice): Set non_ir_ref for references from regular
objects, non_ir_ref_dynamic for references from dynamic objects.
bfd/
* elf64-ppc.c (add_symbol_adjust): Transfer non_ir_ref_dynamic.
* elflink.c (elf_link_add_object_symbols): Update to use
non_ir_ref_dynamic.
(elf_link_input_bfd): Test non_ir_ref_dynamic in addition to
non_ir_ref.
* linker.c (_bfd_generic_link_add_one_symbol): Likewise.

bfd/ChangeLog
bfd/elf64-ppc.c
bfd/elflink.c
bfd/linker.c
include/ChangeLog
include/bfdlink.h
ld/ChangeLog
ld/plugin.c

index 52c192d..8b3f1a5 100644 (file)
@@ -1,3 +1,12 @@
+2017-05-16  Alan Modra  <amodra@gmail.com>
+
+       * elf64-ppc.c (add_symbol_adjust): Transfer non_ir_ref_dynamic.
+       * elflink.c (elf_link_add_object_symbols): Update to use
+       non_ir_ref_dynamic.
+       (elf_link_input_bfd): Test non_ir_ref_dynamic in addition to
+       non_ir_ref.
+       * linker.c (_bfd_generic_link_add_one_symbol): Likewise.
+
 2017-05-15  Maciej W. Rozycki  <macro@imgtec.com>
 
        * elfxx-mips.c (print_mips_ases): Handle MIPS16e2 ASE.
index a20d9b3..a2cc373 100644 (file)
@@ -5119,6 +5119,7 @@ add_symbol_adjust (struct ppc_link_hash_entry *eh, struct bfd_link_info *info)
       /* Propagate reference flags from entry symbol to function
         descriptor symbol.  */
       fdh->elf.root.non_ir_ref |= eh->elf.root.non_ir_ref;
+      fdh->elf.root.non_ir_ref_dynamic |= eh->elf.root.non_ir_ref_dynamic;
       fdh->elf.ref_regular |= eh->elf.ref_regular;
       fdh->elf.ref_regular_nonweak |= eh->elf.ref_regular_nonweak;
 
index ba50b68..8eaf533 100644 (file)
@@ -4939,7 +4939,7 @@ error_free_dyn:
          struct elf_link_hash_entry *h;
          bfd_size_type size;
          unsigned int alignment_power;
-         unsigned int dynamic_ref_after_ir_def;
+         unsigned int non_ir_ref_dynamic;
 
          for (p = htab->root.table.table[i]; p != NULL; p = p->next)
            {
@@ -4961,10 +4961,10 @@ error_free_dyn:
                  size = 0;
                  alignment_power = 0;
                }
-             /* Preserve dynamic_ref_after_ir_def so that this symbol
+             /* Preserve non_ir_ref_dynamic so that this symbol
                 will be exported when the dynamic lib becomes needed
                 in the second pass.  */
-             dynamic_ref_after_ir_def = h->root.dynamic_ref_after_ir_def;
+             non_ir_ref_dynamic = h->root.non_ir_ref_dynamic;
              memcpy (p, old_ent, htab->root.table.entsize);
              old_ent = (char *) old_ent + htab->root.table.entsize;
              h = (struct elf_link_hash_entry *) p;
@@ -4981,7 +4981,7 @@ error_free_dyn:
                  if (alignment_power > h->root.u.c.p->alignment_power)
                    h->root.u.c.p->alignment_power = alignment_power;
                }
-             h->root.dynamic_ref_after_ir_def = dynamic_ref_after_ir_def;
+             h->root.non_ir_ref_dynamic = non_ir_ref_dynamic;
            }
        }
 
@@ -10472,7 +10472,8 @@ elf_link_input_bfd (struct elf_final_link_info *flinfo, bfd *input_bfd)
                     linker may attach linker created dynamic sections
                     to the plugin bfd.  Symbols defined in linker
                     created sections are not plugin symbols.  */
-                 if (h->root.non_ir_ref
+                 if ((h->root.non_ir_ref
+                      || h->root.non_ir_ref_dynamic)
                      && (h->root.type == bfd_link_hash_defined
                          || h->root.type == bfd_link_hash_defweak)
                      && (h->root.u.def.section->flags
index 2f56b46..1f493a3 100644 (file)
@@ -1735,7 +1735,8 @@ _bfd_generic_link_add_one_symbol (struct bfd_link_info *info,
             otherwise add a warning.  */
          if ((!info->lto_plugin_active
               && (h->u.undef.next != NULL || info->hash->undefs_tail == h))
-             || h->non_ir_ref)
+             || h->non_ir_ref
+             || h->non_ir_ref_dynamic)
            {
              (*info->callbacks->warning) (info, string, h->root.string,
                                           hash_entry_bfd (h), NULL, 0);
index 67bf02f..8425760 100644 (file)
@@ -1,3 +1,8 @@
+2017-05-16  Alan Modra  <amodra@gmail.com>
+
+       * bfdlink.h (struct bfd_link_hash_entry): Update non_ir_ref
+       comment.  Rename dynamic_ref_after_ir_def to non_ir_ref_dynamic.
+
 2017-05-15  Maciej W. Rozycki  <macro@imgtec.com>
            Matthew Fortune  <matthew.fortune@imgtec.com>
 
index cb4bad9..41f5338 100644 (file)
@@ -100,13 +100,13 @@ struct bfd_link_hash_entry
   /* Type of this entry.  */
   ENUM_BITFIELD (bfd_link_hash_type) type : 8;
 
-  /* Symbol is referenced in a normal object file, as distict from a LTO
-     IR object file.  */
+  /* Symbol is referenced in a normal regular object file,
+     as distinct from a LTO IR object file.  */
   unsigned int non_ir_ref : 1;
 
-  /* Symbol is referenced in a dynamic object after it has been defined
-     in an IR object.  */
-  unsigned int dynamic_ref_after_ir_def : 1;
+  /* Symbol is referenced in a normal dynamic object file,
+     as distinct from a LTO IR object file.  */
+  unsigned int non_ir_ref_dynamic : 1;
 
   /* Symbol is a built-in define.  These will be overridden by PROVIDE
      in a linker script.  */
index a8dad5c..9fdd758 100644 (file)
@@ -1,3 +1,9 @@
+2017-05-16  Alan Modra  <amodra@gmail.com>
+
+       * plugin.c (is_visible_from_outside): Use non_ir_ref_dynamic.
+       (plugin_notice): Set non_ir_ref for references from regular
+       objects, non_ir_ref_dynamic for references from dynamic objects.
+
 2017-05-15  Maciej W. Rozycki  <macro@imgtec.com>
 
        * testsuite/ld-mips-elf/mips16e2-pcrel-0.d: New test.
index 164b5db..087cedc 100644 (file)
@@ -629,7 +629,7 @@ is_visible_from_outside (struct ld_plugin_symbol *lsym,
 
   if (bfd_link_relocatable (&link_info))
     return TRUE;
-  if (blhe->dynamic_ref_after_ir_def
+  if (blhe->non_ir_ref_dynamic
       || link_info.export_dynamic
       || bfd_link_dll (&link_info))
     {
@@ -1266,9 +1266,10 @@ plugin_call_cleanup (void)
 /* To determine which symbols should be resolved LDPR_PREVAILING_DEF
    and which LDPR_PREVAILING_DEF_IRONLY, we notice all the symbols as
    the linker adds them to the linker hash table.  Mark those
-   referenced from a non-IR file with non_ir_ref.  We have to
-   notice_all symbols, because we won't necessarily know until later
-   which ones will be contributed by IR files.  */
+   referenced from a non-IR file with non_ir_ref or
+   non_ir_ref_dynamic as appropriate.  We have to notice_all symbols,
+   because we won't necessarily know until later which ones will be
+   contributed by IR files.  */
 static bfd_boolean
 plugin_notice (struct bfd_link_info *info,
               struct bfd_link_hash_entry *h,
@@ -1283,6 +1284,7 @@ plugin_notice (struct bfd_link_info *info,
   if (h != NULL)
     {
       bfd *sym_bfd;
+      bfd_boolean ref = FALSE;
 
       if (h->type == bfd_link_hash_warning)
        h = h->u.i.link;
@@ -1298,13 +1300,17 @@ plugin_notice (struct bfd_link_info *info,
        {
          /* ??? Some of this is questionable.  See comments in
             _bfd_generic_link_add_one_symbol for case IND.  */
-         if (h->type != bfd_link_hash_new)
+         if (h->type != bfd_link_hash_new
+             || inh->type == bfd_link_hash_new)
            {
-             h->non_ir_ref = TRUE;
-             inh->non_ir_ref = TRUE;
+             if ((abfd->flags & DYNAMIC) == 0)
+               inh->non_ir_ref = TRUE;
+             else
+               inh->non_ir_ref_dynamic = TRUE;
            }
-         else if (inh->type == bfd_link_hash_new)
-           inh->non_ir_ref = TRUE;
+
+         if (h->type != bfd_link_hash_new)
+           ref = TRUE;
        }
 
       /* Nothing to do here for warning symbols.  */
@@ -1318,34 +1324,18 @@ plugin_notice (struct bfd_link_info *info,
       /* If this is a ref, set non_ir_ref.  */
       else if (bfd_is_und_section (section))
        {
-          if (h->type == bfd_link_hash_defweak
-              || h->type == bfd_link_hash_defined)
-            {
-              /* Check if the symbol is referenced in a dynamic object
-                 after it has been defined in an IR object.  */
-              if ((abfd->flags & DYNAMIC) != 0
-                  && is_ir_dummy_bfd (h->u.def.section->owner))
-                h->dynamic_ref_after_ir_def = TRUE;
-            }
          /* Replace the undefined dummy bfd with the real one.  */
-          else if ((h->type == bfd_link_hash_undefined
-                    || h->type == bfd_link_hash_undefweak)
-                   && (h->u.undef.abfd == NULL
-                       || (h->u.undef.abfd->flags & BFD_PLUGIN) != 0))
+          if ((h->type == bfd_link_hash_undefined
+               || h->type == bfd_link_hash_undefweak)
+              && (h->u.undef.abfd == NULL
+                  || (h->u.undef.abfd->flags & BFD_PLUGIN) != 0))
             h->u.undef.abfd = abfd;
-         h->non_ir_ref = TRUE;
+         ref = TRUE;
        }
 
       /* Otherwise, it must be a new def.  */
       else
        {
-         /* A common symbol should be merged with other commons or
-            defs with the same name.  In particular, a common ought
-            to be overridden by a def in a -flto object.  In that
-            sense a common is also a ref.  */
-         if (bfd_is_com_section (section))
-           h->non_ir_ref = TRUE;
-
          /* Ensure any symbol defined in an IR dummy BFD takes on a
             new value from a real BFD.  Weak symbols are not normally
             overridden by a new weak definition, and strong symbols
@@ -1360,6 +1350,21 @@ plugin_notice (struct bfd_link_info *info,
              h->type = bfd_link_hash_undefweak;
              h->u.undef.abfd = sym_bfd;
            }
+
+         /* A common symbol should be merged with other commons or
+            defs with the same name.  In particular, a common ought
+            to be overridden by a def in a -flto object.  In that
+            sense a common is also a ref.  */
+         if (bfd_is_com_section (section))
+           ref = TRUE;
+       }
+
+      if (ref)
+       {
+         if ((abfd->flags & DYNAMIC) == 0)
+           h->non_ir_ref = TRUE;
+         else
+           h->non_ir_ref_dynamic = TRUE;
        }
     }