/* BFD back-end for VMS archive files.

   Copyright (C) 2010-2017 Free Software Foundation, Inc.
   Written by Tristan Gingold <gingold@adacore.com>, AdaCore.

   This file is part of BFD, the Binary File Descriptor library.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
   MA 02110-1301, USA.  */

#include "sysdep.h"
#include "bfd.h"
#include "libbfd.h"
#include "safe-ctype.h"
#include "bfdver.h"
#include "libiberty.h"
#include "vms.h"
#include "vms/lbr.h"
#include "vms/dcx.h"

/* The standard VMS disk block size.  */
#ifndef VMS_BLOCK_SIZE
#define VMS_BLOCK_SIZE 512
#endif

/* Maximum key length (which is also the maximum symbol length in archive).  */
#define MAX_KEYLEN 128
#define MAX_EKEYLEN 1024

/* DCX Submaps.  */

struct dcxsbm_desc
{
  unsigned char min_char;
  unsigned char max_char;
  unsigned char *flags;
  unsigned char *nodes;
  unsigned short *next;
};

/* Kind of library.  Used to filter in archive_p.  */

enum vms_lib_kind
  {
    vms_lib_vax,
    vms_lib_alpha,
    vms_lib_ia64,
    vms_lib_txt
  };

/* Back-end private data.  */

struct lib_tdata
{
  /* Standard tdata for an archive.  But we don't use many fields.  */
  struct artdata artdata;

  /* Major version.  */
  unsigned char ver;

  /* Type of the archive.  */
  unsigned char type;

  /* Kind of archive.  Summary of its type.  */
  enum vms_lib_kind kind;

  /* Total size of the mhd (element header).  */
  unsigned int mhd_size;

  /* Creation date.  */
  unsigned int credat_lo;
  unsigned int credat_hi;

  /* Vector of modules (archive elements), already sorted.  */
  unsigned int nbr_modules;
  struct carsym *modules;
  bfd **cache;

  /* DCX (decompression) data.  */
  unsigned int nbr_dcxsbm;
  struct dcxsbm_desc *dcxsbm;
};

#define bfd_libdata(bfd) ((struct lib_tdata *)((bfd)->tdata.any))

/* End-Of-Text pattern.  This is a special record to mark the end of file.  */

static const unsigned char eotdesc[] = { 0x03, 0x00, 0x77, 0x00, 0x77, 0x00 };

/* Describe the current state of carsym entries while building the archive
   table of content.  Things are simple with Alpha archives as the number
   of entries is known, but with IA64 archives a entry can make a reference
   to severals members.  Therefore we must be able to extend the table on the
   fly, but it should be allocated on the bfd - which doesn't support realloc.
   To reduce the overhead, the table is initially allocated in the BFD's
   objalloc and extended if necessary on the heap.  In the later case, it
   is finally copied to the BFD's objalloc so that it will automatically be
   freed.  */

struct carsym_mem
{
  /* The table of content.  */
  struct carsym *idx;

  /* Number of entries used in the table.  */
  unsigned int nbr;

  /* Maximum number of entries.  */
  unsigned int max;

  /* If true, the table was reallocated on the heap.  If false, it is still
     in the BFD's objalloc.  */
  bfd_boolean realloced;
};

/* Simply add a name to the index.  */

static bfd_boolean
vms_add_index (struct carsym_mem *cs, char *name,
               unsigned int idx_vbn, unsigned int idx_off)
{
  if (cs->nbr == cs->max)
    {
      struct carsym *n;

      cs->max = 2 * cs->max + 32;

      if (!cs->realloced)
        {
          n = bfd_malloc2 (cs->max, sizeof (struct carsym));
          if (n == NULL)
            return FALSE;
          memcpy (n, cs->idx, cs->nbr * sizeof (struct carsym));
          /* And unfortunately we can't free cs->idx.  */
        }
      else
        {
          n = bfd_realloc_or_free (cs->idx, cs->nbr * sizeof (struct carsym));
          if (n == NULL)
            return FALSE;
        }
      cs->idx = n;
      cs->realloced = TRUE;
    }
  cs->idx[cs->nbr].file_offset = (idx_vbn - 1) * VMS_BLOCK_SIZE + idx_off;
  cs->idx[cs->nbr].name = name;
  cs->nbr++;
  return TRUE;
}

/* Follow all member of a lns list (pointed by RFA) and add indexes for
   NAME.  Return FALSE in case of error.  */

static bfd_boolean
vms_add_indexes_from_list (bfd *abfd, struct carsym_mem *cs, char *name,
                           struct vms_rfa *rfa)
{
  struct vms_lns lns;
  unsigned int vbn;
  file_ptr off;

  while (1)
    {
      vbn = bfd_getl32 (rfa->vbn);
      if (vbn == 0)
        return TRUE;

      /* Read the LHS.  */
      off = (vbn - 1) * VMS_BLOCK_SIZE + bfd_getl16 (rfa->offset);
      if (bfd_seek (abfd, off, SEEK_SET) != 0
          || bfd_bread (&lns, sizeof (lns), abfd) != sizeof (lns))
        return FALSE;

      if (!vms_add_index (cs, name,
                          bfd_getl32 (lns.modrfa.vbn),
                          bfd_getl16 (lns.modrfa.offset)))
        return FALSE;

      rfa = &lns.nxtrfa;
    }
}

/* Read block VBN from ABFD and store it into BLK.  Return FALSE in case of error.  */

static bfd_boolean
vms_read_block (bfd *abfd, unsigned int vbn, void *blk)
{
  file_ptr off;

  off = (vbn - 1) * VMS_BLOCK_SIZE;
  if (bfd_seek (abfd, off, SEEK_SET) != 0
      || bfd_bread (blk, VMS_BLOCK_SIZE, abfd) != VMS_BLOCK_SIZE)
    return FALSE;

  return TRUE;
}

/* Write the content of BLK to block VBN of ABFD.  Return FALSE in case of error.  */

static bfd_boolean
vms_write_block (bfd *abfd, unsigned int vbn, void *blk)
{
  file_ptr off;

  off = (vbn - 1) * VMS_BLOCK_SIZE;
  if (bfd_seek (abfd, off, SEEK_SET) != 0
      || bfd_bwrite (blk, VMS_BLOCK_SIZE, abfd) != VMS_BLOCK_SIZE)
    return FALSE;

  return TRUE;
}

/* Read index block VBN and put the entry in **IDX (which is updated).
   If the entry is indirect, recurse.  */

static bfd_boolean
vms_traverse_index (bfd *abfd, unsigned int vbn, struct carsym_mem *cs)
{
  struct vms_indexdef indexdef;
  file_ptr off;
  unsigned char *p;
  unsigned char *endp;

  /* Read the index block.  */
  BFD_ASSERT (sizeof (indexdef) == VMS_BLOCK_SIZE);
  if (!vms_read_block (abfd, vbn, &indexdef))
    return FALSE;

  /* Traverse it.  */
  p = &indexdef.keys[0];
  endp = p + bfd_getl16 (indexdef.used);
  while (p < endp)
    {
      unsigned int idx_vbn;
      unsigned int idx_off;
      unsigned int keylen;
      unsigned char *keyname;
      unsigned int flags;

      /* Extract key length.  */
      if (bfd_libdata (abfd)->ver == LBR_MAJORID)
        {
          struct vms_idx *ridx = (struct vms_idx *)p;

          idx_vbn = bfd_getl32 (ridx->rfa.vbn);
          idx_off = bfd_getl16 (ridx->rfa.offset);

          keylen = ridx->keylen;
          flags = 0;
          keyname = ridx->keyname;
        }
      else if (bfd_libdata (abfd)->ver == LBR_ELFMAJORID)
        {
          struct vms_elfidx *ridx = (struct vms_elfidx *)p;

          idx_vbn = bfd_getl32 (ridx->rfa.vbn);
          idx_off = bfd_getl16 (ridx->rfa.offset);

          keylen = bfd_getl16 (ridx->keylen);
          flags = ridx->flags;
          keyname = ridx->keyname;
        }
      else
        return FALSE;

      /* Illegal value.  */
      if (idx_vbn == 0)
        return FALSE;

      /* Point to the next index entry.  */
      p = keyname + keylen;

      if (idx_off == RFADEF__C_INDEX)
        {
          /* Indirect entry.  Recurse.  */
          if (!vms_traverse_index (abfd, idx_vbn, cs))
            return FALSE;
        }
      else
        {
          /* Add a new entry.  */
          char *name;

          if (flags & ELFIDX__SYMESC)
            {
              /* Extended key name.  */
              unsigned int noff = 0;
              unsigned int koff;
              unsigned int kvbn;
              struct vms_kbn *kbn;
              unsigned char kblk[VMS_BLOCK_SIZE];

              /* Sanity check.  */
              if (keylen != sizeof (struct vms_kbn))
                return FALSE;

              kbn = (struct vms_kbn *)keyname;
              keylen = bfd_getl16 (kbn->keylen);

              name = bfd_alloc (abfd, keylen + 1);
              if (name == NULL)
                return FALSE;
              kvbn = bfd_getl32 (kbn->rfa.vbn);
              koff = bfd_getl16 (kbn->rfa.offset);

              /* Read the key, chunk by chunk.  */
              do
                {
                  unsigned int klen;

                  if (!vms_read_block (abfd, kvbn, kblk))
                    return FALSE;
                  kbn = (struct vms_kbn *)(kblk + koff);
                  klen = bfd_getl16 (kbn->keylen);
                  kvbn = bfd_getl32 (kbn->rfa.vbn);
                  koff = bfd_getl16 (kbn->rfa.offset);

                  memcpy (name + noff, kbn + 1, klen);
                  noff += klen;
                }
              while (kvbn != 0);

              /* Sanity check.  */
              if (noff != keylen)
                return FALSE;
            }
          else
            {
              /* Usual key name.  */
              name = bfd_alloc (abfd, keylen + 1);
              if (name == NULL)
                return FALSE;

              memcpy (name, keyname, keylen);
            }
          name[keylen] = 0;

          if (flags & ELFIDX__LISTRFA)
            {
              struct vms_lhs lhs;

              /* Read the LHS.  */
              off = (idx_vbn - 1) * VMS_BLOCK_SIZE + idx_off;
              if (bfd_seek (abfd, off, SEEK_SET) != 0
                  || bfd_bread (&lhs, sizeof (lhs), abfd) != sizeof (lhs))
                return FALSE;

              /* FIXME: this adds extra entries that were not accounted.  */
              if (!vms_add_indexes_from_list (abfd, cs, name, &lhs.ng_g_rfa))
                return FALSE;
              if (!vms_add_indexes_from_list (abfd, cs, name, &lhs.ng_wk_rfa))
                return FALSE;
              if (!vms_add_indexes_from_list (abfd, cs, name, &lhs.g_g_rfa))
                return FALSE;
              if (!vms_add_indexes_from_list (abfd, cs, name, &lhs.g_wk_rfa))
                return FALSE;
            }
          else
            {
              if (!vms_add_index (cs, name, idx_vbn, idx_off))
                return FALSE;
            }
        }
    }

  return TRUE;
}

