/* Type handling functions.
   Copyright (C) 2019-2021 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 <assert.h>
#include <string.h>

/* Determine whether a type is a parent or a child.  */

int
ctf_type_isparent (ctf_dict_t *fp, ctf_id_t id)
{
  return (LCTF_TYPE_ISPARENT (fp, id));
}

int
ctf_type_ischild (ctf_dict_t * fp, ctf_id_t id)
{
  return (LCTF_TYPE_ISCHILD (fp, id));
}

/* Expand a structure element into the passed-in ctf_lmember_t.  */

static int
ctf_struct_member (ctf_dict_t *fp, ctf_lmember_t *dst, const ctf_type_t *tp,
		   unsigned char *vlen, size_t vbytes, size_t n)
{
  if (!ctf_assert (fp, n < LCTF_INFO_VLEN (fp, tp->ctt_info)))
    return -1;					/* errno is set for us.  */

  /* Already large.  */
  if (tp->ctt_size == CTF_LSIZE_SENT)
    {
      ctf_lmember_t *lmp = (ctf_lmember_t *) vlen;

      if (!ctf_assert (fp, (n + 1) * sizeof (ctf_lmember_t) <= vbytes))
	return -1;				/* errno is set for us.  */

      memcpy (dst, &lmp[n], sizeof (ctf_lmember_t));
    }
  else
    {
      ctf_member_t *mp = (ctf_member_t *) vlen;
      dst->ctlm_name = mp[n].ctm_name;
      dst->ctlm_type = mp[n].ctm_type;
      dst->ctlm_offsetlo = mp[n].ctm_offset;
      dst->ctlm_offsethi = 0;
    }
  return 0;
}

/* Iterate over the members of a STRUCT or UNION.  We pass the name, member
   type, and offset of each member to the specified callback function.  */

int
ctf_member_iter (ctf_dict_t *fp, ctf_id_t type, ctf_member_f *func, void *arg)
{
  ctf_next_t *i = NULL;
  ssize_t offset;
  const char *name;
  ctf_id_t membtype;

  while ((offset = ctf_member_next (fp, type, &i, &name, &membtype, 0)) >= 0)
    {
      int rc;
      if ((rc = func (name, membtype, offset, arg)) != 0)
	{
	  ctf_next_destroy (i);
	  return rc;
	}
    }
  if (ctf_errno (fp) != ECTF_NEXT_END)
    return -1;					/* errno is set for us.  */

  return 0;
}

/* Iterate over the members of a STRUCT or UNION, returning each member's
   offset and optionally name and member type in turn.  On end-of-iteration,
   returns -1.  If FLAGS is CTF_MN_RECURSE, recurse into unnamed members.  */

ssize_t
ctf_member_next (ctf_dict_t *fp, ctf_id_t type, ctf_next_t **it,
		 const char **name, ctf_id_t *membtype, int flags)
{
  ctf_dict_t *ofp = fp;
  uint32_t kind;
  ssize_t offset;
  uint32_t max_vlen;
  ctf_next_t *i = *it;

  if (!i)
    {
      const ctf_type_t *tp;
      ctf_dtdef_t *dtd;
      ssize_t size;
      ssize_t increment;

      if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
	return -1;			/* errno is set for us.  */

      if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
	return -1;			/* errno is set for us.  */

      if ((i = ctf_next_create ()) == NULL)
	return ctf_set_errno (ofp, ENOMEM);
      i->cu.ctn_fp = ofp;
      i->ctn_tp = tp;

      ctf_get_ctt_size (fp, tp, &size, &increment);
      kind = LCTF_INFO_KIND (fp, tp->ctt_info);

      if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
	{
	  ctf_next_destroy (i);
	  return (ctf_set_errno (ofp, ECTF_NOTSOU));
	}

      if ((dtd = ctf_dynamic_type (fp, type)) != NULL)
	{
	  i->u.ctn_vlen = dtd->dtd_vlen;
	  i->ctn_size = dtd->dtd_vlen_alloc;
	}
      else
	{
	  unsigned long vlen = LCTF_INFO_VLEN (fp, tp->ctt_info);

	  i->u.ctn_vlen = (unsigned char *) tp + increment;
	  i->ctn_size = LCTF_VBYTES (fp, kind, size, vlen);;
	}
      i->ctn_iter_fun = (void (*) (void)) ctf_member_next;
      i->ctn_n = 0;
      *it = i;
    }

  if ((void (*) (void)) ctf_member_next != i->ctn_iter_fun)
    return (ctf_set_errno (ofp, ECTF_NEXT_WRONGFUN));

  if (ofp != i->cu.ctn_fp)
    return (ctf_set_errno (ofp, ECTF_NEXT_WRONGFP));

  /* Resolve to the native dict of this type.  */
  if ((fp = ctf_get_dict (ofp, type)) == NULL)
    return (ctf_set_errno (ofp, ECTF_NOPARENT));

  max_vlen = LCTF_INFO_VLEN (fp, i->ctn_tp->ctt_info);

  /* When we hit an unnamed struct/union member, we set ctn_type to indicate
     that we are inside one, then return the unnamed member: on the next call,
     we must skip over top-level member iteration in favour of iteration within
     the sub-struct until it later turns out that that iteration has ended.  */

 retry:
  if (!i->ctn_type)
    {
      ctf_lmember_t memb;
      const char *membname;

      if (i->ctn_n == max_vlen)
	goto end_iter;

      if (ctf_struct_member (fp, &memb, i->ctn_tp, i->u.ctn_vlen, i->ctn_size,
			     i->ctn_n) < 0)
	return -1;				/* errno is set for us.  */

      membname = ctf_strptr (fp, memb.ctlm_name);

      if (name)
	*name = membname;
      if (membtype)
	*membtype = memb.ctlm_type;
      offset = (unsigned long) CTF_LMEM_OFFSET (&memb);

      if (membname[0] == 0
	  && (ctf_type_kind (fp, memb.ctlm_type) == CTF_K_STRUCT
	      || ctf_type_kind (fp, memb.ctlm_type) == CTF_K_UNION))
	i->ctn_type = memb.ctlm_type;
      i->ctn_n++;

      /* The callers might want automatic recursive sub-struct traversal.  */
      if (!(flags & CTF_MN_RECURSE))
	i->ctn_type = 0;

      /* Sub-struct traversal starting?  Take note of the offset of this member,
	 for later boosting of sub-struct members' offsets.  */
      if (i->ctn_type)
	i->ctn_increment = offset;
    }
  /* Traversing a sub-struct?  Just return it, with the offset adjusted.  */
  else
    {
      ssize_t ret = ctf_member_next (fp, i->ctn_type, &i->ctn_next, name,
				     membtype, flags);

      if (ret >= 0)
	return ret + i->ctn_increment;

      if (ctf_errno (fp) != ECTF_NEXT_END)
	{
	  ctf_next_destroy (i);
	  *it = NULL;
	  i->ctn_type = 0;
	  return ret;				/* errno is set for us.  */
	}

      if (!ctf_assert (fp, (i->ctn_next == NULL)))
	return -1;				/* errno is set for us.  */

      i->ctn_type = 0;
      /* This sub-struct has ended: on to the next real member.  */
      goto retry;
    }

  return offset;

 end_iter:
  ctf_next_destroy (i);
  *it = NULL;
  return ctf_set_errno (ofp, ECTF_NEXT_END);
}

