Fix an abort triggered when objcopy is used to set the "share" section flag on an...
authorNick Clifton <nickc@redhat.com>
Fri, 6 Mar 2020 10:09:22 +0000 (10:09 +0000)
committerNick Clifton <nickc@redhat.com>
Fri, 6 Mar 2020 10:09:22 +0000 (10:09 +0000)
binutils* objcopy.c (check_new_section_flags): New function.  Reject the
SEC_COFF_SHARED flag if the target is not a COFF binary.
(copy_object): Call check_new_section_flags.
(setup_section): Likewise.
* doc/binutils.texi (objcopy): Add a note that the 'share' section
flag cannot be applied to ELF binaries.

bfd * elf.c (_bfd_elf_set_section_contents): Replace call to abort
with error messages and failure return values.

bfd/ChangeLog
bfd/elf.c
binutils/ChangeLog
binutils/doc/binutils.texi
binutils/objcopy.c

index 838b07faf1718261f37530bdd7c724e9bc8a814f..0df437b2ffd16be2a3758d36efe7b56d38405e59 100644 (file)
@@ -1,3 +1,8 @@
+2020-03-06  Nick Clifton  <nickc@redhat.com>
+
+       * elf.c (_bfd_elf_set_section_contents): Replace call to abort
+       with error messages and failure return values.
+
 2020-03-05  Max Filippov  <jcmvbkbc@gmail.com>
 
        * elf32-xtensa.c (shrink_dynamic_reloc_sections): Shrink dynamic
index 747d120101fce8d0190ca725f025eea00552b500..e6db2ff64d8a975b9bab0767d5e010a0f04e7a1e 100644 (file)
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -3218,7 +3218,6 @@ elf_fake_sections (bfd *abfd, asection *asect, void *fsarg)
          /* Set SEC_ELF_COMPRESS to indicate this section should be
             compressed.  */
          asect->flags |= SEC_ELF_COMPRESS;
-
          /* If this section will be compressed, delay adding section
             name to section name section after it is compressed in
             _bfd_elf_assign_file_positions_for_non_load.  */
