/* Symbol, variable and name lookup.
   Copyright (C) 2019 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>

/* 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 = &qhash[h];

  return (h >= 0 && (size_t) h < sizeof (qhash) / sizeof (qhash[0])
	  && (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.  */

ctf_id_t
ctf_lookup_by_name (ctf_file_t *fp, 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_errno (fp, EINVAL));

  for (p = name, end = name + strlen (name); *p != '\0'; p = q)
    {
      while (isspace (*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 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.

	     TODO need to handle parent containers too.  */

	  ntype = fp->ctf_ptrtab[LCTF_TYPE_TO_INDEX (fp, type)];
	  if (ntype == 0)
	    {
	      ntype = ctf_type_resolve_unsliced (fp, type);
	      if (ntype == CTF_ERR
		  || (ntype =
		      fp->ctf_ptrtab[LCTF_TYPE_TO_INDEX (fp, ntype)]) == 0)
		{
		  (void) ctf_set_errno (fp, ECTF_NOTYPE);
		  goto err;
		}
	    }

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

	  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 (*p); p++)
		continue;	/* Skip prefix and next whitespace.  */

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

	      while (isspace (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)
		    {
		      (void) ctf_set_errno (fp, ENOMEM);
		      return CTF_ERR;
		    }
		}

	      if ((type = ctf_hash_lookup_type (lp->ctl_hash, fp,
						fp->ctf_tmp_typeslice)) == 0)
		{
		  (void) ctf_set_errno (fp, ECTF_NOTYPE);
		  goto err;
		}

	      break;
	    }
	}

      if (lp->ctl_prefix == NULL)
	{
	  (void) ctf_set_errno (fp, ECTF_NOTYPE);
	  goto err;
	}
    }

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

  return type;

err:
  if (fp->ctf_parent != NULL
      && (ptype = ctf_lookup_by_name (fp->ctf_parent, name)) != CTF_ERR)
    return ptype;

  return CTF_ERR;
}

typedef struct ctf_lookup_var_key
{
  ctf_file_t *clvk_fp;
  const char *clvk_name;
} ctf_lookup_var_key_t;

/* A bsearch function for variable names.  */

static int
ctf_lookup_var (const void *key_, const void *memb_)
{
  const ctf_lookup_var_key_t *key = key_;
  const ctf_varent_t *memb = memb_;

  return (strcmp (key->clvk_name, ctf_strptr (key->clvk_fp, memb->ctv_name)));
}

/* Given a variable name, return the type of the variable with that name.  */

