/* CTF archive files.
   Copyright (C) 2019-2025 Free Software Foundation, Inc.

   This file is part of libctf.

   libctf 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, 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; see the file COPYING.  If not see
   <http://www.gnu.org/licenses/>.  */

#include <ctf-impl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <elf.h>
#include "ctf-endian.h"
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>

#ifdef HAVE_MMAP
#include <sys/mman.h>
#endif

static off_t arc_write_one_ctf (ctf_dict_t * f, int fd, size_t threshold);
static ctf_dict_t *ctf_dict_open_by_offset (const struct ctf_archive *arc,
					    const ctf_sect_t *symsect,
					    const ctf_sect_t *strsect,
					    size_t offset, int little_endian,
					    int *errp);
static int sort_modent_by_name (const void *one, const void *two, void *n);
static void *arc_mmap_header (int fd, size_t headersz);
static void *arc_mmap_file (int fd, size_t size);
static int arc_mmap_writeout (int fd, void *header, size_t headersz,
			      const char **errmsg);
static int arc_mmap_unmap (void *header, size_t headersz, const char **errmsg);
static int ctf_arc_import_parent (const ctf_archive_t *arc, ctf_dict_t *fp,
				  int *errp);

/* Flag to indicate "symbol not present" in ctf_archive_internal.ctfi_symdicts
   and ctfi_symnamedicts.  Never initialized.  */
static ctf_dict_t enosym;

/* Write out a CTF archive to the start of the file referenced by the passed-in
   fd.  The entries in CTF_DICTS are referenced by name: the names are passed in
   the names array, which must have CTF_DICTS entries.

   Returns 0 on success, or an errno, or an ECTF_* value.  */
int
ctf_arc_write_fd (int fd, ctf_dict_t **ctf_dicts, size_t ctf_dict_cnt,
		  const char **names, size_t threshold)
{
  const char *errmsg;
  struct ctf_archive *archdr;
  size_t i;
  char dummy = 0;
  size_t headersz;
  ssize_t namesz;
  size_t ctf_startoffs;		/* Start of the section we are working over.  */
  char *nametbl = NULL;		/* The name table.  */
  char *np;
  off_t nameoffs;
  struct ctf_archive_modent *modent;

  ctf_dprintf ("Writing CTF archive with %lu files\n",
	       (unsigned long) ctf_dict_cnt);

  /* Figure out the size of the mmap()ed header, including the
     ctf_archive_modent array.  We assume that all of this needs no
     padding: a likely assumption, given that it's all made up of
     uint64_t's.  */
  headersz = sizeof (struct ctf_archive)
    + (ctf_dict_cnt * sizeof (uint64_t) * 2);
  ctf_dprintf ("headersz is %lu\n", (unsigned long) headersz);

  /* From now on we work in two pieces: an mmap()ed region from zero up to the
     headersz, and a region updated via write() starting after that, containing
     all the tables.  Platforms that do not support mmap() just use write().  */
  ctf_startoffs = headersz;
  if (lseek (fd, ctf_startoffs - 1, SEEK_SET) < 0)
    {
      errmsg = N_("ctf_arc_write(): cannot extend file while writing");
      goto err;
    }

  if (write (fd, &dummy, 1) < 0)
    {
      errmsg = N_("ctf_arc_write(): cannot extend file while writing");
      goto err;
    }

  if ((archdr = arc_mmap_header (fd, headersz)) == NULL)
    {
      errmsg = N_("ctf_arc_write(): cannot mmap");
      goto err;
    }

  /* Fill in everything we can, which is everything other than the name
     table offset.  */
  archdr->ctfa_magic = htole64 (CTFA_MAGIC);
  archdr->ctfa_ndicts = htole64 (ctf_dict_cnt);
  archdr->ctfa_ctfs = htole64 (ctf_startoffs);

  /* We could validate that all CTF files have the same data model, but
     since any reasonable construction process will be building things of
     only one bitness anyway, this is pretty pointless, so just use the
     model of the first CTF file for all of them.  (It *is* valid to
     create an empty archive: the value of ctfa_model is irrelevant in
     this case, but we must be sure not to dereference uninitialized
     memory.)  */

  if (ctf_dict_cnt > 0)
    archdr->ctfa_model = htole64 (ctf_getmodel (ctf_dicts[0]));

  /* Now write out the CTFs: ctf_archive_modent array via the mapping,
     ctfs via write().  The names themselves have not been written yet: we
     track them in a local strtab until the time is right, and sort the
     modents array after construction.

    The name table is not sorted.  */

  for (i = 0, namesz = 0; i < le64toh (archdr->ctfa_ndicts); i++)
    namesz += strlen (names[i]) + 1;

  nametbl = malloc (namesz);
  if (nametbl == NULL)
    {
      errmsg = N_("ctf_arc_write(): error writing named CTF to archive");
      goto err_unmap;
    }

  for (i = 0, namesz = 0,
       modent = (ctf_archive_modent_t *) ((char *) archdr
					  + sizeof (struct ctf_archive));
       i < le64toh (archdr->ctfa_ndicts); i++)
    {
      off_t off;

      strcpy (&nametbl[namesz], names[i]);

      off = arc_write_one_ctf (ctf_dicts[i], fd, threshold);
      if ((off < 0) && (off > -ECTF_BASE))
	{
	  errmsg = N_("ctf_arc_write(): cannot determine file "
		      "position while writing to archive");
	  goto err_free;
	}
      if (off < 0)
	{
	  errmsg = N_("ctf_arc_write(): cannot write CTF file to archive");
	  errno = off * -1;
	  goto err_free;
	}

      modent->name_offset = htole64 (namesz);
      modent->ctf_offset = htole64 (off - ctf_startoffs);
      namesz += strlen (names[i]) + 1;
      modent++;
    }

  ctf_qsort_r ((ctf_archive_modent_t *) ((char *) archdr
					 + sizeof (struct ctf_archive)),
	       le64toh (archdr->ctfa_ndicts),
	       sizeof (struct ctf_archive_modent), sort_modent_by_name,
	       nametbl);

   /* Now the name table.  */

  if ((nameoffs = lseek (fd, 0, SEEK_CUR)) < 0)
    {
      errmsg = N_("ctf_arc_write(): cannot get current file position "
		  "in archive");
      goto err_free;
    }
  archdr->ctfa_names = htole64 (nameoffs);
  np = nametbl;
  while (namesz > 0)
    {
      ssize_t len;
      if ((len = write (fd, np, namesz)) < 0)
	{
	  errmsg = N_("ctf_arc_write(): cannot write name table to archive");
	  goto err_free;
	}
      namesz -= len;
      np += len;
    }
  free (nametbl);

  if (arc_mmap_writeout (fd, archdr, headersz, &errmsg) < 0)
    goto err_unmap;
  if (arc_mmap_unmap (archdr, headersz, &errmsg) < 0)
    goto err;
  return 0;

err_free:
  free (nametbl);
err_unmap:
  arc_mmap_unmap (archdr, headersz, NULL);
err:
  /* We report errors into the first file in the archive, if any: if this is a
     zero-file archive, put it in the open-errors stream for lack of anywhere
     else for it to go.  */
  ctf_err_warn (ctf_dict_cnt > 0 ? ctf_dicts[0] : NULL, 0, errno, "%s",
		gettext (errmsg));
  return errno;
}

