1 /* objcopy.c -- copy object file from input to output, optionally massaging it. 2 Copyright (C) 1991, 92, 93, 94, 95, 96, 97, 98, 99, 2000 3 Free Software Foundation, Inc. 4 5 This file is part of GNU Binutils. 6 7 This program is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 2 of the License, or 10 (at your option) any later version. 11 12 This program is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program; if not, write to the Free Software 19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 20 02111-1307, USA. */ 21 22 #include "bfd.h" 23 #include "progress.h" 24 #include "bucomm.h" 25 #include "getopt.h" 26 #include "libiberty.h" 27 #include "budbg.h" 28 #include "filenames.h" 29 #include <sys/stat.h> 30 31 /* A list of symbols to explicitly strip out, or to keep. A linked 32 list is good enough for a small number from the command line, but 33 this will slow things down a lot if many symbols are being 34 deleted. */ 35 36 struct symlist 37 { 38 const char *name; 39 struct symlist *next; 40 }; 41 42 /* A list to support redefine_sym. */ 43 struct redefine_node 44 { 45 char *source; 46 char *target; 47 struct redefine_node *next; 48 }; 49 50 static void copy_usage PARAMS ((FILE *, int)); 51 static void strip_usage PARAMS ((FILE *, int)); 52 static flagword parse_flags PARAMS ((const char *)); 53 static struct section_list *find_section_list PARAMS ((const char *, boolean)); 54 static void setup_section PARAMS ((bfd *, asection *, PTR)); 55 static void copy_section PARAMS ((bfd *, asection *, PTR)); 56 static void get_sections PARAMS ((bfd *, asection *, PTR)); 57 static int compare_section_lma PARAMS ((const PTR, const PTR)); 58 static void add_specific_symbol PARAMS ((const char *, struct symlist **)); 59 static boolean is_specified_symbol PARAMS ((const char *, struct symlist *)); 60 static boolean is_strip_section PARAMS ((bfd *, asection *)); 61 static unsigned int filter_symbols 62 PARAMS ((bfd *, bfd *, asymbol **, asymbol **, long)); 63 static void mark_symbols_used_in_relocations PARAMS ((bfd *, asection *, PTR)); 64 static void filter_bytes PARAMS ((char *, bfd_size_type *)); 65 static boolean write_debugging_info PARAMS ((bfd *, PTR, long *, asymbol ***)); 66 static void copy_object PARAMS ((bfd *, bfd *)); 67 static void copy_archive PARAMS ((bfd *, bfd *, const char *)); 68 static void copy_file 69 PARAMS ((const char *, const char *, const char *, const char *)); 70 static int strip_main PARAMS ((int, char **)); 71 static int copy_main PARAMS ((int, char **)); 72 static const char *lookup_sym_redefinition PARAMS((const char *)); 73 static void redefine_list_append PARAMS ((const char *, const char *)); 74 75 #define RETURN_NONFATAL(s) {bfd_nonfatal (s); status = 1; return;} 76 77 static asymbol **isympp = NULL; /* Input symbols */ 78 static asymbol **osympp = NULL; /* Output symbols that survive stripping */ 79 80 /* If `copy_byte' >= 0, copy only that byte of every `interleave' bytes. */ 81 static int copy_byte = -1; 82 static int interleave = 4; 83 84 static boolean verbose; /* Print file and target names. */ 85 static boolean preserve_dates; /* Preserve input file timestamp. */ 86 static int status = 0; /* Exit status. */ 87 88 enum strip_action 89 { 90 STRIP_UNDEF, 91 STRIP_NONE, /* don't strip */ 92 STRIP_DEBUG, /* strip all debugger symbols */ 93 STRIP_UNNEEDED, /* strip unnecessary symbols */ 94 STRIP_ALL /* strip all symbols */ 95 }; 96 97 /* Which symbols to remove. */ 98 static enum strip_action strip_symbols; 99 100 enum locals_action 101 { 102 LOCALS_UNDEF, 103 LOCALS_START_L, /* discard locals starting with L */ 104 LOCALS_ALL /* discard all locals */ 105 }; 106 107 /* Which local symbols to remove. Overrides STRIP_ALL. */ 108 static enum locals_action discard_locals; 109 110 /* What kind of change to perform. */ 111 enum change_action 112 { 113 CHANGE_IGNORE, 114 CHANGE_MODIFY, 115 CHANGE_SET 116 }; 117 118 /* Structure used to hold lists of sections and actions to take. */ 119 struct section_list 120 { 121 struct section_list * next; /* Next section to change. */ 122 const char * name; /* Section name. */ 123 boolean used; /* Whether this entry was used. */ 124 boolean remove; /* Whether to remove this section. */ 125 boolean copy; /* Whether to copy this section. */ 126 enum change_action change_vma;/* Whether to change or set VMA. */ 127 bfd_vma vma_val; /* Amount to change by or set to. */ 128 enum change_action change_lma;/* Whether to change or set LMA. */ 129 bfd_vma lma_val; /* Amount to change by or set to. */ 130 boolean set_flags; /* Whether to set the section flags. */ 131 flagword flags; /* What to set the section flags to. */ 132 }; 133 134 static struct section_list *change_sections; 135 static boolean sections_removed; 136 static boolean sections_copied; 137 138 /* Changes to the start address. */ 139 static bfd_vma change_start = 0; 140 static boolean set_start_set = false; 141 static bfd_vma set_start; 142 143 /* Changes to section addresses. */ 144 static bfd_vma change_section_address = 0; 145 146 /* Filling gaps between sections. */ 147 static boolean gap_fill_set = false; 148 static bfd_byte gap_fill = 0; 149 150 /* Pad to a given address. */ 151 static boolean pad_to_set = false; 152 static bfd_vma pad_to; 153 154 /* List of sections to add. */ 155 156 struct section_add 157 { 158 /* Next section to add. */ 159 struct section_add *next; 160 /* Name of section to add. */ 161 const char *name; 162 /* Name of file holding section contents. */ 163 const char *filename; 164 /* Size of file. */ 165 size_t size; 166 /* Contents of file. */ 167 bfd_byte *contents; 168 /* BFD section, after it has been added. */ 169 asection *section; 170 }; 171 172 static struct section_add *add_sections; 173 174 /* Whether to convert debugging information. */ 175 176 static boolean convert_debugging = false; 177 178 /* Whether to change the leading character in symbol names. */ 179 180 static boolean change_leading_char = false; 181 182 /* Whether to remove the leading character from global symbol names. */ 183 184 static boolean remove_leading_char = false; 185 186 /* List of symbols to strip, keep, localize, weaken, or redefine. */ 187 188 static struct symlist *strip_specific_list = NULL; 189 static struct symlist *keep_specific_list = NULL; 190 static struct symlist *localize_specific_list = NULL; 191 static struct symlist *weaken_specific_list = NULL; 192 static struct redefine_node *redefine_sym_list = NULL; 193 194 /* If this is true, we weaken global symbols (set BSF_WEAK). */ 195 196 static boolean weaken = false; 197 198 /* 150 isn't special; it's just an arbitrary non-ASCII char value. */ 199 200 #define OPTION_ADD_SECTION 150 201 #define OPTION_CHANGE_ADDRESSES (OPTION_ADD_SECTION + 1) 202 #define OPTION_CHANGE_LEADING_CHAR (OPTION_CHANGE_ADDRESSES + 1) 203 #define OPTION_CHANGE_START (OPTION_CHANGE_LEADING_CHAR + 1) 204 #define OPTION_CHANGE_SECTION_ADDRESS (OPTION_CHANGE_START + 1) 205 #define OPTION_CHANGE_SECTION_LMA (OPTION_CHANGE_SECTION_ADDRESS + 1) 206 #define OPTION_CHANGE_SECTION_VMA (OPTION_CHANGE_SECTION_LMA + 1) 207 #define OPTION_CHANGE_WARNINGS (OPTION_CHANGE_SECTION_VMA + 1) 208 #define OPTION_DEBUGGING (OPTION_CHANGE_WARNINGS + 1) 209 #define OPTION_GAP_FILL (OPTION_DEBUGGING + 1) 210 #define OPTION_NO_CHANGE_WARNINGS (OPTION_GAP_FILL + 1) 211 #define OPTION_PAD_TO (OPTION_NO_CHANGE_WARNINGS + 1) 212 #define OPTION_REMOVE_LEADING_CHAR (OPTION_PAD_TO + 1) 213 #define OPTION_SET_SECTION_FLAGS (OPTION_REMOVE_LEADING_CHAR + 1) 214 #define OPTION_SET_START (OPTION_SET_SECTION_FLAGS + 1) 215 #define OPTION_STRIP_UNNEEDED (OPTION_SET_START + 1) 216 #define OPTION_WEAKEN (OPTION_STRIP_UNNEEDED + 1) 217 #define OPTION_REDEFINE_SYM (OPTION_WEAKEN + 1) 218 219 /* Options to handle if running as "strip". */ 220 221 static struct option strip_options[] = 222 { 223 {"discard-all", no_argument, 0, 'x'}, 224 {"discard-locals", no_argument, 0, 'X'}, 225 {"format", required_argument, 0, 'F'}, /* Obsolete */ 226 {"help", no_argument, 0, 'h'}, 227 {"input-format", required_argument, 0, 'I'}, /* Obsolete */ 228 {"input-target", required_argument, 0, 'I'}, 229 {"keep-symbol", required_argument, 0, 'K'}, 230 {"output-format", required_argument, 0, 'O'}, /* Obsolete */ 231 {"output-target", required_argument, 0, 'O'}, 232 {"preserve-dates", no_argument, 0, 'p'}, 233 {"remove-section", required_argument, 0, 'R'}, 234 {"strip-all", no_argument, 0, 's'}, 235 {"strip-debug", no_argument, 0, 'S'}, 236 {"strip-unneeded", no_argument, 0, OPTION_STRIP_UNNEEDED}, 237 {"strip-symbol", required_argument, 0, 'N'}, 238 {"target", required_argument, 0, 'F'}, 239 {"verbose", no_argument, 0, 'v'}, 240 {"version", no_argument, 0, 'V'}, 241 {0, no_argument, 0, 0} 242 }; 243 244 /* Options to handle if running as "objcopy". */ 245 246 static struct option copy_options[] = 247 { 248 {"add-section", required_argument, 0, OPTION_ADD_SECTION}, 249 {"adjust-start", required_argument, 0, OPTION_CHANGE_START}, 250 {"adjust-vma", required_argument, 0, OPTION_CHANGE_ADDRESSES}, 251 {"adjust-section-vma", required_argument, 0, OPTION_CHANGE_SECTION_ADDRESS}, 252 {"adjust-warnings", no_argument, 0, OPTION_CHANGE_WARNINGS}, 253 {"byte", required_argument, 0, 'b'}, 254 {"change-addresses", required_argument, 0, OPTION_CHANGE_ADDRESSES}, 255 {"change-leading-char", no_argument, 0, OPTION_CHANGE_LEADING_CHAR}, 256 {"change-section-address", required_argument, 0, OPTION_CHANGE_SECTION_ADDRESS}, 257 {"change-section-lma", required_argument, 0, OPTION_CHANGE_SECTION_LMA}, 258 {"change-section-vma", required_argument, 0, OPTION_CHANGE_SECTION_VMA}, 259 {"change-start", required_argument, 0, OPTION_CHANGE_START}, 260 {"change-warnings", no_argument, 0, OPTION_CHANGE_WARNINGS}, 261 {"debugging", no_argument, 0, OPTION_DEBUGGING}, 262 {"discard-all", no_argument, 0, 'x'}, 263 {"discard-locals", no_argument, 0, 'X'}, 264 {"only-section", required_argument, 0, 'j'}, 265 {"format", required_argument, 0, 'F'}, /* Obsolete */ 266 {"gap-fill", required_argument, 0, OPTION_GAP_FILL}, 267 {"help", no_argument, 0, 'h'}, 268 {"input-format", required_argument, 0, 'I'}, /* Obsolete */ 269 {"input-target", required_argument, 0, 'I'}, 270 {"interleave", required_argument, 0, 'i'}, 271 {"keep-symbol", required_argument, 0, 'K'}, 272 {"no-adjust-warnings", no_argument, 0, OPTION_NO_CHANGE_WARNINGS}, 273 {"no-change-warnings", no_argument, 0, OPTION_NO_CHANGE_WARNINGS}, 274 {"output-format", required_argument, 0, 'O'}, /* Obsolete */ 275 {"output-target", required_argument, 0, 'O'}, 276 {"pad-to", required_argument, 0, OPTION_PAD_TO}, 277 {"preserve-dates", no_argument, 0, 'p'}, 278 {"localize-symbol", required_argument, 0, 'L'}, 279 {"remove-leading-char", no_argument, 0, OPTION_REMOVE_LEADING_CHAR}, 280 {"remove-section", required_argument, 0, 'R'}, 281 {"set-section-flags", required_argument, 0, OPTION_SET_SECTION_FLAGS}, 282 {"set-start", required_argument, 0, OPTION_SET_START}, 283 {"strip-all", no_argument, 0, 'S'}, 284 {"strip-debug", no_argument, 0, 'g'}, 285 {"strip-unneeded", no_argument, 0, OPTION_STRIP_UNNEEDED}, 286 {"strip-symbol", required_argument, 0, 'N'}, 287 {"target", required_argument, 0, 'F'}, 288 {"verbose", no_argument, 0, 'v'}, 289 {"version", no_argument, 0, 'V'}, 290 {"weaken", no_argument, 0, OPTION_WEAKEN}, 291 {"weaken-symbol", required_argument, 0, 'W'}, 292 {"redefine-sym", required_argument, 0, OPTION_REDEFINE_SYM}, 293 {0, no_argument, 0, 0} 294 }; 295 296 /* IMPORTS */ 297 extern char *program_name; 298 299 /* This flag distinguishes between strip and objcopy: 300 1 means this is 'strip'; 0 means this is 'objcopy'. 301 -1 means if we should use argv[0] to decide. */ 302 extern int is_strip; 303 304 305 static void 306 copy_usage (stream, exit_status) 307 FILE *stream; 308 int exit_status; 309 { 310 fprintf (stream, _("Usage: %s <switches> in-file [out-file]\n"), program_name); 311 fprintf (stream, _(" The switches are:\n")); 312 fprintf (stream, _("\ 313 -I --input-target <bfdname> Assume input file is in format <bfdname>\n\ 314 -O --output-target <bfdname> Create an output file in format <bfdname>\n\ 315 -F --target <bfdname> Set both input and output format to <bfdname>\n\ 316 --debugging Convert debugging information, if possible\n\ 317 -p --preserve-dates Copy modified/access timestamps to the output\n\ 318 -j --only-section <name> Only copy section <name> into the output\n\ 319 -R --remove-section <name> Remove section <name> from the output\n\ 320 -S --strip-all Remove all symbol and relocation information\n\ 321 -g --strip-debug Remove all debugging symbols\n\ 322 --strip-unneeded Remove all symbols not needed by relocations\n\ 323 -N --strip-symbol <name> Do not copy symbol <name>\n\ 324 -K --keep-symbol <name> Only copy symbol <name>\n\ 325 -L --localize-symbol <name> Force symbol <name> to be marked as a local\n\ 326 -W --weaken-symbol <name> Force symbol <name> to be marked as a weak\n\ 327 --weaken Force all global symbols to be marked as weak\n\ 328 -x --discard-all Remove all non-global symbols\n\ 329 -X --discard-locals Remove any compiler-generated symbols\n\ 330 -i --interleave <number> Only copy one out of every <number> bytes\n\ 331 -b --byte <num> Select byte <num> in every interleaved block\n\ 332 --gap-fill <val> Fill gaps between sections with <val>\n\ 333 --pad-to <addr> Pad the last section up to address <addr>\n\ 334 --set-start <addr> Set the start address to <addr>\n\ 335 {--change-start|--adjust-start} <incr>\n\ 336 Add <incr> to the start address\n\ 337 {--change-addresses|--adjust-vma} <incr>\n\ 338 Add <incr> to LMA, VMA and start addresses\n\ 339 {--change-section-address|--adjust-section-vma} <name>{=|+|-}<val>\n\ 340 Change LMA and VMA of section <name> by <val>\n\ 341 --change-section-lma <name>{=|+|-}<val>\n\ 342 Change the LMA of section <name> by <val>\n\ 343 --change-section-vma <name>{=|+|-}<val>\n\ 344 Change the VMA of section <name> by <val>\n\ 345 {--[no-]change-warnings|--[no-]adjust-warnings}\n\ 346 Warn if a named section does not exist\n\ 347 --set-section-flags <name>=<flags>\n\ 348 Set section <name>'s properties to <flags>\n\ 349 --add-section <name>=<file> Add section <name> found in <file> to output\n\ 350 --change-leading-char Force output format's leading character style\n\ 351 --remove-leading-char Remove leading character from global symbols\n\ 352 --redefine-sym <old>=<new> Redefine symbol name <old> to <new>\n\ 353 -v --verbose List all object files modified\n\ 354 -V --version Display this program's version number\n\ 355 -h --help Display this output\n\ 356 ")); 357 list_supported_targets (program_name, stream); 358 if (exit_status == 0) 359 fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO); 360 exit (exit_status); 361 } 362 363 static void 364 strip_usage (stream, exit_status) 365 FILE *stream; 366 int exit_status; 367 { 368 fprintf (stream, _("Usage: %s <switches> in-file(s)\n"), program_name); 369 fprintf (stream, _(" The switches are:\n")); 370 fprintf (stream, _("\ 371 -I --input-target <bfdname> Assume input file is in format <bfdname>\n\ 372 -O --output-target <bfdname> Create an output file in format <bfdname>\n\ 373 -F --target <bfdname> Set both input and output format to <bfdname>\n\ 374 -p --preserve-dates Copy modified/access timestamps to the output\n\ 375 -R --remove-section <name> Remove section <name> from the output\n\ 376 -s --strip-all Remove all symbol and relocation information\n\ 377 -g -S --strip-debug Remove all debugging symbols\n\ 378 --strip-unneeded Remove all symbols not needed by relocations\n\ 379 -N --strip-symbol <name> Do not copy symbol <name>\n\ 380 -K --keep-symbol <name> Only copy symbol <name>\n\ 381 -x --discard-all Remove all non-global symbols\n\ 382 -X --discard-locals Remove any compiler-generated symbols\n\ 383 -v --verbose List all object files modified\n\ 384 -V --version Display this program's version number\n\ 385 -h --help Display this output\n\ 386 -o <file> Place stripped output into <file>\n\ 387 ")); 388 389 list_supported_targets (program_name, stream); 390 if (exit_status == 0) 391 fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO); 392 exit (exit_status); 393 } 394 395 /* Parse section flags into a flagword, with a fatal error if the 396 string can't be parsed. */ 397 398 static flagword 399 parse_flags (s) 400 const char *s; 401 { 402 flagword ret; 403 const char *snext; 404 int len; 405 406 ret = SEC_NO_FLAGS; 407 408 do 409 { 410 snext = strchr (s, ','); 411 if (snext == NULL) 412 len = strlen (s); 413 else 414 { 415 len = snext - s; 416 ++snext; 417 } 418 419 if (0) ; 420 #define PARSE_FLAG(fname,fval) \ 421 else if (strncasecmp (fname, s, len) == 0) ret |= fval 422 PARSE_FLAG ("alloc", SEC_ALLOC); 423 PARSE_FLAG ("load", SEC_LOAD); 424 PARSE_FLAG ("noload", SEC_NEVER_LOAD); 425 PARSE_FLAG ("readonly", SEC_READONLY); 426 PARSE_FLAG ("debug", SEC_DEBUGGING); 427 PARSE_FLAG ("code", SEC_CODE); 428 PARSE_FLAG ("data", SEC_DATA); 429 PARSE_FLAG ("rom", SEC_ROM); 430 PARSE_FLAG ("share", SEC_SHARED); 431 PARSE_FLAG ("contents", SEC_HAS_CONTENTS); 432 #undef PARSE_FLAG 433 else 434 { 435 char *copy; 436 437 copy = xmalloc (len + 1); 438 strncpy (copy, s, len); 439 copy[len] = '\0'; 440 non_fatal (_("unrecognized section flag `%s'"), copy); 441 fatal (_("supported flags: %s"), 442 "alloc, load, noload, readonly, debug, code, data, rom, share, contents"); 443 } 444 445 s = snext; 446 } 447 while (s != NULL); 448 449 return ret; 450 } 451 452 /* Find and optionally add an entry in the change_sections list. */ 453 454 static struct section_list * 455 find_section_list (name, add) 456 const char *name; 457 boolean add; 458 { 459 register struct section_list *p; 460 461 for (p = change_sections; p != NULL; p = p->next) 462 if (strcmp (p->name, name) == 0) 463 return p; 464 465 if (! add) 466 return NULL; 467 468 p = (struct section_list *) xmalloc (sizeof (struct section_list)); 469 p->name = name; 470 p->used = false; 471 p->remove = false; 472 p->copy = false; 473 p->change_vma = CHANGE_IGNORE; 474 p->change_lma = CHANGE_IGNORE; 475 p->vma_val = 0; 476 p->lma_val = 0; 477 p->set_flags = false; 478 p->flags = 0; 479 480 p->next = change_sections; 481 change_sections = p; 482 483 return p; 484 } 485 486 /* Add a symbol to strip_specific_list. */ 487 488 static void 489 add_specific_symbol (name, list) 490 const char *name; 491 struct symlist **list; 492 { 493 struct symlist *tmp_list; 494 495 tmp_list = (struct symlist *) xmalloc (sizeof (struct symlist)); 496 tmp_list->name = name; 497 tmp_list->next = *list; 498 *list = tmp_list; 499 } 500 501 /* See whether a symbol should be stripped or kept based on 502 strip_specific_list and keep_symbols. */ 503 504 static boolean 505 is_specified_symbol (name, list) 506 const char *name; 507 struct symlist *list; 508 { 509 struct symlist *tmp_list; 510 511 for (tmp_list = list; tmp_list; tmp_list = tmp_list->next) 512 { 513 if (strcmp (name, tmp_list->name) == 0) 514 return true; 515 } 516 return false; 517 } 518 519 /* See if a section is being removed. */ 520 521 static boolean 522 is_strip_section (abfd, sec) 523 bfd *abfd ATTRIBUTE_UNUSED; 524 asection *sec; 525 { 526 struct section_list *p; 527 528 if ((bfd_get_section_flags (abfd, sec) & SEC_DEBUGGING) != 0 529 && (strip_symbols == STRIP_DEBUG 530 || strip_symbols == STRIP_UNNEEDED 531 || strip_symbols == STRIP_ALL 532 || discard_locals == LOCALS_ALL 533 || convert_debugging)) 534 return true; 535 536 if (! sections_removed && ! sections_copied) 537 return false; 538 539 p = find_section_list (bfd_get_section_name (abfd, sec), false); 540 if (sections_removed && p != NULL && p->remove) 541 return true; 542 if (sections_copied && (p == NULL || ! p->copy)) 543 return true; 544 return false; 545 } 546 547 /* Choose which symbol entries to copy; put the result in OSYMS. 548 We don't copy in place, because that confuses the relocs. 549 Return the number of symbols to print. */ 550 551 static unsigned int 552 filter_symbols (abfd, obfd, osyms, isyms, symcount) 553 bfd *abfd; 554 bfd *obfd; 555 asymbol **osyms, **isyms; 556 long symcount; 557 { 558 register asymbol **from = isyms, **to = osyms; 559 long src_count = 0, dst_count = 0; 560 561 for (; src_count < symcount; src_count++) 562 { 563 asymbol *sym = from[src_count]; 564 flagword flags = sym->flags; 565 const char *name = bfd_asymbol_name (sym); 566 int keep; 567 568 if (redefine_sym_list) 569 { 570 const char *old_name, *new_name; 571 572 old_name = bfd_asymbol_name (sym); 573 new_name = lookup_sym_redefinition (old_name); 574 name = bfd_asymbol_name (sym) = new_name; 575 } 576 577 if (change_leading_char 578 && (bfd_get_symbol_leading_char (abfd) 579 != bfd_get_symbol_leading_char (obfd)) 580 && (bfd_get_symbol_leading_char (abfd) == '\0' 581 || (name[0] == bfd_get_symbol_leading_char (abfd)))) 582 { 583 if (bfd_get_symbol_leading_char (obfd) == '\0') 584 name = bfd_asymbol_name (sym) = name + 1; 585 else 586 { 587 char *n; 588 589 n = xmalloc (strlen (name) + 2); 590 n[0] = bfd_get_symbol_leading_char (obfd); 591 if (bfd_get_symbol_leading_char (abfd) == '\0') 592 strcpy (n + 1, name); 593 else 594 strcpy (n + 1, name + 1); 595 name = bfd_asymbol_name (sym) = n; 596 } 597 } 598 599 if (remove_leading_char 600 && ((flags & BSF_GLOBAL) != 0 601 || (flags & BSF_WEAK) != 0 602 || bfd_is_und_section (bfd_get_section (sym)) 603 || bfd_is_com_section (bfd_get_section (sym))) 604 && name[0] == bfd_get_symbol_leading_char (abfd)) 605 name = bfd_asymbol_name (sym) = name + 1; 606 607 if (strip_symbols == STRIP_ALL) 608 keep = 0; 609 else if ((flags & BSF_KEEP) != 0 /* Used in relocation. */ 610 || ((flags & BSF_SECTION_SYM) != 0 611 && ((*bfd_get_section (sym)->symbol_ptr_ptr)->flags 612 & BSF_KEEP) != 0)) 613 keep = 1; 614 else if ((flags & BSF_GLOBAL) != 0 /* Global symbol. */ 615 || (flags & BSF_WEAK) != 0 616 || bfd_is_und_section (bfd_get_section (sym)) 617 || bfd_is_com_section (bfd_get_section (sym))) 618 keep = strip_symbols != STRIP_UNNEEDED; 619 else if ((flags & BSF_DEBUGGING) != 0) /* Debugging symbol. */ 620 keep = (strip_symbols != STRIP_DEBUG 621 && strip_symbols != STRIP_UNNEEDED 622 && ! convert_debugging); 623 else /* Local symbol. */ 624 keep = (strip_symbols != STRIP_UNNEEDED 625 && (discard_locals != LOCALS_ALL 626 && (discard_locals != LOCALS_START_L 627 || ! bfd_is_local_label (abfd, sym)))); 628 629 if (keep && is_specified_symbol (name, strip_specific_list)) 630 keep = 0; 631 if (!keep && is_specified_symbol (name, keep_specific_list)) 632 keep = 1; 633 if (keep && is_strip_section (abfd, bfd_get_section (sym))) 634 keep = 0; 635 636 if (keep && (flags & BSF_GLOBAL) != 0 637 && (weaken || is_specified_symbol (name, weaken_specific_list))) 638 { 639 sym->flags &=~ BSF_GLOBAL; 640 sym->flags |= BSF_WEAK; 641 } 642 if (keep && (flags & (BSF_GLOBAL | BSF_WEAK)) 643 && is_specified_symbol (name, localize_specific_list)) 644 { 645 sym->flags &= ~(BSF_GLOBAL | BSF_WEAK); 646 sym->flags |= BSF_LOCAL; 647 } 648 649 if (keep) 650 to[dst_count++] = sym; 651 } 652 653 to[dst_count] = NULL; 654 655 return dst_count; 656 } 657 658 static const char * 659 lookup_sym_redefinition (source) 660 const char *source; 661 { 662 const char *result; 663 struct redefine_node *list; 664 665 result = source; 666 667 for (list = redefine_sym_list; list != NULL; list = list->next) 668 { 669 if (strcmp (source, list->source) == 0) 670 { 671 result = list->target; 672 break; 673 } 674 } 675 return result; 676 } 677 678 /* Add a node to a symbol redefine list */ 679 680 static void 681 redefine_list_append (source, target) 682 const char *source; 683 const char *target; 684 { 685 struct redefine_node **p; 686 struct redefine_node *list; 687 struct redefine_node *new_node; 688 689 for (p = &redefine_sym_list; (list = *p) != NULL; p = &list->next) 690 { 691 if (strcmp (source, list->source) == 0) 692 { 693 fatal (_("%s: Multiple redefinition of symbol \"%s\""), 694 "--redefine-sym", 695 source); 696 } 697 698 if (strcmp (target, list->target) == 0) 699 { 700 fatal (_("%s: Symbol \"%s\" is target of more than one redefinition"), 701 "--redefine-sym", 702 target); 703 } 704 } 705 706 new_node = (struct redefine_node *) xmalloc (sizeof (struct redefine_node)); 707 708 new_node->source = strdup (source); 709 new_node->target = strdup (target); 710 new_node->next = NULL; 711 712 *p = new_node; 713 } 714 715 716 /* Keep only every `copy_byte'th byte in MEMHUNK, which is *SIZE bytes long. 717 Adjust *SIZE. */ 718 719 static void 720 filter_bytes (memhunk, size) 721 char *memhunk; 722 bfd_size_type *size; 723 { 724 char *from = memhunk + copy_byte, *to = memhunk, *end = memhunk + *size; 725 726 for (; from < end; from += interleave) 727 *to++ = *from; 728 if (*size % interleave > (bfd_size_type) copy_byte) 729 *size = (*size / interleave) + 1; 730 else 731 *size /= interleave; 732 } 733 734 /* Copy object file IBFD onto OBFD. */ 735 736 static void 737 copy_object (ibfd, obfd) 738 bfd *ibfd; 739 bfd *obfd; 740 { 741 bfd_vma start; 742 long symcount; 743 asection **osections = NULL; 744 bfd_size_type *gaps = NULL; 745 bfd_size_type max_gap = 0; 746 long symsize; 747 PTR dhandle; 748 749 750 if (!bfd_set_format (obfd, bfd_get_format (ibfd))) 751 RETURN_NONFATAL (bfd_get_filename (obfd)); 752 753 if (verbose) 754 printf (_("copy from %s(%s) to %s(%s)\n"), 755 bfd_get_filename (ibfd), bfd_get_target (ibfd), 756 bfd_get_filename (obfd), bfd_get_target (obfd)); 757 758 if (set_start_set) 759 start = set_start; 760 else 761 start = bfd_get_start_address (ibfd); 762 start += change_start; 763 764 if (!bfd_set_start_address (obfd, start) 765 || !bfd_set_file_flags (obfd, 766 (bfd_get_file_flags (ibfd) 767 & bfd_applicable_file_flags (obfd)))) 768 RETURN_NONFATAL (bfd_get_filename (ibfd)); 769 770 /* Copy architecture of input file to output file */ 771 if (!bfd_set_arch_mach (obfd, bfd_get_arch (ibfd), 772 bfd_get_mach (ibfd))) 773 non_fatal (_("Warning: Output file cannot represent architecture %s"), 774 bfd_printable_arch_mach (bfd_get_arch (ibfd), 775 bfd_get_mach (ibfd))); 776 777 if (!bfd_set_format (obfd, bfd_get_format (ibfd))) 778 RETURN_NONFATAL (bfd_get_filename (ibfd)); 779 780 if (isympp) 781 free (isympp); 782 783 if (osympp != isympp) 784 free (osympp); 785 786 /* BFD mandates that all output sections be created and sizes set before 787 any output is done. Thus, we traverse all sections multiple times. */ 788 bfd_map_over_sections (ibfd, setup_section, (void *) obfd); 789 790 if (add_sections != NULL) 791 { 792 struct section_add *padd; 793 struct section_list *pset; 794 795 for (padd = add_sections; padd != NULL; padd = padd->next) 796 { 797 padd->section = bfd_make_section (obfd, padd->name); 798 if (padd->section == NULL) 799 { 800 non_fatal (_("can't create section `%s': %s"), 801 padd->name, bfd_errmsg (bfd_get_error ())); 802 status = 1; 803 return; 804 } 805 else 806 { 807 flagword flags; 808 809 if (! bfd_set_section_size (obfd, padd->section, padd->size)) 810 RETURN_NONFATAL (bfd_get_filename (obfd)); 811 812 pset = find_section_list (padd->name, false); 813 if (pset != NULL) 814 pset->used = true; 815 816 if (pset != NULL && pset->set_flags) 817 flags = pset->flags | SEC_HAS_CONTENTS; 818 else 819 flags = SEC_HAS_CONTENTS | SEC_READONLY | SEC_DATA; 820 821 if (! bfd_set_section_flags (obfd, padd->section, flags)) 822 RETURN_NONFATAL (bfd_get_filename (obfd)); 823 824 if (pset != NULL) 825 { 826 if (pset->change_vma != CHANGE_IGNORE) 827 if (! bfd_set_section_vma (obfd, padd->section, pset->vma_val)) 828 RETURN_NONFATAL (bfd_get_filename (obfd)); 829 830 if (pset->change_lma != CHANGE_IGNORE) 831 { 832 padd->section->lma = pset->lma_val; 833 834 if (! bfd_set_section_alignment 835 (obfd, padd->section, 836 bfd_section_alignment (obfd, padd->section))) 837 RETURN_NONFATAL (bfd_get_filename (obfd)); 838 } 839 } 840 } 841 } 842 } 843 844 if (gap_fill_set || pad_to_set) 845 { 846 asection **set; 847 unsigned int c, i; 848 849 /* We must fill in gaps between the sections and/or we must pad 850 the last section to a specified address. We do this by 851 grabbing a list of the sections, sorting them by VMA, and 852 increasing the section sizes as required to fill the gaps. 853 We write out the gap contents below. */ 854 855 c = bfd_count_sections (obfd); 856 osections = (asection **) xmalloc (c * sizeof (asection *)); 857 set = osections; 858 bfd_map_over_sections (obfd, get_sections, (void *) &set); 859 860 qsort (osections, c, sizeof (asection *), compare_section_lma); 861 862 gaps = (bfd_size_type *) xmalloc (c * sizeof (bfd_size_type)); 863 memset (gaps, 0, c * sizeof (bfd_size_type)); 864 865 if (gap_fill_set) 866 { 867 for (i = 0; i < c - 1; i++) 868 { 869 flagword flags; 870 bfd_size_type size; 871 bfd_vma gap_start, gap_stop; 872 873 flags = bfd_get_section_flags (obfd, osections[i]); 874 if ((flags & SEC_HAS_CONTENTS) == 0 875 || (flags & SEC_LOAD) == 0) 876 continue; 877 878 size = bfd_section_size (obfd, osections[i]); 879 gap_start = bfd_section_lma (obfd, osections[i]) + size; 880 gap_stop = bfd_section_lma (obfd, osections[i + 1]); 881 if (gap_start < gap_stop) 882 { 883 if (! bfd_set_section_size (obfd, osections[i], 884 size + (gap_stop - gap_start))) 885 { 886 non_fatal (_("Can't fill gap after %s: %s"), 887 bfd_get_section_name (obfd, osections[i]), 888 bfd_errmsg (bfd_get_error ())); 889 status = 1; 890 break; 891 } 892 gaps[i] = gap_stop - gap_start; 893 if (max_gap < gap_stop - gap_start) 894 max_gap = gap_stop - gap_start; 895 } 896 } 897 } 898 899 if (pad_to_set) 900 { 901 bfd_vma lma; 902 bfd_size_type size; 903 904 lma = bfd_section_lma (obfd, osections[c - 1]); 905 size = bfd_section_size (obfd, osections[c - 1]); 906 if (lma + size < pad_to) 907 { 908 if (! bfd_set_section_size (obfd, osections[c - 1], 909 pad_to - lma)) 910 { 911 non_fatal (_("Can't add padding to %s: %s"), 912 bfd_get_section_name (obfd, osections[c - 1]), 913 bfd_errmsg (bfd_get_error ())); 914 status = 1; 915 } 916 else 917 { 918 gaps[c - 1] = pad_to - (lma + size); 919 if (max_gap < pad_to - (lma + size)) 920 max_gap = pad_to - (lma + size); 921 } 922 } 923 } 924 } 925 926 /* Symbol filtering must happen after the output sections have 927 been created, but before their contents are set. */ 928 dhandle = NULL; 929 symsize = bfd_get_symtab_upper_bound (ibfd); 930 if (symsize < 0) 931 RETURN_NONFATAL (bfd_get_filename (ibfd)); 932 933 osympp = isympp = (asymbol **) xmalloc (symsize); 934 symcount = bfd_canonicalize_symtab (ibfd, isympp); 935 if (symcount < 0) 936 RETURN_NONFATAL (bfd_get_filename (ibfd)); 937 938 if (convert_debugging) 939 dhandle = read_debugging_info (ibfd, isympp, symcount); 940 941 if (strip_symbols == STRIP_DEBUG 942 || strip_symbols == STRIP_ALL 943 || strip_symbols == STRIP_UNNEEDED 944 || discard_locals != LOCALS_UNDEF 945 || strip_specific_list != NULL 946 || keep_specific_list != NULL 947 || localize_specific_list != NULL 948 || weaken_specific_list != NULL 949 || sections_removed 950 || sections_copied 951 || convert_debugging 952 || change_leading_char 953 || remove_leading_char 954 || redefine_sym_list 955 || weaken) 956 { 957 /* Mark symbols used in output relocations so that they 958 are kept, even if they are local labels or static symbols. 959 960 Note we iterate over the input sections examining their 961 relocations since the relocations for the output sections 962 haven't been set yet. mark_symbols_used_in_relocations will 963 ignore input sections which have no corresponding output 964 section. */ 965 if (strip_symbols != STRIP_ALL) 966 bfd_map_over_sections (ibfd, 967 mark_symbols_used_in_relocations, 968 (PTR)isympp); 969 osympp = (asymbol **) xmalloc ((symcount + 1) * sizeof (asymbol *)); 970 symcount = filter_symbols (ibfd, obfd, osympp, isympp, symcount); 971 } 972 973 if (convert_debugging && dhandle != NULL) 974 { 975 if (! write_debugging_info (obfd, dhandle, &symcount, &osympp)) 976 { 977 status = 1; 978 return; 979 } 980 } 981 982 bfd_set_symtab (obfd, osympp, symcount); 983 984 /* This has to happen after the symbol table has been set. */ 985 bfd_map_over_sections (ibfd, copy_section, (void *) obfd); 986 987 if (add_sections != NULL) 988 { 989 struct section_add *padd; 990 991 for (padd = add_sections; padd != NULL; padd = padd->next) 992 { 993 if (! bfd_set_section_contents (obfd, padd->section, 994 (PTR) padd->contents, 995 (file_ptr) 0, 996 (bfd_size_type) padd->size)) 997 RETURN_NONFATAL (bfd_get_filename (obfd)); 998 } 999 } 1000 1001 if (gap_fill_set || pad_to_set) 1002 { 1003 bfd_byte *buf; 1004 int c, i; 1005 1006 /* Fill in the gaps. */ 1007 1008 if (max_gap > 8192) 1009 max_gap = 8192; 1010 buf = (bfd_byte *) xmalloc (max_gap); 1011 memset (buf, gap_fill, (size_t) max_gap); 1012 1013 c = bfd_count_sections (obfd); 1014 for (i = 0; i < c; i++) 1015 { 1016 if (gaps[i] != 0) 1017 { 1018 bfd_size_type left; 1019 file_ptr off; 1020 1021 left = gaps[i]; 1022 off = bfd_section_size (obfd, osections[i]) - left; 1023 while (left > 0) 1024 { 1025 bfd_size_type now; 1026 1027 if (left > 8192) 1028 now = 8192; 1029 else 1030 now = left; 1031 1032 if (! bfd_set_section_contents (obfd, osections[i], buf, 1033 off, now)) 1034 RETURN_NONFATAL (bfd_get_filename (obfd)); 1035 1036 left -= now; 1037 off += now; 1038 } 1039 } 1040 } 1041 } 1042 1043 /* Allow the BFD backend to copy any private data it understands 1044 from the input BFD to the output BFD. This is done last to 1045 permit the routine to look at the filtered symbol table, which is 1046 important for the ECOFF code at least. */ 1047 if (!bfd_copy_private_bfd_data (ibfd, obfd)) 1048 { 1049 non_fatal (_("%s: error copying private BFD data: %s"), 1050 bfd_get_filename (obfd), 1051 bfd_errmsg (bfd_get_error ())); 1052 status = 1; 1053 return; 1054 } 1055 } 1056 1057 /* Read each archive element in turn from IBFD, copy the 1058 contents to temp file, and keep the temp file handle. */ 1059 1060 static void 1061 copy_archive (ibfd, obfd, output_target) 1062 bfd *ibfd; 1063 bfd *obfd; 1064 const char *output_target; 1065 { 1066 struct name_list 1067 { 1068 struct name_list *next; 1069 char *name; 1070 bfd *obfd; 1071 } *list, *l; 1072 bfd **ptr = &obfd->archive_head; 1073 bfd *this_element; 1074 char *dir = make_tempname (bfd_get_filename (obfd), 1); 1075 1076 /* Make a temp directory to hold the contents. */ 1077 if (dir == (char *) NULL) 1078 { 1079 fatal (_("cannot make temp directory for archive copying (error: %s)"), 1080 strerror (errno)); 1081 } 1082 obfd->has_armap = ibfd->has_armap; 1083 1084 list = NULL; 1085 1086 this_element = bfd_openr_next_archived_file (ibfd, NULL); 1087 while (!status && this_element != (bfd *) NULL) 1088 { 1089 /* Create an output file for this member. */ 1090 char *output_name = concat (dir, "/", bfd_get_filename (this_element), 1091 (char *) NULL); 1092 bfd *output_bfd = bfd_openw (output_name, output_target); 1093 bfd *last_element; 1094 struct stat buf; 1095 int stat_status = 0; 1096 1097 if (preserve_dates) 1098 { 1099 stat_status = bfd_stat_arch_elt (this_element, &buf); 1100 if (stat_status != 0) 1101 non_fatal (_("internal stat error on %s"), 1102 bfd_get_filename (this_element)); 1103 } 1104 1105 l = (struct name_list *) xmalloc (sizeof (struct name_list)); 1106 l->name = output_name; 1107 l->next = list; 1108 list = l; 1109 1110 if (output_bfd == (bfd *) NULL) 1111 RETURN_NONFATAL (output_name); 1112 1113 if (!bfd_set_format (obfd, bfd_get_format (ibfd))) 1114 RETURN_NONFATAL (bfd_get_filename (obfd)); 1115 1116 if (bfd_check_format (this_element, bfd_object) == true) 1117 copy_object (this_element, output_bfd); 1118 1119 if (!bfd_close (output_bfd)) 1120 { 1121 bfd_nonfatal (bfd_get_filename (output_bfd)); 1122 /* Error in new object file. Don't change archive. */ 1123 status = 1; 1124 } 1125 1126 if (preserve_dates && stat_status == 0) 1127 set_times (output_name, &buf); 1128 1129 /* Open the newly output file and attach to our list. */ 1130 output_bfd = bfd_openr (output_name, output_target); 1131 1132 l->obfd = output_bfd; 1133 1134 *ptr = output_bfd; 1135 ptr = &output_bfd->next; 1136 1137 last_element = this_element; 1138 1139 this_element = bfd_openr_next_archived_file (ibfd, last_element); 1140 1141 bfd_close (last_element); 1142 } 1143 *ptr = (bfd *) NULL; 1144 1145 if (!bfd_close (obfd)) 1146 RETURN_NONFATAL (bfd_get_filename (obfd)); 1147 1148 if (!bfd_close (ibfd)) 1149 RETURN_NONFATAL (bfd_get_filename (ibfd)); 1150 1151 /* Delete all the files that we opened. */ 1152 for (l = list; l != NULL; l = l->next) 1153 { 1154 bfd_close (l->obfd); 1155 unlink (l->name); 1156 } 1157 rmdir (dir); 1158 } 1159 1160 /* The top-level control. */ 1161 1162 static void 1163 copy_file (input_filename, output_filename, input_target, output_target) 1164 const char *input_filename; 1165 const char *output_filename; 1166 const char *input_target; 1167 const char *output_target; 1168 { 1169 bfd *ibfd; 1170 char **matching; 1171 1172 /* To allow us to do "strip *" without dying on the first 1173 non-object file, failures are nonfatal. */ 1174 1175 ibfd = bfd_openr (input_filename, input_target); 1176 if (ibfd == NULL) 1177 RETURN_NONFATAL (input_filename); 1178 1179 if (bfd_check_format (ibfd, bfd_archive)) 1180 { 1181 bfd *obfd; 1182 1183 /* bfd_get_target does not return the correct value until 1184 bfd_check_format succeeds. */ 1185 if (output_target == NULL) 1186 output_target = bfd_get_target (ibfd); 1187 1188 obfd = bfd_openw (output_filename, output_target); 1189 if (obfd == NULL) 1190 RETURN_NONFATAL (output_filename); 1191 1192 copy_archive (ibfd, obfd, output_target); 1193 } 1194 else if (bfd_check_format_matches (ibfd, bfd_object, &matching)) 1195 { 1196 bfd *obfd; 1197 1198 /* bfd_get_target does not return the correct value until 1199 bfd_check_format succeeds. */ 1200 if (output_target == NULL) 1201 output_target = bfd_get_target (ibfd); 1202 1203 obfd = bfd_openw (output_filename, output_target); 1204 if (obfd == NULL) 1205 RETURN_NONFATAL (output_filename); 1206 1207 copy_object (ibfd, obfd); 1208 1209 if (!bfd_close (obfd)) 1210 RETURN_NONFATAL (output_filename); 1211 1212 if (!bfd_close (ibfd)) 1213 RETURN_NONFATAL (input_filename); 1214 } 1215 else 1216 { 1217 bfd_nonfatal (input_filename); 1218 1219 if (bfd_get_error () == bfd_error_file_ambiguously_recognized) 1220 { 1221 list_matching_formats (matching); 1222 free (matching); 1223 } 1224 1225 status = 1; 1226 } 1227 } 1228 1229 /* Create a section in OBFD with the same name and attributes 1230 as ISECTION in IBFD. */ 1231 1232 static void 1233 setup_section (ibfd, isection, obfdarg) 1234 bfd *ibfd; 1235 sec_ptr isection; 1236 PTR obfdarg; 1237 { 1238 bfd *obfd = (bfd *) obfdarg; 1239 struct section_list *p; 1240 sec_ptr osection; 1241 bfd_size_type size; 1242 bfd_vma vma; 1243 bfd_vma lma; 1244 flagword flags; 1245 char *err; 1246 1247 if ((bfd_get_section_flags (ibfd, isection) & SEC_DEBUGGING) != 0 1248 && (strip_symbols == STRIP_DEBUG 1249 || strip_symbols == STRIP_UNNEEDED 1250 || strip_symbols == STRIP_ALL 1251 || discard_locals == LOCALS_ALL 1252 || convert_debugging)) 1253 return; 1254 1255 p = find_section_list (bfd_section_name (ibfd, isection), false); 1256 if (p != NULL) 1257 p->used = true; 1258 1259 if (sections_removed && p != NULL && p->remove) 1260 return; 1261 if (sections_copied && (p == NULL || ! p->copy)) 1262 return; 1263 1264 osection = bfd_make_section_anyway (obfd, bfd_section_name (ibfd, isection)); 1265 1266 if (osection == NULL) 1267 { 1268 err = "making"; 1269 goto loser; 1270 } 1271 1272 size = bfd_section_size (ibfd, isection); 1273 if (copy_byte >= 0) 1274 size = (size + interleave - 1) / interleave; 1275 if (! bfd_set_section_size (obfd, osection, size)) 1276 { 1277 err = "size"; 1278 goto loser; 1279 } 1280 1281 vma = bfd_section_vma (ibfd, isection); 1282 if (p != NULL && p->change_vma == CHANGE_MODIFY) 1283 vma += p->vma_val; 1284 else if (p != NULL && p->change_vma == CHANGE_SET) 1285 vma = p->vma_val; 1286 else 1287 vma += change_section_address; 1288 1289 if (! bfd_set_section_vma (obfd, osection, vma)) 1290 { 1291 err = "vma"; 1292 goto loser; 1293 } 1294 1295 lma = isection->lma; 1296 if ((p != NULL) && p->change_lma != CHANGE_IGNORE) 1297 { 1298 if (p->change_lma == CHANGE_MODIFY) 1299 lma += p->lma_val; 1300 else if (p->change_lma == CHANGE_SET) 1301 lma = p->lma_val; 1302 else 1303 abort (); 1304 } 1305 else 1306 lma += change_section_address; 1307 1308 osection->lma = lma; 1309 1310 /* FIXME: This is probably not enough. If we change the LMA we 1311 may have to recompute the header for the file as well. */ 1312 if (bfd_set_section_alignment (obfd, 1313 osection, 1314 bfd_section_alignment (ibfd, isection)) 1315 == false) 1316 { 1317 err = "alignment"; 1318 goto loser; 1319 } 1320 1321 flags = bfd_get_section_flags (ibfd, isection); 1322 if (p != NULL && p->set_flags) 1323 flags = p->flags | (flags & SEC_HAS_CONTENTS); 1324 if (!bfd_set_section_flags (obfd, osection, flags)) 1325 { 1326 err = "flags"; 1327 goto loser; 1328 } 1329 1330 /* This used to be mangle_section; we do here to avoid using 1331 bfd_get_section_by_name since some formats allow multiple 1332 sections with the same name. */ 1333 isection->output_section = osection; 1334 isection->output_offset = 0; 1335 1336 /* Allow the BFD backend to copy any private data it understands 1337 from the input section to the output section. */ 1338 if (!bfd_copy_private_section_data (ibfd, isection, obfd, osection)) 1339 { 1340 err = "private data"; 1341 goto loser; 1342 } 1343 1344 /* All went well */ 1345 return; 1346 1347 loser: 1348 non_fatal (_("%s: section `%s': error in %s: %s"), 1349 bfd_get_filename (ibfd), 1350 bfd_section_name (ibfd, isection), 1351 err, bfd_errmsg (bfd_get_error ())); 1352 status = 1; 1353 } 1354 1355 /* Copy the data of input section ISECTION of IBFD 1356 to an output section with the same name in OBFD. 1357 If stripping then don't copy any relocation info. */ 1358 1359 static void 1360 copy_section (ibfd, isection, obfdarg) 1361 bfd *ibfd; 1362 sec_ptr isection; 1363 PTR obfdarg; 1364 { 1365 bfd *obfd = (bfd *) obfdarg; 1366 struct section_list *p; 1367 arelent **relpp; 1368 long relcount; 1369 sec_ptr osection; 1370 bfd_size_type size; 1371 long relsize; 1372 1373 /* If we have already failed earlier on, do not keep on generating 1374 complaints now. */ 1375 if (status != 0) 1376 return; 1377 1378 if ((bfd_get_section_flags (ibfd, isection) & SEC_DEBUGGING) != 0 1379 && (strip_symbols == STRIP_DEBUG 1380 || strip_symbols == STRIP_UNNEEDED 1381 || strip_symbols == STRIP_ALL 1382 || discard_locals == LOCALS_ALL 1383 || convert_debugging)) 1384 { 1385 return; 1386 } 1387 1388 p = find_section_list (bfd_section_name (ibfd, isection), false); 1389 1390 if (sections_removed && p != NULL && p->remove) 1391 return; 1392 if (sections_copied && (p == NULL || ! p->copy)) 1393 return; 1394 1395 osection = isection->output_section; 1396 size = bfd_get_section_size_before_reloc (isection); 1397 1398 if (size == 0 || osection == 0) 1399 return; 1400 1401 1402 relsize = bfd_get_reloc_upper_bound (ibfd, isection); 1403 if (relsize < 0) 1404 RETURN_NONFATAL (bfd_get_filename (ibfd)); 1405 1406 if (relsize == 0) 1407 bfd_set_reloc (obfd, osection, (arelent **) NULL, 0); 1408 else 1409 { 1410 relpp = (arelent **) xmalloc (relsize); 1411 relcount = bfd_canonicalize_reloc (ibfd, isection, relpp, isympp); 1412 if (relcount < 0) 1413 RETURN_NONFATAL (bfd_get_filename (ibfd)); 1414 1415 if (strip_symbols == STRIP_ALL) 1416 { 1417 /* Remove relocations which are not in 1418 keep_strip_specific_list. */ 1419 arelent **temp_relpp; 1420 long temp_relcount = 0; 1421 long i; 1422 1423 temp_relpp = (arelent **) xmalloc (relsize); 1424 for (i = 0; i < relcount; i++) 1425 if (is_specified_symbol 1426 (bfd_asymbol_name (*relpp [i]->sym_ptr_ptr), 1427 keep_specific_list)) 1428 temp_relpp [temp_relcount++] = relpp [i]; 1429 relcount = temp_relcount; 1430 free (relpp); 1431 relpp = temp_relpp; 1432 } 1433 bfd_set_reloc (obfd, osection, 1434 (relcount == 0 ? (arelent **) NULL : relpp), relcount); 1435 } 1436 1437 isection->_cooked_size = isection->_raw_size; 1438 isection->reloc_done = true; 1439 1440 if (bfd_get_section_flags (ibfd, isection) & SEC_HAS_CONTENTS) 1441 { 1442 PTR memhunk = (PTR) xmalloc ((unsigned) size); 1443 1444 if (!bfd_get_section_contents (ibfd, isection, memhunk, (file_ptr) 0, 1445 size)) 1446 RETURN_NONFATAL (bfd_get_filename (ibfd)); 1447 1448 if (copy_byte >= 0) 1449 filter_bytes (memhunk, &size); 1450 1451 if (!bfd_set_section_contents (obfd, osection, memhunk, (file_ptr) 0, 1452 size)) 1453 RETURN_NONFATAL (bfd_get_filename (obfd)); 1454 1455 free (memhunk); 1456 } 1457 else if (p != NULL && p->set_flags && (p->flags & SEC_HAS_CONTENTS) != 0) 1458 { 1459 PTR memhunk = (PTR) xmalloc ((unsigned) size); 1460 1461 /* We don't permit the user to turn off the SEC_HAS_CONTENTS 1462 flag--they can just remove the section entirely and add it 1463 back again. However, we do permit them to turn on the 1464 SEC_HAS_CONTENTS flag, and take it to mean that the section 1465 contents should be zeroed out. */ 1466 1467 memset (memhunk, 0, size); 1468 if (! bfd_set_section_contents (obfd, osection, memhunk, (file_ptr) 0, 1469 size)) 1470 RETURN_NONFATAL (bfd_get_filename (obfd)); 1471 free (memhunk); 1472 } 1473 } 1474 1475 /* Get all the sections. This is used when --gap-fill or --pad-to is 1476 used. */ 1477 1478 static void 1479 get_sections (obfd, osection, secppparg) 1480 bfd *obfd ATTRIBUTE_UNUSED; 1481 asection *osection; 1482 PTR secppparg; 1483 { 1484 asection ***secppp = (asection ***) secppparg; 1485 1486 **secppp = osection; 1487 ++(*secppp); 1488 } 1489 1490 /* Sort sections by VMA. This is called via qsort, and is used when 1491 --gap-fill or --pad-to is used. We force non loadable or empty 1492 sections to the front, where they are easier to ignore. */ 1493 1494 static int 1495 compare_section_lma (arg1, arg2) 1496 const PTR arg1; 1497 const PTR arg2; 1498 { 1499 const asection **sec1 = (const asection **) arg1; 1500 const asection **sec2 = (const asection **) arg2; 1501 flagword flags1, flags2; 1502 1503 /* Sort non loadable sections to the front. */ 1504 flags1 = (*sec1)->flags; 1505 flags2 = (*sec2)->flags; 1506 if ((flags1 & SEC_HAS_CONTENTS) == 0 1507 || (flags1 & SEC_LOAD) == 0) 1508 { 1509 if ((flags2 & SEC_HAS_CONTENTS) != 0 1510 && (flags2 & SEC_LOAD) != 0) 1511 return -1; 1512 } 1513 else 1514 { 1515 if ((flags2 & SEC_HAS_CONTENTS) == 0 1516 || (flags2 & SEC_LOAD) == 0) 1517 return 1; 1518 } 1519 1520 /* Sort sections by LMA. */ 1521 if ((*sec1)->lma > (*sec2)->lma) 1522 return 1; 1523 else if ((*sec1)->lma < (*sec2)->lma) 1524 return -1; 1525 1526 /* Sort sections with the same LMA by size. */ 1527 if ((*sec1)->_raw_size > (*sec2)->_raw_size) 1528 return 1; 1529 else if ((*sec1)->_raw_size < (*sec2)->_raw_size) 1530 return -1; 1531 1532 return 0; 1533 } 1534 1535 /* Mark all the symbols which will be used in output relocations with 1536 the BSF_KEEP flag so that those symbols will not be stripped. 1537 1538 Ignore relocations which will not appear in the output file. */ 1539 1540 static void 1541 mark_symbols_used_in_relocations (ibfd, isection, symbolsarg) 1542 bfd *ibfd; 1543 sec_ptr isection; 1544 PTR symbolsarg; 1545 { 1546 asymbol **symbols = (asymbol **) symbolsarg; 1547 long relsize; 1548 arelent **relpp; 1549 long relcount, i; 1550 1551 /* Ignore an input section with no corresponding output section. */ 1552 if (isection->output_section == NULL) 1553 return; 1554 1555 relsize = bfd_get_reloc_upper_bound (ibfd, isection); 1556 if (relsize < 0) 1557 bfd_fatal (bfd_get_filename (ibfd)); 1558 1559 if (relsize == 0) 1560 return; 1561 1562 relpp = (arelent **) xmalloc (relsize); 1563 relcount = bfd_canonicalize_reloc (ibfd, isection, relpp, symbols); 1564 if (relcount < 0) 1565 bfd_fatal (bfd_get_filename (ibfd)); 1566 1567 /* Examine each symbol used in a relocation. If it's not one of the 1568 special bfd section symbols, then mark it with BSF_KEEP. */ 1569 for (i = 0; i < relcount; i++) 1570 { 1571 if (*relpp[i]->sym_ptr_ptr != bfd_com_section_ptr->symbol 1572 && *relpp[i]->sym_ptr_ptr != bfd_abs_section_ptr->symbol 1573 && *relpp[i]->sym_ptr_ptr != bfd_und_section_ptr->symbol) 1574 (*relpp[i]->sym_ptr_ptr)->flags |= BSF_KEEP; 1575 } 1576 1577 if (relpp != NULL) 1578 free (relpp); 1579 } 1580 1581 /* Write out debugging information. */ 1582 1583 static boolean 1584 write_debugging_info (obfd, dhandle, symcountp, symppp) 1585 bfd *obfd; 1586 PTR dhandle; 1587 long *symcountp ATTRIBUTE_UNUSED; 1588 asymbol ***symppp ATTRIBUTE_UNUSED; 1589 { 1590 if (bfd_get_flavour (obfd) == bfd_target_ieee_flavour) 1591 return write_ieee_debugging_info (obfd, dhandle); 1592 1593 if (bfd_get_flavour (obfd) == bfd_target_coff_flavour 1594 || bfd_get_flavour (obfd) == bfd_target_elf_flavour) 1595 { 1596 bfd_byte *syms, *strings; 1597 bfd_size_type symsize, stringsize; 1598 asection *stabsec, *stabstrsec; 1599 1600 if (! write_stabs_in_sections_debugging_info (obfd, dhandle, &syms, 1601 &symsize, &strings, 1602 &stringsize)) 1603 return false; 1604 1605 stabsec = bfd_make_section (obfd, ".stab"); 1606 stabstrsec = bfd_make_section (obfd, ".stabstr"); 1607 if (stabsec == NULL 1608 || stabstrsec == NULL 1609 || ! bfd_set_section_size (obfd, stabsec, symsize) 1610 || ! bfd_set_section_size (obfd, stabstrsec, stringsize) 1611 || ! bfd_set_section_alignment (obfd, stabsec, 2) 1612 || ! bfd_set_section_alignment (obfd, stabstrsec, 0) 1613 || ! bfd_set_section_flags (obfd, stabsec, 1614 (SEC_HAS_CONTENTS 1615 | SEC_READONLY 1616 | SEC_DEBUGGING)) 1617 || ! bfd_set_section_flags (obfd, stabstrsec, 1618 (SEC_HAS_CONTENTS 1619 | SEC_READONLY 1620 | SEC_DEBUGGING))) 1621 { 1622 non_fatal (_("%s: can't create debugging section: %s"), 1623 bfd_get_filename (obfd), 1624 bfd_errmsg (bfd_get_error ())); 1625 return false; 1626 } 1627 1628 /* We can get away with setting the section contents now because 1629 the next thing the caller is going to do is copy over the 1630 real sections. We may someday have to split the contents 1631 setting out of this function. */ 1632 if (! bfd_set_section_contents (obfd, stabsec, syms, (file_ptr) 0, 1633 symsize) 1634 || ! bfd_set_section_contents (obfd, stabstrsec, strings, 1635 (file_ptr) 0, stringsize)) 1636 { 1637 non_fatal (_("%s: can't set debugging section contents: %s"), 1638 bfd_get_filename (obfd), 1639 bfd_errmsg (bfd_get_error ())); 1640 return false; 1641 } 1642 1643 return true; 1644 } 1645 1646 non_fatal (_("%s: don't know how to write debugging information for %s"), 1647 bfd_get_filename (obfd), bfd_get_target (obfd)); 1648 return false; 1649 } 1650 1651 static int 1652 strip_main (argc, argv) 1653 int argc; 1654 char *argv[]; 1655 { 1656 char *input_target = NULL, *output_target = NULL; 1657 boolean show_version = false; 1658 int c, i; 1659 struct section_list *p; 1660 char *output_file = NULL; 1661 1662 while ((c = getopt_long (argc, argv, "I:O:F:K:N:R:o:sSpdgxXVv", 1663 strip_options, (int *) 0)) != EOF) 1664 { 1665 switch (c) 1666 { 1667 case 'I': 1668 input_target = optarg; 1669 break; 1670 case 'O': 1671 output_target = optarg; 1672 break; 1673 case 'F': 1674 input_target = output_target = optarg; 1675 break; 1676 case 'R': 1677 p = find_section_list (optarg, true); 1678 p->remove = true; 1679 sections_removed = true; 1680 break; 1681 case 's': 1682 strip_symbols = STRIP_ALL; 1683 break; 1684 case 'S': 1685 case 'g': 1686 case 'd': /* NetBSD, historic BSD strip */ 1687 strip_symbols = STRIP_DEBUG; 1688 break; 1689 case OPTION_STRIP_UNNEEDED: 1690 strip_symbols = STRIP_UNNEEDED; 1691 break; 1692 case 'K': 1693 add_specific_symbol (optarg, &keep_specific_list); 1694 break; 1695 case 'N': 1696 add_specific_symbol (optarg, &strip_specific_list); 1697 break; 1698 case 'o': 1699 output_file = optarg; 1700 break; 1701 case 'p': 1702 preserve_dates = true; 1703 break; 1704 case 'x': 1705 discard_locals = LOCALS_ALL; 1706 break; 1707 case 'X': 1708 discard_locals = LOCALS_START_L; 1709 break; 1710 case 'v': 1711 verbose = true; 1712 break; 1713 case 'V': 1714 show_version = true; 1715 break; 1716 case 0: 1717 break; /* we've been given a long option */ 1718 case 'h': 1719 strip_usage (stdout, 0); 1720 default: 1721 strip_usage (stderr, 1); 1722 } 1723 } 1724 1725 if (show_version) 1726 print_version ("strip"); 1727 1728 /* Default is to strip all symbols. */ 1729 if (strip_symbols == STRIP_UNDEF 1730 && discard_locals == LOCALS_UNDEF 1731 && strip_specific_list == NULL) 1732 strip_symbols = STRIP_ALL; 1733 1734 if (output_target == (char *) NULL) 1735 output_target = input_target; 1736 1737 i = optind; 1738 if (i == argc 1739 || (output_file != NULL && (i + 1) < argc)) 1740 strip_usage (stderr, 1); 1741 1742 for (; i < argc; i++) 1743 { 1744 int hold_status = status; 1745 struct stat statbuf; 1746 char *tmpname; 1747 1748 if (preserve_dates) 1749 { 1750 if (stat (argv[i], &statbuf) < 0) 1751 { 1752 non_fatal (_("%s: cannot stat: %s"), argv[i], strerror (errno)); 1753 continue; 1754 } 1755 } 1756 1757 if (output_file != NULL) 1758 tmpname = output_file; 1759 else 1760 tmpname = make_tempname (argv[i], 0); 1761 status = 0; 1762 1763 copy_file (argv[i], tmpname, input_target, output_target); 1764 if (status == 0) 1765 { 1766 if (preserve_dates) 1767 set_times (tmpname, &statbuf); 1768 if (output_file == NULL) 1769 smart_rename (tmpname, argv[i], preserve_dates); 1770 status = hold_status; 1771 } 1772 else 1773 unlink (tmpname); 1774 if (output_file == NULL) 1775 free (tmpname); 1776 } 1777 1778 return 0; 1779 } 1780 1781 static int 1782 copy_main (argc, argv) 1783 int argc; 1784 char *argv[]; 1785 { 1786 char *input_filename = NULL, *output_filename = NULL; 1787 char *input_target = NULL, *output_target = NULL; 1788 boolean show_version = false; 1789 boolean change_warn = true; 1790 int c; 1791 struct section_list *p; 1792 struct stat statbuf; 1793 1794 while ((c = getopt_long (argc, argv, "b:i:I:j:K:N:s:O:d:F:L:R:SpgxXVvW:", 1795 copy_options, (int *) 0)) != EOF) 1796 { 1797 switch (c) 1798 { 1799 case 'b': 1800 copy_byte = atoi (optarg); 1801 if (copy_byte < 0) 1802 fatal (_("byte number must be non-negative")); 1803 break; 1804 1805 case 'i': 1806 interleave = atoi (optarg); 1807 if (interleave < 1) 1808 fatal (_("interleave must be positive")); 1809 break; 1810 1811 case 'I': 1812 case 's': /* "source" - 'I' is preferred */ 1813 input_target = optarg; 1814 break; 1815 1816 case 'O': 1817 case 'd': /* "destination" - 'O' is preferred */ 1818 output_target = optarg; 1819 break; 1820 1821 case 'F': 1822 input_target = output_target = optarg; 1823 break; 1824 1825 case 'j': 1826 p = find_section_list (optarg, true); 1827 if (p->remove) 1828 fatal (_("%s both copied and removed"), optarg); 1829 p->copy = true; 1830 sections_copied = true; 1831 break; 1832 1833 case 'R': 1834 p = find_section_list (optarg, true); 1835 if (p->copy) 1836 fatal (_("%s both copied and removed"), optarg); 1837 p->remove = true; 1838 sections_removed = true; 1839 break; 1840 1841 case 'S': 1842 strip_symbols = STRIP_ALL; 1843 break; 1844 1845 case 'g': 1846 strip_symbols = STRIP_DEBUG; 1847 break; 1848 1849 case OPTION_STRIP_UNNEEDED: 1850 strip_symbols = STRIP_UNNEEDED; 1851 break; 1852 1853 case 'K': 1854 add_specific_symbol (optarg, &keep_specific_list); 1855 break; 1856 1857 case 'N': 1858 add_specific_symbol (optarg, &strip_specific_list); 1859 break; 1860 1861 case 'L': 1862 add_specific_symbol (optarg, &localize_specific_list); 1863 break; 1864 1865 case 'W': 1866 add_specific_symbol (optarg, &weaken_specific_list); 1867 break; 1868 1869 case 'p': 1870 preserve_dates = true; 1871 break; 1872 1873 case 'x': 1874 discard_locals = LOCALS_ALL; 1875 break; 1876 1877 case 'X': 1878 discard_locals = LOCALS_START_L; 1879 break; 1880 1881 case 'v': 1882 verbose = true; 1883 break; 1884 1885 case 'V': 1886 show_version = true; 1887 break; 1888 1889 case OPTION_WEAKEN: 1890 weaken = true; 1891 break; 1892 1893 case OPTION_ADD_SECTION: 1894 { 1895 const char *s; 1896 struct stat st; 1897 struct section_add *pa; 1898 int len; 1899 char *name; 1900 FILE *f; 1901 1902 s = strchr (optarg, '='); 1903 1904 if (s == NULL) 1905 fatal (_("bad format for %s"), "--add-section"); 1906 1907 if (stat (s + 1, & st) < 0) 1908 fatal (_("cannot stat: %s: %s"), s + 1, strerror (errno)); 1909 1910 pa = (struct section_add *) xmalloc (sizeof (struct section_add)); 1911 1912 len = s - optarg; 1913 name = (char *) xmalloc (len + 1); 1914 strncpy (name, optarg, len); 1915 name[len] = '\0'; 1916 pa->name = name; 1917 1918 pa->filename = s + 1; 1919 1920 pa->size = st.st_size; 1921 1922 pa->contents = (bfd_byte *) xmalloc (pa->size); 1923 f = fopen (pa->filename, FOPEN_RB); 1924 1925 if (f == NULL) 1926 fatal (_("cannot open: %s: %s"), pa->filename, strerror (errno)); 1927 1928 if (fread (pa->contents, 1, pa->size, f) == 0 1929 || ferror (f)) 1930 fatal (_("%s: fread failed"), pa->filename); 1931 1932 fclose (f); 1933 1934 pa->next = add_sections; 1935 add_sections = pa; 1936 } 1937 break; 1938 1939 case OPTION_CHANGE_START: 1940 change_start = parse_vma (optarg, "--change-start"); 1941 break; 1942 1943 case OPTION_CHANGE_SECTION_ADDRESS: 1944 case OPTION_CHANGE_SECTION_LMA: 1945 case OPTION_CHANGE_SECTION_VMA: 1946 { 1947 const char *s; 1948 int len; 1949 char *name; 1950 char *option = NULL; 1951 bfd_vma val; 1952 enum change_action what = CHANGE_IGNORE; 1953 1954 switch (c) 1955 { 1956 case OPTION_CHANGE_SECTION_ADDRESS: 1957 option = "--change-section-address"; 1958 break; 1959 case OPTION_CHANGE_SECTION_LMA: 1960 option = "--change-section-lma"; 1961 break; 1962 case OPTION_CHANGE_SECTION_VMA: 1963 option = "--change-section-vma"; 1964 break; 1965 } 1966 1967 s = strchr (optarg, '='); 1968 if (s == NULL) 1969 { 1970 s = strchr (optarg, '+'); 1971 if (s == NULL) 1972 { 1973 s = strchr (optarg, '-'); 1974 if (s == NULL) 1975 fatal (_("bad format for %s"), option); 1976 } 1977 } 1978 1979 len = s - optarg; 1980 name = (char *) xmalloc (len + 1); 1981 strncpy (name, optarg, len); 1982 name[len] = '\0'; 1983 1984 p = find_section_list (name, true); 1985 1986 val = parse_vma (s + 1, option); 1987 1988 switch (*s) 1989 { 1990 case '=': what = CHANGE_SET; break; 1991 case '-': val = - val; /* Drop through. */ 1992 case '+': what = CHANGE_MODIFY; break; 1993 } 1994 1995 switch (c) 1996 { 1997 case OPTION_CHANGE_SECTION_ADDRESS: 1998 p->change_vma = what; 1999 p->vma_val = val; 2000 /* Drop through. */ 2001 2002 case OPTION_CHANGE_SECTION_LMA: 2003 p->change_lma = what; 2004 p->lma_val = val; 2005 break; 2006 2007 case OPTION_CHANGE_SECTION_VMA: 2008 p->change_vma = what; 2009 p->vma_val = val; 2010 break; 2011 } 2012 } 2013 break; 2014 2015 case OPTION_CHANGE_ADDRESSES: 2016 change_section_address = parse_vma (optarg, "--change-addresses"); 2017 change_start = change_section_address; 2018 break; 2019 2020 case OPTION_CHANGE_WARNINGS: 2021 change_warn = true; 2022 break; 2023 2024 case OPTION_CHANGE_LEADING_CHAR: 2025 change_leading_char = true; 2026 break; 2027 2028 case OPTION_DEBUGGING: 2029 convert_debugging = true; 2030 break; 2031 2032 case OPTION_GAP_FILL: 2033 { 2034 bfd_vma gap_fill_vma; 2035 2036 gap_fill_vma = parse_vma (optarg, "--gap-fill"); 2037 gap_fill = (bfd_byte) gap_fill_vma; 2038 if ((bfd_vma) gap_fill != gap_fill_vma) 2039 { 2040 char buff[20]; 2041 2042 sprintf_vma (buff, gap_fill_vma); 2043 2044 non_fatal (_("Warning: truncating gap-fill from 0x%s to 0x%x"), 2045 buff, gap_fill); 2046 } 2047 gap_fill_set = true; 2048 } 2049 break; 2050 2051 case OPTION_NO_CHANGE_WARNINGS: 2052 change_warn = false; 2053 break; 2054 2055 case OPTION_PAD_TO: 2056 pad_to = parse_vma (optarg, "--pad-to"); 2057 pad_to_set = true; 2058 break; 2059 2060 case OPTION_REMOVE_LEADING_CHAR: 2061 remove_leading_char = true; 2062 break; 2063 2064 case OPTION_REDEFINE_SYM: 2065 { 2066 /* Push this redefinition onto redefine_symbol_list. */ 2067 2068 int len; 2069 const char *s; 2070 const char *nextarg; 2071 char *source, *target; 2072 2073 s = strchr (optarg, '='); 2074 if (s == NULL) 2075 { 2076 fatal (_("bad format for %s"), "--redefine-sym"); 2077 } 2078 2079 len = s - optarg; 2080 source = (char *) xmalloc (len + 1); 2081 strncpy (source, optarg, len); 2082 source[len] = '\0'; 2083 2084 nextarg = s + 1; 2085 len = strlen (nextarg); 2086 target = (char *) xmalloc (len + 1); 2087 strcpy (target, nextarg); 2088 2089 redefine_list_append (source, target); 2090 2091 free (source); 2092 free (target); 2093 } 2094 break; 2095 2096 case OPTION_SET_SECTION_FLAGS: 2097 { 2098 const char *s; 2099 int len; 2100 char *name; 2101 2102 s = strchr (optarg, '='); 2103 if (s == NULL) 2104 fatal (_("bad format for %s"), "--set-section-flags"); 2105 2106 len = s - optarg; 2107 name = (char *) xmalloc (len + 1); 2108 strncpy (name, optarg, len); 2109 name[len] = '\0'; 2110 2111 p = find_section_list (name, true); 2112 2113 p->set_flags = true; 2114 p->flags = parse_flags (s + 1); 2115 } 2116 break; 2117 2118 case OPTION_SET_START: 2119 set_start = parse_vma (optarg, "--set-start"); 2120 set_start_set = true; 2121 break; 2122 2123 case 0: 2124 break; /* we've been given a long option */ 2125 2126 case 'h': 2127 copy_usage (stdout, 0); 2128 2129 default: 2130 copy_usage (stderr, 1); 2131 } 2132 } 2133 2134 if (show_version) 2135 print_version ("objcopy"); 2136 2137 if (copy_byte >= interleave) 2138 fatal (_("byte number must be less than interleave")); 2139 2140 if (optind == argc || optind + 2 < argc) 2141 copy_usage (stderr, 1); 2142 2143 input_filename = argv[optind]; 2144 if (optind + 1 < argc) 2145 output_filename = argv[optind + 1]; 2146 2147 /* Default is to strip no symbols. */ 2148 if (strip_symbols == STRIP_UNDEF && discard_locals == LOCALS_UNDEF) 2149 strip_symbols = STRIP_NONE; 2150 2151 if (output_target == (char *) NULL) 2152 output_target = input_target; 2153 2154 if (preserve_dates) 2155 { 2156 if (stat (input_filename, &statbuf) < 0) 2157 fatal (_("Cannot stat: %s: %s"), input_filename, strerror (errno)); 2158 } 2159 2160 /* If there is no destination file then create a temp and rename 2161 the result into the input. */ 2162 2163 if (output_filename == (char *) NULL) 2164 { 2165 char *tmpname = make_tempname (input_filename, 0); 2166 2167 copy_file (input_filename, tmpname, input_target, output_target); 2168 if (status == 0) 2169 { 2170 if (preserve_dates) 2171 set_times (tmpname, &statbuf); 2172 smart_rename (tmpname, input_filename, preserve_dates); 2173 } 2174 else 2175 unlink (tmpname); 2176 } 2177 else 2178 { 2179 copy_file (input_filename, output_filename, input_target, output_target); 2180 if (status == 0 && preserve_dates) 2181 set_times (output_filename, &statbuf); 2182 } 2183 2184 if (change_warn) 2185 { 2186 for (p = change_sections; p != NULL; p = p->next) 2187 { 2188 if (! p->used) 2189 { 2190 if (p->change_vma != CHANGE_IGNORE) 2191 { 2192 char buff [20]; 2193 2194 sprintf_vma (buff, p->vma_val); 2195 2196 /* xgettext:c-format */ 2197 non_fatal (_("%s %s%c0x%s never used"), 2198 "--change-section-vma", 2199 p->name, 2200 p->change_vma == CHANGE_SET ? '=' : '+', 2201 buff); 2202 } 2203 2204 if (p->change_lma != CHANGE_IGNORE) 2205 { 2206 char buff [20]; 2207 2208 sprintf_vma (buff, p->lma_val); 2209 2210 /* xgettext:c-format */ 2211 non_fatal (_("%s %s%c0x%s never used"), 2212 "--change-section-lma", 2213 p->name, 2214 p->change_lma == CHANGE_SET ? '=' : '+', 2215 buff); 2216 } 2217 } 2218 } 2219 } 2220 2221 return 0; 2222 } 2223 2224 int 2225 main (argc, argv) 2226 int argc; 2227 char *argv[]; 2228 { 2229 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES) 2230 setlocale (LC_MESSAGES, ""); 2231 #endif 2232 bindtextdomain (PACKAGE, LOCALEDIR); 2233 textdomain (PACKAGE); 2234 2235 program_name = argv[0]; 2236 xmalloc_set_program_name (program_name); 2237 2238 START_PROGRESS (program_name, 0); 2239 2240 strip_symbols = STRIP_UNDEF; 2241 discard_locals = LOCALS_UNDEF; 2242 2243 bfd_init (); 2244 set_default_bfd_target (); 2245 2246 if (is_strip < 0) 2247 { 2248 int i = strlen (program_name); 2249 #ifdef HAVE_DOS_BASED_FILE_SYSTEM 2250 /* Drop the .exe suffix, if any. */ 2251 if (i > 4 && FILENAME_CMP (program_name + i - 4, ".exe") == 0) 2252 { 2253 i -= 4; 2254 program_name[i] = '\0'; 2255 } 2256 #endif 2257 is_strip = (i >= 5 && FILENAME_CMP (program_name + i - 5, "strip") == 0); 2258 } 2259 2260 if (is_strip) 2261 strip_main (argc, argv); 2262 else 2263 copy_main (argc, argv); 2264 2265 END_PROGRESS (program_name); 2266 2267 return status; 2268 } 2269