/* 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_lookup_by_rawhash (fp, lp->ctl_hash,
						 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;
    }

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

  /* Check for a type in the static portion.  */

  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));
    }

  (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;
}