/* Write out a CTF archive.  The entries in CTF_DICTS are referenced by name:
   the names are passed in the names array, which must have CTF_DICTS entries.

   If the filename is NULL, create a temporary file and return a pointer to it.

   Returns 0 on success, or an errno, or an ECTF_* value.  */
int
ctf_arc_write (const char *file, ctf_dict_t **ctf_dicts, size_t ctf_dict_cnt,
	       const char **names, size_t threshold)
{
  int err;
  int fd;

  if ((fd = open (file, O_RDWR | O_CREAT | O_TRUNC | O_CLOEXEC, 0666)) < 0)
    {
      ctf_err_warn (ctf_dict_cnt > 0 ? ctf_dicts[0] : NULL, 0, errno,
		    _("ctf_arc_write(): cannot create %s"), file);
      return errno;
    }

  err = ctf_arc_write_fd (fd, ctf_dicts, ctf_dict_cnt, names, threshold);
  if (err)
    goto err_close;

  if ((err = close (fd)) < 0)
    ctf_err_warn (ctf_dict_cnt > 0 ? ctf_dicts[0] : NULL, 0, errno,
		  _("ctf_arc_write(): cannot close after writing to archive"));
  goto err;

 err_close:
  (void) close (fd);
 err:
  if (err < 0)
    unlink (file);

  return err;
}

/* Write one CTF dict out.  Return the file position of the written file (or
   rather, of the file-size uint64_t that precedes it): negative return is a
   negative errno or ctf_errno value.  On error, the file position may no longer
   be at the end of the file.  */
static off_t
arc_write_one_ctf (ctf_dict_t *f, int fd, size_t threshold)
{
  off_t off, end_off;
  uint64_t ctfsz = 0;
  char *ctfszp;
  size_t ctfsz_len;

  if ((off = lseek (fd, 0, SEEK_CUR)) < 0)
    return errno * -1;

  /* This zero-write turns into the size in a moment. */
  ctfsz_len = sizeof (ctfsz);
  ctfszp = (char *) &ctfsz;
  while (ctfsz_len > 0)
    {
      ssize_t writelen = write (fd, ctfszp, ctfsz_len);
      if (writelen < 0)
	return errno * -1;
      ctfsz_len -= writelen;
      ctfszp += writelen;
    }

  if (ctf_write_thresholded (f, fd, threshold) != 0)
    return f->ctf_errno * -1;

  if ((end_off = lseek (fd, 0, SEEK_CUR)) < 0)
    return errno * -1;
  ctfsz = htole64 (end_off - off);

  if ((lseek (fd, off, SEEK_SET)) < 0)
    return errno * -1;

  /* ... here.  */
  ctfsz_len = sizeof (ctfsz);
  ctfszp = (char *) &ctfsz;
  while (ctfsz_len > 0)
    {
      ssize_t writelen = write (fd, ctfszp, ctfsz_len);
      if (writelen < 0)
	return errno * -1;
      ctfsz_len -= writelen;
      ctfszp += writelen;
    }

  end_off = LCTF_ALIGN_OFFS (end_off, 8);
  if ((lseek (fd, end_off, SEEK_SET)) < 0)
    return errno * -1;

  return off;
}

/* qsort() function to sort the array of struct ctf_archive_modents into
   ascending name order.  */
static int
sort_modent_by_name (const void *one, const void *two, void *n)
{
  const struct ctf_archive_modent *a = one;
  const struct ctf_archive_modent *b = two;
  char *nametbl = n;

  return strcmp (&nametbl[le64toh (a->name_offset)],
		 &nametbl[le64toh (b->name_offset)]);
}

/* bsearch_r() function to search for a given name in the sorted array of struct
   ctf_archive_modents.  */
static int
search_modent_by_name (const void *key, const void *ent, void *arg)
{
  const char *k = key;
  const struct ctf_archive_modent *v = ent;
  const char *search_nametbl = arg;

  return strcmp (k, &search_nametbl[le64toh (v->name_offset)]);
}

