Memory leaks and ineffective bounds checking in wasm_scan
[deliverable/binutils-gdb.git] / binutils / objcopy.c
index ea6eb646b4f01077d474d3a7aef4e4965bc8e292..ef3b693be4916106d4afd132f50ec90b10b125dc 100644 (file)
@@ -1,5 +1,5 @@
 /* objcopy.c -- copy object file from input to output, optionally massaging it.
-   Copyright (C) 1991-2019 Free Software Foundation, Inc.
+   Copyright (C) 1991-2020 Free Software Foundation, Inc.
 
    This file is part of GNU Binutils.
 
@@ -68,7 +68,7 @@ struct addsym_node
   long      symval;
   flagword  flags;
   char *    section;
-  char *    othersym;
+  const char *  othersym;
 };
 
 typedef struct section_rename
@@ -808,7 +808,7 @@ parse_flags (const char *s)
    string can't be parsed.  */
 
 static flagword
-parse_symflags (const char *s, char **other)
+parse_symflags (const char *s, const char **other)
 {
   flagword ret;
   const char *snext;
@@ -1421,16 +1421,16 @@ static bfd_boolean
 is_nondebug_keep_contents_section (bfd *ibfd, asection *isection)
 {
   /* Always keep ELF note sections.  */
-  if (ibfd->xvec->flavour == bfd_target_elf_flavour)
-    return (elf_section_type (isection) == SHT_NOTE);
+  if (bfd_get_flavour (ibfd) == bfd_target_elf_flavour)
+    return elf_section_type (isection) == SHT_NOTE;
 
   /* Always keep the .buildid section for PE/COFF.
 
      Strictly, this should be written "always keep the section storing the debug
      directory", but that may be the .text section for objects produced by some
      tools, which it is not sensible to keep.  */
-  if (ibfd->xvec->flavour == bfd_target_coff_flavour)
-    return (strcmp (bfd_section_name (isection), ".buildid") == 0);
+  if (bfd_get_flavour (ibfd) == bfd_target_coff_flavour)
+    return strcmp (bfd_section_name (isection), ".buildid") == 0;
 
   return FALSE;
 }
@@ -1453,6 +1453,9 @@ is_hidden_symbol (asymbol *sym)
   return FALSE;
 }
 
