/* Generate CTF.
   Copyright (C) 2019-2022 Free Software Foundation, Inc.

This file is part of GCC.

GCC 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.

GCC 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 GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "target.h"
#include "toplev.h"
#include "ctfc.h"
#include "diagnostic-core.h"

/* A CTF container object - one per translation unit.  */

ctf_container_ref tu_ctfc;

ctf_container_ref
ctf_get_tu_ctfc (void)
{
  return tu_ctfc;
}

/* If the next ctf type id is still set to the init value, no ctf records to
   report.  */
bool
ctfc_is_empty_container (ctf_container_ref ctfc)
{
  return ((ctfc)->ctfc_nextid == CTF_INIT_TYPEID);
}

/* Get the total number of CTF types in the container.  */

unsigned int
ctfc_get_num_ctf_types (ctf_container_ref ctfc)
{
  return ctfc->ctfc_types->elements ();
}

/* Get the total number of CTF variables in the container.  */

unsigned int ctfc_get_num_ctf_vars (ctf_container_ref ctfc)
{
  return ctfc->ctfc_vars->elements ();
}

/* Get reference to the CTF string table or the CTF auxilliary
   string table.  */

ctf_strtable_t *
ctfc_get_strtab (ctf_container_ref ctfc, int aux)
{
  return aux ? &(ctfc)->ctfc_aux_strtable : &(ctfc->ctfc_strtable);
}

/* Get the length of the specified string table of the CTF container.  */

size_t
ctfc_get_strtab_len (ctf_container_ref ctfc, int aux)
{
  ctf_strtable_t * strtab = ctfc_get_strtab (ctfc, aux);
  return strtab->ctstab_len;
}

/* Get the number of bytes to represent the variable length portion of all CTF
   types in the CTF container.  */

size_t ctfc_get_num_vlen_bytes (ctf_container_ref ctfc)
{
  return ctfc->ctfc_num_vlen_bytes;
}

/* Return which member of the union is used in CTFTYPE.  Used for garbage
   collection.  */

enum ctf_dtu_d_union_enum
ctf_dtu_d_union_selector (ctf_dtdef_ref ctftype)
{
  uint32_t kind = CTF_V2_INFO_KIND (ctftype->dtd_data.ctti_info);
  switch (kind)
    {
    case CTF_K_UNKNOWN:
    case CTF_K_INTEGER:
    case CTF_K_FLOAT:
      return CTF_DTU_D_ENCODING;
    case CTF_K_STRUCT:
    case CTF_K_UNION:
    case CTF_K_ENUM:
      return CTF_DTU_D_MEMBERS;
    case CTF_K_ARRAY:
      return CTF_DTU_D_ARRAY;
    case CTF_K_FUNCTION:
      return CTF_DTU_D_ARGUMENTS;
    case CTF_K_SLICE:
      return CTF_DTU_D_SLICE;
    default:
      /* The largest member as default.  */
      return CTF_DTU_D_ARRAY;
    }
}

/* Insert CTF type into the CTF container.  */

static void
ctf_dtd_insert (ctf_container_ref ctfc, ctf_dtdef_ref dtd)
{
  bool existed = false;
  ctf_dtdef_ref entry = dtd;

  ctf_dtdef_ref * item = ctfc->ctfc_types->find_slot (entry, INSERT);
  if (*item == NULL)
     *item = dtd;
  else
    existed = true;
  /* Duplicate CTF type records not expected to be inserted.  */
  gcc_assert (!existed);
}

/* Lookup CTF type given a DWARF die for the type.  */

ctf_dtdef_ref
ctf_dtd_lookup (const ctf_container_ref ctfc, const dw_die_ref type)
{
  ctf_dtdef_t entry;
  entry.dtd_key = type;

  ctf_dtdef_ref * slot = ctfc->ctfc_types->find_slot (&entry, NO_INSERT);

  if (slot)
    return (ctf_dtdef_ref)*slot;

  return NULL;
}

/* Insert CTF variable into the CTF container.  */

static void
ctf_dvd_insert (ctf_container_ref ctfc, ctf_dvdef_ref dvd)
{
  bool existed = false;
  ctf_dvdef_ref entry = dvd;

  ctf_dvdef_ref * item = ctfc->ctfc_vars->find_slot (entry, INSERT);
  if (*item == NULL)
     *item = dvd;
  else
    existed = true;
  /* Duplicate variable records not expected to be inserted.  */
  gcc_assert (!existed);
}

/* Lookup CTF variable given a DWARF die for the decl.  */