/* Iterate over the members of an ENUM.  We pass the string name and associated
   integer value of each enum element to the specified callback function.  */

int
ctf_enum_iter (ctf_dict_t *fp, ctf_id_t type, ctf_enum_f *func, void *arg)
{
  ctf_next_t *i = NULL;
  const char *name;
  int val;

  while ((name = ctf_enum_next (fp, type, &i, &val)) != NULL)
    {
      int rc;
      if ((rc = func (name, val, arg)) != 0)
	{
	  ctf_next_destroy (i);
	  return rc;
	}
    }
  if (ctf_errno (fp) != ECTF_NEXT_END)
    return -1;					/* errno is set for us.  */

  return 0;
}

/* Iterate over the members of an enum TYPE, returning each enumerand's NAME or
   NULL at end of iteration or error, and optionally passing back the
   enumerand's integer VALue.  */

const char *
ctf_enum_next (ctf_dict_t *fp, ctf_id_t type, ctf_next_t **it,
	       int *val)
{
  ctf_dict_t *ofp = fp;
  uint32_t kind;
  const char *name;
  ctf_next_t *i = *it;

  if (!i)
    {
      const ctf_type_t *tp;
      ctf_dtdef_t *dtd;

      if ((type = ctf_type_resolve_unsliced (fp, type)) == CTF_ERR)
	return NULL;			/* errno is set for us.  */

      if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
	return NULL;			/* errno is set for us.  */

      if ((i = ctf_next_create ()) == NULL)
	{
	  ctf_set_errno (ofp, ENOMEM);
	  return NULL;
	}
      i->cu.ctn_fp = ofp;

      (void) ctf_get_ctt_size (fp, tp, NULL,
			       &i->ctn_increment);
      kind = LCTF_INFO_KIND (fp, tp->ctt_info);

      if (kind != CTF_K_ENUM)
	{
	  ctf_next_destroy (i);
	  ctf_set_errno (ofp, ECTF_NOTENUM);
	  return NULL;
	}

      dtd = ctf_dynamic_type (fp, type);
      i->ctn_iter_fun = (void (*) (void)) ctf_enum_next;
      i->ctn_n = LCTF_INFO_VLEN (fp, tp->ctt_info);

      if (dtd == NULL)
	i->u.ctn_en = (const ctf_enum_t *) ((uintptr_t) tp +
					    i->ctn_increment);
      else
	i->u.ctn_en = (const ctf_enum_t *) dtd->dtd_vlen;

      *it = i;
    }

  if ((void (*) (void)) ctf_enum_next != i->ctn_iter_fun)
    {
      ctf_set_errno (ofp, ECTF_NEXT_WRONGFUN);
      return NULL;
    }

  if (ofp != i->cu.ctn_fp)
    {
      ctf_set_errno (ofp, ECTF_NEXT_WRONGFP);
      return NULL;
    }

  /* Resolve to the native dict of this type.  */
  if ((fp = ctf_get_dict (ofp, type)) == NULL)
    {
      ctf_set_errno (ofp, ECTF_NOPARENT);
      return NULL;
    }

  if (i->ctn_n == 0)
    goto end_iter;

  name = ctf_strptr (fp, i->u.ctn_en->cte_name);
  if (val)
    *val = i->u.ctn_en->cte_value;
  i->u.ctn_en++;
  i->ctn_n--;

  return name;

 end_iter:
  ctf_next_destroy (i);
  *it = NULL;
  ctf_set_errno (ofp, ECTF_NEXT_END);
  return NULL;
}

/* Iterate over every root (user-visible) type in the given CTF dict.
   We pass the type ID of each type to the specified callback function.

   Does not traverse parent types: you have to do that explicitly.  This is by
   design, to avoid traversing them more than once if traversing many children
   of a single parent.  */

int
ctf_type_iter (ctf_dict_t *fp, ctf_type_f *func, void *arg)
{
  ctf_next_t *i = NULL;
  ctf_id_t type;

  while ((type = ctf_type_next (fp, &i, NULL, 0)) != CTF_ERR)
    {
      int rc;
      if ((rc = func (type, arg)) != 0)
	{
	  ctf_next_destroy (i);
	  return rc;
	}
    }
  if (ctf_errno (fp) != ECTF_NEXT_END)
    return -1;					/* errno is set for us.  */

  return 0;
}

/* Iterate over every type in the given CTF dict, user-visible or not.
   We pass the type ID of each type to the specified callback function.

   Does not traverse parent types: you have to do that explicitly.  This is by
   design, to avoid traversing them more than once if traversing many children
   of a single parent.  */

int
ctf_type_iter_all (ctf_dict_t *fp, ctf_type_all_f *func, void *arg)
{
  ctf_next_t *i = NULL;
  ctf_id_t type;
  int flag;

  while ((type = ctf_type_next (fp, &i, &flag, 1)) != CTF_ERR)
    {
      int rc;
      if ((rc = func (type, flag, arg)) != 0)
	{
	  ctf_next_destroy (i);
	  return rc;
	}
    }
  if (ctf_errno (fp) != ECTF_NEXT_END)
    return -1;					/* errno is set for us.  */

  return 0;
}

/* Iterate over every type in the given CTF dict, optionally including
   non-user-visible types, returning each type ID and hidden flag in turn.
   Returns CTF_ERR on end of iteration or error.

   Does not traverse parent types: you have to do that explicitly.  This is by
   design, to avoid traversing them more than once if traversing many children
   of a single parent.  */

ctf_id_t
ctf_type_next (ctf_dict_t *fp, ctf_next_t **it, int *flag, int want_hidden)
{
  ctf_next_t *i = *it;

  if (!i)
    {
      if ((i = ctf_next_create ()) == NULL)
	return ctf_set_errno (fp, ENOMEM);

      i->cu.ctn_fp = fp;
      i->ctn_type = 1;
      i->ctn_iter_fun = (void (*) (void)) ctf_type_next;
      *it = i;
    }

  if ((void (*) (void)) ctf_type_next != i->ctn_iter_fun)
    return (ctf_set_errno (fp, ECTF_NEXT_WRONGFUN));

  if (fp != i->cu.ctn_fp)
    return (ctf_set_errno (fp, ECTF_NEXT_WRONGFP));

  while (i->ctn_type <= fp->ctf_typemax)
    {
      const ctf_type_t *tp = LCTF_INDEX_TO_TYPEPTR (fp, i->ctn_type);

      if ((!want_hidden) && (!LCTF_INFO_ISROOT (fp, tp->ctt_info)))
	{
	  i->ctn_type++;
	  continue;
	}

      if (flag)
	*flag = LCTF_INFO_ISROOT (fp, tp->ctt_info);
      return LCTF_INDEX_TO_TYPE (fp, i->ctn_type++, fp->ctf_flags & LCTF_CHILD);
    }
  ctf_next_destroy (i);
  *it = NULL;
  return ctf_set_errno (fp, ECTF_NEXT_END);
}

