Mercurial > hg > CbC > CbC_gcc
comparison gcc/plugin.c @ 131:84e7813d76e9
gcc-8.2
author | mir3636 |
---|---|
date | Thu, 25 Oct 2018 07:37:49 +0900 |
parents | 04ced10e8804 |
children | 1830386684a0 |
comparison
equal
deleted
inserted
replaced
111:04ced10e8804 | 131:84e7813d76e9 |
---|---|
1 /* Support for GCC plugin mechanism. | 1 /* Support for GCC plugin mechanism. |
2 Copyright (C) 2009-2017 Free Software Foundation, Inc. | 2 Copyright (C) 2009-2018 Free Software Foundation, Inc. |
3 | 3 |
4 This file is part of GCC. | 4 This file is part of GCC. |
5 | 5 |
6 GCC is free software; you can redistribute it and/or modify | 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 | 7 it under the terms of the GNU General Public License as published by |
32 | 32 |
33 #ifdef ENABLE_PLUGIN | 33 #ifdef ENABLE_PLUGIN |
34 #include "plugin-version.h" | 34 #include "plugin-version.h" |
35 #endif | 35 #endif |
36 | 36 |
37 #ifdef __MINGW32__ | |
38 #ifndef WIN32_LEAN_AND_MEAN | |
39 #define WIN32_LEAN_AND_MEAN | |
40 #endif | |
41 #ifndef NOMINMAX | |
42 #define NOMINMAX | |
43 #endif | |
44 #include <windows.h> | |
45 #endif | |
46 | |
37 #define GCC_PLUGIN_STRINGIFY0(X) #X | 47 #define GCC_PLUGIN_STRINGIFY0(X) #X |
38 #define GCC_PLUGIN_STRINGIFY1(X) GCC_PLUGIN_STRINGIFY0 (X) | 48 #define GCC_PLUGIN_STRINGIFY1(X) GCC_PLUGIN_STRINGIFY0 (X) |
39 | 49 |
40 /* Event names as strings. Keep in sync with enum plugin_event. */ | 50 /* Event names as strings. Keep in sync with enum plugin_event. */ |
41 static const char *plugin_event_name_init[] = | 51 static const char *plugin_event_name_init[] = |
142 get_plugin_base_name (const char *full_name) | 152 get_plugin_base_name (const char *full_name) |
143 { | 153 { |
144 /* First get the base name part of the full-path name, i.e. NAME.so. */ | 154 /* First get the base name part of the full-path name, i.e. NAME.so. */ |
145 char *base_name = xstrdup (lbasename (full_name)); | 155 char *base_name = xstrdup (lbasename (full_name)); |
146 | 156 |
147 /* Then get rid of '.so' part of the name. */ | 157 /* Then get rid of the extension in the name, e.g., .so. */ |
148 strip_off_ending (base_name, strlen (base_name)); | 158 strip_off_ending (base_name, strlen (base_name)); |
149 | 159 |
150 return base_name; | 160 return base_name; |
151 } | 161 } |
152 | 162 |
173 name_is_short = false; | 183 name_is_short = false; |
174 | 184 |
175 if (name_is_short) | 185 if (name_is_short) |
176 { | 186 { |
177 base_name = CONST_CAST (char*, plugin_name); | 187 base_name = CONST_CAST (char*, plugin_name); |
178 /* FIXME: the ".so" suffix is currently builtin, since plugins | 188 |
179 only work on ELF host systems like e.g. Linux or Solaris. | 189 #if defined(__MINGW32__) |
180 When plugins shall be available on non ELF systems such as | 190 static const char plugin_ext[] = ".dll"; |
181 Windows or MacOS, this code has to be greatly improved. */ | 191 #elif defined(__APPLE__) |
192 /* Mac OS has two types of libraries: dynamic libraries (.dylib) and | |
193 plugins (.bundle). Both can be used with dlopen()/dlsym() but the | |
194 former cannot be linked at build time (i.e., with the -lfoo linker | |
195 option). A GCC plugin is therefore probably a Mac OS plugin but their | |
196 use seems to be quite rare and the .bundle extension is more of a | |
197 recommendation rather than the rule. This raises the questions of how | |
198 well they are supported by tools (e.g., libtool). So to avoid | |
199 complications let's use the .dylib extension for now. In the future, | |
200 if this proves to be an issue, we can always check for both | |
201 extensions. */ | |
202 static const char plugin_ext[] = ".dylib"; | |
203 #else | |
204 static const char plugin_ext[] = ".so"; | |
205 #endif | |
206 | |
182 plugin_name = concat (default_plugin_dir_name (), "/", | 207 plugin_name = concat (default_plugin_dir_name (), "/", |
183 plugin_name, ".so", NULL); | 208 plugin_name, plugin_ext, NULL); |
184 if (access (plugin_name, R_OK)) | 209 if (access (plugin_name, R_OK)) |
185 fatal_error | 210 fatal_error |
186 (input_location, | 211 (input_location, |
187 "inaccessible plugin file %s expanded from short plugin name %s: %m", | 212 "inaccessible plugin file %s expanded from short plugin name %s: %m", |
188 plugin_name, base_name); | 213 plugin_name, base_name); |
571 timevar_pop (TV_PLUGIN_RUN); | 596 timevar_pop (TV_PLUGIN_RUN); |
572 return retval; | 597 return retval; |
573 } | 598 } |
574 | 599 |
575 #ifdef ENABLE_PLUGIN | 600 #ifdef ENABLE_PLUGIN |
601 | |
602 /* Try to initialize PLUGIN. Return true if successful. */ | |
603 | |
604 #ifdef __MINGW32__ | |
605 | |
606 // Return a message string for last error or NULL if unknown. Must be freed | |
607 // with LocalFree(). | |
608 static inline char * | |
609 win32_error_msg () | |
610 { | |
611 char *msg; | |
612 return FormatMessageA (FORMAT_MESSAGE_ALLOCATE_BUFFER | | |
613 FORMAT_MESSAGE_FROM_SYSTEM | | |
614 FORMAT_MESSAGE_IGNORE_INSERTS | | |
615 FORMAT_MESSAGE_MAX_WIDTH_MASK, | |
616 0, | |
617 GetLastError (), | |
618 MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), | |
619 (char*)&msg, | |
620 0, | |
621 0) | |
622 ? msg | |
623 : NULL; | |
624 } | |
625 | |
626 static bool | |
627 try_init_one_plugin (struct plugin_name_args *plugin) | |
628 { | |
629 HMODULE dl_handle; | |
630 plugin_init_func plugin_init; | |
631 | |
632 dl_handle = LoadLibrary (plugin->full_name); | |
633 if (!dl_handle) | |
634 { | |
635 char *err = win32_error_msg (); | |
636 error ("cannot load plugin %s\n%s", plugin->full_name, err); | |
637 LocalFree (err); | |
638 return false; | |
639 } | |
640 | |
641 /* Check the plugin license. Unlike the name suggests, GetProcAddress() | |
642 can be used for both functions and variables. */ | |
643 if (GetProcAddress (dl_handle, str_license) == NULL) | |
644 { | |
645 char *err = win32_error_msg (); | |
646 fatal_error (input_location, | |
647 "plugin %s is not licensed under a GPL-compatible license\n" | |
648 "%s", plugin->full_name, err); | |
649 } | |
650 | |
651 /* Unlike dlsym(), GetProcAddress() returns a pointer to a function so we | |
652 can cast directly without union tricks. */ | |
653 plugin_init = (plugin_init_func) | |
654 GetProcAddress (dl_handle, str_plugin_init_func_name); | |
655 | |
656 if (plugin_init == NULL) | |
657 { | |
658 char *err = win32_error_msg (); | |
659 FreeLibrary (dl_handle); | |
660 error ("cannot find %s in plugin %s\n%s", str_plugin_init_func_name, | |
661 plugin->full_name, err); | |
662 LocalFree (err); | |
663 return false; | |
664 } | |
665 | |
666 /* Call the plugin-provided initialization routine with the arguments. */ | |
667 if ((*plugin_init) (plugin, &gcc_version)) | |
668 { | |
669 FreeLibrary (dl_handle); | |
670 error ("fail to initialize plugin %s", plugin->full_name); | |
671 return false; | |
672 } | |
673 /* Leak dl_handle on purpose to ensure the plugin is loaded for the | |
674 entire run of the compiler. */ | |
675 return true; | |
676 } | |
677 | |
678 #else // POSIX-like with dlopen()/dlsym(). | |
679 | |
576 /* We need a union to cast dlsym return value to a function pointer | 680 /* We need a union to cast dlsym return value to a function pointer |
577 as ISO C forbids assignment between function pointer and 'void *'. | 681 as ISO C forbids assignment between function pointer and 'void *'. |
578 Use explicit union instead of __extension__(<union_cast>) for | 682 Use explicit union instead of __extension__(<union_cast>) for |
579 portability. */ | 683 portability. */ |
580 #define PTR_UNION_TYPE(TOTYPE) union { void *_q; TOTYPE _nq; } | 684 #define PTR_UNION_TYPE(TOTYPE) union { void *_q; TOTYPE _nq; } |
581 #define PTR_UNION_AS_VOID_PTR(NAME) (NAME._q) | 685 #define PTR_UNION_AS_VOID_PTR(NAME) (NAME._q) |
582 #define PTR_UNION_AS_CAST_PTR(NAME) (NAME._nq) | 686 #define PTR_UNION_AS_CAST_PTR(NAME) (NAME._nq) |
583 | 687 |
584 /* Try to initialize PLUGIN. Return true if successful. */ | |
585 | |
586 static bool | 688 static bool |
587 try_init_one_plugin (struct plugin_name_args *plugin) | 689 try_init_one_plugin (struct plugin_name_args *plugin) |
588 { | 690 { |
589 void *dl_handle; | 691 void *dl_handle; |
590 plugin_init_func plugin_init; | 692 plugin_init_func plugin_init; |
632 } | 734 } |
633 /* leak dl_handle on purpose to ensure the plugin is loaded for the | 735 /* leak dl_handle on purpose to ensure the plugin is loaded for the |
634 entire run of the compiler. */ | 736 entire run of the compiler. */ |
635 return true; | 737 return true; |
636 } | 738 } |
637 | 739 #endif |
638 | 740 |
639 /* Routine to dlopen and initialize one plugin. This function is passed to | 741 /* Routine to dlopen and initialize one plugin. This function is passed to |
640 (and called by) the hash table traverse routine. Return 1 for the | 742 (and called by) the hash table traverse routine. Return 1 for the |
641 htab_traverse to continue scan, 0 to stop. | 743 htab_traverse to continue scan, 0 to stop. |
642 | 744 |