This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[vms/committed] Handle archive long key names


Hi,

VMS ia64 archives allow long key names (ie symbols longer than 128 bytes).  This patch will make vms-lib.c
able to read them.

Tristan.

bfd/
2010-04-30  Tristan Gingold  <gingold@adacore.com>

	* vms-lib.c (vms_read_block): New function.
	(vms_traverse_index): Use vms_read_block.  Handle long key names.

include/vms/
2010-04-30  Tristan Gingold  <gingold@adacore.com>

	* lbr.h (struct vms_kbn): New structure.

Index: bfd/vms-lib.c
===================================================================
RCS file: /cvs/src/src/bfd/vms-lib.c,v
retrieving revision 1.4
diff -c -r1.4 vms-lib.c
*** bfd/vms-lib.c	30 Apr 2010 09:40:42 -0000	1.4
--- bfd/vms-lib.c	30 Apr 2010 12:27:46 -0000
***************
*** 186,191 ****
--- 186,207 ----
      }
  }
  
+ /* Read block VBN from ABFD and store it into BLK.  */
+ 
+ static bfd_boolean
+ vms_read_block (bfd *abfd, unsigned int vbn, void *blk)
+ {
+   file_ptr off;
+ 
+   /* Read the index block.  */
+   off = (vbn - 1) * VMS_BLOCK_SIZE;
+   if (bfd_seek (abfd, off, SEEK_SET) != 0
+       || bfd_bread (blk, VMS_BLOCK_SIZE, abfd) != VMS_BLOCK_SIZE)
+     return FALSE;
+ 
+   return TRUE;
+ }
+ 
  /* Read index block VBN and put the entry in **IDX (which is updated).
     If the entry is indirect, recurse.  */
  
***************
*** 198,206 ****
    unsigned char *endp;
  
    /* Read the index block.  */
!   off = (vbn - 1) * VMS_BLOCK_SIZE;
!   if (bfd_seek (abfd, off, SEEK_SET) != 0
!       || bfd_bread (&indexdef, sizeof (indexdef), abfd) != sizeof (indexdef))
      return FALSE;
  
    /* Traverse it.  */
--- 214,221 ----
    unsigned char *endp;
  
    /* Read the index block.  */
!   BFD_ASSERT (sizeof (indexdef) == VMS_BLOCK_SIZE);
!   if (!vms_read_block (abfd, vbn, &indexdef))
      return FALSE;
  
    /* Traverse it.  */
***************
*** 244,253 ****
        if (idx_vbn == 0)
          return FALSE;
  
-       /* Long symbol names are not yet supported.  */
-       if (flags & ELFIDX__SYMESC)
-         return FALSE;
- 
        if (idx_off == RFADEF__C_INDEX)
          {
            /* Indirect entry.  Recurse.  */
--- 259,264 ----
***************
*** 259,268 ****
            /* Add a new entry.  */
            char *name;
  
!           name = bfd_alloc (abfd, keylen + 1);
!           if (name == NULL)
!             return FALSE;
!           memcpy (name, keyname, keylen);
            name[keylen] = 0;
  
            if (flags & ELFIDX__LISTRFA)
--- 270,327 ----
            /* Add a new entry.  */
            char *name;
  
!           if (flags & ELFIDX__SYMESC)
!             {
!               /* Extended key name.  */
!               unsigned int noff = 0;
!               unsigned int koff;
!               unsigned int kvbn;
!               struct vms_kbn *kbn;
!               unsigned char kblk[VMS_BLOCK_SIZE];
! 
!               /* Sanity check.  */
!               if (keylen != sizeof (struct vms_kbn))
!                 return FALSE;
! 
!               kbn = (struct vms_kbn *)keyname;
!               keylen = bfd_getl16 (kbn->keylen);
! 
!               name = bfd_alloc (abfd, keylen + 1);
!               if (name == NULL)
!                 return FALSE;
!               kvbn = bfd_getl32 (kbn->rfa.vbn);
!               koff = bfd_getl16 (kbn->rfa.offset);
! 
!               /* Read the key, chunk by chunk.  */
!               do
!                 {
!                   unsigned int klen;
! 
!                   if (!vms_read_block (abfd, kvbn, kblk))
!                     return FALSE;
!                   kbn = (struct vms_kbn *)(kblk + koff);
!                   klen = bfd_getl16 (kbn->keylen);
!                   kvbn = bfd_getl32 (kbn->rfa.vbn);
!                   koff = bfd_getl16 (kbn->rfa.offset);
! 
!                   memcpy (name + noff, kbn + 1, klen);
!                   noff += klen;
!                 }
!               while (kvbn != 0);
! 
!               /* Sanity check.  */
!               if (noff != keylen)
!                 return FALSE;
!             }
!           else
!             {
!               /* Usual key name.  */
!               name = bfd_alloc (abfd, keylen + 1);
!               if (name == NULL)
!                 return FALSE;
! 
!               memcpy (name, keyname, keylen);
!             }
            name[keylen] = 0;
  
            if (flags & ELFIDX__LISTRFA)
Index: include/vms/lbr.h
===================================================================
RCS file: /cvs/src/src/include/vms/lbr.h,v
retrieving revision 1.2
diff -c -r1.2 lbr.h
*** include/vms/lbr.h	30 Apr 2010 09:40:42 -0000	1.2
--- include/vms/lbr.h	30 Apr 2010 12:27:47 -0000
***************
*** 255,260 ****
--- 255,273 ----
  #define DATA__LENGTH 512
  #define DATA__DATA 6
  
+ /* Key name block.  This is used for keys longer than 128 bytes.  */
+ 
+ struct vms_kbn
+ {
+   /* Length of the key chunk.  */
+   unsigned char keylen[2];
+ 
+   /* RFA of the next chunk.  */
+   struct vms_rfa rfa;
+ 
+   /* Followed by the key chunk.  */
+ };
+ 
  /* Module header.  */
  struct vms_mhd
  {


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]