PR25651, objcopy SIGSEGV in copy_object
authorAlan Modra <amodra@gmail.com>
Wed, 11 Mar 2020 03:20:35 +0000 (13:50 +1030)
committerAlan Modra <amodra@gmail.com>
Wed, 11 Mar 2020 04:31:15 +0000 (15:01 +1030)
With the right set of options, the second block of code dealing with
padding can see a different section count.  So don't use the new count.
Since I was editing those lines, I've also changed the code allocating
arrays a little.
    array = malloc (n * sizeof (*array));
for an array of ints is just better than
    array = malloc (n * sizeof (int));
It's easier to write correctly in the first place and more robust
against code changes that might modify the array element type.

PR 25651
* objcopy.c (copy_object): Test "gaps" not gap_fill_set or
pad_to_set on second block of code dealing with padding.
Replace "c" with "num_sec" and don't recalculate number of
sections on second block.  Size arrays using sizeof (element)
rather than sizeof (element type).

binutils/ChangeLog
binutils/objcopy.c

index fc456a2259d82c54ef74586dec8f3efcbe93e60f..0ca05640d82b8ce1a8e131f0f1724c0037a05496 100644 (file)
@@ -1,3 +1,12 @@
+2020-03-11  Alan Modra  <amodra@gmail.com>
+
+       PR 25651
+       * objcopy.c (copy_object): Test "gaps" not gap_fill_set or
+       pad_to_set on second block of code dealing with padding.
+       Replace "c" with "num_sec" and don't recalculate number of
+       sections on second block.  Size arrays using sizeof (element)
+       rather than sizeof (element type).
+
 2020-03-10  Alan Modra  <amodra@gmail.com>
 
        * objdump.c (disassemble_section): Don't call qsort unless
index 09facf0061ea28865eabe83e6feb36c38bd35dad..e6711a99fb2f0324c8f7edea21580daa061cfdaa 100644 (file)
@@ -2596,7 +2596,7 @@ copy_object (bfd *ibfd, bfd *obfd, const bfd_arch_info_type *input_arch)
   void *dhandle;
   enum bfd_architecture iarch;
   unsigned int imach;
-  unsigned int c, i;
+  unsigned int num_sec, i;
 
   if (ibfd->xvec->byteorder != obfd->xvec->byteorder
       && ibfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN
@@ -3101,8 +3101,8 @@ copy_object (bfd *ibfd, bfd *obfd, const bfd_arch_info_type *input_arch)
        }
     }
 
-  c = bfd_count_sections (obfd);
-  if (c != 0
+  num_sec = bfd_count_sections (obfd);
+  if (num_sec != 0
       && (gap_fill_set || pad_to_set))
     {
       asection **set;
@@ -3113,18 +3113,18 @@ copy_object (bfd *ibfd, bfd *obfd, const bfd_arch_info_type *input_arch)
         increasing the section sizes as required to fill the gaps.
         We write out the gap contents below.  */
 
-      osections = (asection **) xmalloc (c * sizeof (asection *));
+      osections = xmalloc (num_sec * sizeof (*osections));
       set = osections;
       bfd_map_over_sections (obfd, get_sections, &set);
 
-      qsort (osections, c, sizeof (asection *), compare_section_lma);
+      qsort (osections, num_sec, sizeof (*osections), compare_section_lma);
 
-      gaps = (bfd_size_type *) xmalloc (c * sizeof (bfd_size_type));
-      memset (gaps, 0, c * sizeof (bfd_size_type));
+      gaps = xmalloc (num_sec * sizeof (*gaps));
+      memset (gaps, 0, num_sec * sizeof (*gaps));
 
       if (gap_fill_set)
        {
-         for (i = 0; i < c - 1; i++)
+         for (i = 0; i < num_sec - 1; i++)
            {
              flagword flags;
              bfd_size_type size;           /* Octets.  */
@@ -3161,22 +3161,22 @@ copy_object (bfd *ibfd, bfd *obfd, const bfd_arch_info_type *input_arch)
        {
          bfd_vma lma;         /* Octets.  */
          bfd_size_type size;  /* Octets.  */
-         unsigned int opb = bfd_octets_per_byte (obfd, osections[c - 1]);
+         unsigned int opb = bfd_octets_per_byte (obfd, osections[num_sec - 1]);
          bfd_vma _pad_to = pad_to * opb;
 
-         lma = bfd_section_lma (osections[c - 1]) * opb;
-         size = bfd_section_size (osections[c - 1]);
+         lma = bfd_section_lma (osections[num_sec - 1]) * opb;
+         size = bfd_section_size (osections[num_sec - 1]);
          if (lma + size < _pad_to)
            {
-             if (!bfd_set_section_size (osections[c - 1], _pad_to - lma))
+             if (!bfd_set_section_size (osections[num_sec - 1], _pad_to - lma))
                {
-                 bfd_nonfatal_message (NULL, obfd, osections[c - 1],
+                 bfd_nonfatal_message (NULL, obfd, osections[num_sec - 1],
                                        _("can't add padding"));
                  status = 1;
                }
              else
                {
-                 gaps[c - 1] = _pad_to - (lma + size);
+                 gaps[num_sec - 1] = _pad_to - (lma + size);
                  if (max_gap < _pad_to - (lma + size))
                    max_gap = _pad_to - (lma + size);
                }
@@ -3376,7 +3376,7 @@ copy_object (bfd *ibfd, bfd *obfd, const bfd_arch_info_type *input_arch)
        }
     }
 
-  if (gap_fill_set || pad_to_set)
+  if (gaps != NULL)
     {
       bfd_byte *buf;
 
@@ -3386,8 +3386,7 @@ copy_object (bfd *ibfd, bfd *obfd, const bfd_arch_info_type *input_arch)
       buf = (bfd_byte *) xmalloc (max_gap);
       memset (buf, gap_fill, max_gap);
 
-      c = bfd_count_sections (obfd);
-      for (i = 0; i < c; i++)
+      for (i = 0; i < num_sec; i++)
        {
          if (gaps[i] != 0)
            {