/* Opening CTF 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 <stddef.h>
#include <string.h>
#include <sys/types.h>
#include <elf.h>
#include "swap.h"
#include <bfd.h>
#include <zlib.h>

static const ctf_dmodel_t _libctf_models[] = {
  {"ILP32", CTF_MODEL_ILP32, 4, 1, 2, 4, 4},
  {"LP64", CTF_MODEL_LP64, 8, 1, 2, 4, 8},
  {NULL, 0, 0, 0, 0, 0, 0}
};

const char _CTF_SECTION[] = ".ctf";
const char _CTF_NULLSTR[] = "";

/* Version-sensitive accessors.  */

static uint32_t
get_kind_v1 (uint32_t info)
{
  return (CTF_V1_INFO_KIND (info));
}

static uint32_t
get_root_v1 (uint32_t info)
{
  return (CTF_V1_INFO_ISROOT (info));
}

static uint32_t
get_vlen_v1 (uint32_t info)
{
  return (CTF_V1_INFO_VLEN (info));
}

static uint32_t
get_kind_v2 (uint32_t info)
{
  return (CTF_V2_INFO_KIND (info));
}

static uint32_t
get_root_v2 (uint32_t info)
{
  return (CTF_V2_INFO_ISROOT (info));
}

static uint32_t
get_vlen_v2 (uint32_t info)
{
  return (CTF_V2_INFO_VLEN (info));
}

static inline ssize_t
get_ctt_size_common (const ctf_dict_t *fp _libctf_unused_,
		     const ctf_type_t *tp _libctf_unused_,
		     ssize_t *sizep, ssize_t *incrementp, size_t lsize,
		     size_t csize, size_t ctf_type_size,
		     size_t ctf_stype_size, size_t ctf_lsize_sent)
{
  ssize_t size, increment;

  if (csize == ctf_lsize_sent)
    {
      size = lsize;
      increment = ctf_type_size;
    }
  else
    {
      size = csize;
      increment = ctf_stype_size;
    }

  if (sizep)
    *sizep = size;
  if (incrementp)
    *incrementp = increment;

  return size;
}

static ssize_t
get_ctt_size_v1 (const ctf_dict_t *fp, const ctf_type_t *tp,
		 ssize_t *sizep, ssize_t *incrementp)
{
  ctf_type_v1_t *t1p = (ctf_type_v1_t *) tp;

  return (get_ctt_size_common (fp, tp, sizep, incrementp,
			       CTF_TYPE_LSIZE (t1p), t1p->ctt_size,
			       sizeof (ctf_type_v1_t), sizeof (ctf_stype_v1_t),
			       CTF_LSIZE_SENT_V1));
}

/* Return the size that a v1 will be once it is converted to v2.  */

static ssize_t
get_ctt_size_v2_unconverted (const ctf_dict_t *fp, const ctf_type_t *tp,
			     ssize_t *sizep, ssize_t *incrementp)
{
  ctf_type_v1_t *t1p = (ctf_type_v1_t *) tp;

  return (get_ctt_size_common (fp, tp, sizep, incrementp,
			       CTF_TYPE_LSIZE (t1p), t1p->ctt_size,
			       sizeof (ctf_type_t), sizeof (ctf_stype_t),
			       CTF_LSIZE_SENT));
}

static ssize_t
get_ctt_size_v2 (const ctf_dict_t *fp, const ctf_type_t *tp,
		 ssize_t *sizep, ssize_t *incrementp)
{
  return (get_ctt_size_common (fp, tp, sizep, incrementp,
			       CTF_TYPE_LSIZE (tp), tp->ctt_size,
			       sizeof (ctf_type_t), sizeof (ctf_stype_t),
			       CTF_LSIZE_SENT));
}

static ssize_t
get_vbytes_common (ctf_dict_t *fp, unsigned short kind,
		   ssize_t size _libctf_unused_, size_t vlen)
{
  switch (kind)
    {
    case CTF_K_INTEGER:
    case CTF_K_FLOAT:
      return (sizeof (uint32_t));
    case CTF_K_SLICE:
      return (sizeof (ctf_slice_t));
    case CTF_K_ENUM:
      return (sizeof (ctf_enum_t) * vlen);
    case CTF_K_FORWARD:
    case CTF_K_UNKNOWN:
    case CTF_K_POINTER:
    case CTF_K_TYPEDEF:
    case CTF_K_VOLATILE:
    case CTF_K_CONST:
    case CTF_K_RESTRICT:
      return 0;
    default:
      ctf_set_errno (fp, ECTF_CORRUPT);
      ctf_err_warn (fp, 0, 0, _("detected invalid CTF kind: %x"), kind);
      return -1;
    }
}

static ssize_t
get_vbytes_v1 (ctf_dict_t *fp, unsigned short kind, ssize_t size, size_t vlen)
{
  switch (kind)
    {
    case CTF_K_ARRAY:
      return (sizeof (ctf_array_v1_t));
    case CTF_K_FUNCTION:
      return (sizeof (unsigned short) * (vlen + (vlen & 1)));
    case CTF_K_STRUCT:
    case CTF_K_UNION:
      if (size < CTF_LSTRUCT_THRESH_V1)
	return (sizeof (ctf_member_v1_t) * vlen);
      else
	return (sizeof (ctf_lmember_v1_t) * vlen);
    }

  return (get_vbytes_common (fp, kind, size, vlen));
}

static ssize_t
get_vbytes_v2 (ctf_dict_t *fp, unsigned short kind, ssize_t size, size_t vlen)
{
  switch (kind)
    {
    case CTF_K_ARRAY:
      return (sizeof (ctf_array_t));
    case CTF_K_FUNCTION:
      return (sizeof (uint32_t) * (vlen + (vlen & 1)));
    case CTF_K_STRUCT:
    case CTF_K_UNION:
      if (size < CTF_LSTRUCT_THRESH)
	return (sizeof (ctf_member_t) * vlen);
      else
	return (sizeof (ctf_lmember_t) * vlen);
    }

  return (get_vbytes_common (fp, kind, size, vlen));
}

static const ctf_dictops_t ctf_dictops[] = {
  {NULL, NULL, NULL, NULL, NULL},
  /* CTF_VERSION_1 */
  {get_kind_v1, get_root_v1, get_vlen_v1, get_ctt_size_v1, get_vbytes_v1},
  /* CTF_VERSION_1_UPGRADED_3 */
  {get_kind_v2, get_root_v2, get_vlen_v2, get_ctt_size_v2, get_vbytes_v2},
  /* CTF_VERSION_2 */
  {get_kind_v2, get_root_v2, get_vlen_v2, get_ctt_size_v2, get_vbytes_v2},
  /* CTF_VERSION_3, identical to 2: only new type kinds */
  {get_kind_v2, get_root_v2, get_vlen_v2, get_ctt_size_v2, get_vbytes_v2},
};

/* Initialize the symtab translation table as appropriate for its indexing
   state.  For unindexed symtypetabs, fill each entry with the offset of the CTF
   type or function data corresponding to each STT_FUNC or STT_OBJECT entry in
   the symbol table.  For indexed symtypetabs, do nothing: the needed
   initialization for indexed lookups may be quite expensive, so it is done only
   as needed, when lookups happen.  (In particular, the majority of indexed
   symtypetabs come from the compiler, and all the linker does is iteration over
   all entries, which doesn't need this initialization.)

   The SP symbol table section may be NULL if there is no symtab.

   If init_symtab works on one call, it cannot fail on future calls to the same
   fp: ctf_symsect_endianness relies on this.  */

static int
init_symtab (ctf_dict_t *fp, const ctf_header_t *hp, const ctf_sect_t *sp)
{
  const unsigned char *symp;
  int skip_func_info = 0;
  int i;
  uint32_t *xp = fp->ctf_sxlate;
  uint32_t *xend = PTR_ADD (xp, fp->ctf_nsyms);

  uint32_t objtoff = hp->cth_objtoff;
  uint32_t funcoff = hp->cth_funcoff;

  /* If the CTF_F_NEWFUNCINFO flag is not set, pretend the func info section
     is empty: this compiler is too old to emit a function info section we
     understand.  */

  if (!(hp->cth_flags & CTF_F_NEWFUNCINFO))
    skip_func_info = 1;

  if (hp->cth_objtidxoff < hp->cth_funcidxoff)
    fp->ctf_objtidx_names = (uint32_t *) (fp->ctf_buf + hp->cth_objtidxoff);
  if (hp->cth_funcidxoff < hp->cth_varoff && !skip_func_info)
    fp->ctf_funcidx_names = (uint32_t *) (fp->ctf_buf + hp->cth_funcidxoff);

  /* Don't bother doing the rest if everything is indexed, or if we don't have a
     symbol table: we will never use it.  */
  if ((fp->ctf_objtidx_names && fp->ctf_funcidx_names) || !sp || !sp->cts_data)
    return 0;

  /* The CTF data object and function type sections are ordered to match the
     relative order of the respective symbol types in the symtab, unless there
     is an index section, in which case the order is arbitrary and the index
     gives the mapping.  If no type information is available for a symbol table
     entry, a pad is inserted in the CTF section.  As a further optimization,
     anonymous or undefined symbols are omitted from the CTF data.  If an
     index is available for function symbols but not object symbols, or vice
     versa, we populate the xslate table for the unindexed symbols only.  */

  for (i = 0, symp = sp->cts_data; xp < xend; xp++, symp += sp->cts_entsize,
	 i++)
    {
      ctf_link_sym_t sym;

      switch (sp->cts_entsize)
	{
	case sizeof (Elf64_Sym):
	  {
	    const Elf64_Sym *symp64 = (Elf64_Sym *) (uintptr_t) symp;
	    ctf_elf64_to_link_sym (fp, &sym, symp64, i);
	  }
	  break;
	case sizeof (Elf32_Sym):
	  {
	    const Elf32_Sym *symp32 = (Elf32_Sym *) (uintptr_t) symp;
	    ctf_elf32_to_link_sym (fp, &sym, symp32, i);
	  }
	  break;
	default:
	  return ECTF_SYMTAB;
	}

      /* This call may be led astray if our idea of the symtab's endianness is
	 wrong, but when this is fixed by a call to ctf_symsect_endianness,
	 init_symtab will be called again with the right endianness in
	 force.  */
      if (ctf_symtab_skippable (&sym))
	{
	  *xp = -1u;
	  continue;
	}

      switch (sym.st_type)
	{
	case STT_OBJECT:
	  if (fp->ctf_objtidx_names || objtoff >= hp->cth_funcoff)
	    {
	      *xp = -1u;
	      break;
	    }

	  *xp = objtoff;
	  objtoff += sizeof (uint32_t);
	  break;

	case STT_FUNC:
	  if (fp->ctf_funcidx_names || funcoff >= hp->cth_objtidxoff
	      || skip_func_info)
	    {
	      *xp = -1u;
	      break;
	    }

	  *xp = funcoff;
	  funcoff += sizeof (uint32_t);
	  break;

	default:
	  *xp = -1u;
	  break;
	}
    }

  ctf_dprintf ("loaded %lu symtab entries\n", fp->ctf_nsyms);
  return 0;
}

