/* Support for GCC plugin mechanism.
   Copyright (C) 2009-2026 Free Software Foundation, Inc.

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.

GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

/* This file contains the support for GCC plugin mechanism based on the
   APIs described in doc/plugin.texi.  */

#include "config.h"
#define INCLUDE_DLFCN_H
#include "system.h"
#include "coretypes.h"
#include "options.h"
#include "tree-pass.h"
#include "diagnostic-core.h"
#include "flags.h"
#include "intl.h"
#include "plugin.h"

#ifdef ENABLE_PLUGIN
#include "plugin-version.h"
#endif

#ifdef __MINGW32__
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#ifndef NOMINMAX
#define NOMINMAX
#endif
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#endif

#define GCC_PLUGIN_STRINGIFY0(X) #X
#define GCC_PLUGIN_STRINGIFY1(X) GCC_PLUGIN_STRINGIFY0 (X)

/* Event names as strings.  Keep in sync with enum plugin_event.  */
static const char *plugin_event_name_init[] =
{
# define DEFEVENT(NAME) GCC_PLUGIN_STRINGIFY1 (NAME),
# include "plugin.def"
# undef DEFEVENT
};

/* A printf format large enough for the largest event above.  */
#define FMT_FOR_PLUGIN_EVENT "%-32s"

const char **plugin_event_name = plugin_event_name_init;

/* Event hashtable helpers.  */

struct event_hasher : nofree_ptr_hash <const char *>
{
  static inline hashval_t hash (const char **);
  static inline bool equal (const char **, const char **);
};

/* Helper function for the event hash table that hashes the entry V.  */

inline hashval_t
event_hasher::hash (const char **v)
{
  return htab_hash_string (*v);
}

/* Helper function for the event hash table that compares the name of an
   existing entry (S1) with the given string (S2).  */

inline bool
event_hasher::equal (const char **s1, const char **s2)
{
  return !strcmp (*s1, *s2);
}

/* A hash table to map event names to the position of the names in the
   plugin_event_name table.  */
static hash_table<event_hasher> *event_tab;

/* Keep track of the limit of allocated events and space ready for
   allocating events.  */
static int event_last = PLUGIN_EVENT_FIRST_DYNAMIC;
static int event_horizon = PLUGIN_EVENT_FIRST_DYNAMIC;

/* Hash table for the plugin_name_args objects created during command-line
   parsing.  */
static htab_t plugin_name_args_tab = NULL;

/* List node for keeping track of plugin-registered callback.  */
struct callback_info
{
  const char *plugin_name;   /* Name of plugin that registers the callback.  */
  plugin_callback_func func; /* Callback to be called.  */
  void *user_data;           /* plugin-specified data.  */
  struct callback_info *next;
};

/* An array of lists of 'callback_info' objects indexed by the event id.  */
static struct callback_info *plugin_callbacks_init[PLUGIN_EVENT_FIRST_DYNAMIC];
static struct callback_info **plugin_callbacks = plugin_callbacks_init;

/* For invoke_plugin_callbacks(), see plugin.h.  */
bool flag_plugin_added = false;

#ifdef ENABLE_PLUGIN
/* Each plugin should define an initialization function with exactly
   this name.  */
static const char *str_plugin_init_func_name = "plugin_init";

/* Each plugin should define this symbol to assert that it is
   distributed under a GPL-compatible license.  */
static const char *str_license = "plugin_is_GPL_compatible";
#endif

/* Helper function for hashing the base_name of the plugin_name_args
   structure to be inserted into the hash table.  */

static hashval_t
htab_hash_plugin (const void *p)
{
  const struct plugin_name_args *plugin = (const struct plugin_name_args *) p;
  return htab_hash_string (plugin->base_name);
 }

/* Helper function for the hash table that compares the base_name of the
   existing entry (S1) with the given string (S2).  */

static int
htab_str_eq (const void *s1, const void *s2)
{
  const struct plugin_name_args *plugin = (const struct plugin_name_args *) s1;
  return !strcmp (plugin->base_name, (const char *) s2);
}


/* Given a plugin's full-path name FULL_NAME, e.g. /pass/to/NAME.so,
   return NAME.  */