@@ -9181,20 +9180,47 @@ _bfd_elf_set_section_contents (bfd *abfd,
   hdr = &elf_section_data (section)->this_hdr;
   if (hdr->sh_offset == (file_ptr) -1)
     {
+      unsigned char *contents;
+
       if (bfd_section_is_ctf (section))
        /* Nothing to do with this section: the contents are generated
           later.  */
        return TRUE;
 
-      /* We must compress this section.  Write output to the buffer.  */
-      unsigned char *contents = hdr->contents;
-      if ((offset + count) > hdr->sh_size
-         || (section->flags & SEC_ELF_COMPRESS) == 0
-         || contents == NULL)
-       abort ();
+      if ((section->flags & SEC_ELF_COMPRESS) == 0)
+       {
+         _bfd_error_handler
+           (_("%pB:%pA: error: attempting to write into an unallocated compressed section"),
+            abfd, section);
+         bfd_set_error (bfd_error_invalid_operation);
+         return FALSE;
+       }
+      
+      if ((offset + count) > hdr->sh_size)
+       {
+         _bfd_error_handler
+           (_("%pB:%pA: error: attempting to write over the end of the section"),
+            abfd, section);
+
+         bfd_set_error (bfd_error_invalid_operation);
+         return FALSE;
+       }
+
+      contents = hdr->contents;
+      if (contents == NULL)
+       {
+         _bfd_error_handler
+           (_("%pB:%pA: error: attempting to write section into an empty buffer"),
+            abfd, section);
+
+         bfd_set_error (bfd_error_invalid_operation);
+         return FALSE;
+       }
+
       memcpy (contents + offset, location, count);
       return TRUE;
     }
+
   pos = hdr->sh_offset + offset;
   if (bfd_seek (abfd, pos, SEEK_SET) != 0
       || bfd_bwrite (location, count, abfd) != count)
index 1fe7f15419284cdaf6ee1fc9e83b5bd7061d0faa..840fc4d5891ecb9c7493881b8aa011a653936b54 100644 (file)
@@ -1,3 +1,12 @@
+2020-03-06  Nick Clifton  <nickc@redhat.com>
+
+       * objcopy.c (check_new_section_flags): New function.  Reject the
+       SEC_COFF_SHARED flag if the target is not a COFF binary.
+       (copy_object): Call check_new_section_flags.
+       (setup_section): Likewise.
+       * doc/binutils.texi (objcopy): Add a note that the 'share' section
+       flag cannot be applied to ELF binaries.
+
 2020-03-06  Alan Modra  <amodra@gmail.com>
 
        PR 25637
index 3099e3f545eb18267a1cd86b5a44af752cfaacf1..de3f1babb2787a67c67b81fdfe3403af56be4b21 100644 (file)
@@ -1648,7 +1648,9 @@ recognized names are @samp{alloc}, @samp{contents}, @samp{load},
 @samp{contents} flag for a section which does not have contents, but it
 is not meaningful to clear the @samp{contents} flag of a section which
 does have contents--just remove the section instead.  Not all flags are
-meaningful for all object file formats.
+meaningful for all object file formats.  In particular the
+@samp{share} flag is only meaningful for COFF format files and not for
+ELF format files.
 
 @item --set-section-alignment @var{sectionpattern}=@var{align}
 Set the alignment for any sections matching @var{sectionpattern}.
@@ -1704,7 +1706,8 @@ Rename a section from @var{oldname} to @var{newname}, optionally
 changing the section's flags to @var{flags} in the process.  This has
 the advantage over using a linker script to perform the rename in that
 the output stays as an object file and does not become a linked
-executable.
+executable.  This option accepts the same set of flags as the
+@option{--sect-section-flags} option.
 
 This option is particularly helpful when the input format is binary,
 since this will always create a section called .data.  If for example,
index 16affa9960fafc0822c3adac559b50c89282ba39..09facf0061ea28865eabe83e6feb36c38bd35dad 100644 (file)
@@ -2562,6 +2562,23 @@ merge_gnu_build_notes (bfd *          abfd,
   return size;
 }
 
+static flagword
+check_new_section_flags (flagword flags, bfd * abfd, const char * secname)
+{
+  /* Only set the SEC_COFF_SHARED flag on COFF files.
+     The same bit value is used by ELF targets to indicate
+     compressed sections, and setting that flag here breaks
+     things.  */
+  if ((flags & SEC_COFF_SHARED)
+      && bfd_get_flavour (abfd) != bfd_target_coff_flavour)
+    {
+      non_fatal (_("%s[%s]: Note - dropping 'share' flag as output format is not COFF"),
+                bfd_get_filename (abfd), secname);
+      flags &= ~ SEC_COFF_SHARED;
+    }
+  return flags;
+}
+
 /* Copy object file IBFD onto OBFD.
    Returns TRUE upon success, FALSE otherwise.  */
 
@@ -2810,7 +2827,10 @@ copy_object (bfd *ibfd, bfd *obfd, const bfd_arch_info_type *input_arch)
          pset = find_section_list (padd->name, FALSE,
                                    SECTION_CONTEXT_SET_FLAGS);
          if (pset != NULL)
-           flags = pset->flags | SEC_HAS_CONTENTS;
+           {         
+             flags = pset->flags | SEC_HAS_CONTENTS;
+             flags = check_new_section_flags (flags, obfd, padd->name);
+           }
          else
            flags = SEC_HAS_CONTENTS | SEC_READONLY | SEC_DATA;
 
@@ -3950,6 +3970,7 @@ setup_section (bfd *ibfd, sec_ptr isection, void *obfdarg)
   flagword flags;
   const char *err;
   const char * name;
+  const char * new_name;
   char *prefix = NULL;
   bfd_boolean make_nobits;
   unsigned int alignment;
@@ -3965,7 +3986,12 @@ setup_section (bfd *ibfd, sec_ptr isection, void *obfdarg)
       flags &= bfd_applicable_section_flags (ibfd);
       flags &= bfd_applicable_section_flags (obfd);
     }
-  name = find_section_rename (name, &flags);
+  new_name = find_section_rename (name, &flags);
+  if (new_name != name)
+    {
+      name = new_name;
+      flags = check_new_section_flags (flags, obfd, name);
+    }
 
   /* Prefix sections.  */
   if (prefix_alloc_sections_string
@@ -3989,7 +4015,10 @@ setup_section (bfd *ibfd, sec_ptr isection, void *obfdarg)
   p = find_section_list (bfd_section_name (isection), FALSE,
                         SECTION_CONTEXT_SET_FLAGS);
   if (p != NULL)
-    flags = p->flags | (flags & (SEC_HAS_CONTENTS | SEC_RELOC));
+    {
+      flags = p->flags | (flags & (SEC_HAS_CONTENTS | SEC_RELOC));
+      flags = check_new_section_flags (flags, obfd, bfd_section_name (isection));
+    }
   else if (strip_symbols == STRIP_NONDEBUG
           && (flags & (SEC_ALLOC | SEC_GROUP)) != 0
           && !is_nondebug_keep_contents_section (ibfd, isection))