/* Reset the CTF base pointer and derive the buf pointer from it, initializing
   everything in the ctf_dict that depends on the base or buf pointers.

   The original gap between the buf and base pointers, if any -- the original,
   unconverted CTF header -- is kept, but its contents are not specified and are
   never used.  */

static void
ctf_set_base (ctf_dict_t *fp, const ctf_header_t *hp, unsigned char *base)
{
  fp->ctf_buf = base + (fp->ctf_buf - fp->ctf_base);
  fp->ctf_base = base;
  fp->ctf_vars = (ctf_varent_t *) ((const char *) fp->ctf_buf +
				   hp->cth_varoff);
  fp->ctf_nvars = (hp->cth_typeoff - hp->cth_varoff) / sizeof (ctf_varent_t);

  fp->ctf_str[CTF_STRTAB_0].cts_strs = (const char *) fp->ctf_buf
    + hp->cth_stroff;
  fp->ctf_str[CTF_STRTAB_0].cts_len = hp->cth_strlen;

  /* If we have a parent dict name and label, store the relocated string
     pointers in the CTF dict for easy access later. */

  /* Note: before conversion, these will be set to values that will be
     immediately invalidated by the conversion process, but the conversion
     process will call ctf_set_base() again to fix things up.  */

  if (hp->cth_parlabel != 0)
    fp->ctf_parlabel = ctf_strptr (fp, hp->cth_parlabel);
  if (hp->cth_parname != 0)
    fp->ctf_parname = ctf_strptr (fp, hp->cth_parname);
  if (hp->cth_cuname != 0)
    fp->ctf_cuname = ctf_strptr (fp, hp->cth_cuname);

  if (fp->ctf_cuname)
    ctf_dprintf ("ctf_set_base: CU name %s\n", fp->ctf_cuname);
  if (fp->ctf_parname)
    ctf_dprintf ("ctf_set_base: parent name %s (label %s)\n",
	       fp->ctf_parname,
	       fp->ctf_parlabel ? fp->ctf_parlabel : "<NULL>");
}

/* Set the version of the CTF file. */

/* When this is reset, LCTF_* changes behaviour, but there is no guarantee that
   the variable data list associated with each type has been upgraded: the
   caller must ensure this has been done in advance.  */

static void
ctf_set_version (ctf_dict_t *fp, ctf_header_t *cth, int ctf_version)
{
  fp->ctf_version = ctf_version;
  cth->cth_version = ctf_version;
  fp->ctf_dictops = &ctf_dictops[ctf_version];
}


/* Upgrade the header to CTF_VERSION_3.  The upgrade is done in-place.  */
static void
upgrade_header (ctf_header_t *hp)
{
  ctf_header_v2_t *oldhp = (ctf_header_v2_t *) hp;

  hp->cth_strlen = oldhp->cth_strlen;
  hp->cth_stroff = oldhp->cth_stroff;
  hp->cth_typeoff = oldhp->cth_typeoff;
  hp->cth_varoff = oldhp->cth_varoff;
  hp->cth_funcidxoff = hp->cth_varoff;		/* No index sections.  */
  hp->cth_objtidxoff = hp->cth_funcidxoff;
  hp->cth_funcoff = oldhp->cth_funcoff;
  hp->cth_objtoff = oldhp->cth_objtoff;
  hp->cth_lbloff = oldhp->cth_lbloff;
  hp->cth_cuname = 0;				/* No CU name.  */
}

/* Upgrade the type table to CTF_VERSION_3 (really CTF_VERSION_1_UPGRADED_3)
   from CTF_VERSION_1.

   The upgrade is not done in-place: the ctf_base is moved.  ctf_strptr() must
   not be called before reallocation is complete.

   Sections not checked here due to nonexistence or nonpopulated state in older
   formats: objtidx, funcidx.

   Type kinds not checked here due to nonexistence in older formats:
      CTF_K_SLICE.  */
static int
upgrade_types_v1 (ctf_dict_t *fp, ctf_header_t *cth)
{
  const ctf_type_v1_t *tbuf;
  const ctf_type_v1_t *tend;
  unsigned char *ctf_base, *old_ctf_base = (unsigned char *) fp->ctf_dynbase;
  ctf_type_t *t2buf;

  ssize_t increase = 0, size, increment, v2increment, vbytes, v2bytes;
  const ctf_type_v1_t *tp;
  ctf_type_t *t2p;

  tbuf = (ctf_type_v1_t *) (fp->ctf_buf + cth->cth_typeoff);
  tend = (ctf_type_v1_t *) (fp->ctf_buf + cth->cth_stroff);

  /* Much like init_static_types(), this is a two-pass process.

     First, figure out the new type-section size needed.  (It is possible,
     in theory, for it to be less than the old size, but this is very
     unlikely.  It cannot be so small that cth_typeoff ends up of negative
     size.  We validate this with an assertion below.)

     We must cater not only for changes in vlen and types sizes but also
     for changes in 'increment', which happen because v2 places some types
     into ctf_stype_t where v1 would be forced to use the larger non-stype.  */

  for (tp = tbuf; tp < tend;
       tp = (ctf_type_v1_t *) ((uintptr_t) tp + increment + vbytes))
    {
      unsigned short kind = CTF_V1_INFO_KIND (tp->ctt_info);
      unsigned long vlen = CTF_V1_INFO_VLEN (tp->ctt_info);

      size = get_ctt_size_v1 (fp, (const ctf_type_t *) tp, NULL, &increment);
      vbytes = get_vbytes_v1 (fp, kind, size, vlen);

      get_ctt_size_v2_unconverted (fp, (const ctf_type_t *) tp, NULL,
				   &v2increment);
      v2bytes = get_vbytes_v2 (fp, kind, size, vlen);

      if ((vbytes < 0) || (size < 0))
	return ECTF_CORRUPT;

      increase += v2increment - increment;	/* May be negative.  */
      increase += v2bytes - vbytes;
    }

  /* Allocate enough room for the new buffer, then copy everything but the type
     section into place, and reset the base accordingly.  Leave the version
     number unchanged, so that LCTF_INFO_* still works on the
     as-yet-untranslated type info.  */

  if ((ctf_base = malloc (fp->ctf_size + increase)) == NULL)
    return ECTF_ZALLOC;

  /* Start at ctf_buf, not ctf_base, to squeeze out the original header: we
     never use it and it is unconverted.  */

  memcpy (ctf_base, fp->ctf_buf, cth->cth_typeoff);
  memcpy (ctf_base + cth->cth_stroff + increase,
	  fp->ctf_buf + cth->cth_stroff, cth->cth_strlen);

  memset (ctf_base + cth->cth_typeoff, 0, cth->cth_stroff - cth->cth_typeoff
	  + increase);

  cth->cth_stroff += increase;
  fp->ctf_size += increase;
  assert (cth->cth_stroff >= cth->cth_typeoff);
  fp->ctf_base = ctf_base;
  fp->ctf_buf = ctf_base;
  fp->ctf_dynbase = ctf_base;
  ctf_set_base (fp, cth, ctf_base);

  t2buf = (ctf_type_t *) (fp->ctf_buf + cth->cth_typeoff);

  /* Iterate through all the types again, upgrading them.

     Everything that hasn't changed can just be outright memcpy()ed.
     Things that have changed need field-by-field consideration.  */

  for (tp = tbuf, t2p = t2buf; tp < tend;
       tp = (ctf_type_v1_t *) ((uintptr_t) tp + increment + vbytes),
       t2p = (ctf_type_t *) ((uintptr_t) t2p + v2increment + v2bytes))
    {
      unsigned short kind = CTF_V1_INFO_KIND (tp->ctt_info);
      int isroot = CTF_V1_INFO_ISROOT (tp->ctt_info);
      unsigned long vlen = CTF_V1_INFO_VLEN (tp->ctt_info);
      ssize_t v2size;
      void *vdata, *v2data;

      size = get_ctt_size_v1 (fp, (const ctf_type_t *) tp, NULL, &increment);
      vbytes = get_vbytes_v1 (fp, kind, size, vlen);

      t2p->ctt_name = tp->ctt_name;
      t2p->ctt_info = CTF_TYPE_INFO (kind, isroot, vlen);

      switch (kind)
	{
	case CTF_K_FUNCTION:
	case CTF_K_FORWARD:
	case CTF_K_TYPEDEF:
	case CTF_K_POINTER:
	case CTF_K_VOLATILE:
	case CTF_K_CONST:
	case CTF_K_RESTRICT:
	  t2p->ctt_type = tp->ctt_type;
	  break;
	case CTF_K_INTEGER:
	case CTF_K_FLOAT:
	case CTF_K_ARRAY:
	case CTF_K_STRUCT:
	case CTF_K_UNION:
	case CTF_K_ENUM:
	case CTF_K_UNKNOWN:
	  if ((size_t) size <= CTF_MAX_SIZE)
	    t2p->ctt_size = size;
	  else
	    {
	      t2p->ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI (size);
	      t2p->ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO (size);
	    }
	  break;
	}

      v2size = get_ctt_size_v2 (fp, t2p, NULL, &v2increment);
      v2bytes = get_vbytes_v2 (fp, kind, v2size, vlen);

      /* Catch out-of-sync get_ctt_size_*().  The count goes wrong if
	 these are not identical (and having them different makes no
	 sense semantically).  */

      assert (size == v2size);

      /* Now the varlen info.  */

      vdata = (void *) ((uintptr_t) tp + increment);
      v2data = (void *) ((uintptr_t) t2p + v2increment);

      switch (kind)
	{
	case CTF_K_ARRAY:
	  {
	    const ctf_array_v1_t *ap = (const ctf_array_v1_t *) vdata;
	    ctf_array_t *a2p = (ctf_array_t *) v2data;

	    a2p->cta_contents = ap->cta_contents;
	    a2p->cta_index = ap->cta_index;
	    a2p->cta_nelems = ap->cta_nelems;
	    break;
	  }
	case CTF_K_STRUCT:
	case CTF_K_UNION:
	  {
	    ctf_member_t tmp;
	    const ctf_member_v1_t *m1 = (const ctf_member_v1_t *) vdata;
	    const ctf_lmember_v1_t *lm1 = (const ctf_lmember_v1_t *) m1;
	    ctf_member_t *m2 = (ctf_member_t *) v2data;
	    ctf_lmember_t *lm2 = (ctf_lmember_t *) m2;
	    unsigned long i;

	    /* We walk all four pointers forward, but only reference the two
	       that are valid for the given size, to avoid quadruplicating all
	       the code.  */

	    for (i = vlen; i != 0; i--, m1++, lm1++, m2++, lm2++)
	      {
		size_t offset;
		if (size < CTF_LSTRUCT_THRESH_V1)
		  {
		    offset = m1->ctm_offset;
		    tmp.ctm_name = m1->ctm_name;
		    tmp.ctm_type = m1->ctm_type;
		  }
		else
		  {
		    offset = CTF_LMEM_OFFSET (lm1);
		    tmp.ctm_name = lm1->ctlm_name;
		    tmp.ctm_type = lm1->ctlm_type;
		  }
		if (size < CTF_LSTRUCT_THRESH)
		  {
		    m2->ctm_name = tmp.ctm_name;
		    m2->ctm_type = tmp.ctm_type;
		    m2->ctm_offset = offset;
		  }
		else
		  {
		    lm2->ctlm_name = tmp.ctm_name;
		    lm2->ctlm_type = tmp.ctm_type;
		    lm2->ctlm_offsethi = CTF_OFFSET_TO_LMEMHI (offset);
		    lm2->ctlm_offsetlo = CTF_OFFSET_TO_LMEMLO (offset);
		  }
	      }
	    break;
	  }
	case CTF_K_FUNCTION:
	  {
	    unsigned long i;
	    unsigned short *a1 = (unsigned short *) vdata;
	    uint32_t *a2 = (uint32_t *) v2data;

	    for (i = vlen; i != 0; i--, a1++, a2++)
	      *a2 = *a1;
	  }
	/* FALLTHRU */
	default:
	  /* Catch out-of-sync get_vbytes_*().  */
	  assert (vbytes == v2bytes);
	  memcpy (v2data, vdata, vbytes);
	}
    }

  /* Verify that the entire region was converted.  If not, we are either
     converting too much, or too little (leading to a buffer overrun either here
     or at read time, in init_static_types().) */

  assert ((size_t) t2p - (size_t) fp->ctf_buf == cth->cth_stroff);

  ctf_set_version (fp, cth, CTF_VERSION_1_UPGRADED_3);
  free (old_ctf_base);

  return 0;
}