static char *
get_plugin_base_name (const char *full_name)
{
  /* First get the base name part of the full-path name, i.e. NAME.so.  */
  char *base_name = xstrdup (lbasename (full_name));

  /* Then get rid of the extension in the name, e.g., .so.  */
  strip_off_ending (base_name, strlen (base_name));

  return base_name;
}


/* Create a plugin_name_args object for the given plugin and insert it
   to the hash table. This function is called when
   -fplugin=/path/to/NAME.so or -fplugin=NAME option is processed.  */

void
add_new_plugin (const char* plugin_name)
{
  struct plugin_name_args *plugin;
  void **slot;
  char *base_name;
  bool name_is_short;
  const char *pc;

  flag_plugin_added = true;

  /* Replace short names by their full path when relevant.  */
  name_is_short  = !IS_ABSOLUTE_PATH (plugin_name);
  for (pc = plugin_name; name_is_short && *pc; pc++)
    if (*pc == '.' || IS_DIR_SEPARATOR (*pc))
      name_is_short = false;

  if (name_is_short)
    {
      base_name = CONST_CAST (char*, plugin_name);

#if defined(__MINGW32__)
      static const char plugin_ext[] = ".dll";
#elif defined(__APPLE__)
      /* macOS has two types of libraries: dynamic libraries (.dylib) and
         plugins (.bundle). Both can be used with dlopen()/dlsym() but the
         former cannot be linked at build time (i.e., with the -lfoo linker
         option). A GCC plugin is therefore probably a macOS plugin but their
         use seems to be quite rare and the .bundle extension is more of a
         recommendation rather than the rule. This raises the questions of how
         well they are supported by tools (e.g., libtool). So to avoid
         complications let's use the .dylib extension for now. In the future,
         if this proves to be an issue, we can always check for both
         extensions.  */
      static const char plugin_ext[] = ".dylib";
#else
      static const char plugin_ext[] = ".so";
#endif

      plugin_name = concat (default_plugin_dir_name (), "/",
			    plugin_name, plugin_ext, NULL);
      if (access (plugin_name, R_OK))
	fatal_error
	  (input_location,
	   "inaccessible plugin file %s expanded from short plugin name %s: %m",
	   plugin_name, base_name);
    }
  else
    base_name = get_plugin_base_name (plugin_name);

  /* If this is the first -fplugin= option we encounter, create
     'plugin_name_args_tab' hash table.  */
  if (!plugin_name_args_tab)
    plugin_name_args_tab = htab_create (10, htab_hash_plugin, htab_str_eq,
                                        NULL);

  slot = htab_find_slot_with_hash (plugin_name_args_tab, base_name,
				   htab_hash_string (base_name), INSERT);

  /* If the same plugin (name) has been specified earlier, either emit an
     error or a warning message depending on if they have identical full
     (path) names.  */
  if (*slot)
    {
      plugin = (struct plugin_name_args *) *slot;
      if (strcmp (plugin->full_name, plugin_name))
	error ("plugin %qs was specified with different paths: %qs and %qs",
               plugin->base_name, plugin->full_name, plugin_name);
      return;
    }

  plugin = XCNEW (struct plugin_name_args);
  plugin->base_name = base_name;
  plugin->full_name = plugin_name;

  *slot = plugin;
}


/* Parse the -fplugin-arg-<name>-<key>[=<value>] option and create a
   'plugin_argument' object for the parsed key-value pair. ARG is
   the <name>-<key>[=<value>] part of the option.  */