/* Make a new struct ctf_archive_internal wrapper for a ctf_archive or a
   ctf_dict.  Closes ARC and/or FP on error.  Arrange to free the SYMSECT or
   STRSECT, as needed, on close.  Possibly do not unmap on close.  */

struct ctf_archive_internal *
ctf_new_archive_internal (int is_archive, int unmap_on_close,
			  struct ctf_archive *arc,
			  ctf_dict_t *fp, const ctf_sect_t *symsect,
			  const ctf_sect_t *strsect,
			  int *errp)
{
  struct ctf_archive_internal *arci;

  if ((arci = calloc (1, sizeof (struct ctf_archive_internal))) == NULL)
    {
      if (is_archive)
	{
	  if (unmap_on_close)
	    ctf_arc_close_internal (arc);
	}
      else
	ctf_dict_close (fp);
      return (ctf_set_open_errno (errp, errno));
    }
  arci->ctfi_is_archive = is_archive;
  if (is_archive)
    arci->ctfi_archive = arc;
  else
    arci->ctfi_dict = fp;
  if (symsect)
     memcpy (&arci->ctfi_symsect, symsect, sizeof (struct ctf_sect));
  if (strsect)
     memcpy (&arci->ctfi_strsect, strsect, sizeof (struct ctf_sect));
  arci->ctfi_free_symsect = 0;
  arci->ctfi_free_strsect = 0;
  arci->ctfi_unmap_on_close = unmap_on_close;
  arci->ctfi_symsect_little_endian = -1;

  return arci;
}

/* Set the symbol-table endianness of an archive (defaulting the symtab
   endianness of all ctf_file_t's opened from that archive).  */
void
ctf_arc_symsect_endianness (ctf_archive_t *arc, int little_endian)
{
  arc->ctfi_symsect_little_endian = !!little_endian;
  if (!arc->ctfi_is_archive)
    ctf_symsect_endianness (arc->ctfi_dict, arc->ctfi_symsect_little_endian);
}

/* Get the CTF preamble from data in a buffer, which may be either an archive or
   a CTF dict.  If multiple dicts are present in an archive, the preamble comes
   from an arbitrary dict.  The preamble is a pointer into the ctfsect passed
   in.  */

const ctf_preamble_t *
ctf_arc_bufpreamble (const ctf_sect_t *ctfsect)
{
  if (ctfsect->cts_data != NULL
      && ctfsect->cts_size >= sizeof (struct ctf_archive)
      && (le64toh ((*(uint64_t *) ctfsect->cts_data)) == CTFA_MAGIC))
    {
      struct ctf_archive *arc = (struct ctf_archive *) ctfsect->cts_data;
      return (const ctf_preamble_t *) ((char *) arc + le64toh (arc->ctfa_ctfs)
				       + sizeof (uint64_t));
    }
  else
    return (const ctf_preamble_t *) ctfsect->cts_data;
}

/* Open a CTF archive or dictionary from data in a buffer (which the caller must
   preserve until ctf_arc_close() time).  Returns the archive, or NULL and an
   error in *err (if not NULL).  */
ctf_archive_t *
ctf_arc_bufopen (const ctf_sect_t *ctfsect, const ctf_sect_t *symsect,
		 const ctf_sect_t *strsect, int *errp)
{
  struct ctf_archive *arc = NULL;
  int is_archive;
  ctf_dict_t *fp = NULL;

  if (ctfsect->cts_data != NULL
      && ctfsect->cts_size >= sizeof (struct ctf_archive)
      && (le64toh ((*(uint64_t *) ctfsect->cts_data)) == CTFA_MAGIC))
    {
      /* The archive is mmappable, so this operation is trivial.

	 This buffer is nonmodifiable, so the trick involving mmapping only part
	 of it and storing the length in the magic number is not applicable: so
	 record this fact in the archive-wrapper header.  (We cannot record it
	 in the archive, because the archive may very well be a read-only
	 mapping.)  */

      is_archive = 1;
      arc = (struct ctf_archive *) ctfsect->cts_data;
    }
  else
    {
      is_archive = 0;
      if ((fp = ctf_bufopen (ctfsect, symsect, strsect, errp)) == NULL)
	{
	  ctf_err_warn (NULL, 0, *errp, _("ctf_arc_bufopen(): cannot open CTF"));
	  return NULL;
	}
    }
  return ctf_new_archive_internal (is_archive, 0, arc, fp, symsect, strsect,
				   errp);
}

/* Open a CTF archive.  Returns the archive, or NULL and an error in *err (if
   not NULL).  */
struct ctf_archive *
ctf_arc_open_internal (const char *filename, int *errp)
{
  const char *errmsg;
  int fd;
  struct stat s;
  struct ctf_archive *arc;		/* (Actually the whole file.)  */

  libctf_init_debug();
  if ((fd = open (filename, O_RDONLY)) < 0)
    {
      errmsg = N_("ctf_arc_open(): cannot open %s");
      goto err;
    }
  if (fstat (fd, &s) < 0)
    {
      errmsg = N_("ctf_arc_open(): cannot stat %s");
      goto err_close;
    }

  if ((arc = arc_mmap_file (fd, s.st_size)) == NULL)
    {
      errmsg = N_("ctf_arc_open(): cannot read in %s");
      goto err_close;
    }

  if (le64toh (arc->ctfa_magic) != CTFA_MAGIC)
    {
      errmsg = N_("ctf_arc_open(): %s: invalid magic number");
      errno = ECTF_FMT;
      goto err_unmap;
    }

  /* This horrible hack lets us know how much to unmap when the file is
     closed.  (We no longer need the magic number, and the mapping
     is private.)  */
  arc->ctfa_magic = s.st_size;
  close (fd);

  if (errp)
    *errp = 0;

  return arc;

err_unmap:
  arc_mmap_unmap (arc, s.st_size, NULL);
err_close:
  close (fd);
err:
  if (errp)
    *errp = errno;
  ctf_err_warn (NULL, 0, errno, gettext (errmsg), filename);
  return NULL;
}

