/* Compact ANSI-C Type Format (CTF) support in GDB.

   Copyright (C) 2019-2021 Free Software Foundation, Inc.

   This file is part of GDB.

   This program 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 of the License, 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.  If not, see <http://www.gnu.org/licenses/>.  */

/* This file format can be used to compactly represent the information needed
   by a debugger to interpret the ANSI-C types used by a given program.
   Traditionally, this kind of information is generated by the compiler when
   invoked with the -g flag and is stored in "stabs" strings or in the more
   modern DWARF format. A new -gtLEVEL option has been added in gcc to generate
   such information. CTF provides a representation of only the information
   that is relevant to debugging a complex, optimized C program such as the
   operating system kernel in a form that is significantly more compact than
   the equivalent stabs or DWARF representation.  The format is data-model
   independent, so consumers do not need different code depending on whether
   they are 32-bit or 64-bit programs.  CTF assumes that a standard ELF symbol
   table is available for use in the debugger, and uses the structure and data
   of the symbol table to avoid storing redundant information.  The CTF data
   may be compressed on disk or in memory, indicated by a bit in the header.
   CTF may be interpreted in a raw disk file, or it may be stored in an ELF
   section, typically named .ctf.  Data structures are aligned so that a raw
   CTF file or CTF ELF section may be manipulated using mmap(2).

   The CTF file or section itself has the following structure:

   +--------+--------+---------+----------+----------+-------+--------+
   |  file  |  type  |  data   | function | variable | data  | string |
   | header | labels | objects |   info   |   info   | types | table  |
   +--------+--------+---------+----------+----------+-------+--------+

   The file header stores a magic number and version information, encoding
   flags, and the byte offset of each of the sections relative to the end of the
   header itself.  If the CTF data has been uniquified against another set of
   CTF data, a reference to that data also appears in the header.  This
   reference is the name of the label corresponding to the types uniquified
   against.

   Following the header is a list of labels, used to group the types included in
   the data types section.  Each label is accompanied by a type ID i.  A given
   label refers to the group of types whose IDs are in the range [0, i].

   Data object and function records are stored in the same order as they appear
   in the corresponding symbol table, except that symbols marked SHN_UNDEF are
   not stored and symbols that have no type data are padded out with zeroes.
   For each data object, the type ID (a small integer) is recorded.  For each
   function, the type ID of the return type and argument types is recorded.

   Variable records (as distinct from data objects) provide a modicum of support
   for non-ELF systems, mapping a variable name to a CTF type ID.  The variable
   names are sorted into ASCIIbetical order, permitting binary searching.

   The data types section is a list of variable size records that represent each
   type, in order by their ID.  The types themselves form a directed graph,
   where each node may contain one or more outgoing edges to other type nodes,
   denoted by their ID.

   Strings are recorded as a string table ID (0 or 1) and a byte offset into the
   string table.  String table 0 is the internal CTF string table.  String table
   1 is the external string table, which is the string table associated with the
   ELF symbol table for this object.  CTF does not record any strings that are
   already in the symbol table, and the CTF string table does not contain any
   duplicated strings.  */

#include "defs.h"
#include "buildsym.h"
#include "complaints.h"
#include "block.h"
#include "ctfread.h"
#include "psympriv.h"

#if ENABLE_LIBCTF

#include "ctf.h"
#include "ctf-api.h"

static const struct objfile_key<htab, htab_deleter> ctf_tid_key;

struct ctf_fp_info
{
  explicit ctf_fp_info (ctf_file_t *cfp) : fp (cfp) {}
  ~ctf_fp_info ();
  ctf_file_t *fp;
};

/* Cleanup function for the ctf_file_key data.  */
ctf_fp_info::~ctf_fp_info ()
{
  if (!fp)
    return;

  ctf_archive_t *arc = ctf_get_arc (fp);
  ctf_file_close (fp);
  ctf_close (arc);
}

static const objfile_key<ctf_fp_info> ctf_file_key;

/* A CTF context consists of a file pointer and an objfile pointer.  */

struct ctf_context
{
  ctf_file_t *fp;
  struct objfile *of;
  struct buildsym_compunit *builder;
};

/* A partial symtab, specialized for this module.  */
struct ctf_psymtab : public standard_psymtab
{
  ctf_psymtab (const char *filename, struct objfile *objfile, CORE_ADDR addr)
    : standard_psymtab (filename, objfile, addr)
  {
  }

  void read_symtab (struct objfile *) override;
  void expand_psymtab (struct objfile *) override;

  struct ctf_context *context;
};

/* The routines that read and process fields/members of a C struct, union,
   or enumeration, pass lists of data member fields in an instance of a
   ctf_field_info structure. It is derived from dwarf2read.c.  */

struct ctf_nextfield
{
  struct field field {};
};

struct ctf_field_info
{
  /* List of data member fields.  */
  std::vector<struct ctf_nextfield> fields;

  /* Context.  */
  struct ctf_context *cur_context;

  /* Parent type.  */
  struct type *ptype;

  /* typedefs defined inside this class.  TYPEDEF_FIELD_LIST contains head
     of a NULL terminated list of TYPEDEF_FIELD_LIST_COUNT elements.  */
  std::vector<struct decl_field> typedef_field_list;

  /* Nested types defined by this struct and the number of elements in
     this list.  */
  std::vector<struct decl_field> nested_types_list;
};


/* Local function prototypes */

static int ctf_add_type_cb (ctf_id_t tid, void *arg);

static struct type *read_array_type (struct ctf_context *cp, ctf_id_t tid);

static struct type *read_pointer_type (struct ctf_context *cp, ctf_id_t tid,
				       ctf_id_t btid);

static struct type *read_structure_type (struct ctf_context *cp, ctf_id_t tid);

static struct type *read_enum_type (struct ctf_context *cp, ctf_id_t tid);

static struct type *read_typedef_type (struct ctf_context *cp, ctf_id_t tid,
				       ctf_id_t btid, const char *name);

static struct type *read_type_record (struct ctf_context *cp, ctf_id_t tid);

static void process_structure_type (struct ctf_context *cp, ctf_id_t tid);

static void process_struct_members (struct ctf_context *cp, ctf_id_t tid,
				    struct type *type);

