/* Load up and initialise all plugins after argument parsing.  */
int
plugin_load_plugins (void)
{
  struct ld_plugin_tv *my_tv;
  unsigned int max_args = 0;
  plugin_t *curplug = plugins_list;

  /* If there are no plugins, we need do nothing this run.  */
  if (!curplug)
    return 0;

  /* First pass over plugins to find max # args needed so that we
     can size and allocate the tv array.  */
  while (curplug)
    {
      if (curplug->n_args > max_args)
	max_args = curplug->n_args;
      curplug = curplug->next;
    }

  /* Allocate tv array and initialise constant part.  */
  my_tv = xmalloc ((max_args + 1 + tv_header_size) * sizeof *my_tv);
  set_tv_header (my_tv);

  /* Pass over plugins again, activating them.  */
  curplug = plugins_list;
  while (curplug)
    {
      enum ld_plugin_status rv;
      ld_plugin_onload onloadfn = dlsym (curplug->dlhandle, "onload");
      if (!onloadfn)
	onloadfn = dlsym (curplug->dlhandle, "_onload");
      if (!onloadfn)
	return set_plugin_error (curplug->name);
      set_tv_plugin_args (curplug, &my_tv[tv_header_size]);
      called_plugin = curplug;
      rv = (*onloadfn) (my_tv);
      called_plugin = NULL;
      if (rv != LDPS_OK)
	return set_plugin_error (curplug->name);
      curplug = curplug->next;
    }

  /* Since plugin(s) inited ok, assume they're going to want symbol
     resolutions, which needs us to track which symbols are referenced
     by non-IR files using the linker's notice callback.  */
  orig_notice_all = link_info.notice_all;
  orig_callbacks = link_info.callbacks;
  plugin_callbacks = *orig_callbacks;
  plugin_callbacks.notice = &plugin_notice;
  link_info.notice_all = TRUE;
  link_info.callbacks = &plugin_callbacks;

  return 0;
}
Exemple #2
0
/* Accumulate option arguments for last-loaded plugin, or return
   error if none.  */
int
plugin_opt_plugin_arg (const char *arg)
{
    plugin_arg_t *newarg;

    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;

    /* Chain on end to preserve command-line order.  */
    *last_plugin_args_tail_chain_ptr = newarg;
    last_plugin_args_tail_chain_ptr = &newarg->next;
    last_plugin->n_args++;
    return 0;
}
Exemple #3
0
/* Call 'claim file' hook for all plugins.  */
static int
plugin_call_claim_file (const struct ld_plugin_input_file *file, int *claimed)
{
    plugin_t *curplug = plugins_list;
    *claimed = FALSE;
    while (curplug && !*claimed)
    {
        if (curplug->claim_file_handler)
        {
            off_t cur_offset;
            enum ld_plugin_status rv;

            called_plugin = curplug;
            cur_offset = lseek (file->fd, 0, SEEK_CUR);
            rv = (*curplug->claim_file_handler) (file, claimed);
            if (!*claimed)
                lseek (file->fd, cur_offset, SEEK_SET);
            called_plugin = NULL;
            if (rv != LDPS_OK)
                set_plugin_error (curplug->name);
        }
        curplug = curplug->next;
    }
    return plugin_error_p () ? -1 : 0;
}
/* Accumulate option arguments for last-loaded plugin, or return
   error if none.  */
int
plugin_opt_plugin_arg (const char *arg)
{
  plugin_arg_t *newarg;

  if (!last_plugin)
    return set_plugin_error (_("<no plugin>"));

  newarg = xmalloc (sizeof *newarg);
  newarg->arg = arg;
  newarg->next = NULL;

  /* Chain on end to preserve command-line order.  */
  *last_plugin_args_tail_chain_ptr = newarg;
  last_plugin_args_tail_chain_ptr = &newarg->next;
  last_plugin->n_args++;
  return 0;
}
Exemple #5
0
/* Call 'claim file' hook for all plugins.  */
static int
plugin_call_claim_file (const struct ld_plugin_input_file *file, int *claimed)
{
  plugin_t *curplug = plugins_list;
  *claimed = FALSE;
  while (curplug && !*claimed)
    {
      if (curplug->claim_file_handler)
	{
	  enum ld_plugin_status rv;
	  called_plugin = curplug;
	  rv = (*curplug->claim_file_handler) (file, claimed);
	  called_plugin = NULL;
	  if (rv != LDPS_OK)
	    set_plugin_error (curplug->name);
	}
      curplug = curplug->next;
    }
  return plugin_error_p () ? -1 : 0;
}
/* Handle -plugin arg: find and load plugin, or return error.  */
int
plugin_opt_plugin (const char *plugin)
{
  plugin_t *newplug;

  newplug = xmalloc (sizeof *newplug);
  memset (newplug, 0, sizeof *newplug);
  newplug->name = plugin;
  newplug->dlhandle = dlopen (plugin, RTLD_NOW);
  if (!newplug->dlhandle)
    return set_plugin_error (plugin);

  /* Chain on end, so when we run list it is in command-line order.  */
  *plugins_tail_chain_ptr = newplug;
  plugins_tail_chain_ptr = &newplug->next;

  /* Record it as current plugin for receiving args.  */
  last_plugin = newplug;
  last_plugin_args_tail_chain_ptr = &newplug->args;
  return 0;
}
/* Call 'cleanup' hook for all plugins at exit.  */
void
plugin_call_cleanup (void)
{
  plugin_t *curplug = plugins_list;
  while (curplug)
    {
      if (curplug->cleanup_handler && !curplug->cleanup_done)
	{
	  enum ld_plugin_status rv;
	  curplug->cleanup_done = TRUE;
	  called_plugin = curplug;
	  rv = (*curplug->cleanup_handler) ();
	  called_plugin = NULL;
	  if (rv != LDPS_OK)
	    set_plugin_error (curplug->name);
	  dlclose (curplug->dlhandle);
	}
      curplug = curplug->next;
    }
  if (plugin_error_p ())
    info_msg (_("%P: %s: error in plugin cleanup (ignored)\n"),
	      plugin_error_plugin ());
}
/* Call 'all symbols read' hook for all plugins.  */
int
plugin_call_all_symbols_read (void)
{
  plugin_t *curplug = plugins_list;

  /* Disable any further file-claiming.  */
  no_more_claiming = TRUE;

  while (curplug)
    {
      if (curplug->all_symbols_read_handler)
	{
	  enum ld_plugin_status rv;
	  called_plugin = curplug;
	  rv = (*curplug->all_symbols_read_handler) ();
	  called_plugin = NULL;
	  if (rv != LDPS_OK)
	    set_plugin_error (curplug->name);
	}
      curplug = curplug->next;
    }
  return plugin_error_p () ? -1 : 0;
}