/* Close an archive.  */
void
ctf_arc_close_internal (struct ctf_archive *arc)
{
  if (arc == NULL)
    return;

  /* See the comment in ctf_arc_open().  */
  arc_mmap_unmap (arc, arc->ctfa_magic, NULL);
}

/* Public entry point: close an archive, or CTF file.  */
void
ctf_arc_close (ctf_archive_t *arc)
{
  if (arc == NULL)
    return;

  if (arc->ctfi_is_archive)
    {
      if (arc->ctfi_unmap_on_close)
	ctf_arc_close_internal (arc->ctfi_archive);
    }
  else
    ctf_dict_close (arc->ctfi_dict);
  free (arc->ctfi_symdicts);
  free (arc->ctfi_symnamedicts);
  ctf_dynhash_destroy (arc->ctfi_dicts);
  if (arc->ctfi_free_symsect)
    free ((void *) arc->ctfi_symsect.cts_data);
  if (arc->ctfi_free_strsect)
    free ((void *) arc->ctfi_strsect.cts_data);
  free (arc->ctfi_data);
  if (arc->ctfi_bfd_close)
    arc->ctfi_bfd_close (arc);
  free (arc);
}

/* Return the ctf_dict_t with the given name, or NULL if none, setting 'err' if
   non-NULL.  A name of NULL means to open the default file.  */
static ctf_dict_t *
ctf_dict_open_internal (const struct ctf_archive *arc,
			const ctf_sect_t *symsect,
			const ctf_sect_t *strsect,
			const char *name, int little_endian,
			int *errp)
{
  struct ctf_archive_modent *modent;
  const char *search_nametbl;

  if (name == NULL)
    name = _CTF_SECTION;		 /* The default name.  */

  ctf_dprintf ("ctf_dict_open_internal(%s): opening\n", name);

  modent = (ctf_archive_modent_t *) ((char *) arc
				     + sizeof (struct ctf_archive));

  search_nametbl = (const char *) arc + le64toh (arc->ctfa_names);
  modent = bsearch_r (name, modent, le64toh (arc->ctfa_ndicts),
		      sizeof (struct ctf_archive_modent),
		      search_modent_by_name, (void *) search_nametbl);

  /* This is actually a common case and normal operation: no error
     debug output.  */
  if (modent == NULL)
    {
      if (errp)
	*errp = ECTF_ARNNAME;
      return NULL;
    }

  return ctf_dict_open_by_offset (arc, symsect, strsect,
				  le64toh (modent->ctf_offset),
				  little_endian, errp);
}

/* Return the ctf_dict_t with the given name, or NULL if none, setting 'err' if
   non-NULL.  A name of NULL means to open the default file.

   Use the specified string and symbol table sections.

   Public entry point.  */
ctf_dict_t *
ctf_dict_open_sections (const ctf_archive_t *arc,
			const ctf_sect_t *symsect,
			const ctf_sect_t *strsect,
			const char *name,
			int *errp)
{
  if (errp)
    *errp = 0;

  if (arc->ctfi_is_archive)
    {
      ctf_dict_t *ret;
      ret = ctf_dict_open_internal (arc->ctfi_archive, symsect, strsect,
				    name, arc->ctfi_symsect_little_endian,
				    errp);
      if (ret)
	{
	  ret->ctf_archive = (ctf_archive_t *) arc;
	  if (ctf_arc_import_parent (arc, ret, errp) < 0)
	    {
	      ctf_dict_close (ret);
	      return NULL;
	    }
	}
      return ret;
    }

  if ((name != NULL) && (strcmp (name, _CTF_SECTION) != 0))
    {
      if (errp)
	*errp = ECTF_ARNNAME;
      return NULL;
    }
  arc->ctfi_dict->ctf_archive = (ctf_archive_t *) arc;

  /* Bump the refcount so that the user can ctf_dict_close() it.  */
  arc->ctfi_dict->ctf_refcnt++;
  return arc->ctfi_dict;
}

/* Return the ctf_dict_t with the given name, or NULL if none, setting 'err' if
   non-NULL.  A name of NULL means to open the default file.

   Public entry point.  */
ctf_dict_t *
ctf_dict_open (const ctf_archive_t *arc, const char *name, int *errp)
{
  const ctf_sect_t *symsect = &arc->ctfi_symsect;
  const ctf_sect_t *strsect = &arc->ctfi_strsect;

  if (symsect->cts_name == NULL)
    symsect = NULL;
  if (strsect->cts_name == NULL)
    strsect = NULL;

  return ctf_dict_open_sections (arc, symsect, strsect, name, errp);
}

static void
ctf_cached_dict_close (void *fp)
{
  ctf_dict_close ((ctf_dict_t *) fp);
}

/* Return the ctf_dict_t with the given name and cache it in the archive's
   ctfi_dicts.  If this is the first cached dict, designate it the
   crossdict_cache.  */
static ctf_dict_t *
ctf_dict_open_cached (ctf_archive_t *arc, const char *name, int *errp)
{
  ctf_dict_t *fp;
  char *dupname;

  /* Just return from the cache if possible.  */
  if (arc->ctfi_dicts
      && ((fp = ctf_dynhash_lookup (arc->ctfi_dicts, name)) != NULL))
    {
      fp->ctf_refcnt++;
      return fp;
    }

  /* Not yet cached: open it.  */
  fp = ctf_dict_open (arc, name, errp);
  dupname = strdup (name);

  if (!fp || !dupname)
    goto oom;

  if (arc->ctfi_dicts == NULL)
    if ((arc->ctfi_dicts
	 = ctf_dynhash_create (ctf_hash_string, ctf_hash_eq_string,
			       free, ctf_cached_dict_close)) == NULL)
      goto oom;

  if (ctf_dynhash_insert (arc->ctfi_dicts, dupname, fp) < 0)
    goto oom;
  fp->ctf_refcnt++;

  if (arc->ctfi_crossdict_cache == NULL)
    arc->ctfi_crossdict_cache = fp;

  return fp;

 oom:
  ctf_dict_close (fp);
  free (dupname);
  if (errp)
    *errp = ENOMEM;
  return NULL;
}