void
parse_plugin_arg_opt (const char *arg)
{
  size_t len = 0, name_len = 0, key_len = 0, value_len = 0;
  const char *ptr, *name_start = arg, *key_start = NULL, *value_start = NULL;
  char *name, *key, *value;
  void **slot;
  bool name_parsed = false, key_parsed = false;

  /* Iterate over the ARG string and identify the starting character position
     of 'name', 'key', and 'value' and their lengths.  */
  for (ptr = arg; *ptr; ++ptr)
    {
      /* Only the first '-' encountered is considered a separator between
         'name' and 'key'. All the subsequent '-'s are considered part of
         'key'. For example, given -fplugin-arg-foo-bar-primary-key=value,
         the plugin name is 'foo' and the key is 'bar-primary-key'.  */
      if (*ptr == '-' && !name_parsed)
        {
          name_len = len;
          len = 0;
          key_start = ptr + 1;
          name_parsed = true;
          continue;
        }
      else if (*ptr == '=')
        {
	  if (!key_parsed)
	    {
	      key_len = len;
	      len = 0;
	      value_start = ptr + 1;
	      key_parsed = true;
	    }
          continue;
        }
      else
        ++len;
    }

  if (!key_start)
    {
      error ("malformed option %<-fplugin-arg-%s%>: "
	     "missing %<-<key>[=<value>]%>",
             arg);
      return;
    }

  /* If the option doesn't contain the 'value' part, LEN is the KEY_LEN.
     Otherwise, it is the VALUE_LEN.  */
  if (!value_start)
    key_len = len;
  else
    value_len = len;

  name = XNEWVEC (char, name_len + 1);
  strncpy (name, name_start, name_len);
  name[name_len] = '\0';

  /* Check if the named plugin has already been specified earlier in the
     command-line.  */
  if (plugin_name_args_tab
      && ((slot = htab_find_slot_with_hash (plugin_name_args_tab, name,
					    htab_hash_string (name), NO_INSERT))
          != NULL))
    {
      struct plugin_name_args *plugin = (struct plugin_name_args *) *slot;

      key = XNEWVEC (char, key_len + 1);
      strncpy (key, key_start, key_len);
      key[key_len] = '\0';
      if (value_start)
        {
          value = XNEWVEC (char, value_len + 1);
          strncpy (value, value_start, value_len);
          value[value_len] = '\0';
        }
      else
        value = NULL;

      /* Create a plugin_argument object for the parsed key-value pair.
         If there are already arguments for this plugin, we will need to
         adjust the argument array size by creating a new array and deleting
         the old one. If the performance ever becomes an issue, we can
         change the code by pre-allocating a larger array first.  */
      if (plugin->argc > 0)
        {
          struct plugin_argument *args = XNEWVEC (struct plugin_argument,
                                                  plugin->argc + 1);
          memcpy (args, plugin->argv,
                  sizeof (struct plugin_argument) * plugin->argc);
          XDELETEVEC (plugin->argv);
          plugin->argv = args;
          ++plugin->argc;
        }
      else
        {
          gcc_assert (plugin->argv == NULL);
          plugin->argv = XNEWVEC (struct plugin_argument, 1);
          plugin->argc = 1;
        }

      plugin->argv[plugin->argc - 1].key = key;
      plugin->argv[plugin->argc - 1].value = value;
    }
  else
    error ("plugin %s should be specified before %<-fplugin-arg-%s%> "
           "in the command line", name, arg);

  /* We don't need the plugin's name anymore. Just release it.  */
  XDELETEVEC (name);
}

/* Register additional plugin information. NAME is the name passed to
   plugin_init. INFO is the information that should be registered. */

static void
register_plugin_info (const char* name, struct plugin_info *info)
{
  void **slot = htab_find_slot_with_hash (plugin_name_args_tab, name,
					  htab_hash_string (name), NO_INSERT);
  struct plugin_name_args *plugin;

  if (slot == NULL)
    {
      error ("unable to register info for plugin %qs - plugin name not found",
	     name);
      return;
    }
  plugin = (struct plugin_name_args *) *slot;
  plugin->version = info->version;
  plugin->help = info->help;
}

/* Look up the event id for NAME.  If the name is not found, return -1
   if INSERT is NO_INSERT.  */