ctf_dvdef_ref
ctf_dvd_lookup (const ctf_container_ref ctfc, dw_die_ref die)
{
  ctf_dvdef_t entry;
  entry.dvd_key = die;

  ctf_dvdef_ref * slot = ctfc->ctfc_vars->find_slot (&entry, NO_INSERT);

  if (slot)
    return (ctf_dvdef_ref)*slot;

  return NULL;
}

/* Insert a dummy CTF variable into the list of variables to be ignored.  */

static void
ctf_dvd_ignore_insert (ctf_container_ref ctfc, ctf_dvdef_ref dvd)
{
  bool existed = false;
  ctf_dvdef_ref entry = dvd;

  ctf_dvdef_ref * item = ctfc->ctfc_ignore_vars->find_slot (entry, INSERT);
  if (*item == NULL)
     *item = dvd;
  else
    existed = true;
  /* Duplicate variable records not expected to be inserted.  */
  gcc_assert (!existed);
}

/* Lookup the dummy CTF variable given the DWARF die for the non-defining
   decl to be ignored.  */

bool
ctf_dvd_ignore_lookup (const ctf_container_ref ctfc, dw_die_ref die)
{
  ctf_dvdef_t entry;
  entry.dvd_key = die;

  ctf_dvdef_ref * slot = ctfc->ctfc_ignore_vars->find_slot (&entry, NO_INSERT);

  if (slot)
    return true;

  return false;
}

/* Append member definition to the list.  Member list is a singly-linked list
   with list start pointing to the head.  */

static void
ctf_dmd_list_append (ctf_dmdef_t ** dmd, ctf_dmdef_t * elem)
{
  ctf_dmdef_t * tail = (dmd && *dmd) ? *dmd : NULL;
  if (tail)
    {
      while (tail->dmd_next)
	tail = tail->dmd_next;

      tail->dmd_next = elem;
    }
  else
    *dmd = elem;

  elem->dmd_next = NULL;
}

/* Append function argument to the list.  Member list is a singly-linked list
   with list start pointing to the head.  */

static void
ctf_farg_list_append (ctf_func_arg_t ** farg, ctf_func_arg_t * elem)
{
  ctf_func_arg_t * tail = (farg && *farg) ? *farg : NULL;
  if (tail)
    {
      while (tail->farg_next)
	tail = tail->farg_next;

      tail->farg_next = elem;
    }
  else
    *farg = elem;

  elem->farg_next = NULL;
}

/* Append str to the CTF string table.  */

static void
ctfc_strtable_append_str (ctf_strtable_t * str_table, const char * str)
{
  ctf_string_t * ctf_string = ggc_cleared_alloc<ctf_string_t> ();
  /* Keep a reference to the input STR.  */
  ctf_string->cts_str = str;
  ctf_string->cts_next = NULL;

  if (!str_table->ctstab_head)
    str_table->ctstab_head = ctf_string;

  /* Append to the end of the list.  */
  if (str_table->ctstab_tail)
    str_table->ctstab_tail->cts_next = ctf_string;

  str_table->ctstab_tail = ctf_string;
}

/* Wrapper function to add str to the CTF string table.  No de-duplication of
   CTF strings is done by the compiler.  */

static const char *
ctfc_strtable_add_str (ctf_strtable_t * str_table, const char * name,
		      uint32_t * name_offset)
{
  size_t len;
  char * ctf_string;
  /* Return value is the offset to the string in the string table.  */
  uint32_t str_offset = str_table->ctstab_len;

  /* Add empty string only once at the beginning of the string table.  Also, do
     not add null strings, return the offset to the empty string for them.  */
  if ((!name || (name != NULL && !strcmp (name, ""))) && str_offset)
    {
      ctf_string = CONST_CAST (char *, str_table->ctstab_estr);
      str_offset = 0;
    }
  else
    {
      gcc_assert (name);
      /* Add null-terminated strings to the string table.  */
      len = strlen (name) + 1;
      ctf_string = CONST_CAST (char *, ggc_strdup (name));

      ctfc_strtable_append_str (str_table, ctf_string);
      /* Add string to the string table.  Keep number of strings updated.  */
      str_table->ctstab_num++;
      /* Keep the number of bytes contained in the string table updated.  */
      str_table->ctstab_len += len;
    }

  *name_offset = str_offset;

  return (const char *) ctf_string;

}

/* Add string to the appropriate string table in the CTF container.  */

