bfd_asymbol_* macros
[deliverable/binutils-gdb.git] / binutils / objcopy.c
index 3563792304349d2f4815c4c2f793b248b063a93b..ce4a4afa55c6fb49d9530319c00b4821fa5affc9 100644 (file)
@@ -1,5 +1,5 @@
 /* objcopy.c -- copy object file from input to output, optionally massaging it.
-   Copyright (C) 1991-2018 Free Software Foundation, Inc.
+   Copyright (C) 1991-2019 Free Software Foundation, Inc.
 
    This file is part of GNU Binutils.
 
@@ -143,10 +143,12 @@ struct section_list
 #define SECTION_CONTEXT_ALTER_LMA (1 << 5) /* Increment or decrement the section's LMA address.  */
 #define SECTION_CONTEXT_SET_FLAGS (1 << 6) /* Set the section's flags.  */
 #define SECTION_CONTEXT_REMOVE_RELOCS (1 << 7) /* Remove relocations for this section.  */
+#define SECTION_CONTEXT_SET_ALIGNMENT (1 << 8) /* Set alignment for section.  */
 
   bfd_vma              vma_val;   /* Amount to change by or set to.  */
   bfd_vma              lma_val;   /* Amount to change by or set to.  */
   flagword             flags;     /* What to set the section flags to.  */
+  unsigned int         alignment; /* Alignment of output section.  */
 };
 
 static struct section_list *change_sections;
@@ -253,6 +255,14 @@ static htab_t redefine_specific_reverse_htab = NULL;
 static struct addsym_node *add_sym_list = NULL, **add_sym_tail = &add_sym_list;
 static int add_symbols = 0;
 
+static char *strip_specific_buffer = NULL;
+static char *strip_unneeded_buffer = NULL;
+static char *keep_specific_buffer = NULL;
+static char *localize_specific_buffer = NULL;
+static char *globalize_specific_buffer = NULL;
+static char *keepglobal_specific_buffer = NULL;
+static char *weaken_specific_buffer = NULL;
+
 /* If this is TRUE, we weaken global symbols (set BSF_WEAK).  */
 static bfd_boolean weaken = FALSE;
 
@@ -336,8 +346,9 @@ enum command_line_switch
   OPTION_REMOVE_RELOCS,
   OPTION_RENAME_SECTION,
   OPTION_REVERSE_BYTES,
-  OPTION_SECTION_ALIGNMENT,
+  OPTION_PE_SECTION_ALIGNMENT,
   OPTION_SET_SECTION_FLAGS,
+  OPTION_SET_SECTION_ALIGNMENT,
   OPTION_SET_START,
   OPTION_SREC_FORCES3,
   OPTION_SREC_LEN,
@@ -349,6 +360,7 @@ enum command_line_switch
   OPTION_STRIP_UNNEEDED_SYMBOLS,
   OPTION_SUBSYSTEM,
   OPTION_UPDATE_SECTION,
+  OPTION_VERILOG_DATA_WIDTH,
   OPTION_WEAKEN,
   OPTION_WEAKEN_SYMBOLS,
   OPTION_WRITABLE_TEXT
@@ -467,8 +479,9 @@ static struct option copy_options[] =
   {"remove-relocations", required_argument, 0, OPTION_REMOVE_RELOCS},
   {"rename-section", required_argument, 0, OPTION_RENAME_SECTION},
   {"reverse-bytes", required_argument, 0, OPTION_REVERSE_BYTES},
-  {"section-alignment", required_argument, 0, OPTION_SECTION_ALIGNMENT},
+  {"section-alignment", required_argument, 0, OPTION_PE_SECTION_ALIGNMENT},
   {"set-section-flags", required_argument, 0, OPTION_SET_SECTION_FLAGS},
+  {"set-section-alignment", required_argument, 0, OPTION_SET_SECTION_ALIGNMENT},
   {"set-start", required_argument, 0, OPTION_SET_START},
   {"srec-forceS3", no_argument, 0, OPTION_SREC_FORCES3},
   {"srec-len", required_argument, 0, OPTION_SREC_LEN},