int
get_named_event_id (const char *name, enum insert_option insert)
{
  const char ***slot;

  if (!event_tab)
    {
      int i;

      event_tab = new hash_table<event_hasher> (150);
      for (i = 0; i < event_last; i++)
	{
	  slot = event_tab->find_slot (&plugin_event_name[i], INSERT);
	  gcc_assert (*slot == HTAB_EMPTY_ENTRY);
	  *slot = &plugin_event_name[i];
	}
    }
  slot = event_tab->find_slot (&name, insert);
  if (slot == NULL)
    return -1;
  if (*slot != HTAB_EMPTY_ENTRY)
    return *slot - &plugin_event_name[0];

  if (event_last >= event_horizon)
    {
      event_horizon = event_last * 2;
      if (plugin_event_name == plugin_event_name_init)
	{
	  plugin_event_name = XNEWVEC (const char *, event_horizon);
	  memcpy (plugin_event_name, plugin_event_name_init,
		  sizeof plugin_event_name_init);
	  plugin_callbacks = XNEWVEC (struct callback_info *, event_horizon);
	  memcpy (plugin_callbacks, plugin_callbacks_init,
		  sizeof plugin_callbacks_init);
	}
      else
	{
	  plugin_event_name
	    = XRESIZEVEC (const char *, plugin_event_name, event_horizon);
	  plugin_callbacks = XRESIZEVEC (struct callback_info *,
					 plugin_callbacks, event_horizon);
	}
      /* All the pointers in the hash table will need to be updated.  */
      delete event_tab;
      event_tab = NULL;
    }
  else
    *slot = &plugin_event_name[event_last];
  plugin_event_name[event_last] = name;
  return event_last++;
}

/* Called from the plugin's initialization code. Register a single callback.
   This function can be called multiple times.

   PLUGIN_NAME - display name for this plugin
   EVENT       - which event the callback is for
   CALLBACK    - the callback to be called at the event
   USER_DATA   - plugin-provided data   */

void
register_callback (const char *plugin_name,
		   int event,
                   plugin_callback_func callback,
                   void *user_data)
{
  switch (event)
    {
      case PLUGIN_PASS_MANAGER_SETUP:
	gcc_assert (!callback);
        register_pass ((struct register_pass_info *) user_data);
        break;
      case PLUGIN_INFO:
	gcc_assert (!callback);
	register_plugin_info (plugin_name, (struct plugin_info *) user_data);
	break;
      case PLUGIN_REGISTER_GGC_ROOTS:
	gcc_assert (!callback);
        ggc_register_root_tab ((const struct ggc_root_tab*) user_data);
	break;
      case PLUGIN_EVENT_FIRST_DYNAMIC:
      default:
	if (event < PLUGIN_EVENT_FIRST_DYNAMIC || event >= event_last)
	  {
	    error ("unknown callback event registered by plugin %s",
		   plugin_name);
	    return;
	  }
      /* Fall through.  */
      case PLUGIN_START_PARSE_FUNCTION:
      case PLUGIN_FINISH_PARSE_FUNCTION:
      case PLUGIN_FINISH_TYPE:
      case PLUGIN_FINISH_DECL:
      case PLUGIN_START_UNIT:
      case PLUGIN_FINISH_UNIT:
      case PLUGIN_PRE_GENERICIZE:
      case PLUGIN_GGC_START:
      case PLUGIN_GGC_MARKING:
      case PLUGIN_GGC_END:
      case PLUGIN_ATTRIBUTES:
      case PLUGIN_PRAGMAS:
      case PLUGIN_FINISH:
      case PLUGIN_ALL_PASSES_START:
      case PLUGIN_ALL_PASSES_END:
      case PLUGIN_ALL_IPA_PASSES_START:
      case PLUGIN_ALL_IPA_PASSES_END:
      case PLUGIN_OVERRIDE_GATE:
      case PLUGIN_PASS_EXECUTION:
      case PLUGIN_EARLY_GIMPLE_PASSES_START:
      case PLUGIN_EARLY_GIMPLE_PASSES_END:
      case PLUGIN_NEW_PASS:
      case PLUGIN_INCLUDE_FILE:
        {
          struct callback_info *new_callback;
          if (!callback)
            {
              error ("plugin %s registered a null callback function "
		     "for event %s", plugin_name, plugin_event_name[event]);
              return;
            }
          new_callback = XNEW (struct callback_info);
          new_callback->plugin_name = plugin_name;
          new_callback->func = callback;
          new_callback->user_data = user_data;
          new_callback->next = plugin_callbacks[event];
          plugin_callbacks[event] = new_callback;
        }
        break;
    }
}