const char *
ctf_add_string (ctf_container_ref ctfc, const char * name,
		uint32_t * name_offset, int aux_str = CTF_STRTAB)
{
  /* Get the CTF string table or the CTF auxilliary string table,
     as applicable.  */
  ctf_strtable_t *str_table = ctfc_get_strtab (ctfc, aux_str);
  return ctfc_strtable_add_str (str_table, name, name_offset);
}

/* Add the compilation unit (CU) name string to the CTF string table.  The
   CU name has a prepended pwd string if it is a relative path.  Also set the
   CU name offset in the CTF container.  */

void
ctf_add_cuname (ctf_container_ref ctfc, const char * filename)
{
  char * cuname = NULL;

  /* (filename at this point of compilation cannot be null).  */

  if (!IS_DIR_SEPARATOR (filename[0]))
    {
      /* Filename is a relative path.  */
      const char * cu_pwd = get_src_pwd ();
      const int cu_pwd_len = strlen (cu_pwd);

      /* Add a DIR_SEPARATOR char before the filename.  */
      const int len = cu_pwd_len + 2 + strlen (filename);

      cuname = (char *) ggc_alloc_atomic (len);
      memset (cuname, 0, len);

      strcpy (cuname, cu_pwd);
      cuname[cu_pwd_len] = DIR_SEPARATOR;
      cuname[cu_pwd_len+1] = 0;
      strcat (cuname, filename);
    }
  else
    /* Filename is an absolute path.  */
    cuname = CONST_CAST (char *, ggc_strdup (filename));

  ctf_add_string (ctfc, cuname, &(ctfc->ctfc_cuname_offset));
  /* Add 1 as CTF strings in the CTF string table are null-terminated
     strings.  */
  ctfc->ctfc_strlen += strlen (cuname) + 1;

  /* Mark cuname for garbage collection.  */
  cuname = NULL;
}

/* Functions to create CTF types.

   These functions perform the task of adding CTF types to the CTF container.
   No de-duplication is done by them; the onus is on the calling function to do
   so.  The caller must first do a lookup via ctf_dtd_lookup or
   ctf_dvd_lookup, as applicable, to ascertain that the CTF type or the CTF
   variable respectively does not already exist, and then add it.  */

static ctf_id_t
ctf_add_generic (ctf_container_ref ctfc, uint32_t flag, const char * name,
		 ctf_dtdef_ref * rp, dw_die_ref die)
{
  ctf_dtdef_ref dtd;
  ctf_id_t type;

  gcc_assert (flag == CTF_ADD_NONROOT || flag == CTF_ADD_ROOT);

  dtd = ggc_cleared_alloc<ctf_dtdef_t> ();

  type = ctfc->ctfc_nextid++;
  gcc_assert (type < CTF_MAX_TYPE); /* CTF type ID overflow.  */

  /* Buffer the strings in the CTF string table.  */
  dtd->dtd_name = ctf_add_string (ctfc, name, &(dtd->dtd_data.ctti_name));
  dtd->dtd_type = type;
  dtd->dtd_key = die;

  if ((name != NULL) && strcmp (name, ""))
    ctfc->ctfc_strlen += strlen (name) + 1;

  ctf_dtd_insert (ctfc, dtd);

  *rp = dtd;
  return type;
}

static ctf_id_t
ctf_add_encoded (ctf_container_ref ctfc, uint32_t flag, const char * name,
		 const ctf_encoding_t * ep, uint32_t kind, dw_die_ref die)
{
  ctf_dtdef_ref dtd;
  ctf_id_t type;

  type = ctf_add_generic (ctfc, flag, name, &dtd, die);

  dtd->dtd_data.ctti_info = CTF_TYPE_INFO (kind, flag, 0);

  uint32_t roundup_nbytes = (ROUND_UP (ep->cte_bits, BITS_PER_UNIT)
				    / BITS_PER_UNIT);

  /* FIXME, stay close to what libctf does.  But by getting next power of two,
     aren't we conveying less precise information.  E.g. floating point mode
     XF has a size of 12 bytes.  */
  dtd->dtd_data.ctti_size = roundup_nbytes ? (1 << ceil_log2 (roundup_nbytes))
			   : roundup_nbytes;
  dtd->dtd_u.dtu_enc = *ep;

  ctfc->ctfc_num_stypes++;

  return type;
}