@@ -485,6 +498,7 @@ static struct option copy_options[] =
   {"target", required_argument, 0, 'F'},
   {"update-section", required_argument, 0, OPTION_UPDATE_SECTION},
   {"verbose", no_argument, 0, 'v'},
+  {"verilog-data-width", required_argument, 0, OPTION_VERILOG_DATA_WIDTH},
   {"version", no_argument, 0, 'V'},
   {"weaken", no_argument, 0, OPTION_WEAKEN},
   {"weaken-symbol", required_argument, 0, 'W'},
@@ -511,6 +525,11 @@ extern unsigned int _bfd_srec_len;
    on by the --srec-forceS3 command line switch.  */
 extern bfd_boolean _bfd_srec_forceS3;
 
+/* Width of data in bytes for verilog output.
+   This variable is declared in bfd/verilog.c and can be modified by
+   the --verilog-data-width parameter.  */
+extern unsigned int VerilogDataWidth;
+
 /* Forward declarations.  */
 static void setup_section (bfd *, asection *, void *);
 static void setup_bfd_headers (bfd *, bfd *);
@@ -595,6 +614,8 @@ copy_usage (FILE *stream, int exit_status)
                                    Warn if a named section does not exist\n\
      --set-section-flags <name>=<flags>\n\
                                    Set section <name>'s properties to <flags>\n\
+     --set-section-alignment <name>=<align>\n\
+                                   Set section <name>'s alignment to 2^<align> bytes\n\
      --add-section <name>=<file>   Add section <name> found in <file> to output\n\
      --update-section <name>=<file>\n\
                                    Update contents of section <name> with\n\
@@ -645,6 +666,7 @@ copy_usage (FILE *stream, int exit_status)
      --decompress-debug-sections   Decompress DWARF debug sections using zlib\n\
      --elf-stt-common=[yes|no]     Generate ELF common symbols with STT_COMMON\n\
                                      type\n\
+     --verilog-data-width <number> Specifies data width, in bytes, for verilog output\n\
   -M  --merge-notes                Remove redundant entries in note sections\n\
       --no-merge-notes             Do not attempt to remove redundant notes (default)\n\
   -v --verbose                     List all object files modified\n\
@@ -948,6 +970,7 @@ find_section_list (const char *name, bfd_boolean add, unsigned int context)
   p->vma_val = 0;
   p->lma_val = 0;
   p->flags = 0;
+  p->alignment = 0;
   p->next = change_sections;
   change_sections = p;
 
@@ -1034,7 +1057,7 @@ add_specific_symbol_node (const void *node, htab_t htab)
 #define IS_LINE_TERMINATOR(c) ((c) == '\n' || (c) == '\r' || (c) == '\0')
 
 static void
-add_specific_symbols (const char *filename, htab_t htab)
+add_specific_symbols (const char *filename, htab_t htab, char **buffer_p)
 {
   off_t  size;
   FILE * f;
@@ -1142,6 +1165,10 @@ add_specific_symbols (const char *filename, htab_t htab)
       line = eol;
       line_count ++;
     }
+
+  /* Do not free the buffer.  Parts of it will have been referenced
+     in the calls to add_specific_symbol.  */
+  *buffer_p = buffer;
 }
 
 /* See whether a symbol should be stripped or kept
@@ -1438,7 +1465,7 @@ create_new_symbol (struct addsym_node *ptr, bfd *obfd)
 {
   asymbol *sym = bfd_make_empty_symbol (obfd);
 
-  bfd_asymbol_name (sym) = ptr->symdef;
+  bfd_set_asymbol_name (sym, ptr->symdef);
   sym->value = ptr->symval;
   sym->flags = ptr->flags;
   if (ptr->section)
@@ -1476,7 +1503,7 @@ filter_symbols (bfd *abfd, bfd *obfd, asymbol **osyms,
       bfd_boolean rem_leading_char;
       bfd_boolean add_leading_char;
 
-      undefined = bfd_is_und_section (bfd_get_section (sym));
+      undefined = bfd_is_und_section (bfd_asymbol_section (sym));
 
       if (add_sym_list)
        {
@@ -1494,7 +1521,7 @@ filter_symbols (bfd *abfd, bfd *obfd, asymbol **osyms,
          if (new_name == name
              && (flags & BSF_SECTION_SYM) != 0)
            new_name = (char *) find_section_rename (name, NULL);
-         bfd_asymbol_name (sym) = new_name;
+         bfd_set_asymbol_name (sym, new_name);
          name = new_name;
        }
 
@@ -1505,7 +1532,7 @@ filter_symbols (bfd *abfd, bfd *obfd, asymbol **osyms,
            || (remove_leading_char
                && ((flags & (BSF_GLOBAL | BSF_WEAK)) != 0
                    || undefined
-                   || bfd_is_com_section (bfd_get_section (sym)))));
+                   || bfd_is_com_section (bfd_asymbol_section (sym)))));
 
       /* Check if we will add a new leading character.  */
       add_leading_char =