/* Iterate over every variable in the given CTF dict, in arbitrary order.
   We pass the name of each variable to the specified callback function.  */

int
ctf_variable_iter (ctf_dict_t *fp, ctf_variable_f *func, void *arg)
{
  ctf_next_t *i = NULL;
  ctf_id_t type;
  const char *name;

  while ((type = ctf_variable_next (fp, &i, &name)) != CTF_ERR)
    {
      int rc;
      if ((rc = func (name, type, arg)) != 0)
	{
	  ctf_next_destroy (i);
	  return rc;
	}
    }
  if (ctf_errno (fp) != ECTF_NEXT_END)
    return -1;					/* errno is set for us.  */

  return 0;
}

/* Iterate over every variable in the given CTF dict, in arbitrary order,
   returning the name and type of each variable in turn.  The name argument is
   not optional.  Returns CTF_ERR on end of iteration or error.  */

ctf_id_t
ctf_variable_next (ctf_dict_t *fp, ctf_next_t **it, const char **name)
{
  ctf_next_t *i = *it;

  if ((fp->ctf_flags & LCTF_CHILD) && (fp->ctf_parent == NULL))
    return (ctf_set_errno (fp, ECTF_NOPARENT));

  if (!i)
    {
      if ((i = ctf_next_create ()) == NULL)
	return ctf_set_errno (fp, ENOMEM);

      i->cu.ctn_fp = fp;
      i->ctn_iter_fun = (void (*) (void)) ctf_variable_next;
      if (fp->ctf_flags & LCTF_RDWR)
	i->u.ctn_dvd = ctf_list_next (&fp->ctf_dvdefs);
      *it = i;
    }

  if ((void (*) (void)) ctf_variable_next != i->ctn_iter_fun)
    return (ctf_set_errno (fp, ECTF_NEXT_WRONGFUN));

  if (fp != i->cu.ctn_fp)
    return (ctf_set_errno (fp, ECTF_NEXT_WRONGFP));

  if (!(fp->ctf_flags & LCTF_RDWR))
    {
      if (i->ctn_n >= fp->ctf_nvars)
	goto end_iter;

      *name = ctf_strptr (fp, fp->ctf_vars[i->ctn_n].ctv_name);
      return fp->ctf_vars[i->ctn_n++].ctv_type;
    }
  else
    {
      ctf_id_t id;

      if (i->u.ctn_dvd == NULL)
	goto end_iter;

      *name = i->u.ctn_dvd->dvd_name;
      id = i->u.ctn_dvd->dvd_type;
      i->u.ctn_dvd = ctf_list_next (i->u.ctn_dvd);
      return id;
    }

 end_iter:
  ctf_next_destroy (i);
  *it = NULL;
  return ctf_set_errno (fp, ECTF_NEXT_END);
}

/* Follow a given type through the graph for TYPEDEF, VOLATILE, CONST, and
   RESTRICT nodes until we reach a "base" type node.  This is useful when
   we want to follow a type ID to a node that has members or a size.  To guard
   against infinite loops, we implement simplified cycle detection and check
   each link against itself, the previous node, and the topmost node.

   Does not drill down through slices to their contained type.

   Callers of this function must not presume that a type it returns must have a
   valid ctt_size: forwards do not, and must be separately handled.  */

ctf_id_t
ctf_type_resolve (ctf_dict_t *fp, ctf_id_t type)
{
  ctf_id_t prev = type, otype = type;
  ctf_dict_t *ofp = fp;
  const ctf_type_t *tp;

  if (type == 0)
    return (ctf_set_errno (ofp, ECTF_NONREPRESENTABLE));

  while ((tp = ctf_lookup_by_id (&fp, type)) != NULL)
    {
      switch (LCTF_INFO_KIND (fp, tp->ctt_info))
	{
	case CTF_K_TYPEDEF:
	case CTF_K_VOLATILE:
	case CTF_K_CONST:
	case CTF_K_RESTRICT:
	  if (tp->ctt_type == type || tp->ctt_type == otype
	      || tp->ctt_type == prev)
	    {
	      ctf_err_warn (ofp, 0, ECTF_CORRUPT, _("type %lx cycle detected"),
			    otype);
	      return (ctf_set_errno (ofp, ECTF_CORRUPT));
	    }
	  prev = type;
	  type = tp->ctt_type;
	  break;
	case CTF_K_UNKNOWN:
	  return (ctf_set_errno (ofp, ECTF_NONREPRESENTABLE));
	default:
	  return type;
	}
      if (type == 0)
	return (ctf_set_errno (ofp, ECTF_NONREPRESENTABLE));
    }

  return CTF_ERR;		/* errno is set for us.  */
}

/* Like ctf_type_resolve(), but traverse down through slices to their contained
   type.  */

ctf_id_t
ctf_type_resolve_unsliced (ctf_dict_t *fp, ctf_id_t type)
{
  const ctf_type_t *tp;

  if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
    return -1;

  if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
    return CTF_ERR;		/* errno is set for us.  */

  if ((LCTF_INFO_KIND (fp, tp->ctt_info)) == CTF_K_SLICE)
    return ctf_type_reference (fp, type);
  return type;
}

/* Return the native dict of a given type: if called on a child and the
   type is in the parent, return the parent.  Needed if you plan to access
   the type directly, without using the API.  */
ctf_dict_t *
ctf_get_dict (ctf_dict_t *fp, ctf_id_t type)
{
    if ((fp->ctf_flags & LCTF_CHILD) && LCTF_TYPE_ISPARENT (fp, type))
      return fp->ctf_parent;

    return fp;
}

/* Look up a name in the given name table, in the appropriate hash given the
   kind of the identifier.  The name is a raw, undecorated identifier.  */

ctf_id_t ctf_lookup_by_rawname (ctf_dict_t *fp, int kind, const char *name)
{
  return ctf_lookup_by_rawhash (fp, ctf_name_table (fp, kind), name);
}

/* Look up a name in the given name table, in the appropriate hash given the
   readability state of the dictionary.  The name is a raw, undecorated
   identifier.  */

ctf_id_t ctf_lookup_by_rawhash (ctf_dict_t *fp, ctf_names_t *np, const char *name)
{
  ctf_id_t id;

  if (fp->ctf_flags & LCTF_RDWR)
    id = (ctf_id_t) (uintptr_t) ctf_dynhash_lookup (np->ctn_writable, name);
  else
    id = ctf_hash_lookup_type (np->ctn_readonly, fp, name);
  return id;
}

/* Lookup the given type ID and return its name as a new dynamically-allocated
   string.  */