/* Read index #IDX, which must have NBREL entries.  */

static struct carsym *
vms_lib_read_index (bfd *abfd, int idx, unsigned int *nbrel)
{
  struct vms_idd idd;
  unsigned int flags;
  unsigned int vbn;
  struct carsym *csbuf;
  struct carsym_mem csm;

  /* Read index desription.  */
  if (bfd_seek (abfd, LHD_IDXDESC + idx * IDD_LENGTH, SEEK_SET) != 0
      || bfd_bread (&idd, sizeof (idd), abfd) != sizeof (idd))
    return NULL;

  /* Sanity checks.  */
  flags = bfd_getl16 (idd.flags);
  if (!(flags & IDD__FLAGS_ASCII)
      || !(flags & IDD__FLAGS_VARLENIDX))
    return NULL;

  csbuf = bfd_alloc (abfd, *nbrel * sizeof (struct carsym));
  if (csbuf == NULL)
    return NULL;

  csm.max = *nbrel;
  csm.nbr = 0;
  csm.realloced = FALSE;
  csm.idx = csbuf;

  /* Note: if the index is empty, there is no block to traverse.  */
  vbn = bfd_getl32 (idd.vbn);
  if (vbn != 0 && !vms_traverse_index (abfd, vbn, &csm))
    {
      if (csm.realloced && csm.idx != NULL)
        free (csm.idx);

      /* Note: in case of error, we can free what was allocated on the
         BFD's objalloc.  */
      bfd_release (abfd, csbuf);
      return NULL;
    }

  if (csm.realloced)
    {
      /* There are more entries than the first estimate.  Allocate on
         the BFD's objalloc.  */
      csbuf = bfd_alloc (abfd, csm.nbr * sizeof (struct carsym));
      if (csbuf == NULL)
        return NULL;
      memcpy (csbuf, csm.idx, csm.nbr * sizeof (struct carsym));
      free (csm.idx);
      *nbrel = csm.nbr;
    }
  return csbuf;
}

/* Standard function.  */

static const bfd_target *
_bfd_vms_lib_archive_p (bfd *abfd, enum vms_lib_kind kind)
{
  struct vms_lhd lhd;
  unsigned int sanity;
  unsigned int majorid;
  struct lib_tdata *tdata_hold;
  struct lib_tdata *tdata;
  unsigned int dcxvbn;
  unsigned int nbr_ent;

  /* Read header.  */
  if (bfd_bread (&lhd, sizeof (lhd), abfd) != sizeof (lhd))
    {
      if (bfd_get_error () != bfd_error_system_call)
	bfd_set_error (bfd_error_wrong_format);
      return NULL;
    }

  /* Check sanity (= magic) number.  */
  sanity = bfd_getl32 (lhd.sanity);
  if (!(sanity == LHD_SANEID3
        || sanity == LHD_SANEID6
        || sanity == LHD_SANEID_DCX))
    {
      bfd_set_error (bfd_error_wrong_format);
      return NULL;
    }
  majorid = bfd_getl32 (lhd.majorid);

  /* Check archive kind.  */
  switch (kind)
    {
    case vms_lib_alpha:
      if ((lhd.type != LBR__C_TYP_EOBJ && lhd.type != LBR__C_TYP_ESHSTB)
          || majorid != LBR_MAJORID
          || lhd.nindex != 2)
        {
          bfd_set_error (bfd_error_wrong_format);
          return NULL;
        }
      break;
    case vms_lib_ia64:
      if ((lhd.type != LBR__C_TYP_IOBJ && lhd.type != LBR__C_TYP_ISHSTB)
          || majorid != LBR_ELFMAJORID
          || lhd.nindex != 2)
        {
          bfd_set_error (bfd_error_wrong_format);
          return NULL;
        }
      break;
    case vms_lib_txt:
      if ((lhd.type != LBR__C_TYP_TXT
           && lhd.type != LBR__C_TYP_MLB
           && lhd.type != LBR__C_TYP_HLP)
          || majorid != LBR_MAJORID
          || lhd.nindex != 1)
        {
          bfd_set_error (bfd_error_wrong_format);
          return NULL;
        }
      break;
    default:
      abort ();
    }

  /* Allocate and initialize private data.  */
  tdata_hold = bfd_libdata (abfd);
  tdata = (struct lib_tdata *) bfd_zalloc (abfd, sizeof (struct lib_tdata));
  if (tdata == NULL)
    return NULL;
  abfd->tdata.any = (void *)tdata;
  tdata->ver = majorid;
  tdata->mhd_size = MHD__C_USRDAT + lhd.mhdusz;
  tdata->type = lhd.type;
  tdata->kind = kind;
  tdata->credat_lo = bfd_getl32 (lhd.credat + 0);
  tdata->credat_hi = bfd_getl32 (lhd.credat + 4);

  /* Read indexes.  */
  tdata->nbr_modules = bfd_getl32 (lhd.modcnt);
  tdata->artdata.symdef_count = bfd_getl32 (lhd.idxcnt) - tdata->nbr_modules;
  nbr_ent = tdata->nbr_modules;
  tdata->modules = vms_lib_read_index (abfd, 0, &nbr_ent);
  if (tdata->modules == NULL || nbr_ent != tdata->nbr_modules)
    goto err;
  if (lhd.nindex == 2)
    {
      nbr_ent = tdata->artdata.symdef_count;
      tdata->artdata.symdefs = vms_lib_read_index (abfd, 1, &nbr_ent);
      if (tdata->artdata.symdefs == NULL)
        goto err;
      /* Only IA64 archives may have more entries in the index that what
         was declared.  */
      if (nbr_ent != tdata->artdata.symdef_count
          && kind != vms_lib_ia64)
        goto err;
      tdata->artdata.symdef_count = nbr_ent;
    }
  tdata->cache = bfd_zalloc (abfd, sizeof (bfd *) * tdata->nbr_modules);
  if (tdata->cache == NULL)
    goto err;

  /* Read DCX submaps.  */
  dcxvbn = bfd_getl32 (lhd.dcxmapvbn);
  if (dcxvbn != 0)
    {
      unsigned char buf_reclen[4];
      unsigned int reclen;
      unsigned char *buf;
      struct vms_dcxmap *map;
      unsigned int sbm_off;
      unsigned int i;

      if (bfd_seek (abfd, (dcxvbn - 1) * VMS_BLOCK_SIZE, SEEK_SET) != 0
          || bfd_bread (buf_reclen, sizeof (buf_reclen), abfd)
          != sizeof (buf_reclen))
        goto err;
      reclen = bfd_getl32 (buf_reclen);
      buf = bfd_malloc (reclen);
      if (buf == NULL)
        goto err;
      if (bfd_bread (buf, reclen, abfd) != reclen)
        {
          free (buf);
          goto err;
        }
      map = (struct vms_dcxmap *)buf;
      tdata->nbr_dcxsbm = bfd_getl16 (map->nsubs);
      sbm_off = bfd_getl16 (map->sub0);
      tdata->dcxsbm = (struct dcxsbm_desc *)bfd_alloc
        (abfd, tdata->nbr_dcxsbm * sizeof (struct dcxsbm_desc));
      for (i = 0; i < tdata->nbr_dcxsbm; i++)
        {
          struct vms_dcxsbm *sbm = (struct vms_dcxsbm *) (buf + sbm_off);
          struct dcxsbm_desc *sbmdesc = &tdata->dcxsbm[i];
          unsigned int sbm_len;
          unsigned int sbm_sz;
          unsigned int off;
          unsigned char *data = (unsigned char *)sbm;
          unsigned char *buf1;
          unsigned int l, j;

          sbm_sz = bfd_getl16 (sbm->size);
          sbm_off += sbm_sz;
          BFD_ASSERT (sbm_off <= reclen);

          sbmdesc->min_char = sbm->min_char;
          BFD_ASSERT (sbmdesc->min_char == 0);
          sbmdesc->max_char = sbm->max_char;
          sbm_len = sbmdesc->max_char - sbmdesc->min_char + 1;
          l = (2 * sbm_len + 7) / 8;
          BFD_ASSERT
            (sbm_sz >= sizeof (struct vms_dcxsbm) + l + 3 * sbm_len
             || (tdata->nbr_dcxsbm == 1
                 && sbm_sz >= sizeof (struct vms_dcxsbm) + l + sbm_len));
          sbmdesc->flags = (unsigned char *)bfd_alloc (abfd, l);
          memcpy (sbmdesc->flags, data + bfd_getl16 (sbm->flags), l);
          sbmdesc->nodes = (unsigned char *)bfd_alloc (abfd, 2 * sbm_len);
          memcpy (sbmdesc->nodes, data + bfd_getl16 (sbm->nodes), 2 * sbm_len);
          off = bfd_getl16 (sbm->next);
          if (off != 0)
            {
              /* Read the 'next' array.  */
              sbmdesc->next = (unsigned short *)bfd_alloc
                (abfd, sbm_len * sizeof (unsigned short));
              buf1 = data + off;
              for (j = 0; j < sbm_len; j++)
                sbmdesc->next[j] = bfd_getl16 (buf1 + j * 2);
            }
          else
            {
              /* There is no next array if there is only one submap.  */
              BFD_ASSERT (tdata->nbr_dcxsbm == 1);
              sbmdesc->next = NULL;
            }
        }
      free (buf);
    }
  else
    {
      tdata->nbr_dcxsbm = 0;
    }

  /* The map is always present.  Also mark shared image library.  */
  abfd->has_armap = TRUE;
  if (tdata->type == LBR__C_TYP_ESHSTB || tdata->type == LBR__C_TYP_ISHSTB)
    abfd->is_thin_archive = TRUE;

  return abfd->xvec;

 err:
  bfd_release (abfd, tdata);
  abfd->tdata.any = (void *)tdata_hold;
  return NULL;
}

