When disabling target async, remove all target event sources from the event loop
[deliverable/binutils-gdb.git] / ld / plugin.c
index d880164ded9511d56c038f04f82f54ffbef1ac52..cfbca0b102fa226631d0f166fbb4bef23c806fd3 100644 (file)
@@ -1,5 +1,5 @@
 /* Plugin control for the GNU linker.
-   Copyright 2010, 2011, 2012 Free Software Foundation, Inc.
+   Copyright (C) 2010-2015 Free Software Foundation, Inc.
 
    This file is part of the GNU Binutils.
 
@@ -114,6 +114,7 @@ static const enum ld_plugin_tag tv_header_tags[] =
   LDPT_REGISTER_CLEANUP_HOOK,
   LDPT_ADD_SYMBOLS,
   LDPT_GET_INPUT_FILE,
+  LDPT_GET_VIEW,
   LDPT_RELEASE_INPUT_FILE,
   LDPT_GET_SYMBOLS,
   LDPT_GET_SYMBOLS_V2,
@@ -127,8 +128,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)
 
@@ -217,6 +219,17 @@ plugin_opt_plugin_arg (const char *arg)
   if (!last_plugin)
     return set_plugin_error (_("<no plugin>"));
 
+  /* Ignore -pass-through= from GCC driver.  */
+  if (*arg == '-')
+    {
+      const char *p = arg + 1;
+
+      if (*p == '-')
+       ++p;
+      if (strncmp (p, "pass-through=", 13) == 0)
+       return 0;
+    }
+
   newarg = xmalloc (sizeof *newarg);
   newarg->arg = arg;
   newarg->next = NULL;
@@ -228,8 +241,12 @@ plugin_opt_plugin_arg (const char *arg)
   return 0;
 }
 
-/* Create a dummy BFD.  */
-bfd *
+/* Generate a dummy BFD to represent an IR file, for any callers of
+   plugin_call_claim_file to use as the handle in the ld_plugin_input_file
+   struct that they build to pass in.  The BFD is initially writable, so
+   that symbols can be added to it; it must be made readable after the
+   add_symbols hook has been called so that it can be read when linking.  */
+static bfd *
 plugin_get_ir_dummy_bfd (const char *name, bfd *srctemplate)
 {
   bfd *abfd;
@@ -259,17 +276,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.  */
@@ -429,20 +441,27 @@ add_symbols (void *handle, int nsyms, const struct ld_plugin_symbol *syms)
 /* Get the input file information with an open (possibly re-opened)
    file descriptor.  */
 static enum ld_plugin_status
-get_input_file (const void *handle, struct ld_plugin_input_file *file)
+get_input_file (const void *handle ATTRIBUTE_UNUSED,
+                struct ld_plugin_input_file *file ATTRIBUTE_UNUSED)
+{
+  ASSERT (called_plugin);
+  return LDPS_ERR;
+}
+
+/* Get view of the input file.  */
+static enum ld_plugin_status
+get_view (const void *handle ATTRIBUTE_UNUSED,
+         const void **viewp ATTRIBUTE_UNUSED)
 {
   ASSERT (called_plugin);
-  handle = handle;
-  file = file;
   return LDPS_ERR;
 }
 
 /* Release the input file.  */
 static enum ld_plugin_status
-release_input_file (const void *handle)
+release_input_file (const void *handle ATTRIBUTE_UNUSED)
 {
   ASSERT (called_plugin);
-  handle = handle;
   return LDPS_ERR;
 }
 
@@ -726,6 +745,9 @@ set_tv_header (struct ld_plugin_tv *tv)
        case LDPT_GET_INPUT_FILE:
          TVU(get_input_file) = get_input_file;
          break;
+       case LDPT_GET_VIEW:
+         TVU(get_view) = get_view;
+         break;
        case LDPT_RELEASE_INPUT_FILE:
          TVU(release_input_file) = release_input_file;
          break;
@@ -769,14 +791,6 @@ set_tv_plugin_args (plugin_t *plugin, struct ld_plugin_tv *tv)
   tv->tv_u.tv_val = 0;
 }
 
-/* Return true if any plugins are active this run.  Only valid
-   after options have been processed.  */
-bfd_boolean
-plugin_active_plugins_p (void)
-{
-  return plugins_list != NULL;
-}
-
 /* Load up and initialise all plugins after argument parsing.  */
 void
 plugin_load_plugins (void)
@@ -832,6 +846,7 @@ plugin_load_plugins (void)
   plugin_callbacks = *orig_callbacks;
   plugin_callbacks.notice = &plugin_notice;
   link_info.notice_all = TRUE;
+  link_info.lto_plugin_active = TRUE;
   link_info.callbacks = &plugin_callbacks;
 }
 
@@ -952,16 +967,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))
        ;
@@ -971,16 +991,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.  */
@@ -997,7 +1016,8 @@ plugin_notice (struct bfd_link_info *info,
          /* Replace the undefined dummy bfd with the real one.  */
          if ((h->type == bfd_link_hash_undefined
               || h->type == bfd_link_hash_undefweak)
-             && (h->u.undef.abfd->flags & BFD_PLUGIN) != 0)
+             && (h->u.undef.abfd == NULL
+                 || (h->u.undef.abfd->flags & BFD_PLUGIN) != 0))
            h->u.undef.abfd = abfd;
          h->non_ir_ref = TRUE;
        }
@@ -1020,23 +1040,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 bfd is a dynamic library that should be reloaded.  */
-
-bfd_boolean
-plugin_should_reload (bfd *abfd)
-{
-  return ((abfd->flags & DYNAMIC) != 0
-         && bfd_get_flavour (abfd) == bfd_target_elf_flavour
-         && bfd_get_format (abfd) == bfd_object
-         && (elf_dyn_lib_class (abfd) & DYN_AS_NEEDED) != 0);
-}
This page took 0.028184 seconds and 4 git commands to generate.