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

   Copyright (C) 2019-2022 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,
	       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 = 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;

  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);
      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 (objfile_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)));
    }

  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->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 = alloc_type (of);

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

  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->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 = 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->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 = 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)
    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 = 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->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 = objfile_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 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.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.  SECTION is
   the .text section number.  */

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

  ccp = &pst->context;
  struct compunit_symtab *result
    = ccp->builder->end_compunit_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)
	{
	  gdb_printf (_("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_compunit_symtab (this, objfile, offset);
      expand_psymtab (objfile);

      set_text_low (offset);
      set_text_high (offset + tsize);
      compunit_symtab = ctf_end_compunit_symtab (this, offset + tsize,
						 SECT_OFF_TEXT (objfile));

      /* 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, 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,
			 0, language_c, ccp->partial_symtabs, ccp->of);

  return 0;
}

/* Callback to add variable NAME with ID to partial symbol table.  */

static int
ctf_psymtab_var_cb (const char *name, ctf_id_t id, void *arg)
{
  struct ctf_context *ccp = (struct ctf_context *) arg;

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

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

static void
scan_partial_symbols (ctf_dict_t *cfp, psymtab_storage *partial_symtabs,
		      struct 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 */
