/* BFD back-end for VMS archive files.

   Copyright 2010, 2011 Free Software Foundation, Inc.
   Written by Tristan Gingold <gingold@adacore.com>, AdaCore.

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

   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 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_zalloc (res, 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
};
