/* BFD back-end for VMS archive files.

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

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

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

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

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

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

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

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

/* DCX Submaps.  */

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

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

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

/* Back-end private data.  */

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

  /* Major version.  */
  unsigned char ver;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

      rfa = &lns.nxtrfa;
    }
}

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

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

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

  return TRUE;
}

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

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

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

  return TRUE;
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	  if (flags & ELFIDX__LISTRFA)
	    {
	      struct vms_lhs lhs;

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

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

  return TRUE;
}

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

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

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

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

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

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

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

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

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

/* Standard function.  */

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

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

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

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

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

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

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

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

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

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

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

  return abfd->xvec;

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

/* Standard function for alpha libraries.  */

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

/* Standard function for ia64 libraries.  */

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

/* Standard function for text libraries.  */

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

/* Standard bfd function.  */

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

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

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

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

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

  return TRUE;
}

bfd_boolean
_bfd_vms_lib_alpha_mkarchive (bfd *abfd)
{
  return _bfd_vms_lib_mkarchive (abfd, vms_lib_alpha);
}

bfd_boolean
_bfd_vms_lib_ia64_mkarchive (bfd *abfd)
{
  return _bfd_vms_lib_mkarchive (abfd, vms_lib_ia64);
}

/* Find NAME in the symbol index.  Return the index.  */

symindex
_bfd_vms_lib_find_symbol (bfd *abfd, const char *name)
{
  struct lib_tdata *tdata = bfd_libdata (abfd);
  carsym *syms = tdata->artdata.symdefs;
  int lo, hi;

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

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

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

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

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

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

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

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

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

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

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

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

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

/* Return the current position.  */

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

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

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

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

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

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

static file_ptr
vms_lib_bread_raw (struct bfd *abfd, unsigned char *buf, file_ptr nbytes)
{
  struct vms_lib_iovec *vec = (struct vms_lib_iovec *) abfd->iostream;
  file_ptr res;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

/* Standard IOVEC function.  */

static file_ptr
vms_lib_bread (struct bfd *abfd, void *vbuf, file_ptr nbytes)
{
  struct vms_lib_iovec *vec = (struct vms_lib_iovec *) abfd->iostream;
  file_ptr res;
  file_ptr chunk;
  unsigned char *buf = (unsigned char *)vbuf;

  /* Do not read past the end.  */
  if (vec->where >= vec->file_len)
    return 0;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

static void *
vms_lib_bmmap (struct bfd *abfd ATTRIBUTE_UNUSED,
	       void *addr ATTRIBUTE_UNUSED,
	       bfd_size_type len ATTRIBUTE_UNUSED,
	       int prot ATTRIBUTE_UNUSED,
	       int flags ATTRIBUTE_UNUSED,
	       file_ptr offset ATTRIBUTE_UNUSED,
	       void **map_addr ATTRIBUTE_UNUSED,
	       bfd_size_type *map_len ATTRIBUTE_UNUSED)
{
  return (void *) -1;
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  /* 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;

      mhd = (struct vms_mhd *) buf;
      if (mhd->id != MHD__C_MHDID)
	return NULL;

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

      /* Get info from mhd.  */
      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;
  namelen = strlen (name);
  newname = bfd_malloc (namelen + 4 + 1);
  if (newname == NULL)
    {
      bfd_close (res);
      return NULL;
    }
  strcpy (newname, name);
  switch (tdata->type)
    {
    case LBR__C_TYP_IOBJ:
    case LBR__C_TYP_EOBJ:
      /* For object archives, append .obj to mimic standard behaviour.  */
      strcpy (newname + namelen, ".obj");
      break;
    default:
      break;
    }
  bfd_set_filename (res, newname);

  tdata->cache[modidx] = res;

  return res;
}

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

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

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

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

  return _bfd_vms_lib_get_module (abfd, modidx);
}

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

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

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

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

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

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

/* Standard function.  */

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

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

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

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

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

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

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

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

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

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

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

  return 0;
}

/* Internal representation of an index entry.  */

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

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

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

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

/* Used to sort index entries.  */

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

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

/* Maximum number of index blocks level.  */

#define MAX_LEVEL 10

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

static unsigned int
get_idxlen (struct lib_index *idx, bfd_boolean is_elfidx)
{
  if (is_elfidx)
    {
      /* 9 is the size of struct vms_elfidx without keyname.  */
      if (idx->namlen > MAX_KEYLEN)
	return 9 + sizeof (struct vms_kbn);
      else
	return 9 + idx->namlen;
    }
  else
    {
      /* 7 is the size of struct vms_idx without keyname.  */
      return 7 + idx->namlen;
    }
}

/* Write the index composed by NBR symbols contained in IDX.
   VBN is the first vbn to be used, and will contain on return the last vbn.
   Can be called with ABFD set to NULL just to size the index.
   If not null, TOPVBN will be assigned to the vbn of the root index tree.
   IS_ELFIDX is true for elfidx (ie ia64) indexes layout.
   Return TRUE on success.  */

static bfd_boolean
vms_write_index (bfd *abfd,
		 struct lib_index *idx, unsigned int nbr, unsigned int *vbn,
		 unsigned int *topvbn, bfd_boolean is_elfidx)
{
  /* The index is organized as a tree.  This function implements a naive
     algorithm to balance the tree: it fills the leaves, and create a new
     branch when all upper leaves and branches are full.  We only keep in
     memory a path to the current leaf.  */
  unsigned int i;
  int j;
  int level;
  /* Disk blocks for the current path.  */
  struct vms_indexdef *rblk[MAX_LEVEL];
  /* Info on the current blocks.  */
  struct idxblk
  {
    unsigned int vbn;		/* VBN of the block.  */
    /* The last entry is identified so that it could be copied to the
       parent block.  */
    unsigned short len;		/* Length up to the last entry.  */
    unsigned short lastlen;	/* Length of the last entry.  */
  } blk[MAX_LEVEL];

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

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

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

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

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

      idxlen = get_idxlen (idx, is_elfidx);

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

	  /* Write the key in the kbn, chunk after chunk.  */
	  do
	    {
	      if (kbn_sz < sizeof (struct vms_kbn))
		{
		  /* Not enough room in the kbn block.  */
		  if (abfd != NULL)
		    {
		      /* Write it to the disk (if there is one).  */
		      if (kbn_vbn != 0)
			{
			  if (!vms_write_block (abfd, kbn_vbn, kbn_blk))
			    return FALSE;
			}
		      else
			{
			  kbn_blk = bfd_malloc (VMS_BLOCK_SIZE);
			  if (kbn_blk == NULL)
			    return FALSE;
			}
		      *(unsigned short *)kbn_blk = 0;
		    }
		  /* Allocate a new block for the keys.  */
		  kbn_vbn = (*vbn)++;
		  kbn_sz = VMS_BLOCK_SIZE - 2;
		}
	      /* Size of the chunk written to the current key block.  */
	      if (kl + sizeof (struct vms_kbn) > kbn_sz)
		kl_chunk = kbn_sz - sizeof (struct vms_kbn);
	      else
		kl_chunk = kl;

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

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

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

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

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

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

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

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

		  level++;
		}

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

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

		  /* Copy the whole entry.  */
		  BFD_ASSERT (blk[j + 1].lastlen == blk[j].lastlen);
		  memcpy (rfa, rblk[j]->keys + blk[j].len, blk[j].lastlen);
		  /* Fix the entry (which in always the first field of an
		     entry.  */
		  bfd_putl32 (blk[j].vbn, rfa->vbn);
		  bfd_putl16 (RFADEF__C_INDEX, rfa->offset);
		}

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

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

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

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

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

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

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

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

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

  if (abfd == NULL)
    return TRUE;

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

      en = rblk[j - 1]->keys + blk[j - 1].len;
      par = rblk[j]->keys + blk[j].len;
      BFD_ASSERT (blk[j].lastlen == blk[j - 1].lastlen);
      memcpy (par, en, blk[j - 1].lastlen);
      rfa = (struct vms_rfa *)par;
      bfd_putl32 (blk[j - 1].vbn, rfa->vbn);
      bfd_putl16 (RFADEF__C_INDEX, rfa->offset);
    }

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

      free (rblk[j]);
    }

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

  return TRUE;
}

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

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

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

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

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

	  *off += DATA__LENGTH - doff;

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