/* Upgrade from any earlier version.  */
static int
upgrade_types (ctf_dict_t *fp, ctf_header_t *cth)
{
  switch (cth->cth_version)
    {
      /* v1 requires a full pass and reformatting.  */
    case CTF_VERSION_1:
      upgrade_types_v1 (fp, cth);
      /* FALLTHRU */
      /* Already-converted v1 is just like later versions except that its
	 parent/child boundary is unchanged (and much lower).  */

    case CTF_VERSION_1_UPGRADED_3:
      fp->ctf_parmax = CTF_MAX_PTYPE_V1;

      /* v2 is just the same as v3 except for new types and sections:
	 no upgrading required. */
    case CTF_VERSION_2: ;
      /* FALLTHRU */
    }
  return 0;
}

static int
init_static_types_internal (ctf_dict_t *fp, ctf_header_t *cth,
			    ctf_dynset_t *all_enums);

/* Populate statically-defined types (those loaded from a saved buffer).

   Initialize the type ID translation table with the byte offset of each type,
   and initialize the hash tables of each named type.  Upgrade the type table to
   the latest supported representation in the process, if needed, and if this
   recension of libctf supports upgrading.

   This is a wrapper to simplify memory allocation on error in the _internal
   function that does all the actual work.  */

static int
init_static_types (ctf_dict_t *fp, ctf_header_t *cth)
{
  ctf_dynset_t *all_enums;
  int err;

  if ((all_enums = ctf_dynset_create (htab_hash_pointer, htab_eq_pointer,
				      NULL)) == NULL)
    return ENOMEM;

  err = init_static_types_internal (fp, cth, all_enums);
  ctf_dynset_destroy (all_enums);
  return err;
}