/* Remove a callback for EVENT which has been registered with for a plugin
   PLUGIN_NAME.  Return PLUGEVT_SUCCESS if a matching callback was
   found & removed, PLUGEVT_NO_CALLBACK if the event does not have a matching
   callback, and PLUGEVT_NO_SUCH_EVENT if EVENT is invalid.  */
int
unregister_callback (const char *plugin_name, int event)
{
  struct callback_info *callback, **cbp;

  if (event >= event_last)
    return PLUGEVT_NO_SUCH_EVENT;

  for (cbp = &plugin_callbacks[event]; (callback = *cbp); cbp = &callback->next)
    if (strcmp (callback->plugin_name, plugin_name) == 0)
      {
	*cbp = callback->next;
	return PLUGEVT_SUCCESS;
      }
  return PLUGEVT_NO_CALLBACK;
}

/* Invoke all plugin callbacks registered with the specified event,
   called from invoke_plugin_callbacks().  */

int
invoke_plugin_callbacks_full (int event, void *gcc_data)
{
  int retval = PLUGEVT_SUCCESS;

  timevar_push (TV_PLUGIN_RUN);

  switch (event)
    {
      case PLUGIN_EVENT_FIRST_DYNAMIC:
      default:
	gcc_assert (event >= PLUGIN_EVENT_FIRST_DYNAMIC);
	gcc_assert (event < event_last);
      /* Fall through.  */
      case PLUGIN_START_PARSE_FUNCTION:
      case PLUGIN_FINISH_PARSE_FUNCTION:
      case PLUGIN_FINISH_TYPE:
      case PLUGIN_FINISH_DECL:
      case PLUGIN_START_UNIT:
      case PLUGIN_FINISH_UNIT:
      case PLUGIN_PRE_GENERICIZE:
      case PLUGIN_ATTRIBUTES:
      case PLUGIN_PRAGMAS:
      case PLUGIN_FINISH:
      case PLUGIN_GGC_START:
      case PLUGIN_GGC_MARKING:
      case PLUGIN_GGC_END:
      case PLUGIN_ALL_PASSES_START:
      case PLUGIN_ALL_PASSES_END:
      case PLUGIN_ALL_IPA_PASSES_START:
      case PLUGIN_ALL_IPA_PASSES_END:
      case PLUGIN_OVERRIDE_GATE:
      case PLUGIN_PASS_EXECUTION:
      case PLUGIN_EARLY_GIMPLE_PASSES_START:
      case PLUGIN_EARLY_GIMPLE_PASSES_END:
      case PLUGIN_NEW_PASS:
      case PLUGIN_INCLUDE_FILE:
        {
          /* Iterate over every callback registered with this event and
             call it.  */
          struct callback_info *callback = plugin_callbacks[event];

	  if (!callback)
	    retval = PLUGEVT_NO_CALLBACK;
          for ( ; callback; callback = callback->next)
            (*callback->func) (gcc_data, callback->user_data);
        }
        break;

      case PLUGIN_PASS_MANAGER_SETUP:
      case PLUGIN_REGISTER_GGC_ROOTS:
        gcc_assert (false);
    }

  timevar_pop (TV_PLUGIN_RUN);
  return retval;
}

#ifdef ENABLE_PLUGIN

/* Try to initialize PLUGIN. Return true if successful. */

#ifdef __MINGW32__

// Return a message string for last error or NULL if unknown. Must be freed
// with LocalFree().
static inline char *
win32_error_msg ()
{
  char *msg;
  return FormatMessageA (FORMAT_MESSAGE_ALLOCATE_BUFFER |
			 FORMAT_MESSAGE_FROM_SYSTEM |
			 FORMAT_MESSAGE_IGNORE_INSERTS |
			 FORMAT_MESSAGE_MAX_WIDTH_MASK,
			 0,
			 GetLastError (),
			 MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
			 (char*)&msg,
			 0,
			 0)
    ? msg
    : NULL;
}

