[BACK]Return to vms-lib.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / external / gpl3 / binutils.old / dist / bfd

Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.

Diff for /src/external/gpl3/binutils.old/dist/bfd/vms-lib.c between version 1.5 and 1.6

version 1.5, 2018/04/14 15:49:39 version 1.6, 2020/04/03 17:51:05
Line 1 
Line 1 
 /* BFD back-end for VMS archive files.  /* BFD back-end for VMS archive files.
   
    Copyright (C) 2010-2016 Free Software Foundation, Inc.     Copyright (C) 2010-2018 Free Software Foundation, Inc.
    Written by Tristan Gingold <gingold@adacore.com>, AdaCore.     Written by Tristan Gingold <gingold@adacore.com>, AdaCore.
   
    This file is part of BFD, the Binary File Descriptor library.     This file is part of BFD, the Binary File Descriptor library.
Line 129  struct carsym_mem
Line 129  struct carsym_mem
   
 static bfd_boolean  static bfd_boolean
 vms_add_index (struct carsym_mem *cs, char *name,  vms_add_index (struct carsym_mem *cs, char *name,
                unsigned int idx_vbn, unsigned int idx_off)                 unsigned int idx_vbn, unsigned int idx_off)
 {  {
   if (cs->nbr == cs->max)    if (cs->nbr == cs->max)
     {      {
Line 138  vms_add_index (struct carsym_mem *cs, ch
Line 138  vms_add_index (struct carsym_mem *cs, ch
       cs->max = 2 * cs->max + 32;        cs->max = 2 * cs->max + 32;
   
       if (!cs->realloced)        if (!cs->realloced)
         {          {
           n = bfd_malloc2 (cs->max, sizeof (struct carsym));            n = bfd_malloc2 (cs->max, sizeof (struct carsym));
           if (n == NULL)            if (n == NULL)
             return FALSE;              return FALSE;
           memcpy (n, cs->idx, cs->nbr * sizeof (struct carsym));            memcpy (n, cs->idx, cs->nbr * sizeof (struct carsym));
           /* And unfortunately we can't free cs->idx.  */            /* And unfortunately we can't free cs->idx.  */
         }          }
       else        else
         {          {
           n = bfd_realloc_or_free (cs->idx, cs->nbr * sizeof (struct carsym));            n = bfd_realloc_or_free (cs->idx, cs->nbr * sizeof (struct carsym));
           if (n == NULL)            if (n == NULL)
             return FALSE;              return FALSE;
         }          }
       cs->idx = n;        cs->idx = n;
       cs->realloced = TRUE;        cs->realloced = TRUE;
     }      }
