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).
This commit is contained in:
Alan Modra
2020-03-11 13:50:35 +10:30
parent 1db6f99030
commit 9cc89dc0ac
2 changed files with 25 additions and 17 deletions

View 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> 2020-03-10 Alan Modra <amodra@gmail.com>
* objdump.c (disassemble_section): Don't call qsort unless * objdump.c (disassemble_section): Don't call qsort unless

View File

@ -2596,7 +2596,7 @@ copy_object (bfd *ibfd, bfd *obfd, const bfd_arch_info_type *input_arch)
void *dhandle; void *dhandle;
enum bfd_architecture iarch; enum bfd_architecture iarch;
unsigned int imach; unsigned int imach;
unsigned int c, i; unsigned int num_sec, i;
if (ibfd->xvec->byteorder != obfd->xvec->byteorder if (ibfd->xvec->byteorder != obfd->xvec->byteorder
&& ibfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN && 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); num_sec = bfd_count_sections (obfd);
if (c != 0 if (num_sec != 0
&& (gap_fill_set || pad_to_set)) && (gap_fill_set || pad_to_set))
{ {
asection **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. increasing the section sizes as required to fill the gaps.
We write out the gap contents below. */ We write out the gap contents below. */
osections = (asection **) xmalloc (c * sizeof (asection *)); osections = xmalloc (num_sec * sizeof (*osections));
set = osections; set = osections;
bfd_map_over_sections (obfd, get_sections, &set); 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)); gaps = xmalloc (num_sec * sizeof (*gaps));
memset (gaps, 0, c * sizeof (bfd_size_type)); memset (gaps, 0, num_sec * sizeof (*gaps));
if (gap_fill_set) if (gap_fill_set)
{ {
for (i = 0; i < c - 1; i++) for (i = 0; i < num_sec - 1; i++)
{ {
flagword flags; flagword flags;
bfd_size_type size; /* Octets. */ 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_vma lma; /* Octets. */
bfd_size_type size; /* 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; bfd_vma _pad_to = pad_to * opb;
lma = bfd_section_lma (osections[c - 1]) * opb; lma = bfd_section_lma (osections[num_sec - 1]) * opb;
size = bfd_section_size (osections[c - 1]); size = bfd_section_size (osections[num_sec - 1]);
if (lma + size < _pad_to) 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")); _("can't add padding"));
status = 1; status = 1;
} }
else else
{ {
gaps[c - 1] = _pad_to - (lma + size); gaps[num_sec - 1] = _pad_to - (lma + size);
if (max_gap < _pad_to - (lma + size)) if (max_gap < _pad_to - (lma + size))
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; 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); buf = (bfd_byte *) xmalloc (max_gap);
memset (buf, gap_fill, max_gap); memset (buf, gap_fill, max_gap);
c = bfd_count_sections (obfd); for (i = 0; i < num_sec; i++)
for (i = 0; i < c; i++)
{ {
if (gaps[i] != 0) if (gaps[i] != 0)
{ {