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

   Copyright (C) 2019-2023 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 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)
{
  struct bound_minimal_symbol msym;

  msym = lookup_minimal_symbol (name, nullptr, 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->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;

  type_allocator alloc (objfile);
  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);
  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);
      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 (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)));
    }

  type_allocator alloc (of);
  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).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).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->set_fields
	((struct field *) TYPE_ZALLOC (type, argc * sizeof (struct field)));
      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).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);
  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).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).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;
  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,
			 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 */
