This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[VMS/committed]: Handle dcx with only one sub-bitmap
- From: Tristan Gingold <gingold at adacore dot com>
- To: binutils <binutils at sourceware dot org>
- Date: Mon, 3 May 2010 12:22:20 +0200
- Subject: [VMS/committed]: Handle dcx with only one sub-bitmap
Hi,
as reported on the mailing list, ld crashed while reading some compressed archives. This is because these
archives have only one sub-bitmap and in this case the 'next' field (used to point to the next sub-bitmap)
was not present (simply because it is useless). This case was not handled and this patch addresses this
issue.
Tristan.
bfd/
2010-05-03 Tristan Gingold <gingold@adacore.com>
* vms-lib.c (_bfd_vms_lib_archive_p): Adjust for a possible empty
next array.
(vms_lib_dcx): Adjust for the above change.
Index: bfd/vms-lib.c
===================================================================
RCS file: /cvs/src/src/bfd/vms-lib.c,v
retrieving revision 1.5
diff -c -r1.5 vms-lib.c
*** bfd/vms-lib.c 30 Apr 2010 12:44:50 -0000 1.5
--- bfd/vms-lib.c 3 May 2010 10:18:39 -0000
***************
*** 552,557 ****
--- 552,558 ----
struct dcxsbm_desc *sbmdesc = &tdata->dcxsbm[i];
unsigned int sbm_len;
unsigned int sbm_sz;
+ unsigned int off;
unsigned char *data = (unsigned char *)sbm;
unsigned char *buf1;
unsigned int l, j;
***************
*** 565,580 ****
sbmdesc->max_char = sbm->max_char;
sbm_len = sbmdesc->max_char - sbmdesc->min_char + 1;
l = (2 * sbm_len + 7) / 8;
! BFD_ASSERT (sbm_sz >= sizeof (struct vms_dcxsbm) + l + 3 * sbm_len);
sbmdesc->flags = (unsigned char *)bfd_alloc (abfd, l);
memcpy (sbmdesc->flags, data + bfd_getl16 (sbm->flags), l);
sbmdesc->nodes = (unsigned char *)bfd_alloc (abfd, 2 * sbm_len);
memcpy (sbmdesc->nodes, data + bfd_getl16 (sbm->nodes), 2 * sbm_len);
! sbmdesc->next = (unsigned short *)bfd_alloc
! (abfd, sbm_len * sizeof (unsigned short));
! buf1 = data + bfd_getl16 (sbm->next);
! for (j = 0; j < sbm_len; j++)
! sbmdesc->next[j] = bfd_getl16 (buf1 + j * 2);
}
free (buf);
}
--- 566,593 ----
sbmdesc->max_char = sbm->max_char;
sbm_len = sbmdesc->max_char - sbmdesc->min_char + 1;
l = (2 * sbm_len + 7) / 8;
! BFD_ASSERT
! (sbm_sz >= sizeof (struct vms_dcxsbm) + l + 3 * sbm_len
! || (tdata->nbr_dcxsbm == 1
! && sbm_sz >= sizeof (struct vms_dcxsbm) + l + sbm_len));
sbmdesc->flags = (unsigned char *)bfd_alloc (abfd, l);
memcpy (sbmdesc->flags, data + bfd_getl16 (sbm->flags), l);
sbmdesc->nodes = (unsigned char *)bfd_alloc (abfd, 2 * sbm_len);
memcpy (sbmdesc->nodes, data + bfd_getl16 (sbm->nodes), 2 * sbm_len);
! off = bfd_getl16 (sbm->next);
! if (off != 0)
! {
! sbmdesc->next = (unsigned short *)bfd_alloc
! (abfd, sbm_len * sizeof (unsigned short));
! buf1 = data + off;
! for (j = 0; j < sbm_len; j++)
! sbmdesc->next[j] = bfd_getl16 (buf1 + j * 2);
! }
! else
! {
! BFD_ASSERT (tdata->nbr_dcxsbm == 1);
! sbmdesc->next = NULL;
! }
}
free (buf);
}
***************
*** 850,856 ****
{
unsigned char v = sbm->nodes[offset];
! sbm = vec->dcxsbms + sbm->next[v];
offset = 0;
res++;
--- 863,870 ----
{
unsigned char v = sbm->nodes[offset];
! if (sbm->next != NULL)
! sbm = vec->dcxsbms + sbm->next[v];
offset = 0;
res++;