@@ -1518,14 +1545,14 @@ filter_symbols (bfd *abfd, bfd *obfd, asymbol **osyms,
       if (rem_leading_char && add_leading_char && !prefix_symbols_string)
        {
          name[0] = bfd_get_symbol_leading_char (obfd);
-         bfd_asymbol_name (sym) = name;
+         bfd_set_asymbol_name (sym, name);
          rem_leading_char = FALSE;
          add_leading_char = FALSE;
        }
 
       /* Remove leading char.  */
       if (rem_leading_char)
-       bfd_asymbol_name (sym) = ++name;
+       bfd_set_asymbol_name (sym, ++name);
 
       /* Add new leading char and/or prefix.  */
       if (add_leading_char || prefix_symbols_string)
@@ -1544,7 +1571,7 @@ filter_symbols (bfd *abfd, bfd *obfd, asymbol **osyms,
            }
 
          strcpy (ptr, name);
-         bfd_asymbol_name (sym) = n;
+         bfd_set_asymbol_name (sym, n);
          name = n;
        }
 
@@ -1552,7 +1579,7 @@ filter_symbols (bfd *abfd, bfd *obfd, asymbol **osyms,
        keep = FALSE;
       else if ((flags & BSF_KEEP) != 0         /* Used in relocation.  */
               || ((flags & BSF_SECTION_SYM) != 0
-                  && ((*bfd_get_section (sym)->symbol_ptr_ptr)->flags
+                  && ((*bfd_asymbol_section (sym)->symbol_ptr_ptr)->flags
                       & BSF_KEEP) != 0))
        {
          keep = TRUE;
@@ -1560,7 +1587,7 @@ filter_symbols (bfd *abfd, bfd *obfd, asymbol **osyms,
        }
       else if (relocatable                     /* Relocatable file.  */
               && ((flags & (BSF_GLOBAL | BSF_WEAK)) != 0
-                  || bfd_is_com_section (bfd_get_section (sym))))
+                  || bfd_is_com_section (bfd_asymbol_section (sym))))
        keep = TRUE;
       else if (bfd_decode_symclass (sym) == 'I')
        /* Global symbols in $idata sections need to be retained
@@ -1571,13 +1598,13 @@ filter_symbols (bfd *abfd, bfd *obfd, asymbol **osyms,
       else if ((flags & BSF_GLOBAL) != 0       /* Global symbol.  */
               || (flags & BSF_WEAK) != 0
               || undefined
-              || bfd_is_com_section (bfd_get_section (sym)))
+              || bfd_is_com_section (bfd_asymbol_section (sym)))
        keep = strip_symbols != STRIP_UNNEEDED;
       else if ((flags & BSF_DEBUGGING) != 0)   /* Debugging symbol.  */
        keep = (strip_symbols != STRIP_DEBUG
                && strip_symbols != STRIP_UNNEEDED
                && ! convert_debugging);
-      else if (bfd_coff_get_comdat_section (abfd, bfd_get_section (sym)))
+      else if (bfd_coff_get_comdat_section (abfd, bfd_asymbol_section (sym)))
        /* COMDAT sections store special information in local
           symbols, so we cannot risk stripping any of them.  */
        keep = TRUE;
@@ -1610,7 +1637,7 @@ filter_symbols (bfd *abfd, bfd *obfd, asymbol **osyms,
              || is_specified_symbol (name, keep_specific_htab)))
        keep = TRUE;
 
