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