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