Home | History | Annotate | Line # | Download | only in binutils
objcopy.c revision 1.1
      1  1.1  christos /* objcopy.c -- copy object file from input to output, optionally massaging it.
      2  1.1  christos    Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
      3  1.1  christos    2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013
      4  1.1  christos    Free Software Foundation, Inc.
      5  1.1  christos 
      6  1.1  christos    This file is part of GNU Binutils.
      7  1.1  christos 
      8  1.1  christos    This program is free software; you can redistribute it and/or modify
      9  1.1  christos    it under the terms of the GNU General Public License as published by
     10  1.1  christos    the Free Software Foundation; either version 3 of the License, or
     11  1.1  christos    (at your option) any later version.
     12  1.1  christos 
     13  1.1  christos    This program is distributed in the hope that it will be useful,
     14  1.1  christos    but WITHOUT ANY WARRANTY; without even the implied warranty of
     15  1.1  christos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     16  1.1  christos    GNU General Public License for more details.
     17  1.1  christos 
     18  1.1  christos    You should have received a copy of the GNU General Public License
     19  1.1  christos    along with this program; if not, write to the Free Software
     20  1.1  christos    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
     21  1.1  christos    02110-1301, USA.  */
     22  1.1  christos 
     23  1.1  christos #include "sysdep.h"
     25  1.1  christos #include "bfd.h"
     26  1.1  christos #include "progress.h"
     27  1.1  christos #include "getopt.h"
     28  1.1  christos #include "libiberty.h"
     29  1.1  christos #include "bucomm.h"
     30  1.1  christos #include "budbg.h"
     31  1.1  christos #include "filenames.h"
     32  1.1  christos #include "fnmatch.h"
     33  1.1  christos #include "elf-bfd.h"
     34  1.1  christos #include <sys/stat.h>
     35  1.1  christos #include <ctype.h>
     36  1.1  christos #include "libbfd.h"
     37  1.1  christos #include "coff/internal.h"
     38  1.1  christos #include "libcoff.h"
     39  1.1  christos 
     40  1.1  christos /* FIXME: See bfd/peXXigen.c for why we include an architecture specific
     41  1.1  christos    header in generic PE code.  */
     42  1.1  christos #include "coff/i386.h"
     43  1.1  christos #include "coff/pe.h"
     44  1.1  christos 
     45  1.1  christos static bfd_vma pe_file_alignment = (bfd_vma) -1;
     46  1.1  christos static bfd_vma pe_heap_commit = (bfd_vma) -1;
     47  1.1  christos static bfd_vma pe_heap_reserve = (bfd_vma) -1;
     48  1.1  christos static bfd_vma pe_image_base = (bfd_vma) -1;
     49  1.1  christos static bfd_vma pe_section_alignment = (bfd_vma) -1;
     50  1.1  christos static bfd_vma pe_stack_commit = (bfd_vma) -1;
     51  1.1  christos static bfd_vma pe_stack_reserve = (bfd_vma) -1;
     52  1.1  christos static short pe_subsystem = -1;
     53  1.1  christos static short pe_major_subsystem_version = -1;
     54  1.1  christos static short pe_minor_subsystem_version = -1;
     55  1.1  christos 
     56  1.1  christos struct is_specified_symbol_predicate_data
     57  1.1  christos {
     58  1.1  christos   const char	*name;
     59  1.1  christos   bfd_boolean	found;
     60  1.1  christos };
     61  1.1  christos 
     62  1.1  christos /* A list to support redefine_sym.  */
     63  1.1  christos struct redefine_node
     64  1.1  christos {
     65  1.1  christos   char *source;
     66  1.1  christos   char *target;
     67  1.1  christos   struct redefine_node *next;
     68  1.1  christos };
     69  1.1  christos 
     70  1.1  christos typedef struct section_rename
     71  1.1  christos {
     72  1.1  christos   const char *            old_name;
     73  1.1  christos   const char *            new_name;
     74  1.1  christos   flagword                flags;
     75  1.1  christos   struct section_rename * next;
     76  1.1  christos }
     77  1.1  christos section_rename;
     78  1.1  christos 
     79  1.1  christos /* List of sections to be renamed.  */
     80  1.1  christos static section_rename *section_rename_list;
     81  1.1  christos 
     82  1.1  christos static asymbol **isympp = NULL;	/* Input symbols.  */
     83  1.1  christos static asymbol **osympp = NULL;	/* Output symbols that survive stripping.  */
     84  1.1  christos 
     85  1.1  christos /* If `copy_byte' >= 0, copy 'copy_width' byte(s) of every `interleave' bytes.  */
     86  1.1  christos static int copy_byte = -1;
     87  1.1  christos static int interleave = 0; /* Initialised to 4 in copy_main().  */
     88  1.1  christos static int copy_width = 1;
     89  1.1  christos 
     90  1.1  christos static bfd_boolean verbose;		/* Print file and target names.  */
     91  1.1  christos static bfd_boolean preserve_dates;	/* Preserve input file timestamp.  */
     92  1.1  christos static int deterministic = -1;		/* Enable deterministic archives.  */
     93  1.1  christos static int status = 0;		/* Exit status.  */
     94  1.1  christos 
     95  1.1  christos enum strip_action
     96  1.1  christos   {
     97  1.1  christos     STRIP_UNDEF,
     98  1.1  christos     STRIP_NONE,			/* Don't strip.  */
     99  1.1  christos     STRIP_DEBUG,		/* Strip all debugger symbols.  */
    100  1.1  christos     STRIP_UNNEEDED,		/* Strip unnecessary symbols.  */
    101  1.1  christos     STRIP_NONDEBUG,		/* Strip everything but debug info.  */
    102  1.1  christos     STRIP_DWO,			/* Strip all DWO info.  */
    103  1.1  christos     STRIP_NONDWO,		/* Strip everything but DWO info.  */
    104  1.1  christos     STRIP_ALL			/* Strip all symbols.  */
    105  1.1  christos   };
    106  1.1  christos 
    107  1.1  christos /* Which symbols to remove.  */
    108  1.1  christos static enum strip_action strip_symbols;
    109  1.1  christos 
    110  1.1  christos enum locals_action
    111  1.1  christos   {
    112  1.1  christos     LOCALS_UNDEF,
    113  1.1  christos     LOCALS_START_L,		/* Discard locals starting with L.  */
    114  1.1  christos     LOCALS_ALL			/* Discard all locals.  */
    115  1.1  christos   };
    116  1.1  christos 
    117  1.1  christos /* Which local symbols to remove.  Overrides STRIP_ALL.  */
    118  1.1  christos static enum locals_action discard_locals;
    119  1.1  christos 
    120  1.1  christos /* What kind of change to perform.  */
    121  1.1  christos enum change_action
    122  1.1  christos {
    123  1.1  christos   CHANGE_IGNORE,
    124  1.1  christos   CHANGE_MODIFY,
    125  1.1  christos   CHANGE_SET
    126  1.1  christos };
    127  1.1  christos 
    128  1.1  christos /* Structure used to hold lists of sections and actions to take.  */
    129  1.1  christos struct section_list
    130  1.1  christos {
    131  1.1  christos   struct section_list * next;	   /* Next section to change.  */
    132  1.1  christos   const char *		name;	   /* Section name.  */
    133  1.1  christos   bfd_boolean		used;	   /* Whether this entry was used.  */
    134  1.1  christos   bfd_boolean		remove;	   /* Whether to remove this section.  */
    135  1.1  christos   bfd_boolean		copy;	   /* Whether to copy this section.  */
    136  1.1  christos   enum change_action	change_vma;/* Whether to change or set VMA.  */
    137  1.1  christos   bfd_vma		vma_val;   /* Amount to change by or set to.  */
    138  1.1  christos   enum change_action	change_lma;/* Whether to change or set LMA.  */
    139  1.1  christos   bfd_vma		lma_val;   /* Amount to change by or set to.  */
    140  1.1  christos   bfd_boolean		set_flags; /* Whether to set the section flags.	 */
    141  1.1  christos   flagword		flags;	   /* What to set the section flags to.	 */
    142  1.1  christos };
    143  1.1  christos 
    144  1.1  christos static struct section_list *change_sections;
    145  1.1  christos 
    146  1.1  christos /* TRUE if some sections are to be removed.  */
    147  1.1  christos static bfd_boolean sections_removed;
    148  1.1  christos 
    149  1.1  christos /* TRUE if only some sections are to be copied.  */
    150  1.1  christos static bfd_boolean sections_copied;
    151  1.1  christos 
    152  1.1  christos /* Changes to the start address.  */
    153  1.1  christos static bfd_vma change_start = 0;
    154  1.1  christos static bfd_boolean set_start_set = FALSE;
    155  1.1  christos static bfd_vma set_start;
    156  1.1  christos 
    157  1.1  christos /* Changes to section addresses.  */
    158  1.1  christos static bfd_vma change_section_address = 0;
    159  1.1  christos 
    160  1.1  christos /* Filling gaps between sections.  */
    161  1.1  christos static bfd_boolean gap_fill_set = FALSE;
    162  1.1  christos static bfd_byte gap_fill = 0;
    163  1.1  christos 
    164  1.1  christos /* Pad to a given address.  */
    165  1.1  christos static bfd_boolean pad_to_set = FALSE;
    166  1.1  christos static bfd_vma pad_to;
    167  1.1  christos 
    168  1.1  christos /* Use alternative machine code?  */
    169  1.1  christos static unsigned long use_alt_mach_code = 0;
    170  1.1  christos 
    171  1.1  christos /* Output BFD flags user wants to set or clear */
    172  1.1  christos static flagword bfd_flags_to_set;
    173  1.1  christos static flagword bfd_flags_to_clear;
    174  1.1  christos 
    175  1.1  christos /* List of sections to add.  */
    176  1.1  christos struct section_add
    177  1.1  christos {
    178  1.1  christos   /* Next section to add.  */
    179  1.1  christos   struct section_add *next;
    180  1.1  christos   /* Name of section to add.  */
    181  1.1  christos   const char *name;
    182  1.1  christos   /* Name of file holding section contents.  */
    183  1.1  christos   const char *filename;
    184  1.1  christos   /* Size of file.  */
    185  1.1  christos   size_t size;
    186  1.1  christos   /* Contents of file.  */
    187  1.1  christos   bfd_byte *contents;
    188  1.1  christos   /* BFD section, after it has been added.  */
    189  1.1  christos   asection *section;
    190  1.1  christos };
    191  1.1  christos 
    192  1.1  christos /* List of sections to add to the output BFD.  */
    193  1.1  christos static struct section_add *add_sections;
    194  1.1  christos 
    195  1.1  christos /* If non-NULL the argument to --add-gnu-debuglink.
    196  1.1  christos    This should be the filename to store in the .gnu_debuglink section.  */
    197  1.1  christos static const char * gnu_debuglink_filename = NULL;
    198  1.1  christos 
    199  1.1  christos /* Whether to convert debugging information.  */
    200  1.1  christos static bfd_boolean convert_debugging = FALSE;
    201  1.1  christos 
    202  1.1  christos /* Whether to compress/decompress DWARF debug sections.  */
    203  1.1  christos static enum
    204  1.1  christos {
    205  1.1  christos   nothing,
    206  1.1  christos   compress,
    207  1.1  christos   decompress
    208  1.1  christos } do_debug_sections = nothing;
    209  1.1  christos 
    210  1.1  christos /* Whether to change the leading character in symbol names.  */
    211  1.1  christos static bfd_boolean change_leading_char = FALSE;
    212  1.1  christos 
    213  1.1  christos /* Whether to remove the leading character from global symbol names.  */
    214  1.1  christos static bfd_boolean remove_leading_char = FALSE;
    215  1.1  christos 
    216  1.1  christos /* Whether to permit wildcard in symbol comparison.  */
    217  1.1  christos static bfd_boolean wildcard = FALSE;
    218  1.1  christos 
    219  1.1  christos /* True if --localize-hidden is in effect.  */
    220  1.1  christos static bfd_boolean localize_hidden = FALSE;
    221  1.1  christos 
    222  1.1  christos /* List of symbols to strip, keep, localize, keep-global, weaken,
    223  1.1  christos    or redefine.  */
    224  1.1  christos static htab_t strip_specific_htab = NULL;
    225  1.1  christos static htab_t strip_unneeded_htab = NULL;
    226  1.1  christos static htab_t keep_specific_htab = NULL;
    227  1.1  christos static htab_t localize_specific_htab = NULL;
    228  1.1  christos static htab_t globalize_specific_htab = NULL;
    229  1.1  christos static htab_t keepglobal_specific_htab = NULL;
    230  1.1  christos static htab_t weaken_specific_htab = NULL;
    231  1.1  christos static struct redefine_node *redefine_sym_list = NULL;
    232  1.1  christos 
    233  1.1  christos /* If this is TRUE, we weaken global symbols (set BSF_WEAK).  */
    234  1.1  christos static bfd_boolean weaken = FALSE;
    235  1.1  christos 
    236  1.1  christos /* If this is TRUE, we retain BSF_FILE symbols.  */
    237  1.1  christos static bfd_boolean keep_file_symbols = FALSE;
    238  1.1  christos 
    239  1.1  christos /* Prefix symbols/sections.  */
    240  1.1  christos static char *prefix_symbols_string = 0;
    241  1.1  christos static char *prefix_sections_string = 0;
    242  1.1  christos static char *prefix_alloc_sections_string = 0;
    243  1.1  christos 
    244  1.1  christos /* True if --extract-symbol was passed on the command line.  */
    245  1.1  christos static bfd_boolean extract_symbol = FALSE;
    246  1.1  christos 
    247  1.1  christos /* If `reverse_bytes' is nonzero, then reverse the order of every chunk
    248  1.1  christos    of <reverse_bytes> bytes within each output section.  */
    249  1.1  christos static int reverse_bytes = 0;
    250  1.1  christos 
    251  1.1  christos /* For Coff objects, we may want to allow or disallow long section names,
    252  1.1  christos    or preserve them where found in the inputs.  Debug info relies on them.  */
    253  1.1  christos enum long_section_name_handling
    254  1.1  christos   {
    255  1.1  christos     DISABLE,
    256  1.1  christos     ENABLE,
    257  1.1  christos     KEEP
    258  1.1  christos   };
    259  1.1  christos 
    260  1.1  christos /* The default long section handling mode is to preserve them.
    261  1.1  christos    This is also the only behaviour for 'strip'.  */
    262  1.1  christos static enum long_section_name_handling long_section_names = KEEP;
    263  1.1  christos 
    264  1.1  christos /* 150 isn't special; it's just an arbitrary non-ASCII char value.  */
    265  1.1  christos enum command_line_switch
    266  1.1  christos   {
    267  1.1  christos     OPTION_ADD_SECTION=150,
    268  1.1  christos     OPTION_CHANGE_ADDRESSES,
    269  1.1  christos     OPTION_CHANGE_LEADING_CHAR,
    270  1.1  christos     OPTION_CHANGE_START,
    271  1.1  christos     OPTION_CHANGE_SECTION_ADDRESS,
    272  1.1  christos     OPTION_CHANGE_SECTION_LMA,
    273  1.1  christos     OPTION_CHANGE_SECTION_VMA,
    274  1.1  christos     OPTION_CHANGE_WARNINGS,
    275  1.1  christos     OPTION_COMPRESS_DEBUG_SECTIONS,
    276  1.1  christos     OPTION_DEBUGGING,
    277  1.1  christos     OPTION_DECOMPRESS_DEBUG_SECTIONS,
    278  1.1  christos     OPTION_GAP_FILL,
    279  1.1  christos     OPTION_NO_CHANGE_WARNINGS,
    280  1.1  christos     OPTION_PAD_TO,
    281  1.1  christos     OPTION_REMOVE_LEADING_CHAR,
    282  1.1  christos     OPTION_SET_SECTION_FLAGS,
    283  1.1  christos     OPTION_SET_START,
    284  1.1  christos     OPTION_STRIP_UNNEEDED,
    285  1.1  christos     OPTION_WEAKEN,
    286  1.1  christos     OPTION_REDEFINE_SYM,
    287  1.1  christos     OPTION_REDEFINE_SYMS,
    288  1.1  christos     OPTION_SREC_LEN,
    289  1.1  christos     OPTION_SREC_FORCES3,
    290  1.1  christos     OPTION_STRIP_SYMBOLS,
    291  1.1  christos     OPTION_STRIP_UNNEEDED_SYMBOL,
    292  1.1  christos     OPTION_STRIP_UNNEEDED_SYMBOLS,
    293  1.1  christos     OPTION_KEEP_SYMBOLS,
    294  1.1  christos     OPTION_LOCALIZE_HIDDEN,
    295  1.1  christos     OPTION_LOCALIZE_SYMBOLS,
    296  1.1  christos     OPTION_LONG_SECTION_NAMES,
    297  1.1  christos     OPTION_GLOBALIZE_SYMBOL,
    298  1.1  christos     OPTION_GLOBALIZE_SYMBOLS,
    299  1.1  christos     OPTION_KEEPGLOBAL_SYMBOLS,
    300  1.1  christos     OPTION_WEAKEN_SYMBOLS,
    301  1.1  christos     OPTION_RENAME_SECTION,
    302  1.1  christos     OPTION_ALT_MACH_CODE,
    303  1.1  christos     OPTION_PREFIX_SYMBOLS,
    304  1.1  christos     OPTION_PREFIX_SECTIONS,
    305  1.1  christos     OPTION_PREFIX_ALLOC_SECTIONS,
    306  1.1  christos     OPTION_FORMATS_INFO,
    307  1.1  christos     OPTION_ADD_GNU_DEBUGLINK,
    308  1.1  christos     OPTION_ONLY_KEEP_DEBUG,
    309  1.1  christos     OPTION_KEEP_FILE_SYMBOLS,
    310  1.1  christos     OPTION_READONLY_TEXT,
    311  1.1  christos     OPTION_WRITABLE_TEXT,
    312  1.1  christos     OPTION_PURE,
    313  1.1  christos     OPTION_IMPURE,
    314  1.1  christos     OPTION_EXTRACT_SYMBOL,
    315  1.1  christos     OPTION_REVERSE_BYTES,
    316  1.1  christos     OPTION_FILE_ALIGNMENT,
    317  1.1  christos     OPTION_HEAP,
    318  1.1  christos     OPTION_IMAGE_BASE,
    319  1.1  christos     OPTION_SECTION_ALIGNMENT,
    320  1.1  christos     OPTION_STACK,
    321  1.1  christos     OPTION_INTERLEAVE_WIDTH,
    322  1.1  christos     OPTION_SUBSYSTEM,
    323  1.1  christos     OPTION_EXTRACT_DWO,
    324  1.1  christos     OPTION_STRIP_DWO
    325  1.1  christos   };
    326  1.1  christos 
    327  1.1  christos /* Options to handle if running as "strip".  */
    328  1.1  christos 
    329  1.1  christos static struct option strip_options[] =
    330  1.1  christos {
    331  1.1  christos   {"disable-deterministic-archives", no_argument, 0, 'U'},
    332  1.1  christos   {"discard-all", no_argument, 0, 'x'},
    333  1.1  christos   {"discard-locals", no_argument, 0, 'X'},
    334  1.1  christos   {"enable-deterministic-archives", no_argument, 0, 'D'},
    335  1.1  christos   {"format", required_argument, 0, 'F'}, /* Obsolete */
    336  1.1  christos   {"help", no_argument, 0, 'h'},
    337  1.1  christos   {"info", no_argument, 0, OPTION_FORMATS_INFO},
    338  1.1  christos   {"input-format", required_argument, 0, 'I'}, /* Obsolete */
    339  1.1  christos   {"input-target", required_argument, 0, 'I'},
    340  1.1  christos   {"keep-file-symbols", no_argument, 0, OPTION_KEEP_FILE_SYMBOLS},
    341  1.1  christos   {"keep-symbol", required_argument, 0, 'K'},
    342  1.1  christos   {"only-keep-debug", no_argument, 0, OPTION_ONLY_KEEP_DEBUG},
    343  1.1  christos   {"output-format", required_argument, 0, 'O'},	/* Obsolete */
    344  1.1  christos   {"output-target", required_argument, 0, 'O'},
    345  1.1  christos   {"output-file", required_argument, 0, 'o'},
    346  1.1  christos   {"preserve-dates", no_argument, 0, 'p'},
    347  1.1  christos   {"remove-section", required_argument, 0, 'R'},
    348  1.1  christos   {"strip-all", no_argument, 0, 's'},
    349  1.1  christos   {"strip-debug", no_argument, 0, 'S'},
    350  1.1  christos   {"strip-dwo", no_argument, 0, OPTION_STRIP_DWO},
    351  1.1  christos   {"strip-unneeded", no_argument, 0, OPTION_STRIP_UNNEEDED},
    352  1.1  christos   {"strip-symbol", required_argument, 0, 'N'},
    353  1.1  christos   {"target", required_argument, 0, 'F'},
    354  1.1  christos   {"verbose", no_argument, 0, 'v'},
    355  1.1  christos   {"version", no_argument, 0, 'V'},
    356  1.1  christos   {"wildcard", no_argument, 0, 'w'},
    357  1.1  christos   {0, no_argument, 0, 0}
    358  1.1  christos };
    359  1.1  christos 
    360  1.1  christos /* Options to handle if running as "objcopy".  */
    361  1.1  christos 
    362  1.1  christos static struct option copy_options[] =
    363  1.1  christos {
    364  1.1  christos   {"add-gnu-debuglink", required_argument, 0, OPTION_ADD_GNU_DEBUGLINK},
    365  1.1  christos   {"add-section", required_argument, 0, OPTION_ADD_SECTION},
    366  1.1  christos   {"adjust-start", required_argument, 0, OPTION_CHANGE_START},
    367  1.1  christos   {"adjust-vma", required_argument, 0, OPTION_CHANGE_ADDRESSES},
    368  1.1  christos   {"adjust-section-vma", required_argument, 0, OPTION_CHANGE_SECTION_ADDRESS},
    369  1.1  christos   {"adjust-warnings", no_argument, 0, OPTION_CHANGE_WARNINGS},
    370  1.1  christos   {"alt-machine-code", required_argument, 0, OPTION_ALT_MACH_CODE},
    371  1.1  christos   {"binary-architecture", required_argument, 0, 'B'},
    372  1.1  christos   {"byte", required_argument, 0, 'b'},
    373  1.1  christos   {"change-addresses", required_argument, 0, OPTION_CHANGE_ADDRESSES},
    374  1.1  christos   {"change-leading-char", no_argument, 0, OPTION_CHANGE_LEADING_CHAR},
    375  1.1  christos   {"change-section-address", required_argument, 0, OPTION_CHANGE_SECTION_ADDRESS},
    376  1.1  christos   {"change-section-lma", required_argument, 0, OPTION_CHANGE_SECTION_LMA},
    377  1.1  christos   {"change-section-vma", required_argument, 0, OPTION_CHANGE_SECTION_VMA},
    378  1.1  christos   {"change-start", required_argument, 0, OPTION_CHANGE_START},
    379  1.1  christos   {"change-warnings", no_argument, 0, OPTION_CHANGE_WARNINGS},
    380  1.1  christos   {"compress-debug-sections", no_argument, 0, OPTION_COMPRESS_DEBUG_SECTIONS},
    381  1.1  christos   {"debugging", no_argument, 0, OPTION_DEBUGGING},
    382  1.1  christos   {"decompress-debug-sections", no_argument, 0, OPTION_DECOMPRESS_DEBUG_SECTIONS},
    383  1.1  christos   {"disable-deterministic-archives", no_argument, 0, 'U'},
    384  1.1  christos   {"discard-all", no_argument, 0, 'x'},
    385  1.1  christos   {"discard-locals", no_argument, 0, 'X'},
    386  1.1  christos   {"enable-deterministic-archives", no_argument, 0, 'D'},
    387  1.1  christos   {"extract-dwo", no_argument, 0, OPTION_EXTRACT_DWO},
    388  1.1  christos   {"extract-symbol", no_argument, 0, OPTION_EXTRACT_SYMBOL},
    389  1.1  christos   {"format", required_argument, 0, 'F'}, /* Obsolete */
    390  1.1  christos   {"gap-fill", required_argument, 0, OPTION_GAP_FILL},
    391  1.1  christos   {"globalize-symbol", required_argument, 0, OPTION_GLOBALIZE_SYMBOL},
    392  1.1  christos   {"globalize-symbols", required_argument, 0, OPTION_GLOBALIZE_SYMBOLS},
    393  1.1  christos   {"help", no_argument, 0, 'h'},
    394  1.1  christos   {"impure", no_argument, 0, OPTION_IMPURE},
    395  1.1  christos   {"info", no_argument, 0, OPTION_FORMATS_INFO},
    396  1.1  christos   {"input-format", required_argument, 0, 'I'}, /* Obsolete */
    397  1.1  christos   {"input-target", required_argument, 0, 'I'},
    398  1.1  christos   {"interleave", optional_argument, 0, 'i'},
    399  1.1  christos   {"interleave-width", required_argument, 0, OPTION_INTERLEAVE_WIDTH},
    400  1.1  christos   {"keep-file-symbols", no_argument, 0, OPTION_KEEP_FILE_SYMBOLS},
    401  1.1  christos   {"keep-global-symbol", required_argument, 0, 'G'},
    402  1.1  christos   {"keep-global-symbols", required_argument, 0, OPTION_KEEPGLOBAL_SYMBOLS},
    403  1.1  christos   {"keep-symbol", required_argument, 0, 'K'},
    404  1.1  christos   {"keep-symbols", required_argument, 0, OPTION_KEEP_SYMBOLS},
    405  1.1  christos   {"localize-hidden", no_argument, 0, OPTION_LOCALIZE_HIDDEN},
    406  1.1  christos   {"localize-symbol", required_argument, 0, 'L'},
    407  1.1  christos   {"localize-symbols", required_argument, 0, OPTION_LOCALIZE_SYMBOLS},
    408  1.1  christos   {"long-section-names", required_argument, 0, OPTION_LONG_SECTION_NAMES},
    409  1.1  christos   {"no-adjust-warnings", no_argument, 0, OPTION_NO_CHANGE_WARNINGS},
    410  1.1  christos   {"no-change-warnings", no_argument, 0, OPTION_NO_CHANGE_WARNINGS},
    411  1.1  christos   {"only-keep-debug", no_argument, 0, OPTION_ONLY_KEEP_DEBUG},
    412  1.1  christos   {"only-section", required_argument, 0, 'j'},
    413  1.1  christos   {"output-format", required_argument, 0, 'O'},	/* Obsolete */
    414  1.1  christos   {"output-target", required_argument, 0, 'O'},
    415  1.1  christos   {"pad-to", required_argument, 0, OPTION_PAD_TO},
    416  1.1  christos   {"prefix-symbols", required_argument, 0, OPTION_PREFIX_SYMBOLS},
    417  1.1  christos   {"prefix-sections", required_argument, 0, OPTION_PREFIX_SECTIONS},
    418  1.1  christos   {"prefix-alloc-sections", required_argument, 0, OPTION_PREFIX_ALLOC_SECTIONS},
    419  1.1  christos   {"preserve-dates", no_argument, 0, 'p'},
    420  1.1  christos   {"pure", no_argument, 0, OPTION_PURE},
    421  1.1  christos   {"readonly-text", no_argument, 0, OPTION_READONLY_TEXT},
    422  1.1  christos   {"redefine-sym", required_argument, 0, OPTION_REDEFINE_SYM},
    423  1.1  christos   {"redefine-syms", required_argument, 0, OPTION_REDEFINE_SYMS},
    424  1.1  christos   {"remove-leading-char", no_argument, 0, OPTION_REMOVE_LEADING_CHAR},
    425  1.1  christos   {"remove-section", required_argument, 0, 'R'},
    426  1.1  christos   {"rename-section", required_argument, 0, OPTION_RENAME_SECTION},
    427  1.1  christos   {"reverse-bytes", required_argument, 0, OPTION_REVERSE_BYTES},
    428  1.1  christos   {"set-section-flags", required_argument, 0, OPTION_SET_SECTION_FLAGS},
    429  1.1  christos   {"set-start", required_argument, 0, OPTION_SET_START},
    430  1.1  christos   {"srec-len", required_argument, 0, OPTION_SREC_LEN},
    431  1.1  christos   {"srec-forceS3", no_argument, 0, OPTION_SREC_FORCES3},
    432  1.1  christos   {"strip-all", no_argument, 0, 'S'},
    433  1.1  christos   {"strip-debug", no_argument, 0, 'g'},
    434  1.1  christos   {"strip-dwo", no_argument, 0, OPTION_STRIP_DWO},
    435  1.1  christos   {"strip-unneeded", no_argument, 0, OPTION_STRIP_UNNEEDED},
    436  1.1  christos   {"strip-unneeded-symbol", required_argument, 0, OPTION_STRIP_UNNEEDED_SYMBOL},
    437  1.1  christos   {"strip-unneeded-symbols", required_argument, 0, OPTION_STRIP_UNNEEDED_SYMBOLS},
    438  1.1  christos   {"strip-symbol", required_argument, 0, 'N'},
    439  1.1  christos   {"strip-symbols", required_argument, 0, OPTION_STRIP_SYMBOLS},
    440  1.1  christos   {"target", required_argument, 0, 'F'},
    441  1.1  christos   {"verbose", no_argument, 0, 'v'},
    442  1.1  christos   {"version", no_argument, 0, 'V'},
    443  1.1  christos   {"weaken", no_argument, 0, OPTION_WEAKEN},
    444  1.1  christos   {"weaken-symbol", required_argument, 0, 'W'},
    445  1.1  christos   {"weaken-symbols", required_argument, 0, OPTION_WEAKEN_SYMBOLS},
    446  1.1  christos   {"wildcard", no_argument, 0, 'w'},
    447  1.1  christos   {"writable-text", no_argument, 0, OPTION_WRITABLE_TEXT},
    448  1.1  christos   {"file-alignment", required_argument, 0, OPTION_FILE_ALIGNMENT},
    449  1.1  christos   {"heap", required_argument, 0, OPTION_HEAP},
    450  1.1  christos   {"image-base", required_argument, 0 , OPTION_IMAGE_BASE},
    451  1.1  christos   {"section-alignment", required_argument, 0, OPTION_SECTION_ALIGNMENT},
    452  1.1  christos   {"stack", required_argument, 0, OPTION_STACK},
    453  1.1  christos   {"subsystem", required_argument, 0, OPTION_SUBSYSTEM},
    454  1.1  christos   {0, no_argument, 0, 0}
    455  1.1  christos };
    456  1.1  christos 
    457  1.1  christos /* IMPORTS */
    458  1.1  christos extern char *program_name;
    459  1.1  christos 
    460  1.1  christos /* This flag distinguishes between strip and objcopy:
    461  1.1  christos    1 means this is 'strip'; 0 means this is 'objcopy'.
    462  1.1  christos    -1 means if we should use argv[0] to decide.  */
    463  1.1  christos extern int is_strip;
    464  1.1  christos 
    465  1.1  christos /* The maximum length of an S record.  This variable is declared in srec.c
    466  1.1  christos    and can be modified by the --srec-len parameter.  */
    467  1.1  christos extern unsigned int Chunk;
    468  1.1  christos 
    469  1.1  christos /* Restrict the generation of Srecords to type S3 only.
    470  1.1  christos    This variable is declare in bfd/srec.c and can be toggled
    471  1.1  christos    on by the --srec-forceS3 command line switch.  */
    472  1.1  christos extern bfd_boolean S3Forced;
    473  1.1  christos 
    474  1.1  christos /* Forward declarations.  */
    475  1.1  christos static void setup_section (bfd *, asection *, void *);
    476  1.1  christos static void setup_bfd_headers (bfd *, bfd *);
    477  1.1  christos static void copy_relocations_in_section (bfd *, asection *, void *);
    478  1.1  christos static void copy_section (bfd *, asection *, void *);
    479  1.1  christos static void get_sections (bfd *, asection *, void *);
    480  1.1  christos static int compare_section_lma (const void *, const void *);
    481  1.1  christos static void mark_symbols_used_in_relocations (bfd *, asection *, void *);
    482  1.1  christos static bfd_boolean write_debugging_info (bfd *, void *, long *, asymbol ***);
    483  1.1  christos static const char *lookup_sym_redefinition (const char *);
    484  1.1  christos 
    485  1.1  christos static void
    487  1.1  christos copy_usage (FILE *stream, int exit_status)
    488  1.1  christos {
    489  1.1  christos   fprintf (stream, _("Usage: %s [option(s)] in-file [out-file]\n"), program_name);
    490  1.1  christos   fprintf (stream, _(" Copies a binary file, possibly transforming it in the process\n"));
    491  1.1  christos   fprintf (stream, _(" The options are:\n"));
    492  1.1  christos   fprintf (stream, _("\
    493  1.1  christos   -I --input-target <bfdname>      Assume input file is in format <bfdname>\n\
    494  1.1  christos   -O --output-target <bfdname>     Create an output file in format <bfdname>\n\
    495  1.1  christos   -B --binary-architecture <arch>  Set output arch, when input is arch-less\n\
    496  1.1  christos   -F --target <bfdname>            Set both input and output format to <bfdname>\n\
    497  1.1  christos      --debugging                   Convert debugging information, if possible\n\
    498  1.1  christos   -p --preserve-dates              Copy modified/access timestamps to the output\n"));
    499  1.1  christos   if (DEFAULT_AR_DETERMINISTIC)
    500  1.1  christos     fprintf (stream, _("\
    501  1.1  christos   -D --enable-deterministic-archives\n\
    502  1.1  christos                                    Produce deterministic output when stripping archives (default)\n\
    503  1.1  christos   -U --disable-deterministic-archives\n\
    504  1.1  christos                                    Disable -D behavior\n"));
    505  1.1  christos   else
    506  1.1  christos     fprintf (stream, _("\
    507  1.1  christos   -D --enable-deterministic-archives\n\
    508  1.1  christos                                    Produce deterministic output when stripping archives\n\
    509  1.1  christos   -U --disable-deterministic-archives\n\
    510  1.1  christos                                    Disable -D behavior (default)\n"));
    511  1.1  christos   fprintf (stream, _("\
    512  1.1  christos   -j --only-section <name>         Only copy section <name> into the output\n\
    513  1.1  christos      --add-gnu-debuglink=<file>    Add section .gnu_debuglink linking to <file>\n\
    514  1.1  christos   -R --remove-section <name>       Remove section <name> from the output\n\
    515  1.1  christos   -S --strip-all                   Remove all symbol and relocation information\n\
    516  1.1  christos   -g --strip-debug                 Remove all debugging symbols & sections\n\
    517  1.1  christos      --strip-dwo                   Remove all DWO sections\n\
    518  1.1  christos      --strip-unneeded              Remove all symbols not needed by relocations\n\
    519  1.1  christos   -N --strip-symbol <name>         Do not copy symbol <name>\n\
    520  1.1  christos      --strip-unneeded-symbol <name>\n\
    521  1.1  christos                                    Do not copy symbol <name> unless needed by\n\
    522  1.1  christos                                      relocations\n\
    523  1.1  christos      --only-keep-debug             Strip everything but the debug information\n\
    524  1.1  christos      --extract-dwo                 Copy only DWO sections\n\
    525  1.1  christos      --extract-symbol              Remove section contents but keep symbols\n\
    526  1.1  christos   -K --keep-symbol <name>          Do not strip symbol <name>\n\
    527  1.1  christos      --keep-file-symbols           Do not strip file symbol(s)\n\
    528  1.1  christos      --localize-hidden             Turn all ELF hidden symbols into locals\n\
    529  1.1  christos   -L --localize-symbol <name>      Force symbol <name> to be marked as a local\n\
    530  1.1  christos      --globalize-symbol <name>     Force symbol <name> to be marked as a global\n\
    531  1.1  christos   -G --keep-global-symbol <name>   Localize all symbols except <name>\n\
    532  1.1  christos   -W --weaken-symbol <name>        Force symbol <name> to be marked as a weak\n\
    533  1.1  christos      --weaken                      Force all global symbols to be marked as weak\n\
    534  1.1  christos   -w --wildcard                    Permit wildcard in symbol comparison\n\
    535  1.1  christos   -x --discard-all                 Remove all non-global symbols\n\
    536  1.1  christos   -X --discard-locals              Remove any compiler-generated symbols\n\
    537  1.1  christos   -i --interleave [<number>]       Only copy N out of every <number> bytes\n\
    538  1.1  christos      --interleave-width <number>   Set N for --interleave\n\
    539  1.1  christos   -b --byte <num>                  Select byte <num> in every interleaved block\n\
    540  1.1  christos      --gap-fill <val>              Fill gaps between sections with <val>\n\
    541  1.1  christos      --pad-to <addr>               Pad the last section up to address <addr>\n\
    542  1.1  christos      --set-start <addr>            Set the start address to <addr>\n\
    543  1.1  christos     {--change-start|--adjust-start} <incr>\n\
    544  1.1  christos                                    Add <incr> to the start address\n\
    545  1.1  christos     {--change-addresses|--adjust-vma} <incr>\n\
    546  1.1  christos                                    Add <incr> to LMA, VMA and start addresses\n\
    547  1.1  christos     {--change-section-address|--adjust-section-vma} <name>{=|+|-}<val>\n\
    548  1.1  christos                                    Change LMA and VMA of section <name> by <val>\n\
    549  1.1  christos      --change-section-lma <name>{=|+|-}<val>\n\
    550  1.1  christos                                    Change the LMA of section <name> by <val>\n\
    551  1.1  christos      --change-section-vma <name>{=|+|-}<val>\n\
    552  1.1  christos                                    Change the VMA of section <name> by <val>\n\
    553  1.1  christos     {--[no-]change-warnings|--[no-]adjust-warnings}\n\
    554  1.1  christos                                    Warn if a named section does not exist\n\
    555  1.1  christos      --set-section-flags <name>=<flags>\n\
    556  1.1  christos                                    Set section <name>'s properties to <flags>\n\
    557  1.1  christos      --add-section <name>=<file>   Add section <name> found in <file> to output\n\
    558  1.1  christos      --rename-section <old>=<new>[,<flags>] Rename section <old> to <new>\n\
    559  1.1  christos      --long-section-names {enable|disable|keep}\n\
    560  1.1  christos                                    Handle long section names in Coff objects.\n\
    561  1.1  christos      --change-leading-char         Force output format's leading character style\n\
    562  1.1  christos      --remove-leading-char         Remove leading character from global symbols\n\
    563  1.1  christos      --reverse-bytes=<num>         Reverse <num> bytes at a time, in output sections with content\n\
    564  1.1  christos      --redefine-sym <old>=<new>    Redefine symbol name <old> to <new>\n\
    565  1.1  christos      --redefine-syms <file>        --redefine-sym for all symbol pairs \n\
    566  1.1  christos                                      listed in <file>\n\
    567  1.1  christos      --srec-len <number>           Restrict the length of generated Srecords\n\
    568  1.1  christos      --srec-forceS3                Restrict the type of generated Srecords to S3\n\
    569  1.1  christos      --strip-symbols <file>        -N for all symbols listed in <file>\n\
    570  1.1  christos      --strip-unneeded-symbols <file>\n\
    571  1.1  christos                                    --strip-unneeded-symbol for all symbols listed\n\
    572  1.1  christos                                      in <file>\n\
    573  1.1  christos      --keep-symbols <file>         -K for all symbols listed in <file>\n\
    574  1.1  christos      --localize-symbols <file>     -L for all symbols listed in <file>\n\
    575  1.1  christos      --globalize-symbols <file>    --globalize-symbol for all in <file>\n\
    576  1.1  christos      --keep-global-symbols <file>  -G for all symbols listed in <file>\n\
    577  1.1  christos      --weaken-symbols <file>       -W for all symbols listed in <file>\n\
    578  1.1  christos      --alt-machine-code <index>    Use the target's <index>'th alternative machine\n\
    579  1.1  christos      --writable-text               Mark the output text as writable\n\
    580  1.1  christos      --readonly-text               Make the output text write protected\n\
    581  1.1  christos      --pure                        Mark the output file as demand paged\n\
    582  1.1  christos      --impure                      Mark the output file as impure\n\
    583  1.1  christos      --prefix-symbols <prefix>     Add <prefix> to start of every symbol name\n\
    584  1.1  christos      --prefix-sections <prefix>    Add <prefix> to start of every section name\n\
    585  1.1  christos      --prefix-alloc-sections <prefix>\n\
    586  1.1  christos                                    Add <prefix> to start of every allocatable\n\
    587  1.1  christos                                      section name\n\
    588  1.1  christos      --file-alignment <num>        Set PE file alignment to <num>\n\
    589  1.1  christos      --heap <reserve>[,<commit>]   Set PE reserve/commit heap to <reserve>/\n\
    590  1.1  christos                                    <commit>\n\
    591  1.1  christos      --image-base <address>        Set PE image base to <address>\n\
    592  1.1  christos      --section-alignment <num>     Set PE section alignment to <num>\n\
    593  1.1  christos      --stack <reserve>[,<commit>]  Set PE reserve/commit stack to <reserve>/\n\
    594  1.1  christos                                    <commit>\n\
    595  1.1  christos      --subsystem <name>[:<version>]\n\
    596  1.1  christos                                    Set PE subsystem to <name> [& <version>]\n\
    597  1.1  christos      --compress-debug-sections     Compress DWARF debug sections using zlib\n\
    598  1.1  christos      --decompress-debug-sections   Decompress DWARF debug sections using zlib\n\
    599  1.1  christos   -v --verbose                     List all object files modified\n\
    600  1.1  christos   @<file>                          Read options from <file>\n\
    601  1.1  christos   -V --version                     Display this program's version number\n\
    602  1.1  christos   -h --help                        Display this output\n\
    603  1.1  christos      --info                        List object formats & architectures supported\n\
    604  1.1  christos "));
    605  1.1  christos   list_supported_targets (program_name, stream);
    606  1.1  christos   if (REPORT_BUGS_TO[0] && exit_status == 0)
    607  1.1  christos     fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO);
    608  1.1  christos   exit (exit_status);
    609  1.1  christos }
    610  1.1  christos 
    611  1.1  christos static void
    612  1.1  christos strip_usage (FILE *stream, int exit_status)
    613  1.1  christos {
    614  1.1  christos   fprintf (stream, _("Usage: %s <option(s)> in-file(s)\n"), program_name);
    615  1.1  christos   fprintf (stream, _(" Removes symbols and sections from files\n"));
    616  1.1  christos   fprintf (stream, _(" The options are:\n"));
    617  1.1  christos   fprintf (stream, _("\
    618  1.1  christos   -I --input-target=<bfdname>      Assume input file is in format <bfdname>\n\
    619  1.1  christos   -O --output-target=<bfdname>     Create an output file in format <bfdname>\n\
    620  1.1  christos   -F --target=<bfdname>            Set both input and output format to <bfdname>\n\
    621  1.1  christos   -p --preserve-dates              Copy modified/access timestamps to the output\n\
    622  1.1  christos "));
    623  1.1  christos   if (DEFAULT_AR_DETERMINISTIC)
    624  1.1  christos     fprintf (stream, _("\
    625  1.1  christos   -D --enable-deterministic-archives\n\
    626  1.1  christos                                    Produce deterministic output when stripping archives (default)\n\
    627  1.1  christos   -U --disable-deterministic-archives\n\
    628  1.1  christos                                    Disable -D behavior\n"));
    629  1.1  christos   else
    630  1.1  christos     fprintf (stream, _("\
    631  1.1  christos   -D --enable-deterministic-archives\n\
    632  1.1  christos                                    Produce deterministic output when stripping archives\n\
    633  1.1  christos   -U --disable-deterministic-archives\n\
    634  1.1  christos                                    Disable -D behavior (default)\n"));
    635  1.1  christos   fprintf (stream, _("\
    636  1.1  christos   -R --remove-section=<name>       Remove section <name> from the output\n\
    637  1.1  christos   -s --strip-all                   Remove all symbol and relocation information\n\
    638  1.1  christos   -g -S -d --strip-debug           Remove all debugging symbols & sections\n\
    639  1.1  christos      --strip-dwo                   Remove all DWO sections\n\
    640  1.1  christos      --strip-unneeded              Remove all symbols not needed by relocations\n\
    641  1.1  christos      --only-keep-debug             Strip everything but the debug information\n\
    642  1.1  christos   -N --strip-symbol=<name>         Do not copy symbol <name>\n\
    643  1.1  christos   -K --keep-symbol=<name>          Do not strip symbol <name>\n\
    644  1.1  christos      --keep-file-symbols           Do not strip file symbol(s)\n\
    645  1.1  christos   -w --wildcard                    Permit wildcard in symbol comparison\n\
    646  1.1  christos   -x --discard-all                 Remove all non-global symbols\n\
    647  1.1  christos   -X --discard-locals              Remove any compiler-generated symbols\n\
    648  1.1  christos   -v --verbose                     List all object files modified\n\
    649  1.1  christos   -V --version                     Display this program's version number\n\
    650  1.1  christos   -h --help                        Display this output\n\
    651  1.1  christos      --info                        List object formats & architectures supported\n\
    652  1.1  christos   -o <file>                        Place stripped output into <file>\n\
    653  1.1  christos "));
    654  1.1  christos 
    655  1.1  christos   list_supported_targets (program_name, stream);
    656  1.1  christos   if (REPORT_BUGS_TO[0] && exit_status == 0)
    657  1.1  christos     fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO);
    658  1.1  christos   exit (exit_status);
    659  1.1  christos }
    660  1.1  christos 
    661  1.1  christos /* Parse section flags into a flagword, with a fatal error if the
    662  1.1  christos    string can't be parsed.  */
    663  1.1  christos 
    664  1.1  christos static flagword
    665  1.1  christos parse_flags (const char *s)
    666  1.1  christos {
    667  1.1  christos   flagword ret;
    668  1.1  christos   const char *snext;
    669  1.1  christos   int len;
    670  1.1  christos 
    671  1.1  christos   ret = SEC_NO_FLAGS;
    672  1.1  christos 
    673  1.1  christos   do
    674  1.1  christos     {
    675  1.1  christos       snext = strchr (s, ',');
    676  1.1  christos       if (snext == NULL)
    677  1.1  christos 	len = strlen (s);
    678  1.1  christos       else
    679  1.1  christos 	{
    680  1.1  christos 	  len = snext - s;
    681  1.1  christos 	  ++snext;
    682  1.1  christos 	}
    683  1.1  christos 
    684  1.1  christos       if (0) ;
    685  1.1  christos #define PARSE_FLAG(fname,fval) \
    686  1.1  christos   else if (strncasecmp (fname, s, len) == 0) ret |= fval
    687  1.1  christos       PARSE_FLAG ("alloc", SEC_ALLOC);
    688  1.1  christos       PARSE_FLAG ("load", SEC_LOAD);
    689  1.1  christos       PARSE_FLAG ("noload", SEC_NEVER_LOAD);
    690  1.1  christos       PARSE_FLAG ("readonly", SEC_READONLY);
    691  1.1  christos       PARSE_FLAG ("debug", SEC_DEBUGGING);
    692  1.1  christos       PARSE_FLAG ("code", SEC_CODE);
    693  1.1  christos       PARSE_FLAG ("data", SEC_DATA);
    694  1.1  christos       PARSE_FLAG ("rom", SEC_ROM);
    695  1.1  christos       PARSE_FLAG ("share", SEC_COFF_SHARED);
    696  1.1  christos       PARSE_FLAG ("contents", SEC_HAS_CONTENTS);
    697  1.1  christos #undef PARSE_FLAG
    698  1.1  christos       else
    699  1.1  christos 	{
    700  1.1  christos 	  char *copy;
    701  1.1  christos 
    702  1.1  christos 	  copy = (char *) xmalloc (len + 1);
    703  1.1  christos 	  strncpy (copy, s, len);
    704  1.1  christos 	  copy[len] = '\0';
    705  1.1  christos 	  non_fatal (_("unrecognized section flag `%s'"), copy);
    706  1.1  christos 	  fatal (_("supported flags: %s"),
    707  1.1  christos 		 "alloc, load, noload, readonly, debug, code, data, rom, share, contents");
    708  1.1  christos 	}
    709  1.1  christos 
    710  1.1  christos       s = snext;
    711  1.1  christos     }
    712  1.1  christos   while (s != NULL);
    713  1.1  christos 
    714  1.1  christos   return ret;
    715  1.1  christos }
    716  1.1  christos 
    717  1.1  christos /* Find and optionally add an entry in the change_sections list.  */
    718  1.1  christos 
    719  1.1  christos static struct section_list *
    720  1.1  christos find_section_list (const char *name, bfd_boolean add)
    721  1.1  christos {
    722  1.1  christos   struct section_list *p;
    723  1.1  christos 
    724  1.1  christos   for (p = change_sections; p != NULL; p = p->next)
    725  1.1  christos     if (strcmp (p->name, name) == 0)
    726  1.1  christos       return p;
    727  1.1  christos 
    728  1.1  christos   if (! add)
    729  1.1  christos     return NULL;
    730  1.1  christos 
    731  1.1  christos   p = (struct section_list *) xmalloc (sizeof (struct section_list));
    732  1.1  christos   p->name = name;
    733  1.1  christos   p->used = FALSE;
    734  1.1  christos   p->remove = FALSE;
    735  1.1  christos   p->copy = FALSE;
    736  1.1  christos   p->change_vma = CHANGE_IGNORE;
    737  1.1  christos   p->change_lma = CHANGE_IGNORE;
    738  1.1  christos   p->vma_val = 0;
    739  1.1  christos   p->lma_val = 0;
    740  1.1  christos   p->set_flags = FALSE;
    741  1.1  christos   p->flags = 0;
    742  1.1  christos 
    743  1.1  christos   p->next = change_sections;
    744  1.1  christos   change_sections = p;
    745  1.1  christos 
    746  1.1  christos   return p;
    747  1.1  christos }
    748  1.1  christos 
    749  1.1  christos /* There is htab_hash_string but no htab_eq_string. Makes sense.  */
    750  1.1  christos 
    751  1.1  christos static int
    752  1.1  christos eq_string (const void *s1, const void *s2)
    753  1.1  christos {
    754  1.1  christos   return strcmp ((const char *) s1, (const char *) s2) == 0;
    755  1.1  christos }
    756  1.1  christos 
    757  1.1  christos static htab_t
    758  1.1  christos create_symbol_htab (void)
    759  1.1  christos {
    760  1.1  christos   return htab_create_alloc (16, htab_hash_string, eq_string, NULL, xcalloc, free);
    761  1.1  christos }
    762  1.1  christos 
    763  1.1  christos static void
    764  1.1  christos create_symbol_htabs (void)
    765  1.1  christos {
    766  1.1  christos   strip_specific_htab = create_symbol_htab ();
    767  1.1  christos   strip_unneeded_htab = create_symbol_htab ();
    768  1.1  christos   keep_specific_htab = create_symbol_htab ();
    769  1.1  christos   localize_specific_htab = create_symbol_htab ();
    770  1.1  christos   globalize_specific_htab = create_symbol_htab ();
    771  1.1  christos   keepglobal_specific_htab = create_symbol_htab ();
    772  1.1  christos   weaken_specific_htab = create_symbol_htab ();
    773  1.1  christos }
    774  1.1  christos 
    775  1.1  christos /* Add a symbol to strip_specific_list.  */
    776  1.1  christos 
    777  1.1  christos static void
    778  1.1  christos add_specific_symbol (const char *name, htab_t htab)
    779  1.1  christos {
    780  1.1  christos   *htab_find_slot (htab, name, INSERT) = (char *) name;
    781  1.1  christos }
    782  1.1  christos 
    783  1.1  christos /* Add symbols listed in `filename' to strip_specific_list.  */
    784  1.1  christos 
    785  1.1  christos #define IS_WHITESPACE(c)      ((c) == ' ' || (c) == '\t')
    786  1.1  christos #define IS_LINE_TERMINATOR(c) ((c) == '\n' || (c) == '\r' || (c) == '\0')
    787  1.1  christos 
    788  1.1  christos static void
    789  1.1  christos add_specific_symbols (const char *filename, htab_t htab)
    790  1.1  christos {
    791  1.1  christos   off_t  size;
    792  1.1  christos   FILE * f;
    793  1.1  christos   char * line;
    794  1.1  christos   char * buffer;
    795  1.1  christos   unsigned int line_count;
    796  1.1  christos 
    797  1.1  christos   size = get_file_size (filename);
    798  1.1  christos   if (size == 0)
    799  1.1  christos     {
    800  1.1  christos       status = 1;
    801  1.1  christos       return;
    802  1.1  christos     }
    803  1.1  christos 
    804  1.1  christos   buffer = (char *) xmalloc (size + 2);
    805  1.1  christos   f = fopen (filename, FOPEN_RT);
    806  1.1  christos   if (f == NULL)
    807  1.1  christos     fatal (_("cannot open '%s': %s"), filename, strerror (errno));
    808  1.1  christos 
    809  1.1  christos   if (fread (buffer, 1, size, f) == 0 || ferror (f))
    810  1.1  christos     fatal (_("%s: fread failed"), filename);
    811  1.1  christos 
    812  1.1  christos   fclose (f);
    813  1.1  christos   buffer [size] = '\n';
    814  1.1  christos   buffer [size + 1] = '\0';
    815  1.1  christos 
    816  1.1  christos   line_count = 1;
    817  1.1  christos 
    818  1.1  christos   for (line = buffer; * line != '\0'; line ++)
    819  1.1  christos     {
    820  1.1  christos       char * eol;
    821  1.1  christos       char * name;
    822  1.1  christos       char * name_end;
    823  1.1  christos       int finished = FALSE;
    824  1.1  christos 
    825  1.1  christos       for (eol = line;; eol ++)
    826  1.1  christos 	{
    827  1.1  christos 	  switch (* eol)
    828  1.1  christos 	    {
    829  1.1  christos 	    case '\n':
    830  1.1  christos 	      * eol = '\0';
    831  1.1  christos 	      /* Cope with \n\r.  */
    832  1.1  christos 	      if (eol[1] == '\r')
    833  1.1  christos 		++ eol;
    834  1.1  christos 	      finished = TRUE;
    835  1.1  christos 	      break;
    836  1.1  christos 
    837  1.1  christos 	    case '\r':
    838  1.1  christos 	      * eol = '\0';
    839  1.1  christos 	      /* Cope with \r\n.  */
    840  1.1  christos 	      if (eol[1] == '\n')
    841  1.1  christos 		++ eol;
    842  1.1  christos 	      finished = TRUE;
    843  1.1  christos 	      break;
    844  1.1  christos 
    845  1.1  christos 	    case 0:
    846  1.1  christos 	      finished = TRUE;
    847  1.1  christos 	      break;
    848  1.1  christos 
    849  1.1  christos 	    case '#':
    850  1.1  christos 	      /* Line comment, Terminate the line here, in case a
    851  1.1  christos 		 name is present and then allow the rest of the
    852  1.1  christos 		 loop to find the real end of the line.  */
    853  1.1  christos 	      * eol = '\0';
    854  1.1  christos 	      break;
    855  1.1  christos 
    856  1.1  christos 	    default:
    857  1.1  christos 	      break;
    858  1.1  christos 	    }
    859  1.1  christos 
    860  1.1  christos 	  if (finished)
    861  1.1  christos 	    break;
    862  1.1  christos 	}
    863  1.1  christos 
    864  1.1  christos       /* A name may now exist somewhere between 'line' and 'eol'.
    865  1.1  christos 	 Strip off leading whitespace and trailing whitespace,
    866  1.1  christos 	 then add it to the list.  */
    867  1.1  christos       for (name = line; IS_WHITESPACE (* name); name ++)
    868  1.1  christos 	;
    869  1.1  christos       for (name_end = name;
    870  1.1  christos 	   (! IS_WHITESPACE (* name_end))
    871  1.1  christos 	   && (! IS_LINE_TERMINATOR (* name_end));
    872  1.1  christos 	   name_end ++)
    873  1.1  christos 	;
    874  1.1  christos 
    875  1.1  christos       if (! IS_LINE_TERMINATOR (* name_end))
    876  1.1  christos 	{
    877  1.1  christos 	  char * extra;
    878  1.1  christos 
    879  1.1  christos 	  for (extra = name_end + 1; IS_WHITESPACE (* extra); extra ++)
    880  1.1  christos 	    ;
    881  1.1  christos 
    882  1.1  christos 	  if (! IS_LINE_TERMINATOR (* extra))
    883  1.1  christos 	    non_fatal (_("%s:%d: Ignoring rubbish found on this line"),
    884  1.1  christos 		       filename, line_count);
    885  1.1  christos 	}
    886  1.1  christos 
    887  1.1  christos       * name_end = '\0';
    888  1.1  christos 
    889  1.1  christos       if (name_end > name)
    890  1.1  christos 	add_specific_symbol (name, htab);
    891  1.1  christos 
    892  1.1  christos       /* Advance line pointer to end of line.  The 'eol ++' in the for
    893  1.1  christos 	 loop above will then advance us to the start of the next line.  */
    894  1.1  christos       line = eol;
    895  1.1  christos       line_count ++;
    896  1.1  christos     }
    897  1.1  christos }
    898  1.1  christos 
    899  1.1  christos /* See whether a symbol should be stripped or kept
    900  1.1  christos    based on strip_specific_list and keep_symbols.  */
    901  1.1  christos 
    902  1.1  christos static int
    903  1.1  christos is_specified_symbol_predicate (void **slot, void *data)
    904  1.1  christos {
    905  1.1  christos   struct is_specified_symbol_predicate_data *d =
    906  1.1  christos       (struct is_specified_symbol_predicate_data *) data;
    907  1.1  christos   const char *slot_name = (char *) *slot;
    908  1.1  christos 
    909  1.1  christos   if (*slot_name != '!')
    910  1.1  christos     {
    911  1.1  christos       if (! fnmatch (slot_name, d->name, 0))
    912  1.1  christos 	{
    913  1.1  christos 	  d->found = TRUE;
    914  1.1  christos 	  /* Stop traversal.  */
    915  1.1  christos 	  return 0;
    916  1.1  christos 	}
    917  1.1  christos     }
    918  1.1  christos   else
    919  1.1  christos     {
    920  1.1  christos       if (fnmatch (slot_name + 1, d->name, 0))
    921  1.1  christos 	{
    922  1.1  christos 	  d->found = TRUE;
    923  1.1  christos 	  /* Stop traversal.  */
    924  1.1  christos 	  return 0;
    925  1.1  christos 	}
    926  1.1  christos     }
    927  1.1  christos 
    928  1.1  christos   /* Continue traversal.  */
    929  1.1  christos   return 1;
    930  1.1  christos }
    931  1.1  christos 
    932  1.1  christos static bfd_boolean
    933  1.1  christos is_specified_symbol (const char *name, htab_t htab)
    934  1.1  christos {
    935  1.1  christos   if (wildcard)
    936  1.1  christos     {
    937  1.1  christos       struct is_specified_symbol_predicate_data data;
    938  1.1  christos 
    939  1.1  christos       data.name = name;
    940  1.1  christos       data.found = FALSE;
    941  1.1  christos 
    942  1.1  christos       htab_traverse (htab, is_specified_symbol_predicate, &data);
    943  1.1  christos 
    944  1.1  christos       return data.found;
    945  1.1  christos     }
    946  1.1  christos 
    947  1.1  christos   return htab_find (htab, name) != NULL;
    948  1.1  christos }
    949  1.1  christos 
    950  1.1  christos /* Return a pointer to the symbol used as a signature for GROUP.  */
    951  1.1  christos 
    952  1.1  christos static asymbol *
    953  1.1  christos group_signature (asection *group)
    954  1.1  christos {
    955  1.1  christos   bfd *abfd = group->owner;
    956  1.1  christos   Elf_Internal_Shdr *ghdr;
    957  1.1  christos 
    958  1.1  christos   if (bfd_get_flavour (abfd) != bfd_target_elf_flavour)
    959  1.1  christos     return NULL;
    960  1.1  christos 
    961  1.1  christos   ghdr = &elf_section_data (group)->this_hdr;
    962  1.1  christos   if (ghdr->sh_link < elf_numsections (abfd))
    963  1.1  christos     {
    964  1.1  christos       const struct elf_backend_data *bed = get_elf_backend_data (abfd);
    965  1.1  christos       Elf_Internal_Shdr *symhdr = elf_elfsections (abfd) [ghdr->sh_link];
    966  1.1  christos 
    967  1.1  christos       if (symhdr->sh_type == SHT_SYMTAB
    968  1.1  christos 	  && ghdr->sh_info < symhdr->sh_size / bed->s->sizeof_sym)
    969  1.1  christos 	return isympp[ghdr->sh_info - 1];
    970  1.1  christos     }
    971  1.1  christos   return NULL;
    972  1.1  christos }
    973  1.1  christos 
    974  1.1  christos /* Return TRUE if the section is a DWO section.  */
    975  1.1  christos 
    976  1.1  christos static bfd_boolean
    977  1.1  christos is_dwo_section (bfd *abfd ATTRIBUTE_UNUSED, asection *sec)
    978  1.1  christos {
    979  1.1  christos   const char *name = bfd_get_section_name (abfd, sec);
    980  1.1  christos   int len = strlen (name);
    981  1.1  christos 
    982  1.1  christos   return strncmp (name + len - 4, ".dwo", 4) == 0;
    983  1.1  christos }
    984  1.1  christos 
    985  1.1  christos /* See if a non-group section is being removed.  */
    986  1.1  christos 
    987  1.1  christos static bfd_boolean
    988  1.1  christos is_strip_section_1 (bfd *abfd ATTRIBUTE_UNUSED, asection *sec)
    989  1.1  christos {
    990  1.1  christos   if (sections_removed || sections_copied)
    991  1.1  christos     {
    992  1.1  christos       struct section_list *p;
    993  1.1  christos 
    994  1.1  christos       p = find_section_list (bfd_get_section_name (abfd, sec), FALSE);
    995  1.1  christos 
    996  1.1  christos       if (sections_removed && p != NULL && p->remove)
    997  1.1  christos 	return TRUE;
    998  1.1  christos       if (sections_copied && (p == NULL || ! p->copy))
    999  1.1  christos 	return TRUE;
   1000  1.1  christos     }
   1001  1.1  christos 
   1002  1.1  christos   if ((bfd_get_section_flags (abfd, sec) & SEC_DEBUGGING) != 0)
   1003  1.1  christos     {
   1004  1.1  christos       if (strip_symbols == STRIP_DEBUG
   1005  1.1  christos 	  || strip_symbols == STRIP_UNNEEDED
   1006  1.1  christos 	  || strip_symbols == STRIP_ALL
   1007  1.1  christos 	  || discard_locals == LOCALS_ALL
   1008  1.1  christos 	  || convert_debugging)
   1009  1.1  christos 	return TRUE;
   1010  1.1  christos 
   1011  1.1  christos       if (strip_symbols == STRIP_DWO)
   1012  1.1  christos 	return is_dwo_section (abfd, sec);
   1013  1.1  christos 
   1014  1.1  christos       if (strip_symbols == STRIP_NONDEBUG)
   1015  1.1  christos 	return FALSE;
   1016  1.1  christos     }
   1017  1.1  christos 
   1018  1.1  christos   if (strip_symbols == STRIP_NONDWO)
   1019  1.1  christos     return !is_dwo_section (abfd, sec);
   1020  1.1  christos 
   1021  1.1  christos   return FALSE;
   1022  1.1  christos }
   1023  1.1  christos 
   1024  1.1  christos /* See if a section is being removed.  */
   1025  1.1  christos 
   1026  1.1  christos static bfd_boolean
   1027  1.1  christos is_strip_section (bfd *abfd ATTRIBUTE_UNUSED, asection *sec)
   1028  1.1  christos {
   1029  1.1  christos   if (is_strip_section_1 (abfd, sec))
   1030  1.1  christos     return TRUE;
   1031  1.1  christos 
   1032  1.1  christos   if ((bfd_get_section_flags (abfd, sec) & SEC_GROUP) != 0)
   1033  1.1  christos     {
   1034  1.1  christos       asymbol *gsym;
   1035  1.1  christos       const char *gname;
   1036  1.1  christos       asection *elt, *first;
   1037  1.1  christos 
   1038  1.1  christos       /* PR binutils/3181
   1039  1.1  christos 	 If we are going to strip the group signature symbol, then
   1040  1.1  christos 	 strip the group section too.  */
   1041  1.1  christos       gsym = group_signature (sec);
   1042  1.1  christos       if (gsym != NULL)
   1043  1.1  christos 	gname = gsym->name;
   1044  1.1  christos       else
   1045  1.1  christos 	gname = sec->name;
   1046  1.1  christos       if ((strip_symbols == STRIP_ALL
   1047  1.1  christos 	   && !is_specified_symbol (gname, keep_specific_htab))
   1048  1.1  christos 	  || is_specified_symbol (gname, strip_specific_htab))
   1049  1.1  christos 	return TRUE;
   1050  1.1  christos 
   1051  1.1  christos       /* Remove the group section if all members are removed.  */
   1052  1.1  christos       first = elt = elf_next_in_group (sec);
   1053  1.1  christos       while (elt != NULL)
   1054  1.1  christos 	{
   1055  1.1  christos 	  if (!is_strip_section_1 (abfd, elt))
   1056  1.1  christos 	    return FALSE;
   1057  1.1  christos 	  elt = elf_next_in_group (elt);
   1058  1.1  christos 	  if (elt == first)
   1059  1.1  christos 	    break;
   1060  1.1  christos 	}
   1061  1.1  christos 
   1062  1.1  christos       return TRUE;
   1063  1.1  christos     }
   1064  1.1  christos 
   1065  1.1  christos   return FALSE;
   1066  1.1  christos }
   1067  1.1  christos 
   1068  1.1  christos /* Return true if SYM is a hidden symbol.  */
   1069  1.1  christos 
   1070  1.1  christos static bfd_boolean
   1071  1.1  christos is_hidden_symbol (asymbol *sym)
   1072  1.1  christos {
   1073  1.1  christos   elf_symbol_type *elf_sym;
   1074  1.1  christos 
   1075  1.1  christos   elf_sym = elf_symbol_from (sym->the_bfd, sym);
   1076  1.1  christos   if (elf_sym != NULL)
   1077  1.1  christos     switch (ELF_ST_VISIBILITY (elf_sym->internal_elf_sym.st_other))
   1078  1.1  christos       {
   1079  1.1  christos       case STV_HIDDEN:
   1080  1.1  christos       case STV_INTERNAL:
   1081  1.1  christos 	return TRUE;
   1082  1.1  christos       }
   1083  1.1  christos   return FALSE;
   1084  1.1  christos }
   1085  1.1  christos 
   1086  1.1  christos /* Choose which symbol entries to copy; put the result in OSYMS.
   1087  1.1  christos    We don't copy in place, because that confuses the relocs.
   1088  1.1  christos    Return the number of symbols to print.  */
   1089  1.1  christos 
   1090  1.1  christos static unsigned int
   1091  1.1  christos filter_symbols (bfd *abfd, bfd *obfd, asymbol **osyms,
   1092  1.1  christos 		asymbol **isyms, long symcount)
   1093  1.1  christos {
   1094  1.1  christos   asymbol **from = isyms, **to = osyms;
   1095  1.1  christos   long src_count = 0, dst_count = 0;
   1096  1.1  christos   int relocatable = (abfd->flags & (EXEC_P | DYNAMIC)) == 0;
   1097  1.1  christos 
   1098  1.1  christos   for (; src_count < symcount; src_count++)
   1099  1.1  christos     {
   1100  1.1  christos       asymbol *sym = from[src_count];
   1101  1.1  christos       flagword flags = sym->flags;
   1102  1.1  christos       char *name = (char *) bfd_asymbol_name (sym);
   1103  1.1  christos       bfd_boolean keep;
   1104  1.1  christos       bfd_boolean used_in_reloc = FALSE;
   1105  1.1  christos       bfd_boolean undefined;
   1106  1.1  christos       bfd_boolean rem_leading_char;
   1107  1.1  christos       bfd_boolean add_leading_char;
   1108  1.1  christos 
   1109  1.1  christos       undefined = bfd_is_und_section (bfd_get_section (sym));
   1110  1.1  christos 
   1111  1.1  christos       if (redefine_sym_list)
   1112  1.1  christos 	{
   1113  1.1  christos 	  char *old_name, *new_name;
   1114  1.1  christos 
   1115  1.1  christos 	  old_name = (char *) bfd_asymbol_name (sym);
   1116  1.1  christos 	  new_name = (char *) lookup_sym_redefinition (old_name);
   1117  1.1  christos 	  bfd_asymbol_name (sym) = new_name;
   1118  1.1  christos 	  name = new_name;
   1119  1.1  christos 	}
   1120  1.1  christos 
   1121  1.1  christos       /* Check if we will remove the current leading character.  */
   1122  1.1  christos       rem_leading_char =
   1123  1.1  christos 	(name[0] == bfd_get_symbol_leading_char (abfd))
   1124  1.1  christos 	&& (change_leading_char
   1125  1.1  christos 	    || (remove_leading_char
   1126  1.1  christos 		&& ((flags & (BSF_GLOBAL | BSF_WEAK)) != 0
   1127  1.1  christos 		    || undefined
   1128  1.1  christos 		    || bfd_is_com_section (bfd_get_section (sym)))));
   1129  1.1  christos 
   1130  1.1  christos       /* Check if we will add a new leading character.  */
   1131  1.1  christos       add_leading_char =
   1132  1.1  christos 	change_leading_char
   1133  1.1  christos 	&& (bfd_get_symbol_leading_char (obfd) != '\0')
   1134  1.1  christos 	&& (bfd_get_symbol_leading_char (abfd) == '\0'
   1135  1.1  christos 	    || (name[0] == bfd_get_symbol_leading_char (abfd)));
   1136  1.1  christos 
   1137  1.1  christos       /* Short circuit for change_leading_char if we can do it in-place.  */
   1138  1.1  christos       if (rem_leading_char && add_leading_char && !prefix_symbols_string)
   1139  1.1  christos         {
   1140  1.1  christos 	  name[0] = bfd_get_symbol_leading_char (obfd);
   1141  1.1  christos 	  bfd_asymbol_name (sym) = name;
   1142  1.1  christos 	  rem_leading_char = FALSE;
   1143  1.1  christos 	  add_leading_char = FALSE;
   1144  1.1  christos         }
   1145  1.1  christos 
   1146  1.1  christos       /* Remove leading char.  */
   1147  1.1  christos       if (rem_leading_char)
   1148  1.1  christos 	bfd_asymbol_name (sym) = ++name;
   1149  1.1  christos 
   1150  1.1  christos       /* Add new leading char and/or prefix.  */
   1151  1.1  christos       if (add_leading_char || prefix_symbols_string)
   1152  1.1  christos         {
   1153  1.1  christos           char *n, *ptr;
   1154  1.1  christos 
   1155  1.1  christos           ptr = n = (char *) xmalloc (1 + strlen (prefix_symbols_string)
   1156  1.1  christos                                       + strlen (name) + 1);
   1157  1.1  christos           if (add_leading_char)
   1158  1.1  christos 	    *ptr++ = bfd_get_symbol_leading_char (obfd);
   1159  1.1  christos 
   1160  1.1  christos           if (prefix_symbols_string)
   1161  1.1  christos             {
   1162  1.1  christos               strcpy (ptr, prefix_symbols_string);
   1163  1.1  christos               ptr += strlen (prefix_symbols_string);
   1164  1.1  christos            }
   1165  1.1  christos 
   1166  1.1  christos           strcpy (ptr, name);
   1167  1.1  christos           bfd_asymbol_name (sym) = n;
   1168  1.1  christos           name = n;
   1169  1.1  christos 	}
   1170  1.1  christos 
   1171  1.1  christos       if (strip_symbols == STRIP_ALL)
   1172  1.1  christos 	keep = FALSE;
   1173  1.1  christos       else if ((flags & BSF_KEEP) != 0		/* Used in relocation.  */
   1174  1.1  christos 	       || ((flags & BSF_SECTION_SYM) != 0
   1175  1.1  christos 		   && ((*bfd_get_section (sym)->symbol_ptr_ptr)->flags
   1176  1.1  christos 		       & BSF_KEEP) != 0))
   1177  1.1  christos 	{
   1178  1.1  christos 	  keep = TRUE;
   1179  1.1  christos 	  used_in_reloc = TRUE;
   1180  1.1  christos 	}
   1181  1.1  christos       else if (relocatable			/* Relocatable file.  */
   1182  1.1  christos 	       && ((flags & (BSF_GLOBAL | BSF_WEAK)) != 0
   1183  1.1  christos 		   || bfd_is_com_section (bfd_get_section (sym))))
   1184  1.1  christos 	keep = TRUE;
   1185  1.1  christos       else if (bfd_decode_symclass (sym) == 'I')
   1186  1.1  christos 	/* Global symbols in $idata sections need to be retained
   1187  1.1  christos 	   even if relocatable is FALSE.  External users of the
   1188  1.1  christos 	   library containing the $idata section may reference these
   1189  1.1  christos 	   symbols.  */
   1190  1.1  christos 	keep = TRUE;
   1191  1.1  christos       else if ((flags & BSF_GLOBAL) != 0	/* Global symbol.  */
   1192  1.1  christos 	       || (flags & BSF_WEAK) != 0
   1193  1.1  christos 	       || undefined
   1194  1.1  christos 	       || bfd_is_com_section (bfd_get_section (sym)))
   1195  1.1  christos 	keep = strip_symbols != STRIP_UNNEEDED;
   1196  1.1  christos       else if ((flags & BSF_DEBUGGING) != 0)	/* Debugging symbol.  */
   1197  1.1  christos 	keep = (strip_symbols != STRIP_DEBUG
   1198  1.1  christos 		&& strip_symbols != STRIP_UNNEEDED
   1199  1.1  christos 		&& ! convert_debugging);
   1200  1.1  christos       else if (bfd_coff_get_comdat_section (abfd, bfd_get_section (sym)))
   1201  1.1  christos 	/* COMDAT sections store special information in local
   1202  1.1  christos 	   symbols, so we cannot risk stripping any of them.  */
   1203  1.1  christos 	keep = TRUE;
   1204  1.1  christos       else			/* Local symbol.  */
   1205  1.1  christos 	keep = (strip_symbols != STRIP_UNNEEDED
   1206  1.1  christos 		&& (discard_locals != LOCALS_ALL
   1207  1.1  christos 		    && (discard_locals != LOCALS_START_L
   1208  1.1  christos 			|| ! bfd_is_local_label (abfd, sym))));
   1209  1.1  christos 
   1210  1.1  christos       if (keep && is_specified_symbol (name, strip_specific_htab))
   1211  1.1  christos 	{
   1212  1.1  christos 	  /* There are multiple ways to set 'keep' above, but if it
   1213  1.1  christos 	     was the relocatable symbol case, then that's an error.  */
   1214  1.1  christos 	  if (used_in_reloc)
   1215  1.1  christos 	    {
   1216  1.1  christos 	      non_fatal (_("not stripping symbol `%s' because it is named in a relocation"), name);
   1217  1.1  christos 	      status = 1;
   1218  1.1  christos 	    }
   1219  1.1  christos 	  else
   1220  1.1  christos 	    keep = FALSE;
   1221  1.1  christos 	}
   1222  1.1  christos 
   1223  1.1  christos       if (keep
   1224  1.1  christos 	  && !(flags & BSF_KEEP)
   1225  1.1  christos 	  && is_specified_symbol (name, strip_unneeded_htab))
   1226  1.1  christos 	keep = FALSE;
   1227  1.1  christos 
   1228  1.1  christos       if (!keep
   1229  1.1  christos 	  && ((keep_file_symbols && (flags & BSF_FILE))
   1230  1.1  christos 	      || is_specified_symbol (name, keep_specific_htab)))
   1231  1.1  christos 	keep = TRUE;
   1232  1.1  christos 
   1233  1.1  christos       if (keep && is_strip_section (abfd, bfd_get_section (sym)))
   1234  1.1  christos 	keep = FALSE;
   1235  1.1  christos 
   1236  1.1  christos       if (keep)
   1237  1.1  christos 	{
   1238  1.1  christos 	  if ((flags & BSF_GLOBAL) != 0
   1239  1.1  christos 	      && (weaken || is_specified_symbol (name, weaken_specific_htab)))
   1240  1.1  christos 	    {
   1241  1.1  christos 	      sym->flags &= ~ BSF_GLOBAL;
   1242  1.1  christos 	      sym->flags |= BSF_WEAK;
   1243  1.1  christos 	    }
   1244  1.1  christos 
   1245  1.1  christos 	  if (!undefined
   1246  1.1  christos 	      && (flags & (BSF_GLOBAL | BSF_WEAK))
   1247  1.1  christos 	      && (is_specified_symbol (name, localize_specific_htab)
   1248  1.1  christos 		  || (htab_elements (keepglobal_specific_htab) != 0
   1249  1.1  christos 		      && ! is_specified_symbol (name, keepglobal_specific_htab))
   1250  1.1  christos 		  || (localize_hidden && is_hidden_symbol (sym))))
   1251  1.1  christos 	    {
   1252  1.1  christos 	      sym->flags &= ~ (BSF_GLOBAL | BSF_WEAK);
   1253  1.1  christos 	      sym->flags |= BSF_LOCAL;
   1254  1.1  christos 	    }
   1255  1.1  christos 
   1256  1.1  christos 	  if (!undefined
   1257  1.1  christos 	      && (flags & BSF_LOCAL)
   1258  1.1  christos 	      && is_specified_symbol (name, globalize_specific_htab))
   1259  1.1  christos 	    {
   1260  1.1  christos 	      sym->flags &= ~ BSF_LOCAL;
   1261  1.1  christos 	      sym->flags |= BSF_GLOBAL;
   1262  1.1  christos 	    }
   1263  1.1  christos 
   1264  1.1  christos 	  to[dst_count++] = sym;
   1265  1.1  christos 	}
   1266  1.1  christos     }
   1267  1.1  christos 
   1268  1.1  christos   to[dst_count] = NULL;
   1269  1.1  christos 
   1270  1.1  christos   return dst_count;
   1271  1.1  christos }
   1272  1.1  christos 
   1273  1.1  christos /* Find the redefined name of symbol SOURCE.  */
   1274  1.1  christos 
   1275  1.1  christos static const char *
   1276  1.1  christos lookup_sym_redefinition (const char *source)
   1277  1.1  christos {
   1278  1.1  christos   struct redefine_node *list;
   1279  1.1  christos 
   1280  1.1  christos   for (list = redefine_sym_list; list != NULL; list = list->next)
   1281  1.1  christos     if (strcmp (source, list->source) == 0)
   1282  1.1  christos       return list->target;
   1283  1.1  christos 
   1284  1.1  christos   return source;
   1285  1.1  christos }
   1286  1.1  christos 
   1287  1.1  christos /* Add a node to a symbol redefine list.  */
   1288  1.1  christos 
   1289  1.1  christos static void
   1290  1.1  christos redefine_list_append (const char *cause, const char *source, const char *target)
   1291  1.1  christos {
   1292  1.1  christos   struct redefine_node **p;
   1293  1.1  christos   struct redefine_node *list;
   1294  1.1  christos   struct redefine_node *new_node;
   1295  1.1  christos 
   1296  1.1  christos   for (p = &redefine_sym_list; (list = *p) != NULL; p = &list->next)
   1297  1.1  christos     {
   1298  1.1  christos       if (strcmp (source, list->source) == 0)
   1299  1.1  christos 	fatal (_("%s: Multiple redefinition of symbol \"%s\""),
   1300  1.1  christos 	       cause, source);
   1301  1.1  christos 
   1302  1.1  christos       if (strcmp (target, list->target) == 0)
   1303  1.1  christos 	fatal (_("%s: Symbol \"%s\" is target of more than one redefinition"),
   1304  1.1  christos 	       cause, target);
   1305  1.1  christos     }
   1306  1.1  christos 
   1307  1.1  christos   new_node = (struct redefine_node *) xmalloc (sizeof (struct redefine_node));
   1308  1.1  christos 
   1309  1.1  christos   new_node->source = strdup (source);
   1310  1.1  christos   new_node->target = strdup (target);
   1311  1.1  christos   new_node->next = NULL;
   1312  1.1  christos 
   1313  1.1  christos   *p = new_node;
   1314  1.1  christos }
   1315  1.1  christos 
   1316  1.1  christos /* Handle the --redefine-syms option.  Read lines containing "old new"
   1317  1.1  christos    from the file, and add them to the symbol redefine list.  */
   1318  1.1  christos 
   1319  1.1  christos static void
   1320  1.1  christos add_redefine_syms_file (const char *filename)
   1321  1.1  christos {
   1322  1.1  christos   FILE *file;
   1323  1.1  christos   char *buf;
   1324  1.1  christos   size_t bufsize;
   1325  1.1  christos   size_t len;
   1326  1.1  christos   size_t outsym_off;
   1327  1.1  christos   int c, lineno;
   1328  1.1  christos 
   1329  1.1  christos   file = fopen (filename, "r");
   1330  1.1  christos   if (file == NULL)
   1331  1.1  christos     fatal (_("couldn't open symbol redefinition file %s (error: %s)"),
   1332  1.1  christos 	   filename, strerror (errno));
   1333  1.1  christos 
   1334  1.1  christos   bufsize = 100;
   1335  1.1  christos   buf = (char *) xmalloc (bufsize + 1 /* For the terminating NUL.  */);
   1336  1.1  christos 
   1337  1.1  christos   lineno = 1;
   1338  1.1  christos   c = getc (file);
   1339  1.1  christos   len = 0;
   1340  1.1  christos   outsym_off = 0;
   1341  1.1  christos   while (c != EOF)
   1342  1.1  christos     {
   1343  1.1  christos       /* Collect the input symbol name.  */
   1344  1.1  christos       while (! IS_WHITESPACE (c) && ! IS_LINE_TERMINATOR (c) && c != EOF)
   1345  1.1  christos 	{
   1346  1.1  christos 	  if (c == '#')
   1347  1.1  christos 	    goto comment;
   1348  1.1  christos 	  buf[len++] = c;
   1349  1.1  christos 	  if (len >= bufsize)
   1350  1.1  christos 	    {
   1351  1.1  christos 	      bufsize *= 2;
   1352  1.1  christos 	      buf = (char *) xrealloc (buf, bufsize + 1);
   1353  1.1  christos 	    }
   1354  1.1  christos 	  c = getc (file);
   1355  1.1  christos 	}
   1356  1.1  christos       buf[len++] = '\0';
   1357  1.1  christos       if (c == EOF)
   1358  1.1  christos 	break;
   1359  1.1  christos 
   1360  1.1  christos       /* Eat white space between the symbol names.  */
   1361  1.1  christos       while (IS_WHITESPACE (c))
   1362  1.1  christos 	c = getc (file);
   1363  1.1  christos       if (c == '#' || IS_LINE_TERMINATOR (c))
   1364  1.1  christos 	goto comment;
   1365  1.1  christos       if (c == EOF)
   1366  1.1  christos 	break;
   1367  1.1  christos 
   1368  1.1  christos       /* Collect the output symbol name.  */
   1369  1.1  christos       outsym_off = len;
   1370  1.1  christos       while (! IS_WHITESPACE (c) && ! IS_LINE_TERMINATOR (c) && c != EOF)
   1371  1.1  christos 	{
   1372  1.1  christos 	  if (c == '#')
   1373  1.1  christos 	    goto comment;
   1374  1.1  christos 	  buf[len++] = c;
   1375  1.1  christos 	  if (len >= bufsize)
   1376  1.1  christos 	    {
   1377  1.1  christos 	      bufsize *= 2;
   1378  1.1  christos 	      buf = (char *) xrealloc (buf, bufsize + 1);
   1379  1.1  christos 	    }
   1380  1.1  christos 	  c = getc (file);
   1381  1.1  christos 	}
   1382  1.1  christos       buf[len++] = '\0';
   1383  1.1  christos       if (c == EOF)
   1384  1.1  christos 	break;
   1385  1.1  christos 
   1386  1.1  christos       /* Eat white space at end of line.  */
   1387  1.1  christos       while (! IS_LINE_TERMINATOR(c) && c != EOF && IS_WHITESPACE (c))
   1388  1.1  christos 	c = getc (file);
   1389  1.1  christos       if (c == '#')
   1390  1.1  christos 	goto comment;
   1391  1.1  christos       /* Handle \r\n.  */
   1392  1.1  christos       if ((c == '\r' && (c = getc (file)) == '\n')
   1393  1.1  christos 	  || c == '\n' || c == EOF)
   1394  1.1  christos 	{
   1395  1.1  christos  end_of_line:
   1396  1.1  christos 	  /* Append the redefinition to the list.  */
   1397  1.1  christos 	  if (buf[0] != '\0')
   1398  1.1  christos 	    redefine_list_append (filename, &buf[0], &buf[outsym_off]);
   1399  1.1  christos 
   1400  1.1  christos 	  lineno++;
   1401  1.1  christos 	  len = 0;
   1402  1.1  christos 	  outsym_off = 0;
   1403  1.1  christos 	  if (c == EOF)
   1404  1.1  christos 	    break;
   1405  1.1  christos 	  c = getc (file);
   1406  1.1  christos 	  continue;
   1407  1.1  christos 	}
   1408  1.1  christos       else
   1409  1.1  christos 	fatal (_("%s:%d: garbage found at end of line"), filename, lineno);
   1410  1.1  christos  comment:
   1411  1.1  christos       if (len != 0 && (outsym_off == 0 || outsym_off == len))
   1412  1.1  christos 	fatal (_("%s:%d: missing new symbol name"), filename, lineno);
   1413  1.1  christos       buf[len++] = '\0';
   1414  1.1  christos 
   1415  1.1  christos       /* Eat the rest of the line and finish it.  */
   1416  1.1  christos       while (c != '\n' && c != EOF)
   1417  1.1  christos 	c = getc (file);
   1418  1.1  christos       goto end_of_line;
   1419  1.1  christos     }
   1420  1.1  christos 
   1421  1.1  christos   if (len != 0)
   1422  1.1  christos     fatal (_("%s:%d: premature end of file"), filename, lineno);
   1423  1.1  christos 
   1424  1.1  christos   free (buf);
   1425  1.1  christos }
   1426  1.1  christos 
   1427  1.1  christos /* Copy unkown object file IBFD onto OBFD.
   1428  1.1  christos    Returns TRUE upon success, FALSE otherwise.  */
   1429  1.1  christos 
   1430  1.1  christos static bfd_boolean
   1431  1.1  christos copy_unknown_object (bfd *ibfd, bfd *obfd)
   1432  1.1  christos {
   1433  1.1  christos   char *cbuf;
   1434  1.1  christos   int tocopy;
   1435  1.1  christos   long ncopied;
   1436  1.1  christos   long size;
   1437  1.1  christos   struct stat buf;
   1438  1.1  christos 
   1439  1.1  christos   if (bfd_stat_arch_elt (ibfd, &buf) != 0)
   1440  1.1  christos     {
   1441  1.1  christos       bfd_nonfatal_message (NULL, ibfd, NULL, NULL);
   1442  1.1  christos       return FALSE;
   1443  1.1  christos     }
   1444  1.1  christos 
   1445  1.1  christos   size = buf.st_size;
   1446  1.1  christos   if (size < 0)
   1447  1.1  christos     {
   1448  1.1  christos       non_fatal (_("stat returns negative size for `%s'"),
   1449  1.1  christos 		 bfd_get_archive_filename (ibfd));
   1450  1.1  christos       return FALSE;
   1451  1.1  christos     }
   1452  1.1  christos 
   1453  1.1  christos   if (bfd_seek (ibfd, (file_ptr) 0, SEEK_SET) != 0)
   1454  1.1  christos     {
   1455  1.1  christos       bfd_nonfatal (bfd_get_archive_filename (ibfd));
   1456  1.1  christos       return FALSE;
   1457  1.1  christos     }
   1458  1.1  christos 
   1459  1.1  christos   if (verbose)
   1460  1.1  christos     printf (_("copy from `%s' [unknown] to `%s' [unknown]\n"),
   1461  1.1  christos 	    bfd_get_archive_filename (ibfd), bfd_get_filename (obfd));
   1462  1.1  christos 
   1463  1.1  christos   cbuf = (char *) xmalloc (BUFSIZE);
   1464  1.1  christos   ncopied = 0;
   1465  1.1  christos   while (ncopied < size)
   1466  1.1  christos     {
   1467  1.1  christos       tocopy = size - ncopied;
   1468  1.1  christos       if (tocopy > BUFSIZE)
   1469  1.1  christos 	tocopy = BUFSIZE;
   1470  1.1  christos 
   1471  1.1  christos       if (bfd_bread (cbuf, (bfd_size_type) tocopy, ibfd)
   1472  1.1  christos 	  != (bfd_size_type) tocopy)
   1473  1.1  christos 	{
   1474  1.1  christos 	  bfd_nonfatal_message (NULL, ibfd, NULL, NULL);
   1475  1.1  christos 	  free (cbuf);
   1476  1.1  christos 	  return FALSE;
   1477  1.1  christos 	}
   1478  1.1  christos 
   1479  1.1  christos       if (bfd_bwrite (cbuf, (bfd_size_type) tocopy, obfd)
   1480  1.1  christos 	  != (bfd_size_type) tocopy)
   1481  1.1  christos 	{
   1482  1.1  christos 	  bfd_nonfatal_message (NULL, obfd, NULL, NULL);
   1483  1.1  christos 	  free (cbuf);
   1484  1.1  christos 	  return FALSE;
   1485  1.1  christos 	}
   1486  1.1  christos 
   1487  1.1  christos       ncopied += tocopy;
   1488  1.1  christos     }
   1489  1.1  christos 
   1490  1.1  christos   /* We should at least to be able to read it back when copying an
   1491  1.1  christos      unknown object in an archive.  */
   1492  1.1  christos   chmod (bfd_get_filename (obfd), buf.st_mode | S_IRUSR);
   1493  1.1  christos   free (cbuf);
   1494  1.1  christos   return TRUE;
   1495  1.1  christos }
   1496  1.1  christos 
   1497  1.1  christos /* Copy object file IBFD onto OBFD.
   1498  1.1  christos    Returns TRUE upon success, FALSE otherwise.  */
   1499  1.1  christos 
   1500  1.1  christos static bfd_boolean
   1501  1.1  christos copy_object (bfd *ibfd, bfd *obfd, const bfd_arch_info_type *input_arch)
   1502  1.1  christos {
   1503  1.1  christos   bfd_vma start;
   1504  1.1  christos   long symcount;
   1505  1.1  christos   asection **osections = NULL;
   1506  1.1  christos   asection *gnu_debuglink_section = NULL;
   1507  1.1  christos   bfd_size_type *gaps = NULL;
   1508  1.1  christos   bfd_size_type max_gap = 0;
   1509  1.1  christos   long symsize;
   1510  1.1  christos   void *dhandle;
   1511  1.1  christos   enum bfd_architecture iarch;
   1512  1.1  christos   unsigned int imach;
   1513  1.1  christos 
   1514  1.1  christos   if (ibfd->xvec->byteorder != obfd->xvec->byteorder
   1515  1.1  christos       && ibfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN
   1516  1.1  christos       && obfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN)
   1517  1.1  christos     fatal (_("Unable to change endianness of input file(s)"));
   1518  1.1  christos 
   1519  1.1  christos   if (!bfd_set_format (obfd, bfd_get_format (ibfd)))
   1520  1.1  christos     {
   1521  1.1  christos       bfd_nonfatal_message (NULL, obfd, NULL, NULL);
   1522  1.1  christos       return FALSE;
   1523  1.1  christos     }
   1524  1.1  christos 
   1525  1.1  christos   if (verbose)
   1526  1.1  christos     printf (_("copy from `%s' [%s] to `%s' [%s]\n"),
   1527  1.1  christos 	    bfd_get_archive_filename (ibfd), bfd_get_target (ibfd),
   1528  1.1  christos 	    bfd_get_filename (obfd), bfd_get_target (obfd));
   1529  1.1  christos 
   1530  1.1  christos   if (extract_symbol)
   1531  1.1  christos     start = 0;
   1532  1.1  christos   else
   1533  1.1  christos     {
   1534  1.1  christos       if (set_start_set)
   1535  1.1  christos 	start = set_start;
   1536  1.1  christos       else
   1537  1.1  christos 	start = bfd_get_start_address (ibfd);
   1538  1.1  christos       start += change_start;
   1539  1.1  christos     }
   1540  1.1  christos 
   1541  1.1  christos   /* Neither the start address nor the flags
   1542  1.1  christos      need to be set for a core file.  */
   1543  1.1  christos   if (bfd_get_format (obfd) != bfd_core)
   1544  1.1  christos     {
   1545  1.1  christos       flagword flags;
   1546  1.1  christos 
   1547  1.1  christos       flags = bfd_get_file_flags (ibfd);
   1548  1.1  christos       flags |= bfd_flags_to_set;
   1549  1.1  christos       flags &= ~bfd_flags_to_clear;
   1550  1.1  christos       flags &= bfd_applicable_file_flags (obfd);
   1551  1.1  christos 
   1552  1.1  christos       if (strip_symbols == STRIP_ALL)
   1553  1.1  christos 	flags &= ~HAS_RELOC;
   1554  1.1  christos 
   1555  1.1  christos       if (!bfd_set_start_address (obfd, start)
   1556  1.1  christos 	  || !bfd_set_file_flags (obfd, flags))
   1557  1.1  christos 	{
   1558  1.1  christos 	  bfd_nonfatal_message (NULL, ibfd, NULL, NULL);
   1559  1.1  christos 	  return FALSE;
   1560  1.1  christos 	}
   1561  1.1  christos     }
   1562  1.1  christos 
   1563  1.1  christos   /* Copy architecture of input file to output file.  */
   1564  1.1  christos   iarch = bfd_get_arch (ibfd);
   1565  1.1  christos   imach = bfd_get_mach (ibfd);
   1566  1.1  christos   if (input_arch)
   1567  1.1  christos     {
   1568  1.1  christos       if (bfd_get_arch_info (ibfd) == NULL
   1569  1.1  christos 	  || bfd_get_arch_info (ibfd)->arch == bfd_arch_unknown)
   1570  1.1  christos 	{
   1571  1.1  christos 	  iarch = input_arch->arch;
   1572  1.1  christos 	  imach = input_arch->mach;
   1573  1.1  christos 	}
   1574  1.1  christos       else
   1575  1.1  christos 	non_fatal (_("Input file `%s' ignores binary architecture parameter."),
   1576  1.1  christos 		   bfd_get_archive_filename (ibfd));
   1577  1.1  christos     }
   1578  1.1  christos   if (!bfd_set_arch_mach (obfd, iarch, imach)
   1579  1.1  christos       && (ibfd->target_defaulted
   1580  1.1  christos 	  || bfd_get_arch (ibfd) != bfd_get_arch (obfd)))
   1581  1.1  christos     {
   1582  1.1  christos       if (bfd_get_arch (ibfd) == bfd_arch_unknown)
   1583  1.1  christos 	non_fatal (_("Unable to recognise the format of the input file `%s'"),
   1584  1.1  christos 		   bfd_get_archive_filename (ibfd));
   1585  1.1  christos       else
   1586  1.1  christos 	non_fatal (_("Output file cannot represent architecture `%s'"),
   1587  1.1  christos 		   bfd_printable_arch_mach (bfd_get_arch (ibfd),
   1588  1.1  christos 					    bfd_get_mach (ibfd)));
   1589  1.1  christos       return FALSE;
   1590  1.1  christos     }
   1591  1.1  christos 
   1592  1.1  christos   if (!bfd_set_format (obfd, bfd_get_format (ibfd)))
   1593  1.1  christos     {
   1594  1.1  christos       bfd_nonfatal_message (NULL, ibfd, NULL, NULL);
   1595  1.1  christos       return FALSE;
   1596  1.1  christos     }
   1597  1.1  christos 
   1598  1.1  christos   if (bfd_get_flavour (obfd) == bfd_target_coff_flavour
   1599  1.1  christos       && bfd_pei_p (obfd))
   1600  1.1  christos     {
   1601  1.1  christos       /* Set up PE parameters.  */
   1602  1.1  christos       pe_data_type *pe = pe_data (obfd);
   1603  1.1  christos 
   1604  1.1  christos       /* Copy PE parameters before changing them.  */
   1605  1.1  christos       if (ibfd->xvec->flavour == bfd_target_coff_flavour
   1606  1.1  christos 	  && bfd_pei_p (ibfd))
   1607  1.1  christos 	pe->pe_opthdr = pe_data (ibfd)->pe_opthdr;
   1608  1.1  christos 
   1609  1.1  christos       if (pe_file_alignment != (bfd_vma) -1)
   1610  1.1  christos 	pe->pe_opthdr.FileAlignment = pe_file_alignment;
   1611  1.1  christos       else
   1612  1.1  christos 	pe_file_alignment = PE_DEF_FILE_ALIGNMENT;
   1613  1.1  christos 
   1614  1.1  christos       if (pe_heap_commit != (bfd_vma) -1)
   1615  1.1  christos 	pe->pe_opthdr.SizeOfHeapCommit = pe_heap_commit;
   1616  1.1  christos 
   1617  1.1  christos       if (pe_heap_reserve != (bfd_vma) -1)
   1618  1.1  christos 	pe->pe_opthdr.SizeOfHeapCommit = pe_heap_reserve;
   1619  1.1  christos 
   1620  1.1  christos       if (pe_image_base != (bfd_vma) -1)
   1621  1.1  christos 	pe->pe_opthdr.ImageBase = pe_image_base;
   1622  1.1  christos 
   1623  1.1  christos       if (pe_section_alignment != (bfd_vma) -1)
   1624  1.1  christos 	pe->pe_opthdr.SectionAlignment = pe_section_alignment;
   1625  1.1  christos       else
   1626  1.1  christos 	pe_section_alignment = PE_DEF_SECTION_ALIGNMENT;
   1627  1.1  christos 
   1628  1.1  christos       if (pe_stack_commit != (bfd_vma) -1)
   1629  1.1  christos 	pe->pe_opthdr.SizeOfStackCommit = pe_stack_commit;
   1630  1.1  christos 
   1631  1.1  christos       if (pe_stack_reserve != (bfd_vma) -1)
   1632  1.1  christos 	pe->pe_opthdr.SizeOfStackCommit = pe_stack_reserve;
   1633  1.1  christos 
   1634  1.1  christos       if (pe_subsystem != -1)
   1635  1.1  christos 	pe->pe_opthdr.Subsystem = pe_subsystem;
   1636  1.1  christos 
   1637  1.1  christos       if (pe_major_subsystem_version != -1)
   1638  1.1  christos 	pe->pe_opthdr.MajorSubsystemVersion = pe_major_subsystem_version;
   1639  1.1  christos 
   1640  1.1  christos       if (pe_minor_subsystem_version != -1)
   1641  1.1  christos 	pe->pe_opthdr.MinorSubsystemVersion = pe_minor_subsystem_version;
   1642  1.1  christos 
   1643  1.1  christos       if (pe_file_alignment > pe_section_alignment)
   1644  1.1  christos 	{
   1645  1.1  christos 	  char file_alignment[20], section_alignment[20];
   1646  1.1  christos 
   1647  1.1  christos 	  sprintf_vma (file_alignment, pe_file_alignment);
   1648  1.1  christos 	  sprintf_vma (section_alignment, pe_section_alignment);
   1649  1.1  christos 	  non_fatal (_("warning: file alignment (0x%s) > section alignment (0x%s)"),
   1650  1.1  christos 
   1651  1.1  christos 		     file_alignment, section_alignment);
   1652  1.1  christos 	}
   1653  1.1  christos     }
   1654  1.1  christos 
   1655  1.1  christos   if (isympp)
   1656  1.1  christos     free (isympp);
   1657  1.1  christos 
   1658  1.1  christos   if (osympp != isympp)
   1659  1.1  christos     free (osympp);
   1660  1.1  christos 
   1661  1.1  christos   isympp = NULL;
   1662  1.1  christos   osympp = NULL;
   1663  1.1  christos 
   1664  1.1  christos   symsize = bfd_get_symtab_upper_bound (ibfd);
   1665  1.1  christos   if (symsize < 0)
   1666  1.1  christos     {
   1667  1.1  christos       bfd_nonfatal_message (NULL, ibfd, NULL, NULL);
   1668  1.1  christos       return FALSE;
   1669  1.1  christos     }
   1670  1.1  christos 
   1671  1.1  christos   osympp = isympp = (asymbol **) xmalloc (symsize);
   1672  1.1  christos   symcount = bfd_canonicalize_symtab (ibfd, isympp);
   1673  1.1  christos   if (symcount < 0)
   1674  1.1  christos     {
   1675  1.1  christos       bfd_nonfatal_message (NULL, ibfd, NULL, NULL);
   1676  1.1  christos       return FALSE;
   1677  1.1  christos     }
   1678  1.1  christos 
   1679  1.1  christos   /* BFD mandates that all output sections be created and sizes set before
   1680  1.1  christos      any output is done.  Thus, we traverse all sections multiple times.  */
   1681  1.1  christos   bfd_map_over_sections (ibfd, setup_section, obfd);
   1682  1.1  christos 
   1683  1.1  christos   if (!extract_symbol)
   1684  1.1  christos     setup_bfd_headers (ibfd, obfd);
   1685  1.1  christos 
   1686  1.1  christos   if (add_sections != NULL)
   1687  1.1  christos     {
   1688  1.1  christos       struct section_add *padd;
   1689  1.1  christos       struct section_list *pset;
   1690  1.1  christos 
   1691  1.1  christos       for (padd = add_sections; padd != NULL; padd = padd->next)
   1692  1.1  christos 	{
   1693  1.1  christos 	  flagword flags;
   1694  1.1  christos 
   1695  1.1  christos 	  pset = find_section_list (padd->name, FALSE);
   1696  1.1  christos 	  if (pset != NULL)
   1697  1.1  christos 	    pset->used = TRUE;
   1698  1.1  christos 
   1699  1.1  christos 	  flags = SEC_HAS_CONTENTS | SEC_READONLY | SEC_DATA;
   1700  1.1  christos 	  if (pset != NULL && pset->set_flags)
   1701  1.1  christos 	    flags = pset->flags | SEC_HAS_CONTENTS;
   1702  1.1  christos 
   1703  1.1  christos 	  /* bfd_make_section_with_flags() does not return very helpful
   1704  1.1  christos 	     error codes, so check for the most likely user error first.  */
   1705  1.1  christos 	  if (bfd_get_section_by_name (obfd, padd->name))
   1706  1.1  christos 	    {
   1707  1.1  christos 	      bfd_nonfatal_message (NULL, obfd, NULL,
   1708  1.1  christos 				 _("can't add section '%s'"), padd->name);
   1709  1.1  christos 	      return FALSE;
   1710  1.1  christos 	    }
   1711  1.1  christos 	  else
   1712  1.1  christos 	    {
   1713  1.1  christos 	      /* We use LINKER_CREATED here so that the backend hooks
   1714  1.1  christos 	         will create any special section type information,
   1715  1.1  christos 	         instead of presuming we know what we're doing merely
   1716  1.1  christos 	         because we set the flags.  */
   1717  1.1  christos 	      padd->section = bfd_make_section_with_flags
   1718  1.1  christos 		(obfd, padd->name, flags | SEC_LINKER_CREATED);
   1719  1.1  christos 	      if (padd->section == NULL)
   1720  1.1  christos 		{
   1721  1.1  christos 		  bfd_nonfatal_message (NULL, obfd, NULL,
   1722  1.1  christos 					_("can't create section `%s'"),
   1723  1.1  christos 					padd->name);
   1724  1.1  christos 		  return FALSE;
   1725  1.1  christos 		}
   1726  1.1  christos 	    }
   1727  1.1  christos 
   1728  1.1  christos 	  if (! bfd_set_section_size (obfd, padd->section, padd->size))
   1729  1.1  christos 	    {
   1730  1.1  christos 	      bfd_nonfatal_message (NULL, obfd, padd->section, NULL);
   1731  1.1  christos 	      return FALSE;
   1732  1.1  christos 	    }
   1733  1.1  christos 
   1734  1.1  christos 	  if (pset != NULL)
   1735  1.1  christos 	    {
   1736  1.1  christos 	      if (pset->change_vma != CHANGE_IGNORE)
   1737  1.1  christos 		if (! bfd_set_section_vma (obfd, padd->section,
   1738  1.1  christos 					   pset->vma_val))
   1739  1.1  christos 		  {
   1740  1.1  christos 		    bfd_nonfatal_message (NULL, obfd, padd->section, NULL);
   1741  1.1  christos 		    return FALSE;
   1742  1.1  christos 		  }
   1743  1.1  christos 
   1744  1.1  christos 	      if (pset->change_lma != CHANGE_IGNORE)
   1745  1.1  christos 		{
   1746  1.1  christos 		  padd->section->lma = pset->lma_val;
   1747  1.1  christos 
   1748  1.1  christos 		  if (! bfd_set_section_alignment
   1749  1.1  christos 		      (obfd, padd->section,
   1750  1.1  christos 		       bfd_section_alignment (obfd, padd->section)))
   1751  1.1  christos 		    {
   1752  1.1  christos 		      bfd_nonfatal_message (NULL, obfd, padd->section, NULL);
   1753  1.1  christos 		      return FALSE;
   1754  1.1  christos 		    }
   1755  1.1  christos 		}
   1756  1.1  christos 	    }
   1757  1.1  christos 	}
   1758  1.1  christos     }
   1759  1.1  christos 
   1760  1.1  christos   if (gnu_debuglink_filename != NULL)
   1761  1.1  christos     {
   1762  1.1  christos       gnu_debuglink_section = bfd_create_gnu_debuglink_section
   1763  1.1  christos 	(obfd, gnu_debuglink_filename);
   1764  1.1  christos 
   1765  1.1  christos       if (gnu_debuglink_section == NULL)
   1766  1.1  christos 	{
   1767  1.1  christos 	  bfd_nonfatal_message (NULL, obfd, NULL,
   1768  1.1  christos 				_("cannot create debug link section `%s'"),
   1769  1.1  christos 				gnu_debuglink_filename);
   1770  1.1  christos 	  return FALSE;
   1771  1.1  christos 	}
   1772  1.1  christos 
   1773  1.1  christos       /* Special processing for PE format files.  We
   1774  1.1  christos 	 have no way to distinguish PE from COFF here.  */
   1775  1.1  christos       if (bfd_get_flavour (obfd) == bfd_target_coff_flavour)
   1776  1.1  christos 	{
   1777  1.1  christos 	  bfd_vma debuglink_vma;
   1778  1.1  christos 	  asection * highest_section;
   1779  1.1  christos 	  asection * sec;
   1780  1.1  christos 
   1781  1.1  christos 	  /* The PE spec requires that all sections be adjacent and sorted
   1782  1.1  christos 	     in ascending order of VMA.  It also specifies that debug
   1783  1.1  christos 	     sections should be last.  This is despite the fact that debug
   1784  1.1  christos 	     sections are not loaded into memory and so in theory have no
   1785  1.1  christos 	     use for a VMA.
   1786  1.1  christos 
   1787  1.1  christos 	     This means that the debuglink section must be given a non-zero
   1788  1.1  christos 	     VMA which makes it contiguous with other debug sections.  So
   1789  1.1  christos 	     walk the current section list, find the section with the
   1790  1.1  christos 	     highest VMA and start the debuglink section after that one.  */
   1791  1.1  christos 	  for (sec = obfd->sections, highest_section = NULL;
   1792  1.1  christos 	       sec != NULL;
   1793  1.1  christos 	       sec = sec->next)
   1794  1.1  christos 	    if (sec->vma > 0
   1795  1.1  christos 		&& (highest_section == NULL
   1796  1.1  christos 		    || sec->vma > highest_section->vma))
   1797  1.1  christos 	      highest_section = sec;
   1798  1.1  christos 
   1799  1.1  christos 	  if (highest_section)
   1800  1.1  christos 	    debuglink_vma = BFD_ALIGN (highest_section->vma
   1801  1.1  christos 				       + highest_section->size,
   1802  1.1  christos 				       /* FIXME: We ought to be using
   1803  1.1  christos 					  COFF_PAGE_SIZE here or maybe
   1804  1.1  christos 					  bfd_get_section_alignment() (if it
   1805  1.1  christos 					  was set) but since this is for PE
   1806  1.1  christos 					  and we know the required alignment
   1807  1.1  christos 					  it is easier just to hard code it.  */
   1808  1.1  christos 				       0x1000);
   1809  1.1  christos 	  else
   1810  1.1  christos 	    /* Umm, not sure what to do in this case.  */
   1811  1.1  christos 	    debuglink_vma = 0x1000;
   1812  1.1  christos 
   1813  1.1  christos 	  bfd_set_section_vma (obfd, gnu_debuglink_section, debuglink_vma);
   1814  1.1  christos 	}
   1815  1.1  christos     }
   1816  1.1  christos 
   1817  1.1  christos   if (bfd_count_sections (obfd) != 0
   1818  1.1  christos       && (gap_fill_set || pad_to_set))
   1819  1.1  christos     {
   1820  1.1  christos       asection **set;
   1821  1.1  christos       unsigned int c, i;
   1822  1.1  christos 
   1823  1.1  christos       /* We must fill in gaps between the sections and/or we must pad
   1824  1.1  christos 	 the last section to a specified address.  We do this by
   1825  1.1  christos 	 grabbing a list of the sections, sorting them by VMA, and
   1826  1.1  christos 	 increasing the section sizes as required to fill the gaps.
   1827  1.1  christos 	 We write out the gap contents below.  */
   1828  1.1  christos 
   1829  1.1  christos       c = bfd_count_sections (obfd);
   1830  1.1  christos       osections = (asection **) xmalloc (c * sizeof (asection *));
   1831  1.1  christos       set = osections;
   1832  1.1  christos       bfd_map_over_sections (obfd, get_sections, &set);
   1833  1.1  christos 
   1834  1.1  christos       qsort (osections, c, sizeof (asection *), compare_section_lma);
   1835  1.1  christos 
   1836  1.1  christos       gaps = (bfd_size_type *) xmalloc (c * sizeof (bfd_size_type));
   1837  1.1  christos       memset (gaps, 0, c * sizeof (bfd_size_type));
   1838  1.1  christos 
   1839  1.1  christos       if (gap_fill_set)
   1840  1.1  christos 	{
   1841  1.1  christos 	  for (i = 0; i < c - 1; i++)
   1842  1.1  christos 	    {
   1843  1.1  christos 	      flagword flags;
   1844  1.1  christos 	      bfd_size_type size;
   1845  1.1  christos 	      bfd_vma gap_start, gap_stop;
   1846  1.1  christos 
   1847  1.1  christos 	      flags = bfd_get_section_flags (obfd, osections[i]);
   1848  1.1  christos 	      if ((flags & SEC_HAS_CONTENTS) == 0
   1849  1.1  christos 		  || (flags & SEC_LOAD) == 0)
   1850  1.1  christos 		continue;
   1851  1.1  christos 
   1852  1.1  christos 	      size = bfd_section_size (obfd, osections[i]);
   1853  1.1  christos 	      gap_start = bfd_section_lma (obfd, osections[i]) + size;
   1854  1.1  christos 	      gap_stop = bfd_section_lma (obfd, osections[i + 1]);
   1855  1.1  christos 	      if (gap_start < gap_stop)
   1856  1.1  christos 		{
   1857  1.1  christos 		  if (! bfd_set_section_size (obfd, osections[i],
   1858  1.1  christos 					      size + (gap_stop - gap_start)))
   1859  1.1  christos 		    {
   1860  1.1  christos 		      bfd_nonfatal_message (NULL, obfd, osections[i],
   1861  1.1  christos 					    _("Can't fill gap after section"));
   1862  1.1  christos 		      status = 1;
   1863  1.1  christos 		      break;
   1864  1.1  christos 		    }
   1865  1.1  christos 		  gaps[i] = gap_stop - gap_start;
   1866  1.1  christos 		  if (max_gap < gap_stop - gap_start)
   1867  1.1  christos 		    max_gap = gap_stop - gap_start;
   1868  1.1  christos 		}
   1869  1.1  christos 	    }
   1870  1.1  christos 	}
   1871  1.1  christos 
   1872  1.1  christos       if (pad_to_set)
   1873  1.1  christos 	{
   1874  1.1  christos 	  bfd_vma lma;
   1875  1.1  christos 	  bfd_size_type size;
   1876  1.1  christos 
   1877  1.1  christos 	  lma = bfd_section_lma (obfd, osections[c - 1]);
   1878  1.1  christos 	  size = bfd_section_size (obfd, osections[c - 1]);
   1879  1.1  christos 	  if (lma + size < pad_to)
   1880  1.1  christos 	    {
   1881  1.1  christos 	      if (! bfd_set_section_size (obfd, osections[c - 1],
   1882  1.1  christos 					  pad_to - lma))
   1883  1.1  christos 		{
   1884  1.1  christos 		  bfd_nonfatal_message (NULL, obfd, osections[c - 1],
   1885  1.1  christos 					_("can't add padding"));
   1886  1.1  christos 		  status = 1;
   1887  1.1  christos 		}
   1888  1.1  christos 	      else
   1889  1.1  christos 		{
   1890  1.1  christos 		  gaps[c - 1] = pad_to - (lma + size);
   1891  1.1  christos 		  if (max_gap < pad_to - (lma + size))
   1892  1.1  christos 		    max_gap = pad_to - (lma + size);
   1893  1.1  christos 		}
   1894  1.1  christos 	    }
   1895  1.1  christos 	}
   1896  1.1  christos     }
   1897  1.1  christos 
   1898  1.1  christos   /* Symbol filtering must happen after the output sections
   1899  1.1  christos      have been created, but before their contents are set.  */
   1900  1.1  christos   dhandle = NULL;
   1901  1.1  christos   if (convert_debugging)
   1902  1.1  christos     dhandle = read_debugging_info (ibfd, isympp, symcount, FALSE);
   1903  1.1  christos 
   1904  1.1  christos   if (strip_symbols == STRIP_DEBUG
   1905  1.1  christos       || strip_symbols == STRIP_ALL
   1906  1.1  christos       || strip_symbols == STRIP_UNNEEDED
   1907  1.1  christos       || strip_symbols == STRIP_NONDEBUG
   1908  1.1  christos       || strip_symbols == STRIP_DWO
   1909  1.1  christos       || strip_symbols == STRIP_NONDWO
   1910  1.1  christos       || discard_locals != LOCALS_UNDEF
   1911  1.1  christos       || localize_hidden
   1912  1.1  christos       || htab_elements (strip_specific_htab) != 0
   1913  1.1  christos       || htab_elements (keep_specific_htab) != 0
   1914  1.1  christos       || htab_elements (localize_specific_htab) != 0
   1915  1.1  christos       || htab_elements (globalize_specific_htab) != 0
   1916  1.1  christos       || htab_elements (keepglobal_specific_htab) != 0
   1917  1.1  christos       || htab_elements (weaken_specific_htab) != 0
   1918  1.1  christos       || prefix_symbols_string
   1919  1.1  christos       || sections_removed
   1920  1.1  christos       || sections_copied
   1921  1.1  christos       || convert_debugging
   1922  1.1  christos       || change_leading_char
   1923  1.1  christos       || remove_leading_char
   1924  1.1  christos       || redefine_sym_list
   1925  1.1  christos       || weaken)
   1926  1.1  christos     {
   1927  1.1  christos       /* Mark symbols used in output relocations so that they
   1928  1.1  christos 	 are kept, even if they are local labels or static symbols.
   1929  1.1  christos 
   1930  1.1  christos 	 Note we iterate over the input sections examining their
   1931  1.1  christos 	 relocations since the relocations for the output sections
   1932  1.1  christos 	 haven't been set yet.  mark_symbols_used_in_relocations will
   1933  1.1  christos 	 ignore input sections which have no corresponding output
   1934  1.1  christos 	 section.  */
   1935  1.1  christos       if (strip_symbols != STRIP_ALL)
   1936  1.1  christos 	bfd_map_over_sections (ibfd,
   1937  1.1  christos 			       mark_symbols_used_in_relocations,
   1938  1.1  christos 			       isympp);
   1939  1.1  christos       osympp = (asymbol **) xmalloc ((symcount + 1) * sizeof (asymbol *));
   1940  1.1  christos       symcount = filter_symbols (ibfd, obfd, osympp, isympp, symcount);
   1941  1.1  christos     }
   1942  1.1  christos 
   1943  1.1  christos   if (convert_debugging && dhandle != NULL)
   1944  1.1  christos     {
   1945  1.1  christos       if (! write_debugging_info (obfd, dhandle, &symcount, &osympp))
   1946  1.1  christos 	{
   1947  1.1  christos 	  status = 1;
   1948  1.1  christos 	  return FALSE;
   1949  1.1  christos 	}
   1950  1.1  christos     }
   1951  1.1  christos 
   1952  1.1  christos   bfd_set_symtab (obfd, osympp, symcount);
   1953  1.1  christos 
   1954  1.1  christos   /* This has to happen before section positions are set.  */
   1955  1.1  christos   bfd_map_over_sections (ibfd, copy_relocations_in_section, obfd);
   1956  1.1  christos 
   1957  1.1  christos   /* This has to happen after the symbol table has been set.  */
   1958  1.1  christos   bfd_map_over_sections (ibfd, copy_section, obfd);
   1959  1.1  christos 
   1960  1.1  christos   if (add_sections != NULL)
   1961  1.1  christos     {
   1962  1.1  christos       struct section_add *padd;
   1963  1.1  christos 
   1964  1.1  christos       for (padd = add_sections; padd != NULL; padd = padd->next)
   1965  1.1  christos 	{
   1966  1.1  christos 	  if (! bfd_set_section_contents (obfd, padd->section, padd->contents,
   1967  1.1  christos 					  0, padd->size))
   1968  1.1  christos 	    {
   1969  1.1  christos 	      bfd_nonfatal_message (NULL, obfd, padd->section, NULL);
   1970  1.1  christos 	      return FALSE;
   1971  1.1  christos 	    }
   1972  1.1  christos 	}
   1973  1.1  christos     }
   1974  1.1  christos 
   1975  1.1  christos   if (gnu_debuglink_filename != NULL)
   1976  1.1  christos     {
   1977  1.1  christos       if (! bfd_fill_in_gnu_debuglink_section
   1978  1.1  christos 	  (obfd, gnu_debuglink_section, gnu_debuglink_filename))
   1979  1.1  christos 	{
   1980  1.1  christos 	  bfd_nonfatal_message (NULL, obfd, NULL,
   1981  1.1  christos 				_("cannot fill debug link section `%s'"),
   1982  1.1  christos 				gnu_debuglink_filename);
   1983  1.1  christos 	  return FALSE;
   1984  1.1  christos 	}
   1985  1.1  christos     }
   1986  1.1  christos 
   1987  1.1  christos   if (gap_fill_set || pad_to_set)
   1988  1.1  christos     {
   1989  1.1  christos       bfd_byte *buf;
   1990  1.1  christos       int c, i;
   1991  1.1  christos 
   1992  1.1  christos       /* Fill in the gaps.  */
   1993  1.1  christos       if (max_gap > 8192)
   1994  1.1  christos 	max_gap = 8192;
   1995  1.1  christos       buf = (bfd_byte *) xmalloc (max_gap);
   1996  1.1  christos       memset (buf, gap_fill, max_gap);
   1997  1.1  christos 
   1998  1.1  christos       c = bfd_count_sections (obfd);
   1999  1.1  christos       for (i = 0; i < c; i++)
   2000  1.1  christos 	{
   2001  1.1  christos 	  if (gaps[i] != 0)
   2002  1.1  christos 	    {
   2003  1.1  christos 	      bfd_size_type left;
   2004  1.1  christos 	      file_ptr off;
   2005  1.1  christos 
   2006  1.1  christos 	      left = gaps[i];
   2007  1.1  christos 	      off = bfd_section_size (obfd, osections[i]) - left;
   2008  1.1  christos 
   2009  1.1  christos 	      while (left > 0)
   2010  1.1  christos 		{
   2011  1.1  christos 		  bfd_size_type now;
   2012  1.1  christos 
   2013  1.1  christos 		  if (left > 8192)
   2014  1.1  christos 		    now = 8192;
   2015  1.1  christos 		  else
   2016  1.1  christos 		    now = left;
   2017  1.1  christos 
   2018  1.1  christos 		  if (! bfd_set_section_contents (obfd, osections[i], buf,
   2019  1.1  christos 						  off, now))
   2020  1.1  christos 		    {
   2021  1.1  christos 		      bfd_nonfatal_message (NULL, obfd, osections[i], NULL);
   2022  1.1  christos 		      return FALSE;
   2023  1.1  christos 		    }
   2024  1.1  christos 
   2025  1.1  christos 		  left -= now;
   2026  1.1  christos 		  off += now;
   2027  1.1  christos 		}
   2028  1.1  christos 	    }
   2029  1.1  christos 	}
   2030  1.1  christos     }
   2031  1.1  christos 
   2032  1.1  christos   /* Do not copy backend data if --extract-symbol is passed; anything
   2033  1.1  christos      that needs to look at the section contents will fail.  */
   2034  1.1  christos   if (extract_symbol)
   2035  1.1  christos     return TRUE;
   2036  1.1  christos 
   2037  1.1  christos   /* Allow the BFD backend to copy any private data it understands
   2038  1.1  christos      from the input BFD to the output BFD.  This is done last to
   2039  1.1  christos      permit the routine to look at the filtered symbol table, which is
   2040  1.1  christos      important for the ECOFF code at least.  */
   2041  1.1  christos   if (! bfd_copy_private_bfd_data (ibfd, obfd))
   2042  1.1  christos     {
   2043  1.1  christos       bfd_nonfatal_message (NULL, obfd, NULL,
   2044  1.1  christos 			    _("error copying private BFD data"));
   2045  1.1  christos       return FALSE;
   2046  1.1  christos     }
   2047  1.1  christos 
   2048  1.1  christos   /* Switch to the alternate machine code.  We have to do this at the
   2049  1.1  christos      very end, because we only initialize the header when we create
   2050  1.1  christos      the first section.  */
   2051  1.1  christos   if (use_alt_mach_code != 0)
   2052  1.1  christos     {
   2053  1.1  christos       if (! bfd_alt_mach_code (obfd, use_alt_mach_code))
   2054  1.1  christos 	{
   2055  1.1  christos 	  non_fatal (_("this target does not support %lu alternative machine codes"),
   2056  1.1  christos 		     use_alt_mach_code);
   2057  1.1  christos 	  if (bfd_get_flavour (obfd) == bfd_target_elf_flavour)
   2058  1.1  christos 	    {
   2059  1.1  christos 	      non_fatal (_("treating that number as an absolute e_machine value instead"));
   2060  1.1  christos 	      elf_elfheader (obfd)->e_machine = use_alt_mach_code;
   2061  1.1  christos 	    }
   2062  1.1  christos 	  else
   2063  1.1  christos 	    non_fatal (_("ignoring the alternative value"));
   2064  1.1  christos 	}
   2065  1.1  christos     }
   2066  1.1  christos 
   2067  1.1  christos   return TRUE;
   2068  1.1  christos }
   2069  1.1  christos 
   2070  1.1  christos /* Read each archive element in turn from IBFD, copy the
   2071  1.1  christos    contents to temp file, and keep the temp file handle.
   2072  1.1  christos    If 'force_output_target' is TRUE then make sure that
   2073  1.1  christos    all elements in the new archive are of the type
   2074  1.1  christos    'output_target'.  */
   2075  1.1  christos 
   2076  1.1  christos static void
   2077  1.1  christos copy_archive (bfd *ibfd, bfd *obfd, const char *output_target,
   2078  1.1  christos 	      bfd_boolean force_output_target,
   2079  1.1  christos 	      const bfd_arch_info_type *input_arch)
   2080  1.1  christos {
   2081  1.1  christos   struct name_list
   2082  1.1  christos     {
   2083  1.1  christos       struct name_list *next;
   2084  1.1  christos       const char *name;
   2085  1.1  christos       bfd *obfd;
   2086  1.1  christos     } *list, *l;
   2087  1.1  christos   bfd **ptr = &obfd->archive_head;
   2088  1.1  christos   bfd *this_element;
   2089  1.1  christos   char *dir;
   2090  1.1  christos   const char *filename;
   2091  1.1  christos 
   2092  1.1  christos   /* Make a temp directory to hold the contents.  */
   2093  1.1  christos   dir = make_tempdir (bfd_get_filename (obfd));
   2094  1.1  christos   if (dir == NULL)
   2095  1.1  christos       fatal (_("cannot create tempdir for archive copying (error: %s)"),
   2096  1.1  christos 	   strerror (errno));
   2097  1.1  christos 
   2098  1.1  christos   if (strip_symbols == STRIP_ALL)
   2099  1.1  christos     obfd->has_armap = FALSE;
   2100  1.1  christos   else
   2101  1.1  christos     obfd->has_armap = ibfd->has_armap;
   2102  1.1  christos   obfd->is_thin_archive = ibfd->is_thin_archive;
   2103  1.1  christos 
   2104  1.1  christos   if (deterministic)
   2105  1.1  christos     obfd->flags |= BFD_DETERMINISTIC_OUTPUT;
   2106  1.1  christos 
   2107  1.1  christos   list = NULL;
   2108  1.1  christos 
   2109  1.1  christos   this_element = bfd_openr_next_archived_file (ibfd, NULL);
   2110  1.1  christos 
   2111  1.1  christos   if (!bfd_set_format (obfd, bfd_get_format (ibfd)))
   2112  1.1  christos     {
   2113  1.1  christos       status = 1;
   2114  1.1  christos       bfd_nonfatal_message (NULL, obfd, NULL, NULL);
   2115  1.1  christos       return;
   2116  1.1  christos     }
   2117  1.1  christos 
   2118  1.1  christos   while (!status && this_element != NULL)
   2119  1.1  christos     {
   2120  1.1  christos       char *output_name;
   2121  1.1  christos       bfd *output_bfd;
   2122  1.1  christos       bfd *last_element;
   2123  1.1  christos       struct stat buf;
   2124  1.1  christos       int stat_status = 0;
   2125  1.1  christos       bfd_boolean del = TRUE;
   2126  1.1  christos       bfd_boolean ok_object;
   2127  1.1  christos 
   2128  1.1  christos       /* Create an output file for this member.  */
   2129  1.1  christos       output_name = concat (dir, "/",
   2130  1.1  christos 			    bfd_get_filename (this_element), (char *) 0);
   2131  1.1  christos 
   2132  1.1  christos       /* If the file already exists, make another temp dir.  */
   2133  1.1  christos       if (stat (output_name, &buf) >= 0)
   2134  1.1  christos 	{
   2135  1.1  christos 	  output_name = make_tempdir (output_name);
   2136  1.1  christos 	  if (output_name == NULL)
   2137  1.1  christos 	    fatal (_("cannot create tempdir for archive copying (error: %s)"),
   2138  1.1  christos 		   strerror (errno));
   2139  1.1  christos 
   2140  1.1  christos 	  l = (struct name_list *) xmalloc (sizeof (struct name_list));
   2141  1.1  christos 	  l->name = output_name;
   2142  1.1  christos 	  l->next = list;
   2143  1.1  christos 	  l->obfd = NULL;
   2144  1.1  christos 	  list = l;
   2145  1.1  christos 	  output_name = concat (output_name, "/",
   2146  1.1  christos 				bfd_get_filename (this_element), (char *) 0);
   2147  1.1  christos 	}
   2148  1.1  christos 
   2149  1.1  christos       if (preserve_dates)
   2150  1.1  christos 	{
   2151  1.1  christos 	  stat_status = bfd_stat_arch_elt (this_element, &buf);
   2152  1.1  christos 
   2153  1.1  christos 	  if (stat_status != 0)
   2154  1.1  christos 	    non_fatal (_("internal stat error on %s"),
   2155  1.1  christos 		       bfd_get_filename (this_element));
   2156  1.1  christos 	}
   2157  1.1  christos 
   2158  1.1  christos       l = (struct name_list *) xmalloc (sizeof (struct name_list));
   2159  1.1  christos       l->name = output_name;
   2160  1.1  christos       l->next = list;
   2161  1.1  christos       l->obfd = NULL;
   2162  1.1  christos       list = l;
   2163  1.1  christos 
   2164  1.1  christos       ok_object = bfd_check_format (this_element, bfd_object);
   2165  1.1  christos       if (!ok_object)
   2166  1.1  christos 	bfd_nonfatal_message (NULL, this_element, NULL,
   2167  1.1  christos 			      _("Unable to recognise the format of file"));
   2168  1.1  christos 
   2169  1.1  christos       /* PR binutils/3110: Cope with archives
   2170  1.1  christos 	 containing multiple target types.  */
   2171  1.1  christos       if (force_output_target || !ok_object)
   2172  1.1  christos 	output_bfd = bfd_openw (output_name, output_target);
   2173  1.1  christos       else
   2174  1.1  christos 	output_bfd = bfd_openw (output_name, bfd_get_target (this_element));
   2175  1.1  christos 
   2176  1.1  christos       if (output_bfd == NULL)
   2177  1.1  christos 	{
   2178  1.1  christos 	  bfd_nonfatal_message (output_name, NULL, NULL, NULL);
   2179  1.1  christos 	  status = 1;
   2180  1.1  christos 	  return;
   2181  1.1  christos 	}
   2182  1.1  christos 
   2183  1.1  christos       if (ok_object)
   2184  1.1  christos 	{
   2185  1.1  christos 	  del = !copy_object (this_element, output_bfd, input_arch);
   2186  1.1  christos 
   2187  1.1  christos 	  if (del && bfd_get_arch (this_element) == bfd_arch_unknown)
   2188  1.1  christos 	    /* Try again as an unknown object file.  */
   2189  1.1  christos 	    ok_object = FALSE;
   2190  1.1  christos 	  else if (!bfd_close (output_bfd))
   2191  1.1  christos 	    {
   2192  1.1  christos 	      bfd_nonfatal_message (output_name, NULL, NULL, NULL);
   2193  1.1  christos 	      /* Error in new object file. Don't change archive.  */
   2194  1.1  christos 	      status = 1;
   2195  1.1  christos 	    }
   2196  1.1  christos 	}
   2197  1.1  christos 
   2198  1.1  christos       if (!ok_object)
   2199  1.1  christos 	{
   2200  1.1  christos 	  del = !copy_unknown_object (this_element, output_bfd);
   2201  1.1  christos 	  if (!bfd_close_all_done (output_bfd))
   2202  1.1  christos 	    {
   2203  1.1  christos 	      bfd_nonfatal_message (output_name, NULL, NULL, NULL);
   2204  1.1  christos 	      /* Error in new object file. Don't change archive.  */
   2205  1.1  christos 	      status = 1;
   2206  1.1  christos 	    }
   2207  1.1  christos 	}
   2208  1.1  christos 
   2209  1.1  christos       if (del)
   2210  1.1  christos 	{
   2211  1.1  christos 	  unlink (output_name);
   2212  1.1  christos 	  status = 1;
   2213  1.1  christos 	}
   2214  1.1  christos       else
   2215  1.1  christos 	{
   2216  1.1  christos 	  if (preserve_dates && stat_status == 0)
   2217  1.1  christos 	    set_times (output_name, &buf);
   2218  1.1  christos 
   2219  1.1  christos 	  /* Open the newly output file and attach to our list.  */
   2220  1.1  christos 	  output_bfd = bfd_openr (output_name, output_target);
   2221  1.1  christos 
   2222  1.1  christos 	  l->obfd = output_bfd;
   2223  1.1  christos 
   2224  1.1  christos 	  *ptr = output_bfd;
   2225  1.1  christos 	  ptr = &output_bfd->archive_next;
   2226  1.1  christos 
   2227  1.1  christos 	  last_element = this_element;
   2228  1.1  christos 
   2229  1.1  christos 	  this_element = bfd_openr_next_archived_file (ibfd, last_element);
   2230  1.1  christos 
   2231  1.1  christos 	  bfd_close (last_element);
   2232  1.1  christos 	}
   2233  1.1  christos     }
   2234  1.1  christos   *ptr = NULL;
   2235  1.1  christos 
   2236  1.1  christos   filename = bfd_get_filename (obfd);
   2237  1.1  christos   if (!bfd_close (obfd))
   2238  1.1  christos     {
   2239  1.1  christos       status = 1;
   2240  1.1  christos       bfd_nonfatal_message (filename, NULL, NULL, NULL);
   2241  1.1  christos       return;
   2242  1.1  christos     }
   2243  1.1  christos 
   2244  1.1  christos   filename = bfd_get_filename (ibfd);
   2245  1.1  christos   if (!bfd_close (ibfd))
   2246  1.1  christos     {
   2247  1.1  christos       status = 1;
   2248  1.1  christos       bfd_nonfatal_message (filename, NULL, NULL, NULL);
   2249  1.1  christos       return;
   2250  1.1  christos     }
   2251  1.1  christos 
   2252  1.1  christos   /* Delete all the files that we opened.  */
   2253  1.1  christos   for (l = list; l != NULL; l = l->next)
   2254  1.1  christos     {
   2255  1.1  christos       if (l->obfd == NULL)
   2256  1.1  christos 	rmdir (l->name);
   2257  1.1  christos       else
   2258  1.1  christos 	{
   2259  1.1  christos 	  bfd_close (l->obfd);
   2260  1.1  christos 	  unlink (l->name);
   2261  1.1  christos 	}
   2262  1.1  christos     }
   2263  1.1  christos   rmdir (dir);
   2264  1.1  christos }
   2265  1.1  christos 
   2266  1.1  christos static void
   2267  1.1  christos set_long_section_mode (bfd *output_bfd, bfd *input_bfd, enum long_section_name_handling style)
   2268  1.1  christos {
   2269  1.1  christos   /* This is only relevant to Coff targets.  */
   2270  1.1  christos   if (bfd_get_flavour (output_bfd) == bfd_target_coff_flavour)
   2271  1.1  christos     {
   2272  1.1  christos       if (style == KEEP
   2273  1.1  christos 	  && bfd_get_flavour (input_bfd) == bfd_target_coff_flavour)
   2274  1.1  christos 	style = bfd_coff_long_section_names (input_bfd) ? ENABLE : DISABLE;
   2275  1.1  christos       bfd_coff_set_long_section_names (output_bfd, style != DISABLE);
   2276  1.1  christos     }
   2277  1.1  christos }
   2278  1.1  christos 
   2279  1.1  christos /* The top-level control.  */
   2280  1.1  christos 
   2281  1.1  christos static void
   2282  1.1  christos copy_file (const char *input_filename, const char *output_filename,
   2283  1.1  christos 	   const char *input_target,   const char *output_target,
   2284  1.1  christos 	   const bfd_arch_info_type *input_arch)
   2285  1.1  christos {
   2286  1.1  christos   bfd *ibfd;
   2287  1.1  christos   char **obj_matching;
   2288  1.1  christos   char **core_matching;
   2289  1.1  christos   off_t size = get_file_size (input_filename);
   2290  1.1  christos 
   2291  1.1  christos   if (size < 1)
   2292  1.1  christos     {
   2293  1.1  christos       if (size == 0)
   2294  1.1  christos 	non_fatal (_("error: the input file '%s' is empty"),
   2295  1.1  christos 		   input_filename);
   2296  1.1  christos       status = 1;
   2297  1.1  christos       return;
   2298  1.1  christos     }
   2299  1.1  christos 
   2300  1.1  christos   /* To allow us to do "strip *" without dying on the first
   2301  1.1  christos      non-object file, failures are nonfatal.  */
   2302  1.1  christos   ibfd = bfd_openr (input_filename, input_target);
   2303  1.1  christos   if (ibfd == NULL)
   2304  1.1  christos     {
   2305  1.1  christos       bfd_nonfatal_message (input_filename, NULL, NULL, NULL);
   2306  1.1  christos       status = 1;
   2307  1.1  christos       return;
   2308  1.1  christos     }
   2309  1.1  christos 
   2310  1.1  christos   switch (do_debug_sections)
   2311  1.1  christos     {
   2312  1.1  christos     case compress:
   2313  1.1  christos       ibfd->flags |= BFD_COMPRESS;
   2314  1.1  christos       break;
   2315  1.1  christos     case decompress:
   2316  1.1  christos       ibfd->flags |= BFD_DECOMPRESS;
   2317  1.1  christos       break;
   2318  1.1  christos     default:
   2319  1.1  christos       break;
   2320  1.1  christos     }
   2321  1.1  christos 
   2322  1.1  christos   if (bfd_check_format (ibfd, bfd_archive))
   2323  1.1  christos     {
   2324  1.1  christos       bfd_boolean force_output_target;
   2325  1.1  christos       bfd *obfd;
   2326  1.1  christos 
   2327  1.1  christos       /* bfd_get_target does not return the correct value until
   2328  1.1  christos          bfd_check_format succeeds.  */
   2329  1.1  christos       if (output_target == NULL)
   2330  1.1  christos 	{
   2331  1.1  christos 	  output_target = bfd_get_target (ibfd);
   2332  1.1  christos 	  force_output_target = FALSE;
   2333  1.1  christos 	}
   2334  1.1  christos       else
   2335  1.1  christos 	force_output_target = TRUE;
   2336  1.1  christos 
   2337  1.1  christos       obfd = bfd_openw (output_filename, output_target);
   2338  1.1  christos       if (obfd == NULL)
   2339  1.1  christos 	{
   2340  1.1  christos 	  bfd_nonfatal_message (output_filename, NULL, NULL, NULL);
   2341  1.1  christos 	  status = 1;
   2342  1.1  christos 	  return;
   2343  1.1  christos 	}
   2344  1.1  christos       /* This is a no-op on non-Coff targets.  */
   2345  1.1  christos       set_long_section_mode (obfd, ibfd, long_section_names);
   2346  1.1  christos 
   2347  1.1  christos       copy_archive (ibfd, obfd, output_target, force_output_target, input_arch);
   2348  1.1  christos     }
   2349  1.1  christos   else if (bfd_check_format_matches (ibfd, bfd_object, &obj_matching))
   2350  1.1  christos     {
   2351  1.1  christos       bfd *obfd;
   2352  1.1  christos     do_copy:
   2353  1.1  christos 
   2354  1.1  christos       /* bfd_get_target does not return the correct value until
   2355  1.1  christos          bfd_check_format succeeds.  */
   2356  1.1  christos       if (output_target == NULL)
   2357  1.1  christos 	output_target = bfd_get_target (ibfd);
   2358  1.1  christos 
   2359  1.1  christos       obfd = bfd_openw (output_filename, output_target);
   2360  1.1  christos       if (obfd == NULL)
   2361  1.1  christos  	{
   2362  1.1  christos  	  bfd_nonfatal_message (output_filename, NULL, NULL, NULL);
   2363  1.1  christos  	  status = 1;
   2364  1.1  christos  	  return;
   2365  1.1  christos  	}
   2366  1.1  christos       /* This is a no-op on non-Coff targets.  */
   2367  1.1  christos       set_long_section_mode (obfd, ibfd, long_section_names);
   2368  1.1  christos 
   2369  1.1  christos       if (! copy_object (ibfd, obfd, input_arch))
   2370  1.1  christos 	status = 1;
   2371  1.1  christos 
   2372  1.1  christos       if (!bfd_close (obfd))
   2373  1.1  christos 	{
   2374  1.1  christos 	  status = 1;
   2375  1.1  christos 	  bfd_nonfatal_message (output_filename, NULL, NULL, NULL);
   2376  1.1  christos 	  return;
   2377  1.1  christos 	}
   2378  1.1  christos 
   2379  1.1  christos       if (!bfd_close (ibfd))
   2380  1.1  christos 	{
   2381  1.1  christos 	  status = 1;
   2382  1.1  christos 	  bfd_nonfatal_message (input_filename, NULL, NULL, NULL);
   2383  1.1  christos 	  return;
   2384  1.1  christos 	}
   2385  1.1  christos     }
   2386  1.1  christos   else
   2387  1.1  christos     {
   2388  1.1  christos       bfd_error_type obj_error = bfd_get_error ();
   2389  1.1  christos       bfd_error_type core_error;
   2390  1.1  christos 
   2391  1.1  christos       if (bfd_check_format_matches (ibfd, bfd_core, &core_matching))
   2392  1.1  christos 	{
   2393  1.1  christos 	  /* This probably can't happen..  */
   2394  1.1  christos 	  if (obj_error == bfd_error_file_ambiguously_recognized)
   2395  1.1  christos 	    free (obj_matching);
   2396  1.1  christos 	  goto do_copy;
   2397  1.1  christos 	}
   2398  1.1  christos 
   2399  1.1  christos       core_error = bfd_get_error ();
   2400  1.1  christos       /* Report the object error in preference to the core error.  */
   2401  1.1  christos       if (obj_error != core_error)
   2402  1.1  christos 	bfd_set_error (obj_error);
   2403  1.1  christos 
   2404  1.1  christos       bfd_nonfatal_message (input_filename, NULL, NULL, NULL);
   2405  1.1  christos 
   2406  1.1  christos       if (obj_error == bfd_error_file_ambiguously_recognized)
   2407  1.1  christos 	{
   2408  1.1  christos 	  list_matching_formats (obj_matching);
   2409  1.1  christos 	  free (obj_matching);
   2410  1.1  christos 	}
   2411  1.1  christos       if (core_error == bfd_error_file_ambiguously_recognized)
   2412  1.1  christos 	{
   2413  1.1  christos 	  list_matching_formats (core_matching);
   2414  1.1  christos 	  free (core_matching);
   2415  1.1  christos 	}
   2416  1.1  christos 
   2417  1.1  christos       status = 1;
   2418  1.1  christos     }
   2419  1.1  christos }
   2420  1.1  christos 
   2421  1.1  christos /* Add a name to the section renaming list.  */
   2422  1.1  christos 
   2423  1.1  christos static void
   2424  1.1  christos add_section_rename (const char * old_name, const char * new_name,
   2425  1.1  christos 		    flagword flags)
   2426  1.1  christos {
   2427  1.1  christos   section_rename * srename;
   2428  1.1  christos 
   2429  1.1  christos   /* Check for conflicts first.  */
   2430  1.1  christos   for (srename = section_rename_list; srename != NULL; srename = srename->next)
   2431  1.1  christos     if (strcmp (srename->old_name, old_name) == 0)
   2432  1.1  christos       {
   2433  1.1  christos 	/* Silently ignore duplicate definitions.  */
   2434  1.1  christos 	if (strcmp (srename->new_name, new_name) == 0
   2435  1.1  christos 	    && srename->flags == flags)
   2436  1.1  christos 	  return;
   2437  1.1  christos 
   2438  1.1  christos 	fatal (_("Multiple renames of section %s"), old_name);
   2439  1.1  christos       }
   2440  1.1  christos 
   2441  1.1  christos   srename = (section_rename *) xmalloc (sizeof (* srename));
   2442  1.1  christos 
   2443  1.1  christos   srename->old_name = old_name;
   2444  1.1  christos   srename->new_name = new_name;
   2445  1.1  christos   srename->flags    = flags;
   2446  1.1  christos   srename->next     = section_rename_list;
   2447  1.1  christos 
   2448  1.1  christos   section_rename_list = srename;
   2449  1.1  christos }
   2450  1.1  christos 
   2451  1.1  christos /* Check the section rename list for a new name of the input section
   2452  1.1  christos    ISECTION.  Return the new name if one is found.
   2453  1.1  christos    Also set RETURNED_FLAGS to the flags to be used for this section.  */
   2454  1.1  christos 
   2455  1.1  christos static const char *
   2456  1.1  christos find_section_rename (bfd * ibfd ATTRIBUTE_UNUSED, sec_ptr isection,
   2457  1.1  christos 		     flagword * returned_flags)
   2458  1.1  christos {
   2459  1.1  christos   const char * old_name = bfd_section_name (ibfd, isection);
   2460  1.1  christos   section_rename * srename;
   2461  1.1  christos 
   2462  1.1  christos   /* Default to using the flags of the input section.  */
   2463  1.1  christos   * returned_flags = bfd_get_section_flags (ibfd, isection);
   2464  1.1  christos 
   2465  1.1  christos   for (srename = section_rename_list; srename != NULL; srename = srename->next)
   2466  1.1  christos     if (strcmp (srename->old_name, old_name) == 0)
   2467  1.1  christos       {
   2468  1.1  christos 	if (srename->flags != (flagword) -1)
   2469  1.1  christos 	  * returned_flags = srename->flags;
   2470  1.1  christos 
   2471  1.1  christos 	return srename->new_name;
   2472  1.1  christos       }
   2473  1.1  christos 
   2474  1.1  christos   return old_name;
   2475  1.1  christos }
   2476  1.1  christos 
   2477  1.1  christos /* Once each of the sections is copied, we may still need to do some
   2478  1.1  christos    finalization work for private section headers.  Do that here.  */
   2479  1.1  christos 
   2480  1.1  christos static void
   2481  1.1  christos setup_bfd_headers (bfd *ibfd, bfd *obfd)
   2482  1.1  christos {
   2483  1.1  christos   /* Allow the BFD backend to copy any private data it understands
   2484  1.1  christos      from the input section to the output section.  */
   2485  1.1  christos   if (! bfd_copy_private_header_data (ibfd, obfd))
   2486  1.1  christos     {
   2487  1.1  christos       status = 1;
   2488  1.1  christos       bfd_nonfatal_message (NULL, ibfd, NULL,
   2489  1.1  christos 			    _("error in private header data"));
   2490  1.1  christos       return;
   2491  1.1  christos     }
   2492  1.1  christos 
   2493  1.1  christos   /* All went well.  */
   2494  1.1  christos   return;
   2495  1.1  christos }
   2496  1.1  christos 
   2497  1.1  christos /* Create a section in OBFD with the same
   2498  1.1  christos    name and attributes as ISECTION in IBFD.  */
   2499  1.1  christos 
   2500  1.1  christos static void
   2501  1.1  christos setup_section (bfd *ibfd, sec_ptr isection, void *obfdarg)
   2502  1.1  christos {
   2503  1.1  christos   bfd *obfd = (bfd *) obfdarg;
   2504  1.1  christos   struct section_list *p;
   2505  1.1  christos   sec_ptr osection;
   2506  1.1  christos   bfd_size_type size;
   2507  1.1  christos   bfd_vma vma;
   2508  1.1  christos   bfd_vma lma;
   2509  1.1  christos   flagword flags;
   2510  1.1  christos   const char *err;
   2511  1.1  christos   const char * name;
   2512  1.1  christos   char *prefix = NULL;
   2513  1.1  christos   bfd_boolean make_nobits;
   2514  1.1  christos 
   2515  1.1  christos   if (is_strip_section (ibfd, isection))
   2516  1.1  christos     return;
   2517  1.1  christos 
   2518  1.1  christos   p = find_section_list (bfd_section_name (ibfd, isection), FALSE);
   2519  1.1  christos   if (p != NULL)
   2520  1.1  christos     p->used = TRUE;
   2521  1.1  christos 
   2522  1.1  christos   /* Get the, possibly new, name of the output section.  */
   2523  1.1  christos   name = find_section_rename (ibfd, isection, & flags);
   2524  1.1  christos 
   2525  1.1  christos   /* Prefix sections.  */
   2526  1.1  christos   if ((prefix_alloc_sections_string)
   2527  1.1  christos       && (bfd_get_section_flags (ibfd, isection) & SEC_ALLOC))
   2528  1.1  christos     prefix = prefix_alloc_sections_string;
   2529  1.1  christos   else if (prefix_sections_string)
   2530  1.1  christos     prefix = prefix_sections_string;
   2531  1.1  christos 
   2532  1.1  christos   if (prefix)
   2533  1.1  christos     {
   2534  1.1  christos       char *n;
   2535  1.1  christos 
   2536  1.1  christos       n = (char *) xmalloc (strlen (prefix) + strlen (name) + 1);
   2537  1.1  christos       strcpy (n, prefix);
   2538  1.1  christos       strcat (n, name);
   2539  1.1  christos       name = n;
   2540  1.1  christos     }
   2541  1.1  christos 
   2542  1.1  christos   make_nobits = FALSE;
   2543  1.1  christos   if (p != NULL && p->set_flags)
   2544  1.1  christos     flags = p->flags | (flags & (SEC_HAS_CONTENTS | SEC_RELOC));
   2545  1.1  christos   else if (strip_symbols == STRIP_NONDEBUG
   2546  1.1  christos 	   && (flags & (SEC_ALLOC | SEC_GROUP)) != 0
   2547  1.1  christos 	   && !(ibfd->xvec->flavour == bfd_target_elf_flavour
   2548  1.1  christos 		&& elf_section_type (isection) == SHT_NOTE))
   2549  1.1  christos     {
   2550  1.1  christos       flags &= ~(SEC_HAS_CONTENTS | SEC_LOAD | SEC_GROUP);
   2551  1.1  christos       if (obfd->xvec->flavour == bfd_target_elf_flavour)
   2552  1.1  christos 	{
   2553  1.1  christos 	  make_nobits = TRUE;
   2554  1.1  christos 
   2555  1.1  christos 	  /* Twiddle the input section flags so that it seems to
   2556  1.1  christos 	     elf.c:copy_private_bfd_data that section flags have not
   2557  1.1  christos 	     changed between input and output sections.  This hack
   2558  1.1  christos 	     prevents wholesale rewriting of the program headers.  */
   2559  1.1  christos 	  isection->flags &= ~(SEC_HAS_CONTENTS | SEC_LOAD | SEC_GROUP);
   2560  1.1  christos 	}
   2561  1.1  christos     }
   2562  1.1  christos 
   2563  1.1  christos   osection = bfd_make_section_anyway_with_flags (obfd, name, flags);
   2564  1.1  christos 
   2565  1.1  christos   if (osection == NULL)
   2566  1.1  christos     {
   2567  1.1  christos       err = _("failed to create output section");
   2568  1.1  christos       goto loser;
   2569  1.1  christos     }
   2570  1.1  christos 
   2571  1.1  christos   if (make_nobits)
   2572  1.1  christos     elf_section_type (osection) = SHT_NOBITS;
   2573  1.1  christos 
   2574  1.1  christos   size = bfd_section_size (ibfd, isection);
   2575  1.1  christos   if (copy_byte >= 0)
   2576  1.1  christos     size = (size + interleave - 1) / interleave * copy_width;
   2577  1.1  christos   else if (extract_symbol)
   2578  1.1  christos     size = 0;
   2579  1.1  christos   if (! bfd_set_section_size (obfd, osection, size))
   2580  1.1  christos     {
   2581  1.1  christos       err = _("failed to set size");
   2582  1.1  christos       goto loser;
   2583  1.1  christos     }
   2584  1.1  christos 
   2585  1.1  christos   vma = bfd_section_vma (ibfd, isection);
   2586  1.1  christos   if (p != NULL && p->change_vma == CHANGE_MODIFY)
   2587  1.1  christos     vma += p->vma_val;
   2588  1.1  christos   else if (p != NULL && p->change_vma == CHANGE_SET)
   2589  1.1  christos     vma = p->vma_val;
   2590  1.1  christos   else
   2591  1.1  christos     vma += change_section_address;
   2592  1.1  christos 
   2593  1.1  christos   if (! bfd_set_section_vma (obfd, osection, vma))
   2594  1.1  christos     {
   2595  1.1  christos       err = _("failed to set vma");
   2596  1.1  christos       goto loser;
   2597  1.1  christos     }
   2598  1.1  christos 
   2599  1.1  christos   lma = isection->lma;
   2600  1.1  christos   if ((p != NULL) && p->change_lma != CHANGE_IGNORE)
   2601  1.1  christos     {
   2602  1.1  christos       if (p->change_lma == CHANGE_MODIFY)
   2603  1.1  christos 	lma += p->lma_val;
   2604  1.1  christos       else if (p->change_lma == CHANGE_SET)
   2605  1.1  christos 	lma = p->lma_val;
   2606  1.1  christos       else
   2607  1.1  christos 	abort ();
   2608  1.1  christos     }
   2609  1.1  christos   else
   2610  1.1  christos     lma += change_section_address;
   2611  1.1  christos 
   2612  1.1  christos   osection->lma = lma;
   2613  1.1  christos 
   2614  1.1  christos   /* FIXME: This is probably not enough.  If we change the LMA we
   2615  1.1  christos      may have to recompute the header for the file as well.  */
   2616  1.1  christos   if (!bfd_set_section_alignment (obfd,
   2617  1.1  christos 				  osection,
   2618  1.1  christos 				  bfd_section_alignment (ibfd, isection)))
   2619  1.1  christos     {
   2620  1.1  christos       err = _("failed to set alignment");
   2621  1.1  christos       goto loser;
   2622  1.1  christos     }
   2623  1.1  christos 
   2624  1.1  christos   /* Copy merge entity size.  */
   2625  1.1  christos   osection->entsize = isection->entsize;
   2626  1.1  christos 
   2627  1.1  christos   /* This used to be mangle_section; we do here to avoid using
   2628  1.1  christos      bfd_get_section_by_name since some formats allow multiple
   2629  1.1  christos      sections with the same name.  */
   2630  1.1  christos   isection->output_section = osection;
   2631  1.1  christos   isection->output_offset = 0;
   2632  1.1  christos 
   2633  1.1  christos   /* Do not copy backend data if --extract-symbol is passed; anything
   2634  1.1  christos      that needs to look at the section contents will fail.  */
   2635  1.1  christos   if (extract_symbol)
   2636  1.1  christos     return;
   2637  1.1  christos 
   2638  1.1  christos   if ((isection->flags & SEC_GROUP) != 0)
   2639  1.1  christos     {
   2640  1.1  christos       asymbol *gsym = group_signature (isection);
   2641  1.1  christos 
   2642  1.1  christos       if (gsym != NULL)
   2643  1.1  christos 	{
   2644  1.1  christos 	  gsym->flags |= BSF_KEEP;
   2645  1.1  christos 	  if (ibfd->xvec->flavour == bfd_target_elf_flavour)
   2646  1.1  christos 	    elf_group_id (isection) = gsym;
   2647  1.1  christos 	}
   2648  1.1  christos     }
   2649  1.1  christos 
   2650  1.1  christos   /* Allow the BFD backend to copy any private data it understands
   2651  1.1  christos      from the input section to the output section.  */
   2652  1.1  christos   if (!bfd_copy_private_section_data (ibfd, isection, obfd, osection))
   2653  1.1  christos     {
   2654  1.1  christos       err = _("failed to copy private data");
   2655  1.1  christos       goto loser;
   2656  1.1  christos     }
   2657  1.1  christos 
   2658  1.1  christos   /* All went well.  */
   2659  1.1  christos   return;
   2660  1.1  christos 
   2661  1.1  christos loser:
   2662  1.1  christos   status = 1;
   2663  1.1  christos   bfd_nonfatal_message (NULL, obfd, osection, err);
   2664  1.1  christos }
   2665  1.1  christos 
   2666  1.1  christos /* Return TRUE if input section ISECTION should be skipped.  */
   2667  1.1  christos 
   2668  1.1  christos static bfd_boolean
   2669  1.1  christos skip_section (bfd *ibfd, sec_ptr isection)
   2670  1.1  christos {
   2671  1.1  christos   sec_ptr osection;
   2672  1.1  christos   bfd_size_type size;
   2673  1.1  christos   flagword flags;
   2674  1.1  christos 
   2675  1.1  christos   /* If we have already failed earlier on,
   2676  1.1  christos      do not keep on generating complaints now.  */
   2677  1.1  christos   if (status != 0)
   2678  1.1  christos     return TRUE;
   2679  1.1  christos 
   2680  1.1  christos   if (extract_symbol)
   2681  1.1  christos     return TRUE;
   2682  1.1  christos 
   2683  1.1  christos   if (is_strip_section (ibfd, isection))
   2684  1.1  christos     return TRUE;
   2685  1.1  christos 
   2686  1.1  christos   flags = bfd_get_section_flags (ibfd, isection);
   2687  1.1  christos   if ((flags & SEC_GROUP) != 0)
   2688  1.1  christos     return TRUE;
   2689  1.1  christos 
   2690  1.1  christos   osection = isection->output_section;
   2691  1.1  christos   size = bfd_get_section_size (isection);
   2692  1.1  christos 
   2693  1.1  christos   if (size == 0 || osection == 0)
   2694  1.1  christos     return TRUE;
   2695  1.1  christos 
   2696  1.1  christos   return FALSE;
   2697  1.1  christos }
   2698  1.1  christos 
   2699  1.1  christos /* Copy relocations in input section ISECTION of IBFD to an output
   2700  1.1  christos    section with the same name in OBFDARG.  If stripping then don't
   2701  1.1  christos    copy any relocation info.  */
   2702  1.1  christos 
   2703  1.1  christos static void
   2704  1.1  christos copy_relocations_in_section (bfd *ibfd, sec_ptr isection, void *obfdarg)
   2705  1.1  christos {
   2706  1.1  christos   bfd *obfd = (bfd *) obfdarg;
   2707  1.1  christos   long relsize;
   2708  1.1  christos   arelent **relpp;
   2709  1.1  christos   long relcount;
   2710  1.1  christos   sec_ptr osection;
   2711  1.1  christos 
   2712  1.1  christos   if (skip_section (ibfd, isection))
   2713  1.1  christos     return;
   2714  1.1  christos 
   2715  1.1  christos   osection = isection->output_section;
   2716  1.1  christos 
   2717  1.1  christos   /* Core files and DWO files do not need to be relocated.  */
   2718  1.1  christos   if (bfd_get_format (obfd) == bfd_core || strip_symbols == STRIP_NONDWO)
   2719  1.1  christos     relsize = 0;
   2720  1.1  christos   else
   2721  1.1  christos     {
   2722  1.1  christos       relsize = bfd_get_reloc_upper_bound (ibfd, isection);
   2723  1.1  christos 
   2724  1.1  christos       if (relsize < 0)
   2725  1.1  christos 	{
   2726  1.1  christos 	  /* Do not complain if the target does not support relocations.  */
   2727  1.1  christos 	  if (relsize == -1 && bfd_get_error () == bfd_error_invalid_operation)
   2728  1.1  christos 	    relsize = 0;
   2729  1.1  christos 	  else
   2730  1.1  christos 	    {
   2731  1.1  christos 	      status = 1;
   2732  1.1  christos 	      bfd_nonfatal_message (NULL, ibfd, isection, NULL);
   2733  1.1  christos 	      return;
   2734  1.1  christos 	    }
   2735  1.1  christos 	}
   2736  1.1  christos     }
   2737  1.1  christos 
   2738  1.1  christos   if (relsize == 0)
   2739  1.1  christos     {
   2740  1.1  christos       bfd_set_reloc (obfd, osection, NULL, 0);
   2741  1.1  christos       osection->flags &= ~SEC_RELOC;
   2742  1.1  christos     }
   2743  1.1  christos   else
   2744  1.1  christos     {
   2745  1.1  christos       relpp = (arelent **) xmalloc (relsize);
   2746  1.1  christos       relcount = bfd_canonicalize_reloc (ibfd, isection, relpp, isympp);
   2747  1.1  christos       if (relcount < 0)
   2748  1.1  christos 	{
   2749  1.1  christos 	  status = 1;
   2750  1.1  christos 	  bfd_nonfatal_message (NULL, ibfd, isection,
   2751  1.1  christos 				_("relocation count is negative"));
   2752  1.1  christos 	  return;
   2753  1.1  christos 	}
   2754  1.1  christos 
   2755  1.1  christos       if (strip_symbols == STRIP_ALL)
   2756  1.1  christos 	{
   2757  1.1  christos 	  /* Remove relocations which are not in
   2758  1.1  christos 	     keep_strip_specific_list.  */
   2759  1.1  christos 	  arelent **temp_relpp;
   2760  1.1  christos 	  long temp_relcount = 0;
   2761  1.1  christos 	  long i;
   2762  1.1  christos 
   2763  1.1  christos 	  temp_relpp = (arelent **) xmalloc (relsize);
   2764  1.1  christos 	  for (i = 0; i < relcount; i++)
   2765  1.1  christos 	    if (is_specified_symbol (bfd_asymbol_name (*relpp[i]->sym_ptr_ptr),
   2766  1.1  christos 				     keep_specific_htab))
   2767  1.1  christos 	      temp_relpp [temp_relcount++] = relpp [i];
   2768  1.1  christos 	  relcount = temp_relcount;
   2769  1.1  christos 	  free (relpp);
   2770  1.1  christos 	  relpp = temp_relpp;
   2771  1.1  christos 	}
   2772  1.1  christos 
   2773  1.1  christos       bfd_set_reloc (obfd, osection, relcount == 0 ? NULL : relpp, relcount);
   2774  1.1  christos       if (relcount == 0)
   2775  1.1  christos 	{
   2776  1.1  christos 	  osection->flags &= ~SEC_RELOC;
   2777  1.1  christos 	  free (relpp);
   2778  1.1  christos 	}
   2779  1.1  christos     }
   2780  1.1  christos }
   2781  1.1  christos 
   2782  1.1  christos /* Copy the data of input section ISECTION of IBFD
   2783  1.1  christos    to an output section with the same name in OBFD.  */
   2784  1.1  christos 
   2785  1.1  christos static void
   2786  1.1  christos copy_section (bfd *ibfd, sec_ptr isection, void *obfdarg)
   2787  1.1  christos {
   2788  1.1  christos   bfd *obfd = (bfd *) obfdarg;
   2789  1.1  christos   struct section_list *p;
   2790  1.1  christos   sec_ptr osection;
   2791  1.1  christos   bfd_size_type size;
   2792  1.1  christos 
   2793  1.1  christos   if (skip_section (ibfd, isection))
   2794  1.1  christos     return;
   2795  1.1  christos 
   2796  1.1  christos   osection = isection->output_section;
   2797  1.1  christos   size = bfd_get_section_size (isection);
   2798  1.1  christos 
   2799  1.1  christos   p = find_section_list (bfd_get_section_name (ibfd, isection), FALSE);
   2800  1.1  christos 
   2801  1.1  christos   if (bfd_get_section_flags (ibfd, isection) & SEC_HAS_CONTENTS
   2802  1.1  christos       && bfd_get_section_flags (obfd, osection) & SEC_HAS_CONTENTS)
   2803  1.1  christos     {
   2804  1.1  christos       bfd_byte *memhunk = NULL;
   2805  1.1  christos 
   2806  1.1  christos       if (!bfd_get_full_section_contents (ibfd, isection, &memhunk))
   2807  1.1  christos 	{
   2808  1.1  christos 	  status = 1;
   2809  1.1  christos 	  bfd_nonfatal_message (NULL, ibfd, isection, NULL);
   2810  1.1  christos 	  return;
   2811  1.1  christos 	}
   2812  1.1  christos 
   2813  1.1  christos       if (reverse_bytes)
   2814  1.1  christos 	{
   2815  1.1  christos 	  /* We don't handle leftover bytes (too many possible behaviors,
   2816  1.1  christos 	     and we don't know what the user wants).  The section length
   2817  1.1  christos 	     must be a multiple of the number of bytes to swap.  */
   2818  1.1  christos 	  if ((size % reverse_bytes) == 0)
   2819  1.1  christos 	    {
   2820  1.1  christos 	      unsigned long i, j;
   2821  1.1  christos 	      bfd_byte b;
   2822  1.1  christos 
   2823  1.1  christos 	      for (i = 0; i < size; i += reverse_bytes)
   2824  1.1  christos 		for (j = 0; j < (unsigned long)(reverse_bytes / 2); j++)
   2825  1.1  christos 		  {
   2826  1.1  christos 		    bfd_byte *m = (bfd_byte *) memhunk;
   2827  1.1  christos 
   2828  1.1  christos 		    b = m[i + j];
   2829  1.1  christos 		    m[i + j] = m[(i + reverse_bytes) - (j + 1)];
   2830  1.1  christos 		    m[(i + reverse_bytes) - (j + 1)] = b;
   2831  1.1  christos 		  }
   2832  1.1  christos 	    }
   2833  1.1  christos 	  else
   2834  1.1  christos 	    /* User must pad the section up in order to do this.  */
   2835  1.1  christos 	    fatal (_("cannot reverse bytes: length of section %s must be evenly divisible by %d"),
   2836  1.1  christos 		   bfd_section_name (ibfd, isection), reverse_bytes);
   2837  1.1  christos 	}
   2838  1.1  christos 
   2839  1.1  christos       if (copy_byte >= 0)
   2840  1.1  christos 	{
   2841  1.1  christos 	  /* Keep only every `copy_byte'th byte in MEMHUNK.  */
   2842  1.1  christos 	  char *from = (char *) memhunk + copy_byte;
   2843  1.1  christos 	  char *to = (char *) memhunk;
   2844  1.1  christos 	  char *end = (char *) memhunk + size;
   2845  1.1  christos 	  int i;
   2846  1.1  christos 
   2847  1.1  christos 	  for (; from < end; from += interleave)
   2848  1.1  christos 	    for (i = 0; i < copy_width; i++)
   2849  1.1  christos 	      *to++ = from[i];
   2850  1.1  christos 
   2851  1.1  christos 	  size = (size + interleave - 1 - copy_byte) / interleave * copy_width;
   2852  1.1  christos 	  osection->lma /= interleave;
   2853  1.1  christos 	}
   2854  1.1  christos 
   2855  1.1  christos       if (!bfd_set_section_contents (obfd, osection, memhunk, 0, size))
   2856  1.1  christos 	{
   2857  1.1  christos 	  status = 1;
   2858  1.1  christos 	  bfd_nonfatal_message (NULL, obfd, osection, NULL);
   2859  1.1  christos 	  return;
   2860  1.1  christos 	}
   2861  1.1  christos       free (memhunk);
   2862  1.1  christos     }
   2863  1.1  christos   else if (p != NULL && p->set_flags && (p->flags & SEC_HAS_CONTENTS) != 0)
   2864  1.1  christos     {
   2865  1.1  christos       void *memhunk = xmalloc (size);
   2866  1.1  christos 
   2867  1.1  christos       /* We don't permit the user to turn off the SEC_HAS_CONTENTS
   2868  1.1  christos 	 flag--they can just remove the section entirely and add it
   2869  1.1  christos 	 back again.  However, we do permit them to turn on the
   2870  1.1  christos 	 SEC_HAS_CONTENTS flag, and take it to mean that the section
   2871  1.1  christos 	 contents should be zeroed out.  */
   2872  1.1  christos 
   2873  1.1  christos       memset (memhunk, 0, size);
   2874  1.1  christos       if (! bfd_set_section_contents (obfd, osection, memhunk, 0, size))
   2875  1.1  christos 	{
   2876  1.1  christos 	  status = 1;
   2877  1.1  christos 	  bfd_nonfatal_message (NULL, obfd, osection, NULL);
   2878  1.1  christos 	  return;
   2879  1.1  christos 	}
   2880  1.1  christos       free (memhunk);
   2881  1.1  christos     }
   2882  1.1  christos }
   2883  1.1  christos 
   2884  1.1  christos /* Get all the sections.  This is used when --gap-fill or --pad-to is
   2885  1.1  christos    used.  */
   2886  1.1  christos 
   2887  1.1  christos static void
   2888  1.1  christos get_sections (bfd *obfd ATTRIBUTE_UNUSED, asection *osection, void *secppparg)
   2889  1.1  christos {
   2890  1.1  christos   asection ***secppp = (asection ***) secppparg;
   2891  1.1  christos 
   2892  1.1  christos   **secppp = osection;
   2893  1.1  christos   ++(*secppp);
   2894  1.1  christos }
   2895  1.1  christos 
   2896  1.1  christos /* Sort sections by VMA.  This is called via qsort, and is used when
   2897  1.1  christos    --gap-fill or --pad-to is used.  We force non loadable or empty
   2898  1.1  christos    sections to the front, where they are easier to ignore.  */
   2899  1.1  christos 
   2900  1.1  christos static int
   2901  1.1  christos compare_section_lma (const void *arg1, const void *arg2)
   2902  1.1  christos {
   2903  1.1  christos   const asection *const *sec1 = (const asection * const *) arg1;
   2904  1.1  christos   const asection *const *sec2 = (const asection * const *) arg2;
   2905  1.1  christos   flagword flags1, flags2;
   2906  1.1  christos 
   2907  1.1  christos   /* Sort non loadable sections to the front.  */
   2908  1.1  christos   flags1 = (*sec1)->flags;
   2909  1.1  christos   flags2 = (*sec2)->flags;
   2910  1.1  christos   if ((flags1 & SEC_HAS_CONTENTS) == 0
   2911  1.1  christos       || (flags1 & SEC_LOAD) == 0)
   2912  1.1  christos     {
   2913  1.1  christos       if ((flags2 & SEC_HAS_CONTENTS) != 0
   2914  1.1  christos 	  && (flags2 & SEC_LOAD) != 0)
   2915  1.1  christos 	return -1;
   2916  1.1  christos     }
   2917  1.1  christos   else
   2918  1.1  christos     {
   2919  1.1  christos       if ((flags2 & SEC_HAS_CONTENTS) == 0
   2920  1.1  christos 	  || (flags2 & SEC_LOAD) == 0)
   2921  1.1  christos 	return 1;
   2922  1.1  christos     }
   2923  1.1  christos 
   2924  1.1  christos   /* Sort sections by LMA.  */
   2925  1.1  christos   if ((*sec1)->lma > (*sec2)->lma)
   2926  1.1  christos     return 1;
   2927  1.1  christos   else if ((*sec1)->lma < (*sec2)->lma)
   2928  1.1  christos     return -1;
   2929  1.1  christos 
   2930  1.1  christos   /* Sort sections with the same LMA by size.  */
   2931  1.1  christos   if (bfd_get_section_size (*sec1) > bfd_get_section_size (*sec2))
   2932  1.1  christos     return 1;
   2933  1.1  christos   else if (bfd_get_section_size (*sec1) < bfd_get_section_size (*sec2))
   2934  1.1  christos     return -1;
   2935  1.1  christos 
   2936  1.1  christos   return 0;
   2937  1.1  christos }
   2938  1.1  christos 
   2939  1.1  christos /* Mark all the symbols which will be used in output relocations with
   2940  1.1  christos    the BSF_KEEP flag so that those symbols will not be stripped.
   2941  1.1  christos 
   2942  1.1  christos    Ignore relocations which will not appear in the output file.  */
   2943  1.1  christos 
   2944  1.1  christos static void
   2945  1.1  christos mark_symbols_used_in_relocations (bfd *ibfd, sec_ptr isection, void *symbolsarg)
   2946  1.1  christos {
   2947  1.1  christos   asymbol **symbols = (asymbol **) symbolsarg;
   2948  1.1  christos   long relsize;
   2949  1.1  christos   arelent **relpp;
   2950  1.1  christos   long relcount, i;
   2951  1.1  christos 
   2952  1.1  christos   /* Ignore an input section with no corresponding output section.  */
   2953  1.1  christos   if (isection->output_section == NULL)
   2954  1.1  christos     return;
   2955  1.1  christos 
   2956  1.1  christos   relsize = bfd_get_reloc_upper_bound (ibfd, isection);
   2957  1.1  christos   if (relsize < 0)
   2958  1.1  christos     {
   2959  1.1  christos       /* Do not complain if the target does not support relocations.  */
   2960  1.1  christos       if (relsize == -1 && bfd_get_error () == bfd_error_invalid_operation)
   2961  1.1  christos 	return;
   2962  1.1  christos       bfd_fatal (bfd_get_filename (ibfd));
   2963  1.1  christos     }
   2964  1.1  christos 
   2965  1.1  christos   if (relsize == 0)
   2966  1.1  christos     return;
   2967  1.1  christos 
   2968  1.1  christos   relpp = (arelent **) xmalloc (relsize);
   2969  1.1  christos   relcount = bfd_canonicalize_reloc (ibfd, isection, relpp, symbols);
   2970  1.1  christos   if (relcount < 0)
   2971  1.1  christos     bfd_fatal (bfd_get_filename (ibfd));
   2972  1.1  christos 
   2973  1.1  christos   /* Examine each symbol used in a relocation.  If it's not one of the
   2974  1.1  christos      special bfd section symbols, then mark it with BSF_KEEP.  */
   2975  1.1  christos   for (i = 0; i < relcount; i++)
   2976  1.1  christos     {
   2977  1.1  christos       if (*relpp[i]->sym_ptr_ptr != bfd_com_section_ptr->symbol
   2978  1.1  christos 	  && *relpp[i]->sym_ptr_ptr != bfd_abs_section_ptr->symbol
   2979  1.1  christos 	  && *relpp[i]->sym_ptr_ptr != bfd_und_section_ptr->symbol)
   2980  1.1  christos 	(*relpp[i]->sym_ptr_ptr)->flags |= BSF_KEEP;
   2981  1.1  christos     }
   2982  1.1  christos 
   2983  1.1  christos   if (relpp != NULL)
   2984  1.1  christos     free (relpp);
   2985  1.1  christos }
   2986  1.1  christos 
   2987  1.1  christos /* Write out debugging information.  */
   2988  1.1  christos 
   2989  1.1  christos static bfd_boolean
   2990  1.1  christos write_debugging_info (bfd *obfd, void *dhandle,
   2991  1.1  christos 		      long *symcountp ATTRIBUTE_UNUSED,
   2992  1.1  christos 		      asymbol ***symppp ATTRIBUTE_UNUSED)
   2993  1.1  christos {
   2994  1.1  christos   if (bfd_get_flavour (obfd) == bfd_target_ieee_flavour)
   2995  1.1  christos     return write_ieee_debugging_info (obfd, dhandle);
   2996  1.1  christos 
   2997  1.1  christos   if (bfd_get_flavour (obfd) == bfd_target_coff_flavour
   2998  1.1  christos       || bfd_get_flavour (obfd) == bfd_target_elf_flavour)
   2999  1.1  christos     {
   3000  1.1  christos       bfd_byte *syms, *strings;
   3001  1.1  christos       bfd_size_type symsize, stringsize;
   3002  1.1  christos       asection *stabsec, *stabstrsec;
   3003  1.1  christos       flagword flags;
   3004  1.1  christos 
   3005  1.1  christos       if (! write_stabs_in_sections_debugging_info (obfd, dhandle, &syms,
   3006  1.1  christos 						    &symsize, &strings,
   3007  1.1  christos 						    &stringsize))
   3008  1.1  christos 	return FALSE;
   3009  1.1  christos 
   3010  1.1  christos       flags = SEC_HAS_CONTENTS | SEC_READONLY | SEC_DEBUGGING;
   3011  1.1  christos       stabsec = bfd_make_section_with_flags (obfd, ".stab", flags);
   3012  1.1  christos       stabstrsec = bfd_make_section_with_flags (obfd, ".stabstr", flags);
   3013  1.1  christos       if (stabsec == NULL
   3014  1.1  christos 	  || stabstrsec == NULL
   3015  1.1  christos 	  || ! bfd_set_section_size (obfd, stabsec, symsize)
   3016  1.1  christos 	  || ! bfd_set_section_size (obfd, stabstrsec, stringsize)
   3017  1.1  christos 	  || ! bfd_set_section_alignment (obfd, stabsec, 2)
   3018  1.1  christos 	  || ! bfd_set_section_alignment (obfd, stabstrsec, 0))
   3019  1.1  christos 	{
   3020  1.1  christos 	  bfd_nonfatal_message (NULL, obfd, NULL,
   3021  1.1  christos 				_("can't create debugging section"));
   3022  1.1  christos 	  return FALSE;
   3023  1.1  christos 	}
   3024  1.1  christos 
   3025  1.1  christos       /* We can get away with setting the section contents now because
   3026  1.1  christos          the next thing the caller is going to do is copy over the
   3027  1.1  christos          real sections.  We may someday have to split the contents
   3028  1.1  christos          setting out of this function.  */
   3029  1.1  christos       if (! bfd_set_section_contents (obfd, stabsec, syms, 0, symsize)
   3030  1.1  christos 	  || ! bfd_set_section_contents (obfd, stabstrsec, strings, 0,
   3031  1.1  christos 					 stringsize))
   3032  1.1  christos 	{
   3033  1.1  christos 	  bfd_nonfatal_message (NULL, obfd, NULL,
   3034  1.1  christos 				_("can't set debugging section contents"));
   3035  1.1  christos 	  return FALSE;
   3036  1.1  christos 	}
   3037  1.1  christos 
   3038  1.1  christos       return TRUE;
   3039  1.1  christos     }
   3040  1.1  christos 
   3041  1.1  christos   bfd_nonfatal_message (NULL, obfd, NULL,
   3042  1.1  christos 			_("don't know how to write debugging information for %s"),
   3043  1.1  christos 	     bfd_get_target (obfd));
   3044  1.1  christos   return FALSE;
   3045  1.1  christos }
   3046  1.1  christos 
   3047  1.1  christos /* If neither -D nor -U was specified explicitly,
   3048  1.1  christos    then use the configured default.  */
   3049  1.1  christos static void
   3050  1.1  christos default_deterministic (void)
   3051  1.1  christos {
   3052  1.1  christos   if (deterministic < 0)
   3053  1.1  christos     deterministic = DEFAULT_AR_DETERMINISTIC;
   3054  1.1  christos }
   3055  1.1  christos 
   3056  1.1  christos static int
   3057  1.1  christos strip_main (int argc, char *argv[])
   3058  1.1  christos {
   3059  1.1  christos   char *input_target = NULL;
   3060  1.1  christos   char *output_target = NULL;
   3061  1.1  christos   bfd_boolean show_version = FALSE;
   3062  1.1  christos   bfd_boolean formats_info = FALSE;
   3063  1.1  christos   int c;
   3064  1.1  christos   int i;
   3065  1.1  christos   struct section_list *p;
   3066  1.1  christos   char *output_file = NULL;
   3067  1.1  christos 
   3068  1.1  christos   while ((c = getopt_long (argc, argv, "I:O:F:K:N:R:o:sSpdgxXHhVvw",
   3069  1.1  christos 			   strip_options, (int *) 0)) != EOF)
   3070  1.1  christos     {
   3071  1.1  christos       switch (c)
   3072  1.1  christos 	{
   3073  1.1  christos 	case 'I':
   3074  1.1  christos 	  input_target = optarg;
   3075  1.1  christos 	  break;
   3076  1.1  christos 	case 'O':
   3077  1.1  christos 	  output_target = optarg;
   3078  1.1  christos 	  break;
   3079  1.1  christos 	case 'F':
   3080  1.1  christos 	  input_target = output_target = optarg;
   3081  1.1  christos 	  break;
   3082  1.1  christos 	case 'R':
   3083  1.1  christos 	  p = find_section_list (optarg, TRUE);
   3084  1.1  christos 	  p->remove = TRUE;
   3085  1.1  christos 	  sections_removed = TRUE;
   3086  1.1  christos 	  break;
   3087  1.1  christos 	case 's':
   3088  1.1  christos 	  strip_symbols = STRIP_ALL;
   3089  1.1  christos 	  break;
   3090  1.1  christos 	case 'S':
   3091  1.1  christos 	case 'g':
   3092  1.1  christos 	case 'd':	/* Historic BSD alias for -g.  Used by early NetBSD.  */
   3093  1.1  christos 	  strip_symbols = STRIP_DEBUG;
   3094  1.1  christos 	  break;
   3095  1.1  christos 	case OPTION_STRIP_DWO:
   3096  1.1  christos 	  strip_symbols = STRIP_DWO;
   3097  1.1  christos 	  break;
   3098  1.1  christos 	case OPTION_STRIP_UNNEEDED:
   3099  1.1  christos 	  strip_symbols = STRIP_UNNEEDED;
   3100  1.1  christos 	  break;
   3101  1.1  christos 	case 'K':
   3102  1.1  christos 	  add_specific_symbol (optarg, keep_specific_htab);
   3103  1.1  christos 	  break;
   3104  1.1  christos 	case 'N':
   3105  1.1  christos 	  add_specific_symbol (optarg, strip_specific_htab);
   3106  1.1  christos 	  break;
   3107  1.1  christos 	case 'o':
   3108  1.1  christos 	  output_file = optarg;
   3109  1.1  christos 	  break;
   3110  1.1  christos 	case 'p':
   3111  1.1  christos 	  preserve_dates = TRUE;
   3112  1.1  christos 	  break;
   3113  1.1  christos 	case 'D':
   3114  1.1  christos 	  deterministic = TRUE;
   3115  1.1  christos 	  break;
   3116  1.1  christos 	case 'U':
   3117  1.1  christos 	  deterministic = FALSE;
   3118  1.1  christos 	  break;
   3119  1.1  christos 	case 'x':
   3120  1.1  christos 	  discard_locals = LOCALS_ALL;
   3121  1.1  christos 	  break;
   3122  1.1  christos 	case 'X':
   3123  1.1  christos 	  discard_locals = LOCALS_START_L;
   3124  1.1  christos 	  break;
   3125  1.1  christos 	case 'v':
   3126  1.1  christos 	  verbose = TRUE;
   3127  1.1  christos 	  break;
   3128  1.1  christos 	case 'V':
   3129  1.1  christos 	  show_version = TRUE;
   3130  1.1  christos 	  break;
   3131  1.1  christos 	case OPTION_FORMATS_INFO:
   3132  1.1  christos 	  formats_info = TRUE;
   3133  1.1  christos 	  break;
   3134  1.1  christos 	case OPTION_ONLY_KEEP_DEBUG:
   3135  1.1  christos 	  strip_symbols = STRIP_NONDEBUG;
   3136  1.1  christos 	  break;
   3137  1.1  christos 	case OPTION_KEEP_FILE_SYMBOLS:
   3138  1.1  christos 	  keep_file_symbols = 1;
   3139  1.1  christos 	  break;
   3140  1.1  christos 	case 0:
   3141  1.1  christos 	  /* We've been given a long option.  */
   3142  1.1  christos 	  break;
   3143  1.1  christos 	case 'w':
   3144  1.1  christos 	  wildcard = TRUE;
   3145  1.1  christos 	  break;
   3146  1.1  christos 	case 'H':
   3147  1.1  christos 	case 'h':
   3148  1.1  christos 	  strip_usage (stdout, 0);
   3149  1.1  christos 	default:
   3150  1.1  christos 	  strip_usage (stderr, 1);
   3151  1.1  christos 	}
   3152  1.1  christos     }
   3153  1.1  christos 
   3154  1.1  christos   if (formats_info)
   3155  1.1  christos     {
   3156  1.1  christos       display_info ();
   3157  1.1  christos       return 0;
   3158  1.1  christos     }
   3159  1.1  christos 
   3160  1.1  christos   if (show_version)
   3161  1.1  christos     print_version ("strip");
   3162  1.1  christos 
   3163  1.1  christos   default_deterministic ();
   3164  1.1  christos 
   3165  1.1  christos   /* Default is to strip all symbols.  */
   3166  1.1  christos   if (strip_symbols == STRIP_UNDEF
   3167  1.1  christos       && discard_locals == LOCALS_UNDEF
   3168  1.1  christos       && htab_elements (strip_specific_htab) == 0)
   3169  1.1  christos     strip_symbols = STRIP_ALL;
   3170  1.1  christos 
   3171  1.1  christos   if (output_target == NULL)
   3172  1.1  christos     output_target = input_target;
   3173  1.1  christos 
   3174  1.1  christos   i = optind;
   3175  1.1  christos   if (i == argc
   3176  1.1  christos       || (output_file != NULL && (i + 1) < argc))
   3177  1.1  christos     strip_usage (stderr, 1);
   3178  1.1  christos 
   3179  1.1  christos   for (; i < argc; i++)
   3180  1.1  christos     {
   3181  1.1  christos       int hold_status = status;
   3182  1.1  christos       struct stat statbuf;
   3183  1.1  christos       char *tmpname;
   3184  1.1  christos 
   3185  1.1  christos       if (get_file_size (argv[i]) < 1)
   3186  1.1  christos 	{
   3187  1.1  christos 	  status = 1;
   3188  1.1  christos 	  continue;
   3189  1.1  christos 	}
   3190  1.1  christos 
   3191  1.1  christos       if (preserve_dates)
   3192  1.1  christos 	/* No need to check the return value of stat().
   3193  1.1  christos 	   It has already been checked in get_file_size().  */
   3194  1.1  christos 	stat (argv[i], &statbuf);
   3195  1.1  christos 
   3196  1.1  christos       if (output_file == NULL
   3197  1.1  christos 	  || filename_cmp (argv[i], output_file) == 0)
   3198  1.1  christos 	tmpname = make_tempname (argv[i]);
   3199  1.1  christos       else
   3200  1.1  christos 	tmpname = output_file;
   3201  1.1  christos 
   3202  1.1  christos       if (tmpname == NULL)
   3203  1.1  christos 	{
   3204  1.1  christos 	  bfd_nonfatal_message (argv[i], NULL, NULL,
   3205  1.1  christos 				_("could not create temporary file to hold stripped copy"));
   3206  1.1  christos 	  status = 1;
   3207  1.1  christos 	  continue;
   3208  1.1  christos 	}
   3209  1.1  christos 
   3210  1.1  christos       status = 0;
   3211  1.1  christos       copy_file (argv[i], tmpname, input_target, output_target, NULL);
   3212  1.1  christos       if (status == 0)
   3213  1.1  christos 	{
   3214  1.1  christos 	  if (preserve_dates)
   3215  1.1  christos 	    set_times (tmpname, &statbuf);
   3216  1.1  christos 	  if (output_file != tmpname)
   3217  1.1  christos 	    status = (smart_rename (tmpname,
   3218  1.1  christos 				    output_file ? output_file : argv[i],
   3219  1.1  christos 				    preserve_dates) != 0);
   3220  1.1  christos 	  if (status == 0)
   3221  1.1  christos 	    status = hold_status;
   3222  1.1  christos 	}
   3223  1.1  christos       else
   3224  1.1  christos 	unlink_if_ordinary (tmpname);
   3225  1.1  christos       if (output_file != tmpname)
   3226  1.1  christos 	free (tmpname);
   3227  1.1  christos     }
   3228  1.1  christos 
   3229  1.1  christos   return status;
   3230  1.1  christos }
   3231  1.1  christos 
   3232  1.1  christos /* Set up PE subsystem.  */
   3233  1.1  christos 
   3234  1.1  christos static void
   3235  1.1  christos set_pe_subsystem (const char *s)
   3236  1.1  christos {
   3237  1.1  christos   const char *version, *subsystem;
   3238  1.1  christos   size_t i;
   3239  1.1  christos   static const struct
   3240  1.1  christos     {
   3241  1.1  christos       const char *name;
   3242  1.1  christos       const char set_def;
   3243  1.1  christos       const short value;
   3244  1.1  christos     }
   3245  1.1  christos   v[] =
   3246  1.1  christos     {
   3247  1.1  christos       { "native", 0, IMAGE_SUBSYSTEM_NATIVE },
   3248  1.1  christos       { "windows", 0, IMAGE_SUBSYSTEM_WINDOWS_GUI },
   3249  1.1  christos       { "console", 0, IMAGE_SUBSYSTEM_WINDOWS_CUI },
   3250  1.1  christos       { "posix", 0, IMAGE_SUBSYSTEM_POSIX_CUI },
   3251  1.1  christos       { "wince", 0, IMAGE_SUBSYSTEM_WINDOWS_CE_GUI },
   3252  1.1  christos       { "efi-app", 1, IMAGE_SUBSYSTEM_EFI_APPLICATION },
   3253  1.1  christos       { "efi-bsd", 1, IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER },
   3254  1.1  christos       { "efi-rtd", 1, IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER },
   3255  1.1  christos       { "sal-rtd", 1, IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER },
   3256  1.1  christos       { "xbox", 0, IMAGE_SUBSYSTEM_XBOX }
   3257  1.1  christos     };
   3258  1.1  christos   short value;
   3259  1.1  christos   char *copy;
   3260  1.1  christos   int set_def = -1;
   3261  1.1  christos 
   3262  1.1  christos   /* Check for the presence of a version number.  */
   3263  1.1  christos   version = strchr (s, ':');
   3264  1.1  christos   if (version == NULL)
   3265  1.1  christos     subsystem = s;
   3266  1.1  christos   else
   3267  1.1  christos     {
   3268  1.1  christos       int len = version - s;
   3269  1.1  christos       copy = xstrdup (s);
   3270  1.1  christos       subsystem = copy;
   3271  1.1  christos       copy[len] = '\0';
   3272  1.1  christos       version = copy + 1 + len;
   3273  1.1  christos       pe_major_subsystem_version = strtoul (version, &copy, 0);
   3274  1.1  christos       if (*copy == '.')
   3275  1.1  christos 	pe_minor_subsystem_version = strtoul (copy + 1, &copy, 0);
   3276  1.1  christos       if (*copy != '\0')
   3277  1.1  christos 	non_fatal (_("%s: bad version in PE subsystem"), s);
   3278  1.1  christos     }
   3279  1.1  christos 
   3280  1.1  christos   /* Check for numeric subsystem.  */
   3281  1.1  christos   value = (short) strtol (subsystem, &copy, 0);
   3282  1.1  christos   if (*copy == '\0')
   3283  1.1  christos     {
   3284  1.1  christos       for (i = 0; i < ARRAY_SIZE (v); i++)
   3285  1.1  christos 	if (v[i].value == value)
   3286  1.1  christos 	  {
   3287  1.1  christos 	    pe_subsystem = value;
   3288  1.1  christos 	    set_def = v[i].set_def;
   3289  1.1  christos 	    break;
   3290  1.1  christos 	  }
   3291  1.1  christos     }
   3292  1.1  christos   else
   3293  1.1  christos     {
   3294  1.1  christos       /* Search for subsystem by name.  */
   3295  1.1  christos       for (i = 0; i < ARRAY_SIZE (v); i++)
   3296  1.1  christos 	if (strcmp (subsystem, v[i].name) == 0)
   3297  1.1  christos 	  {
   3298  1.1  christos 	    pe_subsystem = v[i].value;
   3299  1.1  christos 	    set_def = v[i].set_def;
   3300  1.1  christos 	    break;
   3301  1.1  christos 	  }
   3302  1.1  christos     }
   3303  1.1  christos 
   3304  1.1  christos   switch (set_def)
   3305  1.1  christos     {
   3306  1.1  christos     case -1:
   3307  1.1  christos       fatal (_("unknown PE subsystem: %s"), s);
   3308  1.1  christos       break;
   3309  1.1  christos     case 0:
   3310  1.1  christos       break;
   3311  1.1  christos     default:
   3312  1.1  christos       if (pe_file_alignment == (bfd_vma) -1)
   3313  1.1  christos 	pe_file_alignment = PE_DEF_FILE_ALIGNMENT;
   3314  1.1  christos       if (pe_section_alignment == (bfd_vma) -1)
   3315  1.1  christos 	pe_section_alignment = PE_DEF_SECTION_ALIGNMENT;
   3316  1.1  christos       break;
   3317  1.1  christos     }
   3318  1.1  christos   if (s != subsystem)
   3319  1.1  christos     free ((char *) subsystem);
   3320  1.1  christos }
   3321  1.1  christos 
   3322  1.1  christos /* Convert EFI target to PEI target.  */
   3323  1.1  christos 
   3324  1.1  christos static void
   3325  1.1  christos convert_efi_target (char *efi)
   3326  1.1  christos {
   3327  1.1  christos   efi[0] = 'p';
   3328  1.1  christos   efi[1] = 'e';
   3329  1.1  christos   efi[2] = 'i';
   3330  1.1  christos 
   3331  1.1  christos   if (strcmp (efi + 4, "ia32") == 0)
   3332  1.1  christos     {
   3333  1.1  christos       /* Change ia32 to i386.  */
   3334  1.1  christos       efi[5]= '3';
   3335  1.1  christos       efi[6]= '8';
   3336  1.1  christos       efi[7]= '6';
   3337  1.1  christos     }
   3338  1.1  christos   else if (strcmp (efi + 4, "x86_64") == 0)
   3339  1.1  christos     {
   3340  1.1  christos       /* Change x86_64 to x86-64.  */
   3341  1.1  christos       efi[7] = '-';
   3342  1.1  christos     }
   3343  1.1  christos }
   3344  1.1  christos 
   3345  1.1  christos static int
   3346  1.1  christos copy_main (int argc, char *argv[])
   3347  1.1  christos {
   3348  1.1  christos   char *input_filename = NULL;
   3349  1.1  christos   char *output_filename = NULL;
   3350  1.1  christos   char *tmpname;
   3351  1.1  christos   char *input_target = NULL;
   3352  1.1  christos   char *output_target = NULL;
   3353  1.1  christos   bfd_boolean show_version = FALSE;
   3354  1.1  christos   bfd_boolean change_warn = TRUE;
   3355  1.1  christos   bfd_boolean formats_info = FALSE;
   3356  1.1  christos   int c;
   3357  1.1  christos   struct section_list *p;
   3358  1.1  christos   struct stat statbuf;
   3359  1.1  christos   const bfd_arch_info_type *input_arch = NULL;
   3360  1.1  christos 
   3361  1.1  christos   while ((c = getopt_long (argc, argv, "b:B:i:I:j:K:N:s:O:d:F:L:G:R:SpgxXHhVvW:w",
   3362  1.1  christos 			   copy_options, (int *) 0)) != EOF)
   3363  1.1  christos     {
   3364  1.1  christos       switch (c)
   3365  1.1  christos 	{
   3366  1.1  christos 	case 'b':
   3367  1.1  christos 	  copy_byte = atoi (optarg);
   3368  1.1  christos 	  if (copy_byte < 0)
   3369  1.1  christos 	    fatal (_("byte number must be non-negative"));
   3370  1.1  christos 	  break;
   3371  1.1  christos 
   3372  1.1  christos 	case 'B':
   3373  1.1  christos 	  input_arch = bfd_scan_arch (optarg);
   3374  1.1  christos 	  if (input_arch == NULL)
   3375  1.1  christos 	    fatal (_("architecture %s unknown"), optarg);
   3376  1.1  christos 	  break;
   3377  1.1  christos 
   3378  1.1  christos 	case 'i':
   3379  1.1  christos 	  if (optarg)
   3380  1.1  christos 	    {
   3381  1.1  christos 	      interleave = atoi (optarg);
   3382  1.1  christos 	      if (interleave < 1)
   3383  1.1  christos 		fatal (_("interleave must be positive"));
   3384  1.1  christos 	    }
   3385  1.1  christos 	  else
   3386  1.1  christos 	    interleave = 4;
   3387  1.1  christos 	  break;
   3388  1.1  christos 
   3389  1.1  christos 	case OPTION_INTERLEAVE_WIDTH:
   3390  1.1  christos 	  copy_width = atoi (optarg);
   3391  1.1  christos 	  if (copy_width < 1)
   3392  1.1  christos 	    fatal(_("interleave width must be positive"));
   3393  1.1  christos 	  break;
   3394  1.1  christos 
   3395  1.1  christos 	case 'I':
   3396  1.1  christos 	case 's':		/* "source" - 'I' is preferred */
   3397  1.1  christos 	  input_target = optarg;
   3398  1.1  christos 	  break;
   3399  1.1  christos 
   3400  1.1  christos 	case 'O':
   3401  1.1  christos 	case 'd':		/* "destination" - 'O' is preferred */
   3402  1.1  christos 	  output_target = optarg;
   3403  1.1  christos 	  break;
   3404  1.1  christos 
   3405  1.1  christos 	case 'F':
   3406  1.1  christos 	  input_target = output_target = optarg;
   3407  1.1  christos 	  break;
   3408  1.1  christos 
   3409  1.1  christos 	case 'j':
   3410  1.1  christos 	  p = find_section_list (optarg, TRUE);
   3411  1.1  christos 	  if (p->remove)
   3412  1.1  christos 	    fatal (_("%s both copied and removed"), optarg);
   3413  1.1  christos 	  p->copy = TRUE;
   3414  1.1  christos 	  sections_copied = TRUE;
   3415  1.1  christos 	  break;
   3416  1.1  christos 
   3417  1.1  christos 	case 'R':
   3418  1.1  christos 	  p = find_section_list (optarg, TRUE);
   3419  1.1  christos 	  if (p->copy)
   3420  1.1  christos 	    fatal (_("%s both copied and removed"), optarg);
   3421  1.1  christos 	  p->remove = TRUE;
   3422  1.1  christos 	  sections_removed = TRUE;
   3423  1.1  christos 	  break;
   3424  1.1  christos 
   3425  1.1  christos 	case 'S':
   3426  1.1  christos 	  strip_symbols = STRIP_ALL;
   3427  1.1  christos 	  break;
   3428  1.1  christos 
   3429  1.1  christos 	case 'g':
   3430  1.1  christos 	  strip_symbols = STRIP_DEBUG;
   3431  1.1  christos 	  break;
   3432  1.1  christos 
   3433  1.1  christos 	case OPTION_STRIP_DWO:
   3434  1.1  christos 	  strip_symbols = STRIP_DWO;
   3435  1.1  christos 	  break;
   3436  1.1  christos 
   3437  1.1  christos 	case OPTION_STRIP_UNNEEDED:
   3438  1.1  christos 	  strip_symbols = STRIP_UNNEEDED;
   3439  1.1  christos 	  break;
   3440  1.1  christos 
   3441  1.1  christos 	case OPTION_ONLY_KEEP_DEBUG:
   3442  1.1  christos 	  strip_symbols = STRIP_NONDEBUG;
   3443  1.1  christos 	  break;
   3444  1.1  christos 
   3445  1.1  christos 	case OPTION_KEEP_FILE_SYMBOLS:
   3446  1.1  christos 	  keep_file_symbols = 1;
   3447  1.1  christos 	  break;
   3448  1.1  christos 
   3449  1.1  christos 	case OPTION_ADD_GNU_DEBUGLINK:
   3450  1.1  christos 	  gnu_debuglink_filename = optarg;
   3451  1.1  christos 	  break;
   3452  1.1  christos 
   3453  1.1  christos 	case 'K':
   3454  1.1  christos 	  add_specific_symbol (optarg, keep_specific_htab);
   3455  1.1  christos 	  break;
   3456  1.1  christos 
   3457  1.1  christos 	case 'N':
   3458  1.1  christos 	  add_specific_symbol (optarg, strip_specific_htab);
   3459  1.1  christos 	  break;
   3460  1.1  christos 
   3461  1.1  christos 	case OPTION_STRIP_UNNEEDED_SYMBOL:
   3462  1.1  christos 	  add_specific_symbol (optarg, strip_unneeded_htab);
   3463  1.1  christos 	  break;
   3464  1.1  christos 
   3465  1.1  christos 	case 'L':
   3466  1.1  christos 	  add_specific_symbol (optarg, localize_specific_htab);
   3467  1.1  christos 	  break;
   3468  1.1  christos 
   3469  1.1  christos 	case OPTION_GLOBALIZE_SYMBOL:
   3470  1.1  christos 	  add_specific_symbol (optarg, globalize_specific_htab);
   3471  1.1  christos 	  break;
   3472  1.1  christos 
   3473  1.1  christos 	case 'G':
   3474  1.1  christos 	  add_specific_symbol (optarg, keepglobal_specific_htab);
   3475  1.1  christos 	  break;
   3476  1.1  christos 
   3477  1.1  christos 	case 'W':
   3478  1.1  christos 	  add_specific_symbol (optarg, weaken_specific_htab);
   3479  1.1  christos 	  break;
   3480  1.1  christos 
   3481  1.1  christos 	case 'p':
   3482  1.1  christos 	  preserve_dates = TRUE;
   3483  1.1  christos 	  break;
   3484  1.1  christos 
   3485  1.1  christos 	case 'D':
   3486  1.1  christos 	  deterministic = TRUE;
   3487  1.1  christos 	  break;
   3488  1.1  christos 
   3489  1.1  christos 	case 'U':
   3490  1.1  christos 	  deterministic = FALSE;
   3491  1.1  christos 	  break;
   3492  1.1  christos 
   3493  1.1  christos 	case 'w':
   3494  1.1  christos 	  wildcard = TRUE;
   3495  1.1  christos 	  break;
   3496  1.1  christos 
   3497  1.1  christos 	case 'x':
   3498  1.1  christos 	  discard_locals = LOCALS_ALL;
   3499  1.1  christos 	  break;
   3500  1.1  christos 
   3501  1.1  christos 	case 'X':
   3502  1.1  christos 	  discard_locals = LOCALS_START_L;
   3503  1.1  christos 	  break;
   3504  1.1  christos 
   3505  1.1  christos 	case 'v':
   3506  1.1  christos 	  verbose = TRUE;
   3507  1.1  christos 	  break;
   3508  1.1  christos 
   3509  1.1  christos 	case 'V':
   3510  1.1  christos 	  show_version = TRUE;
   3511  1.1  christos 	  break;
   3512  1.1  christos 
   3513  1.1  christos 	case OPTION_FORMATS_INFO:
   3514  1.1  christos 	  formats_info = TRUE;
   3515  1.1  christos 	  break;
   3516  1.1  christos 
   3517  1.1  christos 	case OPTION_WEAKEN:
   3518  1.1  christos 	  weaken = TRUE;
   3519  1.1  christos 	  break;
   3520  1.1  christos 
   3521  1.1  christos 	case OPTION_ADD_SECTION:
   3522  1.1  christos 	  {
   3523  1.1  christos 	    const char *s;
   3524  1.1  christos 	    size_t off, alloc;
   3525  1.1  christos 	    struct section_add *pa;
   3526  1.1  christos 	    FILE *f;
   3527  1.1  christos 
   3528  1.1  christos 	    s = strchr (optarg, '=');
   3529  1.1  christos 
   3530  1.1  christos 	    if (s == NULL)
   3531  1.1  christos 	      fatal (_("bad format for %s"), "--add-section");
   3532  1.1  christos 
   3533  1.1  christos 	    pa = (struct section_add *) xmalloc (sizeof (struct section_add));
   3534  1.1  christos 	    pa->name = xstrndup (optarg, s - optarg);
   3535  1.1  christos 	    pa->filename = s + 1;
   3536  1.1  christos 
   3537  1.1  christos 	    /* We don't use get_file_size so that we can do
   3538  1.1  christos 	         --add-section .note.GNU_stack=/dev/null
   3539  1.1  christos 	       get_file_size doesn't work on /dev/null.  */
   3540  1.1  christos 
   3541  1.1  christos 	    f = fopen (pa->filename, FOPEN_RB);
   3542  1.1  christos 	    if (f == NULL)
   3543  1.1  christos 	      fatal (_("cannot open: %s: %s"),
   3544  1.1  christos 		     pa->filename, strerror (errno));
   3545  1.1  christos 
   3546  1.1  christos 	    off = 0;
   3547  1.1  christos 	    alloc = 4096;
   3548  1.1  christos 	    pa->contents = (bfd_byte *) xmalloc (alloc);
   3549  1.1  christos 	    while (!feof (f))
   3550  1.1  christos 	      {
   3551  1.1  christos 		off_t got;
   3552  1.1  christos 
   3553  1.1  christos 		if (off == alloc)
   3554  1.1  christos 		  {
   3555  1.1  christos 		    alloc <<= 1;
   3556  1.1  christos 		    pa->contents = (bfd_byte *) xrealloc (pa->contents, alloc);
   3557  1.1  christos 		  }
   3558  1.1  christos 
   3559  1.1  christos 		got = fread (pa->contents + off, 1, alloc - off, f);
   3560  1.1  christos 		if (ferror (f))
   3561  1.1  christos 		  fatal (_("%s: fread failed"), pa->filename);
   3562  1.1  christos 
   3563  1.1  christos 		off += got;
   3564  1.1  christos 	      }
   3565  1.1  christos 
   3566  1.1  christos 	    pa->size = off;
   3567  1.1  christos 
   3568  1.1  christos 	    fclose (f);
   3569  1.1  christos 
   3570  1.1  christos 	    pa->next = add_sections;
   3571  1.1  christos 	    add_sections = pa;
   3572  1.1  christos 	  }
   3573  1.1  christos 	  break;
   3574  1.1  christos 
   3575  1.1  christos 	case OPTION_CHANGE_START:
   3576  1.1  christos 	  change_start = parse_vma (optarg, "--change-start");
   3577  1.1  christos 	  break;
   3578  1.1  christos 
   3579  1.1  christos 	case OPTION_CHANGE_SECTION_ADDRESS:
   3580  1.1  christos 	case OPTION_CHANGE_SECTION_LMA:
   3581  1.1  christos 	case OPTION_CHANGE_SECTION_VMA:
   3582  1.1  christos 	  {
   3583  1.1  christos 	    const char *s;
   3584  1.1  christos 	    int len;
   3585  1.1  christos 	    char *name;
   3586  1.1  christos 	    char *option = NULL;
   3587  1.1  christos 	    bfd_vma val;
   3588  1.1  christos 	    enum change_action what = CHANGE_IGNORE;
   3589  1.1  christos 
   3590  1.1  christos 	    switch (c)
   3591  1.1  christos 	      {
   3592  1.1  christos 	      case OPTION_CHANGE_SECTION_ADDRESS:
   3593  1.1  christos 		option = "--change-section-address";
   3594  1.1  christos 		break;
   3595  1.1  christos 	      case OPTION_CHANGE_SECTION_LMA:
   3596  1.1  christos 		option = "--change-section-lma";
   3597  1.1  christos 		break;
   3598  1.1  christos 	      case OPTION_CHANGE_SECTION_VMA:
   3599  1.1  christos 		option = "--change-section-vma";
   3600  1.1  christos 		break;
   3601  1.1  christos 	      }
   3602  1.1  christos 
   3603  1.1  christos 	    s = strchr (optarg, '=');
   3604  1.1  christos 	    if (s == NULL)
   3605  1.1  christos 	      {
   3606  1.1  christos 		s = strchr (optarg, '+');
   3607  1.1  christos 		if (s == NULL)
   3608  1.1  christos 		  {
   3609  1.1  christos 		    s = strchr (optarg, '-');
   3610  1.1  christos 		    if (s == NULL)
   3611  1.1  christos 		      fatal (_("bad format for %s"), option);
   3612  1.1  christos 		  }
   3613  1.1  christos 	      }
   3614  1.1  christos 
   3615  1.1  christos 	    len = s - optarg;
   3616  1.1  christos 	    name = (char *) xmalloc (len + 1);
   3617  1.1  christos 	    strncpy (name, optarg, len);
   3618  1.1  christos 	    name[len] = '\0';
   3619  1.1  christos 
   3620  1.1  christos 	    p = find_section_list (name, TRUE);
   3621  1.1  christos 
   3622  1.1  christos 	    val = parse_vma (s + 1, option);
   3623  1.1  christos 
   3624  1.1  christos 	    switch (*s)
   3625  1.1  christos 	      {
   3626  1.1  christos 	      case '=': what = CHANGE_SET; break;
   3627  1.1  christos 	      case '-': val  = - val; /* Drop through.  */
   3628  1.1  christos 	      case '+': what = CHANGE_MODIFY; break;
   3629  1.1  christos 	      }
   3630  1.1  christos 
   3631  1.1  christos 	    switch (c)
   3632  1.1  christos 	      {
   3633  1.1  christos 	      case OPTION_CHANGE_SECTION_ADDRESS:
   3634  1.1  christos 		p->change_vma = what;
   3635  1.1  christos 		p->vma_val    = val;
   3636  1.1  christos 		/* Drop through.  */
   3637  1.1  christos 
   3638  1.1  christos 	      case OPTION_CHANGE_SECTION_LMA:
   3639  1.1  christos 		p->change_lma = what;
   3640  1.1  christos 		p->lma_val    = val;
   3641  1.1  christos 		break;
   3642  1.1  christos 
   3643  1.1  christos 	      case OPTION_CHANGE_SECTION_VMA:
   3644  1.1  christos 		p->change_vma = what;
   3645  1.1  christos 		p->vma_val    = val;
   3646  1.1  christos 		break;
   3647  1.1  christos 	      }
   3648  1.1  christos 	  }
   3649  1.1  christos 	  break;
   3650  1.1  christos 
   3651  1.1  christos 	case OPTION_CHANGE_ADDRESSES:
   3652  1.1  christos 	  change_section_address = parse_vma (optarg, "--change-addresses");
   3653  1.1  christos 	  change_start = change_section_address;
   3654  1.1  christos 	  break;
   3655  1.1  christos 
   3656  1.1  christos 	case OPTION_CHANGE_WARNINGS:
   3657  1.1  christos 	  change_warn = TRUE;
   3658  1.1  christos 	  break;
   3659  1.1  christos 
   3660  1.1  christos 	case OPTION_CHANGE_LEADING_CHAR:
   3661  1.1  christos 	  change_leading_char = TRUE;
   3662  1.1  christos 	  break;
   3663  1.1  christos 
   3664  1.1  christos 	case OPTION_COMPRESS_DEBUG_SECTIONS:
   3665  1.1  christos 	  do_debug_sections = compress;
   3666  1.1  christos 	  break;
   3667  1.1  christos 
   3668  1.1  christos 	case OPTION_DEBUGGING:
   3669  1.1  christos 	  convert_debugging = TRUE;
   3670  1.1  christos 	  break;
   3671  1.1  christos 
   3672  1.1  christos 	case OPTION_DECOMPRESS_DEBUG_SECTIONS:
   3673  1.1  christos 	  do_debug_sections = decompress;
   3674  1.1  christos 	  break;
   3675  1.1  christos 
   3676  1.1  christos 	case OPTION_GAP_FILL:
   3677  1.1  christos 	  {
   3678  1.1  christos 	    bfd_vma gap_fill_vma;
   3679  1.1  christos 
   3680  1.1  christos 	    gap_fill_vma = parse_vma (optarg, "--gap-fill");
   3681  1.1  christos 	    gap_fill = (bfd_byte) gap_fill_vma;
   3682  1.1  christos 	    if ((bfd_vma) gap_fill != gap_fill_vma)
   3683  1.1  christos 	      {
   3684  1.1  christos 		char buff[20];
   3685  1.1  christos 
   3686  1.1  christos 		sprintf_vma (buff, gap_fill_vma);
   3687  1.1  christos 
   3688  1.1  christos 		non_fatal (_("Warning: truncating gap-fill from 0x%s to 0x%x"),
   3689  1.1  christos 			   buff, gap_fill);
   3690  1.1  christos 	      }
   3691  1.1  christos 	    gap_fill_set = TRUE;
   3692  1.1  christos 	  }
   3693  1.1  christos 	  break;
   3694  1.1  christos 
   3695  1.1  christos 	case OPTION_NO_CHANGE_WARNINGS:
   3696  1.1  christos 	  change_warn = FALSE;
   3697  1.1  christos 	  break;
   3698  1.1  christos 
   3699  1.1  christos 	case OPTION_PAD_TO:
   3700  1.1  christos 	  pad_to = parse_vma (optarg, "--pad-to");
   3701  1.1  christos 	  pad_to_set = TRUE;
   3702  1.1  christos 	  break;
   3703  1.1  christos 
   3704  1.1  christos 	case OPTION_REMOVE_LEADING_CHAR:
   3705  1.1  christos 	  remove_leading_char = TRUE;
   3706  1.1  christos 	  break;
   3707  1.1  christos 
   3708  1.1  christos 	case OPTION_REDEFINE_SYM:
   3709  1.1  christos 	  {
   3710  1.1  christos 	    /* Push this redefinition onto redefine_symbol_list.  */
   3711  1.1  christos 
   3712  1.1  christos 	    int len;
   3713  1.1  christos 	    const char *s;
   3714  1.1  christos 	    const char *nextarg;
   3715  1.1  christos 	    char *source, *target;
   3716  1.1  christos 
   3717  1.1  christos 	    s = strchr (optarg, '=');
   3718  1.1  christos 	    if (s == NULL)
   3719  1.1  christos 	      fatal (_("bad format for %s"), "--redefine-sym");
   3720  1.1  christos 
   3721  1.1  christos 	    len = s - optarg;
   3722  1.1  christos 	    source = (char *) xmalloc (len + 1);
   3723  1.1  christos 	    strncpy (source, optarg, len);
   3724  1.1  christos 	    source[len] = '\0';
   3725  1.1  christos 
   3726  1.1  christos 	    nextarg = s + 1;
   3727  1.1  christos 	    len = strlen (nextarg);
   3728  1.1  christos 	    target = (char *) xmalloc (len + 1);
   3729  1.1  christos 	    strcpy (target, nextarg);
   3730  1.1  christos 
   3731  1.1  christos 	    redefine_list_append ("--redefine-sym", source, target);
   3732  1.1  christos 
   3733  1.1  christos 	    free (source);
   3734  1.1  christos 	    free (target);
   3735  1.1  christos 	  }
   3736  1.1  christos 	  break;
   3737  1.1  christos 
   3738  1.1  christos 	case OPTION_REDEFINE_SYMS:
   3739  1.1  christos 	  add_redefine_syms_file (optarg);
   3740  1.1  christos 	  break;
   3741  1.1  christos 
   3742  1.1  christos 	case OPTION_SET_SECTION_FLAGS:
   3743  1.1  christos 	  {
   3744  1.1  christos 	    const char *s;
   3745  1.1  christos 	    int len;
   3746  1.1  christos 	    char *name;
   3747  1.1  christos 
   3748  1.1  christos 	    s = strchr (optarg, '=');
   3749  1.1  christos 	    if (s == NULL)
   3750  1.1  christos 	      fatal (_("bad format for %s"), "--set-section-flags");
   3751  1.1  christos 
   3752  1.1  christos 	    len = s - optarg;
   3753  1.1  christos 	    name = (char *) xmalloc (len + 1);
   3754  1.1  christos 	    strncpy (name, optarg, len);
   3755  1.1  christos 	    name[len] = '\0';
   3756  1.1  christos 
   3757  1.1  christos 	    p = find_section_list (name, TRUE);
   3758  1.1  christos 
   3759  1.1  christos 	    p->set_flags = TRUE;
   3760  1.1  christos 	    p->flags = parse_flags (s + 1);
   3761  1.1  christos 	  }
   3762  1.1  christos 	  break;
   3763  1.1  christos 
   3764  1.1  christos 	case OPTION_RENAME_SECTION:
   3765  1.1  christos 	  {
   3766  1.1  christos 	    flagword flags;
   3767  1.1  christos 	    const char *eq, *fl;
   3768  1.1  christos 	    char *old_name;
   3769  1.1  christos 	    char *new_name;
   3770  1.1  christos 	    unsigned int len;
   3771  1.1  christos 
   3772  1.1  christos 	    eq = strchr (optarg, '=');
   3773  1.1  christos 	    if (eq == NULL)
   3774  1.1  christos 	      fatal (_("bad format for %s"), "--rename-section");
   3775  1.1  christos 
   3776  1.1  christos 	    len = eq - optarg;
   3777  1.1  christos 	    if (len == 0)
   3778  1.1  christos 	      fatal (_("bad format for %s"), "--rename-section");
   3779  1.1  christos 
   3780  1.1  christos 	    old_name = (char *) xmalloc (len + 1);
   3781  1.1  christos 	    strncpy (old_name, optarg, len);
   3782  1.1  christos 	    old_name[len] = 0;
   3783  1.1  christos 
   3784  1.1  christos 	    eq++;
   3785  1.1  christos 	    fl = strchr (eq, ',');
   3786  1.1  christos 	    if (fl)
   3787  1.1  christos 	      {
   3788  1.1  christos 		flags = parse_flags (fl + 1);
   3789  1.1  christos 		len = fl - eq;
   3790  1.1  christos 	      }
   3791  1.1  christos 	    else
   3792  1.1  christos 	      {
   3793  1.1  christos 		flags = -1;
   3794  1.1  christos 		len = strlen (eq);
   3795  1.1  christos 	      }
   3796  1.1  christos 
   3797  1.1  christos 	    if (len == 0)
   3798  1.1  christos 	      fatal (_("bad format for %s"), "--rename-section");
   3799  1.1  christos 
   3800  1.1  christos 	    new_name = (char *) xmalloc (len + 1);
   3801  1.1  christos 	    strncpy (new_name, eq, len);
   3802  1.1  christos 	    new_name[len] = 0;
   3803  1.1  christos 
   3804  1.1  christos 	    add_section_rename (old_name, new_name, flags);
   3805  1.1  christos 	  }
   3806  1.1  christos 	  break;
   3807  1.1  christos 
   3808  1.1  christos 	case OPTION_SET_START:
   3809  1.1  christos 	  set_start = parse_vma (optarg, "--set-start");
   3810  1.1  christos 	  set_start_set = TRUE;
   3811  1.1  christos 	  break;
   3812  1.1  christos 
   3813  1.1  christos 	case OPTION_SREC_LEN:
   3814  1.1  christos 	  Chunk = parse_vma (optarg, "--srec-len");
   3815  1.1  christos 	  break;
   3816  1.1  christos 
   3817  1.1  christos 	case OPTION_SREC_FORCES3:
   3818  1.1  christos 	  S3Forced = TRUE;
   3819  1.1  christos 	  break;
   3820  1.1  christos 
   3821  1.1  christos 	case OPTION_STRIP_SYMBOLS:
   3822  1.1  christos 	  add_specific_symbols (optarg, strip_specific_htab);
   3823  1.1  christos 	  break;
   3824  1.1  christos 
   3825  1.1  christos 	case OPTION_STRIP_UNNEEDED_SYMBOLS:
   3826  1.1  christos 	  add_specific_symbols (optarg, strip_unneeded_htab);
   3827  1.1  christos 	  break;
   3828  1.1  christos 
   3829  1.1  christos 	case OPTION_KEEP_SYMBOLS:
   3830  1.1  christos 	  add_specific_symbols (optarg, keep_specific_htab);
   3831  1.1  christos 	  break;
   3832  1.1  christos 
   3833  1.1  christos 	case OPTION_LOCALIZE_HIDDEN:
   3834  1.1  christos 	  localize_hidden = TRUE;
   3835  1.1  christos 	  break;
   3836  1.1  christos 
   3837  1.1  christos 	case OPTION_LOCALIZE_SYMBOLS:
   3838  1.1  christos 	  add_specific_symbols (optarg, localize_specific_htab);
   3839  1.1  christos 	  break;
   3840  1.1  christos 
   3841  1.1  christos 	case OPTION_LONG_SECTION_NAMES:
   3842  1.1  christos 	  if (!strcmp ("enable", optarg))
   3843  1.1  christos 	    long_section_names = ENABLE;
   3844  1.1  christos 	  else if (!strcmp ("disable", optarg))
   3845  1.1  christos 	    long_section_names = DISABLE;
   3846  1.1  christos 	  else if (!strcmp ("keep", optarg))
   3847  1.1  christos 	    long_section_names = KEEP;
   3848  1.1  christos 	  else
   3849  1.1  christos 	    fatal (_("unknown long section names option '%s'"), optarg);
   3850  1.1  christos 	  break;
   3851  1.1  christos 
   3852  1.1  christos 	case OPTION_GLOBALIZE_SYMBOLS:
   3853  1.1  christos 	  add_specific_symbols (optarg, globalize_specific_htab);
   3854  1.1  christos 	  break;
   3855  1.1  christos 
   3856  1.1  christos 	case OPTION_KEEPGLOBAL_SYMBOLS:
   3857  1.1  christos 	  add_specific_symbols (optarg, keepglobal_specific_htab);
   3858  1.1  christos 	  break;
   3859  1.1  christos 
   3860  1.1  christos 	case OPTION_WEAKEN_SYMBOLS:
   3861  1.1  christos 	  add_specific_symbols (optarg, weaken_specific_htab);
   3862  1.1  christos 	  break;
   3863  1.1  christos 
   3864  1.1  christos 	case OPTION_ALT_MACH_CODE:
   3865  1.1  christos 	  use_alt_mach_code = strtoul (optarg, NULL, 0);
   3866  1.1  christos 	  if (use_alt_mach_code == 0)
   3867  1.1  christos 	    fatal (_("unable to parse alternative machine code"));
   3868  1.1  christos 	  break;
   3869  1.1  christos 
   3870  1.1  christos 	case OPTION_PREFIX_SYMBOLS:
   3871  1.1  christos 	  prefix_symbols_string = optarg;
   3872  1.1  christos 	  break;
   3873  1.1  christos 
   3874  1.1  christos 	case OPTION_PREFIX_SECTIONS:
   3875  1.1  christos 	  prefix_sections_string = optarg;
   3876  1.1  christos 	  break;
   3877  1.1  christos 
   3878  1.1  christos 	case OPTION_PREFIX_ALLOC_SECTIONS:
   3879  1.1  christos 	  prefix_alloc_sections_string = optarg;
   3880  1.1  christos 	  break;
   3881  1.1  christos 
   3882  1.1  christos 	case OPTION_READONLY_TEXT:
   3883  1.1  christos 	  bfd_flags_to_set |= WP_TEXT;
   3884  1.1  christos 	  bfd_flags_to_clear &= ~WP_TEXT;
   3885  1.1  christos 	  break;
   3886  1.1  christos 
   3887  1.1  christos 	case OPTION_WRITABLE_TEXT:
   3888  1.1  christos 	  bfd_flags_to_clear |= WP_TEXT;
   3889  1.1  christos 	  bfd_flags_to_set &= ~WP_TEXT;
   3890  1.1  christos 	  break;
   3891  1.1  christos 
   3892  1.1  christos 	case OPTION_PURE:
   3893  1.1  christos 	  bfd_flags_to_set |= D_PAGED;
   3894  1.1  christos 	  bfd_flags_to_clear &= ~D_PAGED;
   3895  1.1  christos 	  break;
   3896  1.1  christos 
   3897  1.1  christos 	case OPTION_IMPURE:
   3898  1.1  christos 	  bfd_flags_to_clear |= D_PAGED;
   3899  1.1  christos 	  bfd_flags_to_set &= ~D_PAGED;
   3900  1.1  christos 	  break;
   3901  1.1  christos 
   3902  1.1  christos 	case OPTION_EXTRACT_DWO:
   3903  1.1  christos 	  strip_symbols = STRIP_NONDWO;
   3904  1.1  christos 	  break;
   3905  1.1  christos 
   3906  1.1  christos 	case OPTION_EXTRACT_SYMBOL:
   3907  1.1  christos 	  extract_symbol = TRUE;
   3908  1.1  christos 	  break;
   3909  1.1  christos 
   3910  1.1  christos 	case OPTION_REVERSE_BYTES:
   3911  1.1  christos           {
   3912  1.1  christos             int prev = reverse_bytes;
   3913  1.1  christos 
   3914  1.1  christos             reverse_bytes = atoi (optarg);
   3915  1.1  christos             if ((reverse_bytes <= 0) || ((reverse_bytes % 2) != 0))
   3916  1.1  christos               fatal (_("number of bytes to reverse must be positive and even"));
   3917  1.1  christos 
   3918  1.1  christos             if (prev && prev != reverse_bytes)
   3919  1.1  christos               non_fatal (_("Warning: ignoring previous --reverse-bytes value of %d"),
   3920  1.1  christos                          prev);
   3921  1.1  christos             break;
   3922  1.1  christos           }
   3923  1.1  christos 
   3924  1.1  christos 	case OPTION_FILE_ALIGNMENT:
   3925  1.1  christos 	  pe_file_alignment = parse_vma (optarg, "--file-alignment");
   3926  1.1  christos 	  break;
   3927  1.1  christos 
   3928  1.1  christos 	case OPTION_HEAP:
   3929  1.1  christos 	    {
   3930  1.1  christos 	      char *end;
   3931  1.1  christos 	      pe_heap_reserve = strtoul (optarg, &end, 0);
   3932  1.1  christos 	      if (end == optarg
   3933  1.1  christos 		  || (*end != '.' && *end != '\0'))
   3934  1.1  christos 		non_fatal (_("%s: invalid reserve value for --heap"),
   3935  1.1  christos 			   optarg);
   3936  1.1  christos 	      else if (*end != '\0')
   3937  1.1  christos 		{
   3938  1.1  christos 		  pe_heap_commit = strtoul (end + 1, &end, 0);
   3939  1.1  christos 		  if (*end != '\0')
   3940  1.1  christos 		    non_fatal (_("%s: invalid commit value for --heap"),
   3941  1.1  christos 			       optarg);
   3942  1.1  christos 		}
   3943  1.1  christos 	    }
   3944  1.1  christos 	  break;
   3945  1.1  christos 
   3946  1.1  christos 	case OPTION_IMAGE_BASE:
   3947  1.1  christos 	  pe_image_base = parse_vma (optarg, "--image-base");
   3948  1.1  christos 	  break;
   3949  1.1  christos 
   3950  1.1  christos 	case OPTION_SECTION_ALIGNMENT:
   3951  1.1  christos 	  pe_section_alignment = parse_vma (optarg,
   3952  1.1  christos 					    "--section-alignment");
   3953  1.1  christos 	  break;
   3954  1.1  christos 
   3955  1.1  christos 	case OPTION_SUBSYSTEM:
   3956  1.1  christos 	  set_pe_subsystem (optarg);
   3957  1.1  christos 	  break;
   3958  1.1  christos 
   3959  1.1  christos 	case OPTION_STACK:
   3960  1.1  christos 	    {
   3961  1.1  christos 	      char *end;
   3962  1.1  christos 	      pe_stack_reserve = strtoul (optarg, &end, 0);
   3963  1.1  christos 	      if (end == optarg
   3964  1.1  christos 		  || (*end != '.' && *end != '\0'))
   3965  1.1  christos 		non_fatal (_("%s: invalid reserve value for --stack"),
   3966  1.1  christos 			   optarg);
   3967  1.1  christos 	      else if (*end != '\0')
   3968  1.1  christos 		{
   3969  1.1  christos 		  pe_stack_commit = strtoul (end + 1, &end, 0);
   3970  1.1  christos 		  if (*end != '\0')
   3971  1.1  christos 		    non_fatal (_("%s: invalid commit value for --stack"),
   3972  1.1  christos 			       optarg);
   3973  1.1  christos 		}
   3974  1.1  christos 	    }
   3975  1.1  christos 	  break;
   3976  1.1  christos 
   3977  1.1  christos 	case 0:
   3978  1.1  christos 	  /* We've been given a long option.  */
   3979  1.1  christos 	  break;
   3980  1.1  christos 
   3981  1.1  christos 	case 'H':
   3982  1.1  christos 	case 'h':
   3983  1.1  christos 	  copy_usage (stdout, 0);
   3984  1.1  christos 
   3985  1.1  christos 	default:
   3986  1.1  christos 	  copy_usage (stderr, 1);
   3987  1.1  christos 	}
   3988  1.1  christos     }
   3989  1.1  christos 
   3990  1.1  christos   if (formats_info)
   3991  1.1  christos     {
   3992  1.1  christos       display_info ();
   3993  1.1  christos       return 0;
   3994  1.1  christos     }
   3995  1.1  christos 
   3996  1.1  christos   if (show_version)
   3997  1.1  christos     print_version ("objcopy");
   3998  1.1  christos 
   3999  1.1  christos   if (interleave && copy_byte == -1)
   4000  1.1  christos     fatal (_("interleave start byte must be set with --byte"));
   4001  1.1  christos 
   4002  1.1  christos   if (copy_byte >= interleave)
   4003  1.1  christos     fatal (_("byte number must be less than interleave"));
   4004  1.1  christos 
   4005  1.1  christos   if (copy_width > interleave - copy_byte)
   4006  1.1  christos     fatal (_("interleave width must be less than or equal to interleave - byte`"));
   4007  1.1  christos 
   4008  1.1  christos   if (optind == argc || optind + 2 < argc)
   4009  1.1  christos     copy_usage (stderr, 1);
   4010  1.1  christos 
   4011  1.1  christos   input_filename = argv[optind];
   4012  1.1  christos   if (optind + 1 < argc)
   4013  1.1  christos     output_filename = argv[optind + 1];
   4014  1.1  christos 
   4015  1.1  christos   default_deterministic ();
   4016  1.1  christos 
   4017  1.1  christos   /* Default is to strip no symbols.  */
   4018  1.1  christos   if (strip_symbols == STRIP_UNDEF && discard_locals == LOCALS_UNDEF)
   4019  1.1  christos     strip_symbols = STRIP_NONE;
   4020  1.1  christos 
   4021  1.1  christos   if (output_target == NULL)
   4022  1.1  christos     output_target = input_target;
   4023  1.1  christos 
   4024  1.1  christos   /* Convert input EFI target to PEI target.  */
   4025  1.1  christos   if (input_target != NULL
   4026  1.1  christos       && strncmp (input_target, "efi-", 4) == 0)
   4027  1.1  christos     {
   4028  1.1  christos       char *efi;
   4029  1.1  christos 
   4030  1.1  christos       efi = xstrdup (output_target + 4);
   4031  1.1  christos       if (strncmp (efi, "bsdrv-", 6) == 0
   4032  1.1  christos 	  || strncmp (efi, "rtdrv-", 6) == 0)
   4033  1.1  christos 	efi += 2;
   4034  1.1  christos       else if (strncmp (efi, "app-", 4) != 0)
   4035  1.1  christos 	fatal (_("unknown input EFI target: %s"), input_target);
   4036  1.1  christos 
   4037  1.1  christos       input_target = efi;
   4038  1.1  christos       convert_efi_target (efi);
   4039  1.1  christos     }
   4040  1.1  christos 
   4041  1.1  christos   /* Convert output EFI target to PEI target.  */
   4042  1.1  christos   if (output_target != NULL
   4043  1.1  christos       && strncmp (output_target, "efi-", 4) == 0)
   4044  1.1  christos     {
   4045  1.1  christos       char *efi;
   4046  1.1  christos 
   4047  1.1  christos       efi = xstrdup (output_target + 4);
   4048  1.1  christos       if (strncmp (efi, "app-", 4) == 0)
   4049  1.1  christos 	{
   4050  1.1  christos 	  if (pe_subsystem == -1)
   4051  1.1  christos 	    pe_subsystem = IMAGE_SUBSYSTEM_EFI_APPLICATION;
   4052  1.1  christos 	}
   4053  1.1  christos       else if (strncmp (efi, "bsdrv-", 6) == 0)
   4054  1.1  christos 	{
   4055  1.1  christos 	  if (pe_subsystem == -1)
   4056  1.1  christos 	    pe_subsystem = IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER;
   4057  1.1  christos 	  efi += 2;
   4058  1.1  christos 	}
   4059  1.1  christos       else if (strncmp (efi, "rtdrv-", 6) == 0)
   4060  1.1  christos 	{
   4061  1.1  christos 	  if (pe_subsystem == -1)
   4062  1.1  christos 	    pe_subsystem = IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER;
   4063  1.1  christos 	  efi += 2;
   4064  1.1  christos 	}
   4065  1.1  christos       else
   4066  1.1  christos 	fatal (_("unknown output EFI target: %s"), output_target);
   4067  1.1  christos 
   4068  1.1  christos       if (pe_file_alignment == (bfd_vma) -1)
   4069  1.1  christos 	pe_file_alignment = PE_DEF_FILE_ALIGNMENT;
   4070  1.1  christos       if (pe_section_alignment == (bfd_vma) -1)
   4071  1.1  christos 	pe_section_alignment = PE_DEF_SECTION_ALIGNMENT;
   4072  1.1  christos 
   4073  1.1  christos       output_target = efi;
   4074  1.1  christos       convert_efi_target (efi);
   4075  1.1  christos     }
   4076  1.1  christos 
   4077  1.1  christos   if (preserve_dates)
   4078  1.1  christos     if (stat (input_filename, & statbuf) < 0)
   4079  1.1  christos       fatal (_("warning: could not locate '%s'.  System error message: %s"),
   4080  1.1  christos 	     input_filename, strerror (errno));
   4081  1.1  christos 
   4082  1.1  christos   /* If there is no destination file, or the source and destination files
   4083  1.1  christos      are the same, then create a temp and rename the result into the input.  */
   4084  1.1  christos   if (output_filename == NULL
   4085  1.1  christos       || filename_cmp (input_filename, output_filename) == 0)
   4086  1.1  christos     tmpname = make_tempname (input_filename);
   4087  1.1  christos   else
   4088  1.1  christos     tmpname = output_filename;
   4089  1.1  christos 
   4090  1.1  christos   if (tmpname == NULL)
   4091  1.1  christos     fatal (_("warning: could not create temporary file whilst copying '%s', (error: %s)"),
   4092  1.1  christos 	   input_filename, strerror (errno));
   4093  1.1  christos 
   4094  1.1  christos   copy_file (input_filename, tmpname, input_target, output_target, input_arch);
   4095  1.1  christos   if (status == 0)
   4096  1.1  christos     {
   4097  1.1  christos       if (preserve_dates)
   4098  1.1  christos 	set_times (tmpname, &statbuf);
   4099  1.1  christos       if (tmpname != output_filename)
   4100  1.1  christos 	status = (smart_rename (tmpname, input_filename,
   4101  1.1  christos 				preserve_dates) != 0);
   4102  1.1  christos     }
   4103  1.1  christos   else
   4104  1.1  christos     unlink_if_ordinary (tmpname);
   4105  1.1  christos 
   4106  1.1  christos   if (change_warn)
   4107  1.1  christos     {
   4108  1.1  christos       for (p = change_sections; p != NULL; p = p->next)
   4109  1.1  christos 	{
   4110  1.1  christos 	  if (! p->used)
   4111  1.1  christos 	    {
   4112  1.1  christos 	      if (p->change_vma != CHANGE_IGNORE)
   4113  1.1  christos 		{
   4114  1.1  christos 		  char buff [20];
   4115  1.1  christos 
   4116  1.1  christos 		  sprintf_vma (buff, p->vma_val);
   4117  1.1  christos 
   4118  1.1  christos 		  /* xgettext:c-format */
   4119  1.1  christos 		  non_fatal (_("%s %s%c0x%s never used"),
   4120  1.1  christos 			     "--change-section-vma",
   4121  1.1  christos 			     p->name,
   4122  1.1  christos 			     p->change_vma == CHANGE_SET ? '=' : '+',
   4123  1.1  christos 			     buff);
   4124  1.1  christos 		}
   4125  1.1  christos 
   4126  1.1  christos 	      if (p->change_lma != CHANGE_IGNORE)
   4127  1.1  christos 		{
   4128  1.1  christos 		  char buff [20];
   4129  1.1  christos 
   4130  1.1  christos 		  sprintf_vma (buff, p->lma_val);
   4131  1.1  christos 
   4132  1.1  christos 		  /* xgettext:c-format */
   4133  1.1  christos 		  non_fatal (_("%s %s%c0x%s never used"),
   4134  1.1  christos 			     "--change-section-lma",
   4135  1.1  christos 			     p->name,
   4136  1.1  christos 			     p->change_lma == CHANGE_SET ? '=' : '+',
   4137  1.1  christos 			     buff);
   4138  1.1  christos 		}
   4139  1.1  christos 	    }
   4140  1.1  christos 	}
   4141  1.1  christos     }
   4142  1.1  christos 
   4143  1.1  christos   return 0;
   4144  1.1  christos }
   4145  1.1  christos 
   4146  1.1  christos int
   4147  1.1  christos main (int argc, char *argv[])
   4148  1.1  christos {
   4149  1.1  christos #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
   4150  1.1  christos   setlocale (LC_MESSAGES, "");
   4151  1.1  christos #endif
   4152  1.1  christos #if defined (HAVE_SETLOCALE)
   4153  1.1  christos   setlocale (LC_CTYPE, "");
   4154  1.1  christos #endif
   4155  1.1  christos   bindtextdomain (PACKAGE, LOCALEDIR);
   4156  1.1  christos   textdomain (PACKAGE);
   4157  1.1  christos 
   4158  1.1  christos   program_name = argv[0];
   4159  1.1  christos   xmalloc_set_program_name (program_name);
   4160  1.1  christos 
   4161  1.1  christos   START_PROGRESS (program_name, 0);
   4162  1.1  christos 
   4163  1.1  christos   expandargv (&argc, &argv);
   4164  1.1  christos 
   4165  1.1  christos   strip_symbols = STRIP_UNDEF;
   4166  1.1  christos   discard_locals = LOCALS_UNDEF;
   4167  1.1  christos 
   4168  1.1  christos   bfd_init ();
   4169  1.1  christos   set_default_bfd_target ();
   4170  1.1  christos 
   4171  1.1  christos   if (is_strip < 0)
   4172  1.1  christos     {
   4173  1.1  christos       int i = strlen (program_name);
   4174  1.1  christos #ifdef HAVE_DOS_BASED_FILE_SYSTEM
   4175  1.1  christos       /* Drop the .exe suffix, if any.  */
   4176  1.1  christos       if (i > 4 && FILENAME_CMP (program_name + i - 4, ".exe") == 0)
   4177  1.1  christos 	{
   4178  1.1  christos 	  i -= 4;
   4179  1.1  christos 	  program_name[i] = '\0';
   4180  1.1  christos 	}
   4181  1.1  christos #endif
   4182  1.1  christos       is_strip = (i >= 5 && FILENAME_CMP (program_name + i - 5, "strip") == 0);
   4183  1.1  christos     }
   4184  1.1  christos 
   4185  1.1  christos   create_symbol_htabs ();
   4186  1.1  christos 
   4187  1.1  christos   if (is_strip)
   4188  1.1  christos     strip_main (argc, argv);
   4189  1.1  christos   else
   4190  1.1  christos     copy_main (argc, argv);
   4191  1.1  christos 
   4192  1.1  christos   END_PROGRESS (program_name);
   4193  1.1  christos 
   4194                  return status;
   4195                }
   4196