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

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

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

  unsigned long pop[CTF_K_MAX + 1] = { 0 };
  const ctf_type_t *tp;
  uint32_t id;
  uint32_t *xp;
  unsigned long typemax = 0;

  /* 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.  In this first
     pass, we count the number of each type 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 (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],
				   ctf_hash_string,
				   ctf_hash_eq_string, NULL, 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.

     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;
	  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);
  ctf_dprintf ("%zu enum names hashed\n",
	       ctf_dynhash_elements (fp->ctf_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 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);
  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_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;
}
