objcopy.c revision 68765
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 36struct symlist 37{ 38 const char *name; 39 struct symlist *next; 40}; 41 42/* A list to support redefine_sym. */ 43struct redefine_node 44{ 45 char *source; 46 char *target; 47 struct redefine_node *next; 48}; 49 50static void copy_usage PARAMS ((FILE *, int)); 51static void strip_usage PARAMS ((FILE *, int)); 52static flagword parse_flags PARAMS ((const char *)); 53static struct section_list *find_section_list PARAMS ((const char *, boolean)); 54static void setup_section PARAMS ((bfd *, asection *, PTR)); 55static void copy_section PARAMS ((bfd *, asection *, PTR)); 56static void get_sections PARAMS ((bfd *, asection *, PTR)); 57static int compare_section_lma PARAMS ((const PTR, const PTR)); 58static void add_specific_symbol PARAMS ((const char *, struct symlist **)); 59static boolean is_specified_symbol PARAMS ((const char *, struct symlist *)); 60static boolean is_strip_section PARAMS ((bfd *, asection *)); 61static unsigned int filter_symbols 62 PARAMS ((bfd *, bfd *, asymbol **, asymbol **, long)); 63static void mark_symbols_used_in_relocations PARAMS ((bfd *, asection *, PTR)); 64static void filter_bytes PARAMS ((char *, bfd_size_type *)); 65static boolean write_debugging_info PARAMS ((bfd *, PTR, long *, asymbol ***)); 66static void copy_object PARAMS ((bfd *, bfd *)); 67static void copy_archive PARAMS ((bfd *, bfd *, const char *)); 68static void copy_file 69 PARAMS ((const char *, const char *, const char *, const char *)); 70static int strip_main PARAMS ((int, char **)); 71static int copy_main PARAMS ((int, char **)); 72static const char *lookup_sym_redefinition PARAMS((const char *)); 73static void redefine_list_append PARAMS ((const char *, const char *)); 74 75#define RETURN_NONFATAL(s) {bfd_nonfatal (s); status = 1; return;} 76 77static asymbol **isympp = NULL; /* Input symbols */ 78static asymbol **osympp = NULL; /* Output symbols that survive stripping */ 79 80/* If `copy_byte' >= 0, copy only that byte of every `interleave' bytes. */ 81static int copy_byte = -1; 82static int interleave = 4; 83 84static boolean verbose; /* Print file and target names. */ 85static boolean preserve_dates; /* Preserve input file timestamp. */ 86static int status = 0; /* Exit status. */ 87 88enum 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. */ 98static enum strip_action strip_symbols; 99 100enum 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. */ 108static enum locals_action discard_locals; 109 110/* What kind of change to perform. */ 111enum 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. */ 119struct 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 134static struct section_list *change_sections; 135static boolean sections_removed; 136static boolean sections_copied; 137 138/* Changes to the start address. */ 139static bfd_vma change_start = 0; 140static boolean set_start_set = false; 141static bfd_vma set_start; 142 143/* Changes to section addresses. */ 144static bfd_vma change_section_address = 0; 145 146/* Filling gaps between sections. */ 147static boolean gap_fill_set = false; 148static bfd_byte gap_fill = 0; 149 150/* Pad to a given address. */ 151static boolean pad_to_set = false; 152static bfd_vma pad_to; 153 154/* List of sections to add. */ 155 156struct 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 172static struct section_add *add_sections; 173 174/* Whether to convert debugging information. */ 175 176static boolean convert_debugging = false; 177 178/* Whether to change the leading character in symbol names. */ 179 180static boolean change_leading_char = false; 181 182/* Whether to remove the leading character from global symbol names. */ 183 184static boolean remove_leading_char = false; 185 186/* List of symbols to strip, keep, localize, weaken, or redefine. */ 187 188static struct symlist *strip_specific_list = NULL; 189static struct symlist *keep_specific_list = NULL; 190static struct symlist *localize_specific_list = NULL; 191static struct symlist *weaken_specific_list = NULL; 192static struct redefine_node *redefine_sym_list = NULL; 193 194/* If this is true, we weaken global symbols (set BSF_WEAK). */ 195 196static 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 221static 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 246static 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 */ 297extern 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. */ 302extern int is_strip; 303 304 305static void 306copy_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 363static void 364strip_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 398static flagword 399parse_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 454static struct section_list * 455find_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 488static void 489add_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 504static boolean 505is_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 521static boolean 522is_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 551static unsigned int 552filter_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 658static const char * 659lookup_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 680static void 681redefine_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 719static void 720filter_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 736static void 737copy_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 1060static void 1061copy_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)); 1075 1076 /* Make a temp directory to hold the contents. */ 1077#if defined (_WIN32) && !defined (__CYGWIN32__) 1078 if (mkdir (dir) != 0) 1079#else 1080 if (mkdir (dir, 0700) != 0) 1081#endif 1082 { 1083 fatal (_("cannot mkdir %s for archive copying (error: %s)"), 1084 dir, strerror (errno)); 1085 } 1086 obfd->has_armap = ibfd->has_armap; 1087 1088 list = NULL; 1089 1090 this_element = bfd_openr_next_archived_file (ibfd, NULL); 1091 while (!status && this_element != (bfd *) NULL) 1092 { 1093 /* Create an output file for this member. */ 1094 char *output_name = concat (dir, "/", bfd_get_filename (this_element), 1095 (char *) NULL); 1096 bfd *output_bfd = bfd_openw (output_name, output_target); 1097 bfd *last_element; 1098 struct stat buf; 1099 int stat_status = 0; 1100 1101 if (preserve_dates) 1102 { 1103 stat_status = bfd_stat_arch_elt (this_element, &buf); 1104 if (stat_status != 0) 1105 non_fatal (_("internal stat error on %s"), 1106 bfd_get_filename (this_element)); 1107 } 1108 1109 l = (struct name_list *) xmalloc (sizeof (struct name_list)); 1110 l->name = output_name; 1111 l->next = list; 1112 list = l; 1113 1114 if (output_bfd == (bfd *) NULL) 1115 RETURN_NONFATAL (output_name); 1116 1117 if (!bfd_set_format (obfd, bfd_get_format (ibfd))) 1118 RETURN_NONFATAL (bfd_get_filename (obfd)); 1119 1120 if (bfd_check_format (this_element, bfd_object) == true) 1121 copy_object (this_element, output_bfd); 1122 1123 if (!bfd_close (output_bfd)) 1124 { 1125 bfd_nonfatal (bfd_get_filename (output_bfd)); 1126 /* Error in new object file. Don't change archive. */ 1127 status = 1; 1128 } 1129 1130 if (preserve_dates && stat_status == 0) 1131 set_times (output_name, &buf); 1132 1133 /* Open the newly output file and attach to our list. */ 1134 output_bfd = bfd_openr (output_name, output_target); 1135 1136 l->obfd = output_bfd; 1137 1138 *ptr = output_bfd; 1139 ptr = &output_bfd->next; 1140 1141 last_element = this_element; 1142 1143 this_element = bfd_openr_next_archived_file (ibfd, last_element); 1144 1145 bfd_close (last_element); 1146 } 1147 *ptr = (bfd *) NULL; 1148 1149 if (!bfd_close (obfd)) 1150 RETURN_NONFATAL (bfd_get_filename (obfd)); 1151 1152 if (!bfd_close (ibfd)) 1153 RETURN_NONFATAL (bfd_get_filename (ibfd)); 1154 1155 /* Delete all the files that we opened. */ 1156 for (l = list; l != NULL; l = l->next) 1157 { 1158 bfd_close (l->obfd); 1159 unlink (l->name); 1160 } 1161 rmdir (dir); 1162} 1163 1164/* The top-level control. */ 1165 1166static void 1167copy_file (input_filename, output_filename, input_target, output_target) 1168 const char *input_filename; 1169 const char *output_filename; 1170 const char *input_target; 1171 const char *output_target; 1172{ 1173 bfd *ibfd; 1174 char **matching; 1175 1176 /* To allow us to do "strip *" without dying on the first 1177 non-object file, failures are nonfatal. */ 1178 1179 ibfd = bfd_openr (input_filename, input_target); 1180 if (ibfd == NULL) 1181 RETURN_NONFATAL (input_filename); 1182 1183 if (bfd_check_format (ibfd, bfd_archive)) 1184 { 1185 bfd *obfd; 1186 1187 /* bfd_get_target does not return the correct value until 1188 bfd_check_format succeeds. */ 1189 if (output_target == NULL) 1190 output_target = bfd_get_target (ibfd); 1191 1192 obfd = bfd_openw (output_filename, output_target); 1193 if (obfd == NULL) 1194 RETURN_NONFATAL (output_filename); 1195 1196 copy_archive (ibfd, obfd, output_target); 1197 } 1198 else if (bfd_check_format_matches (ibfd, bfd_object, &matching)) 1199 { 1200 bfd *obfd; 1201 1202 /* bfd_get_target does not return the correct value until 1203 bfd_check_format succeeds. */ 1204 if (output_target == NULL) 1205 output_target = bfd_get_target (ibfd); 1206 1207 obfd = bfd_openw (output_filename, output_target); 1208 if (obfd == NULL) 1209 RETURN_NONFATAL (output_filename); 1210 1211 copy_object (ibfd, obfd); 1212 1213 if (!bfd_close (obfd)) 1214 RETURN_NONFATAL (output_filename); 1215 1216 if (!bfd_close (ibfd)) 1217 RETURN_NONFATAL (input_filename); 1218 } 1219 else 1220 { 1221 bfd_nonfatal (input_filename); 1222 1223 if (bfd_get_error () == bfd_error_file_ambiguously_recognized) 1224 { 1225 list_matching_formats (matching); 1226 free (matching); 1227 } 1228 1229 status = 1; 1230 } 1231} 1232 1233/* Create a section in OBFD with the same name and attributes 1234 as ISECTION in IBFD. */ 1235 1236static void 1237setup_section (ibfd, isection, obfdarg) 1238 bfd *ibfd; 1239 sec_ptr isection; 1240 PTR obfdarg; 1241{ 1242 bfd *obfd = (bfd *) obfdarg; 1243 struct section_list *p; 1244 sec_ptr osection; 1245 bfd_size_type size; 1246 bfd_vma vma; 1247 bfd_vma lma; 1248 flagword flags; 1249 char *err; 1250 1251 if ((bfd_get_section_flags (ibfd, isection) & SEC_DEBUGGING) != 0 1252 && (strip_symbols == STRIP_DEBUG 1253 || strip_symbols == STRIP_UNNEEDED 1254 || strip_symbols == STRIP_ALL 1255 || discard_locals == LOCALS_ALL 1256 || convert_debugging)) 1257 return; 1258 1259 p = find_section_list (bfd_section_name (ibfd, isection), false); 1260 if (p != NULL) 1261 p->used = true; 1262 1263 if (sections_removed && p != NULL && p->remove) 1264 return; 1265 if (sections_copied && (p == NULL || ! p->copy)) 1266 return; 1267 1268 osection = bfd_make_section_anyway (obfd, bfd_section_name (ibfd, isection)); 1269 1270 if (osection == NULL) 1271 { 1272 err = "making"; 1273 goto loser; 1274 } 1275 1276 size = bfd_section_size (ibfd, isection); 1277 if (copy_byte >= 0) 1278 size = (size + interleave - 1) / interleave; 1279 if (! bfd_set_section_size (obfd, osection, size)) 1280 { 1281 err = "size"; 1282 goto loser; 1283 } 1284 1285 vma = bfd_section_vma (ibfd, isection); 1286 if (p != NULL && p->change_vma == CHANGE_MODIFY) 1287 vma += p->vma_val; 1288 else if (p != NULL && p->change_vma == CHANGE_SET) 1289 vma = p->vma_val; 1290 else 1291 vma += change_section_address; 1292 1293 if (! bfd_set_section_vma (obfd, osection, vma)) 1294 { 1295 err = "vma"; 1296 goto loser; 1297 } 1298 1299 lma = isection->lma; 1300 if ((p != NULL) && p->change_lma != CHANGE_IGNORE) 1301 { 1302 if (p->change_lma == CHANGE_MODIFY) 1303 lma += p->lma_val; 1304 else if (p->change_lma == CHANGE_SET) 1305 lma = p->lma_val; 1306 else 1307 abort (); 1308 } 1309 else 1310 lma += change_section_address; 1311 1312 osection->lma = lma; 1313 1314 /* FIXME: This is probably not enough. If we change the LMA we 1315 may have to recompute the header for the file as well. */ 1316 if (bfd_set_section_alignment (obfd, 1317 osection, 1318 bfd_section_alignment (ibfd, isection)) 1319 == false) 1320 { 1321 err = "alignment"; 1322 goto loser; 1323 } 1324 1325 flags = bfd_get_section_flags (ibfd, isection); 1326 if (p != NULL && p->set_flags) 1327 flags = p->flags | (flags & SEC_HAS_CONTENTS); 1328 if (!bfd_set_section_flags (obfd, osection, flags)) 1329 { 1330 err = "flags"; 1331 goto loser; 1332 } 1333 1334 /* This used to be mangle_section; we do here to avoid using 1335 bfd_get_section_by_name since some formats allow multiple 1336 sections with the same name. */ 1337 isection->output_section = osection; 1338 isection->output_offset = 0; 1339 1340 /* Allow the BFD backend to copy any private data it understands 1341 from the input section to the output section. */ 1342 if (!bfd_copy_private_section_data (ibfd, isection, obfd, osection)) 1343 { 1344 err = "private data"; 1345 goto loser; 1346 } 1347 1348 /* All went well */ 1349 return; 1350 1351loser: 1352 non_fatal (_("%s: section `%s': error in %s: %s"), 1353 bfd_get_filename (ibfd), 1354 bfd_section_name (ibfd, isection), 1355 err, bfd_errmsg (bfd_get_error ())); 1356 status = 1; 1357} 1358 1359/* Copy the data of input section ISECTION of IBFD 1360 to an output section with the same name in OBFD. 1361 If stripping then don't copy any relocation info. */ 1362 1363static void 1364copy_section (ibfd, isection, obfdarg) 1365 bfd *ibfd; 1366 sec_ptr isection; 1367 PTR obfdarg; 1368{ 1369 bfd *obfd = (bfd *) obfdarg; 1370 struct section_list *p; 1371 arelent **relpp; 1372 long relcount; 1373 sec_ptr osection; 1374 bfd_size_type size; 1375 long relsize; 1376 1377 /* If we have already failed earlier on, do not keep on generating 1378 complaints now. */ 1379 if (status != 0) 1380 return; 1381 1382 if ((bfd_get_section_flags (ibfd, isection) & SEC_DEBUGGING) != 0 1383 && (strip_symbols == STRIP_DEBUG 1384 || strip_symbols == STRIP_UNNEEDED 1385 || strip_symbols == STRIP_ALL 1386 || discard_locals == LOCALS_ALL 1387 || convert_debugging)) 1388 { 1389 return; 1390 } 1391 1392 p = find_section_list (bfd_section_name (ibfd, isection), false); 1393 1394 if (sections_removed && p != NULL && p->remove) 1395 return; 1396 if (sections_copied && (p == NULL || ! p->copy)) 1397 return; 1398 1399 osection = isection->output_section; 1400 size = bfd_get_section_size_before_reloc (isection); 1401 1402 if (size == 0 || osection == 0) 1403 return; 1404 1405 1406 relsize = bfd_get_reloc_upper_bound (ibfd, isection); 1407 if (relsize < 0) 1408 RETURN_NONFATAL (bfd_get_filename (ibfd)); 1409 1410 if (relsize == 0) 1411 bfd_set_reloc (obfd, osection, (arelent **) NULL, 0); 1412 else 1413 { 1414 relpp = (arelent **) xmalloc (relsize); 1415 relcount = bfd_canonicalize_reloc (ibfd, isection, relpp, isympp); 1416 if (relcount < 0) 1417 RETURN_NONFATAL (bfd_get_filename (ibfd)); 1418 1419 if (strip_symbols == STRIP_ALL) 1420 { 1421 /* Remove relocations which are not in 1422 keep_strip_specific_list. */ 1423 arelent **temp_relpp; 1424 long temp_relcount = 0; 1425 long i; 1426 1427 temp_relpp = (arelent **) xmalloc (relsize); 1428 for (i = 0; i < relcount; i++) 1429 if (is_specified_symbol 1430 (bfd_asymbol_name (*relpp [i]->sym_ptr_ptr), 1431 keep_specific_list)) 1432 temp_relpp [temp_relcount++] = relpp [i]; 1433 relcount = temp_relcount; 1434 free (relpp); 1435 relpp = temp_relpp; 1436 } 1437 bfd_set_reloc (obfd, osection, 1438 (relcount == 0 ? (arelent **) NULL : relpp), relcount); 1439 } 1440 1441 isection->_cooked_size = isection->_raw_size; 1442 isection->reloc_done = true; 1443 1444 if (bfd_get_section_flags (ibfd, isection) & SEC_HAS_CONTENTS) 1445 { 1446 PTR memhunk = (PTR) xmalloc ((unsigned) size); 1447 1448 if (!bfd_get_section_contents (ibfd, isection, memhunk, (file_ptr) 0, 1449 size)) 1450 RETURN_NONFATAL (bfd_get_filename (ibfd)); 1451 1452 if (copy_byte >= 0) 1453 filter_bytes (memhunk, &size); 1454 1455 if (!bfd_set_section_contents (obfd, osection, memhunk, (file_ptr) 0, 1456 size)) 1457 RETURN_NONFATAL (bfd_get_filename (obfd)); 1458 1459 free (memhunk); 1460 } 1461 else if (p != NULL && p->set_flags && (p->flags & SEC_HAS_CONTENTS) != 0) 1462 { 1463 PTR memhunk = (PTR) xmalloc ((unsigned) size); 1464 1465 /* We don't permit the user to turn off the SEC_HAS_CONTENTS 1466 flag--they can just remove the section entirely and add it 1467 back again. However, we do permit them to turn on the 1468 SEC_HAS_CONTENTS flag, and take it to mean that the section 1469 contents should be zeroed out. */ 1470 1471 memset (memhunk, 0, size); 1472 if (! bfd_set_section_contents (obfd, osection, memhunk, (file_ptr) 0, 1473 size)) 1474 RETURN_NONFATAL (bfd_get_filename (obfd)); 1475 free (memhunk); 1476 } 1477} 1478 1479/* Get all the sections. This is used when --gap-fill or --pad-to is 1480 used. */ 1481 1482static void 1483get_sections (obfd, osection, secppparg) 1484 bfd *obfd ATTRIBUTE_UNUSED; 1485 asection *osection; 1486 PTR secppparg; 1487{ 1488 asection ***secppp = (asection ***) secppparg; 1489 1490 **secppp = osection; 1491 ++(*secppp); 1492} 1493 1494/* Sort sections by VMA. This is called via qsort, and is used when 1495 --gap-fill or --pad-to is used. We force non loadable or empty 1496 sections to the front, where they are easier to ignore. */ 1497 1498static int 1499compare_section_lma (arg1, arg2) 1500 const PTR arg1; 1501 const PTR arg2; 1502{ 1503 const asection **sec1 = (const asection **) arg1; 1504 const asection **sec2 = (const asection **) arg2; 1505 flagword flags1, flags2; 1506 1507 /* Sort non loadable sections to the front. */ 1508 flags1 = (*sec1)->flags; 1509 flags2 = (*sec2)->flags; 1510 if ((flags1 & SEC_HAS_CONTENTS) == 0 1511 || (flags1 & SEC_LOAD) == 0) 1512 { 1513 if ((flags2 & SEC_HAS_CONTENTS) != 0 1514 && (flags2 & SEC_LOAD) != 0) 1515 return -1; 1516 } 1517 else 1518 { 1519 if ((flags2 & SEC_HAS_CONTENTS) == 0 1520 || (flags2 & SEC_LOAD) == 0) 1521 return 1; 1522 } 1523 1524 /* Sort sections by LMA. */ 1525 if ((*sec1)->lma > (*sec2)->lma) 1526 return 1; 1527 else if ((*sec1)->lma < (*sec2)->lma) 1528 return -1; 1529 1530 /* Sort sections with the same LMA by size. */ 1531 if ((*sec1)->_raw_size > (*sec2)->_raw_size) 1532 return 1; 1533 else if ((*sec1)->_raw_size < (*sec2)->_raw_size) 1534 return -1; 1535 1536 return 0; 1537} 1538 1539/* Mark all the symbols which will be used in output relocations with 1540 the BSF_KEEP flag so that those symbols will not be stripped. 1541 1542 Ignore relocations which will not appear in the output file. */ 1543 1544static void 1545mark_symbols_used_in_relocations (ibfd, isection, symbolsarg) 1546 bfd *ibfd; 1547 sec_ptr isection; 1548 PTR symbolsarg; 1549{ 1550 asymbol **symbols = (asymbol **) symbolsarg; 1551 long relsize; 1552 arelent **relpp; 1553 long relcount, i; 1554 1555 /* Ignore an input section with no corresponding output section. */ 1556 if (isection->output_section == NULL) 1557 return; 1558 1559 relsize = bfd_get_reloc_upper_bound (ibfd, isection); 1560 if (relsize < 0) 1561 bfd_fatal (bfd_get_filename (ibfd)); 1562 1563 if (relsize == 0) 1564 return; 1565 1566 relpp = (arelent **) xmalloc (relsize); 1567 relcount = bfd_canonicalize_reloc (ibfd, isection, relpp, symbols); 1568 if (relcount < 0) 1569 bfd_fatal (bfd_get_filename (ibfd)); 1570 1571 /* Examine each symbol used in a relocation. If it's not one of the 1572 special bfd section symbols, then mark it with BSF_KEEP. */ 1573 for (i = 0; i < relcount; i++) 1574 { 1575 if (*relpp[i]->sym_ptr_ptr != bfd_com_section_ptr->symbol 1576 && *relpp[i]->sym_ptr_ptr != bfd_abs_section_ptr->symbol 1577 && *relpp[i]->sym_ptr_ptr != bfd_und_section_ptr->symbol) 1578 (*relpp[i]->sym_ptr_ptr)->flags |= BSF_KEEP; 1579 } 1580 1581 if (relpp != NULL) 1582 free (relpp); 1583} 1584 1585/* Write out debugging information. */ 1586 1587static boolean 1588write_debugging_info (obfd, dhandle, symcountp, symppp) 1589 bfd *obfd; 1590 PTR dhandle; 1591 long *symcountp ATTRIBUTE_UNUSED; 1592 asymbol ***symppp ATTRIBUTE_UNUSED; 1593{ 1594 if (bfd_get_flavour (obfd) == bfd_target_ieee_flavour) 1595 return write_ieee_debugging_info (obfd, dhandle); 1596 1597 if (bfd_get_flavour (obfd) == bfd_target_coff_flavour 1598 || bfd_get_flavour (obfd) == bfd_target_elf_flavour) 1599 { 1600 bfd_byte *syms, *strings; 1601 bfd_size_type symsize, stringsize; 1602 asection *stabsec, *stabstrsec; 1603 1604 if (! write_stabs_in_sections_debugging_info (obfd, dhandle, &syms, 1605 &symsize, &strings, 1606 &stringsize)) 1607 return false; 1608 1609 stabsec = bfd_make_section (obfd, ".stab"); 1610 stabstrsec = bfd_make_section (obfd, ".stabstr"); 1611 if (stabsec == NULL 1612 || stabstrsec == NULL 1613 || ! bfd_set_section_size (obfd, stabsec, symsize) 1614 || ! bfd_set_section_size (obfd, stabstrsec, stringsize) 1615 || ! bfd_set_section_alignment (obfd, stabsec, 2) 1616 || ! bfd_set_section_alignment (obfd, stabstrsec, 0) 1617 || ! bfd_set_section_flags (obfd, stabsec, 1618 (SEC_HAS_CONTENTS 1619 | SEC_READONLY 1620 | SEC_DEBUGGING)) 1621 || ! bfd_set_section_flags (obfd, stabstrsec, 1622 (SEC_HAS_CONTENTS 1623 | SEC_READONLY 1624 | SEC_DEBUGGING))) 1625 { 1626 non_fatal (_("%s: can't create debugging section: %s"), 1627 bfd_get_filename (obfd), 1628 bfd_errmsg (bfd_get_error ())); 1629 return false; 1630 } 1631 1632 /* We can get away with setting the section contents now because 1633 the next thing the caller is going to do is copy over the 1634 real sections. We may someday have to split the contents 1635 setting out of this function. */ 1636 if (! bfd_set_section_contents (obfd, stabsec, syms, (file_ptr) 0, 1637 symsize) 1638 || ! bfd_set_section_contents (obfd, stabstrsec, strings, 1639 (file_ptr) 0, stringsize)) 1640 { 1641 non_fatal (_("%s: can't set debugging section contents: %s"), 1642 bfd_get_filename (obfd), 1643 bfd_errmsg (bfd_get_error ())); 1644 return false; 1645 } 1646 1647 return true; 1648 } 1649 1650 non_fatal (_("%s: don't know how to write debugging information for %s"), 1651 bfd_get_filename (obfd), bfd_get_target (obfd)); 1652 return false; 1653} 1654 1655static int 1656strip_main (argc, argv) 1657 int argc; 1658 char *argv[]; 1659{ 1660 char *input_target = NULL, *output_target = NULL; 1661 boolean show_version = false; 1662 int c, i; 1663 struct section_list *p; 1664 char *output_file = NULL; 1665 1666 while ((c = getopt_long (argc, argv, "I:O:F:K:N:R:o:sSpdgxXVv", 1667 strip_options, (int *) 0)) != EOF) 1668 { 1669 switch (c) 1670 { 1671 case 'I': 1672 input_target = optarg; 1673 break; 1674 case 'O': 1675 output_target = optarg; 1676 break; 1677 case 'F': 1678 input_target = output_target = optarg; 1679 break; 1680 case 'R': 1681 p = find_section_list (optarg, true); 1682 p->remove = true; 1683 sections_removed = true; 1684 break; 1685 case 's': 1686 strip_symbols = STRIP_ALL; 1687 break; 1688 case 'S': 1689 case 'g': 1690 case 'd': /* NetBSD, historic BSD strip */ 1691 strip_symbols = STRIP_DEBUG; 1692 break; 1693 case OPTION_STRIP_UNNEEDED: 1694 strip_symbols = STRIP_UNNEEDED; 1695 break; 1696 case 'K': 1697 add_specific_symbol (optarg, &keep_specific_list); 1698 break; 1699 case 'N': 1700 add_specific_symbol (optarg, &strip_specific_list); 1701 break; 1702 case 'o': 1703 output_file = optarg; 1704 break; 1705 case 'p': 1706 preserve_dates = true; 1707 break; 1708 case 'x': 1709 discard_locals = LOCALS_ALL; 1710 break; 1711 case 'X': 1712 discard_locals = LOCALS_START_L; 1713 break; 1714 case 'v': 1715 verbose = true; 1716 break; 1717 case 'V': 1718 show_version = true; 1719 break; 1720 case 0: 1721 break; /* we've been given a long option */ 1722 case 'h': 1723 strip_usage (stdout, 0); 1724 default: 1725 strip_usage (stderr, 1); 1726 } 1727 } 1728 1729 if (show_version) 1730 print_version ("strip"); 1731 1732 /* Default is to strip all symbols. */ 1733 if (strip_symbols == STRIP_UNDEF 1734 && discard_locals == LOCALS_UNDEF 1735 && strip_specific_list == NULL) 1736 strip_symbols = STRIP_ALL; 1737 1738 if (output_target == (char *) NULL) 1739 output_target = input_target; 1740 1741 i = optind; 1742 if (i == argc 1743 || (output_file != NULL && (i + 1) < argc)) 1744 strip_usage (stderr, 1); 1745 1746 for (; i < argc; i++) 1747 { 1748 int hold_status = status; 1749 struct stat statbuf; 1750 char *tmpname; 1751 1752 if (preserve_dates) 1753 { 1754 if (stat (argv[i], &statbuf) < 0) 1755 { 1756 non_fatal (_("%s: cannot stat: %s"), argv[i], strerror (errno)); 1757 continue; 1758 } 1759 } 1760 1761 if (output_file != NULL) 1762 tmpname = output_file; 1763 else 1764 tmpname = make_tempname (argv[i]); 1765 status = 0; 1766 1767 copy_file (argv[i], tmpname, input_target, output_target); 1768 if (status == 0) 1769 { 1770 if (preserve_dates) 1771 set_times (tmpname, &statbuf); 1772 if (output_file == NULL) 1773 smart_rename (tmpname, argv[i], preserve_dates); 1774 status = hold_status; 1775 } 1776 else 1777 unlink (tmpname); 1778 if (output_file == NULL) 1779 free (tmpname); 1780 } 1781 1782 return 0; 1783} 1784 1785static int 1786copy_main (argc, argv) 1787 int argc; 1788 char *argv[]; 1789{ 1790 char *input_filename = NULL, *output_filename = NULL; 1791 char *input_target = NULL, *output_target = NULL; 1792 boolean show_version = false; 1793 boolean change_warn = true; 1794 int c; 1795 struct section_list *p; 1796 struct stat statbuf; 1797 1798 while ((c = getopt_long (argc, argv, "b:i:I:j:K:N:s:O:d:F:L:R:SpgxXVvW:", 1799 copy_options, (int *) 0)) != EOF) 1800 { 1801 switch (c) 1802 { 1803 case 'b': 1804 copy_byte = atoi (optarg); 1805 if (copy_byte < 0) 1806 fatal (_("byte number must be non-negative")); 1807 break; 1808 1809 case 'i': 1810 interleave = atoi (optarg); 1811 if (interleave < 1) 1812 fatal (_("interleave must be positive")); 1813 break; 1814 1815 case 'I': 1816 case 's': /* "source" - 'I' is preferred */ 1817 input_target = optarg; 1818 break; 1819 1820 case 'O': 1821 case 'd': /* "destination" - 'O' is preferred */ 1822 output_target = optarg; 1823 break; 1824 1825 case 'F': 1826 input_target = output_target = optarg; 1827 break; 1828 1829 case 'j': 1830 p = find_section_list (optarg, true); 1831 if (p->remove) 1832 fatal (_("%s both copied and removed"), optarg); 1833 p->copy = true; 1834 sections_copied = true; 1835 break; 1836 1837 case 'R': 1838 p = find_section_list (optarg, true); 1839 if (p->copy) 1840 fatal (_("%s both copied and removed"), optarg); 1841 p->remove = true; 1842 sections_removed = true; 1843 break; 1844 1845 case 'S': 1846 strip_symbols = STRIP_ALL; 1847 break; 1848 1849 case 'g': 1850 strip_symbols = STRIP_DEBUG; 1851 break; 1852 1853 case OPTION_STRIP_UNNEEDED: 1854 strip_symbols = STRIP_UNNEEDED; 1855 break; 1856 1857 case 'K': 1858 add_specific_symbol (optarg, &keep_specific_list); 1859 break; 1860 1861 case 'N': 1862 add_specific_symbol (optarg, &strip_specific_list); 1863 break; 1864 1865 case 'L': 1866 add_specific_symbol (optarg, &localize_specific_list); 1867 break; 1868 1869 case 'W': 1870 add_specific_symbol (optarg, &weaken_specific_list); 1871 break; 1872 1873 case 'p': 1874 preserve_dates = true; 1875 break; 1876 1877 case 'x': 1878 discard_locals = LOCALS_ALL; 1879 break; 1880 1881 case 'X': 1882 discard_locals = LOCALS_START_L; 1883 break; 1884 1885 case 'v': 1886 verbose = true; 1887 break; 1888 1889 case 'V': 1890 show_version = true; 1891 break; 1892 1893 case OPTION_WEAKEN: 1894 weaken = true; 1895 break; 1896 1897 case OPTION_ADD_SECTION: 1898 { 1899 const char *s; 1900 struct stat st; 1901 struct section_add *pa; 1902 int len; 1903 char *name; 1904 FILE *f; 1905 1906 s = strchr (optarg, '='); 1907 1908 if (s == NULL) 1909 fatal (_("bad format for %s"), "--add-section"); 1910 1911 if (stat (s + 1, & st) < 0) 1912 fatal (_("cannot stat: %s: %s"), s + 1, strerror (errno)); 1913 1914 pa = (struct section_add *) xmalloc (sizeof (struct section_add)); 1915 1916 len = s - optarg; 1917 name = (char *) xmalloc (len + 1); 1918 strncpy (name, optarg, len); 1919 name[len] = '\0'; 1920 pa->name = name; 1921 1922 pa->filename = s + 1; 1923 1924 pa->size = st.st_size; 1925 1926 pa->contents = (bfd_byte *) xmalloc (pa->size); 1927 f = fopen (pa->filename, FOPEN_RB); 1928 1929 if (f == NULL) 1930 fatal (_("cannot open: %s: %s"), pa->filename, strerror (errno)); 1931 1932 if (fread (pa->contents, 1, pa->size, f) == 0 1933 || ferror (f)) 1934 fatal (_("%s: fread failed"), pa->filename); 1935 1936 fclose (f); 1937 1938 pa->next = add_sections; 1939 add_sections = pa; 1940 } 1941 break; 1942 1943 case OPTION_CHANGE_START: 1944 change_start = parse_vma (optarg, "--change-start"); 1945 break; 1946 1947 case OPTION_CHANGE_SECTION_ADDRESS: 1948 case OPTION_CHANGE_SECTION_LMA: 1949 case OPTION_CHANGE_SECTION_VMA: 1950 { 1951 const char *s; 1952 int len; 1953 char *name; 1954 char *option = NULL; 1955 bfd_vma val; 1956 enum change_action what = CHANGE_IGNORE; 1957 1958 switch (c) 1959 { 1960 case OPTION_CHANGE_SECTION_ADDRESS: 1961 option = "--change-section-address"; 1962 break; 1963 case OPTION_CHANGE_SECTION_LMA: 1964 option = "--change-section-lma"; 1965 break; 1966 case OPTION_CHANGE_SECTION_VMA: 1967 option = "--change-section-vma"; 1968 break; 1969 } 1970 1971 s = strchr (optarg, '='); 1972 if (s == NULL) 1973 { 1974 s = strchr (optarg, '+'); 1975 if (s == NULL) 1976 { 1977 s = strchr (optarg, '-'); 1978 if (s == NULL) 1979 fatal (_("bad format for %s"), option); 1980 } 1981 } 1982 1983 len = s - optarg; 1984 name = (char *) xmalloc (len + 1); 1985 strncpy (name, optarg, len); 1986 name[len] = '\0'; 1987 1988 p = find_section_list (name, true); 1989 1990 val = parse_vma (s + 1, option); 1991 1992 switch (*s) 1993 { 1994 case '=': what = CHANGE_SET; break; 1995 case '-': val = - val; /* Drop through. */ 1996 case '+': what = CHANGE_MODIFY; break; 1997 } 1998 1999 switch (c) 2000 { 2001 case OPTION_CHANGE_SECTION_ADDRESS: 2002 p->change_vma = what; 2003 p->vma_val = val; 2004 /* Drop through. */ 2005 2006 case OPTION_CHANGE_SECTION_LMA: 2007 p->change_lma = what; 2008 p->lma_val = val; 2009 break; 2010 2011 case OPTION_CHANGE_SECTION_VMA: 2012 p->change_vma = what; 2013 p->vma_val = val; 2014 break; 2015 } 2016 } 2017 break; 2018 2019 case OPTION_CHANGE_ADDRESSES: 2020 change_section_address = parse_vma (optarg, "--change-addresses"); 2021 change_start = change_section_address; 2022 break; 2023 2024 case OPTION_CHANGE_WARNINGS: 2025 change_warn = true; 2026 break; 2027 2028 case OPTION_CHANGE_LEADING_CHAR: 2029 change_leading_char = true; 2030 break; 2031 2032 case OPTION_DEBUGGING: 2033 convert_debugging = true; 2034 break; 2035 2036 case OPTION_GAP_FILL: 2037 { 2038 bfd_vma gap_fill_vma; 2039 2040 gap_fill_vma = parse_vma (optarg, "--gap-fill"); 2041 gap_fill = (bfd_byte) gap_fill_vma; 2042 if ((bfd_vma) gap_fill != gap_fill_vma) 2043 { 2044 char buff[20]; 2045 2046 sprintf_vma (buff, gap_fill_vma); 2047 2048 non_fatal (_("Warning: truncating gap-fill from 0x%s to 0x%x"), 2049 buff, gap_fill); 2050 } 2051 gap_fill_set = true; 2052 } 2053 break; 2054 2055 case OPTION_NO_CHANGE_WARNINGS: 2056 change_warn = false; 2057 break; 2058 2059 case OPTION_PAD_TO: 2060 pad_to = parse_vma (optarg, "--pad-to"); 2061 pad_to_set = true; 2062 break; 2063 2064 case OPTION_REMOVE_LEADING_CHAR: 2065 remove_leading_char = true; 2066 break; 2067 2068 case OPTION_REDEFINE_SYM: 2069 { 2070 /* Push this redefinition onto redefine_symbol_list. */ 2071 2072 int len; 2073 const char *s; 2074 const char *nextarg; 2075 char *source, *target; 2076 2077 s = strchr (optarg, '='); 2078 if (s == NULL) 2079 { 2080 fatal (_("bad format for %s"), "--redefine-sym"); 2081 } 2082 2083 len = s - optarg; 2084 source = (char *) xmalloc (len + 1); 2085 strncpy (source, optarg, len); 2086 source[len] = '\0'; 2087 2088 nextarg = s + 1; 2089 len = strlen (nextarg); 2090 target = (char *) xmalloc (len + 1); 2091 strcpy (target, nextarg); 2092 2093 redefine_list_append (source, target); 2094 2095 free (source); 2096 free (target); 2097 } 2098 break; 2099 2100 case OPTION_SET_SECTION_FLAGS: 2101 { 2102 const char *s; 2103 int len; 2104 char *name; 2105 2106 s = strchr (optarg, '='); 2107 if (s == NULL) 2108 fatal (_("bad format for %s"), "--set-section-flags"); 2109 2110 len = s - optarg; 2111 name = (char *) xmalloc (len + 1); 2112 strncpy (name, optarg, len); 2113 name[len] = '\0'; 2114 2115 p = find_section_list (name, true); 2116 2117 p->set_flags = true; 2118 p->flags = parse_flags (s + 1); 2119 } 2120 break; 2121 2122 case OPTION_SET_START: 2123 set_start = parse_vma (optarg, "--set-start"); 2124 set_start_set = true; 2125 break; 2126 2127 case 0: 2128 break; /* we've been given a long option */ 2129 2130 case 'h': 2131 copy_usage (stdout, 0); 2132 2133 default: 2134 copy_usage (stderr, 1); 2135 } 2136 } 2137 2138 if (show_version) 2139 print_version ("objcopy"); 2140 2141 if (copy_byte >= interleave) 2142 fatal (_("byte number must be less than interleave")); 2143 2144 if (optind == argc || optind + 2 < argc) 2145 copy_usage (stderr, 1); 2146 2147 input_filename = argv[optind]; 2148 if (optind + 1 < argc) 2149 output_filename = argv[optind + 1]; 2150 2151 /* Default is to strip no symbols. */ 2152 if (strip_symbols == STRIP_UNDEF && discard_locals == LOCALS_UNDEF) 2153 strip_symbols = STRIP_NONE; 2154 2155 if (output_target == (char *) NULL) 2156 output_target = input_target; 2157 2158 if (preserve_dates) 2159 { 2160 if (stat (input_filename, &statbuf) < 0) 2161 fatal (_("Cannot stat: %s: %s"), input_filename, strerror (errno)); 2162 } 2163 2164 /* If there is no destination file then create a temp and rename 2165 the result into the input. */ 2166 2167 if (output_filename == (char *) NULL) 2168 { 2169 char *tmpname = make_tempname (input_filename); 2170 2171 copy_file (input_filename, tmpname, input_target, output_target); 2172 if (status == 0) 2173 { 2174 if (preserve_dates) 2175 set_times (tmpname, &statbuf); 2176 smart_rename (tmpname, input_filename, preserve_dates); 2177 } 2178 else 2179 unlink (tmpname); 2180 } 2181 else 2182 { 2183 copy_file (input_filename, output_filename, input_target, output_target); 2184 if (status == 0 && preserve_dates) 2185 set_times (output_filename, &statbuf); 2186 } 2187 2188 if (change_warn) 2189 { 2190 for (p = change_sections; p != NULL; p = p->next) 2191 { 2192 if (! p->used) 2193 { 2194 if (p->change_vma != CHANGE_IGNORE) 2195 { 2196 char buff [20]; 2197 2198 sprintf_vma (buff, p->vma_val); 2199 2200 /* xgettext:c-format */ 2201 non_fatal (_("%s %s%c0x%s never used"), 2202 "--change-section-vma", 2203 p->name, 2204 p->change_vma == CHANGE_SET ? '=' : '+', 2205 buff); 2206 } 2207 2208 if (p->change_lma != CHANGE_IGNORE) 2209 { 2210 char buff [20]; 2211 2212 sprintf_vma (buff, p->lma_val); 2213 2214 /* xgettext:c-format */ 2215 non_fatal (_("%s %s%c0x%s never used"), 2216 "--change-section-lma", 2217 p->name, 2218 p->change_lma == CHANGE_SET ? '=' : '+', 2219 buff); 2220 } 2221 } 2222 } 2223 } 2224 2225 return 0; 2226} 2227 2228int 2229main (argc, argv) 2230 int argc; 2231 char *argv[]; 2232{ 2233#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES) 2234 setlocale (LC_MESSAGES, ""); 2235#endif 2236 bindtextdomain (PACKAGE, LOCALEDIR); 2237 textdomain (PACKAGE); 2238 2239 program_name = argv[0]; 2240 xmalloc_set_program_name (program_name); 2241 2242 START_PROGRESS (program_name, 0); 2243 2244 strip_symbols = STRIP_UNDEF; 2245 discard_locals = LOCALS_UNDEF; 2246 2247 bfd_init (); 2248 set_default_bfd_target (); 2249 2250 if (is_strip < 0) 2251 { 2252 int i = strlen (program_name); 2253#ifdef HAVE_DOS_BASED_FILE_SYSTEM 2254 /* Drop the .exe suffix, if any. */ 2255 if (i > 4 && FILENAME_CMP (program_name + i - 4, ".exe") == 0) 2256 { 2257 i -= 4; 2258 program_name[i] = '\0'; 2259 } 2260#endif 2261 is_strip = (i >= 5 && FILENAME_CMP (program_name + i - 5, "strip") == 0); 2262 } 2263 2264 if (is_strip) 2265 strip_main (argc, argv); 2266 else 2267 copy_main (argc, argv); 2268 2269 END_PROGRESS (program_name); 2270 2271 return status; 2272} 2273