static int
init_static_types_internal (ctf_dict_t *fp, ctf_header_t *cth,
			    ctf_dynset_t *all_enums)
{
  const ctf_type_t *tbuf;
  const ctf_type_t *tend;

  unsigned long pop[CTF_K_MAX + 1] = { 0 };
  int pop_enumerators = 0;
  const ctf_type_t *tp;
  uint32_t id;
  uint32_t *xp;
  unsigned long typemax = 0;
  ctf_next_t *i = NULL;
  void *k;

  /* We determine whether the dict is a child or a parent based on the value of
     cth_parname.  */

  int child = cth->cth_parname != 0;
  int nlstructs = 0, nlunions = 0;
  int err;

  if (_libctf_unlikely_ (fp->ctf_version == CTF_VERSION_1))
    {
      int err;
      if ((err = upgrade_types (fp, cth)) != 0)
	return err;				/* Upgrade failed.  */
    }

  tbuf = (ctf_type_t *) (fp->ctf_buf + cth->cth_typeoff);
  tend = (ctf_type_t *) (fp->ctf_buf + cth->cth_stroff);

  /* We make two passes through the entire type section, and one third pass
     through part of it.  In this first pass, we count the number of each type
     and type-like identifier (like enumerators) and the total number of
     types.  */

  for (tp = tbuf; tp < tend; typemax++)
    {
      unsigned short kind = LCTF_INFO_KIND (fp, tp->ctt_info);
      unsigned long vlen = LCTF_INFO_VLEN (fp, tp->ctt_info);
      ssize_t size, increment, vbytes;

      (void) ctf_get_ctt_size (fp, tp, &size, &increment);
      vbytes = LCTF_VBYTES (fp, kind, size, vlen);

      if (vbytes < 0)
	return ECTF_CORRUPT;

      /* For forward declarations, ctt_type is the CTF_K_* kind for the tag,
	 so bump that population count too.  */
      if (kind == CTF_K_FORWARD)
	pop[tp->ctt_type]++;

      tp = (ctf_type_t *) ((uintptr_t) tp + increment + vbytes);
      pop[kind]++;

      if (kind == CTF_K_ENUM)
	pop_enumerators += vlen;
    }

  if (child)
    {
      ctf_dprintf ("CTF dict %p is a child\n", (void *) fp);
      fp->ctf_flags |= LCTF_CHILD;
    }
  else
    ctf_dprintf ("CTF dict %p is a parent\n", (void *) fp);

  /* Now that we've counted up the number of each type, we can allocate
     the hash tables, type translation table, and pointer table.  */

  if ((fp->ctf_structs
       = ctf_dynhash_create_sized (pop[CTF_K_STRUCT], ctf_hash_string,
				   ctf_hash_eq_string, NULL, NULL)) == NULL)
    return ENOMEM;

  if ((fp->ctf_unions
       = ctf_dynhash_create_sized (pop[CTF_K_UNION], ctf_hash_string,
				   ctf_hash_eq_string, NULL, NULL)) == NULL)
    return ENOMEM;

  if ((fp->ctf_enums
       = ctf_dynhash_create_sized (pop[CTF_K_ENUM], ctf_hash_string,
				   ctf_hash_eq_string, NULL, NULL)) == NULL)
    return ENOMEM;

  if ((fp->ctf_names
       = ctf_dynhash_create_sized (pop[CTF_K_UNKNOWN] +
				   pop[CTF_K_INTEGER] +
				   pop[CTF_K_FLOAT] +
				   pop[CTF_K_FUNCTION] +
				   pop[CTF_K_TYPEDEF] +
				   pop[CTF_K_POINTER] +
				   pop[CTF_K_VOLATILE] +
				   pop[CTF_K_CONST] +
				   pop[CTF_K_RESTRICT] +
				   pop_enumerators,
				   ctf_hash_string,
				   ctf_hash_eq_string, NULL, NULL)) == NULL)
    return ENOMEM;

  if ((fp->ctf_conflicting_enums
       = ctf_dynset_create (htab_hash_string, htab_eq_string, NULL)) == NULL)
    return ENOMEM;

  /* The ptrtab and txlate can be appropriately sized for precisely this set
     of types: the txlate because it is only used to look up static types,
     so dynamic types added later will never go through it, and the ptrtab
     because later-added types will call grow_ptrtab() automatically, as
     needed.  */

  fp->ctf_txlate = malloc (sizeof (uint32_t) * (typemax + 1));
  fp->ctf_ptrtab_len = typemax + 1;
  fp->ctf_ptrtab = malloc (sizeof (uint32_t) * fp->ctf_ptrtab_len);
  fp->ctf_stypes = typemax;

  if (fp->ctf_txlate == NULL || fp->ctf_ptrtab == NULL)
    return ENOMEM;		/* Memory allocation failed.  */

  xp = fp->ctf_txlate;
  *xp++ = 0;			/* Type id 0 is used as a sentinel value.  */

  memset (fp->ctf_txlate, 0, sizeof (uint32_t) * (typemax + 1));
  memset (fp->ctf_ptrtab, 0, sizeof (uint32_t) * (typemax + 1));

  /* In the second pass through the types, we fill in each entry of the
     type and pointer tables and add names to the appropriate hashes.

     (Not all names are added in this pass, only type names.  See below.)

     Bump ctf_typemax as we go, but keep it one higher than normal, so that
     the type being read in is considered a valid type and it is at least
     barely possible to run simple lookups on it.  */

  for (id = 1, fp->ctf_typemax = 1, tp = tbuf; tp < tend; xp++, id++, fp->ctf_typemax++)
    {
      unsigned short kind = LCTF_INFO_KIND (fp, tp->ctt_info);
      unsigned short isroot = LCTF_INFO_ISROOT (fp, tp->ctt_info);
      unsigned long vlen = LCTF_INFO_VLEN (fp, tp->ctt_info);
      ssize_t size, increment, vbytes;

      const char *name;

      (void) ctf_get_ctt_size (fp, tp, &size, &increment);
      name = ctf_strptr (fp, tp->ctt_name);
      /* Cannot fail: shielded by call in loop above.  */
      vbytes = LCTF_VBYTES (fp, kind, size, vlen);

      *xp = (uint32_t) ((uintptr_t) tp - (uintptr_t) fp->ctf_buf);

      switch (kind)
	{
	case CTF_K_UNKNOWN:
	case CTF_K_INTEGER:
	case CTF_K_FLOAT:
	  {
	    ctf_id_t existing;
	    ctf_encoding_t existing_en;
	    ctf_encoding_t this_en;

	    if (!isroot)
	      break;

	    /* Names are reused by bitfields, which are differentiated by
	       their encodings.  So check for the type already existing, and
	       iff the new type is a root-visible non-bitfield, replace the
	       old one.  It's a little hard to figure out whether a type is
	       a non-bitfield without already knowing that type's native
	       width, but we can converge on it by replacing an existing
	       type as long as the new type is zero-offset and has a
	       bit-width wider than the existing one, since the native type
	       must necessarily have a bit-width at least as wide as any
	       bitfield based on it. */

	    if (((existing = ctf_dynhash_lookup_type (fp->ctf_names, name)) == 0)
		|| ctf_type_encoding (fp, existing, &existing_en) != 0
		|| (ctf_type_encoding (fp, LCTF_INDEX_TO_TYPE (fp, id, child), &this_en) == 0
		    && this_en.cte_offset == 0
		    && (existing_en.cte_offset != 0
			|| existing_en.cte_bits < this_en.cte_bits)))
	      {
		err = ctf_dynhash_insert_type (fp, fp->ctf_names,
					       LCTF_INDEX_TO_TYPE (fp, id, child),
					       tp->ctt_name);
		if (err != 0)
		  return err;
	      }
	    break;
	  }

	  /* These kinds have no name, so do not need interning into any
	     hashtables.  */
	case CTF_K_ARRAY:
	case CTF_K_SLICE:
	  break;

	case CTF_K_FUNCTION:
	  if (!isroot)
	    break;

	  err = ctf_dynhash_insert_type (fp, fp->ctf_names,
					 LCTF_INDEX_TO_TYPE (fp, id, child),
					 tp->ctt_name);
	  if (err != 0)
	    return err;
	  break;

	case CTF_K_STRUCT:
	  if (size >= CTF_LSTRUCT_THRESH)
	    nlstructs++;

	  if (!isroot)
	    break;

	  err = ctf_dynhash_insert_type (fp, fp->ctf_structs,
					 LCTF_INDEX_TO_TYPE (fp, id, child),
					 tp->ctt_name);

	  if (err != 0)
	    return err;

	  break;

	case CTF_K_UNION:
	  if (size >= CTF_LSTRUCT_THRESH)
	    nlunions++;

	  if (!isroot)
	    break;

	  err = ctf_dynhash_insert_type (fp, fp->ctf_unions,
					 LCTF_INDEX_TO_TYPE (fp, id, child),
					 tp->ctt_name);

	  if (err != 0)
	    return err;
	  break;

	case CTF_K_ENUM:
	  {
	    if (!isroot)
	      break;

	    err = ctf_dynhash_insert_type (fp, fp->ctf_enums,
					   LCTF_INDEX_TO_TYPE (fp, id, child),
					   tp->ctt_name);

	    if (err != 0)
	      return err;

	    /* Remember all enums for later rescanning.  */

	    err = ctf_dynset_insert (all_enums, (void *) (ptrdiff_t)
				     LCTF_INDEX_TO_TYPE (fp, id, child));
	    if (err != 0)
	      return err;
	    break;
	  }

	case CTF_K_TYPEDEF:
	  if (!isroot)
	    break;

	  err = ctf_dynhash_insert_type (fp, fp->ctf_names,
					 LCTF_INDEX_TO_TYPE (fp, id, child),
					 tp->ctt_name);
	  if (err != 0)
	    return err;
	  break;

	case CTF_K_FORWARD:
	  {
	    ctf_dynhash_t *h = ctf_name_table (fp, tp->ctt_type);

	    if (!isroot)
	      break;

	    /* Only insert forward tags into the given hash if the type or tag
	       name is not already present.  */
	    if (ctf_dynhash_lookup_type (h, name) == 0)
	      {
		err = ctf_dynhash_insert_type (fp, h, LCTF_INDEX_TO_TYPE (fp, id, child),
					       tp->ctt_name);
		if (err != 0)
		  return err;
	      }
	    break;
	  }

	case CTF_K_POINTER:
	  /* If the type referenced by the pointer is in this CTF dict, then
	     store the index of the pointer type in fp->ctf_ptrtab[ index of
	     referenced type ].  */

	  if (LCTF_TYPE_ISCHILD (fp, tp->ctt_type) == child
	      && LCTF_TYPE_TO_INDEX (fp, tp->ctt_type) <= fp->ctf_typemax)
	    fp->ctf_ptrtab[LCTF_TYPE_TO_INDEX (fp, tp->ctt_type)] = id;
	 /*FALLTHRU*/

	case CTF_K_VOLATILE:
	case CTF_K_CONST:
	case CTF_K_RESTRICT:
	  if (!isroot)
	    break;

	  err = ctf_dynhash_insert_type (fp, fp->ctf_names,
					 LCTF_INDEX_TO_TYPE (fp, id, child),
					 tp->ctt_name);
	  if (err != 0)
	    return err;
	  break;
	default:
	  ctf_err_warn (fp, 0, ECTF_CORRUPT,
			_("init_static_types(): unhandled CTF kind: %x"), kind);
	  return ECTF_CORRUPT;
	}
      tp = (ctf_type_t *) ((uintptr_t) tp + increment + vbytes);
    }
  fp->ctf_typemax--;
  assert (fp->ctf_typemax == typemax);

  ctf_dprintf ("%lu total types processed\n", fp->ctf_typemax);

  /* In the third pass, we traverse the enums we spotted earlier and add all
     the enumeration constants therein either to the types table (if no
     type exists with that name) or to ctf_conflciting_enums (otherwise).

     Doing this in a third pass is necessary to avoid the case where an
     enum appears with a constant FOO, then later a type named FOO appears,
     too late to spot the conflict by checking the enum's constants.  */

  while ((err = ctf_dynset_next (all_enums, &i, &k)) == 0)
    {
      ctf_id_t enum_id = (uintptr_t) k;
      ctf_next_t *i_constants = NULL;
      const char *cte_name;

      while ((cte_name = ctf_enum_next (fp, enum_id, &i_constants, NULL)) != NULL)
	{
	  /* Add all the enumeration constants as identifiers.  They all appear
	     as types that cite the original enum.

	     Constants that appear in more than one enum, or which are already
	     the names of types, appear in ctf_conflicting_enums as well.  */

	  if (ctf_dynhash_lookup_type (fp->ctf_names, cte_name) == 0)
	    {
	      uint32_t name = ctf_str_add (fp, cte_name);

	      if (name == 0)
		goto enum_err;

	      err = ctf_dynhash_insert_type (fp, fp->ctf_names, enum_id, name);
	    }
	  else
	    {
	      err = ctf_dynset_insert (fp->ctf_conflicting_enums, (void *)
				       cte_name);

	      if (err != 0)
		goto enum_err;
	    }
	  continue;

	enum_err:
	  ctf_next_destroy (i_constants);
	  ctf_next_destroy (i);
	  return ctf_errno (fp);
	}
      if (ctf_errno (fp) != ECTF_NEXT_END)
	{
	  ctf_next_destroy (i);
	  return ctf_errno (fp);
	}
    }
  if (err != ECTF_NEXT_END)
    return err;

  ctf_dprintf ("%zu enum names hashed\n",
	       ctf_dynhash_elements (fp->ctf_enums));
  ctf_dprintf ("%zu conflicting enumerators identified\n",
	       ctf_dynset_elements (fp->ctf_conflicting_enums));
  ctf_dprintf ("%zu struct names hashed (%d long)\n",
	       ctf_dynhash_elements (fp->ctf_structs), nlstructs);
  ctf_dprintf ("%zu union names hashed (%d long)\n",
	       ctf_dynhash_elements (fp->ctf_unions), nlunions);
  ctf_dprintf ("%zu base type names and identifiers hashed\n",
	       ctf_dynhash_elements (fp->ctf_names));

  return 0;
}

/* Endianness-flipping routines.

   We flip everything, mindlessly, even 1-byte entities, so that future
   expansions do not require changes to this code.  */

/* Flip the endianness of the CTF header.  */

void
ctf_flip_header (ctf_header_t *cth)
{
  swap_thing (cth->cth_preamble.ctp_magic);
  swap_thing (cth->cth_preamble.ctp_version);
  swap_thing (cth->cth_preamble.ctp_flags);
  swap_thing (cth->cth_parlabel);
  swap_thing (cth->cth_parname);
  swap_thing (cth->cth_cuname);
  swap_thing (cth->cth_objtoff);
  swap_thing (cth->cth_funcoff);
  swap_thing (cth->cth_objtidxoff);
  swap_thing (cth->cth_funcidxoff);
  swap_thing (cth->cth_varoff);
  swap_thing (cth->cth_typeoff);
  swap_thing (cth->cth_stroff);
  swap_thing (cth->cth_strlen);
}

