OSDN Git Service

daily update
[pf3gnuchains/pf3gnuchains4x.git] / bfd / vms-lib.c
index b7c8f83..b325d74 100644 (file)
@@ -1,6 +1,6 @@
 /* BFD back-end for VMS archive files.
 
-   Copyright 2010 Free Software Foundation, Inc.
+   Copyright 2010, 2011 Free Software Foundation, Inc.
    Written by Tristan Gingold <gingold@adacore.com>, AdaCore.
 
    This file is part of BFD, the Binary File Descriptor library.
@@ -703,6 +703,12 @@ _bfd_vms_lib_alpha_mkarchive (bfd *abfd)
   return _bfd_vms_lib_mkarchive (abfd, vms_lib_alpha);
 }
 
+bfd_boolean
+_bfd_vms_lib_ia64_mkarchive (bfd *abfd)
+{
+  return _bfd_vms_lib_mkarchive (abfd, vms_lib_ia64);
+}
+
 /* Find NAME in the symbol index.  Return the index.  */
 
 symindex
@@ -827,7 +833,7 @@ vms_lib_read_block (struct bfd *abfd)
    function does not handle records nor EOF.  */
 
 static file_ptr
-vms_lib_bread_raw (struct bfd *abfd, void *buf, file_ptr nbytes)
+vms_lib_bread_raw (struct bfd *abfd, unsigned char *buf, file_ptr nbytes)
 {
   struct vms_lib_iovec *vec = (struct vms_lib_iovec *) abfd->iostream;
   file_ptr res;
@@ -945,11 +951,12 @@ vms_lib_dcx (struct vms_lib_iovec *vec, unsigned char *buf, file_ptr nbytes)
 /* Standard IOVEC function.  */
 
 static file_ptr
-vms_lib_bread (struct bfd *abfd, void *buf, file_ptr nbytes)
+vms_lib_bread (struct bfd *abfd, void *vbuf, file_ptr nbytes)
 {
   struct vms_lib_iovec *vec = (struct vms_lib_iovec *) abfd->iostream;
   file_ptr res;
   file_ptr chunk;
+  unsigned char *buf = (unsigned char *)vbuf;
 
   /* Do not read past the end.  */
   if (vec->where >= vec->file_len)
@@ -963,7 +970,7 @@ vms_lib_bread (struct bfd *abfd, void *buf, file_ptr nbytes)
           unsigned char blen[2];
 
           /* Read record length.  */
-          if (vms_lib_bread_raw (abfd, &blen, sizeof (blen)) != sizeof (blen))
+          if (vms_lib_bread_raw (abfd, blen, sizeof (blen)) != sizeof (blen))
             return -1;
           vec->rec_len = bfd_getl16 (blen);
           if (bfd_libdata (abfd->my_archive)->kind == vms_lib_txt)
@@ -1065,7 +1072,7 @@ vms_lib_bread (struct bfd *abfd, void *buf, file_ptr nbytes)
             }
           if (buf != NULL)
             {
-              *(unsigned char *)buf = c;
+              *buf = c;
               buf++;
             }
           nbytes--;
@@ -1189,11 +1196,13 @@ vms_lib_bstat (struct bfd *abfd ATTRIBUTE_UNUSED,
 
 static void *
 vms_lib_bmmap (struct bfd *abfd ATTRIBUTE_UNUSED,
-             void *addr ATTRIBUTE_UNUSED,
-             bfd_size_type len ATTRIBUTE_UNUSED,
-             int prot ATTRIBUTE_UNUSED,
-             int flags ATTRIBUTE_UNUSED,
-             file_ptr offset ATTRIBUTE_UNUSED)
+               void *addr ATTRIBUTE_UNUSED,
+               bfd_size_type len ATTRIBUTE_UNUSED,
+               int prot ATTRIBUTE_UNUSED,
+               int flags ATTRIBUTE_UNUSED,
+               file_ptr offset ATTRIBUTE_UNUSED,
+               void **map_addr ATTRIBUTE_UNUSED,
+               bfd_size_type *map_len ATTRIBUTE_UNUSED)
 {
   return (void *) -1;
 }
@@ -1209,7 +1218,7 @@ static bfd_boolean
 vms_lib_bopen (bfd *el, file_ptr filepos)
 {
   struct vms_lib_iovec *vec;
-  char buf[256];
+  unsigned char buf[256];
   struct vms_mhd *mhd;
   struct lib_tdata *tdata = bfd_libdata (el->my_archive);
   unsigned int len;
@@ -1533,17 +1542,24 @@ get_idxlen (struct lib_index *idx, bfd_boolean is_elfidx)
 {
   if (is_elfidx)
     {
+      /* 9 is the size of struct vms_elfidx without keyname.  */
       if (idx->namlen > MAX_KEYLEN)
-        return 9 + sizeof (struct vms_rfa);
+        return 9 + sizeof (struct vms_kbn);
       else
         return 9 + idx->namlen;
     }
   else
-    return 7 + idx->namlen;
+    {
+      /* 7 is the size of struct vms_idx without keyname.  */
+      return 7 + idx->namlen;
+    }
 }
 
-/* Write the index.  VBN is the first vbn to be used, and will contain
-   on return the last vbn.
+/* Write the index composed by NBR symbols contained in IDX.
+   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.
+   If not null, TOPVBN will be assigned to the vbn of the root index tree.
+   IS_ELFIDX is true for elfidx (ie ia64) indexes layout.
    Return TRUE on success.  */
 
 static bfd_boolean
@@ -1563,8 +1579,8 @@ vms_write_index (bfd *abfd,
   } 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 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)
@@ -1584,7 +1600,7 @@ vms_write_index (bfd *abfd,
   /* Allocate first index block.  */
   level = 1;
   if (abfd != NULL)
-    rblk[0] = bfd_malloc (sizeof (struct vms_indexdef));
+    rblk[0] = bfd_zmalloc (sizeof (struct vms_indexdef));
   blk[0].vbn = (*vbn)++;
   blk[0].len = 0;
   blk[0].lastlen = 0;
@@ -1600,12 +1616,12 @@ vms_write_index (bfd *abfd,
 
       if (is_elfidx && idx->namlen >= MAX_KEYLEN)
         {
-          /* If the name is too long, write it in the kbn block.  */
+          /* 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 name in the kbn, chunk after chunk.  */
+          /* Write the key in the kbn, chunk after chunk.  */
           do
             {
               if (kbn_sz < sizeof (struct vms_kbn))
@@ -1627,9 +1643,11 @@ vms_write_index (bfd *abfd,
                         }
                       *(unsigned short *)kbn_blk = 0;
                     }
+                  /* Allocate a new block for the keys.  */
                   kbn_vbn = (*vbn)++;
                   kbn_sz = VMS_BLOCK_SIZE - 2;
                 }
+              /* Size of the chunk written to the current key block.  */
               if (kl + sizeof (struct vms_kbn) > kbn_sz)
                 kl_chunk = kbn_sz - sizeof (struct vms_kbn);
               else
@@ -1691,7 +1709,7 @@ vms_write_index (bfd *abfd,
                   /* Need to create a parent.  */
                   if (abfd != NULL)
                     {
-                      rblk[level] = bfd_malloc (sizeof (struct vms_indexdef));
+                      rblk[level] = bfd_zmalloc (sizeof (struct vms_indexdef));
                       bfd_putl32 (*vbn, rblk[j]->parent);
                     }
                   blk[level].vbn = (*vbn)++;
@@ -1710,7 +1728,8 @@ vms_write_index (bfd *abfd,
                   memcpy (rblk[j + 1]->keys + blk[j + 1].len,
                           rblk[j]->keys + blk[j].len,
                           blk[j].lastlen);
-                  /* Fix the entry (which in always the first field of an entry.  */
+                  /* Fix the entry (which in always the first field of an
+                    entry.  */
                   rfa = (struct vms_rfa *)(rblk[j + 1]->keys + blk[j + 1].len);
                   bfd_putl32 (blk[j].vbn, rfa->vbn);
                   bfd_putl16 (RFADEF__C_INDEX, rfa->offset);
@@ -1799,23 +1818,23 @@ vms_write_index (bfd *abfd,
     return TRUE;
 
   /* Flush.  */
-  for (j = 0; j < level; j++)
+  for (j = 1; j < level; 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);
-        }
+      /* 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)
@@ -1824,6 +1843,7 @@ vms_write_index (bfd *abfd,
       free (rblk[j]);
     }
 
+  /* Write the last kbn (if any).  */
   if (kbn_vbn != 0)
     {
       if (vms_write_block (abfd, kbn_vbn, kbn_blk) != TRUE)
@@ -2105,6 +2125,7 @@ _bfd_vms_lib_write_archive_contents (bfd *arch)
           /* Write the first block (which contains an mhd).  */
           if (bfd_bwrite (blk, VMS_BLOCK_SIZE, arch) != VMS_BLOCK_SIZE)
             goto input_err;
+          off += VMS_BLOCK_SIZE;
 
           if (amt == VMS_BLOCK_SIZE - sz)
             {
@@ -2257,6 +2278,7 @@ const bfd_target vms_lib_txt_vec =
   0,                           /* symbol_leading_char.  */
   ' ',                         /* ar_pad_char.  */
   15,                          /* ar_max_namelen.  */
+  0,                           /* match priority.  */
   bfd_getl64, bfd_getl_signed_64, bfd_putl64,
   bfd_getl32, bfd_getl_signed_32, bfd_putl32,
   bfd_getl16, bfd_getl_signed_16, bfd_putl16,