?? objcopy.c
字號:
/* objcopy.c -- copy object file from input to output, optionally massaging it. Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. This file is part of GNU Binutils. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */#include "bfd.h"#include "progress.h"#include "bucomm.h"#include "getopt.h"#include "libiberty.h"#include "budbg.h"#include "filenames.h"#include <sys/stat.h>/* A list of symbols to explicitly strip out, or to keep. A linked list is good enough for a small number from the command line, but this will slow things down a lot if many symbols are being deleted. */struct symlist{ const char *name; struct symlist *next;};/* A list to support redefine_sym. */struct redefine_node{ char *source; char *target; struct redefine_node *next;};static void copy_usage PARAMS ((FILE *, int));static void strip_usage PARAMS ((FILE *, int));static flagword parse_flags PARAMS ((const char *));static struct section_list *find_section_list PARAMS ((const char *, boolean));static void setup_section PARAMS ((bfd *, asection *, PTR));static void copy_section PARAMS ((bfd *, asection *, PTR));static void get_sections PARAMS ((bfd *, asection *, PTR));static int compare_section_lma PARAMS ((const PTR, const PTR));static void add_specific_symbol PARAMS ((const char *, struct symlist **));static void add_specific_symbols PARAMS ((const char *, struct symlist **));static boolean is_specified_symbol PARAMS ((const char *, struct symlist *));static boolean is_strip_section PARAMS ((bfd *, asection *));static unsigned int filter_symbols PARAMS ((bfd *, bfd *, asymbol **, asymbol **, long));static void mark_symbols_used_in_relocations PARAMS ((bfd *, asection *, PTR));static void filter_bytes PARAMS ((char *, bfd_size_type *));static boolean write_debugging_info PARAMS ((bfd *, PTR, long *, asymbol ***));static void copy_object PARAMS ((bfd *, bfd *));static void copy_archive PARAMS ((bfd *, bfd *, const char *));static void copy_file PARAMS ((const char *, const char *, const char *, const char *));static int strip_main PARAMS ((int, char **));static int copy_main PARAMS ((int, char **));static const char *lookup_sym_redefinition PARAMS((const char *));static void redefine_list_append PARAMS ((const char *, const char *));#define RETURN_NONFATAL(s) {bfd_nonfatal (s); status = 1; return;}static asymbol **isympp = NULL; /* Input symbols */static asymbol **osympp = NULL; /* Output symbols that survive stripping *//* If `copy_byte' >= 0, copy only that byte of every `interleave' bytes. */static int copy_byte = -1;static int interleave = 4;static boolean verbose; /* Print file and target names. */static boolean preserve_dates; /* Preserve input file timestamp. */static int status = 0; /* Exit status. */enum strip_action { STRIP_UNDEF, STRIP_NONE, /* don't strip */ STRIP_DEBUG, /* strip all debugger symbols */ STRIP_UNNEEDED, /* strip unnecessary symbols */ STRIP_ALL /* strip all symbols */ };/* Which symbols to remove. */static enum strip_action strip_symbols;enum locals_action { LOCALS_UNDEF, LOCALS_START_L, /* discard locals starting with L */ LOCALS_ALL /* discard all locals */ };/* Which local symbols to remove. Overrides STRIP_ALL. */static enum locals_action discard_locals;/* What kind of change to perform. */enum change_action{ CHANGE_IGNORE, CHANGE_MODIFY, CHANGE_SET};/* Structure used to hold lists of sections and actions to take. */struct section_list{ struct section_list * next; /* Next section to change. */ const char * name; /* Section name. */ boolean used; /* Whether this entry was used. */ boolean remove; /* Whether to remove this section. */ boolean copy; /* Whether to copy this section. */ enum change_action change_vma;/* Whether to change or set VMA. */ bfd_vma vma_val; /* Amount to change by or set to. */ enum change_action change_lma;/* Whether to change or set LMA. */ bfd_vma lma_val; /* Amount to change by or set to. */ boolean set_flags; /* Whether to set the section flags. */ flagword flags; /* What to set the section flags to. */};static struct section_list *change_sections;static boolean sections_removed;static boolean sections_copied;/* Changes to the start address. */static bfd_vma change_start = 0;static boolean set_start_set = false;static bfd_vma set_start;/* Changes to section addresses. */static bfd_vma change_section_address = 0;/* Filling gaps between sections. */static boolean gap_fill_set = false;static bfd_byte gap_fill = 0;/* Pad to a given address. */static boolean pad_to_set = false;static bfd_vma pad_to;/* List of sections to add. */struct section_add{ /* Next section to add. */ struct section_add *next; /* Name of section to add. */ const char *name; /* Name of file holding section contents. */ const char *filename; /* Size of file. */ size_t size; /* Contents of file. */ bfd_byte *contents; /* BFD section, after it has been added. */ asection *section;};static struct section_add *add_sections;/* Whether to convert debugging information. */static boolean convert_debugging = false;/* Whether to change the leading character in symbol names. */static boolean change_leading_char = false;/* Whether to remove the leading character from global symbol names. */static boolean remove_leading_char = false;/* List of symbols to strip, keep, localize, keep-global, weaken, or redefine. */static struct symlist *strip_specific_list = NULL;static struct symlist *keep_specific_list = NULL;static struct symlist *localize_specific_list = NULL;static struct symlist *keepglobal_specific_list = NULL;static struct symlist *weaken_specific_list = NULL;static struct redefine_node *redefine_sym_list = NULL;/* If this is true, we weaken global symbols (set BSF_WEAK). */static boolean weaken = false;/* 150 isn't special; it's just an arbitrary non-ASCII char value. */#define OPTION_ADD_SECTION 150#define OPTION_CHANGE_ADDRESSES (OPTION_ADD_SECTION + 1)#define OPTION_CHANGE_LEADING_CHAR (OPTION_CHANGE_ADDRESSES + 1)#define OPTION_CHANGE_START (OPTION_CHANGE_LEADING_CHAR + 1)#define OPTION_CHANGE_SECTION_ADDRESS (OPTION_CHANGE_START + 1)#define OPTION_CHANGE_SECTION_LMA (OPTION_CHANGE_SECTION_ADDRESS + 1)#define OPTION_CHANGE_SECTION_VMA (OPTION_CHANGE_SECTION_LMA + 1)#define OPTION_CHANGE_WARNINGS (OPTION_CHANGE_SECTION_VMA + 1)#define OPTION_DEBUGGING (OPTION_CHANGE_WARNINGS + 1)#define OPTION_GAP_FILL (OPTION_DEBUGGING + 1)#define OPTION_NO_CHANGE_WARNINGS (OPTION_GAP_FILL + 1)#define OPTION_PAD_TO (OPTION_NO_CHANGE_WARNINGS + 1)#define OPTION_REMOVE_LEADING_CHAR (OPTION_PAD_TO + 1)#define OPTION_SET_SECTION_FLAGS (OPTION_REMOVE_LEADING_CHAR + 1)#define OPTION_SET_START (OPTION_SET_SECTION_FLAGS + 1)#define OPTION_STRIP_UNNEEDED (OPTION_SET_START + 1)#define OPTION_WEAKEN (OPTION_STRIP_UNNEEDED + 1)#define OPTION_REDEFINE_SYM (OPTION_WEAKEN + 1)#define OPTION_SREC_LEN (OPTION_REDEFINE_SYM + 1)#define OPTION_SREC_FORCES3 (OPTION_SREC_LEN + 1)#define OPTION_STRIP_SYMBOLS (OPTION_SREC_FORCES3 + 1)#define OPTION_KEEP_SYMBOLS (OPTION_STRIP_SYMBOLS + 1)#define OPTION_LOCALIZE_SYMBOLS (OPTION_KEEP_SYMBOLS + 1)#define OPTION_KEEPGLOBAL_SYMBOLS (OPTION_LOCALIZE_SYMBOLS + 1)#define OPTION_WEAKEN_SYMBOLS (OPTION_KEEPGLOBAL_SYMBOLS + 1)/* Options to handle if running as "strip". */static struct option strip_options[] ={ {"discard-all", no_argument, 0, 'x'}, {"discard-locals", no_argument, 0, 'X'}, {"format", required_argument, 0, 'F'}, /* Obsolete */ {"help", no_argument, 0, 'h'}, {"input-format", required_argument, 0, 'I'}, /* Obsolete */ {"input-target", required_argument, 0, 'I'}, {"keep-symbol", required_argument, 0, 'K'}, {"output-format", required_argument, 0, 'O'}, /* Obsolete */ {"output-target", required_argument, 0, 'O'}, {"preserve-dates", no_argument, 0, 'p'}, {"remove-section", required_argument, 0, 'R'}, {"strip-all", no_argument, 0, 's'}, {"strip-debug", no_argument, 0, 'S'}, {"strip-unneeded", no_argument, 0, OPTION_STRIP_UNNEEDED}, {"strip-symbol", required_argument, 0, 'N'}, {"target", required_argument, 0, 'F'}, {"verbose", no_argument, 0, 'v'}, {"version", no_argument, 0, 'V'}, {0, no_argument, 0, 0}};/* Options to handle if running as "objcopy". */static struct option copy_options[] ={ {"add-section", required_argument, 0, OPTION_ADD_SECTION}, {"adjust-start", required_argument, 0, OPTION_CHANGE_START}, {"adjust-vma", required_argument, 0, OPTION_CHANGE_ADDRESSES}, {"adjust-section-vma", required_argument, 0, OPTION_CHANGE_SECTION_ADDRESS}, {"adjust-warnings", no_argument, 0, OPTION_CHANGE_WARNINGS}, {"byte", required_argument, 0, 'b'}, {"change-addresses", required_argument, 0, OPTION_CHANGE_ADDRESSES}, {"change-leading-char", no_argument, 0, OPTION_CHANGE_LEADING_CHAR}, {"change-section-address", required_argument, 0, OPTION_CHANGE_SECTION_ADDRESS}, {"change-section-lma", required_argument, 0, OPTION_CHANGE_SECTION_LMA}, {"change-section-vma", required_argument, 0, OPTION_CHANGE_SECTION_VMA}, {"change-start", required_argument, 0, OPTION_CHANGE_START}, {"change-warnings", no_argument, 0, OPTION_CHANGE_WARNINGS}, {"debugging", no_argument, 0, OPTION_DEBUGGING}, {"discard-all", no_argument, 0, 'x'}, {"discard-locals", no_argument, 0, 'X'}, {"only-section", required_argument, 0, 'j'}, {"format", required_argument, 0, 'F'}, /* Obsolete */ {"gap-fill", required_argument, 0, OPTION_GAP_FILL}, {"help", no_argument, 0, 'h'}, {"input-format", required_argument, 0, 'I'}, /* Obsolete */ {"input-target", required_argument, 0, 'I'}, {"interleave", required_argument, 0, 'i'}, {"keep-symbol", required_argument, 0, 'K'}, {"no-adjust-warnings", no_argument, 0, OPTION_NO_CHANGE_WARNINGS}, {"no-change-warnings", no_argument, 0, OPTION_NO_CHANGE_WARNINGS}, {"output-format", required_argument, 0, 'O'}, /* Obsolete */ {"output-target", required_argument, 0, 'O'}, {"pad-to", required_argument, 0, OPTION_PAD_TO}, {"preserve-dates", no_argument, 0, 'p'}, {"localize-symbol", required_argument, 0, 'L'}, {"keep-global-symbol", required_argument, 0, 'G'}, {"remove-leading-char", no_argument, 0, OPTION_REMOVE_LEADING_CHAR}, {"remove-section", required_argument, 0, 'R'}, {"set-section-flags", required_argument, 0, OPTION_SET_SECTION_FLAGS}, {"set-start", required_argument, 0, OPTION_SET_START}, {"strip-all", no_argument, 0, 'S'}, {"strip-debug", no_argument, 0, 'g'}, {"strip-unneeded", no_argument, 0, OPTION_STRIP_UNNEEDED}, {"strip-symbol", required_argument, 0, 'N'}, {"target", required_argument, 0, 'F'}, {"verbose", no_argument, 0, 'v'}, {"version", no_argument, 0, 'V'}, {"weaken", no_argument, 0, OPTION_WEAKEN}, {"weaken-symbol", required_argument, 0, 'W'}, {"redefine-sym", required_argument, 0, OPTION_REDEFINE_SYM}, {"srec-len", required_argument, 0, OPTION_SREC_LEN}, {"srec-forceS3", no_argument, 0, OPTION_SREC_FORCES3}, {"keep-symbols", required_argument, 0, OPTION_KEEP_SYMBOLS}, {"strip-symbols", required_argument, 0, OPTION_STRIP_SYMBOLS}, {"keep-global-symbols", required_argument, 0, OPTION_KEEPGLOBAL_SYMBOLS}, {"localize-symbols", required_argument, 0, OPTION_LOCALIZE_SYMBOLS}, {"weaken-symbols", required_argument, 0, OPTION_WEAKEN_SYMBOLS}, {0, no_argument, 0, 0}};/* IMPORTS */extern char *program_name;/* This flag distinguishes between strip and objcopy: 1 means this is 'strip'; 0 means this is 'objcopy'. -1 means if we should use argv[0] to decide. */extern int is_strip;/* The maximum length of an S record. This variable is declared in srec.c and can be modified by the --srec-len parameter. */extern unsigned int Chunk;/* Restrict the generation of Srecords to type S3 only. This variable is declare in bfd/srec.c and can be toggled on by the --srec-forceS3 command line switch. */extern boolean S3Forced;static voidcopy_usage (stream, exit_status) FILE *stream; int exit_status;{ fprintf (stream, _("Usage: %s <switches> in-file [out-file]\n"), program_name); fprintf (stream, _(" The switches are:\n")); fprintf (stream, _("\ -I --input-target <bfdname> Assume input file is in format <bfdname>\n\ -O --output-target <bfdname> Create an output file in format <bfdname>\n\ -F --target <bfdname> Set both input and output format to <bfdname>\n\ --debugging Convert debugging information, if possible\n\ -p --preserve-dates Copy modified/access timestamps to the output\n\ -j --only-section <name> Only copy section <name> into the output\n\ -R --remove-section <name> Remove section <name> from the output\n\ -S --strip-all Remove all symbol and relocation information\n\ -g --strip-debug Remove all debugging symbols\n\ --strip-unneeded Remove all symbols not needed by relocations\n\ -N --strip-symbol <name> Do not copy symbol <name>\n\ -K --keep-symbol <name> Only copy symbol <name>\n\ -L --localize-symbol <name> Force symbol <name> to be marked as a local\n\ -G --keep-global-symbol <name> Localize all symbols except <name>\n\ -W --weaken-symbol <name> Force symbol <name> to be marked as a weak\n\ --weaken Force all global symbols to be marked as weak\n\ -x --discard-all Remove all non-global symbols\n\ -X --discard-locals Remove any compiler-generated symbols\n\ -i --interleave <number> Only copy one out of every <number> bytes\n\ -b --byte <num> Select byte <num> in every interleaved block\n\ --gap-fill <val> Fill gaps between sections with <val>\n\ --pad-to <addr> Pad the last section up to address <addr>\n\ --set-start <addr> Set the start address to <addr>\n\ {--change-start|--adjust-start} <incr>\n\ Add <incr> to the start address\n\ {--change-addresses|--adjust-vma} <incr>\n\ Add <incr> to LMA, VMA and start addresses\n\ {--change-section-address|--adjust-section-vma} <name>{=|+|-}<val>\n\ Change LMA and VMA of section <name> by <val>\n\ --change-section-lma <name>{=|+|-}<val>\n\ Change the LMA of section <name> by <val>\n\ --change-section-vma <name>{=|+|-}<val>\n\ Change the VMA of section <name> by <val>\n\ {--[no-]change-warnings|--[no-]adjust-warnings}\n\ Warn if a named section does not exist\n\ --set-section-flags <name>=<flags>\n\ Set section <name>'s properties to <flags>\n\ --add-section <name>=<file> Add section <name> found in <file> to output\n\ --change-leading-char Force output format's leading character style\n\ --remove-leading-char Remove leading character from global symbols\n\ --redefine-sym <old>=<new> Redefine symbol name <old> to <new>\n\ --srec-len <number> Restrict the length of generated Srecords\n\ --srec-forceS3 Restrict the type of generated Srecords to S3\n\ --strip-symbols <file> -N for all symbols listed in <file>\n\ --keep-symbols <file> -K for all symbols listed in <file>\n\ --localize-symbols <file> -L for all symbols listed in <file>\n\ --keep-global-symbols <file> -G for all symbols listed in <file>\n\ --weaken-symbols <file> -W for all symbols listed in <file>\n\ -v --verbose List all object files modified\n\ -V --version Display this program's version number\n\ -h --help Display this output\n\")); list_supported_targets (program_name, stream); if (exit_status == 0) fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO); exit (exit_status);}static voidstrip_usage (stream, exit_status) FILE *stream; int exit_status;{ fprintf (stream, _("Usage: %s <switches> in-file(s)\n"), program_name); fprintf (stream, _(" The switches are:\n")); fprintf (stream, _("\ -I --input-target <bfdname> Assume input file is in format <bfdname>\n\ -O --output-target <bfdname> Create an output file in format <bfdname>\n\ -F --target <bfdname> Set both input and output format to <bfdname>\n\ -p --preserve-dates Copy modified/access timestamps to the output\n\ -R --remove-section <name> Remove section <name> from the output\n\ -s --strip-all Remove all symbol and relocation information\n\ -g -S --strip-debug Remove all debugging symbols\n\ --strip-unneeded Remove all symbols not needed by relocations\n\ -N --strip-symbol <name> Do not copy symbol <name>\n\ -K --keep-symbol <name> Only copy symbol <name>\n\ -x --discard-all Remove all non-global symbols\n\ -X --discard-locals Remove any compiler-generated symbols\n\ -v --verbose List all object files modified\n\ -V --version Display this program's version number\n\ -h --help Display this output\n\ -o <file> Place stripped output into <file>\n\")); list_supported_targets (program_name, stream); if (exit_status == 0) fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO); exit (exit_status);}/* Parse section flags into a flagword, with a fatal error if the string can't be parsed. */static flagwordparse_flags (s) const char *s;{ flagword ret; const char *snext; int len; ret = SEC_NO_FLAGS; do { snext = strchr (s, ','); if (snext == NULL) len = strlen (s); else { len = snext - s; ++snext; } if (0) ;#define PARSE_FLAG(fname,fval) \ else if (strncasecmp (fname, s, len) == 0) ret |= fval PARSE_FLAG ("alloc", SEC_ALLOC); PARSE_FLAG ("load", SEC_LOAD); PARSE_FLAG ("noload", SEC_NEVER_LOAD); PARSE_FLAG ("readonly", SEC_READONLY); PARSE_FLAG ("debug", SEC_DEBUGGING); PARSE_FLAG ("code", SEC_CODE); PARSE_FLAG ("data", SEC_DATA); PARSE_FLAG ("rom", SEC_ROM); PARSE_FLAG ("share", SEC_SHARED);
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -