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

/* Data held for a translation unit.  */

struct ctf_per_tu_data
{
  ctf_dict_t *fp;
  struct objfile *of;
  ctf_archive_t *arc;
  psymtab_storage *pss;
  psymbol_functions *psf;
};

/* 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 == nullptr)
    *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;
  fp->set_name (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);
  fp->set_loc_bitpos (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;
  fp->set_name (name);
  fp->set_type (nullptr);
  fp->set_loc_enumval (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_file_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 = fetch_tid_type (ccp, 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 != nullptr)
	  {
	    sym = new_symbol (ccp, type, id);
	    if (sym != nullptr)
	      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_file_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 entries in either data objects or function info section, controlled
   by FUNCTIONS.  */

static void
add_stt_entries (struct ctf_context *ccp, int functions)
{
  ctf_next_t *i = nullptr;
  const char *tname;
  ctf_id_t tid;
  struct symbol *sym = nullptr;
  struct type *type;

  while ((tid = ctf_symbol_next (ccp->fp, &i, &tname, functions)) != CTF_ERR)
    {
      type = get_tid_type (ccp->of, tid);
      if (type == nullptr)
	continue;
      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_STATIC;
      sym->compute_and_set_names (tname, false, ccp->of->per_bfd);
      add_symbol_to_list (sym, ccp->builder->get_global_symbols ());
      set_symbol_address (ccp->of, sym, tname);
    }
}

/* Add entries in data objects section.  */

static void
add_stt_obj (struct ctf_context *ccp)
{
  add_stt_entries (ccp, 0);
}

/* Add entries in function info section.  */

static void
add_stt_func (struct ctf_context *ccp)
{
  add_stt_entries (ccp, 1);
}

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

/* Add entries in either data objects or function info section, controlled
   by FUNCTIONS, to psymtab.  */

static void
ctf_psymtab_add_stt_entries (ctf_dict_t *cfp, ctf_psymtab *pst,
			     struct objfile *of, int functions)
{
  ctf_next_t *i = nullptr;
  ctf_id_t tid;
  const char *tname;

  while ((tid = ctf_symbol_next (cfp, &i, &tname, functions)) != CTF_ERR)
    {
      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, true,
			tdomain, aclass, -1,
			psymbol_placement::GLOBAL,
			0, language_c, pst->context.partial_symtabs, of);
    }
}

/* Add entries in data objects section to psymtab.  */

static void
ctf_psymtab_add_stt_obj (ctf_dict_t *cfp, ctf_psymtab *pst,
			 struct objfile *of)
{
  ctf_psymtab_add_stt_entries (cfp, pst, of, 0);
}

/* Add entries in function info section to psymtab.  */

static void
ctf_psymtab_add_stt_func (ctf_dict_t *cfp, ctf_psymtab *pst,
			  struct objfile *of)
{
  ctf_psymtab_add_stt_entries (cfp, pst, of, 1);
}

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

void
ctf_psymtab::expand_psymtab (struct objfile *objfile)
{
  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.  */
  add_stt_obj (ccp);
  add_stt_func (ccp);

  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_archive_t *arc,
		       ctf_dict_t *cfp,
		       psymtab_storage *partial_symtabs,
		       struct objfile *objfile)
{
  ctf_psymtab *pst;

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

  pst->context.arc = arc;
  pst->context.fp = cfp;
  pst->context.of = objfile;
  pst->context.partial_symtabs = partial_symtabs;
  pst->context.pst = pst;

  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::STATIC,
			 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;
}

/* Start a subfile for CTF. FNAME is the name of the archive.  */

static void
ctf_start_archive (struct ctf_context *ccx, struct objfile *of,
		   const char *fname)
{
  if (ccx->builder == nullptr)
    {
      ccx->builder = new buildsym_compunit (of,
		      of->original_name, nullptr, language_c, 0);
      ccx->builder->record_debugformat ("ctf");
    }
  ccx->builder->start_subfile (fname);
}

/* 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 ctf_per_tu_data *tup, const char *fname)
{
  struct objfile *of = tup->of;
  bool isparent = false;

  if (strcmp (fname, ".ctf") == 0)
    {
      fname = bfd_get_filename (of->obfd);
      isparent = true;
    }

  ctf_psymtab *pst = create_partial_symtab (fname, tup->arc, cfp,
					    partial_symtabs, of);

  struct ctf_context *ccx = &pst->context;
  if (isparent == false)
    {
      ctf_start_archive (ccx, of, fname);
      ccx->pst = pst;
    }

  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.  */
  ctf_psymtab_add_stt_obj (cfp, pst, of);
  ctf_psymtab_add_stt_func (cfp, pst, of);

  pst->end ();
}

/* Callback to build the psymtab for archive member NAME.  */

static int
build_ctf_archive_member (ctf_dict_t *ctf, const char *name, void *arg)
{
  struct ctf_per_tu_data *tup = (struct ctf_per_tu_data *) arg;
  ctf_dict_t *parent = tup->fp;

  if (strcmp (name, ".ctf") != 0)
    ctf_import (ctf, parent);

  if (info_verbose)
    {
      printf_filtered (_("Scanning archive member %s..."), name);
      gdb_flush (gdb_stdout);
    }

  psymtab_storage *pss = tup->psf->get_partial_symtabs ().get ();
  scan_partial_symbols (ctf, pss, tup, name);

  return 0;
}

/* 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)
{
  struct ctf_per_tu_data pcu;
  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);

  pcu.fp = fp;
  pcu.of = of;
  pcu.arc = arc;

  psymbol_functions *psf = new psymbol_functions ();
  of->qf.emplace_front (psf);
  pcu.psf = psf;

  if (ctf_archive_iter (arc, build_ctf_archive_member, &pcu) < 0)
    error (_("ctf_archive_iter failed in input file %s: - %s"),
	   bfd_get_filename (abfd), ctf_errmsg (err));
}

#else

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

#endif /* ENABLE_LIBCTF */