static struct symbol *new_symbol (struct ctf_context *cp, struct type *type,
				  ctf_id_t tid);

struct ctf_tid_and_type
{
  ctf_id_t tid;
  struct type *type;
};

/* Hash function for a ctf_tid_and_type.  */

static hashval_t
tid_and_type_hash (const void *item)
{
  const struct ctf_tid_and_type *ids
    = (const struct ctf_tid_and_type *) item;

  return ids->tid;
}

/* Equality function for a ctf_tid_and_type.  */

static int
tid_and_type_eq (const void *item_lhs, const void *item_rhs)
{
  const struct ctf_tid_and_type *ids_lhs
    = (const struct ctf_tid_and_type *) item_lhs;
  const struct ctf_tid_and_type *ids_rhs
    = (const struct ctf_tid_and_type *) item_rhs;

  return ids_lhs->tid == ids_rhs->tid;
}

/* Set the type associated with TID to TYP.  */

static struct type *
set_tid_type (struct objfile *of, ctf_id_t tid, struct type *typ)
{
  htab_t htab;

  htab = (htab_t) ctf_tid_key.get (of);
  if (htab == NULL)
    {
      htab = htab_create_alloc (1, tid_and_type_hash,
				tid_and_type_eq,
				NULL, xcalloc, xfree);
      ctf_tid_key.set (of, htab);
    }

  struct ctf_tid_and_type **slot, ids;
  ids.tid = tid;
  ids.type = typ;
  slot = (struct ctf_tid_and_type **) htab_find_slot (htab, &ids, INSERT);
  if (*slot)
    complaint (_("An internal GDB problem: ctf_ id_t %ld type already set"),
	       (tid));
  *slot = XOBNEW (&of->objfile_obstack, struct ctf_tid_and_type);
  **slot = ids;
  return typ;
}

/* Look up the type for TID in tid_and_type hash, return NULL if hash is
   empty or TID does not have a saved type.  */

static struct type *
get_tid_type (struct objfile *of, ctf_id_t tid)
{
  struct ctf_tid_and_type *slot, ids;
  htab_t htab;

  htab = (htab_t) ctf_tid_key.get (of);
  if (htab == NULL)
    return NULL;

  ids.tid = tid;
  ids.type = NULL;
  slot = (struct ctf_tid_and_type *) htab_find (htab, &ids);
  if (slot)
    return slot->type;
  else
    return NULL;
}

/* Return the size of storage in bits for INTEGER, FLOAT, or ENUM.  */

static int
get_bitsize (ctf_file_t *fp, ctf_id_t tid, uint32_t kind)
{
  ctf_encoding_t cet;

  if ((kind == CTF_K_INTEGER || kind == CTF_K_ENUM
      || kind == CTF_K_FLOAT)
      && ctf_type_reference (fp, tid) != CTF_ERR
      && ctf_type_encoding (fp, tid, &cet) != CTF_ERR)
    return cet.cte_bits;

  return 0;
}

/* Set SYM's address, with NAME, from its minimal symbol entry.  */

static void
set_symbol_address (struct objfile *of, struct symbol *sym, const char *name)
{
  struct bound_minimal_symbol msym;

  msym = lookup_minimal_symbol (name, NULL, of);
  if (msym.minsym != NULL)
    {
      SET_SYMBOL_VALUE_ADDRESS (sym, BMSYMBOL_VALUE_ADDRESS (msym));
      SYMBOL_ACLASS_INDEX (sym) = LOC_STATIC;
      SYMBOL_SECTION (sym) = MSYMBOL_SECTION (msym.minsym);
    }
}

/* Create the vector of fields, and attach it to TYPE.  */

static void
attach_fields_to_type (struct ctf_field_info *fip, struct type *type)
{
  int nfields = fip->fields.size ();

  if (nfields == 0)
    return;

  /* Record the field count, allocate space for the array of fields.  */
  type->set_num_fields (nfields);
  type->set_fields
    ((struct field *) TYPE_ZALLOC (type, sizeof (struct field) * nfields));

  /* Copy the saved-up fields into the field vector.  */
  for (int i = 0; i < nfields; ++i)
    {
      struct ctf_nextfield &field = fip->fields[i];
      type->field (i) = field.field;
    }
}

/* Allocate a floating-point type of size BITS and name NAME.  Pass NAME_HINT
   (which may be different from NAME) to the architecture back-end to allow
   it to guess the correct format if necessary.  */

static struct type *
ctf_init_float_type (struct objfile *objfile,
		     int bits,
		     const char *name,
		     const char *name_hint)
{
  struct gdbarch *gdbarch = objfile->arch ();
  const struct floatformat **format;
  struct type *type;

  format = gdbarch_floatformat_for_type (gdbarch, name_hint, bits);
  if (format != NULL)
    type = init_float_type (objfile, bits, name, format);
  else
    type = init_type (objfile, TYPE_CODE_ERROR, bits, name);

  return type;
}

/* Callback to add member NAME to a struct/union type. TID is the type
   of struct/union member, OFFSET is the offset of member in bits,
   and ARG contains the ctf_field_info.  */

static int
ctf_add_member_cb (const char *name,
		   ctf_id_t tid,
		   unsigned long offset,
		   void *arg)
{
  struct ctf_field_info *fip = (struct ctf_field_info *) arg;
  struct ctf_context *ccp = fip->cur_context;
  struct ctf_nextfield new_field;
  struct field *fp;
  struct type *t;
  uint32_t kind;

  fp = &new_field.field;
  FIELD_NAME (*fp) = name;

  kind = ctf_type_kind (ccp->fp, tid);
  t = get_tid_type (ccp->of, tid);
  if (t == NULL)
    {
      t = read_type_record (ccp, tid);
      if (t == NULL)
	{
	  complaint (_("ctf_add_member_cb: %s has NO type (%ld)"), name, tid);
	  t = objfile_type (ccp->of)->builtin_error;
	  set_tid_type (ccp->of, tid, t);
	}
    }

  if (kind == CTF_K_STRUCT || kind == CTF_K_UNION)
    process_struct_members (ccp, tid, t);

  fp->set_type (t);
  SET_FIELD_BITPOS (*fp, offset / TARGET_CHAR_BIT);
  FIELD_BITSIZE (*fp) = get_bitsize (ccp->fp, tid, kind);

  fip->fields.emplace_back (new_field);

  return 0;
}

