/* Symbol, variable and name lookup.
   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 <elf.h>
#include <string.h>
#include <assert.h>

/* Grow the pptrtab so that it is at least NEW_LEN long.  */
static int
grow_pptrtab (ctf_dict_t *fp, size_t new_len)
{
  uint32_t *new_pptrtab;

  if ((new_pptrtab = realloc (fp->ctf_pptrtab, sizeof (uint32_t)
			      * new_len)) == NULL)
    return (ctf_set_errno (fp, ENOMEM));

  fp->ctf_pptrtab = new_pptrtab;

  memset (fp->ctf_pptrtab + fp->ctf_pptrtab_len, 0,
	  sizeof (uint32_t) * (new_len - fp->ctf_pptrtab_len));

  fp->ctf_pptrtab_len = new_len;
  return 0;
}

/* Update entries in the pptrtab that relate to types newly added in the
   child.  */
static int
refresh_pptrtab (ctf_dict_t *fp, ctf_dict_t *pfp)
{
  uint32_t i;
  for (i = fp->ctf_pptrtab_typemax; i <= fp->ctf_typemax; i++)
    {
      ctf_id_t type = LCTF_INDEX_TO_TYPE (fp, i, 1);
      ctf_id_t reffed_type;

      if (ctf_type_kind (fp, type) != CTF_K_POINTER)
	continue;

      reffed_type = ctf_type_reference (fp, type);

      if (LCTF_TYPE_ISPARENT (fp, reffed_type))
	{
	  uint32_t idx = LCTF_TYPE_TO_INDEX (fp, reffed_type);

	  /* Guard against references to invalid types.  No need to consider
	     the CTF dict corrupt in this case: this pointer just can't be a
	     pointer to any type we know about.  */
	  if (idx <= pfp->ctf_typemax)
	    {
	      if (idx >= fp->ctf_pptrtab_len
		  && grow_pptrtab (fp, pfp->ctf_ptrtab_len) < 0)
		return -1;			/* errno is set for us.  */

	      fp->ctf_pptrtab[idx] = i;
	    }
	}
    }

  fp->ctf_pptrtab_typemax = fp->ctf_typemax;

  return 0;
}

/* Compare the given input string and length against a table of known C storage
   qualifier keywords.  We just ignore these in ctf_lookup_by_name, below.  To
   do this quickly, we use a pre-computed Perfect Hash Function similar to the
   technique originally described in the classic paper:

   R.J. Cichelli, "Minimal Perfect Hash Functions Made Simple",
   Communications of the ACM, Volume 23, Issue 1, January 1980, pp. 17-19.

   For an input string S of length N, we use hash H = S[N - 1] + N - 105, which
   for the current set of qualifiers yields a unique H in the range [0 .. 20].
   The hash can be modified when the keyword set changes as necessary.  We also
   store the length of each keyword and check it prior to the final strcmp().

   TODO: just use gperf.  */

static int
isqualifier (const char *s, size_t len)
{
  static const struct qual
  {
    const char *q_name;
    size_t q_len;
  } qhash[] = {
    {"static", 6}, {"", 0}, {"", 0}, {"", 0},
    {"volatile", 8}, {"", 0}, {"", 0}, {"", 0}, {"", 0},
    {"", 0}, {"auto", 4}, {"extern", 6}, {"", 0}, {"", 0},
    {"", 0}, {"", 0}, {"const", 5}, {"register", 8},
    {"", 0}, {"restrict", 8}, {"_Restrict", 9}
  };

  int h = s[len - 1] + (int) len - 105;
  const struct qual *qp;

  if (h < 0 || (size_t) h >= sizeof (qhash) / sizeof (qhash[0]))
    return 0;

  qp = &qhash[h];

  return ((size_t) len == qp->q_len &&
	  strncmp (qp->q_name, s, qp->q_len) == 0);
}

/* Attempt to convert the given C type name into the corresponding CTF type ID.
   It is not possible to do complete and proper conversion of type names
   without implementing a more full-fledged parser, which is necessary to
   handle things like types that are function pointers to functions that
   have arguments that are function pointers, and fun stuff like that.
   Instead, this function implements a very simple conversion algorithm that
   finds the things that we actually care about: structs, unions, enums,
   integers, floats, typedefs, and pointers to any of these named types.  */

