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