/* Callback to add member NAME of EVAL to an enumeration type.
   ARG contains the ctf_field_info.  */

static int
ctf_add_enum_member_cb (const char *name, int enum_value, void *arg)
{
  struct ctf_field_info *fip = (struct ctf_field_info *) arg;
  struct ctf_nextfield new_field;
  struct field *fp;
  struct ctf_context *ccp = fip->cur_context;

  fp = &new_field.field;
  FIELD_NAME (*fp) = name;
  fp->set_type (NULL);
  SET_FIELD_ENUMVAL (*fp, enum_value);
  FIELD_BITSIZE (*fp) = 0;

  if (name != NULL)
    {
      struct symbol *sym = new (&ccp->of->objfile_obstack) symbol;
      OBJSTAT (ccp->of, n_syms++);

      sym->set_language (language_c, &ccp->of->objfile_obstack);
      sym->compute_and_set_names (name, false, ccp->of->per_bfd);
      SYMBOL_ACLASS_INDEX (sym) = LOC_CONST;
      SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
      SYMBOL_TYPE (sym) = fip->ptype;
      add_symbol_to_list (sym, ccp->builder->get_global_symbols ());
    }

  fip->fields.emplace_back (new_field);

  return 0;
}

/* Add a new symbol entry, with its name from TID, its access index and
   domain from TID's kind, and its type from TYPE.  */

static struct symbol *
new_symbol (struct ctf_context *ccp, struct type *type, ctf_id_t tid)
{
  struct objfile *objfile = ccp->of;
  ctf_file_t *fp = ccp->fp;
  struct symbol *sym = NULL;

  gdb::unique_xmalloc_ptr<char> name (ctf_type_aname_raw (fp, tid));
  if (name != NULL)
    {
      sym = new (&objfile->objfile_obstack) symbol;
      OBJSTAT (objfile, n_syms++);

      sym->set_language (language_c, &objfile->objfile_obstack);
      sym->compute_and_set_names (name.get (), true, objfile->per_bfd);
      SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
      SYMBOL_ACLASS_INDEX (sym) = LOC_OPTIMIZED_OUT;

      if (type != NULL)
	SYMBOL_TYPE (sym) = type;

      uint32_t kind = ctf_type_kind (fp, tid);
      switch (kind)
	{
	  case CTF_K_STRUCT:
	  case CTF_K_UNION:
	  case CTF_K_ENUM:
	    SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
	    SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
	    break;
	  case CTF_K_FUNCTION:
	    SYMBOL_ACLASS_INDEX (sym) = LOC_STATIC;
	    break;
	  case CTF_K_CONST:
	    if (SYMBOL_TYPE (sym)->code () == TYPE_CODE_VOID)
	      SYMBOL_TYPE (sym) = objfile_type (objfile)->builtin_int;
	    break;
	  case CTF_K_TYPEDEF:
	  case CTF_K_INTEGER:
	  case CTF_K_FLOAT:
	    SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
	    SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
	    break;
	  case CTF_K_POINTER:
	    break;
	  case CTF_K_VOLATILE:
	  case CTF_K_RESTRICT:
	    break;
	  case CTF_K_SLICE:
	  case CTF_K_ARRAY:
	  case CTF_K_UNKNOWN:
	    break;
	}

      add_symbol_to_list (sym, ccp->builder->get_global_symbols ());
    }

  return sym;
}

/* Given a TID of kind CTF_K_INTEGER or CTF_K_FLOAT, find a representation
   and create the symbol for it.  */

static struct type *
read_base_type (struct ctf_context *ccp, ctf_id_t tid)
{
  struct objfile *of = ccp->of;
  ctf_file_t *fp = ccp->fp;
  ctf_encoding_t cet;
  struct type *type = NULL;
  char *name;
  uint32_t kind;

  if (ctf_type_encoding (fp, tid, &cet))
    {
      complaint (_("ctf_type_encoding read_base_type failed - %s"),
		 ctf_errmsg (ctf_errno (fp)));
      return NULL;
    }

  gdb::unique_xmalloc_ptr<char> copied_name (ctf_type_aname_raw (fp, tid));
  if (copied_name == NULL || strlen (copied_name.get ()) == 0)
    {
      name = ctf_type_aname (fp, tid);
      if (name == NULL)
	complaint (_("ctf_type_aname read_base_type failed - %s"),
		   ctf_errmsg (ctf_errno (fp)));
    }
  else
    name = obstack_strdup (&of->objfile_obstack, copied_name.get ());

  kind = ctf_type_kind (fp, tid);
  if (kind == CTF_K_INTEGER)
    {
      uint32_t issigned, ischar, isbool;
      struct gdbarch *gdbarch = of->arch ();

      issigned = cet.cte_format & CTF_INT_SIGNED;
      ischar = cet.cte_format & CTF_INT_CHAR;
      isbool = cet.cte_format & CTF_INT_BOOL;
      if (ischar)
	type = init_character_type (of, TARGET_CHAR_BIT, !issigned, name);
      else if (isbool)
	type = init_boolean_type (of, gdbarch_int_bit (gdbarch),
				  !issigned, name);
      else
	{
	  int bits;
	  if (cet.cte_bits && ((cet.cte_bits % TARGET_CHAR_BIT) == 0))
	    bits = cet.cte_bits;
	  else
	    bits = gdbarch_int_bit (gdbarch);
	  type = init_integer_type (of, bits, !issigned, name);
	}
    }
  else if (kind == CTF_K_FLOAT)
    {
      uint32_t isflt;
      isflt = !((cet.cte_format & CTF_FP_IMAGRY) == CTF_FP_IMAGRY
		 || (cet.cte_format & CTF_FP_DIMAGRY) == CTF_FP_DIMAGRY
		 || (cet.cte_format & CTF_FP_LDIMAGRY) == CTF_FP_LDIMAGRY);
      if (isflt)
	type = ctf_init_float_type (of, cet.cte_bits, name, name);
      else
	{
	  struct type *t
	    = ctf_init_float_type (of, cet.cte_bits / 2, NULL, name);
	  type = init_complex_type (name, t);
	}
    }
  else
    {
      complaint (_("read_base_type: unsupported base kind (%d)"), kind);
      type = init_type (of, TYPE_CODE_ERROR, cet.cte_bits, name);
    }

  if (name != NULL && strcmp (name, "char") == 0)
    TYPE_NOSIGN (type) = 1;

  return set_tid_type (of, tid, type);
}

