GCC Middle and Back End API Reference
plugin.c File Reference

Data Structures

struct  event_hasher
struct  callback_info
struct  print_options

Functions

static int htab_str_eq ()
static char * get_plugin_base_name ()
void add_new_plugin ()
void parse_plugin_arg_opt ()
static void register_plugin_info ()
int get_named_event_id ()
void register_callback (const char *plugin_name, int event, plugin_callback_func callback, void *user_data)
int unregister_callback ()
int invoke_plugin_callbacks_full ()
static bool try_init_one_plugin ()
static int init_one_plugin (void **slot, void *ARG_UNUSED(info))
void initialize_plugins ()
static int finalize_one_plugin (void **slot, void *ARG_UNUSED(info))
void finalize_plugins ()
static int print_version_one_plugin ()
void print_plugins_versions ()
static int print_help_one_plugin ()
void print_plugins_help ()
bool plugins_active_p ()
DEBUG_FUNCTION void dump_active_plugins ()
DEBUG_FUNCTION void debug_active_plugins ()
void warn_if_plugins ()
void plugins_internal_error_function (diagnostic_context *context, const char *msgid, va_list *ap)
bool plugin_default_version_check (struct plugin_gcc_version *gcc_version, struct plugin_gcc_version *plugin_version)
int get_event_last ()
const char * default_plugin_dir_name ()

Variables

static const char * plugin_event_name_init []
const char ** plugin_event_name = plugin_event_name_init
static hash_table< event_hasherevent_tab
static int event_last = PLUGIN_EVENT_FIRST_DYNAMIC
static int event_horizon = PLUGIN_EVENT_FIRST_DYNAMIC
static htab_t plugin_name_args_tab = NULL
static struct callback_infoplugin_callbacks_init [PLUGIN_EVENT_FIRST_DYNAMIC]
static struct callback_info ** plugin_callbacks = plugin_callbacks_init
bool flag_plugin_added = false
static const char * str_plugin_init_func_name = "plugin_init"
static const char * str_license = "plugin_is_GPL_compatible"

Function Documentation

void add_new_plugin ( )
   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.  
     Replace short names by their full path when relevant.  
         FIXME: the ".so" suffix is currently builtin, since plugins
         only work on ELF host systems like e.g. Linux or Solaris.
         When plugins shall be available on non ELF systems such as
         Windows or MacOS, this code has to be greatly improved.  
     If this is the first -fplugin= option we encounter, create
     'plugin_name_args_tab' hash table.  
     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.  
DEBUG_FUNCTION void debug_active_plugins ( void  )
   Dump active plugins to stderr.  
const char* default_plugin_dir_name ( void  )
   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.  
DEBUG_FUNCTION void dump_active_plugins ( )
static int finalize_one_plugin ( void **  slot,
void *  ARG_UNUSEDinfo 
)
static
   Release memory used by one plugin. 

References print_options::file, indent, print_options::indent, plugin_name_args_tab, and print_version_one_plugin().

Referenced by init_one_plugin().

void finalize_plugins ( void  )
   Free memory allocated by the plugin system. 
     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.  
     PLUGIN_NAME_ARGS_TAB is no longer needed, just delete it.  

References plugin_name_args::base_name, print_options::file, plugin_name_args::help, and print_options::indent.

int get_event_last ( void  )
   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_named_event_id ( )
   Look up the event id for NAME.  If the name is not found, return -1
   if INSERT is NO_INSERT.  
         All the pointers in the hash table will need to be updated.  
static char* get_plugin_base_name ( )
static
   Given a plugin's full-path name FULL_NAME, e.g. /pass/to/NAME.so,
   return NAME.  
     First get the base name part of the full-path name, i.e. NAME.so.  
     Then get rid of '.so' part of the name.  

References plugin_name_args::base_name, and flag_plugin_added.

static int htab_str_eq ( )
static
   Helper function for the hash table that compares the base_name of the
   existing entry (S1) with the given string (S2).  
static int init_one_plugin ( void **  slot,
void *  ARG_UNUSEDinfo 
)
static
   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)  

References finalize_one_plugin(), and plugin_name_args_tab.

void initialize_plugins ( void  )
   Main plugin initialization function.  Called from compile_file() in
   toplev.c.  
     If no plugin was specified in the command-line, simply return.  
     Traverse and initialize each plugin specified in the command-line.  