/* Standard function for alpha libraries.  */

const bfd_target *
_bfd_vms_lib_alpha_archive_p (bfd *abfd)
{
  return _bfd_vms_lib_archive_p (abfd, vms_lib_alpha);
}

/* Standard function for ia64 libraries.  */

const bfd_target *
_bfd_vms_lib_ia64_archive_p (bfd *abfd)
{
  return _bfd_vms_lib_archive_p (abfd, vms_lib_ia64);
}

/* Standard function for text libraries.  */

static const bfd_target *
_bfd_vms_lib_txt_archive_p (bfd *abfd)
{
  return _bfd_vms_lib_archive_p (abfd, vms_lib_txt);
}

/* Standard bfd function.  */

static bfd_boolean
_bfd_vms_lib_mkarchive (bfd *abfd, enum vms_lib_kind kind)
{
  struct lib_tdata *tdata;

  tdata = (struct lib_tdata *) bfd_zalloc (abfd, sizeof (struct lib_tdata));
  if (tdata == NULL)
    return FALSE;

  abfd->tdata.any = (void *)tdata;
  vms_get_time (&tdata->credat_hi, &tdata->credat_lo);

  tdata->kind = kind;
  switch (kind)
    {
    case vms_lib_alpha:
      tdata->ver = LBR_MAJORID;
      tdata->mhd_size = offsetof (struct vms_mhd, pad1);
      tdata->type = LBR__C_TYP_EOBJ;
      break;
    case vms_lib_ia64:
      tdata->ver = LBR_ELFMAJORID;
      tdata->mhd_size = sizeof (struct vms_mhd);
      tdata->type = LBR__C_TYP_IOBJ;
      break;
    default:
      abort ();
    }

  tdata->nbr_modules = 0;
  tdata->artdata.symdef_count = 0;
  tdata->modules = NULL;
  tdata->artdata.symdefs = NULL;
  tdata->cache = NULL;

  return TRUE;
}

bfd_boolean
_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
_bfd_vms_lib_find_symbol (bfd *abfd, const char *name)
{
  struct lib_tdata *tdata = bfd_libdata (abfd);
  carsym *syms = tdata->artdata.symdefs;
  int lo, hi;

  /* Open-coded binary search for speed.  */
  lo = 0;
  hi = tdata->artdata.symdef_count - 1;

  while (lo <= hi)
    {
      int mid = lo + (hi - lo) / 2;
      int diff;

      diff = (char)(name[0] - syms[mid].name[0]);
      if (diff == 0)
        diff = strcmp (name, syms[mid].name);
      if (diff == 0)
        return mid;
      else if (diff < 0)
        hi = mid - 1;
      else
        lo = mid + 1;
    }
  return BFD_NO_MORE_SYMBOLS;
}

/* IO vector for archive member.  Need that because members are not linearly
   stored in archives.  */

struct vms_lib_iovec
{
  /* Current offset.  */
  ufile_ptr where;

  /* Length of the module, when known.  */
  ufile_ptr file_len;

  /* Current position in the record from bfd_bread point of view (ie, after
     decompression).  0 means that no data byte have been read, -2 and -1
     are reserved for the length word.  */
  int rec_pos;
#define REC_POS_NL   -4
#define REC_POS_PAD  -3
#define REC_POS_LEN0 -2
#define REC_POS_LEN1 -1

  /* Record length.  */
  unsigned short rec_len;
  /* Number of bytes to read in the current record.  */
  unsigned short rec_rem;
  /* Offset of the next block.  */
  file_ptr next_block;
  /* Current *data* offset in the data block.  */
  unsigned short blk_off;

  /* Offset of the first block.  Extracted from the index.  */
  file_ptr first_block;

  /* Initial next_block.  Extracted when the MHD is read.  */
  file_ptr init_next_block;
  /* Initial blk_off, once the MHD is read.  */
  unsigned short init_blk_off;

  /* Used to store any 3 byte record, which could be the EOF pattern.  */
  unsigned char pattern[4];

  /* DCX.  */
  struct dcxsbm_desc *dcxsbms;
  /* Current submap.  */
  struct dcxsbm_desc *dcx_sbm;
  /* Current offset in the submap.  */
  unsigned int dcx_offset;
  int dcx_pos;

  /* Compressed buffer.  */
  unsigned char *dcx_buf;
  /* Size of the buffer.  Used to resize.  */
  unsigned int dcx_max;
  /* Number of valid bytes in the buffer.  */
  unsigned int dcx_rlen;
};

/* Return the current position.  */

static file_ptr
vms_lib_btell (struct bfd *abfd)
{
  struct vms_lib_iovec *vec = (struct vms_lib_iovec *) abfd->iostream;
  return vec->where;
}

/* Read the header of the next data block if all bytes of the current block
   have been read.  */

static bfd_boolean
vms_lib_read_block (struct bfd *abfd)
{
  struct vms_lib_iovec *vec = (struct vms_lib_iovec *) abfd->iostream;

  if (vec->blk_off == DATA__LENGTH)
    {
      unsigned char hdr[DATA__DATA];

      /* Read next block.  */
      if (bfd_seek (abfd->my_archive, vec->next_block, SEEK_SET) != 0)
        return FALSE;
      if (bfd_bread (hdr, sizeof (hdr), abfd->my_archive) != sizeof (hdr))
        return FALSE;
      vec->next_block = (bfd_getl32 (hdr + 2) - 1) * VMS_BLOCK_SIZE;
      vec->blk_off = sizeof (hdr);
    }
  return TRUE;
}

/* Read NBYTES from ABFD into BUF if not NULL.  If BUF is NULL, bytes are
   not stored.  Read linearly from the library, but handle blocks.  This
   function does not handle records nor EOF.  */