/* Flush any caches the CTF archive may have open.  */
void
ctf_arc_flush_caches (ctf_archive_t *wrapper)
{
  free (wrapper->ctfi_symdicts);
  ctf_dynhash_destroy (wrapper->ctfi_symnamedicts);
  ctf_dynhash_destroy (wrapper->ctfi_dicts);
  wrapper->ctfi_symdicts = NULL;
  wrapper->ctfi_symnamedicts = NULL;
  wrapper->ctfi_dicts = NULL;
  wrapper->ctfi_crossdict_cache = NULL;
}

/* Return the ctf_dict_t at the given ctfa_ctfs-relative offset, or NULL if
   none, setting 'err' if non-NULL.  */
static ctf_dict_t *
ctf_dict_open_by_offset (const struct ctf_archive *arc,
			 const ctf_sect_t *symsect,
			 const ctf_sect_t *strsect, size_t offset,
			 int little_endian, int *errp)
{
  ctf_sect_t ctfsect;
  ctf_dict_t *fp;

  ctf_dprintf ("ctf_dict_open_by_offset(%lu): opening\n", (unsigned long) offset);

  memset (&ctfsect, 0, sizeof (ctf_sect_t));

  offset += le64toh (arc->ctfa_ctfs);

  ctfsect.cts_name = _CTF_SECTION;
  ctfsect.cts_size = le64toh (*((uint64_t *) ((char *) arc + offset)));
  ctfsect.cts_entsize = 1;
  ctfsect.cts_data = (void *) ((char *) arc + offset + sizeof (uint64_t));
  fp = ctf_bufopen (&ctfsect, symsect, strsect, errp);
  if (fp)
    {
      ctf_setmodel (fp, le64toh (arc->ctfa_model));
      if (little_endian >= 0)
	ctf_symsect_endianness (fp, little_endian);
    }
  return fp;
}

/* Backward compatibility.  */
ctf_dict_t *
ctf_arc_open_by_name (const ctf_archive_t *arc, const char *name,
		      int *errp)
{
  return ctf_dict_open (arc, name, errp);
}

ctf_dict_t *
ctf_arc_open_by_name_sections (const ctf_archive_t *arc,
			       const ctf_sect_t *symsect,
			       const ctf_sect_t *strsect,
			       const char *name,
			       int *errp)
{
  return ctf_dict_open_sections (arc, symsect, strsect, name, errp);
}

/* Import the parent into a ctf archive, if this is a child, the parent is not
   already set, and a suitable archive member exists.  No error is raised if
   this is not possible: this is just a best-effort helper operation to give
   people useful dicts to start with.  */
static int
ctf_arc_import_parent (const ctf_archive_t *arc, ctf_dict_t *fp, int *errp)
{
  if ((fp->ctf_flags & LCTF_CHILD) && fp->ctf_parname && !fp->ctf_parent)
    {
      int err = 0;
      ctf_dict_t *parent = ctf_dict_open_cached ((ctf_archive_t *) arc,
						 fp->ctf_parname, &err);
      if (errp)
	*errp = err;

      if (parent)
	{
	  ctf_import (fp, parent);
	  ctf_dict_close (parent);
	}
      else if (err != ECTF_ARNNAME)
	return -1;				/* errno is set for us.  */
    }
  return 0;
}

/* Return the number of members in an archive.  */
size_t
ctf_archive_count (const ctf_archive_t *wrapper)
{
  if (!wrapper->ctfi_is_archive)
    return 1;

  return le64toh (wrapper->ctfi_archive->ctfa_ndicts);
}

/* Look up a symbol in an archive by name or index (if the name is set, a lookup
   by name is done).  Return the dict in the archive that the symbol is found
   in, and (optionally) the ctf_id_t of the symbol in that dict (so you don't
   have to look it up yourself).  The dict is cached, so repeated lookups are
   nearly free.

   As usual, you should ctf_dict_close() the returned dict once you are done
   with it.

   Returns NULL on error, and an error in errp (if set).  */