static ctf_id_t
ctf_lookup_by_name_internal (ctf_dict_t *fp, ctf_dict_t *child,
			     const char *name)
{
  static const char delimiters[] = " \t\n\r\v\f*";

  const ctf_lookup_t *lp;
  const char *p, *q, *end;
  ctf_id_t type = 0;
  ctf_id_t ntype, ptype;

  if (name == NULL)
    return (ctf_set_typed_errno (fp, EINVAL));

  for (p = name, end = name + strlen (name); *p != '\0'; p = q)
    {
      while (isspace ((int) *p))
	p++;			/* Skip leading whitespace.  */

      if (p == end)
	break;

      if ((q = strpbrk (p + 1, delimiters)) == NULL)
	q = end;		/* Compare until end.  */

      if (*p == '*')
	{
	  /* Find a pointer to type by looking in child->ctf_pptrtab (if child
	     is set) and 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 tries to access "foo_t *" in the
	     debugger.

	     There is extra complexity here because uninitialized elements in
	     the pptrtab and ptrtab are set to zero, but zero (as the type ID
	     meaning the unimplemented type) is a valid return type from
	     ctf_lookup_by_name.  (Pointers to types are never of type 0, so
	     this is unambiguous, just fiddly to deal with.)  */

	  uint32_t idx = LCTF_TYPE_TO_INDEX (fp, type);
	  int in_child = 0;

	  ntype = CTF_ERR;
	  if (child && idx < child->ctf_pptrtab_len)
	    {
	      ntype = child->ctf_pptrtab[idx];
	      if (ntype)
		in_child = 1;
	      else
		ntype = CTF_ERR;
	    }

	  if (ntype == CTF_ERR)
	    {
	      ntype = fp->ctf_ptrtab[idx];
	      if (ntype == 0)
		ntype = CTF_ERR;
	    }

	  /* Try resolving to its base type and check again.  */
	  if (ntype == CTF_ERR)
	    {
	      if (child)
		ntype = ctf_type_resolve_unsliced (child, type);
	      else
		ntype = ctf_type_resolve_unsliced (fp, type);

	      if (ntype == CTF_ERR)
		goto notype;

	      idx = LCTF_TYPE_TO_INDEX (fp, ntype);

	      ntype = CTF_ERR;
	      if (child && idx < child->ctf_pptrtab_len)
		{
		  ntype = child->ctf_pptrtab[idx];
		  if (ntype)
		    in_child = 1;
		  else
		    ntype = CTF_ERR;
		}

	      if (ntype == CTF_ERR)
		{
		  ntype = fp->ctf_ptrtab[idx];
		  if (ntype == 0)
		    ntype = CTF_ERR;
		}
	      if (ntype == CTF_ERR)
		goto notype;
	    }

	  type = LCTF_INDEX_TO_TYPE (fp, ntype, (fp->ctf_flags & LCTF_CHILD)
				     || in_child);

	  /* We are looking up a type in the parent, but the pointed-to type is
	     in the child.  Switch to looking in the child: if we need to go
	     back into the parent, we can recurse again.  */
	  if (in_child)
	    {
	      fp = child;
	      child = NULL;
	    }

	  q = p + 1;
	  continue;
	}

      if (isqualifier (p, (size_t) (q - p)))
	continue;		/* Skip qualifier keyword.  */

      for (lp = fp->ctf_lookups; lp->ctl_prefix != NULL; lp++)
	{
	  /* TODO: This is not MT-safe.  */
	  if ((lp->ctl_prefix[0] == '\0' ||
	       strncmp (p, lp->ctl_prefix, (size_t) (q - p)) == 0) &&
	      (size_t) (q - p) >= lp->ctl_len)
	    {
	      for (p += lp->ctl_len; isspace ((int) *p); p++)
		continue;	/* Skip prefix and next whitespace.  */

	      if ((q = strchr (p, '*')) == NULL)
		q = end;	/* Compare until end.  */

	      while (isspace ((int) q[-1]))
		q--;		/* Exclude trailing whitespace.  */

	      /* Expand and/or allocate storage for a slice of the name, then
		 copy it in.  */

	      if (fp->ctf_tmp_typeslicelen >= (size_t) (q - p) + 1)
		{
		  memcpy (fp->ctf_tmp_typeslice, p, (size_t) (q - p));
		  fp->ctf_tmp_typeslice[(size_t) (q - p)] = '\0';
		}
	      else
		{
		  free (fp->ctf_tmp_typeslice);
		  fp->ctf_tmp_typeslice = xstrndup (p, (size_t) (q - p));
		  if (fp->ctf_tmp_typeslice == NULL)
		    return ctf_set_typed_errno (fp, ENOMEM);
		}

	      if ((type = (ctf_id_t) (uintptr_t)
		   ctf_dynhash_lookup (lp->ctl_hash,
				       fp->ctf_tmp_typeslice)) == 0)
		goto notype;

	      break;
	    }
	}

      if (lp->ctl_prefix == NULL)
	goto notype;
    }

  if (*p != '\0' || type == 0)
    return (ctf_set_typed_errno (fp, ECTF_SYNTAX));

  return type;

 notype:
  ctf_set_errno (fp, ECTF_NOTYPE);
  if (fp->ctf_parent != NULL)
    {
      /* Need to look up in the parent, from the child's perspective.
	 Make sure the pptrtab is up to date.  */

      if (fp->ctf_pptrtab_typemax < fp->ctf_typemax)
	{
	  if (refresh_pptrtab (fp, fp->ctf_parent) < 0)
	    return CTF_ERR;			/* errno is set for us.  */
	}

      if ((ptype = ctf_lookup_by_name_internal (fp->ctf_parent, fp,
						name)) != CTF_ERR)
	return ptype;
      return (ctf_set_typed_errno (fp, ctf_errno (fp->ctf_parent)));
    }

  return CTF_ERR;
}

ctf_id_t
ctf_lookup_by_name (ctf_dict_t *fp, const char *name)
{
  return ctf_lookup_by_name_internal (fp, NULL, name);
}

/* Return the pointer to the internal CTF type data corresponding to the
   given type ID.  If the ID is invalid, the function returns NULL.
   This function is not exported outside of the library.  */