ctf_id_t
ctf_lookup_variable (ctf_file_t *fp, const char *name)
{
  ctf_varent_t *ent;
  ctf_lookup_var_key_t key = { fp, name };

  /* 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)
    {
      if (fp->ctf_parent != NULL)
	return ctf_lookup_variable (fp->ctf_parent, name);

      return (ctf_set_errno (fp, ECTF_NOTYPEDAT));
    }

  return ent->ctv_type;
}

/* Given a symbol table index, return the name of that symbol from the secondary
   string table, or the null string (never NULL).  */
const char *
ctf_lookup_symbol_name (ctf_file_t *fp, unsigned long symidx)
{
  const ctf_sect_t *sp = &fp->ctf_symtab;
  Elf64_Sym sym, *gsp;

  if (sp->cts_data == NULL)
    {
      ctf_set_errno (fp, ECTF_NOSYMTAB);
      return _CTF_NULLSTR;
    }

  if (symidx >= fp->ctf_nsyms)
    {
      ctf_set_errno (fp, EINVAL);
      return _CTF_NULLSTR;
    }

  if (sp->cts_entsize == sizeof (Elf32_Sym))
    {
      const Elf32_Sym *symp = (Elf32_Sym *) sp->cts_data + symidx;
      gsp = ctf_sym_to_elf64 (symp, &sym);
    }
  else
      gsp = (Elf64_Sym *) sp->cts_data + symidx;

  if (gsp->st_name < fp->ctf_str[CTF_STRTAB_1].cts_len)
    return (const char *) fp->ctf_str[CTF_STRTAB_1].cts_strs + gsp->st_name;

  return _CTF_NULLSTR;
}

/* Given a symbol table index, return the type of the data object described
   by the corresponding entry in the symbol table.  */

ctf_id_t
ctf_lookup_by_symbol (ctf_file_t *fp, unsigned long symidx)
{
  const ctf_sect_t *sp = &fp->ctf_symtab;
  ctf_id_t type;

  if (sp->cts_data == NULL)
    return (ctf_set_errno (fp, ECTF_NOSYMTAB));

  if (symidx >= fp->ctf_nsyms)
    return (ctf_set_errno (fp, EINVAL));

  if (sp->cts_entsize == sizeof (Elf32_Sym))
    {
      const Elf32_Sym *symp = (Elf32_Sym *) sp->cts_data + symidx;
      if (ELF32_ST_TYPE (symp->st_info) != STT_OBJECT)
	return (ctf_set_errno (fp, ECTF_NOTDATA));
    }
  else
    {
      const Elf64_Sym *symp = (Elf64_Sym *) sp->cts_data + symidx;
      if (ELF64_ST_TYPE (symp->st_info) != STT_OBJECT)
	return (ctf_set_errno (fp, ECTF_NOTDATA));
    }

  if (fp->ctf_sxlate[symidx] == -1u)
    return (ctf_set_errno (fp, ECTF_NOTYPEDAT));

  type = *(uint32_t *) ((uintptr_t) fp->ctf_buf + fp->ctf_sxlate[symidx]);
  if (type == 0)
    return (ctf_set_errno (fp, ECTF_NOTYPEDAT));

  return type;
}

/* 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_file_t **fpp, ctf_id_t type)
{
  ctf_file_t *fp = *fpp;	/* Caller passes in starting CTF container.  */
  ctf_id_t idx;

  if ((fp->ctf_flags & LCTF_CHILD) && LCTF_TYPE_ISPARENT (fp, type)
      && (fp = fp->ctf_parent) == 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;		/* Function returns ending CTF container.  */
      return (LCTF_INDEX_TO_TYPEPTR (fp, idx));
    }

  /* If this container is writable, check for a dynamic type.  */

  if (fp->ctf_flags & LCTF_RDWR)
    {
      ctf_dtdef_t *dtd;

      if ((dtd = ctf_dynamic_type (fp, type)) != NULL)
	{
	  *fpp = fp;
	  return &dtd->dtd_data;
	}
    }
  (void) ctf_set_errno (*fpp, ECTF_BADID);
  return NULL;
}

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

int
ctf_func_info (ctf_file_t *fp, unsigned long symidx, ctf_funcinfo_t *fip)
{
  const ctf_sect_t *sp = &fp->ctf_symtab;
  const uint32_t *dp;
  uint32_t info, kind, n;

  if (sp->cts_data == NULL)
    return (ctf_set_errno (fp, ECTF_NOSYMTAB));

  if (symidx >= fp->ctf_nsyms)
    return (ctf_set_errno (fp, EINVAL));

  if (sp->cts_entsize == sizeof (Elf32_Sym))
    {
      const Elf32_Sym *symp = (Elf32_Sym *) sp->cts_data + symidx;
      if (ELF32_ST_TYPE (symp->st_info) != STT_FUNC)
	return (ctf_set_errno (fp, ECTF_NOTFUNC));
    }
  else
    {
      const Elf64_Sym *symp = (Elf64_Sym *) sp->cts_data + symidx;
      if (ELF64_ST_TYPE (symp->st_info) != STT_FUNC)
	return (ctf_set_errno (fp, ECTF_NOTFUNC));
    }

  if (fp->ctf_sxlate[symidx] == -1u)
    return (ctf_set_errno (fp, ECTF_NOFUNCDAT));

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

  info = *dp++;
  kind = LCTF_INFO_KIND (fp, info);
  n = LCTF_INFO_VLEN (fp, info);

  if (kind == CTF_K_UNKNOWN && n == 0)
    return (ctf_set_errno (fp, ECTF_NOFUNCDAT));

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

  fip->ctc_return = *dp++;
  fip->ctc_argc = n;
  fip->ctc_flags = 0;

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

  return 0;
}

/* 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_file_t * fp, unsigned long symidx, uint32_t argc,
	       ctf_id_t * argv)
{
  const uint32_t *dp;
  ctf_funcinfo_t f;

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

  /* The argument data is two uint32_t's past the translation table
     offset: one for the function info, and one for the return type. */

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

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

  return 0;
}