static file_ptr
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;

  res = 0;
  while (nbytes > 0)
    {
      unsigned int l;

      /* Be sure the current data block is read.  */
      if (!vms_lib_read_block (abfd))
        return -1;

      /* Do not read past the data block, do not read more than requested.  */
      l = DATA__LENGTH - vec->blk_off;
      if (l > nbytes)
        l = nbytes;
      if (l == 0)
        return 0;
      if (buf != NULL)
        {
          /* Really read into BUF.  */
          if (bfd_bread (buf, l, abfd->my_archive) != l)
            return -1;
        }
      else
        {
          /* Make as if we are reading.  */
          if (bfd_seek (abfd->my_archive, l, SEEK_CUR) != 0)
            return -1;
        }

      if (buf != NULL)
        buf += l;
      vec->blk_off += l;
      nbytes -= l;
      res += l;
    }
  return res;
}

/* Decompress NBYTES from VEC.  Store the bytes into BUF if not NULL.  */

static file_ptr
vms_lib_dcx (struct vms_lib_iovec *vec, unsigned char *buf, file_ptr nbytes)
{
  struct dcxsbm_desc *sbm;
  unsigned int i;
  unsigned int offset;
  unsigned int j;
  file_ptr res = 0;

  /* The loop below expect to deliver at least one byte.  */
  if (nbytes == 0)
    return 0;

  /* Get the current state.  */
  sbm = vec->dcx_sbm;
  offset = vec->dcx_offset;
  j = vec->dcx_pos & 7;

  for (i = vec->dcx_pos >> 3; i < vec->dcx_rlen; i++)
    {
      unsigned char b = vec->dcx_buf[i];

      for (; j < 8; j++)
        {
          if (b & (1 << j))
            offset++;
          if (!(sbm->flags[offset >> 3] & (1 << (offset & 7))))
            {
              unsigned int n_offset = sbm->nodes[offset];
              if (n_offset == 0)
                {
                  /* End of buffer.  Stay where we are.  */
                  vec->dcx_pos = (i << 3) + j;
                  if (b & (1 << j))
                    offset--;
                  vec->dcx_offset = offset;
                  vec->dcx_sbm = sbm;
                  return res;
                }
              offset = 2 * n_offset;
            }
          else
            {
              unsigned char v = sbm->nodes[offset];

              if (sbm->next != NULL)
                sbm = vec->dcxsbms + sbm->next[v];
              offset = 0;
              res++;

              if (buf)
                {
                  *buf++ = v;
                  nbytes--;

                  if (nbytes == 0)
                    {
                      vec->dcx_pos = (i << 3) + j + 1;
                      vec->dcx_offset = offset;
                      vec->dcx_sbm = sbm;

                      return res;
                    }
                }
            }
        }
      j = 0;
    }
  return -1;
}

/* Standard IOVEC function.  */

static file_ptr
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)
    return 0;

  res = 0;
  while (nbytes > 0)
    {
      if (vec->rec_rem == 0)
        {
          unsigned char blen[2];

          /* Read record length.  */
          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)
            {
              /* Discard record size and align byte.  */
              vec->rec_pos = 0;
              vec->rec_rem = vec->rec_len;
            }
          else
            {
              /* Prepend record size.  */
              vec->rec_pos = REC_POS_LEN0;
              vec->rec_rem = (vec->rec_len + 1) & ~1;	/* With align byte.  */
            }
          if (vec->rec_len == 3)
            {
              /* Possibly end of file.  Check the pattern.  */
              if (vms_lib_bread_raw (abfd, vec->pattern, 4) != 4)
                return -1;
              if (!memcmp (vec->pattern, eotdesc + 2, 3))
                {
                  /* This is really an EOF.  */
                  vec->where += res;
                  vec->file_len = vec->where;
                  return res;
                }
            }

          if (vec->dcxsbms != NULL)
            {
              /* This is a compressed member.  */
              unsigned int len;
              file_ptr elen;

              /* Be sure there is enough room for the expansion.  */
              len = (vec->rec_len + 1) & ~1;
              if (len > vec->dcx_max)
                {
                  while (len > vec->dcx_max)
                    vec->dcx_max *= 2;
                  vec->dcx_buf = bfd_alloc (abfd, vec->dcx_max);
                  if (vec->dcx_buf == NULL)
                    return -1;
                }

              /* Read the compressed record.  */
              vec->dcx_rlen = len;
              if (vec->rec_len == 3)
                {
                  /* Already read.  */
                  memcpy (vec->dcx_buf, vec->pattern, 3);
                }
              else
                {
                  elen = vms_lib_bread_raw (abfd, vec->dcx_buf, len);
                  if (elen != len)
                    return -1;
                }

              /* Dummy expansion to get the expanded length.  */
              vec->dcx_offset = 0;
              vec->dcx_sbm = vec->dcxsbms;
              vec->dcx_pos = 0;
              elen = vms_lib_dcx (vec, NULL, 0x10000);
              if (elen < 0)
                return -1;
              vec->rec_len = elen;
              vec->rec_rem = elen;

              /* Reset the state.  */
              vec->dcx_offset = 0;
              vec->dcx_sbm = vec->dcxsbms;
              vec->dcx_pos = 0;
            }
        }
      if (vec->rec_pos < 0)
        {
          unsigned char c;
          switch (vec->rec_pos)
            {
            case REC_POS_LEN0:
              c = vec->rec_len & 0xff;
              vec->rec_pos = REC_POS_LEN1;
              break;
            case REC_POS_LEN1:
              c = (vec->rec_len >> 8) & 0xff;
              vec->rec_pos = 0;
              break;
            case REC_POS_PAD:
              c = 0;
              vec->rec_rem = 0;
              break;
            case REC_POS_NL:
              c = '\n';
              vec->rec_rem = 0;
              break;
            default:
              abort ();
            }
          if (buf != NULL)
            {
              *buf = c;
              buf++;
            }
          nbytes--;
          res++;
          continue;
        }

      if (nbytes > vec->rec_rem)
        chunk = vec->rec_rem;
      else
        chunk = nbytes;

      if (vec->dcxsbms != NULL)
        {
          /* Optimize the stat() case: no need to decompress again as we
             know the length.  */
          if (!(buf == NULL && chunk == vec->rec_rem))
            chunk = vms_lib_dcx (vec, buf, chunk);
        }
      else
        {
          if (vec->rec_len == 3)
            {
              if (buf != NULL)
                memcpy (buf, vec->pattern + vec->rec_pos, chunk);
            }
          else
            chunk = vms_lib_bread_raw (abfd, buf, chunk);
        }
      if (chunk < 0)
        return -1;
      res += chunk;
      if (buf != NULL)
        buf += chunk;
      nbytes -= chunk;
      vec->rec_pos += chunk;
      vec->rec_rem -= chunk;

      if (vec->rec_rem == 0)
        {
          /* End of record reached.  */
          if (bfd_libdata (abfd->my_archive)->kind == vms_lib_txt)
            {
              if ((vec->rec_len & 1) == 1
                  && vec->rec_len != 3
                  && vec->dcxsbms == NULL)
                {
                  /* Eat the pad byte.  */
                  unsigned char pad;
                  if (vms_lib_bread_raw (abfd, &pad, 1) != 1)
                    return -1;
                }
              vec->rec_pos = REC_POS_NL;
              vec->rec_rem = 1;
            }
          else
            {
              if ((vec->rec_len & 1) == 1 && vec->dcxsbms != NULL)
                {
                  vec->rec_pos = REC_POS_PAD;
                  vec->rec_rem = 1;
                }
            }
        }
    }
  vec->where += res;
  return res;
}

/* Standard function, but we currently only handle the rewind case.  */

static int
vms_lib_bseek (struct bfd *abfd, file_ptr offset, int whence)
{
  struct vms_lib_iovec *vec = (struct vms_lib_iovec *) abfd->iostream;

  if (whence == SEEK_SET && offset == 0)
    {
      vec->where = 0;
      vec->rec_rem = 0;
      vec->dcx_pos = -1;
      vec->blk_off = vec->init_blk_off;
      vec->next_block = vec->init_next_block;

      if (bfd_seek (abfd->my_archive, vec->first_block, SEEK_SET) != 0)
        return -1;
    }
  else
    abort ();
  return 0;
}

static file_ptr
vms_lib_bwrite (struct bfd *abfd ATTRIBUTE_UNUSED,
	      const void *where ATTRIBUTE_UNUSED,
	      file_ptr nbytes ATTRIBUTE_UNUSED)
{
  return -1;
}

static int
vms_lib_bclose (struct bfd *abfd)
{
  abfd->iostream = NULL;
  return 0;
}

static int
vms_lib_bflush (struct bfd *abfd ATTRIBUTE_UNUSED)
{
  return 0;
}