const ctf_type_t *
ctf_lookup_by_id (ctf_dict_t **fpp, ctf_id_t type)
{
  ctf_dict_t *fp = *fpp;
  ctf_id_t idx;

  if ((fp = ctf_get_dict (fp, type)) == NULL)
    {
      (void) ctf_set_errno (*fpp, ECTF_NOPARENT);
      return NULL;
    }

  idx = LCTF_TYPE_TO_INDEX (fp, type);
  if (idx > 0 && (unsigned long) idx <= fp->ctf_typemax)
    {
      *fpp = fp;		/* Possibly the parent CTF dict.  */
      return (LCTF_INDEX_TO_TYPEPTR (fp, idx));
    }

  (void) ctf_set_errno (*fpp, ECTF_BADID);
  return NULL;
}

typedef struct ctf_lookup_idx_key
{
  ctf_dict_t *clik_fp;
  const char *clik_name;
  uint32_t *clik_names;
} ctf_lookup_idx_key_t;

/* A bsearch function for variable names.  */

static int
ctf_lookup_var (const void *key_, const void *lookup_)
{
  const ctf_lookup_idx_key_t *key = key_;
  const ctf_varent_t *lookup = lookup_;

  return (strcmp (key->clik_name, ctf_strptr (key->clik_fp, lookup->ctv_name)));
}

/* Given a variable name, return the type of the variable with that name.
   Look only in this dict, not in the parent. */

ctf_id_t
ctf_lookup_variable_here (ctf_dict_t *fp, const char *name)
{
  ctf_dvdef_t *dvd = ctf_dvd_lookup (fp, name);
  ctf_varent_t *ent;
  ctf_lookup_idx_key_t key = { fp, name, NULL };

  if (dvd != NULL)
    return dvd->dvd_type;

  /* This array is sorted, so we can bsearch for it.  */

  ent = bsearch (&key, fp->ctf_vars, fp->ctf_nvars, sizeof (ctf_varent_t),
		 ctf_lookup_var);

  if (ent == NULL)
      return (ctf_set_typed_errno (fp, ECTF_NOTYPEDAT));

  return ent->ctv_type;
}

/* As above, but look in the parent too.  */

ctf_id_t
ctf_lookup_variable (ctf_dict_t *fp, const char *name)
{
  ctf_id_t type;

  if ((type = ctf_lookup_variable_here (fp, name)) == CTF_ERR)
    {
      if (ctf_errno (fp) == ECTF_NOTYPEDAT && fp->ctf_parent != NULL)
	{
	  if ((type = ctf_lookup_variable_here (fp->ctf_parent, name)) != CTF_ERR)
	    return type;
	  return (ctf_set_typed_errno (fp, ctf_errno (fp->ctf_parent)));
	}

      return -1;				/* errno is set for us.  */
    }

  return type;
}

/* Look up a single enumerator by enumeration constant name.  Returns the ID of
   the enum it is contained within and optionally its value.  Error out with
   ECTF_DUPLICATE if multiple exist (which can happen in some older dicts).  See
   ctf_lookup_enumerator_next in that case.  Enumeration constants in non-root
   types are not returned, but constants in parents are, if not overridden by
   an enum in the child..  */

ctf_id_t
ctf_lookup_enumerator (ctf_dict_t *fp, const char *name, int64_t *enum_value)
{
  ctf_id_t type;
  int enum_int_value;

  if (ctf_dynset_lookup (fp->ctf_conflicting_enums, name))
    return (ctf_set_typed_errno (fp, ECTF_DUPLICATE));

  /* CTF_K_UNKNOWN suffices for things like enumeration constants that aren't
     actually types at all (ending up in the global name table).  */
  type = ctf_lookup_by_rawname (fp, CTF_K_UNKNOWN, name);
  /* Nonexistent type? It may be in the parent.  */
  if (type == 0 && fp->ctf_parent)
    {
      if ((type = ctf_lookup_enumerator (fp->ctf_parent, name, enum_value)) == 0)
	return ctf_set_typed_errno (fp, ECTF_NOENUMNAM);
      return type;
    }

  /* Nothing more to do if this type didn't exist or we don't have to look up
     the enum value.  */
  if (type == 0)
    return ctf_set_typed_errno (fp, ECTF_NOENUMNAM);

  if (enum_value == NULL)
    return type;

  if (ctf_enum_value (fp, type, name, &enum_int_value) < 0)
    return CTF_ERR;
  *enum_value = enum_int_value;

  return type;
}

/* Return all enumeration constants with a given name in a given dict, similar
   to ctf_lookup_enumerator above but capable of returning multiple values.
   Enumerators in parent dictionaries are not returned: enumerators in
   hidden types *are* returned.  */