char *
ctf_type_aname (ctf_dict_t *fp, ctf_id_t type)
{
  ctf_decl_t cd;
  ctf_decl_node_t *cdp;
  ctf_decl_prec_t prec, lp, rp;
  int ptr, arr;
  uint32_t k;
  char *buf;

  if (fp == NULL && type == CTF_ERR)
    return NULL;	/* Simplify caller code by permitting CTF_ERR.  */

  ctf_decl_init (&cd);
  ctf_decl_push (&cd, fp, type);

  if (cd.cd_err != 0)
    {
      ctf_decl_fini (&cd);
      ctf_set_errno (fp, cd.cd_err);
      return NULL;
    }

  /* If the type graph's order conflicts with lexical precedence order
     for pointers or arrays, then we need to surround the declarations at
     the corresponding lexical precedence with parentheses.  This can
     result in either a parenthesized pointer (*) as in int (*)() or
     int (*)[], or in a parenthesized pointer and array as in int (*[])().  */

  ptr = cd.cd_order[CTF_PREC_POINTER] > CTF_PREC_POINTER;
  arr = cd.cd_order[CTF_PREC_ARRAY] > CTF_PREC_ARRAY;

  rp = arr ? CTF_PREC_ARRAY : ptr ? CTF_PREC_POINTER : -1;
  lp = ptr ? CTF_PREC_POINTER : arr ? CTF_PREC_ARRAY : -1;

  k = CTF_K_POINTER;		/* Avoid leading whitespace (see below).  */

  for (prec = CTF_PREC_BASE; prec < CTF_PREC_MAX; prec++)
    {
      for (cdp = ctf_list_next (&cd.cd_nodes[prec]);
	   cdp != NULL; cdp = ctf_list_next (cdp))
	{
	  ctf_dict_t *rfp = fp;
	  const ctf_type_t *tp = ctf_lookup_by_id (&rfp, cdp->cd_type);
	  const char *name = ctf_strptr (rfp, tp->ctt_name);

	  if (k != CTF_K_POINTER && k != CTF_K_ARRAY)
	    ctf_decl_sprintf (&cd, " ");

	  if (lp == prec)
	    {
	      ctf_decl_sprintf (&cd, "(");
	      lp = -1;
	    }

	  switch (cdp->cd_kind)
	    {
	    case CTF_K_INTEGER:
	    case CTF_K_FLOAT:
	    case CTF_K_TYPEDEF:
	      /* Integers, floats, and typedefs must always be named types.  */

	      if (name[0] == '\0')
		{
		  ctf_set_errno (fp, ECTF_CORRUPT);
		  ctf_decl_fini (&cd);
		  return NULL;
		}

	      ctf_decl_sprintf (&cd, "%s", name);
	      break;
	    case CTF_K_POINTER:
	      ctf_decl_sprintf (&cd, "*");
	      break;
	    case CTF_K_ARRAY:
	      ctf_decl_sprintf (&cd, "[%u]", cdp->cd_n);
	      break;
	    case CTF_K_FUNCTION:
	      {
		size_t i;
		ctf_funcinfo_t fi;
		ctf_id_t *argv = NULL;

		if (ctf_func_type_info (rfp, cdp->cd_type, &fi) < 0)
		  goto err;		/* errno is set for us.  */

		if ((argv = calloc (fi.ctc_argc, sizeof (ctf_id_t *))) == NULL)
		  {
		    ctf_set_errno (rfp, errno);
		    goto err;
		  }

		if (ctf_func_type_args (rfp, cdp->cd_type,
					fi.ctc_argc, argv) < 0)
		  goto err;		/* errno is set for us.  */

		ctf_decl_sprintf (&cd, "(*) (");
		for (i = 0; i < fi.ctc_argc; i++)
		  {
		    char *arg = ctf_type_aname (rfp, argv[i]);

		    if (arg == NULL)
		      goto err;		/* errno is set for us.  */
		    ctf_decl_sprintf (&cd, "%s", arg);
		    free (arg);

		    if ((i < fi.ctc_argc - 1)
			|| (fi.ctc_flags & CTF_FUNC_VARARG))
		      ctf_decl_sprintf (&cd, ", ");
		  }

		if (fi.ctc_flags & CTF_FUNC_VARARG)
		  ctf_decl_sprintf (&cd, "...");
		ctf_decl_sprintf (&cd, ")");

		free (argv);
		break;

	      err:
		free (argv);
		ctf_decl_fini (&cd);
		return NULL;
	      }
	      break;
	    case CTF_K_STRUCT:
	      ctf_decl_sprintf (&cd, "struct %s", name);
	      break;
	    case CTF_K_UNION:
	      ctf_decl_sprintf (&cd, "union %s", name);
	      break;
	    case CTF_K_ENUM:
	      ctf_decl_sprintf (&cd, "enum %s", name);
	      break;
	    case CTF_K_FORWARD:
	      {
		switch (ctf_type_kind_forwarded (fp, cdp->cd_type))
		  {
		  case CTF_K_STRUCT:
		    ctf_decl_sprintf (&cd, "struct %s", name);
		    break;
		  case CTF_K_UNION:
		    ctf_decl_sprintf (&cd, "union %s", name);
		    break;
		  case CTF_K_ENUM:
		    ctf_decl_sprintf (&cd, "enum %s", name);
		    break;
		  default:
		    ctf_set_errno (fp, ECTF_CORRUPT);
		    ctf_decl_fini (&cd);
		    return NULL;
		  }
		break;
	      }
	    case CTF_K_VOLATILE:
	      ctf_decl_sprintf (&cd, "volatile");
	      break;
	    case CTF_K_CONST:
	      ctf_decl_sprintf (&cd, "const");
	      break;
	    case CTF_K_RESTRICT:
	      ctf_decl_sprintf (&cd, "restrict");
	      break;
	    case CTF_K_UNKNOWN:
	      if (name[0] == '\0')
		ctf_decl_sprintf (&cd, _("(nonrepresentable type)"));
	      else
		ctf_decl_sprintf (&cd, _("(nonrepresentable type %s)"),
				  name);
	      break;
	    }

	  k = cdp->cd_kind;
	}

      if (rp == prec)
	ctf_decl_sprintf (&cd, ")");
    }

  if (cd.cd_enomem)
    (void) ctf_set_errno (fp, ENOMEM);

  buf = ctf_decl_buf (&cd);

  ctf_decl_fini (&cd);
  return buf;
}

/* Lookup the given type ID and print a string name for it into buf.  Return
   the actual number of bytes (not including \0) needed to format the name.  */

ssize_t
ctf_type_lname (ctf_dict_t *fp, ctf_id_t type, char *buf, size_t len)
{
  char *str = ctf_type_aname (fp, type);
  size_t slen;

  if (str == NULL)
    return CTF_ERR;			/* errno is set for us.  */

  slen = strlen (str);
  snprintf (buf, len, "%s", str);
  free (str);

  if (slen >= len)
    (void) ctf_set_errno (fp, ECTF_NAMELEN);

  return slen;
}

