Remove trailing white spaces.
[gcc.git] / gcc / plugin.c
1 /* Support for GCC plugin mechanism.
2 Copyright (C) 2009 Free Software Foundation, Inc.
3
4 This file is part of GCC.
5
6 GCC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3, or (at your option)
9 any later version.
10
11 GCC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
19
20 /* This file contains the support for GCC plugin mechanism based on the
21 APIs described in doc/plugin.texi. */
22
23 #include "config.h"
24 #include "system.h"
25
26 /* If plugin support is not enabled, do not try to execute any code
27 that may reference libdl. The generic code is still compiled in to
28 avoid including too many conditional compilation paths in the rest
29 of the compiler. */
30 #ifdef ENABLE_PLUGIN
31 #include <dlfcn.h>
32 #endif
33
34 #include "coretypes.h"
35 #include "toplev.h"
36 #include "tree.h"
37 #include "tree-pass.h"
38 #include "intl.h"
39 #include "plugin.h"
40 #include "timevar.h"
41 #include "ggc.h"
42
43 #ifdef ENABLE_PLUGIN
44 #include "plugin-version.h"
45 #endif
46
47 /* Event names as strings. Keep in sync with enum plugin_event. */
48 const char *plugin_event_name[] =
49 {
50 "PLUGIN_PASS_MANAGER_SETUP",
51 "PLUGIN_FINISH_TYPE",
52 "PLUGIN_FINISH_UNIT",
53 "PLUGIN_CXX_CP_PRE_GENERICIZE",
54 "PLUGIN_FINISH",
55 "PLUGIN_INFO",
56 "PLUGIN_GGC_START",
57 "PLUGIN_GGC_MARKING",
58 "PLUGIN_GGC_END",
59 "PLUGIN_REGISTER_GGC_ROOTS",
60 "PLUGIN_REGISTER_GGC_CACHES",
61 "PLUGIN_ATTRIBUTES",
62 "PLUGIN_START_UNIT",
63 "PLUGIN_PRAGMAS",
64 "PLUGIN_EVENT_LAST"
65 };
66
67 /* A printf format large enough for the largest event above. */
68 #define FMT_FOR_PLUGIN_EVENT "%-26s"
69
70 /* Hash table for the plugin_name_args objects created during command-line
71 parsing. */
72 static htab_t plugin_name_args_tab = NULL;
73
74 /* List node for keeping track of plugin-registered callback. */
75 struct callback_info
76 {
77 const char *plugin_name; /* Name of plugin that registers the callback. */
78 plugin_callback_func func; /* Callback to be called. */
79 void *user_data; /* plugin-specified data. */
80 struct callback_info *next;
81 };
82
83 /* An array of lists of 'callback_info' objects indexed by the event id. */
84 static struct callback_info *plugin_callbacks[PLUGIN_EVENT_LAST] = { NULL };
85
86
87 #ifdef ENABLE_PLUGIN
88 /* Each plugin should define an initialization function with exactly
89 this name. */
90 static const char *str_plugin_init_func_name = "plugin_init";
91
92 /* Each plugin should define this symbol to assert that it is
93 distributed under a GPL-compatible license. */
94 static const char *str_license = "plugin_is_GPL_compatible";
95 #endif
96
97 /* Helper function for the hash table that compares the base_name of the
98 existing entry (S1) with the given string (S2). */
99
100 static int
101 htab_str_eq (const void *s1, const void *s2)
102 {
103 const struct plugin_name_args *plugin = (const struct plugin_name_args *) s1;
104 return !strcmp (plugin->base_name, (const char *) s2);
105 }
106
107
108 /* Given a plugin's full-path name FULL_NAME, e.g. /pass/to/NAME.so,
109 return NAME. */
110
111 static char *
112 get_plugin_base_name (const char *full_name)
113 {
114 /* First get the base name part of the full-path name, i.e. NAME.so. */
115 char *base_name = xstrdup (lbasename (full_name));
116
117 /* Then get rid of '.so' part of the name. */
118 strip_off_ending (base_name, strlen (base_name));
119
120 return base_name;
121 }
122
123
124 /* Create a plugin_name_args object for the give plugin and insert it to
125 the hash table. This function is called when -fplugin=/path/to/NAME.so
126 option is processed. */
127
128 void
129 add_new_plugin (const char* plugin_name)
130 {
131 struct plugin_name_args *plugin;
132 void **slot;
133 char *base_name = get_plugin_base_name (plugin_name);
134
135 /* If this is the first -fplugin= option we encounter, create
136 'plugin_name_args_tab' hash table. */
137 if (!plugin_name_args_tab)
138 plugin_name_args_tab = htab_create (10, htab_hash_string, htab_str_eq,
139 NULL);
140
141 slot = htab_find_slot (plugin_name_args_tab, base_name, INSERT);
142
143 /* If the same plugin (name) has been specified earlier, either emit an
144 error or a warning message depending on if they have identical full
145 (path) names. */
146 if (*slot)
147 {
148 plugin = (struct plugin_name_args *) *slot;
149 if (strcmp (plugin->full_name, plugin_name))
150 error ("Plugin %s was specified with different paths:\n%s\n%s",
151 plugin->base_name, plugin->full_name, plugin_name);
152 return;
153 }
154
155 plugin = XCNEW (struct plugin_name_args);
156 plugin->base_name = base_name;
157 plugin->full_name = plugin_name;
158
159 *slot = plugin;
160 }
161
162
163 /* Parse the -fplugin-arg-<name>-<key>[=<value>] option and create a
164 'plugin_argument' object for the parsed key-value pair. ARG is
165 the <name>-<key>[=<value>] part of the option. */
166
167 void
168 parse_plugin_arg_opt (const char *arg)
169 {
170 size_t len = 0, name_len = 0, key_len = 0, value_len = 0;
171 const char *ptr, *name_start = arg, *key_start = NULL, *value_start = NULL;
172 char *name, *key, *value;
173 void **slot;
174 bool name_parsed = false, key_parsed = false;
175
176 /* Iterate over the ARG string and identify the starting character position
177 of 'name', 'key', and 'value' and their lengths. */
178 for (ptr = arg; *ptr; ++ptr)
179 {
180 /* Only the first '-' encountered is considered a separator between
181 'name' and 'key'. All the subsequent '-'s are considered part of
182 'key'. For example, given -fplugin-arg-foo-bar-primary-key=value,
183 the plugin name is 'foo' and the key is 'bar-primary-key'. */
184 if (*ptr == '-' && !name_parsed)
185 {
186 name_len = len;
187 len = 0;
188 key_start = ptr + 1;
189 name_parsed = true;
190 continue;
191 }
192 else if (*ptr == '=')
193 {
194 if (key_parsed)
195 {
196 error ("Malformed option -fplugin-arg-%s (multiple '=' signs)",
197 arg);
198 return;
199 }
200 key_len = len;
201 len = 0;
202 value_start = ptr + 1;
203 key_parsed = true;
204 continue;
205 }
206 else
207 ++len;
208 }
209
210 if (!key_start)
211 {
212 error ("Malformed option -fplugin-arg-%s (missing -<key>[=<value>])",
213 arg);
214 return;
215 }
216
217 /* If the option doesn't contain the 'value' part, LEN is the KEY_LEN.
218 Otherwise, it is the VALUE_LEN. */
219 if (!value_start)
220 key_len = len;
221 else
222 value_len = len;
223
224 name = XNEWVEC (char, name_len + 1);
225 strncpy (name, name_start, name_len);
226 name[name_len] = '\0';
227
228 /* Check if the named plugin has already been specified earlier in the
229 command-line. */
230 if (plugin_name_args_tab
231 && ((slot = htab_find_slot (plugin_name_args_tab, name, NO_INSERT))
232 != NULL))
233 {
234 struct plugin_name_args *plugin = (struct plugin_name_args *) *slot;
235
236 key = XNEWVEC (char, key_len + 1);
237 strncpy (key, key_start, key_len);
238 key[key_len] = '\0';
239 if (value_start)
240 {
241 value = XNEWVEC (char, value_len + 1);
242 strncpy (value, value_start, value_len);
243 value[value_len] = '\0';
244 }
245 else
246 value = NULL;
247
248 /* Create a plugin_argument object for the parsed key-value pair.
249 If there are already arguments for this plugin, we will need to
250 adjust the argument array size by creating a new array and deleting
251 the old one. If the performance ever becomes an issue, we can
252 change the code by pre-allocating a larger array first. */
253 if (plugin->argc > 0)
254 {
255 struct plugin_argument *args = XNEWVEC (struct plugin_argument,
256 plugin->argc + 1);
257 memcpy (args, plugin->argv,
258 sizeof (struct plugin_argument) * plugin->argc);
259 XDELETEVEC (plugin->argv);
260 plugin->argv = args;
261 ++plugin->argc;
262 }
263 else
264 {
265 gcc_assert (plugin->argv == NULL);
266 plugin->argv = XNEWVEC (struct plugin_argument, 1);
267 plugin->argc = 1;
268 }
269
270 plugin->argv[plugin->argc - 1].key = key;
271 plugin->argv[plugin->argc - 1].value = value;
272 }
273 else
274 error ("Plugin %s should be specified before -fplugin-arg-%s "
275 "in the command line", name, arg);
276
277 /* We don't need the plugin's name anymore. Just release it. */
278 XDELETEVEC (name);
279 }
280
281 /* Register additional plugin information. NAME is the name passed to
282 plugin_init. INFO is the information that should be registered. */
283
284 static void
285 register_plugin_info (const char* name, struct plugin_info *info)
286 {
287 void **slot = htab_find_slot (plugin_name_args_tab, name, NO_INSERT);
288 struct plugin_name_args *plugin = (struct plugin_name_args *) *slot;
289 plugin->version = info->version;
290 plugin->help = info->help;
291 }
292
293 /* Called from the plugin's initialization code. Register a single callback.
294 This function can be called multiple times.
295
296 PLUGIN_NAME - display name for this plugin
297 EVENT - which event the callback is for
298 CALLBACK - the callback to be called at the event
299 USER_DATA - plugin-provided data */
300
301 void
302 register_callback (const char *plugin_name,
303 enum plugin_event event,
304 plugin_callback_func callback,
305 void *user_data)
306 {
307 switch (event)
308 {
309 case PLUGIN_PASS_MANAGER_SETUP:
310 gcc_assert (!callback);
311 register_pass ((struct register_pass_info *) user_data);
312 break;
313 case PLUGIN_INFO:
314 gcc_assert (!callback);
315 register_plugin_info (plugin_name, (struct plugin_info *) user_data);
316 break;
317 case PLUGIN_REGISTER_GGC_ROOTS:
318 gcc_assert (!callback);
319 ggc_register_root_tab ((const struct ggc_root_tab*) user_data);
320 break;
321 case PLUGIN_REGISTER_GGC_CACHES:
322 gcc_assert (!callback);
323 ggc_register_cache_tab ((const struct ggc_cache_tab*) user_data);
324 break;
325 case PLUGIN_FINISH_TYPE:
326 case PLUGIN_START_UNIT:
327 case PLUGIN_FINISH_UNIT:
328 case PLUGIN_CXX_CP_PRE_GENERICIZE:
329 case PLUGIN_GGC_START:
330 case PLUGIN_GGC_MARKING:
331 case PLUGIN_GGC_END:
332 case PLUGIN_ATTRIBUTES:
333 case PLUGIN_PRAGMAS:
334 case PLUGIN_FINISH:
335 {
336 struct callback_info *new_callback;
337 if (!callback)
338 {
339 error ("Plugin %s registered a null callback function "
340 "for event %s", plugin_name, plugin_event_name[event]);
341 return;
342 }
343 new_callback = XNEW (struct callback_info);
344 new_callback->plugin_name = plugin_name;
345 new_callback->func = callback;
346 new_callback->user_data = user_data;
347 new_callback->next = plugin_callbacks[event];
348 plugin_callbacks[event] = new_callback;
349 }
350 break;
351 case PLUGIN_EVENT_LAST:
352 default:
353 error ("Unknown callback event registered by plugin %s",
354 plugin_name);
355 }
356 }
357
358
359 /* Called from inside GCC. Invoke all plug-in callbacks registered with
360 the specified event.
361
362 EVENT - the event identifier
363 GCC_DATA - event-specific data provided by the compiler */
364
365 void
366 invoke_plugin_callbacks (enum plugin_event event, void *gcc_data)
367 {
368 timevar_push (TV_PLUGIN_RUN);
369
370 switch (event)
371 {
372 case PLUGIN_FINISH_TYPE:
373 case PLUGIN_START_UNIT:
374 case PLUGIN_FINISH_UNIT:
375 case PLUGIN_CXX_CP_PRE_GENERICIZE:
376 case PLUGIN_ATTRIBUTES:
377 case PLUGIN_PRAGMAS:
378 case PLUGIN_FINISH:
379 case PLUGIN_GGC_START:
380 case PLUGIN_GGC_MARKING:
381 case PLUGIN_GGC_END:
382 {
383 /* Iterate over every callback registered with this event and
384 call it. */
385 struct callback_info *callback = plugin_callbacks[event];
386 for ( ; callback; callback = callback->next)
387 (*callback->func) (gcc_data, callback->user_data);
388 }
389 break;
390
391 case PLUGIN_PASS_MANAGER_SETUP:
392 case PLUGIN_EVENT_LAST:
393 case PLUGIN_REGISTER_GGC_ROOTS:
394 case PLUGIN_REGISTER_GGC_CACHES:
395 default:
396 gcc_assert (false);
397 }
398
399 timevar_pop (TV_PLUGIN_RUN);
400 }
401
402 #ifdef ENABLE_PLUGIN
403 /* We need a union to cast dlsym return value to a function pointer
404 as ISO C forbids assignment between function pointer and 'void *'.
405 Use explicit union instead of __extension__(<union_cast>) for
406 portability. */
407 #define PTR_UNION_TYPE(TOTYPE) union { void *_q; TOTYPE _nq; }
408 #define PTR_UNION_AS_VOID_PTR(NAME) (NAME._q)
409 #define PTR_UNION_AS_CAST_PTR(NAME) (NAME._nq)
410
411 /* Try to initialize PLUGIN. Return true if successful. */
412
413 static bool
414 try_init_one_plugin (struct plugin_name_args *plugin)
415 {
416 void *dl_handle;
417 plugin_init_func plugin_init;
418 const char *err;
419 PTR_UNION_TYPE (plugin_init_func) plugin_init_union;
420
421 /* We use RTLD_NOW to accelerate binding and detect any mismatch
422 between the API expected by the plugin and the GCC API; we use
423 RTLD_GLOBAL which is useful to plugins which themselves call
424 dlopen. */
425 dl_handle = dlopen (plugin->full_name, RTLD_NOW | RTLD_GLOBAL);
426 if (!dl_handle)
427 {
428 error ("Cannot load plugin %s\n%s", plugin->full_name, dlerror ());
429 return false;
430 }
431
432 /* Clear any existing error. */
433 dlerror ();
434
435 /* Check the plugin license. */
436 if (dlsym (dl_handle, str_license) == NULL)
437 fatal_error ("plugin %s is not licensed under a GPL-compatible license\n"
438 "%s", plugin->full_name, dlerror ());
439
440 PTR_UNION_AS_VOID_PTR (plugin_init_union) =
441 dlsym (dl_handle, str_plugin_init_func_name);
442 plugin_init = PTR_UNION_AS_CAST_PTR (plugin_init_union);
443
444 if ((err = dlerror ()) != NULL)
445 {
446 error ("Cannot find %s in plugin %s\n%s", str_plugin_init_func_name,
447 plugin->full_name, err);
448 return false;
449 }
450
451 /* Call the plugin-provided initialization routine with the arguments. */
452 if ((*plugin_init) (plugin, &gcc_version))
453 {
454 error ("Fail to initialize plugin %s", plugin->full_name);
455 return false;
456 }
457
458 return true;
459 }
460
461
462 /* Routine to dlopen and initialize one plugin. This function is passed to
463 (and called by) the hash table traverse routine. Return 1 for the
464 htab_traverse to continue scan, 0 to stop.
465
466 SLOT - slot of the hash table element
467 INFO - auxiliary pointer handed to hash table traverse routine
468 (unused in this function) */
469
470 static int
471 init_one_plugin (void **slot, void * ARG_UNUSED (info))
472 {
473 struct plugin_name_args *plugin = (struct plugin_name_args *) *slot;
474 bool ok = try_init_one_plugin (plugin);
475 if (!ok)
476 {
477 htab_remove_elt (plugin_name_args_tab, plugin->base_name);
478 XDELETE (plugin);
479 }
480 return 1;
481 }
482
483 #endif /* ENABLE_PLUGIN */
484
485 /* Main plugin initialization function. Called from compile_file() in
486 toplev.c. */
487
488 void
489 initialize_plugins (void)
490 {
491 /* If no plugin was specified in the command-line, simply return. */
492 if (!plugin_name_args_tab)
493 return;
494
495 timevar_push (TV_PLUGIN_INIT);
496
497 #ifdef ENABLE_PLUGIN
498 /* Traverse and initialize each plugin specified in the command-line. */
499 htab_traverse_noresize (plugin_name_args_tab, init_one_plugin, NULL);
500 #endif
501
502 timevar_pop (TV_PLUGIN_INIT);
503 }
504
505 /* Release memory used by one plugin. */
506
507 static int
508 finalize_one_plugin (void **slot, void * ARG_UNUSED (info))
509 {
510 struct plugin_name_args *plugin = (struct plugin_name_args *) *slot;
511 XDELETE (plugin);
512 return 1;
513 }
514
515 /* Free memory allocated by the plugin system. */
516
517 void
518 finalize_plugins (void)
519 {
520 if (!plugin_name_args_tab)
521 return;
522
523 /* We can now delete the plugin_name_args object as it will no longer
524 be used. Note that base_name and argv fields (both of which were also
525 dynamically allocated) are not freed as they could still be used by
526 the plugin code. */
527
528 htab_traverse_noresize (plugin_name_args_tab, finalize_one_plugin, NULL);
529
530 /* PLUGIN_NAME_ARGS_TAB is no longer needed, just delete it. */
531 htab_delete (plugin_name_args_tab);
532 plugin_name_args_tab = NULL;
533 }
534
535 /* Used to pass options to htab_traverse callbacks. */
536
537 struct print_options
538 {
539 FILE *file;
540 const char *indent;
541 };
542
543 /* Print the version of one plugin. */
544
545 static int
546 print_version_one_plugin (void **slot, void *data)
547 {
548 struct print_options *opt = (struct print_options *) data;
549 struct plugin_name_args *plugin = (struct plugin_name_args *) *slot;
550 const char *version = plugin->version ? plugin->version : "Unknown version.";
551
552 fprintf (opt->file, " %s%s: %s\n", opt->indent, plugin->base_name, version);
553 return 1;
554 }
555
556 /* Print the version of each plugin. */
557
558 void
559 print_plugins_versions (FILE *file, const char *indent)
560 {
561 struct print_options opt;
562 opt.file = file;
563 opt.indent = indent;
564 if (!plugin_name_args_tab || htab_elements (plugin_name_args_tab) == 0)
565 return;
566
567 fprintf (file, "%sVersions of loaded plugins:\n", indent);
568 htab_traverse_noresize (plugin_name_args_tab, print_version_one_plugin, &opt);
569 }
570
571 /* Print help for one plugin. SLOT is the hash table slot. DATA is the
572 argument to htab_traverse_noresize. */
573
574 static int
575 print_help_one_plugin (void **slot, void *data)
576 {
577 struct print_options *opt = (struct print_options *) data;
578 struct plugin_name_args *plugin = (struct plugin_name_args *) *slot;
579 const char *help = plugin->help ? plugin->help : "No help available .";
580
581 char *dup = xstrdup (help);
582 char *p, *nl;
583 fprintf (opt->file, " %s%s:\n", opt->indent, plugin->base_name);
584
585 for (p = nl = dup; nl; p = nl)
586 {
587 nl = strchr (nl, '\n');
588 if (nl)
589 {
590 *nl = '\0';
591 nl++;
592 }
593 fprintf (opt->file, " %s %s\n", opt->indent, p);
594 }
595
596 free (dup);
597 return 1;
598 }
599
600 /* Print help for each plugin. The output goes to FILE and every line starts
601 with INDENT. */
602
603 void
604 print_plugins_help (FILE *file, const char *indent)
605 {
606 struct print_options opt;
607 opt.file = file;
608 opt.indent = indent;
609 if (!plugin_name_args_tab || htab_elements (plugin_name_args_tab) == 0)
610 return;
611
612 fprintf (file, "%sHelp for the loaded plugins:\n", indent);
613 htab_traverse_noresize (plugin_name_args_tab, print_help_one_plugin, &opt);
614 }
615
616
617 /* Return true if plugins have been loaded. */
618
619 bool
620 plugins_active_p (void)
621 {
622 int event;
623
624 for (event = PLUGIN_PASS_MANAGER_SETUP; event < PLUGIN_EVENT_LAST; event++)
625 if (plugin_callbacks[event])
626 return true;
627
628 return false;
629 }
630
631
632 /* Dump to FILE the names and associated events for all the active
633 plugins. */
634
635 void
636 dump_active_plugins (FILE *file)
637 {
638 int event;
639
640 if (!plugins_active_p ())
641 return;
642
643 fprintf (file, FMT_FOR_PLUGIN_EVENT " | %s\n", _("Event"), _("Plugins"));
644 for (event = PLUGIN_PASS_MANAGER_SETUP; event < PLUGIN_EVENT_LAST; event++)
645 if (plugin_callbacks[event])
646 {
647 struct callback_info *ci;
648
649 fprintf (file, FMT_FOR_PLUGIN_EVENT " |", plugin_event_name[event]);
650
651 for (ci = plugin_callbacks[event]; ci; ci = ci->next)
652 fprintf (file, " %s", ci->plugin_name);
653
654 putc('\n', file);
655 }
656 }
657
658
659 /* Dump active plugins to stderr. */
660
661 void
662 debug_active_plugins (void)
663 {
664 dump_active_plugins (stderr);
665 }
666
667 /* The default version check. Compares every field in VERSION. */
668
669 bool
670 plugin_default_version_check (struct plugin_gcc_version *gcc_version,
671 struct plugin_gcc_version *plugin_version)
672 {
673 if (!gcc_version || !plugin_version)
674 return false;
675
676 if (strcmp (gcc_version->basever, plugin_version->basever))
677 return false;
678 if (strcmp (gcc_version->datestamp, plugin_version->datestamp))
679 return false;
680 if (strcmp (gcc_version->devphase, plugin_version->devphase))
681 return false;
682 if (strcmp (gcc_version->revision, plugin_version->revision))
683 return false;
684 if (strcmp (gcc_version->configuration_arguments,
685 plugin_version->configuration_arguments))
686 return false;
687 return true;
688 }