ctf_id_t
ctf_lookup_enumerator_next (ctf_dict_t *fp, const char *name,
			    ctf_next_t **it, int64_t *val)
{
  ctf_next_t *i = *it;
  int found = 0;

  /* We use ctf_type_next() to iterate across all types, but then traverse each
     enumerator found by hand: traversing enumerators is very easy, and it would
     probably be more confusing to use two nested iterators than to do it this
     way.  We use ctn_next to work over enums, then ctn_en and ctn_n to work
     over enumerators within each enum.  */
  if (!i)
    {
      if ((i = ctf_next_create ()) == NULL)
	return ctf_set_typed_errno (fp, ENOMEM);

      i->cu.ctn_fp = fp;
      i->ctn_iter_fun = (void (*) (void)) ctf_lookup_enumerator_next;
      i->ctn_increment = 0;
      i->ctn_tp = NULL;
      i->u.ctn_en = NULL;
      i->ctn_n = 0;
      *it = i;
    }

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

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

  do
    {
      const char *this_name;

      /* At end of enum? Traverse to next one, if any are left.  */

      if (i->u.ctn_en == NULL || i->ctn_n == 0)
	{
	  const ctf_type_t *tp;
	  ctf_dtdef_t *dtd;

	  do
	    i->ctn_type = ctf_type_next (i->cu.ctn_fp, &i->ctn_next, NULL, 1);
	  while (i->ctn_type != CTF_ERR
		 && ctf_type_kind_unsliced (i->cu.ctn_fp, i->ctn_type)
		 != CTF_K_ENUM);

	  if (i->ctn_type == CTF_ERR)
	    {
	      /* Conveniently, when the iterator over all types is done, so is the
		 iteration as a whole: so we can just pass all errors from the
		 internal iterator straight back out..  */
	      ctf_next_destroy (i);
	      *it = NULL;
	      return CTF_ERR;			/* errno is set for us.  */
	    }

	  if ((tp = ctf_lookup_by_id (&fp, i->ctn_type)) == NULL)
	    return CTF_ERR;			/* errno is set for us.  */
	  i->ctn_n = LCTF_INFO_VLEN (fp, tp->ctt_info);

	  dtd = ctf_dynamic_type (fp, i->ctn_type);

	  if (dtd == NULL)
	    {
	      (void) ctf_get_ctt_size (fp, tp, NULL, &i->ctn_increment);
	      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;
	}

      this_name = ctf_strptr (fp, i->u.ctn_en->cte_name);

      i->ctn_n--;

      if (strcmp (name, this_name) == 0)
	{
	  if (val)
	    *val = i->u.ctn_en->cte_value;
	  found = 1;

	  /* Constant found in this enum: try the next one.  (Constant names
	     cannot be duplicated within a given enum.)  */

	  i->ctn_n = 0;
	}

      i->u.ctn_en++;
    }
  while (!found);

  return i->ctn_type;
}

typedef struct ctf_symidx_sort_arg_cb
{
  ctf_dict_t *fp;
  uint32_t *names;
} ctf_symidx_sort_arg_cb_t;

static int
sort_symidx_by_name (const void *one_, const void *two_, void *arg_)
{
  const uint32_t *one = one_;
  const uint32_t *two = two_;
  ctf_symidx_sort_arg_cb_t *arg = arg_;

  return (strcmp (ctf_strptr (arg->fp, arg->names[*one]),
		  ctf_strptr (arg->fp, arg->names[*two])));
}

/* Sort a symbol index section by name.  Takes a 1:1 mapping of names to the
   corresponding symbol table.  Returns a lexicographically sorted array of idx
   indexes (and thus, of indexes into the corresponding func info / data object
   section).  */

static uint32_t *
ctf_symidx_sort (ctf_dict_t *fp, uint32_t *idx, size_t *nidx,
			 size_t len)
{
  uint32_t *sorted;
  size_t i;

  if ((sorted = malloc (len)) == NULL)
    {
      ctf_set_errno (fp, ENOMEM);
      return NULL;
    }

  *nidx = len / sizeof (uint32_t);
  for (i = 0; i < *nidx; i++)
    sorted[i] = i;

  if (!(fp->ctf_header->cth_flags & CTF_F_IDXSORTED))
    {
      ctf_symidx_sort_arg_cb_t arg = { fp, idx };
      ctf_dprintf ("Index section unsorted: sorting.\n");
      ctf_qsort_r (sorted, *nidx, sizeof (uint32_t), sort_symidx_by_name, &arg);
      fp->ctf_header->cth_flags |= CTF_F_IDXSORTED;
    }

  return sorted;
}

/* Given a symbol index, return the name of that symbol from the table provided
   by ctf_link_shuffle_syms, or failing that from the secondary string table, or
   the null string.  */
static const char *
ctf_lookup_symbol_name (ctf_dict_t *fp, unsigned long symidx)
{
  const ctf_sect_t *sp = &fp->ctf_ext_symtab;
  ctf_link_sym_t sym;
  int err;

  if (fp->ctf_dynsymidx)
    {
      err = EINVAL;
      if (symidx > fp->ctf_dynsymmax)
	goto try_parent;

      ctf_link_sym_t *symp = fp->ctf_dynsymidx[symidx];

      if (!symp)
	goto try_parent;

      return symp->st_name;
    }

  err = ECTF_NOSYMTAB;
  if (sp->cts_data == NULL)
    goto try_parent;

  if (symidx >= fp->ctf_nsyms)
    goto try_parent;

  switch (sp->cts_entsize)
    {
    case sizeof (Elf64_Sym):
      {
	const Elf64_Sym *symp = (Elf64_Sym *) sp->cts_data + symidx;
	ctf_elf64_to_link_sym (fp, &sym, symp, symidx);
      }
      break;
    case sizeof (Elf32_Sym):
      {
	const Elf32_Sym *symp = (Elf32_Sym *) sp->cts_data + symidx;
	ctf_elf32_to_link_sym (fp, &sym, symp, symidx);
      }
      break;
    default:
      ctf_set_errno (fp, ECTF_SYMTAB);
      return _CTF_NULLSTR;
    }

  assert (!sym.st_nameidx_set);

  return sym.st_name;

 try_parent:
  if (fp->ctf_parent)
    {
      const char *ret;
      ret = ctf_lookup_symbol_name (fp->ctf_parent, symidx);
      if (ret == NULL)
	ctf_set_errno (fp, ctf_errno (fp->ctf_parent));
      return ret;
    }
  else
    {
      ctf_set_errno (fp, err);
      return _CTF_NULLSTR;
    }
}

/* Given a symbol name, return the index of that symbol, or -1 on error or if
   not found.  If is_function is >= 0, return only function or data object
   symbols, respectively.  */
static unsigned long
ctf_lookup_symbol_idx (ctf_dict_t *fp, const char *symname, int try_parent,
		       int is_function)
{
  const ctf_sect_t *sp = &fp->ctf_ext_symtab;
  ctf_link_sym_t sym;
  void *known_idx;
  int err;
  ctf_dict_t *cache = fp;

  if (fp->ctf_dynsyms)
    {
      err = EINVAL;

      ctf_link_sym_t *symp;

      if (((symp = ctf_dynhash_lookup (fp->ctf_dynsyms, symname)) == NULL)
	  || (symp->st_type != STT_OBJECT && is_function == 0)
	  || (symp->st_type != STT_FUNC && is_function == 1))
	goto try_parent;

      return symp->st_symidx;
    }

  err = ECTF_NOSYMTAB;
  if (sp->cts_data == NULL)
    goto try_parent;

  /* First, try a hash lookup to see if we have already spotted this symbol
     during a past iteration: create the hash first if need be.  The
     lifespan of the strings is equal to the lifespan of the cts_data, so we
     don't need to strdup them.  If this dict was opened as part of an
     archive, and this archive has a crossdict_cache to cache results that
     are the same across all dicts in an archive, use it.  */

  if (fp->ctf_archive && fp->ctf_archive->ctfi_crossdict_cache)
    cache = fp->ctf_archive->ctfi_crossdict_cache;

  if (!cache->ctf_symhash_func)
    if ((cache->ctf_symhash_func = ctf_dynhash_create (ctf_hash_string,
						       ctf_hash_eq_string,
						       NULL, NULL)) == NULL)
      goto oom;

  if (!cache->ctf_symhash_objt)
    if ((cache->ctf_symhash_objt = ctf_dynhash_create (ctf_hash_string,
						       ctf_hash_eq_string,
						       NULL, NULL)) == NULL)
      goto oom;

  if (is_function != 0 &&
      ctf_dynhash_lookup_kv (cache->ctf_symhash_func, symname, NULL, &known_idx))
    return (unsigned long) (uintptr_t) known_idx;

  if (is_function != 1 &&
      ctf_dynhash_lookup_kv (cache->ctf_symhash_objt, symname, NULL, &known_idx))
    return (unsigned long) (uintptr_t) known_idx;

  /* Hash lookup unsuccessful: linear search, populating the hashtab for later
     lookups as we go.  */

  for (; cache->ctf_symhash_latest < sp->cts_size / sp->cts_entsize;
       cache->ctf_symhash_latest++)
    {
      ctf_dynhash_t *h;

      switch (sp->cts_entsize)
	{
	case sizeof (Elf64_Sym):
	  {
	    Elf64_Sym *symp = (Elf64_Sym *) sp->cts_data;

	    ctf_elf64_to_link_sym (fp, &sym, &symp[cache->ctf_symhash_latest],
				   cache->ctf_symhash_latest);
	  }
	  break;
	case sizeof (Elf32_Sym):
	  {
	    Elf32_Sym *symp = (Elf32_Sym *) sp->cts_data;
	    ctf_elf32_to_link_sym (fp, &sym, &symp[cache->ctf_symhash_latest],
				   cache->ctf_symhash_latest);
	    break;
	  }
	default:
	  ctf_set_errno (fp, ECTF_SYMTAB);
	  return (unsigned long) -1;
	}

      if (sym.st_type == STT_FUNC)
	h = cache->ctf_symhash_func;
      else if (sym.st_type == STT_OBJECT)
	h = cache->ctf_symhash_objt;
      else
	continue;					/* Not of interest.  */

      if (!ctf_dynhash_lookup_kv (h, sym.st_name,
				  NULL, NULL))
	if (ctf_dynhash_cinsert (h, sym.st_name,
				 (const void *) (uintptr_t)
				 cache->ctf_symhash_latest) < 0)
	  goto oom;
      if (strcmp (sym.st_name, symname) == 0)
	return cache->ctf_symhash_latest++;
    }

  /* Searched everything, still not found.  */

  return (unsigned long) -1;

 try_parent:
  if (fp->ctf_parent && try_parent)
    {
      unsigned long psym;

      if ((psym = ctf_lookup_symbol_idx (fp->ctf_parent, symname, try_parent,
					 is_function))
          != (unsigned long) -1)
        return psym;

      ctf_set_errno (fp, ctf_errno (fp->ctf_parent));
      return (unsigned long) -1;
    }
  else
    {
      ctf_set_errno (fp, err);
      return (unsigned long) -1;
    }
oom:
  ctf_set_errno (fp, ENOMEM);
  ctf_err_warn (fp, 0, 0, _("cannot allocate memory for symbol "
			    "lookup hashtab"));
  return (unsigned long) -1;

}

ctf_id_t
ctf_symbol_next_static (ctf_dict_t *fp, ctf_next_t **it, const char **name,
			int functions);

/* Iterate over all symbols with types: if FUNC, function symbols,
   otherwise, data symbols.  The name argument is not optional.  The return
   order is arbitrary, though is likely to be in symbol index or name order.
   Changing the value of 'functions' in the middle of iteration has
   unpredictable effects (probably skipping symbols, etc) and is not
   recommended.  Adding symbols while iteration is underway may also lead
   to other symbols being skipped.  */

ctf_id_t
ctf_symbol_next (ctf_dict_t *fp, ctf_next_t **it, const char **name,
		 int functions)
{
  ctf_id_t sym = CTF_ERR;
  ctf_next_t *i = *it;
  int err;

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

      i->cu.ctn_fp = fp;
      i->ctn_iter_fun = (void (*) (void)) ctf_symbol_next;
      i->ctn_n = 0;
      *it = i;
    }

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

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

  /* Check the dynamic set of names first, to allow previously-written names
     to be replaced with dynamic ones (there is still no way to remove them,
     though).

     We intentionally use raw access, not ctf_lookup_by_symbol, to avoid
     incurring additional sorting cost for unsorted symtypetabs coming from the
     compiler, to allow ctf_symbol_next to work in the absence of a symtab, and
     finally because it's easier to work out what the name of each symbol is if
     we do that.  */

  ctf_dynhash_t *dynh = functions ? fp->ctf_funchash : fp->ctf_objthash;
  void *dyn_name = NULL, *dyn_value = NULL;
  size_t dyn_els = dynh ? ctf_dynhash_elements (dynh) : 0;

  if (i->ctn_n < dyn_els)
    {
      err = ctf_dynhash_next (dynh, &i->ctn_next, &dyn_name, &dyn_value);

      /* This covers errors and also end-of-iteration.  */
      if (err != 0)
	{
	  ctf_next_destroy (i);
	  *it = NULL;
	  return ctf_set_typed_errno (fp, err);
	}

      *name = dyn_name;
      sym = (ctf_id_t) (uintptr_t) dyn_value;
      i->ctn_n++;

      return sym;
    }

  return ctf_symbol_next_static (fp, it, name, functions);
}