Line 165  vms_add_index (struct carsym_mem *cs, ch
Line 165  vms_add_index (struct carsym_mem *cs, ch
   
 static bfd_boolean  static bfd_boolean
 vms_add_indexes_from_list (bfd *abfd, struct carsym_mem *cs, char *name,  vms_add_indexes_from_list (bfd *abfd, struct carsym_mem *cs, char *name,
                            struct vms_rfa *rfa)                             struct vms_rfa *rfa)
 {  {
   struct vms_lns lns;    struct vms_lns lns;
   unsigned int vbn;    unsigned int vbn;
Line 175  vms_add_indexes_from_list (bfd *abfd, st
Line 175  vms_add_indexes_from_list (bfd *abfd, st
     {      {
       vbn = bfd_getl32 (rfa->vbn);        vbn = bfd_getl32 (rfa->vbn);
       if (vbn == 0)        if (vbn == 0)
         return TRUE;          return TRUE;
   
       /* Read the LHS.  */        /* Read the LHS.  */
       off = (vbn - 1) * VMS_BLOCK_SIZE + bfd_getl16 (rfa->offset);        off = (vbn - 1) * VMS_BLOCK_SIZE + bfd_getl16 (rfa->offset);
       if (bfd_seek (abfd, off, SEEK_SET) != 0        if (bfd_seek (abfd, off, SEEK_SET) != 0
           || bfd_bread (&lns, sizeof (lns), abfd) != sizeof (lns))            || bfd_bread (&lns, sizeof (lns), abfd) != sizeof (lns))
         return FALSE;          return FALSE;
   
       if (!vms_add_index (cs, name,        if (!vms_add_index (cs, name,
                           bfd_getl32 (lns.modrfa.vbn),                            bfd_getl32 (lns.modrfa.vbn),
                           bfd_getl16 (lns.modrfa.offset)))                            bfd_getl16 (lns.modrfa.offset)))
         return FALSE;          return FALSE;
   
       rfa = &lns.nxtrfa;        rfa = &lns.nxtrfa;
     }      }
Line 251  vms_traverse_index (bfd *abfd, unsigned 
Line 251  vms_traverse_index (bfd *abfd, unsigned 
   
       /* Extract key length.  */        /* Extract key length.  */
       if (bfd_libdata (abfd)->ver == LBR_MAJORID)        if (bfd_libdata (abfd)->ver == LBR_MAJORID)
         {          {
           struct vms_idx *ridx = (struct vms_idx *)p;            struct vms_idx *ridx = (struct vms_idx *)p;
   
           idx_vbn = bfd_getl32 (ridx->rfa.vbn);            idx_vbn = bfd_getl32 (ridx->rfa.vbn);
           idx_off = bfd_getl16 (ridx->rfa.offset);            idx_off = bfd_getl16 (ridx->rfa.offset);
   
           keylen = ridx->keylen;            keylen = ridx->keylen;
           flags = 0;            flags = 0;
           keyname = ridx->keyname;            keyname = ridx->keyname;
         }          }
       else if (bfd_libdata (abfd)->ver == LBR_ELFMAJORID)        else if (bfd_libdata (abfd)->ver == LBR_ELFMAJORID)
         {          {
           struct vms_elfidx *ridx = (struct vms_elfidx *)p;            struct vms_elfidx *ridx = (struct vms_elfidx *)p;
   
           idx_vbn = bfd_getl32 (ridx->rfa.vbn);            idx_vbn = bfd_getl32 (ridx->rfa.vbn);
           idx_off = bfd_getl16 (ridx->rfa.offset);            idx_off = bfd_getl16 (ridx->rfa.offset);
   
           keylen = bfd_getl16 (ridx->keylen);            keylen = bfd_getl16 (ridx->keylen);
           flags = ridx->flags;            flags = ridx->flags;
           keyname = ridx->keyname;            keyname = ridx->keyname;
         }          }
       else        else
         return FALSE;          return FALSE;
   
       /* Illegal value.  */        /* Illegal value.  */
       if (idx_vbn == 0)        if (idx_vbn == 0)
         return FALSE;          return FALSE;
   
       /* Point to the next index entry.  */        /* Point to the next index entry.  */
       p = keyname + keylen;        p = keyname + keylen;
   
       if (idx_off == RFADEF__C_INDEX)        if (idx_off == RFADEF__C_INDEX)
         {          {
           /* Indirect entry.  Recurse.  */            /* Indirect entry.  Recurse.  */
           if (!vms_traverse_index (abfd, idx_vbn, cs))            if (!vms_traverse_index (abfd, idx_vbn, cs))
             return FALSE;              return FALSE;
         }          }
       else        else
         {          {
           /* Add a new entry.  */            /* Add a new entry.  */
           char *name;            char *name;
   
           if (flags & ELFIDX__SYMESC)            if (flags & ELFIDX__SYMESC)
             {              {
               /* Extended key name.  */                /* Extended key name.  */
               unsigned int noff = 0;                unsigned int noff = 0;
               unsigned int koff;                unsigned int koff;
               unsigned int kvbn;                unsigned int kvbn;
               struct vms_kbn *kbn;                struct vms_kbn *kbn;
               unsigned char kblk[VMS_BLOCK_SIZE];                unsigned char kblk[VMS_BLOCK_SIZE];
   
               /* Sanity check.  */                /* Sanity check.  */
               if (keylen != sizeof (struct vms_kbn))                if (keylen != sizeof (struct vms_kbn))
                 return FALSE;                  return FALSE;
   
               kbn = (struct vms_kbn *)keyname;                kbn = (struct vms_kbn *)keyname;
               keylen = bfd_getl16 (kbn->keylen);                keylen = bfd_getl16 (kbn->keylen);
   
               name = bfd_alloc (abfd, keylen + 1);                name = bfd_alloc (abfd, keylen + 1);
               if (name == NULL)                if (name == NULL)
                 return FALSE;                  return FALSE;
               kvbn = bfd_getl32 (kbn->rfa.vbn);                kvbn = bfd_getl32 (kbn->rfa.vbn);
               koff = bfd_getl16 (kbn->rfa.offset);                koff = bfd_getl16 (kbn->rfa.offset);
   
               /* Read the key, chunk by chunk.  */                /* Read the key, chunk by chunk.  */
               do                do
                 {                  {
                   unsigned int klen;                    unsigned int klen;
   
                   if (!vms_read_block (abfd, kvbn, kblk))                    if (!vms_read_block (abfd, kvbn, kblk))
                     return FALSE;                      return FALSE;
                   kbn = (struct vms_kbn *)(kblk + koff);                    kbn = (struct vms_kbn *)(kblk + koff);
                   klen = bfd_getl16 (kbn->keylen);                    klen = bfd_getl16 (kbn->keylen);
                   kvbn = bfd_getl32 (kbn->rfa.vbn);                    kvbn = bfd_getl32 (kbn->rfa.vbn);
                   koff = bfd_getl16 (kbn->rfa.offset);                    koff = bfd_getl16 (kbn->rfa.offset);
   
                   memcpy (name + noff, kbn + 1, klen);                    memcpy (name + noff, kbn + 1, klen);
                   noff += klen;                    noff += klen;
                 }                  }
               while (kvbn != 0);                while (kvbn != 0);
   
               /* Sanity check.  */                /* Sanity check.  */
               if (noff != keylen)                if (noff != keylen)
                 return FALSE;                  return FALSE;
             }              }
           else            else
             {              {
               /* Usual key name.  */                /* Usual key name.  */
               name = bfd_alloc (abfd, keylen + 1);                name = bfd_alloc (abfd, keylen + 1);
               if (name == NULL)                if (name == NULL)
                 return FALSE;                  return FALSE;
   
               memcpy (name, keyname, keylen);                memcpy (name, keyname, keylen);
             }              }
           name[keylen] = 0;            name[keylen] = 0;
   
           if (flags & ELFIDX__LISTRFA)            if (flags & ELFIDX__LISTRFA)
             {              {
               struct vms_lhs lhs;                struct vms_lhs lhs;
   
               /* Read the LHS.  */                /* Read the LHS.  */
               off = (idx_vbn - 1) * VMS_BLOCK_SIZE + idx_off;                off = (idx_vbn - 1) * VMS_BLOCK_SIZE + idx_off;
               if (bfd_seek (abfd, off, SEEK_SET) != 0                if (bfd_seek (abfd, off, SEEK_SET) != 0
                   || bfd_bread (&lhs, sizeof (lhs), abfd) != sizeof (lhs))                    || bfd_bread (&lhs, sizeof (lhs), abfd) != sizeof (lhs))
                 return FALSE;                  return FALSE;
   
               /* FIXME: this adds extra entries that were not accounted.  */                /* FIXME: this adds extra entries that were not accounted.  */
               if (!vms_add_indexes_from_list (abfd, cs, name, &lhs.ng_g_rfa))                if (!vms_add_indexes_from_list (abfd, cs, name, &lhs.ng_g_rfa))
                 return FALSE;                  return FALSE;
               if (!vms_add_indexes_from_list (abfd, cs, name, &lhs.ng_wk_rfa))                if (!vms_add_indexes_from_list (abfd, cs, name, &lhs.ng_wk_rfa))
                 return FALSE;                  return FALSE;
               if (!vms_add_indexes_from_list (abfd, cs, name, &lhs.g_g_rfa))                if (!vms_add_indexes_from_list (abfd, cs, name, &lhs.g_g_rfa))
                 return FALSE;                  return FALSE;
               if (!vms_add_indexes_from_list (abfd, cs, name, &lhs.g_wk_rfa))                if (!vms_add_indexes_from_list (abfd, cs, name, &lhs.g_wk_rfa))
                 return FALSE;                  return FALSE;
             }              }
           else            else
             {              {
               if (!vms_add_index (cs, name, idx_vbn, idx_off))                if (!vms_add_index (cs, name, idx_vbn, idx_off))
                 return FALSE;                  return FALSE;
             }              }
         }          }
     }      }
   
   return TRUE;    return TRUE;
Line 414  vms_lib_read_index (bfd *abfd, int idx, 
Line 414  vms_lib_read_index (bfd *abfd, int idx, 
   if (vbn != 0 && !vms_traverse_index (abfd, vbn, &csm))    if (vbn != 0 && !vms_traverse_index (abfd, vbn, &csm))
     {      {
       if (csm.realloced && csm.idx != NULL)        if (csm.realloced && csm.idx != NULL)
         free (csm.idx);          free (csm.idx);
   
       /* Note: in case of error, we can free what was allocated on the        /* Note: in case of error, we can free what was allocated on the
          BFD's objalloc.  */           BFD's objalloc.  */
       bfd_release (abfd, csbuf);        bfd_release (abfd, csbuf);
       return NULL;        return NULL;
     }      }
Line 425  vms_lib_read_index (bfd *abfd, int idx, 
Line 425  vms_lib_read_index (bfd *abfd, int idx, 
   if (csm.realloced)    if (csm.realloced)
     {      {
       /* There are more entries than the first estimate.  Allocate on        /* There are more entries than the first estimate.  Allocate on
          the BFD's objalloc.  */           the BFD's objalloc.  */
       csbuf = bfd_alloc (abfd, csm.nbr * sizeof (struct carsym));        csbuf = bfd_alloc (abfd, csm.nbr * sizeof (struct carsym));
       if (csbuf == NULL)        if (csbuf == NULL)
         return NULL;          return NULL;
       memcpy (csbuf, csm.idx, csm.nbr * sizeof (struct carsym));        memcpy (csbuf, csm.idx, csm.nbr * sizeof (struct carsym));
       free (csm.idx);        free (csm.idx);
       *nbrel = csm.nbr;        *nbrel = csm.nbr;
Line 460  _bfd_vms_lib_archive_p (bfd *abfd, enum 
Line 460  _bfd_vms_lib_archive_p (bfd *abfd, enum 
   /* Check sanity (= magic) number.  */    /* Check sanity (= magic) number.  */
   sanity = bfd_getl32 (lhd.sanity);    sanity = bfd_getl32 (lhd.sanity);
   if (!(sanity == LHD_SANEID3    if (!(sanity == LHD_SANEID3
         || sanity == LHD_SANEID6          || sanity == LHD_SANEID6
         || sanity == LHD_SANEID_DCX))          || sanity == LHD_SANEID_DCX))
     {      {
       bfd_set_error (bfd_error_wrong_format);        bfd_set_error (bfd_error_wrong_format);
       return NULL;        return NULL;
Line 473  _bfd_vms_lib_archive_p (bfd *abfd, enum 
Line 473  _bfd_vms_lib_archive_p (bfd *abfd, enum 
     {      {
     case vms_lib_alpha:      case vms_lib_alpha:
       if ((lhd.type != LBR__C_TYP_EOBJ && lhd.type != LBR__C_TYP_ESHSTB)        if ((lhd.type != LBR__C_TYP_EOBJ && lhd.type != LBR__C_TYP_ESHSTB)
           || majorid != LBR_MAJORID            || majorid != LBR_MAJORID
           || lhd.nindex != 2)            || lhd.nindex != 2)
         {          {
           bfd_set_error (bfd_error_wrong_format);            bfd_set_error (bfd_error_wrong_format);
           return NULL;            return NULL;
         }          }
       break;        break;
     case vms_lib_ia64:      case vms_lib_ia64:
       if ((lhd.type != LBR__C_TYP_IOBJ && lhd.type != LBR__C_TYP_ISHSTB)        if ((lhd.type != LBR__C_TYP_IOBJ && lhd.type != LBR__C_TYP_ISHSTB)
           || majorid != LBR_ELFMAJORID            || majorid != LBR_ELFMAJORID
           || lhd.nindex != 2)            || lhd.nindex != 2)
         {          {
           bfd_set_error (bfd_error_wrong_format);            bfd_set_error (bfd_error_wrong_format);
           return NULL;            return NULL;
         }          }
       break;        break;
     case vms_lib_txt:      case vms_lib_txt:
       if ((lhd.type != LBR__C_TYP_TXT        if ((lhd.type != LBR__C_TYP_TXT
            && lhd.type != LBR__C_TYP_MLB             && lhd.type != LBR__C_TYP_MLB
            && lhd.type != LBR__C_TYP_HLP)             && lhd.type != LBR__C_TYP_HLP)
           || majorid != LBR_MAJORID            || majorid != LBR_MAJORID
           || lhd.nindex != 1)            || lhd.nindex != 1)
         {          {
           bfd_set_error (bfd_error_wrong_format);            bfd_set_error (bfd_error_wrong_format);
           return NULL;            return NULL;
         }          }
       break;        break;
     default:      default:
       abort ();        abort ();
Line 529  _bfd_vms_lib_archive_p (bfd *abfd, enum 
Line 529  _bfd_vms_lib_archive_p (bfd *abfd, enum 
       nbr_ent = tdata->artdata.symdef_count;        nbr_ent = tdata->artdata.symdef_count;
       tdata->artdata.symdefs = vms_lib_read_index (abfd, 1, &nbr_ent);        tdata->artdata.symdefs = vms_lib_read_index (abfd, 1, &nbr_ent);
       if (tdata->artdata.symdefs == NULL)        if (tdata->artdata.symdefs == NULL)
         goto err;          goto err;
       /* Only IA64 archives may have more entries in the index that what        /* Only IA64 archives may have more entries in the index that what
          was declared.  */           was declared.  */
       if (nbr_ent != tdata->artdata.symdef_count        if (nbr_ent != tdata->artdata.symdef_count
           && kind != vms_lib_ia64)            && kind != vms_lib_ia64)
         goto err;          goto err;
       tdata->artdata.symdef_count = nbr_ent;        tdata->artdata.symdef_count = nbr_ent;
     }      }
   tdata->cache = bfd_zalloc (abfd, sizeof (bfd *) * tdata->nbr_modules);    tdata->cache = bfd_zalloc (abfd, sizeof (bfd *) * tdata->nbr_modules);
Line 553  _bfd_vms_lib_archive_p (bfd *abfd, enum 
Line 553  _bfd_vms_lib_archive_p (bfd *abfd, enum 
       unsigned int i;        unsigned int i;
   
       if (bfd_seek (abfd, (dcxvbn - 1) * VMS_BLOCK_SIZE, SEEK_SET) != 0        if (bfd_seek (abfd, (dcxvbn - 1) * VMS_BLOCK_SIZE, SEEK_SET) != 0
           || bfd_bread (buf_reclen, sizeof (buf_reclen), abfd)            || bfd_bread (buf_reclen, sizeof (buf_reclen), abfd)
           != sizeof (buf_reclen))            != sizeof (buf_reclen))
         goto err;          goto err;
       reclen = bfd_getl32 (buf_reclen);        reclen = bfd_getl32 (buf_reclen);
       buf = bfd_malloc (reclen);        buf = bfd_malloc (reclen);
       if (buf == NULL)        if (buf == NULL)
         goto err;          goto err;
       if (bfd_bread (buf, reclen, abfd) != reclen)        if (bfd_bread (buf, reclen, abfd) != reclen)
         {          {
           free (buf);            free (buf);
           goto err;            goto err;
         }          }
       map = (struct vms_dcxmap *)buf;        map = (struct vms_dcxmap *)buf;
       tdata->nbr_dcxsbm = bfd_getl16 (map->nsubs);        tdata->nbr_dcxsbm = bfd_getl16 (map->nsubs);
       sbm_off = bfd_getl16 (map->sub0);        sbm_off = bfd_getl16 (map->sub0);
       tdata->dcxsbm = (struct dcxsbm_desc *)bfd_alloc        tdata->dcxsbm = (struct dcxsbm_desc *)bfd_alloc
         (abfd, tdata->nbr_dcxsbm * sizeof (struct dcxsbm_desc));          (abfd, tdata->nbr_dcxsbm * sizeof (struct dcxsbm_desc));
       for (i = 0; i < tdata->nbr_dcxsbm; i++)        for (i = 0; i < tdata->nbr_dcxsbm; i++)
         {          {
           struct vms_dcxsbm *sbm = (struct vms_dcxsbm *) (buf + sbm_off);            struct vms_dcxsbm *sbm = (struct vms_dcxsbm *) (buf + sbm_off);
           struct dcxsbm_desc *sbmdesc = &tdata->dcxsbm[i];            struct dcxsbm_desc *sbmdesc = &tdata->dcxsbm[i];
           unsigned int sbm_len;            unsigned int sbm_len;
           unsigned int sbm_sz;            unsigned int sbm_sz;
           unsigned int off;            unsigned int off;
           unsigned char *data = (unsigned char *)sbm;            unsigned char *data = (unsigned char *)sbm;
           unsigned char *buf1;            unsigned char *buf1;
           unsigned int l, j;            unsigned int l, j;
   
           sbm_sz = bfd_getl16 (sbm->size);            sbm_sz = bfd_getl16 (sbm->size);
           sbm_off += sbm_sz;            sbm_off += sbm_sz;
           BFD_ASSERT (sbm_off <= reclen);            BFD_ASSERT (sbm_off <= reclen);
   
           sbmdesc->min_char = sbm->min_char;            sbmdesc->min_char = sbm->min_char;
           BFD_ASSERT (sbmdesc->min_char == 0);            BFD_ASSERT (sbmdesc->min_char == 0);
           sbmdesc->max_char = sbm->max_char;            sbmdesc->max_char = sbm->max_char;
           sbm_len = sbmdesc->max_char - sbmdesc->min_char + 1;            sbm_len = sbmdesc->max_char - sbmdesc->min_char + 1;
           l = (2 * sbm_len + 7) / 8;            l = (2 * sbm_len + 7) / 8;
           BFD_ASSERT            BFD_ASSERT
             (sbm_sz >= sizeof (struct vms_dcxsbm) + l + 3 * sbm_len              (sbm_sz >= sizeof (struct vms_dcxsbm) + l + 3 * sbm_len
              || (tdata->nbr_dcxsbm == 1               || (tdata->nbr_dcxsbm == 1
                  && sbm_sz >= sizeof (struct vms_dcxsbm) + l + sbm_len));                   && sbm_sz >= sizeof (struct vms_dcxsbm) + l + sbm_len));
           sbmdesc->flags = (unsigned char *)bfd_alloc (abfd, l);            sbmdesc->flags = (unsigned char *)bfd_alloc (abfd, l);
           memcpy (sbmdesc->flags, data + bfd_getl16 (sbm->flags), l);            memcpy (sbmdesc->flags, data + bfd_getl16 (sbm->flags), l);
           sbmdesc->nodes = (unsigned char *)bfd_alloc (abfd, 2 * sbm_len);            sbmdesc->nodes = (unsigned char *)bfd_alloc (abfd, 2 * sbm_len);
           memcpy (sbmdesc->nodes, data + bfd_getl16 (sbm->nodes), 2 * sbm_len);            memcpy (sbmdesc->nodes, data + bfd_getl16 (sbm->nodes), 2 * sbm_len);
           off = bfd_getl16 (sbm->next);            off = bfd_getl16 (sbm->next);
           if (off != 0)            if (off != 0)
             {              {
               /* Read the 'next' array.  */                /* Read the 'next' array.  */
               sbmdesc->next = (unsigned short *)bfd_alloc                sbmdesc->next = (unsigned short *)bfd_alloc
                 (abfd, sbm_len * sizeof (unsigned short));                  (abfd, sbm_len * sizeof (unsigned short));
               buf1 = data + off;                buf1 = data + off;
               for (j = 0; j < sbm_len; j++)                for (j = 0; j < sbm_len; j++)
                 sbmdesc->next[j] = bfd_getl16 (buf1 + j * 2);                  sbmdesc->next[j] = bfd_getl16 (buf1 + j * 2);
             }              }
           else            else
             {              {
               /* There is no next array if there is only one submap.  */                /* There is no next array if there is only one submap.  */
               BFD_ASSERT (tdata->nbr_dcxsbm == 1);                BFD_ASSERT (tdata->nbr_dcxsbm == 1);
               sbmdesc->next = NULL;                sbmdesc->next = NULL;
             }              }
         }          }
       free (buf);        free (buf);
     }      }
   else    else
Line 731  _bfd_vms_lib_find_symbol (bfd *abfd, con
Line 731  _bfd_vms_lib_find_symbol (bfd *abfd, con
   
       diff = (char)(name[0] - syms[mid].name[0]);        diff = (char)(name[0] - syms[mid].name[0]);
       if (diff == 0)        if (diff == 0)
         diff = strcmp (name, syms[mid].name);          diff = strcmp (name, syms[mid].name);
       if (diff == 0)        if (diff == 0)
         return mid;          return mid;
       else if (diff < 0)        else if (diff < 0)
         hi = mid - 1;          hi = mid - 1;
       else        else
         lo = mid + 1;          lo = mid + 1;
     }      }
   return BFD_NO_MORE_SYMBOLS;    return BFD_NO_MORE_SYMBOLS;
 }  }
Line 821  vms_lib_read_block (struct bfd *abfd)
Line 821  vms_lib_read_block (struct bfd *abfd)
   
       /* Read next block.  */        /* Read next block.  */
       if (bfd_seek (abfd->my_archive, vec->next_block, SEEK_SET) != 0)        if (bfd_seek (abfd->my_archive, vec->next_block, SEEK_SET) != 0)
         return FALSE;          return FALSE;
       if (bfd_bread (hdr, sizeof (hdr), abfd->my_archive) != sizeof (hdr))        if (bfd_bread (hdr, sizeof (hdr), abfd->my_archive) != sizeof (hdr))
         return FALSE;          return FALSE;
       vec->next_block = (bfd_getl32 (hdr + 2) - 1) * VMS_BLOCK_SIZE;        vec->next_block = (bfd_getl32 (hdr + 2) - 1) * VMS_BLOCK_SIZE;
       vec->blk_off = sizeof (hdr);        vec->blk_off = sizeof (hdr);
     }      }
Line 847  vms_lib_bread_raw (struct bfd *abfd, uns
Line 847  vms_lib_bread_raw (struct bfd *abfd, uns
   
       /* Be sure the current data block is read.  */        /* Be sure the current data block is read.  */
       if (!vms_lib_read_block (abfd))        if (!vms_lib_read_block (abfd))
         return -1;          return -1;
   
       /* Do not read past the data block, do not read more than requested.  */        /* Do not read past the data block, do not read more than requested.  */
       l = DATA__LENGTH - vec->blk_off;        l = DATA__LENGTH - vec->blk_off;
       if (l > nbytes)        if (l > nbytes)
         l = nbytes;          l = nbytes;
       if (l == 0)        if (l == 0)
         return 0;          return 0;
       if (buf != NULL)        if (buf != NULL)
         {          {
           /* Really read into BUF.  */            /* Really read into BUF.  */
           if (bfd_bread (buf, l, abfd->my_archive) != l)            if (bfd_bread (buf, l, abfd->my_archive) != l)
             return -1;              return -1;
         }          }
       else        else
         {          {
           /* Make as if we are reading.  */            /* Make as if we are reading.  */
           if (bfd_seek (abfd->my_archive, l, SEEK_CUR) != 0)            if (bfd_seek (abfd->my_archive, l, SEEK_CUR) != 0)
             return -1;              return -1;
         }          }
   
       if (buf != NULL)        if (buf != NULL)
         buf += l;          buf += l;
       vec->blk_off += l;        vec->blk_off += l;
       nbytes -= l;        nbytes -= l;
       res += l;        res += l;
Line 902  vms_lib_dcx (struct vms_lib_iovec *vec, 
Line 902  vms_lib_dcx (struct vms_lib_iovec *vec, 
       unsigned char b = vec->dcx_buf[i];        unsigned char b = vec->dcx_buf[i];
   
       for (; j < 8; j++)        for (; j < 8; j++)
         {          {
           if (b & (1 << j))            if (b & (1 << j))
             offset++;              offset++;
           if (!(sbm->flags[offset >> 3] & (1 << (offset & 7))))            if (!(sbm->flags[offset >> 3] & (1 << (offset & 7))))
             {              {
               unsigned int n_offset = sbm->nodes[offset];                unsigned int n_offset = sbm->nodes[offset];
               if (n_offset == 0)                if (n_offset == 0)
                 {                  {
                   /* End of buffer.  Stay where we are.  */                    /* End of buffer.  Stay where we are.  */
                   vec->dcx_pos = (i << 3) + j;                    vec->dcx_pos = (i << 3) + j;
                   if (b & (1 << j))                    if (b & (1 << j))
                     offset--;                      offset--;
                   vec->dcx_offset = offset;                    vec->dcx_offset = offset;
                   vec->dcx_sbm = sbm;                    vec->dcx_sbm = sbm;
                   return res;                    return res;
                 }                  }
               offset = 2 * n_offset;                offset = 2 * n_offset;
             }              }
           else            else
             {              {
               unsigned char v = sbm->nodes[offset];                unsigned char v = sbm->nodes[offset];
   
               if (sbm->next != NULL)                if (sbm->next != NULL)
                 sbm = vec->dcxsbms + sbm->next[v];                  sbm = vec->dcxsbms + sbm->next[v];
               offset = 0;                offset = 0;
               res++;                res++;
   
               if (buf)                if (buf)
                 {                  {
                   *buf++ = v;                    *buf++ = v;
                   nbytes--;                    nbytes--;
   
                   if (nbytes == 0)                    if (nbytes == 0)
                     {                      {
                       vec->dcx_pos = (i << 3) + j + 1;                        vec->dcx_pos = (i << 3) + j + 1;
                       vec->dcx_offset = offset;                        vec->dcx_offset = offset;
                       vec->dcx_sbm = sbm;                        vec->dcx_sbm = sbm;
   
                       return res;                        return res;
                     }                      }
                 }                  }
             }              }
         }          }
       j = 0;        j = 0;
     }      }
   return -1;    return -1;
Line 968  vms_lib_bread (struct bfd *abfd, void *v
Line 968  vms_lib_bread (struct bfd *abfd, void *v
   while (nbytes > 0)    while (nbytes > 0)
     {      {
       if (vec->rec_rem == 0)        if (vec->rec_rem == 0)
         {          {
           unsigned char blen[2];            unsigned char blen[2];
   
           /* Read record length.  */            /* 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;              return -1;
           vec->rec_len = bfd_getl16 (blen);            vec->rec_len = bfd_getl16 (blen);
           if (bfd_libdata (abfd->my_archive)->kind == vms_lib_txt)            if (bfd_libdata (abfd->my_archive)->kind == vms_lib_txt)
             {              {
               /* Discard record size and align byte.  */                /* Discard record size and align byte.  */
               vec->rec_pos = 0;                vec->rec_pos = 0;
               vec->rec_rem = vec->rec_len;                vec->rec_rem = vec->rec_len;
             }              }
           else            else
             {              {
               /* Prepend record size.  */                /* Prepend record size.  */
               vec->rec_pos = REC_POS_LEN0;                vec->rec_pos = REC_POS_LEN0;
               vec->rec_rem = (vec->rec_len + 1) & ~1;   /* With align byte.  */                vec->rec_rem = (vec->rec_len + 1) & ~1;   /* With align byte.  */
             }              }
           if (vec->rec_len == 3)            if (vec->rec_len == 3)
             {              {
               /* Possibly end of file.  Check the pattern.  */                /* Possibly end of file.  Check the pattern.  */
               if (vms_lib_bread_raw (abfd, vec->pattern, 4) != 4)                if (vms_lib_bread_raw (abfd, vec->pattern, 4) != 4)
                 return -1;                  return -1;
               if (!memcmp (vec->pattern, eotdesc + 2, 3))                if (!memcmp (vec->pattern, eotdesc + 2, 3))
                 {                  {
                   /* This is really an EOF.  */                    /* This is really an EOF.  */
                   vec->where += res;                    vec->where += res;
                   vec->file_len = vec->where;                    vec->file_len = vec->where;
                   return res;                    return res;
                 }                  }
             }              }
   
           if (vec->dcxsbms != NULL)            if (vec->dcxsbms != NULL)
             {              {
               /* This is a compressed member.  */                /* This is a compressed member.  */
               unsigned int len;                unsigned int len;
               file_ptr elen;                file_ptr elen;
   
               /* Be sure there is enough room for the expansion.  */                /* Be sure there is enough room for the expansion.  */
               len = (vec->rec_len + 1) & ~1;                len = (vec->rec_len + 1) & ~1;
               if (len > vec->dcx_max)                if (len > vec->dcx_max)
                 {                  {
                   while (len > vec->dcx_max)                    while (len > vec->dcx_max)
                     vec->dcx_max *= 2;                      vec->dcx_max *= 2;
                   vec->dcx_buf = bfd_alloc (abfd, vec->dcx_max);                    vec->dcx_buf = bfd_alloc (abfd, vec->dcx_max);
                   if (vec->dcx_buf == NULL)                    if (vec->dcx_buf == NULL)
                     return -1;                      return -1;
                 }                  }
   
               /* Read the compressed record.  */                /* Read the compressed record.  */
               vec->dcx_rlen = len;                vec->dcx_rlen = len;
               if (vec->rec_len == 3)                if (vec->rec_len == 3)
                 {                  {
                   /* Already read.  */                    /* Already read.  */
                   memcpy (vec->dcx_buf, vec->pattern, 3);                    memcpy (vec->dcx_buf, vec->pattern, 3);
                 }                  }
               else                else
                 {                  {
                   elen = vms_lib_bread_raw (abfd, vec->dcx_buf, len);                    elen = vms_lib_bread_raw (abfd, vec->dcx_buf, len);
                   if (elen != len)                    if (elen != len)
                     return -1;                      return -1;
                 }                  }
   
               /* Dummy expansion to get the expanded length.  */                /* Dummy expansion to get the expanded length.  */
               vec->dcx_offset = 0;                vec->dcx_offset = 0;
               vec->dcx_sbm = vec->dcxsbms;                vec->dcx_sbm = vec->dcxsbms;
               vec->dcx_pos = 0;                vec->dcx_pos = 0;
               elen = vms_lib_dcx (vec, NULL, 0x10000);                elen = vms_lib_dcx (vec, NULL, 0x10000);
               if (elen < 0)                if (elen < 0)
                 return -1;                  return -1;
               vec->rec_len = elen;                vec->rec_len = elen;
               vec->rec_rem = elen;                vec->rec_rem = elen;
   
               /* Reset the state.  */                /* Reset the state.  */
               vec->dcx_offset = 0;                vec->dcx_offset = 0;
               vec->dcx_sbm = vec->dcxsbms;                vec->dcx_sbm = vec->dcxsbms;
               vec->dcx_pos = 0;                vec->dcx_pos = 0;
             }              }
         }          }
       if (vec->rec_pos < 0)        if (vec->rec_pos < 0)
         {          {
           unsigned char c;            unsigned char c;
           switch (vec->rec_pos)            switch (vec->rec_pos)
             {              {
             case REC_POS_LEN0:              case REC_POS_LEN0:
               c = vec->rec_len & 0xff;                c = vec->rec_len & 0xff;
               vec->rec_pos = REC_POS_LEN1;                vec->rec_pos = REC_POS_LEN1;
               break;                break;
             case REC_POS_LEN1:              case REC_POS_LEN1:
               c = (vec->rec_len >> 8) & 0xff;                c = (vec->rec_len >> 8) & 0xff;
               vec->rec_pos = 0;                vec->rec_pos = 0;
               break;                break;
             case REC_POS_PAD:              case REC_POS_PAD:
               c = 0;                c = 0;
               vec->rec_rem = 0;                vec->rec_rem = 0;
               break;                break;
             case REC_POS_NL:              case REC_POS_NL:
               c = '\n';                c = '\n';
               vec->rec_rem = 0;                vec->rec_rem = 0;
               break;                break;
             default:              default:
               abort ();                abort ();
             }              }
           if (buf != NULL)            if (buf != NULL)
             {              {
               *buf = c;                *buf = c;
               buf++;                buf++;
             }              }
           nbytes--;            nbytes--;
           res++;            res++;
           continue;            continue;
         }          }
   
       if (nbytes > vec->rec_rem)        if (nbytes > vec->rec_rem)
         chunk = vec->rec_rem;          chunk = vec->rec_rem;
       else        else
         chunk = nbytes;          chunk = nbytes;
   
       if (vec->dcxsbms != NULL)        if (vec->dcxsbms != NULL)
         {          {
           /* Optimize the stat() case: no need to decompress again as we            /* Optimize the stat() case: no need to decompress again as we
              know the length.  */               know the length.  */
           if (!(buf == NULL && chunk == vec->rec_rem))            if (!(buf == NULL && chunk == vec->rec_rem))
             chunk = vms_lib_dcx (vec, buf, chunk);              chunk = vms_lib_dcx (vec, buf, chunk);
         }          }
       else        else
         {          {
           if (vec->rec_len == 3)            if (vec->rec_len == 3)
             {              {
               if (buf != NULL)                if (buf != NULL)
                 memcpy (buf, vec->pattern + vec->rec_pos, chunk);                  memcpy (buf, vec->pattern + vec->rec_pos, chunk);
             }              }
           else            else
             chunk = vms_lib_bread_raw (abfd, buf, chunk);              chunk = vms_lib_bread_raw (abfd, buf, chunk);
         }          }
       if (chunk < 0)        if (chunk < 0)
         return -1;          return -1;
       res += chunk;        res += chunk;
       if (buf != NULL)        if (buf != NULL)
         buf += chunk;          buf += chunk;
       nbytes -= chunk;        nbytes -= chunk;
       vec->rec_pos += chunk;        vec->rec_pos += chunk;
       vec->rec_rem -= chunk;        vec->rec_rem -= chunk;
   
       if (vec->rec_rem == 0)        if (vec->rec_rem == 0)
         {          {
           /* End of record reached.  */            /* End of record reached.  */
           if (bfd_libdata (abfd->my_archive)->kind == vms_lib_txt)            if (bfd_libdata (abfd->my_archive)->kind == vms_lib_txt)
             {              {
               if ((vec->rec_len & 1) == 1                if ((vec->rec_len & 1) == 1
                   && vec->rec_len != 3                    && vec->rec_len != 3
                   && vec->dcxsbms == NULL)                    && vec->dcxsbms == NULL)
                 {                  {
                   /* Eat the pad byte.  */                    /* Eat the pad byte.  */
                   unsigned char pad;                    unsigned char pad;
                   if (vms_lib_bread_raw (abfd, &pad, 1) != 1)                    if (vms_lib_bread_raw (abfd, &pad, 1) != 1)
                     return -1;                      return -1;
                 }                  }
               vec->rec_pos = REC_POS_NL;                vec->rec_pos = REC_POS_NL;
               vec->rec_rem = 1;                vec->rec_rem = 1;
             }              }
           else            else
             {              {
               if ((vec->rec_len & 1) == 1 && vec->dcxsbms != NULL)                if ((vec->rec_len & 1) == 1 && vec->dcxsbms != NULL)
                 {                  {
                   vec->rec_pos = REC_POS_PAD;                    vec->rec_pos = REC_POS_PAD;
                   vec->rec_rem = 1;                    vec->rec_rem = 1;
                 }                  }
             }              }
         }          }
     }      }
   vec->where += res;    vec->where += res;
   return res;    return res;
Line 1160  vms_lib_bseek (struct bfd *abfd, file_pt
Line 1160  vms_lib_bseek (struct bfd *abfd, file_pt
       vec->next_block = vec->init_next_block;        vec->next_block = vec->init_next_block;
   
       if (bfd_seek (abfd->my_archive, vec->first_block, SEEK_SET) != 0)        if (bfd_seek (abfd->my_archive, vec->first_block, SEEK_SET) != 0)
         return -1;          return -1;
     }      }
   else    else
     abort ();      abort ();
Line 1190  vms_lib_bflush (struct bfd *abfd ATTRIBU
Line 1190  vms_lib_bflush (struct bfd *abfd ATTRIBU
   
 static int  static int
 vms_lib_bstat (struct bfd *abfd ATTRIBUTE_UNUSED,  vms_lib_bstat (struct bfd *abfd ATTRIBUTE_UNUSED,
                struct stat *sb ATTRIBUTE_UNUSED)                 struct stat *sb ATTRIBUTE_UNUSED)
 {  {
   /* Not supported.  */    /* Not supported.  */
   return 0;    return 0;
Line 1198  vms_lib_bstat (struct bfd *abfd ATTRIBUT
Line 1198  vms_lib_bstat (struct bfd *abfd ATTRIBUT
   
 static void *  static void *
 vms_lib_bmmap (struct bfd *abfd ATTRIBUTE_UNUSED,  vms_lib_bmmap (struct bfd *abfd ATTRIBUTE_UNUSED,
                void *addr ATTRIBUTE_UNUSED,                 void *addr ATTRIBUTE_UNUSED,
                bfd_size_type len ATTRIBUTE_UNUSED,                 bfd_size_type len ATTRIBUTE_UNUSED,
                int prot ATTRIBUTE_UNUSED,                 int prot ATTRIBUTE_UNUSED,
                int flags ATTRIBUTE_UNUSED,                 int flags ATTRIBUTE_UNUSED,
                file_ptr offset ATTRIBUTE_UNUSED,                 file_ptr offset ATTRIBUTE_UNUSED,
                void **map_addr ATTRIBUTE_UNUSED,                 void **map_addr ATTRIBUTE_UNUSED,
                bfd_size_type *map_len ATTRIBUTE_UNUSED)                 bfd_size_type *map_len ATTRIBUTE_UNUSED)
 {  {
   return (void *) -1;    return (void *) -1;
 }  }
Line 1284  vms_lib_bopen (bfd *el, file_ptr filepos
Line 1284  vms_lib_bopen (bfd *el, file_ptr filepos
       vec->dcx_buf = bfd_alloc (el, vec->dcx_max);        vec->dcx_buf = bfd_alloc (el, vec->dcx_max);
       vec->dcx_pos = -1;        vec->dcx_pos = -1;
       if (vec->dcx_buf == NULL)        if (vec->dcx_buf == NULL)
         return -1;          return -1;
     }      }
   return TRUE;    return TRUE;
 }  }
Line 1313  _bfd_vms_lib_get_module (bfd *abfd, unsi
Line 1313  _bfd_vms_lib_get_module (bfd *abfd, unsi
     {      {
       res = _bfd_create_empty_archive_element_shell (abfd);        res = _bfd_create_empty_archive_element_shell (abfd);
       if (res == NULL)        if (res == NULL)
         return NULL;          return NULL;
   
       /* Special reader to deal with data blocks.  */        /* Special reader to deal with data blocks.  */
       if (!vms_lib_bopen (res, file_off))        if (!vms_lib_bopen (res, file_off))
         return NULL;          return NULL;
     }      }
   else    else
     {      {
Line 1327  _bfd_vms_lib_get_module (bfd *abfd, unsi
Line 1327  _bfd_vms_lib_get_module (bfd *abfd, unsi
   
       /* Sanity check.  The MHD must be big enough to contain module size.  */        /* Sanity check.  The MHD must be big enough to contain module size.  */
       if (tdata->mhd_size < offsetof (struct vms_mhd, modsize) + 4)        if (tdata->mhd_size < offsetof (struct vms_mhd, modsize) + 4)
         return NULL;          return NULL;
   
       /* Read the MHD now.  */        /* Read the MHD now.  */
       if (bfd_seek (abfd, file_off, SEEK_SET) != 0)        if (bfd_seek (abfd, file_off, SEEK_SET) != 0)
         return NULL;          return NULL;
       if (bfd_bread (buf, tdata->mhd_size, abfd) != tdata->mhd_size)        if (bfd_bread (buf, tdata->mhd_size, abfd) != tdata->mhd_size)
         return NULL;          return NULL;
   
       res = _bfd_create_empty_archive_element_shell (abfd);        res = _bfd_create_empty_archive_element_shell (abfd);
       if (res == NULL)        if (res == NULL)
         return NULL;          return NULL;
       arelt = bfd_zmalloc (sizeof (*arelt));        arelt = bfd_zmalloc (sizeof (*arelt));
       if (arelt == NULL)        if (arelt == NULL)
         return NULL;          return NULL;
       res->arelt_data = arelt;        res->arelt_data = arelt;
   
       /* Get info from mhd.  */        /* Get info from mhd.  */
       mhd = (struct vms_mhd *)buf;        mhd = (struct vms_mhd *)buf;
       if (mhd->id != MHD__C_MHDID)        if (mhd->id != MHD__C_MHDID)
         return NULL;          return NULL;
       if (tdata->mhd_size >= offsetof (struct vms_mhd, objstat) + 1)        if (tdata->mhd_size >= offsetof (struct vms_mhd, objstat) + 1)
         res->selective_search = (mhd->objstat & MHD__M_SELSRC) ? 1 : 0;          res->selective_search = (mhd->objstat & MHD__M_SELSRC) ? 1 : 0;
       res->mtime = vms_rawtime_to_time_t (mhd->datim);        res->mtime = vms_rawtime_to_time_t (mhd->datim);
       res->mtime_set = TRUE;        res->mtime_set = TRUE;
   
       arelt->parsed_size = bfd_getl32 (mhd->modsize);        arelt->parsed_size = bfd_getl32 (mhd->modsize);
   
       /* No need for a special reader as members are stored linearly.        /* No need for a special reader as members are stored linearly.
          Just skip the MHD.  */           Just skip the MHD.  */
       res->origin = file_off + tdata->mhd_size;        res->origin = file_off + tdata->mhd_size;
     }      }
   
Line 1402  _bfd_vms_lib_get_elt_at_index (bfd *abfd
Line 1402  _bfd_vms_lib_get_elt_at_index (bfd *abfd
   for (modidx = 0; modidx < tdata->nbr_modules; modidx++)    for (modidx = 0; modidx < tdata->nbr_modules; modidx++)
     {      {
       if (tdata->modules[modidx].file_offset == file_off)        if (tdata->modules[modidx].file_offset == file_off)
         break;          break;
     }      }
   if (modidx >= tdata->nbr_modules)    if (modidx >= tdata->nbr_modules)
     return NULL;      return NULL;
Line 1441  _bfd_vms_lib_get_imagelib_file (bfd *el)
Line 1441  _bfd_vms_lib_get_imagelib_file (bfd *el)
   
   if (res == NULL)    if (res == NULL)
     {      {
       (*_bfd_error_handler)(_("could not open shared image '%s' from '%s'"),        /* xgettext:c-format */
                             filename, archive->filename);        _bfd_error_handler(_("could not open shared image '%s' from '%s'"),
                            filename, archive->filename);
       bfd_release (archive, filename);        bfd_release (archive, filename);
       return NULL;        return NULL;
     }      }
Line 1455  _bfd_vms_lib_get_imagelib_file (bfd *el)
Line 1456  _bfd_vms_lib_get_imagelib_file (bfd *el)
   
 bfd *  bfd *
 _bfd_vms_lib_openr_next_archived_file (bfd *archive,  _bfd_vms_lib_openr_next_archived_file (bfd *archive,
                                        bfd *last_file)                                         bfd *last_file)
 {  {
   unsigned int idx;    unsigned int idx;
   bfd *res;    bfd *res;
Line 1498  _bfd_vms_lib_generic_stat_arch_elt (bfd 
Line 1499  _bfd_vms_lib_generic_stat_arch_elt (bfd 
       struct vms_lib_iovec *vec = (struct vms_lib_iovec *) abfd->iostream;        struct vms_lib_iovec *vec = (struct vms_lib_iovec *) abfd->iostream;
   
       if (vec->file_len == (ufile_ptr)-1)        if (vec->file_len == (ufile_ptr)-1)
         {          {
           if (vms_lib_bseek (abfd, 0, SEEK_SET) != 0)            if (vms_lib_bseek (abfd, 0, SEEK_SET) != 0)
             return -1;              return -1;
   
           /* Compute length.  */            /* Compute length.  */
           while (vms_lib_bread (abfd, NULL, 1 << 20) > 0)            while (vms_lib_bread (abfd, NULL, 1 << 20) > 0)
             ;              ;
         }          }
       st->st_size = vec->file_len;        st->st_size = vec->file_len;
     }      }
   else    else
Line 1565  get_idxlen (struct lib_index *idx, bfd_b
Line 1566  get_idxlen (struct lib_index *idx, bfd_b
     {      {
       /* 9 is the size of struct vms_elfidx without keyname.  */        /* 9 is the size of struct vms_elfidx without keyname.  */
       if (idx->namlen > MAX_KEYLEN)        if (idx->namlen > MAX_KEYLEN)
         return 9 + sizeof (struct vms_kbn);          return 9 + sizeof (struct vms_kbn);
       else        else
         return 9 + idx->namlen;          return 9 + idx->namlen;
     }      }
   else    else
     {      {
Line 1585  get_idxlen (struct lib_index *idx, bfd_b
Line 1586  get_idxlen (struct lib_index *idx, bfd_b
   
 static bfd_boolean  static bfd_boolean
 vms_write_index (bfd *abfd,  vms_write_index (bfd *abfd,
                  struct lib_index *idx, unsigned int nbr, unsigned int *vbn,                   struct lib_index *idx, unsigned int nbr, unsigned int *vbn,
                  unsigned int *topvbn, bfd_boolean is_elfidx)                   unsigned int *topvbn, bfd_boolean is_elfidx)
 {  {
   /* The index is organized as a tree.  This function implements a naive    /* The index is organized as a tree.  This function implements a naive
      algorithm to balance the tree: it fills the leaves, and create a new       algorithm to balance the tree: it fills the leaves, and create a new
Line 1616  vms_write_index (bfd *abfd,
Line 1617  vms_write_index (bfd *abfd,
     {      {
       /* No entries.  Very easy to handle.  */        /* No entries.  Very easy to handle.  */
       if (topvbn != NULL)        if (topvbn != NULL)
         *topvbn = 0;          *topvbn = 0;
       return TRUE;        return TRUE;
     }      }
   
Line 1644  vms_write_index (bfd *abfd,
Line 1645  vms_write_index (bfd *abfd,
       idxlen = get_idxlen (idx, is_elfidx);        idxlen = get_idxlen (idx, is_elfidx);
   
       if (is_elfidx && idx->namlen > MAX_KEYLEN)        if (is_elfidx && idx->namlen > MAX_KEYLEN)
         {          {
           /* If the key (ie 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 = idx->namlen;
           unsigned int kl_chunk;            unsigned int kl_chunk;
           const char *key = idx->name;            const char *key = idx->name;
   
           /* Write the key in the kbn, chunk after chunk.  */            /* Write the key in the kbn, chunk after chunk.  */
           do            do
             {              {
               if (kbn_sz < sizeof (struct vms_kbn))                if (kbn_sz < sizeof (struct vms_kbn))
                 {                  {
                   /* Not enough room in the kbn block.  */                    /* Not enough room in the kbn block.  */
                   if (abfd != NULL)                    if (abfd != NULL)
                     {                      {
                       /* Write it to the disk (if there is one).  */                        /* Write it to the disk (if there is one).  */
                       if (kbn_vbn != 0)                        if (kbn_vbn != 0)
                         {                          {
                           if (vms_write_block (abfd, kbn_vbn, kbn_blk) != TRUE)                            if (!vms_write_block (abfd, kbn_vbn, kbn_blk))
                             return FALSE;                              return FALSE;
                         }                          }
                       else                        else
                         {                          {
                           kbn_blk = bfd_malloc (VMS_BLOCK_SIZE);                            kbn_blk = bfd_malloc (VMS_BLOCK_SIZE);
                           if (kbn_blk == NULL)                            if (kbn_blk == NULL)
                             return FALSE;                              return FALSE;
                         }                          }
                       *(unsigned short *)kbn_blk = 0;                        *(unsigned short *)kbn_blk = 0;
                     }                      }
                   /* Allocate a new block for the keys.  */                    /* Allocate a new block for the keys.  */
                   kbn_vbn = (*vbn)++;                    kbn_vbn = (*vbn)++;
                   kbn_sz = VMS_BLOCK_SIZE - 2;                    kbn_sz = VMS_BLOCK_SIZE - 2;
                 }                  }
               /* Size of the chunk written to the current key block.  */                /* Size of the chunk written to the current key block.  */
               if (kl + sizeof (struct vms_kbn) > kbn_sz)                if (kl + sizeof (struct vms_kbn) > kbn_sz)
                 kl_chunk = kbn_sz - sizeof (struct vms_kbn);                  kl_chunk = kbn_sz - sizeof (struct vms_kbn);
               else                else
                 kl_chunk = kl;                  kl_chunk = kl;
   
               if (kbn_blk != NULL)                if (kbn_blk != NULL)
                 {                  {
                   struct vms_kbn *kbn;                    struct vms_kbn *kbn;
   
                   kbn = (struct vms_kbn *)(kbn_blk + VMS_BLOCK_SIZE - kbn_sz);                    kbn = (struct vms_kbn *)(kbn_blk + VMS_BLOCK_SIZE - kbn_sz);
   
                   if (key_vbn == 0)                    if (key_vbn == 0)
                     {                      {
                       /* Save the rfa of the first chunk.  */                        /* Save the rfa of the first chunk.  */
                       key_vbn = kbn_vbn;                        key_vbn = kbn_vbn;
                       key_off = VMS_BLOCK_SIZE - kbn_sz;                        key_off = VMS_BLOCK_SIZE - kbn_sz;
                     }                      }
   
                   bfd_putl16 (kl_chunk, kbn->keylen);                    bfd_putl16 (kl_chunk, kbn->keylen);
                   if (kl_chunk == kl)                    if (kl_chunk == kl)
                     {                      {
                       /* No next chunk.  */                        /* No next chunk.  */
                       bfd_putl32 (0, kbn->rfa.vbn);                        bfd_putl32 (0, kbn->rfa.vbn);
                       bfd_putl16 (0, kbn->rfa.offset);                        bfd_putl16 (0, kbn->rfa.offset);
                     }                      }
                   else                    else
                     {                      {
                       /* Next chunk will be at the start of the next block.  */                        /* Next chunk will be at the start of the next block.  */
                       bfd_putl32 (*vbn, kbn->rfa.vbn);                        bfd_putl32 (*vbn, kbn->rfa.vbn);
                       bfd_putl16 (2, kbn->rfa.offset);                        bfd_putl16 (2, kbn->rfa.offset);
                     }                      }
                   memcpy ((char *)(kbn + 1), key, kl_chunk);                    memcpy ((char *)(kbn + 1), key, kl_chunk);
                   key += kl_chunk;                    key += kl_chunk;
                 }                  }
               kl -= kl_chunk;                kl -= kl_chunk;
               kl_chunk = (kl_chunk + 1) & ~1;     /* Always align.  */                kl_chunk = (kl_chunk + 1) & ~1;     /* Always align.  */
               kbn_sz -= kl_chunk + sizeof (struct vms_kbn);                kbn_sz -= kl_chunk + sizeof (struct vms_kbn);
             }              }
           while (kl > 0);            while (kl > 0);
         }          }
   
       /* Check if a block might overflow.  In this case we will flush this        /* Check if a block might overflow.  In this case we will flush this
          block and all the blocks below it.  */           block and all the blocks below it.  */
       for (j = 0; j < level; j++)        for (j = 0; j < level; j++)
         if (blk[j].len + blk[j].lastlen + idxlen > INDEXDEF__BLKSIZ)          if (blk[j].len + blk[j].lastlen + idxlen > INDEXDEF__BLKSIZ)
           flush = j + 1;            flush = j + 1;
   
       for (j = 0; j < level; j++)        for (j = 0; j < level; j++)
         {          {
           if (j < flush)            if (j < flush)
             {              {
               /* There is not enough room to write the new entry in this                /* There is not enough room to write the new entry in this
                  block or in a parent block.  */                   block or in a parent block.  */
   
               if (j + 1 == level)                if (j + 1 == level)
                 {                  {
                   BFD_ASSERT (level < MAX_LEVEL);                    BFD_ASSERT (level < MAX_LEVEL);
   
                   /* Need to create a parent.  */                    /* Need to create a parent.  */
                   if (abfd != NULL)                    if (abfd != NULL)
                     {                      {
                       rblk[level] = bfd_zmalloc (sizeof (struct vms_indexdef));                        rblk[level] = bfd_zmalloc (sizeof (struct vms_indexdef));
                       bfd_putl32 (*vbn, rblk[j]->parent);                        bfd_putl32 (*vbn, rblk[j]->parent);
                     }                      }
                   blk[level].vbn = (*vbn)++;                    blk[level].vbn = (*vbn)++;
                   blk[level].len = 0;                    blk[level].len = 0;
                   blk[level].lastlen = blk[j].lastlen;                    blk[level].lastlen = blk[j].lastlen;
   
                   level++;                    level++;
                 }                  }
   
               /* Update parent block: write the last entry from the current                /* Update parent block: write the last entry from the current
                  block.  */                   block.  */
               if (abfd != NULL)                if (abfd != NULL)
                 {                  {
                   struct vms_rfa *rfa;                    struct vms_rfa *rfa;
   
                   /* Pointer to the last entry in parent block.  */                    /* Pointer to the last entry in parent block.  */
                   rfa = (struct vms_rfa *)(rblk[j + 1]->keys + blk[j + 1].len);                    rfa = (struct vms_rfa *)(rblk[j + 1]->keys + blk[j + 1].len);
   
                   /* Copy the whole entry.  */                    /* Copy the whole entry.  */
                   BFD_ASSERT (blk[j + 1].lastlen == blk[j].lastlen);                    BFD_ASSERT (blk[j + 1].lastlen == blk[j].lastlen);
                   memcpy (rfa, rblk[j]->keys + blk[j].len, blk[j].lastlen);                    memcpy (rfa, rblk[j]->keys + blk[j].len, blk[j].lastlen);
                   /* Fix the entry (which in always the first field of an                    /* Fix the entry (which in always the first field of an
                      entry.  */                       entry.  */
                   bfd_putl32 (blk[j].vbn, rfa->vbn);                    bfd_putl32 (blk[j].vbn, rfa->vbn);
                   bfd_putl16 (RFADEF__C_INDEX, rfa->offset);                    bfd_putl16 (RFADEF__C_INDEX, rfa->offset);
                 }                  }
   
               if (j + 1 == flush)                if (j + 1 == flush)
                 {                  {
                   /* And allocate it.  Do it only on the block that won't be                    /* And allocate it.  Do it only on the block that won't be
                      flushed (so that the parent of the parent can be                       flushed (so that the parent of the parent can be
                      updated too).  */                       updated too).  */
                   blk[j + 1].len += blk[j + 1].lastlen;                    blk[j + 1].len += blk[j + 1].lastlen;
                   blk[j + 1].lastlen = 0;                    blk[j + 1].lastlen = 0;
                 }                  }
   
               /* Write this block on the disk.  */                /* Write this block on the disk.  */
               if (abfd != NULL)                if (abfd != NULL)
                 {                  {
                   bfd_putl16 (blk[j].len + blk[j].lastlen, rblk[j]->used);                    bfd_putl16 (blk[j].len + blk[j].lastlen, rblk[j]->used);
                   if (vms_write_block (abfd, blk[j].vbn, rblk[j]) != TRUE)                    if (!vms_write_block (abfd, blk[j].vbn, rblk[j]))
                     return FALSE;                      return FALSE;
                 }                  }
   
               /* Reset this block.  */                /* Reset this block.  */
               blk[j].len = 0;                blk[j].len = 0;
               blk[j].lastlen = 0;                blk[j].lastlen = 0;
               blk[j].vbn = (*vbn)++;                blk[j].vbn = (*vbn)++;
             }              }
   
           /* Append it to the block.  */            /* Append it to the block.  */
           if (j == 0)            if (j == 0)
             {              {
               /* Keep the previous last entry.  */                /* Keep the previous last entry.  */
               blk[j].len += blk[j].lastlen;                blk[j].len += blk[j].lastlen;
   
               if (abfd != NULL)                if (abfd != NULL)
                 {                  {
                   struct vms_rfa *rfa;                    struct vms_rfa *rfa;
   
                   rfa = (struct vms_rfa *)(rblk[j]->keys + blk[j].len);                    rfa = (struct vms_rfa *)(rblk[j]->keys + blk[j].len);
                   bfd_putl32 ((idx->abfd->proxy_origin / VMS_BLOCK_SIZE) + 1,                    bfd_putl32 ((idx->abfd->proxy_origin / VMS_BLOCK_SIZE) + 1,
                               rfa->vbn);                                rfa->vbn);
                   bfd_putl16                    bfd_putl16
                     ((idx->abfd->proxy_origin % VMS_BLOCK_SIZE)                      ((idx->abfd->proxy_origin % VMS_BLOCK_SIZE)
                      + (is_elfidx ? 0 : DATA__DATA),                       + (is_elfidx ? 0 : DATA__DATA),
                      rfa->offset);                       rfa->offset);
   
                   if (is_elfidx)                    if (is_elfidx)
                     {                      {
                       /* Use elfidx format.  */                        /* Use elfidx format.  */
                       struct vms_elfidx *en = (struct vms_elfidx *)rfa;                        struct vms_elfidx *en = (struct vms_elfidx *)rfa;
   
                       en->flags = 0;                        en->flags = 0;
                       if (key_vbn != 0)                        if (key_vbn != 0)
                         {                          {
                           /* Long symbol name.  */                            /* Long symbol name.  */
                           struct vms_kbn *k = (struct vms_kbn *)(en->keyname);                            struct vms_kbn *k = (struct vms_kbn *)(en->keyname);
                           bfd_putl16 (sizeof (struct vms_kbn), en->keylen);                            bfd_putl16 (sizeof (struct vms_kbn), en->keylen);
                           bfd_putl16 (idx->namlen, k->keylen);                            bfd_putl16 (idx->namlen, k->keylen);
                           bfd_putl32 (key_vbn, k->rfa.vbn);                            bfd_putl32 (key_vbn, k->rfa.vbn);
                           bfd_putl16 (key_off, k->rfa.offset);                            bfd_putl16 (key_off, k->rfa.offset);
                           en->flags |= ELFIDX__SYMESC;                            en->flags |= ELFIDX__SYMESC;
                         }                          }
                       else                        else
                         {                          {
                           bfd_putl16 (idx->namlen, en->keylen);                            bfd_putl16 (idx->namlen, en->keylen);
                           memcpy (en->keyname, idx->name, idx->namlen);                            memcpy (en->keyname, idx->name, idx->namlen);
                         }                          }
                     }                      }
                   else                    else
                     {                      {
                       /* Use idx format.  */                        /* Use idx format.  */
                       struct vms_idx *en = (struct vms_idx *)rfa;                        struct vms_idx *en = (struct vms_idx *)rfa;
                       en->keylen = idx->namlen;                        en->keylen = idx->namlen;
                       memcpy (en->keyname, idx->name, idx->namlen);                        memcpy (en->keyname, idx->name, idx->namlen);
                     }                      }
                 }                  }
             }              }
           /* The last added key can now be the last one all blocks in the            /* The last added key can now be the last one all blocks in the
              path.  */               path.  */
           blk[j].lastlen = idxlen;            blk[j].lastlen = idxlen;
         }          }
     }      }
   
   /* Save VBN of the root.  */    /* Save VBN of the root.  */
Line 1872  vms_write_index (bfd *abfd,
Line 1873  vms_write_index (bfd *abfd,
     {      {
       /* Write this block on the disk.  */        /* Write this block on the disk.  */
       bfd_putl16 (blk[j].len + blk[j].lastlen, rblk[j]->used);        bfd_putl16 (blk[j].len + blk[j].lastlen, rblk[j]->used);
       if (vms_write_block (abfd, blk[j].vbn, rblk[j]) != TRUE)        if (!vms_write_block (abfd, blk[j].vbn, rblk[j]))
         return FALSE;          return FALSE;
   
       free (rblk[j]);        free (rblk[j]);
     }      }
Line 1881  vms_write_index (bfd *abfd,
Line 1882  vms_write_index (bfd *abfd,
   /* Write the last kbn (if any).  */    /* Write the last kbn (if any).  */
   if (kbn_vbn != 0)    if (kbn_vbn != 0)
     {      {
       if (vms_write_block (abfd, kbn_vbn, kbn_blk) != TRUE)        if (!vms_write_block (abfd, kbn_vbn, kbn_blk))
         return FALSE;          return FALSE;
       free (kbn_blk);        free (kbn_blk);
     }      }
   
Line 1893  vms_write_index (bfd *abfd,
Line 1894  vms_write_index (bfd *abfd,
   
 static bfd_boolean  static bfd_boolean
 vms_write_data_block (bfd *arch, struct vms_datadef *data, file_ptr *off,  vms_write_data_block (bfd *arch, struct vms_datadef *data, file_ptr *off,
                       const unsigned char *buf, unsigned int len, int pad)                        const unsigned char *buf, unsigned int len, int pad)
 {  {
   while (len > 0 || pad)    while (len > 0 || pad)
     {      {
Line 1909  vms_write_data_block (bfd *arch, struct 
Line 1910  vms_write_data_block (bfd *arch, struct 
       *off += l;        *off += l;
   
       if (doff == (DATA__LENGTH - DATA__DATA) || (len == 0 && pad))        if (doff == (DATA__LENGTH - DATA__DATA) || (len == 0 && pad))
         {          {
           data->recs = 0;            data->recs = 0;
           data->fill_1 = 0;            data->fill_1 = 0;
           bfd_putl32 ((*off / VMS_BLOCK_SIZE) + 2, data->link);            bfd_putl32 ((*off / VMS_BLOCK_SIZE) + 2, data->link);
   
           if (bfd_bwrite (data, sizeof (*data), arch) != sizeof (*data))            if (bfd_bwrite (data, sizeof (*data), arch) != sizeof (*data))
             return FALSE;              return FALSE;
   
           *off += DATA__LENGTH - doff;            *off += DATA__LENGTH - doff;
   
           if (len == 0)            if (len == 0)
             break;              break;
         }          }
     }      }
   return TRUE;    return TRUE;
 }  }
Line 1930  vms_write_data_block (bfd *arch, struct 
Line 1931  vms_write_data_block (bfd *arch, struct 
   
 static bfd_boolean  static bfd_boolean
 _bfd_vms_lib_build_map (unsigned int nbr_modules,  _bfd_vms_lib_build_map (unsigned int nbr_modules,
                         struct lib_index *modules,                          struct lib_index *modules,
                         unsigned int *res_cnt,                          unsigned int *res_cnt,
                         struct lib_index **res)                          struct lib_index **res)
 {  {
   unsigned int i;    unsigned int i;
   asymbol **syms = NULL;    asymbol **syms = NULL;
Line 1954  _bfd_vms_lib_build_map (unsigned int nbr
Line 1955  _bfd_vms_lib_build_map (unsigned int nbr
       bfd *current = modules[i].abfd;        bfd *current = modules[i].abfd;
   
       if ((bfd_get_file_flags (current) & HAS_SYMS) == 0)        if ((bfd_get_file_flags (current) & HAS_SYMS) == 0)
         continue;          continue;
   
       storage = bfd_get_symtab_upper_bound (current);        storage = bfd_get_symtab_upper_bound (current);
       if (storage < 0)        if (storage < 0)
         goto error_return;          goto error_return;
   
       if (storage != 0)        if (storage != 0)
         {          {
           if (storage > syms_max)            if (storage > syms_max)
             {              {
               if (syms_max > 0)                if (syms_max > 0)
                 free (syms);                  free (syms);
               syms_max = storage;                syms_max = storage;
               syms = (asymbol **) bfd_malloc (syms_max);                syms = (asymbol **) bfd_malloc (syms_max);
               if (syms == NULL)                if (syms == NULL)
                 goto error_return;                  goto error_return;
             }              }
           symcount = bfd_canonicalize_symtab (current, syms);            symcount = bfd_canonicalize_symtab (current, syms);
           if (symcount < 0)            if (symcount < 0)
             goto error_return;              goto error_return;
   
           /* Now map over all the symbols, picking out the ones we            /* Now map over all the symbols, picking out the ones we
              want.  */               want.  */
           for (src_count = 0; src_count < symcount; src_count++)            for (src_count = 0; src_count < symcount; src_count++)
             {              {
               flagword flags = (syms[src_count])->flags;                flagword flags = (syms[src_count])->flags;
               asection *sec = syms[src_count]->section;                asection *sec = syms[src_count]->section;
   
               if ((flags & BSF_GLOBAL                if ((flags & BSF_GLOBAL
                    || flags & BSF_WEAK                     || flags & BSF_WEAK
                    || flags & BSF_INDIRECT                     || flags & BSF_INDIRECT
                    || bfd_is_com_section (sec))                     || bfd_is_com_section (sec))
                   && ! bfd_is_und_section (sec))                    && ! bfd_is_und_section (sec))
                 {                  {
                   struct lib_index *new_map;                    struct lib_index *new_map;
   
                   /* This symbol will go into the archive header.  */                    /* This symbol will go into the archive header.  */
                   if (map_count == map_max)                    if (map_count == map_max)
                     {                      {
                       map_max *= 2;                        map_max *= 2;
                       new_map = (struct lib_index *)                        new_map = (struct lib_index *)
                         bfd_realloc (map, map_max * sizeof (struct lib_index));                          bfd_realloc (map, map_max * sizeof (struct lib_index));
                       if (new_map == NULL)                        if (new_map == NULL)
                         goto error_return;                          goto error_return;
                       map = new_map;                        map = new_map;
                     }                      }
   
                   map[map_count].abfd = current;                    map[map_count].abfd = current;
                   map[map_count].namlen = strlen (syms[src_count]->name);                    map[map_count].namlen = strlen (syms[src_count]->name);
                   map[map_count].name = syms[src_count]->name;                    map[map_count].name = syms[src_count]->name;
                   map_count++;                    map_count++;
                   modules[i].ref++;                    modules[i].ref++;
                 }                  }
             }              }
         }          }
     }      }
   
Line 2117  _bfd_vms_lib_write_archive_contents (bfd
Line 2118  _bfd_vms_lib_write_archive_contents (bfd
       current->proxy_origin = off;        current->proxy_origin = off;
   
       if (is_elfidx)        if (is_elfidx)
         sz = 0;          sz = 0;
       else        else
         {          {
           /* Write the MHD as a record (ie, size first).  */            /* Write the MHD as a record (ie, size first).  */
           sz = 2;            sz = 2;
           bfd_putl16 (tdata->mhd_size, blk);            bfd_putl16 (tdata->mhd_size, blk);
         }          }
       mhd = (struct vms_mhd *)(blk + sz);        mhd = (struct vms_mhd *)(blk + sz);
       memset (mhd, 0, sizeof (struct vms_mhd));        memset (mhd, 0, sizeof (struct vms_mhd));
       mhd->lbrflag = 0;        mhd->lbrflag = 0;
Line 2138  _bfd_vms_lib_write_archive_contents (bfd
Line 2139  _bfd_vms_lib_write_archive_contents (bfd
   
       /* Rewind the member to be put into the archive.  */        /* Rewind the member to be put into the archive.  */
       if (bfd_seek (current, 0, SEEK_SET) != 0)        if (bfd_seek (current, 0, SEEK_SET) != 0)
         goto input_err;          goto input_err;
   
       /* Copy the member into the archive.  */        /* Copy the member into the archive.  */
       if (is_elfidx)        if (is_elfidx)
         {          {
           unsigned int modsize = 0;            unsigned int modsize = 0;
           bfd_size_type amt;            bfd_size_type amt;
           file_ptr off_hdr = off;            file_ptr off_hdr = off;
   
           /* Read to complete the first block.  */            /* Read to complete the first block.  */
           amt = bfd_bread (blk + sz, VMS_BLOCK_SIZE - sz, current);            amt = bfd_bread (blk + sz, VMS_BLOCK_SIZE - sz, current);
           if (amt == (bfd_size_type)-1)            if (amt == (bfd_size_type)-1)
             goto input_err;              goto input_err;
           modsize = amt;            modsize = amt;
           if (amt < VMS_BLOCK_SIZE - sz)            if (amt < VMS_BLOCK_SIZE - sz)
             {              {
               /* The member size is less than a block.  Pad the block.  */                /* The member size is less than a block.  Pad the block.  */
               memset (blk + sz + amt, 0, VMS_BLOCK_SIZE - sz - amt);                memset (blk + sz + amt, 0, VMS_BLOCK_SIZE - sz - amt);
             }              }
           bfd_putl32 (modsize, mhd->modsize);            bfd_putl32 (modsize, mhd->modsize);
   
           /* Write the first block (which contains an mhd).  */            /* Write the first block (which contains an mhd).  */
           if (bfd_bwrite (blk, VMS_BLOCK_SIZE, arch) != VMS_BLOCK_SIZE)            if (bfd_bwrite (blk, VMS_BLOCK_SIZE, arch) != VMS_BLOCK_SIZE)
             goto input_err;              goto input_err;
           off += VMS_BLOCK_SIZE;            off += VMS_BLOCK_SIZE;
   
           if (amt == VMS_BLOCK_SIZE - sz)            if (amt == VMS_BLOCK_SIZE - sz)
             {              {
               /* Copy the remaining.  */                /* Copy the remaining.  */
               char buffer[DEFAULT_BUFFERSIZE];                char buffer[DEFAULT_BUFFERSIZE];
   
               while (1)                while (1)
                 {                  {
                   amt = bfd_bread (buffer, sizeof (buffer), current);                    amt = bfd_bread (buffer, sizeof (buffer), current);
                   if (amt == (bfd_size_type)-1)                    if (amt == (bfd_size_type)-1)
                     goto input_err;                      goto input_err;
                   if (amt == 0)                    if (amt == 0)
                     break;                      break;
                   modsize += amt;                    modsize += amt;
                   if (amt != sizeof (buffer))                    if (amt != sizeof (buffer))
                     {                      {
                       /* Clear the padding.  */                        /* Clear the padding.  */
                       memset (buffer + amt, 0, sizeof (buffer) - amt);                        memset (buffer + amt, 0, sizeof (buffer) - amt);
                       amt = (amt + VMS_BLOCK_SIZE) & ~(VMS_BLOCK_SIZE - 1);                        amt = (amt + VMS_BLOCK_SIZE) & ~(VMS_BLOCK_SIZE - 1);
                     }                      }
                   if (bfd_bwrite (buffer, amt, arch) != amt)                    if (bfd_bwrite (buffer, amt, arch) != amt)
                     goto input_err;                      goto input_err;
                   off += amt;                    off += amt;
                 }                  }
   
               /* Now that the size is known, write the first block (again).  */                /* Now that the size is known, write the first block (again).  */
               bfd_putl32 (modsize, mhd->modsize);                bfd_putl32 (modsize, mhd->modsize);
               if (bfd_seek (arch, off_hdr, SEEK_SET) != 0                if (bfd_seek (arch, off_hdr, SEEK_SET) != 0
                   || bfd_bwrite (blk, VMS_BLOCK_SIZE, arch) != VMS_BLOCK_SIZE)                    || bfd_bwrite (blk, VMS_BLOCK_SIZE, arch) != VMS_BLOCK_SIZE)
                 goto input_err;                  goto input_err;
               if (bfd_seek (arch, off, SEEK_SET) != 0)                if (bfd_seek (arch, off, SEEK_SET) != 0)
                 goto input_err;                  goto input_err;
             }              }
         }          }
       else        else
         {          {
           /* Write the MHD.  */            /* Write the MHD.  */
           if (vms_write_data_block (arch, &data, &off, blk, sz, 0) < 0)            if (vms_write_data_block (arch, &data, &off, blk, sz, 0) < 0)
             goto input_err;              goto input_err;
   
           /* Write the member.  */            /* Write the member.  */
           while (1)            while (1)
             {              {
               sz = bfd_bread (blk, sizeof (blk), current);                sz = bfd_bread (blk, sizeof (blk), current);
               if (sz == 0)                if (sz == 0)
                 break;                  break;
               if (vms_write_data_block (arch, &data, &off, blk, sz, 0) < 0)                if (vms_write_data_block (arch, &data, &off, blk, sz, 0) < 0)
                 goto input_err;                  goto input_err;
             }              }
   
           /* Write the end of module marker.  */            /* Write the end of module marker.  */
           if (vms_write_data_block (arch, &data, &off,            if (vms_write_data_block (arch, &data, &off,
                                     eotdesc, sizeof (eotdesc), 1) < 0)                                      eotdesc, sizeof (eotdesc), 1) < 0)
             goto input_err;              goto input_err;
         }          }
     }      }
   
   /* Write the indexes.  */    /* Write the indexes.  */
   vbn = 2;    vbn = 2;
   if (vms_write_index (arch, modules, nbr_modules, &vbn, &mod_idx_vbn,    if (!vms_write_index (arch, modules, nbr_modules, &vbn, &mod_idx_vbn,
                        is_elfidx) != TRUE)                          is_elfidx))
     return FALSE;      return FALSE;
   if (vms_write_index (arch, symbols, nbr_symbols, &vbn, &sym_idx_vbn,    if (!vms_write_index (arch, symbols, nbr_symbols, &vbn, &sym_idx_vbn,
                        is_elfidx) != TRUE)                          is_elfidx))
     return FALSE;      return FALSE;
   
   /* Write libary header.  */    /* Write libary header.  */
Line 2244  _bfd_vms_lib_write_archive_contents (bfd
Line 2245  _bfd_vms_lib_write_archive_contents (bfd
     switch (tdata->kind)      switch (tdata->kind)
       {        {
       case vms_lib_alpha:        case vms_lib_alpha:
         saneid = LHD_SANEID3;          saneid = LHD_SANEID3;
         break;          break;
       case vms_lib_ia64:        case vms_lib_ia64:
         saneid = LHD_SANEID6;          saneid = LHD_SANEID6;
         break;          break;
       default:        default:
         abort ();          abort ();
       }        }
     bfd_putl32 (saneid, lhd->sanity);      bfd_putl32 (saneid, lhd->sanity);
     bfd_putl16 (tdata->ver, lhd->majorid);      bfd_putl16 (tdata->ver, lhd->majorid);
     bfd_putl16 (0, lhd->minorid);      bfd_putl16 (0, lhd->minorid);
     snprintf ((char *)lhd->lbrver + 1, sizeof (lhd->lbrver) - 1,      snprintf ((char *)lhd->lbrver + 1, sizeof (lhd->lbrver) - 1,
               "GNU ar %u.%u.%u",                "GNU ar %u.%u.%u",
               (unsigned)(BFD_VERSION / 100000000UL),                (unsigned)(BFD_VERSION / 100000000UL),
               (unsigned)(BFD_VERSION / 1000000UL) % 100,                (unsigned)(BFD_VERSION / 1000000UL) % 100,
               (unsigned)(BFD_VERSION / 10000UL) % 100);                (unsigned)(BFD_VERSION / 10000UL) % 100);
     lhd->lbrver[sizeof (lhd->lbrver) - 1] = 0;      lhd->lbrver[sizeof (lhd->lbrver) - 1] = 0;
     lhd->lbrver[0] = strlen ((char *)lhd->lbrver + 1);      lhd->lbrver[0] = strlen ((char *)lhd->lbrver + 1);
   
Line 2297  _bfd_vms_lib_write_archive_contents (bfd
Line 2298  _bfd_vms_lib_write_archive_contents (bfd
     bfd_putl16 (sym_idx_vbn, idd->vbn);      bfd_putl16 (sym_idx_vbn, idd->vbn);
     idd++;      idd++;
   
     if (vms_write_block (arch, 1, blk) != TRUE)      if (!vms_write_block (arch, 1, blk))
       return FALSE;        return FALSE;
   }    }
   
   return TRUE;    return TRUE;
   
  input_err:   input_err:
   bfd_set_error (bfd_error_on_input, current, bfd_get_error ());    bfd_set_input_error (current, bfd_get_error ());
   return FALSE;    return FALSE;
 }  }
   
Line 2329  const bfd_target alpha_vms_lib_txt_vec =
Line 2330  const bfd_target alpha_vms_lib_txt_vec =
   bfd_getl64, bfd_getl_signed_64, bfd_putl64,    bfd_getl64, bfd_getl_signed_64, bfd_putl64,
   bfd_getl32, bfd_getl_signed_32, bfd_putl32,    bfd_getl32, bfd_getl_signed_32, bfd_putl32,
   bfd_getl16, bfd_getl_signed_16, bfd_putl16,    bfd_getl16, bfd_getl_signed_16, bfd_putl16,
     {                             /* bfd_check_format.  */
   {_bfd_dummy_target, _bfd_dummy_target,        /* bfd_check_format.  */      _bfd_dummy_target,
    _bfd_vms_lib_txt_archive_p, _bfd_dummy_target},      _bfd_dummy_target,
   {bfd_false, bfd_false, bfd_false, bfd_false}, /* bfd_set_format.  */      _bfd_vms_lib_txt_archive_p,
   {bfd_false, bfd_false, bfd_false, bfd_false}, /* bfd_write_contents.  */      _bfd_dummy_target
     },
     {                             /* bfd_set_format.  */
       _bfd_bool_bfd_false_error,
       _bfd_bool_bfd_false_error,
       _bfd_bool_bfd_false_error,
       _bfd_bool_bfd_false_error
     },
     {                             /* bfd_write_contents.  */
       _bfd_bool_bfd_false_error,
       _bfd_bool_bfd_false_error,
       _bfd_bool_bfd_false_error,
       _bfd_bool_bfd_false_error
     },
   BFD_JUMP_TABLE_GENERIC (_bfd_generic),    BFD_JUMP_TABLE_GENERIC (_bfd_generic),
   BFD_JUMP_TABLE_COPY (_bfd_generic),    BFD_JUMP_TABLE_COPY (_bfd_generic),
   BFD_JUMP_TABLE_CORE (_bfd_nocore),    BFD_JUMP_TABLE_CORE (_bfd_nocore),

Legend:
Removed from v.1.5  
changed lines
  Added in v.1.6

CVSweb <webmaster@jp.NetBSD.org>