ctf_id_t
ctf_add_reftype (ctf_container_ref ctfc, uint32_t flag, ctf_id_t ref,
		 uint32_t kind, dw_die_ref die)
{
  ctf_dtdef_ref dtd;
  ctf_id_t type;

  gcc_assert (ref <= CTF_MAX_TYPE);

  type = ctf_add_generic (ctfc, flag, NULL, &dtd, die);
  dtd->dtd_data.ctti_info = CTF_TYPE_INFO (kind, flag, 0);
  /* Caller of this API must guarantee that a CTF type with id = ref already
     exists.  This will also be validated for us at link-time.  */
  dtd->dtd_data.ctti_type = (uint32_t) ref;

  ctfc->ctfc_num_stypes++;

  return type;
}

ctf_id_t
ctf_add_forward (ctf_container_ref ctfc, uint32_t flag, const char * name,
		 uint32_t kind, dw_die_ref die)
{
  ctf_dtdef_ref dtd;
  ctf_id_t type = 0;

  type = ctf_add_generic (ctfc, flag, name, &dtd, die);

  dtd->dtd_data.ctti_info = CTF_TYPE_INFO (CTF_K_FORWARD, flag, 0);
  dtd->dtd_data.ctti_type = kind;

  ctfc->ctfc_num_stypes++;

  return type;
}

ctf_id_t
ctf_add_typedef (ctf_container_ref ctfc, uint32_t flag, const char * name,
		 ctf_id_t ref, dw_die_ref die)
{
  ctf_dtdef_ref dtd;
  ctf_id_t type;

  gcc_assert (ref <= CTF_MAX_TYPE);
  /* Nameless Typedefs are not expected.  */
  gcc_assert ((name != NULL) && strcmp (name, ""));

  type = ctf_add_generic (ctfc, flag, name, &dtd, die);
  dtd->dtd_data.ctti_info = CTF_TYPE_INFO (CTF_K_TYPEDEF, flag, 0);
  /* Caller of this API must guarantee that a CTF type with id = ref already
     exists.  This will also be validated for us at link-time.  */
  dtd->dtd_data.ctti_type = (uint32_t) ref;

  gcc_assert (dtd->dtd_type != dtd->dtd_data.ctti_type);

  ctfc->ctfc_num_stypes++;

  return type;
}

ctf_id_t
ctf_add_slice (ctf_container_ref ctfc, uint32_t flag, ctf_id_t ref,
	       uint32_t bit_offset, uint32_t bit_size, dw_die_ref die)
{
  ctf_dtdef_ref dtd;
  ctf_id_t type;
  uint32_t roundup_nbytes;

  gcc_assert ((bit_size <= 255) && (bit_offset <= 255));

  gcc_assert (ref <= CTF_MAX_TYPE);

  type = ctf_add_generic (ctfc, flag, NULL, &dtd, die);

  dtd->dtd_data.ctti_info = CTF_TYPE_INFO (CTF_K_SLICE, flag, 0);

  roundup_nbytes = (ROUND_UP (bit_size, BITS_PER_UNIT) / BITS_PER_UNIT);
  /* FIXME, stay close to what libctf does.  But by getting next power of two,
     aren't we conveying less precise information, especially for bitfields.
     For example, cte_bits = 33, roundup_nbytes = 5, ctti_size = 8 in the
     implementation below.  */
  dtd->dtd_data.ctti_size = roundup_nbytes ? (1 << ceil_log2 (roundup_nbytes))
					   : 0;

  /* Caller of this API must guarantee that a CTF type with id = ref already
     exists.  This will also be validated for us at link-time.  */
  dtd->dtd_u.dtu_slice.cts_type = (uint32_t) ref;
  dtd->dtd_u.dtu_slice.cts_bits = bit_size;
  dtd->dtd_u.dtu_slice.cts_offset = bit_offset;

  ctfc->ctfc_num_stypes++;

  return type;
}

ctf_id_t
ctf_add_float (ctf_container_ref ctfc, uint32_t flag,
	       const char * name, const ctf_encoding_t * ep, dw_die_ref die)
{
  return (ctf_add_encoded (ctfc, flag, name, ep, CTF_K_FLOAT, die));
}

ctf_id_t
ctf_add_integer (ctf_container_ref ctfc, uint32_t flag,
		 const char * name, const ctf_encoding_t * ep, dw_die_ref die)
{
  return (ctf_add_encoded (ctfc, flag, name, ep, CTF_K_INTEGER, die));
}

ctf_id_t
ctf_add_unknown (ctf_container_ref ctfc, uint32_t flag,
		 const char * name, const ctf_encoding_t * ep, dw_die_ref die)
{
  return (ctf_add_encoded (ctfc, flag, name, ep, CTF_K_UNKNOWN, die));
}