References print_options::file, and print_options::indent.

int invoke_plugin_callbacks_full ( )
   Invoke all plugin callbacks registered with the specified event,
   called from invoke_plugin_callbacks().  
         Fall through.  
             Iterate over every callback registered with this event and
             call it.  

Referenced by invoke_plugin_callbacks().

void parse_plugin_arg_opt ( )
   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.  
     Iterate over the ARG string and identify the starting character position
     of 'name', 'key', and 'value' and their lengths.  
         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 the option doesn't contain the 'value' part, LEN is the KEY_LEN.
     Otherwise, it is the VALUE_LEN.  
     Check if the named plugin has already been specified earlier in the
     command-line.  
         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.  
     We don't need the plugin's name anymore. Just release it.  

References len.

bool plugin_default_version_check ( struct plugin_gcc_version gcc_version,
struct plugin_gcc_version plugin_version 
)
   The default version check. Compares every field in VERSION. 
bool plugins_active_p ( void  )
   Return true if plugins have been loaded.  

Referenced by print_help_one_plugin().

void plugins_internal_error_function ( diagnostic_context context,
const char *  msgid,
va_list *  ap 
)
   Likewise, as a callback from the diagnostics code.  
static int print_help_one_plugin ( )
static
   Print help for one plugin. SLOT is the hash table slot. DATA is the
   argument to htab_traverse_noresize. 

References event_last, callback_info::next, callback_info::plugin_name, and plugins_active_p().

Referenced by print_version_one_plugin().

void print_plugins_help ( )
   Print help for each plugin. The output goes to FILE and every line starts
   with INDENT. 

References dump_active_plugins().

void print_plugins_versions ( )
   Print the version of each plugin. 

References event_last.

static int print_version_one_plugin ( )
static
   Print the version of one plugin. 

References print_options::file, indent, print_options::indent, plugin_name_args_tab, and print_help_one_plugin().

Referenced by finalize_one_plugin().

void register_callback ( const char *  plugin_name,
int  event,
plugin_callback_func  callback,
void *  user_data 
)
   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   
         Fall through.  

References error(), callback_info::func, callback_info::next, callback_info::plugin_name, and callback_info::user_data.

static void register_plugin_info ( )
static
   Register additional plugin information. NAME is the name passed to
   plugin_init. INFO is the information that should be registered. 

References event_horizon, memcpy(), and plugin_event_name_init.

static bool try_init_one_plugin ( )
static
   Try to initialize PLUGIN. Return true if successful. 
     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.  
     Clear any existing error.  
     Check the plugin license.  
     Call the plugin-provided initialization routine with the arguments.  
int unregister_callback ( )
   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.  
void warn_if_plugins ( void  )
   Give a warning if plugins are present, before an ICE message asking
   to submit a bug report.  

Variable Documentation

int event_horizon = PLUGIN_EVENT_FIRST_DYNAMIC
static

Referenced by register_plugin_info().

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

Referenced by print_help_one_plugin(), and print_plugins_versions().

hash_table<event_hasher> event_tab
static
   A hash table to map event names to the position of the names in the
   plugin_event_name table.  
bool flag_plugin_added = false
   For invoke_plugin_callbacks(), see plugin.h.  

Referenced by get_plugin_base_name(), and invoke_plugin_callbacks().

struct callback_info** plugin_callbacks = plugin_callbacks_init
static
struct callback_info* plugin_callbacks_init[PLUGIN_EVENT_FIRST_DYNAMIC]
static
   An array of lists of 'callback_info' objects indexed by the event id.  
const char** plugin_event_name = plugin_event_name_init
   All globals declared here have C linkage to reduce link compatibility
   issues with implementation language choice and mangling.  
const char* plugin_event_name_init[]
static
Initial value:
{
# define DEFEVENT(NAME) GCC_PLUGIN_STRINGIFY1 (NAME),
# include "plugin.def"
# undef DEFEVENT
}
   Event names as strings.  Keep in sync with enum plugin_event.  

Referenced by register_plugin_info().

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

Referenced by finalize_one_plugin(), init_one_plugin(), and print_version_one_plugin().

const char* str_license = "plugin_is_GPL_compatible"
static
   Each plugin should define this symbol to assert that it is
   distributed under a GPL-compatible license.  
const char* str_plugin_init_func_name = "plugin_init"
static
   Each plugin should define an initialization function with exactly
   this name.