/* BFD back-end for VMS archive files.

   Copyright 2010, 2011, 2012 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 "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 bfd_boolean
vms_lib_bclose (struct bfd *abfd)
{
  abfd->iostream = NULL;
  return TRUE;
}

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 = 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)
    {
      (*_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) != TRUE)
                            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]) != TRUE)
                    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]) != TRUE)
        return FALSE;

      free (rblk[j]);
    }

  /* Write the last kbn (if any).  */
  if (kbn_vbn != 0)
    {
      if (vms_write_block (abfd, kbn_vbn, kbn_blk) != TRUE)
        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) != TRUE)
    return FALSE;
  if (vms_write_index (arch, symbols, nbr_symbols, &vbn, &sym_idx_vbn,
                       is_elfidx) != TRUE)
    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) != TRUE)
      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 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
};