static ctf_dict_t *
ctf_arc_lookup_sym_or_name (ctf_archive_t *wrapper, unsigned long symidx,
			    const char *symname, ctf_id_t *typep, int *errp)
{
  ctf_dict_t *fp;
  void *fpkey;
  ctf_id_t type;

  /* The usual non-archive-transparent-wrapper special case.  */
  if (!wrapper->ctfi_is_archive)
    {
      if (!symname)
	{
	  if ((type = ctf_lookup_by_symbol (wrapper->ctfi_dict, symidx)) == CTF_ERR)
	    {
	      if (errp)
		*errp = ctf_errno (wrapper->ctfi_dict);
	      return NULL;
	    }
	}
      else
	{
	  if ((type = ctf_lookup_by_symbol_name (wrapper->ctfi_dict,
						 symname)) == CTF_ERR)
	    {
	      if (errp)
		*errp = ctf_errno (wrapper->ctfi_dict);
	      return NULL;
	    }
	}
      if (typep)
	*typep = type;
      wrapper->ctfi_dict->ctf_refcnt++;
      return wrapper->ctfi_dict;
    }

  if (wrapper->ctfi_symsect.cts_name == NULL
      || wrapper->ctfi_symsect.cts_data == NULL
      || wrapper->ctfi_symsect.cts_size == 0
      || wrapper->ctfi_symsect.cts_entsize == 0)
    {
      if (errp)
	*errp = ECTF_NOSYMTAB;
      return NULL;
    }

  /* Make enough space for all possible symbol indexes, if not already done.  We
     cache the originating dictionary of all symbols.  The dict links are weak,
     to the dictionaries cached in ctfi_dicts: their refcnts are *not* bumped.
     We also cache similar mappings for symbol names: these are ordinary
     dynhashes, with weak links to dicts.  */

  if (!wrapper->ctfi_symdicts)
    {
      if ((wrapper->ctfi_symdicts = calloc (wrapper->ctfi_symsect.cts_size
					    / wrapper->ctfi_symsect.cts_entsize,
					    sizeof (ctf_dict_t *))) == NULL)
	{
	  if (errp)
	    *errp = ENOMEM;
	  return NULL;
	}
    }
  if (!wrapper->ctfi_symnamedicts)
    {
      if ((wrapper->ctfi_symnamedicts = ctf_dynhash_create (ctf_hash_string,
							    ctf_hash_eq_string,
							    free, NULL)) == NULL)
	{
	  if (errp)
	    *errp = ENOMEM;
	  return NULL;
	}
    }

  /* Perhaps the dict in which we found a previous lookup is cached.  If it's
     supposed to be cached but we don't find it, pretend it was always not
     found: this should never happen, but shouldn't be allowed to cause trouble
     if it does.  */

  if ((symname && ctf_dynhash_lookup_kv (wrapper->ctfi_symnamedicts,
					 symname, NULL, &fpkey))
      || (!symname && wrapper->ctfi_symdicts[symidx] != NULL))
    {
      if (symname)
	fp = (ctf_dict_t *) fpkey;
      else
	fp = wrapper->ctfi_symdicts[symidx];

      if (fp == &enosym)
	goto no_sym;

      if (symname)
	{
	  if ((type = ctf_lookup_by_symbol_name (fp, symname)) == CTF_ERR)
	    goto cache_no_sym;
	}
      else
	{
	  if ((type = ctf_lookup_by_symbol (fp, symidx)) == CTF_ERR)
	    goto cache_no_sym;
	}

      if (typep)
	*typep = type;
      fp->ctf_refcnt++;
      return fp;
    }

  /* Not cached: find it and cache it.  We must track open errors ourselves even
     if our caller doesn't, to be able to distinguish no-error end-of-iteration
     from open errors.  */

  int local_err;
  int *local_errp;
  ctf_next_t *i = NULL;
  const char *name;

  if (errp)
    local_errp = errp;
  else
    local_errp = &local_err;

  while ((fp = ctf_archive_next (wrapper, &i, &name, 0, local_errp)) != NULL)
    {
      if (!symname)
	{
	  if ((type = ctf_lookup_by_symbol (fp, symidx)) != CTF_ERR)
	    wrapper->ctfi_symdicts[symidx] = fp;
	}
      else
	{
	  if ((type = ctf_lookup_by_symbol_name (fp, symname)) != CTF_ERR)
	    {
	      char *tmp;
	      /* No error checking, as above.  */
	      if ((tmp = strdup (symname)) != NULL)
		ctf_dynhash_insert (wrapper->ctfi_symnamedicts, tmp, fp);
	    }
	}

      if (type != CTF_ERR)
	{
	  if (typep)
	    *typep = type;
	  ctf_next_destroy (i);
	  return fp;
	}
      if (ctf_errno (fp) != ECTF_NOTYPEDAT)
	{
	  if (errp)
	    *errp = ctf_errno (fp);
	  ctf_dict_close (fp);
	  ctf_next_destroy (i);
	  return NULL;				/* errno is set for us.  */
	}
      ctf_dict_close (fp);
    }
  if (*local_errp != ECTF_NEXT_END)
    {
      ctf_next_destroy (i);
      return NULL;
    }

  /* Don't leak end-of-iteration to the caller.  */
  *local_errp = 0;

 cache_no_sym:
  if (!symname)
    wrapper->ctfi_symdicts[symidx] = &enosym;
  else
    {
      char *tmp;

      /* No error checking: if caching fails, there is only a slight performance
	 impact.  */
      if ((tmp = strdup (symname)) != NULL)
	if (ctf_dynhash_insert (wrapper->ctfi_symnamedicts, tmp, &enosym) < 0)
	  free (tmp);
    }

 no_sym:
  if (errp)
    *errp = ECTF_NOTYPEDAT;
  if (typep)
    *typep = CTF_ERR;
  return NULL;
}

/* The public API for looking up a symbol by index.  */
ctf_dict_t *
ctf_arc_lookup_symbol (ctf_archive_t *wrapper, unsigned long symidx,
		       ctf_id_t *typep, int *errp)
{
  return ctf_arc_lookup_sym_or_name (wrapper, symidx, NULL, typep, errp);
}

/* The public API for looking up a symbol by name. */

ctf_dict_t *
ctf_arc_lookup_symbol_name (ctf_archive_t *wrapper, const char *symname,
			    ctf_id_t *typep, int *errp)
{
  return ctf_arc_lookup_sym_or_name (wrapper, 0, symname, typep, errp);
}

/* Return all enumeration constants with a given NAME across all dicts in an
   archive, similar to ctf_lookup_enumerator_next.  The DICT is cached, so
   opening costs are paid only once, but (unlike ctf_arc_lookup_symbol*
   above) the results of the iterations are not cached.  dict and errp are
   not optional.  */