-      if (keep && is_strip_section (abfd, bfd_get_section (sym)))
+      if (keep && is_strip_section (abfd, bfd_asymbol_section (sym)))
        keep = FALSE;
 
       if (keep)
@@ -1817,6 +1844,7 @@ add_redefine_syms_file (const char *filename)
     fatal (_("%s:%d: premature end of file"), filename, lineno);
 
   free (buf);
+  fclose (file);
 }
 
 /* Copy unknown object file IBFD onto OBFD.
@@ -1975,7 +2003,6 @@ merge_gnu_build_notes (bfd * abfd, asection * sec, bfd_size_type size, bfd_byte
   unsigned long       previous_open_end = 0;
   long                relsize;
 
-
   relsize = bfd_get_reloc_upper_bound (abfd, sec);
   if (relsize > 0)
     {
@@ -1992,7 +2019,8 @@ merge_gnu_build_notes (bfd * abfd, asection * sec, bfd_size_type size, bfd_byte
     }
   
   /* Make a copy of the notes and convert to our internal format.
-     Minimum size of a note is 12 bytes.  */
+     Minimum size of a note is 12 bytes.  Also locate the version
+     notes and check them.  */
   pnote = pnotes = (objcopy_internal_note *) xcalloc ((size / 12), sizeof (* pnote));
   while (remain >= 12)
     {
@@ -2161,12 +2189,10 @@ merge_gnu_build_notes (bfd * abfd, asection * sec, bfd_size_type size, bfd_byte
   attribute_type_byte = version_1_seen ? 1 : 3;
   val_start = attribute_type_byte + 1;
 
-  /* The first note should be the first version note.  */
-  if (pnotes[0].note.namedata[attribute_type_byte] != GNU_BUILD_ATTRIBUTE_VERSION)
-    {
-      err = _("bad GNU build attribute notes: first note not version note");
-      goto done;
-    }
+  /* We used to require that the first note be a version note,
+     but this is no longer enforced.  Due to the problems with
+     linking sections with the same name (eg .gnu.build.note.hot)
+     we cannot guarantee that the first note will be a version note.  */
 
   /* Now merge the notes.  The rules are:
      1. Preserve the ordering of the notes.
@@ -2174,7 +2200,7 @@ merge_gnu_build_notes (bfd * abfd, asection * sec, bfd_size_type size, bfd_byte
      3. Eliminate any NT_GNU_BUILD_ATTRIBUTE_OPEN notes that have the same
         full name field as the immediately preceeding note with the same type
        of name and whose address ranges coincide.
-       IE - it there are gaps in the coverage of the notes, then these gaps
+       IE - if there are gaps in the coverage of the notes, then these gaps
        must be preserved.
      4. Combine the numeric value of any NT_GNU_BUILD_ATTRIBUTE_OPEN notes
         of type GNU_BUILD_ATTRIBUTE_STACK_SIZE.
@@ -2182,16 +2208,48 @@ merge_gnu_build_notes (bfd * abfd, asection * sec, bfd_size_type size, bfd_byte
         its description field is empty then the nearest preceeding OPEN note
        with a non-empty description field must also be preserved *OR* the
        description field of the note must be changed to contain the starting
-       address to which it refers.  */
-  for (pnote = pnotes + 1; pnote < pnotes_end; pnote ++)
+       address to which it refers.
+     6. Notes with the same start and end address can be deleted.
+     7. FIXME: Elminate duplicate version notes - even function specific ones ?  */
+  for (pnote = pnotes; pnote < pnotes_end; pnote ++)
     {
       int                      note_type;
       objcopy_internal_note *  back;
       objcopy_internal_note *  prev_open_with_range = NULL;
 
+      /* Rule 6 - delete 0-range notes.  */
+      if (pnote->start == pnote->end)
+       {
+         duplicate_found = TRUE;
+         pnote->note.type = 0;
+         continue;
+       }
+
       /* Rule 2 - preserve function notes.  */
       if (! is_open_note (pnote))
-       continue;
+       {
+         int iter;
+
+         /* Check to see if there is an identical previous function note.
+            This can happen with overlays for example.  */
+         for (iter = 0, back = pnote -1; back >= pnotes; back --)
+           {
+             if (back->start == pnote->start
+                 && back->end == pnote->end
+                 && back->note.namesz == pnote->note.namesz
+                 && memcmp (back->note.namedata, pnote->note.namedata, pnote->note.namesz) == 0)
+               {
+                 duplicate_found = TRUE;
+                 pnote->note.type = 0;
+                 break;
+               }
+
+             /* Don't scan too far back however.  */
+             if (iter ++ > 16)
+               break;
+           }
+         continue;
+       }
 
       note_type = pnote->note.namedata[attribute_type_byte];
 
@@ -2823,6 +2881,7 @@ copy_object (bfd *ibfd, bfd *obfd, const bfd_arch_info_type *input_arch)
                             pdump->filename,
                             strerror (errno));
                  free (contents);
+                 fclose (f);
                  return FALSE;
                }
            }