/* ctf_symbol_next, but only for static symbols.  Mostly an internal
   implementation detail of ctf_symbol_next, but also used to simplify
   serialization.  */
ctf_id_t
ctf_symbol_next_static (ctf_dict_t *fp, ctf_next_t **it, const char **name,
			int functions)
{
  ctf_id_t sym = CTF_ERR;
  ctf_next_t *i = *it;
  ctf_dynhash_t *dynh = functions ? fp->ctf_funchash : fp->ctf_objthash;
  size_t dyn_els = dynh ? ctf_dynhash_elements (dynh) : 0;

  /* Only relevant for direct internal-to-library calls, not via
     ctf_symbol_next (but important then).  */

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

      i->cu.ctn_fp = fp;
      i->ctn_iter_fun = (void (*) (void)) ctf_symbol_next;
      i->ctn_n = dyn_els;
      *it = i;
    }

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

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

  /* TODO-v4: Indexed after non-indexed portions?  */

  if ((!functions && fp->ctf_objtidx_names) ||
      (functions && fp->ctf_funcidx_names))
    {
      ctf_header_t *hp = fp->ctf_header;
      uint32_t *idx = functions ? fp->ctf_funcidx_names : fp->ctf_objtidx_names;
      uint32_t *tab;
      size_t len;

      if (functions)
	{
	  len = (hp->cth_varoff - hp->cth_funcidxoff) / sizeof (uint32_t);
	  tab = (uint32_t *) (fp->ctf_buf + hp->cth_funcoff);
	}
      else
	{
	  len = (hp->cth_funcidxoff - hp->cth_objtidxoff) / sizeof (uint32_t);
	  tab = (uint32_t *) (fp->ctf_buf + hp->cth_objtoff);
	}

      do
	{
	  if (i->ctn_n - dyn_els >= len)
	    goto end;

	  *name = ctf_strptr (fp, idx[i->ctn_n - dyn_els]);
	  sym = tab[i->ctn_n - dyn_els];
	  i->ctn_n++;
	}
      while (sym == -1u || sym == 0);
    }
  else
    {
      /* Skip over pads in ctf_sxlate, padding for typeless symbols in the
	 symtypetab itself, and symbols in the wrong table.  */
      for (; i->ctn_n - dyn_els < fp->ctf_nsyms; i->ctn_n++)
	{
	  ctf_header_t *hp = fp->ctf_header;
	  size_t n = i->ctn_n - dyn_els;

	  if (fp->ctf_sxlate[n] == -1u)
	    continue;

	  sym = *(uint32_t *) ((uintptr_t) fp->ctf_buf + fp->ctf_sxlate[n]);

	  if (sym == 0)
	    continue;

	  if (functions)
	    {
	      if (fp->ctf_sxlate[n] >= hp->cth_funcoff
		  && fp->ctf_sxlate[n] < hp->cth_objtidxoff)
		break;
	    }
	  else
	    {
	      if (fp->ctf_sxlate[n] >= hp->cth_objtoff
		  && fp->ctf_sxlate[n] < hp->cth_funcoff)
		break;
	    }
	}

      if (i->ctn_n - dyn_els >= fp->ctf_nsyms)
	goto end;

      *name = ctf_lookup_symbol_name (fp, i->ctn_n - dyn_els);
      i->ctn_n++;
    }

  return sym;

 end:
  ctf_next_destroy (i);
  *it = NULL;
  return (ctf_set_typed_errno (fp, ECTF_NEXT_END));
}