/* Lookup the given type ID and print a string name for it into buf.  If buf
   is too small, return NULL: the ECTF_NAMELEN error is set on 'fp' for us.  */

char *
ctf_type_name (ctf_dict_t *fp, ctf_id_t type, char *buf, size_t len)
{
  ssize_t rv = ctf_type_lname (fp, type, buf, len);
  return (rv >= 0 && (size_t) rv < len ? buf : NULL);
}

/* Lookup the given type ID and return its raw, unadorned, undecorated name.
   The name will live as long as its ctf_dict_t does.

   The only decoration is that a NULL return always means an error: nameless
   types return a null string.  */

const char *
ctf_type_name_raw (ctf_dict_t *fp, ctf_id_t type)
{
  const ctf_type_t *tp;

  if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
    return NULL;		/* errno is set for us.  */

  if (tp->ctt_name == 0)
    return "";

  return ctf_strraw (fp, tp->ctt_name);
}

/* Lookup the given type ID and return its raw, unadorned, undecorated name as a
   new dynamically-allocated string.  */

char *
ctf_type_aname_raw (ctf_dict_t *fp, ctf_id_t type)
{
  const char *name = ctf_type_name_raw (fp, type);

  if (name != NULL)
    return strdup (name);

  return NULL;
}

/* Resolve the type down to a base type node, and then return the size
   of the type storage in bytes.  */

ssize_t
ctf_type_size (ctf_dict_t *fp, ctf_id_t type)
{
  ctf_dict_t *ofp = fp;
  const ctf_type_t *tp;
  ssize_t size;
  ctf_arinfo_t ar;

  if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
    return -1;			/* errno is set for us.  */

  if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
    return -1;			/* errno is set for us.  */

  switch (LCTF_INFO_KIND (fp, tp->ctt_info))
    {
    case CTF_K_POINTER:
      return fp->ctf_dmodel->ctd_pointer;

    case CTF_K_FUNCTION:
      return 0;		/* Function size is only known by symtab.  */

    case CTF_K_ENUM:
      return fp->ctf_dmodel->ctd_int;

    case CTF_K_ARRAY:
      /* ctf_add_array() does not directly encode the element size, but
	 requires the user to multiply to determine the element size.

	 If ctf_get_ctt_size() returns nonzero, then use the recorded
	 size instead.  */

      if ((size = ctf_get_ctt_size (fp, tp, NULL, NULL)) > 0)
	return size;

      if (ctf_array_info (ofp, type, &ar) < 0
	  || (size = ctf_type_size (ofp, ar.ctr_contents)) < 0)
	return -1;		/* errno is set for us.  */

      return size * ar.ctr_nelems;

    case CTF_K_FORWARD:
      /* Forwards do not have a meaningful size.  */
      return (ctf_set_errno (ofp, ECTF_INCOMPLETE));

    default: /* including slices of enums, etc */
      return (ctf_get_ctt_size (fp, tp, NULL, NULL));
    }
}

/* Resolve the type down to a base type node, and then return the alignment
   needed for the type storage in bytes.

   XXX may need arch-dependent attention.  */

ssize_t
ctf_type_align (ctf_dict_t *fp, ctf_id_t type)
{
  const ctf_type_t *tp;
  ctf_dict_t *ofp = fp;
  int kind;

  if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
    return -1;			/* errno is set for us.  */

  if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
    return -1;			/* errno is set for us.  */

  kind = LCTF_INFO_KIND (fp, tp->ctt_info);
  switch (kind)
    {
    case CTF_K_POINTER:
    case CTF_K_FUNCTION:
      return fp->ctf_dmodel->ctd_pointer;

    case CTF_K_ARRAY:
      {
	ctf_arinfo_t r;
	if (ctf_array_info (ofp, type, &r) < 0)
	  return -1;		/* errno is set for us.  */
	return (ctf_type_align (ofp, r.ctr_contents));
      }

    case CTF_K_STRUCT:
    case CTF_K_UNION:
      {
	size_t align = 0;
	ctf_dtdef_t *dtd;
	unsigned char *vlen;
	uint32_t i = 0, n = LCTF_INFO_VLEN (fp, tp->ctt_info);
	ssize_t size, increment, vbytes;

	ctf_get_ctt_size (fp, tp, &size, &increment);

	if ((dtd = ctf_dynamic_type (fp, type)) != NULL)
	  {
	    vlen = dtd->dtd_vlen;
	    vbytes = dtd->dtd_vlen_alloc;
	  }
	else
	  {
	    vlen = (unsigned char *) tp + increment;
	    vbytes = LCTF_VBYTES (fp, kind, size, n);
	  }

	if (kind == CTF_K_STRUCT)
	  n = MIN (n, 1);	/* Only use first member for structs.  */

	for (; n != 0; n--, i++)
	  {
	    ctf_lmember_t memb;

	    if (ctf_struct_member (fp, &memb, tp, vlen, vbytes, i) < 0)
	      return -1;				/* errno is set for us.  */

	    ssize_t am = ctf_type_align (ofp, memb.ctlm_type);
	    align = MAX (align, (size_t) am);
	  }
	return align;
      }

    case CTF_K_ENUM:
      return fp->ctf_dmodel->ctd_int;

    case CTF_K_FORWARD:
      /* Forwards do not have a meaningful alignment.  */
      return (ctf_set_errno (ofp, ECTF_INCOMPLETE));

    default:  /* including slices of enums, etc */
      return (ctf_get_ctt_size (fp, tp, NULL, NULL));
    }
}

/* Return the kind (CTF_K_* constant) for the specified type ID.  */

int
ctf_type_kind_unsliced (ctf_dict_t *fp, ctf_id_t type)
{
  const ctf_type_t *tp;

  if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
    return -1;			/* errno is set for us.  */

  return (LCTF_INFO_KIND (fp, tp->ctt_info));
}

/* Return the kind (CTF_K_* constant) for the specified type ID.
   Slices are considered to be of the same kind as the type sliced.  */

int
ctf_type_kind (ctf_dict_t *fp, ctf_id_t type)
{
  int kind;

  if ((kind = ctf_type_kind_unsliced (fp, type)) < 0)
    return -1;

  if (kind == CTF_K_SLICE)
    {
      if ((type = ctf_type_reference (fp, type)) == CTF_ERR)
	return -1;
      kind = ctf_type_kind_unsliced (fp, type);
    }

  return kind;
}

/* Return the kind of this type, except, for forwards, return the kind of thing
   this is a forward to.  */
int
ctf_type_kind_forwarded (ctf_dict_t *fp, ctf_id_t type)
{
  int kind;
  const ctf_type_t *tp;

  if ((kind = ctf_type_kind (fp, type)) < 0)
    return -1;			/* errno is set for us.  */

  if (kind != CTF_K_FORWARD)
    return kind;

  if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
    return -1;			/* errno is set for us.  */

  return tp->ctt_type;
}

