/* 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 void ctf_arc_import_parent (const ctf_archive_t *arc, ctf_dict_t *fp);

/* 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 file 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 (ctf_serialize (f) < 0)
    return f->ctf_errno * -1;

  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;
	  ctf_arc_import_parent (arc, ret);
	}
      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);
  free (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 void
ctf_arc_import_parent (const ctf_archive_t *arc, ctf_dict_t *fp)
{
  if ((fp->ctf_flags & LCTF_CHILD) && fp->ctf_parname && !fp->ctf_parent)
    {
      ctf_dict_t *parent = ctf_dict_open_cached ((ctf_archive_t *) arc,
						 fp->ctf_parname, NULL);
      if (parent)
	{
	  ctf_import (fp, parent);
	  ctf_dict_close (parent);
	}
    }
}

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

  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);
    }
  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