/* A bsearch function for function and object index names.  */

static int
ctf_lookup_idx_name (const void *key_, const void *idx_)
{
  const ctf_lookup_idx_key_t *key = key_;
  const uint32_t *idx = idx_;

  return (strcmp (key->clik_name, ctf_strptr (key->clik_fp, key->clik_names[*idx])));
}

/* Given a symbol name or (failing that) number, look up that symbol in the
   function or object index table (which must exist).  Return 0 if not found
   there (or pad).  */

static ctf_id_t
ctf_try_lookup_indexed (ctf_dict_t *fp, unsigned long symidx,
			const char *symname, int is_function)
{
  struct ctf_header *hp = fp->ctf_header;
  uint32_t *symtypetab;
  uint32_t *names;
  uint32_t *sxlate;
  size_t nidx;

  if (symname == NULL)
    symname = ctf_lookup_symbol_name (fp, symidx);

  /* Dynamic dict with no static portion: just return.  */
  if (!hp)
    {
      ctf_dprintf ("%s not found in idx: dict is dynamic\n", symname);
      return 0;
    }

  ctf_dprintf ("Looking up type of object with symtab idx %lx or name %s in "
	       "indexed symtypetab\n", symidx, symname);

  if (symname[0] == '\0')
    return CTF_ERR;					/* errno is set for us.  */

  if (is_function)
    {
      if (!fp->ctf_funcidx_sxlate)
	{
	  if ((fp->ctf_funcidx_sxlate
	       = ctf_symidx_sort (fp, (uint32_t *)
				  (fp->ctf_buf + hp->cth_funcidxoff),
				  &fp->ctf_nfuncidx,
				  hp->cth_varoff - hp->cth_funcidxoff))
	      == NULL)
	    {
	      ctf_err_warn (fp, 0, 0, _("cannot sort function symidx"));
	      return CTF_ERR;				/* errno is set for us.  */
	    }
	}
      symtypetab = (uint32_t *) (fp->ctf_buf + hp->cth_funcoff);
      sxlate = fp->ctf_funcidx_sxlate;
      names = fp->ctf_funcidx_names;
      nidx = fp->ctf_nfuncidx;
    }
  else
    {
      if (!fp->ctf_objtidx_sxlate)
	{
	  if ((fp->ctf_objtidx_sxlate
	       = ctf_symidx_sort (fp, (uint32_t *)
				  (fp->ctf_buf + hp->cth_objtidxoff),
				  &fp->ctf_nobjtidx,
				  hp->cth_funcidxoff - hp->cth_objtidxoff))
	      == NULL)
	    {
	      ctf_err_warn (fp, 0, 0, _("cannot sort object symidx"));
	      return CTF_ERR;				/* errno is set for us. */
	    }
	}

      symtypetab = (uint32_t *) (fp->ctf_buf + hp->cth_objtoff);
      sxlate = fp->ctf_objtidx_sxlate;
      names = fp->ctf_objtidx_names;
      nidx = fp->ctf_nobjtidx;
    }

  ctf_lookup_idx_key_t key = { fp, symname, names };
  uint32_t *idx;

  idx = bsearch (&key, sxlate, nidx, sizeof (uint32_t), ctf_lookup_idx_name);

  if (!idx)
    {
      ctf_dprintf ("%s not found in idx\n", symname);
      return 0;
    }

  /* Should be impossible, but be paranoid.  */
  if ((idx - sxlate) > (ptrdiff_t) nidx)
    return (ctf_set_typed_errno (fp, ECTF_CORRUPT));

  ctf_dprintf ("Symbol %lx (%s) is of type %x\n", symidx, symname,
	       symtypetab[*idx]);
  return symtypetab[*idx];
}