static void
process_base_type (struct ctf_context *ccp, ctf_id_t tid)
{
  struct type *type;

  type = read_base_type (ccp, tid);
  new_symbol (ccp, type, tid);
}

/* Start a structure or union scope (definition) with TID to create a type
   for the structure or union.

   Fill in the type's name and general properties. The members will not be
   processed, nor a symbol table entry be done until process_structure_type
   (assuming the type has a name).  */

static struct type *
read_structure_type (struct ctf_context *ccp, ctf_id_t tid)
{
  struct objfile *of = ccp->of;
  ctf_file_t *fp = ccp->fp;
  struct type *type;
  uint32_t kind;

  type = alloc_type (of);

  gdb::unique_xmalloc_ptr<char> name (ctf_type_aname_raw (fp, tid));
  if (name != NULL && strlen (name.get() ) != 0)
    type->set_name (obstack_strdup (&of->objfile_obstack, name.get ()));

  kind = ctf_type_kind (fp, tid);
  if (kind == CTF_K_UNION)
    type->set_code (TYPE_CODE_UNION);
  else
    type->set_code (TYPE_CODE_STRUCT);

  TYPE_LENGTH (type) = ctf_type_size (fp, tid);
  set_type_align (type, ctf_type_align (fp, tid));

  return set_tid_type (ccp->of, tid, type);
}

/* Given a tid of CTF_K_STRUCT or CTF_K_UNION, process all its members
   and create the symbol for it.  */

static void
process_struct_members (struct ctf_context *ccp,
			ctf_id_t tid,
			struct type *type)
{
  struct ctf_field_info fi;

  fi.cur_context = ccp;
  if (ctf_member_iter (ccp->fp, tid, ctf_add_member_cb, &fi) == CTF_ERR)
    complaint (_("ctf_member_iter process_struct_members failed - %s"),
	       ctf_errmsg (ctf_errno (ccp->fp)));

  /* Attach fields to the type.  */
  attach_fields_to_type (&fi, type);

  new_symbol (ccp, type, tid);
}

static void
process_structure_type (struct ctf_context *ccp, ctf_id_t tid)
{
  struct type *type;

  type = read_structure_type (ccp, tid);
  process_struct_members (ccp, tid, type);
}

/* Create a function type for TID and set its return type.  */

static struct type *
read_func_kind_type (struct ctf_context *ccp, ctf_id_t tid)
{
  struct objfile *of = ccp->of;
  ctf_file_t *fp = ccp->fp;
  struct type *type, *rettype;
  ctf_funcinfo_t cfi;

  type = alloc_type (of);

  gdb::unique_xmalloc_ptr<char> name (ctf_type_aname_raw (fp, tid));
  if (name != NULL && strlen (name.get ()) != 0)
    type->set_name (obstack_strdup (&of->objfile_obstack, name.get ()));

  type->set_code (TYPE_CODE_FUNC);
  ctf_func_type_info (fp, tid, &cfi);
  rettype = get_tid_type (of, cfi.ctc_return);
  TYPE_TARGET_TYPE (type) = rettype;
  set_type_align (type, ctf_type_align (fp, tid));

  return set_tid_type (of, tid, type);
}

/* Given a TID of CTF_K_ENUM, process all the members of the
   enumeration, and create the symbol for the enumeration type.  */

static struct type *
read_enum_type (struct ctf_context *ccp, ctf_id_t tid)
{
  struct objfile *of = ccp->of;
  ctf_file_t *fp = ccp->fp;
  struct type *type, *target_type;
  ctf_funcinfo_t fi;

  type = alloc_type (of);

  gdb::unique_xmalloc_ptr<char> name (ctf_type_aname_raw (fp, tid));
  if (name != NULL && strlen (name.get ()) != 0)
    type->set_name (obstack_strdup (&of->objfile_obstack, name.get ()));

  type->set_code (TYPE_CODE_ENUM);
  TYPE_LENGTH (type) = ctf_type_size (fp, tid);
  ctf_func_type_info (fp, tid, &fi);
  target_type = get_tid_type (of, fi.ctc_return);
  TYPE_TARGET_TYPE (type) = target_type;
  set_type_align (type, ctf_type_align (fp, tid));

  return set_tid_type (of, tid, type);
}

static void
process_enum_type (struct ctf_context *ccp, ctf_id_t tid)
{
  struct type *type;
  struct ctf_field_info fi;

  type = read_enum_type (ccp, tid);

  fi.cur_context = ccp;
  fi.ptype = type;
  if (ctf_enum_iter (ccp->fp, tid, ctf_add_enum_member_cb, &fi) == CTF_ERR)
    complaint (_("ctf_enum_iter process_enum_type failed - %s"),
	       ctf_errmsg (ctf_errno (ccp->fp)));

  /* Attach fields to the type.  */
  attach_fields_to_type (&fi, type);

  new_symbol (ccp, type, tid);
}

/* Add given cv-qualifiers CNST+VOLTL to the BASE_TYPE of array TID.  */

static struct type *
add_array_cv_type (struct ctf_context *ccp,
		   ctf_id_t tid,
		   struct type *base_type,
		   int cnst,
		   int voltl)
{
  struct type *el_type, *inner_array;

  base_type = copy_type (base_type);
  inner_array = base_type;

  while (TYPE_TARGET_TYPE (inner_array)->code () == TYPE_CODE_ARRAY)
    {
      TYPE_TARGET_TYPE (inner_array)
	= copy_type (TYPE_TARGET_TYPE (inner_array));
      inner_array = TYPE_TARGET_TYPE (inner_array);
    }

  el_type = TYPE_TARGET_TYPE (inner_array);
  cnst |= TYPE_CONST (el_type);
  voltl |= TYPE_VOLATILE (el_type);
  TYPE_TARGET_TYPE (inner_array) = make_cv_type (cnst, voltl, el_type, NULL);

  return set_tid_type (ccp->of, tid, base_type);
}

