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