/* Given a symbol name or (if NULL) symbol index, return the type of the
   function or data object described by the corresponding entry in the symbol
   table.  We can only return symbols in read-only dicts and in dicts for which
   ctf_link_shuffle_syms has been called to assign symbol indexes to symbol
   names.

   If try_parent is false, do not check the parent dict too.

   If is_function is > -1, only look for data objects or functions in
   particular.  */

ctf_id_t
ctf_lookup_by_sym_or_name (ctf_dict_t *fp, unsigned long symidx,
			   const char *symname, int try_parent,
			   int is_function)
{
  const ctf_sect_t *sp = &fp->ctf_ext_symtab;
  ctf_id_t type = 0;
  int err = 0;

  /* Shuffled dynsymidx present?  Use that.  For now, the dynsymidx and
     shuffled-symbol lookup only support dynamically-added symbols, because
     this interface is meant for use by linkers, and linkers are only going
     to report symbols against newly-created, freshly-ctf_link'ed dicts: so
     there will be no static component in any case.  */
  if (fp->ctf_dynsymidx)
    {
      const ctf_link_sym_t *sym;

      if (symname)
	ctf_dprintf ("Looking up type of object with symname %s in "
		     "writable dict symtypetab\n", symname);
      else
	ctf_dprintf ("Looking up type of object with symtab idx %lx in "
		     "writable dict symtypetab\n", symidx);

      /* No name? Need to look it up.  */
      if (!symname)
	{
	  err = EINVAL;
	  if (symidx > fp->ctf_dynsymmax)
	    goto try_parent;

	  sym = fp->ctf_dynsymidx[symidx];
	  err = ECTF_NOTYPEDAT;
	  if (!sym || (sym->st_type != STT_OBJECT && sym->st_type != STT_FUNC)
	      || (sym->st_type != STT_OBJECT && is_function == 0)
	      || (sym->st_type != STT_FUNC && is_function == 1))
	    goto try_parent;

	  if (!ctf_assert (fp, !sym->st_nameidx_set))
	    return CTF_ERR;
	  symname = sym->st_name;
     }

      if (fp->ctf_objthash == NULL
	  || is_function == 1
	  || (type = (ctf_id_t) (uintptr_t)
	      ctf_dynhash_lookup (fp->ctf_objthash, symname)) == 0)
	{
	  if (fp->ctf_funchash == NULL
	      || is_function == 0
	      || (type = (ctf_id_t) (uintptr_t)
		  ctf_dynhash_lookup (fp->ctf_funchash, symname)) == 0)
	    goto try_parent;
	}

      return type;
    }

  /* Dict not shuffled: look for a dynamic sym first, and look it up
     directly.  */
  if (symname)
    {
      if (fp->ctf_objthash != NULL
	  && is_function != 1
	  && ((type = (ctf_id_t) (uintptr_t)
	       ctf_dynhash_lookup (fp->ctf_objthash, symname)) != 0))
	return type;

      if (fp->ctf_funchash != NULL
	  && is_function != 0
	  && ((type = (ctf_id_t) (uintptr_t)
	       ctf_dynhash_lookup (fp->ctf_funchash, symname)) != 0))
	return type;
    }

  err = ECTF_NOSYMTAB;
  if (sp->cts_data == NULL && symname == NULL &&
      ((is_function && !fp->ctf_funcidx_names) ||
       (!is_function && !fp->ctf_objtidx_names)))
    goto try_parent;

  /* This covers both out-of-range lookups by index and a dynamic dict which
     hasn't been shuffled yet.  */
  err = EINVAL;
  if (symname == NULL && symidx >= fp->ctf_nsyms)
    goto try_parent;

  /* Try an indexed lookup.  */

  if (fp->ctf_objtidx_names && is_function != 1)
    {
      if ((type = ctf_try_lookup_indexed (fp, symidx, symname, 0)) == CTF_ERR)
	return CTF_ERR;				/* errno is set for us.  */
    }
  if (type == 0 && fp->ctf_funcidx_names && is_function != 0)
    {
      if ((type = ctf_try_lookup_indexed (fp, symidx, symname, 1)) == CTF_ERR)
	return CTF_ERR;				/* errno is set for us.  */
    }
  if (type != 0)
    return type;

  /* Indexed but no symbol found -> not present, try the parent.  */
  err = ECTF_NOTYPEDAT;
  if (fp->ctf_objtidx_names && fp->ctf_funcidx_names)
    goto try_parent;

  /* Table must be nonindexed.  */

  ctf_dprintf ("Looking up object type %lx in 1:1 dict symtypetab\n", symidx);

  if (symname != NULL)
    if ((symidx = ctf_lookup_symbol_idx (fp, symname, try_parent, is_function))
	== (unsigned long) -1)
      goto try_parent;

  if (fp->ctf_sxlate[symidx] == -1u)
    goto try_parent;

  type = *(uint32_t *) ((uintptr_t) fp->ctf_buf + fp->ctf_sxlate[symidx]);

  if (type == 0)
    goto try_parent;

  return type;

 try_parent:
  if (!try_parent)
    return ctf_set_errno (fp, err);

  if (fp->ctf_parent)
    {
      ctf_id_t ret = ctf_lookup_by_sym_or_name (fp->ctf_parent, symidx,
						symname, try_parent,
						is_function);
      if (ret == CTF_ERR)
	ctf_set_errno (fp, ctf_errno (fp->ctf_parent));
      return ret;
    }
  else
    return (ctf_set_typed_errno (fp, err));
}