/* Read all information from a TID of CTF_K_ARRAY.  */

static struct type *
read_array_type (struct ctf_context *ccp, ctf_id_t tid)
{
  struct objfile *objfile = ccp->of;
  ctf_file_t *fp = ccp->fp;
  struct type *element_type, *range_type, *idx_type;
  struct type *type;
  ctf_arinfo_t ar;

  if (ctf_array_info (fp, tid, &ar) == CTF_ERR)
    {
      complaint (_("ctf_array_info read_array_type failed - %s"),
		 ctf_errmsg (ctf_errno (fp)));
      return NULL;
    }

  element_type = get_tid_type (objfile, ar.ctr_contents);
  if (element_type == NULL)
    return NULL;

  idx_type = get_tid_type (objfile, ar.ctr_index);
  if (idx_type == NULL)
    idx_type = objfile_type (objfile)->builtin_int;

  range_type = create_static_range_type (NULL, idx_type, 0, ar.ctr_nelems - 1);
  type = create_array_type (NULL, element_type, range_type);
  if (ar.ctr_nelems <= 1)	/* Check if undefined upper bound.  */
    {
      range_type->bounds ()->high.set_undefined ();
      TYPE_LENGTH (type) = 0;
      TYPE_TARGET_STUB (type) = 1;
    }
  else
    TYPE_LENGTH (type) = ctf_type_size (fp, tid);

  set_type_align (type, ctf_type_align (fp, tid));

  return set_tid_type (objfile, tid, type);
}

/* Read TID of kind CTF_K_CONST with base type BTID.  */

static struct type *
read_const_type (struct ctf_context *ccp, ctf_id_t tid, ctf_id_t btid)
{
  struct objfile *objfile = ccp->of;
  struct type *base_type, *cv_type;

  base_type = get_tid_type (objfile, btid);
  if (base_type == NULL)
    {
      base_type = read_type_record (ccp, btid);
      if (base_type == NULL)
	{
	  complaint (_("read_const_type: NULL base type (%ld)"), btid);
	  base_type = objfile_type (objfile)->builtin_error;
	}
    }
  cv_type = make_cv_type (1, TYPE_VOLATILE (base_type), base_type, 0);

  return set_tid_type (objfile, tid, cv_type);
}

/* Read TID of kind CTF_K_VOLATILE with base type BTID.  */

static struct type *
read_volatile_type (struct ctf_context *ccp, ctf_id_t tid, ctf_id_t btid)
{
  struct objfile *objfile = ccp->of;
  ctf_file_t *fp = ccp->fp;
  struct type *base_type, *cv_type;

  base_type = get_tid_type (objfile, btid);
  if (base_type == NULL)
    {
      base_type = read_type_record (ccp, btid);
      if (base_type == NULL)
	{
	  complaint (_("read_volatile_type: NULL base type (%ld)"), btid);
	  base_type = objfile_type (objfile)->builtin_error;
	}
    }

  if (ctf_type_kind (fp, btid) == CTF_K_ARRAY)
    return add_array_cv_type (ccp, tid, base_type, 0, 1);
  cv_type = make_cv_type (TYPE_CONST (base_type), 1, base_type, 0);

  return set_tid_type (objfile, tid, cv_type);
}

/* Read TID of kind CTF_K_RESTRICT with base type BTID.  */

static struct type *
read_restrict_type (struct ctf_context *ccp, ctf_id_t tid, ctf_id_t btid)
{
  struct objfile *objfile = ccp->of;
  struct type *base_type, *cv_type;

  base_type = get_tid_type (objfile, btid);
  if (base_type == NULL)
    {
      base_type = read_type_record (ccp, btid);
      if (base_type == NULL)
	{
	  complaint (_("read_restrict_type: NULL base type (%ld)"), btid);
	  base_type = objfile_type (objfile)->builtin_error;
	}
    }
  cv_type = make_restrict_type (base_type);

  return set_tid_type (objfile, tid, cv_type);
}

/* Read TID of kind CTF_K_TYPEDEF with its NAME and base type BTID.  */

static struct type *
read_typedef_type (struct ctf_context *ccp, ctf_id_t tid,
		   ctf_id_t btid, const char *name)
{
  struct objfile *objfile = ccp->of;
  struct type *this_type, *target_type;

  char *aname = obstack_strdup (&objfile->objfile_obstack, name);
  this_type = init_type (objfile, TYPE_CODE_TYPEDEF, 0, aname);
  set_tid_type (objfile, tid, this_type);
  target_type = get_tid_type (objfile, btid);
  if (target_type != this_type)
    TYPE_TARGET_TYPE (this_type) = target_type;
  else
    TYPE_TARGET_TYPE (this_type) = NULL;
  TYPE_TARGET_STUB (this_type) = TYPE_TARGET_TYPE (this_type) ? 1 : 0;

  return set_tid_type (objfile, tid, this_type);
}

/* Read TID of kind CTF_K_POINTER with base type BTID.  */

static struct type *
read_pointer_type (struct ctf_context *ccp, ctf_id_t tid, ctf_id_t btid)
{
  struct objfile *of = ccp->of;
  struct type *target_type, *type;

  target_type = get_tid_type (of, btid);
  if (target_type == NULL)
    {
      target_type = read_type_record (ccp, btid);
      if (target_type == NULL)
	{
	  complaint (_("read_pointer_type: NULL target type (%ld)"), btid);
	  target_type = objfile_type (ccp->of)->builtin_error;
	}
    }

  type = lookup_pointer_type (target_type);
  set_type_align (type, ctf_type_align (ccp->fp, tid));

  return set_tid_type (of, tid, type);
}

/* Read information associated with type TID.  */

