X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=binutils%2Fobjcopy.c;h=28b9d3bf9291518bffe93e98aa9b9b50a8fff3e2;hb=92434a14b97bf07546701613a16aaf4d8a3b3eca;hp=8e06cd284f5a72dfed52ff73ff70b3457b326a86;hpb=508d0c9b5945d30bcf163b9b88213d277949e9a8;p=deliverable%2Fbinutils-gdb.git diff --git a/binutils/objcopy.c b/binutils/objcopy.c index 8e06cd284f..28b9d3bf92 100644 --- a/binutils/objcopy.c +++ b/binutils/objcopy.c @@ -1,5 +1,5 @@ /* objcopy.c -- copy object file from input to output, optionally massaging it. - Copyright (C) 1991-2018 Free Software Foundation, Inc. + Copyright (C) 1991-2019 Free Software Foundation, Inc. This file is part of GNU Binutils. @@ -253,6 +253,14 @@ static htab_t redefine_specific_reverse_htab = NULL; static struct addsym_node *add_sym_list = NULL, **add_sym_tail = &add_sym_list; static int add_symbols = 0; +static char *strip_specific_buffer = NULL; +static char *strip_unneeded_buffer = NULL; +static char *keep_specific_buffer = NULL; +static char *localize_specific_buffer = NULL; +static char *globalize_specific_buffer = NULL; +static char *keepglobal_specific_buffer = NULL; +static char *weaken_specific_buffer = NULL; + /* If this is TRUE, we weaken global symbols (set BSF_WEAK). */ static bfd_boolean weaken = FALSE; @@ -349,6 +357,7 @@ enum command_line_switch OPTION_STRIP_UNNEEDED_SYMBOLS, OPTION_SUBSYSTEM, OPTION_UPDATE_SECTION, + OPTION_VERILOG_DATA_WIDTH, OPTION_WEAKEN, OPTION_WEAKEN_SYMBOLS, OPTION_WRITABLE_TEXT @@ -485,6 +494,7 @@ static struct option copy_options[] = {"target", required_argument, 0, 'F'}, {"update-section", required_argument, 0, OPTION_UPDATE_SECTION}, {"verbose", no_argument, 0, 'v'}, + {"verilog-data-width", required_argument, 0, OPTION_VERILOG_DATA_WIDTH}, {"version", no_argument, 0, 'V'}, {"weaken", no_argument, 0, OPTION_WEAKEN}, {"weaken-symbol", required_argument, 0, 'W'}, @@ -511,6 +521,11 @@ extern unsigned int _bfd_srec_len; on by the --srec-forceS3 command line switch. */ extern bfd_boolean _bfd_srec_forceS3; +/* Width of data in bytes for verilog output. + This variable is declared in bfd/verilog.c and can be modified by + the --verilog-data-width parameter. */ +extern unsigned int VerilogDataWidth; + /* Forward declarations. */ static void setup_section (bfd *, asection *, void *); static void setup_bfd_headers (bfd *, bfd *); @@ -645,6 +660,7 @@ copy_usage (FILE *stream, int exit_status) --decompress-debug-sections Decompress DWARF debug sections using zlib\n\ --elf-stt-common=[yes|no] Generate ELF common symbols with STT_COMMON\n\ type\n\ + --verilog-data-width Specifies data width, in bytes, for verilog output\n\ -M --merge-notes Remove redundant entries in note sections\n\ --no-merge-notes Do not attempt to remove redundant notes (default)\n\ -v --verbose List all object files modified\n\ @@ -1034,7 +1050,7 @@ add_specific_symbol_node (const void *node, htab_t htab) #define IS_LINE_TERMINATOR(c) ((c) == '\n' || (c) == '\r' || (c) == '\0') static void -add_specific_symbols (const char *filename, htab_t htab) +add_specific_symbols (const char *filename, htab_t htab, char **buffer_p) { off_t size; FILE * f; @@ -1145,6 +1161,7 @@ add_specific_symbols (const char *filename, htab_t htab) /* Do not free the buffer. Parts of it will have been referenced in the calls to add_specific_symbol. */ + *buffer_p = buffer; } /* See whether a symbol should be stripped or kept @@ -3078,7 +3095,14 @@ copy_object (bfd *ibfd, bfd *obfd, const bfd_arch_info_type *input_arch) if (convert_debugging && dhandle != NULL) { - if (! write_debugging_info (obfd, dhandle, &symcount, &osympp)) + bfd_boolean res; + + res = write_debugging_info (obfd, dhandle, &symcount, &osympp); + + free (dhandle); + dhandle = NULL; /* Paranoia... */ + + if (! res) { status = 1; return FALSE; @@ -3260,6 +3284,27 @@ copy_archive (bfd *ibfd, bfd *obfd, const char *output_target, char *dir; const char *filename; + /* PR 24281: It is not clear what should happen when copying a thin archive. + One part is straight forward - if the output archive is in a different + directory from the input archive then any relative paths in the library + should be adjusted to the new location. But if any transformation + options are active (eg strip, rename, add, etc) then the implication is + that these should be applied to the files pointed to by the archive. + But since objcopy is not destructive, this means that new files must be + created, and there is no guidance for the names of the new files. (Plus + this conflicts with one of the goals of thin libraries - only taking up + a minimal amount of space in the file system). + + So for now we fail if an attempt is made to copy such libraries. */ + if (ibfd->is_thin_archive) + { + status = 1; + bfd_set_error (bfd_error_invalid_operation); + bfd_nonfatal_message (NULL, ibfd, NULL, + _("sorry: copying thin archives is not currently supported")); + return; + } + /* Make a temp directory to hold the contents. */ dir = make_tempdir (bfd_get_filename (obfd)); if (dir == NULL) @@ -3943,18 +3988,21 @@ discard_relocations (bfd *ibfd ATTRIBUTE_UNUSED, asection *isection) /* Wrapper for dealing with --remove-section (-R) command line arguments. A special case is detected here, if the user asks to remove a relocation - section (one starting with ".rela." or ".rel.") then this removal must + section (one starting with ".rela" or ".rel") then this removal must be done using a different technique in a relocatable object. */ static void handle_remove_section_option (const char *section_pattern) { - if (strncmp (section_pattern, ".rela.", 6) == 0) - handle_remove_relocations_option (section_pattern + 5); - else if (strncmp (section_pattern, ".rel.", 5) == 0) - handle_remove_relocations_option (section_pattern + 4); - find_section_list (section_pattern, TRUE, SECTION_CONTEXT_REMOVE); + if (strncmp (section_pattern, ".rel", 4) == 0) + { + section_pattern += 4; + if (*section_pattern == 'a') + section_pattern++; + if (*section_pattern) + handle_remove_relocations_option (section_pattern); + } sections_removed = TRUE; } @@ -4370,8 +4418,7 @@ strip_main (int argc, char *argv[]) int c; int i; char *output_file = NULL; - - merge_notes = TRUE; + bfd_boolean merge_notes_set = FALSE; while ((c = getopt_long (argc, argv, "I:O:F:K:MN:R:o:sSpdgxXHhVvwDU", strip_options, (int *) 0)) != EOF) @@ -4412,9 +4459,11 @@ strip_main (int argc, char *argv[]) break; case 'M': merge_notes = TRUE; + merge_notes_set = TRUE; break; case OPTION_NO_MERGE_NOTES: merge_notes = FALSE; + merge_notes_set = TRUE; break; case 'N': add_specific_symbol (optarg, strip_specific_htab); @@ -4466,6 +4515,16 @@ strip_main (int argc, char *argv[]) } } + /* If the user has not expressly chosen to merge/not-merge ELF notes + then enable the merging unless we are stripping debug or dwo info. */ + if (! merge_notes_set + && (strip_symbols == STRIP_UNDEF + || strip_symbols == STRIP_ALL + || strip_symbols == STRIP_UNNEEDED + || strip_symbols == STRIP_NONDEBUG + || strip_symbols == STRIP_NONDWO)) + merge_notes = TRUE; + if (formats_info) { display_info (); @@ -4741,6 +4800,8 @@ copy_main (int argc, char *argv[]) bfd_boolean show_version = FALSE; bfd_boolean change_warn = TRUE; bfd_boolean formats_info = FALSE; + bfd_boolean use_globalize = FALSE; + bfd_boolean use_keep_global = FALSE; int c; struct stat statbuf; const bfd_arch_info_type *input_arch = NULL; @@ -4859,10 +4920,12 @@ copy_main (int argc, char *argv[]) break; case OPTION_GLOBALIZE_SYMBOL: + use_globalize = TRUE; add_specific_symbol (optarg, globalize_specific_htab); break; case 'G': + use_keep_global = TRUE; add_specific_symbol (optarg, keepglobal_specific_htab); break; @@ -5259,15 +5322,18 @@ copy_main (int argc, char *argv[]) break; case OPTION_STRIP_SYMBOLS: - add_specific_symbols (optarg, strip_specific_htab); + add_specific_symbols (optarg, strip_specific_htab, + &strip_specific_buffer); break; case OPTION_STRIP_UNNEEDED_SYMBOLS: - add_specific_symbols (optarg, strip_unneeded_htab); + add_specific_symbols (optarg, strip_unneeded_htab, + &strip_unneeded_buffer); break; case OPTION_KEEP_SYMBOLS: - add_specific_symbols (optarg, keep_specific_htab); + add_specific_symbols (optarg, keep_specific_htab, + &keep_specific_buffer); break; case OPTION_LOCALIZE_HIDDEN: @@ -5275,7 +5341,8 @@ copy_main (int argc, char *argv[]) break; case OPTION_LOCALIZE_SYMBOLS: - add_specific_symbols (optarg, localize_specific_htab); + add_specific_symbols (optarg, localize_specific_htab, + &localize_specific_buffer); break; case OPTION_LONG_SECTION_NAMES: @@ -5290,15 +5357,20 @@ copy_main (int argc, char *argv[]) break; case OPTION_GLOBALIZE_SYMBOLS: - add_specific_symbols (optarg, globalize_specific_htab); + use_globalize = TRUE; + add_specific_symbols (optarg, globalize_specific_htab, + &globalize_specific_buffer); break; case OPTION_KEEPGLOBAL_SYMBOLS: - add_specific_symbols (optarg, keepglobal_specific_htab); + use_keep_global = TRUE; + add_specific_symbols (optarg, keepglobal_specific_htab, + &keepglobal_specific_buffer); break; case OPTION_WEAKEN_SYMBOLS: - add_specific_symbols (optarg, weaken_specific_htab); + add_specific_symbols (optarg, weaken_specific_htab, + &weaken_specific_buffer); break; case OPTION_ALT_MACH_CODE: @@ -5414,6 +5486,12 @@ copy_main (int argc, char *argv[]) } break; + case OPTION_VERILOG_DATA_WIDTH: + VerilogDataWidth = parse_vma (optarg, "--verilog-data-width"); + if (VerilogDataWidth < 1) + fatal (_("verilog data width must be at least 1 byte")); + break; + case 0: /* We've been given a long option. */ break; @@ -5427,6 +5505,9 @@ copy_main (int argc, char *argv[]) } } + if (use_globalize && use_keep_global) + fatal(_("--globalize-symbol(s) is incompatible with -G/--keep-global-symbol(s)")); + if (formats_info) { display_info (); @@ -5585,6 +5666,27 @@ copy_main (int argc, char *argv[]) } } + if (strip_specific_buffer) + free (strip_specific_buffer); + + if (strip_unneeded_buffer) + free (strip_unneeded_buffer); + + if (keep_specific_buffer) + free (keep_specific_buffer); + + if (localize_specific_buffer) + free (globalize_specific_buffer); + + if (globalize_specific_buffer) + free (globalize_specific_buffer); + + if (keepglobal_specific_buffer) + free (keepglobal_specific_buffer); + + if (weaken_specific_buffer) + free (weaken_specific_buffer); + return 0; } @@ -5610,7 +5712,8 @@ main (int argc, char *argv[]) strip_symbols = STRIP_UNDEF; discard_locals = LOCALS_UNDEF; - bfd_init (); + if (bfd_init () != BFD_INIT_MAGIC) + fatal (_("fatal error: libbfd ABI mismatch")); set_default_bfd_target (); if (is_strip < 0)