/* Build the symbols index.  */

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

      nbr_modules++;
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	  /* Write the first block (which contains an mhd).  */
	  if (bfd_bwrite (blk, VMS_BLOCK_SIZE, arch) != VMS_BLOCK_SIZE)
	    goto input_err;
	  off += VMS_BLOCK_SIZE;

	  if (amt == VMS_BLOCK_SIZE - sz)
	    {
	      /* Copy the remaining.  */
	      char buffer[DEFAULT_BUFFERSIZE];

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  return TRUE;

 input_err:
  bfd_set_input_error (current, bfd_get_error ());
  return FALSE;
}

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

const bfd_target alpha_vms_lib_txt_vec =
{
  "vms-libtxt",			/* Name.  */
  bfd_target_unknown_flavour,
  BFD_ENDIAN_UNKNOWN,		/* byteorder */
  BFD_ENDIAN_UNKNOWN,		/* header_byteorder */
  0,				/* Object flags.  */
  0,				/* Sect flags.  */
  0,				/* symbol_leading_char.  */
  ' ',				/* ar_pad_char.  */
  15,				/* ar_max_namelen.  */
  0,				/* match priority.  */
  bfd_getl64, bfd_getl_signed_64, bfd_putl64,
  bfd_getl32, bfd_getl_signed_32, bfd_putl32,
  bfd_getl16, bfd_getl_signed_16, bfd_putl16,
  bfd_getl64, bfd_getl_signed_64, bfd_putl64,
  bfd_getl32, bfd_getl_signed_32, bfd_putl32,
  bfd_getl16, bfd_getl_signed_16, bfd_putl16,
  {				/* bfd_check_format.  */
    _bfd_dummy_target,
    _bfd_dummy_target,
    _bfd_vms_lib_txt_archive_p,
    _bfd_dummy_target
  },
  {				/* bfd_set_format.  */
    _bfd_bool_bfd_false_error,
    _bfd_bool_bfd_false_error,
    _bfd_bool_bfd_false_error,
    _bfd_bool_bfd_false_error
  },
  {				/* bfd_write_contents.  */
    _bfd_bool_bfd_false_error,
    _bfd_bool_bfd_false_error,
    _bfd_bool_bfd_false_error,
    _bfd_bool_bfd_false_error
  },
  BFD_JUMP_TABLE_GENERIC (_bfd_generic),
  BFD_JUMP_TABLE_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
};