static struct type *
read_type_record (struct ctf_context *ccp, ctf_id_t tid)
{
  ctf_file_t *fp = ccp->fp;
  uint32_t kind;
  struct type *type = NULL;
  ctf_id_t btid;

  kind = ctf_type_kind (fp, tid);
  switch (kind)
    {
      case CTF_K_STRUCT:
      case CTF_K_UNION:
	type = read_structure_type (ccp, tid);
	break;
      case CTF_K_ENUM:
	type = read_enum_type (ccp, tid);
	break;
      case CTF_K_FUNCTION:
	type = read_func_kind_type (ccp, tid);
	break;
      case CTF_K_CONST:
	btid = ctf_type_reference (fp, tid);
	type = read_const_type (ccp, tid, btid);
	break;
      case CTF_K_TYPEDEF:
	{
	  gdb::unique_xmalloc_ptr<char> name (ctf_type_aname_raw (fp, tid));
	  btid = ctf_type_reference (fp, tid);
	  type = read_typedef_type (ccp, tid, btid, name.get ());
	}
	break;
      case CTF_K_VOLATILE:
	btid = ctf_type_reference (fp, tid);
	type = read_volatile_type (ccp, tid, btid);
	break;
      case CTF_K_RESTRICT:
	btid = ctf_type_reference (fp, tid);
	type = read_restrict_type (ccp, tid, btid);
	break;
      case CTF_K_POINTER:
	btid = ctf_type_reference (fp, tid);
	type = read_pointer_type (ccp, tid, btid);
	break;
      case CTF_K_INTEGER:
      case CTF_K_FLOAT:
	type = read_base_type (ccp, tid);
	break;
      case CTF_K_ARRAY:
	type = read_array_type (ccp, tid);
	break;
      case CTF_K_UNKNOWN:
	break;
      default:
	break;
    }

  return type;
}

/* Callback to add type TID to the symbol table.  */

static int
ctf_add_type_cb (ctf_id_t tid, void *arg)
{
  struct ctf_context *ccp = (struct ctf_context *) arg;
  struct type *type;
  uint32_t kind;

  /* Check if tid's type has already been defined.  */
  type = get_tid_type (ccp->of, tid);
  if (type != NULL)
    return 0;

  ctf_id_t btid = ctf_type_reference (ccp->fp, tid);
  kind = ctf_type_kind (ccp->fp, tid);
  switch (kind)
    {
      case CTF_K_STRUCT:
      case CTF_K_UNION:
	process_structure_type (ccp, tid);
	break;
      case CTF_K_ENUM:
	process_enum_type (ccp, tid);
	break;
      case CTF_K_FUNCTION:
	type = read_func_kind_type (ccp, tid);
	new_symbol (ccp, type, tid);
	break;
      case CTF_K_INTEGER:
      case CTF_K_FLOAT:
	process_base_type (ccp, tid);
	break;
      case CTF_K_TYPEDEF:
	new_symbol (ccp, read_type_record (ccp, tid), tid);
	break;
      case CTF_K_CONST:
	type = read_const_type (ccp, tid, btid);
	new_symbol (ccp, type, tid);
	break;
      case CTF_K_VOLATILE:
	type = read_volatile_type (ccp, tid, btid);
	new_symbol (ccp, type, tid);
	break;
      case CTF_K_RESTRICT:
	type = read_restrict_type (ccp, tid, btid);
	new_symbol (ccp, type, tid);
	break;
      case CTF_K_POINTER:
	type = read_pointer_type (ccp, tid, btid);
	new_symbol (ccp, type, tid);
	break;
      case CTF_K_ARRAY:
	type = read_array_type (ccp, tid);
	new_symbol (ccp, type, tid);
	break;
      case CTF_K_UNKNOWN:
	break;
      default:
	break;
    }

  return 0;
}

/* Callback to add variable NAME with TID to the symbol table.  */

static int
ctf_add_var_cb (const char *name, ctf_id_t id, void *arg)
{
  struct ctf_context *ccp = (struct ctf_context *) arg;
  struct symbol *sym = NULL;
  struct type *type;
  uint32_t kind;

  type = get_tid_type (ccp->of, id);

  kind = ctf_type_kind (ccp->fp, id);
  switch (kind)
    {
      case CTF_K_FUNCTION:
	if (name && !strcmp(name, "main"))
	  set_objfile_main_name (ccp->of, name, language_c);
	break;
      case CTF_K_INTEGER:
      case CTF_K_FLOAT:
      case CTF_K_VOLATILE:
      case CTF_K_RESTRICT:
      case CTF_K_TYPEDEF:
      case CTF_K_CONST:
      case CTF_K_POINTER:
      case CTF_K_ARRAY:
	if (type)
	  {
	    sym = new_symbol (ccp, type, id);
	    sym->compute_and_set_names (name, false, ccp->of->per_bfd);
	  }
	break;
      case CTF_K_STRUCT:
      case CTF_K_UNION:
      case CTF_K_ENUM:
	if (type == NULL)
	{
	  complaint (_("ctf_add_var_cb: %s has NO type (%ld)"), name, id);
	  type = objfile_type (ccp->of)->builtin_error;
	}
	sym = new (&ccp->of->objfile_obstack) symbol;
	OBJSTAT (ccp->of, n_syms++);
	SYMBOL_TYPE (sym) = type;
	SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
	SYMBOL_ACLASS_INDEX (sym) = LOC_OPTIMIZED_OUT;
	sym->compute_and_set_names (name, false, ccp->of->per_bfd);
	add_symbol_to_list (sym, ccp->builder->get_global_symbols ());
	break;
      default:
	complaint (_("ctf_add_var_cb: kind unsupported (%d)"), kind);
	break;
    }

  if (sym)
    set_symbol_address (ccp->of, sym, name);

  return 0;
}

/* Add an ELF STT_OBJ symbol with index IDX to the symbol table.  */

static struct symbol *
add_stt_obj (struct ctf_context *ccp, unsigned long idx)
{
  struct symbol *sym;
  struct type *type;
  ctf_id_t tid;

  if ((tid = ctf_lookup_by_symbol (ccp->fp, idx)) == CTF_ERR)
    return NULL;

  type = get_tid_type (ccp->of, tid);
  if (type == NULL)
    return NULL;

  sym = new_symbol (ccp, type, tid);

  return sym;
}

/* Add an ELF STT_FUNC symbol with index IDX to the symbol table.  */

