/* 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_dict_t *cfp) : fp (cfp) {}
  ~ctf_fp_info ();
  ctf_dict_t *fp;
};

/* Cleanup function for the ctf_dict_key data.  */
ctf_fp_info::~ctf_fp_info ()
{
  if (fp == nullptr)
    return;

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

static const objfile_key<ctf_fp_info> ctf_dict_key;

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

struct ctf_context
{
  ctf_dict_t *fp;
  struct objfile *of;
  psymtab_storage *partial_symtabs;
  partial_symtab *pst;
  struct buildsym_compunit *builder;
};

/* A partial symtab, specialized for this module.  */
struct ctf_psymtab : public standard_psymtab
{
  ctf_psymtab (const char *filename,
	       psymtab_storage *partial_symtabs,
	       objfile_per_bfd_storage *objfile_per_bfd,
	       CORE_ADDR addr)
    : standard_psymtab (filename, partial_symtabs, objfile_per_bfd, 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 type *read_forward_type (struct ctf_context *cp, ctf_id_t tid);

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 nullptr;

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

/* Fetch the type for TID in CCP OF's tid_and_type hash, add the type to
 *    context CCP if hash is empty or TID does not have a saved type.  */

static struct type *
fetch_tid_type (struct ctf_context *ccp, ctf_id_t tid)
{
  struct objfile *of = ccp->of;
  struct type *typ;

  typ = get_tid_type (of, tid);
  if (typ == nullptr)
    {
      ctf_add_type_cb (tid, ccp);
      typ = get_tid_type (of, tid);
    }

  return typ;
}

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

static int
get_bitsize (ctf_dict_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, nullptr, of);
  if (msym.minsym != NULL)
    {
      SET_SYMBOL_VALUE_ADDRESS (sym, BMSYMBOL_VALUE_ADDRESS (msym));
      SYMBOL_ACLASS_INDEX (sym) = LOC_STATIC;
      sym->set_section_index (msym.minsym->section_index ());
    }
}

/* 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 != nullptr)
    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 = fetch_tid_type (ccp, tid);
  if (t == nullptr)
    {
      t = read_type_record (ccp, tid);
      if (t == nullptr)
	{
	  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 (nullptr);
  SET_FIELD_ENUMVAL (*fp, enum_value);
  FIELD_BITSIZE (*fp) = 0;

  if (name != nullptr)
    {
      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_dict_t *fp = ccp->fp;
  struct symbol *sym = nullptr;

  const char *name = ctf_type_name_raw (fp, tid);
  if (name != nullptr)
    {
      sym = new (&objfile->objfile_obstack) symbol;
      OBJSTAT (objfile, n_syms++);

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

      if (type != nullptr)
	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;
	    set_symbol_address (objfile, sym, sym->linkage_name ());
	    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_dict_t *fp = ccp->fp;
  ctf_encoding_t cet;
  struct type *type = nullptr;
  const 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 nullptr;
    }

  name = ctf_type_name_raw (fp, tid);
  if (name == nullptr || strlen (name) == 0)
    {
      name = ctf_type_aname (fp, tid);
      if (name == nullptr)
	complaint (_("ctf_type_aname read_base_type failed - %s"),
		   ctf_errmsg (ctf_errno (fp)));
    }

  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 != nullptr && strcmp (name, "char") == 0)
    type->set_has_no_signedness (true);

  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_dict_t *fp = ccp->fp;
  struct type *type;
  uint32_t kind;

  type = alloc_type (of);

  const char *name = ctf_type_name_raw (fp, tid);
  if (name != nullptr && strlen (name) != 0)
    type->set_name (name);

  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_dict_t *fp = ccp->fp;
  struct type *type, *rettype, *atype;
  ctf_funcinfo_t cfi;
  uint32_t argc;

  type = alloc_type (of);

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

  /* Set up function's arguments.  */
  argc = cfi.ctc_argc;
  type->set_num_fields (argc);
  if ((cfi.ctc_flags & CTF_FUNC_VARARG) != 0)
    type->set_has_varargs (true);

  if (argc != 0)
    {
      std::vector<ctf_id_t> argv (argc);
      if (ctf_func_type_args (fp, tid, argc, argv.data ()) == CTF_ERR)
	return nullptr;

      type->set_fields
	((struct field *) TYPE_ZALLOC (type, argc * sizeof (struct field)));
      struct type *void_type = objfile_type (of)->builtin_void;
      /* If failed to find the argument type, fill it with void_type.  */
      for (int iparam = 0; iparam < argc; iparam++)
	{
	  atype = get_tid_type (of, argv[iparam]);
	  if (atype != nullptr)
	    type->field (iparam).set_type (atype);
	  else
	    type->field (iparam).set_type (void_type);
	}
    }

  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_dict_t *fp = ccp->fp;
  struct type *type, *target_type;
  ctf_funcinfo_t fi;

  type = alloc_type (of);

  const char *name = ctf_type_name_raw (fp, tid);
  if (name != nullptr && strlen (name) != 0)
    type->set_name (name);

  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, nullptr);

  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_dict_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 nullptr;
    }

  element_type = fetch_tid_type (ccp, ar.ctr_contents);
  if (element_type == nullptr)
    return nullptr;

  idx_type = fetch_tid_type (ccp, ar.ctr_index);
  if (idx_type == nullptr)
    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->set_target_is_stub (true);
    }
  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 = fetch_tid_type (ccp, btid);
  if (base_type == nullptr)
    {
      base_type = read_type_record (ccp, btid);
      if (base_type == nullptr)
	{
	  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_dict_t *fp = ccp->fp;
  struct type *base_type, *cv_type;

  base_type = fetch_tid_type (ccp, btid);
  if (base_type == nullptr)
    {
      base_type = read_type_record (ccp, btid);
      if (base_type == nullptr)
	{
	  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 = fetch_tid_type (ccp, btid);
  if (base_type == nullptr)
    {
      base_type = read_type_record (ccp, btid);
      if (base_type == nullptr)
	{
	  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 = fetch_tid_type (ccp, btid);
  if (target_type != this_type)
    TYPE_TARGET_TYPE (this_type) = target_type;
  else
    TYPE_TARGET_TYPE (this_type) = nullptr;

  this_type->set_target_is_stub (TYPE_TARGET_TYPE (this_type) != nullptr);

  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 = fetch_tid_type (ccp, btid);
  if (target_type == nullptr)
    {
      target_type = read_type_record (ccp, btid);
      if (target_type == nullptr)
	{
	  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 from a TID of CTF_K_FORWARD.  */

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

  type = alloc_type (of);

  const char *name = ctf_type_name_raw (fp, tid);
  if (name != nullptr && strlen (name) != 0)
    type->set_name (name);

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

  TYPE_LENGTH (type) = 0;
  type->set_is_stub (true);

  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_dict_t *fp = ccp->fp;
  uint32_t kind;
  struct type *type = nullptr;
  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:
	{
	  const char *name = ctf_type_name_raw (fp, tid);
	  btid = ctf_type_reference (fp, tid);
	  type = read_typedef_type (ccp, tid, btid, name);
	}
	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_FORWARD:
	type = read_forward_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 != nullptr)
    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 = nullptr;
  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 != nullptr && strcmp (name, "main") == 0)
	  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 == nullptr)
	  {
	    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 != nullptr)
    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 nullptr;

  type = fetch_tid_type (ccp, tid);
  if (type == nullptr)
    return nullptr;

  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 nullptr;

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

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

  tid = ctf_lookup_by_symbol (ccp->fp, idx);
  ftype = fetch_tid_type (ccp, tid);
  if ((finfo.ctc_flags & CTF_FUNC_VARARG) != 0)
    ftype->set_has_varargs (true);
  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 = fetch_tid_type (ccp, 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 = fetch_tid_type (ccp, finfo.ctc_return);
  if (rettyp != nullptr)
    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, nullptr,
		       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 = nullptr;
  return result;
}

/* Add all members of an enum with type TID to partial symbol table.  */

static void
ctf_psymtab_add_enums (struct ctf_context *ccp, ctf_id_t tid)
{
  int val;
  const char *ename;
  ctf_next_t *i = nullptr;

  while ((ename = ctf_enum_next (ccp->fp, tid, &i, &val)) != nullptr)
    {
      ccp->pst->add_psymbol (ename, true,
			     VAR_DOMAIN, LOC_CONST, -1,
			     psymbol_placement::GLOBAL,
			     0, language_c, ccp->partial_symtabs, ccp->of);
    }
  if (ctf_errno (ccp->fp) != ECTF_NEXT_END)
    complaint (_("ctf_enum_next ctf_psymtab_add_enums failed - %s"),
	       ctf_errmsg (ctf_errno (ccp->fp)));
}

/* 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 == nullptr)
	{
	  if (ctf_errno (ccp->fp) == EINVAL
	      || ctf_errno (ccp->fp) == ECTF_NOSYMTAB)
	    break;
	  sym = add_stt_func (ccp, i);
	}
      if (sym == nullptr)
	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_dict_t *cfp,
		       psymtab_storage *partial_symtabs,
		       struct objfile *objfile)
{
  ctf_psymtab *pst;
  struct ctf_context *ccx;

  pst = new ctf_psymtab (name, partial_symtabs, objfile->per_bfd, 0);

  ccx = XOBNEW (&objfile->objfile_obstack, struct ctf_context);
  ccx->fp = cfp;
  ccx->of = objfile;
  ccx->partial_symtabs = partial_symtabs;
  ccx->pst = pst;
  ccx->builder = nullptr;
  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;

  domain_enum domain = UNDEF_DOMAIN;
  enum address_class aclass = LOC_UNDEF;
  kind = ctf_type_kind (ccp->fp, tid);
  switch (kind)
    {
      case CTF_K_ENUM:
	ctf_psymtab_add_enums (ccp, tid);
	/* FALL THROUGH */
      case CTF_K_STRUCT:
      case CTF_K_UNION:
	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;
    }

  const char *name = ctf_type_name_raw (ccp->fp, tid);
  if (name == nullptr || strlen (name) == 0)
    return 0;

  ccp->pst->add_psymbol (name, false,
			 domain, aclass, section,
			 psymbol_placement::GLOBAL,
			 0, language_c, ccp->partial_symtabs, 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;

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

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

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

  struct ctf_context *ccx = pst->context;

  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;
	}
      const char *tname = ctf_type_name_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;

      pst->add_psymbol (tname, false,
			tdomain, aclass, -1,
			psymbol_placement::STATIC,
			0, language_c, partial_symtabs, of);
    }

  pst->end ();
}

/* 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 == nullptr)
    error (_("ctf_bfdopen failed on %s - %s"),
	   bfd_get_filename (abfd), ctf_errmsg (err));

  ctf_dict_t *fp = ctf_dict_open (arc, NULL, &err);
  if (fp == nullptr)
    error (_("ctf_dict_open failed on %s - %s"),
	   bfd_get_filename (abfd), ctf_errmsg (err));
  ctf_dict_key.emplace (of, fp);

  psymbol_functions *psf = new psymbol_functions ();
  psymtab_storage *partial_symtabs = psf->get_partial_symtabs ().get ();
  of->qf.emplace_front (psf);
  scan_partial_symbols (fp, partial_symtabs, of);
}

#else

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

#endif /* ENABLE_LIBCTF */