/* Flip the endianness of the label section, an array of ctf_lblent_t.  */

static void
flip_lbls (void *start, size_t len)
{
  ctf_lblent_t *lbl = start;
  ssize_t i;

  for (i = len / sizeof (struct ctf_lblent); i > 0; lbl++, i--)
    {
      swap_thing (lbl->ctl_label);
      swap_thing (lbl->ctl_type);
    }
}

/* Flip the endianness of the data-object or function sections or their indexes,
   all arrays of uint32_t.  */

static void
flip_objts (void *start, size_t len)
{
  uint32_t *obj = start;
  ssize_t i;

  for (i = len / sizeof (uint32_t); i > 0; obj++, i--)
      swap_thing (*obj);
}

/* Flip the endianness of the variable section, an array of ctf_varent_t.  */

static void
flip_vars (void *start, size_t len)
{
  ctf_varent_t *var = start;
  ssize_t i;

  for (i = len / sizeof (struct ctf_varent); i > 0; var++, i--)
    {
      swap_thing (var->ctv_name);
      swap_thing (var->ctv_type);
    }
}

/* Flip the endianness of the type section, a tagged array of ctf_type or
   ctf_stype followed by variable data.  */

static int
flip_types (ctf_dict_t *fp, void *start, size_t len, int to_foreign)
{
  ctf_type_t *t = start;

  while ((uintptr_t) t < ((uintptr_t) start) + len)
    {
      uint32_t kind;
      size_t size;
      uint32_t vlen;
      size_t vbytes;

      if (to_foreign)
	{
	  kind = CTF_V2_INFO_KIND (t->ctt_info);
	  size = t->ctt_size;
	  vlen = CTF_V2_INFO_VLEN (t->ctt_info);
	  vbytes = get_vbytes_v2 (fp, kind, size, vlen);
	}

      swap_thing (t->ctt_name);
      swap_thing (t->ctt_info);
      swap_thing (t->ctt_size);

      if (!to_foreign)
	{
	  kind = CTF_V2_INFO_KIND (t->ctt_info);
	  size = t->ctt_size;
	  vlen = CTF_V2_INFO_VLEN (t->ctt_info);
	  vbytes = get_vbytes_v2 (fp, kind, size, vlen);
	}

      if (_libctf_unlikely_ (size == CTF_LSIZE_SENT))
	{
	  if (to_foreign)
	    size = CTF_TYPE_LSIZE (t);

	  swap_thing (t->ctt_lsizehi);
	  swap_thing (t->ctt_lsizelo);

	  if (!to_foreign)
	    size = CTF_TYPE_LSIZE (t);

	  t = (ctf_type_t *) ((uintptr_t) t + sizeof (ctf_type_t));
	}
      else
	t = (ctf_type_t *) ((uintptr_t) t + sizeof (ctf_stype_t));

      switch (kind)
	{
	case CTF_K_FORWARD:
	case CTF_K_UNKNOWN:
	case CTF_K_POINTER:
	case CTF_K_TYPEDEF:
	case CTF_K_VOLATILE:
	case CTF_K_CONST:
	case CTF_K_RESTRICT:
	  /* These types have no vlen data to swap.  */
	  assert (vbytes == 0);
	  break;

	case CTF_K_INTEGER:
	case CTF_K_FLOAT:
	  {
	    /* These types have a single uint32_t.  */

	    uint32_t *item = (uint32_t *) t;

	    swap_thing (*item);
	    break;
	  }

	case CTF_K_FUNCTION:
	  {
	    /* This type has a bunch of uint32_ts.  */

	    uint32_t *item = (uint32_t *) t;
	    ssize_t i;

	    for (i = vlen; i > 0; item++, i--)
	      swap_thing (*item);
	    break;
	  }

	case CTF_K_ARRAY:
	  {
	    /* This has a single ctf_array_t.  */

	    ctf_array_t *a = (ctf_array_t *) t;

	    assert (vbytes == sizeof (ctf_array_t));
	    swap_thing (a->cta_contents);
	    swap_thing (a->cta_index);
	    swap_thing (a->cta_nelems);

	    break;
	  }

	case CTF_K_SLICE:
	  {
	    /* This has a single ctf_slice_t.  */

	    ctf_slice_t *s = (ctf_slice_t *) t;

	    assert (vbytes == sizeof (ctf_slice_t));
	    swap_thing (s->cts_type);
	    swap_thing (s->cts_offset);
	    swap_thing (s->cts_bits);

	    break;
	  }

	case CTF_K_STRUCT:
	case CTF_K_UNION:
	  {
	    /* This has an array of ctf_member or ctf_lmember, depending on
	       size.  We could consider it to be a simple array of uint32_t,
	       but for safety's sake in case these structures ever acquire
	       non-uint32_t members, do it member by member.  */

	    if (_libctf_unlikely_ (size >= CTF_LSTRUCT_THRESH))
	      {
		ctf_lmember_t *lm = (ctf_lmember_t *) t;
		ssize_t i;
		for (i = vlen; i > 0; i--, lm++)
		  {
		    swap_thing (lm->ctlm_name);
		    swap_thing (lm->ctlm_offsethi);
		    swap_thing (lm->ctlm_type);
		    swap_thing (lm->ctlm_offsetlo);
		  }
	      }
	    else
	      {
		ctf_member_t *m = (ctf_member_t *) t;
		ssize_t i;
		for (i = vlen; i > 0; i--, m++)
		  {
		    swap_thing (m->ctm_name);
		    swap_thing (m->ctm_offset);
		    swap_thing (m->ctm_type);
		  }
	      }
	    break;
	  }

	case CTF_K_ENUM:
	  {
	    /* This has an array of ctf_enum_t.  */

	    ctf_enum_t *item = (ctf_enum_t *) t;
	    ssize_t i;

	    for (i = vlen; i > 0; item++, i--)
	      {
		swap_thing (item->cte_name);
		swap_thing (item->cte_value);
	      }
	    break;
	  }
	default:
	  ctf_err_warn (fp, 0, ECTF_CORRUPT,
			_("unhandled CTF kind in endianness conversion: %x"),
			kind);
	  return ECTF_CORRUPT;
	}

      t = (ctf_type_t *) ((uintptr_t) t + vbytes);
    }

  return 0;
}

/* Flip the endianness of BUF, given the offsets in the (native-endianness) CTH.
   If TO_FOREIGN is set, flip to foreign-endianness; if not, flip away.

   All of this stuff happens before the header is fully initialized, so the
   LCTF_*() macros cannot be used yet.  Since we do not try to endian-convert v1
   data, this is no real loss.  */

int
ctf_flip (ctf_dict_t *fp, ctf_header_t *cth, unsigned char *buf,
	  int to_foreign)
{
  ctf_dprintf("flipping endianness\n");

  flip_lbls (buf + cth->cth_lbloff, cth->cth_objtoff - cth->cth_lbloff);
  flip_objts (buf + cth->cth_objtoff, cth->cth_funcoff - cth->cth_objtoff);
  flip_objts (buf + cth->cth_funcoff, cth->cth_objtidxoff - cth->cth_funcoff);
  flip_objts (buf + cth->cth_objtidxoff, cth->cth_funcidxoff - cth->cth_objtidxoff);
  flip_objts (buf + cth->cth_funcidxoff, cth->cth_varoff - cth->cth_funcidxoff);
  flip_vars (buf + cth->cth_varoff, cth->cth_typeoff - cth->cth_varoff);
  return flip_types (fp, buf + cth->cth_typeoff,
		     cth->cth_stroff - cth->cth_typeoff, to_foreign);
}

/* Set up the ctl hashes in a ctf_dict_t.  Called by both writable and
   non-writable dictionary initialization.  */
void ctf_set_ctl_hashes (ctf_dict_t *fp)
{
  /* Initialize the ctf_lookup_by_name top-level dictionary.  We keep an
     array of type name prefixes and the corresponding ctf_hash to use.  */
  fp->ctf_lookups[0].ctl_prefix = "struct";
  fp->ctf_lookups[0].ctl_len = strlen (fp->ctf_lookups[0].ctl_prefix);
  fp->ctf_lookups[0].ctl_hash = fp->ctf_structs;
  fp->ctf_lookups[1].ctl_prefix = "union";
  fp->ctf_lookups[1].ctl_len = strlen (fp->ctf_lookups[1].ctl_prefix);
  fp->ctf_lookups[1].ctl_hash = fp->ctf_unions;
  fp->ctf_lookups[2].ctl_prefix = "enum";
  fp->ctf_lookups[2].ctl_len = strlen (fp->ctf_lookups[2].ctl_prefix);
  fp->ctf_lookups[2].ctl_hash = fp->ctf_enums;
  fp->ctf_lookups[3].ctl_prefix = _CTF_NULLSTR;
  fp->ctf_lookups[3].ctl_len = strlen (fp->ctf_lookups[3].ctl_prefix);
  fp->ctf_lookups[3].ctl_hash = fp->ctf_names;
  fp->ctf_lookups[4].ctl_prefix = NULL;
  fp->ctf_lookups[4].ctl_len = 0;
  fp->ctf_lookups[4].ctl_hash = NULL;
}

/* Open a CTF file, mocking up a suitable ctf_sect.  */