static int
vms_lib_bstat (struct bfd *abfd ATTRIBUTE_UNUSED,
               struct stat *sb ATTRIBUTE_UNUSED)
{
  /* Not supported.  */
  return 0;
}

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 **map_addr ATTRIBUTE_UNUSED,
               bfd_size_type *map_len ATTRIBUTE_UNUSED)
{
  return (void *) -1;
}

static const struct bfd_iovec vms_lib_iovec = {
  &vms_lib_bread, &vms_lib_bwrite, &vms_lib_btell, &vms_lib_bseek,
  &vms_lib_bclose, &vms_lib_bflush, &vms_lib_bstat, &vms_lib_bmmap
};

/* Open a library module.  FILEPOS is the position of the module header.  */

static bfd_boolean
vms_lib_bopen (bfd *el, file_ptr filepos)
{
  struct vms_lib_iovec *vec;
  unsigned char buf[256];
  struct vms_mhd *mhd;
  struct lib_tdata *tdata = bfd_libdata (el->my_archive);
  unsigned int len;

  /* Allocate and initialized the iovec.  */
  vec = bfd_zalloc (el, sizeof (*vec));
  if (vec == NULL)
    return FALSE;

  el->iostream = vec;
  el->iovec = &vms_lib_iovec;

  /* File length is not known.  */
  vec->file_len = -1;

  /* Read the first data block.  */
  vec->next_block = filepos & ~(VMS_BLOCK_SIZE - 1);
  vec->blk_off = DATA__LENGTH;
  if (!vms_lib_read_block (el))
    return FALSE;

  /* Prepare to read the first record.  */
  vec->blk_off = filepos & (VMS_BLOCK_SIZE - 1);
  vec->rec_rem = 0;
  if (bfd_seek (el->my_archive, filepos, SEEK_SET) != 0)
    return FALSE;

  /* Read Record length + MHD + align byte.  */
  len = tdata->mhd_size;
  if (vms_lib_bread_raw (el, buf, 2) != 2)
    return FALSE;
  if (bfd_getl16 (buf) != len)
    return FALSE;
  len = (len + 1) & ~1;
  BFD_ASSERT (len <= sizeof (buf));
  if (vms_lib_bread_raw (el, buf, len) != len)
    return FALSE;

  /* Get info from mhd.  */
  mhd = (struct vms_mhd *)buf;
  /* Check id.  */
  if (mhd->id != MHD__C_MHDID)
    return FALSE;
  if (len >= MHD__C_MHDLEN + 1)
    el->selective_search = (mhd->objstat & MHD__M_SELSRC) ? 1 : 0;
  el->mtime = vms_rawtime_to_time_t (mhd->datim);
  el->mtime_set = TRUE;

  /* Reinit the iovec so that seek() will point to the first record after
     the mhd.  */
  vec->where = 0;
  vec->init_blk_off = vec->blk_off;
  vec->init_next_block = vec->next_block;
  vec->first_block = bfd_tell (el->my_archive);
  vec->dcxsbms = bfd_libdata (el->my_archive)->dcxsbm;

  if (vec->dcxsbms != NULL)
    {
      /* Handle DCX.  */
      vec->dcx_max = 10 * 1024;
      vec->dcx_buf = bfd_alloc (el, vec->dcx_max);
      vec->dcx_pos = -1;
      if (vec->dcx_buf == NULL)
        return -1;
    }
  return TRUE;
}

/* Get member MODIDX.  Return NULL in case of error.  */

static bfd *
_bfd_vms_lib_get_module (bfd *abfd, unsigned int modidx)
{
  struct lib_tdata *tdata = bfd_libdata (abfd);
  bfd *res;
  file_ptr file_off;
  char *name;

  /* Sanity check.  */
  if (modidx >= tdata->nbr_modules)
    return NULL;

  /* Already loaded.  */
  if (tdata->cache[modidx])
    return tdata->cache[modidx];

  /* Build it.  */
  file_off = tdata->modules[modidx].file_offset;
  if (tdata->type != LBR__C_TYP_IOBJ)
    {
      res = _bfd_create_empty_archive_element_shell (abfd);
      if (res == NULL)
        return NULL;

      /* Special reader to deal with data blocks.  */
      if (!vms_lib_bopen (res, file_off))
        return NULL;
    }
  else
    {
      char buf[256];
      struct vms_mhd *mhd;
      struct areltdata *arelt;

      /* Sanity check.  The MHD must be big enough to contain module size.  */
      if (tdata->mhd_size < offsetof (struct vms_mhd, modsize) + 4)
        return NULL;

      /* Read the MHD now.  */
      if (bfd_seek (abfd, file_off, SEEK_SET) != 0)
        return NULL;
      if (bfd_bread (buf, tdata->mhd_size, abfd) != tdata->mhd_size)
        return NULL;

      res = _bfd_create_empty_archive_element_shell (abfd);
      if (res == NULL)
        return NULL;
      arelt = bfd_zmalloc (sizeof (*arelt));
      if (arelt == NULL)
        return NULL;
      res->arelt_data = arelt;

      /* Get info from mhd.  */
      mhd = (struct vms_mhd *)buf;
      if (mhd->id != MHD__C_MHDID)
        return NULL;
      if (tdata->mhd_size >= offsetof (struct vms_mhd, objstat) + 1)
        res->selective_search = (mhd->objstat & MHD__M_SELSRC) ? 1 : 0;
      res->mtime = vms_rawtime_to_time_t (mhd->datim);
      res->mtime_set = TRUE;

      arelt->parsed_size = bfd_getl32 (mhd->modsize);

      /* No need for a special reader as members are stored linearly.
         Just skip the MHD.  */
      res->origin = file_off + tdata->mhd_size;
    }

  /* Set filename.  */
  name = tdata->modules[modidx].name;
  switch (tdata->type)
    {
    case LBR__C_TYP_IOBJ:
    case LBR__C_TYP_EOBJ:
      /* For object archives, append .obj to mimic standard behaviour.  */
      {
	size_t namelen = strlen (name);
	char *name1 = bfd_alloc (res, namelen + 4 + 1);
	memcpy (name1, name, namelen);
	strcpy (name1 + namelen, ".obj");
	name = name1;
      }
      break;
    default:
      break;
    }
  res->filename = xstrdup (name);

  tdata->cache[modidx] = res;

  return res;
}

/* Standard function: get member at IDX.  */

bfd *
_bfd_vms_lib_get_elt_at_index (bfd *abfd, symindex symidx)
{
  struct lib_tdata *tdata = bfd_libdata (abfd);
  file_ptr file_off;
  unsigned int modidx;

  /* Check symidx.  */
  if (symidx > tdata->artdata.symdef_count)
    return NULL;
  file_off = tdata->artdata.symdefs[symidx].file_offset;

  /* Linear-scan.  */
  for (modidx = 0; modidx < tdata->nbr_modules; modidx++)
    {
      if (tdata->modules[modidx].file_offset == file_off)
        break;
    }
  if (modidx >= tdata->nbr_modules)
    return NULL;

  return _bfd_vms_lib_get_module (abfd, modidx);
}

/* Elements of an imagelib are stubs.  You can get the real image with this
   function.  */

bfd *
_bfd_vms_lib_get_imagelib_file (bfd *el)
{
  bfd *archive = el->my_archive;
  const char *modname = el->filename;
  int modlen = strlen (modname);
  char *filename;
  int j;
  bfd *res;

  /* Convert module name to lower case and append '.exe'.  */
  filename = bfd_alloc (el, modlen + 5);
  if (filename == NULL)
    return NULL;
  for (j = 0; j < modlen; j++)
    if (ISALPHA (modname[j]))
      filename[j] = TOLOWER (modname[j]);
    else
      filename[j] = modname[j];
  memcpy (filename + modlen, ".exe", 5);

  filename = _bfd_append_relative_path (archive, filename);
  if (filename == NULL)
    return NULL;
  res = bfd_openr (filename, NULL);

  if (res == NULL)
    {
      /* xgettext:c-format */
      _bfd_error_handler(_("could not open shared image '%s' from '%s'"),
			 filename, archive->filename);
      bfd_release (archive, filename);
      return NULL;
    }

  /* FIXME: put it in a cache ?  */
  return res;
}

/* Standard function.  */

bfd *
_bfd_vms_lib_openr_next_archived_file (bfd *archive,
                                       bfd *last_file)
{
  unsigned int idx;
  bfd *res;

  if (!last_file)
    idx = 0;
  else
    idx = last_file->proxy_origin + 1;

  if (idx >= bfd_libdata (archive)->nbr_modules)
    {
      bfd_set_error (bfd_error_no_more_archived_files);
      return NULL;
    }

  res = _bfd_vms_lib_get_module (archive, idx);
  if (res == NULL)
    return res;
  res->proxy_origin = idx;
  return res;
}

/* Standard function.  Just compute the length.  */