ctf_id_t
ctf_add_pointer (ctf_container_ref ctfc, uint32_t flag, ctf_id_t ref,
		 dw_die_ref die)
{
  return (ctf_add_reftype (ctfc, flag, ref, CTF_K_POINTER, die));
}

ctf_id_t
ctf_add_array (ctf_container_ref ctfc, uint32_t flag, const ctf_arinfo_t * arp,
	       dw_die_ref die)
{
  ctf_dtdef_ref dtd;
  ctf_id_t type;

  gcc_assert (arp);

  /* Caller of this API must make sure CTF type for arp->ctr_contents and
     arp->ctr_index are already added.  This will also be validated for us at
     link-time.  */

  type = ctf_add_generic (ctfc, flag, NULL, &dtd, die);

  dtd->dtd_data.ctti_info = CTF_TYPE_INFO (CTF_K_ARRAY, flag, 0);
  dtd->dtd_data.ctti_size = 0;
  dtd->dtd_u.dtu_arr = *arp;

  ctfc->ctfc_num_stypes++;

  return type;
}

ctf_id_t
ctf_add_enum (ctf_container_ref ctfc, uint32_t flag, const char * name,
	      HOST_WIDE_INT size, dw_die_ref die)
{
  ctf_dtdef_ref dtd;
  ctf_id_t type;

  /* In the compiler, no need to handle the case of promoting forwards to
     enums.  This comment is simply to note a divergence from libctf.  */

  /* The compiler does, however, update any previously existing forward types
     to non-root.  CTF does not allow existence of two root types with the same
     name.  */
  ctf_dtdef_ref enum_fwd_type = ctf_dtd_lookup (ctfc, die);
  if (enum_fwd_type)
    {
      enum_fwd_type->dtd_data.ctti_info
	= CTF_TYPE_INFO (CTF_K_FORWARD, CTF_ADD_NONROOT, 0);
    }

  type = ctf_add_generic (ctfc, flag, name, &dtd, die);

  dtd->dtd_data.ctti_info = CTF_TYPE_INFO (CTF_K_ENUM, flag, 0);

  /* Size in bytes should always fit, of course.
     TBD WARN - warn instead?  */
  gcc_assert (size <= CTF_MAX_SIZE);

  dtd->dtd_data.ctti_size = size;

  ctfc->ctfc_num_stypes++;

  return type;
}

int
ctf_add_enumerator (ctf_container_ref ctfc, ctf_id_t enid, const char * name,
		    HOST_WIDE_INT value, dw_die_ref die)
{
  ctf_dmdef_t * dmd;
  uint32_t kind, vlen, root;

  /* Callers of this API must make sure that CTF_K_ENUM with enid has been
     addded.  This will also be validated for us at link-time.  */
  ctf_dtdef_ref dtd = ctf_dtd_lookup (ctfc, die);
  gcc_assert (dtd);
  gcc_assert (dtd->dtd_type == enid);
  gcc_assert (name);

  kind = CTF_V2_INFO_KIND (dtd->dtd_data.ctti_info);
  root = CTF_V2_INFO_ISROOT (dtd->dtd_data.ctti_info);
  vlen = CTF_V2_INFO_VLEN (dtd->dtd_data.ctti_info);

  gcc_assert (kind == CTF_K_ENUM && vlen < CTF_MAX_VLEN);

  /* Enum value is of type HOST_WIDE_INT in the compiler, dmd_value is int32_t
     on the other hand.  Check bounds and skip adding this enum value if out of
     bounds.  */
  if ((value > INT_MAX) || (value < INT_MIN))
    {
      /* FIXME - Note this TBD_CTF_REPRESENTATION_LIMIT.  */
      return (1);
    }

  dmd = ggc_cleared_alloc<ctf_dmdef_t> ();

  /* Buffer the strings in the CTF string table.  */
  dmd->dmd_name = ctf_add_string (ctfc, name, &(dmd->dmd_name_offset));
  dmd->dmd_type = CTF_NULL_TYPEID;
  dmd->dmd_offset = 0;

  dmd->dmd_value = value;

  dtd->dtd_data.ctti_info = CTF_TYPE_INFO (kind, root, vlen + 1);
  ctf_dmd_list_append (&dtd->dtd_u.dtu_members, dmd);

  if ((name != NULL) && strcmp (name, ""))
    ctfc->ctfc_strlen += strlen (name) + 1;

  return (0);
}