ctf_dict_t *ctf_simple_open (const char *ctfsect, size_t ctfsect_size,
			     const char *symsect, size_t symsect_size,
			     size_t symsect_entsize,
			     const char *strsect, size_t strsect_size,
			     int *errp)
{
  ctf_sect_t skeleton;

  ctf_sect_t ctf_sect, sym_sect, str_sect;
  ctf_sect_t *ctfsectp = NULL;
  ctf_sect_t *symsectp = NULL;
  ctf_sect_t *strsectp = NULL;

  skeleton.cts_name = _CTF_SECTION;
  skeleton.cts_entsize = 1;

  if (ctfsect)
    {
      memcpy (&ctf_sect, &skeleton, sizeof (struct ctf_sect));
      ctf_sect.cts_data = ctfsect;
      ctf_sect.cts_size = ctfsect_size;
      ctfsectp = &ctf_sect;
    }

  if (symsect)
    {
      memcpy (&sym_sect, &skeleton, sizeof (struct ctf_sect));
      sym_sect.cts_data = symsect;
      sym_sect.cts_size = symsect_size;
      sym_sect.cts_entsize = symsect_entsize;
      symsectp = &sym_sect;
    }

  if (strsect)
    {
      memcpy (&str_sect, &skeleton, sizeof (struct ctf_sect));
      str_sect.cts_data = strsect;
      str_sect.cts_size = strsect_size;
      strsectp = &str_sect;
    }

  return ctf_bufopen (ctfsectp, symsectp, strsectp, errp);
}

/* Decode the specified CTF buffer and optional symbol table, and create a new
   CTF dict representing the symbolic debugging information.  This code can
   be used directly by the debugger, or it can be used as the engine for
   ctf_fdopen() or ctf_open(), below.  */

ctf_dict_t *
ctf_bufopen (const ctf_sect_t *ctfsect, const ctf_sect_t *symsect,
	     const ctf_sect_t *strsect, int *errp)
{
  const ctf_preamble_t *pp;
  size_t hdrsz = sizeof (ctf_header_t);
  ctf_header_t *hp;
  ctf_dict_t *fp;
  int foreign_endian = 0;
  int err;

  libctf_init_debug();

  if ((ctfsect == NULL) || ((symsect != NULL) && (strsect == NULL)))
    return (ctf_set_open_errno (errp, EINVAL));

  if (symsect != NULL && symsect->cts_entsize != sizeof (Elf32_Sym) &&
      symsect->cts_entsize != sizeof (Elf64_Sym))
    return (ctf_set_open_errno (errp, ECTF_SYMTAB));

  if (symsect != NULL && symsect->cts_data == NULL)
    return (ctf_set_open_errno (errp, ECTF_SYMBAD));

  if (strsect != NULL && strsect->cts_data == NULL)
    return (ctf_set_open_errno (errp, ECTF_STRBAD));

  if (ctfsect->cts_data == NULL
      || ctfsect->cts_size < sizeof (ctf_preamble_t))
    return (ctf_set_open_errno (errp, ECTF_NOCTFBUF));

  pp = (const ctf_preamble_t *) ctfsect->cts_data;

  ctf_dprintf ("ctf_bufopen: magic=0x%x version=%u\n",
	       pp->ctp_magic, pp->ctp_version);

  /* Validate each part of the CTF header.

     First, we validate the preamble (common to all versions).  At that point,
     we know the endianness and specific header version, and can validate the
     version-specific parts including section offsets and alignments.

     We specifically do not support foreign-endian old versions.  */

  if (_libctf_unlikely_ (pp->ctp_magic != CTF_MAGIC))
    {
      if (pp->ctp_magic == bswap_16 (CTF_MAGIC))
	{
	  if (pp->ctp_version != CTF_VERSION_3)
	    return (ctf_set_open_errno (errp, ECTF_CTFVERS));
	  foreign_endian = 1;
	}
      else
	return (ctf_set_open_errno (errp, ECTF_NOCTFBUF));
    }

  if (_libctf_unlikely_ ((pp->ctp_version < CTF_VERSION_1)
			 || (pp->ctp_version > CTF_VERSION_3)))
    return (ctf_set_open_errno (errp, ECTF_CTFVERS));

  if ((symsect != NULL) && (pp->ctp_version < CTF_VERSION_2))
    {
      /* The symtab can contain function entries which contain embedded ctf
	 info.  We do not support dynamically upgrading such entries (none
	 should exist in any case, since dwarf2ctf does not create them).  */

      ctf_err_warn (NULL, 0, ECTF_NOTSUP, _("ctf_bufopen: CTF version %d "
					    "symsect not supported"),
		    pp->ctp_version);
      return (ctf_set_open_errno (errp, ECTF_NOTSUP));
    }

  if (pp->ctp_version < CTF_VERSION_3)
    hdrsz = sizeof (ctf_header_v2_t);

  if (_libctf_unlikely_ (pp->ctp_flags > CTF_F_MAX))
    {
      ctf_err_warn (NULL, 0, ECTF_FLAGS, _("ctf_bufopen: invalid header "
					   "flags: %x"),
		    (unsigned int) pp->ctp_flags);
      return (ctf_set_open_errno (errp, ECTF_FLAGS));
    }

  if (ctfsect->cts_size < hdrsz)
    return (ctf_set_open_errno (errp, ECTF_NOCTFBUF));

  if ((fp = malloc (sizeof (ctf_dict_t))) == NULL)
    return (ctf_set_open_errno (errp, ENOMEM));

  memset (fp, 0, sizeof (ctf_dict_t));

  if ((fp->ctf_header = malloc (sizeof (struct ctf_header))) == NULL)
    {
      free (fp);
      return (ctf_set_open_errno (errp, ENOMEM));
    }
  hp = fp->ctf_header;
  memcpy (hp, ctfsect->cts_data, hdrsz);
  if (pp->ctp_version < CTF_VERSION_3)
    upgrade_header (hp);

  if (foreign_endian)
    ctf_flip_header (hp);
  fp->ctf_openflags = hp->cth_flags;
  fp->ctf_size = hp->cth_stroff + hp->cth_strlen;

  ctf_dprintf ("ctf_bufopen: uncompressed size=%lu\n",
	       (unsigned long) fp->ctf_size);

  if (hp->cth_lbloff > fp->ctf_size || hp->cth_objtoff > fp->ctf_size
      || hp->cth_funcoff > fp->ctf_size || hp->cth_objtidxoff > fp->ctf_size
      || hp->cth_funcidxoff > fp->ctf_size || hp->cth_typeoff > fp->ctf_size
      || hp->cth_stroff > fp->ctf_size)
    {
      ctf_err_warn (NULL, 0, ECTF_CORRUPT, _("header offset exceeds CTF size"));
      return (ctf_set_open_errno (errp, ECTF_CORRUPT));
    }

  if (hp->cth_lbloff > hp->cth_objtoff
      || hp->cth_objtoff > hp->cth_funcoff
      || hp->cth_funcoff > hp->cth_typeoff
      || hp->cth_funcoff > hp->cth_objtidxoff
      || hp->cth_objtidxoff > hp->cth_funcidxoff
      || hp->cth_funcidxoff > hp->cth_varoff
      || hp->cth_varoff > hp->cth_typeoff || hp->cth_typeoff > hp->cth_stroff)
    {
      ctf_err_warn (NULL, 0, ECTF_CORRUPT, _("overlapping CTF sections"));
      return (ctf_set_open_errno (errp, ECTF_CORRUPT));
    }

  if ((hp->cth_lbloff & 3) || (hp->cth_objtoff & 2)
      || (hp->cth_funcoff & 2) || (hp->cth_objtidxoff & 2)
      || (hp->cth_funcidxoff & 2) || (hp->cth_varoff & 3)
      || (hp->cth_typeoff & 3))
    {
      ctf_err_warn (NULL, 0, ECTF_CORRUPT,
		    _("CTF sections not properly aligned"));
      return (ctf_set_open_errno (errp, ECTF_CORRUPT));
    }

  /* This invariant will be lifted in v4, but for now it is true.  */

  if ((hp->cth_funcidxoff - hp->cth_objtidxoff != 0) &&
      (hp->cth_funcidxoff - hp->cth_objtidxoff
       != hp->cth_funcoff - hp->cth_objtoff))
    {
      ctf_err_warn (NULL, 0, ECTF_CORRUPT,
		    _("Object index section is neither empty nor the "
		      "same length as the object section: %u versus %u "
		      "bytes"), hp->cth_funcoff - hp->cth_objtoff,
		    hp->cth_funcidxoff - hp->cth_objtidxoff);
      return (ctf_set_open_errno (errp, ECTF_CORRUPT));
    }

  if ((hp->cth_varoff - hp->cth_funcidxoff != 0) &&
      (hp->cth_varoff - hp->cth_funcidxoff
       != hp->cth_objtidxoff - hp->cth_funcoff) &&
      (hp->cth_flags & CTF_F_NEWFUNCINFO))
    {
      ctf_err_warn (NULL, 0, ECTF_CORRUPT,
		    _("Function index section is neither empty nor the "
		      "same length as the function section: %u versus %u "
		      "bytes"), hp->cth_objtidxoff - hp->cth_funcoff,
		    hp->cth_varoff - hp->cth_funcidxoff);
      return (ctf_set_open_errno (errp, ECTF_CORRUPT));
    }

  /* Once everything is determined to be valid, attempt to decompress the CTF
     data buffer if it is compressed, or copy it into new storage if it is not
     compressed but needs endian-flipping.  Otherwise we just put the data
     section's buffer pointer into ctf_buf, below.  */

  /* Note: if this is a v1 buffer, it will be reallocated and expanded by
     init_static_types().  */

  if (hp->cth_flags & CTF_F_COMPRESS)
    {
      size_t srclen;
      uLongf dstlen;
      const void *src;
      int rc = Z_OK;

      /* We are allocating this ourselves, so we can drop the ctf header
	 copy in favour of ctf->ctf_header.  */

      if ((fp->ctf_base = malloc (fp->ctf_size)) == NULL)
	{
	  err = ECTF_ZALLOC;
	  goto bad;
	}
      fp->ctf_dynbase = fp->ctf_base;
      hp->cth_flags &= ~CTF_F_COMPRESS;

      src = (unsigned char *) ctfsect->cts_data + hdrsz;
      srclen = ctfsect->cts_size - hdrsz;
      dstlen = fp->ctf_size;
      fp->ctf_buf = fp->ctf_base;

      if ((rc = uncompress (fp->ctf_base, &dstlen, src, srclen)) != Z_OK)
	{
	  ctf_err_warn (NULL, 0, ECTF_DECOMPRESS, _("zlib inflate err: %s"),
			zError (rc));
	  err = ECTF_DECOMPRESS;
	  goto bad;
	}

      if ((size_t) dstlen != fp->ctf_size)
	{
	  ctf_err_warn (NULL, 0, ECTF_CORRUPT,
			_("zlib inflate short: got %lu of %lu bytes"),
			(unsigned long) dstlen, (unsigned long) fp->ctf_size);
	  err = ECTF_CORRUPT;
	  goto bad;
	}
    }
  else
    {
      if (_libctf_unlikely_ (ctfsect->cts_size < hdrsz + fp->ctf_size))
	{
	  ctf_err_warn (NULL, 0, ECTF_CORRUPT,
			_("%lu byte long CTF dictionary overruns %lu byte long CTF section"),
			(unsigned long) ctfsect->cts_size,
			(unsigned long) (hdrsz + fp->ctf_size));
	  err = ECTF_CORRUPT;
	  goto bad;
	}

      if (foreign_endian)
	{
	  if ((fp->ctf_base = malloc (fp->ctf_size)) == NULL)
	    {
	      err = ECTF_ZALLOC;
	      goto bad;
	    }
	  fp->ctf_dynbase = fp->ctf_base;
	  memcpy (fp->ctf_base, ((unsigned char *) ctfsect->cts_data) + hdrsz,
		  fp->ctf_size);
	  fp->ctf_buf = fp->ctf_base;
	}
      else
	{
	  /* We are just using the section passed in -- but its header may
	     be an old version.  Point ctf_buf past the old header, and
	     never touch it again.  */
	  fp->ctf_base = (unsigned char *) ctfsect->cts_data;
	  fp->ctf_dynbase = NULL;
	  fp->ctf_buf = fp->ctf_base + hdrsz;
	}
    }

  /* Once we have uncompressed and validated the CTF data buffer, we can
     proceed with initializing the ctf_dict_t we allocated above.

     Nothing that depends on buf or base should be set directly in this function
     before the init_static_types() call, because it may be reallocated during
     transparent upgrade if this recension of libctf is so configured: see
     ctf_set_base().  */

  ctf_set_version (fp, hp, hp->cth_version);

  /* Temporary assignment, just enough to be able to initialize
     the atoms table.  */

  fp->ctf_str[CTF_STRTAB_0].cts_strs = (const char *) fp->ctf_buf
    + hp->cth_stroff;
  fp->ctf_str[CTF_STRTAB_0].cts_len = hp->cth_strlen;
  if (ctf_str_create_atoms (fp) < 0)
    {
      err = ENOMEM;
      goto bad;
    }

  fp->ctf_parmax = CTF_MAX_PTYPE;
  memcpy (&fp->ctf_data, ctfsect, sizeof (ctf_sect_t));

  if (symsect != NULL)
    {
      memcpy (&fp->ctf_ext_symtab, symsect, sizeof (ctf_sect_t));
      memcpy (&fp->ctf_ext_strtab, strsect, sizeof (ctf_sect_t));
    }

  if (fp->ctf_data.cts_name != NULL)
    if ((fp->ctf_data.cts_name = strdup (fp->ctf_data.cts_name)) == NULL)
      {
	err = ENOMEM;
	goto bad;
      }
  if (fp->ctf_ext_symtab.cts_name != NULL)
    if ((fp->ctf_ext_symtab.cts_name = strdup (fp->ctf_ext_symtab.cts_name)) == NULL)
      {
	err = ENOMEM;
	goto bad;
      }
  if (fp->ctf_ext_strtab.cts_name != NULL)
    if ((fp->ctf_ext_strtab.cts_name = strdup (fp->ctf_ext_strtab.cts_name)) == NULL)
      {
	err = ENOMEM;
	goto bad;
      }

  if (fp->ctf_data.cts_name == NULL)
    fp->ctf_data.cts_name = _CTF_NULLSTR;
  if (fp->ctf_ext_symtab.cts_name == NULL)
    fp->ctf_ext_symtab.cts_name = _CTF_NULLSTR;
  if (fp->ctf_ext_strtab.cts_name == NULL)
    fp->ctf_ext_strtab.cts_name = _CTF_NULLSTR;

  if (strsect != NULL)
    {
      fp->ctf_str[CTF_STRTAB_1].cts_strs = strsect->cts_data;
      fp->ctf_str[CTF_STRTAB_1].cts_len = strsect->cts_size;
    }

  /* Dynamic state, for dynamic addition to this dict after loading.  */

  fp->ctf_dthash = ctf_dynhash_create (ctf_hash_integer, ctf_hash_eq_integer,
				       NULL, NULL);
  fp->ctf_dvhash = ctf_dynhash_create (ctf_hash_string, ctf_hash_eq_string,
				       NULL, NULL);
  fp->ctf_snapshots = 1;

  fp->ctf_objthash = ctf_dynhash_create (ctf_hash_string, ctf_hash_eq_string,
					   free, NULL);
  fp->ctf_funchash = ctf_dynhash_create (ctf_hash_string, ctf_hash_eq_string,
					 free, NULL);

  if (!fp->ctf_dthash || !fp->ctf_dvhash || !fp->ctf_snapshots ||
      !fp->ctf_objthash || !fp->ctf_funchash)
    {
      err = ENOMEM;
      goto bad;
    }

  if (foreign_endian &&
      (err = ctf_flip (fp, hp, fp->ctf_buf, 0)) != 0)
    {
      /* We can be certain that ctf_flip() will have endian-flipped everything
	 other than the types table when we return.  In particular the header
	 is fine, so set it, to allow freeing to use the usual code path.  */

      ctf_set_base (fp, hp, fp->ctf_base);
      goto bad;
    }

  ctf_set_base (fp, hp, fp->ctf_base);

  if ((err = init_static_types (fp, hp)) != 0)
    goto bad;

  /* Allocate and initialize the symtab translation table, pointed to by
     ctf_sxlate, and the corresponding index sections.  This table may be too
     large for the actual size of the object and function info sections: if so,
     ctf_nsyms will be adjusted and the excess will never be used.  It's
     possible to do indexed symbol lookups even without a symbol table, so check
     even in that case.  Initially, we assume the symtab is native-endian: if it
     isn't, the caller will inform us later by calling ctf_symsect_endianness.  */
#ifdef WORDS_BIGENDIAN
  fp->ctf_symsect_little_endian = 0;
#else
  fp->ctf_symsect_little_endian = 1;
#endif

  if (symsect != NULL)
    {
      fp->ctf_nsyms = symsect->cts_size / symsect->cts_entsize;
      fp->ctf_sxlate = malloc (fp->ctf_nsyms * sizeof (uint32_t));

      if (fp->ctf_sxlate == NULL)
	{
	  err = ENOMEM;
	  goto bad;
	}
    }

  if ((err = init_symtab (fp, hp, symsect)) != 0)
    goto bad;

  ctf_set_ctl_hashes (fp);

  if (symsect != NULL)
    {
      if (symsect->cts_entsize == sizeof (Elf64_Sym))
	(void) ctf_setmodel (fp, CTF_MODEL_LP64);
      else
	(void) ctf_setmodel (fp, CTF_MODEL_ILP32);
    }
  else
    (void) ctf_setmodel (fp, CTF_MODEL_NATIVE);

  fp->ctf_refcnt = 1;
  return fp;

bad:
  ctf_set_open_errno (errp, err);
  ctf_err_warn_to_open (fp);
  /* Without this, the refcnt is zero on entry and ctf_dict_close() won't
     actually do anything on the grounds that this is a recursive call via
     another dict being closed.  */
  fp->ctf_refcnt = 1;
  ctf_dict_close (fp);
  return NULL;
}