@@ -3041,7 +3100,14 @@ copy_object (bfd *ibfd, bfd *obfd, const bfd_arch_info_type *input_arch)
 
   if (convert_debugging && dhandle != NULL)
     {
-      if (! write_debugging_info (obfd, dhandle, &symcount, &osympp))
+      bfd_boolean res;
+
+      res = write_debugging_info (obfd, dhandle, &symcount, &osympp);
+
+      free (dhandle);
+      dhandle = NULL; /* Paranoia...  */
+
+      if (! res)
        {
          status = 1;
          return FALSE;
@@ -3153,6 +3219,7 @@ copy_object (bfd *ibfd, bfd *obfd, const bfd_arch_info_type *input_arch)
                                                  off, now))
                    {
                      bfd_nonfatal_message (NULL, obfd, osections[i], NULL);
+                     free (buf);
                      return FALSE;
                    }
 
@@ -3161,6 +3228,10 @@ copy_object (bfd *ibfd, bfd *obfd, const bfd_arch_info_type *input_arch)
                }
            }
        }
+
+      free (buf);
+      free (gaps);
+      gaps = NULL;
     }
 
   /* Allow the BFD backend to copy any private data it understands
@@ -3218,6 +3289,27 @@ copy_archive (bfd *ibfd, bfd *obfd, const char *output_target,
   char *dir;
   const char *filename;
 
+  /* PR 24281: It is not clear what should happen when copying a thin archive.
+     One part is straight forward - if the output archive is in a different
+     directory from the input archive then any relative paths in the library
+     should be adjusted to the new location.  But if any transformation
+     options are active (eg strip, rename, add, etc) then the implication is
+     that these should be applied to the files pointed to by the archive.
+     But since objcopy is not destructive, this means that new files must be
+     created, and there is no guidance for the names of the new files.  (Plus
+     this conflicts with one of the goals of thin libraries - only taking up
+     a  minimal amount of space in the file system).
+
+     So for now we fail if an attempt is made to copy such libraries.  */
+  if (ibfd->is_thin_archive)
+    {
+      status = 1;
+      bfd_set_error (bfd_error_invalid_operation);
+      bfd_nonfatal_message (NULL, ibfd, NULL,
+                           _("sorry: copying thin archives is not currently supported"));
+      return;
+    }
+
   /* Make a temp directory to hold the contents.  */
   dir = make_tempdir (bfd_get_filename (obfd));
   if (dir == NULL)
