diff options
Diffstat (limited to 'binutils/objcopy.c')
-rw-r--r-- | binutils/objcopy.c | 261 |
1 files changed, 112 insertions, 149 deletions
diff --git a/binutils/objcopy.c b/binutils/objcopy.c index 654d2b9..3c1bcf6 100644 --- a/binutils/objcopy.c +++ b/binutils/objcopy.c @@ -30,9 +30,7 @@ #include "coff/internal.h" #include "libcoff.h" #include "safe-ctype.h" -#if BFD_SUPPORTS_PLUGINS #include "plugin.h" -#endif /* FIXME: See bfd/peXXigen.c for why we include an architecture specific header in generic PE code. */ @@ -168,13 +166,6 @@ static struct section_list *change_sections; /* TRUE if some sections are to be removed. */ static bool sections_removed; -#if BFD_SUPPORTS_PLUGINS -/* TRUE if all GCC LTO sections are to be removed. */ -static bool lto_sections_removed; -#else -#define lto_sections_removed false -#endif - /* TRUE if only some sections are to be copied. */ static bool sections_copied; @@ -770,10 +761,9 @@ strip_usage (FILE *stream, int exit_status) --info List object formats & architectures supported\n\ -o <file> Place stripped output into <file>\n\ ")); -#if BFD_SUPPORTS_PLUGINS - fprintf (stream, _("\ + if (bfd_plugin_enabled ()) + fprintf (stream, _("\ --plugin NAME Load the specified plugin\n")); -#endif list_supported_targets (program_name, stream); if (REPORT_BUGS_TO[0] && exit_status == 0) @@ -2664,8 +2654,7 @@ set_long_section_mode (bfd *output_bfd, bfd *input_bfd, enum long_section_name_h Returns TRUE upon success, FALSE otherwise. */ static bool -copy_object (bfd *ibfd, bfd *obfd, const bfd_arch_info_type *input_arch, - bool target_defaulted) +copy_object (bfd *ibfd, bfd *obfd, const bfd_arch_info_type *input_arch) { bfd_vma start; long symcount; @@ -2815,17 +2804,20 @@ copy_object (bfd *ibfd, bfd *obfd, const bfd_arch_info_type *input_arch, iarch = bed->arch; imach = 0; } + if (iarch == bfd_arch_unknown + && bfd_get_flavour (ibfd) == bfd_target_elf_flavour + && ibfd->target_defaulted) + { + non_fatal (_("Unable to recognise the architecture of the input file `%s'"), + bfd_get_archive_filename (ibfd)); + return false; + } if (!bfd_set_arch_mach (obfd, iarch, imach) - && (target_defaulted - || bfd_get_arch (ibfd) != bfd_get_arch (obfd))) + && iarch != bfd_arch_unknown) { - if (bfd_get_arch (ibfd) == bfd_arch_unknown) - non_fatal (_("Unable to recognise the format of the input file `%s'"), - bfd_get_archive_filename (ibfd)); - else - non_fatal (_("Output file cannot represent architecture `%s'"), - bfd_printable_arch_mach (bfd_get_arch (ibfd), - bfd_get_mach (ibfd))); + non_fatal (_("Output file cannot represent architecture `%s'"), + bfd_printable_arch_mach (bfd_get_arch (ibfd), + bfd_get_mach (ibfd))); return false; } @@ -3619,8 +3611,7 @@ fail: static bool copy_archive (bfd *ibfd, bfd *obfd, const char *output_target, bool force_output_target, - const bfd_arch_info_type *input_arch, - bool target_defaulted) + const bfd_arch_info_type *input_arch) { struct name_list { @@ -3690,8 +3681,6 @@ copy_archive (bfd *ibfd, bfd *obfd, const char *output_target, bool ok_object; const char *element_name; - this_element->is_strip_input = 1; - element_name = bfd_get_filename (this_element); /* PR binutils/17533: Do not allow directory traversal outside of the current directory tree by archive members. */ @@ -3748,11 +3737,7 @@ copy_archive (bfd *ibfd, bfd *obfd, const char *output_target, l->obfd = NULL; list = l; -#if BFD_SUPPORTS_PLUGINS - /* Ignore plugin target if all LTO sections should be removed. */ - if (lto_sections_removed) - this_element->plugin_format = bfd_plugin_no; -#endif + this_element->plugin_format = bfd_plugin_no; ok_object = bfd_check_format (this_element, bfd_object); /* PR binutils/3110: Cope with archives @@ -3770,18 +3755,12 @@ copy_archive (bfd *ibfd, bfd *obfd, const char *output_target, goto cleanup_and_exit; } -#if BFD_SUPPORTS_PLUGINS - /* Copy LTO IR file as unknown object. */ - if ((!lto_sections_removed - && this_element->lto_type == lto_slim_ir_object) - || bfd_plugin_target_p (this_element->xvec)) + /* Copy slim LTO IR file as unknown object. */ + if (this_element->lto_type == lto_slim_ir_object) ok_object = false; - else -#endif if (ok_object) { - ok = copy_object (this_element, output_element, input_arch, - target_defaulted); + ok = copy_object (this_element, output_element, input_arch); if (!ok && bfd_get_arch (this_element) == bfd_arch_unknown) /* Try again as an unknown object file. */ @@ -3812,7 +3791,8 @@ copy_archive (bfd *ibfd, bfd *obfd, const char *output_target, set_times (output_name, &buf); /* Open the newly created output file and attach to our list. */ - output_element = bfd_openr (output_name, output_target); + const char *targ = force_output_target ? output_target : NULL; + output_element = bfd_openr (output_name, targ); list->obfd = output_element; @@ -3869,25 +3849,6 @@ copy_archive (bfd *ibfd, bfd *obfd, const char *output_target, return ok; } -static bool -check_format_object (bfd *ibfd, char ***obj_matching, - bool no_plugins ATTRIBUTE_UNUSED) -{ -#if BFD_SUPPORTS_PLUGINS - /* Ignore plugin target first if all LTO sections should be - removed. Try with plugin target next if ignoring plugin - target fails to match the format. */ - if (no_plugins && ibfd->plugin_format == bfd_plugin_unknown) - { - ibfd->plugin_format = bfd_plugin_no; - if (bfd_check_format_matches (ibfd, bfd_object, obj_matching)) - return true; - ibfd->plugin_format = bfd_plugin_unknown; - } -#endif - return bfd_check_format_matches (ibfd, bfd_object, obj_matching); -} - /* The top-level control. */ static void @@ -3900,8 +3861,6 @@ copy_file (const char *input_filename, const char *output_filename, int ofd, char **core_matching; off_t size = get_file_size (input_filename); const char *target = input_target; - bool target_defaulted = (!input_target - || strcmp (input_target, "default") == 0); if (size < 1) { @@ -3912,18 +3871,15 @@ copy_file (const char *input_filename, const char *output_filename, int ofd, return; } -#if BFD_SUPPORTS_PLUGINS - /* Enable LTO plugin in strip. */ - if (is_strip && !target) - target = "plugin"; -#endif - /* To allow us to do "strip *" without dying on the first non-object file, failures are nonfatal. */ ibfd = bfd_openr (input_filename, target); if (ibfd == NULL || bfd_stat (ibfd, in_stat) != 0) { - bfd_nonfatal_message (input_filename, NULL, NULL, NULL); + if (bfd_get_error () == bfd_error_invalid_target && target != NULL) + bfd_nonfatal_message (target, NULL, NULL, NULL); + else + bfd_nonfatal_message (input_filename, NULL, NULL, NULL); if (ibfd != NULL) bfd_close (ibfd); status = 1; @@ -3971,7 +3927,7 @@ copy_file (const char *input_filename, const char *output_filename, int ofd, break; } - ibfd->is_strip_input = 1; + ibfd->plugin_format = bfd_plugin_no; if (bfd_check_format (ibfd, bfd_archive)) { @@ -3998,7 +3954,10 @@ copy_file (const char *input_filename, const char *output_filename, int ofd, { if (ofd >= 0) close (ofd); - bfd_nonfatal_message (output_filename, NULL, NULL, NULL); + if (force_output_target && bfd_get_error () == bfd_error_invalid_target) + bfd_nonfatal_message (output_target, NULL, NULL, NULL); + else + bfd_nonfatal_message (output_filename, NULL, NULL, NULL); bfd_close (ibfd); status = 1; return; @@ -4012,18 +3971,66 @@ copy_file (const char *input_filename, const char *output_filename, int ofd, } if (!copy_archive (ibfd, obfd, output_target, force_output_target, - input_arch, target_defaulted)) + input_arch)) status = 1; + return; } - else if (check_format_object (ibfd, &obj_matching, lto_sections_removed)) + + bool ok_plugin = false; + bool ok_object = bfd_check_format_matches (ibfd, bfd_object, &obj_matching); + bfd_error_type obj_error = bfd_get_error (); + bfd_error_type core_error = bfd_error_no_error; + if (!ok_object) + { + ok_object = bfd_check_format_matches (ibfd, bfd_core, &core_matching); + core_error = bfd_get_error (); + if (ok_object) + { + if (obj_error == bfd_error_file_ambiguously_recognized) + free (obj_matching); + obj_error = bfd_error_no_error; + } + else if (bfd_plugin_enabled ()) + { + /* This is for LLVM bytecode files, which are not ELF objects. + Since objcopy/strip does nothing with these files except + copy them whole perhaps we ought to just reject them? */ + bfd_find_target ("plugin", ibfd); + ibfd->plugin_format = bfd_plugin_unknown; + ok_plugin = bfd_check_format (ibfd, bfd_object); + } + } + + if (obj_error == bfd_error_file_ambiguously_recognized) + { + if (core_error == bfd_error_file_ambiguously_recognized) + free (core_matching); + bfd_set_error (obj_error); + status = 1; + bfd_nonfatal_message (input_filename, NULL, NULL, NULL); + list_matching_formats (obj_matching); + } + else if (core_error == bfd_error_file_ambiguously_recognized) + { + status = 1; + bfd_nonfatal_message (input_filename, NULL, NULL, NULL); + list_matching_formats (core_matching); + } + else if (!ok_object && !ok_plugin) + { + status = 1; + bfd_set_error (obj_error); + bfd_nonfatal_message (input_filename, NULL, NULL, NULL); + } + else { bfd *obfd; - do_copy: /* bfd_get_target does not return the correct value until bfd_check_format succeeds. */ - if (output_target == NULL - || strcmp (output_target, "default") == 0) + if (ok_object + && (output_target == NULL + || strcmp (output_target, "default") == 0)) output_target = bfd_get_target (ibfd); if (ofd >= 0) @@ -4035,72 +4042,39 @@ copy_file (const char *input_filename, const char *output_filename, int ofd, { if (ofd >= 0) close (ofd); - bfd_nonfatal_message (output_filename, NULL, NULL, NULL); + if (bfd_get_error () == bfd_error_invalid_target) + bfd_nonfatal_message (output_target, NULL, NULL, NULL); + else + bfd_nonfatal_message (output_filename, NULL, NULL, NULL); bfd_close (ibfd); status = 1; return; } -#if BFD_SUPPORTS_PLUGINS - if (bfd_plugin_target_p (ibfd->xvec)) - { - /* Copy LTO IR file as unknown file. */ - if (!copy_unknown_file (ibfd, obfd, in_stat->st_size, - in_stat->st_mode)) - status = 1; - else if (!bfd_close_all_done (obfd)) - status = 1; - } - else -#endif - { - if (! copy_object (ibfd, obfd, input_arch, target_defaulted)) - status = 1; - - /* PR 17512: file: 0f15796a. - If the file could not be copied it may not be in a writeable - state. So use bfd_close_all_done to avoid the possibility of - writing uninitialised data into the file. */ - if (! (status ? bfd_close_all_done (obfd) : bfd_close (obfd))) - { - status = 1; - bfd_nonfatal_message (output_filename, NULL, NULL, NULL); - } - } + /* Copy slim LTO IR file as unknown file. */ + if (ibfd->lto_type == lto_slim_ir_object) + ok_object = false; + if (ok_object + ? !copy_object (ibfd, obfd, input_arch) + : !copy_unknown_file (ibfd, obfd, + in_stat->st_size, in_stat->st_mode)) + status = 1; - if (!bfd_close (ibfd)) + /* PR 17512: file: 0f15796a. + If the file could not be copied it may not be in a writeable + state. So use bfd_close_all_done to avoid the possibility of + writing uninitialised data into the file. */ + if (!(ok_object && !status ? bfd_close : bfd_close_all_done) (obfd)) { status = 1; - bfd_nonfatal_message (input_filename, NULL, NULL, NULL); + bfd_nonfatal_message (output_filename, NULL, NULL, NULL); } } - else - { - bfd_error_type obj_error = bfd_get_error (); - bfd_error_type core_error; - - if (bfd_check_format_matches (ibfd, bfd_core, &core_matching)) - { - /* This probably can't happen.. */ - if (obj_error == bfd_error_file_ambiguously_recognized) - free (obj_matching); - goto do_copy; - } - core_error = bfd_get_error (); - /* Report the object error in preference to the core error. */ - if (obj_error != core_error) - bfd_set_error (obj_error); - - bfd_nonfatal_message (input_filename, NULL, NULL, NULL); - - if (obj_error == bfd_error_file_ambiguously_recognized) - list_matching_formats (obj_matching); - if (core_error == bfd_error_file_ambiguously_recognized) - list_matching_formats (core_matching); - - bfd_close (ibfd); + if (!bfd_close (ibfd)) + { status = 1; + bfd_nonfatal_message (input_filename, NULL, NULL, NULL); } } @@ -4924,9 +4898,7 @@ strip_main (int argc, char *argv[]) char *output_file = NULL; bool merge_notes_set = false; -#if BFD_SUPPORTS_PLUGINS bfd_plugin_set_program_name (argv[0]); -#endif while ((c = getopt_long (argc, argv, "I:O:F:K:MN:R:o:sSpdgxXHhVvwDU", strip_options, (int *) 0)) != EOF) @@ -5019,11 +4991,9 @@ strip_main (int argc, char *argv[]) keep_section_symbols = true; break; case OPTION_PLUGIN: /* --plugin */ -#if BFD_SUPPORTS_PLUGINS + if (!bfd_plugin_enabled ()) + fatal (_("sorry - this program has been built without plugin support\n")); bfd_plugin_set_plugin (optarg); -#else - fatal (_("sorry - this program has been built without plugin support\n")); -#endif break; case 0: /* We've been given a long option. */ @@ -5069,22 +5039,15 @@ strip_main (int argc, char *argv[]) if (output_target == NULL) output_target = input_target; -#if BFD_SUPPORTS_PLUGINS /* Check if all GCC LTO sections should be removed, assuming all LTO - sections will be removed with -R .gnu.lto_.*. * Remove .gnu.lto_.* - sections will also remove .gnu.debuglto_. sections. LLVM IR - bitcode is stored in .llvm.lto section which will be removed with - -R .llvm.lto. */ - lto_sections_removed = (!!find_section_list (".gnu.lto_.*", false, - SECTION_CONTEXT_REMOVE) - || !!find_section_list (".llvm.lto", false, - SECTION_CONTEXT_REMOVE)); - /* NB: Must keep .gnu.debuglto_* sections unless all GCC LTO sections + sections will be removed with -R .gnu.lto_.*. Remove .gnu.lto_.* + sections will also remove .gnu.debuglto_.* sections. + + NB: Must keep .gnu.debuglto_* sections unless all GCC LTO sections will be removed to avoid undefined references to symbols in GCC LTO debug sections. */ - if (!lto_sections_removed) + if (!find_section_list (".gnu.lto_.*", false, SECTION_CONTEXT_REMOVE)) find_section_list (".gnu.debuglto_*", true, SECTION_CONTEXT_KEEP); -#endif i = optind; if (i == argc |