build as needed
[platform/upstream/binutils.git] / ld / plugin.c
index 8d6ae05..f02a97f 100644 (file)
@@ -127,8 +127,9 @@ static const size_t tv_header_size = ARRAY_SIZE (tv_header_tags);
 
 /* Forward references.  */
 static bfd_boolean plugin_notice (struct bfd_link_info *,
-                                 struct bfd_link_hash_entry *, bfd *,
-                                 asection *, bfd_vma, flagword, const char *);
+                                 struct bfd_link_hash_entry *,
+                                 struct bfd_link_hash_entry *,
+                                 bfd *, asection *, bfd_vma, flagword);
 
 #if !defined (HAVE_DLFCN_H) && defined (HAVE_WINDOWS_H)
 
@@ -270,17 +271,12 @@ plugin_get_ir_dummy_bfd (const char *name, bfd *srctemplate)
 }
 
 /* Check if the BFD passed in is an IR dummy object file.  */
-static bfd_boolean
+static inline bfd_boolean
 is_ir_dummy_bfd (const bfd *abfd)
 {
   /* ABFD can sometimes legitimately be NULL, e.g. when called from one
-     of the linker callbacks for a symbol in the *ABS* or *UND* sections.
-     Likewise, the usrdata field may be NULL if ABFD was added by the
-     backend without a corresponding input statement, as happens e.g.
-     when processing DT_NEEDED dependencies.  */
-  return (abfd
-         && abfd->usrdata
-         && ((lang_input_statement_type *)(abfd->usrdata))->flags.claimed);
+     of the linker callbacks for a symbol in the *ABS* or *UND* sections.  */
+  return abfd != NULL && (abfd->flags & BFD_PLUGIN) != 0;
 }
 
 /* Helpers to convert between BFD and GOLD symbol formats.  */
@@ -962,16 +958,21 @@ plugin_call_cleanup (void)
 static bfd_boolean
 plugin_notice (struct bfd_link_info *info,
               struct bfd_link_hash_entry *h,
+              struct bfd_link_hash_entry *inh,
               bfd *abfd,
               asection *section,
               bfd_vma value,
-              flagword flags,
-              const char *string)
+              flagword flags)
 {
+  struct bfd_link_hash_entry *orig_h = h;
+
   if (h != NULL)
     {
       bfd *sym_bfd;
 
+      if (h->type == bfd_link_hash_warning)
+       h = h->u.i.link;
+
       /* Nothing to do here if this def/ref is from an IR dummy BFD.  */
       if (is_ir_dummy_bfd (abfd))
        ;
@@ -981,16 +982,15 @@ plugin_notice (struct bfd_link_info *info,
       else if (bfd_is_ind_section (section)
               || (flags & BSF_INDIRECT) != 0)
        {
+         /* ??? Some of this is questionable.  See comments in
+            _bfd_generic_link_add_one_symbol for case IND.  */
          if (h->type != bfd_link_hash_new)
            {
-             struct bfd_link_hash_entry *inh;
-
              h->non_ir_ref = TRUE;
-             inh = bfd_wrapped_link_hash_lookup (abfd, info, string, FALSE,
-                                                 FALSE, FALSE);
-             if (inh != NULL)
-               inh->non_ir_ref = TRUE;
+             inh->non_ir_ref = TRUE;
            }
+         else if (inh->type == bfd_link_hash_new)
+           inh->non_ir_ref = TRUE;
        }
 
       /* Nothing to do here for warning symbols.  */
@@ -1031,21 +1031,12 @@ plugin_notice (struct bfd_link_info *info,
     }
 
   /* Continue with cref/nocrossref/trace-sym processing.  */
-  if (h == NULL
+  if (orig_h == NULL
       || orig_notice_all
       || (info->notice_hash != NULL
-         && bfd_hash_lookup (info->notice_hash, h->root.string,
+         && bfd_hash_lookup (info->notice_hash, orig_h->root.string,
                              FALSE, FALSE) != NULL))
-    return (*orig_callbacks->notice) (info, h,
-                                     abfd, section, value, flags, string);
+    return (*orig_callbacks->notice) (info, orig_h, inh,
+                                     abfd, section, value, flags);
   return TRUE;
 }
-
-/* Return true if ABFD, a dynamic library, should be reloaded.  */
-
-bfd_boolean
-plugin_should_reload (bfd *abfd)
-{
-  return (bfd_get_flavour (abfd) == bfd_target_elf_flavour
-         && (elf_dyn_lib_class (abfd) & DYN_AS_NEEDED) != 0);
-}