This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[vms/committed] Fix (again!) badly ordered index in VMS archives
- From: Tristan Gingold <gingold at adacore dot com>
- To: Binutils <binutils at sourceware dot org>
- Date: Wed, 17 Nov 2010 12:32:26 +0100
- Subject: [vms/committed] Fix (again!) badly ordered index in VMS archives
Hi,
I am committing this patch that partially revert my previous patch. The previous one was not totally correct as it could generate not ordered index.
I will commit it also on the branch as it fixes a bug and as it is VMS specific.
Tristan.
bfd/
2010-11-17 Tristan Gingold <gingold@adacore.com>
* vms-lib.c (vms_write_index): Add comments.
Partially revert previous patch. Free blocks later.
Index: vms-lib.c
===================================================================
RCS file: /cvs/src/src/bfd/vms-lib.c,v
retrieving revision 1.14
diff -c -r1.14 vms-lib.c
*** vms-lib.c 4 Nov 2010 16:17:44 -0000 1.14
--- vms-lib.c 17 Nov 2010 11:29:08 -0000
***************
*** 1551,1556 ****
--- 1551,1557 ----
/* Write the index. VBN is the first vbn to be used, and will contain
on return the last vbn.
+ Can be called with ABFD set to NULL just to size the index.
Return TRUE on success. */
static bfd_boolean
***************
*** 1570,1577 ****
} blk[MAX_LEVEL];
/* The kbn blocks are used to store long symbol names. */
! unsigned int kbn_sz = 0; /* Number of bytes availble in the kbn block. */
! unsigned int kbn_vbn = 0; /* VBN of the kbn block. */
unsigned char *kbn_blk = NULL; /* Contents of the kbn block. */
if (nbr == 0)
--- 1571,1578 ----
} blk[MAX_LEVEL];
/* The kbn blocks are used to store long symbol names. */
! unsigned int kbn_sz = 0; /* Number of bytes available in the kbn block. */
! unsigned int kbn_vbn = 0; /* VBN of the kbn block. */
unsigned char *kbn_blk = NULL; /* Contents of the kbn block. */
if (nbr == 0)
***************
*** 1607,1618 ****
if (is_elfidx && idx->namlen >= MAX_KEYLEN)
{
! /* If the name is too long, write it in the kbn block. */
unsigned int kl = idx->namlen;
unsigned int kl_chunk;
const char *key = idx->name;
! /* Write the name in the kbn, chunk after chunk. */
do
{
if (kbn_sz < sizeof (struct vms_kbn))
--- 1608,1619 ----
if (is_elfidx && idx->namlen >= MAX_KEYLEN)
{
! /* If the key (ie name) is too long, write it in the kbn block. */
unsigned int kl = idx->namlen;
unsigned int kl_chunk;
const char *key = idx->name;
! /* Write the key in the kbn, chunk after chunk. */
do
{
if (kbn_sz < sizeof (struct vms_kbn))
***************
*** 1807,1829 ****
return TRUE;
/* Flush. */
! for (j = level - 1; j >= 0; j--)
{
! if (j > 0)
! {
! /* Update parent block: write the new entry. */
! unsigned char *en;
! unsigned char *par;
! struct vms_rfa *rfa;
!
! en = rblk[j - 1]->keys + blk[j - 1].len;
! par = rblk[j]->keys + blk[j].len;
! memcpy (par, en, blk[j - 1].lastlen);
! rfa = (struct vms_rfa *)par;
! bfd_putl32 (blk[j - 1].vbn, rfa->vbn);
! bfd_putl16 (RFADEF__C_INDEX, rfa->offset);
! }
/* Write this block on the disk. */
bfd_putl16 (blk[j].len + blk[j].lastlen, rblk[j]->used);
if (vms_write_block (abfd, blk[j].vbn, rblk[j]) != TRUE)
--- 1808,1830 ----
return TRUE;
/* Flush. */
! for (j = 1; j < level; j++)
{
! /* Update parent block: write the new entry. */
! unsigned char *en;
! unsigned char *par;
! struct vms_rfa *rfa;
!
! en = rblk[j - 1]->keys + blk[j - 1].len;
! par = rblk[j]->keys + blk[j].len;
! memcpy (par, en, blk[j - 1].lastlen);
! rfa = (struct vms_rfa *)par;
! bfd_putl32 (blk[j - 1].vbn, rfa->vbn);
! bfd_putl16 (RFADEF__C_INDEX, rfa->offset);
! }
+ for (j = 0; j < level; j++)
+ {
/* Write this block on the disk. */
bfd_putl16 (blk[j].len + blk[j].lastlen, rblk[j]->used);
if (vms_write_block (abfd, blk[j].vbn, rblk[j]) != TRUE)
***************
*** 1832,1837 ****
--- 1833,1839 ----
free (rblk[j]);
}
+ /* Write the last kbn (if any). */
if (kbn_vbn != 0)
{
if (vms_write_block (abfd, kbn_vbn, kbn_blk) != TRUE)