/* If the type is one that directly references another type (such as POINTER),
   then return the ID of the type to which it refers.  */

ctf_id_t
ctf_type_reference (ctf_dict_t *fp, ctf_id_t type)
{
  ctf_dict_t *ofp = fp;
  const ctf_type_t *tp;

  if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
    return CTF_ERR;		/* errno is set for us.  */

  switch (LCTF_INFO_KIND (fp, tp->ctt_info))
    {
    case CTF_K_POINTER:
    case CTF_K_TYPEDEF:
    case CTF_K_VOLATILE:
    case CTF_K_CONST:
    case CTF_K_RESTRICT:
      return tp->ctt_type;
      /* Slices store their type in an unusual place.  */
    case CTF_K_SLICE:
      {
	ctf_dtdef_t *dtd;
	const ctf_slice_t *sp;

	if ((dtd = ctf_dynamic_type (ofp, type)) == NULL)
	  {
	    ssize_t increment;

	    (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
	    sp = (const ctf_slice_t *) ((uintptr_t) tp + increment);
	  }
	else
	  sp = (const ctf_slice_t *) dtd->dtd_vlen;

	return sp->cts_type;
      }
    default:
      return (ctf_set_errno (ofp, ECTF_NOTREF));
    }
}

/* Find a pointer to type by looking in fp->ctf_ptrtab.  If we can't find a
   pointer to the given type, see if we can compute a pointer to the type
   resulting from resolving the type down to its base type and use that
   instead.  This helps with cases where the CTF data includes "struct foo *"
   but not "foo_t *" and the user accesses "foo_t *" in the debugger.

   XXX what about parent dicts?  */

ctf_id_t
ctf_type_pointer (ctf_dict_t *fp, ctf_id_t type)
{
  ctf_dict_t *ofp = fp;
  ctf_id_t ntype;

  if (ctf_lookup_by_id (&fp, type) == NULL)
    return CTF_ERR;		/* errno is set for us.  */

  if ((ntype = fp->ctf_ptrtab[LCTF_TYPE_TO_INDEX (fp, type)]) != 0)
    return (LCTF_INDEX_TO_TYPE (fp, ntype, (fp->ctf_flags & LCTF_CHILD)));

  if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
    return (ctf_set_errno (ofp, ECTF_NOTYPE));

  if (ctf_lookup_by_id (&fp, type) == NULL)
    return (ctf_set_errno (ofp, ECTF_NOTYPE));

  if ((ntype = fp->ctf_ptrtab[LCTF_TYPE_TO_INDEX (fp, type)]) != 0)
    return (LCTF_INDEX_TO_TYPE (fp, ntype, (fp->ctf_flags & LCTF_CHILD)));

  return (ctf_set_errno (ofp, ECTF_NOTYPE));
}

/* Return the encoding for the specified INTEGER, FLOAT, or ENUM.  */

int
ctf_type_encoding (ctf_dict_t *fp, ctf_id_t type, ctf_encoding_t *ep)
{
  ctf_dict_t *ofp = fp;
  ctf_dtdef_t *dtd;
  const ctf_type_t *tp;
  ssize_t increment;
  const unsigned char *vlen;
  uint32_t data;

  if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
    return -1;			/* errno is set for us.  */

  if ((dtd = ctf_dynamic_type (ofp, type)) != NULL)
    vlen = dtd->dtd_vlen;
  else
    {
      ctf_get_ctt_size (fp, tp, NULL, &increment);
      vlen = (const unsigned char *) ((uintptr_t) tp + increment);
    }

  switch (LCTF_INFO_KIND (fp, tp->ctt_info))
    {
    case CTF_K_INTEGER:
      data = *(const uint32_t *) vlen;
      ep->cte_format = CTF_INT_ENCODING (data);
      ep->cte_offset = CTF_INT_OFFSET (data);
      ep->cte_bits = CTF_INT_BITS (data);
      break;
    case CTF_K_FLOAT:
      data = *(const uint32_t *) vlen;
      ep->cte_format = CTF_FP_ENCODING (data);
      ep->cte_offset = CTF_FP_OFFSET (data);
      ep->cte_bits = CTF_FP_BITS (data);
      break;
    case CTF_K_ENUM:
      /* v3 only: we must guess at the underlying integral format.  */
      ep->cte_format = CTF_INT_SIGNED;
      ep->cte_offset = 0;
      ep->cte_bits = 0;
      break;
    case CTF_K_SLICE:
      {
	const ctf_slice_t *slice;
	ctf_encoding_t underlying_en;
	ctf_id_t underlying;

	slice = (ctf_slice_t *) vlen;
	underlying = ctf_type_resolve (fp, slice->cts_type);
	if (ctf_type_encoding (fp, underlying, &underlying_en) < 0)
	  return -1;				/* errno is set for us.  */

	ep->cte_format = underlying_en.cte_format;
	ep->cte_offset = slice->cts_offset;
	ep->cte_bits = slice->cts_bits;
	break;
      }
    default:
      return (ctf_set_errno (ofp, ECTF_NOTINTFP));
    }

  return 0;
}

int
ctf_type_cmp (ctf_dict_t *lfp, ctf_id_t ltype, ctf_dict_t *rfp,
	      ctf_id_t rtype)
{
  int rval;

  if (ltype < rtype)
    rval = -1;
  else if (ltype > rtype)
    rval = 1;
  else
    rval = 0;

  if (lfp == rfp)
    return rval;

  if (LCTF_TYPE_ISPARENT (lfp, ltype) && lfp->ctf_parent != NULL)
    lfp = lfp->ctf_parent;

  if (LCTF_TYPE_ISPARENT (rfp, rtype) && rfp->ctf_parent != NULL)
    rfp = rfp->ctf_parent;

  if (lfp < rfp)
    return -1;

  if (lfp > rfp)
    return 1;

  return rval;
}

/* Return a boolean value indicating if two types are compatible.  This function
   returns true if the two types are the same, or if they (or their ultimate
   base type) have the same encoding properties, or (for structs / unions /
   enums / forward declarations) if they have the same name and (for structs /
   unions) member count.  */

int
ctf_type_compat (ctf_dict_t *lfp, ctf_id_t ltype,
		 ctf_dict_t *rfp, ctf_id_t rtype)
{
  const ctf_type_t *ltp, *rtp;
  ctf_encoding_t le, re;
  ctf_arinfo_t la, ra;
  uint32_t lkind, rkind;
  int same_names = 0;

  if (ctf_type_cmp (lfp, ltype, rfp, rtype) == 0)
    return 1;

  ltype = ctf_type_resolve (lfp, ltype);
  lkind = ctf_type_kind (lfp, ltype);

  rtype = ctf_type_resolve (rfp, rtype);
  rkind = ctf_type_kind (rfp, rtype);

  ltp = ctf_lookup_by_id (&lfp, ltype);
  rtp = ctf_lookup_by_id (&rfp, rtype);

  if (ltp != NULL && rtp != NULL)
    same_names = (strcmp (ctf_strptr (lfp, ltp->ctt_name),
			  ctf_strptr (rfp, rtp->ctt_name)) == 0);

  if (((lkind == CTF_K_ENUM) && (rkind == CTF_K_INTEGER)) ||
      ((rkind == CTF_K_ENUM) && (lkind == CTF_K_INTEGER)))
    return 1;

  if (lkind != rkind)
    return 0;

  switch (lkind)
    {
    case CTF_K_INTEGER:
    case CTF_K_FLOAT:
      memset (&le, 0, sizeof (le));
      memset (&re, 0, sizeof (re));
      return (ctf_type_encoding (lfp, ltype, &le) == 0
	      && ctf_type_encoding (rfp, rtype, &re) == 0
	      && memcmp (&le, &re, sizeof (ctf_encoding_t)) == 0);
    case CTF_K_POINTER:
      return (ctf_type_compat (lfp, ctf_type_reference (lfp, ltype),
			       rfp, ctf_type_reference (rfp, rtype)));
    case CTF_K_ARRAY:
      return (ctf_array_info (lfp, ltype, &la) == 0
	      && ctf_array_info (rfp, rtype, &ra) == 0
	      && la.ctr_nelems == ra.ctr_nelems
	      && ctf_type_compat (lfp, la.ctr_contents, rfp, ra.ctr_contents)
	      && ctf_type_compat (lfp, la.ctr_index, rfp, ra.ctr_index));
    case CTF_K_STRUCT:
    case CTF_K_UNION:
      return (same_names && (ctf_type_size (lfp, ltype)
			     == ctf_type_size (rfp, rtype)));
    case CTF_K_ENUM:
      {
	int lencoded, rencoded;
	lencoded = ctf_type_encoding (lfp, ltype, &le);
	rencoded = ctf_type_encoding (rfp, rtype, &re);

	if ((lencoded != rencoded) ||
	    ((lencoded == 0) && memcmp (&le, &re, sizeof (ctf_encoding_t)) != 0))
	  return 0;
      }
      /* FALLTHRU */
    case CTF_K_FORWARD:
      return same_names;   /* No other checks required for these type kinds.  */
    default:
      return 0;		      /* Should not get here since we did a resolve.  */
    }
}

/* Return the number of members in a STRUCT or UNION, or the number of
   enumerators in an ENUM.  The count does not include unnamed sub-members.  */

int
ctf_member_count (ctf_dict_t *fp, ctf_id_t type)
{
  ctf_dict_t *ofp = fp;
  const ctf_type_t *tp;
  uint32_t kind;

  if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
    return -1;			/* errno is set for us.  */

  if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
    return -1;			/* errno is set for us.  */

  kind = LCTF_INFO_KIND (fp, tp->ctt_info);

  if (kind != CTF_K_STRUCT && kind != CTF_K_UNION && kind != CTF_K_ENUM)
    return (ctf_set_errno (ofp, ECTF_NOTSUE));

  return LCTF_INFO_VLEN (fp, tp->ctt_info);
}

/* Return the type and offset for a given member of a STRUCT or UNION.  */

int
ctf_member_info (ctf_dict_t *fp, ctf_id_t type, const char *name,
		 ctf_membinfo_t *mip)
{
  ctf_dict_t *ofp = fp;
  const ctf_type_t *tp;
  ctf_dtdef_t *dtd;
  unsigned char *vlen;
  ssize_t size, increment, vbytes;
  uint32_t kind, n, i = 0;

  if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
    return -1;			/* errno is set for us.  */

  if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
    return -1;			/* errno is set for us.  */

  ctf_get_ctt_size (fp, tp, &size, &increment);
  kind = LCTF_INFO_KIND (fp, tp->ctt_info);

  if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
    return (ctf_set_errno (ofp, ECTF_NOTSOU));

  n = LCTF_INFO_VLEN (fp, tp->ctt_info);
  if ((dtd = ctf_dynamic_type (fp, type)) != NULL)
    {
      vlen = dtd->dtd_vlen;
      vbytes = dtd->dtd_vlen_alloc;
    }
  else
    {
      vlen = (unsigned char *) tp + increment;
      vbytes = LCTF_VBYTES (fp, kind, size, n);
    }

  for (; n != 0; n--, i++)
    {
      ctf_lmember_t memb;
      const char *membname;

      if (ctf_struct_member (fp, &memb, tp, vlen, vbytes, i) < 0)
	return -1;				/* errno is set for us.  */

      membname = ctf_strptr (fp, memb.ctlm_name);

      if (membname[0] == 0
	  && (ctf_type_kind (fp, memb.ctlm_type) == CTF_K_STRUCT
	      || ctf_type_kind (fp, memb.ctlm_type) == CTF_K_UNION)
	  && (ctf_member_info (fp, memb.ctlm_type, name, mip) == 0))
	return 0;

      if (strcmp (membname, name) == 0)
	{
	  mip->ctm_type = memb.ctlm_type;
	  mip->ctm_offset = (unsigned long) CTF_LMEM_OFFSET (&memb);
	  return 0;
	}
    }

  return (ctf_set_errno (ofp, ECTF_NOMEMBNAM));
}

/* Return the array type, index, and size information for the specified ARRAY.  */

int
ctf_array_info (ctf_dict_t *fp, ctf_id_t type, ctf_arinfo_t *arp)
{
  ctf_dict_t *ofp = fp;
  const ctf_type_t *tp;
  const ctf_array_t *ap;
  const ctf_dtdef_t *dtd;
  ssize_t increment;

  if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
    return -1;			/* errno is set for us.  */

  if (LCTF_INFO_KIND (fp, tp->ctt_info) != CTF_K_ARRAY)
    return (ctf_set_errno (ofp, ECTF_NOTARRAY));

  if ((dtd = ctf_dynamic_type (ofp, type)) != NULL)
    ap = (const ctf_array_t *) dtd->dtd_vlen;
  else
    {
      ctf_get_ctt_size (fp, tp, NULL, &increment);
      ap = (const ctf_array_t *) ((uintptr_t) tp + increment);
    }
  arp->ctr_contents = ap->cta_contents;
  arp->ctr_index = ap->cta_index;
  arp->ctr_nelems = ap->cta_nelems;

  return 0;
}

/* Convert the specified value to the corresponding enum tag name, if a
   matching name can be found.  Otherwise NULL is returned.  */

const char *
ctf_enum_name (ctf_dict_t *fp, ctf_id_t type, int value)
{
  ctf_dict_t *ofp = fp;
  const ctf_type_t *tp;
  const ctf_enum_t *ep;
  const ctf_dtdef_t *dtd;
  ssize_t increment;
  uint32_t n;

  if ((type = ctf_type_resolve_unsliced (fp, type)) == CTF_ERR)
    return NULL;		/* errno is set for us.  */

  if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
    return NULL;		/* errno is set for us.  */

  if (LCTF_INFO_KIND (fp, tp->ctt_info) != CTF_K_ENUM)
    {
      ctf_set_errno (ofp, ECTF_NOTENUM);
      return NULL;
    }

  ctf_get_ctt_size (fp, tp, NULL, &increment);

  if ((dtd = ctf_dynamic_type (ofp, type)) == NULL)
    ep = (const ctf_enum_t *) ((uintptr_t) tp + increment);
  else
    ep = (const ctf_enum_t *) dtd->dtd_vlen;

  for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, ep++)
    {
      if (ep->cte_value == value)
	return (ctf_strptr (fp, ep->cte_name));
    }

  ctf_set_errno (ofp, ECTF_NOENUMNAM);
  return NULL;
}