@@ -3271,8 +3363,10 @@ copy_archive (bfd *ibfd, bfd *obfd, const char *output_target,
       /* If the file already exists, make another temp dir.  */
       if (stat (output_name, &buf) >= 0)
        {
-         output_name = make_tempdir (output_name);
-         if (output_name == NULL)
+         char * tmpdir = make_tempdir (output_name);
+
+         free (output_name);
+         if (tmpdir == NULL)
            {
              non_fatal (_("cannot create tempdir for archive copying (error: %s)"),
                         strerror (errno));
@@ -3281,11 +3375,11 @@ copy_archive (bfd *ibfd, bfd *obfd, const char *output_target,
            }
 
          l = (struct name_list *) xmalloc (sizeof (struct name_list));
-         l->name = output_name;
+         l->name = tmpdir;
          l->next = list;
          l->obfd = NULL;
          list = l;
-         output_name = concat (output_name, "/",
+         output_name = concat (tmpdir, "/",
                                bfd_get_filename (this_element), (char *) 0);
        }
 
@@ -3392,16 +3486,22 @@ copy_archive (bfd *ibfd, bfd *obfd, const char *output_target,
 
  cleanup_and_exit:
   /* Delete all the files that we opened.  */
-  for (l = list; l != NULL; l = l->next)
-    {
-      if (l->obfd == NULL)
-       rmdir (l->name);
-      else
-       {
-         bfd_close (l->obfd);
-         unlink (l->name);
-       }
-    }
+  {
+    struct name_list * next;
+
+    for (l = list; l != NULL; l = next)
+      {
+       if (l->obfd == NULL)
+         rmdir (l->name);
+       else
+         {
+           bfd_close (l->obfd);
+           unlink (l->name);
+         }
+       next = l->next;
+       free (l);
+      }
+  }
 
   rmdir (dir);
 }
@@ -3673,6 +3773,7 @@ setup_section (bfd *ibfd, sec_ptr isection, void *obfdarg)
   const char * name;
   char *prefix = NULL;
   bfd_boolean make_nobits;
+  unsigned int alignment;
 
   if (is_strip_section (ibfd, isection))
     return;
@@ -3779,11 +3880,18 @@ setup_section (bfd *ibfd, sec_ptr isection, void *obfdarg)
 
   osection->lma = lma;
 
+  p = find_section_list (bfd_section_name (ibfd, isection), FALSE,
+                        SECTION_CONTEXT_SET_ALIGNMENT);
+  if (p != NULL)
+    alignment = p->alignment;
+  else
+    alignment = bfd_section_alignment (ibfd, isection);
+  
   /* FIXME: This is probably not enough.  If we change the LMA we
      may have to recompute the header for the file as well.  */
   if (!bfd_set_section_alignment (obfd,
                                  osection,
-                                 bfd_section_alignment (ibfd, isection)))
+                                 alignment))
     {
       err = _("failed to set alignment");
       goto loser;
@@ -3893,21 +4001,22 @@ discard_relocations (bfd *ibfd ATTRIBUTE_UNUSED, asection *isection)
 
 /* Wrapper for dealing with --remove-section (-R) command line arguments.
    A special case is detected here, if the user asks to remove a relocation
-   section (one starting with ".rela." or ".rel.") then this removal must
-   be done using a different technique.  */
+   section (one starting with ".rela" or ".rel") then this removal must
+   be done using a different technique in a relocatable object.  */
 
 static void
 handle_remove_section_option (const char *section_pattern)
 {
-  if (strncmp (section_pattern, ".rela.", 6) == 0)
-    handle_remove_relocations_option (section_pattern + 5);
-  else if (strncmp (section_pattern, ".rel.", 5) == 0)
-    handle_remove_relocations_option (section_pattern + 4);
-  else
+  find_section_list (section_pattern, TRUE, SECTION_CONTEXT_REMOVE);
+  if (strncmp (section_pattern, ".rel", 4) == 0)
     {
-      find_section_list (section_pattern, TRUE, SECTION_CONTEXT_REMOVE);
-      sections_removed = TRUE;
+      section_pattern += 4;
+      if (*section_pattern == 'a')
+       section_pattern++;
+      if (*section_pattern)
+       handle_remove_relocations_option (section_pattern);
     }
+  sections_removed = TRUE;
 }
 
 /* Copy relocations in input section ISECTION of IBFD to an output
@@ -4254,7 +4363,7 @@ write_debugging_info (bfd *obfd, void *dhandle,
   if (bfd_get_flavour (obfd) == bfd_target_coff_flavour
       || bfd_get_flavour (obfd) == bfd_target_elf_flavour)
     {
-      bfd_byte *syms, *strings;
+      bfd_byte *syms, *strings = NULL;
       bfd_size_type symsize, stringsize;
       asection *stabsec, *stabstrsec;
       flagword flags;
@@ -4276,6 +4385,7 @@ write_debugging_info (bfd *obfd, void *dhandle,
        {
          bfd_nonfatal_message (NULL, obfd, NULL,
                                _("can't create debugging section"));
+         free (strings);
          return FALSE;
        }
 
@@ -4289,6 +4399,7 @@ write_debugging_info (bfd *obfd, void *dhandle,
        {
          bfd_nonfatal_message (NULL, obfd, NULL,
                                _("can't set debugging section contents"));
+         free (strings);
          return FALSE;
        }
 
@@ -4320,8 +4431,7 @@ strip_main (int argc, char *argv[])
   int c;
   int i;
   char *output_file = NULL;
-
-  merge_notes = TRUE;
+  bfd_boolean merge_notes_set = FALSE;
 
   while ((c = getopt_long (argc, argv, "I:O:F:K:MN:R:o:sSpdgxXHhVvwDU",
                           strip_options, (int *) 0)) != EOF)
@@ -4362,9 +4472,11 @@ strip_main (int argc, char *argv[])
          break;
        case 'M':
          merge_notes = TRUE;
+         merge_notes_set = TRUE;
          break;
        case OPTION_NO_MERGE_NOTES:
          merge_notes = FALSE;
+         merge_notes_set = TRUE;
          break;
        case 'N':
          add_specific_symbol (optarg, strip_specific_htab);
@@ -4416,6 +4528,16 @@ strip_main (int argc, char *argv[])
        }
     }
 
+  /* If the user has not expressly chosen to merge/not-merge ELF notes
+     then enable the merging unless we are stripping debug or dwo info.  */
+  if (! merge_notes_set
+      && (strip_symbols == STRIP_UNDEF
+         || strip_symbols == STRIP_ALL
+         || strip_symbols == STRIP_UNNEEDED
+         || strip_symbols == STRIP_NONDEBUG
+         || strip_symbols == STRIP_NONDWO))
+    merge_notes = TRUE;
+
   if (formats_info)
     {
       display_info ();
@@ -4691,6 +4813,8 @@ copy_main (int argc, char *argv[])
   bfd_boolean show_version = FALSE;
   bfd_boolean change_warn = TRUE;
   bfd_boolean formats_info = FALSE;
+  bfd_boolean use_globalize = FALSE;
+  bfd_boolean use_keep_global = FALSE;
   int c;
   struct stat statbuf;
   const bfd_arch_info_type *input_arch = NULL;
@@ -4809,10 +4933,12 @@ copy_main (int argc, char *argv[])
          break;
 
        case OPTION_GLOBALIZE_SYMBOL:
+         use_globalize = TRUE;
          add_specific_symbol (optarg, globalize_specific_htab);
          break;
 
        case 'G':
+         use_keep_global = TRUE;
          add_specific_symbol (optarg, keepglobal_specific_htab);
          break;
 
@@ -5151,6 +5277,33 @@ copy_main (int argc, char *argv[])
          }
          break;
 
+       case OPTION_SET_SECTION_ALIGNMENT:
+         {
+           struct section_list *p;
+           const char *s;
+           int len;
+           char *name;
+           int align;
+
+           s = strchr (optarg, '=');
+           if (s == NULL)
+             fatal (_("bad format for %s"), "--set-section-alignment");
+           
+           align = atoi(s+1);
+           if (align < 0)
+             fatal (_("bad format for %s"), "--set-section-alignment");
+
+           len = s - optarg;
+           name = (char *) xmalloc (len + 1);
+           strncpy (name, optarg, len);
+           name[len] = '\0';
+
+           p = find_section_list (name, TRUE, SECTION_CONTEXT_SET_ALIGNMENT);
+
+           p->alignment = align;
+         }
+         break;
+         
        case OPTION_RENAME_SECTION:
          {
            flagword flags;
@@ -5209,15 +5362,18 @@ copy_main (int argc, char *argv[])
          break;
 
        case OPTION_STRIP_SYMBOLS:
-         add_specific_symbols (optarg, strip_specific_htab);
+         add_specific_symbols (optarg, strip_specific_htab,
+                               &strip_specific_buffer);
          break;
 
        case OPTION_STRIP_UNNEEDED_SYMBOLS:
-         add_specific_symbols (optarg, strip_unneeded_htab);
+         add_specific_symbols (optarg, strip_unneeded_htab,
+                               &strip_unneeded_buffer);
          break;
 
        case OPTION_KEEP_SYMBOLS:
-         add_specific_symbols (optarg, keep_specific_htab);
+         add_specific_symbols (optarg, keep_specific_htab,
+                               &keep_specific_buffer);
          break;
 
        case OPTION_LOCALIZE_HIDDEN:
@@ -5225,7 +5381,8 @@ copy_main (int argc, char *argv[])
          break;
 
        case OPTION_LOCALIZE_SYMBOLS:
-         add_specific_symbols (optarg, localize_specific_htab);
+         add_specific_symbols (optarg, localize_specific_htab,
+                               &localize_specific_buffer);
          break;
 
        case OPTION_LONG_SECTION_NAMES:
@@ -5240,15 +5397,20 @@ copy_main (int argc, char *argv[])
          break;
 
        case OPTION_GLOBALIZE_SYMBOLS:
-         add_specific_symbols (optarg, globalize_specific_htab);
+         use_globalize = TRUE;
+         add_specific_symbols (optarg, globalize_specific_htab,
+                               &globalize_specific_buffer);
          break;
 
        case OPTION_KEEPGLOBAL_SYMBOLS:
-         add_specific_symbols (optarg, keepglobal_specific_htab);
+         use_keep_global = TRUE;
+         add_specific_symbols (optarg, keepglobal_specific_htab,
+                               &keepglobal_specific_buffer);
          break;
 
        case OPTION_WEAKEN_SYMBOLS:
-         add_specific_symbols (optarg, weaken_specific_htab);
+         add_specific_symbols (optarg, weaken_specific_htab,
+                               &weaken_specific_buffer);
          break;
 
        case OPTION_ALT_MACH_CODE:
@@ -5337,7 +5499,7 @@ copy_main (int argc, char *argv[])
          pe_image_base = parse_vma (optarg, "--image-base");
          break;
 
-       case OPTION_SECTION_ALIGNMENT:
+       case OPTION_PE_SECTION_ALIGNMENT:
          pe_section_alignment = parse_vma (optarg,
                                            "--section-alignment");
          break;
@@ -5364,6 +5526,12 @@ copy_main (int argc, char *argv[])
          }
          break;
 
+       case OPTION_VERILOG_DATA_WIDTH:
+         VerilogDataWidth = parse_vma (optarg, "--verilog-data-width");
+         if (VerilogDataWidth < 1)
+           fatal (_("verilog data width must be at least 1 byte"));
+         break;
+
        case 0:
          /* We've been given a long option.  */
          break;
@@ -5377,6 +5545,9 @@ copy_main (int argc, char *argv[])
        }
     }
 
