[VMS/committed]: Handle dcx with only one sub-bitmap

Tristan Gingold gingold@adacore.com
Mon May 3 10:22:00 GMT 2010


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++;
  



More information about the Binutils mailing list