static struct symbol *
add_stt_func (struct ctf_context *ccp, unsigned long idx)
{
  struct type *ftype, *atyp, *rettyp;
  struct symbol *sym;
  ctf_funcinfo_t finfo;
  ctf_id_t argv[32];
  uint32_t argc;
  ctf_id_t tid;
  struct type *void_type = objfile_type (ccp->of)->builtin_void;

  if (ctf_func_info (ccp->fp, idx, &finfo) == CTF_ERR)
    return NULL;

  argc = finfo.ctc_argc;
  if (ctf_func_args (ccp->fp, idx, argc, argv) == CTF_ERR)
    return NULL;

  gdb::unique_xmalloc_ptr<char> name (ctf_type_aname_raw (ccp->fp, idx));
  if (name == NULL)
    return NULL;

  tid = ctf_lookup_by_symbol (ccp->fp, idx);
  ftype = get_tid_type (ccp->of, tid);
  if (finfo.ctc_flags & CTF_FUNC_VARARG)
    TYPE_VARARGS (ftype) = 1;
  ftype->set_num_fields (argc);

  /* If argc is 0, it has a "void" type.  */
  if (argc != 0)
    ftype->set_fields
      ((struct field *) TYPE_ZALLOC (ftype, argc * sizeof (struct field)));

  /* TYPE_FIELD_TYPE must never be NULL.  Fill it with void_type, if failed
     to find the argument type.  */
  for (int iparam = 0; iparam < argc; iparam++)
    {
      atyp = get_tid_type (ccp->of, argv[iparam]);
      if (atyp)
	ftype->field (iparam).set_type (atyp);
      else
	ftype->field (iparam).set_type (void_type);
    }

  sym = new_symbol (ccp, ftype, tid);
  rettyp = get_tid_type (ccp->of, finfo.ctc_return);
  if (rettyp != NULL)
    SYMBOL_TYPE (sym) = rettyp;
  else
    SYMBOL_TYPE (sym) = void_type;

  return sym;
}

/* Get text segment base for OBJFILE, TSIZE contains the segment size.  */

static CORE_ADDR
get_objfile_text_range (struct objfile *of, int *tsize)
{
  bfd *abfd = of->obfd;
  const asection *codes;

  codes = bfd_get_section_by_name (abfd, ".text");
  *tsize = codes ? bfd_section_size (codes) : 0;
  return of->text_section_offset ();
}

/* Start a symtab for OBJFILE in CTF format.  */

static void
ctf_start_symtab (ctf_psymtab *pst,
		  struct objfile *of, CORE_ADDR text_offset)
{
  struct ctf_context *ccp;

  ccp = pst->context;
  ccp->builder = new buildsym_compunit
		       (of, of->original_name, NULL,
		       language_c, text_offset);
  ccp->builder->record_debugformat ("ctf");
}

/* Finish reading symbol/type definitions in CTF format.
   END_ADDR is the end address of the file's text.  SECTION is
   the .text section number.  */

static struct compunit_symtab *
ctf_end_symtab (ctf_psymtab *pst,
		CORE_ADDR end_addr, int section)
{
  struct ctf_context *ccp;

  ccp = pst->context;
  struct compunit_symtab *result
    = ccp->builder->end_symtab (end_addr, section);
  delete ccp->builder;
  ccp->builder = NULL;
  return result;
}

/* Read in full symbols for PST, and anything it depends on.  */

void
ctf_psymtab::expand_psymtab (struct objfile *objfile)
{
  struct symbol *sym;
  struct ctf_context *ccp;

  gdb_assert (!readin);

  ccp = context;

  /* Iterate over entries in data types section.  */
  if (ctf_type_iter (ccp->fp, ctf_add_type_cb, ccp) == CTF_ERR)
    complaint (_("ctf_type_iter psymtab_to_symtab failed - %s"),
	       ctf_errmsg (ctf_errno (ccp->fp)));


  /* Iterate over entries in variable info section.  */
  if (ctf_variable_iter (ccp->fp, ctf_add_var_cb, ccp) == CTF_ERR)
    complaint (_("ctf_variable_iter psymtab_to_symtab failed - %s"),
	       ctf_errmsg (ctf_errno (ccp->fp)));

  /* Add entries in data objects and function info sections.  */
  for (unsigned long i = 0; ; i++)
    {
      sym = add_stt_obj (ccp, i);
      if (sym == NULL)
	{
	  if (ctf_errno (ccp->fp) == EINVAL
	      || ctf_errno (ccp->fp) == ECTF_NOSYMTAB)
	    break;
	  sym = add_stt_func (ccp, i);
	}
      if (sym == NULL)
	continue;

      set_symbol_address (ccp->of, sym, sym->linkage_name ());
    }

  readin = true;
}

/* Expand partial symbol table PST into a full symbol table.
   PST is not NULL.  */

void
ctf_psymtab::read_symtab (struct objfile *objfile)
{
  if (readin)
    warning (_("bug: psymtab for %s is already read in."), filename);
  else
    {
      if (info_verbose)
	{
	  printf_filtered (_("Reading in CTF data for %s..."), filename);
	  gdb_flush (gdb_stdout);
	}

      /* Start a symtab.  */
      CORE_ADDR offset;        /* Start of text segment.  */
      int tsize;

      offset = get_objfile_text_range (objfile, &tsize);
      ctf_start_symtab (this, objfile, offset);
      expand_psymtab (objfile);

      set_text_low (offset);
      set_text_high (offset + tsize);
      compunit_symtab = ctf_end_symtab (this, offset + tsize,
					SECT_OFF_TEXT (objfile));

      /* Finish up the debug error message.  */
      if (info_verbose)
	printf_filtered (_("done.\n"));
    }
}

/* Allocate a new partial_symtab NAME.

   Each source file that has not been fully read in is represented by
   a partial_symtab.  This contains the information on where in the
   executable the debugging symbols for a specific file are, and a
   list of names of global symbols which are located in this file.
   They are all chained on partial symtab lists.

   Even after the source file has been read into a symtab, the
   partial_symtab remains around.  They are allocated on an obstack,
   objfile_obstack.  */