int
ctf_add_member_offset (ctf_container_ref ctfc, dw_die_ref sou,
		       const char * name, ctf_id_t type,
		       uint64_t bit_offset)
{
  ctf_dtdef_ref dtd = ctf_dtd_lookup (ctfc, sou);
  ctf_dmdef_t * dmd;

  uint32_t kind, vlen, root;

  /* The type of the member being added must already exist.  */
  gcc_assert (dtd);

  kind = CTF_V2_INFO_KIND (dtd->dtd_data.ctti_info);
  root = CTF_V2_INFO_ISROOT (dtd->dtd_data.ctti_info);
  vlen = CTF_V2_INFO_VLEN (dtd->dtd_data.ctti_info);

  gcc_assert (kind == CTF_K_STRUCT || kind == CTF_K_UNION);
  gcc_assert (vlen < CTF_MAX_VLEN);

  dmd = ggc_cleared_alloc<ctf_dmdef_t> ();

  /* Buffer the strings in the CTF string table.  */
  dmd->dmd_name = ctf_add_string (ctfc, name, &(dmd->dmd_name_offset));
  dmd->dmd_type = type;
  dmd->dmd_value = -1;

  if (kind == CTF_K_STRUCT && vlen != 0)
    dmd->dmd_offset = bit_offset;
  else
    dmd->dmd_offset = 0;

  dtd->dtd_data.ctti_info = CTF_TYPE_INFO (kind, root, vlen + 1);
  ctf_dmd_list_append (&dtd->dtd_u.dtu_members, dmd);

  if ((name != NULL) && strcmp (name, ""))
    ctfc->ctfc_strlen += strlen (name) + 1;

  return 0;
}

int
ctf_add_variable (ctf_container_ref ctfc, const char * name, ctf_id_t ref,
		  dw_die_ref die, unsigned int external_vis,
		  dw_die_ref die_var_decl)
{
  ctf_dvdef_ref dvd, dvd_ignore;

  gcc_assert (name);

  if (name != NULL)
    {
      dvd = ggc_cleared_alloc<ctf_dvdef_t> ();
      dvd->dvd_key = die;
      /* Buffer the strings in the CTF string table.  */
      dvd->dvd_name = ctf_add_string (ctfc, name, &(dvd->dvd_name_offset));
      dvd->dvd_visibility = external_vis;
      dvd->dvd_type = ref;

      /* If DW_AT_specification attribute exists, keep track of it as this is
	 the non-defining declaration corresponding to the variable.  We will
	 skip emitting CTF variable for such incomplete, non-defining
	 declarations.
	 There could be some non-defining declarations, however, for which a
	 defining declaration does not show up in the same CU.  For such
	 cases, the compiler continues to emit CTF variable record as
	 usual.  */
      if (die_var_decl)
	{
	  dvd_ignore = ggc_cleared_alloc<ctf_dvdef_t> ();
	  dvd_ignore->dvd_key = die_var_decl;
	  /* It's alright to leave other fields as zero.  No valid CTF
	     variable will be added for these DW_TAG_variable DIEs.  */
	  ctf_dvd_ignore_insert (ctfc, dvd_ignore);
	}

      ctf_dvd_insert (ctfc, dvd);

      if (strcmp (name, ""))
	ctfc->ctfc_strlen += strlen (name) + 1;
    }

  return 0;
}

int
ctf_add_function_arg (ctf_container_ref ctfc, dw_die_ref func,
		      const char * name, ctf_id_t type)
{
  ctf_dtdef_ref dtd = ctf_dtd_lookup (ctfc, func);
  ctf_func_arg_t * farg;
  uint32_t vlen;

  /* The function to which argument is being added must already exist.  */
  gcc_assert (dtd);
  /* The number of args must have been non-zero.  */
  vlen = CTF_V2_INFO_VLEN (dtd->dtd_data.ctti_info);
  gcc_assert (vlen);

  farg = ggc_cleared_alloc<ctf_func_arg_t> ();

  /* Buffer the strings in the auxilliary string table.  CTF V3 format does not
     require function argument names.  Use auxilliary string table to keep
     these strings to avoid unnecessary bloat in CTF section in CTF V3.  */
  farg->farg_name = ctf_add_string (ctfc, name, &(farg->farg_name_offset),
				    CTF_AUX_STRTAB);
  farg->farg_type = type;

  ctf_farg_list_append (&dtd->dtd_u.dtu_argv, farg);

  /* For aux_str, keep ctfc_aux_strlen updated for debugging.  */
  if ((name != NULL) && strcmp (name, ""))
    ctfc->ctfc_aux_strlen += strlen (name) + 1;

  return 0;
}