ctf_id_t
ctf_arc_lookup_enumerator_next (ctf_archive_t *arc, const char *name,
				ctf_next_t **it, int64_t *enum_value,
				ctf_dict_t **dict, int *errp)
{
  ctf_next_t *i = *it;
  ctf_id_t type;
  int opened_this_time = 0;
  int err;

  /* We have two nested iterators in here: ctn_next tracks archives, while
     within it ctn_next_inner tracks enumerators within an archive.  We
     keep track of the dict by simply reusing the passed-in arg: if it's
     changed by the caller, the caller will get an ECTF_WRONGFP error,
     so this is quite safe and means we don't have to track the arc and fp
     simultaneously in the ctf_next_t.  */

  if (!i)
    {
      if ((i = ctf_next_create ()) == NULL)
	{
	  err = ENOMEM;
	  goto err;
	}
      i->ctn_iter_fun = (void (*) (void)) ctf_arc_lookup_enumerator_next;
      i->cu.ctn_arc = arc;
      *it = i;
    }

  if ((void (*) (void)) ctf_arc_lookup_enumerator_next != i->ctn_iter_fun)
    {
      err = ECTF_NEXT_WRONGFUN;
      goto err;
    }

  if (arc != i->cu.ctn_arc)
    {
      err = ECTF_NEXT_WRONGFP;
      goto err;
    }

  /* Prevent any earlier end-of-iteration on this dict from confusing the
     test below.  */
  if (i->ctn_next != NULL)
    ctf_set_errno (*dict, 0);

  do
    {
      /* At end of one dict, or not started any iterations yet?
	 Traverse to next dict.  If we never returned this dict to the
	 caller, close it ourselves: the caller will never see it and cannot
	 do so.  */

      if (i->ctn_next == NULL || ctf_errno (*dict) == ECTF_NEXT_END)
	{
	  if (opened_this_time)
	    {
	      ctf_dict_close (*dict);
	      *dict = NULL;
	      opened_this_time = 0;
	    }

	  *dict = ctf_archive_next (arc, &i->ctn_next, NULL, 0, &err);
	  if (!*dict)
	    goto err;
	  opened_this_time = 1;
	}

      type = ctf_lookup_enumerator_next (*dict, name, &i->ctn_next_inner,
					 enum_value);
    }
  while (type == CTF_ERR && ctf_errno (*dict) == ECTF_NEXT_END);

  if (type == CTF_ERR)
    {
      err = ctf_errno (*dict);
      goto err;
    }

  /* If this dict is being reused from the previous iteration, bump its
     refcnt: the caller is going to close it and has no idea that we didn't
     open it this time round.  */
  if (!opened_this_time)
    ctf_ref (*dict);

  return type;

 err:						/* Also ECTF_NEXT_END. */
  if (opened_this_time)
    {
      ctf_dict_close (*dict);
      *dict = NULL;
    }

  ctf_next_destroy (i);
  *it = NULL;
  if (errp)
    *errp = err;
  return CTF_ERR;
}

/* Raw iteration over all CTF files in an archive.  We pass the raw data for all
   CTF files in turn to the specified callback function.  */
static int
ctf_archive_raw_iter_internal (const struct ctf_archive *arc,
			       ctf_archive_raw_member_f *func, void *data)
{
  int rc;
  size_t i;
  struct ctf_archive_modent *modent;
  const char *nametbl;

  modent = (ctf_archive_modent_t *) ((char *) arc
				     + sizeof (struct ctf_archive));
  nametbl = (((const char *) arc) + le64toh (arc->ctfa_names));

  for (i = 0; i < le64toh (arc->ctfa_ndicts); i++)
    {
      const char *name;
      char *fp;

      name = &nametbl[le64toh (modent[i].name_offset)];
      fp = ((char *) arc + le64toh (arc->ctfa_ctfs)
	    + le64toh (modent[i].ctf_offset));

      if ((rc = func (name, (void *) (fp + sizeof (uint64_t)),
		      le64toh (*((uint64_t *) fp)), data)) != 0)
	return rc;
    }
  return 0;
}

/* Raw iteration over all CTF files in an archive: public entry point.

   Returns -EINVAL if not supported for this sort of archive.  */
int
ctf_archive_raw_iter (const ctf_archive_t *arc,
		      ctf_archive_raw_member_f * func, void *data)
{
  if (arc->ctfi_is_archive)
    return ctf_archive_raw_iter_internal (arc->ctfi_archive, func, data);

  return -EINVAL;			 /* Not supported. */
}

/* Iterate over all CTF files in an archive: public entry point.  We pass all
   CTF files in turn to the specified callback function.  */
int
ctf_archive_iter (const ctf_archive_t *arc, ctf_archive_member_f *func,
		  void *data)
{
  ctf_next_t *i = NULL;
  ctf_dict_t *fp;
  const char *name;
  int err = 0;

  while ((fp = ctf_archive_next (arc, &i, &name, 0, &err)) != NULL)
    {
      int rc;

      if ((rc = func (fp, name, data)) != 0)
	{
	  ctf_dict_close (fp);
	  ctf_next_destroy (i);
	  return rc;
	}
      ctf_dict_close (fp);
    }
  if (err != ECTF_NEXT_END && err != 0)
    {
      ctf_next_destroy (i);
      return -1;
    }
  return 0;
}

/* Iterate over all CTF files in an archive, returning each dict in turn as a
   ctf_dict_t, and NULL on error or end of iteration.  It is the caller's
   responsibility to close it.  Parent dicts may be skipped.

   The archive member is cached for rapid return on future calls.

   We identify parents by name rather than by flag value: for now, with the
   linker only emitting parents named _CTF_SECTION, this works well enough.  */

