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