ctf_id_t
ctf_add_function (ctf_container_ref ctfc, uint32_t flag, const char * name,
		  const ctf_funcinfo_t * ctc, dw_die_ref die,
		  bool from_global_func, int linkage)
{
  ctf_dtdef_ref dtd;
  ctf_id_t type;
  uint32_t vlen;

  gcc_assert (ctc);

  vlen = ctc->ctc_argc;
  gcc_assert (vlen <= CTF_MAX_VLEN);

  type = ctf_add_generic (ctfc, flag, name, &dtd, die);

  dtd->from_global_func = from_global_func;
  dtd->linkage = linkage;
  dtd->dtd_data.ctti_info = CTF_TYPE_INFO (CTF_K_FUNCTION, flag, vlen);
  /* Caller must make sure CTF types for ctc->ctc_return are already added.  */
  dtd->dtd_data.ctti_type = (uint32_t) ctc->ctc_return;
  /* Caller must make sure CTF types for function arguments are already added
     via ctf_add_function_arg () API.  */

  ctfc->ctfc_num_stypes++;

  return type;
}

ctf_id_t
ctf_add_sou (ctf_container_ref ctfc, uint32_t flag, const char * name,
	     uint32_t kind, size_t size, dw_die_ref die)
{
  ctf_dtdef_ref dtd;
  ctf_id_t type = 0;

  gcc_assert ((kind == CTF_K_STRUCT) || (kind == CTF_K_UNION));

  /* In the compiler, no need to handle the case of promoting forwards to
     structs.  This comment is simply to note a divergence from libctf.  */

  /* The compiler does, however, update any previously existing forward types
     to non-root.  CTF does not allow existence of two root types with the same
     name.  */
  ctf_dtdef_ref sou_fwd_type = ctf_dtd_lookup (ctfc, die);
  if (sou_fwd_type)
    {
      sou_fwd_type->dtd_data.ctti_info
	= CTF_TYPE_INFO (CTF_K_FORWARD, CTF_ADD_NONROOT, 0);
    }

  type = ctf_add_generic (ctfc, flag, name, &dtd, die);

  dtd->dtd_data.ctti_info = CTF_TYPE_INFO (kind, flag, 0);

  if (size > CTF_MAX_SIZE)
    {
      dtd->dtd_data.ctti_size = CTF_LSIZE_SENT;
      dtd->dtd_data.ctti_lsizehi = CTF_SIZE_TO_LSIZE_HI (size);
      dtd->dtd_data.ctti_lsizelo = CTF_SIZE_TO_LSIZE_LO (size);
      ctfc->ctfc_num_types++;
    }
  else
    {
      dtd->dtd_data.ctti_size = (uint32_t) size;
      ctfc->ctfc_num_stypes++;
    }

  return type;
}

/* Given a TREE_TYPE node, return the CTF type ID for that type.  */

ctf_id_t
ctf_lookup_tree_type (ctf_container_ref ctfc, const tree type)
{
  dw_die_ref die = lookup_type_die (type);
  if (die == NULL)
    return CTF_NULL_TYPEID;

  ctf_dtdef_ref dtd = ctf_dtd_lookup (ctfc, die);
  if (dtd == NULL)
    return CTF_NULL_TYPEID;

  return dtd->dtd_type;
}

/* Check if CTF for TYPE has already been generated.  Mainstay for
   de-duplication.  If CTF type already exists, returns TRUE and updates
   the TYPE_ID for the caller.  */

bool
ctf_type_exists (ctf_container_ref ctfc, dw_die_ref type,
		 ctf_id_t * type_id)
{
  bool exists = false;
  ctf_dtdef_ref ctf_type_seen = ctf_dtd_lookup (ctfc, type);

  if (ctf_type_seen)
    {
      exists = true;
      /* CTF type for this type exists.  */
      *type_id = ctf_type_seen->dtd_type;
    }

  return exists;
}

/* Location information for CTF Types and CTF Variables.  CTF section does not
   emit location information; at this time, location information is needed for
   BTF CO-RE use-cases.  */

int
ctfc_get_dtd_srcloc (ctf_dtdef_ref dtd, ctf_srcloc_ref loc)
{
  loc->ctsloc_file = ctf_get_die_loc_file (dtd->dtd_key);
  loc->ctsloc_line = ctf_get_die_loc_line (dtd->dtd_key);
  loc->ctsloc_col = ctf_get_die_loc_col (dtd->dtd_key);

  if (loc->ctsloc_file == NULL)
    return 1;

  return 0;
}