static ctf_psymtab *
create_partial_symtab (const char *name,
		       ctf_file_t *cfp,
		       struct objfile *objfile)
{
  ctf_psymtab *pst;
  struct ctf_context *ccx;

  pst = new ctf_psymtab (name, objfile, 0);

  ccx = XOBNEW (&objfile->objfile_obstack, struct ctf_context);
  ccx->fp = cfp;
  ccx->of = objfile;
  pst->context = ccx;

  return pst;
}

/* Callback to add type TID to partial symbol table.  */

static int
ctf_psymtab_type_cb (ctf_id_t tid, void *arg)
{
  struct ctf_context *ccp;
  uint32_t kind;
  short section = -1;

  ccp = (struct ctf_context *) arg;
  gdb::unique_xmalloc_ptr<char> name (ctf_type_aname_raw (ccp->fp, tid));
  if (name == NULL || strlen (name.get ()) == 0)
    return 0;

  domain_enum domain = UNDEF_DOMAIN;
  enum address_class aclass = LOC_UNDEF;
  kind = ctf_type_kind (ccp->fp, tid);
  switch (kind)
    {
      case CTF_K_STRUCT:
      case CTF_K_UNION:
      case CTF_K_ENUM:
	domain = STRUCT_DOMAIN;
	aclass = LOC_TYPEDEF;
	break;
      case CTF_K_FUNCTION:
      case CTF_K_FORWARD:
	domain = VAR_DOMAIN;
	aclass = LOC_STATIC;
	section = SECT_OFF_TEXT (ccp->of);
	break;
      case CTF_K_CONST:
	domain = VAR_DOMAIN;
	aclass = LOC_STATIC;
	break;
      case CTF_K_TYPEDEF:
      case CTF_K_POINTER:
      case CTF_K_VOLATILE:
      case CTF_K_RESTRICT:
	domain = VAR_DOMAIN;
	aclass = LOC_TYPEDEF;
	break;
      case CTF_K_INTEGER:
      case CTF_K_FLOAT:
	domain = VAR_DOMAIN;
	aclass = LOC_TYPEDEF;
	break;
      case CTF_K_ARRAY:
      case CTF_K_UNKNOWN:
	return 0;
    }

    add_psymbol_to_list (name.get (), true,
			 domain, aclass, section,
			 psymbol_placement::GLOBAL,
			 0, language_c, ccp->of);

  return 0;
}

/* Callback to add variable NAME with ID to partial symbol table.  */

static int
ctf_psymtab_var_cb (const char *name, ctf_id_t id, void *arg)
{
  struct ctf_context *ccp = (struct ctf_context *) arg;

  add_psymbol_to_list (name, true,
		       VAR_DOMAIN, LOC_STATIC, -1,
		       psymbol_placement::GLOBAL,
		       0, language_c, ccp->of);
  return 0;
}

/* Setup partial_symtab's describing each source file for which
   debugging information is available.  */

static void
scan_partial_symbols (ctf_file_t *cfp, struct objfile *of)
{
  struct ctf_context ccx;
  bfd *abfd = of->obfd;
  const char *name = bfd_get_filename (abfd);
  ctf_psymtab *pst = create_partial_symtab (name, cfp, of);

  ccx.fp = cfp;
  ccx.of = of;

  if (ctf_type_iter (cfp, ctf_psymtab_type_cb, &ccx) == CTF_ERR)
    complaint (_("ctf_type_iter scan_partial_symbols failed - %s"),
	       ctf_errmsg (ctf_errno (cfp)));

  if (ctf_variable_iter (cfp, ctf_psymtab_var_cb, &ccx) == CTF_ERR)
    complaint (_("ctf_variable_iter scan_partial_symbols failed - %s"),
	       ctf_errmsg (ctf_errno (cfp)));

  /* Scan CTF object and function sections which correspond to each
     STT_FUNC or STT_OBJECT entry in the symbol table,
     pick up what init_symtab has done.  */
  for (unsigned long idx = 0; ; idx++)
    {
      ctf_id_t tid;
      if ((tid = ctf_lookup_by_symbol (cfp, idx)) == CTF_ERR)
	{
	if (ctf_errno (cfp) == EINVAL || ctf_errno (cfp) == ECTF_NOSYMTAB)
	  break;	// Done, reach end of the section.
	else
	  continue;
	}
      gdb::unique_xmalloc_ptr<char> tname (ctf_type_aname_raw (cfp, tid));
      uint32_t kind = ctf_type_kind (cfp, tid);
      address_class aclass;
      domain_enum tdomain;
      switch (kind)
	{
	  case CTF_K_STRUCT:
	  case CTF_K_UNION:
	  case CTF_K_ENUM:
	    tdomain = STRUCT_DOMAIN;
	    break;
	  default:
	    tdomain = VAR_DOMAIN;
	    break;
	}

      if (kind == CTF_K_FUNCTION)
	aclass = LOC_STATIC;
      else if (kind == CTF_K_CONST)
	aclass = LOC_CONST;
      else
	aclass = LOC_TYPEDEF;

      add_psymbol_to_list (tname.get (), true,
			   tdomain, aclass, -1,
			   psymbol_placement::STATIC,
			   0, language_c, of);
    }

  end_psymtab_common (of, pst);
}

/* Read CTF debugging information from a BFD section.  This is
   called from elfread.c.  It does a quick pass through the
   .ctf section to set up the partial symbol table.  */

void
elfctf_build_psymtabs (struct objfile *of)
{
  bfd *abfd = of->obfd;
  int err;

  ctf_archive_t *arc = ctf_bfdopen (abfd, &err);
  if (arc == NULL)
    error (_("ctf_bfdopen failed on %s - %s"),
	   bfd_get_filename (abfd), ctf_errmsg (err));

  ctf_file_t *fp = ctf_arc_open_by_name (arc, NULL, &err);
  if (fp == NULL)
    error (_("ctf_arc_open_by_name failed on %s - %s"),
	   bfd_get_filename (abfd), ctf_errmsg (err));
  ctf_file_key.emplace (of, fp);

  scan_partial_symbols (fp, of);
}

#else

void
elfctf_build_psymtabs (struct objfile *of)
{
  /* Nothing to do if CTF is disabled.  */
}

#endif /* ENABLE_LIBCTF */