/* Bump the refcount on the specified CTF dict, to allow export of ctf_dict_t's
   from iterators that open and close the ctf_dict_t around the loop.  (This
   does not extend their lifetime beyond that of the ctf_archive_t in which they
   are contained.)  */

void
ctf_ref (ctf_dict_t *fp)
{
  fp->ctf_refcnt++;
}

/* Close the specified CTF dict and free associated data structures.  Note that
   ctf_dict_close() is a reference counted operation: if the specified file is
   the parent of other active dict, its reference count will be greater than one
   and it will be freed later when no active children exist.  */

void
ctf_dict_close (ctf_dict_t *fp)
{
  ctf_dtdef_t *dtd, *ntd;
  ctf_dvdef_t *dvd, *nvd;
  ctf_in_flight_dynsym_t *did, *nid;
  ctf_err_warning_t *err, *nerr;

  if (fp == NULL)
    return;		   /* Allow ctf_dict_close(NULL) to simplify caller code.  */

  ctf_dprintf ("ctf_dict_close(%p) refcnt=%u\n", (void *) fp, fp->ctf_refcnt);

  if (fp->ctf_refcnt > 1)
    {
      fp->ctf_refcnt--;
      return;
    }

  /* It is possible to recurse back in here, notably if dicts in the
     ctf_link_inputs or ctf_link_outputs cite this dict as a parent without
     using ctf_import_unref.  Do nothing in that case.  */
  if (fp->ctf_refcnt == 0)
    return;

  fp->ctf_refcnt--;
  free (fp->ctf_dyncuname);
  free (fp->ctf_dynparname);
  if (fp->ctf_parent && !fp->ctf_parent_unreffed)
    ctf_dict_close (fp->ctf_parent);

  for (dtd = ctf_list_next (&fp->ctf_dtdefs); dtd != NULL; dtd = ntd)
    {
      ntd = ctf_list_next (dtd);
      ctf_dtd_delete (fp, dtd);
    }
  ctf_dynhash_destroy (fp->ctf_dthash);

  ctf_dynset_destroy (fp->ctf_conflicting_enums);
  ctf_dynhash_destroy (fp->ctf_structs);
  ctf_dynhash_destroy (fp->ctf_unions);
  ctf_dynhash_destroy (fp->ctf_enums);
  ctf_dynhash_destroy (fp->ctf_names);

  for (dvd = ctf_list_next (&fp->ctf_dvdefs); dvd != NULL; dvd = nvd)
    {
      nvd = ctf_list_next (dvd);
      ctf_dvd_delete (fp, dvd);
    }
  ctf_dynhash_destroy (fp->ctf_dvhash);

  ctf_dynhash_destroy (fp->ctf_symhash_func);
  ctf_dynhash_destroy (fp->ctf_symhash_objt);
  free (fp->ctf_funcidx_sxlate);
  free (fp->ctf_objtidx_sxlate);
  ctf_dynhash_destroy (fp->ctf_objthash);
  ctf_dynhash_destroy (fp->ctf_funchash);
  free (fp->ctf_dynsymidx);
  ctf_dynhash_destroy (fp->ctf_dynsyms);
  for (did = ctf_list_next (&fp->ctf_in_flight_dynsyms); did != NULL; did = nid)
    {
      nid = ctf_list_next (did);
      ctf_list_delete (&fp->ctf_in_flight_dynsyms, did);
      free (did);
    }

  ctf_str_free_atoms (fp);
  free (fp->ctf_tmp_typeslice);

  if (fp->ctf_data.cts_name != _CTF_NULLSTR)
    free ((char *) fp->ctf_data.cts_name);

  if (fp->ctf_ext_symtab.cts_name != _CTF_NULLSTR)
    free ((char *) fp->ctf_ext_symtab.cts_name);

  if (fp->ctf_ext_strtab.cts_name != _CTF_NULLSTR)
    free ((char *) fp->ctf_ext_strtab.cts_name);
  else if (fp->ctf_data_mmapped)
    ctf_munmap (fp->ctf_data_mmapped, fp->ctf_data_mmapped_len);

  free (fp->ctf_dynbase);

  ctf_dynhash_destroy (fp->ctf_syn_ext_strtab);
  ctf_dynhash_destroy (fp->ctf_link_inputs);
  ctf_dynhash_destroy (fp->ctf_link_outputs);
  ctf_dynhash_destroy (fp->ctf_link_type_mapping);
  ctf_dynhash_destroy (fp->ctf_link_in_cu_mapping);
  ctf_dynhash_destroy (fp->ctf_link_out_cu_mapping);
  ctf_dynhash_destroy (fp->ctf_add_processing);
  ctf_dedup_fini (fp, NULL, 0);
  ctf_dynset_destroy (fp->ctf_dedup_atoms_alloc);

  for (err = ctf_list_next (&fp->ctf_errs_warnings); err != NULL; err = nerr)
    {
      nerr = ctf_list_next (err);
      ctf_list_delete (&fp->ctf_errs_warnings, err);
      free (err->cew_text);
      free (err);
    }

  free (fp->ctf_sxlate);
  free (fp->ctf_txlate);
  free (fp->ctf_ptrtab);
  free (fp->ctf_pptrtab);

  free (fp->ctf_header);
  free (fp);
}

