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