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