static bool
try_init_one_plugin (struct plugin_name_args *plugin)
{
  HMODULE dl_handle;
  plugin_init_func plugin_init;

  dl_handle = LoadLibrary (plugin->full_name);
  if (!dl_handle)
    {
      char *err = win32_error_msg ();
      error ("cannot load plugin %s\n%s", plugin->full_name, err);
      LocalFree (err);
      return false;
    }

  /* Check the plugin license. Unlike the name suggests, GetProcAddress()
     can be used for both functions and variables.  */
  if (GetProcAddress (dl_handle, str_license) == NULL)
    {
      char *err = win32_error_msg ();
      fatal_error (input_location,
		   "plugin %s is not licensed under a GPL-compatible license\n"
		   "%s", plugin->full_name, err);
    }

  /* Unlike dlsym(), GetProcAddress() returns a pointer to a function so we
     can cast directly without union tricks.  */
  plugin_init = (plugin_init_func)
    GetProcAddress (dl_handle, str_plugin_init_func_name);

  if (plugin_init == NULL)
    {
      char *err = win32_error_msg ();
      FreeLibrary (dl_handle);
      error ("cannot find %s in plugin %s\n%s", str_plugin_init_func_name,
             plugin->full_name, err);
      LocalFree (err);
      return false;
    }

  /* Call the plugin-provided initialization routine with the arguments.  */
  if ((*plugin_init) (plugin, &gcc_version))
    {
      FreeLibrary (dl_handle);
      error ("fail to initialize plugin %s", plugin->full_name);
      return false;
    }
  /* Leak dl_handle on purpose to ensure the plugin is loaded for the
     entire run of the compiler. */
  return true;
}

#else // POSIX-like with dlopen()/dlsym().

/* We need a union to cast dlsym return value to a function pointer
   as ISO C forbids assignment between function pointer and 'void *'.
   Use explicit union instead of __extension__(<union_cast>) for
   portability.  */
#define PTR_UNION_TYPE(TOTYPE) union { void *_q; TOTYPE _nq; }
#define PTR_UNION_AS_VOID_PTR(NAME) (NAME._q)
#define PTR_UNION_AS_CAST_PTR(NAME) (NAME._nq)

static bool
try_init_one_plugin (struct plugin_name_args *plugin)
{
  void *dl_handle;
  plugin_init_func plugin_init;
  const char *err;
  PTR_UNION_TYPE (plugin_init_func) plugin_init_union;

  /* We use RTLD_NOW to accelerate binding and detect any mismatch
     between the API expected by the plugin and the GCC API; we use
     RTLD_GLOBAL which is useful to plugins which themselves call
     dlopen.  */
  dl_handle = dlopen (plugin->full_name, RTLD_NOW | RTLD_GLOBAL);
  if (!dl_handle)
    {
      error ("cannot load plugin %s: %s", plugin->full_name, dlerror ());
      return false;
    }

  /* Clear any existing error.  */
  dlerror ();

  /* Check the plugin license.  */
  if (dlsym (dl_handle, str_license) == NULL)
    fatal_error (input_location,
		 "plugin %s is not licensed under a GPL-compatible license:"
		 " %s", plugin->full_name, dlerror ());

  PTR_UNION_AS_VOID_PTR (plugin_init_union)
    = dlsym (dl_handle, str_plugin_init_func_name);
  plugin_init = PTR_UNION_AS_CAST_PTR (plugin_init_union);

  if ((err = dlerror ()) != NULL)
    {
      dlclose(dl_handle);
      error ("cannot find %s in plugin %s: %s", str_plugin_init_func_name,
             plugin->full_name, err);
      return false;
    }

  /* Call the plugin-provided initialization routine with the arguments.  */
  if ((*plugin_init) (plugin, &gcc_version))
    {
      dlclose(dl_handle);
      error ("failed to initialize plugin %s", plugin->full_name);
      return false;
    }
  /* leak dl_handle on purpose to ensure the plugin is loaded for the
     entire run of the compiler. */
  return true;
}
#endif

/* Routine to dlopen and initialize one plugin. This function is passed to
   (and called by) the hash table traverse routine. Return 1 for the
   htab_traverse to continue scan, 0 to stop.

   SLOT - slot of the hash table element
   INFO - auxiliary pointer handed to hash table traverse routine
          (unused in this function)  */

