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

   Copyright (C) 2019-2020 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 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"
#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_NFIELDS (type) = nfields;
  TYPE_FIELDS (type)
    = (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 (type, 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 = get_objfile_arch (objfile);
  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);

  FIELD_TYPE (*fp) = 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;
  FIELD_TYPE (*fp) = NULL;
  SET_FIELD_ENUMVAL (*fp, enum_value);
  FIELD_BITSIZE (*fp) = 0;

  if (name != NULL)
    {
      struct symbol *sym = allocate_symbol (ccp->of);
      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 = allocate_symbol (objfile);
      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 (TYPE_CODE (SYMBOL_TYPE (sym)) == 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 = get_objfile_arch (of);

      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 (of, 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_NAME (type) = obstack_strdup (&of->objfile_obstack, name.get ());

  kind = ctf_type_kind (fp, tid);
  if (kind == CTF_K_UNION)
    TYPE_CODE (type) = TYPE_CODE_UNION;
  else
    TYPE_CODE (type) = 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_NAME (type) = obstack_strdup (&of->objfile_obstack, name.get ());

  TYPE_CODE (type) = 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_NAME (type) = obstack_strdup (&of->objfile_obstack, name.get ());

  TYPE_CODE (type) = 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_CODE (TYPE_TARGET_TYPE (inner_array)) == 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.  */
    {
      TYPE_HIGH_BOUND_KIND (range_type) = PROP_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 = allocate_symbol (ccp->of);
	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;
  TYPE_NFIELDS (ftype) = argc;

  /* If argc is 0, it has a "void" type.  */
  if (argc != 0)
    TYPE_FIELDS (ftype)
      = (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)
	TYPE_FIELD_TYPE (ftype, iparam) = atyp;
      else
	TYPE_FIELD_TYPE (ftype, iparam) = 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);
}
