1 /* objcopy.c -- copy object file from input to output, optionally massaging it. 2 Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 3 2001, 2002, 2003, 2004, 2005, 2006 4 Free Software Foundation, Inc. 5 6 This file is part of GNU Binutils. 7 8 This program is free software; you can redistribute it and/or modify 9 it under the terms of the GNU General Public License as published by 10 the Free Software Foundation; either version 2 of the License, or 11 (at your option) any later version. 12 13 This program is distributed in the hope that it will be useful, 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 GNU General Public License for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with this program; if not, write to the Free Software 20 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 21 02110-1301, USA. */ 22 23 #include "bfd.h" 24 #include "progress.h" 25 #include "bucomm.h" 26 #include "getopt.h" 27 #include "libiberty.h" 28 #include "budbg.h" 29 #include "filenames.h" 30 #include "fnmatch.h" 31 #include "elf-bfd.h" 32 #include <sys/stat.h> 33 #include "libbfd.h" 34 35 /* A list of symbols to explicitly strip out, or to keep. A linked 36 list is good enough for a small number from the command line, but 37 this will slow things down a lot if many symbols are being 38 deleted. */ 39 40 struct symlist 41 { 42 const char *name; 43 struct symlist *next; 44 }; 45 46 /* A list to support redefine_sym. */ 47 struct redefine_node 48 { 49 char *source; 50 char *target; 51 struct redefine_node *next; 52 }; 53 54 typedef struct section_rename 55 { 56 const char * old_name; 57 const char * new_name; 58 flagword flags; 59 struct section_rename * next; 60 } 61 section_rename; 62 63 /* List of sections to be renamed. */ 64 static section_rename *section_rename_list; 65 66 #define RETURN_NONFATAL(s) {bfd_nonfatal (s); status = 1; return;} 67 68 static asymbol **isympp = NULL; /* Input symbols. */ 69 static asymbol **osympp = NULL; /* Output symbols that survive stripping. */ 70 71 /* If `copy_byte' >= 0, copy only that byte of every `interleave' bytes. */ 72 static int copy_byte = -1; 73 static int interleave = 4; 74 75 static bfd_boolean verbose; /* Print file and target names. */ 76 static bfd_boolean preserve_dates; /* Preserve input file timestamp. */ 77 static int status = 0; /* Exit status. */ 78 79 enum strip_action 80 { 81 STRIP_UNDEF, 82 STRIP_NONE, /* Don't strip. */ 83 STRIP_DEBUG, /* Strip all debugger symbols. */ 84 STRIP_UNNEEDED, /* Strip unnecessary symbols. */ 85 STRIP_NONDEBUG, /* Strip everything but debug info. */ 86 STRIP_ALL /* Strip all symbols. */ 87 }; 88 89 /* Which symbols to remove. */ 90 static enum strip_action strip_symbols; 91 92 enum locals_action 93 { 94 LOCALS_UNDEF, 95 LOCALS_START_L, /* Discard locals starting with L. */ 96 LOCALS_ALL /* Discard all locals. */ 97 }; 98 99 /* Which local symbols to remove. Overrides STRIP_ALL. */ 100 static enum locals_action discard_locals; 101 102 /* What kind of change to perform. */ 103 enum change_action 104 { 105 CHANGE_IGNORE, 106 CHANGE_MODIFY, 107 CHANGE_SET 108 }; 109 110 /* Structure used to hold lists of sections and actions to take. */ 111 struct section_list 112 { 113 struct section_list * next; /* Next section to change. */ 114 const char * name; /* Section name. */ 115 bfd_boolean used; /* Whether this entry was used. */ 116 bfd_boolean remove; /* Whether to remove this section. */ 117 bfd_boolean copy; /* Whether to copy this section. */ 118 enum change_action change_vma;/* Whether to change or set VMA. */ 119 bfd_vma vma_val; /* Amount to change by or set to. */ 120 enum change_action change_lma;/* Whether to change or set LMA. */ 121 bfd_vma lma_val; /* Amount to change by or set to. */ 122 bfd_boolean set_flags; /* Whether to set the section flags. */ 123 flagword flags; /* What to set the section flags to. */ 124 }; 125 126 static struct section_list *change_sections; 127 128 /* TRUE if some sections are to be removed. */ 129 static bfd_boolean sections_removed; 130 131 /* TRUE if only some sections are to be copied. */ 132 static bfd_boolean sections_copied; 133 134 /* Changes to the start address. */ 135 static bfd_vma change_start = 0; 136 static bfd_boolean set_start_set = FALSE; 137 static bfd_vma set_start; 138 139 /* Changes to section addresses. */ 140 static bfd_vma change_section_address = 0; 141 142 /* Filling gaps between sections. */ 143 static bfd_boolean gap_fill_set = FALSE; 144 static bfd_byte gap_fill = 0; 145 146 /* Pad to a given address. */ 147 static bfd_boolean pad_to_set = FALSE; 148 static bfd_vma pad_to; 149 150 /* Use alternative machine code? */ 151 static unsigned long use_alt_mach_code = 0; 152 153 /* Output BFD flags user wants to set or clear */ 154 static flagword bfd_flags_to_set; 155 static flagword bfd_flags_to_clear; 156 157 /* List of sections to add. */ 158 struct section_add 159 { 160 /* Next section to add. */ 161 struct section_add *next; 162 /* Name of section to add. */ 163 const char *name; 164 /* Name of file holding section contents. */ 165 const char *filename; 166 /* Size of file. */ 167 size_t size; 168 /* Contents of file. */ 169 bfd_byte *contents; 170 /* BFD section, after it has been added. */ 171 asection *section; 172 }; 173 174 /* List of sections to add to the output BFD. */ 175 static struct section_add *add_sections; 176 177 /* If non-NULL the argument to --add-gnu-debuglink. 178 This should be the filename to store in the .gnu_debuglink section. */ 179 static const char * gnu_debuglink_filename = NULL; 180 181 /* Whether to convert debugging information. */ 182 static bfd_boolean convert_debugging = FALSE; 183 184 /* Whether to change the leading character in symbol names. */ 185 static bfd_boolean change_leading_char = FALSE; 186 187 /* Whether to remove the leading character from global symbol names. */ 188 static bfd_boolean remove_leading_char = FALSE; 189 190 /* Whether to permit wildcard in symbol comparison. */ 191 static bfd_boolean wildcard = FALSE; 192 193 /* List of symbols to strip, keep, localize, keep-global, weaken, 194 or redefine. */ 195 static struct symlist *strip_specific_list = NULL; 196 static struct symlist *strip_unneeded_list = NULL; 197 static struct symlist *keep_specific_list = NULL; 198 static struct symlist *localize_specific_list = NULL; 199 static struct symlist *globalize_specific_list = NULL; 200 static struct symlist *keepglobal_specific_list = NULL; 201 static struct symlist *weaken_specific_list = NULL; 202 static struct redefine_node *redefine_sym_list = NULL; 203 204 /* If this is TRUE, we weaken global symbols (set BSF_WEAK). */ 205 static bfd_boolean weaken = FALSE; 206 207 /* If this is TRUE, we retain BSF_FILE symbols. */ 208 static bfd_boolean keep_file_symbols = FALSE; 209 210 /* Prefix symbols/sections. */ 211 static char *prefix_symbols_string = 0; 212 static char *prefix_sections_string = 0; 213 static char *prefix_alloc_sections_string = 0; 214 215 /* 150 isn't special; it's just an arbitrary non-ASCII char value. */ 216 enum command_line_switch 217 { 218 OPTION_ADD_SECTION=150, 219 OPTION_CHANGE_ADDRESSES, 220 OPTION_CHANGE_LEADING_CHAR, 221 OPTION_CHANGE_START, 222 OPTION_CHANGE_SECTION_ADDRESS, 223 OPTION_CHANGE_SECTION_LMA, 224 OPTION_CHANGE_SECTION_VMA, 225 OPTION_CHANGE_WARNINGS, 226 OPTION_DEBUGGING, 227 OPTION_GAP_FILL, 228 OPTION_NO_CHANGE_WARNINGS, 229 OPTION_PAD_TO, 230 OPTION_REMOVE_LEADING_CHAR, 231 OPTION_SET_SECTION_FLAGS, 232 OPTION_SET_START, 233 OPTION_STRIP_UNNEEDED, 234 OPTION_WEAKEN, 235 OPTION_REDEFINE_SYM, 236 OPTION_REDEFINE_SYMS, 237 OPTION_SREC_LEN, 238 OPTION_SREC_FORCES3, 239 OPTION_STRIP_SYMBOLS, 240 OPTION_STRIP_UNNEEDED_SYMBOL, 241 OPTION_STRIP_UNNEEDED_SYMBOLS, 242 OPTION_KEEP_SYMBOLS, 243 OPTION_LOCALIZE_SYMBOLS, 244 OPTION_GLOBALIZE_SYMBOL, 245 OPTION_GLOBALIZE_SYMBOLS, 246 OPTION_KEEPGLOBAL_SYMBOLS, 247 OPTION_WEAKEN_SYMBOLS, 248 OPTION_RENAME_SECTION, 249 OPTION_ALT_MACH_CODE, 250 OPTION_PREFIX_SYMBOLS, 251 OPTION_PREFIX_SECTIONS, 252 OPTION_PREFIX_ALLOC_SECTIONS, 253 OPTION_FORMATS_INFO, 254 OPTION_ADD_GNU_DEBUGLINK, 255 OPTION_ONLY_KEEP_DEBUG, 256 OPTION_KEEP_FILE_SYMBOLS, 257 OPTION_READONLY_TEXT, 258 OPTION_WRITABLE_TEXT, 259 OPTION_PURE, 260 OPTION_IMPURE 261 }; 262 263 /* Options to handle if running as "strip". */ 264 265 static struct option strip_options[] = 266 { 267 {"discard-all", no_argument, 0, 'x'}, 268 {"discard-locals", no_argument, 0, 'X'}, 269 {"format", required_argument, 0, 'F'}, /* Obsolete */ 270 {"help", no_argument, 0, 'h'}, 271 {"info", no_argument, 0, OPTION_FORMATS_INFO}, 272 {"input-format", required_argument, 0, 'I'}, /* Obsolete */ 273 {"input-target", required_argument, 0, 'I'}, 274 {"keep-file-symbols", no_argument, 0, OPTION_KEEP_FILE_SYMBOLS}, 275 {"keep-symbol", required_argument, 0, 'K'}, 276 {"only-keep-debug", no_argument, 0, OPTION_ONLY_KEEP_DEBUG}, 277 {"output-format", required_argument, 0, 'O'}, /* Obsolete */ 278 {"output-target", required_argument, 0, 'O'}, 279 {"output-file", required_argument, 0, 'o'}, 280 {"preserve-dates", no_argument, 0, 'p'}, 281 {"remove-section", required_argument, 0, 'R'}, 282 {"strip-all", no_argument, 0, 's'}, 283 {"strip-debug", no_argument, 0, 'S'}, 284 {"strip-unneeded", no_argument, 0, OPTION_STRIP_UNNEEDED}, 285 {"strip-symbol", required_argument, 0, 'N'}, 286 {"target", required_argument, 0, 'F'}, 287 {"verbose", no_argument, 0, 'v'}, 288 {"version", no_argument, 0, 'V'}, 289 {"wildcard", no_argument, 0, 'w'}, 290 {0, no_argument, 0, 0} 291 }; 292 293 /* Options to handle if running as "objcopy". */ 294 295 static struct option copy_options[] = 296 { 297 {"add-gnu-debuglink", required_argument, 0, OPTION_ADD_GNU_DEBUGLINK}, 298 {"add-section", required_argument, 0, OPTION_ADD_SECTION}, 299 {"adjust-start", required_argument, 0, OPTION_CHANGE_START}, 300 {"adjust-vma", required_argument, 0, OPTION_CHANGE_ADDRESSES}, 301 {"adjust-section-vma", required_argument, 0, OPTION_CHANGE_SECTION_ADDRESS}, 302 {"adjust-warnings", no_argument, 0, OPTION_CHANGE_WARNINGS}, 303 {"alt-machine-code", required_argument, 0, OPTION_ALT_MACH_CODE}, 304 {"binary-architecture", required_argument, 0, 'B'}, 305 {"byte", required_argument, 0, 'b'}, 306 {"change-addresses", required_argument, 0, OPTION_CHANGE_ADDRESSES}, 307 {"change-leading-char", no_argument, 0, OPTION_CHANGE_LEADING_CHAR}, 308 {"change-section-address", required_argument, 0, OPTION_CHANGE_SECTION_ADDRESS}, 309 {"change-section-lma", required_argument, 0, OPTION_CHANGE_SECTION_LMA}, 310 {"change-section-vma", required_argument, 0, OPTION_CHANGE_SECTION_VMA}, 311 {"change-start", required_argument, 0, OPTION_CHANGE_START}, 312 {"change-warnings", no_argument, 0, OPTION_CHANGE_WARNINGS}, 313 {"debugging", no_argument, 0, OPTION_DEBUGGING}, 314 {"discard-all", no_argument, 0, 'x'}, 315 {"discard-locals", no_argument, 0, 'X'}, 316 {"format", required_argument, 0, 'F'}, /* Obsolete */ 317 {"gap-fill", required_argument, 0, OPTION_GAP_FILL}, 318 {"globalize-symbol", required_argument, 0, OPTION_GLOBALIZE_SYMBOL}, 319 {"globalize-symbols", required_argument, 0, OPTION_GLOBALIZE_SYMBOLS}, 320 {"help", no_argument, 0, 'h'}, 321 {"impure", no_argument, 0, OPTION_IMPURE}, 322 {"info", no_argument, 0, OPTION_FORMATS_INFO}, 323 {"input-format", required_argument, 0, 'I'}, /* Obsolete */ 324 {"input-target", required_argument, 0, 'I'}, 325 {"interleave", required_argument, 0, 'i'}, 326 {"keep-file-symbols", no_argument, 0, OPTION_KEEP_FILE_SYMBOLS}, 327 {"keep-global-symbol", required_argument, 0, 'G'}, 328 {"keep-global-symbols", required_argument, 0, OPTION_KEEPGLOBAL_SYMBOLS}, 329 {"keep-symbol", required_argument, 0, 'K'}, 330 {"keep-symbols", required_argument, 0, OPTION_KEEP_SYMBOLS}, 331 {"localize-symbol", required_argument, 0, 'L'}, 332 {"localize-symbols", required_argument, 0, OPTION_LOCALIZE_SYMBOLS}, 333 {"no-adjust-warnings", no_argument, 0, OPTION_NO_CHANGE_WARNINGS}, 334 {"no-change-warnings", no_argument, 0, OPTION_NO_CHANGE_WARNINGS}, 335 {"only-keep-debug", no_argument, 0, OPTION_ONLY_KEEP_DEBUG}, 336 {"only-section", required_argument, 0, 'j'}, 337 {"output-format", required_argument, 0, 'O'}, /* Obsolete */ 338 {"output-target", required_argument, 0, 'O'}, 339 {"pad-to", required_argument, 0, OPTION_PAD_TO}, 340 {"prefix-symbols", required_argument, 0, OPTION_PREFIX_SYMBOLS}, 341 {"prefix-sections", required_argument, 0, OPTION_PREFIX_SECTIONS}, 342 {"prefix-alloc-sections", required_argument, 0, OPTION_PREFIX_ALLOC_SECTIONS}, 343 {"preserve-dates", no_argument, 0, 'p'}, 344 {"pure", no_argument, 0, OPTION_PURE}, 345 {"readonly-text", no_argument, 0, OPTION_READONLY_TEXT}, 346 {"redefine-sym", required_argument, 0, OPTION_REDEFINE_SYM}, 347 {"redefine-syms", required_argument, 0, OPTION_REDEFINE_SYMS}, 348 {"remove-leading-char", no_argument, 0, OPTION_REMOVE_LEADING_CHAR}, 349 {"remove-section", required_argument, 0, 'R'}, 350 {"rename-section", required_argument, 0, OPTION_RENAME_SECTION}, 351 {"set-section-flags", required_argument, 0, OPTION_SET_SECTION_FLAGS}, 352 {"set-start", required_argument, 0, OPTION_SET_START}, 353 {"srec-len", required_argument, 0, OPTION_SREC_LEN}, 354 {"srec-forceS3", no_argument, 0, OPTION_SREC_FORCES3}, 355 {"strip-all", no_argument, 0, 'S'}, 356 {"strip-debug", no_argument, 0, 'g'}, 357 {"strip-unneeded", no_argument, 0, OPTION_STRIP_UNNEEDED}, 358 {"strip-unneeded-symbol", required_argument, 0, OPTION_STRIP_UNNEEDED_SYMBOL}, 359 {"strip-unneeded-symbols", required_argument, 0, OPTION_STRIP_UNNEEDED_SYMBOLS}, 360 {"strip-symbol", required_argument, 0, 'N'}, 361 {"strip-symbols", required_argument, 0, OPTION_STRIP_SYMBOLS}, 362 {"target", required_argument, 0, 'F'}, 363 {"verbose", no_argument, 0, 'v'}, 364 {"version", no_argument, 0, 'V'}, 365 {"weaken", no_argument, 0, OPTION_WEAKEN}, 366 {"weaken-symbol", required_argument, 0, 'W'}, 367 {"weaken-symbols", required_argument, 0, OPTION_WEAKEN_SYMBOLS}, 368 {"wildcard", no_argument, 0, 'w'}, 369 {"writable-text", no_argument, 0, OPTION_WRITABLE_TEXT}, 370 {0, no_argument, 0, 0} 371 }; 372 373 /* IMPORTS */ 374 extern char *program_name; 375 376 /* This flag distinguishes between strip and objcopy: 377 1 means this is 'strip'; 0 means this is 'objcopy'. 378 -1 means if we should use argv[0] to decide. */ 379 extern int is_strip; 380 381 /* The maximum length of an S record. This variable is declared in srec.c 382 and can be modified by the --srec-len parameter. */ 383 extern unsigned int Chunk; 384 385 /* Restrict the generation of Srecords to type S3 only. 386 This variable is declare in bfd/srec.c and can be toggled 387 on by the --srec-forceS3 command line switch. */ 388 extern bfd_boolean S3Forced; 389 390 /* Defined in bfd/binary.c. Used to set architecture and machine of input 391 binary files. */ 392 extern enum bfd_architecture bfd_external_binary_architecture; 393 extern unsigned long bfd_external_machine; 394 395 /* Forward declarations. */ 396 static void setup_section (bfd *, asection *, void *); 397 static void setup_bfd_headers (bfd *, bfd *); 398 static void copy_section (bfd *, asection *, void *); 399 static void get_sections (bfd *, asection *, void *); 400 static int compare_section_lma (const void *, const void *); 401 static void mark_symbols_used_in_relocations (bfd *, asection *, void *); 402 static bfd_boolean write_debugging_info (bfd *, void *, long *, asymbol ***); 403 static const char *lookup_sym_redefinition (const char *); 404 405 static void 406 copy_usage (FILE *stream, int exit_status) 407 { 408 fprintf (stream, _("Usage: %s [option(s)] in-file [out-file]\n"), program_name); 409 fprintf (stream, _(" Copies a binary file, possibly transforming it in the process\n")); 410 fprintf (stream, _(" The options are:\n")); 411 fprintf (stream, _("\ 412 -I --input-target <bfdname> Assume input file is in format <bfdname>\n\ 413 -O --output-target <bfdname> Create an output file in format <bfdname>\n\ 414 -B --binary-architecture <arch> Set arch of output file, when input is binary\n\ 415 -F --target <bfdname> Set both input and output format to <bfdname>\n\ 416 --debugging Convert debugging information, if possible\n\ 417 -p --preserve-dates Copy modified/access timestamps to the output\n\ 418 -j --only-section <name> Only copy section <name> into the output\n\ 419 --add-gnu-debuglink=<file> Add section .gnu_debuglink linking to <file>\n\ 420 -R --remove-section <name> Remove section <name> from the output\n\ 421 -S --strip-all Remove all symbol and relocation information\n\ 422 -g --strip-debug Remove all debugging symbols & sections\n\ 423 --strip-unneeded Remove all symbols not needed by relocations\n\ 424 -N --strip-symbol <name> Do not copy symbol <name>\n\ 425 --strip-unneeded-symbol <name>\n\ 426 Do not copy symbol <name> unless needed by\n\ 427 relocations\n\ 428 --only-keep-debug Strip everything but the debug information\n\ 429 -K --keep-symbol <name> Do not strip symbol <name>\n\ 430 --keep-file-symbols Do not strip file symbol(s)\n\ 431 -L --localize-symbol <name> Force symbol <name> to be marked as a local\n\ 432 --globalize-symbol <name> Force symbol <name> to be marked as a global\n\ 433 -G --keep-global-symbol <name> Localize all symbols except <name>\n\ 434 -W --weaken-symbol <name> Force symbol <name> to be marked as a weak\n\ 435 --weaken Force all global symbols to be marked as weak\n\ 436 -w --wildcard Permit wildcard in symbol comparison\n\ 437 -x --discard-all Remove all non-global symbols\n\ 438 -X --discard-locals Remove any compiler-generated symbols\n\ 439 -i --interleave <number> Only copy one out of every <number> bytes\n\ 440 -b --byte <num> Select byte <num> in every interleaved block\n\ 441 --gap-fill <val> Fill gaps between sections with <val>\n\ 442 --pad-to <addr> Pad the last section up to address <addr>\n\ 443 --set-start <addr> Set the start address to <addr>\n\ 444 {--change-start|--adjust-start} <incr>\n\ 445 Add <incr> to the start address\n\ 446 {--change-addresses|--adjust-vma} <incr>\n\ 447 Add <incr> to LMA, VMA and start addresses\n\ 448 {--change-section-address|--adjust-section-vma} <name>{=|+|-}<val>\n\ 449 Change LMA and VMA of section <name> by <val>\n\ 450 --change-section-lma <name>{=|+|-}<val>\n\ 451 Change the LMA of section <name> by <val>\n\ 452 --change-section-vma <name>{=|+|-}<val>\n\ 453 Change the VMA of section <name> by <val>\n\ 454 {--[no-]change-warnings|--[no-]adjust-warnings}\n\ 455 Warn if a named section does not exist\n\ 456 --set-section-flags <name>=<flags>\n\ 457 Set section <name>'s properties to <flags>\n\ 458 --add-section <name>=<file> Add section <name> found in <file> to output\n\ 459 --rename-section <old>=<new>[,<flags>] Rename section <old> to <new>\n\ 460 --change-leading-char Force output format's leading character style\n\ 461 --remove-leading-char Remove leading character from global symbols\n\ 462 --redefine-sym <old>=<new> Redefine symbol name <old> to <new>\n\ 463 --redefine-syms <file> --redefine-sym for all symbol pairs \n\ 464 listed in <file>\n\ 465 --srec-len <number> Restrict the length of generated Srecords\n\ 466 --srec-forceS3 Restrict the type of generated Srecords to S3\n\ 467 --strip-symbols <file> -N for all symbols listed in <file>\n\ 468 --strip-unneeded-symbols <file>\n\ 469 --strip-unneeded-symbol for all symbols listed\n\ 470 in <file>\n\ 471 --keep-symbols <file> -K for all symbols listed in <file>\n\ 472 --localize-symbols <file> -L for all symbols listed in <file>\n\ 473 --globalize-symbols <file> --globalize-symbol for all in <file>\n\ 474 --keep-global-symbols <file> -G for all symbols listed in <file>\n\ 475 --weaken-symbols <file> -W for all symbols listed in <file>\n\ 476 --alt-machine-code <index> Use the target's <index>'th alternative machine\n\ 477 --writable-text Mark the output text as writable\n\ 478 --readonly-text Make the output text write protected\n\ 479 --pure Mark the output file as demand paged\n\ 480 --impure Mark the output file as impure\n\ 481 --prefix-symbols <prefix> Add <prefix> to start of every symbol name\n\ 482 --prefix-sections <prefix> Add <prefix> to start of every section name\n\ 483 --prefix-alloc-sections <prefix>\n\ 484 Add <prefix> to start of every allocatable\n\ 485 section name\n\ 486 -v --verbose List all object files modified\n\ 487 @<file> Read options from <file>\n\ 488 -V --version Display this program's version number\n\ 489 -h --help Display this output\n\ 490 --info List object formats & architectures supported\n\ 491 ")); 492 list_supported_targets (program_name, stream); 493 if (exit_status == 0) 494 fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO); 495 exit (exit_status); 496 } 497 498 static void 499 strip_usage (FILE *stream, int exit_status) 500 { 501 fprintf (stream, _("Usage: %s <option(s)> in-file(s)\n"), program_name); 502 fprintf (stream, _(" Removes symbols and sections from files\n")); 503 fprintf (stream, _(" The options are:\n")); 504 fprintf (stream, _("\ 505 -I --input-target=<bfdname> Assume input file is in format <bfdname>\n\ 506 -O --output-target=<bfdname> Create an output file in format <bfdname>\n\ 507 -F --target=<bfdname> Set both input and output format to <bfdname>\n\ 508 -p --preserve-dates Copy modified/access timestamps to the output\n\ 509 -R --remove-section=<name> Remove section <name> from the output\n\ 510 -s --strip-all Remove all symbol and relocation information\n\ 511 -g -S -d --strip-debug Remove all debugging symbols & sections\n\ 512 --strip-unneeded Remove all symbols not needed by relocations\n\ 513 --only-keep-debug Strip everything but the debug information\n\ 514 -N --strip-symbol=<name> Do not copy symbol <name>\n\ 515 -K --keep-symbol=<name> Do not strip symbol <name>\n\ 516 --keep-file-symbols Do not strip file symbol(s)\n\ 517 -w --wildcard Permit wildcard in symbol comparison\n\ 518 -x --discard-all Remove all non-global symbols\n\ 519 -X --discard-locals Remove any compiler-generated symbols\n\ 520 -v --verbose List all object files modified\n\ 521 -V --version Display this program's version number\n\ 522 -h --help Display this output\n\ 523 --info List object formats & architectures supported\n\ 524 -o <file> Place stripped output into <file>\n\ 525 ")); 526 527 list_supported_targets (program_name, stream); 528 if (exit_status == 0) 529 fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO); 530 exit (exit_status); 531 } 532 533 /* Parse section flags into a flagword, with a fatal error if the 534 string can't be parsed. */ 535 536 static flagword 537 parse_flags (const char *s) 538 { 539 flagword ret; 540 const char *snext; 541 int len; 542 543 ret = SEC_NO_FLAGS; 544 545 do 546 { 547 snext = strchr (s, ','); 548 if (snext == NULL) 549 len = strlen (s); 550 else 551 { 552 len = snext - s; 553 ++snext; 554 } 555 556 if (0) ; 557 #define PARSE_FLAG(fname,fval) \ 558 else if (strncasecmp (fname, s, len) == 0) ret |= fval 559 PARSE_FLAG ("alloc", SEC_ALLOC); 560 PARSE_FLAG ("load", SEC_LOAD); 561 PARSE_FLAG ("noload", SEC_NEVER_LOAD); 562 PARSE_FLAG ("readonly", SEC_READONLY); 563 PARSE_FLAG ("debug", SEC_DEBUGGING); 564 PARSE_FLAG ("code", SEC_CODE); 565 PARSE_FLAG ("data", SEC_DATA); 566 PARSE_FLAG ("rom", SEC_ROM); 567 PARSE_FLAG ("share", SEC_COFF_SHARED); 568 PARSE_FLAG ("contents", SEC_HAS_CONTENTS); 569 #undef PARSE_FLAG 570 else 571 { 572 char *copy; 573 574 copy = xmalloc (len + 1); 575 strncpy (copy, s, len); 576 copy[len] = '\0'; 577 non_fatal (_("unrecognized section flag `%s'"), copy); 578 fatal (_("supported flags: %s"), 579 "alloc, load, noload, readonly, debug, code, data, rom, share, contents"); 580 } 581 582 s = snext; 583 } 584 while (s != NULL); 585 586 return ret; 587 } 588 589 /* Find and optionally add an entry in the change_sections list. */ 590 591 static struct section_list * 592 find_section_list (const char *name, bfd_boolean add) 593 { 594 struct section_list *p; 595 596 for (p = change_sections; p != NULL; p = p->next) 597 if (strcmp (p->name, name) == 0) 598 return p; 599 600 if (! add) 601 return NULL; 602 603 p = xmalloc (sizeof (struct section_list)); 604 p->name = name; 605 p->used = FALSE; 606 p->remove = FALSE; 607 p->copy = FALSE; 608 p->change_vma = CHANGE_IGNORE; 609 p->change_lma = CHANGE_IGNORE; 610 p->vma_val = 0; 611 p->lma_val = 0; 612 p->set_flags = FALSE; 613 p->flags = 0; 614 615 p->next = change_sections; 616 change_sections = p; 617 618 return p; 619 } 620 621 /* Add a symbol to strip_specific_list. */ 622 623 static void 624 add_specific_symbol (const char *name, struct symlist **list) 625 { 626 struct symlist *tmp_list; 627 628 tmp_list = xmalloc (sizeof (struct symlist)); 629 tmp_list->name = name; 630 tmp_list->next = *list; 631 *list = tmp_list; 632 } 633 634 /* Add symbols listed in `filename' to strip_specific_list. */ 635 636 #define IS_WHITESPACE(c) ((c) == ' ' || (c) == '\t') 637 #define IS_LINE_TERMINATOR(c) ((c) == '\n' || (c) == '\r' || (c) == '\0') 638 639 static void 640 add_specific_symbols (const char *filename, struct symlist **list) 641 { 642 off_t size; 643 FILE * f; 644 char * line; 645 char * buffer; 646 unsigned int line_count; 647 648 size = get_file_size (filename); 649 if (size == 0) 650 return; 651 652 buffer = xmalloc (size + 2); 653 f = fopen (filename, FOPEN_RT); 654 if (f == NULL) 655 fatal (_("cannot open '%s': %s"), filename, strerror (errno)); 656 657 if (fread (buffer, 1, size, f) == 0 || ferror (f)) 658 fatal (_("%s: fread failed"), filename); 659 660 fclose (f); 661 buffer [size] = '\n'; 662 buffer [size + 1] = '\0'; 663 664 line_count = 1; 665 666 for (line = buffer; * line != '\0'; line ++) 667 { 668 char * eol; 669 char * name; 670 char * name_end; 671 int finished = FALSE; 672 673 for (eol = line;; eol ++) 674 { 675 switch (* eol) 676 { 677 case '\n': 678 * eol = '\0'; 679 /* Cope with \n\r. */ 680 if (eol[1] == '\r') 681 ++ eol; 682 finished = TRUE; 683 break; 684 685 case '\r': 686 * eol = '\0'; 687 /* Cope with \r\n. */ 688 if (eol[1] == '\n') 689 ++ eol; 690 finished = TRUE; 691 break; 692 693 case 0: 694 finished = TRUE; 695 break; 696 697 case '#': 698 /* Line comment, Terminate the line here, in case a 699 name is present and then allow the rest of the 700 loop to find the real end of the line. */ 701 * eol = '\0'; 702 break; 703 704 default: 705 break; 706 } 707 708 if (finished) 709 break; 710 } 711 712 /* A name may now exist somewhere between 'line' and 'eol'. 713 Strip off leading whitespace and trailing whitespace, 714 then add it to the list. */ 715 for (name = line; IS_WHITESPACE (* name); name ++) 716 ; 717 for (name_end = name; 718 (! IS_WHITESPACE (* name_end)) 719 && (! IS_LINE_TERMINATOR (* name_end)); 720 name_end ++) 721 ; 722 723 if (! IS_LINE_TERMINATOR (* name_end)) 724 { 725 char * extra; 726 727 for (extra = name_end + 1; IS_WHITESPACE (* extra); extra ++) 728 ; 729 730 if (! IS_LINE_TERMINATOR (* extra)) 731 non_fatal (_("%s:%d: Ignoring rubbish found on this line"), 732 filename, line_count); 733 } 734 735 * name_end = '\0'; 736 737 if (name_end > name) 738 add_specific_symbol (name, list); 739 740 /* Advance line pointer to end of line. The 'eol ++' in the for 741 loop above will then advance us to the start of the next line. */ 742 line = eol; 743 line_count ++; 744 } 745 } 746 747 /* See whether a symbol should be stripped or kept based on 748 strip_specific_list and keep_symbols. */ 749 750 static bfd_boolean 751 is_specified_symbol (const char *name, struct symlist *list) 752 { 753 struct symlist *tmp_list; 754 755 if (wildcard) 756 { 757 for (tmp_list = list; tmp_list; tmp_list = tmp_list->next) 758 if (*(tmp_list->name) != '!') 759 { 760 if (!fnmatch (tmp_list->name, name, 0)) 761 return TRUE; 762 } 763 else 764 { 765 if (fnmatch (tmp_list->name + 1, name, 0)) 766 return TRUE; 767 } 768 } 769 else 770 { 771 for (tmp_list = list; tmp_list; tmp_list = tmp_list->next) 772 if (strcmp (name, tmp_list->name) == 0) 773 return TRUE; 774 } 775 776 return FALSE; 777 } 778 779 /* See if a section is being removed. */ 780 781 static bfd_boolean 782 is_strip_section (bfd *abfd ATTRIBUTE_UNUSED, asection *sec) 783 { 784 if (sections_removed || sections_copied) 785 { 786 struct section_list *p; 787 788 p = find_section_list (bfd_get_section_name (abfd, sec), FALSE); 789 790 if (sections_removed && p != NULL && p->remove) 791 return TRUE; 792 if (sections_copied && (p == NULL || ! p->copy)) 793 return TRUE; 794 } 795 796 if ((bfd_get_section_flags (abfd, sec) & SEC_DEBUGGING) != 0) 797 { 798 if (strip_symbols == STRIP_DEBUG 799 || strip_symbols == STRIP_UNNEEDED 800 || strip_symbols == STRIP_ALL 801 || discard_locals == LOCALS_ALL 802 || convert_debugging) 803 return TRUE; 804 805 if (strip_symbols == STRIP_NONDEBUG) 806 return FALSE; 807 } 808 809 return FALSE; 810 } 811 812 /* Choose which symbol entries to copy; put the result in OSYMS. 813 We don't copy in place, because that confuses the relocs. 814 Return the number of symbols to print. */ 815 816 static unsigned int 817 filter_symbols (bfd *abfd, bfd *obfd, asymbol **osyms, 818 asymbol **isyms, long symcount) 819 { 820 asymbol **from = isyms, **to = osyms; 821 long src_count = 0, dst_count = 0; 822 int relocatable = (abfd->flags & (HAS_RELOC | EXEC_P | DYNAMIC)) 823 == HAS_RELOC; 824 825 for (; src_count < symcount; src_count++) 826 { 827 asymbol *sym = from[src_count]; 828 flagword flags = sym->flags; 829 char *name = (char *) bfd_asymbol_name (sym); 830 int keep; 831 bfd_boolean undefined; 832 bfd_boolean rem_leading_char; 833 bfd_boolean add_leading_char; 834 835 undefined = bfd_is_und_section (bfd_get_section (sym)); 836 837 if (redefine_sym_list) 838 { 839 char *old_name, *new_name; 840 841 old_name = (char *) bfd_asymbol_name (sym); 842 new_name = (char *) lookup_sym_redefinition (old_name); 843 bfd_asymbol_name (sym) = new_name; 844 name = new_name; 845 } 846 847 /* Check if we will remove the current leading character. */ 848 rem_leading_char = 849 (name[0] == bfd_get_symbol_leading_char (abfd)) 850 && (change_leading_char 851 || (remove_leading_char 852 && ((flags & (BSF_GLOBAL | BSF_WEAK)) != 0 853 || undefined 854 || bfd_is_com_section (bfd_get_section (sym))))); 855 856 /* Check if we will add a new leading character. */ 857 add_leading_char = 858 change_leading_char 859 && (bfd_get_symbol_leading_char (obfd) != '\0') 860 && (bfd_get_symbol_leading_char (abfd) == '\0' 861 || (name[0] == bfd_get_symbol_leading_char (abfd))); 862 863 /* Short circuit for change_leading_char if we can do it in-place. */ 864 if (rem_leading_char && add_leading_char && !prefix_symbols_string) 865 { 866 name[0] = bfd_get_symbol_leading_char (obfd); 867 bfd_asymbol_name (sym) = name; 868 rem_leading_char = FALSE; 869 add_leading_char = FALSE; 870 } 871 872 /* Remove leading char. */ 873 if (rem_leading_char) 874 bfd_asymbol_name (sym) = ++name; 875 876 /* Add new leading char and/or prefix. */ 877 if (add_leading_char || prefix_symbols_string) 878 { 879 char *n, *ptr; 880 881 ptr = n = xmalloc (1 + strlen (prefix_symbols_string) 882 + strlen (name) + 1); 883 if (add_leading_char) 884 *ptr++ = bfd_get_symbol_leading_char (obfd); 885 886 if (prefix_symbols_string) 887 { 888 strcpy (ptr, prefix_symbols_string); 889 ptr += strlen (prefix_symbols_string); 890 } 891 892 strcpy (ptr, name); 893 bfd_asymbol_name (sym) = n; 894 name = n; 895 } 896 897 if (strip_symbols == STRIP_ALL) 898 keep = 0; 899 else if ((flags & BSF_KEEP) != 0 /* Used in relocation. */ 900 || ((flags & BSF_SECTION_SYM) != 0 901 && ((*bfd_get_section (sym)->symbol_ptr_ptr)->flags 902 & BSF_KEEP) != 0)) 903 keep = 1; 904 else if (relocatable /* Relocatable file. */ 905 && (flags & (BSF_GLOBAL | BSF_WEAK)) != 0) 906 keep = 1; 907 else if (bfd_decode_symclass (sym) == 'I') 908 /* Global symbols in $idata sections need to be retained 909 even if relocatable is FALSE. External users of the 910 library containing the $idata section may reference these 911 symbols. */ 912 keep = 1; 913 else if ((flags & BSF_GLOBAL) != 0 /* Global symbol. */ 914 || (flags & BSF_WEAK) != 0 915 || undefined 916 || bfd_is_com_section (bfd_get_section (sym))) 917 keep = strip_symbols != STRIP_UNNEEDED; 918 else if ((flags & BSF_DEBUGGING) != 0) /* Debugging symbol. */ 919 keep = (strip_symbols != STRIP_DEBUG 920 && strip_symbols != STRIP_UNNEEDED 921 && ! convert_debugging); 922 else if (bfd_coff_get_comdat_section (abfd, bfd_get_section (sym))) 923 /* COMDAT sections store special information in local 924 symbols, so we cannot risk stripping any of them. */ 925 keep = 1; 926 else /* Local symbol. */ 927 keep = (strip_symbols != STRIP_UNNEEDED 928 && (discard_locals != LOCALS_ALL 929 && (discard_locals != LOCALS_START_L 930 || ! bfd_is_local_label (abfd, sym)))); 931 932 if (keep && is_specified_symbol (name, strip_specific_list)) 933 keep = 0; 934 if (keep 935 && !(flags & BSF_KEEP) 936 && is_specified_symbol (name, strip_unneeded_list)) 937 keep = 0; 938 if (!keep 939 && ((keep_file_symbols && (flags & BSF_FILE)) 940 || is_specified_symbol (name, keep_specific_list))) 941 keep = 1; 942 if (keep && is_strip_section (abfd, bfd_get_section (sym))) 943 keep = 0; 944 945 if (keep) 946 { 947 if ((flags & BSF_GLOBAL) != 0 948 && (weaken || is_specified_symbol (name, weaken_specific_list))) 949 { 950 sym->flags &= ~ BSF_GLOBAL; 951 sym->flags |= BSF_WEAK; 952 } 953 954 if (!undefined 955 && (flags & (BSF_GLOBAL | BSF_WEAK)) 956 && (is_specified_symbol (name, localize_specific_list) 957 || (keepglobal_specific_list != NULL 958 && ! is_specified_symbol (name, keepglobal_specific_list)))) 959 { 960 sym->flags &= ~ (BSF_GLOBAL | BSF_WEAK); 961 sym->flags |= BSF_LOCAL; 962 } 963 964 if (!undefined 965 && (flags & BSF_LOCAL) 966 && is_specified_symbol (name, globalize_specific_list)) 967 { 968 sym->flags &= ~ BSF_LOCAL; 969 sym->flags |= BSF_GLOBAL; 970 } 971 972 to[dst_count++] = sym; 973 } 974 } 975 976 to[dst_count] = NULL; 977 978 return dst_count; 979 } 980 981 /* Find the redefined name of symbol SOURCE. */ 982 983 static const char * 984 lookup_sym_redefinition (const char *source) 985 { 986 struct redefine_node *list; 987 988 for (list = redefine_sym_list; list != NULL; list = list->next) 989 if (strcmp (source, list->source) == 0) 990 return list->target; 991 992 return source; 993 } 994 995 /* Add a node to a symbol redefine list. */ 996 997 static void 998 redefine_list_append (const char *cause, const char *source, const char *target) 999 { 1000 struct redefine_node **p; 1001 struct redefine_node *list; 1002 struct redefine_node *new_node; 1003 1004 for (p = &redefine_sym_list; (list = *p) != NULL; p = &list->next) 1005 { 1006 if (strcmp (source, list->source) == 0) 1007 fatal (_("%s: Multiple redefinition of symbol \"%s\""), 1008 cause, source); 1009 1010 if (strcmp (target, list->target) == 0) 1011 fatal (_("%s: Symbol \"%s\" is target of more than one redefinition"), 1012 cause, target); 1013 } 1014 1015 new_node = xmalloc (sizeof (struct redefine_node)); 1016 1017 new_node->source = strdup (source); 1018 new_node->target = strdup (target); 1019 new_node->next = NULL; 1020 1021 *p = new_node; 1022 } 1023 1024 /* Handle the --redefine-syms option. Read lines containing "old new" 1025 from the file, and add them to the symbol redefine list. */ 1026 1027 static void 1028 add_redefine_syms_file (const char *filename) 1029 { 1030 FILE *file; 1031 char *buf; 1032 size_t bufsize; 1033 size_t len; 1034 size_t outsym_off; 1035 int c, lineno; 1036 1037 file = fopen (filename, "r"); 1038 if (file == NULL) 1039 fatal (_("couldn't open symbol redefinition file %s (error: %s)"), 1040 filename, strerror (errno)); 1041 1042 bufsize = 100; 1043 buf = xmalloc (bufsize); 1044 1045 lineno = 1; 1046 c = getc (file); 1047 len = 0; 1048 outsym_off = 0; 1049 while (c != EOF) 1050 { 1051 /* Collect the input symbol name. */ 1052 while (! IS_WHITESPACE (c) && ! IS_LINE_TERMINATOR (c) && c != EOF) 1053 { 1054 if (c == '#') 1055 goto comment; 1056 buf[len++] = c; 1057 if (len >= bufsize) 1058 { 1059 bufsize *= 2; 1060 buf = xrealloc (buf, bufsize); 1061 } 1062 c = getc (file); 1063 } 1064 buf[len++] = '\0'; 1065 if (c == EOF) 1066 break; 1067 1068 /* Eat white space between the symbol names. */ 1069 while (IS_WHITESPACE (c)) 1070 c = getc (file); 1071 if (c == '#' || IS_LINE_TERMINATOR (c)) 1072 goto comment; 1073 if (c == EOF) 1074 break; 1075 1076 /* Collect the output symbol name. */ 1077 outsym_off = len; 1078 while (! IS_WHITESPACE (c) && ! IS_LINE_TERMINATOR (c) && c != EOF) 1079 { 1080 if (c == '#') 1081 goto comment; 1082 buf[len++] = c; 1083 if (len >= bufsize) 1084 { 1085 bufsize *= 2; 1086 buf = xrealloc (buf, bufsize); 1087 } 1088 c = getc (file); 1089 } 1090 buf[len++] = '\0'; 1091 if (c == EOF) 1092 break; 1093 1094 /* Eat white space at end of line. */ 1095 while (! IS_LINE_TERMINATOR(c) && c != EOF && IS_WHITESPACE (c)) 1096 c = getc (file); 1097 if (c == '#') 1098 goto comment; 1099 /* Handle \r\n. */ 1100 if ((c == '\r' && (c = getc (file)) == '\n') 1101 || c == '\n' || c == EOF) 1102 { 1103 end_of_line: 1104 /* Append the redefinition to the list. */ 1105 if (buf[0] != '\0') 1106 redefine_list_append (filename, &buf[0], &buf[outsym_off]); 1107 1108 lineno++; 1109 len = 0; 1110 outsym_off = 0; 1111 if (c == EOF) 1112 break; 1113 c = getc (file); 1114 continue; 1115 } 1116 else 1117 fatal (_("%s:%d: garbage found at end of line"), filename, lineno); 1118 comment: 1119 if (len != 0 && (outsym_off == 0 || outsym_off == len)) 1120 fatal (_("%s:%d: missing new symbol name"), filename, lineno); 1121 buf[len++] = '\0'; 1122 1123 /* Eat the rest of the line and finish it. */ 1124 while (c != '\n' && c != EOF) 1125 c = getc (file); 1126 goto end_of_line; 1127 } 1128 1129 if (len != 0) 1130 fatal (_("%s:%d: premature end of file"), filename, lineno); 1131 1132 free (buf); 1133 } 1134 1135 /* Copy unkown object file IBFD onto OBFD. 1136 Returns TRUE upon success, FALSE otherwise. */ 1137 1138 static bfd_boolean 1139 copy_unknown_object (bfd *ibfd, bfd *obfd) 1140 { 1141 char *cbuf; 1142 int tocopy; 1143 long ncopied; 1144 long size; 1145 struct stat buf; 1146 1147 if (bfd_stat_arch_elt (ibfd, &buf) != 0) 1148 { 1149 bfd_nonfatal (bfd_get_archive_filename (ibfd)); 1150 return FALSE; 1151 } 1152 1153 size = buf.st_size; 1154 if (size < 0) 1155 { 1156 non_fatal (_("stat returns negative size for `%s'"), 1157 bfd_get_archive_filename (ibfd)); 1158 return FALSE; 1159 } 1160 1161 if (bfd_seek (ibfd, (file_ptr) 0, SEEK_SET) != 0) 1162 { 1163 bfd_nonfatal (bfd_get_archive_filename (ibfd)); 1164 return FALSE; 1165 } 1166 1167 if (verbose) 1168 printf (_("copy from `%s' [unknown] to `%s' [unknown]\n"), 1169 bfd_get_archive_filename (ibfd), bfd_get_filename (obfd)); 1170 1171 cbuf = xmalloc (BUFSIZE); 1172 ncopied = 0; 1173 while (ncopied < size) 1174 { 1175 tocopy = size - ncopied; 1176 if (tocopy > BUFSIZE) 1177 tocopy = BUFSIZE; 1178 1179 if (bfd_bread (cbuf, (bfd_size_type) tocopy, ibfd) 1180 != (bfd_size_type) tocopy) 1181 { 1182 bfd_nonfatal (bfd_get_archive_filename (ibfd)); 1183 free (cbuf); 1184 return FALSE; 1185 } 1186 1187 if (bfd_bwrite (cbuf, (bfd_size_type) tocopy, obfd) 1188 != (bfd_size_type) tocopy) 1189 { 1190 bfd_nonfatal (bfd_get_filename (obfd)); 1191 free (cbuf); 1192 return FALSE; 1193 } 1194 1195 ncopied += tocopy; 1196 } 1197 1198 chmod (bfd_get_filename (obfd), buf.st_mode & 0777); 1199 free (cbuf); 1200 return TRUE; 1201 } 1202 1203 /* Copy object file IBFD onto OBFD. 1204 Returns TRUE upon success, FALSE otherwise. */ 1205 1206 static bfd_boolean 1207 copy_object (bfd *ibfd, bfd *obfd) 1208 { 1209 bfd_vma start; 1210 long symcount; 1211 asection **osections = NULL; 1212 asection *gnu_debuglink_section = NULL; 1213 bfd_size_type *gaps = NULL; 1214 bfd_size_type max_gap = 0; 1215 long symsize; 1216 void *dhandle; 1217 enum bfd_architecture iarch; 1218 unsigned int imach; 1219 1220 if (ibfd->xvec->byteorder != obfd->xvec->byteorder 1221 && ibfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN 1222 && obfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN) 1223 fatal (_("Unable to change endianness of input file(s)")); 1224 1225 if (!bfd_set_format (obfd, bfd_get_format (ibfd))) 1226 { 1227 bfd_nonfatal (bfd_get_filename (obfd)); 1228 return FALSE; 1229 } 1230 1231 if (verbose) 1232 printf (_("copy from `%s' [%s] to `%s' [%s]\n"), 1233 bfd_get_archive_filename (ibfd), bfd_get_target (ibfd), 1234 bfd_get_filename (obfd), bfd_get_target (obfd)); 1235 1236 if (set_start_set) 1237 start = set_start; 1238 else 1239 start = bfd_get_start_address (ibfd); 1240 start += change_start; 1241 1242 /* Neither the start address nor the flags 1243 need to be set for a core file. */ 1244 if (bfd_get_format (obfd) != bfd_core) 1245 { 1246 flagword flags; 1247 1248 flags = bfd_get_file_flags (ibfd); 1249 flags |= bfd_flags_to_set; 1250 flags &= ~bfd_flags_to_clear; 1251 flags &= bfd_applicable_file_flags (obfd); 1252 1253 if (!bfd_set_start_address (obfd, start) 1254 || !bfd_set_file_flags (obfd, flags)) 1255 { 1256 bfd_nonfatal (bfd_get_archive_filename (ibfd)); 1257 return FALSE; 1258 } 1259 } 1260 1261 /* Copy architecture of input file to output file. */ 1262 iarch = bfd_get_arch (ibfd); 1263 imach = bfd_get_mach (ibfd); 1264 if (!bfd_set_arch_mach (obfd, iarch, imach) 1265 && (ibfd->target_defaulted 1266 || bfd_get_arch (ibfd) != bfd_get_arch (obfd))) 1267 { 1268 if (bfd_get_arch (ibfd) == bfd_arch_unknown) 1269 non_fatal (_("Unable to recognise the format of the input file `%s'"), 1270 bfd_get_archive_filename (ibfd)); 1271 else 1272 non_fatal (_("Warning: Output file cannot represent architecture `%s'"), 1273 bfd_printable_arch_mach (bfd_get_arch (ibfd), 1274 bfd_get_mach (ibfd))); 1275 return FALSE; 1276 } 1277 1278 if (!bfd_set_format (obfd, bfd_get_format (ibfd))) 1279 { 1280 bfd_nonfatal (bfd_get_archive_filename (ibfd)); 1281 return FALSE; 1282 } 1283 1284 if (isympp) 1285 free (isympp); 1286 1287 if (osympp != isympp) 1288 free (osympp); 1289 1290 isympp = NULL; 1291 osympp = NULL; 1292 1293 /* BFD mandates that all output sections be created and sizes set before 1294 any output is done. Thus, we traverse all sections multiple times. */ 1295 bfd_map_over_sections (ibfd, setup_section, obfd); 1296 1297 setup_bfd_headers (ibfd, obfd); 1298 1299 if (add_sections != NULL) 1300 { 1301 struct section_add *padd; 1302 struct section_list *pset; 1303 1304 for (padd = add_sections; padd != NULL; padd = padd->next) 1305 { 1306 flagword flags; 1307 1308 pset = find_section_list (padd->name, FALSE); 1309 if (pset != NULL) 1310 pset->used = TRUE; 1311 1312 flags = SEC_HAS_CONTENTS | SEC_READONLY | SEC_DATA; 1313 if (pset != NULL && pset->set_flags) 1314 flags = pset->flags | SEC_HAS_CONTENTS; 1315 1316 /* bfd_make_section_with_flags() does not return very helpful 1317 error codes, so check for the most likely user error first. */ 1318 if (bfd_get_section_by_name (obfd, padd->name)) 1319 { 1320 non_fatal (_("can't add section '%s' - it already exists!"), padd->name); 1321 return FALSE; 1322 } 1323 else 1324 { 1325 padd->section = bfd_make_section_with_flags (obfd, padd->name, flags); 1326 if (padd->section == NULL) 1327 { 1328 non_fatal (_("can't create section `%s': %s"), 1329 padd->name, bfd_errmsg (bfd_get_error ())); 1330 return FALSE; 1331 } 1332 } 1333 1334 if (! bfd_set_section_size (obfd, padd->section, padd->size)) 1335 { 1336 bfd_nonfatal (bfd_get_filename (obfd)); 1337 return FALSE; 1338 } 1339 1340 if (pset != NULL) 1341 { 1342 if (pset->change_vma != CHANGE_IGNORE) 1343 if (! bfd_set_section_vma (obfd, padd->section, 1344 pset->vma_val)) 1345 { 1346 bfd_nonfatal (bfd_get_filename (obfd)); 1347 return FALSE; 1348 } 1349 1350 if (pset->change_lma != CHANGE_IGNORE) 1351 { 1352 padd->section->lma = pset->lma_val; 1353 1354 if (! bfd_set_section_alignment 1355 (obfd, padd->section, 1356 bfd_section_alignment (obfd, padd->section))) 1357 { 1358 bfd_nonfatal (bfd_get_filename (obfd)); 1359 return FALSE; 1360 } 1361 } 1362 } 1363 } 1364 } 1365 1366 if (gnu_debuglink_filename != NULL) 1367 { 1368 gnu_debuglink_section = bfd_create_gnu_debuglink_section 1369 (obfd, gnu_debuglink_filename); 1370 1371 if (gnu_debuglink_section == NULL) 1372 { 1373 bfd_nonfatal (gnu_debuglink_filename); 1374 return FALSE; 1375 } 1376 1377 /* Special processing for PE format files. We 1378 have no way to distinguish PE from COFF here. */ 1379 if (bfd_get_flavour (obfd) == bfd_target_coff_flavour) 1380 { 1381 bfd_vma debuglink_vma; 1382 asection * highest_section; 1383 asection * sec; 1384 1385 /* The PE spec requires that all sections be adjacent and sorted 1386 in ascending order of VMA. It also specifies that debug 1387 sections should be last. This is despite the fact that debug 1388 sections are not loaded into memory and so in theory have no 1389 use for a VMA. 1390 1391 This means that the debuglink section must be given a non-zero 1392 VMA which makes it contiguous with other debug sections. So 1393 walk the current section list, find the section with the 1394 highest VMA and start the debuglink section after that one. */ 1395 for (sec = obfd->sections, highest_section = NULL; 1396 sec != NULL; 1397 sec = sec->next) 1398 if (sec->vma > 0 1399 && (highest_section == NULL 1400 || sec->vma > highest_section->vma)) 1401 highest_section = sec; 1402 1403 if (highest_section) 1404 debuglink_vma = BFD_ALIGN (highest_section->vma 1405 + highest_section->size, 1406 /* FIXME: We ought to be using 1407 COFF_PAGE_SIZE here or maybe 1408 bfd_get_section_alignment() (if it 1409 was set) but since this is for PE 1410 and we know the required alignment 1411 it is easier just to hard code it. */ 1412 0x1000); 1413 else 1414 /* Umm, not sure what to do in this case. */ 1415 debuglink_vma = 0x1000; 1416 1417 bfd_set_section_vma (obfd, gnu_debuglink_section, debuglink_vma); 1418 } 1419 } 1420 1421 if (bfd_count_sections (obfd) == 0) 1422 { 1423 non_fatal (_("there are no sections to be copied!")); 1424 return FALSE; 1425 } 1426 1427 if (gap_fill_set || pad_to_set) 1428 { 1429 asection **set; 1430 unsigned int c, i; 1431 1432 /* We must fill in gaps between the sections and/or we must pad 1433 the last section to a specified address. We do this by 1434 grabbing a list of the sections, sorting them by VMA, and 1435 increasing the section sizes as required to fill the gaps. 1436 We write out the gap contents below. */ 1437 1438 c = bfd_count_sections (obfd); 1439 osections = xmalloc (c * sizeof (asection *)); 1440 set = osections; 1441 bfd_map_over_sections (obfd, get_sections, &set); 1442 1443 qsort (osections, c, sizeof (asection *), compare_section_lma); 1444 1445 gaps = xmalloc (c * sizeof (bfd_size_type)); 1446 memset (gaps, 0, c * sizeof (bfd_size_type)); 1447 1448 if (gap_fill_set) 1449 { 1450 for (i = 0; i < c - 1; i++) 1451 { 1452 flagword flags; 1453 bfd_size_type size; 1454 bfd_vma gap_start, gap_stop; 1455 1456 flags = bfd_get_section_flags (obfd, osections[i]); 1457 if ((flags & SEC_HAS_CONTENTS) == 0 1458 || (flags & SEC_LOAD) == 0) 1459 continue; 1460 1461 size = bfd_section_size (obfd, osections[i]); 1462 gap_start = bfd_section_lma (obfd, osections[i]) + size; 1463 gap_stop = bfd_section_lma (obfd, osections[i + 1]); 1464 if (gap_start < gap_stop) 1465 { 1466 if (! bfd_set_section_size (obfd, osections[i], 1467 size + (gap_stop - gap_start))) 1468 { 1469 non_fatal (_("Can't fill gap after %s: %s"), 1470 bfd_get_section_name (obfd, osections[i]), 1471 bfd_errmsg (bfd_get_error ())); 1472 status = 1; 1473 break; 1474 } 1475 gaps[i] = gap_stop - gap_start; 1476 if (max_gap < gap_stop - gap_start) 1477 max_gap = gap_stop - gap_start; 1478 } 1479 } 1480 } 1481 1482 if (pad_to_set) 1483 { 1484 bfd_vma lma; 1485 bfd_size_type size; 1486 1487 lma = bfd_section_lma (obfd, osections[c - 1]); 1488 size = bfd_section_size (obfd, osections[c - 1]); 1489 if (lma + size < pad_to) 1490 { 1491 if (! bfd_set_section_size (obfd, osections[c - 1], 1492 pad_to - lma)) 1493 { 1494 non_fatal (_("Can't add padding to %s: %s"), 1495 bfd_get_section_name (obfd, osections[c - 1]), 1496 bfd_errmsg (bfd_get_error ())); 1497 status = 1; 1498 } 1499 else 1500 { 1501 gaps[c - 1] = pad_to - (lma + size); 1502 if (max_gap < pad_to - (lma + size)) 1503 max_gap = pad_to - (lma + size); 1504 } 1505 } 1506 } 1507 } 1508 1509 /* Symbol filtering must happen after the output sections 1510 have been created, but before their contents are set. */ 1511 dhandle = NULL; 1512 symsize = bfd_get_symtab_upper_bound (ibfd); 1513 if (symsize < 0) 1514 { 1515 bfd_nonfatal (bfd_get_archive_filename (ibfd)); 1516 return FALSE; 1517 } 1518 1519 osympp = isympp = xmalloc (symsize); 1520 symcount = bfd_canonicalize_symtab (ibfd, isympp); 1521 if (symcount < 0) 1522 { 1523 bfd_nonfatal (bfd_get_filename (ibfd)); 1524 return FALSE; 1525 } 1526 1527 if (convert_debugging) 1528 dhandle = read_debugging_info (ibfd, isympp, symcount); 1529 1530 if (strip_symbols == STRIP_DEBUG 1531 || strip_symbols == STRIP_ALL 1532 || strip_symbols == STRIP_UNNEEDED 1533 || strip_symbols == STRIP_NONDEBUG 1534 || discard_locals != LOCALS_UNDEF 1535 || strip_specific_list != NULL 1536 || keep_specific_list != NULL 1537 || localize_specific_list != NULL 1538 || globalize_specific_list != NULL 1539 || keepglobal_specific_list != NULL 1540 || weaken_specific_list != NULL 1541 || prefix_symbols_string 1542 || sections_removed 1543 || sections_copied 1544 || convert_debugging 1545 || change_leading_char 1546 || remove_leading_char 1547 || redefine_sym_list 1548 || weaken) 1549 { 1550 /* Mark symbols used in output relocations so that they 1551 are kept, even if they are local labels or static symbols. 1552 1553 Note we iterate over the input sections examining their 1554 relocations since the relocations for the output sections 1555 haven't been set yet. mark_symbols_used_in_relocations will 1556 ignore input sections which have no corresponding output 1557 section. */ 1558 if (strip_symbols != STRIP_ALL) 1559 bfd_map_over_sections (ibfd, 1560 mark_symbols_used_in_relocations, 1561 isympp); 1562 osympp = xmalloc ((symcount + 1) * sizeof (asymbol *)); 1563 symcount = filter_symbols (ibfd, obfd, osympp, isympp, symcount); 1564 } 1565 1566 if (convert_debugging && dhandle != NULL) 1567 { 1568 if (! write_debugging_info (obfd, dhandle, &symcount, &osympp)) 1569 { 1570 status = 1; 1571 return FALSE; 1572 } 1573 } 1574 1575 bfd_set_symtab (obfd, osympp, symcount); 1576 1577 /* This has to happen after the symbol table has been set. */ 1578 bfd_map_over_sections (ibfd, copy_section, obfd); 1579 1580 if (add_sections != NULL) 1581 { 1582 struct section_add *padd; 1583 1584 for (padd = add_sections; padd != NULL; padd = padd->next) 1585 { 1586 if (! bfd_set_section_contents (obfd, padd->section, padd->contents, 1587 0, padd->size)) 1588 { 1589 bfd_nonfatal (bfd_get_filename (obfd)); 1590 return FALSE; 1591 } 1592 } 1593 } 1594 1595 if (gnu_debuglink_filename != NULL) 1596 { 1597 if (! bfd_fill_in_gnu_debuglink_section 1598 (obfd, gnu_debuglink_section, gnu_debuglink_filename)) 1599 { 1600 bfd_nonfatal (gnu_debuglink_filename); 1601 return FALSE; 1602 } 1603 } 1604 1605 if (gap_fill_set || pad_to_set) 1606 { 1607 bfd_byte *buf; 1608 int c, i; 1609 1610 /* Fill in the gaps. */ 1611 if (max_gap > 8192) 1612 max_gap = 8192; 1613 buf = xmalloc (max_gap); 1614 memset (buf, gap_fill, max_gap); 1615 1616 c = bfd_count_sections (obfd); 1617 for (i = 0; i < c; i++) 1618 { 1619 if (gaps[i] != 0) 1620 { 1621 bfd_size_type left; 1622 file_ptr off; 1623 1624 left = gaps[i]; 1625 off = bfd_section_size (obfd, osections[i]) - left; 1626 1627 while (left > 0) 1628 { 1629 bfd_size_type now; 1630 1631 if (left > 8192) 1632 now = 8192; 1633 else 1634 now = left; 1635 1636 if (! bfd_set_section_contents (obfd, osections[i], buf, 1637 off, now)) 1638 { 1639 bfd_nonfatal (bfd_get_filename (obfd)); 1640 return FALSE; 1641 } 1642 1643 left -= now; 1644 off += now; 1645 } 1646 } 1647 } 1648 } 1649 1650 /* Allow the BFD backend to copy any private data it understands 1651 from the input BFD to the output BFD. This is done last to 1652 permit the routine to look at the filtered symbol table, which is 1653 important for the ECOFF code at least. */ 1654 if (bfd_get_flavour (ibfd) == bfd_target_elf_flavour 1655 && strip_symbols == STRIP_NONDEBUG) 1656 /* Do not copy the private data when creating an ELF format 1657 debug info file. We do not want the program headers. */ 1658 ; 1659 else if (! bfd_copy_private_bfd_data (ibfd, obfd)) 1660 { 1661 non_fatal (_("%s: error copying private BFD data: %s"), 1662 bfd_get_filename (obfd), 1663 bfd_errmsg (bfd_get_error ())); 1664 return FALSE; 1665 } 1666 1667 /* Switch to the alternate machine code. We have to do this at the 1668 very end, because we only initialize the header when we create 1669 the first section. */ 1670 if (use_alt_mach_code != 0) 1671 { 1672 if (! bfd_alt_mach_code (obfd, use_alt_mach_code)) 1673 { 1674 non_fatal (_("this target does not support %lu alternative machine codes"), 1675 use_alt_mach_code); 1676 if (bfd_get_flavour (obfd) == bfd_target_elf_flavour) 1677 { 1678 non_fatal (_("treating that number as an absolute e_machine value instead")); 1679 elf_elfheader (obfd)->e_machine = use_alt_mach_code; 1680 } 1681 else 1682 non_fatal (_("ignoring the alternative value")); 1683 } 1684 } 1685 1686 return TRUE; 1687 } 1688 1689 /* Read each archive element in turn from IBFD, copy the 1690 contents to temp file, and keep the temp file handle. */ 1691 1692 static void 1693 copy_archive (bfd *ibfd, bfd *obfd, const char *output_target) 1694 { 1695 struct name_list 1696 { 1697 struct name_list *next; 1698 const char *name; 1699 bfd *obfd; 1700 } *list, *l; 1701 bfd **ptr = &obfd->archive_head; 1702 bfd *this_element; 1703 char *dir = make_tempname (bfd_get_filename (obfd), 1); 1704 1705 /* Make a temp directory to hold the contents. */ 1706 if (dir == (char *) NULL) 1707 fatal (_("cannot make temp directory for archive copying (error: %s)"), 1708 strerror (errno)); 1709 1710 obfd->has_armap = ibfd->has_armap; 1711 1712 list = NULL; 1713 1714 this_element = bfd_openr_next_archived_file (ibfd, NULL); 1715 1716 if (!bfd_set_format (obfd, bfd_get_format (ibfd))) 1717 RETURN_NONFATAL (bfd_get_filename (obfd)); 1718 1719 while (!status && this_element != NULL) 1720 { 1721 char *output_name; 1722 bfd *output_bfd; 1723 bfd *last_element; 1724 struct stat buf; 1725 int stat_status = 0; 1726 bfd_boolean delete = TRUE; 1727 1728 /* Create an output file for this member. */ 1729 output_name = concat (dir, "/", 1730 bfd_get_filename (this_element), (char *) 0); 1731 1732 /* If the file already exists, make another temp dir. */ 1733 if (stat (output_name, &buf) >= 0) 1734 { 1735 output_name = make_tempname (output_name, 1); 1736 if (output_name == (char *) NULL) 1737 fatal (_("cannot make temp directory for archive copying (error: %s)"), 1738 strerror (errno)); 1739 1740 l = xmalloc (sizeof (struct name_list)); 1741 l->name = output_name; 1742 l->next = list; 1743 l->obfd = NULL; 1744 list = l; 1745 output_name = concat (output_name, "/", 1746 bfd_get_filename (this_element), (char *) 0); 1747 } 1748 1749 output_bfd = bfd_openw (output_name, output_target); 1750 if (preserve_dates) 1751 { 1752 stat_status = bfd_stat_arch_elt (this_element, &buf); 1753 1754 if (stat_status != 0) 1755 non_fatal (_("internal stat error on %s"), 1756 bfd_get_filename (this_element)); 1757 } 1758 1759 l = xmalloc (sizeof (struct name_list)); 1760 l->name = output_name; 1761 l->next = list; 1762 l->obfd = NULL; 1763 list = l; 1764 1765 if (output_bfd == NULL) 1766 RETURN_NONFATAL (output_name); 1767 1768 if (bfd_check_format (this_element, bfd_object)) 1769 { 1770 delete = ! copy_object (this_element, output_bfd); 1771 1772 if (! delete 1773 || bfd_get_arch (this_element) != bfd_arch_unknown) 1774 { 1775 if (!bfd_close (output_bfd)) 1776 { 1777 bfd_nonfatal (bfd_get_filename (output_bfd)); 1778 /* Error in new object file. Don't change archive. */ 1779 status = 1; 1780 } 1781 } 1782 else 1783 goto copy_unknown_element; 1784 } 1785 else 1786 { 1787 non_fatal (_("Unable to recognise the format of the input file `%s'"), 1788 bfd_get_archive_filename (this_element)); 1789 1790 copy_unknown_element: 1791 delete = !copy_unknown_object (this_element, output_bfd); 1792 if (!bfd_close_all_done (output_bfd)) 1793 { 1794 bfd_nonfatal (bfd_get_filename (output_bfd)); 1795 /* Error in new object file. Don't change archive. */ 1796 status = 1; 1797 } 1798 } 1799 1800 if (delete) 1801 { 1802 unlink (output_name); 1803 status = 1; 1804 } 1805 else 1806 { 1807 if (preserve_dates && stat_status == 0) 1808 set_times (output_name, &buf); 1809 1810 /* Open the newly output file and attach to our list. */ 1811 output_bfd = bfd_openr (output_name, output_target); 1812 1813 l->obfd = output_bfd; 1814 1815 *ptr = output_bfd; 1816 ptr = &output_bfd->next; 1817 1818 last_element = this_element; 1819 1820 this_element = bfd_openr_next_archived_file (ibfd, last_element); 1821 1822 bfd_close (last_element); 1823 } 1824 } 1825 *ptr = NULL; 1826 1827 if (!bfd_close (obfd)) 1828 RETURN_NONFATAL (bfd_get_filename (obfd)); 1829 1830 if (!bfd_close (ibfd)) 1831 RETURN_NONFATAL (bfd_get_filename (ibfd)); 1832 1833 /* Delete all the files that we opened. */ 1834 for (l = list; l != NULL; l = l->next) 1835 { 1836 if (l->obfd == NULL) 1837 rmdir (l->name); 1838 else 1839 { 1840 bfd_close (l->obfd); 1841 unlink (l->name); 1842 } 1843 } 1844 rmdir (dir); 1845 } 1846 1847 /* The top-level control. */ 1848 1849 static void 1850 copy_file (const char *input_filename, const char *output_filename, 1851 const char *input_target, const char *output_target) 1852 { 1853 bfd *ibfd; 1854 char **obj_matching; 1855 char **core_matching; 1856 1857 if (get_file_size (input_filename) < 1) 1858 { 1859 non_fatal (_("error: the input file '%s' is empty"), input_filename); 1860 status = 1; 1861 return; 1862 } 1863 1864 /* To allow us to do "strip *" without dying on the first 1865 non-object file, failures are nonfatal. */ 1866 ibfd = bfd_openr (input_filename, input_target); 1867 if (ibfd == NULL) 1868 RETURN_NONFATAL (input_filename); 1869 1870 if (bfd_check_format (ibfd, bfd_archive)) 1871 { 1872 bfd *obfd; 1873 1874 /* bfd_get_target does not return the correct value until 1875 bfd_check_format succeeds. */ 1876 if (output_target == NULL) 1877 output_target = bfd_get_target (ibfd); 1878 1879 obfd = bfd_openw (output_filename, output_target); 1880 if (obfd == NULL) 1881 RETURN_NONFATAL (output_filename); 1882 1883 copy_archive (ibfd, obfd, output_target); 1884 } 1885 else if (bfd_check_format_matches (ibfd, bfd_object, &obj_matching)) 1886 { 1887 bfd *obfd; 1888 do_copy: 1889 1890 /* bfd_get_target does not return the correct value until 1891 bfd_check_format succeeds. */ 1892 if (output_target == NULL) 1893 output_target = bfd_get_target (ibfd); 1894 1895 obfd = bfd_openw (output_filename, output_target); 1896 if (obfd == NULL) 1897 RETURN_NONFATAL (output_filename); 1898 1899 if (! copy_object (ibfd, obfd)) 1900 status = 1; 1901 1902 if (!bfd_close (obfd)) 1903 RETURN_NONFATAL (output_filename); 1904 1905 if (!bfd_close (ibfd)) 1906 RETURN_NONFATAL (input_filename); 1907 1908 } 1909 else 1910 { 1911 bfd_error_type obj_error = bfd_get_error (); 1912 bfd_error_type core_error; 1913 1914 if (bfd_check_format_matches (ibfd, bfd_core, &core_matching)) 1915 { 1916 /* This probably can't happen.. */ 1917 if (obj_error == bfd_error_file_ambiguously_recognized) 1918 free (obj_matching); 1919 goto do_copy; 1920 } 1921 1922 core_error = bfd_get_error (); 1923 /* Report the object error in preference to the core error. */ 1924 if (obj_error != core_error) 1925 bfd_set_error (obj_error); 1926 1927 bfd_nonfatal (input_filename); 1928 1929 if (obj_error == bfd_error_file_ambiguously_recognized) 1930 { 1931 list_matching_formats (obj_matching); 1932 free (obj_matching); 1933 } 1934 if (core_error == bfd_error_file_ambiguously_recognized) 1935 { 1936 list_matching_formats (core_matching); 1937 free (core_matching); 1938 } 1939 1940 status = 1; 1941 } 1942 } 1943 1944 /* Add a name to the section renaming list. */ 1945 1946 static void 1947 add_section_rename (const char * old_name, const char * new_name, 1948 flagword flags) 1949 { 1950 section_rename * rename; 1951 1952 /* Check for conflicts first. */ 1953 for (rename = section_rename_list; rename != NULL; rename = rename->next) 1954 if (strcmp (rename->old_name, old_name) == 0) 1955 { 1956 /* Silently ignore duplicate definitions. */ 1957 if (strcmp (rename->new_name, new_name) == 0 1958 && rename->flags == flags) 1959 return; 1960 1961 fatal (_("Multiple renames of section %s"), old_name); 1962 } 1963 1964 rename = xmalloc (sizeof (* rename)); 1965 1966 rename->old_name = old_name; 1967 rename->new_name = new_name; 1968 rename->flags = flags; 1969 rename->next = section_rename_list; 1970 1971 section_rename_list = rename; 1972 } 1973 1974 /* Check the section rename list for a new name of the input section 1975 ISECTION. Return the new name if one is found. 1976 Also set RETURNED_FLAGS to the flags to be used for this section. */ 1977 1978 static const char * 1979 find_section_rename (bfd * ibfd ATTRIBUTE_UNUSED, sec_ptr isection, 1980 flagword * returned_flags) 1981 { 1982 const char * old_name = bfd_section_name (ibfd, isection); 1983 section_rename * rename; 1984 1985 /* Default to using the flags of the input section. */ 1986 * returned_flags = bfd_get_section_flags (ibfd, isection); 1987 1988 for (rename = section_rename_list; rename != NULL; rename = rename->next) 1989 if (strcmp (rename->old_name, old_name) == 0) 1990 { 1991 if (rename->flags != (flagword) -1) 1992 * returned_flags = rename->flags; 1993 1994 return rename->new_name; 1995 } 1996 1997 return old_name; 1998 } 1999 2000 /* Once each of the sections is copied, we may still need to do some 2001 finalization work for private section headers. Do that here. */ 2002 2003 static void 2004 setup_bfd_headers (bfd *ibfd, bfd *obfd) 2005 { 2006 const char *err; 2007 2008 /* Allow the BFD backend to copy any private data it understands 2009 from the input section to the output section. */ 2010 if (! bfd_copy_private_header_data (ibfd, obfd)) 2011 { 2012 err = _("private header data"); 2013 goto loser; 2014 } 2015 2016 /* All went well. */ 2017 return; 2018 2019 loser: 2020 non_fatal (_("%s: error in %s: %s"), 2021 bfd_get_filename (ibfd), 2022 err, bfd_errmsg (bfd_get_error ())); 2023 status = 1; 2024 } 2025 2026 /* Create a section in OBFD with the same 2027 name and attributes as ISECTION in IBFD. */ 2028 2029 static void 2030 setup_section (bfd *ibfd, sec_ptr isection, void *obfdarg) 2031 { 2032 bfd *obfd = obfdarg; 2033 struct section_list *p; 2034 sec_ptr osection; 2035 bfd_size_type size; 2036 bfd_vma vma; 2037 bfd_vma lma; 2038 flagword flags; 2039 const char *err; 2040 const char * name; 2041 char *prefix = NULL; 2042 2043 if (is_strip_section (ibfd, isection)) 2044 return; 2045 2046 p = find_section_list (bfd_section_name (ibfd, isection), FALSE); 2047 if (p != NULL) 2048 p->used = TRUE; 2049 2050 /* Get the, possibly new, name of the output section. */ 2051 name = find_section_rename (ibfd, isection, & flags); 2052 2053 /* Prefix sections. */ 2054 if ((prefix_alloc_sections_string) 2055 && (bfd_get_section_flags (ibfd, isection) & SEC_ALLOC)) 2056 prefix = prefix_alloc_sections_string; 2057 else if (prefix_sections_string) 2058 prefix = prefix_sections_string; 2059 2060 if (prefix) 2061 { 2062 char *n; 2063 2064 n = xmalloc (strlen (prefix) + strlen (name) + 1); 2065 strcpy (n, prefix); 2066 strcat (n, name); 2067 name = n; 2068 } 2069 2070 if (p != NULL && p->set_flags) 2071 flags = p->flags | (flags & (SEC_HAS_CONTENTS | SEC_RELOC)); 2072 else if (strip_symbols == STRIP_NONDEBUG && (flags & SEC_ALLOC) != 0) 2073 flags &= ~(SEC_HAS_CONTENTS | SEC_LOAD); 2074 2075 osection = bfd_make_section_anyway_with_flags (obfd, name, flags); 2076 2077 if (osection == NULL) 2078 { 2079 err = _("making"); 2080 goto loser; 2081 } 2082 2083 if (strip_symbols == STRIP_NONDEBUG 2084 && obfd->xvec->flavour == bfd_target_elf_flavour 2085 && (flags & SEC_ALLOC) != 0 2086 && (p == NULL || !p->set_flags)) 2087 elf_section_type (osection) = SHT_NOBITS; 2088 2089 size = bfd_section_size (ibfd, isection); 2090 if (copy_byte >= 0) 2091 size = (size + interleave - 1) / interleave; 2092 if (! bfd_set_section_size (obfd, osection, size)) 2093 { 2094 err = _("size"); 2095 goto loser; 2096 } 2097 2098 vma = bfd_section_vma (ibfd, isection); 2099 if (p != NULL && p->change_vma == CHANGE_MODIFY) 2100 vma += p->vma_val; 2101 else if (p != NULL && p->change_vma == CHANGE_SET) 2102 vma = p->vma_val; 2103 else 2104 vma += change_section_address; 2105 2106 if (! bfd_set_section_vma (obfd, osection, vma)) 2107 { 2108 err = _("vma"); 2109 goto loser; 2110 } 2111 2112 lma = isection->lma; 2113 if ((p != NULL) && p->change_lma != CHANGE_IGNORE) 2114 { 2115 if (p->change_lma == CHANGE_MODIFY) 2116 lma += p->lma_val; 2117 else if (p->change_lma == CHANGE_SET) 2118 lma = p->lma_val; 2119 else 2120 abort (); 2121 } 2122 else 2123 lma += change_section_address; 2124 2125 osection->lma = lma; 2126 2127 /* FIXME: This is probably not enough. If we change the LMA we 2128 may have to recompute the header for the file as well. */ 2129 if (!bfd_set_section_alignment (obfd, 2130 osection, 2131 bfd_section_alignment (ibfd, isection))) 2132 { 2133 err = _("alignment"); 2134 goto loser; 2135 } 2136 2137 /* Copy merge entity size. */ 2138 osection->entsize = isection->entsize; 2139 2140 /* This used to be mangle_section; we do here to avoid using 2141 bfd_get_section_by_name since some formats allow multiple 2142 sections with the same name. */ 2143 isection->output_section = osection; 2144 isection->output_offset = 0; 2145 2146 /* Allow the BFD backend to copy any private data it understands 2147 from the input section to the output section. */ 2148 if (bfd_get_flavour (ibfd) == bfd_target_elf_flavour 2149 && strip_symbols == STRIP_NONDEBUG) 2150 /* Do not copy the private data when creating an ELF format 2151 debug info file. We do not want the program headers. */ 2152 ; 2153 else if (!bfd_copy_private_section_data (ibfd, isection, obfd, osection)) 2154 { 2155 err = _("private data"); 2156 goto loser; 2157 } 2158 2159 /* All went well. */ 2160 return; 2161 2162 loser: 2163 non_fatal (_("%s: section `%s': error in %s: %s"), 2164 bfd_get_filename (ibfd), 2165 bfd_section_name (ibfd, isection), 2166 err, bfd_errmsg (bfd_get_error ())); 2167 status = 1; 2168 } 2169 2170 /* Copy the data of input section ISECTION of IBFD 2171 to an output section with the same name in OBFD. 2172 If stripping then don't copy any relocation info. */ 2173 2174 static void 2175 copy_section (bfd *ibfd, sec_ptr isection, void *obfdarg) 2176 { 2177 bfd *obfd = obfdarg; 2178 struct section_list *p; 2179 arelent **relpp; 2180 long relcount; 2181 sec_ptr osection; 2182 bfd_size_type size; 2183 long relsize; 2184 flagword flags; 2185 2186 /* If we have already failed earlier on, 2187 do not keep on generating complaints now. */ 2188 if (status != 0) 2189 return; 2190 2191 if (is_strip_section (ibfd, isection)) 2192 return; 2193 2194 flags = bfd_get_section_flags (ibfd, isection); 2195 if ((flags & SEC_GROUP) != 0) 2196 return; 2197 2198 osection = isection->output_section; 2199 size = bfd_get_section_size (isection); 2200 2201 if (size == 0 || osection == 0) 2202 return; 2203 2204 p = find_section_list (bfd_get_section_name (ibfd, isection), FALSE); 2205 2206 /* Core files do not need to be relocated. */ 2207 if (bfd_get_format (obfd) == bfd_core) 2208 relsize = 0; 2209 else 2210 { 2211 relsize = bfd_get_reloc_upper_bound (ibfd, isection); 2212 2213 if (relsize < 0) 2214 { 2215 /* Do not complain if the target does not support relocations. */ 2216 if (relsize == -1 && bfd_get_error () == bfd_error_invalid_operation) 2217 relsize = 0; 2218 else 2219 RETURN_NONFATAL (bfd_get_filename (ibfd)); 2220 } 2221 } 2222 2223 if (relsize == 0) 2224 bfd_set_reloc (obfd, osection, NULL, 0); 2225 else 2226 { 2227 relpp = xmalloc (relsize); 2228 relcount = bfd_canonicalize_reloc (ibfd, isection, relpp, isympp); 2229 if (relcount < 0) 2230 RETURN_NONFATAL (bfd_get_filename (ibfd)); 2231 2232 if (strip_symbols == STRIP_ALL) 2233 { 2234 /* Remove relocations which are not in 2235 keep_strip_specific_list. */ 2236 arelent **temp_relpp; 2237 long temp_relcount = 0; 2238 long i; 2239 2240 temp_relpp = xmalloc (relsize); 2241 for (i = 0; i < relcount; i++) 2242 if (is_specified_symbol (bfd_asymbol_name (*relpp[i]->sym_ptr_ptr), 2243 keep_specific_list)) 2244 temp_relpp [temp_relcount++] = relpp [i]; 2245 relcount = temp_relcount; 2246 free (relpp); 2247 relpp = temp_relpp; 2248 } 2249 2250 bfd_set_reloc (obfd, osection, relcount == 0 ? NULL : relpp, relcount); 2251 if (relcount == 0) 2252 free (relpp); 2253 } 2254 2255 if (bfd_get_section_flags (ibfd, isection) & SEC_HAS_CONTENTS 2256 && bfd_get_section_flags (obfd, osection) & SEC_HAS_CONTENTS) 2257 { 2258 void *memhunk = xmalloc (size); 2259 2260 if (!bfd_get_section_contents (ibfd, isection, memhunk, 0, size)) 2261 RETURN_NONFATAL (bfd_get_filename (ibfd)); 2262 2263 if (copy_byte >= 0) 2264 { 2265 /* Keep only every `copy_byte'th byte in MEMHUNK. */ 2266 char *from = (char *) memhunk + copy_byte; 2267 char *to = memhunk; 2268 char *end = (char *) memhunk + size; 2269 2270 for (; from < end; from += interleave) 2271 *to++ = *from; 2272 2273 size = (size + interleave - 1 - copy_byte) / interleave; 2274 osection->lma /= interleave; 2275 } 2276 2277 if (!bfd_set_section_contents (obfd, osection, memhunk, 0, size)) 2278 RETURN_NONFATAL (bfd_get_filename (obfd)); 2279 2280 free (memhunk); 2281 } 2282 else if (p != NULL && p->set_flags && (p->flags & SEC_HAS_CONTENTS) != 0) 2283 { 2284 void *memhunk = xmalloc (size); 2285 2286 /* We don't permit the user to turn off the SEC_HAS_CONTENTS 2287 flag--they can just remove the section entirely and add it 2288 back again. However, we do permit them to turn on the 2289 SEC_HAS_CONTENTS flag, and take it to mean that the section 2290 contents should be zeroed out. */ 2291 2292 memset (memhunk, 0, size); 2293 if (! bfd_set_section_contents (obfd, osection, memhunk, 0, size)) 2294 RETURN_NONFATAL (bfd_get_filename (obfd)); 2295 free (memhunk); 2296 } 2297 } 2298 2299 /* Get all the sections. This is used when --gap-fill or --pad-to is 2300 used. */ 2301 2302 static void 2303 get_sections (bfd *obfd ATTRIBUTE_UNUSED, asection *osection, void *secppparg) 2304 { 2305 asection ***secppp = secppparg; 2306 2307 **secppp = osection; 2308 ++(*secppp); 2309 } 2310 2311 /* Sort sections by VMA. This is called via qsort, and is used when 2312 --gap-fill or --pad-to is used. We force non loadable or empty 2313 sections to the front, where they are easier to ignore. */ 2314 2315 static int 2316 compare_section_lma (const void *arg1, const void *arg2) 2317 { 2318 const asection *const *sec1 = arg1; 2319 const asection *const *sec2 = arg2; 2320 flagword flags1, flags2; 2321 2322 /* Sort non loadable sections to the front. */ 2323 flags1 = (*sec1)->flags; 2324 flags2 = (*sec2)->flags; 2325 if ((flags1 & SEC_HAS_CONTENTS) == 0 2326 || (flags1 & SEC_LOAD) == 0) 2327 { 2328 if ((flags2 & SEC_HAS_CONTENTS) != 0 2329 && (flags2 & SEC_LOAD) != 0) 2330 return -1; 2331 } 2332 else 2333 { 2334 if ((flags2 & SEC_HAS_CONTENTS) == 0 2335 || (flags2 & SEC_LOAD) == 0) 2336 return 1; 2337 } 2338 2339 /* Sort sections by LMA. */ 2340 if ((*sec1)->lma > (*sec2)->lma) 2341 return 1; 2342 else if ((*sec1)->lma < (*sec2)->lma) 2343 return -1; 2344 2345 /* Sort sections with the same LMA by size. */ 2346 if (bfd_get_section_size (*sec1) > bfd_get_section_size (*sec2)) 2347 return 1; 2348 else if (bfd_get_section_size (*sec1) < bfd_get_section_size (*sec2)) 2349 return -1; 2350 2351 return 0; 2352 } 2353 2354 /* Mark all the symbols which will be used in output relocations with 2355 the BSF_KEEP flag so that those symbols will not be stripped. 2356 2357 Ignore relocations which will not appear in the output file. */ 2358 2359 static void 2360 mark_symbols_used_in_relocations (bfd *ibfd, sec_ptr isection, void *symbolsarg) 2361 { 2362 asymbol **symbols = symbolsarg; 2363 long relsize; 2364 arelent **relpp; 2365 long relcount, i; 2366 2367 /* Ignore an input section with no corresponding output section. */ 2368 if (isection->output_section == NULL) 2369 return; 2370 2371 relsize = bfd_get_reloc_upper_bound (ibfd, isection); 2372 if (relsize < 0) 2373 { 2374 /* Do not complain if the target does not support relocations. */ 2375 if (relsize == -1 && bfd_get_error () == bfd_error_invalid_operation) 2376 return; 2377 bfd_fatal (bfd_get_filename (ibfd)); 2378 } 2379 2380 if (relsize == 0) 2381 return; 2382 2383 relpp = xmalloc (relsize); 2384 relcount = bfd_canonicalize_reloc (ibfd, isection, relpp, symbols); 2385 if (relcount < 0) 2386 bfd_fatal (bfd_get_filename (ibfd)); 2387 2388 /* Examine each symbol used in a relocation. If it's not one of the 2389 special bfd section symbols, then mark it with BSF_KEEP. */ 2390 for (i = 0; i < relcount; i++) 2391 { 2392 if (*relpp[i]->sym_ptr_ptr != bfd_com_section_ptr->symbol 2393 && *relpp[i]->sym_ptr_ptr != bfd_abs_section_ptr->symbol 2394 && *relpp[i]->sym_ptr_ptr != bfd_und_section_ptr->symbol) 2395 (*relpp[i]->sym_ptr_ptr)->flags |= BSF_KEEP; 2396 } 2397 2398 if (relpp != NULL) 2399 free (relpp); 2400 } 2401 2402 /* Write out debugging information. */ 2403 2404 static bfd_boolean 2405 write_debugging_info (bfd *obfd, void *dhandle, 2406 long *symcountp ATTRIBUTE_UNUSED, 2407 asymbol ***symppp ATTRIBUTE_UNUSED) 2408 { 2409 if (bfd_get_flavour (obfd) == bfd_target_ieee_flavour) 2410 return write_ieee_debugging_info (obfd, dhandle); 2411 2412 if (bfd_get_flavour (obfd) == bfd_target_coff_flavour 2413 || bfd_get_flavour (obfd) == bfd_target_elf_flavour) 2414 { 2415 bfd_byte *syms, *strings; 2416 bfd_size_type symsize, stringsize; 2417 asection *stabsec, *stabstrsec; 2418 flagword flags; 2419 2420 if (! write_stabs_in_sections_debugging_info (obfd, dhandle, &syms, 2421 &symsize, &strings, 2422 &stringsize)) 2423 return FALSE; 2424 2425 flags = SEC_HAS_CONTENTS | SEC_READONLY | SEC_DEBUGGING; 2426 stabsec = bfd_make_section_with_flags (obfd, ".stab", flags); 2427 stabstrsec = bfd_make_section_with_flags (obfd, ".stabstr", flags); 2428 if (stabsec == NULL 2429 || stabstrsec == NULL 2430 || ! bfd_set_section_size (obfd, stabsec, symsize) 2431 || ! bfd_set_section_size (obfd, stabstrsec, stringsize) 2432 || ! bfd_set_section_alignment (obfd, stabsec, 2) 2433 || ! bfd_set_section_alignment (obfd, stabstrsec, 0)) 2434 { 2435 non_fatal (_("%s: can't create debugging section: %s"), 2436 bfd_get_filename (obfd), 2437 bfd_errmsg (bfd_get_error ())); 2438 return FALSE; 2439 } 2440 2441 /* We can get away with setting the section contents now because 2442 the next thing the caller is going to do is copy over the 2443 real sections. We may someday have to split the contents 2444 setting out of this function. */ 2445 if (! bfd_set_section_contents (obfd, stabsec, syms, 0, symsize) 2446 || ! bfd_set_section_contents (obfd, stabstrsec, strings, 0, 2447 stringsize)) 2448 { 2449 non_fatal (_("%s: can't set debugging section contents: %s"), 2450 bfd_get_filename (obfd), 2451 bfd_errmsg (bfd_get_error ())); 2452 return FALSE; 2453 } 2454 2455 return TRUE; 2456 } 2457 2458 non_fatal (_("%s: don't know how to write debugging information for %s"), 2459 bfd_get_filename (obfd), bfd_get_target (obfd)); 2460 return FALSE; 2461 } 2462 2463 static int 2464 strip_main (int argc, char *argv[]) 2465 { 2466 char *input_target = NULL; 2467 char *output_target = NULL; 2468 bfd_boolean show_version = FALSE; 2469 bfd_boolean formats_info = FALSE; 2470 int c; 2471 int i; 2472 struct section_list *p; 2473 char *output_file = NULL; 2474 2475 while ((c = getopt_long (argc, argv, "I:O:F:K:N:R:o:sSpdgxXHhVvw", 2476 strip_options, (int *) 0)) != EOF) 2477 { 2478 switch (c) 2479 { 2480 case 'I': 2481 input_target = optarg; 2482 break; 2483 case 'O': 2484 output_target = optarg; 2485 break; 2486 case 'F': 2487 input_target = output_target = optarg; 2488 break; 2489 case 'R': 2490 p = find_section_list (optarg, TRUE); 2491 p->remove = TRUE; 2492 sections_removed = TRUE; 2493 break; 2494 case 's': 2495 strip_symbols = STRIP_ALL; 2496 break; 2497 case 'S': 2498 case 'g': 2499 case 'd': /* Historic BSD alias for -g. Used by early NetBSD. */ 2500 strip_symbols = STRIP_DEBUG; 2501 break; 2502 case OPTION_STRIP_UNNEEDED: 2503 strip_symbols = STRIP_UNNEEDED; 2504 break; 2505 case 'K': 2506 add_specific_symbol (optarg, &keep_specific_list); 2507 break; 2508 case 'N': 2509 add_specific_symbol (optarg, &strip_specific_list); 2510 break; 2511 case 'o': 2512 output_file = optarg; 2513 break; 2514 case 'p': 2515 preserve_dates = TRUE; 2516 break; 2517 case 'x': 2518 discard_locals = LOCALS_ALL; 2519 break; 2520 case 'X': 2521 discard_locals = LOCALS_START_L; 2522 break; 2523 case 'v': 2524 verbose = TRUE; 2525 break; 2526 case 'V': 2527 show_version = TRUE; 2528 break; 2529 case OPTION_FORMATS_INFO: 2530 formats_info = TRUE; 2531 break; 2532 case OPTION_ONLY_KEEP_DEBUG: 2533 strip_symbols = STRIP_NONDEBUG; 2534 break; 2535 case OPTION_KEEP_FILE_SYMBOLS: 2536 keep_file_symbols = 1; 2537 break; 2538 case 0: 2539 /* We've been given a long option. */ 2540 break; 2541 case 'w': 2542 wildcard = TRUE; 2543 break; 2544 case 'H': 2545 case 'h': 2546 strip_usage (stdout, 0); 2547 default: 2548 strip_usage (stderr, 1); 2549 } 2550 } 2551 2552 if (formats_info) 2553 { 2554 display_info (); 2555 return 0; 2556 } 2557 2558 if (show_version) 2559 print_version ("strip"); 2560 2561 /* Default is to strip all symbols. */ 2562 if (strip_symbols == STRIP_UNDEF 2563 && discard_locals == LOCALS_UNDEF 2564 && strip_specific_list == NULL) 2565 strip_symbols = STRIP_ALL; 2566 2567 if (output_target == NULL) 2568 output_target = input_target; 2569 2570 i = optind; 2571 if (i == argc 2572 || (output_file != NULL && (i + 1) < argc)) 2573 strip_usage (stderr, 1); 2574 2575 for (; i < argc; i++) 2576 { 2577 int hold_status = status; 2578 struct stat statbuf; 2579 char *tmpname; 2580 2581 if (get_file_size (argv[i]) < 1) 2582 { 2583 status = 1; 2584 continue; 2585 } 2586 2587 if (preserve_dates) 2588 /* No need to check the return value of stat(). 2589 It has already been checked in get_file_size(). */ 2590 stat (argv[i], &statbuf); 2591 2592 if (output_file != NULL) 2593 tmpname = output_file; 2594 else 2595 tmpname = make_tempname (argv[i], 0); 2596 status = 0; 2597 2598 copy_file (argv[i], tmpname, input_target, output_target); 2599 if (status == 0) 2600 { 2601 if (preserve_dates) 2602 set_times (tmpname, &statbuf); 2603 if (output_file == NULL) 2604 smart_rename (tmpname, argv[i], preserve_dates); 2605 status = hold_status; 2606 } 2607 else 2608 unlink_if_ordinary (tmpname); 2609 if (output_file == NULL) 2610 free (tmpname); 2611 } 2612 2613 return 0; 2614 } 2615 2616 static int 2617 copy_main (int argc, char *argv[]) 2618 { 2619 char * binary_architecture = NULL; 2620 char *input_filename = NULL; 2621 char *output_filename = NULL; 2622 char *input_target = NULL; 2623 char *output_target = NULL; 2624 bfd_boolean show_version = FALSE; 2625 bfd_boolean change_warn = TRUE; 2626 bfd_boolean formats_info = FALSE; 2627 int c; 2628 struct section_list *p; 2629 struct stat statbuf; 2630 2631 while ((c = getopt_long (argc, argv, "b:B:i:I:j:K:N:s:O:d:F:L:G:R:SpgxXHhVvW:w", 2632 copy_options, (int *) 0)) != EOF) 2633 { 2634 switch (c) 2635 { 2636 case 'b': 2637 copy_byte = atoi (optarg); 2638 if (copy_byte < 0) 2639 fatal (_("byte number must be non-negative")); 2640 break; 2641 2642 case 'B': 2643 binary_architecture = optarg; 2644 break; 2645 2646 case 'i': 2647 interleave = atoi (optarg); 2648 if (interleave < 1) 2649 fatal (_("interleave must be positive")); 2650 break; 2651 2652 case 'I': 2653 case 's': /* "source" - 'I' is preferred */ 2654 input_target = optarg; 2655 break; 2656 2657 case 'O': 2658 case 'd': /* "destination" - 'O' is preferred */ 2659 output_target = optarg; 2660 break; 2661 2662 case 'F': 2663 input_target = output_target = optarg; 2664 break; 2665 2666 case 'j': 2667 p = find_section_list (optarg, TRUE); 2668 if (p->remove) 2669 fatal (_("%s both copied and removed"), optarg); 2670 p->copy = TRUE; 2671 sections_copied = TRUE; 2672 break; 2673 2674 case 'R': 2675 p = find_section_list (optarg, TRUE); 2676 if (p->copy) 2677 fatal (_("%s both copied and removed"), optarg); 2678 p->remove = TRUE; 2679 sections_removed = TRUE; 2680 break; 2681 2682 case 'S': 2683 strip_symbols = STRIP_ALL; 2684 break; 2685 2686 case 'g': 2687 strip_symbols = STRIP_DEBUG; 2688 break; 2689 2690 case OPTION_STRIP_UNNEEDED: 2691 strip_symbols = STRIP_UNNEEDED; 2692 break; 2693 2694 case OPTION_ONLY_KEEP_DEBUG: 2695 strip_symbols = STRIP_NONDEBUG; 2696 break; 2697 2698 case OPTION_KEEP_FILE_SYMBOLS: 2699 keep_file_symbols = 1; 2700 break; 2701 2702 case OPTION_ADD_GNU_DEBUGLINK: 2703 gnu_debuglink_filename = optarg; 2704 break; 2705 2706 case 'K': 2707 add_specific_symbol (optarg, &keep_specific_list); 2708 break; 2709 2710 case 'N': 2711 add_specific_symbol (optarg, &strip_specific_list); 2712 break; 2713 2714 case OPTION_STRIP_UNNEEDED_SYMBOL: 2715 add_specific_symbol (optarg, &strip_unneeded_list); 2716 break; 2717 2718 case 'L': 2719 add_specific_symbol (optarg, &localize_specific_list); 2720 break; 2721 2722 case OPTION_GLOBALIZE_SYMBOL: 2723 add_specific_symbol (optarg, &globalize_specific_list); 2724 break; 2725 2726 case 'G': 2727 add_specific_symbol (optarg, &keepglobal_specific_list); 2728 break; 2729 2730 case 'W': 2731 add_specific_symbol (optarg, &weaken_specific_list); 2732 break; 2733 2734 case 'p': 2735 preserve_dates = TRUE; 2736 break; 2737 2738 case 'w': 2739 wildcard = TRUE; 2740 break; 2741 2742 case 'x': 2743 discard_locals = LOCALS_ALL; 2744 break; 2745 2746 case 'X': 2747 discard_locals = LOCALS_START_L; 2748 break; 2749 2750 case 'v': 2751 verbose = TRUE; 2752 break; 2753 2754 case 'V': 2755 show_version = TRUE; 2756 break; 2757 2758 case OPTION_FORMATS_INFO: 2759 formats_info = TRUE; 2760 break; 2761 2762 case OPTION_WEAKEN: 2763 weaken = TRUE; 2764 break; 2765 2766 case OPTION_ADD_SECTION: 2767 { 2768 const char *s; 2769 off_t size; 2770 struct section_add *pa; 2771 int len; 2772 char *name; 2773 FILE *f; 2774 2775 s = strchr (optarg, '='); 2776 2777 if (s == NULL) 2778 fatal (_("bad format for %s"), "--add-section"); 2779 2780 size = get_file_size (s + 1); 2781 if (size < 1) 2782 break; 2783 2784 pa = xmalloc (sizeof (struct section_add)); 2785 2786 len = s - optarg; 2787 name = xmalloc (len + 1); 2788 strncpy (name, optarg, len); 2789 name[len] = '\0'; 2790 pa->name = name; 2791 2792 pa->filename = s + 1; 2793 pa->size = size; 2794 pa->contents = xmalloc (size); 2795 2796 f = fopen (pa->filename, FOPEN_RB); 2797 2798 if (f == NULL) 2799 fatal (_("cannot open: %s: %s"), 2800 pa->filename, strerror (errno)); 2801 2802 if (fread (pa->contents, 1, pa->size, f) == 0 2803 || ferror (f)) 2804 fatal (_("%s: fread failed"), pa->filename); 2805 2806 fclose (f); 2807 2808 pa->next = add_sections; 2809 add_sections = pa; 2810 } 2811 break; 2812 2813 case OPTION_CHANGE_START: 2814 change_start = parse_vma (optarg, "--change-start"); 2815 break; 2816 2817 case OPTION_CHANGE_SECTION_ADDRESS: 2818 case OPTION_CHANGE_SECTION_LMA: 2819 case OPTION_CHANGE_SECTION_VMA: 2820 { 2821 const char *s; 2822 int len; 2823 char *name; 2824 char *option = NULL; 2825 bfd_vma val; 2826 enum change_action what = CHANGE_IGNORE; 2827 2828 switch (c) 2829 { 2830 case OPTION_CHANGE_SECTION_ADDRESS: 2831 option = "--change-section-address"; 2832 break; 2833 case OPTION_CHANGE_SECTION_LMA: 2834 option = "--change-section-lma"; 2835 break; 2836 case OPTION_CHANGE_SECTION_VMA: 2837 option = "--change-section-vma"; 2838 break; 2839 } 2840 2841 s = strchr (optarg, '='); 2842 if (s == NULL) 2843 { 2844 s = strchr (optarg, '+'); 2845 if (s == NULL) 2846 { 2847 s = strchr (optarg, '-'); 2848 if (s == NULL) 2849 fatal (_("bad format for %s"), option); 2850 } 2851 } 2852 2853 len = s - optarg; 2854 name = xmalloc (len + 1); 2855 strncpy (name, optarg, len); 2856 name[len] = '\0'; 2857 2858 p = find_section_list (name, TRUE); 2859 2860 val = parse_vma (s + 1, option); 2861 2862 switch (*s) 2863 { 2864 case '=': what = CHANGE_SET; break; 2865 case '-': val = - val; /* Drop through. */ 2866 case '+': what = CHANGE_MODIFY; break; 2867 } 2868 2869 switch (c) 2870 { 2871 case OPTION_CHANGE_SECTION_ADDRESS: 2872 p->change_vma = what; 2873 p->vma_val = val; 2874 /* Drop through. */ 2875 2876 case OPTION_CHANGE_SECTION_LMA: 2877 p->change_lma = what; 2878 p->lma_val = val; 2879 break; 2880 2881 case OPTION_CHANGE_SECTION_VMA: 2882 p->change_vma = what; 2883 p->vma_val = val; 2884 break; 2885 } 2886 } 2887 break; 2888 2889 case OPTION_CHANGE_ADDRESSES: 2890 change_section_address = parse_vma (optarg, "--change-addresses"); 2891 change_start = change_section_address; 2892 break; 2893 2894 case OPTION_CHANGE_WARNINGS: 2895 change_warn = TRUE; 2896 break; 2897 2898 case OPTION_CHANGE_LEADING_CHAR: 2899 change_leading_char = TRUE; 2900 break; 2901 2902 case OPTION_DEBUGGING: 2903 convert_debugging = TRUE; 2904 break; 2905 2906 case OPTION_GAP_FILL: 2907 { 2908 bfd_vma gap_fill_vma; 2909 2910 gap_fill_vma = parse_vma (optarg, "--gap-fill"); 2911 gap_fill = (bfd_byte) gap_fill_vma; 2912 if ((bfd_vma) gap_fill != gap_fill_vma) 2913 { 2914 char buff[20]; 2915 2916 sprintf_vma (buff, gap_fill_vma); 2917 2918 non_fatal (_("Warning: truncating gap-fill from 0x%s to 0x%x"), 2919 buff, gap_fill); 2920 } 2921 gap_fill_set = TRUE; 2922 } 2923 break; 2924 2925 case OPTION_NO_CHANGE_WARNINGS: 2926 change_warn = FALSE; 2927 break; 2928 2929 case OPTION_PAD_TO: 2930 pad_to = parse_vma (optarg, "--pad-to"); 2931 pad_to_set = TRUE; 2932 break; 2933 2934 case OPTION_REMOVE_LEADING_CHAR: 2935 remove_leading_char = TRUE; 2936 break; 2937 2938 case OPTION_REDEFINE_SYM: 2939 { 2940 /* Push this redefinition onto redefine_symbol_list. */ 2941 2942 int len; 2943 const char *s; 2944 const char *nextarg; 2945 char *source, *target; 2946 2947 s = strchr (optarg, '='); 2948 if (s == NULL) 2949 fatal (_("bad format for %s"), "--redefine-sym"); 2950 2951 len = s - optarg; 2952 source = xmalloc (len + 1); 2953 strncpy (source, optarg, len); 2954 source[len] = '\0'; 2955 2956 nextarg = s + 1; 2957 len = strlen (nextarg); 2958 target = xmalloc (len + 1); 2959 strcpy (target, nextarg); 2960 2961 redefine_list_append ("--redefine-sym", source, target); 2962 2963 free (source); 2964 free (target); 2965 } 2966 break; 2967 2968 case OPTION_REDEFINE_SYMS: 2969 add_redefine_syms_file (optarg); 2970 break; 2971 2972 case OPTION_SET_SECTION_FLAGS: 2973 { 2974 const char *s; 2975 int len; 2976 char *name; 2977 2978 s = strchr (optarg, '='); 2979 if (s == NULL) 2980 fatal (_("bad format for %s"), "--set-section-flags"); 2981 2982 len = s - optarg; 2983 name = xmalloc (len + 1); 2984 strncpy (name, optarg, len); 2985 name[len] = '\0'; 2986 2987 p = find_section_list (name, TRUE); 2988 2989 p->set_flags = TRUE; 2990 p->flags = parse_flags (s + 1); 2991 } 2992 break; 2993 2994 case OPTION_RENAME_SECTION: 2995 { 2996 flagword flags; 2997 const char *eq, *fl; 2998 char *old_name; 2999 char *new_name; 3000 unsigned int len; 3001 3002 eq = strchr (optarg, '='); 3003 if (eq == NULL) 3004 fatal (_("bad format for %s"), "--rename-section"); 3005 3006 len = eq - optarg; 3007 if (len == 0) 3008 fatal (_("bad format for %s"), "--rename-section"); 3009 3010 old_name = xmalloc (len + 1); 3011 strncpy (old_name, optarg, len); 3012 old_name[len] = 0; 3013 3014 eq++; 3015 fl = strchr (eq, ','); 3016 if (fl) 3017 { 3018 flags = parse_flags (fl + 1); 3019 len = fl - eq; 3020 } 3021 else 3022 { 3023 flags = -1; 3024 len = strlen (eq); 3025 } 3026 3027 if (len == 0) 3028 fatal (_("bad format for %s"), "--rename-section"); 3029 3030 new_name = xmalloc (len + 1); 3031 strncpy (new_name, eq, len); 3032 new_name[len] = 0; 3033 3034 add_section_rename (old_name, new_name, flags); 3035 } 3036 break; 3037 3038 case OPTION_SET_START: 3039 set_start = parse_vma (optarg, "--set-start"); 3040 set_start_set = TRUE; 3041 break; 3042 3043 case OPTION_SREC_LEN: 3044 Chunk = parse_vma (optarg, "--srec-len"); 3045 break; 3046 3047 case OPTION_SREC_FORCES3: 3048 S3Forced = TRUE; 3049 break; 3050 3051 case OPTION_STRIP_SYMBOLS: 3052 add_specific_symbols (optarg, &strip_specific_list); 3053 break; 3054 3055 case OPTION_STRIP_UNNEEDED_SYMBOLS: 3056 add_specific_symbols (optarg, &strip_unneeded_list); 3057 break; 3058 3059 case OPTION_KEEP_SYMBOLS: 3060 add_specific_symbols (optarg, &keep_specific_list); 3061 break; 3062 3063 case OPTION_LOCALIZE_SYMBOLS: 3064 add_specific_symbols (optarg, &localize_specific_list); 3065 break; 3066 3067 case OPTION_GLOBALIZE_SYMBOLS: 3068 add_specific_symbols (optarg, &globalize_specific_list); 3069 break; 3070 3071 case OPTION_KEEPGLOBAL_SYMBOLS: 3072 add_specific_symbols (optarg, &keepglobal_specific_list); 3073 break; 3074 3075 case OPTION_WEAKEN_SYMBOLS: 3076 add_specific_symbols (optarg, &weaken_specific_list); 3077 break; 3078 3079 case OPTION_ALT_MACH_CODE: 3080 use_alt_mach_code = strtoul (optarg, NULL, 0); 3081 if (use_alt_mach_code == 0) 3082 fatal (_("unable to parse alternative machine code")); 3083 break; 3084 3085 case OPTION_PREFIX_SYMBOLS: 3086 prefix_symbols_string = optarg; 3087 break; 3088 3089 case OPTION_PREFIX_SECTIONS: 3090 prefix_sections_string = optarg; 3091 break; 3092 3093 case OPTION_PREFIX_ALLOC_SECTIONS: 3094 prefix_alloc_sections_string = optarg; 3095 break; 3096 3097 case OPTION_READONLY_TEXT: 3098 bfd_flags_to_set |= WP_TEXT; 3099 bfd_flags_to_clear &= ~WP_TEXT; 3100 break; 3101 3102 case OPTION_WRITABLE_TEXT: 3103 bfd_flags_to_clear |= WP_TEXT; 3104 bfd_flags_to_set &= ~WP_TEXT; 3105 break; 3106 3107 case OPTION_PURE: 3108 bfd_flags_to_set |= D_PAGED; 3109 bfd_flags_to_clear &= ~D_PAGED; 3110 break; 3111 3112 case OPTION_IMPURE: 3113 bfd_flags_to_clear |= D_PAGED; 3114 bfd_flags_to_set &= ~D_PAGED; 3115 break; 3116 3117 case 0: 3118 /* We've been given a long option. */ 3119 break; 3120 3121 case 'H': 3122 case 'h': 3123 copy_usage (stdout, 0); 3124 3125 default: 3126 copy_usage (stderr, 1); 3127 } 3128 } 3129 3130 if (formats_info) 3131 { 3132 display_info (); 3133 return 0; 3134 } 3135 3136 if (show_version) 3137 print_version ("objcopy"); 3138 3139 if (copy_byte >= interleave) 3140 fatal (_("byte number must be less than interleave")); 3141 3142 if (optind == argc || optind + 2 < argc) 3143 copy_usage (stderr, 1); 3144 3145 input_filename = argv[optind]; 3146 if (optind + 1 < argc) 3147 output_filename = argv[optind + 1]; 3148 3149 /* Default is to strip no symbols. */ 3150 if (strip_symbols == STRIP_UNDEF && discard_locals == LOCALS_UNDEF) 3151 strip_symbols = STRIP_NONE; 3152 3153 if (output_target == NULL) 3154 output_target = input_target; 3155 3156 if (binary_architecture != NULL) 3157 { 3158 if (input_target && strcmp (input_target, "binary") == 0) 3159 { 3160 const bfd_arch_info_type * temp_arch_info; 3161 3162 temp_arch_info = bfd_scan_arch (binary_architecture); 3163 3164 if (temp_arch_info != NULL) 3165 { 3166 bfd_external_binary_architecture = temp_arch_info->arch; 3167 bfd_external_machine = temp_arch_info->mach; 3168 } 3169 else 3170 fatal (_("architecture %s unknown"), binary_architecture); 3171 } 3172 else 3173 { 3174 non_fatal (_("Warning: input target 'binary' required for binary architecture parameter.")); 3175 non_fatal (_(" Argument %s ignored"), binary_architecture); 3176 } 3177 } 3178 3179 if (preserve_dates) 3180 if (stat (input_filename, & statbuf) < 0) 3181 fatal (_("warning: could not locate '%s'. System error message: %s"), 3182 input_filename, strerror (errno)); 3183 3184 /* If there is no destination file, or the source and destination files 3185 are the same, then create a temp and rename the result into the input. */ 3186 if (output_filename == NULL || strcmp (input_filename, output_filename) == 0) 3187 { 3188 char *tmpname = make_tempname (input_filename, 0); 3189 3190 copy_file (input_filename, tmpname, input_target, output_target); 3191 if (status == 0) 3192 { 3193 if (preserve_dates) 3194 set_times (tmpname, &statbuf); 3195 smart_rename (tmpname, input_filename, preserve_dates); 3196 } 3197 else 3198 unlink (tmpname); 3199 } 3200 else 3201 { 3202 copy_file (input_filename, output_filename, input_target, output_target); 3203 3204 if (status == 0 && preserve_dates) 3205 set_times (output_filename, &statbuf); 3206 else if (status != 0) 3207 unlink_if_ordinary (output_filename); 3208 } 3209 3210 if (change_warn) 3211 { 3212 for (p = change_sections; p != NULL; p = p->next) 3213 { 3214 if (! p->used) 3215 { 3216 if (p->change_vma != CHANGE_IGNORE) 3217 { 3218 char buff [20]; 3219 3220 sprintf_vma (buff, p->vma_val); 3221 3222 /* xgettext:c-format */ 3223 non_fatal (_("%s %s%c0x%s never used"), 3224 "--change-section-vma", 3225 p->name, 3226 p->change_vma == CHANGE_SET ? '=' : '+', 3227 buff); 3228 } 3229 3230 if (p->change_lma != CHANGE_IGNORE) 3231 { 3232 char buff [20]; 3233 3234 sprintf_vma (buff, p->lma_val); 3235 3236 /* xgettext:c-format */ 3237 non_fatal (_("%s %s%c0x%s never used"), 3238 "--change-section-lma", 3239 p->name, 3240 p->change_lma == CHANGE_SET ? '=' : '+', 3241 buff); 3242 } 3243 } 3244 } 3245 } 3246 3247 return 0; 3248 } 3249 3250 int 3251 main (int argc, char *argv[]) 3252 { 3253 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES) 3254 setlocale (LC_MESSAGES, ""); 3255 #endif 3256 #if defined (HAVE_SETLOCALE) 3257 setlocale (LC_CTYPE, ""); 3258 #endif 3259 bindtextdomain (PACKAGE, LOCALEDIR); 3260 textdomain (PACKAGE); 3261 3262 program_name = argv[0]; 3263 xmalloc_set_program_name (program_name); 3264 3265 START_PROGRESS (program_name, 0); 3266 3267 if (pledge ("stdio rpath wpath cpath fattr", NULL) == -1) 3268 fatal (_("pledge: %s"), strerror (errno)); 3269 3270 expandargv (&argc, &argv); 3271 3272 strip_symbols = STRIP_UNDEF; 3273 discard_locals = LOCALS_UNDEF; 3274 3275 bfd_init (); 3276 set_default_bfd_target (); 3277 3278 if (is_strip < 0) 3279 { 3280 int i = strlen (program_name); 3281 #ifdef HAVE_DOS_BASED_FILE_SYSTEM 3282 /* Drop the .exe suffix, if any. */ 3283 if (i > 4 && FILENAME_CMP (program_name + i - 4, ".exe") == 0) 3284 { 3285 i -= 4; 3286 program_name[i] = '\0'; 3287 } 3288 #endif 3289 is_strip = (i >= 5 && FILENAME_CMP (program_name + i - 5, "strip") == 0); 3290 } 3291 3292 if (is_strip) 3293 strip_main (argc, argv); 3294 else 3295 copy_main (argc, argv); 3296 3297 END_PROGRESS (program_name); 3298 3299 return status; 3300 } 3301