+/* Empty name is hopefully never a valid symbol name.  */
+static const char * empty_name = "";
+
 static bfd_boolean
 need_sym_before (struct addsym_node **node, const char *sym)
 {
@@ -1464,10 +1467,12 @@ need_sym_before (struct addsym_node **node, const char *sym)
     {
       if (!ptr->othersym)
        break;
+      if (ptr->othersym == empty_name)
+       continue;
       else if (strcmp (ptr->othersym, sym) == 0)
        {
-         free (ptr->othersym);
-         ptr->othersym = ""; /* Empty name is hopefully never a valid symbol name.  */
+         free ((char *) ptr->othersym);
+         ptr->othersym = empty_name;
          *node = ptr;
          return TRUE;
        }
@@ -1695,7 +1700,7 @@ filter_symbols (bfd *abfd, bfd *obfd, asymbol **osyms,
        {
          if (ptr->othersym)
            {
-             if (strcmp (ptr->othersym, ""))
+             if (ptr->othersym != empty_name)
                fatal (_("'before=%s' not found"), ptr->othersym);
            }
          else
@@ -2460,7 +2465,9 @@ merge_gnu_build_notes (bfd *          abfd,
   bfd_vma        prev_start = 0;
   bfd_vma        prev_end = 0;
 
-  new = new_contents = xmalloc (size);
+  /* Not sure how, but the notes might grow in size.
+     (eg see PR 1774507).  Allow for this here.  */
+  new = new_contents = xmalloc (size * 2);
   for (pnote = pnotes, old = contents;
        pnote < pnotes_end;
        pnote ++)
@@ -2527,8 +2534,11 @@ merge_gnu_build_notes (bfd *          abfd,
 #endif
   
   new_size = new - new_contents;
-  memcpy (contents, new_contents, new_size);
-  size = new_size;
+  if (new_size < size)
+    {
+      memcpy (contents, new_contents, new_size);
+      size = new_size;
+    }
   free (new_contents);
 
  done:
@@ -2585,7 +2595,7 @@ copy_object (bfd *ibfd, bfd *obfd, const bfd_arch_info_type *input_arch)
       return FALSE;
     }
 
-  if (ibfd->xvec->flavour != bfd_target_elf_flavour)
+  if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour)
     {
       if ((do_debug_sections & compress) != 0
          && do_debug_sections != compress)
@@ -2646,8 +2656,7 @@ copy_object (bfd *ibfd, bfd *obfd, const bfd_arch_info_type *input_arch)
   imach = bfd_get_mach (ibfd);
   if (input_arch)
     {
-      if (bfd_get_arch_info (ibfd) == NULL
-         || bfd_get_arch_info (ibfd)->arch == bfd_arch_unknown)
+      if (iarch == bfd_arch_unknown)
        {
          iarch = input_arch->arch;
          imach = input_arch->mach;
@@ -2656,6 +2665,14 @@ copy_object (bfd *ibfd, bfd *obfd, const bfd_arch_info_type *input_arch)
        non_fatal (_("Input file `%s' ignores binary architecture parameter."),
                   bfd_get_archive_filename (ibfd));
     }
+  if (iarch == bfd_arch_unknown
+      && bfd_get_flavour (ibfd) != bfd_target_elf_flavour
+      && bfd_get_flavour (obfd) == bfd_target_elf_flavour)
+    {
+      const struct elf_backend_data *bed = get_elf_backend_data (obfd);
+      iarch = bed->arch;
+      imach = 0;
+    }
   if (!bfd_set_arch_mach (obfd, iarch, imach)
       && (ibfd->target_defaulted
          || bfd_get_arch (ibfd) != bfd_get_arch (obfd)))
@@ -2683,7 +2700,7 @@ copy_object (bfd *ibfd, bfd *obfd, const bfd_arch_info_type *input_arch)
       pe_data_type *pe = pe_data (obfd);
 
       /* Copy PE parameters before changing them.  */
-      if (ibfd->xvec->flavour == bfd_target_coff_flavour
+      if (bfd_get_flavour (ibfd) == bfd_target_coff_flavour
          && bfd_pei_p (ibfd))
        pe->pe_opthdr = pe_data (ibfd)->pe_opthdr;
 
@@ -3745,6 +3762,14 @@ copy_file (const char *input_filename, const char *output_filename,
          status = 1;
          return;
        }
+
+      if (gnu_debuglink_filename != NULL)
+       {
+         non_fatal (_("--add-gnu-debuglink ignored for archive %s"),
+                    bfd_get_filename (ibfd));
+         gnu_debuglink_filename = NULL;
+       }
+
       /* This is a no-op on non-Coff targets.  */
       set_long_section_mode (obfd, ibfd, long_section_names);
 
@@ -3922,11 +3947,16 @@ setup_section (bfd *ibfd, sec_ptr isection, void *obfdarg)
   /* Get the, possibly new, name of the output section.  */
   name = bfd_section_name (isection);
   flags = bfd_section_flags (isection);
+  if (bfd_get_flavour (ibfd) != bfd_get_flavour (obfd))
+    {
+      flags &= bfd_applicable_section_flags (ibfd);
+      flags &= bfd_applicable_section_flags (obfd);
+    }
   name = find_section_rename (name, &flags);
 
   /* Prefix sections.  */
-  if ((prefix_alloc_sections_string)
-      && (bfd_section_flags (isection) & SEC_ALLOC))
+  if (prefix_alloc_sections_string
+      && (bfd_section_flags (isection) & SEC_ALLOC) != 0)
     prefix = prefix_alloc_sections_string;
   else if (prefix_sections_string)
     prefix = prefix_sections_string;
@@ -3952,7 +3982,7 @@ setup_section (bfd *ibfd, sec_ptr isection, void *obfdarg)
           && !is_nondebug_keep_contents_section (ibfd, isection))
     {
       flags &= ~(SEC_HAS_CONTENTS | SEC_LOAD | SEC_GROUP);
-      if (obfd->xvec->flavour == bfd_target_elf_flavour)
+      if (bfd_get_flavour (obfd) == bfd_target_elf_flavour)
        {
          make_nobits = TRUE;
 
@@ -4055,7 +4085,7 @@ setup_section (bfd *ibfd, sec_ptr isection, void *obfdarg)
       if (gsym != NULL)
        {
          gsym->flags |= BSF_KEEP;
-         if (ibfd->xvec->flavour == bfd_target_elf_flavour)
+         if (bfd_get_flavour (ibfd) == bfd_target_elf_flavour)
            elf_group_id (isection) = gsym;
        }
     }
This page took 0.025794 seconds and 4 git commands to generate.