static int
init_one_plugin (void **slot, void * ARG_UNUSED (info))
{
  struct plugin_name_args *plugin = (struct plugin_name_args *) *slot;
  bool ok = try_init_one_plugin (plugin);
  if (!ok)
    {
      htab_remove_elt_with_hash (plugin_name_args_tab, plugin->base_name,
				 htab_hash_string (plugin->base_name));
      XDELETE (plugin);
    }
  return 1;
}

#endif	/* ENABLE_PLUGIN  */

/* Main plugin initialization function.  Called from compile_file() in
   toplev.cc.  */

void
initialize_plugins (void)
{
  /* If no plugin was specified in the command-line, simply return.  */
  if (!plugin_name_args_tab)
    return;

  timevar_push (TV_PLUGIN_INIT);

#ifdef ENABLE_PLUGIN
  /* Traverse and initialize each plugin specified in the command-line.  */
  htab_traverse_noresize (plugin_name_args_tab, init_one_plugin, NULL);
#endif

  timevar_pop (TV_PLUGIN_INIT);
}

/* Release memory used by one plugin. */

static int
finalize_one_plugin (void **slot, void * ARG_UNUSED (info))
{
  struct plugin_name_args *plugin = (struct plugin_name_args *) *slot;
  XDELETE (plugin);
  return 1;
}

/* Free memory allocated by the plugin system. */

void
finalize_plugins (void)
{
  if (!plugin_name_args_tab)
    return;

  /* We can now delete the plugin_name_args object as it will no longer
     be used. Note that base_name and argv fields (both of which were also
     dynamically allocated) are not freed as they could still be used by
     the plugin code.  */

  htab_traverse_noresize (plugin_name_args_tab, finalize_one_plugin, NULL);

  /* PLUGIN_NAME_ARGS_TAB is no longer needed, just delete it.  */
  htab_delete (plugin_name_args_tab);
  plugin_name_args_tab = NULL;
}

/* Implementation detail of for_each_plugin.  */

struct for_each_plugin_closure
{
  void (*cb) (const plugin_name_args *,
	      void *user_data);
  void *user_data;
};

/* Implementation detail of for_each_plugin: callback for htab_traverse_noresize
   that calls the user-provided callback.  */

static int
for_each_plugin_cb (void **slot, void *info)
{
  struct plugin_name_args *plugin = (struct plugin_name_args *) *slot;
  for_each_plugin_closure *c = (for_each_plugin_closure *)info;
  c->cb (plugin, c->user_data);
  return 1;
}

/* Call CB with USER_DATA on each plugin.  */

void
for_each_plugin (void (*cb) (const plugin_name_args *,
			     void *user_data),
		 void *user_data)
{
  if (!plugin_name_args_tab)
    return;

  for_each_plugin_closure c;
  c.cb = cb;
  c.user_data = user_data;

  htab_traverse_noresize (plugin_name_args_tab, for_each_plugin_cb, &c);
}

/* Used to pass options to htab_traverse callbacks. */

struct print_options
{
  FILE *file;
  const char *indent;
};

/* Print the version of one plugin. */

static int
print_version_one_plugin (void **slot, void *data)
{
  struct print_options *opt = (struct print_options *) data;
  struct plugin_name_args *plugin = (struct plugin_name_args *) *slot;
  const char *version = plugin->version ? plugin->version : "Unknown version.";

  fprintf (opt->file, " %s%s: %s\n", opt->indent, plugin->base_name, version);
  return 1;
}

/* Print the version of each plugin. */

void
print_plugins_versions (FILE *file, const char *indent)
{
  struct print_options opt;
  opt.file = file;
  opt.indent = indent;
  if (!plugin_name_args_tab || htab_elements (plugin_name_args_tab) == 0)
    return;

  fprintf (file, "%sVersions of loaded plugins:\n", indent);
  htab_traverse_noresize (plugin_name_args_tab, print_version_one_plugin, &opt);
}

/* Print help for one plugin. SLOT is the hash table slot. DATA is the
   argument to htab_traverse_noresize. */

