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

   Copyright (C) 2019-2024 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 "buildsym.h"
#include "complaints.h"
#include "block.h"
#include "ctfread.h"
#include "psymtab.h"

#if ENABLE_LIBCTF

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

static const registry<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 registry<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,
	       unrelocated_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 = 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 = 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)
{
  bound_minimal_symbol msym
    = lookup_minimal_symbol (current_program_space, name, of);
  if (msym.minsym != NULL)
    {
      sym->set_value_address (msym.value_address ());
      sym->set_aclass_index (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->alloc_fields (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;

  type_allocator alloc (objfile, language_c);
  format = gdbarch_floatformat_for_type (gdbarch, name_hint, bits);
  if (format != nullptr)
    type = init_float_type (alloc, bits, name, format);
  else
    type = alloc.new_type (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 = builtin_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);
  fp->set_bitsize (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);
  fp->set_bitsize (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);
      sym->set_aclass_index (LOC_CONST);
      sym->set_domain (VAR_DOMAIN);
      sym->set_type (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);
      sym->set_domain (VAR_DOMAIN);
      sym->set_aclass_index (LOC_OPTIMIZED_OUT);

      if (type != nullptr)
	sym->set_type (type);

      uint32_t kind = ctf_type_kind (fp, tid);
      switch (kind)
	{
	  case CTF_K_STRUCT:
	  case CTF_K_UNION:
	  case CTF_K_ENUM:
	    sym->set_aclass_index (LOC_TYPEDEF);
	    sym->set_domain (STRUCT_DOMAIN);
	    break;
	  case CTF_K_FUNCTION:
	    sym->set_aclass_index (LOC_STATIC);
	    set_symbol_address (objfile, sym, sym->linkage_name ());
	    break;
	  case CTF_K_CONST:
	    if (sym->type ()->code () == TYPE_CODE_VOID)
	      sym->set_type (builtin_type (objfile)->builtin_int);
	    break;
	  case CTF_K_TYPEDEF:
	  case CTF_K_INTEGER:
	  case CTF_K_FLOAT:
	    sym->set_aclass_index (LOC_TYPEDEF);
	    sym->set_domain (TYPE_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)));
    }

  type_allocator alloc (of, language_c);
  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 (alloc, TARGET_CHAR_BIT, !issigned, name);
      else if (isbool)
	type = init_boolean_type (alloc, 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 (alloc, 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 = alloc.new_type (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 = type_allocator (of, language_c).new_type ();

  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->set_length (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 = type_allocator (of, language_c).new_type ();

  type->set_code (TYPE_CODE_FUNC);
  if (ctf_func_type_info (fp, tid, &cfi) < 0)
    {
      const char *fname = ctf_type_name_raw (fp, tid);
      error (_("Error getting function type info: %s"),
	     fname == nullptr ? "noname" : fname);
    }
  rettype = fetch_tid_type (ccp, cfi.ctc_return);
  type->set_target_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->alloc_fields (argc);
      struct type *void_type = builtin_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;

  type = type_allocator (of, language_c).new_type ();

  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->set_length (ctf_type_size (fp, tid));
  /* Set the underlying type based on its ctf_type_size bits.  */
  type->set_target_type (objfile_int_type (of, type->length (), false));
  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 (inner_array->target_type ()->code () == TYPE_CODE_ARRAY)
    {
      inner_array->set_target_type (copy_type (inner_array->target_type ()));
      inner_array = inner_array->target_type ();
    }

  el_type = inner_array->target_type ();
  cnst |= TYPE_CONST (el_type);
  voltl |= TYPE_VOLATILE (el_type);
  inner_array->set_target_type (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 = builtin_type (objfile)->builtin_int;

  type_allocator alloc (objfile, language_c);
  range_type = create_static_range_type (alloc, idx_type, 0, ar.ctr_nelems - 1);
  type = create_array_type (alloc, element_type, range_type);
  if (ar.ctr_nelems <= 1)	/* Check if undefined upper bound.  */
    {
      range_type->bounds ()->high.set_undefined ();
      type->set_length (0);
      type->set_target_is_stub (true);
    }
  else
    type->set_length (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 = builtin_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 = builtin_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 = builtin_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 = type_allocator (objfile, language_c).new_type (TYPE_CODE_TYPEDEF,
							     0, aname);
  set_tid_type (objfile, tid, this_type);
  target_type = fetch_tid_type (ccp, btid);
  if (target_type != this_type)
    this_type->set_target_type (target_type);
  else
    this_type->set_target_type (nullptr);

  this_type->set_target_is_stub (this_type->target_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 = builtin_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 = type_allocator (of, language_c).new_type ();

  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->set_length (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 = builtin_type (ccp->of)->builtin_error;
	  }
	sym = new (&ccp->of->objfile_obstack) symbol;
	OBJSTAT (ccp->of, n_syms++);
	sym->set_type (type);
	sym->set_domain (VAR_DOMAIN);
	sym->set_aclass_index (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++);
      sym->set_type (type);
      sym->set_domain (VAR_DOMAIN);
      sym->set_aclass_index (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 section base for OBJFILE, TSIZE contains the size.  */

static CORE_ADDR
get_objfile_text_range (struct objfile *of, size_t *tsize)
{
  bfd *abfd = of->obfd.get ();
  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_compunit_symtab (ctf_psymtab *pst,
			   struct objfile *of, CORE_ADDR text_offset)
{
  struct ctf_context *ccp;

  ccp = &pst->context;
  ccp->builder = new buildsym_compunit
		       (of, pst->filename, 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.  */

static struct compunit_symtab *
ctf_end_compunit_symtab (ctf_psymtab *pst,
			 CORE_ADDR end_addr)
{
  struct ctf_context *ccp;

  ccp = &pst->context;
  struct compunit_symtab *result
    = ccp->builder->end_compunit_symtab (end_addr);
  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,
			     unrelocated_addr (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,
			unrelocated_addr (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)
	{
	  gdb_printf (_("Reading in CTF data for %s..."), filename);
	  gdb_flush (gdb_stdout);
	}

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

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

      set_text_low (unrelocated_addr (0));
      set_text_high (unrelocated_addr (tsize));
      compunit_symtab = ctf_end_compunit_symtab (this, offset + tsize);

      /* Finish up the debug error message.  */
      if (info_verbose)
	gdb_printf (_("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,
			 unrelocated_addr (0));

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

  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;
  int 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);
	[[fallthrough]];
      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,
			 unrelocated_addr (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,
			 unrelocated_addr (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 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.get ());
      isparent = true;
    }

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

  struct ctf_context *ccx = &pst->context;
  if (isparent == false)
    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)
    {
      gdb_printf (_("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.get ();
  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 */