int
_bfd_vms_lib_generic_stat_arch_elt (bfd *abfd, struct stat *st)
{
  struct lib_tdata *tdata;

  /* Sanity check.  */
  if (abfd->my_archive == NULL)
    {
      bfd_set_error (bfd_error_invalid_operation);
      return -1;
    }

  tdata = bfd_libdata (abfd->my_archive);
  if (tdata->type != LBR__C_TYP_IOBJ)
    {
      struct vms_lib_iovec *vec = (struct vms_lib_iovec *) abfd->iostream;

      if (vec->file_len == (ufile_ptr)-1)
        {
          if (vms_lib_bseek (abfd, 0, SEEK_SET) != 0)
            return -1;

          /* Compute length.  */
          while (vms_lib_bread (abfd, NULL, 1 << 20) > 0)
            ;
        }
      st->st_size = vec->file_len;
    }
  else
    {
      st->st_size = ((struct areltdata *)abfd->arelt_data)->parsed_size;
    }

  if (abfd->mtime_set)
    st->st_mtime = abfd->mtime;
  else
    st->st_mtime = 0;
  st->st_uid = 0;
  st->st_gid = 0;
  st->st_mode = 0644;

  return 0;
}

/* Internal representation of an index entry.  */

struct lib_index
{
  /* Corresponding archive member.  */
  bfd *abfd;

  /* Number of reference to this entry.  */
  unsigned int ref;

  /* Length of the key.  */
  unsigned short namlen;

  /* Key.  */
  const char *name;
};

/* Used to sort index entries.  */

static int
lib_index_cmp (const void *lv, const void *rv)
{
  const struct lib_index *l = lv;
  const struct lib_index *r = rv;

  return strcmp (l->name, r->name);
}

/* Maximum number of index blocks level.  */

#define MAX_LEVEL 10

/* Get the size of an index entry.  */

static unsigned int
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_kbn);
      else
        return 9 + idx->namlen;
    }
  else
    {
      /* 7 is the size of struct vms_idx without keyname.  */
      return 7 + idx->namlen;
    }
}

/* 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
vms_write_index (bfd *abfd,
                 struct lib_index *idx, unsigned int nbr, unsigned int *vbn,
                 unsigned int *topvbn, bfd_boolean is_elfidx)
{
  /* 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
     branch when all upper leaves and branches are full.  We only keep in
     memory a path to the current leaf.  */
  unsigned int i;
  int j;
  int level;
  /* Disk blocks for the current path.  */
  struct vms_indexdef *rblk[MAX_LEVEL];
  /* Info on the current blocks.  */
  struct idxblk
  {
    unsigned int vbn;		/* VBN of the block.  */
    /* The last entry is identified so that it could be copied to the
       parent block.  */
    unsigned short len;		/* Length up to the last entry.  */
    unsigned short lastlen;	/* Length of the last entry.  */
  } blk[MAX_LEVEL];

  /* The kbn blocks are used to store long symbol names.  */
  unsigned int kbn_sz = 0;   /* Number of bytes available in the kbn block.  */
  unsigned int kbn_vbn = 0;  /* VBN of the kbn block.  */
  unsigned char *kbn_blk = NULL; /* Contents of the kbn block.  */

  if (nbr == 0)
    {
      /* No entries.  Very easy to handle.  */
      if (topvbn != NULL)
        *topvbn = 0;
      return TRUE;
    }

  if (abfd == NULL)
    {
      /* Sort the index the first time this function is called.  */
      qsort (idx, nbr, sizeof (struct lib_index), lib_index_cmp);
    }

  /* Allocate first index block.  */
  level = 1;
  if (abfd != NULL)
    rblk[0] = bfd_zmalloc (sizeof (struct vms_indexdef));
  blk[0].vbn = (*vbn)++;
  blk[0].len = 0;
  blk[0].lastlen = 0;

  for (i = 0; i < nbr; i++, idx++)
    {
      unsigned int idxlen;
      int flush = 0;
      unsigned int key_vbn = 0;
      unsigned int key_off = 0;

      idxlen = get_idxlen (idx, is_elfidx);

      if (is_elfidx && idx->namlen > MAX_KEYLEN)
        {
          /* If the key (ie name) is too long, write it in the kbn block.  */
          unsigned int kl = idx->namlen;
          unsigned int kl_chunk;
          const char *key = idx->name;

          /* Write the key in the kbn, chunk after chunk.  */
          do
            {
              if (kbn_sz < sizeof (struct vms_kbn))
                {
                  /* Not enough room in the kbn block.  */
                  if (abfd != NULL)
                    {
                      /* Write it to the disk (if there is one).  */
                      if (kbn_vbn != 0)
                        {
                          if (!vms_write_block (abfd, kbn_vbn, kbn_blk))
                            return FALSE;
                        }
                      else
                        {
                          kbn_blk = bfd_malloc (VMS_BLOCK_SIZE);
                          if (kbn_blk == NULL)
                            return FALSE;
                        }
                      *(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
                kl_chunk = kl;

              if (kbn_blk != NULL)
                {
                  struct vms_kbn *kbn;

                  kbn = (struct vms_kbn *)(kbn_blk + VMS_BLOCK_SIZE - kbn_sz);

                  if (key_vbn == 0)
                    {
                      /* Save the rfa of the first chunk.  */
                      key_vbn = kbn_vbn;
                      key_off = VMS_BLOCK_SIZE - kbn_sz;
                    }

                  bfd_putl16 (kl_chunk, kbn->keylen);
                  if (kl_chunk == kl)
                    {
                      /* No next chunk.  */
                      bfd_putl32 (0, kbn->rfa.vbn);
                      bfd_putl16 (0, kbn->rfa.offset);
                    }
                  else
                    {
                      /* Next chunk will be at the start of the next block.  */
                      bfd_putl32 (*vbn, kbn->rfa.vbn);
                      bfd_putl16 (2, kbn->rfa.offset);
                    }
                  memcpy ((char *)(kbn + 1), key, kl_chunk);
                  key += kl_chunk;
                }
              kl -= kl_chunk;
              kl_chunk = (kl_chunk + 1) & ~1;	  /* Always align.  */
              kbn_sz -= kl_chunk + sizeof (struct vms_kbn);
            }
          while (kl > 0);
        }

      /* Check if a block might overflow.  In this case we will flush this
         block and all the blocks below it.  */
      for (j = 0; j < level; j++)
        if (blk[j].len + blk[j].lastlen + idxlen > INDEXDEF__BLKSIZ)
	  flush = j + 1;

      for (j = 0; j < level; j++)
        {
          if (j < flush)
            {
              /* There is not enough room to write the new entry in this
                 block or in a parent block.  */

              if (j + 1 == level)
                {
                  BFD_ASSERT (level < MAX_LEVEL);

                  /* Need to create a parent.  */
                  if (abfd != NULL)
                    {
                      rblk[level] = bfd_zmalloc (sizeof (struct vms_indexdef));
                      bfd_putl32 (*vbn, rblk[j]->parent);
                    }
                  blk[level].vbn = (*vbn)++;
                  blk[level].len = 0;
                  blk[level].lastlen = blk[j].lastlen;

                  level++;
                }

              /* Update parent block: write the last entry from the current
		 block.  */
              if (abfd != NULL)
                {
                  struct vms_rfa *rfa;

		  /* Pointer to the last entry in parent block.  */
		  rfa = (struct vms_rfa *)(rblk[j + 1]->keys + blk[j + 1].len);

                  /* Copy the whole entry.  */
		  BFD_ASSERT (blk[j + 1].lastlen == 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
		     entry.  */
                  bfd_putl32 (blk[j].vbn, rfa->vbn);
                  bfd_putl16 (RFADEF__C_INDEX, rfa->offset);
                }

              if (j + 1 == flush)
                {
                  /* And allocate it.  Do it only on the block that won't be
                     flushed (so that the parent of the parent can be
                     updated too).  */
                  blk[j + 1].len += blk[j + 1].lastlen;
                  blk[j + 1].lastlen = 0;
                }

              /* Write this block on the disk.  */
              if (abfd != NULL)
                {
                  bfd_putl16 (blk[j].len + blk[j].lastlen, rblk[j]->used);
                  if (!vms_write_block (abfd, blk[j].vbn, rblk[j]))
                    return FALSE;
                }

              /* Reset this block.  */
              blk[j].len = 0;
              blk[j].lastlen = 0;
              blk[j].vbn = (*vbn)++;
            }

          /* Append it to the block.  */
          if (j == 0)
            {
	      /* Keep the previous last entry.  */
              blk[j].len += blk[j].lastlen;

              if (abfd != NULL)
                {
                  struct vms_rfa *rfa;

                  rfa = (struct vms_rfa *)(rblk[j]->keys + blk[j].len);
                  bfd_putl32 ((idx->abfd->proxy_origin / VMS_BLOCK_SIZE) + 1,
                              rfa->vbn);
                  bfd_putl16
                    ((idx->abfd->proxy_origin % VMS_BLOCK_SIZE)
                     + (is_elfidx ? 0 : DATA__DATA),
                     rfa->offset);

                  if (is_elfidx)
                    {
                      /* Use elfidx format.  */
                      struct vms_elfidx *en = (struct vms_elfidx *)rfa;

                      en->flags = 0;
                      if (key_vbn != 0)
                        {
                          /* Long symbol name.  */
                          struct vms_kbn *k = (struct vms_kbn *)(en->keyname);
                          bfd_putl16 (sizeof (struct vms_kbn), en->keylen);
                          bfd_putl16 (idx->namlen, k->keylen);
                          bfd_putl32 (key_vbn, k->rfa.vbn);
                          bfd_putl16 (key_off, k->rfa.offset);
                          en->flags |= ELFIDX__SYMESC;
                        }
                      else
                        {
                          bfd_putl16 (idx->namlen, en->keylen);
                          memcpy (en->keyname, idx->name, idx->namlen);
                        }
                    }
                  else
                    {
                      /* Use idx format.  */
                      struct vms_idx *en = (struct vms_idx *)rfa;
                      en->keylen = idx->namlen;
                      memcpy (en->keyname, idx->name, idx->namlen);
                    }
                }
	    }
	  /* The last added key can now be the last one all blocks in the
	     path.  */
	  blk[j].lastlen = idxlen;
        }
    }

  /* Save VBN of the root.  */
  if (topvbn != NULL)
    *topvbn = blk[level - 1].vbn;

  if (abfd == NULL)
    return TRUE;

  /* Flush.  */
  for (j = 1; j < level; j++)
    {
      /* Update parent block: write the new entry.  */
      unsigned char *en;
      unsigned char *par;
      struct vms_rfa *rfa;

      en = rblk[j - 1]->keys + blk[j - 1].len;
      par = rblk[j]->keys + blk[j].len;
      BFD_ASSERT (blk[j].lastlen == blk[j - 1].lastlen);
      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]))
        return FALSE;

      free (rblk[j]);
    }

  /* Write the last kbn (if any).  */
  if (kbn_vbn != 0)
    {
      if (!vms_write_block (abfd, kbn_vbn, kbn_blk))
        return FALSE;
      free (kbn_blk);
    }

  return TRUE;
}