static int
print_help_one_plugin (void **slot, void *data)
{
  struct print_options *opt = (struct print_options *) data;
  struct plugin_name_args *plugin = (struct plugin_name_args *) *slot;
  const char *help = plugin->help ? plugin->help : "No help available .";

  char *dup = xstrdup (help);
  char *p, *nl;
  fprintf (opt->file, " %s%s:\n", opt->indent, plugin->base_name);

  for (p = nl = dup; nl; p = nl)
    {
      nl = strchr (nl, '\n');
      if (nl)
	{
	  *nl = '\0';
	  nl++;
	}
      fprintf (opt->file, "   %s %s\n", opt->indent, p);
    }

  free (dup);
  return 1;
}

/* Print help for each plugin. The output goes to FILE and every line starts
   with INDENT. */

void
print_plugins_help (FILE *file, const char *indent)
{
  struct print_options opt;
  opt.file = file;
  opt.indent = indent;
  if (!plugin_name_args_tab || htab_elements (plugin_name_args_tab) == 0)
    return;

  fprintf (file, "%sHelp for the loaded plugins:\n", indent);
  htab_traverse_noresize (plugin_name_args_tab, print_help_one_plugin, &opt);
}


/* Return true if plugins have been loaded.  */

bool
plugins_active_p (void)
{
  int event;

  for (event = PLUGIN_PASS_MANAGER_SETUP; event < event_last; event++)
    if (plugin_callbacks[event])
      return true;

  return false;
}


/* Dump to FILE the names and associated events for all the active
   plugins.  */

DEBUG_FUNCTION void
dump_active_plugins (FILE *file)
{
  int event;

  if (!plugins_active_p ())
    return;

  fprintf (file, FMT_FOR_PLUGIN_EVENT " | %s\n", _("Event"), _("Plugins"));
  for (event = PLUGIN_PASS_MANAGER_SETUP; event < event_last; event++)
    if (plugin_callbacks[event])
      {
	struct callback_info *ci;

	fprintf (file, FMT_FOR_PLUGIN_EVENT " |", plugin_event_name[event]);

	for (ci = plugin_callbacks[event]; ci; ci = ci->next)
	  fprintf (file, " %s", ci->plugin_name);

	putc ('\n', file);
      }
}


/* Dump active plugins to stderr.  */

DEBUG_FUNCTION void
debug_active_plugins (void)
{
  dump_active_plugins (stderr);
}

/* Give a warning if plugins are present, before an ICE message asking
   to submit a bug report.  */

void
warn_if_plugins (void)
{
  if (plugins_active_p ())
    {
      fnotice (stderr, "*** WARNING *** there are active plugins, do not report"
	       " this as a bug unless you can reproduce it without enabling"
	       " any plugins.\n");
      dump_active_plugins (stderr);
    }

}

/* The default version check. Compares every field in VERSION. */

bool
plugin_default_version_check (struct plugin_gcc_version *gcc_version,
			      struct plugin_gcc_version *plugin_version)
{
  if (!gcc_version || !plugin_version)
    return false;

  if (strcmp (gcc_version->basever, plugin_version->basever))
    return false;
  if (strcmp (gcc_version->datestamp, plugin_version->datestamp))
    return false;
  if (strcmp (gcc_version->devphase, plugin_version->devphase))
    return false;
  if (strcmp (gcc_version->revision, plugin_version->revision))
    return false;
  if (strcmp (gcc_version->configuration_arguments,
	      plugin_version->configuration_arguments))
    return false;
  return true;
}


/* Return the current value of event_last, so that plugins which provide
   additional functionality for events for the benefit of high-level plugins
   know how many valid entries plugin_event_name holds.  */

int
get_event_last (void)
{
  return event_last;
}


/* Retrieve the default plugin directory.  The gcc driver should have passed
   it as -iplugindir <dir> to the cc1 program, and it is queriable through the
   -print-file-name=plugin option to gcc.  */
const char*
default_plugin_dir_name (void)
{
  if (!plugindir_string)
    fatal_error (input_location,
		 "%<-iplugindir%> option not passed from the gcc driver");
  return plugindir_string;
}