/* Backward compatibility.  */
void
ctf_file_close (ctf_file_t *fp)
{
  ctf_dict_close (fp);
}

/* The converse of ctf_open().  ctf_open() disguises whatever it opens as an
   archive, so closing one is just like closing an archive.  */
void
ctf_close (ctf_archive_t *arc)
{
  ctf_arc_close (arc);
}

/* Get the CTF archive from which this ctf_dict_t is derived.  */
ctf_archive_t *
ctf_get_arc (const ctf_dict_t *fp)
{
  return fp->ctf_archive;
}

/* Return the ctfsect out of the core ctf_impl.  Useful for freeing the
   ctfsect's data * after ctf_dict_close(), which is why we return the actual
   structure, not a pointer to it, since that is likely to become a pointer to
   freed data before the return value is used under the expected use case of
   ctf_getsect()/ ctf_dict_close()/free().  */
ctf_sect_t
ctf_getdatasect (const ctf_dict_t *fp)
{
  return fp->ctf_data;
}

ctf_sect_t
ctf_getsymsect (const ctf_dict_t *fp)
{
  return fp->ctf_ext_symtab;
}

ctf_sect_t
ctf_getstrsect (const ctf_dict_t *fp)
{
  return fp->ctf_ext_strtab;
}

/* Set the endianness of the symbol table attached to FP.  */
void
ctf_symsect_endianness (ctf_dict_t *fp, int little_endian)
{
  int old_endianness = fp->ctf_symsect_little_endian;

  fp->ctf_symsect_little_endian = !!little_endian;

  /* If we already have a symtab translation table, we need to repopulate it if
     our idea of the endianness has changed.  */

  if (old_endianness != fp->ctf_symsect_little_endian
      && fp->ctf_sxlate != NULL && fp->ctf_ext_symtab.cts_data != NULL)
    assert (init_symtab (fp, fp->ctf_header, &fp->ctf_ext_symtab) == 0);
}

/* Return the CTF handle for the parent CTF dict, if one exists.  Otherwise
   return NULL to indicate this dict has no imported parent.  */
ctf_dict_t *
ctf_parent_dict (ctf_dict_t *fp)
{
  return fp->ctf_parent;
}

/* Backward compatibility.  */
ctf_dict_t *
ctf_parent_file (ctf_dict_t *fp)
{
  return ctf_parent_dict (fp);
}

/* Return the name of the parent CTF dict, if one exists, or NULL otherwise.  */
const char *
ctf_parent_name (ctf_dict_t *fp)
{
  return fp->ctf_parname;
}

/* Set the parent name.  It is an error to call this routine without calling
   ctf_import() at some point.  */
int
ctf_parent_name_set (ctf_dict_t *fp, const char *name)
{
  if (fp->ctf_dynparname != NULL)
    free (fp->ctf_dynparname);

  if ((fp->ctf_dynparname = strdup (name)) == NULL)
    return (ctf_set_errno (fp, ENOMEM));
  fp->ctf_parname = fp->ctf_dynparname;
  return 0;
}

/* Return the name of the compilation unit this CTF file applies to.  Usually
   non-NULL only for non-parent dicts.  */
const char *
ctf_cuname (ctf_dict_t *fp)
{
  return fp->ctf_cuname;
}

/* Set the compilation unit name.  */
int
ctf_cuname_set (ctf_dict_t *fp, const char *name)
{
  if (fp->ctf_dyncuname != NULL)
    free (fp->ctf_dyncuname);

  if ((fp->ctf_dyncuname = strdup (name)) == NULL)
    return (ctf_set_errno (fp, ENOMEM));
  fp->ctf_cuname = fp->ctf_dyncuname;
  return 0;
}

/* Import the types from the specified parent dict by storing a pointer to it in
   ctf_parent and incrementing its reference count.  Only one parent is allowed:
   if a parent already exists, it is replaced by the new parent.  The pptrtab
   is wiped, and will be refreshed by the next ctf_lookup_by_name call.  */
int
ctf_import (ctf_dict_t *fp, ctf_dict_t *pfp)
{
  if (fp == NULL || fp == pfp || (pfp != NULL && pfp->ctf_refcnt == 0))
    return (ctf_set_errno (fp, EINVAL));

  if (pfp != NULL && pfp->ctf_dmodel != fp->ctf_dmodel)
    return (ctf_set_errno (fp, ECTF_DMODEL));

  if (fp->ctf_parent && !fp->ctf_parent_unreffed)
    ctf_dict_close (fp->ctf_parent);
  fp->ctf_parent = NULL;

  free (fp->ctf_pptrtab);
  fp->ctf_pptrtab = NULL;
  fp->ctf_pptrtab_len = 0;
  fp->ctf_pptrtab_typemax = 0;

  if (pfp != NULL)
    {
      int err;

      if (fp->ctf_parname == NULL)
	if ((err = ctf_parent_name_set (fp, "PARENT")) < 0)
	  return err;

      fp->ctf_flags |= LCTF_CHILD;
      pfp->ctf_refcnt++;
      fp->ctf_parent_unreffed = 0;
    }

  fp->ctf_parent = pfp;
  return 0;
}

/* Like ctf_import, but does not increment the refcount on the imported parent
   or close it at any point: as a result it can go away at any time and the
   caller must do all freeing itself.  Used internally to avoid refcount
   loops.  */
int
ctf_import_unref (ctf_dict_t *fp, ctf_dict_t *pfp)
{
  if (fp == NULL || fp == pfp || (pfp != NULL && pfp->ctf_refcnt == 0))
    return (ctf_set_errno (fp, EINVAL));

  if (pfp != NULL && pfp->ctf_dmodel != fp->ctf_dmodel)
    return (ctf_set_errno (fp, ECTF_DMODEL));

  if (fp->ctf_parent && !fp->ctf_parent_unreffed)
    ctf_dict_close (fp->ctf_parent);
  fp->ctf_parent = NULL;

  free (fp->ctf_pptrtab);
  fp->ctf_pptrtab = NULL;
  fp->ctf_pptrtab_len = 0;
  fp->ctf_pptrtab_typemax = 0;
  if (pfp != NULL)
    {
      int err;

      if (fp->ctf_parname == NULL)
	if ((err = ctf_parent_name_set (fp, "PARENT")) < 0)
	  return err;

      fp->ctf_flags |= LCTF_CHILD;
      fp->ctf_parent_unreffed = 1;
    }

  fp->ctf_parent = pfp;
  return 0;
}

/* Set the data model constant for the CTF dict.  */
int
ctf_setmodel (ctf_dict_t *fp, int model)
{
  const ctf_dmodel_t *dp;

  for (dp = _libctf_models; dp->ctd_name != NULL; dp++)
    {
      if (dp->ctd_code == model)
	{
	  fp->ctf_dmodel = dp;
	  return 0;
	}
    }

  return (ctf_set_errno (fp, EINVAL));
}

/* Return the data model constant for the CTF dict.  */
int
ctf_getmodel (ctf_dict_t *fp)
{
  return fp->ctf_dmodel->ctd_code;
}

/* The caller can hang an arbitrary pointer off each ctf_dict_t using this
   function.  */
void
ctf_setspecific (ctf_dict_t *fp, void *data)
{
  fp->ctf_specific = data;
}

/* Retrieve the arbitrary pointer again.  */
void *
ctf_getspecific (ctf_dict_t *fp)
{
  return fp->ctf_specific;
}