ctf_dict_t *
ctf_archive_next (const ctf_archive_t *wrapper, ctf_next_t **it, const char **name,
		  int skip_parent, int *errp)
{
  ctf_dict_t *f;
  ctf_next_t *i = *it;
  struct ctf_archive *arc;
  struct ctf_archive_modent *modent;
  const char *nametbl;
  const char *name_;

  if (!i)
    {
      if ((i = ctf_next_create()) == NULL)
	{
	  if (errp)
	    *errp = ENOMEM;
	  return NULL;
	}
      i->cu.ctn_arc = wrapper;
      i->ctn_iter_fun = (void (*) (void)) ctf_archive_next;
      *it = i;
    }

  if ((void (*) (void)) ctf_archive_next != i->ctn_iter_fun)
    {
      if (errp)
	*errp = ECTF_NEXT_WRONGFUN;
      return NULL;
    }

  if (wrapper != i->cu.ctn_arc)
    {
      if (errp)
	*errp = ECTF_NEXT_WRONGFP;
      return NULL;
    }

  /* Iteration is made a bit more complex by the need to handle ctf_dict_t's
     transparently wrapped in a single-member archive.  These are parents: if
     skip_parent is on, they are skipped and the iterator terminates
     immediately.  */

  if (!wrapper->ctfi_is_archive && i->ctn_n == 0)
    {
      i->ctn_n++;
      if (!skip_parent)
	{
	  wrapper->ctfi_dict->ctf_refcnt++;
	  if (name)
	    *name = _CTF_SECTION;
	  return wrapper->ctfi_dict;
	}
    }

  arc = wrapper->ctfi_archive;

  /* The loop keeps going when skip_parent is on as long as the member we find
     is the parent (i.e. at most two iterations, but possibly an early return if
     *all* we have is a parent).  */

  do
    {
      if ((!wrapper->ctfi_is_archive) || (i->ctn_n >= le64toh (arc->ctfa_ndicts)))
	{
	  ctf_next_destroy (i);
	  *it = NULL;
	  if (errp)
	    *errp = ECTF_NEXT_END;
	  return NULL;
	}

      modent = (ctf_archive_modent_t *) ((char *) arc
					 + sizeof (struct ctf_archive));
      nametbl = (((const char *) arc) + le64toh (arc->ctfa_names));

      name_ = &nametbl[le64toh (modent[i->ctn_n].name_offset)];
      i->ctn_n++;
    }
  while (skip_parent && strcmp (name_, _CTF_SECTION) == 0);

  if (name)
    *name = name_;

  f = ctf_dict_open_cached ((ctf_archive_t *) wrapper, name_, errp);
  return f;
}

#ifdef HAVE_MMAP
/* Map the header in.  Only used on new, empty files.  */
static void *arc_mmap_header (int fd, size_t headersz)
{
  void *hdr;
  if ((hdr = mmap (NULL, headersz, PROT_READ | PROT_WRITE, MAP_SHARED, fd,
		   0)) == MAP_FAILED)
    return NULL;
  return hdr;
}

/* mmap() the whole file, for reading only.  (Map it writably, but privately: we
   need to modify the region, but don't need anyone else to see the
   modifications.)  */
static void *arc_mmap_file (int fd, size_t size)
{
  void *arc;
  if ((arc = mmap (NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE,
		   fd, 0)) == MAP_FAILED)
    return NULL;
  return arc;
}

/* Persist the header to disk.  */
static int arc_mmap_writeout (int fd _libctf_unused_, void *header,
			      size_t headersz, const char **errmsg)
{
    if (msync (header, headersz, MS_ASYNC) < 0)
    {
      if (errmsg)
	*errmsg = N_("arc_mmap_writeout(): cannot sync after writing "
		     "to %s: %s");
      return -1;
    }
    return 0;
}

/* Unmap the region.  */
static int arc_mmap_unmap (void *header, size_t headersz, const char **errmsg)
{
  if (munmap (header, headersz) < 0)
    {
      if (errmsg)
	*errmsg = N_("arc_mmap_munmap(): cannot unmap after writing "
		     "to %s: %s");
      return -1;
    }
    return 0;
}
#else
/* Map the header in.  Only used on new, empty files.  */
static void *arc_mmap_header (int fd _libctf_unused_, size_t headersz)
{
  void *hdr;
  if ((hdr = malloc (headersz)) == NULL)
    return NULL;
  return hdr;
}

/* Pull in the whole file, for reading only.  We assume the current file
   position is at the start of the file.  */
static void *arc_mmap_file (int fd, size_t size)
{
  char *data;

  if ((data = malloc (size)) == NULL)
    return NULL;

  if (ctf_pread (fd, data, size, 0) < 0)
    {
      free (data);
      return NULL;
    }
  return data;
}

/* Persist the header to disk.  */
static int arc_mmap_writeout (int fd, void *header, size_t headersz,
			      const char **errmsg)
{
  ssize_t len;
  char *data = (char *) header;
  ssize_t count = headersz;

  if ((lseek (fd, 0, SEEK_SET)) < 0)
    {
      if (errmsg)
	*errmsg = N_("arc_mmap_writeout(): cannot seek while writing header to "
		     "%s: %s");
      return -1;
    }

  while (headersz > 0)
    {
      if ((len = write (fd, data, count)) < 0)
	{
	  if (errmsg)
	    *errmsg = N_("arc_mmap_writeout(): cannot write header to %s: %s");
	  return len;
	}
      if (len == EINTR)
	continue;

      if (len == 0)				/* EOF.  */
	break;

      count -= len;
      data += len;
    }
  return 0;
}

/* Unmap the region.  */
static int arc_mmap_unmap (void *header, size_t headersz _libctf_unused_,
			   const char **errmsg _libctf_unused_)
{
  free (header);
  return 0;
}
#endif