/* Given a symbol table index, return the type of the function or data object
   described by the corresponding entry in the symbol table.  */
ctf_id_t
ctf_lookup_by_symbol (ctf_dict_t *fp, unsigned long symidx)
{
  return ctf_lookup_by_sym_or_name (fp, symidx, NULL, 1, -1);
}

/* Given a symbol name, return the type of the function or data object described
   by the corresponding entry in the symbol table.  */
ctf_id_t
ctf_lookup_by_symbol_name (ctf_dict_t *fp, const char *symname)
{
  return ctf_lookup_by_sym_or_name (fp, 0, symname, 1, -1);
}

/* Given a symbol table index, return the info for the function described
   by the corresponding entry in the symbol table, which may be a function
   symbol or may be a data symbol that happens to be a function pointer.  */

int
ctf_func_info (ctf_dict_t *fp, unsigned long symidx, ctf_funcinfo_t *fip)
{
  ctf_id_t type;

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

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

  return ctf_func_type_info (fp, type, fip);
}

/* Given a symbol table index, return the arguments for the function described
   by the corresponding entry in the symbol table.  */

int
ctf_func_args (ctf_dict_t *fp, unsigned long symidx, uint32_t argc,
	       ctf_id_t *argv)
{
  ctf_id_t type;

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

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

  return ctf_func_type_args (fp, type, argc, argv);
}