/* Append data to the data block DATA.  Force write if PAD is true.  */

static bfd_boolean
vms_write_data_block (bfd *arch, struct vms_datadef *data, file_ptr *off,
                      const unsigned char *buf, unsigned int len, int pad)
{
  while (len > 0 || pad)
    {
      unsigned int doff = *off & (VMS_BLOCK_SIZE - 1);
      unsigned int remlen = (DATA__LENGTH - DATA__DATA) - doff;
      unsigned int l;

      l = (len > remlen) ? remlen : len;
      memcpy (data->data + doff, buf, l);
      buf += l;
      len -= l;
      doff += l;
      *off += l;

      if (doff == (DATA__LENGTH - DATA__DATA) || (len == 0 && pad))
        {
          data->recs = 0;
          data->fill_1 = 0;
          bfd_putl32 ((*off / VMS_BLOCK_SIZE) + 2, data->link);

          if (bfd_bwrite (data, sizeof (*data), arch) != sizeof (*data))
            return FALSE;

          *off += DATA__LENGTH - doff;

          if (len == 0)
            break;
        }
    }
  return TRUE;
}

/* Build the symbols index.  */

static bfd_boolean
_bfd_vms_lib_build_map (unsigned int nbr_modules,
                        struct lib_index *modules,
                        unsigned int *res_cnt,
                        struct lib_index **res)
{
  unsigned int i;
  asymbol **syms = NULL;
  long syms_max = 0;
  struct lib_index *map = NULL;
  unsigned int map_max = 1024;		/* Fine initial default.  */
  unsigned int map_count = 0;

  map = (struct lib_index *) bfd_malloc (map_max * sizeof (struct lib_index));
  if (map == NULL)
    goto error_return;

  /* Gather symbols.  */
  for (i = 0; i < nbr_modules; i++)
    {
      long storage;
      long symcount;
      long src_count;
      bfd *current = modules[i].abfd;

      if ((bfd_get_file_flags (current) & HAS_SYMS) == 0)
        continue;

      storage = bfd_get_symtab_upper_bound (current);
      if (storage < 0)
        goto error_return;

      if (storage != 0)
        {
          if (storage > syms_max)
            {
              if (syms_max > 0)
                free (syms);
              syms_max = storage;
              syms = (asymbol **) bfd_malloc (syms_max);
              if (syms == NULL)
                goto error_return;
            }
          symcount = bfd_canonicalize_symtab (current, syms);
          if (symcount < 0)
            goto error_return;

          /* Now map over all the symbols, picking out the ones we
             want.  */
          for (src_count = 0; src_count < symcount; src_count++)
            {
              flagword flags = (syms[src_count])->flags;
              asection *sec = syms[src_count]->section;

              if ((flags & BSF_GLOBAL
                   || flags & BSF_WEAK
                   || flags & BSF_INDIRECT
                   || bfd_is_com_section (sec))
                  && ! bfd_is_und_section (sec))
                {
                  struct lib_index *new_map;

                  /* This symbol will go into the archive header.  */
                  if (map_count == map_max)
                    {
                      map_max *= 2;
                      new_map = (struct lib_index *)
                        bfd_realloc (map, map_max * sizeof (struct lib_index));
                      if (new_map == NULL)
                        goto error_return;
                      map = new_map;
                    }

                  map[map_count].abfd = current;
                  map[map_count].namlen = strlen (syms[src_count]->name);
                  map[map_count].name = syms[src_count]->name;
                  map_count++;
                  modules[i].ref++;
                }
            }
	}
    }

  *res_cnt = map_count;
  *res = map;
  return TRUE;

 error_return:
  if (syms_max > 0)
    free (syms);
  if (map != NULL)
    free (map);
  return FALSE;
}

/* Do the hard work: write an archive on the disk.  */

