From: Alan Modra Date: Wed, 11 Mar 2020 03:20:35 +0000 (+1030) Subject: PR25651, objcopy SIGSEGV in copy_object X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=9cc89dc0acc140cb27e21d2597af42d36444673b;p=binutils-gdb.git PR25651, objcopy SIGSEGV in copy_object 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). --- diff --git a/binutils/ChangeLog b/binutils/ChangeLog index fc456a2259d..0ca05640d82 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,12 @@ +2020-03-11 Alan Modra + + 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 * objdump.c (disassemble_section): Don't call qsort unless diff --git a/binutils/objcopy.c b/binutils/objcopy.c index 09facf0061e..e6711a99fb2 100644 --- a/binutils/objcopy.c +++ b/binutils/objcopy.c @@ -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) {