+  if (use_globalize && use_keep_global)
+    fatal(_("--globalize-symbol(s) is incompatible with -G/--keep-global-symbol(s)"));
+
   if (formats_info)
     {
       display_info ();
@@ -5535,6 +5706,27 @@ copy_main (int argc, char *argv[])
        }
     }
 
+  if (strip_specific_buffer)
+    free (strip_specific_buffer);
+
+  if (strip_unneeded_buffer)
+    free (strip_unneeded_buffer);
+
+  if (keep_specific_buffer)
+    free (keep_specific_buffer);
+
+  if (localize_specific_buffer)
+    free (globalize_specific_buffer);
+
+  if (globalize_specific_buffer)
+    free (globalize_specific_buffer);
+
+  if (keepglobal_specific_buffer)
+    free (keepglobal_specific_buffer);
+
+  if (weaken_specific_buffer)
+    free (weaken_specific_buffer);
+
   return 0;
 }
 
@@ -5560,7 +5752,8 @@ main (int argc, char *argv[])
   strip_symbols = STRIP_UNDEF;
   discard_locals = LOCALS_UNDEF;
 
-  bfd_init ();
+  if (bfd_init () != BFD_INIT_MAGIC)
+    fatal (_("fatal error: libbfd ABI mismatch"));
   set_default_bfd_target ();
 
   if (is_strip < 0)
This page took 0.03263 seconds and 4 git commands to generate.