/* Convert the specified enum tag name to the corresponding value, if a
   matching name can be found.  Otherwise CTF_ERR is returned.  */

int
ctf_enum_value (ctf_dict_t *fp, ctf_id_t type, const char *name, int *valp)
{
  ctf_dict_t *ofp = fp;
  const ctf_type_t *tp;
  const ctf_enum_t *ep;
  const ctf_dtdef_t *dtd;
  ssize_t increment;
  uint32_t n;

  if ((type = ctf_type_resolve_unsliced (fp, type)) == CTF_ERR)
    return -1;			/* errno is set for us.  */

  if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
    return -1;			/* errno is set for us.  */

  if (LCTF_INFO_KIND (fp, tp->ctt_info) != CTF_K_ENUM)
    {
      (void) ctf_set_errno (ofp, ECTF_NOTENUM);
      return -1;
    }

  ctf_get_ctt_size (fp, tp, NULL, &increment);

  if ((dtd = ctf_dynamic_type (ofp, type)) == NULL)
    ep = (const ctf_enum_t *) ((uintptr_t) tp + increment);
  else
    ep = (const ctf_enum_t *) dtd->dtd_vlen;

  for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, ep++)
    {
      if (strcmp (ctf_strptr (fp, ep->cte_name), name) == 0)
	{
	  if (valp != NULL)
	    *valp = ep->cte_value;
	  return 0;
	}
    }

  ctf_set_errno (ofp, ECTF_NOENUMNAM);
  return -1;
}

