/* CTF archive files.
   Copyright (C) 2019-2024 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;
  int (*writefn) (ctf_dict_t * fp, int fd);

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

  if (f->ctf_size > threshold)
    writefn = ctf_compress_write;
  else
    writefn = ctf_write;

  /* 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 (writefn (f, fd) != 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 (uint64_t)
      && (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 (uint64_t)
      && (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);
  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 (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;
      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 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_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);
}

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