bfd_boolean
_bfd_vms_lib_write_archive_contents (bfd *arch)
{
  bfd *current;
  unsigned int nbr_modules;
  struct lib_index *modules;
  unsigned int nbr_symbols;
  struct lib_index *symbols;
  struct lib_tdata *tdata = bfd_libdata (arch);
  unsigned int i;
  file_ptr off;
  unsigned int nbr_mod_iblk;
  unsigned int nbr_sym_iblk;
  unsigned int vbn;
  unsigned int mod_idx_vbn;
  unsigned int sym_idx_vbn;
  bfd_boolean is_elfidx = tdata->kind == vms_lib_ia64;
  unsigned int max_keylen = is_elfidx ? MAX_EKEYLEN : MAX_KEYLEN;

  /* Count the number of modules (and do a first sanity check).  */
  nbr_modules = 0;
  for (current = arch->archive_head;
       current != NULL;
       current = current->archive_next)
    {
      /* This check is checking the bfds for the objects we're reading
	 from (which are usually either an object file or archive on
	 disk), not the archive entries we're writing to.  We don't
	 actually create bfds for the archive members, we just copy
	 them byte-wise when we write out the archive.  */
      if (bfd_write_p (current) || !bfd_check_format (current, bfd_object))
	{
	  bfd_set_error (bfd_error_invalid_operation);
	  goto input_err;
	}

      nbr_modules++;
    }

  /* Build the modules list.  */
  BFD_ASSERT (tdata->modules == NULL);
  modules = bfd_alloc (arch, nbr_modules * sizeof (struct lib_index));
  if (modules == NULL)
    return FALSE;

  for (current = arch->archive_head, i = 0;
       current != NULL;
       current = current->archive_next, i++)
    {
      unsigned int nl;

      modules[i].abfd = current;
      modules[i].name = vms_get_module_name (current->filename, FALSE);
      modules[i].ref = 1;

      /* FIXME: silently truncate long names ?  */
      nl = strlen (modules[i].name);
      modules[i].namlen = (nl > max_keylen ? max_keylen : nl);
    }

  /* Create the module index.  */
  vbn = 0;
  if (!vms_write_index (NULL, modules, nbr_modules, &vbn, NULL, is_elfidx))
    return FALSE;
  nbr_mod_iblk = vbn;

  /* Create symbol index.  */
  if (!_bfd_vms_lib_build_map (nbr_modules, modules, &nbr_symbols, &symbols))
    return FALSE;

  vbn = 0;
  if (!vms_write_index (NULL, symbols, nbr_symbols, &vbn, NULL, is_elfidx))
    return FALSE;
  nbr_sym_iblk = vbn;

  /* Write modules and remember their position.  */
  off = (1 + nbr_mod_iblk + nbr_sym_iblk) * VMS_BLOCK_SIZE;

  if (bfd_seek (arch, off, SEEK_SET) != 0)
    return FALSE;

  for (i = 0; i < nbr_modules; i++)
    {
      struct vms_datadef data;
      unsigned char blk[VMS_BLOCK_SIZE];
      struct vms_mhd *mhd;
      unsigned int sz;

      current = modules[i].abfd;
      current->proxy_origin = off;

      if (is_elfidx)
        sz = 0;
      else
        {
          /* Write the MHD as a record (ie, size first).  */
          sz = 2;
          bfd_putl16 (tdata->mhd_size, blk);
        }
      mhd = (struct vms_mhd *)(blk + sz);
      memset (mhd, 0, sizeof (struct vms_mhd));
      mhd->lbrflag = 0;
      mhd->id = MHD__C_MHDID;
      mhd->objidlng = 4;
      memcpy (mhd->objid, "V1.0", 4);
      bfd_putl32 (modules[i].ref, mhd->refcnt);
      /* FIXME: datim.  */

      sz += tdata->mhd_size;
      sz = (sz + 1) & ~1;

      /* Rewind the member to be put into the archive.  */
      if (bfd_seek (current, 0, SEEK_SET) != 0)
        goto input_err;

      /* Copy the member into the archive.  */
      if (is_elfidx)
        {
          unsigned int modsize = 0;
          bfd_size_type amt;
          file_ptr off_hdr = off;

          /* Read to complete the first block.  */
          amt = bfd_bread (blk + sz, VMS_BLOCK_SIZE - sz, current);
          if (amt == (bfd_size_type)-1)
            goto input_err;
          modsize = amt;
          if (amt < VMS_BLOCK_SIZE - sz)
            {
              /* The member size is less than a block.  Pad the block.  */
              memset (blk + sz + amt, 0, VMS_BLOCK_SIZE - sz - amt);
            }
          bfd_putl32 (modsize, mhd->modsize);

          /* 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)
            {
              /* Copy the remaining.  */
              char buffer[DEFAULT_BUFFERSIZE];

              while (1)
                {
                  amt = bfd_bread (buffer, sizeof (buffer), current);
                  if (amt == (bfd_size_type)-1)
                    goto input_err;
                  if (amt == 0)
                    break;
                  modsize += amt;
                  if (amt != sizeof (buffer))
                    {
                      /* Clear the padding.  */
                      memset (buffer + amt, 0, sizeof (buffer) - amt);
                      amt = (amt + VMS_BLOCK_SIZE) & ~(VMS_BLOCK_SIZE - 1);
                    }
                  if (bfd_bwrite (buffer, amt, arch) != amt)
                    goto input_err;
                  off += amt;
                }

              /* Now that the size is known, write the first block (again).  */
              bfd_putl32 (modsize, mhd->modsize);
              if (bfd_seek (arch, off_hdr, SEEK_SET) != 0
                  || bfd_bwrite (blk, VMS_BLOCK_SIZE, arch) != VMS_BLOCK_SIZE)
                goto input_err;
              if (bfd_seek (arch, off, SEEK_SET) != 0)
                goto input_err;
            }
        }
      else
        {
          /* Write the MHD.  */
          if (vms_write_data_block (arch, &data, &off, blk, sz, 0) < 0)
            goto input_err;

          /* Write the member.  */
          while (1)
            {
              sz = bfd_bread (blk, sizeof (blk), current);
              if (sz == 0)
                break;
              if (vms_write_data_block (arch, &data, &off, blk, sz, 0) < 0)
                goto input_err;
            }

          /* Write the end of module marker.  */
          if (vms_write_data_block (arch, &data, &off,
                                    eotdesc, sizeof (eotdesc), 1) < 0)
            goto input_err;
        }
    }

  /* Write the indexes.  */
  vbn = 2;
  if (!vms_write_index (arch, modules, nbr_modules, &vbn, &mod_idx_vbn,
			is_elfidx))
    return FALSE;
  if (!vms_write_index (arch, symbols, nbr_symbols, &vbn, &sym_idx_vbn,
			is_elfidx))
    return FALSE;

  /* Write libary header.  */
  {
    unsigned char blk[VMS_BLOCK_SIZE];
    struct vms_lhd *lhd = (struct vms_lhd *)blk;
    struct vms_idd *idd = (struct vms_idd *)(blk + sizeof (*lhd));
    unsigned int idd_flags;
    unsigned int saneid;

    memset (blk, 0, sizeof (blk));

    lhd->type = tdata->type;
    lhd->nindex = 2;
    switch (tdata->kind)
      {
      case vms_lib_alpha:
        saneid = LHD_SANEID3;
        break;
      case vms_lib_ia64:
        saneid = LHD_SANEID6;
        break;
      default:
        abort ();
      }
    bfd_putl32 (saneid, lhd->sanity);
    bfd_putl16 (tdata->ver, lhd->majorid);
    bfd_putl16 (0, lhd->minorid);
    snprintf ((char *)lhd->lbrver + 1, sizeof (lhd->lbrver) - 1,
              "GNU ar %u.%u.%u",
              (unsigned)(BFD_VERSION / 100000000UL),
              (unsigned)(BFD_VERSION / 1000000UL) % 100,
              (unsigned)(BFD_VERSION / 10000UL) % 100);
    lhd->lbrver[sizeof (lhd->lbrver) - 1] = 0;
    lhd->lbrver[0] = strlen ((char *)lhd->lbrver + 1);

    bfd_putl32 (tdata->credat_lo, lhd->credat + 0);
    bfd_putl32 (tdata->credat_hi, lhd->credat + 4);
    vms_raw_get_time (lhd->updtim);

    lhd->mhdusz = tdata->mhd_size - MHD__C_USRDAT;

    bfd_putl32 (nbr_modules + nbr_symbols, lhd->idxcnt);
    bfd_putl32 (nbr_modules, lhd->modcnt);
    bfd_putl32 (nbr_modules, lhd->modhdrs);

    /* Number of blocks for index.  */
    bfd_putl32 (nbr_mod_iblk + nbr_sym_iblk, lhd->idxblks);
    bfd_putl32 (vbn - 1, lhd->hipreal);
    bfd_putl32 (vbn - 1, lhd->hiprusd);

    /* VBN of the next free block.  */
    bfd_putl32 ((off / VMS_BLOCK_SIZE) + 1, lhd->nextvbn);
    bfd_putl32 ((off / VMS_BLOCK_SIZE) + 1, lhd->nextrfa + 0);
    bfd_putl16 (0, lhd->nextrfa + 4);

    /* First index (modules name).  */
    idd_flags = IDD__FLAGS_ASCII | IDD__FLAGS_VARLENIDX
      | IDD__FLAGS_NOCASECMP | IDD__FLAGS_NOCASENTR;
    bfd_putl16 (idd_flags, idd->flags);
    bfd_putl16 (max_keylen + 1, idd->keylen);
    bfd_putl16 (mod_idx_vbn, idd->vbn);
    idd++;

    /* Second index (symbols name).  */
    bfd_putl16 (idd_flags, idd->flags);
    bfd_putl16 (max_keylen + 1, idd->keylen);
    bfd_putl16 (sym_idx_vbn, idd->vbn);
    idd++;

    if (!vms_write_block (arch, 1, blk))
      return FALSE;
  }

  return TRUE;

 input_err:
  bfd_set_error (bfd_error_on_input, current, bfd_get_error ());
  return FALSE;
}

/* Add a target for text library.  This costs almost nothing and is useful to
   read VMS library on the host.  */

const bfd_target alpha_vms_lib_txt_vec =
{
  "vms-libtxt",			/* Name.  */
  bfd_target_unknown_flavour,
  BFD_ENDIAN_UNKNOWN,		/* byteorder */
  BFD_ENDIAN_UNKNOWN,		/* header_byteorder */
  0,				/* Object flags.  */
  0,				/* Sect flags.  */
  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,
  bfd_getl64, bfd_getl_signed_64, bfd_putl64,
  bfd_getl32, bfd_getl_signed_32, bfd_putl32,
  bfd_getl16, bfd_getl_signed_16, bfd_putl16,

  {_bfd_dummy_target, _bfd_dummy_target,	/* bfd_check_format.  */
   _bfd_vms_lib_txt_archive_p, _bfd_dummy_target},
  {bfd_false, bfd_false, bfd_false, bfd_false},	/* bfd_set_format.  */
  {bfd_false, bfd_false, bfd_false, bfd_false},	/* bfd_write_contents.  */

  BFD_JUMP_TABLE_GENERIC (_bfd_generic),
  BFD_JUMP_TABLE_COPY (_bfd_generic),
  BFD_JUMP_TABLE_CORE (_bfd_nocore),
  BFD_JUMP_TABLE_ARCHIVE (_bfd_vms_lib),
  BFD_JUMP_TABLE_SYMBOLS (_bfd_nosymbols),
  BFD_JUMP_TABLE_RELOCS (_bfd_norelocs),
  BFD_JUMP_TABLE_WRITE (_bfd_nowrite),
  BFD_JUMP_TABLE_LINK (_bfd_nolink),
  BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),

  NULL,

  NULL
};
