diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2020-03-20 03:55:17 -0700 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2020-03-20 03:55:30 -0700 |
commit | 3d98c46092341c1373d960d0a66ca502d5b7ee7f (patch) | |
tree | a4a9dc215ec7af582ce3e022c56a6ccda2e48586 /bfd/plugin.c | |
parent | c3a1714ce7806002726a60c0db09371425fe3097 (diff) | |
download | gdb-3d98c46092341c1373d960d0a66ca502d5b7ee7f.zip gdb-3d98c46092341c1373d960d0a66ca502d5b7ee7f.tar.gz gdb-3d98c46092341c1373d960d0a66ca502d5b7ee7f.tar.bz2 |
plugin: Don't invoke LTO-wrapper
Don't invoke LTO-wrapper since the LTO wrapper approach is not only
slow but also unreliable. For GCC 10 or newer, LDPT_ADD_SYMBOLS_V2
will be used.
bfd/
* configure.ac (HAVE_EXECUTABLE_SUFFIX): Removed.
(EXECUTABLE_SUFFIX): Likewise.
* config.in: Regenerated.
* configure: Likewise.
* plugin.c (bfd_plugin_close_and_cleanup): Defined as
_bfd_generic_close_and_cleanup.
(plugin_list_entry): Remove resolution_file, resolution_option,
real_bfd, real_nsyms, real_syms, lto_nsyms, lto_syms, gcc,
lto_wrapper, gcc_env and initialized,
(need_lto_wrapper_p): Removed.
(get_lto_wrapper): Likewise.
(setup_lto_wrapper_env): Likewise.
(register_all_symbols_read): Likewise.
(egister_cleanup): Likewise.
(get_symbols): Likewise.
(add_input_file): Likewise.
(bfd_plugin_set_program_name): Remove need_lto_wrapper.
(add_symbols): Updated.
(try_claim): Likewise.
(try_load_plugin): Likewise.
(bfd_plugin_canonicalize_symtab): Likewise.
* plugin.h (bfd_plugin_set_program_name): Remove int argument.
(plugin_data_struct): Remove real_bfd, real_nsyms and real_syms.
binutils/
* ar.c (main): Update bfd_plugin_set_program_name call.
* nm.c (main): Likewise.
ld/
* testsuite/ld-plugin/lto.exp (lto_link_tests): Run PR ld/25355
test only for GCC 10 or newer.
Diffstat (limited to 'bfd/plugin.c')
-rw-r--r-- | bfd/plugin.c | 453 |
1 files changed, 10 insertions, 443 deletions
diff --git a/bfd/plugin.c b/bfd/plugin.c index 13549d2..48387fa 100644 --- a/bfd/plugin.c +++ b/bfd/plugin.c @@ -69,6 +69,7 @@ dlerror (void) #endif /* !defined (HAVE_DLFCN_H) && defined (HAVE_WINDOWS_H) */ +#define bfd_plugin_close_and_cleanup _bfd_generic_close_and_cleanup #define bfd_plugin_bfd_free_cached_info _bfd_generic_bfd_free_cached_info #define bfd_plugin_new_section_hook _bfd_generic_new_section_hook #define bfd_plugin_get_section_contents _bfd_generic_get_section_contents @@ -129,196 +130,20 @@ struct plugin_list_entry ld_plugin_claim_file_handler claim_file; ld_plugin_all_symbols_read_handler all_symbols_read; ld_plugin_all_symbols_read_handler cleanup_handler; - char *resolution_file; - char *resolution_option; - bfd *real_bfd; - long real_nsyms; - asymbol **real_syms; - int lto_nsyms; - const struct ld_plugin_symbol *lto_syms; bfd_boolean has_symbol_type; struct plugin_list_entry *next; /* These can be reused for all IR objects. */ const char *plugin_name; - char *gcc; - char *lto_wrapper; - char *gcc_env; - bfd_boolean initialized; }; static const char *plugin_program_name; -static int need_lto_wrapper_p; void -bfd_plugin_set_program_name (const char *program_name, - int need_lto_wrapper) +bfd_plugin_set_program_name (const char *program_name) { plugin_program_name = program_name; - need_lto_wrapper_p = need_lto_wrapper; -} - -/* Use GCC LTO wrapper to covert LTO IR object to the real object. */ - -static bfd_boolean -get_lto_wrapper (struct plugin_list_entry *plugin) -{ - struct stat st; - const char *real_name; - const char *base_name; - size_t length; - const char *target_start = NULL; - const char *target_end = NULL; - size_t target_length = 0; - char *gcc_name; - char *wrapper_name; - char *p; - char dir_seperator = '\0'; - char *resolution_file; - - if (!need_lto_wrapper_p) - return FALSE; - - if (plugin->initialized) - { - if (plugin->lto_wrapper) - { - resolution_file = make_temp_file (".res"); - if (resolution_file) - { - plugin->resolution_file = resolution_file; - plugin->resolution_option = concat ("-fresolution=", - resolution_file, NULL); - return TRUE; - } - else - { - /* Something is wrong. Give up. */ - free (plugin->gcc); - free (plugin->lto_wrapper); - free (plugin->gcc_env); - plugin->gcc = NULL; - plugin->gcc_env = NULL; - plugin->lto_wrapper = NULL; - } - } - - return FALSE; - } - - plugin->initialized = TRUE; - - /* Check for PREFIX/libexec/gcc/TARGET/VERSION/liblto_plugin.so. */ - real_name = lrealpath (plugin->plugin_name); - base_name = lbasename (real_name); - - /* The directory length in plugin pathname. */ - length = base_name - real_name; - - /* Skip if there is no PREFIX. */ - if (!length) - return FALSE; - - p = (char *) real_name + length - 1; - if (IS_DIR_SEPARATOR (*p)) - { - int level = 0; - for (; p != real_name; p--) - if (IS_DIR_SEPARATOR (*p)) - { - level++; - if (level == 2) - target_end = p; - else if (level == 3) - { - target_start = p + 1; - target_length = target_end - target_start; - } - else if (level == 5) - { - dir_seperator = *p; - break; - } - } - } - - /* Skip if there is no TARGET nor PREFIX. */ - if (!target_length || !dir_seperator) - return FALSE; - -#ifdef HAVE_EXECUTABLE_SUFFIX -# define GCC_EXECUTABLE "gcc" EXECUTABLE_SUFFIX -# define LTO_WRAPPER_EXECUTABLE "lto-wrapper" EXECUTABLE_SUFFIX -#else -# define GCC_EXECUTABLE "gcc" -# define LTO_WRAPPER_EXECUTABLE "lto-wrapper" -#endif - gcc_name = bfd_malloc (length + target_length - + sizeof (GCC_EXECUTABLE)); - if (gcc_name == NULL) - return FALSE; - memcpy (gcc_name, real_name, length); - - /* Get PREFIX/bin/. */ - p += gcc_name - real_name; - memcpy (p + 1, "bin", 3); - p[4] = dir_seperator; - - /* Try PREFIX/bin/TARGET-gcc first. */ - memcpy (p + 5, target_start, target_length); - p[5 + target_length] = '-'; - memcpy (p + 5 + target_length + 1, GCC_EXECUTABLE, - sizeof (GCC_EXECUTABLE)); - if (stat (gcc_name, &st) != 0 || !S_ISREG (st.st_mode)) - { - /* Then try PREFIX/bin/gcc. */ - memcpy (p + 5, GCC_EXECUTABLE, sizeof (GCC_EXECUTABLE)); - if (stat (gcc_name, &st) != 0 || !S_ISREG (st.st_mode)) - { - free (gcc_name); - return FALSE; - } - } - - /* lto-wrapper should be in the same directory with LTO plugin. */ - wrapper_name = bfd_malloc (length + sizeof (LTO_WRAPPER_EXECUTABLE)); - if (wrapper_name == NULL) - { - free (gcc_name); - return FALSE; - } - memcpy (wrapper_name, real_name, length); - memcpy (wrapper_name + length, LTO_WRAPPER_EXECUTABLE, - sizeof (LTO_WRAPPER_EXECUTABLE)); - if (stat (wrapper_name, &st) == 0 && S_ISREG (st.st_mode)) - { - resolution_file = make_temp_file (".res"); - if (resolution_file) - { - plugin->gcc = gcc_name; - plugin->lto_wrapper = wrapper_name; - plugin->gcc_env = concat ("COLLECT_GCC=", gcc_name, NULL); - plugin->resolution_file = resolution_file; - plugin->resolution_option = concat ("-fresolution=", - resolution_file, NULL); - return TRUE; - } - } - - free (gcc_name); - free (wrapper_name); - return FALSE; -} - -/* Set environment variables for GCC LTO wrapper to covert LTO IR - object to the real object. */ - -static int -setup_lto_wrapper_env (struct plugin_list_entry *plugin) -{ - return (putenv (plugin->gcc_env) - || putenv ("COLLECT_GCC_OPTIONS=")); } static struct plugin_list_entry *plugin_list = NULL; @@ -333,119 +158,6 @@ register_claim_file (ld_plugin_claim_file_handler handler) return LDPS_OK; } -/* Register an all-symbols-read handler. */ - -static enum ld_plugin_status -register_all_symbols_read (ld_plugin_all_symbols_read_handler handler) -{ - current_plugin->all_symbols_read = handler; - return LDPS_OK; -} - -/* Register a cleanup handler. */ - -static enum ld_plugin_status -register_cleanup (ld_plugin_all_symbols_read_handler handler) -{ - current_plugin->cleanup_handler = handler; - return LDPS_OK; -} - -/* Get the symbol resolution info for a plugin-claimed input file. */ - -static enum ld_plugin_status -get_symbols (const void *handle ATTRIBUTE_UNUSED, int nsyms, - struct ld_plugin_symbol *syms) -{ - if (syms) - { - int n; - for (n = 0; n < nsyms; n++) - { - switch (syms[n].def) - { - default: - BFD_ASSERT (0); - break; - case LDPK_UNDEF: - case LDPK_WEAKUNDEF: - syms[n].resolution = LDPR_UNDEF; - break; - case LDPK_DEF: - case LDPK_WEAKDEF: - case LDPK_COMMON: - /* Tell plugin that LTO symbol has references from regular - object code. */ - syms[n].resolution = LDPR_PREVAILING_DEF; - break; - } - } - } - - return LDPS_OK; -} - -/* Add a new (real) input file generated by a plugin. */ - -static enum ld_plugin_status -add_input_file (const char *pathname) -{ - /* Get symbols from the real LTO object. */ - char **matching; - long real_symsize; - long real_nsyms; - asymbol **real_syms; - int lto_nsyms; - bfd_boolean lto_symbol_found = FALSE; - const struct ld_plugin_symbol *lto_syms; - bfd *rbfd; - int i, j; - - rbfd = bfd_openr (pathname, NULL); - if (!bfd_check_format_matches (rbfd, bfd_object, &matching)) - BFD_ASSERT (0); - - real_symsize = bfd_get_symtab_upper_bound (rbfd); - if (real_symsize < 0) - BFD_ASSERT (0); - - real_syms = (asymbol **) bfd_malloc (real_symsize); - if (real_syms) - { - real_nsyms = bfd_canonicalize_symtab (rbfd, real_syms); - if (real_nsyms < 0) - BFD_ASSERT (0); - - /* NB: LTO plugin may generate more than one real object from one - LTO IR object. We use the one which contains LTO symbols. */ - lto_syms = current_plugin->lto_syms; - lto_nsyms = current_plugin->lto_nsyms; - for (i = 0; i < lto_nsyms; i++) - for (j = 0; j < real_nsyms; j++) - if (real_syms[j]->name - && strcmp (lto_syms[i].name, real_syms[j]->name) == 0) - { - lto_symbol_found = TRUE; - break; - } - } - - if (lto_symbol_found) - { - current_plugin->real_nsyms = real_nsyms; - current_plugin->real_syms = real_syms; - /* NB: We can't close RBFD which own the real symbol info. */ - current_plugin->real_bfd = rbfd; - } - else - { - bfd_close (rbfd); - free (real_syms); - } - - return LDPS_OK; -} - static enum ld_plugin_status add_symbols (void * handle, int nsyms, @@ -455,52 +167,16 @@ add_symbols (void * handle, struct plugin_data_struct *plugin_data = bfd_alloc (abfd, sizeof (plugin_data_struct)); - if (plugin_data) - { - struct ld_plugin_symbol *sym_info; - char *strtab; - size_t sym_info_size, name_length; - int i; - - memset (plugin_data, 0, sizeof (*plugin_data)); - - abfd->tdata.plugin_data = plugin_data; - - /* NB: LTO symbols are owned by LTO plugin. Create a copy so - that we can use it in bfd_plugin_canonicalize_symtab. */ - sym_info_size = nsyms * sizeof (*syms); + if (!plugin_data) + return LDPS_ERR; - /* Allocate a string table */ - for (i = 0; i < nsyms; i++) - sym_info_size += strlen (syms[i].name) + 1; - - sym_info = bfd_alloc (abfd, sym_info_size); - if (sym_info) - { - /* Copy symbol table. */ - memcpy (sym_info, syms, nsyms * sizeof (*syms)); - - /* Copy symbol names in symbol table. */ - strtab = (char *) (sym_info + nsyms); - for (i = 0; i < nsyms; i++) - { - name_length = strlen (syms[i].name); - memcpy (strtab, syms[i].name, name_length + 1); - sym_info[i].name = strtab; - strtab += name_length + 1; - } - - plugin_data->nsyms = nsyms; - plugin_data->syms = sym_info; - - current_plugin->lto_nsyms = nsyms; - current_plugin->lto_syms = sym_info; - } - } + plugin_data->nsyms = nsyms; + plugin_data->syms = syms; if (nsyms != 0) abfd->flags |= HAS_SYMS; + abfd->tdata.plugin_data = plugin_data; return LDPS_OK; } @@ -567,42 +243,9 @@ try_claim (bfd *abfd) && current_plugin->claim_file) { current_plugin->claim_file (&file, &claimed); - if (claimed) - { - if (current_plugin->all_symbols_read - && !current_plugin->has_symbol_type) - { - struct plugin_data_struct *plugin_data - = abfd->tdata.plugin_data; - if (plugin_data) - { - /* Get real symbols from LTO wrapper. */ - current_plugin->all_symbols_read (); - - /* Copy real symbols to plugin_data. */ - plugin_data->real_bfd = current_plugin->real_bfd; - plugin_data->real_nsyms = current_plugin->real_nsyms; - plugin_data->real_syms = current_plugin->real_syms; - - /* Clean up LTO plugin. */ - if (current_plugin->cleanup_handler) - current_plugin->cleanup_handler (); - } - } - } - close (file.fd); } - if (current_plugin->lto_wrapper) - { - /* Clean up for LTO wrapper. NB: Resolution file and option - have been created regardless if an IR object is claimed or - not. */ - unlink (current_plugin->resolution_file); - free (current_plugin->resolution_option); - } - return claimed; } @@ -612,7 +255,7 @@ try_load_plugin (const char *pname, bfd *abfd, bfd_boolean build_list_p) { void *plugin_handle; - struct ld_plugin_tv tv[13]; + struct ld_plugin_tv tv[5]; int i; ld_plugin_onload onload; enum ld_plugin_status status; @@ -679,41 +322,6 @@ try_load_plugin (const char *pname, tv[i].tv_tag = LDPT_ADD_SYMBOLS_V2; tv[i].tv_u.tv_add_symbols = add_symbols_v2; - if (get_lto_wrapper (plugin_list_iter)) - { - ++i; - tv[i].tv_tag = LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK; - tv[i].tv_u.tv_register_all_symbols_read = register_all_symbols_read; - - ++i; - tv[i].tv_tag = LDPT_REGISTER_CLEANUP_HOOK; - tv[i].tv_u.tv_register_cleanup = register_cleanup; - - ++i; - tv[i].tv_tag = LDPT_GET_SYMBOLS; - tv[i].tv_u.tv_get_symbols = get_symbols; - - ++i; - tv[i].tv_tag = LDPT_GET_SYMBOLS_V2; - tv[i].tv_u.tv_get_symbols = get_symbols; - - ++i; - tv[i].tv_tag = LDPT_OPTION; - tv[i].tv_u.tv_string = plugin_list_iter->lto_wrapper; - - ++i; - tv[i].tv_tag = LDPT_OPTION; - tv[i].tv_u.tv_string = plugin_list_iter->resolution_option; - - ++i; - tv[i].tv_tag = LDPT_LINKER_OUTPUT; - tv[i].tv_u.tv_val = LDPO_EXEC; - - ++i; - tv[i].tv_tag = LDPT_ADD_INPUT_FILE; - tv[i].tv_u.tv_add_input_file = add_input_file; - } - ++i; tv[i].tv_tag = LDPT_NULL; tv[i].tv_u.tv_val = 0; @@ -724,10 +332,6 @@ try_load_plugin (const char *pname, if (status != LDPS_OK) goto short_circuit; - if (current_plugin->lto_wrapper - && setup_lto_wrapper_env (current_plugin)) - goto short_circuit; - abfd->plugin_format = bfd_plugin_no; if (!current_plugin->claim_file) @@ -1002,15 +606,7 @@ bfd_plugin_canonicalize_symtab (bfd *abfd, SEC_ALLOC); static asection fake_common_section = BFD_FAKE_SECTION (fake_common_section, NULL, "plug", 0, SEC_IS_COMMON); - int i, j; - long real_nsyms; - asymbol **real_syms; - - real_syms = plugin_data->real_syms; - if (real_syms) - real_nsyms = plugin_data->real_nsyms; - else - real_nsyms = 0; + int i; for (i = 0; i < nsyms; i++) { @@ -1050,18 +646,7 @@ bfd_plugin_canonicalize_symtab (bfd *abfd, break; } else - { - s->section = &fake_text_section; - if (real_nsyms) - /* Use real LTO symbols if possible. */ - for (j = 0; j < real_nsyms; j++) - if (real_syms[j]->name - && strcmp (syms[i].name, real_syms[j]->name) == 0) - { - s->section = real_syms[j]->section; - break; - } - } + s->section = &fake_text_section; break; default: BFD_ASSERT (0); @@ -1110,24 +695,6 @@ bfd_plugin_sizeof_headers (bfd *a ATTRIBUTE_UNUSED, return 0; } -static bfd_boolean -bfd_plugin_close_and_cleanup (bfd *abfd) -{ - struct plugin_data_struct *plugin_data; - - if (abfd->format != bfd_archive - && (plugin_data = abfd->tdata.plugin_data)) - { - if (plugin_data->real_bfd) - bfd_close (plugin_data->real_bfd); - - if (plugin_data->real_syms) - free (plugin_data->real_syms); - } - - return _bfd_generic_close_and_cleanup (abfd); -} - const bfd_target plugin_vec = { "plugin", /* Name. */ |