/* Given a type ID relating to a function type, return info on return types and
   arg counts for that function.  */

int
ctf_func_type_info (ctf_dict_t *fp, ctf_id_t type, ctf_funcinfo_t *fip)
{
  const ctf_type_t *tp;
  uint32_t kind;
  const uint32_t *args;
  const ctf_dtdef_t *dtd;
  ssize_t size, increment;

  if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
    return -1;			/* errno is set for us.  */

  if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
    return -1;			/* errno is set for us.  */

  (void) ctf_get_ctt_size (fp, tp, &size, &increment);
  kind = LCTF_INFO_KIND (fp, tp->ctt_info);

  if (kind != CTF_K_FUNCTION)
    return (ctf_set_errno (fp, ECTF_NOTFUNC));

  fip->ctc_return = tp->ctt_type;
  fip->ctc_flags = 0;
  fip->ctc_argc = LCTF_INFO_VLEN (fp, tp->ctt_info);

  if ((dtd = ctf_dynamic_type (fp, type)) == NULL)
    args = (uint32_t *) ((uintptr_t) tp + increment);
  else
    args = (uint32_t *) dtd->dtd_vlen;

  if (fip->ctc_argc != 0 && args[fip->ctc_argc - 1] == 0)
    {
      fip->ctc_flags |= CTF_FUNC_VARARG;
      fip->ctc_argc--;
    }

  return 0;
}

/* Given a type ID relating to a function type, return the arguments for the
   function.  */

int
ctf_func_type_args (ctf_dict_t *fp, ctf_id_t type, uint32_t argc, ctf_id_t *argv)
{
  const ctf_type_t *tp;
  const uint32_t *args;
  const ctf_dtdef_t *dtd;
  ssize_t size, increment;
  ctf_funcinfo_t f;

  if (ctf_func_type_info (fp, type, &f) < 0)
    return -1;			/* errno is set for us.  */

  if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
    return -1;			/* errno is set for us.  */

  if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
    return -1;			/* errno is set for us.  */

  (void) ctf_get_ctt_size (fp, tp, &size, &increment);

  if ((dtd = ctf_dynamic_type (fp, type)) == NULL)
    args = (uint32_t *) ((uintptr_t) tp + increment);
  else
    args = (uint32_t *) dtd->dtd_vlen;

  for (argc = MIN (argc, f.ctc_argc); argc != 0; argc--)
    *argv++ = *args++;

  return 0;
}

/* Recursively visit the members of any type.  This function is used as the
   engine for ctf_type_visit, below.  We resolve the input type, recursively
   invoke ourself for each type member if the type is a struct or union, and
   then invoke the callback function on the current type.  If any callback
   returns non-zero, we abort and percolate the error code back up to the top.  */

static int
ctf_type_rvisit (ctf_dict_t *fp, ctf_id_t type, ctf_visit_f *func,
		 void *arg, const char *name, unsigned long offset, int depth)
{
  ctf_id_t otype = type;
  const ctf_type_t *tp;
  const ctf_dtdef_t *dtd;
  unsigned char *vlen;
  ssize_t size, increment, vbytes;
  uint32_t kind, n, i = 0;
  int rc;

  if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
    return -1;			/* errno is set for us.  */

  if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
    return -1;			/* errno is set for us.  */

  if ((rc = func (name, otype, offset, depth, arg)) != 0)
    return rc;

  kind = LCTF_INFO_KIND (fp, tp->ctt_info);

  if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
    return 0;

  ctf_get_ctt_size (fp, tp, &size, &increment);

  n = LCTF_INFO_VLEN (fp, tp->ctt_info);
  if ((dtd = ctf_dynamic_type (fp, type)) != NULL)
    {
      vlen = dtd->dtd_vlen;
      vbytes = dtd->dtd_vlen_alloc;
    }
  else
    {
      vlen = (unsigned char *) tp + increment;
      vbytes = LCTF_VBYTES (fp, kind, size, n);
    }

  for (; n != 0; n--, i++)
    {
      ctf_lmember_t memb;

      if (ctf_struct_member (fp, &memb, tp, vlen, vbytes, i) < 0)
	return -1;				/* errno is set for us.  */

      if ((rc = ctf_type_rvisit (fp, memb.ctlm_type,
				 func, arg, ctf_strptr (fp, memb.ctlm_name),
				 offset + (unsigned long) CTF_LMEM_OFFSET (&memb),
				 depth + 1)) != 0)
	return rc;
    }

  return 0;
}

/* Recursively visit the members of any type.  We pass the name, member
 type, and offset of each member to the specified callback function.  */
int
ctf_type_visit (ctf_dict_t *fp, ctf_id_t type, ctf_visit_f *func, void *arg)
{
  return (ctf_type_rvisit (fp, type, func, arg, "", 0, 0));
}
