X-Git-Url: http://git.sourceforge.jp/view?p=pf3gnuchains%2Fgcc-fork.git;a=blobdiff_plain;f=gcc%2Fplugin.c;h=63d1cae4ede4c2417f7ec6a1a719677fe99b6cb3;hp=25e5b95be8fe923097cdf7bffacdee07c3787346;hb=913e1c8e01bfd9dee51290e2a3b1efdadf02b7d2;hpb=0bac94cb594aa47c9a883f83daeaa628401baf8d diff --git a/gcc/plugin.c b/gcc/plugin.c index 25e5b95be8f..63d1cae4ede 100644 --- a/gcc/plugin.c +++ b/gcc/plugin.c @@ -1,5 +1,5 @@ /* Support for GCC plugin mechanism. - Copyright (C) 2009 Free Software Foundation, Inc. + Copyright (C) 2009, 2010, 2011 Free Software Foundation, Inc. This file is part of GCC. @@ -22,17 +22,8 @@ along with GCC; see the file COPYING3. If not see #include "config.h" #include "system.h" - -/* If plugin support is not enabled, do not try to execute any code - that may reference libdl. The generic code is still compiled in to - avoid including too many conditional compilation paths in the rest - of the compiler. */ -#ifdef ENABLE_PLUGIN -#include -#endif - #include "coretypes.h" -#include "toplev.h" +#include "diagnostic-core.h" #include "tree.h" #include "tree-pass.h" #include "intl.h" @@ -86,6 +77,8 @@ struct callback_info 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 @@ -124,16 +117,43 @@ get_plugin_base_name (const char *full_name) } -/* Create a plugin_name_args object for the give plugin and insert it to - the hash table. This function is called when -fplugin=/path/to/NAME.so - option is processed. */ +/* 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 = get_plugin_base_name (plugin_name); + 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); + /* 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. */ + plugin_name = concat (default_plugin_dir_name (), "/", + plugin_name, ".so", NULL); + if (access (plugin_name, R_OK)) + fatal_error + ("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. */ @@ -150,7 +170,7 @@ add_new_plugin (const char* plugin_name) { plugin = (struct plugin_name_args *) *slot; if (strcmp (plugin->full_name, plugin_name)) - error ("Plugin %s was specified with different paths:\n%s\n%s", + error ("plugin %s was specified with different paths:\n%s\n%s", plugin->base_name, plugin->full_name, plugin_name); return; } @@ -196,7 +216,7 @@ parse_plugin_arg_opt (const char *arg) { if (key_parsed) { - error ("Malformed option -fplugin-arg-%s (multiple '=' signs)", + error ("malformed option -fplugin-arg-%s (multiple '=' signs)", arg); return; } @@ -212,7 +232,7 @@ parse_plugin_arg_opt (const char *arg) if (!key_start) { - error ("Malformed option -fplugin-arg-%s (missing -[=])", + error ("malformed option -fplugin-arg-%s (missing -[=])", arg); return; } @@ -274,7 +294,7 @@ parse_plugin_arg_opt (const char *arg) plugin->argv[plugin->argc - 1].value = value; } else - error ("Plugin %s should be specified before -fplugin-arg-%s " + 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. */ @@ -394,12 +414,13 @@ register_callback (const char *plugin_name, default: if (event < PLUGIN_EVENT_FIRST_DYNAMIC || event >= event_last) { - error ("Unknown callback event registered by plugin %s", + error ("unknown callback event registered by plugin %s", plugin_name); return; } /* Fall through. */ case PLUGIN_FINISH_TYPE: + case PLUGIN_FINISH_DECL: case PLUGIN_START_UNIT: case PLUGIN_FINISH_UNIT: case PLUGIN_PRE_GENERICIZE: @@ -422,7 +443,7 @@ register_callback (const char *plugin_name, struct callback_info *new_callback; if (!callback) { - error ("Plugin %s registered a null callback function " + error ("plugin %s registered a null callback function " "for event %s", plugin_name, plugin_event_name[event]); return; } @@ -458,16 +479,11 @@ unregister_callback (const char *plugin_name, int event) return PLUGEVT_NO_CALLBACK; } -/* Called from inside GCC. Invoke all plug-in callbacks registered with - the specified event. - Return PLUGEVT_SUCCESS if at least one callback was called, - PLUGEVT_NO_CALLBACK if there was no callback. - - EVENT - the event identifier - GCC_DATA - event-specific data provided by the compiler */ +/* Invoke all plugin callbacks registered with the specified event, + called from invoke_plugin_callbacks(). */ int -invoke_plugin_callbacks (int event, void *gcc_data) +invoke_plugin_callbacks_full (int event, void *gcc_data) { int retval = PLUGEVT_SUCCESS; @@ -481,6 +497,7 @@ invoke_plugin_callbacks (int event, void *gcc_data) gcc_assert (event < event_last); /* Fall through. */ case PLUGIN_FINISH_TYPE: + case PLUGIN_FINISH_DECL: case PLUGIN_START_UNIT: case PLUGIN_FINISH_UNIT: case PLUGIN_PRE_GENERICIZE: @@ -547,7 +564,7 @@ try_init_one_plugin (struct plugin_name_args *plugin) dl_handle = dlopen (plugin->full_name, RTLD_NOW | RTLD_GLOBAL); if (!dl_handle) { - error ("Cannot load plugin %s\n%s", plugin->full_name, dlerror ()); + error ("cannot load plugin %s\n%s", plugin->full_name, dlerror ()); return false; } @@ -565,7 +582,7 @@ try_init_one_plugin (struct plugin_name_args *plugin) if ((err = dlerror ()) != NULL) { - error ("Cannot find %s in plugin %s\n%s", str_plugin_init_func_name, + error ("cannot find %s in plugin %s\n%s", str_plugin_init_func_name, plugin->full_name, err); return false; } @@ -573,7 +590,7 @@ try_init_one_plugin (struct plugin_name_args *plugin) /* Call the plugin-provided initialization routine with the arguments. */ if ((*plugin_init) (plugin, &gcc_version)) { - error ("Fail to initialize plugin %s", plugin->full_name); + error ("fail to initialize plugin %s", plugin->full_name); return false; } @@ -754,7 +771,7 @@ plugins_active_p (void) /* Dump to FILE the names and associated events for all the active plugins. */ -void +DEBUG_FUNCTION void dump_active_plugins (FILE *file) { int event; @@ -780,12 +797,38 @@ dump_active_plugins (FILE *file) /* Dump active plugins to stderr. */ -void +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); + } + +} + +/* Likewise, as a callback from the diagnostics code. */ + +void +plugins_internal_error_function (diagnostic_context *context ATTRIBUTE_UNUSED, + const char *msgid ATTRIBUTE_UNUSED, + va_list *ap ATTRIBUTE_UNUSED) +{ + warn_if_plugins (); +} + /* The default version check. Compares every field in VERSION. */ bool @@ -809,6 +852,7 @@ plugin_default_version_check (struct plugin_gcc_version *gcc_version, 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. */ @@ -818,3 +862,15 @@ get_event_last (void) { return event_last; } + + +/* Retrieve the default plugin directory. The gcc driver should have passed + it as -iplugindir to the cc1 program, and it is queriable thru the + -print-file-name=plugin option to gcc. */ +const char* +default_plugin_dir_name (void) +{ + if (!plugindir_string) + fatal_error ("-iplugindir option not passed from the gcc driver"); + return plugindir_string; +}