/* Support for GCC plugin mechanism.
   Copyright (C) 2009-2024 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"
#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:
      case PLUGIN_ANALYZER_INIT:
        {
          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:
      case PLUGIN_ANALYZER_INIT:
        {
          /* 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;
}