int
ctfc_get_dvd_srcloc (ctf_dvdef_ref dvd, ctf_srcloc_ref loc)
{
  loc->ctsloc_file = ctf_get_die_loc_file (dvd->dvd_key);
  loc->ctsloc_line = ctf_get_die_loc_line (dvd->dvd_key);
  loc->ctsloc_col = ctf_get_die_loc_col (dvd->dvd_key);

  if (loc->ctsloc_file == NULL)
    return 1;

  return 0;
}

/* CTF container setup and teardown routines.  */

/* Initialize the CTF string table.
   The first entry in the CTF string table (empty string) is added.  */

static void
init_ctf_strtable (ctf_strtable_t * strtab)
{
  strtab->ctstab_head = NULL;
  strtab->ctstab_tail = NULL;
  strtab->ctstab_num = 0;
  strtab->ctstab_len = 0;

  /* The first entry in the CTF string table is an empty string.  E.g., CTF
     type records with no name (like CTF_K_CONST, CTF_K_VOLATILE etc) point to
     this string.  */
  uint32_t estr_offset = 0;
  strtab->ctstab_estr = ctfc_strtable_add_str (strtab, "", &estr_offset);
}

/* Initialize the string tables in the CTF container.  */

static void
init_ctf_string_table (ctf_container_ref ctfc)
{
  init_ctf_strtable (&ctfc->ctfc_strtable);
  ctfc->ctfc_strlen++;

  init_ctf_strtable (&ctfc->ctfc_aux_strtable);
  ctfc->ctfc_aux_strlen++;
}

/* Allocate a new CTF container with the desired flags.  */

static inline ctf_container_ref
new_ctf_container (void)
{
  tu_ctfc = ggc_cleared_alloc<ctf_container_t> ();
  tu_ctfc->ctfc_types
    = hash_table<ctfc_dtd_hasher>::create_ggc (100);
  tu_ctfc->ctfc_vars
    = hash_table<ctfc_dvd_hasher>::create_ggc (100);
  tu_ctfc->ctfc_ignore_vars
    = hash_table<ctfc_dvd_hasher>::create_ggc (10);

  return tu_ctfc;
}

/* Initialize a CTF container per translation unit.  */

static void
init_ctf_container (void)
{
  tu_ctfc = new_ctf_container ();

  tu_ctfc->ctfc_magic = CTF_MAGIC;
  tu_ctfc->ctfc_version = CTF_VERSION;
  tu_ctfc->ctfc_flags = CTF_F_NEWFUNCINFO;
  tu_ctfc->ctfc_nextid = CTF_INIT_TYPEID;

  init_ctf_string_table (tu_ctfc);
}

void
ctfc_delete_strtab (ctf_strtable_t * strtab)
{
  ctf_string_t * str = NULL;
  ctf_string_t * next_str = NULL;

  str = strtab->ctstab_head;
  next_str = str;
  while (next_str != NULL)
    {
      next_str = str->cts_next;
      ggc_free (str);
      str = next_str;
    }

  strtab->ctstab_head = NULL;
  strtab->ctstab_tail = NULL;
  strtab->ctstab_estr = NULL;
}

/* Delete the CTF container's resources.  */

void
ctfc_delete_container (ctf_container_ref ctfc)
{
  if (ctfc)
    {
      ctfc->ctfc_types->empty ();
      ctfc->ctfc_types = NULL;

      ctfc->ctfc_vars->empty ();
      ctfc->ctfc_types = NULL;

      ctfc->ctfc_ignore_vars->empty ();
      ctfc->ctfc_ignore_vars = NULL;

      ctfc_delete_strtab (&ctfc->ctfc_strtable);
      ctfc_delete_strtab (&ctfc->ctfc_aux_strtable);
      if (ctfc->ctfc_vars_list)
	{
	  ggc_free (ctfc->ctfc_vars_list);
	  ctfc->ctfc_vars_list = NULL;
	}
      if (ctfc->ctfc_types_list)
	{
	  ggc_free (ctfc->ctfc_types_list);
	  ctfc->ctfc_types_list = NULL;
	}
      if (ctfc->ctfc_gfuncs_list)
	{
	  ggc_free (ctfc->ctfc_gfuncs_list);
	  ctfc->ctfc_gfuncs_list = NULL;
	}
      if (ctfc->ctfc_gobjts_list)
	{
	  ggc_free (ctfc->ctfc_gobjts_list);
	  ctfc->ctfc_gobjts_list = NULL;
	}

      ctfc= NULL;
    }
}

/* CTF routines interfacing to the compiler.  */

void
ctf_init (void)
{
  init_ctf_container ();
}
