Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* [RFC PATCH 0/8] Make CTF reader build full symtabs, get rid of psymtab
@ 2026-02-03  6:45 simon.marchi
  2026-02-03  6:45 ` [RFC PATCH 1/8] gdb/ctf: add debug logging in ctfread.c simon.marchi
                   ` (9 more replies)
  0 siblings, 10 replies; 52+ messages in thread
From: simon.marchi @ 2026-02-03  6:45 UTC (permalink / raw)
  To: gdb-patches; +Cc: Nick Alcock, Weimin Pan, Simon Marchi

From: Simon Marchi <simon.marchi@polymtl.ca>

The CTF debug info reader is the last user of psymtabs.  This seriies
changes the CTF reader to no longer create psymtabs, but instead create
full symtabs from the start.  My hypothesis is that CTF debug info is
typically small enough and quick enough to process that we don't need an
intermediate step before the full symtabs.

This is an RFC, because I would like to collect comments (especially
from the CTF experts) on whether the startup time remains acceptable,
even for large programs.  I also think that my use of
expanded_symbols_functions in the last patch is not quite right, I'll
need to look into that further.

Simon Marchi (8):
  gdb/ctf: add debug logging in ctfread.c
  gdb/ctf: add unique_ptr types
  gdb/ctf: editorial renames
  gdb/ctf: use ctf_per_objfile in ctf_archive_iter_psymtab_data and
    ctf_context
  gdb/ctf: check return value of ctf_type_align
  gdb/ctf: add scoped_time_it in elfctf_build_psymtabs
  gdb/ctf: don't use psymtabs, create symtabs directly
  gdb: remove psymtab.{c,h}

 gdb/Makefile.in     |    2 -
 gdb/NEWS            |    4 +
 gdb/ctfread.c       |  691 ++++++++-----------
 gdb/ctfread.h       |    2 +-
 gdb/doc/gdb.texinfo |    7 +
 gdb/elfread.c       |    8 +-
 gdb/psymtab.c       | 1575 -------------------------------------------
 gdb/psymtab.h       |  691 -------------------
 8 files changed, 284 insertions(+), 2696 deletions(-)
 delete mode 100644 gdb/psymtab.c
 delete mode 100644 gdb/psymtab.h


base-commit: b11507b3dcc451e22ee29c89f386fab62b4e5b44
-- 
2.52.0


^ permalink raw reply	[flat|nested] 52+ messages in thread

* [RFC PATCH 1/8] gdb/ctf: add debug logging in ctfread.c
  2026-02-03  6:45 [RFC PATCH 0/8] Make CTF reader build full symtabs, get rid of psymtab simon.marchi
@ 2026-02-03  6:45 ` simon.marchi
  2026-02-03 12:40   ` Eli Zaretskii
  2026-02-03  6:45 ` [RFC PATCH 2/8] gdb/ctf: add unique_ptr types simon.marchi
                   ` (8 subsequent siblings)
  9 siblings, 1 reply; 52+ messages in thread
From: simon.marchi @ 2026-02-03  6:45 UTC (permalink / raw)
  To: gdb-patches; +Cc: Nick Alcock, Weimin Pan, Simon Marchi

From: Simon Marchi <simon.marchi@polymtl.ca>

Add some debug statements, to be able to visualize what is happening
when loading CTF debug info.  Add a new "set debug ctf" command, with
the usual logging macros.

Here's an example of the result, when reading the binary from test
gdb.ctf/cruss-tu-cyclic:

    [ctf] elfctf_build_psymtabs: start: building psymtabs for /home/simark/build/binutils-gdb/gdb/testsuite/outputs/gdb.ctf/cross-tu-cyclic/cross-tu-cyclic
      [ctf] scan_partial_symbols: start: fname='.ctf'
        [ctf] scan_partial_symbols: is parent, using fname='/home/simark/build/binutils-gdb/gdb/testsuite/outputs/gdb.ctf/cross-tu-cyclic/cross-tu-cyclic'
        [ctf] ctf_psymtab_type_cb: adding type tid=0x1 kind=INTEGER name='int'
        [ctf] ctf_psymtab_type_cb: adding type tid=0x2 kind=INTEGER name='long int'
        [ctf] ctf_psymtab_type_cb: adding type tid=0x3 kind=FORWARD name='B'
        [ctf] ctf_psymtab_type_cb: adding type tid=0x5 kind=FORWARD name='A'
        [ctf] ctf_psymtab_type_cb: adding type tid=0x8 kind=STRUCT name='C'
        [ctf] ctf_psymtab_add_stt_entries: adding function psym 'main' tid=0x7 kind=FUNCTION
      [ctf] scan_partial_symbols: end: fname='.ctf'
      [ctf] scan_partial_symbols: start: fname='/home/simark/src/binutils-gdb/gdb/testsuite/gdb.ctf/cross-tu-cyclic-1.c'
        [ctf] ctf_psymtab_type_cb: adding type tid=0x80000001 kind=STRUCT name='B'
        [ctf] ctf_psymtab_type_cb: adding type tid=0x80000002 kind=STRUCT name='A'
      [ctf] scan_partial_symbols: end: fname='/home/simark/src/binutils-gdb/gdb/testsuite/gdb.ctf/cross-tu-cyclic-1.c'
      [ctf] scan_partial_symbols: start: fname='/home/simark/src/binutils-gdb/gdb/testsuite/gdb.ctf/cross-tu-cyclic-2.c'
        [ctf] ctf_psymtab_type_cb: adding type tid=0x80000001 kind=STRUCT name='A'
      [ctf] scan_partial_symbols: end: fname='/home/simark/src/binutils-gdb/gdb/testsuite/gdb.ctf/cross-tu-cyclic-2.c'
      [ctf] scan_partial_symbols: start: fname='/home/simark/src/binutils-gdb/gdb/testsuite/gdb.ctf/cross-tu-cyclic-3.c'
        [ctf] ctf_psymtab_type_cb: adding type tid=0x80000001 kind=STRUCT name='A'
      [ctf] scan_partial_symbols: end: fname='/home/simark/src/binutils-gdb/gdb/testsuite/gdb.ctf/cross-tu-cyclic-3.c'
      [ctf] scan_partial_symbols: start: fname='/home/simark/src/binutils-gdb/gdb/testsuite/gdb.ctf/cross-tu-cyclic-4.c'
        [ctf] ctf_psymtab_type_cb: adding type tid=0x80000001 kind=STRUCT name='A'
        [ctf] ctf_psymtab_type_cb: adding type tid=0x80000002 kind=STRUCT name='B'
      [ctf] scan_partial_symbols: end: fname='/home/simark/src/binutils-gdb/gdb/testsuite/gdb.ctf/cross-tu-cyclic-4.c'
    [ctf] elfctf_build_psymtabs: end: building psymtabs for /home/simark/build/binutils-gdb/gdb/testsuite/outputs/gdb.ctf/cross-tu-cyclic/cross-tu-cyclic

Change-Id: If3800d14dd965ccefa67a24ef5c4481aef70ffa4
---
 gdb/NEWS            |  4 ++
 gdb/ctfread.c       | 95 ++++++++++++++++++++++++++++++++++++++++++++-
 gdb/doc/gdb.texinfo |  7 ++++
 3 files changed, 104 insertions(+), 2 deletions(-)

diff --git a/gdb/NEWS b/gdb/NEWS
index fa6e7ca61219..af04fa1e67ae 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -91,6 +91,10 @@ show progress-bars enabled
   content, to be disabled (the set command), or to see if
   progress-bars are currently enabled or not (the show command).
 
+set debug ctf on|off
+show debug ctf
+  Print debug messages about CTF reading.
+
 * Changed commands
 
 maintenance info program-spaces
diff --git a/gdb/ctfread.c b/gdb/ctfread.c
index e24d0ef60d02..141f51f621b0 100644
--- a/gdb/ctfread.c
+++ b/gdb/ctfread.c
@@ -80,12 +80,49 @@
 #include "block.h"
 #include "ctfread.h"
 #include "psymtab.h"
+#include "cli/cli-cmds.h"
+
+/* When true, print debug messages related to CTF reading.  */
+static bool debug_ctf = false;
+
+/* Print a "ctf" debug statement.  */
+
+#define ctf_debug_printf(fmt, ...) \
+  debug_prefixed_printf_cond (debug_ctf, "ctf", fmt, ##__VA_ARGS__)
+
+#define CTF_SCOPED_DEBUG_START_END(fmt, ...) \
+  scoped_debug_start_end (debug_ctf, "ctf", fmt, ##__VA_ARGS__)
 
 #if ENABLE_LIBCTF
 
 #include "ctf.h"
 #include "ctf-api.h"
 
+/* Return a string representation of a CTF type kind.  */
+
+static const char *
+ctf_kind_str (uint32_t kind)
+{
+  switch (kind)
+    {
+    case CTF_K_UNKNOWN: return "UNKNOWN";
+    case CTF_K_INTEGER: return "INTEGER";
+    case CTF_K_FLOAT: return "FLOAT";
+    case CTF_K_POINTER: return "POINTER";
+    case CTF_K_ARRAY: return "ARRAY";
+    case CTF_K_FUNCTION: return "FUNCTION";
+    case CTF_K_STRUCT: return "STRUCT";
+    case CTF_K_UNION: return "UNION";
+    case CTF_K_ENUM: return "ENUM";
+    case CTF_K_FORWARD: return "FORWARD";
+    case CTF_K_TYPEDEF: return "TYPEDEF";
+    case CTF_K_VOLATILE: return "VOLATILE";
+    case CTF_K_CONST: return "CONST";
+    case CTF_K_RESTRICT: return "RESTRICT";
+    default: return "???";
+    }
+}
+
 using ctf_type_map = gdb::unordered_map<ctf_id_t, struct type *>;
 
 struct ctf_dict_info
@@ -992,10 +1029,18 @@ ctf_add_type_cb (ctf_id_t tid, void *arg)
   /* Check if tid's type has already been defined.  */
   type = get_tid_type (ccp->of, tid);
   if (type != nullptr)
-    return 0;
+    {
+      ctf_debug_printf ("tid=%ld already defined, skipping", tid);
+      return 0;
+    }
 
   ctf_id_t btid = ctf_type_reference (ccp->dict, tid);
   kind = ctf_type_kind (ccp->dict, tid);
+
+  ctf_debug_printf ("processing tid=%ld kind=%s name='%s' btid=%ld",
+		    tid, ctf_kind_str (kind),
+		    ctf_type_name_raw (ccp->dict, tid) ? : "(null)", btid);
+
   switch (kind)
     {
       case CTF_K_STRUCT:
@@ -1059,6 +1104,9 @@ ctf_add_var_cb (const char *name, ctf_id_t id, void *arg)
 
   kind = ctf_type_kind (ccp->dict, id);
 
+  ctf_debug_printf ("adding variable name='%s' tid=%ld kind=%s",
+		    name, id, ctf_kind_str (kind));
+
   if (type == nullptr)
     {
       complaint (_("ctf_add_var_cb: %s has NO type (%ld)"), name, id);
@@ -1101,7 +1149,15 @@ add_stt_entries (struct ctf_context *ccp, int functions)
     {
       type = get_tid_type (ccp->of, tid);
       if (type == nullptr)
-	continue;
+	{
+	  ctf_debug_printf ("skipping '%s' tid=0x%lx (no type found)",
+			    tname, tid);
+	  continue;
+	}
+
+      ctf_debug_printf ("adding %s '%s' tid=0x%lx",
+			functions ? "function" : "object", tname, tid);
+
       sym = new (&ccp->of->objfile_obstack) symbol;
       OBJSTAT (ccp->of, n_syms++);
       sym->set_type (type);
@@ -1186,6 +1242,10 @@ ctf_psymtab_add_stt_entries (ctf_dict_t *dict, ctf_psymtab *pst,
       else
 	loc_class = LOC_STATIC;
 
+      ctf_debug_printf ("adding %s psym '%s' tid=0x%lx kind=%s",
+			functions ? "function" : "object", tname, tid,
+			ctf_kind_str (kind));
+
       pst->add_psymbol (tname, true,
 			tdomain, loc_class, -1,
 			psymbol_placement::GLOBAL,
@@ -1219,6 +1279,8 @@ ctf_psymtab::expand_psymtab (struct objfile *objfile)
 {
   struct ctf_context *ccp;
 
+  CTF_SCOPED_DEBUG_START_END ("expanding psymtab");
+
   gdb_assert (!readin);
 
   ccp = &context;
@@ -1247,6 +1309,8 @@ ctf_psymtab::expand_psymtab (struct objfile *objfile)
 void
 ctf_psymtab::read_symtab (struct objfile *objfile)
 {
+  CTF_SCOPED_DEBUG_START_END ("reading symtab for '%s'", filename);
+
   if (readin)
     warning (_("bug: psymtab for %s is already read in."), filename);
   else
@@ -1263,6 +1327,9 @@ ctf_psymtab::read_symtab (struct objfile *objfile)
 
       offset = get_objfile_text_range (objfile, &tsize);
 
+      ctf_debug_printf ("starting buildsym for '%s', offset=%s, tsize=%zu",
+			filename, hex_string (offset), tsize);
+
       buildsym_compunit builder (objfile, this->filename, nullptr,
 				 language_c, offset);
       builder.record_debugformat ("ctf");
@@ -1360,6 +1427,9 @@ ctf_psymtab_type_cb (ctf_id_t tid, void *arg)
   if (name == nullptr || *name == '\0')
     return 0;
 
+  ctf_debug_printf ("adding type tid=0x%lx kind=%s name='%s'",
+		    tid, ctf_kind_str (kind), name);
+
   ccp->pst->add_psymbol (name, false,
 			 domain, loc_class, section,
 			 psymbol_placement::GLOBAL,
@@ -1377,6 +1447,10 @@ ctf_psymtab_var_cb (const char *name, ctf_id_t id, void *arg)
   struct ctf_context *ccp = (struct ctf_context *) arg;
 
   uint32_t kind = ctf_type_kind (ccp->dict, id);
+
+  ctf_debug_printf ("adding variable name='%s' tid=0x%lx kind=%s",
+		    name, id, ctf_kind_str (kind));
+
   ccp->pst->add_psymbol (name, true,
 			 kind == CTF_K_FUNCTION
 			 ? FUNCTION_DOMAIN
@@ -1398,10 +1472,13 @@ scan_partial_symbols (ctf_dict_t *dict, psymtab_storage *partial_symtabs,
   struct objfile *of = tup->of;
   bool isparent = false;
 
+  CTF_SCOPED_DEBUG_START_END ("fname='%s'", fname);
+
   if (strcmp (fname, ".ctf") == 0)
     {
       fname = bfd_get_filename (of->obfd.get ());
       isparent = true;
+      ctf_debug_printf ("is parent, using fname='%s'", fname);
     }
 
   ctf_psymtab *pst = create_partial_symtab (fname, tup->arc, dict,
@@ -1462,6 +1539,9 @@ elfctf_build_psymtabs (struct objfile *of)
   bfd *abfd = of->obfd.get ();
   int err;
 
+  CTF_SCOPED_DEBUG_START_END ("building psymtabs for %s",
+			      bfd_get_filename (abfd));
+
   ctf_archive_t *arc = ctf_bfdopen (abfd, &err);
   if (arc == nullptr)
     error (_("ctf_bfdopen failed on %s - %s"),
@@ -1495,3 +1575,14 @@ elfctf_build_psymtabs (struct objfile *of)
 }
 
 #endif /* ENABLE_LIBCTF */
+
+INIT_GDB_FILE (_initialize_ctfread)
+{
+  add_setshow_boolean_cmd ("ctf", no_class, &debug_ctf,
+			   _("Set CTF reading debugging."),
+			   _("Show CTF reading debugging."),
+			   _("When true, print debug messages related to "
+			     "CTF reading."),
+			   nullptr, nullptr,
+			   &setdebuglist, &showdebuglist);
+}
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index d39fa02b7119..24c6c44e744c 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -29244,6 +29244,13 @@ exported symbols.  The default is off.
 Displays the current state of displaying debugging messages related to
 reading of COFF/PE exported symbols.
 
+@item set debug ctf
+@cindex CTF debug messages
+Turns on or off display of debugging messages related to reading CTF
+debug info.  The default is off.
+@item show debug ctf
+Displays the current state of CTF debug info reading messages.
+
 @item set debug dwarf-die
 @cindex DWARF DIEs
 Dump DWARF DIEs after they are read in.
-- 
2.52.0


^ permalink raw reply	[flat|nested] 52+ messages in thread

* [RFC PATCH 2/8] gdb/ctf: add unique_ptr types
  2026-02-03  6:45 [RFC PATCH 0/8] Make CTF reader build full symtabs, get rid of psymtab simon.marchi
  2026-02-03  6:45 ` [RFC PATCH 1/8] gdb/ctf: add debug logging in ctfread.c simon.marchi
@ 2026-02-03  6:45 ` simon.marchi
  2026-02-03  6:45 ` [RFC PATCH 3/8] gdb/ctf: editorial renames simon.marchi
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 52+ messages in thread
From: simon.marchi @ 2026-02-03  6:45 UTC (permalink / raw)
  To: gdb-patches; +Cc: Nick Alcock, Weimin Pan, Simon Marchi

From: Simon Marchi <simon.marchi@polymtl.ca>

Add ctf_archive_up and ctf_dict_up to automatically manage the lifetime
of a ctf_archive_t of ctf_dict_t and use them.

Change-Id: I51b3548b1bb28941c7bad776a11a238eb25789e4
---
 gdb/ctfread.c | 56 ++++++++++++++++++++++++++++++++-------------------
 1 file changed, 35 insertions(+), 21 deletions(-)

diff --git a/gdb/ctfread.c b/gdb/ctfread.c
index 141f51f621b0..5fd55d3f78f3 100644
--- a/gdb/ctfread.c
+++ b/gdb/ctfread.c
@@ -125,28 +125,40 @@ ctf_kind_str (uint32_t kind)
 
 using ctf_type_map = gdb::unordered_map<ctf_id_t, struct type *>;
 
-struct ctf_dict_info
+struct ctf_archive_closer
 {
-  explicit ctf_dict_info (ctf_dict_t *dict) : dict (dict) {}
-  ~ctf_dict_info ();
+  void operator() (ctf_archive_t *arc) const noexcept
+  {
+    ctf_close (arc);
+  }
+};
 
-  /* Map from IDs to types.  */
-  ctf_type_map type_map;
+using ctf_archive_up = std::unique_ptr<ctf_archive_t, ctf_archive_closer>;
 
-  /* The dictionary.  */
-  ctf_dict_t *dict;
+struct ctf_dict_closer
+{
+  void operator() (ctf_dict_t *dict) const noexcept
+  {
+    ctf_dict_close (dict);
+  }
 };
 
-/* Cleanup function for the ctf_dict_key data.  */
-ctf_dict_info::~ctf_dict_info ()
+using ctf_dict_up = std::unique_ptr<ctf_dict_t, ctf_dict_closer>;
+
+struct ctf_dict_info
 {
-  if (dict == nullptr)
-    return;
+  explicit ctf_dict_info (ctf_archive_up archive, ctf_dict_up dict)
+    : archive (std::move (archive)),
+      dict (std::move (dict))
+  {}
 
-  ctf_archive_t *arc = ctf_get_arc (dict);
-  ctf_dict_close (dict);
-  ctf_close (arc);
-}
+  /* Map from IDs to types.  */
+  ctf_type_map type_map;
+
+  /* The archive and dictionary.  */
+  ctf_archive_up archive;
+  ctf_dict_up dict;
+};
 
 static const registry<objfile>::key<ctf_dict_info> ctf_dict_key;
 
@@ -1542,26 +1554,28 @@ elfctf_build_psymtabs (struct objfile *of)
   CTF_SCOPED_DEBUG_START_END ("building psymtabs for %s",
 			      bfd_get_filename (abfd));
 
-  ctf_archive_t *arc = ctf_bfdopen (abfd, &err);
+  ctf_archive_up 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 *dict = ctf_dict_open (arc, NULL, &err);
+  ctf_dict_up dict (ctf_dict_open (arc.get (), NULL, &err));
   if (dict == nullptr)
     error (_("ctf_dict_open failed on %s - %s"),
 	   bfd_get_filename (abfd), ctf_errmsg (err));
-  ctf_dict_key.emplace (of, dict);
 
-  pcu.dict = dict;
+  ctf_dict_info *dict_info
+    = ctf_dict_key.emplace (of, std::move (arc), std::move (dict));
+
+  pcu.dict = dict_info->dict.get ();
   pcu.of = of;
-  pcu.arc = arc;
+  pcu.arc = dict_info->archive.get ();
 
   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)
+  if (ctf_archive_iter (pcu.arc, build_ctf_archive_member, &pcu) < 0)
     error (_("ctf_archive_iter failed in input file %s: - %s"),
 	   bfd_get_filename (abfd), ctf_errmsg (err));
 }
-- 
2.52.0


^ permalink raw reply	[flat|nested] 52+ messages in thread

* [RFC PATCH 3/8] gdb/ctf: editorial renames
  2026-02-03  6:45 [RFC PATCH 0/8] Make CTF reader build full symtabs, get rid of psymtab simon.marchi
  2026-02-03  6:45 ` [RFC PATCH 1/8] gdb/ctf: add debug logging in ctfread.c simon.marchi
  2026-02-03  6:45 ` [RFC PATCH 2/8] gdb/ctf: add unique_ptr types simon.marchi
@ 2026-02-03  6:45 ` simon.marchi
  2026-02-03  6:45 ` [RFC PATCH 4/8] gdb/ctf: use ctf_per_objfile in ctf_archive_iter_psymtab_data and ctf_context simon.marchi
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 52+ messages in thread
From: simon.marchi @ 2026-02-03  6:45 UTC (permalink / raw)
  To: gdb-patches; +Cc: Nick Alcock, Weimin Pan, Simon Marchi

From: Simon Marchi <simon.marchi@polymtl.ca>

Rename a few things to fit a bit more with how we typically name things,
or make the names more accurate.  I think this makes the code easier to
follow for anyone familiar with the GDB codebase (or at least, familiar
with the DWARF reader).  It's not super important, but it did help me
understand better the flow of the reader.

 - struct ctf_dict_info -> struct ctf_per_objfile
 - ctf_per_objfile::dict -> ctf_per_objfile::parent_dict
 - ctf_dict_key -> ctf_per_objfile_key
 - ctf_per_tu_data -> ctf_archive_iter_psymtab_data
 - ctf_archive_iter_psymtab_data::dict -> ctf_archive_iter_psymtab_data::parent_dict
 - of -> objfile
 - arc -> archive
 - In build_ctf_archive_member, ctf -> dict

Change-Id: I40f3cba8e40e4c9d006a96032a4c3856bd762ed5
---
 gdb/ctfread.c | 235 +++++++++++++++++++++++++-------------------------
 1 file changed, 119 insertions(+), 116 deletions(-)

diff --git a/gdb/ctfread.c b/gdb/ctfread.c
index 5fd55d3f78f3..5106af621dab 100644
--- a/gdb/ctfread.c
+++ b/gdb/ctfread.c
@@ -145,29 +145,29 @@ struct ctf_dict_closer
 
 using ctf_dict_up = std::unique_ptr<ctf_dict_t, ctf_dict_closer>;
 
-struct ctf_dict_info
+struct ctf_per_objfile
 {
-  explicit ctf_dict_info (ctf_archive_up archive, ctf_dict_up dict)
+  explicit ctf_per_objfile (ctf_archive_up archive, ctf_dict_up dict)
     : archive (std::move (archive)),
-      dict (std::move (dict))
+      parent_dict (std::move (dict))
   {}
 
   /* Map from IDs to types.  */
   ctf_type_map type_map;
 
-  /* The archive and dictionary.  */
+  /* The archive and parent dictionary.  */
   ctf_archive_up archive;
-  ctf_dict_up dict;
+  ctf_dict_up parent_dict;
 };
 
-static const registry<objfile>::key<ctf_dict_info> ctf_dict_key;
+static const registry<objfile>::key<ctf_per_objfile> ctf_per_objfile_key;
 
 /* A CTF context consists of a file pointer and an objfile pointer.  */
 
 struct ctf_context
 {
   ctf_dict_t *dict;
-  struct objfile *of;
+  struct objfile *objfile;
   psymtab_storage *partial_symtabs;
   partial_symtab *pst;
   ctf_archive_t *arc;
@@ -220,13 +220,13 @@ struct ctf_field_info
   std::vector<struct decl_field> nested_types_list;
 };
 
-/* Data held for a translation unit.  */
+/* Data held while using ctf_archive_iter to build psymtabs.  */
 
-struct ctf_per_tu_data
+struct ctf_archive_iter_psymtab_data
 {
-  ctf_dict_t *dict;
-  struct objfile *of;
-  ctf_archive_t *arc;
+  ctf_dict_t *parent_dict;
+  struct objfile *objfile;
+  ctf_archive_t *archive;
   psymbol_functions *psf;
 };
 
@@ -258,11 +258,11 @@ static struct type *read_forward_type (struct ctf_context *cp, ctf_id_t 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)
+set_tid_type (struct objfile *objfile, ctf_id_t tid, struct type *typ)
 {
-  ctf_dict_info *info = ctf_dict_key.get (of);
-  gdb_assert (info != nullptr);
-  info->type_map.emplace (tid, typ);
+  ctf_per_objfile *per_objfile = ctf_per_objfile_key.get (objfile);
+  gdb_assert (per_objfile != nullptr);
+  per_objfile->type_map.emplace (tid, typ);
   return typ;
 }
 
@@ -270,13 +270,13 @@ set_tid_type (struct objfile *of, ctf_id_t tid, struct type *typ)
    does not have a saved type.  */
 
 static struct type *
-get_tid_type (struct objfile *of, ctf_id_t tid)
+get_tid_type (struct objfile *objfile, ctf_id_t tid)
 {
-  ctf_dict_info *info = ctf_dict_key.get (of);
-  gdb_assert (info != nullptr);
+  ctf_per_objfile *per_objfile = ctf_per_objfile_key.get (objfile);
+  gdb_assert (per_objfile != nullptr);
 
-  auto iter = info->type_map.find (tid);
-  if (iter == info->type_map.end ())
+  auto iter = per_objfile->type_map.find (tid);
+  if (iter == per_objfile->type_map.end ())
     return nullptr;
   return iter->second;
 }
@@ -287,14 +287,14 @@ get_tid_type (struct objfile *of, ctf_id_t tid)
 static struct type *
 fetch_tid_type (struct ctf_context *ccp, ctf_id_t tid)
 {
-  struct objfile *of = ccp->of;
+  struct objfile *objfile = ccp->objfile;
   struct type *typ;
 
-  typ = get_tid_type (of, tid);
+  typ = get_tid_type (objfile, tid);
   if (typ == nullptr)
     {
       ctf_add_type_cb (tid, ccp);
-      typ = get_tid_type (of, tid);
+      typ = get_tid_type (objfile, tid);
     }
 
   return typ;
@@ -319,10 +319,11 @@ get_bitsize (ctf_dict_t *dict, ctf_id_t tid, uint32_t kind)
 /* 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)
+set_symbol_address (struct objfile *objfile, struct symbol *sym,
+		    const char *name)
 {
   bound_minimal_symbol msym
-    = lookup_minimal_symbol (current_program_space, name, of);
+    = lookup_minimal_symbol (current_program_space, name, objfile);
   if (msym.minsym != NULL)
     {
       sym->set_value_address (msym.value_address ());
@@ -404,8 +405,8 @@ ctf_add_member_cb (const char *name,
       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);
+	  t = builtin_type (ccp->objfile)->builtin_error;
+	  set_tid_type (ccp->objfile, tid, t);
 	}
     }
 
@@ -440,11 +441,11 @@ ctf_add_enum_member_cb (const char *name, int enum_value, void *arg)
 
   if (name != nullptr && *name != '\0')
     {
-      struct symbol *sym = new (&ccp->of->objfile_obstack) symbol;
-      OBJSTAT (ccp->of, n_syms++);
+      struct symbol *sym = new (&ccp->objfile->objfile_obstack) symbol;
+      OBJSTAT (ccp->objfile, n_syms++);
 
-      sym->set_language (language_c, &ccp->of->objfile_obstack);
-      sym->compute_and_set_names (name, false, ccp->of->per_bfd);
+      sym->set_language (language_c, &ccp->objfile->objfile_obstack);
+      sym->compute_and_set_names (name, false, ccp->objfile->per_bfd);
       sym->set_loc_class_index (LOC_CONST);
       sym->set_domain (VAR_DOMAIN);
       sym->set_type (fip->ptype);
@@ -467,7 +468,7 @@ new_type_symbol (struct ctf_context *ccp, struct type *type, ctf_id_t tid)
   const char *name = ctf_type_name_raw (dict, tid);
   if (name != nullptr && *name != '\0')
     {
-      struct objfile *objfile = ccp->of;
+      struct objfile *objfile = ccp->objfile;
       struct symbol *sym = new (&objfile->objfile_obstack) symbol;
       OBJSTAT (objfile, n_syms++);
 
@@ -499,7 +500,7 @@ new_type_symbol (struct ctf_context *ccp, struct type *type, ctf_id_t tid)
 static struct type *
 read_base_type (struct ctf_context *ccp, ctf_id_t tid)
 {
-  struct objfile *of = ccp->of;
+  struct objfile *objfile = ccp->objfile;
   ctf_dict_t *dict = ccp->dict;
   ctf_encoding_t cet;
   struct type *type = nullptr;
@@ -522,12 +523,12 @@ read_base_type (struct ctf_context *ccp, ctf_id_t tid)
 		   ctf_errmsg (ctf_errno (dict)));
     }
 
-  type_allocator alloc (of, language_c);
+  type_allocator alloc (objfile, language_c);
   kind = ctf_type_kind (dict, tid);
   if (kind == CTF_K_INTEGER)
     {
       uint32_t issigned, ischar, isbool;
-      struct gdbarch *gdbarch = of->arch ();
+      struct gdbarch *gdbarch = objfile->arch ();
 
       issigned = cet.cte_format & CTF_INT_SIGNED;
       ischar = cet.cte_format & CTF_INT_CHAR;
@@ -554,11 +555,11 @@ read_base_type (struct ctf_context *ccp, ctf_id_t tid)
 		 || (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);
+	type = ctf_init_float_type (objfile, cet.cte_bits, name, name);
       else
 	{
 	  struct type *t
-	    = ctf_init_float_type (of, cet.cte_bits / 2, NULL, name);
+	    = ctf_init_float_type (objfile, cet.cte_bits / 2, NULL, name);
 	  type = init_complex_type (name, t);
 	}
     }
@@ -571,7 +572,7 @@ read_base_type (struct ctf_context *ccp, ctf_id_t tid)
   if (name != nullptr && strcmp (name, "char") == 0)
     type->set_has_no_signedness (true);
 
-  return set_tid_type (of, tid, type);
+  return set_tid_type (objfile, tid, type);
 }
 
 static void
@@ -593,12 +594,12 @@ process_base_type (struct ctf_context *ccp, ctf_id_t tid)
 static struct type *
 read_structure_type (struct ctf_context *ccp, ctf_id_t tid)
 {
-  struct objfile *of = ccp->of;
+  struct objfile *objfile = ccp->objfile;
   ctf_dict_t *dict = ccp->dict;
   struct type *type;
   uint32_t kind;
 
-  type = type_allocator (of, language_c).new_type ();
+  type = type_allocator (objfile, language_c).new_type ();
 
   const char *name = ctf_type_name_raw (dict, tid);
   if (name != nullptr && *name != '\0')
@@ -613,7 +614,7 @@ read_structure_type (struct ctf_context *ccp, ctf_id_t tid)
   type->set_length (ctf_type_size (dict, tid));
   set_type_align (type, ctf_type_align (dict, tid));
 
-  return set_tid_type (ccp->of, tid, type);
+  return set_tid_type (ccp->objfile, tid, type);
 }
 
 /* Given a tid of CTF_K_STRUCT or CTF_K_UNION, process all its members
@@ -651,13 +652,13 @@ process_structure_type (struct ctf_context *ccp, ctf_id_t tid)
 static struct type *
 read_func_kind_type (struct ctf_context *ccp, ctf_id_t tid)
 {
-  struct objfile *of = ccp->of;
+  struct objfile *objfile = ccp->objfile;
   ctf_dict_t *dict = ccp->dict;
   struct type *type, *rettype, *atype;
   ctf_funcinfo_t cfi;
   uint32_t argc;
 
-  type = type_allocator (of, language_c).new_type ();
+  type = type_allocator (objfile, language_c).new_type ();
 
   type->set_code (TYPE_CODE_FUNC);
   if (ctf_func_type_info (dict, tid, &cfi) < 0)
@@ -683,7 +684,7 @@ read_func_kind_type (struct ctf_context *ccp, ctf_id_t tid)
 	return nullptr;
 
       type->alloc_fields (argc);
-      struct type *void_type = builtin_type (of)->builtin_void;
+      struct type *void_type = builtin_type (objfile)->builtin_void;
       /* If failed to find the argument type, fill it with void_type.  */
       for (int iparam = 0; iparam < argc; iparam++)
 	{
@@ -695,7 +696,7 @@ read_func_kind_type (struct ctf_context *ccp, ctf_id_t tid)
 	}
     }
 
-  return set_tid_type (of, tid, type);
+  return set_tid_type (objfile, tid, type);
 }
 
 /* Given a TID of CTF_K_ENUM, process all the members of the
@@ -704,11 +705,11 @@ read_func_kind_type (struct ctf_context *ccp, ctf_id_t tid)
 static struct type *
 read_enum_type (struct ctf_context *ccp, ctf_id_t tid)
 {
-  struct objfile *of = ccp->of;
+  struct objfile *objfile = ccp->objfile;
   ctf_dict_t *dict = ccp->dict;
   struct type *type;
 
-  type = type_allocator (of, language_c).new_type ();
+  type = type_allocator (objfile, language_c).new_type ();
 
   const char *name = ctf_type_name_raw (dict, tid);
   if (name != nullptr && *name != '\0')
@@ -717,10 +718,10 @@ read_enum_type (struct ctf_context *ccp, ctf_id_t tid)
   type->set_code (TYPE_CODE_ENUM);
   type->set_length (ctf_type_size (dict, tid));
   /* Set the underlying type based on its ctf_type_size bits.  */
-  type->set_target_type (objfile_int_type (of, type->length (), false));
+  type->set_target_type (objfile_int_type (objfile, type->length (), false));
   set_type_align (type, ctf_type_align (dict, tid));
 
-  return set_tid_type (of, tid, type);
+  return set_tid_type (objfile, tid, type);
 }
 
 static void
@@ -768,7 +769,7 @@ add_array_cv_type (struct ctf_context *ccp,
   voltl |= TYPE_VOLATILE (el_type);
   inner_array->set_target_type (make_cv_type (cnst, voltl, el_type));
 
-  return set_tid_type (ccp->of, tid, base_type);
+  return set_tid_type (ccp->objfile, tid, base_type);
 }
 
 /* Read all information from a TID of CTF_K_ARRAY.  */
@@ -776,7 +777,7 @@ add_array_cv_type (struct ctf_context *ccp,
 static struct type *
 read_array_type (struct ctf_context *ccp, ctf_id_t tid)
 {
-  struct objfile *objfile = ccp->of;
+  struct objfile *objfile = ccp->objfile;
   ctf_dict_t *dict = ccp->dict;
   struct type *element_type, *range_type, *idx_type;
   struct type *type;
@@ -819,7 +820,7 @@ read_array_type (struct ctf_context *ccp, ctf_id_t tid)
 static struct type *
 read_const_type (struct ctf_context *ccp, ctf_id_t tid, ctf_id_t btid)
 {
-  struct objfile *objfile = ccp->of;
+  struct objfile *objfile = ccp->objfile;
   struct type *base_type, *cv_type;
 
   base_type = fetch_tid_type (ccp, btid);
@@ -842,7 +843,7 @@ read_const_type (struct ctf_context *ccp, ctf_id_t tid, ctf_id_t btid)
 static struct type *
 read_volatile_type (struct ctf_context *ccp, ctf_id_t tid, ctf_id_t btid)
 {
-  struct objfile *objfile = ccp->of;
+  struct objfile *objfile = ccp->objfile;
   ctf_dict_t *dict = ccp->dict;
   struct type *base_type, *cv_type;
 
@@ -869,7 +870,7 @@ read_volatile_type (struct ctf_context *ccp, ctf_id_t tid, ctf_id_t 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 objfile *objfile = ccp->objfile;
   struct type *base_type, *cv_type;
 
   base_type = fetch_tid_type (ccp, btid);
@@ -893,7 +894,7 @@ 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 objfile *objfile = ccp->objfile;
   struct type *this_type, *target_type;
 
   char *aname = obstack_strdup (&objfile->objfile_obstack, name);
@@ -916,7 +917,7 @@ read_typedef_type (struct ctf_context *ccp, ctf_id_t tid,
 static struct type *
 read_pointer_type (struct ctf_context *ccp, ctf_id_t tid, ctf_id_t btid)
 {
-  struct objfile *of = ccp->of;
+  struct objfile *objfile = ccp->objfile;
   struct type *target_type, *type;
 
   target_type = fetch_tid_type (ccp, btid);
@@ -926,14 +927,14 @@ read_pointer_type (struct ctf_context *ccp, ctf_id_t tid, ctf_id_t btid)
       if (target_type == nullptr)
 	{
 	  complaint (_("read_pointer_type: NULL target type (%ld)"), btid);
-	  target_type = builtin_type (ccp->of)->builtin_error;
+	  target_type = builtin_type (ccp->objfile)->builtin_error;
 	}
     }
 
   type = lookup_pointer_type (target_type);
   set_type_align (type, ctf_type_align (ccp->dict, tid));
 
-  return set_tid_type (of, tid, type);
+  return set_tid_type (objfile, tid, type);
 }
 
 /* Read information from a TID of CTF_K_FORWARD.  */
@@ -941,12 +942,12 @@ read_pointer_type (struct ctf_context *ccp, ctf_id_t tid, ctf_id_t btid)
 static struct type *
 read_forward_type (struct ctf_context *ccp, ctf_id_t tid)
 {
-  struct objfile *of = ccp->of;
+  struct objfile *objfile = ccp->objfile;
   ctf_dict_t *dict = ccp->dict;
   struct type *type;
   uint32_t kind;
 
-  type = type_allocator (of, language_c).new_type ();
+  type = type_allocator (objfile, language_c).new_type ();
 
   const char *name = ctf_type_name_raw (dict, tid);
   if (name != nullptr && *name != '\0')
@@ -961,7 +962,7 @@ read_forward_type (struct ctf_context *ccp, ctf_id_t tid)
   type->set_length (0);
   type->set_is_stub (true);
 
-  return set_tid_type (of, tid, type);
+  return set_tid_type (objfile, tid, type);
 }
 
 /* Read information associated with type TID.  */
@@ -1039,7 +1040,7 @@ ctf_add_type_cb (ctf_id_t tid, void *arg)
   uint32_t kind;
 
   /* Check if tid's type has already been defined.  */
-  type = get_tid_type (ccp->of, tid);
+  type = get_tid_type (ccp->objfile, tid);
   if (type != nullptr)
     {
       ctf_debug_printf ("tid=%ld already defined, skipping", tid);
@@ -1112,7 +1113,7 @@ ctf_add_var_cb (const char *name, ctf_id_t id, void *arg)
   struct type *type;
   uint32_t kind;
 
-  type = get_tid_type (ccp->of, id);
+  type = get_tid_type (ccp->objfile, id);
 
   kind = ctf_type_kind (ccp->dict, id);
 
@@ -1122,25 +1123,25 @@ ctf_add_var_cb (const char *name, ctf_id_t id, void *arg)
   if (type == nullptr)
     {
       complaint (_("ctf_add_var_cb: %s has NO type (%ld)"), name, id);
-      type = builtin_type (ccp->of)->builtin_error;
+      type = builtin_type (ccp->objfile)->builtin_error;
     }
-  sym = new (&ccp->of->objfile_obstack) symbol;
-  OBJSTAT (ccp->of, n_syms++);
+  sym = new (&ccp->objfile->objfile_obstack) symbol;
+  OBJSTAT (ccp->objfile, n_syms++);
   sym->set_type (type);
   sym->set_loc_class_index (LOC_OPTIMIZED_OUT);
-  sym->compute_and_set_names (name, false, ccp->of->per_bfd);
+  sym->compute_and_set_names (name, false, ccp->objfile->per_bfd);
 
   if (kind == CTF_K_FUNCTION)
     {
       sym->set_domain (FUNCTION_DOMAIN);
       if (name != nullptr && strcmp (name, "main") == 0)
-	set_objfile_main_name (ccp->of, name, language_c);
+	set_objfile_main_name (ccp->objfile, name, language_c);
     }
   else
     sym->set_domain (VAR_DOMAIN);
 
   add_symbol_to_list (sym, ccp->builder->get_global_symbols ());
-  set_symbol_address (ccp->of, sym, name);
+  set_symbol_address (ccp->objfile, sym, name);
 
   return 0;
 }
@@ -1159,7 +1160,7 @@ add_stt_entries (struct ctf_context *ccp, int functions)
 
   while ((tid = ctf_symbol_next (ccp->dict, &i, &tname, functions)) != CTF_ERR)
     {
-      type = get_tid_type (ccp->of, tid);
+      type = get_tid_type (ccp->objfile, tid);
       if (type == nullptr)
 	{
 	  ctf_debug_printf ("skipping '%s' tid=0x%lx (no type found)",
@@ -1170,14 +1171,14 @@ add_stt_entries (struct ctf_context *ccp, int functions)
       ctf_debug_printf ("adding %s '%s' tid=0x%lx",
 			functions ? "function" : "object", tname, tid);
 
-      sym = new (&ccp->of->objfile_obstack) symbol;
-      OBJSTAT (ccp->of, n_syms++);
+      sym = new (&ccp->objfile->objfile_obstack) symbol;
+      OBJSTAT (ccp->objfile, n_syms++);
       sym->set_type (type);
       sym->set_domain (functions ? FUNCTION_DOMAIN : VAR_DOMAIN);
       sym->set_loc_class_index (LOC_STATIC);
-      sym->compute_and_set_names (tname, false, ccp->of->per_bfd);
+      sym->compute_and_set_names (tname, false, ccp->objfile->per_bfd);
       add_symbol_to_list (sym, ccp->builder->get_global_symbols ());
-      set_symbol_address (ccp->of, sym, tname);
+      set_symbol_address (ccp->objfile, sym, tname);
     }
 }
 
@@ -1200,14 +1201,14 @@ add_stt_func (struct ctf_context *ccp)
 /* Get text section base for OBJFILE, TSIZE contains the size.  */
 
 static CORE_ADDR
-get_objfile_text_range (struct objfile *of, size_t *tsize)
+get_objfile_text_range (struct objfile *objfile, size_t *tsize)
 {
-  bfd *abfd = of->obfd.get ();
+  bfd *abfd = objfile->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 ();
+  return objfile->text_section_offset ();
 }
 
 /* Add all members of an enum with type TID to partial symbol table.  */
@@ -1225,7 +1226,7 @@ ctf_psymtab_add_enums (struct ctf_context *ccp, ctf_id_t tid)
 			     VAR_DOMAIN, LOC_CONST, -1,
 			     psymbol_placement::GLOBAL,
 			     unrelocated_addr (0),
-			     language_c, ccp->partial_symtabs, ccp->of);
+			     language_c, ccp->partial_symtabs, ccp->objfile);
     }
   if (ctf_errno (ccp->dict) != ECTF_NEXT_END)
     complaint (_("ctf_enum_next ctf_psymtab_add_enums failed - %s"),
@@ -1237,7 +1238,7 @@ ctf_psymtab_add_enums (struct ctf_context *ccp, ctf_id_t tid)
 
 static void
 ctf_psymtab_add_stt_entries (ctf_dict_t *dict, ctf_psymtab *pst,
-			     struct objfile *of, int functions)
+			     struct objfile *objfile, int functions)
 {
   ctf_next_t *i = nullptr;
   ctf_id_t tid;
@@ -1262,7 +1263,7 @@ ctf_psymtab_add_stt_entries (ctf_dict_t *dict, ctf_psymtab *pst,
 			tdomain, loc_class, -1,
 			psymbol_placement::GLOBAL,
 			unrelocated_addr (0),
-			language_c, pst->context.partial_symtabs, of);
+			language_c, pst->context.partial_symtabs, objfile);
     }
 }
 
@@ -1270,18 +1271,18 @@ ctf_psymtab_add_stt_entries (ctf_dict_t *dict, ctf_psymtab *pst,
 
 static void
 ctf_psymtab_add_stt_obj (ctf_dict_t *dict, ctf_psymtab *pst,
-			 struct objfile *of)
+			 struct objfile *objfile)
 {
-  ctf_psymtab_add_stt_entries (dict, pst, of, 0);
+  ctf_psymtab_add_stt_entries (dict, pst, objfile, 0);
 }
 
 /* Add entries in function info section to psymtab.  */
 
 static void
 ctf_psymtab_add_stt_func (ctf_dict_t *dict, ctf_psymtab *pst,
-			  struct objfile *of)
+			  struct objfile *objfile)
 {
-  ctf_psymtab_add_stt_entries (dict, pst, of, 1);
+  ctf_psymtab_add_stt_entries (dict, pst, objfile, 1);
 }
 
 /* Read in full symbols for PST, and anything it depends on.  */
@@ -1386,7 +1387,7 @@ create_partial_symtab (const char *name,
 
   pst->context.arc = arc;
   pst->context.dict = dict;
-  pst->context.of = objfile;
+  pst->context.objfile = objfile;
   pst->context.partial_symtabs = partial_symtabs;
   pst->context.pst = pst;
   pst->context.builder = nullptr;
@@ -1446,7 +1447,7 @@ ctf_psymtab_type_cb (ctf_id_t tid, void *arg)
 			 domain, loc_class, section,
 			 psymbol_placement::GLOBAL,
 			 unrelocated_addr (0),
-			 language_c, ccp->partial_symtabs, ccp->of);
+			 language_c, ccp->partial_symtabs, ccp->objfile);
 
   return 0;
 }
@@ -1470,7 +1471,7 @@ ctf_psymtab_var_cb (const char *name, ctf_id_t id, void *arg)
 			 LOC_STATIC, -1,
 			 psymbol_placement::GLOBAL,
 			 unrelocated_addr (0),
-			 language_c, ccp->partial_symtabs, ccp->of);
+			 language_c, ccp->partial_symtabs, ccp->objfile);
   return 0;
 }
 
@@ -1479,22 +1480,23 @@ ctf_psymtab_var_cb (const char *name, ctf_id_t id, void *arg)
 
 static void
 scan_partial_symbols (ctf_dict_t *dict, psymtab_storage *partial_symtabs,
-		      struct ctf_per_tu_data *tup, const char *fname)
+		      ctf_archive_iter_psymtab_data *iter_data,
+		      const char *fname)
 {
-  struct objfile *of = tup->of;
+  objfile *objfile = iter_data->objfile;
   bool isparent = false;
 
   CTF_SCOPED_DEBUG_START_END ("fname='%s'", fname);
 
   if (strcmp (fname, ".ctf") == 0)
     {
-      fname = bfd_get_filename (of->obfd.get ());
+      fname = bfd_get_filename (objfile->obfd.get ());
       isparent = true;
       ctf_debug_printf ("is parent, using fname='%s'", fname);
     }
 
-  ctf_psymtab *pst = create_partial_symtab (fname, tup->arc, dict,
-					    partial_symtabs, of);
+  ctf_psymtab *pst = create_partial_symtab (fname, iter_data->archive, dict,
+					    partial_symtabs, objfile);
 
   struct ctf_context *ccx = &pst->context;
   if (isparent == false)
@@ -1511,8 +1513,8 @@ scan_partial_symbols (ctf_dict_t *dict, psymtab_storage *partial_symtabs,
   /* 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 (dict, pst, of);
-  ctf_psymtab_add_stt_func (dict, pst, of);
+  ctf_psymtab_add_stt_obj (dict, pst, objfile);
+  ctf_psymtab_add_stt_func (dict, pst, objfile);
 
   pst->end ();
 }
@@ -1520,13 +1522,12 @@ scan_partial_symbols (ctf_dict_t *dict, psymtab_storage *partial_symtabs,
 /* Callback to build the psymtab for archive member NAME.  */
 
 static int
-build_ctf_archive_member (ctf_dict_t *ctf, const char *name, void *arg)
+build_ctf_archive_member (ctf_dict_t *dict, const char *name, void *arg)
 {
-  struct ctf_per_tu_data *tup = (struct ctf_per_tu_data *) arg;
-  ctf_dict_t *parent = tup->dict;
+  auto iter_data = static_cast<ctf_archive_iter_psymtab_data *> (arg);
 
   if (strcmp (name, ".ctf") != 0)
-    ctf_import (ctf, parent);
+    ctf_import (dict, iter_data->parent_dict);
 
   if (info_verbose)
     {
@@ -1534,8 +1535,8 @@ build_ctf_archive_member (ctf_dict_t *ctf, const char *name, void *arg)
       gdb_flush (gdb_stdout);
     }
 
-  psymtab_storage *pss = tup->psf->get_partial_symtabs ().get ();
-  scan_partial_symbols (ctf, pss, tup, name);
+  psymtab_storage *pss = iter_data->psf->get_partial_symtabs ().get ();
+  scan_partial_symbols (dict, pss, iter_data, name);
 
   return 0;
 }
@@ -1545,37 +1546,39 @@ build_ctf_archive_member (ctf_dict_t *ctf, const char *name, void *arg)
    .ctf section to set up the partial symbol table.  */
 
 void
-elfctf_build_psymtabs (struct objfile *of)
+elfctf_build_psymtabs (objfile *objfile)
 {
-  struct ctf_per_tu_data pcu;
-  bfd *abfd = of->obfd.get ();
+  bfd *abfd = objfile->obfd.get ();
   int err;
 
   CTF_SCOPED_DEBUG_START_END ("building psymtabs for %s",
 			      bfd_get_filename (abfd));
 
-  ctf_archive_up arc (ctf_bfdopen (abfd, &err));
-  if (arc == nullptr)
+  ctf_archive_up archive (ctf_bfdopen (abfd, &err));
+  if (archive == nullptr)
     error (_("ctf_bfdopen failed on %s - %s"),
 	   bfd_get_filename (abfd), ctf_errmsg (err));
 
-  ctf_dict_up dict (ctf_dict_open (arc.get (), NULL, &err));
+  ctf_dict_up dict (ctf_dict_open (archive.get (), NULL, &err));
   if (dict == nullptr)
     error (_("ctf_dict_open failed on %s - %s"),
 	   bfd_get_filename (abfd), ctf_errmsg (err));
 
-  ctf_dict_info *dict_info
-    = ctf_dict_key.emplace (of, std::move (arc), std::move (dict));
+  ctf_per_objfile *per_objfile
+    = ctf_per_objfile_key.emplace (objfile, std::move (archive),
+				   std::move (dict));
 
-  pcu.dict = dict_info->dict.get ();
-  pcu.of = of;
-  pcu.arc = dict_info->archive.get ();
+  ctf_archive_iter_psymtab_data iter_data;
+  iter_data.parent_dict = per_objfile->parent_dict.get ();
+  iter_data.objfile = objfile;
+  iter_data.archive = per_objfile->archive.get ();
 
   psymbol_functions *psf = new psymbol_functions ();
-  of->qf.emplace_front (psf);
-  pcu.psf = psf;
+  objfile->qf.emplace_front (psf);
+  iter_data.psf = psf;
 
-  if (ctf_archive_iter (pcu.arc, build_ctf_archive_member, &pcu) < 0)
+  if (ctf_archive_iter (iter_data.archive, build_ctf_archive_member, &iter_data)
+      < 0)
     error (_("ctf_archive_iter failed in input file %s: - %s"),
 	   bfd_get_filename (abfd), ctf_errmsg (err));
 }
@@ -1583,7 +1586,7 @@ elfctf_build_psymtabs (struct objfile *of)
 #else
 
 void
-elfctf_build_psymtabs (struct objfile *of)
+elfctf_build_psymtabs (struct objfile *objfile)
 {
   /* Nothing to do if CTF is disabled.  */
 }
-- 
2.52.0


^ permalink raw reply	[flat|nested] 52+ messages in thread

* [RFC PATCH 4/8] gdb/ctf: use ctf_per_objfile in ctf_archive_iter_psymtab_data and ctf_context
  2026-02-03  6:45 [RFC PATCH 0/8] Make CTF reader build full symtabs, get rid of psymtab simon.marchi
                   ` (2 preceding siblings ...)
  2026-02-03  6:45 ` [RFC PATCH 3/8] gdb/ctf: editorial renames simon.marchi
@ 2026-02-03  6:45 ` simon.marchi
  2026-02-12 17:44   ` Tom Tromey
  2026-02-03  6:45 ` [RFC PATCH 5/8] gdb/ctf: check return value of ctf_type_align simon.marchi
                   ` (5 subsequent siblings)
  9 siblings, 1 reply; 52+ messages in thread
From: simon.marchi @ 2026-02-03  6:45 UTC (permalink / raw)
  To: gdb-patches; +Cc: Nick Alcock, Weimin Pan, Simon Marchi

From: Simon Marchi <simon.marchi@polymtl.ca>

This patch slightly reorganizes the data structures in ctfread.c to be a
bit more like in the DWARF reader.  That is, instead of duplicating the
information (for instance, the objfile pointer), keep the information
once in the most general object where in make sense (in the
ctf_per_objfile in this case) and have the more specific objects (like
ctf_context, ctf_archive_iter_psymtab_data) have a link to the more
general object.

Concretely, that means removing the archive and parent_dict fields from
ctf_archive_iter_psymtab_data and ctf_context (those are per-objfile
information), adding backlink to the ctf_per_objfile and using the
parent_dict and archive fields there.  Similarly, remove the objfile
fields from these and add a new objfile field in ctf_per_objfile.

Remove the objfile and dict parameters from the ctf_psymtab_add_stt_*
functions, since they can be obtained from the other parameters.

No functional changes expected.

Change-Id: I837264eece869f2bb962842998dede8cd7806bfe
---
 gdb/ctfread.c | 188 ++++++++++++++++++++++++--------------------------
 1 file changed, 90 insertions(+), 98 deletions(-)

diff --git a/gdb/ctfread.c b/gdb/ctfread.c
index 5106af621dab..b2557ac31717 100644
--- a/gdb/ctfread.c
+++ b/gdb/ctfread.c
@@ -147,11 +147,16 @@ using ctf_dict_up = std::unique_ptr<ctf_dict_t, ctf_dict_closer>;
 
 struct ctf_per_objfile
 {
-  explicit ctf_per_objfile (ctf_archive_up archive, ctf_dict_up dict)
-    : archive (std::move (archive)),
+  explicit ctf_per_objfile (struct objfile *objfile, ctf_archive_up archive,
+			    ctf_dict_up dict)
+    : objfile (objfile),
+      archive (std::move (archive)),
       parent_dict (std::move (dict))
   {}
 
+  /* Backlink to objfile.  */
+  struct objfile *objfile;
+
   /* Map from IDs to types.  */
   ctf_type_map type_map;
 
@@ -162,15 +167,14 @@ struct ctf_per_objfile
 
 static const registry<objfile>::key<ctf_per_objfile> ctf_per_objfile_key;
 
-/* A CTF context consists of a file pointer and an objfile pointer.  */
+/* Data passed around when creating symtabs.  */
 
 struct ctf_context
 {
+  ctf_per_objfile *per_objfile;
   ctf_dict_t *dict;
-  struct objfile *objfile;
   psymtab_storage *partial_symtabs;
   partial_symtab *pst;
-  ctf_archive_t *arc;
   struct buildsym_compunit *builder;
 };
 
@@ -224,9 +228,7 @@ struct ctf_field_info
 
 struct ctf_archive_iter_psymtab_data
 {
-  ctf_dict_t *parent_dict;
-  struct objfile *objfile;
-  ctf_archive_t *archive;
+  ctf_per_objfile *per_objfile;
   psymbol_functions *psf;
 };
 
@@ -287,7 +289,7 @@ get_tid_type (struct objfile *objfile, ctf_id_t tid)
 static struct type *
 fetch_tid_type (struct ctf_context *ccp, ctf_id_t tid)
 {
-  struct objfile *objfile = ccp->objfile;
+  struct objfile *objfile = ccp->per_objfile->objfile;
   struct type *typ;
 
   typ = get_tid_type (objfile, tid);
@@ -404,9 +406,10 @@ ctf_add_member_cb (const char *name,
       t = read_type_record (ccp, tid);
       if (t == nullptr)
 	{
+	  objfile *objfile = ccp->per_objfile->objfile;
 	  complaint (_("ctf_add_member_cb: %s has NO type (%ld)"), name, tid);
-	  t = builtin_type (ccp->objfile)->builtin_error;
-	  set_tid_type (ccp->objfile, tid, t);
+	  t = builtin_type (objfile)->builtin_error;
+	  set_tid_type (objfile, tid, t);
 	}
     }
 
@@ -441,11 +444,12 @@ ctf_add_enum_member_cb (const char *name, int enum_value, void *arg)
 
   if (name != nullptr && *name != '\0')
     {
-      struct symbol *sym = new (&ccp->objfile->objfile_obstack) symbol;
-      OBJSTAT (ccp->objfile, n_syms++);
+      objfile *objfile = ccp->per_objfile->objfile;
+      struct symbol *sym = new (&objfile->objfile_obstack) symbol;
+      OBJSTAT (objfile, n_syms++);
 
-      sym->set_language (language_c, &ccp->objfile->objfile_obstack);
-      sym->compute_and_set_names (name, false, ccp->objfile->per_bfd);
+      sym->set_language (language_c, &objfile->objfile_obstack);
+      sym->compute_and_set_names (name, false, objfile->per_bfd);
       sym->set_loc_class_index (LOC_CONST);
       sym->set_domain (VAR_DOMAIN);
       sym->set_type (fip->ptype);
@@ -468,7 +472,7 @@ new_type_symbol (struct ctf_context *ccp, struct type *type, ctf_id_t tid)
   const char *name = ctf_type_name_raw (dict, tid);
   if (name != nullptr && *name != '\0')
     {
-      struct objfile *objfile = ccp->objfile;
+      objfile *objfile = ccp->per_objfile->objfile;
       struct symbol *sym = new (&objfile->objfile_obstack) symbol;
       OBJSTAT (objfile, n_syms++);
 
@@ -500,7 +504,7 @@ new_type_symbol (struct ctf_context *ccp, struct type *type, ctf_id_t tid)
 static struct type *
 read_base_type (struct ctf_context *ccp, ctf_id_t tid)
 {
-  struct objfile *objfile = ccp->objfile;
+  objfile *objfile = ccp->per_objfile->objfile;
   ctf_dict_t *dict = ccp->dict;
   ctf_encoding_t cet;
   struct type *type = nullptr;
@@ -594,7 +598,7 @@ process_base_type (struct ctf_context *ccp, ctf_id_t tid)
 static struct type *
 read_structure_type (struct ctf_context *ccp, ctf_id_t tid)
 {
-  struct objfile *objfile = ccp->objfile;
+  objfile *objfile = ccp->per_objfile->objfile;
   ctf_dict_t *dict = ccp->dict;
   struct type *type;
   uint32_t kind;
@@ -614,7 +618,7 @@ read_structure_type (struct ctf_context *ccp, ctf_id_t tid)
   type->set_length (ctf_type_size (dict, tid));
   set_type_align (type, ctf_type_align (dict, tid));
 
-  return set_tid_type (ccp->objfile, tid, type);
+  return set_tid_type (objfile, tid, type);
 }
 
 /* Given a tid of CTF_K_STRUCT or CTF_K_UNION, process all its members
@@ -652,7 +656,7 @@ process_structure_type (struct ctf_context *ccp, ctf_id_t tid)
 static struct type *
 read_func_kind_type (struct ctf_context *ccp, ctf_id_t tid)
 {
-  struct objfile *objfile = ccp->objfile;
+  objfile *objfile = ccp->per_objfile->objfile;
   ctf_dict_t *dict = ccp->dict;
   struct type *type, *rettype, *atype;
   ctf_funcinfo_t cfi;
@@ -705,7 +709,7 @@ read_func_kind_type (struct ctf_context *ccp, ctf_id_t tid)
 static struct type *
 read_enum_type (struct ctf_context *ccp, ctf_id_t tid)
 {
-  struct objfile *objfile = ccp->objfile;
+  objfile *objfile = ccp->per_objfile->objfile;
   ctf_dict_t *dict = ccp->dict;
   struct type *type;
 
@@ -769,7 +773,7 @@ add_array_cv_type (struct ctf_context *ccp,
   voltl |= TYPE_VOLATILE (el_type);
   inner_array->set_target_type (make_cv_type (cnst, voltl, el_type));
 
-  return set_tid_type (ccp->objfile, tid, base_type);
+  return set_tid_type (ccp->per_objfile->objfile, tid, base_type);
 }
 
 /* Read all information from a TID of CTF_K_ARRAY.  */
@@ -777,7 +781,7 @@ add_array_cv_type (struct ctf_context *ccp,
 static struct type *
 read_array_type (struct ctf_context *ccp, ctf_id_t tid)
 {
-  struct objfile *objfile = ccp->objfile;
+  objfile *objfile = ccp->per_objfile->objfile;
   ctf_dict_t *dict = ccp->dict;
   struct type *element_type, *range_type, *idx_type;
   struct type *type;
@@ -820,7 +824,7 @@ read_array_type (struct ctf_context *ccp, ctf_id_t tid)
 static struct type *
 read_const_type (struct ctf_context *ccp, ctf_id_t tid, ctf_id_t btid)
 {
-  struct objfile *objfile = ccp->objfile;
+  objfile *objfile = ccp->per_objfile->objfile;
   struct type *base_type, *cv_type;
 
   base_type = fetch_tid_type (ccp, btid);
@@ -843,7 +847,7 @@ read_const_type (struct ctf_context *ccp, ctf_id_t tid, ctf_id_t btid)
 static struct type *
 read_volatile_type (struct ctf_context *ccp, ctf_id_t tid, ctf_id_t btid)
 {
-  struct objfile *objfile = ccp->objfile;
+  objfile *objfile = ccp->per_objfile->objfile;
   ctf_dict_t *dict = ccp->dict;
   struct type *base_type, *cv_type;
 
@@ -870,7 +874,7 @@ read_volatile_type (struct ctf_context *ccp, ctf_id_t tid, ctf_id_t btid)
 static struct type *
 read_restrict_type (struct ctf_context *ccp, ctf_id_t tid, ctf_id_t btid)
 {
-  struct objfile *objfile = ccp->objfile;
+  objfile *objfile = ccp->per_objfile->objfile;
   struct type *base_type, *cv_type;
 
   base_type = fetch_tid_type (ccp, btid);
@@ -894,7 +898,7 @@ 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->objfile;
+  objfile *objfile = ccp->per_objfile->objfile;
   struct type *this_type, *target_type;
 
   char *aname = obstack_strdup (&objfile->objfile_obstack, name);
@@ -917,7 +921,7 @@ read_typedef_type (struct ctf_context *ccp, ctf_id_t tid,
 static struct type *
 read_pointer_type (struct ctf_context *ccp, ctf_id_t tid, ctf_id_t btid)
 {
-  struct objfile *objfile = ccp->objfile;
+  objfile *objfile = ccp->per_objfile->objfile;
   struct type *target_type, *type;
 
   target_type = fetch_tid_type (ccp, btid);
@@ -927,7 +931,7 @@ read_pointer_type (struct ctf_context *ccp, ctf_id_t tid, ctf_id_t btid)
       if (target_type == nullptr)
 	{
 	  complaint (_("read_pointer_type: NULL target type (%ld)"), btid);
-	  target_type = builtin_type (ccp->objfile)->builtin_error;
+	  target_type = builtin_type (objfile)->builtin_error;
 	}
     }
 
@@ -942,7 +946,7 @@ read_pointer_type (struct ctf_context *ccp, ctf_id_t tid, ctf_id_t btid)
 static struct type *
 read_forward_type (struct ctf_context *ccp, ctf_id_t tid)
 {
-  struct objfile *objfile = ccp->objfile;
+  objfile *objfile = ccp->per_objfile->objfile;
   ctf_dict_t *dict = ccp->dict;
   struct type *type;
   uint32_t kind;
@@ -1040,7 +1044,7 @@ ctf_add_type_cb (ctf_id_t tid, void *arg)
   uint32_t kind;
 
   /* Check if tid's type has already been defined.  */
-  type = get_tid_type (ccp->objfile, tid);
+  type = get_tid_type (ccp->per_objfile->objfile, tid);
   if (type != nullptr)
     {
       ctf_debug_printf ("tid=%ld already defined, skipping", tid);
@@ -1112,8 +1116,9 @@ ctf_add_var_cb (const char *name, ctf_id_t id, void *arg)
   struct symbol *sym = nullptr;
   struct type *type;
   uint32_t kind;
+  objfile *objfile = ccp->per_objfile->objfile;
 
-  type = get_tid_type (ccp->objfile, id);
+  type = get_tid_type (objfile, id);
 
   kind = ctf_type_kind (ccp->dict, id);
 
@@ -1123,25 +1128,25 @@ ctf_add_var_cb (const char *name, ctf_id_t id, void *arg)
   if (type == nullptr)
     {
       complaint (_("ctf_add_var_cb: %s has NO type (%ld)"), name, id);
-      type = builtin_type (ccp->objfile)->builtin_error;
+      type = builtin_type (objfile)->builtin_error;
     }
-  sym = new (&ccp->objfile->objfile_obstack) symbol;
-  OBJSTAT (ccp->objfile, n_syms++);
+  sym = new (&objfile->objfile_obstack) symbol;
+  OBJSTAT (objfile, n_syms++);
   sym->set_type (type);
   sym->set_loc_class_index (LOC_OPTIMIZED_OUT);
-  sym->compute_and_set_names (name, false, ccp->objfile->per_bfd);
+  sym->compute_and_set_names (name, false, objfile->per_bfd);
 
   if (kind == CTF_K_FUNCTION)
     {
       sym->set_domain (FUNCTION_DOMAIN);
       if (name != nullptr && strcmp (name, "main") == 0)
-	set_objfile_main_name (ccp->objfile, name, language_c);
+	set_objfile_main_name (objfile, name, language_c);
     }
   else
     sym->set_domain (VAR_DOMAIN);
 
   add_symbol_to_list (sym, ccp->builder->get_global_symbols ());
-  set_symbol_address (ccp->objfile, sym, name);
+  set_symbol_address (objfile, sym, name);
 
   return 0;
 }
@@ -1160,25 +1165,26 @@ add_stt_entries (struct ctf_context *ccp, int functions)
 
   while ((tid = ctf_symbol_next (ccp->dict, &i, &tname, functions)) != CTF_ERR)
     {
-      type = get_tid_type (ccp->objfile, tid);
+      objfile *objfile = ccp->per_objfile->objfile;
+      type = get_tid_type (objfile, tid);
       if (type == nullptr)
 	{
-	  ctf_debug_printf ("skipping '%s' tid=0x%lx (no type found)",
-			    tname, tid);
+	  ctf_debug_printf ("skipping '%s' tid=0x%lx (no type found)", tname,
+			    tid);
 	  continue;
 	}
 
       ctf_debug_printf ("adding %s '%s' tid=0x%lx",
 			functions ? "function" : "object", tname, tid);
 
-      sym = new (&ccp->objfile->objfile_obstack) symbol;
-      OBJSTAT (ccp->objfile, n_syms++);
+      sym = new (&objfile->objfile_obstack) symbol;
+      OBJSTAT (objfile, n_syms++);
       sym->set_type (type);
       sym->set_domain (functions ? FUNCTION_DOMAIN : VAR_DOMAIN);
       sym->set_loc_class_index (LOC_STATIC);
-      sym->compute_and_set_names (tname, false, ccp->objfile->per_bfd);
+      sym->compute_and_set_names (tname, false, objfile->per_bfd);
       add_symbol_to_list (sym, ccp->builder->get_global_symbols ());
-      set_symbol_address (ccp->objfile, sym, tname);
+      set_symbol_address (objfile, sym, tname);
     }
 }
 
@@ -1222,11 +1228,10 @@ ctf_psymtab_add_enums (struct ctf_context *ccp, ctf_id_t tid)
 
   while ((ename = ctf_enum_next (ccp->dict, 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->objfile);
+      ccp->pst->add_psymbol (ename, true, VAR_DOMAIN, LOC_CONST, -1,
+			     psymbol_placement::GLOBAL, unrelocated_addr (0),
+			     language_c, ccp->partial_symtabs,
+			     ccp->per_objfile->objfile);
     }
   if (ctf_errno (ccp->dict) != ECTF_NEXT_END)
     complaint (_("ctf_enum_next ctf_psymtab_add_enums failed - %s"),
@@ -1237,8 +1242,7 @@ ctf_psymtab_add_enums (struct ctf_context *ccp, ctf_id_t tid)
    by FUNCTIONS, to psymtab.  */
 
 static void
-ctf_psymtab_add_stt_entries (ctf_dict_t *dict, ctf_psymtab *pst,
-			     struct objfile *objfile, int functions)
+ctf_psymtab_add_stt_entries (ctf_dict_t *dict, ctf_psymtab *pst, int functions)
 {
   ctf_next_t *i = nullptr;
   ctf_id_t tid;
@@ -1259,30 +1263,27 @@ ctf_psymtab_add_stt_entries (ctf_dict_t *dict, ctf_psymtab *pst,
 			functions ? "function" : "object", tname, tid,
 			ctf_kind_str (kind));
 
-      pst->add_psymbol (tname, true,
-			tdomain, loc_class, -1,
-			psymbol_placement::GLOBAL,
-			unrelocated_addr (0),
-			language_c, pst->context.partial_symtabs, objfile);
+      pst->add_psymbol (tname, true, tdomain, loc_class, -1,
+			psymbol_placement::GLOBAL, unrelocated_addr (0),
+			language_c, pst->context.partial_symtabs,
+			pst->context.per_objfile->objfile);
     }
 }
 
 /* Add entries in data objects section to psymtab.  */
 
 static void
-ctf_psymtab_add_stt_obj (ctf_dict_t *dict, ctf_psymtab *pst,
-			 struct objfile *objfile)
+ctf_psymtab_add_stt_obj (ctf_dict_t *dict, ctf_psymtab *pst)
 {
-  ctf_psymtab_add_stt_entries (dict, pst, objfile, 0);
+  ctf_psymtab_add_stt_entries (dict, pst, 0);
 }
 
 /* Add entries in function info section to psymtab.  */
 
 static void
-ctf_psymtab_add_stt_func (ctf_dict_t *dict, ctf_psymtab *pst,
-			  struct objfile *objfile)
+ctf_psymtab_add_stt_func (ctf_dict_t *dict, ctf_psymtab *pst)
 {
-  ctf_psymtab_add_stt_entries (dict, pst, objfile, 1);
+  ctf_psymtab_add_stt_entries (dict, pst, 1);
 }
 
 /* Read in full symbols for PST, and anything it depends on.  */
@@ -1375,19 +1376,17 @@ ctf_psymtab::read_symtab (struct objfile *objfile)
 
 static ctf_psymtab *
 create_partial_symtab (const char *name,
-		       ctf_archive_t *arc,
 		       ctf_dict_t *dict,
 		       psymtab_storage *partial_symtabs,
-		       struct objfile *objfile)
+		       ctf_per_objfile *per_objfile)
 {
   ctf_psymtab *pst;
 
-  pst = new ctf_psymtab (name, partial_symtabs, objfile->per_bfd,
+  pst = new ctf_psymtab (name, partial_symtabs, per_objfile->objfile->per_bfd,
 			 unrelocated_addr (0));
 
-  pst->context.arc = arc;
+  pst->context.per_objfile = per_objfile;
   pst->context.dict = dict;
-  pst->context.objfile = objfile;
   pst->context.partial_symtabs = partial_symtabs;
   pst->context.pst = pst;
   pst->context.builder = nullptr;
@@ -1443,11 +1442,10 @@ ctf_psymtab_type_cb (ctf_id_t tid, void *arg)
   ctf_debug_printf ("adding type tid=0x%lx kind=%s name='%s'",
 		    tid, ctf_kind_str (kind), name);
 
-  ccp->pst->add_psymbol (name, false,
-			 domain, loc_class, section,
-			 psymbol_placement::GLOBAL,
-			 unrelocated_addr (0),
-			 language_c, ccp->partial_symtabs, ccp->objfile);
+  ccp->pst->add_psymbol (name, false, domain, loc_class, section,
+			 psymbol_placement::GLOBAL, unrelocated_addr (0),
+			 language_c, ccp->partial_symtabs,
+			 ccp->per_objfile->objfile);
 
   return 0;
 }
@@ -1465,13 +1463,10 @@ ctf_psymtab_var_cb (const char *name, ctf_id_t id, void *arg)
 		    name, id, ctf_kind_str (kind));
 
   ccp->pst->add_psymbol (name, true,
-			 kind == CTF_K_FUNCTION
-			 ? FUNCTION_DOMAIN
-			 : VAR_DOMAIN,
-			 LOC_STATIC, -1,
-			 psymbol_placement::GLOBAL,
-			 unrelocated_addr (0),
-			 language_c, ccp->partial_symtabs, ccp->objfile);
+			 kind == CTF_K_FUNCTION ? FUNCTION_DOMAIN : VAR_DOMAIN,
+			 LOC_STATIC, -1, psymbol_placement::GLOBAL,
+			 unrelocated_addr (0), language_c,
+			 ccp->partial_symtabs, ccp->per_objfile->objfile);
   return 0;
 }
 
@@ -1480,10 +1475,9 @@ ctf_psymtab_var_cb (const char *name, ctf_id_t id, void *arg)
 
 static void
 scan_partial_symbols (ctf_dict_t *dict, psymtab_storage *partial_symtabs,
-		      ctf_archive_iter_psymtab_data *iter_data,
-		      const char *fname)
+		      ctf_per_objfile *per_objfile, const char *fname)
 {
-  objfile *objfile = iter_data->objfile;
+  objfile *objfile = per_objfile->objfile;
   bool isparent = false;
 
   CTF_SCOPED_DEBUG_START_END ("fname='%s'", fname);
@@ -1495,8 +1489,8 @@ scan_partial_symbols (ctf_dict_t *dict, psymtab_storage *partial_symtabs,
       ctf_debug_printf ("is parent, using fname='%s'", fname);
     }
 
-  ctf_psymtab *pst = create_partial_symtab (fname, iter_data->archive, dict,
-					    partial_symtabs, objfile);
+  ctf_psymtab *pst = create_partial_symtab (fname, dict, partial_symtabs,
+					    per_objfile);
 
   struct ctf_context *ccx = &pst->context;
   if (isparent == false)
@@ -1513,8 +1507,8 @@ scan_partial_symbols (ctf_dict_t *dict, psymtab_storage *partial_symtabs,
   /* 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 (dict, pst, objfile);
-  ctf_psymtab_add_stt_func (dict, pst, objfile);
+  ctf_psymtab_add_stt_obj (dict, pst);
+  ctf_psymtab_add_stt_func (dict, pst);
 
   pst->end ();
 }
@@ -1525,9 +1519,10 @@ static int
 build_ctf_archive_member (ctf_dict_t *dict, const char *name, void *arg)
 {
   auto iter_data = static_cast<ctf_archive_iter_psymtab_data *> (arg);
+  ctf_per_objfile *per_objfile = iter_data->per_objfile;
 
   if (strcmp (name, ".ctf") != 0)
-    ctf_import (dict, iter_data->parent_dict);
+    ctf_import (dict, per_objfile->parent_dict.get ());
 
   if (info_verbose)
     {
@@ -1536,7 +1531,7 @@ build_ctf_archive_member (ctf_dict_t *dict, const char *name, void *arg)
     }
 
   psymtab_storage *pss = iter_data->psf->get_partial_symtabs ().get ();
-  scan_partial_symbols (dict, pss, iter_data, name);
+  scan_partial_symbols (dict, pss, per_objfile, name);
 
   return 0;
 }
@@ -1565,19 +1560,16 @@ elfctf_build_psymtabs (objfile *objfile)
 	   bfd_get_filename (abfd), ctf_errmsg (err));
 
   ctf_per_objfile *per_objfile
-    = ctf_per_objfile_key.emplace (objfile, std::move (archive),
+    = ctf_per_objfile_key.emplace (objfile, objfile, std::move (archive),
 				   std::move (dict));
-
-  ctf_archive_iter_psymtab_data iter_data;
-  iter_data.parent_dict = per_objfile->parent_dict.get ();
-  iter_data.objfile = objfile;
-  iter_data.archive = per_objfile->archive.get ();
-
   psymbol_functions *psf = new psymbol_functions ();
+
   objfile->qf.emplace_front (psf);
-  iter_data.psf = psf;
 
-  if (ctf_archive_iter (iter_data.archive, build_ctf_archive_member, &iter_data)
+  ctf_archive_iter_psymtab_data iter_data { per_objfile, psf };
+
+  if (ctf_archive_iter (per_objfile->archive.get (), build_ctf_archive_member,
+			&iter_data)
       < 0)
     error (_("ctf_archive_iter failed in input file %s: - %s"),
 	   bfd_get_filename (abfd), ctf_errmsg (err));
-- 
2.52.0


^ permalink raw reply	[flat|nested] 52+ messages in thread

* [RFC PATCH 5/8] gdb/ctf: check return value of ctf_type_align
  2026-02-03  6:45 [RFC PATCH 0/8] Make CTF reader build full symtabs, get rid of psymtab simon.marchi
                   ` (3 preceding siblings ...)
  2026-02-03  6:45 ` [RFC PATCH 4/8] gdb/ctf: use ctf_per_objfile in ctf_archive_iter_psymtab_data and ctf_context simon.marchi
@ 2026-02-03  6:45 ` simon.marchi
  2026-02-12 17:49   ` Tom Tromey
  2026-02-03  6:45 ` [RFC PATCH 6/8] gdb/ctf: add scoped_time_it in elfctf_build_psymtabs simon.marchi
                   ` (4 subsequent siblings)
  9 siblings, 1 reply; 52+ messages in thread
From: simon.marchi @ 2026-02-03  6:45 UTC (permalink / raw)
  To: gdb-patches; +Cc: Nick Alcock, Weimin Pan, Simon Marchi

From: Simon Marchi <simon.marchi@polymtl.ca>

I tried to build the Linux kernel with -gctf.  I am not sure if the
result is good, because I got plenty of warnings like:

    ld: warning: orphan section `.ctf' from `vmlinux.o' being placed in section `.ctf'

Nevertheless, I tried to load it in GDB, and it didn't complain.
However, when doing "maint expand-symtabs", I did hit this assert:

    /home/simark/src/binutils-gdb/gdb/gdbtypes.c:3640: internal-error: set_type_align: Assertion `(align & (align - 1)) == 0' failed.

This is because ctf_type_align returns -1 for some types, which is an
indication of an error.  Update the code to check the return value of
ctf_type_align for errors, and emit complaints if it happens.

With this patch, if I enable the complaints, I see a bunch of messages
like this:

    During symbol reading: ctf_type_align read_structure_type failed - Type is not a complete type.

Change-Id: Ibed23e7f1490d9163b8dde1318b9e45dec2906d6
---
 gdb/ctfread.c | 40 +++++++++++++++++++++++++++++++++++-----
 1 file changed, 35 insertions(+), 5 deletions(-)

diff --git a/gdb/ctfread.c b/gdb/ctfread.c
index b2557ac31717..971742dba7b3 100644
--- a/gdb/ctfread.c
+++ b/gdb/ctfread.c
@@ -616,7 +616,14 @@ read_structure_type (struct ctf_context *ccp, ctf_id_t tid)
     type->set_code (TYPE_CODE_STRUCT);
 
   type->set_length (ctf_type_size (dict, tid));
-  set_type_align (type, ctf_type_align (dict, tid));
+
+  if (ssize_t align = ctf_type_align (dict, tid);
+      align >= 0)
+    set_type_align (type, align);
+  else
+    complaint (_("ctf_type_align read_structure_type failed - %s"),
+	       ctf_errmsg (ctf_errno (dict)));
+
 
   return set_tid_type (objfile, tid, type);
 }
@@ -673,7 +680,13 @@ read_func_kind_type (struct ctf_context *ccp, ctf_id_t tid)
     }
   rettype = fetch_tid_type (ccp, cfi.ctc_return);
   type->set_target_type (rettype);
-  set_type_align (type, ctf_type_align (dict, tid));
+
+  if (ssize_t align = ctf_type_align (dict, tid);
+      align >= 0)
+    set_type_align (type, align);
+  else
+    complaint (_("ctf_type_align read_func_kind_type failed - %s"),
+	       ctf_errmsg (ctf_errno (dict)));
 
   /* Set up function's arguments.  */
   argc = cfi.ctc_argc;
@@ -723,7 +736,13 @@ read_enum_type (struct ctf_context *ccp, ctf_id_t tid)
   type->set_length (ctf_type_size (dict, tid));
   /* Set the underlying type based on its ctf_type_size bits.  */
   type->set_target_type (objfile_int_type (objfile, type->length (), false));
-  set_type_align (type, ctf_type_align (dict, tid));
+
+  if (ssize_t align = ctf_type_align (dict, tid);
+      align >= 0)
+    set_type_align (type, align);
+  else
+    complaint (_("ctf_type_align read_enum_type failed - %s"),
+	       ctf_errmsg (ctf_errno (dict)));
 
   return set_tid_type (objfile, tid, type);
 }
@@ -814,7 +833,12 @@ read_array_type (struct ctf_context *ccp, ctf_id_t tid)
   else
     type->set_length (ctf_type_size (dict, tid));
 
-  set_type_align (type, ctf_type_align (dict, tid));
+  if (ssize_t align = ctf_type_align (dict, tid);
+      align >= 0)
+    set_type_align (type, align);
+  else
+    complaint (_("ctf_type_align read_array_type failed - %s"),
+	       ctf_errmsg (ctf_errno (dict)));
 
   return set_tid_type (objfile, tid, type);
 }
@@ -936,7 +960,13 @@ read_pointer_type (struct ctf_context *ccp, ctf_id_t tid, ctf_id_t btid)
     }
 
   type = lookup_pointer_type (target_type);
-  set_type_align (type, ctf_type_align (ccp->dict, tid));
+
+  if (ssize_t align = ctf_type_align (ccp->dict, tid);
+      align >= 0)
+    set_type_align (type, align);
+  else
+    complaint (_("ctf_type_align read_pointer_type failed - %s"),
+	       ctf_errmsg (ctf_errno (ccp->dict)));
 
   return set_tid_type (objfile, tid, type);
 }
-- 
2.52.0


^ permalink raw reply	[flat|nested] 52+ messages in thread

* [RFC PATCH 6/8] gdb/ctf: add scoped_time_it in elfctf_build_psymtabs
  2026-02-03  6:45 [RFC PATCH 0/8] Make CTF reader build full symtabs, get rid of psymtab simon.marchi
                   ` (4 preceding siblings ...)
  2026-02-03  6:45 ` [RFC PATCH 5/8] gdb/ctf: check return value of ctf_type_align simon.marchi
@ 2026-02-03  6:45 ` simon.marchi
  2026-02-03  6:45 ` [RFC PATCH 7/8] gdb/ctf: don't use psymtabs, create symtabs directly simon.marchi
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 52+ messages in thread
From: simon.marchi @ 2026-02-03  6:45 UTC (permalink / raw)
  To: gdb-patches; +Cc: Nick Alcock, Weimin Pan, Simon Marchi

From: Simon Marchi <simon.marchi@polymtl.ca>

This will be useful to determine the impact on the startup time getting
rid of partial symtabs has.

I use it like so:

    $ ./gdb -q -nx --data-directory=data-directory -iex "maint set per-command time on" /home/simark/src/linux/vmlinux.unstripped -batch
    ...
    Time for "elfctf_build_psymtabs": wall 0.381, user 0.357, sys 0.015, user+sys 0.372, 97.6 % CPU

Change-Id: I021319212f27eee0bf0f6c230f4e7cdd9c3602c1
---
 gdb/ctfread.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/gdb/ctfread.c b/gdb/ctfread.c
index 971742dba7b3..aa2394af1968 100644
--- a/gdb/ctfread.c
+++ b/gdb/ctfread.c
@@ -79,6 +79,7 @@
 #include "complaints.h"
 #include "block.h"
 #include "ctfread.h"
+#include "maint.h"
 #include "psymtab.h"
 #include "cli/cli-cmds.h"
 
@@ -1576,6 +1577,8 @@ elfctf_build_psymtabs (objfile *objfile)
   bfd *abfd = objfile->obfd.get ();
   int err;
 
+  scoped_time_it time_it (__func__);
+
   CTF_SCOPED_DEBUG_START_END ("building psymtabs for %s",
 			      bfd_get_filename (abfd));
 
-- 
2.52.0


^ permalink raw reply	[flat|nested] 52+ messages in thread

* [RFC PATCH 7/8] gdb/ctf: don't use psymtabs, create symtabs directly
  2026-02-03  6:45 [RFC PATCH 0/8] Make CTF reader build full symtabs, get rid of psymtab simon.marchi
                   ` (5 preceding siblings ...)
  2026-02-03  6:45 ` [RFC PATCH 6/8] gdb/ctf: add scoped_time_it in elfctf_build_psymtabs simon.marchi
@ 2026-02-03  6:45 ` simon.marchi
  2026-02-12 17:54   ` Tom Tromey
  2026-02-03  6:45 ` [RFC PATCH 8/8] gdb: remove psymtab.{c,h} simon.marchi
                   ` (2 subsequent siblings)
  9 siblings, 1 reply; 52+ messages in thread
From: simon.marchi @ 2026-02-03  6:45 UTC (permalink / raw)
  To: gdb-patches; +Cc: Nick Alcock, Weimin Pan, Simon Marchi

From: Simon Marchi <simon.marchi@polymtl.ca>

The CTF debug info reader is the last user of partial symtabs.  Being a
fairly limited debug info format, CTF only uses a fraction of the
psymtab features.  So I see 3 ways forward:

 - keep psymtabs but trim them down, removing everything not useful for
   CTF

 - make the CTF reader implement its own index-like structure that
   implements the quick_symbol_functions interface (which would
   presumably be a small subset of partial symtabs)

 - make the CTF reader skip partial symtabs, create full symtabs
   directly

My hypothesis is that CTF debug info is typically small enough and fast
enough to process that it's not worth it to bother with an intermediate
step before full symbols.  But I will need help to see if this is true,
I'm not sure what representatively big C project I can build with CTF
debug info.  I tried to build the Linux kernel with -gctf, but I got
plenty of warnings like:

  ld: warning: orphan section `.ctf' from `vmlinux.o' being placed in section `.ctf'

GDB is still able to load the resulting ELF, and there are about 150k
calls to ctf_add_type_cb.  Before this patch, elfctf_build_psymtabs
takes anywhere between 300-350 ms.  With this patch, it's around 400 ms.

Implementation
--------------

This patch gets rid of the ctf_psymtab step, creating full symtabs from
the start.

The entry point elfctf_build_psymtabs gets renamed to
elfctf_build_symtabs.

Everything related to ctf_psymtab or partial symtabs is removed.

The build_ctf_archive_member function nows contains the code to build a
full symtab out of one CTF dict.  This code is not new for the most
part, it has been moved from other functions that used to be called when
expanding one symtab.

In order to access the symtabs, elfctf_build_symtabs installs the
expanded_symbols_functions quick_symbol_functions implementation, which
essentially searches in the existing symtabs.  I am pretty sure this is
not 100% correct, because this would search unrelated symtabs, if for
instance the CTF debug info co-existed with DWARF info.  But it's good
enough for a prototype.

Change-Id: I728c1ef35785218c178fb467b80db71d59269a6d
---
 gdb/ctfread.c | 378 +++++++-------------------------------------------
 gdb/ctfread.h |   2 +-
 gdb/elfread.c |   8 +-
 3 files changed, 50 insertions(+), 338 deletions(-)

diff --git a/gdb/ctfread.c b/gdb/ctfread.c
index aa2394af1968..f3f64e6ed2fc 100644
--- a/gdb/ctfread.c
+++ b/gdb/ctfread.c
@@ -79,9 +79,11 @@
 #include "complaints.h"
 #include "block.h"
 #include "ctfread.h"
-#include "maint.h"
-#include "psymtab.h"
 #include "cli/cli-cmds.h"
+#include "expanded-symbol.h"
+#include "maint.h"
+#include "objfiles.h"
+#include "progspace.h"
 
 /* When true, print debug messages related to CTF reading.  */
 static bool debug_ctf = false;
@@ -174,28 +176,9 @@ struct ctf_context
 {
   ctf_per_objfile *per_objfile;
   ctf_dict_t *dict;
-  psymtab_storage *partial_symtabs;
-  partial_symtab *pst;
   struct buildsym_compunit *builder;
 };
 
-/* A partial symtab, specialized for this module.  */
-struct ctf_psymtab : public standard_psymtab
-{
-  ctf_psymtab (const char *filename,
-	       psymtab_storage *partial_symtabs,
-	       objfile_per_bfd_storage *objfile_per_bfd,
-	       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.  */
@@ -225,14 +208,6 @@ struct ctf_field_info
   std::vector<struct decl_field> nested_types_list;
 };
 
-/* Data held while using ctf_archive_iter to build psymtabs.  */
-
-struct ctf_archive_iter_psymtab_data
-{
-  ctf_per_objfile *per_objfile;
-  psymbol_functions *psf;
-};
-
 /* Local function prototypes */
 
 static int ctf_add_type_cb (ctf_id_t tid, void *arg);
@@ -1248,338 +1223,82 @@ get_objfile_text_range (struct objfile *objfile, size_t *tsize)
   return objfile->text_section_offset ();
 }
 
-/* Add all members of an enum with type TID to partial symbol table.  */
+/* ctf_archive_iter callback to build the ssymtab for archive member NAME.  */
 
-static void
-ctf_psymtab_add_enums (struct ctf_context *ccp, ctf_id_t tid)
+static int
+build_ctf_archive_member (ctf_dict_t *dict, const char *name, void *arg)
 {
-  int val;
-  const char *ename;
-  ctf_next_t *i = nullptr;
+  CTF_SCOPED_DEBUG_START_END ("name='%s'", name);
 
-  while ((ename = ctf_enum_next (ccp->dict, 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->per_objfile->objfile);
-    }
-  if (ctf_errno (ccp->dict) != ECTF_NEXT_END)
-    complaint (_("ctf_enum_next ctf_psymtab_add_enums failed - %s"),
-	       ctf_errmsg (ctf_errno (ccp->dict)));
-}
+  auto per_objfile = static_cast<ctf_per_objfile *> (arg);
 
-/* Add entries in either data objects or function info section, controlled
-   by FUNCTIONS, to psymtab.  */
+  if (strcmp (name, ".ctf") != 0)
+    ctf_import (dict, per_objfile->parent_dict.get ());
 
-static void
-ctf_psymtab_add_stt_entries (ctf_dict_t *dict, ctf_psymtab *pst, int functions)
-{
-  ctf_next_t *i = nullptr;
-  ctf_id_t tid;
-  const char *tname;
+  objfile *objfile = per_objfile->objfile;
 
-  while ((tid = ctf_symbol_next (dict, &i, &tname, functions)) != CTF_ERR)
+  if (strcmp (name, ".ctf") == 0)
     {
-      uint32_t kind = ctf_type_kind (dict, tid);
-      location_class loc_class;
-      domain_enum tdomain = functions ? FUNCTION_DOMAIN : VAR_DOMAIN;
-
-      if (kind == CTF_K_FUNCTION)
-	loc_class = LOC_BLOCK;
-      else
-	loc_class = LOC_STATIC;
-
-      ctf_debug_printf ("adding %s psym '%s' tid=0x%lx kind=%s",
-			functions ? "function" : "object", tname, tid,
-			ctf_kind_str (kind));
-
-      pst->add_psymbol (tname, true, tdomain, loc_class, -1,
-			psymbol_placement::GLOBAL, unrelocated_addr (0),
-			language_c, pst->context.partial_symtabs,
-			pst->context.per_objfile->objfile);
+      name = bfd_get_filename (objfile->obfd.get ());
+      ctf_debug_printf ("is parent, using name='%s'", name);
     }
-}
-
-/* Add entries in data objects section to psymtab.  */
-
-static void
-ctf_psymtab_add_stt_obj (ctf_dict_t *dict, ctf_psymtab *pst)
-{
-  ctf_psymtab_add_stt_entries (dict, pst, 0);
-}
-
-/* Add entries in function info section to psymtab.  */
-
-static void
-ctf_psymtab_add_stt_func (ctf_dict_t *dict, ctf_psymtab *pst)
-{
-  ctf_psymtab_add_stt_entries (dict, pst, 1);
-}
-
-/* Read in full symbols for PST, and anything it depends on.  */
-
-void
-ctf_psymtab::expand_psymtab (struct objfile *objfile)
-{
-  struct ctf_context *ccp;
-
-  CTF_SCOPED_DEBUG_START_END ("expanding psymtab");
-
-  gdb_assert (!readin);
-
-  ccp = &context;
-
-  /* Iterate over entries in data types section.  */
-  if (ctf_type_iter (ccp->dict, ctf_add_type_cb, ccp) == CTF_ERR)
-    complaint (_("ctf_type_iter psymtab_to_symtab failed - %s"),
-	       ctf_errmsg (ctf_errno (ccp->dict)));
-
-
-  /* Iterate over entries in variable info section.  */
-  if (ctf_variable_iter (ccp->dict, ctf_add_var_cb, ccp) == CTF_ERR)
-    complaint (_("ctf_variable_iter psymtab_to_symtab failed - %s"),
-	       ctf_errmsg (ctf_errno (ccp->dict)));
-
-  /* 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)
-{
-  CTF_SCOPED_DEBUG_START_END ("reading symtab for '%s'", filename);
-
-  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_debug_printf ("starting buildsym for '%s', offset=%s, tsize=%zu",
-			filename, hex_string (offset), tsize);
-
-      buildsym_compunit builder (objfile, this->filename, nullptr,
-				 language_c, offset);
-      builder.record_debugformat ("ctf");
-      scoped_restore store_builder
-	= make_scoped_restore (&context.builder, &builder);
-
-      expand_psymtab (objfile);
-
-      set_text_low (unrelocated_addr (0));
-      set_text_high (unrelocated_addr (tsize));
-      compunit_symtab = builder.end_compunit_symtab (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_dict_t *dict,
-		       psymtab_storage *partial_symtabs,
-		       ctf_per_objfile *per_objfile)
-{
-  ctf_psymtab *pst;
-
-  pst = new ctf_psymtab (name, partial_symtabs, per_objfile->objfile->per_bfd,
-			 unrelocated_addr (0));
-
-  pst->context.per_objfile = per_objfile;
-  pst->context.dict = dict;
-  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;
-  location_class loc_class = LOC_UNDEF;
-  kind = ctf_type_kind (ccp->dict, tid);
-  switch (kind)
+  if (info_verbose)
     {
-    case CTF_K_ENUM:
-      ctf_psymtab_add_enums (ccp, tid);
-      [[fallthrough]];
-    case CTF_K_STRUCT:
-    case CTF_K_UNION:
-      domain = STRUCT_DOMAIN;
-      loc_class = LOC_TYPEDEF;
-      break;
-    case CTF_K_FUNCTION:
-    case CTF_K_FORWARD:
-    case CTF_K_CONST:
-    case CTF_K_TYPEDEF:
-    case CTF_K_POINTER:
-    case CTF_K_VOLATILE:
-    case CTF_K_RESTRICT:
-    case CTF_K_INTEGER:
-    case CTF_K_FLOAT:
-    case CTF_K_ARRAY:
-      domain = TYPE_DOMAIN;
-      loc_class = LOC_TYPEDEF;
-      break;
-    case CTF_K_UNKNOWN:
-      return 0;
+      gdb_printf (_("Reading in CTF data for %s..."), name);
+      gdb_flush (gdb_stdout);
     }
 
-  const char *name = ctf_type_name_raw (ccp->dict, tid);
-  if (name == nullptr || *name == '\0')
-    return 0;
-
-  ctf_debug_printf ("adding type tid=0x%lx kind=%s name='%s'",
-		    tid, ctf_kind_str (kind), name);
+  /* Start and size of the text segment.  */
+  size_t tsize;
+  CORE_ADDR offset = get_objfile_text_range (objfile, &tsize);
 
-  ccp->pst->add_psymbol (name, false, domain, loc_class, section,
-			 psymbol_placement::GLOBAL, unrelocated_addr (0),
-			 language_c, ccp->partial_symtabs,
-			 ccp->per_objfile->objfile);
+  ctf_debug_printf ("starting buildsym for '%s', offset=0x%s, tsize=%zu",
+		    name, hex_string (offset), tsize);
 
-  return 0;
-}
+  buildsym_compunit builder (objfile, name, nullptr, language_c, offset);
+  builder.record_debugformat ("ctf");
 
-/* 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;
+  ctf_context ccx;
+  ccx.per_objfile = per_objfile;
+  ccx.dict = dict;
+  ccx.builder = &builder;
 
-  uint32_t kind = ctf_type_kind (ccp->dict, id);
-
-  ctf_debug_printf ("adding variable name='%s' tid=0x%lx kind=%s",
-		    name, id, ctf_kind_str (kind));
-
-  ccp->pst->add_psymbol (name, true,
-			 kind == CTF_K_FUNCTION ? FUNCTION_DOMAIN : VAR_DOMAIN,
-			 LOC_STATIC, -1, psymbol_placement::GLOBAL,
-			 unrelocated_addr (0), language_c,
-			 ccp->partial_symtabs, ccp->per_objfile->objfile);
-  return 0;
-}
-
-/* Setup partial_symtab's describing each source file for which
-   debugging information is available.  */
-
-static void
-scan_partial_symbols (ctf_dict_t *dict, psymtab_storage *partial_symtabs,
-		      ctf_per_objfile *per_objfile, const char *fname)
-{
-  objfile *objfile = per_objfile->objfile;
-  bool isparent = false;
-
-  CTF_SCOPED_DEBUG_START_END ("fname='%s'", fname);
-
-  if (strcmp (fname, ".ctf") == 0)
-    {
-      fname = bfd_get_filename (objfile->obfd.get ());
-      isparent = true;
-      ctf_debug_printf ("is parent, using fname='%s'", fname);
-    }
-
-  ctf_psymtab *pst = create_partial_symtab (fname, dict, partial_symtabs,
-					    per_objfile);
-
-  struct ctf_context *ccx = &pst->context;
-  if (isparent == false)
-    ccx->pst = pst;
-
-  if (ctf_type_iter (dict, ctf_psymtab_type_cb, ccx) == CTF_ERR)
-    complaint (_("ctf_type_iter scan_partial_symbols failed - %s"),
-	       ctf_errmsg (ctf_errno (dict)));
-
-  if (ctf_variable_iter (dict, ctf_psymtab_var_cb, ccx) == CTF_ERR)
-    complaint (_("ctf_variable_iter scan_partial_symbols failed - %s"),
+  /* Iterate over entries in data types section.  */
+  if (ctf_type_iter (dict, ctf_add_type_cb, &ccx) == CTF_ERR)
+    complaint (_("ctf_type_iter failed - %s"),
 	       ctf_errmsg (ctf_errno (dict)));
 
-  /* 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 (dict, pst);
-  ctf_psymtab_add_stt_func (dict, pst);
 
-  pst->end ();
-}
-
-/* Callback to build the psymtab for archive member NAME.  */
+  /* Iterate over entries in variable info section.  */
+  if (ctf_variable_iter (dict, ctf_add_var_cb, &ccx) == CTF_ERR)
+    complaint (_("ctf_variable_iter failed - %s"),
+	       ctf_errmsg (ctf_errno (dict)));
 
-static int
-build_ctf_archive_member (ctf_dict_t *dict, const char *name, void *arg)
-{
-  auto iter_data = static_cast<ctf_archive_iter_psymtab_data *> (arg);
-  ctf_per_objfile *per_objfile = iter_data->per_objfile;
+  /* Add entries in data objects and function info sections.  */
+  add_stt_obj (&ccx);
+  add_stt_func (&ccx);
 
-  if (strcmp (name, ".ctf") != 0)
-    ctf_import (dict, per_objfile->parent_dict.get ());
+  builder.end_compunit_symtab (offset + tsize);
 
+  /* Finish up the debug error message.  */
   if (info_verbose)
-    {
-      gdb_printf (_("Scanning archive member %s..."), name);
-      gdb_flush (gdb_stdout);
-    }
-
-  psymtab_storage *pss = iter_data->psf->get_partial_symtabs ().get ();
-  scan_partial_symbols (dict, pss, per_objfile, name);
+    gdb_printf (_("done.\n"));
 
   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.  */
+   called from elfread.c.  */
 
 void
-elfctf_build_psymtabs (objfile *objfile)
+elfctf_build_symtabs (objfile *objfile)
 {
   bfd *abfd = objfile->obfd.get ();
   int err;
-
   scoped_time_it time_it (__func__);
 
-  CTF_SCOPED_DEBUG_START_END ("building psymtabs for %s",
+  CTF_SCOPED_DEBUG_START_END ("building symtabs for %s",
 			      bfd_get_filename (abfd));
 
   ctf_archive_up archive (ctf_bfdopen (abfd, &err));
@@ -1595,14 +1314,11 @@ elfctf_build_psymtabs (objfile *objfile)
   ctf_per_objfile *per_objfile
     = ctf_per_objfile_key.emplace (objfile, objfile, std::move (archive),
 				   std::move (dict));
-  psymbol_functions *psf = new psymbol_functions ();
-
-  objfile->qf.emplace_front (psf);
 
-  ctf_archive_iter_psymtab_data iter_data { per_objfile, psf };
+  objfile->qf.emplace_front (new expanded_symbols_functions);
 
   if (ctf_archive_iter (per_objfile->archive.get (), build_ctf_archive_member,
-			&iter_data)
+			per_objfile)
       < 0)
     error (_("ctf_archive_iter failed in input file %s: - %s"),
 	   bfd_get_filename (abfd), ctf_errmsg (err));
diff --git a/gdb/ctfread.h b/gdb/ctfread.h
index 95aa7f632731..b87f78bba0df 100644
--- a/gdb/ctfread.h
+++ b/gdb/ctfread.h
@@ -20,6 +20,6 @@
 #ifndef GDB_CTFREAD_H
 #define GDB_CTFREAD_H
 
-extern void elfctf_build_psymtabs (struct objfile *objfile);
+extern void elfctf_build_symtabs (struct objfile *objfile);
 
 #endif /* GDB_CTFREAD_H */
diff --git a/gdb/elfread.c b/gdb/elfread.c
index 60785ace56d1..c99f59484458 100644
--- a/gdb/elfread.c
+++ b/gdb/elfread.c
@@ -1262,17 +1262,13 @@ elf_symfile_read (struct objfile *objfile, symfile_add_flags symfile_flags)
 
   /* Read the CTF section only if there is no DWARF info.  */
   if (always_read_ctf && ei.ctfsect)
-    {
-      elfctf_build_psymtabs (objfile);
-    }
+    elfctf_build_symtabs (objfile);
 
   bool has_dwarf2 = elf_symfile_read_dwarf2 (objfile, symfile_flags);
 
   /* Read the CTF section only if there is no DWARF info.  */
   if (!always_read_ctf && !has_dwarf2 && ei.ctfsect)
-    {
-      elfctf_build_psymtabs (objfile);
-    }
+    elfctf_build_symtabs (objfile);
 
   /* Copy relocations are used by some ABIs using the ELF format, so
      set the objfile flag indicating this fact.  */
-- 
2.52.0


^ permalink raw reply	[flat|nested] 52+ messages in thread

* [RFC PATCH 8/8] gdb: remove psymtab.{c,h}
  2026-02-03  6:45 [RFC PATCH 0/8] Make CTF reader build full symtabs, get rid of psymtab simon.marchi
                   ` (6 preceding siblings ...)
  2026-02-03  6:45 ` [RFC PATCH 7/8] gdb/ctf: don't use psymtabs, create symtabs directly simon.marchi
@ 2026-02-03  6:45 ` simon.marchi
  2026-02-12 17:58 ` [RFC PATCH 0/8] Make CTF reader build full symtabs, get rid of psymtab Tom Tromey
  2026-02-17 19:50 ` [PATCH v2 0/9] " simon.marchi
  9 siblings, 0 replies; 52+ messages in thread
From: simon.marchi @ 2026-02-03  6:45 UTC (permalink / raw)
  To: gdb-patches; +Cc: Nick Alcock, Weimin Pan, Simon Marchi

From: Simon Marchi <simon.marchi@polymtl.ca>

The last user of psymtabs has been changed not to use them, remove them.

Change-Id: I58ae48c30e0303bcaa48298146d69fb8f059cb32
---
 gdb/Makefile.in |    2 -
 gdb/psymtab.c   | 1575 -----------------------------------------------
 gdb/psymtab.h   |  691 ---------------------
 3 files changed, 2268 deletions(-)
 delete mode 100644 gdb/psymtab.c
 delete mode 100644 gdb/psymtab.h

diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index 713c0920f6a1..70fefbe749c6 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -1176,7 +1176,6 @@ COMMON_SFILES = \
 	progspace.c \
 	progspace-and-thread.c \
 	prologue-value.c \
-	psymtab.c \
 	record.c \
 	record-btrace.c \
 	record-full.c \
@@ -1610,7 +1609,6 @@ HFILES_NO_SRCDIR = \
 	progspace-and-thread.h \
 	progspace.h \
 	prologue-value.h \
-	psymtab.h \
 	python/py-color.h \
 	python/py-event.h \
 	python/py-events.h \
diff --git a/gdb/psymtab.c b/gdb/psymtab.c
deleted file mode 100644
index 59059616c1aa..000000000000
--- a/gdb/psymtab.c
+++ /dev/null
@@ -1,1575 +0,0 @@
-/* Partial symbol tables.
-
-   Copyright (C) 2009-2026 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/>.  */
-
-#include "event-top.h"
-#include "symtab.h"
-#include "objfiles.h"
-#include "psymtab.h"
-#include "block.h"
-#include "filenames.h"
-#include "source.h"
-#include "gdbtypes.h"
-#include "ui-out.h"
-#include "command.h"
-#include "gdbsupport/gdb_regex.h"
-#include "dictionary.h"
-#include "language.h"
-#include "cp-support.h"
-#include "cli/cli-cmds.h"
-#include <algorithm>
-#include <set>
-#include "gdbsupport/buildargv.h"
-
-static const struct partial_symbol *lookup_partial_symbol
-     (struct objfile *, struct partial_symtab *, const lookup_name_info &,
-      int, domain_search_flags);
-
-static const char *psymtab_to_fullname (struct partial_symtab *ps);
-
-static const struct partial_symbol *find_pc_sect_psymbol
-     (struct objfile *, struct partial_symtab *, CORE_ADDR,
-      struct obj_section *);
-
-static struct compunit_symtab *psymtab_to_symtab (struct objfile *objfile,
-						  struct partial_symtab *pst);
-
-psymtab_storage::~psymtab_storage ()
-{
-  partial_symtab *iter = psymtabs;
-  while (iter != nullptr)
-    {
-      partial_symtab *next = iter->next;
-      delete iter;
-      iter = next;
-    }
-}
-
-/* See psymtab.h.  */
-
-void
-psymtab_storage::install_psymtab (partial_symtab *pst)
-{
-  pst->next = psymtabs;
-  psymtabs = pst;
-}
-
-\f
-
-/* See psymtab.h.  */
-
-psymtab_storage::partial_symtab_range
-psymbol_functions::partial_symbols (struct objfile *objfile)
-{
-  return m_partial_symtabs->range ();
-}
-
-/* Find which partial symtab contains PC and SECTION starting at psymtab PST.
-   We may find a different psymtab than PST.  See FIND_PC_SECT_PSYMTAB.  */
-
-static struct partial_symtab *
-find_pc_sect_psymtab_closer (struct objfile *objfile,
-			     CORE_ADDR pc, struct obj_section *section,
-			     struct partial_symtab *pst,
-			     bound_minimal_symbol msymbol)
-{
-  struct partial_symtab *tpst;
-  struct partial_symtab *best_pst = pst;
-  CORE_ADDR best_addr = pst->text_low (objfile);
-
-  /* An objfile that has its functions reordered might have
-     many partial symbol tables containing the PC, but
-     we want the partial symbol table that contains the
-     function containing the PC.  */
-  if (section == nullptr)
-    return pst;
-
-  if (msymbol.minsym == NULL)
-    return pst;
-
-  /* The code range of partial symtabs sometimes overlap, so, in
-     the loop below, we need to check all partial symtabs and
-     find the one that fits better for the given PC address.  We
-     select the partial symtab that contains a symbol whose
-     address is closest to the PC address.  By closest we mean
-     that find_pc_sect_symbol returns the symbol with address
-     that is closest and still less than the given PC.  */
-  for (tpst = pst; tpst != NULL; tpst = tpst->next)
-    {
-      if (pc >= tpst->text_low (objfile) && pc < tpst->text_high (objfile))
-	{
-	  const struct partial_symbol *p;
-	  CORE_ADDR this_addr;
-
-	  /* NOTE: This assumes that every psymbol has a
-	     corresponding msymbol, which is not necessarily
-	     true; the debug info might be much richer than the
-	     object's symbol table.  */
-	  p = find_pc_sect_psymbol (objfile, tpst, pc, section);
-	  if (p != NULL
-	      && (p->address (objfile) == msymbol.value_address ()))
-	    return tpst;
-
-	  /* Also accept the textlow value of a psymtab as a
-	     "symbol", to provide some support for partial
-	     symbol tables with line information but no debug
-	     symbols (e.g. those produced by an assembler).  */
-	  if (p != NULL)
-	    this_addr = p->address (objfile);
-	  else
-	    this_addr = tpst->text_low (objfile);
-
-	  /* Check whether it is closer than our current
-	     BEST_ADDR.  Since this symbol address is
-	     necessarily lower or equal to PC, the symbol closer
-	     to PC is the symbol which address is the highest.
-	     This way we return the psymtab which contains such
-	     best match symbol.  This can help in cases where the
-	     symbol information/debuginfo is not complete, like
-	     for instance on IRIX6 with gcc, where no debug info
-	     is emitted for statics.  (See also the nodebug.exp
-	     testcase.)  */
-	  if (this_addr > best_addr)
-	    {
-	      best_addr = this_addr;
-	      best_pst = tpst;
-	    }
-	}
-    }
-  return best_pst;
-}
-
-/* See psymtab.h.  */
-
-struct partial_symtab *
-psymbol_functions::find_pc_sect_psymtab (struct objfile *objfile,
-					 CORE_ADDR pc,
-					 struct obj_section *section,
-					 bound_minimal_symbol msymbol)
-{
-  for (partial_symtab *pst : partial_symbols (objfile))
-    if (pc >= pst->text_low (objfile) && pc < pst->text_high (objfile))
-      {
-	struct partial_symtab *best_pst;
-
-	best_pst = find_pc_sect_psymtab_closer (objfile, pc, section, pst,
-						msymbol);
-	if (best_pst != NULL)
-	  return best_pst;
-      }
-
-  return NULL;
-}
-
-/* Psymtab version of find_pc_sect_compunit_symtab.  See its definition in
-   the definition of quick_symbol_functions in symfile.h.  */
-
-struct compunit_symtab *
-psymbol_functions::find_pc_sect_compunit_symtab (struct objfile *objfile,
-						 bound_minimal_symbol msymbol,
-						 CORE_ADDR pc,
-						 struct obj_section *section,
-						 int warn_if_readin)
-{
-  struct partial_symtab *ps = find_pc_sect_psymtab (objfile,
-						    pc, section,
-						    msymbol);
-  if (ps != NULL)
-    {
-      if (warn_if_readin && ps->readin_p (objfile))
-	/* Might want to error() here (in case symtab is corrupt and
-	   will cause a core dump), but maybe we can successfully
-	   continue, so let's not.  */
-	warning (_("\
-(Internal error: pc %s in read in psymtab, but not in symtab.)\n"),
-		 paddress (objfile->arch (), pc));
-      psymtab_to_symtab (objfile, ps);
-      return ps->get_compunit_symtab (objfile);
-    }
-  return NULL;
-}
-
-/* Find which partial symbol within a psymtab matches PC and SECTION.
-   Return NULL if none.  */
-
-static const struct partial_symbol *
-find_pc_sect_psymbol (struct objfile *objfile,
-		      struct partial_symtab *psymtab, CORE_ADDR pc,
-		      struct obj_section *section)
-{
-  const struct partial_symbol *best = NULL;
-  CORE_ADDR best_pc;
-  const CORE_ADDR textlow = psymtab->text_low (objfile);
-
-  gdb_assert (psymtab != NULL);
-
-  /* Cope with programs that start at address 0.  */
-  best_pc = (textlow != 0) ? textlow - 1 : 0;
-
-  /* Search the global symbols as well as the static symbols, so that
-     find_pc_partial_function doesn't use a minimal symbol and thus
-     cache a bad endaddr.  */
-  for (const partial_symbol *p : psymtab->global_psymbols)
-    {
-      if (p->domain == VAR_DOMAIN
-	  && p->loc_class == LOC_BLOCK
-	  && pc >= p->address (objfile)
-	  && (p->address (objfile) > best_pc
-	      || (psymtab->text_low (objfile) == 0
-		  && best_pc == 0 && p->address (objfile) == 0)))
-	{
-	  if (section != NULL)  /* Match on a specific section.  */
-	    {
-	      if (!matching_obj_sections (p->obj_section (objfile),
-					  section))
-		continue;
-	    }
-	  best_pc = p->address (objfile);
-	  best = p;
-	}
-    }
-
-  for (const partial_symbol *p : psymtab->static_psymbols)
-    {
-      if (p->domain == VAR_DOMAIN
-	  && p->loc_class == LOC_BLOCK
-	  && pc >= p->address (objfile)
-	  && (p->address (objfile) > best_pc
-	      || (psymtab->text_low (objfile) == 0
-		  && best_pc == 0 && p->address (objfile) == 0)))
-	{
-	  if (section != NULL)  /* Match on a specific section.  */
-	    {
-	      if (!matching_obj_sections (p->obj_section (objfile),
-					  section))
-		continue;
-	    }
-	  best_pc = p->address (objfile);
-	  best = p;
-	}
-    }
-
-  return best;
-}
-
-/* Psymtab version of lookup_global_symbol_language.  See its definition in
-   the definition of quick_symbol_functions in symfile.h.  */
-
-enum language
-psymbol_functions::lookup_global_symbol_language (struct objfile *objfile,
-						  const char *name,
-						  domain_search_flags domain,
-						  bool *symbol_found_p)
-{
-  *symbol_found_p = false;
-  if (objfile->sf == NULL)
-    return language_unknown;
-
-  lookup_name_info lookup_name (name, symbol_name_match_type::FULL);
-
-  for (partial_symtab *ps : partial_symbols (objfile))
-    {
-      const struct partial_symbol *psym;
-      if (ps->readin_p (objfile))
-	continue;
-
-      psym = lookup_partial_symbol (objfile, ps, lookup_name, 1, domain);
-      if (psym)
-	{
-	  *symbol_found_p = true;
-	  return psym->ginfo.language ();
-	}
-    }
-
-  return language_unknown;
-}
-
-/* Returns true if PSYM matches LOOKUP_NAME.  */
-
-static bool
-psymbol_name_matches (const partial_symbol *psym,
-		      const lookup_name_info &lookup_name)
-{
-  const language_defn *lang = language_def (psym->ginfo.language ());
-  symbol_name_matcher_ftype *name_match
-    = lang->get_symbol_name_matcher (lookup_name);
-  return name_match (psym->ginfo.search_name (), lookup_name, NULL);
-}
-
-/* Look, in partial_symtab PST, for symbol whose natural name is
-   LOOKUP_NAME.  Check the global symbols if GLOBAL, the static
-   symbols if not.  */
-
-static const struct partial_symbol *
-lookup_partial_symbol (struct objfile *objfile,
-		       struct partial_symtab *pst,
-		       const lookup_name_info &lookup_name,
-		       int global, domain_search_flags domain)
-{
-  const struct partial_symbol **start, **psym;
-  const struct partial_symbol **top, **real_top, **bottom, **center;
-  int length = (global
-		? pst->global_psymbols.size ()
-		: pst->static_psymbols.size ());
-  int do_linear_search = 1;
-
-  if (length == 0)
-    return NULL;
-
-  start = (global ?
-	   &pst->global_psymbols[0] :
-	   &pst->static_psymbols[0]);
-
-  if (global)			/* This means we can use a binary search.  */
-    {
-      do_linear_search = 0;
-
-      /* Binary search.  This search is guaranteed to end with center
-	 pointing at the earliest partial symbol whose name might be
-	 correct.  At that point *all* partial symbols with an
-	 appropriate name will be checked against the correct
-	 domain.  */
-
-      bottom = start;
-      top = start + length - 1;
-      real_top = top;
-      while (top > bottom)
-	{
-	  center = bottom + (top - bottom) / 2;
-
-	  gdb_assert (center < top);
-
-	  if (strcmp_iw_ordered ((*center)->ginfo.search_name (),
-				 lookup_name.c_str ()) >= 0)
-	    {
-	      top = center;
-	    }
-	  else
-	    {
-	      bottom = center + 1;
-	    }
-	}
-
-      gdb_assert (top == bottom);
-
-      /* For `case_sensitivity == case_sensitive_off' strcmp_iw_ordered will
-	 search more exactly than what matches SYMBOL_MATCHES_SEARCH_NAME.  */
-      while (top >= start && symbol_matches_search_name (&(*top)->ginfo,
-							 lookup_name))
-	top--;
-
-      /* Fixup to have a symbol which matches SYMBOL_MATCHES_SEARCH_NAME.  */
-      top++;
-
-      while (top <= real_top && symbol_matches_search_name (&(*top)->ginfo,
-							    lookup_name))
-	{
-	  if (search_flags_matches (domain, (*top)->domain))
-	    return *top;
-	  top++;
-	}
-    }
-
-  /* Can't use a binary search or else we found during the binary search that
-     we should also do a linear search.  */
-
-  if (do_linear_search)
-    {
-      for (psym = start; psym < start + length; psym++)
-	{
-	  if (search_flags_matches (domain, (*psym)->domain)
-	      && symbol_matches_search_name (&(*psym)->ginfo, lookup_name))
-	    return *psym;
-	}
-    }
-
-  return NULL;
-}
-
-/* Get the symbol table that corresponds to a partial_symtab.
-   This is fast after the first time you do it.
-   The result will be NULL if the primary symtab has no symbols,
-   which can happen.  Otherwise the result is the primary symtab
-   that contains PST.  */
-
-static struct compunit_symtab *
-psymtab_to_symtab (struct objfile *objfile, struct partial_symtab *pst)
-{
-  /* If it is a shared psymtab, find an unshared psymtab that includes
-     it.  Any such psymtab will do.  */
-  while (pst->user != NULL)
-    pst = pst->user;
-
-  /* If it's been looked up before, return it.  */
-  if (pst->get_compunit_symtab (objfile))
-    return pst->get_compunit_symtab (objfile);
-
-  /* If it has not yet been read in, read it.  */
-  if (!pst->readin_p (objfile))
-    {
-      scoped_restore decrementer = increment_reading_symtab ();
-
-      if (info_verbose)
-	{
-	  gdb_printf (_("Reading in symbols for %s...\n"),
-		      pst->filename);
-	  gdb_flush (gdb_stdout);
-	}
-
-      pst->read_symtab (objfile);
-    }
-
-  return pst->get_compunit_symtab (objfile);
-}
-
-/* Psymtab version of find_last_source_symtab.  See its definition in
-   the definition of quick_symbol_functions in symfile.h.  */
-
-struct symtab *
-psymbol_functions::find_last_source_symtab (struct objfile *ofp)
-{
-  struct partial_symtab *cs_pst = NULL;
-
-  for (partial_symtab *ps : partial_symbols (ofp))
-    {
-      const char *name = ps->filename;
-      int len = strlen (name);
-
-      if (!(len > 2 && (strcmp (&name[len - 2], ".h") == 0
-			|| strcmp (name, "<<C++-namespaces>>") == 0)))
-	cs_pst = ps;
-    }
-
-  if (cs_pst)
-    {
-      if (cs_pst->readin_p (ofp))
-	{
-	  internal_error (_("select_source_symtab: "
-			  "readin pst found and no symtabs."));
-	}
-      else
-	{
-	  struct compunit_symtab *cust = psymtab_to_symtab (ofp, cs_pst);
-
-	  if (cust == NULL)
-	    return NULL;
-	  return cust->primary_filetab ();
-	}
-    }
-  return NULL;
-}
-
-/* Psymtab version of forget_cached_source_info.  See its definition in
-   the definition of quick_symbol_functions in symfile.h.  */
-
-void
-psymbol_functions::forget_cached_source_info (struct objfile *objfile)
-{
-  for (partial_symtab *pst : partial_symbols (objfile))
-    {
-      if (pst->fullname != NULL)
-	{
-	  xfree (pst->fullname);
-	  pst->fullname = NULL;
-	}
-    }
-}
-
-static void
-print_partial_symbols (struct gdbarch *gdbarch, struct objfile *objfile,
-		       const std::vector<const partial_symbol *> &symbols,
-		       const char *what, struct ui_file *outfile)
-{
-  gdb_printf (outfile, "  %s partial symbols:\n", what);
-  for (const partial_symbol *p : symbols)
-    {
-      QUIT;
-      gdb_printf (outfile, "    `%s'", p->ginfo.linkage_name ());
-      if (p->ginfo.demangled_name () != NULL)
-	{
-	  gdb_printf (outfile, "  `%s'",
-		      p->ginfo.demangled_name ());
-	}
-      gdb_puts (", ", outfile);
-      switch (p->domain)
-	{
-	case UNDEF_DOMAIN:
-	  gdb_puts ("undefined domain, ", outfile);
-	  break;
-	case VAR_DOMAIN:
-	  /* This is the usual thing -- don't print it.  */
-	  break;
-	case STRUCT_DOMAIN:
-	  gdb_puts ("struct domain, ", outfile);
-	  break;
-	case MODULE_DOMAIN:
-	  gdb_puts ("module domain, ", outfile);
-	  break;
-	case LABEL_DOMAIN:
-	  gdb_puts ("label domain, ", outfile);
-	  break;
-	case COMMON_BLOCK_DOMAIN:
-	  gdb_puts ("common block domain, ", outfile);
-	  break;
-	case TYPE_DOMAIN:
-	  gdb_puts ("type domain, ", outfile);
-	  break;
-	case FUNCTION_DOMAIN:
-	  gdb_puts ("function domain, ", outfile);
-	  break;
-	default:
-	  gdb_puts ("<invalid domain>, ", outfile);
-	  break;
-	}
-      switch (p->loc_class)
-	{
-	case LOC_UNDEF:
-	  gdb_puts ("undefined", outfile);
-	  break;
-	case LOC_CONST:
-	  gdb_puts ("constant int", outfile);
-	  break;
-	case LOC_STATIC:
-	  gdb_puts ("static", outfile);
-	  break;
-	case LOC_REGISTER:
-	  gdb_puts ("register", outfile);
-	  break;
-	case LOC_ARG:
-	  gdb_puts ("pass by value", outfile);
-	  break;
-	case LOC_REF_ARG:
-	  gdb_puts ("pass by reference", outfile);
-	  break;
-	case LOC_REGPARM_ADDR:
-	  gdb_puts ("register address parameter", outfile);
-	  break;
-	case LOC_LOCAL:
-	  gdb_puts ("stack parameter", outfile);
-	  break;
-	case LOC_TYPEDEF:
-	  gdb_puts ("type", outfile);
-	  break;
-	case LOC_LABEL:
-	  gdb_puts ("label", outfile);
-	  break;
-	case LOC_BLOCK:
-	  gdb_puts ("function", outfile);
-	  break;
-	case LOC_CONST_BYTES:
-	  gdb_puts ("constant bytes", outfile);
-	  break;
-	case LOC_UNRESOLVED:
-	  gdb_puts ("unresolved", outfile);
-	  break;
-	case LOC_OPTIMIZED_OUT:
-	  gdb_puts ("optimized out", outfile);
-	  break;
-	case LOC_COMPUTED:
-	  gdb_puts ("computed at runtime", outfile);
-	  break;
-	default:
-	  gdb_puts ("<invalid location>", outfile);
-	  break;
-	}
-      gdb_puts (", ", outfile);
-      gdb_puts (paddress (gdbarch, CORE_ADDR (p->unrelocated_address ())),
-		outfile);
-      gdb_printf (outfile, "\n");
-    }
-}
-
-static void
-dump_psymtab (struct objfile *objfile, struct partial_symtab *psymtab,
-	      struct ui_file *outfile)
-{
-  struct gdbarch *gdbarch = objfile->arch ();
-  int i;
-
-  if (psymtab->anonymous)
-    {
-      gdb_printf (outfile, "\nAnonymous partial symtab (%s) ",
-		  psymtab->filename);
-    }
-  else
-    {
-      gdb_printf (outfile, "\nPartial symtab for source file %s ",
-		  psymtab->filename);
-    }
-  gdb_printf (outfile, "(object %s)\n\n",
-	      host_address_to_string (psymtab));
-  gdb_printf (outfile, "  Read from object file %s (%s)\n",
-	      objfile_name (objfile),
-	      host_address_to_string (objfile));
-
-  if (psymtab->readin_p (objfile))
-    gdb_printf
-      (outfile,
-       "  Full symtab was read (at %s)\n",
-       host_address_to_string (psymtab->get_compunit_symtab (objfile)));
-
-  gdb_printf (outfile, "  Symbols cover text addresses ");
-  gdb_puts (paddress (gdbarch, psymtab->text_low (objfile)), outfile);
-  gdb_printf (outfile, "-");
-  gdb_puts (paddress (gdbarch, psymtab->text_high (objfile)), outfile);
-  gdb_printf (outfile, "\n");
-  gdb_printf (outfile, "  Depends on %d other partial symtabs.\n",
-	      psymtab->number_of_dependencies);
-  for (i = 0; i < psymtab->number_of_dependencies; i++)
-    gdb_printf (outfile, "    %d %s\n", i,
-		host_address_to_string (psymtab->dependencies[i]));
-  if (psymtab->user != NULL)
-    gdb_printf (outfile, "  Shared partial symtab with user %s\n",
-		host_address_to_string (psymtab->user));
-  if (!psymtab->global_psymbols.empty ())
-    {
-      print_partial_symbols
-	(gdbarch, objfile, psymtab->global_psymbols,
-	 "Global", outfile);
-    }
-  if (!psymtab->static_psymbols.empty ())
-    {
-      print_partial_symbols
-	(gdbarch, objfile, psymtab->static_psymbols,
-	 "Static", outfile);
-    }
-  gdb_printf (outfile, "\n");
-}
-
-/* Count the number of partial symbols in OBJFILE.  */
-
-int
-psymbol_functions::count_psyms ()
-{
-  int count = 0;
-  for (partial_symtab *pst : m_partial_symtabs->range ())
-    {
-      count += pst->global_psymbols.size ();
-      count += pst->static_psymbols.size ();
-    }
-  return count;
-}
-
-/* Psymtab version of print_stats.  See its definition in
-   the definition of quick_symbol_functions in symfile.h.  */
-
-void
-psymbol_functions::print_stats (struct objfile *objfile, bool print_bcache)
-{
-  int i;
-
-  if (!print_bcache)
-    {
-      int n_psyms = count_psyms ();
-      if (n_psyms > 0)
-	gdb_printf (_("  Number of \"partial\" symbols read: %d\n"),
-		    n_psyms);
-
-      i = 0;
-      for (partial_symtab *ps : partial_symbols (objfile))
-	{
-	  if (!ps->readin_p (objfile))
-	    i++;
-	}
-      gdb_printf (_("  Number of psym tables (not yet expanded): %d\n"),
-		  i);
-      gdb_printf (_("  Total memory used for psymbol cache: %d\n"),
-		  m_partial_symtabs->psymbol_cache.memory_used ());
-    }
-  else
-    {
-      gdb_printf (_("Psymbol byte cache statistics:\n"));
-      m_partial_symtabs->psymbol_cache.print_statistics
-	("partial symbol cache");
-    }
-}
-
-/* Psymtab version of dump.  See its definition in
-   the definition of quick_symbol_functions in symfile.h.  */
-
-void
-psymbol_functions::dump (struct objfile *objfile)
-{
-  struct partial_symtab *psymtab;
-
-  if (m_partial_symtabs->psymtabs)
-    {
-      gdb_printf ("Psymtabs:\n");
-      for (psymtab = m_partial_symtabs->psymtabs;
-	   psymtab != NULL;
-	   psymtab = psymtab->next)
-	gdb_printf ("%s at %s\n",
-		    psymtab->filename,
-		    host_address_to_string (psymtab));
-      gdb_printf ("\n\n");
-    }
-}
-
-/* Psymtab version of expand_all_symtabs.  See its definition in
-   the definition of quick_symbol_functions in symfile.h.  */
-
-void
-psymbol_functions::expand_all_symtabs (struct objfile *objfile)
-{
-  for (partial_symtab *psymtab : partial_symbols (objfile))
-    psymtab_to_symtab (objfile, psymtab);
-}
-
-/* Psymtab version of map_symbol_filenames.  See its definition in
-   the definition of quick_symbol_functions in symfile.h.  */
-
-void
-psymbol_functions::map_symbol_filenames (objfile *objfile,
-					 symbol_filename_listener fun,
-					 bool need_fullname)
-{
-  for (partial_symtab *ps : partial_symbols (objfile))
-    {
-      const char *fullname;
-
-      if (ps->readin_p (objfile))
-	continue;
-
-      /* We can skip shared psymtabs here, because any file name will be
-	 attached to the unshared psymtab.  */
-      if (ps->user != NULL)
-	continue;
-
-      /* Anonymous psymtabs don't have a file name.  */
-      if (ps->anonymous)
-	continue;
-
-      QUIT;
-      if (need_fullname)
-	fullname = psymtab_to_fullname (ps);
-      else
-	fullname = NULL;
-      fun (ps->filename, fullname);
-    }
-}
-
-/* Finds the fullname that a partial_symtab represents.
-
-   If this functions finds the fullname, it will save it in ps->fullname
-   and it will also return the value.
-
-   If this function fails to find the file that this partial_symtab represents,
-   NULL will be returned and ps->fullname will be set to NULL.  */
-
-static const char *
-psymtab_to_fullname (struct partial_symtab *ps)
-{
-  gdb_assert (!ps->anonymous);
-
-  /* Use cached copy if we have it.
-     We rely on forget_cached_source_info being called appropriately
-     to handle cases like the file being moved.  */
-  if (ps->fullname == NULL)
-    {
-      gdb::unique_xmalloc_ptr<char> fullname
-	= find_source_or_rewrite (ps->filename, ps->dirname);
-      ps->fullname = fullname.release ();
-    }
-
-  return ps->fullname;
-}
-
-/* A helper for psymbol_functions::search that handles searching
-   included psymtabs.  This returns true if a symbol is found, and
-   false otherwise.  It also updates the 'searched_flag' on the
-   various psymtabs that it searches.  */
-
-static bool
-recursively_search_psymtabs (partial_symtab *ps, objfile *objfile,
-			     block_search_flags search_flags,
-			     domain_search_flags domain,
-			     const lookup_name_info &lookup_name,
-			     search_symtabs_symbol_matcher sym_matcher)
-{
-  int keep_going = 1;
-  enum psymtab_search_status result = PST_SEARCHED_AND_NOT_FOUND;
-  int i;
-
-  if (ps->searched_flag != PST_NOT_SEARCHED)
-    return ps->searched_flag == PST_SEARCHED_AND_FOUND;
-
-  /* Recurse into shared psymtabs first, because they may have already
-     been searched, and this could save some time.  */
-  for (i = 0; i < ps->number_of_dependencies; ++i)
-    {
-      int r;
-
-      /* Skip non-shared dependencies, these are handled elsewhere.  */
-      if (ps->dependencies[i]->user == NULL)
-	continue;
-
-      r = recursively_search_psymtabs (ps->dependencies[i],
-				       objfile, search_flags, domain,
-				       lookup_name, sym_matcher);
-      if (r != 0)
-	{
-	  ps->searched_flag = PST_SEARCHED_AND_FOUND;
-	  return true;
-	}
-    }
-
-  const partial_symbol **gbound = (ps->global_psymbols.data ()
-				   + ps->global_psymbols.size ());
-  const partial_symbol **sbound = (ps->static_psymbols.data ()
-				   + ps->static_psymbols.size ());
-  const partial_symbol **bound = gbound;
-
-  /* Go through all of the symbols stored in a partial
-     symtab in one loop.  */
-  const partial_symbol **psym = ps->global_psymbols.data ();
-
-  if ((search_flags & SEARCH_GLOBAL_BLOCK) == 0)
-    {
-      if (ps->static_psymbols.empty ())
-	keep_going = 0;
-      else
-	{
-	  psym = ps->static_psymbols.data ();
-	  bound = sbound;
-	}
-    }
-
-  while (keep_going)
-    {
-      if (psym >= bound)
-	{
-	  if (bound == gbound && !ps->static_psymbols.empty ()
-	      && (search_flags & SEARCH_STATIC_BLOCK) != 0)
-	    {
-	      psym = ps->static_psymbols.data ();
-	      bound = sbound;
-	    }
-	  else
-	    keep_going = 0;
-	  continue;
-	}
-      else
-	{
-	  QUIT;
-
-	  if (search_flags_matches (domain, (*psym)->domain)
-	      && psymbol_name_matches (*psym, lookup_name)
-	      && (sym_matcher == NULL
-		  || sym_matcher ((*psym)->ginfo.search_name ())))
-	    {
-	      /* Found a match, so notify our caller.  */
-	      result = PST_SEARCHED_AND_FOUND;
-	      keep_going = 0;
-	    }
-	}
-      psym++;
-    }
-
-  ps->searched_flag = result;
-  return result == PST_SEARCHED_AND_FOUND;
-}
-
-/* Psymtab version of search.  See its definition in
-   the definition of quick_symbol_functions in symfile.h.  */
-
-bool
-psymbol_functions::search
-  (struct objfile *objfile,
-   search_symtabs_file_matcher file_matcher,
-   const lookup_name_info *lookup_name,
-   search_symtabs_symbol_matcher symbol_matcher,
-   search_symtabs_expansion_listener listener,
-   block_search_flags search_flags,
-   domain_search_flags domain,
-   search_symtabs_lang_matcher lang_matcher ATTRIBUTE_UNUSED)
-{
-  /* Clear the search flags.  */
-  for (partial_symtab *ps : partial_symbols (objfile))
-    ps->searched_flag = PST_NOT_SEARCHED;
-
-  std::optional<lookup_name_info> psym_lookup_name;
-  if (lookup_name != nullptr)
-    psym_lookup_name = lookup_name->make_ignore_params ();
-
-  /* This invariant is documented in quick-functions.h.  */
-  gdb_assert (lookup_name != nullptr || symbol_matcher == nullptr);
-
-  for (partial_symtab *ps : m_partial_symtabs->range ())
-    {
-      QUIT;
-
-      if (file_matcher)
-	{
-	  bool match;
-
-	  if (ps->anonymous)
-	    continue;
-
-	  match = file_matcher (ps->filename, false);
-	  if (!match)
-	    {
-	      /* Before we invoke realpath, which can get expensive when many
-		 files are involved, do a quick comparison of the basenames.  */
-	      if (basenames_may_differ
-		  || file_matcher (lbasename (ps->filename), true))
-		match = file_matcher (psymtab_to_fullname (ps), false);
-	    }
-	  if (!match)
-	    continue;
-	}
-
-      if (lookup_name == nullptr
-	  || recursively_search_psymtabs (ps, objfile, search_flags,
-					  domain, *psym_lookup_name,
-					  symbol_matcher))
-	{
-	  compunit_symtab *cust = psymtab_to_symtab (objfile, ps);
-
-	  if (cust != nullptr && listener != nullptr)
-	    if (!listener (cust))
-	      return false;
-	}
-    }
-
-  return true;
-}
-
-/* Psymtab version of has_symbols.  See its definition in
-   the definition of quick_symbol_functions in symfile.h.  */
-
-bool
-psymbol_functions::has_symbols (struct objfile *objfile)
-{
-  return m_partial_symtabs->psymtabs != NULL;
-}
-
-/* See quick_symbol_functions::has_unexpanded_symtabs in quick-symbol.h.  */
-
-bool
-psymbol_functions::has_unexpanded_symtabs (struct objfile *objfile)
-{
-  for (partial_symtab *psymtab : partial_symbols (objfile))
-    {
-      /* Is this already expanded?  */
-      if (psymtab->readin_p (objfile))
-	continue;
-
-      /* It has not yet been expanded.  */
-      return true;
-    }
-
-  return false;
-}
-
-\f
-
-/* Partially fill a partial symtab.  It will be completely filled at
-   the end of the symbol list.  */
-
-partial_symtab::partial_symtab (const char *filename,
-				psymtab_storage *partial_symtabs,
-				objfile_per_bfd_storage *objfile_per_bfd,
-				unrelocated_addr textlow)
-  : partial_symtab (filename, partial_symtabs, objfile_per_bfd)
-{
-  set_text_low (textlow);
-  set_text_high (unrelocated_text_low ()); /* default */
-}
-
-/* Perform "finishing up" operations of a partial symtab.  */
-
-void
-partial_symtab::end ()
-{
-  global_psymbols.shrink_to_fit ();
-  static_psymbols.shrink_to_fit ();
-
-  /* Sort the global list; don't sort the static list.  */
-  std::sort (global_psymbols.begin (),
-	     global_psymbols.end (),
-	     [] (const partial_symbol *s1, const partial_symbol *s2)
-    {
-      return strcmp_iw_ordered (s1->ginfo.search_name (),
-				s2->ginfo.search_name ()) < 0;
-    });
-}
-
-/* See psymtab.h.  */
-
-unsigned long
-psymbol_bcache::hash (const void *addr, int length)
-{
-  unsigned long h = 0;
-  struct partial_symbol *psymbol = (struct partial_symbol *) addr;
-  unsigned int lang = psymbol->ginfo.language ();
-  unsigned int domain = psymbol->domain;
-  unsigned int loc_class = psymbol->loc_class;
-
-  h = fast_hash (&psymbol->ginfo.m_value, sizeof (psymbol->ginfo.m_value), h);
-  h = fast_hash (&lang, sizeof (unsigned int), h);
-  h = fast_hash (&domain, sizeof (unsigned int), h);
-  h = fast_hash (&loc_class, sizeof (unsigned int), h);
-  /* Note that psymbol names are interned via compute_and_set_names, so
-     there's no need to hash the contents of the name here.  */
-  h = fast_hash (&psymbol->ginfo.m_name, sizeof (psymbol->ginfo.m_name), h);
-
-  return h;
-}
-
-/* See psymtab.h.  */
-
-int
-psymbol_bcache::compare (const void *addr1, const void *addr2, int length)
-{
-  struct partial_symbol *sym1 = (struct partial_symbol *) addr1;
-  struct partial_symbol *sym2 = (struct partial_symbol *) addr2;
-
-  return (memcmp (&sym1->ginfo.m_value, &sym2->ginfo.m_value,
-		  sizeof (sym1->ginfo.m_value)) == 0
-	  && sym1->ginfo.language () == sym2->ginfo.language ()
-	  && sym1->domain == sym2->domain
-	  && sym1->loc_class == sym2->loc_class
-	  /* Note that psymbol names are interned via
-	     compute_and_set_names, so there's no need to compare the
-	     contents of the name here.  */
-	  && sym1->ginfo.linkage_name () == sym2->ginfo.linkage_name ());
-}
-
-/* See psymtab.h.  */
-
-void
-partial_symtab::add_psymbol (const partial_symbol &psymbol,
-			     psymbol_placement where,
-			     psymtab_storage *partial_symtabs,
-			     struct objfile *objfile)
-{
-  bool added;
-
-  /* Stash the partial symbol away in the cache.  */
-  const partial_symbol *psym = partial_symtabs->psymbol_cache.insert (psymbol,
-								      &added);
-
-  /* Do not duplicate global partial symbols.  */
-  if (where == psymbol_placement::GLOBAL && !added)
-    return;
-
-  /* Save pointer to partial symbol in psymtab, growing symtab if needed.  */
-  std::vector<const partial_symbol *> &list
-    = (where == psymbol_placement::STATIC
-       ? static_psymbols
-       : global_psymbols);
-  list.push_back (psym);
-}
-
-/* See psymtab.h.  */
-
-void
-partial_symtab::add_psymbol (std::string_view name, bool copy_name,
-			     domain_enum domain,
-			     location_class loc_class,
-			     int section,
-			     psymbol_placement where,
-			     unrelocated_addr coreaddr,
-			     enum language language,
-			     psymtab_storage *partial_symtabs,
-			     struct objfile *objfile)
-{
-  struct partial_symbol psymbol;
-  memset (&psymbol, 0, sizeof (psymbol));
-
-  psymbol.set_unrelocated_address (coreaddr);
-  psymbol.ginfo.set_section_index (section);
-  psymbol.domain = domain;
-  psymbol.loc_class = loc_class;
-  psymbol.ginfo.set_language (language, partial_symtabs->obstack ());
-  psymbol.ginfo.compute_and_set_names (name, copy_name, objfile->per_bfd);
-
-  add_psymbol (psymbol, where, partial_symtabs, objfile);
-}
-
-/* See psymtab.h.  */
-
-partial_symtab::partial_symtab (const char *filename_,
-				psymtab_storage *partial_symtabs,
-				objfile_per_bfd_storage *objfile_per_bfd)
-  : searched_flag (PST_NOT_SEARCHED),
-    text_low_valid (0),
-    text_high_valid (0)
-{
-  partial_symtabs->install_psymtab (this);
-
-  filename = objfile_per_bfd->intern (filename_);
-
-  if (symtab_create_debug >= 1)
-    {
-      /* Be a bit clever with debugging messages, and don't print objfile
-	 every time, only when it changes.  */
-      static std::string last_bfd_name;
-      const char *this_bfd_name
-	= bfd_get_filename (objfile_per_bfd->get_bfd ());
-
-      if (last_bfd_name.empty () || last_bfd_name != this_bfd_name)
-	{
-	  last_bfd_name = this_bfd_name;
-
-	  symtab_create_debug_printf ("creating one or more psymtabs for %s",
-				      this_bfd_name);
-	}
-
-      symtab_create_debug_printf ("created psymtab %s for module %s",
-				  host_address_to_string (this), filename);
-    }
-}
-
-/* See psymtab.h.  */
-
-void
-partial_symtab::expand_dependencies (struct objfile *objfile)
-{
-  for (int i = 0; i < number_of_dependencies; ++i)
-    {
-      if (!dependencies[i]->readin_p (objfile)
-	  && dependencies[i]->user == NULL)
-	{
-	  /* Inform about additional files to be read in.  */
-	  if (info_verbose)
-	    {
-	      gdb_puts (" ");
-	      gdb_stdout->wrap_here (0);
-	      gdb_puts ("and ");
-	      gdb_stdout->wrap_here (0);
-	      gdb_printf ("%s...", dependencies[i]->filename);
-	      gdb_flush (gdb_stdout);
-	    }
-	  dependencies[i]->expand_psymtab (objfile);
-	}
-    }
-}
-
-
-void
-psymtab_storage::discard_psymtab (struct partial_symtab *pst)
-{
-  struct partial_symtab **prev_pst;
-
-  /* From dbxread.c:
-     Empty psymtabs happen as a result of header files which don't
-     have any symbols in them.  There can be a lot of them.  But this
-     check is wrong, in that a psymtab with N_SLINE entries but
-     nothing else is not empty, but we don't realize that.  Fixing
-     that without slowing things down might be tricky.  */
-
-  /* First, snip it out of the psymtab chain.  */
-
-  prev_pst = &psymtabs;
-  while ((*prev_pst) != pst)
-    prev_pst = &((*prev_pst)->next);
-  (*prev_pst) = pst->next;
-  delete pst;
-}
-
-\f
-
-static void
-maintenance_print_psymbols (const char *args, int from_tty)
-{
-  struct ui_file *outfile = gdb_stdout;
-  char *address_arg = NULL, *source_arg = NULL, *objfile_arg = NULL;
-  int i, outfile_idx, found;
-  CORE_ADDR pc = 0;
-  struct obj_section *section = NULL;
-
-  dont_repeat ();
-
-  gdb_argv argv (args);
-
-  for (i = 0; argv != NULL && argv[i] != NULL; ++i)
-    {
-      if (strcmp (argv[i], "-pc") == 0)
-	{
-	  if (argv[i + 1] == NULL)
-	    error (_("Missing pc value"));
-	  address_arg = argv[++i];
-	}
-      else if (strcmp (argv[i], "-source") == 0)
-	{
-	  if (argv[i + 1] == NULL)
-	    error (_("Missing source file"));
-	  source_arg = argv[++i];
-	}
-      else if (strcmp (argv[i], "-objfile") == 0)
-	{
-	  if (argv[i + 1] == NULL)
-	    error (_("Missing objfile name"));
-	  objfile_arg = argv[++i];
-	}
-      else if (strcmp (argv[i], "--") == 0)
-	{
-	  /* End of options.  */
-	  ++i;
-	  break;
-	}
-      else if (argv[i][0] == '-')
-	{
-	  /* Future proofing: Don't allow OUTFILE to begin with "-".  */
-	  error (_("Unknown option: %s"), argv[i]);
-	}
-      else
-	break;
-    }
-  outfile_idx = i;
-
-  if (address_arg != NULL && source_arg != NULL)
-    error (_("Must specify at most one of -pc and -source"));
-
-  stdio_file arg_outfile;
-
-  if (argv != NULL && argv[outfile_idx] != NULL)
-    {
-      if (argv[outfile_idx + 1] != NULL)
-	error (_("Junk at end of command"));
-      gdb::unique_xmalloc_ptr<char> outfile_name
-	= gdb_rl_tilde_expand (argv[outfile_idx]);
-      if (!arg_outfile.open (outfile_name.get (), FOPEN_WT))
-	perror_with_name (outfile_name.get ());
-      outfile = &arg_outfile;
-    }
-
-  if (address_arg != NULL)
-    {
-      pc = parse_and_eval_address (address_arg);
-      /* If we fail to find a section, that's ok, try the lookup anyway.  */
-      section = find_pc_section (pc);
-    }
-
-  found = 0;
-  for (objfile &objfile : current_program_space->objfiles ())
-    {
-      int printed_objfile_header = 0;
-      int print_for_objfile = 1;
-
-      QUIT;
-      if (objfile_arg != NULL)
-	print_for_objfile
-	  = compare_filenames_for_search (objfile_name (&objfile),
-					  objfile_arg);
-      if (!print_for_objfile)
-	continue;
-
-      for (const auto &iter : objfile.qf)
-	{
-	  psymbol_functions *psf
-	    = dynamic_cast<psymbol_functions *> (iter.get ());
-	  if (psf == nullptr)
-	    continue;
-
-	  if (address_arg != NULL)
-	    {
-	      bound_minimal_symbol msymbol;
-
-	      /* We don't assume each pc has a unique objfile (this is for
-		 debugging).  */
-	      struct partial_symtab *ps
-		= psf->find_pc_sect_psymtab (&objfile, pc, section, msymbol);
-	      if (ps != NULL)
-		{
-		  if (!printed_objfile_header)
-		    {
-		      outfile->printf ("\nPartial symtabs for objfile %s\n",
-				       objfile_name (&objfile));
-		      printed_objfile_header = 1;
-		    }
-		  dump_psymtab (&objfile, ps, outfile);
-		  found = 1;
-		}
-	    }
-	  else
-	    {
-	      for (partial_symtab *ps : psf->partial_symbols (&objfile))
-		{
-		  int print_for_source = 0;
-
-		  QUIT;
-		  if (source_arg != NULL)
-		    {
-		      print_for_source
-			= compare_filenames_for_search (ps->filename, source_arg);
-		      found = 1;
-		    }
-		  if (source_arg == NULL
-		      || print_for_source)
-		    {
-		      if (!printed_objfile_header)
-			{
-			  outfile->printf ("\nPartial symtabs for objfile %s\n",
-					   objfile_name (&objfile));
-			  printed_objfile_header = 1;
-			}
-		      dump_psymtab (&objfile, ps, outfile);
-		    }
-		}
-	    }
-	}
-    }
-
-  if (!found)
-    {
-      if (address_arg != NULL)
-	error (_("No partial symtab for address: %s"), address_arg);
-      if (source_arg != NULL)
-	error (_("No partial symtab for source file: %s"), source_arg);
-    }
-}
-
-/* List all the partial symbol tables whose names match REGEXP (optional).  */
-
-static void
-maintenance_info_psymtabs (const char *regexp, int from_tty)
-{
-  if (regexp)
-    re_comp (regexp);
-
-  for (struct program_space *pspace : program_spaces)
-    for (objfile &objfile : pspace->objfiles ())
-      {
-	struct gdbarch *gdbarch = objfile.arch ();
-
-	/* We don't want to print anything for this objfile until we
-	   actually find a symtab whose name matches.  */
-	int printed_objfile_start = 0;
-
-	for (const auto &iter : objfile.qf)
-	  {
-	    psymbol_functions *psf
-	      = dynamic_cast<psymbol_functions *> (iter.get ());
-	    if (psf == nullptr)
-	      continue;
-	    for (partial_symtab *psymtab : psf->partial_symbols (&objfile))
-	      {
-		QUIT;
-
-		if (! regexp
-		    || re_exec (psymtab->filename))
-		  {
-		    if (! printed_objfile_start)
-		      {
-			gdb_printf ("{ objfile %s ", objfile_name (&objfile));
-			gdb_stdout->wrap_here (2);
-			gdb_printf ("((struct objfile *) %s)\n",
-				    host_address_to_string (&objfile));
-			printed_objfile_start = 1;
-		      }
-
-		    gdb_printf ("  { psymtab %s ", psymtab->filename);
-		    gdb_stdout->wrap_here (4);
-		    gdb_printf ("((struct partial_symtab *) %s)\n",
-				host_address_to_string (psymtab));
-
-		    gdb_printf ("    readin %s\n",
-				psymtab->readin_p (&objfile) ? "yes" : "no");
-		    gdb_printf ("    fullname %s\n",
-				psymtab->fullname
-				? psymtab->fullname : "(null)");
-		    gdb_printf ("    text addresses ");
-		    gdb_puts (paddress (gdbarch,
-					psymtab->text_low (&objfile)));
-		    gdb_printf (" -- ");
-		    gdb_puts (paddress (gdbarch,
-					psymtab->text_high (&objfile)));
-		    gdb_printf ("\n");
-		    gdb_printf ("    globals ");
-		    if (!psymtab->global_psymbols.empty ())
-		      gdb_printf
-			("(* (struct partial_symbol **) %s @ %d)\n",
-			 host_address_to_string (psymtab->global_psymbols.data ()),
-			 (int) psymtab->global_psymbols.size ());
-		    else
-		      gdb_printf ("(none)\n");
-		    gdb_printf ("    statics ");
-		    if (!psymtab->static_psymbols.empty ())
-		      gdb_printf
-			("(* (struct partial_symbol **) %s @ %d)\n",
-			 host_address_to_string (psymtab->static_psymbols.data ()),
-			 (int) psymtab->static_psymbols.size ());
-		    else
-		      gdb_printf ("(none)\n");
-		    if (psymtab->user)
-		      gdb_printf ("    user %s "
-				  "((struct partial_symtab *) %s)\n",
-				  psymtab->user->filename,
-				  host_address_to_string (psymtab->user));
-		    gdb_printf ("    dependencies ");
-		    if (psymtab->number_of_dependencies)
-		      {
-			int i;
-
-			gdb_printf ("{\n");
-			for (i = 0; i < psymtab->number_of_dependencies; i++)
-			  {
-			    struct partial_symtab *dep = psymtab->dependencies[i];
-
-			    /* Note the string concatenation there --- no
-			       comma.  */
-			    gdb_printf ("      psymtab %s "
-					"((struct partial_symtab *) %s)\n",
-					dep->filename,
-					host_address_to_string (dep));
-			  }
-			gdb_printf ("    }\n");
-		      }
-		    else
-		      gdb_printf ("(none)\n");
-		    gdb_printf ("  }\n");
-		  }
-	      }
-	  }
-
-	if (printed_objfile_start)
-	  gdb_printf ("}\n");
-      }
-}
-
-/* Check consistency of currently expanded psymtabs vs symtabs.  */
-
-static void
-maintenance_check_psymtabs (const char *ignore, int from_tty)
-{
-  struct symbol *sym;
-  struct compunit_symtab *cust = NULL;
-  const struct blockvector *bv;
-  const struct block *b;
-
-  for (objfile &objfile : current_program_space->objfiles ())
-    {
-      for (const auto &iter : objfile.qf)
-	{
-	  psymbol_functions *psf
-	    = dynamic_cast<psymbol_functions *> (iter.get ());
-	  if (psf == nullptr)
-	    continue;
-
-	  for (partial_symtab *ps : psf->partial_symbols (&objfile))
-	    {
-	      struct gdbarch *gdbarch = objfile.arch ();
-
-	      /* We don't call psymtab_to_symtab here because that may cause symtab
-		 expansion.  When debugging a problem it helps if checkers leave
-		 things unchanged.  */
-	      cust = ps->get_compunit_symtab (&objfile);
-
-	      /* First do some checks that don't require the associated symtab.  */
-	      if (ps->text_high (&objfile) < ps->text_low (&objfile))
-		{
-		  gdb_printf ("Psymtab ");
-		  gdb_puts (ps->filename);
-		  gdb_printf (" covers bad range ");
-		  gdb_puts (paddress (gdbarch, ps->text_low (&objfile)));
-		  gdb_printf (" - ");
-		  gdb_puts (paddress (gdbarch, ps->text_high (&objfile)));
-		  gdb_printf ("\n");
-		  continue;
-		}
-
-	      /* Now do checks requiring the associated symtab.  */
-	      if (cust == NULL)
-		continue;
-	      bv = cust->blockvector ();
-	      b = bv->static_block ();
-	      for (const partial_symbol *psym : ps->static_psymbols)
-		{
-		  /* Skip symbols for inlined functions without address.  These may
-		     or may not have a match in the full symtab.  */
-		  if (psym->loc_class == LOC_BLOCK
-		      && psym->ginfo.value_address () == 0)
-		    continue;
-
-		  lookup_name_info lookup_name
-		    (psym->ginfo.search_name (), symbol_name_match_type::SEARCH_NAME);
-		  sym = block_lookup_symbol (b, lookup_name,
-					     to_search_flags (psym->domain));
-		  if (!sym)
-		    {
-		      gdb_printf ("Static symbol `");
-		      gdb_puts (psym->ginfo.linkage_name ());
-		      gdb_printf ("' only found in ");
-		      gdb_puts (ps->filename);
-		      gdb_printf (" psymtab\n");
-		    }
-		}
-	      b = bv->global_block ();
-	      for (const partial_symbol *psym : ps->global_psymbols)
-		{
-		  lookup_name_info lookup_name
-		    (psym->ginfo.search_name (), symbol_name_match_type::SEARCH_NAME);
-		  sym = block_lookup_symbol (b, lookup_name,
-					     to_search_flags (psym->domain));
-		  if (!sym)
-		    {
-		      gdb_printf ("Global symbol `");
-		      gdb_puts (psym->ginfo.linkage_name ());
-		      gdb_printf ("' only found in ");
-		      gdb_puts (ps->filename);
-		      gdb_printf (" psymtab\n");
-		    }
-		}
-	      if (ps->unrelocated_text_high () != unrelocated_addr (0)
-		  && (ps->text_low (&objfile) < b->start ()
-		      || ps->text_high (&objfile) > b->end ()))
-		{
-		  gdb_printf ("Psymtab ");
-		  gdb_puts (ps->filename);
-		  gdb_printf (" covers ");
-		  gdb_puts (paddress (gdbarch, ps->text_low (&objfile)));
-		  gdb_printf (" - ");
-		  gdb_puts (paddress (gdbarch, ps->text_high (&objfile)));
-		  gdb_printf (" but symtab covers only ");
-		  gdb_puts (paddress (gdbarch, b->start ()));
-		  gdb_printf (" - ");
-		  gdb_puts (paddress (gdbarch, b->end ()));
-		  gdb_printf ("\n");
-		}
-	    }
-	}
-    }
-}
-
-INIT_GDB_FILE (psymtab)
-{
-  add_cmd ("psymbols", class_maintenance, maintenance_print_psymbols, _("\
-Print dump of current partial symbol definitions.\n\
-Usage: mt print psymbols [-objfile OBJFILE] [-pc ADDRESS] [--] [OUTFILE]\n\
-       mt print psymbols [-objfile OBJFILE] [-source SOURCE] [--] [OUTFILE]\n\
-Entries in the partial symbol table are dumped to file OUTFILE,\n\
-or the terminal if OUTFILE is unspecified.\n\
-If ADDRESS is provided, dump only the symbols for the file\n\
-with code at that address.\n\
-If SOURCE is provided, dump only that file's symbols.\n\
-If OBJFILE is provided, dump only that object file's symbols."),
-	   &maintenanceprintlist);
-
-  add_cmd ("psymtabs", class_maintenance, maintenance_info_psymtabs, _("\
-List the partial symbol tables for all object files.\n\
-This does not include information about individual partial symbols,\n\
-just the symbol table structures themselves."),
-	   &maintenanceinfolist);
-
-  add_cmd ("psymtabs", class_maintenance, maintenance_check_psymtabs,
-	   _("\
-Check consistency of currently expanded psymtabs versus symtabs."),
-	   &maintenancechecklist);
-}
diff --git a/gdb/psymtab.h b/gdb/psymtab.h
deleted file mode 100644
index be4ed4262667..000000000000
--- a/gdb/psymtab.h
+++ /dev/null
@@ -1,691 +0,0 @@
-/* Public partial symbol table definitions.
-
-   Copyright (C) 2009-2026 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/>.  */
-
-#ifndef GDB_PSYMTAB_H
-#define GDB_PSYMTAB_H
-
-#include "objfiles.h"
-#include <string_view>
-#include "gdbsupport/gdb_obstack.h"
-#include "symfile.h"
-#include "gdbsupport/next-iterator.h"
-#include "bcache.h"
-
-/* Specialization of bcache to store partial symbols.  */
-
-struct psymbol_bcache : public gdb::bcache
-{
-  /* Calculate a hash code for the given partial symbol.  The hash is
-     calculated using the symbol's value, language, domain, class
-     and name.  These are the values which are set by
-     add_psymbol_to_bcache.  */
-  unsigned long hash (const void *addr, int length) override;
-
-  /* Returns true if the symbol LEFT equals the symbol RIGHT.
-     For the comparison this function uses a symbols value,
-     language, domain, class and name.  */
-  int compare (const void *left, const void *right, int length) override;
-};
-
-/* An instance of this class manages the partial symbol tables and
-   partial symbols for a given objfile.
-
-   The core psymtab functions -- those in psymtab.c -- arrange for
-   nearly all psymtab- and psymbol-related allocations to happen
-   either in the psymtab_storage object (either on its obstack or in
-   other memory managed by this class), or on the per-BFD object.  The
-   only link from the psymtab storage object back to the objfile (or
-   objfile_obstack) that is made by the core psymtab code is the
-   compunit_symtab member in the standard_psymtab -- and a given
-   symbol reader can avoid this by implementing its own subclasses of
-   partial_symtab.
-
-   However, it is up to each symbol reader to maintain this invariant
-   in other ways, if it wants to reuse psymtabs across multiple
-   objfiles.  The main issue here is ensuring that read_symtab_private
-   does not point into objfile_obstack.  */
-
-class psymtab_storage
-{
-public:
-  psymtab_storage () = default;
-  ~psymtab_storage ();
-
-  DISABLE_COPY_AND_ASSIGN (psymtab_storage);
-
-  /* Discard all partial symbol tables starting with "psymtabs" and
-     proceeding until "to" has been discarded.  */
-
-  void discard_psymtabs_to (struct partial_symtab *to)
-  {
-    while (psymtabs != to)
-      discard_psymtab (psymtabs);
-  }
-
-  /* Discard the partial symbol table.  */
-
-  void discard_psymtab (struct partial_symtab *pst);
-
-  /* Return the obstack that is used for storage by this object.  */
-
-  struct obstack *obstack ()
-  {
-    if (!m_obstack.has_value ())
-      m_obstack.emplace ();
-    return &*m_obstack;
-  }
-
-  /* Allocate storage for the "dependencies" field of a psymtab.
-     NUMBER says how many dependencies there are.  */
-
-  struct partial_symtab **allocate_dependencies (int number)
-  {
-    return OBSTACK_CALLOC (obstack (), number, struct partial_symtab *);
-  }
-
-  /* Install a psymtab on the psymtab list.  This transfers ownership
-     of PST to this object.  */
-
-  void install_psymtab (partial_symtab *pst);
-
-  using partial_symtab_range = next_range<partial_symtab>;
-
-  /* A range adapter that makes it possible to iterate over all
-     psymtabs in one objfile.  */
-
-  partial_symtab_range range ()
-  {
-    next_iterator<partial_symtab> begin (psymtabs);
-
-    return partial_symtab_range (std::move (begin));
-  }
-
-
-  /* Each objfile points to a linked list of partial symtabs derived from
-     this file, one partial symtab structure for each compilation unit
-     (source file).  */
-
-  struct partial_symtab *psymtabs = nullptr;
-
-  /* A byte cache where we can stash arbitrary "chunks" of bytes that
-     will not change.  */
-
-  psymbol_bcache psymbol_cache;
-
-private:
-
-  /* The obstack where allocations are made.  This is lazily allocated
-     so that we don't waste memory when there are no psymtabs.  */
-
-  std::optional<auto_obstack> m_obstack;
-};
-
-/* A partial_symbol records the name, domain, and address class of
-   symbols whose types we have not parsed yet.  For functions, it also
-   contains their memory address, so we can find them from a PC value.
-   Each partial_symbol sits in a partial_symtab, all of which are chained
-   on a  partial symtab list and which points to the corresponding
-   normal symtab once the partial_symtab has been referenced.  */
-
-/* This structure is space critical.  See space comments at the top of
-   symtab.h.  */
-
-struct partial_symbol
-{
-  /* Return the section for this partial symbol, or nullptr if no
-     section has been set.  */
-  struct obj_section *obj_section (struct objfile *objfile) const
-  {
-    return ginfo.obj_section (objfile);
-  }
-
-  /* Return the unrelocated address of this partial symbol.  */
-  unrelocated_addr unrelocated_address () const
-  {
-    return ginfo.unrelocated_address ();
-  }
-
-  /* Return the address of this partial symbol, relocated according to
-     the offsets provided in OBJFILE.  */
-  CORE_ADDR address (const struct objfile *objfile) const
-  {
-    return (CORE_ADDR (ginfo.unrelocated_address ())
-	    + objfile->section_offsets[ginfo.section_index ()]);
-  }
-
-  /* Set the address of this partial symbol.  The address must be
-     unrelocated.  */
-  void set_unrelocated_address (unrelocated_addr addr)
-  {
-    ginfo.set_unrelocated_address (addr);
-  }
-
-  /* Note that partial_symbol does not derive from general_symbol_info
-     due to the bcache.  See add_psymbol_to_bcache.  */
-
-  struct general_symbol_info ginfo;
-
-  /* Name space code.  */
-
-  ENUM_BITFIELD(domain_enum) domain : SYMBOL_DOMAIN_BITS;
-
-  /* Address class (for info_symbols).  Note that we don't allow
-     synthetic "loc_class" values here at present, simply because there's
-     no need.  */
-
-  ENUM_BITFIELD(location_class) loc_class : SYMBOL_LOC_CLASS_BITS;
-};
-
-/* A convenience enum to give names to some constants used when
-   searching psymtabs.  This is internal to psymtab and should not be
-   used elsewhere.  */
-
-enum psymtab_search_status
-  {
-    PST_NOT_SEARCHED,
-    PST_SEARCHED_AND_FOUND,
-    PST_SEARCHED_AND_NOT_FOUND
-  };
-
-/* Specify whether a partial psymbol should be allocated on the global
-   list or the static list.  */
-
-enum class psymbol_placement
-{
-  STATIC,
-  GLOBAL
-};
-
-/* 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.  */
-
-struct partial_symtab
-{
-  /* Allocate a new partial symbol table.
-
-     FILENAME (which must be non-NULL) is the filename of this partial
-     symbol table; it is copied into the appropriate storage.  The
-     partial symtab will also be installed using
-     psymtab_storage::install.  */
-
-  partial_symtab (const char *filename,
-		  psymtab_storage *partial_symtabs,
-		  objfile_per_bfd_storage *objfile_per_bfd)
-    ATTRIBUTE_NONNULL (2) ATTRIBUTE_NONNULL (3);
-
-  /* Like the above, but also sets the initial text low and text high
-     from the ADDR argument, and sets the global- and
-     static-offsets.  */
-
-  partial_symtab (const char *filename,
-		  psymtab_storage *partial_symtabs,
-		  objfile_per_bfd_storage *objfile_per_bfd,
-		  unrelocated_addr addr)
-    ATTRIBUTE_NONNULL (2) ATTRIBUTE_NONNULL (3);
-
-  virtual ~partial_symtab ()
-  {
-  }
-
-  /* Psymtab expansion is done in two steps:
-     - a call to read_symtab
-     - while that call is in progress, calls to expand_psymtab can be made,
-       both for this psymtab, and its dependencies.
-     This makes a distinction between a toplevel psymtab (for which both
-     read_symtab and expand_psymtab will be called) and a non-toplevel
-     psymtab (for which only expand_psymtab will be called). The
-     distinction can be used f.i. to do things before and after all
-     dependencies of a top-level psymtab have been expanded.
-
-     Read the full symbol table corresponding to this partial symbol
-     table.  Typically calls expand_psymtab.  */
-  virtual void read_symtab (struct objfile *) = 0;
-
-  /* Expand the full symbol table for this partial symbol table.  Typically
-     calls expand_dependencies.  */
-  virtual void expand_psymtab (struct objfile *) = 0;
-
-  /* Ensure that all the dependencies are read in.  Calls
-     expand_psymtab for each non-shared dependency.  */
-  void expand_dependencies (struct objfile *);
-
-  /* Return true if the symtab corresponding to this psymtab has been
-     read in in the context of this objfile.  */
-  virtual bool readin_p (struct objfile *) const = 0;
-
-  /* Return a pointer to the compunit allocated for this source file
-     in the context of this objfile.
-
-     Return nullptr if the compunit was not read in or if there was no
-     symtab.  */
-  virtual struct compunit_symtab *get_compunit_symtab
-    (struct objfile *) const = 0;
-
-  /* Return the unrelocated low text address of this
-     partial_symtab.  */
-  unrelocated_addr unrelocated_text_low () const
-  {
-    return m_text_low;
-  }
-
-  /* Return the unrelocated_addr high text address of this
-     partial_symtab.  */
-  unrelocated_addr unrelocated_text_high () const
-  {
-    return m_text_high;
-  }
-
-  /* Return the relocated low text address of this partial_symtab.  */
-  CORE_ADDR text_low (struct objfile *objfile) const
-  {
-    return CORE_ADDR (m_text_low) + objfile->text_section_offset ();
-  }
-
-  /* Return the relocated high text address of this partial_symtab.  */
-  CORE_ADDR text_high (struct objfile *objfile) const
-  {
-    return CORE_ADDR (m_text_high) + objfile->text_section_offset ();
-  }
-
-  /* Set the low text address of this partial_symtab.  */
-  void set_text_low (unrelocated_addr addr)
-  {
-    m_text_low = addr;
-    text_low_valid = 1;
-  }
-
-  /* Set the high text address of this partial_symtab.  */
-  void set_text_high (unrelocated_addr addr)
-  {
-    m_text_high = addr;
-    text_high_valid = 1;
-  }
-
-  /* Return true if this symtab is empty -- meaning that it contains
-     no symbols.  It may still have dependencies.  */
-  bool empty () const
-  {
-    return global_psymbols.empty () && static_psymbols.empty ();
-  }
-
-  /* Add a symbol to this partial symbol table of OBJFILE.
-
-     If COPY_NAME is true, make a copy of NAME, otherwise use the passed
-     reference.
-
-     LOC_CLASS is the type of symbol.
-
-     SECTION is the index of the section of OBJFILE in which the symbol is found.
-
-     WHERE determines whether the symbol goes in the list of static or global
-     partial symbols.
-
-     COREADDR is the address of the symbol.  For partial symbols that don't have
-     an address, zero is passed.
-
-     LANGUAGE is the language from which the symbol originates.  This will
-     influence, amongst other things, how the symbol name is demangled. */
-
-  void add_psymbol (std::string_view name,
-		    bool copy_name, domain_enum domain,
-		    location_class loc_class,
-		    int section,
-		    psymbol_placement where,
-		    unrelocated_addr coreaddr,
-		    enum language language,
-		    psymtab_storage *partial_symtabs,
-		    struct objfile *objfile);
-
-  /* Add a symbol to this partial symbol table of OBJFILE.  The psymbol
-     must be fully constructed, and the names must be set and intern'd
-     as appropriate.  */
-
-  void add_psymbol (const partial_symbol &psym,
-		    psymbol_placement where,
-		    psymtab_storage *partial_symtabs,
-		    struct objfile *objfile);
-
-
-  /* Indicate that this partial symtab is complete.  */
-
-  void end ();
-
-  /* Chain of all existing partial symtabs.  */
-
-  struct partial_symtab *next = nullptr;
-
-  /* Name of the source file which this partial_symtab defines,
-     or if the psymtab is anonymous then a descriptive name for
-     debugging purposes, or "".  It must not be NULL.  */
-
-  const char *filename = nullptr;
-
-  /* Full path of the source file.  NULL if not known.  */
-
-  char *fullname = nullptr;
-
-  /* Directory in which it was compiled, or NULL if we don't know.  */
-
-  const char *dirname = nullptr;
-
-  /* Range of text addresses covered by this file; texthigh is the
-     beginning of the next section.  Do not refer directly to these
-     fields.  Instead, use the accessors.  The validity of these
-     fields is determined by the text_low_valid and text_high_valid
-     fields; these are located later in this structure for better
-     packing.  */
-
-  unrelocated_addr m_text_low {};
-  unrelocated_addr m_text_high {};
-
-  /* If NULL, this is an ordinary partial symbol table.
-
-     If non-NULL, this holds a single includer of this partial symbol
-     table, and this partial symbol table is a shared one.
-
-     A shared psymtab is one that is referenced by multiple other
-     psymtabs, and which conceptually has its contents directly
-     included in those.
-
-     Shared psymtabs have special semantics.  When a search finds a
-     symbol in a shared table, we instead return one of the non-shared
-     tables that include this one.
-
-     A shared psymtabs can be referred to by other shared ones.
-
-     The psymtabs that refer to a shared psymtab will list the shared
-     psymtab in their 'dependencies' array.
-
-     In DWARF terms, a shared psymtab is a DW_TAG_partial_unit; but
-     of course using a name based on that would be too confusing, so
-     "shared" was chosen instead.
-
-     Only a single user is needed because, when expanding a shared
-     psymtab, we only need to expand its "canonical" non-shared user.
-     The choice of which one should be canonical is left to the
-     debuginfo reader; it can be arbitrary.  */
-
-  struct partial_symtab *user = nullptr;
-
-  /* Array of pointers to all of the partial_symtab's which this one
-     depends on.  Since this array can only be set to previous or
-     the current (?) psymtab, this dependency tree is guaranteed not
-     to have any loops.  "depends on" means that symbols must be read
-     for the dependencies before being read for this psymtab; this is
-     for type references in stabs, where if foo.c includes foo.h, declarations
-     in foo.h may use type numbers defined in foo.c.  For other debugging
-     formats there may be no need to use dependencies.  */
-
-  struct partial_symtab **dependencies = nullptr;
-
-  int number_of_dependencies = 0;
-
-  /* Global symbol list.  This list will be sorted after readin to
-     improve access.  Binary search will be the usual method of
-     finding a symbol within it.  */
-
-  std::vector<const partial_symbol *> global_psymbols;
-
-  /* Static symbol list.  This list will *not* be sorted after readin;
-     to find a symbol in it, exhaustive search must be used.  This is
-     reasonable because searches through this list will eventually
-     lead to either the read in of a files symbols for real (assumed
-     to take a *lot* of time; check) or an error (and we don't care
-     how long errors take).  */
-
-  std::vector<const partial_symbol *> static_psymbols;
-
-  /* True if the name of this partial symtab is not a source file name.  */
-
-  bool anonymous = false;
-
-  /* A flag that is temporarily used when searching psymtabs.  */
-
-  ENUM_BITFIELD (psymtab_search_status) searched_flag : 2;
-
-  /* Validity of the m_text_low and m_text_high fields.  */
-
-  unsigned int text_low_valid : 1;
-  unsigned int text_high_valid : 1;
-};
-
-/* A partial symtab that tracks the "readin" and "compunit_symtab"
-   information in the ordinary way -- by storing it directly in this
-   object.  */
-struct standard_psymtab : public partial_symtab
-{
-  standard_psymtab (const char *filename,
-		    psymtab_storage *partial_symtabs,
-		    objfile_per_bfd_storage *objfile_per_bfd)
-    : partial_symtab (filename, partial_symtabs, objfile_per_bfd)
-  {
-  }
-
-  standard_psymtab (const char *filename,
-		    psymtab_storage *partial_symtabs,
-		    objfile_per_bfd_storage *objfile_per_bfd,
-		    unrelocated_addr addr)
-    : partial_symtab (filename, partial_symtabs, objfile_per_bfd, addr)
-  {
-  }
-
-  bool readin_p (struct objfile *) const override
-  {
-    return readin;
-  }
-
-  struct compunit_symtab *get_compunit_symtab (struct objfile *) const override
-  {
-    return compunit_symtab;
-  }
-
-  /* True if the symtab corresponding to this psymtab has been
-     readin.  */
-
-  bool readin = false;
-
-  /* Pointer to compunit eventually allocated for this source file, 0 if
-     !readin or if we haven't looked for the symtab after it was readin.  */
-
-  struct compunit_symtab *compunit_symtab = nullptr;
-};
-
-/* A partial_symtab that works in the historical db way.  This should
-   not be used in new code, but exists to transition the somewhat
-   unmaintained "legacy" debug formats.  */
-
-struct legacy_psymtab : public standard_psymtab
-{
-  legacy_psymtab (const char *filename,
-		  psymtab_storage *partial_symtabs,
-		  objfile_per_bfd_storage *objfile_per_bfd)
-    : standard_psymtab (filename, partial_symtabs, objfile_per_bfd)
-  {
-  }
-
-  legacy_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 *objf) override
-  {
-    if (legacy_read_symtab)
-      (*legacy_read_symtab) (this, objf);
-  }
-
-  void expand_psymtab (struct objfile *objf) override
-  {
-    (*legacy_expand_psymtab) (this, objf);
-  }
-
-  /* Pointer to function which will read in the symtab corresponding to
-     this psymtab.  */
-
-  void (*legacy_read_symtab) (legacy_psymtab *, struct objfile *) = nullptr;
-
-  /* Pointer to function which will actually expand this psymtab into
-     a full symtab.  */
-
-  void (*legacy_expand_psymtab) (legacy_psymtab *, struct objfile *) = nullptr;
-
-  /* Information that lets read_symtab() locate the part of the symbol table
-     that this psymtab corresponds to.  This information is private to the
-     format-dependent symbol reading routines.  For further detail examine
-     the various symbol reading modules.  */
-
-  void *read_symtab_private = nullptr;
-};
-
-/* Used when recording partial symbol tables.  On destruction,
-   discards any partial symbol tables that have been built.  However,
-   the tables can be kept by calling the "keep" method.  */
-class psymtab_discarder
-{
- public:
-
-  psymtab_discarder (psymtab_storage *partial_symtabs)
-    : m_partial_symtabs (partial_symtabs),
-      m_psymtab (partial_symtabs->psymtabs)
-  {
-  }
-
-  ~psymtab_discarder ()
-  {
-    if (m_partial_symtabs != nullptr)
-      m_partial_symtabs->discard_psymtabs_to (m_psymtab);
-  }
-
-  /* Keep any partial symbol tables that were built.  */
-  void keep ()
-  {
-    m_partial_symtabs = nullptr;
-  }
-
- private:
-
-  /* The partial symbol storage object.  */
-  psymtab_storage *m_partial_symtabs;
-  /* How far back to free.  */
-  struct partial_symtab *m_psymtab;
-};
-
-/* An implementation of quick_symbol_functions, specialized for
-   partial symbols.  */
-struct psymbol_functions : public quick_symbol_functions
-{
-  explicit psymbol_functions (const std::shared_ptr<psymtab_storage> &storage)
-    : m_partial_symtabs (storage)
-  {
-  }
-
-  psymbol_functions ()
-    : m_partial_symtabs (new psymtab_storage)
-  {
-  }
-
-  bool has_symbols (struct objfile *objfile) override;
-
-  bool has_unexpanded_symtabs (struct objfile *objfile) override;
-
-  struct symtab *find_last_source_symtab (struct objfile *objfile) override;
-
-  void forget_cached_source_info (struct objfile *objfile) override;
-
-  enum language lookup_global_symbol_language (struct objfile *objfile,
-					       const char *name,
-					       domain_search_flags domain,
-					       bool *symbol_found_p) override;
-
-  void print_stats (struct objfile *objfile, bool print_bcache) override;
-
-  void dump (struct objfile *objfile) override;
-
-  void expand_all_symtabs (struct objfile *objfile) override;
-
-  bool search
-    (struct objfile *objfile,
-     search_symtabs_file_matcher file_matcher,
-     const lookup_name_info *lookup_name,
-     search_symtabs_symbol_matcher symbol_matcher,
-     search_symtabs_expansion_listener listener,
-     block_search_flags search_flags,
-     domain_search_flags kind,
-     search_symtabs_lang_matcher lang_matcher) override;
-
-  struct compunit_symtab *find_pc_sect_compunit_symtab
-    (struct objfile *objfile, bound_minimal_symbol msymbol, CORE_ADDR pc,
-     struct obj_section *section, int warn_if_readin) override;
-
-  struct symbol *find_symbol_by_address
-    (struct objfile *objfile, CORE_ADDR address) override
-  {
-    return nullptr;
-  }
-
-  void map_symbol_filenames (objfile *objfile, symbol_filename_listener fun,
-			     bool need_fullname) override;
-
-  /* Return a range adapter for the psymtabs.  */
-  psymtab_storage::partial_symtab_range partial_symbols
-       (struct objfile *objfile);
-
-  /* Return the partial symbol storage associated with this
-     object.  */
-  const std::shared_ptr<psymtab_storage> &get_partial_symtabs () const
-  {
-    return m_partial_symtabs;
-  }
-
-  /* Replace the partial symbol table storage in this object with
-     SYMS.  */
-  void set_partial_symtabs (const std::shared_ptr<psymtab_storage> &syms)
-  {
-    m_partial_symtabs = syms;
-  }
-
-  /* Find which partial symtab contains PC and SECTION.  Return NULL if
-     none.  We return the psymtab that contains a symbol whose address
-     exactly matches PC, or, if we cannot find an exact match, the
-     psymtab that contains a symbol whose address is closest to PC.  */
-
-  struct partial_symtab *find_pc_sect_psymtab (struct objfile *objfile,
-					       CORE_ADDR pc,
-					       struct obj_section *section,
-					       bound_minimal_symbol msymbol);
-
-private:
-
-  /* Count the number of partial symbols in *THIS.  */
-  int count_psyms ();
-
-  /* Storage for the partial symbols.  */
-  std::shared_ptr<psymtab_storage> m_partial_symtabs;
-};
-
-#endif /* GDB_PSYMTAB_H */
-- 
2.52.0


^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [RFC PATCH 1/8] gdb/ctf: add debug logging in ctfread.c
  2026-02-03  6:45 ` [RFC PATCH 1/8] gdb/ctf: add debug logging in ctfread.c simon.marchi
@ 2026-02-03 12:40   ` Eli Zaretskii
  2026-02-03 16:21     ` Simon Marchi
  0 siblings, 1 reply; 52+ messages in thread
From: Eli Zaretskii @ 2026-02-03 12:40 UTC (permalink / raw)
  To: simon.marchi; +Cc: gdb-patches, nick.alcock, weimin.pan

> From: simon.marchi@polymtl.ca
> Cc: Nick Alcock <nick.alcock@oracle.com>, Weimin Pan <weimin.pan@oracle.com>, 
>  Simon Marchi <simon.marchi@polymtl.ca>
> Date: Tue,  3 Feb 2026 01:45:42 -0500
> 
> From: Simon Marchi <simon.marchi@polymtl.ca>
> 
> Add some debug statements, to be able to visualize what is happening
> when loading CTF debug info.  Add a new "set debug ctf" command, with
> the usual logging macros.
> 
> Here's an example of the result, when reading the binary from test
> gdb.ctf/cruss-tu-cyclic:
> 
>     [ctf] elfctf_build_psymtabs: start: building psymtabs for /home/simark/build/binutils-gdb/gdb/testsuite/outputs/gdb.ctf/cross-tu-cyclic/cross-tu-cyclic
>       [ctf] scan_partial_symbols: start: fname='.ctf'
>         [ctf] scan_partial_symbols: is parent, using fname='/home/simark/build/binutils-gdb/gdb/testsuite/outputs/gdb.ctf/cross-tu-cyclic/cross-tu-cyclic'
>         [ctf] ctf_psymtab_type_cb: adding type tid=0x1 kind=INTEGER name='int'
>         [ctf] ctf_psymtab_type_cb: adding type tid=0x2 kind=INTEGER name='long int'
>         [ctf] ctf_psymtab_type_cb: adding type tid=0x3 kind=FORWARD name='B'
>         [ctf] ctf_psymtab_type_cb: adding type tid=0x5 kind=FORWARD name='A'
>         [ctf] ctf_psymtab_type_cb: adding type tid=0x8 kind=STRUCT name='C'
>         [ctf] ctf_psymtab_add_stt_entries: adding function psym 'main' tid=0x7 kind=FUNCTION
>       [ctf] scan_partial_symbols: end: fname='.ctf'
>       [ctf] scan_partial_symbols: start: fname='/home/simark/src/binutils-gdb/gdb/testsuite/gdb.ctf/cross-tu-cyclic-1.c'
>         [ctf] ctf_psymtab_type_cb: adding type tid=0x80000001 kind=STRUCT name='B'
>         [ctf] ctf_psymtab_type_cb: adding type tid=0x80000002 kind=STRUCT name='A'
>       [ctf] scan_partial_symbols: end: fname='/home/simark/src/binutils-gdb/gdb/testsuite/gdb.ctf/cross-tu-cyclic-1.c'
>       [ctf] scan_partial_symbols: start: fname='/home/simark/src/binutils-gdb/gdb/testsuite/gdb.ctf/cross-tu-cyclic-2.c'
>         [ctf] ctf_psymtab_type_cb: adding type tid=0x80000001 kind=STRUCT name='A'
>       [ctf] scan_partial_symbols: end: fname='/home/simark/src/binutils-gdb/gdb/testsuite/gdb.ctf/cross-tu-cyclic-2.c'
>       [ctf] scan_partial_symbols: start: fname='/home/simark/src/binutils-gdb/gdb/testsuite/gdb.ctf/cross-tu-cyclic-3.c'
>         [ctf] ctf_psymtab_type_cb: adding type tid=0x80000001 kind=STRUCT name='A'
>       [ctf] scan_partial_symbols: end: fname='/home/simark/src/binutils-gdb/gdb/testsuite/gdb.ctf/cross-tu-cyclic-3.c'
>       [ctf] scan_partial_symbols: start: fname='/home/simark/src/binutils-gdb/gdb/testsuite/gdb.ctf/cross-tu-cyclic-4.c'
>         [ctf] ctf_psymtab_type_cb: adding type tid=0x80000001 kind=STRUCT name='A'
>         [ctf] ctf_psymtab_type_cb: adding type tid=0x80000002 kind=STRUCT name='B'
>       [ctf] scan_partial_symbols: end: fname='/home/simark/src/binutils-gdb/gdb/testsuite/gdb.ctf/cross-tu-cyclic-4.c'
>     [ctf] elfctf_build_psymtabs: end: building psymtabs for /home/simark/build/binutils-gdb/gdb/testsuite/outputs/gdb.ctf/cross-tu-cyclic/cross-tu-cyclic
> 
> Change-Id: If3800d14dd965ccefa67a24ef5c4481aef70ffa4
> ---
>  gdb/NEWS            |  4 ++
>  gdb/ctfread.c       | 95 ++++++++++++++++++++++++++++++++++++++++++++-
>  gdb/doc/gdb.texinfo |  7 ++++
>  3 files changed, 104 insertions(+), 2 deletions(-)

Thanks.

> diff --git a/gdb/NEWS b/gdb/NEWS
> index fa6e7ca61219..af04fa1e67ae 100644
> --- a/gdb/NEWS
> +++ b/gdb/NEWS
> @@ -91,6 +91,10 @@ show progress-bars enabled
>    content, to be disabled (the set command), or to see if
>    progress-bars are currently enabled or not (the show command).
>  
> +set debug ctf on|off
> +show debug ctf
> +  Print debug messages about CTF reading.
> +
>  * Changed commands

This part is okay.

> +@item set debug ctf
> +@cindex CTF debug messages
> +Turns on or off display of debugging messages related to reading CTF

Please always put the indexing commands _before_ the @item line to
which they refer.  This way, following the index entry in the Info
reader will place the cursor on the @item line, not after it.

Reviewed-By: Eli Zaretskii <eliz@gnu.org>

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [RFC PATCH 1/8] gdb/ctf: add debug logging in ctfread.c
  2026-02-03 12:40   ` Eli Zaretskii
@ 2026-02-03 16:21     ` Simon Marchi
  2026-02-03 16:37       ` Eli Zaretskii
  0 siblings, 1 reply; 52+ messages in thread
From: Simon Marchi @ 2026-02-03 16:21 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: gdb-patches, nick.alcock, weimin.pan

>> diff --git a/gdb/NEWS b/gdb/NEWS
>> index fa6e7ca61219..af04fa1e67ae 100644
>> --- a/gdb/NEWS
>> +++ b/gdb/NEWS
>> @@ -91,6 +91,10 @@ show progress-bars enabled
>>    content, to be disabled (the set command), or to see if
>>    progress-bars are currently enabled or not (the show command).
>>  
>> +set debug ctf on|off
>> +show debug ctf
>> +  Print debug messages about CTF reading.
>> +
>>  * Changed commands
> 
> This part is okay.
> 
>> +@item set debug ctf
>> +@cindex CTF debug messages
>> +Turns on or off display of debugging messages related to reading CTF
> 
> Please always put the indexing commands _before_ the @item line to
> which they refer.  This way, following the index entry in the Info
> reader will place the cursor on the @item line, not after it.
> 
> Reviewed-By: Eli Zaretskii <eliz@gnu.org>

Thanks for the review.

I will make that change and apply your Reviewed-By.  This patch will
likely be re-sent as part of a non-RFC series.

Btw, I just copy pasted the doc for some other "set debug" command.  It
seems like there are a lot where the @cindex follows the @item.  Would
you like me to fix those?

Simon

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [RFC PATCH 1/8] gdb/ctf: add debug logging in ctfread.c
  2026-02-03 16:21     ` Simon Marchi
@ 2026-02-03 16:37       ` Eli Zaretskii
  2026-02-03 20:39         ` Simon Marchi
  0 siblings, 1 reply; 52+ messages in thread
From: Eli Zaretskii @ 2026-02-03 16:37 UTC (permalink / raw)
  To: Simon Marchi; +Cc: gdb-patches, nick.alcock, weimin.pan

> Date: Tue, 3 Feb 2026 11:21:50 -0500
> Cc: gdb-patches@sourceware.org, nick.alcock@oracle.com, weimin.pan@oracle.com
> From: Simon Marchi <simon.marchi@polymtl.ca>
> 
> Btw, I just copy pasted the doc for some other "set debug" command.  It
> seems like there are a lot where the @cindex follows the @item.  Would
> you like me to fix those?

Yes, please.  They are all mistakes.

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [RFC PATCH 1/8] gdb/ctf: add debug logging in ctfread.c
  2026-02-03 16:37       ` Eli Zaretskii
@ 2026-02-03 20:39         ` Simon Marchi
  0 siblings, 0 replies; 52+ messages in thread
From: Simon Marchi @ 2026-02-03 20:39 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: gdb-patches, nick.alcock, weimin.pan



On 2026-02-03 11:37, Eli Zaretskii wrote:
>> Date: Tue, 3 Feb 2026 11:21:50 -0500
>> Cc: gdb-patches@sourceware.org, nick.alcock@oracle.com, weimin.pan@oracle.com
>> From: Simon Marchi <simon.marchi@polymtl.ca>
>>
>> Btw, I just copy pasted the doc for some other "set debug" command.  It
>> seems like there are a lot where the @cindex follows the @item.  Would
>> you like me to fix those?
> 
> Yes, please.  They are all mistakes.

Ok, and just to make sure I am headed in the right direction, would
these changes be good?  This rule applies to all the @*index commands,
such as @findex?

diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index d39fa02b7119..5e27d52e1d26 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -982,48 +982,48 @@ than @samp{-}, though we illustrate the more usual convention.)
 @c it.
 
 @table @code
-@item -symbols @var{file}
-@itemx -s @var{file}
 @cindex @code{--symbols}
 @cindex @code{-s}
+@item -symbols @var{file}
+@itemx -s @var{file}
 Read symbol table from file @var{file}.
 
-@item -exec @var{file}
-@itemx -e @var{file}
 @cindex @code{--exec}
 @cindex @code{-e}
+@item -exec @var{file}
+@itemx -e @var{file}
 Use file @var{file} as the executable file to execute when appropriate,
 and for examining pure data in conjunction with a core dump.
 
-@item -se @var{file}
 @cindex @code{--se}
+@item -se @var{file}
 Read symbol table from file @var{file} and use it as the executable
 file.
 
-@item -core @var{file}
-@itemx -c @var{file}
 @cindex @code{--core}
 @cindex @code{-c}
+@item -core @var{file}
+@itemx -c @var{file}
 Use file @var{file} as a core dump to examine.
 
-@item -pid @var{number}
-@itemx -p @var{number}
 @cindex @code{--pid}
 @cindex @code{-p}
+@item -pid @var{number}
+@itemx -p @var{number}
 Connect to process ID @var{number}, as with the @code{attach} command.
 
Simon

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [RFC PATCH 4/8] gdb/ctf: use ctf_per_objfile in ctf_archive_iter_psymtab_data and ctf_context
  2026-02-03  6:45 ` [RFC PATCH 4/8] gdb/ctf: use ctf_per_objfile in ctf_archive_iter_psymtab_data and ctf_context simon.marchi
@ 2026-02-12 17:44   ` Tom Tromey
  2026-02-12 18:35     ` Simon Marchi
  0 siblings, 1 reply; 52+ messages in thread
From: Tom Tromey @ 2026-02-12 17:44 UTC (permalink / raw)
  To: simon.marchi; +Cc: gdb-patches, Nick Alcock, Weimin Pan

>>>>> "Simon" == simon marchi <simon.marchi@polymtl.ca> writes:

Simon> -  explicit ctf_per_objfile (ctf_archive_up archive, ctf_dict_up dict)
Simon> -    : archive (std::move (archive)),
Simon> +  explicit ctf_per_objfile (struct objfile *objfile, ctf_archive_up archive,
Simon> +			    ctf_dict_up dict)

I think we only really need explicit for single-argument constructors.

Tom

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [RFC PATCH 5/8] gdb/ctf: check return value of ctf_type_align
  2026-02-03  6:45 ` [RFC PATCH 5/8] gdb/ctf: check return value of ctf_type_align simon.marchi
@ 2026-02-12 17:49   ` Tom Tromey
  2026-02-12 18:37     ` Simon Marchi
  0 siblings, 1 reply; 52+ messages in thread
From: Tom Tromey @ 2026-02-12 17:49 UTC (permalink / raw)
  To: simon.marchi; +Cc: gdb-patches, Nick Alcock, Weimin Pan

>>>>> "Simon" == simon marchi <simon.marchi@polymtl.ca> writes:

Simon> With this patch, if I enable the complaints, I see a bunch of messages
Simon> like this:

Simon>     During symbol reading: ctf_type_align read_structure_type failed - Type is not a complete type.

I just wanted to rant a little about complaints.  You can leave these in
if you want, but IME complaints are useless.  I don't think we've ever
seen anyone fix a compiler bug on the basis of a complaint being issued.
And, I also don't recall ever debugging some user problem by enabling
complaints -- if a bug gets to that point, I'm invariably debugging the
reader.

That is, they're just noise.

Now, it might still be good to have a checker for DWARF and presumably
for CTF.  But IMO that should be a separate tool.  And for CTF it
doesn't even seem hard to do, given that these errors are coming
straight from it.

thanks for listening,
Tom

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [RFC PATCH 7/8] gdb/ctf: don't use psymtabs, create symtabs directly
  2026-02-03  6:45 ` [RFC PATCH 7/8] gdb/ctf: don't use psymtabs, create symtabs directly simon.marchi
@ 2026-02-12 17:54   ` Tom Tromey
  0 siblings, 0 replies; 52+ messages in thread
From: Tom Tromey @ 2026-02-12 17:54 UTC (permalink / raw)
  To: simon.marchi; +Cc: gdb-patches, Nick Alcock, Weimin Pan

>>>>> "Simon" == simon marchi <simon.marchi@polymtl.ca> writes:

Simon>  - make the CTF reader skip partial symtabs, create full symtabs
Simon>    directly

Simon> My hypothesis is that CTF debug info is typically small enough and fast
Simon> enough to process that it's not worth it to bother with an intermediate
Simon> step before full symbols.

Makes sense to me, if accurate.

Simon> GDB is still able to load the resulting ELF, and there are about 150k
Simon> calls to ctf_add_type_cb.  Before this patch, elfctf_build_psymtabs
Simon> takes anywhere between 300-350 ms.  With this patch, it's around 400 ms.

This seems completely reasonable to me.

Also, the "quick" API isn't really all that large.  So if this turns out
to be slow and CTF wants something fancy -- like lazy type instantiation
-- then that also seems like something that can be done at a later date.

Tom

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [RFC PATCH 0/8] Make CTF reader build full symtabs, get rid of psymtab
  2026-02-03  6:45 [RFC PATCH 0/8] Make CTF reader build full symtabs, get rid of psymtab simon.marchi
                   ` (7 preceding siblings ...)
  2026-02-03  6:45 ` [RFC PATCH 8/8] gdb: remove psymtab.{c,h} simon.marchi
@ 2026-02-12 17:58 ` Tom Tromey
  2026-02-12 18:47   ` Simon Marchi
  2026-02-17 19:50 ` [PATCH v2 0/9] " simon.marchi
  9 siblings, 1 reply; 52+ messages in thread
From: Tom Tromey @ 2026-02-12 17:58 UTC (permalink / raw)
  To: simon.marchi; +Cc: gdb-patches, Nick Alcock, Weimin Pan

Simon> This is an RFC, because I would like to collect comments (especially
Simon> from the CTF experts) on whether the startup time remains acceptable,
Simon> even for large programs.

I'm not a CTF expert but I read through the patches and it seems
basically fine to me.

Simon> I also think that my use of
Simon> expanded_symbols_functions in the last patch is not quite right, I'll
Simon> need to look into that further.

We've since discussed this in a different thread, where we contemplated
putting the compunit_symtabs elsewhere.

The "bad" scenarios (which I think are just performance and not
correctness -related) only seem possible if "always-read-ctf" is set.
Which presumably few people really do.

Tom

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [RFC PATCH 4/8] gdb/ctf: use ctf_per_objfile in ctf_archive_iter_psymtab_data and ctf_context
  2026-02-12 17:44   ` Tom Tromey
@ 2026-02-12 18:35     ` Simon Marchi
  0 siblings, 0 replies; 52+ messages in thread
From: Simon Marchi @ 2026-02-12 18:35 UTC (permalink / raw)
  To: Tom Tromey; +Cc: gdb-patches, Nick Alcock, Weimin Pan

On 2/12/26 12:44 PM, Tom Tromey wrote:
>>>>>> "Simon" == simon marchi <simon.marchi@polymtl.ca> writes:
> 
> Simon> -  explicit ctf_per_objfile (ctf_archive_up archive, ctf_dict_up dict)
> Simon> -    : archive (std::move (archive)),
> Simon> +  explicit ctf_per_objfile (struct objfile *objfile, ctf_archive_up archive,
> Simon> +			    ctf_dict_up dict)
> 
> I think we only really need explicit for single-argument constructors.
> 
> Tom

Ack, removed.

Simon

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [RFC PATCH 5/8] gdb/ctf: check return value of ctf_type_align
  2026-02-12 17:49   ` Tom Tromey
@ 2026-02-12 18:37     ` Simon Marchi
  0 siblings, 0 replies; 52+ messages in thread
From: Simon Marchi @ 2026-02-12 18:37 UTC (permalink / raw)
  To: Tom Tromey; +Cc: gdb-patches, Nick Alcock, Weimin Pan

On 2/12/26 12:49 PM, Tom Tromey wrote:
>>>>>> "Simon" == simon marchi <simon.marchi@polymtl.ca> writes:
> 
> Simon> With this patch, if I enable the complaints, I see a bunch of messages
> Simon> like this:
> 
> Simon>     During symbol reading: ctf_type_align read_structure_type failed - Type is not a complete type.
> 
> I just wanted to rant a little about complaints.  You can leave these in
> if you want, but IME complaints are useless.  I don't think we've ever
> seen anyone fix a compiler bug on the basis of a complaint being issued.
> And, I also don't recall ever debugging some user problem by enabling
> complaints -- if a bug gets to that point, I'm invariably debugging the
> reader.
> 
> That is, they're just noise.
> 
> Now, it might still be good to have a checker for DWARF and presumably
> for CTF.  But IMO that should be a separate tool.  And for CTF it
> doesn't even seem hard to do, given that these errors are coming
> straight from it.
> 
> thanks for listening,
> Tom

Thank you for you TED talk.  I agree that I have never used complaints
myself.  If I had infinite time, I would report bugs to compilers about
them, but I don't have that luxury.

I don't mind removing complaints, but I would still keep the messages as
logging statements (*_debug_printf), to at least be able to have a trace
of what GDB is doing.

Simon

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [RFC PATCH 0/8] Make CTF reader build full symtabs, get rid of psymtab
  2026-02-12 17:58 ` [RFC PATCH 0/8] Make CTF reader build full symtabs, get rid of psymtab Tom Tromey
@ 2026-02-12 18:47   ` Simon Marchi
  0 siblings, 0 replies; 52+ messages in thread
From: Simon Marchi @ 2026-02-12 18:47 UTC (permalink / raw)
  To: Tom Tromey; +Cc: gdb-patches, Nick Alcock, Weimin Pan

On 2/12/26 12:58 PM, Tom Tromey wrote:
> Simon> This is an RFC, because I would like to collect comments (especially
> Simon> from the CTF experts) on whether the startup time remains acceptable,
> Simon> even for large programs.
> 
> I'm not a CTF expert but I read through the patches and it seems
> basically fine to me.
> 
> Simon> I also think that my use of
> Simon> expanded_symbols_functions in the last patch is not quite right, I'll
> Simon> need to look into that further.
> 
> We've since discussed this in a different thread, where we contemplated
> putting the compunit_symtabs elsewhere.

My plan is indeed to make expanded_symbols_functions to hold a list of
compunit symtabs to search.  You can have a sneak peek here if you want:

https://review.lttng.org/c/binutils-gdb/+/16557

This way, you can have two symbol providers using
expanded_symbols_functions (say, jit and ctf) that both push an
expanded_symbols_functions "quick" object.  Each object says which
compunit_symtabs to search.

> The "bad" scenarios (which I think are just performance and not
> correctness -related) only seem possible if "always-read-ctf" is set.
> Which presumably few people really do.

As I stated in that other message (I can't find it now), I think it might
have to do with correctness if we consider the ordering of the symbol
providers (quick symbol functions) represents the priority in the
search.  Having expanded_symbols_functions search all compunit_symtabs
would mess that up.

Simon

^ permalink raw reply	[flat|nested] 52+ messages in thread

* [PATCH v2 0/9] Make CTF reader build full symtabs, get rid of psymtab
  2026-02-03  6:45 [RFC PATCH 0/8] Make CTF reader build full symtabs, get rid of psymtab simon.marchi
                   ` (8 preceding siblings ...)
  2026-02-12 17:58 ` [RFC PATCH 0/8] Make CTF reader build full symtabs, get rid of psymtab Tom Tromey
@ 2026-02-17 19:50 ` simon.marchi
  2026-02-17 19:50   ` [PATCH v2 1/9] gdb/ctf: add debug logging in ctfread.c simon.marchi
                     ` (9 more replies)
  9 siblings, 10 replies; 52+ messages in thread
From: simon.marchi @ 2026-02-17 19:50 UTC (permalink / raw)
  To: gdb-patches; +Cc: Simon Marchi

From: Simon Marchi <simon.marchi@polymtl.ca>

v2 of:

https://inbox.sourceware.org/gdb-patches/20260203065435.3092465-1-simon.marchi@polymtl.ca/

The main change is the inclusion of patch "gdb: make
expanded_symbols_functions hold compunit symtabs", which makes
expanded_symbols_functions only search the list of compunit_symtabs it
is given.

Simon Marchi (9):
  gdb/ctf: add debug logging in ctfread.c
  gdb/ctf: add unique_ptr types
  gdb/ctf: editorial renames
  gdb/ctf: use ctf_per_objfile in ctf_archive_iter_psymtab_data and
    ctf_context
  gdb/ctf: check return value of ctf_type_align
  gdb/ctf: add scoped_time_it in elfctf_build_psymtabs
  gdb: make expanded_symbols_functions hold compunit symtabs
  gdb/ctf: don't use psymtabs, create symtabs directly
  gdb: remove psymtab.{c,h}

 gdb/Makefile.in       |    2 -
 gdb/NEWS              |    4 +
 gdb/ctfread.c         |  705 ++++++++----------
 gdb/ctfread.h         |    2 +-
 gdb/doc/gdb.texinfo   |    7 +
 gdb/elfread.c         |    8 +-
 gdb/expanded-symbol.c |   16 +-
 gdb/expanded-symbol.h |    8 +
 gdb/jit.c             |   16 +-
 gdb/psymtab.c         | 1575 -----------------------------------------
 gdb/psymtab.h         |  691 ------------------
 11 files changed, 321 insertions(+), 2713 deletions(-)
 delete mode 100644 gdb/psymtab.c
 delete mode 100644 gdb/psymtab.h


base-commit: 625b835f63153677bf614de266c7bc8963163ffc
-- 
2.53.0


^ permalink raw reply	[flat|nested] 52+ messages in thread

* [PATCH v2 1/9] gdb/ctf: add debug logging in ctfread.c
  2026-02-17 19:50 ` [PATCH v2 0/9] " simon.marchi
@ 2026-02-17 19:50   ` simon.marchi
  2026-02-17 19:50   ` [PATCH v2 2/9] gdb/ctf: add unique_ptr types simon.marchi
                     ` (8 subsequent siblings)
  9 siblings, 0 replies; 52+ messages in thread
From: simon.marchi @ 2026-02-17 19:50 UTC (permalink / raw)
  To: gdb-patches; +Cc: Simon Marchi, Eli Zaretskii

From: Simon Marchi <simon.marchi@polymtl.ca>

Add some debug statements, to be able to visualize what is happening
when loading CTF debug info.  Add a new "set debug ctf" command, with
the usual logging macros.

Here's an example of the result, when reading the binary from test
gdb.ctf/cruss-tu-cyclic:

    [ctf] elfctf_build_psymtabs: start: building psymtabs for /home/simark/build/binutils-gdb/gdb/testsuite/outputs/gdb.ctf/cross-tu-cyclic/cross-tu-cyclic
      [ctf] scan_partial_symbols: start: fname='.ctf'
        [ctf] scan_partial_symbols: is parent, using fname='/home/simark/build/binutils-gdb/gdb/testsuite/outputs/gdb.ctf/cross-tu-cyclic/cross-tu-cyclic'
        [ctf] ctf_psymtab_type_cb: adding type tid=0x1 kind=INTEGER name='int'
        [ctf] ctf_psymtab_type_cb: adding type tid=0x2 kind=INTEGER name='long int'
        [ctf] ctf_psymtab_type_cb: adding type tid=0x3 kind=FORWARD name='B'
        [ctf] ctf_psymtab_type_cb: adding type tid=0x5 kind=FORWARD name='A'
        [ctf] ctf_psymtab_type_cb: adding type tid=0x8 kind=STRUCT name='C'
        [ctf] ctf_psymtab_add_stt_entries: adding function psym 'main' tid=0x7 kind=FUNCTION
      [ctf] scan_partial_symbols: end: fname='.ctf'
      [ctf] scan_partial_symbols: start: fname='/home/simark/src/binutils-gdb/gdb/testsuite/gdb.ctf/cross-tu-cyclic-1.c'
        [ctf] ctf_psymtab_type_cb: adding type tid=0x80000001 kind=STRUCT name='B'
        [ctf] ctf_psymtab_type_cb: adding type tid=0x80000002 kind=STRUCT name='A'
      [ctf] scan_partial_symbols: end: fname='/home/simark/src/binutils-gdb/gdb/testsuite/gdb.ctf/cross-tu-cyclic-1.c'
      [ctf] scan_partial_symbols: start: fname='/home/simark/src/binutils-gdb/gdb/testsuite/gdb.ctf/cross-tu-cyclic-2.c'
        [ctf] ctf_psymtab_type_cb: adding type tid=0x80000001 kind=STRUCT name='A'
      [ctf] scan_partial_symbols: end: fname='/home/simark/src/binutils-gdb/gdb/testsuite/gdb.ctf/cross-tu-cyclic-2.c'
      [ctf] scan_partial_symbols: start: fname='/home/simark/src/binutils-gdb/gdb/testsuite/gdb.ctf/cross-tu-cyclic-3.c'
        [ctf] ctf_psymtab_type_cb: adding type tid=0x80000001 kind=STRUCT name='A'
      [ctf] scan_partial_symbols: end: fname='/home/simark/src/binutils-gdb/gdb/testsuite/gdb.ctf/cross-tu-cyclic-3.c'
      [ctf] scan_partial_symbols: start: fname='/home/simark/src/binutils-gdb/gdb/testsuite/gdb.ctf/cross-tu-cyclic-4.c'
        [ctf] ctf_psymtab_type_cb: adding type tid=0x80000001 kind=STRUCT name='A'
        [ctf] ctf_psymtab_type_cb: adding type tid=0x80000002 kind=STRUCT name='B'
      [ctf] scan_partial_symbols: end: fname='/home/simark/src/binutils-gdb/gdb/testsuite/gdb.ctf/cross-tu-cyclic-4.c'
    [ctf] elfctf_build_psymtabs: end: building psymtabs for /home/simark/build/binutils-gdb/gdb/testsuite/outputs/gdb.ctf/cross-tu-cyclic/cross-tu-cyclic

Change-Id: If3800d14dd965ccefa67a24ef5c4481aef70ffa4
Reviewed-By: Eli Zaretskii <eliz@gnu.org>
---
 gdb/NEWS            |  4 ++
 gdb/ctfread.c       | 95 ++++++++++++++++++++++++++++++++++++++++++++-
 gdb/doc/gdb.texinfo |  7 ++++
 3 files changed, 104 insertions(+), 2 deletions(-)

diff --git a/gdb/NEWS b/gdb/NEWS
index 1957e63eae44..7e5594bd81cc 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -89,6 +89,10 @@ set debug gnu-ifunc on|off
 show debug gnu-ifunc
   Turn on or off debug messages related to GNU ifunc resolution.
 
+set debug ctf on|off
+show debug ctf
+  Turn on or off debug messages about CTF reading.
+
 set progress-bars enabled on|off
 show progress-bars enabled
   Allows the progress bars, used when debuginfod is downloading
diff --git a/gdb/ctfread.c b/gdb/ctfread.c
index e24d0ef60d02..141f51f621b0 100644
--- a/gdb/ctfread.c
+++ b/gdb/ctfread.c
@@ -80,12 +80,49 @@
 #include "block.h"
 #include "ctfread.h"
 #include "psymtab.h"
+#include "cli/cli-cmds.h"
+
+/* When true, print debug messages related to CTF reading.  */
+static bool debug_ctf = false;
+
+/* Print a "ctf" debug statement.  */
+
+#define ctf_debug_printf(fmt, ...) \
+  debug_prefixed_printf_cond (debug_ctf, "ctf", fmt, ##__VA_ARGS__)
+
+#define CTF_SCOPED_DEBUG_START_END(fmt, ...) \
+  scoped_debug_start_end (debug_ctf, "ctf", fmt, ##__VA_ARGS__)
 
 #if ENABLE_LIBCTF
 
 #include "ctf.h"
 #include "ctf-api.h"
 
+/* Return a string representation of a CTF type kind.  */
+
+static const char *
+ctf_kind_str (uint32_t kind)
+{
+  switch (kind)
+    {
+    case CTF_K_UNKNOWN: return "UNKNOWN";
+    case CTF_K_INTEGER: return "INTEGER";
+    case CTF_K_FLOAT: return "FLOAT";
+    case CTF_K_POINTER: return "POINTER";
+    case CTF_K_ARRAY: return "ARRAY";
+    case CTF_K_FUNCTION: return "FUNCTION";
+    case CTF_K_STRUCT: return "STRUCT";
+    case CTF_K_UNION: return "UNION";
+    case CTF_K_ENUM: return "ENUM";
+    case CTF_K_FORWARD: return "FORWARD";
+    case CTF_K_TYPEDEF: return "TYPEDEF";
+    case CTF_K_VOLATILE: return "VOLATILE";
+    case CTF_K_CONST: return "CONST";
+    case CTF_K_RESTRICT: return "RESTRICT";
+    default: return "???";
+    }
+}
+
 using ctf_type_map = gdb::unordered_map<ctf_id_t, struct type *>;
 
 struct ctf_dict_info
@@ -992,10 +1029,18 @@ ctf_add_type_cb (ctf_id_t tid, void *arg)
   /* Check if tid's type has already been defined.  */
   type = get_tid_type (ccp->of, tid);
   if (type != nullptr)
-    return 0;
+    {
+      ctf_debug_printf ("tid=%ld already defined, skipping", tid);
+      return 0;
+    }
 
   ctf_id_t btid = ctf_type_reference (ccp->dict, tid);
   kind = ctf_type_kind (ccp->dict, tid);
+
+  ctf_debug_printf ("processing tid=%ld kind=%s name='%s' btid=%ld",
+		    tid, ctf_kind_str (kind),
+		    ctf_type_name_raw (ccp->dict, tid) ? : "(null)", btid);
+
   switch (kind)
     {
       case CTF_K_STRUCT:
@@ -1059,6 +1104,9 @@ ctf_add_var_cb (const char *name, ctf_id_t id, void *arg)
 
   kind = ctf_type_kind (ccp->dict, id);
 
+  ctf_debug_printf ("adding variable name='%s' tid=%ld kind=%s",
+		    name, id, ctf_kind_str (kind));
+
   if (type == nullptr)
     {
       complaint (_("ctf_add_var_cb: %s has NO type (%ld)"), name, id);
@@ -1101,7 +1149,15 @@ add_stt_entries (struct ctf_context *ccp, int functions)
     {
       type = get_tid_type (ccp->of, tid);
       if (type == nullptr)
-	continue;
+	{
+	  ctf_debug_printf ("skipping '%s' tid=0x%lx (no type found)",
+			    tname, tid);
+	  continue;
+	}
+
+      ctf_debug_printf ("adding %s '%s' tid=0x%lx",
+			functions ? "function" : "object", tname, tid);
+
       sym = new (&ccp->of->objfile_obstack) symbol;
       OBJSTAT (ccp->of, n_syms++);
       sym->set_type (type);
@@ -1186,6 +1242,10 @@ ctf_psymtab_add_stt_entries (ctf_dict_t *dict, ctf_psymtab *pst,
       else
 	loc_class = LOC_STATIC;
 
+      ctf_debug_printf ("adding %s psym '%s' tid=0x%lx kind=%s",
+			functions ? "function" : "object", tname, tid,
+			ctf_kind_str (kind));
+
       pst->add_psymbol (tname, true,
 			tdomain, loc_class, -1,
 			psymbol_placement::GLOBAL,
@@ -1219,6 +1279,8 @@ ctf_psymtab::expand_psymtab (struct objfile *objfile)
 {
   struct ctf_context *ccp;
 
+  CTF_SCOPED_DEBUG_START_END ("expanding psymtab");
+
   gdb_assert (!readin);
 
   ccp = &context;
@@ -1247,6 +1309,8 @@ ctf_psymtab::expand_psymtab (struct objfile *objfile)
 void
 ctf_psymtab::read_symtab (struct objfile *objfile)
 {
+  CTF_SCOPED_DEBUG_START_END ("reading symtab for '%s'", filename);
+
   if (readin)
     warning (_("bug: psymtab for %s is already read in."), filename);
   else
@@ -1263,6 +1327,9 @@ ctf_psymtab::read_symtab (struct objfile *objfile)
 
       offset = get_objfile_text_range (objfile, &tsize);
 
+      ctf_debug_printf ("starting buildsym for '%s', offset=%s, tsize=%zu",
+			filename, hex_string (offset), tsize);
+
       buildsym_compunit builder (objfile, this->filename, nullptr,
 				 language_c, offset);
       builder.record_debugformat ("ctf");
@@ -1360,6 +1427,9 @@ ctf_psymtab_type_cb (ctf_id_t tid, void *arg)
   if (name == nullptr || *name == '\0')
     return 0;
 
+  ctf_debug_printf ("adding type tid=0x%lx kind=%s name='%s'",
+		    tid, ctf_kind_str (kind), name);
+
   ccp->pst->add_psymbol (name, false,
 			 domain, loc_class, section,
 			 psymbol_placement::GLOBAL,
@@ -1377,6 +1447,10 @@ ctf_psymtab_var_cb (const char *name, ctf_id_t id, void *arg)
   struct ctf_context *ccp = (struct ctf_context *) arg;
 
   uint32_t kind = ctf_type_kind (ccp->dict, id);
+
+  ctf_debug_printf ("adding variable name='%s' tid=0x%lx kind=%s",
+		    name, id, ctf_kind_str (kind));
+
   ccp->pst->add_psymbol (name, true,
 			 kind == CTF_K_FUNCTION
 			 ? FUNCTION_DOMAIN
@@ -1398,10 +1472,13 @@ scan_partial_symbols (ctf_dict_t *dict, psymtab_storage *partial_symtabs,
   struct objfile *of = tup->of;
   bool isparent = false;
 
+  CTF_SCOPED_DEBUG_START_END ("fname='%s'", fname);
+
   if (strcmp (fname, ".ctf") == 0)
     {
       fname = bfd_get_filename (of->obfd.get ());
       isparent = true;
+      ctf_debug_printf ("is parent, using fname='%s'", fname);
     }
 
   ctf_psymtab *pst = create_partial_symtab (fname, tup->arc, dict,
@@ -1462,6 +1539,9 @@ elfctf_build_psymtabs (struct objfile *of)
   bfd *abfd = of->obfd.get ();
   int err;
 
+  CTF_SCOPED_DEBUG_START_END ("building psymtabs for %s",
+			      bfd_get_filename (abfd));
+
   ctf_archive_t *arc = ctf_bfdopen (abfd, &err);
   if (arc == nullptr)
     error (_("ctf_bfdopen failed on %s - %s"),
@@ -1495,3 +1575,14 @@ elfctf_build_psymtabs (struct objfile *of)
 }
 
 #endif /* ENABLE_LIBCTF */
+
+INIT_GDB_FILE (_initialize_ctfread)
+{
+  add_setshow_boolean_cmd ("ctf", no_class, &debug_ctf,
+			   _("Set CTF reading debugging."),
+			   _("Show CTF reading debugging."),
+			   _("When true, print debug messages related to "
+			     "CTF reading."),
+			   nullptr, nullptr,
+			   &setdebuglist, &showdebuglist);
+}
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 103549ece778..0745cf20b130 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -29252,6 +29252,13 @@ exported symbols.  The default is off.
 Displays the current state of displaying debugging messages related to
 reading of COFF/PE exported symbols.
 
+@cindex CTF debug messages
+@item set debug ctf
+Turns on or off display of debugging messages related to reading CTF
+debug info.  The default is off.
+@item show debug ctf
+Displays the current state of CTF debug info reading messages.
+
 @item set debug dwarf-die
 @cindex DWARF DIEs
 Dump DWARF DIEs after they are read in.
-- 
2.53.0


^ permalink raw reply	[flat|nested] 52+ messages in thread

* [PATCH v2 2/9] gdb/ctf: add unique_ptr types
  2026-02-17 19:50 ` [PATCH v2 0/9] " simon.marchi
  2026-02-17 19:50   ` [PATCH v2 1/9] gdb/ctf: add debug logging in ctfread.c simon.marchi
@ 2026-02-17 19:50   ` simon.marchi
  2026-02-17 19:50   ` [PATCH v2 3/9] gdb/ctf: editorial renames simon.marchi
                     ` (7 subsequent siblings)
  9 siblings, 0 replies; 52+ messages in thread
From: simon.marchi @ 2026-02-17 19:50 UTC (permalink / raw)
  To: gdb-patches; +Cc: Simon Marchi

From: Simon Marchi <simon.marchi@polymtl.ca>

Add ctf_archive_up and ctf_dict_up to automatically manage the lifetime
of a ctf_archive_t or ctf_dict_t and use them.

Change-Id: I51b3548b1bb28941c7bad776a11a238eb25789e4
---
 gdb/ctfread.c | 56 ++++++++++++++++++++++++++++++++-------------------
 1 file changed, 35 insertions(+), 21 deletions(-)

diff --git a/gdb/ctfread.c b/gdb/ctfread.c
index 141f51f621b0..6c1bbebcf2c8 100644
--- a/gdb/ctfread.c
+++ b/gdb/ctfread.c
@@ -125,28 +125,40 @@ ctf_kind_str (uint32_t kind)
 
 using ctf_type_map = gdb::unordered_map<ctf_id_t, struct type *>;
 
-struct ctf_dict_info
+struct ctf_archive_closer
 {
-  explicit ctf_dict_info (ctf_dict_t *dict) : dict (dict) {}
-  ~ctf_dict_info ();
+  void operator() (ctf_archive_t *arc) const noexcept
+  {
+    ctf_close (arc);
+  }
+};
 
-  /* Map from IDs to types.  */
-  ctf_type_map type_map;
+using ctf_archive_up = std::unique_ptr<ctf_archive_t, ctf_archive_closer>;
 
-  /* The dictionary.  */
-  ctf_dict_t *dict;
+struct ctf_dict_closer
+{
+  void operator() (ctf_dict_t *dict) const noexcept
+  {
+    ctf_dict_close (dict);
+  }
 };
 
-/* Cleanup function for the ctf_dict_key data.  */
-ctf_dict_info::~ctf_dict_info ()
+using ctf_dict_up = std::unique_ptr<ctf_dict_t, ctf_dict_closer>;
+
+struct ctf_dict_info
 {
-  if (dict == nullptr)
-    return;
+  explicit ctf_dict_info (ctf_archive_up archive, ctf_dict_up dict)
+    : archive (std::move (archive)),
+      dict (std::move (dict))
+  {}
 
-  ctf_archive_t *arc = ctf_get_arc (dict);
-  ctf_dict_close (dict);
-  ctf_close (arc);
-}
+  /* Map from IDs to types.  */
+  ctf_type_map type_map;
+
+  /* The archive and dictionary.  */
+  ctf_archive_up archive;
+  ctf_dict_up dict;
+};
 
 static const registry<objfile>::key<ctf_dict_info> ctf_dict_key;
 
@@ -1542,26 +1554,28 @@ elfctf_build_psymtabs (struct objfile *of)
   CTF_SCOPED_DEBUG_START_END ("building psymtabs for %s",
 			      bfd_get_filename (abfd));
 
-  ctf_archive_t *arc = ctf_bfdopen (abfd, &err);
+  ctf_archive_up 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 *dict = ctf_dict_open (arc, NULL, &err);
+  ctf_dict_up dict (ctf_dict_open (arc.get (), NULL, &err));
   if (dict == nullptr)
     error (_("ctf_dict_open failed on %s - %s"),
 	   bfd_get_filename (abfd), ctf_errmsg (err));
-  ctf_dict_key.emplace (of, dict);
 
-  pcu.dict = dict;
+  ctf_dict_info &dict_info
+    = ctf_dict_key.emplace (of, std::move (arc), std::move (dict));
+
+  pcu.dict = dict_info.dict.get ();
   pcu.of = of;
-  pcu.arc = arc;
+  pcu.arc = dict_info.archive.get ();
 
   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)
+  if (ctf_archive_iter (pcu.arc, build_ctf_archive_member, &pcu) < 0)
     error (_("ctf_archive_iter failed in input file %s: - %s"),
 	   bfd_get_filename (abfd), ctf_errmsg (err));
 }
-- 
2.53.0


^ permalink raw reply	[flat|nested] 52+ messages in thread

* [PATCH v2 3/9] gdb/ctf: editorial renames
  2026-02-17 19:50 ` [PATCH v2 0/9] " simon.marchi
  2026-02-17 19:50   ` [PATCH v2 1/9] gdb/ctf: add debug logging in ctfread.c simon.marchi
  2026-02-17 19:50   ` [PATCH v2 2/9] gdb/ctf: add unique_ptr types simon.marchi
@ 2026-02-17 19:50   ` simon.marchi
  2026-02-17 19:50   ` [PATCH v2 4/9] gdb/ctf: use ctf_per_objfile in ctf_archive_iter_psymtab_data and ctf_context simon.marchi
                     ` (6 subsequent siblings)
  9 siblings, 0 replies; 52+ messages in thread
From: simon.marchi @ 2026-02-17 19:50 UTC (permalink / raw)
  To: gdb-patches; +Cc: Simon Marchi

From: Simon Marchi <simon.marchi@polymtl.ca>

Rename a few things to fit a bit more with how we typically name things,
or make the names more accurate.  I think this makes the code easier to
follow for anyone familiar with the GDB codebase (or at least, familiar
with the DWARF reader).  It's not super important, but it did help me
understand better the flow of the reader.

 - struct ctf_dict_info -> struct ctf_per_objfile
 - ctf_per_objfile::dict -> ctf_per_objfile::parent_dict
 - ctf_dict_key -> ctf_per_objfile_key
 - ctf_per_tu_data -> ctf_archive_iter_psymtab_data
 - ctf_archive_iter_psymtab_data::dict -> ctf_archive_iter_psymtab_data::parent_dict
 - of -> objfile
 - arc -> archive
 - In build_ctf_archive_member, ctf -> dict

Change-Id: I40f3cba8e40e4c9d006a96032a4c3856bd762ed5
---
 gdb/ctfread.c | 235 +++++++++++++++++++++++++-------------------------
 1 file changed, 119 insertions(+), 116 deletions(-)

diff --git a/gdb/ctfread.c b/gdb/ctfread.c
index 6c1bbebcf2c8..9b999c2560b9 100644
--- a/gdb/ctfread.c
+++ b/gdb/ctfread.c
@@ -145,29 +145,29 @@ struct ctf_dict_closer
 
 using ctf_dict_up = std::unique_ptr<ctf_dict_t, ctf_dict_closer>;
 
-struct ctf_dict_info
+struct ctf_per_objfile
 {
-  explicit ctf_dict_info (ctf_archive_up archive, ctf_dict_up dict)
+  explicit ctf_per_objfile (ctf_archive_up archive, ctf_dict_up dict)
     : archive (std::move (archive)),
-      dict (std::move (dict))
+      parent_dict (std::move (dict))
   {}
 
   /* Map from IDs to types.  */
   ctf_type_map type_map;
 
-  /* The archive and dictionary.  */
+  /* The archive and parent dictionary.  */
   ctf_archive_up archive;
-  ctf_dict_up dict;
+  ctf_dict_up parent_dict;
 };
 
-static const registry<objfile>::key<ctf_dict_info> ctf_dict_key;
+static const registry<objfile>::key<ctf_per_objfile> ctf_per_objfile_key;
 
 /* A CTF context consists of a file pointer and an objfile pointer.  */
 
 struct ctf_context
 {
   ctf_dict_t *dict;
-  struct objfile *of;
+  struct objfile *objfile;
   psymtab_storage *partial_symtabs;
   partial_symtab *pst;
   ctf_archive_t *arc;
@@ -220,13 +220,13 @@ struct ctf_field_info
   std::vector<struct decl_field> nested_types_list;
 };
 
-/* Data held for a translation unit.  */
+/* Data held while using ctf_archive_iter to build psymtabs.  */
 
-struct ctf_per_tu_data
+struct ctf_archive_iter_psymtab_data
 {
-  ctf_dict_t *dict;
-  struct objfile *of;
-  ctf_archive_t *arc;
+  ctf_dict_t *parent_dict;
+  struct objfile *objfile;
+  ctf_archive_t *archive;
   psymbol_functions *psf;
 };
 
@@ -258,11 +258,11 @@ static struct type *read_forward_type (struct ctf_context *cp, ctf_id_t 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)
+set_tid_type (struct objfile *objfile, ctf_id_t tid, struct type *typ)
 {
-  ctf_dict_info *info = ctf_dict_key.get (of);
-  gdb_assert (info != nullptr);
-  info->type_map.emplace (tid, typ);
+  ctf_per_objfile *per_objfile = ctf_per_objfile_key.get (objfile);
+  gdb_assert (per_objfile != nullptr);
+  per_objfile->type_map.emplace (tid, typ);
   return typ;
 }
 
@@ -270,13 +270,13 @@ set_tid_type (struct objfile *of, ctf_id_t tid, struct type *typ)
    does not have a saved type.  */
 
 static struct type *
-get_tid_type (struct objfile *of, ctf_id_t tid)
+get_tid_type (struct objfile *objfile, ctf_id_t tid)
 {
-  ctf_dict_info *info = ctf_dict_key.get (of);
-  gdb_assert (info != nullptr);
+  ctf_per_objfile *per_objfile = ctf_per_objfile_key.get (objfile);
+  gdb_assert (per_objfile != nullptr);
 
-  auto iter = info->type_map.find (tid);
-  if (iter == info->type_map.end ())
+  auto iter = per_objfile->type_map.find (tid);
+  if (iter == per_objfile->type_map.end ())
     return nullptr;
   return iter->second;
 }
@@ -287,14 +287,14 @@ get_tid_type (struct objfile *of, ctf_id_t tid)
 static struct type *
 fetch_tid_type (struct ctf_context *ccp, ctf_id_t tid)
 {
-  struct objfile *of = ccp->of;
+  struct objfile *objfile = ccp->objfile;
   struct type *typ;
 
-  typ = get_tid_type (of, tid);
+  typ = get_tid_type (objfile, tid);
   if (typ == nullptr)
     {
       ctf_add_type_cb (tid, ccp);
-      typ = get_tid_type (of, tid);
+      typ = get_tid_type (objfile, tid);
     }
 
   return typ;
@@ -319,10 +319,11 @@ get_bitsize (ctf_dict_t *dict, ctf_id_t tid, uint32_t kind)
 /* 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)
+set_symbol_address (struct objfile *objfile, struct symbol *sym,
+		    const char *name)
 {
   bound_minimal_symbol msym
-    = lookup_minimal_symbol (current_program_space, name, of);
+    = lookup_minimal_symbol (current_program_space, name, objfile);
   if (msym.minsym != NULL)
     {
       sym->set_value_address (msym.value_address ());
@@ -404,8 +405,8 @@ ctf_add_member_cb (const char *name,
       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);
+	  t = builtin_type (ccp->objfile)->builtin_error;
+	  set_tid_type (ccp->objfile, tid, t);
 	}
     }
 
@@ -440,11 +441,11 @@ ctf_add_enum_member_cb (const char *name, int enum_value, void *arg)
 
   if (name != nullptr && *name != '\0')
     {
-      struct symbol *sym = new (&ccp->of->objfile_obstack) symbol;
-      OBJSTAT (ccp->of, n_syms++);
+      struct symbol *sym = new (&ccp->objfile->objfile_obstack) symbol;
+      OBJSTAT (ccp->objfile, n_syms++);
 
-      sym->set_language (language_c, &ccp->of->objfile_obstack);
-      sym->compute_and_set_names (name, false, ccp->of->per_bfd);
+      sym->set_language (language_c, &ccp->objfile->objfile_obstack);
+      sym->compute_and_set_names (name, false, ccp->objfile->per_bfd);
       sym->set_loc_class_index (LOC_CONST);
       sym->set_domain (VAR_DOMAIN);
       sym->set_type (fip->ptype);
@@ -467,7 +468,7 @@ new_type_symbol (struct ctf_context *ccp, struct type *type, ctf_id_t tid)
   const char *name = ctf_type_name_raw (dict, tid);
   if (name != nullptr && *name != '\0')
     {
-      struct objfile *objfile = ccp->of;
+      struct objfile *objfile = ccp->objfile;
       struct symbol *sym = new (&objfile->objfile_obstack) symbol;
       OBJSTAT (objfile, n_syms++);
 
@@ -499,7 +500,7 @@ new_type_symbol (struct ctf_context *ccp, struct type *type, ctf_id_t tid)
 static struct type *
 read_base_type (struct ctf_context *ccp, ctf_id_t tid)
 {
-  struct objfile *of = ccp->of;
+  struct objfile *objfile = ccp->objfile;
   ctf_dict_t *dict = ccp->dict;
   ctf_encoding_t cet;
   struct type *type = nullptr;
@@ -522,12 +523,12 @@ read_base_type (struct ctf_context *ccp, ctf_id_t tid)
 		   ctf_errmsg (ctf_errno (dict)));
     }
 
-  type_allocator alloc (of, language_c);
+  type_allocator alloc (objfile, language_c);
   kind = ctf_type_kind (dict, tid);
   if (kind == CTF_K_INTEGER)
     {
       uint32_t issigned, ischar, isbool;
-      struct gdbarch *gdbarch = of->arch ();
+      struct gdbarch *gdbarch = objfile->arch ();
 
       issigned = cet.cte_format & CTF_INT_SIGNED;
       ischar = cet.cte_format & CTF_INT_CHAR;
@@ -554,11 +555,11 @@ read_base_type (struct ctf_context *ccp, ctf_id_t tid)
 		 || (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);
+	type = ctf_init_float_type (objfile, cet.cte_bits, name, name);
       else
 	{
 	  struct type *t
-	    = ctf_init_float_type (of, cet.cte_bits / 2, NULL, name);
+	    = ctf_init_float_type (objfile, cet.cte_bits / 2, NULL, name);
 	  type = init_complex_type (name, t);
 	}
     }
@@ -571,7 +572,7 @@ read_base_type (struct ctf_context *ccp, ctf_id_t tid)
   if (name != nullptr && strcmp (name, "char") == 0)
     type->set_has_no_signedness (true);
 
-  return set_tid_type (of, tid, type);
+  return set_tid_type (objfile, tid, type);
 }
 
 static void
@@ -593,12 +594,12 @@ process_base_type (struct ctf_context *ccp, ctf_id_t tid)
 static struct type *
 read_structure_type (struct ctf_context *ccp, ctf_id_t tid)
 {
-  struct objfile *of = ccp->of;
+  struct objfile *objfile = ccp->objfile;
   ctf_dict_t *dict = ccp->dict;
   struct type *type;
   uint32_t kind;
 
-  type = type_allocator (of, language_c).new_type ();
+  type = type_allocator (objfile, language_c).new_type ();
 
   const char *name = ctf_type_name_raw (dict, tid);
   if (name != nullptr && *name != '\0')
@@ -613,7 +614,7 @@ read_structure_type (struct ctf_context *ccp, ctf_id_t tid)
   type->set_length (ctf_type_size (dict, tid));
   set_type_align (type, ctf_type_align (dict, tid));
 
-  return set_tid_type (ccp->of, tid, type);
+  return set_tid_type (ccp->objfile, tid, type);
 }
 
 /* Given a tid of CTF_K_STRUCT or CTF_K_UNION, process all its members
@@ -651,13 +652,13 @@ process_structure_type (struct ctf_context *ccp, ctf_id_t tid)
 static struct type *
 read_func_kind_type (struct ctf_context *ccp, ctf_id_t tid)
 {
-  struct objfile *of = ccp->of;
+  struct objfile *objfile = ccp->objfile;
   ctf_dict_t *dict = ccp->dict;
   struct type *type, *rettype, *atype;
   ctf_funcinfo_t cfi;
   uint32_t argc;
 
-  type = type_allocator (of, language_c).new_type ();
+  type = type_allocator (objfile, language_c).new_type ();
 
   type->set_code (TYPE_CODE_FUNC);
   if (ctf_func_type_info (dict, tid, &cfi) < 0)
@@ -683,7 +684,7 @@ read_func_kind_type (struct ctf_context *ccp, ctf_id_t tid)
 	return nullptr;
 
       type->alloc_fields (argc);
-      struct type *void_type = builtin_type (of)->builtin_void;
+      struct type *void_type = builtin_type (objfile)->builtin_void;
       /* If failed to find the argument type, fill it with void_type.  */
       for (int iparam = 0; iparam < argc; iparam++)
 	{
@@ -695,7 +696,7 @@ read_func_kind_type (struct ctf_context *ccp, ctf_id_t tid)
 	}
     }
 
-  return set_tid_type (of, tid, type);
+  return set_tid_type (objfile, tid, type);
 }
 
 /* Given a TID of CTF_K_ENUM, process all the members of the
@@ -704,11 +705,11 @@ read_func_kind_type (struct ctf_context *ccp, ctf_id_t tid)
 static struct type *
 read_enum_type (struct ctf_context *ccp, ctf_id_t tid)
 {
-  struct objfile *of = ccp->of;
+  struct objfile *objfile = ccp->objfile;
   ctf_dict_t *dict = ccp->dict;
   struct type *type;
 
-  type = type_allocator (of, language_c).new_type ();
+  type = type_allocator (objfile, language_c).new_type ();
 
   const char *name = ctf_type_name_raw (dict, tid);
   if (name != nullptr && *name != '\0')
@@ -717,10 +718,10 @@ read_enum_type (struct ctf_context *ccp, ctf_id_t tid)
   type->set_code (TYPE_CODE_ENUM);
   type->set_length (ctf_type_size (dict, tid));
   /* Set the underlying type based on its ctf_type_size bits.  */
-  type->set_target_type (objfile_int_type (of, type->length (), false));
+  type->set_target_type (objfile_int_type (objfile, type->length (), false));
   set_type_align (type, ctf_type_align (dict, tid));
 
-  return set_tid_type (of, tid, type);
+  return set_tid_type (objfile, tid, type);
 }
 
 static void
@@ -768,7 +769,7 @@ add_array_cv_type (struct ctf_context *ccp,
   voltl |= TYPE_VOLATILE (el_type);
   inner_array->set_target_type (make_cv_type (cnst, voltl, el_type));
 
-  return set_tid_type (ccp->of, tid, base_type);
+  return set_tid_type (ccp->objfile, tid, base_type);
 }
 
 /* Read all information from a TID of CTF_K_ARRAY.  */
@@ -776,7 +777,7 @@ add_array_cv_type (struct ctf_context *ccp,
 static struct type *
 read_array_type (struct ctf_context *ccp, ctf_id_t tid)
 {
-  struct objfile *objfile = ccp->of;
+  struct objfile *objfile = ccp->objfile;
   ctf_dict_t *dict = ccp->dict;
   struct type *element_type, *range_type, *idx_type;
   struct type *type;
@@ -819,7 +820,7 @@ read_array_type (struct ctf_context *ccp, ctf_id_t tid)
 static struct type *
 read_const_type (struct ctf_context *ccp, ctf_id_t tid, ctf_id_t btid)
 {
-  struct objfile *objfile = ccp->of;
+  struct objfile *objfile = ccp->objfile;
   struct type *base_type, *cv_type;
 
   base_type = fetch_tid_type (ccp, btid);
@@ -842,7 +843,7 @@ read_const_type (struct ctf_context *ccp, ctf_id_t tid, ctf_id_t btid)
 static struct type *
 read_volatile_type (struct ctf_context *ccp, ctf_id_t tid, ctf_id_t btid)
 {
-  struct objfile *objfile = ccp->of;
+  struct objfile *objfile = ccp->objfile;
   ctf_dict_t *dict = ccp->dict;
   struct type *base_type, *cv_type;
 
@@ -869,7 +870,7 @@ read_volatile_type (struct ctf_context *ccp, ctf_id_t tid, ctf_id_t 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 objfile *objfile = ccp->objfile;
   struct type *base_type, *cv_type;
 
   base_type = fetch_tid_type (ccp, btid);
@@ -893,7 +894,7 @@ 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 objfile *objfile = ccp->objfile;
   struct type *this_type, *target_type;
 
   char *aname = obstack_strdup (&objfile->objfile_obstack, name);
@@ -916,7 +917,7 @@ read_typedef_type (struct ctf_context *ccp, ctf_id_t tid,
 static struct type *
 read_pointer_type (struct ctf_context *ccp, ctf_id_t tid, ctf_id_t btid)
 {
-  struct objfile *of = ccp->of;
+  struct objfile *objfile = ccp->objfile;
   struct type *target_type, *type;
 
   target_type = fetch_tid_type (ccp, btid);
@@ -926,14 +927,14 @@ read_pointer_type (struct ctf_context *ccp, ctf_id_t tid, ctf_id_t btid)
       if (target_type == nullptr)
 	{
 	  complaint (_("read_pointer_type: NULL target type (%ld)"), btid);
-	  target_type = builtin_type (ccp->of)->builtin_error;
+	  target_type = builtin_type (ccp->objfile)->builtin_error;
 	}
     }
 
   type = lookup_pointer_type (target_type);
   set_type_align (type, ctf_type_align (ccp->dict, tid));
 
-  return set_tid_type (of, tid, type);
+  return set_tid_type (objfile, tid, type);
 }
 
 /* Read information from a TID of CTF_K_FORWARD.  */
@@ -941,12 +942,12 @@ read_pointer_type (struct ctf_context *ccp, ctf_id_t tid, ctf_id_t btid)
 static struct type *
 read_forward_type (struct ctf_context *ccp, ctf_id_t tid)
 {
-  struct objfile *of = ccp->of;
+  struct objfile *objfile = ccp->objfile;
   ctf_dict_t *dict = ccp->dict;
   struct type *type;
   uint32_t kind;
 
-  type = type_allocator (of, language_c).new_type ();
+  type = type_allocator (objfile, language_c).new_type ();
 
   const char *name = ctf_type_name_raw (dict, tid);
   if (name != nullptr && *name != '\0')
@@ -961,7 +962,7 @@ read_forward_type (struct ctf_context *ccp, ctf_id_t tid)
   type->set_length (0);
   type->set_is_stub (true);
 
-  return set_tid_type (of, tid, type);
+  return set_tid_type (objfile, tid, type);
 }
 
 /* Read information associated with type TID.  */
@@ -1039,7 +1040,7 @@ ctf_add_type_cb (ctf_id_t tid, void *arg)
   uint32_t kind;
 
   /* Check if tid's type has already been defined.  */
-  type = get_tid_type (ccp->of, tid);
+  type = get_tid_type (ccp->objfile, tid);
   if (type != nullptr)
     {
       ctf_debug_printf ("tid=%ld already defined, skipping", tid);
@@ -1112,7 +1113,7 @@ ctf_add_var_cb (const char *name, ctf_id_t id, void *arg)
   struct type *type;
   uint32_t kind;
 
-  type = get_tid_type (ccp->of, id);
+  type = get_tid_type (ccp->objfile, id);
 
   kind = ctf_type_kind (ccp->dict, id);
 
@@ -1122,25 +1123,25 @@ ctf_add_var_cb (const char *name, ctf_id_t id, void *arg)
   if (type == nullptr)
     {
       complaint (_("ctf_add_var_cb: %s has NO type (%ld)"), name, id);
-      type = builtin_type (ccp->of)->builtin_error;
+      type = builtin_type (ccp->objfile)->builtin_error;
     }
-  sym = new (&ccp->of->objfile_obstack) symbol;
-  OBJSTAT (ccp->of, n_syms++);
+  sym = new (&ccp->objfile->objfile_obstack) symbol;
+  OBJSTAT (ccp->objfile, n_syms++);
   sym->set_type (type);
   sym->set_loc_class_index (LOC_OPTIMIZED_OUT);
-  sym->compute_and_set_names (name, false, ccp->of->per_bfd);
+  sym->compute_and_set_names (name, false, ccp->objfile->per_bfd);
 
   if (kind == CTF_K_FUNCTION)
     {
       sym->set_domain (FUNCTION_DOMAIN);
       if (name != nullptr && strcmp (name, "main") == 0)
-	set_objfile_main_name (ccp->of, name, language_c);
+	set_objfile_main_name (ccp->objfile, name, language_c);
     }
   else
     sym->set_domain (VAR_DOMAIN);
 
   add_symbol_to_list (sym, ccp->builder->get_global_symbols ());
-  set_symbol_address (ccp->of, sym, name);
+  set_symbol_address (ccp->objfile, sym, name);
 
   return 0;
 }
@@ -1159,7 +1160,7 @@ add_stt_entries (struct ctf_context *ccp, int functions)
 
   while ((tid = ctf_symbol_next (ccp->dict, &i, &tname, functions)) != CTF_ERR)
     {
-      type = get_tid_type (ccp->of, tid);
+      type = get_tid_type (ccp->objfile, tid);
       if (type == nullptr)
 	{
 	  ctf_debug_printf ("skipping '%s' tid=0x%lx (no type found)",
@@ -1170,14 +1171,14 @@ add_stt_entries (struct ctf_context *ccp, int functions)
       ctf_debug_printf ("adding %s '%s' tid=0x%lx",
 			functions ? "function" : "object", tname, tid);
 
-      sym = new (&ccp->of->objfile_obstack) symbol;
-      OBJSTAT (ccp->of, n_syms++);
+      sym = new (&ccp->objfile->objfile_obstack) symbol;
+      OBJSTAT (ccp->objfile, n_syms++);
       sym->set_type (type);
       sym->set_domain (functions ? FUNCTION_DOMAIN : VAR_DOMAIN);
       sym->set_loc_class_index (LOC_STATIC);
-      sym->compute_and_set_names (tname, false, ccp->of->per_bfd);
+      sym->compute_and_set_names (tname, false, ccp->objfile->per_bfd);
       add_symbol_to_list (sym, ccp->builder->get_global_symbols ());
-      set_symbol_address (ccp->of, sym, tname);
+      set_symbol_address (ccp->objfile, sym, tname);
     }
 }
 
@@ -1200,14 +1201,14 @@ add_stt_func (struct ctf_context *ccp)
 /* Get text section base for OBJFILE, TSIZE contains the size.  */
 
 static CORE_ADDR
-get_objfile_text_range (struct objfile *of, size_t *tsize)
+get_objfile_text_range (struct objfile *objfile, size_t *tsize)
 {
-  bfd *abfd = of->obfd.get ();
+  bfd *abfd = objfile->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 ();
+  return objfile->text_section_offset ();
 }
 
 /* Add all members of an enum with type TID to partial symbol table.  */
@@ -1225,7 +1226,7 @@ ctf_psymtab_add_enums (struct ctf_context *ccp, ctf_id_t tid)
 			     VAR_DOMAIN, LOC_CONST, -1,
 			     psymbol_placement::GLOBAL,
 			     unrelocated_addr (0),
-			     language_c, ccp->partial_symtabs, ccp->of);
+			     language_c, ccp->partial_symtabs, ccp->objfile);
     }
   if (ctf_errno (ccp->dict) != ECTF_NEXT_END)
     complaint (_("ctf_enum_next ctf_psymtab_add_enums failed - %s"),
@@ -1237,7 +1238,7 @@ ctf_psymtab_add_enums (struct ctf_context *ccp, ctf_id_t tid)
 
 static void
 ctf_psymtab_add_stt_entries (ctf_dict_t *dict, ctf_psymtab *pst,
-			     struct objfile *of, int functions)
+			     struct objfile *objfile, int functions)
 {
   ctf_next_t *i = nullptr;
   ctf_id_t tid;
@@ -1262,7 +1263,7 @@ ctf_psymtab_add_stt_entries (ctf_dict_t *dict, ctf_psymtab *pst,
 			tdomain, loc_class, -1,
 			psymbol_placement::GLOBAL,
 			unrelocated_addr (0),
-			language_c, pst->context.partial_symtabs, of);
+			language_c, pst->context.partial_symtabs, objfile);
     }
 }
 
@@ -1270,18 +1271,18 @@ ctf_psymtab_add_stt_entries (ctf_dict_t *dict, ctf_psymtab *pst,
 
 static void
 ctf_psymtab_add_stt_obj (ctf_dict_t *dict, ctf_psymtab *pst,
-			 struct objfile *of)
+			 struct objfile *objfile)
 {
-  ctf_psymtab_add_stt_entries (dict, pst, of, 0);
+  ctf_psymtab_add_stt_entries (dict, pst, objfile, 0);
 }
 
 /* Add entries in function info section to psymtab.  */
 
 static void
 ctf_psymtab_add_stt_func (ctf_dict_t *dict, ctf_psymtab *pst,
-			  struct objfile *of)
+			  struct objfile *objfile)
 {
-  ctf_psymtab_add_stt_entries (dict, pst, of, 1);
+  ctf_psymtab_add_stt_entries (dict, pst, objfile, 1);
 }
 
 /* Read in full symbols for PST, and anything it depends on.  */
@@ -1386,7 +1387,7 @@ create_partial_symtab (const char *name,
 
   pst->context.arc = arc;
   pst->context.dict = dict;
-  pst->context.of = objfile;
+  pst->context.objfile = objfile;
   pst->context.partial_symtabs = partial_symtabs;
   pst->context.pst = pst;
   pst->context.builder = nullptr;
@@ -1446,7 +1447,7 @@ ctf_psymtab_type_cb (ctf_id_t tid, void *arg)
 			 domain, loc_class, section,
 			 psymbol_placement::GLOBAL,
 			 unrelocated_addr (0),
-			 language_c, ccp->partial_symtabs, ccp->of);
+			 language_c, ccp->partial_symtabs, ccp->objfile);
 
   return 0;
 }
@@ -1470,7 +1471,7 @@ ctf_psymtab_var_cb (const char *name, ctf_id_t id, void *arg)
 			 LOC_STATIC, -1,
 			 psymbol_placement::GLOBAL,
 			 unrelocated_addr (0),
-			 language_c, ccp->partial_symtabs, ccp->of);
+			 language_c, ccp->partial_symtabs, ccp->objfile);
   return 0;
 }
 
@@ -1479,22 +1480,23 @@ ctf_psymtab_var_cb (const char *name, ctf_id_t id, void *arg)
 
 static void
 scan_partial_symbols (ctf_dict_t *dict, psymtab_storage *partial_symtabs,
-		      struct ctf_per_tu_data *tup, const char *fname)
+		      ctf_archive_iter_psymtab_data *iter_data,
+		      const char *fname)
 {
-  struct objfile *of = tup->of;
+  objfile *objfile = iter_data->objfile;
   bool isparent = false;
 
   CTF_SCOPED_DEBUG_START_END ("fname='%s'", fname);
 
   if (strcmp (fname, ".ctf") == 0)
     {
-      fname = bfd_get_filename (of->obfd.get ());
+      fname = bfd_get_filename (objfile->obfd.get ());
       isparent = true;
       ctf_debug_printf ("is parent, using fname='%s'", fname);
     }
 
-  ctf_psymtab *pst = create_partial_symtab (fname, tup->arc, dict,
-					    partial_symtabs, of);
+  ctf_psymtab *pst = create_partial_symtab (fname, iter_data->archive, dict,
+					    partial_symtabs, objfile);
 
   struct ctf_context *ccx = &pst->context;
   if (isparent == false)
@@ -1511,8 +1513,8 @@ scan_partial_symbols (ctf_dict_t *dict, psymtab_storage *partial_symtabs,
   /* 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 (dict, pst, of);
-  ctf_psymtab_add_stt_func (dict, pst, of);
+  ctf_psymtab_add_stt_obj (dict, pst, objfile);
+  ctf_psymtab_add_stt_func (dict, pst, objfile);
 
   pst->end ();
 }
@@ -1520,13 +1522,12 @@ scan_partial_symbols (ctf_dict_t *dict, psymtab_storage *partial_symtabs,
 /* Callback to build the psymtab for archive member NAME.  */
 
 static int
-build_ctf_archive_member (ctf_dict_t *ctf, const char *name, void *arg)
+build_ctf_archive_member (ctf_dict_t *dict, const char *name, void *arg)
 {
-  struct ctf_per_tu_data *tup = (struct ctf_per_tu_data *) arg;
-  ctf_dict_t *parent = tup->dict;
+  auto iter_data = static_cast<ctf_archive_iter_psymtab_data *> (arg);
 
   if (strcmp (name, ".ctf") != 0)
-    ctf_import (ctf, parent);
+    ctf_import (dict, iter_data->parent_dict);
 
   if (info_verbose)
     {
@@ -1534,8 +1535,8 @@ build_ctf_archive_member (ctf_dict_t *ctf, const char *name, void *arg)
       gdb_flush (gdb_stdout);
     }
 
-  psymtab_storage *pss = tup->psf->get_partial_symtabs ().get ();
-  scan_partial_symbols (ctf, pss, tup, name);
+  psymtab_storage *pss = iter_data->psf->get_partial_symtabs ().get ();
+  scan_partial_symbols (dict, pss, iter_data, name);
 
   return 0;
 }
@@ -1545,37 +1546,39 @@ build_ctf_archive_member (ctf_dict_t *ctf, const char *name, void *arg)
    .ctf section to set up the partial symbol table.  */
 
 void
-elfctf_build_psymtabs (struct objfile *of)
+elfctf_build_psymtabs (objfile *objfile)
 {
-  struct ctf_per_tu_data pcu;
-  bfd *abfd = of->obfd.get ();
+  bfd *abfd = objfile->obfd.get ();
   int err;
 
   CTF_SCOPED_DEBUG_START_END ("building psymtabs for %s",
 			      bfd_get_filename (abfd));
 
-  ctf_archive_up arc (ctf_bfdopen (abfd, &err));
-  if (arc == nullptr)
+  ctf_archive_up archive (ctf_bfdopen (abfd, &err));
+  if (archive == nullptr)
     error (_("ctf_bfdopen failed on %s - %s"),
 	   bfd_get_filename (abfd), ctf_errmsg (err));
 
-  ctf_dict_up dict (ctf_dict_open (arc.get (), NULL, &err));
+  ctf_dict_up dict (ctf_dict_open (archive.get (), NULL, &err));
   if (dict == nullptr)
     error (_("ctf_dict_open failed on %s - %s"),
 	   bfd_get_filename (abfd), ctf_errmsg (err));
 
-  ctf_dict_info &dict_info
-    = ctf_dict_key.emplace (of, std::move (arc), std::move (dict));
+  ctf_per_objfile &per_objfile
+    = ctf_per_objfile_key.emplace (objfile, std::move (archive),
+				   std::move (dict));
 
-  pcu.dict = dict_info.dict.get ();
-  pcu.of = of;
-  pcu.arc = dict_info.archive.get ();
+  ctf_archive_iter_psymtab_data iter_data;
+  iter_data.parent_dict = per_objfile.parent_dict.get ();
+  iter_data.objfile = objfile;
+  iter_data.archive = per_objfile.archive.get ();
 
   psymbol_functions *psf = new psymbol_functions ();
-  of->qf.emplace_front (psf);
-  pcu.psf = psf;
+  objfile->qf.emplace_front (psf);
+  iter_data.psf = psf;
 
-  if (ctf_archive_iter (pcu.arc, build_ctf_archive_member, &pcu) < 0)
+  if (ctf_archive_iter (iter_data.archive, build_ctf_archive_member, &iter_data)
+      < 0)
     error (_("ctf_archive_iter failed in input file %s: - %s"),
 	   bfd_get_filename (abfd), ctf_errmsg (err));
 }
@@ -1583,7 +1586,7 @@ elfctf_build_psymtabs (struct objfile *of)
 #else
 
 void
-elfctf_build_psymtabs (struct objfile *of)
+elfctf_build_psymtabs (struct objfile *objfile)
 {
   /* Nothing to do if CTF is disabled.  */
 }
-- 
2.53.0


^ permalink raw reply	[flat|nested] 52+ messages in thread

* [PATCH v2 4/9] gdb/ctf: use ctf_per_objfile in ctf_archive_iter_psymtab_data and ctf_context
  2026-02-17 19:50 ` [PATCH v2 0/9] " simon.marchi
                     ` (2 preceding siblings ...)
  2026-02-17 19:50   ` [PATCH v2 3/9] gdb/ctf: editorial renames simon.marchi
@ 2026-02-17 19:50   ` simon.marchi
  2026-02-17 19:50   ` [PATCH v2 5/9] gdb/ctf: check return value of ctf_type_align simon.marchi
                     ` (5 subsequent siblings)
  9 siblings, 0 replies; 52+ messages in thread
From: simon.marchi @ 2026-02-17 19:50 UTC (permalink / raw)
  To: gdb-patches; +Cc: Simon Marchi

From: Simon Marchi <simon.marchi@polymtl.ca>

This patch slightly reorganizes the data structures in ctfread.c to be a
bit more like in the DWARF reader.  That is, instead of duplicating the
information (for instance, the objfile pointer), keep the information
once in the most general object where in make sense (in the
ctf_per_objfile in this case) and have the more specific objects (like
ctf_context, ctf_archive_iter_psymtab_data) have a link to the more
general object.

Concretely, that means removing the archive and parent_dict fields from
ctf_archive_iter_psymtab_data and ctf_context (those are per-objfile
information), adding backlink to the ctf_per_objfile and using the
parent_dict and archive fields there.  Similarly, remove the objfile
fields from these and add a new objfile field in ctf_per_objfile.

Remove the objfile and dict parameters from the ctf_psymtab_add_stt_*
functions, since they can be obtained from the other parameters.

No functional changes expected.

Change-Id: I837264eece869f2bb962842998dede8cd7806bfe
---
 gdb/ctfread.c | 188 ++++++++++++++++++++++++--------------------------
 1 file changed, 90 insertions(+), 98 deletions(-)

diff --git a/gdb/ctfread.c b/gdb/ctfread.c
index 9b999c2560b9..c8457a70cf46 100644
--- a/gdb/ctfread.c
+++ b/gdb/ctfread.c
@@ -147,11 +147,16 @@ using ctf_dict_up = std::unique_ptr<ctf_dict_t, ctf_dict_closer>;
 
 struct ctf_per_objfile
 {
-  explicit ctf_per_objfile (ctf_archive_up archive, ctf_dict_up dict)
-    : archive (std::move (archive)),
+  ctf_per_objfile (struct objfile *objfile, ctf_archive_up archive,
+		   ctf_dict_up dict)
+    : objfile (objfile),
+      archive (std::move (archive)),
       parent_dict (std::move (dict))
   {}
 
+  /* Backlink to objfile.  */
+  struct objfile *objfile;
+
   /* Map from IDs to types.  */
   ctf_type_map type_map;
 
@@ -162,15 +167,14 @@ struct ctf_per_objfile
 
 static const registry<objfile>::key<ctf_per_objfile> ctf_per_objfile_key;
 
-/* A CTF context consists of a file pointer and an objfile pointer.  */
+/* Data passed around when creating symtabs.  */
 
 struct ctf_context
 {
+  ctf_per_objfile *per_objfile;
   ctf_dict_t *dict;
-  struct objfile *objfile;
   psymtab_storage *partial_symtabs;
   partial_symtab *pst;
-  ctf_archive_t *arc;
   struct buildsym_compunit *builder;
 };
 
@@ -224,9 +228,7 @@ struct ctf_field_info
 
 struct ctf_archive_iter_psymtab_data
 {
-  ctf_dict_t *parent_dict;
-  struct objfile *objfile;
-  ctf_archive_t *archive;
+  ctf_per_objfile *per_objfile;
   psymbol_functions *psf;
 };
 
@@ -287,7 +289,7 @@ get_tid_type (struct objfile *objfile, ctf_id_t tid)
 static struct type *
 fetch_tid_type (struct ctf_context *ccp, ctf_id_t tid)
 {
-  struct objfile *objfile = ccp->objfile;
+  struct objfile *objfile = ccp->per_objfile->objfile;
   struct type *typ;
 
   typ = get_tid_type (objfile, tid);
@@ -404,9 +406,10 @@ ctf_add_member_cb (const char *name,
       t = read_type_record (ccp, tid);
       if (t == nullptr)
 	{
+	  objfile *objfile = ccp->per_objfile->objfile;
 	  complaint (_("ctf_add_member_cb: %s has NO type (%ld)"), name, tid);
-	  t = builtin_type (ccp->objfile)->builtin_error;
-	  set_tid_type (ccp->objfile, tid, t);
+	  t = builtin_type (objfile)->builtin_error;
+	  set_tid_type (objfile, tid, t);
 	}
     }
 
@@ -441,11 +444,12 @@ ctf_add_enum_member_cb (const char *name, int enum_value, void *arg)
 
   if (name != nullptr && *name != '\0')
     {
-      struct symbol *sym = new (&ccp->objfile->objfile_obstack) symbol;
-      OBJSTAT (ccp->objfile, n_syms++);
+      objfile *objfile = ccp->per_objfile->objfile;
+      struct symbol *sym = new (&objfile->objfile_obstack) symbol;
+      OBJSTAT (objfile, n_syms++);
 
-      sym->set_language (language_c, &ccp->objfile->objfile_obstack);
-      sym->compute_and_set_names (name, false, ccp->objfile->per_bfd);
+      sym->set_language (language_c, &objfile->objfile_obstack);
+      sym->compute_and_set_names (name, false, objfile->per_bfd);
       sym->set_loc_class_index (LOC_CONST);
       sym->set_domain (VAR_DOMAIN);
       sym->set_type (fip->ptype);
@@ -468,7 +472,7 @@ new_type_symbol (struct ctf_context *ccp, struct type *type, ctf_id_t tid)
   const char *name = ctf_type_name_raw (dict, tid);
   if (name != nullptr && *name != '\0')
     {
-      struct objfile *objfile = ccp->objfile;
+      objfile *objfile = ccp->per_objfile->objfile;
       struct symbol *sym = new (&objfile->objfile_obstack) symbol;
       OBJSTAT (objfile, n_syms++);
 
@@ -500,7 +504,7 @@ new_type_symbol (struct ctf_context *ccp, struct type *type, ctf_id_t tid)
 static struct type *
 read_base_type (struct ctf_context *ccp, ctf_id_t tid)
 {
-  struct objfile *objfile = ccp->objfile;
+  objfile *objfile = ccp->per_objfile->objfile;
   ctf_dict_t *dict = ccp->dict;
   ctf_encoding_t cet;
   struct type *type = nullptr;
@@ -594,7 +598,7 @@ process_base_type (struct ctf_context *ccp, ctf_id_t tid)
 static struct type *
 read_structure_type (struct ctf_context *ccp, ctf_id_t tid)
 {
-  struct objfile *objfile = ccp->objfile;
+  objfile *objfile = ccp->per_objfile->objfile;
   ctf_dict_t *dict = ccp->dict;
   struct type *type;
   uint32_t kind;
@@ -614,7 +618,7 @@ read_structure_type (struct ctf_context *ccp, ctf_id_t tid)
   type->set_length (ctf_type_size (dict, tid));
   set_type_align (type, ctf_type_align (dict, tid));
 
-  return set_tid_type (ccp->objfile, tid, type);
+  return set_tid_type (objfile, tid, type);
 }
 
 /* Given a tid of CTF_K_STRUCT or CTF_K_UNION, process all its members
@@ -652,7 +656,7 @@ process_structure_type (struct ctf_context *ccp, ctf_id_t tid)
 static struct type *
 read_func_kind_type (struct ctf_context *ccp, ctf_id_t tid)
 {
-  struct objfile *objfile = ccp->objfile;
+  objfile *objfile = ccp->per_objfile->objfile;
   ctf_dict_t *dict = ccp->dict;
   struct type *type, *rettype, *atype;
   ctf_funcinfo_t cfi;
@@ -705,7 +709,7 @@ read_func_kind_type (struct ctf_context *ccp, ctf_id_t tid)
 static struct type *
 read_enum_type (struct ctf_context *ccp, ctf_id_t tid)
 {
-  struct objfile *objfile = ccp->objfile;
+  objfile *objfile = ccp->per_objfile->objfile;
   ctf_dict_t *dict = ccp->dict;
   struct type *type;
 
@@ -769,7 +773,7 @@ add_array_cv_type (struct ctf_context *ccp,
   voltl |= TYPE_VOLATILE (el_type);
   inner_array->set_target_type (make_cv_type (cnst, voltl, el_type));
 
-  return set_tid_type (ccp->objfile, tid, base_type);
+  return set_tid_type (ccp->per_objfile->objfile, tid, base_type);
 }
 
 /* Read all information from a TID of CTF_K_ARRAY.  */
@@ -777,7 +781,7 @@ add_array_cv_type (struct ctf_context *ccp,
 static struct type *
 read_array_type (struct ctf_context *ccp, ctf_id_t tid)
 {
-  struct objfile *objfile = ccp->objfile;
+  objfile *objfile = ccp->per_objfile->objfile;
   ctf_dict_t *dict = ccp->dict;
   struct type *element_type, *range_type, *idx_type;
   struct type *type;
@@ -820,7 +824,7 @@ read_array_type (struct ctf_context *ccp, ctf_id_t tid)
 static struct type *
 read_const_type (struct ctf_context *ccp, ctf_id_t tid, ctf_id_t btid)
 {
-  struct objfile *objfile = ccp->objfile;
+  objfile *objfile = ccp->per_objfile->objfile;
   struct type *base_type, *cv_type;
 
   base_type = fetch_tid_type (ccp, btid);
@@ -843,7 +847,7 @@ read_const_type (struct ctf_context *ccp, ctf_id_t tid, ctf_id_t btid)
 static struct type *
 read_volatile_type (struct ctf_context *ccp, ctf_id_t tid, ctf_id_t btid)
 {
-  struct objfile *objfile = ccp->objfile;
+  objfile *objfile = ccp->per_objfile->objfile;
   ctf_dict_t *dict = ccp->dict;
   struct type *base_type, *cv_type;
 
@@ -870,7 +874,7 @@ read_volatile_type (struct ctf_context *ccp, ctf_id_t tid, ctf_id_t btid)
 static struct type *
 read_restrict_type (struct ctf_context *ccp, ctf_id_t tid, ctf_id_t btid)
 {
-  struct objfile *objfile = ccp->objfile;
+  objfile *objfile = ccp->per_objfile->objfile;
   struct type *base_type, *cv_type;
 
   base_type = fetch_tid_type (ccp, btid);
@@ -894,7 +898,7 @@ 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->objfile;
+  objfile *objfile = ccp->per_objfile->objfile;
   struct type *this_type, *target_type;
 
   char *aname = obstack_strdup (&objfile->objfile_obstack, name);
@@ -917,7 +921,7 @@ read_typedef_type (struct ctf_context *ccp, ctf_id_t tid,
 static struct type *
 read_pointer_type (struct ctf_context *ccp, ctf_id_t tid, ctf_id_t btid)
 {
-  struct objfile *objfile = ccp->objfile;
+  objfile *objfile = ccp->per_objfile->objfile;
   struct type *target_type, *type;
 
   target_type = fetch_tid_type (ccp, btid);
@@ -927,7 +931,7 @@ read_pointer_type (struct ctf_context *ccp, ctf_id_t tid, ctf_id_t btid)
       if (target_type == nullptr)
 	{
 	  complaint (_("read_pointer_type: NULL target type (%ld)"), btid);
-	  target_type = builtin_type (ccp->objfile)->builtin_error;
+	  target_type = builtin_type (objfile)->builtin_error;
 	}
     }
 
@@ -942,7 +946,7 @@ read_pointer_type (struct ctf_context *ccp, ctf_id_t tid, ctf_id_t btid)
 static struct type *
 read_forward_type (struct ctf_context *ccp, ctf_id_t tid)
 {
-  struct objfile *objfile = ccp->objfile;
+  objfile *objfile = ccp->per_objfile->objfile;
   ctf_dict_t *dict = ccp->dict;
   struct type *type;
   uint32_t kind;
@@ -1040,7 +1044,7 @@ ctf_add_type_cb (ctf_id_t tid, void *arg)
   uint32_t kind;
 
   /* Check if tid's type has already been defined.  */
-  type = get_tid_type (ccp->objfile, tid);
+  type = get_tid_type (ccp->per_objfile->objfile, tid);
   if (type != nullptr)
     {
       ctf_debug_printf ("tid=%ld already defined, skipping", tid);
@@ -1112,8 +1116,9 @@ ctf_add_var_cb (const char *name, ctf_id_t id, void *arg)
   struct symbol *sym = nullptr;
   struct type *type;
   uint32_t kind;
+  objfile *objfile = ccp->per_objfile->objfile;
 
-  type = get_tid_type (ccp->objfile, id);
+  type = get_tid_type (objfile, id);
 
   kind = ctf_type_kind (ccp->dict, id);
 
@@ -1123,25 +1128,25 @@ ctf_add_var_cb (const char *name, ctf_id_t id, void *arg)
   if (type == nullptr)
     {
       complaint (_("ctf_add_var_cb: %s has NO type (%ld)"), name, id);
-      type = builtin_type (ccp->objfile)->builtin_error;
+      type = builtin_type (objfile)->builtin_error;
     }
-  sym = new (&ccp->objfile->objfile_obstack) symbol;
-  OBJSTAT (ccp->objfile, n_syms++);
+  sym = new (&objfile->objfile_obstack) symbol;
+  OBJSTAT (objfile, n_syms++);
   sym->set_type (type);
   sym->set_loc_class_index (LOC_OPTIMIZED_OUT);
-  sym->compute_and_set_names (name, false, ccp->objfile->per_bfd);
+  sym->compute_and_set_names (name, false, objfile->per_bfd);
 
   if (kind == CTF_K_FUNCTION)
     {
       sym->set_domain (FUNCTION_DOMAIN);
       if (name != nullptr && strcmp (name, "main") == 0)
-	set_objfile_main_name (ccp->objfile, name, language_c);
+	set_objfile_main_name (objfile, name, language_c);
     }
   else
     sym->set_domain (VAR_DOMAIN);
 
   add_symbol_to_list (sym, ccp->builder->get_global_symbols ());
-  set_symbol_address (ccp->objfile, sym, name);
+  set_symbol_address (objfile, sym, name);
 
   return 0;
 }
@@ -1160,25 +1165,26 @@ add_stt_entries (struct ctf_context *ccp, int functions)
 
   while ((tid = ctf_symbol_next (ccp->dict, &i, &tname, functions)) != CTF_ERR)
     {
-      type = get_tid_type (ccp->objfile, tid);
+      objfile *objfile = ccp->per_objfile->objfile;
+      type = get_tid_type (objfile, tid);
       if (type == nullptr)
 	{
-	  ctf_debug_printf ("skipping '%s' tid=0x%lx (no type found)",
-			    tname, tid);
+	  ctf_debug_printf ("skipping '%s' tid=0x%lx (no type found)", tname,
+			    tid);
 	  continue;
 	}
 
       ctf_debug_printf ("adding %s '%s' tid=0x%lx",
 			functions ? "function" : "object", tname, tid);
 
-      sym = new (&ccp->objfile->objfile_obstack) symbol;
-      OBJSTAT (ccp->objfile, n_syms++);
+      sym = new (&objfile->objfile_obstack) symbol;
+      OBJSTAT (objfile, n_syms++);
       sym->set_type (type);
       sym->set_domain (functions ? FUNCTION_DOMAIN : VAR_DOMAIN);
       sym->set_loc_class_index (LOC_STATIC);
-      sym->compute_and_set_names (tname, false, ccp->objfile->per_bfd);
+      sym->compute_and_set_names (tname, false, objfile->per_bfd);
       add_symbol_to_list (sym, ccp->builder->get_global_symbols ());
-      set_symbol_address (ccp->objfile, sym, tname);
+      set_symbol_address (objfile, sym, tname);
     }
 }
 
@@ -1222,11 +1228,10 @@ ctf_psymtab_add_enums (struct ctf_context *ccp, ctf_id_t tid)
 
   while ((ename = ctf_enum_next (ccp->dict, 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->objfile);
+      ccp->pst->add_psymbol (ename, true, VAR_DOMAIN, LOC_CONST, -1,
+			     psymbol_placement::GLOBAL, unrelocated_addr (0),
+			     language_c, ccp->partial_symtabs,
+			     ccp->per_objfile->objfile);
     }
   if (ctf_errno (ccp->dict) != ECTF_NEXT_END)
     complaint (_("ctf_enum_next ctf_psymtab_add_enums failed - %s"),
@@ -1237,8 +1242,7 @@ ctf_psymtab_add_enums (struct ctf_context *ccp, ctf_id_t tid)
    by FUNCTIONS, to psymtab.  */
 
 static void
-ctf_psymtab_add_stt_entries (ctf_dict_t *dict, ctf_psymtab *pst,
-			     struct objfile *objfile, int functions)
+ctf_psymtab_add_stt_entries (ctf_dict_t *dict, ctf_psymtab *pst, int functions)
 {
   ctf_next_t *i = nullptr;
   ctf_id_t tid;
@@ -1259,30 +1263,27 @@ ctf_psymtab_add_stt_entries (ctf_dict_t *dict, ctf_psymtab *pst,
 			functions ? "function" : "object", tname, tid,
 			ctf_kind_str (kind));
 
-      pst->add_psymbol (tname, true,
-			tdomain, loc_class, -1,
-			psymbol_placement::GLOBAL,
-			unrelocated_addr (0),
-			language_c, pst->context.partial_symtabs, objfile);
+      pst->add_psymbol (tname, true, tdomain, loc_class, -1,
+			psymbol_placement::GLOBAL, unrelocated_addr (0),
+			language_c, pst->context.partial_symtabs,
+			pst->context.per_objfile->objfile);
     }
 }
 
 /* Add entries in data objects section to psymtab.  */
 
 static void
-ctf_psymtab_add_stt_obj (ctf_dict_t *dict, ctf_psymtab *pst,
-			 struct objfile *objfile)
+ctf_psymtab_add_stt_obj (ctf_dict_t *dict, ctf_psymtab *pst)
 {
-  ctf_psymtab_add_stt_entries (dict, pst, objfile, 0);
+  ctf_psymtab_add_stt_entries (dict, pst, 0);
 }
 
 /* Add entries in function info section to psymtab.  */
 
 static void
-ctf_psymtab_add_stt_func (ctf_dict_t *dict, ctf_psymtab *pst,
-			  struct objfile *objfile)
+ctf_psymtab_add_stt_func (ctf_dict_t *dict, ctf_psymtab *pst)
 {
-  ctf_psymtab_add_stt_entries (dict, pst, objfile, 1);
+  ctf_psymtab_add_stt_entries (dict, pst, 1);
 }
 
 /* Read in full symbols for PST, and anything it depends on.  */
@@ -1375,19 +1376,17 @@ ctf_psymtab::read_symtab (struct objfile *objfile)
 
 static ctf_psymtab *
 create_partial_symtab (const char *name,
-		       ctf_archive_t *arc,
 		       ctf_dict_t *dict,
 		       psymtab_storage *partial_symtabs,
-		       struct objfile *objfile)
+		       ctf_per_objfile *per_objfile)
 {
   ctf_psymtab *pst;
 
-  pst = new ctf_psymtab (name, partial_symtabs, objfile->per_bfd,
+  pst = new ctf_psymtab (name, partial_symtabs, per_objfile->objfile->per_bfd,
 			 unrelocated_addr (0));
 
-  pst->context.arc = arc;
+  pst->context.per_objfile = per_objfile;
   pst->context.dict = dict;
-  pst->context.objfile = objfile;
   pst->context.partial_symtabs = partial_symtabs;
   pst->context.pst = pst;
   pst->context.builder = nullptr;
@@ -1443,11 +1442,10 @@ ctf_psymtab_type_cb (ctf_id_t tid, void *arg)
   ctf_debug_printf ("adding type tid=0x%lx kind=%s name='%s'",
 		    tid, ctf_kind_str (kind), name);
 
-  ccp->pst->add_psymbol (name, false,
-			 domain, loc_class, section,
-			 psymbol_placement::GLOBAL,
-			 unrelocated_addr (0),
-			 language_c, ccp->partial_symtabs, ccp->objfile);
+  ccp->pst->add_psymbol (name, false, domain, loc_class, section,
+			 psymbol_placement::GLOBAL, unrelocated_addr (0),
+			 language_c, ccp->partial_symtabs,
+			 ccp->per_objfile->objfile);
 
   return 0;
 }
@@ -1465,13 +1463,10 @@ ctf_psymtab_var_cb (const char *name, ctf_id_t id, void *arg)
 		    name, id, ctf_kind_str (kind));
 
   ccp->pst->add_psymbol (name, true,
-			 kind == CTF_K_FUNCTION
-			 ? FUNCTION_DOMAIN
-			 : VAR_DOMAIN,
-			 LOC_STATIC, -1,
-			 psymbol_placement::GLOBAL,
-			 unrelocated_addr (0),
-			 language_c, ccp->partial_symtabs, ccp->objfile);
+			 kind == CTF_K_FUNCTION ? FUNCTION_DOMAIN : VAR_DOMAIN,
+			 LOC_STATIC, -1, psymbol_placement::GLOBAL,
+			 unrelocated_addr (0), language_c,
+			 ccp->partial_symtabs, ccp->per_objfile->objfile);
   return 0;
 }
 
@@ -1480,10 +1475,9 @@ ctf_psymtab_var_cb (const char *name, ctf_id_t id, void *arg)
 
 static void
 scan_partial_symbols (ctf_dict_t *dict, psymtab_storage *partial_symtabs,
-		      ctf_archive_iter_psymtab_data *iter_data,
-		      const char *fname)
+		      ctf_per_objfile *per_objfile, const char *fname)
 {
-  objfile *objfile = iter_data->objfile;
+  objfile *objfile = per_objfile->objfile;
   bool isparent = false;
 
   CTF_SCOPED_DEBUG_START_END ("fname='%s'", fname);
@@ -1495,8 +1489,8 @@ scan_partial_symbols (ctf_dict_t *dict, psymtab_storage *partial_symtabs,
       ctf_debug_printf ("is parent, using fname='%s'", fname);
     }
 
-  ctf_psymtab *pst = create_partial_symtab (fname, iter_data->archive, dict,
-					    partial_symtabs, objfile);
+  ctf_psymtab *pst = create_partial_symtab (fname, dict, partial_symtabs,
+					    per_objfile);
 
   struct ctf_context *ccx = &pst->context;
   if (isparent == false)
@@ -1513,8 +1507,8 @@ scan_partial_symbols (ctf_dict_t *dict, psymtab_storage *partial_symtabs,
   /* 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 (dict, pst, objfile);
-  ctf_psymtab_add_stt_func (dict, pst, objfile);
+  ctf_psymtab_add_stt_obj (dict, pst);
+  ctf_psymtab_add_stt_func (dict, pst);
 
   pst->end ();
 }
@@ -1525,9 +1519,10 @@ static int
 build_ctf_archive_member (ctf_dict_t *dict, const char *name, void *arg)
 {
   auto iter_data = static_cast<ctf_archive_iter_psymtab_data *> (arg);
+  ctf_per_objfile *per_objfile = iter_data->per_objfile;
 
   if (strcmp (name, ".ctf") != 0)
-    ctf_import (dict, iter_data->parent_dict);
+    ctf_import (dict, per_objfile->parent_dict.get ());
 
   if (info_verbose)
     {
@@ -1536,7 +1531,7 @@ build_ctf_archive_member (ctf_dict_t *dict, const char *name, void *arg)
     }
 
   psymtab_storage *pss = iter_data->psf->get_partial_symtabs ().get ();
-  scan_partial_symbols (dict, pss, iter_data, name);
+  scan_partial_symbols (dict, pss, per_objfile, name);
 
   return 0;
 }
@@ -1565,19 +1560,16 @@ elfctf_build_psymtabs (objfile *objfile)
 	   bfd_get_filename (abfd), ctf_errmsg (err));
 
   ctf_per_objfile &per_objfile
-    = ctf_per_objfile_key.emplace (objfile, std::move (archive),
+    = ctf_per_objfile_key.emplace (objfile, objfile, std::move (archive),
 				   std::move (dict));
-
-  ctf_archive_iter_psymtab_data iter_data;
-  iter_data.parent_dict = per_objfile.parent_dict.get ();
-  iter_data.objfile = objfile;
-  iter_data.archive = per_objfile.archive.get ();
-
   psymbol_functions *psf = new psymbol_functions ();
+
   objfile->qf.emplace_front (psf);
-  iter_data.psf = psf;
 
-  if (ctf_archive_iter (iter_data.archive, build_ctf_archive_member, &iter_data)
+  ctf_archive_iter_psymtab_data iter_data { &per_objfile, psf };
+
+  if (ctf_archive_iter (per_objfile.archive.get (), build_ctf_archive_member,
+			&iter_data)
       < 0)
     error (_("ctf_archive_iter failed in input file %s: - %s"),
 	   bfd_get_filename (abfd), ctf_errmsg (err));
-- 
2.53.0


^ permalink raw reply	[flat|nested] 52+ messages in thread

* [PATCH v2 5/9] gdb/ctf: check return value of ctf_type_align
  2026-02-17 19:50 ` [PATCH v2 0/9] " simon.marchi
                     ` (3 preceding siblings ...)
  2026-02-17 19:50   ` [PATCH v2 4/9] gdb/ctf: use ctf_per_objfile in ctf_archive_iter_psymtab_data and ctf_context simon.marchi
@ 2026-02-17 19:50   ` simon.marchi
  2026-02-17 19:50   ` [PATCH v2 6/9] gdb/ctf: add scoped_time_it in elfctf_build_psymtabs simon.marchi
                     ` (4 subsequent siblings)
  9 siblings, 0 replies; 52+ messages in thread
From: simon.marchi @ 2026-02-17 19:50 UTC (permalink / raw)
  To: gdb-patches; +Cc: Simon Marchi

From: Simon Marchi <simon.marchi@polymtl.ca>

I tried to build the Linux kernel with -gctf.  I am not sure if the
result is good, because I got plenty of warnings like:

    ld: warning: orphan section `.ctf' from `vmlinux.o' being placed in section `.ctf'

Nevertheless, I tried to load it in GDB, and it didn't complain.
However, when doing "maint expand-symtabs", I did hit this assert:

    /home/simark/src/binutils-gdb/gdb/gdbtypes.c:3640: internal-error: set_type_align: Assertion `(align & (align - 1)) == 0' failed.

This is because ctf_type_align returns -1 for some types, which is an
indication of an error.  Update the code to check the return value of
ctf_type_align for errors, and emit complaints if it happens.

With this patch, if I enable the complaints, I see a bunch of messages
like this:

    During symbol reading: ctf_type_align read_structure_type failed - Type is not a complete type.

Change-Id: Ibed23e7f1490d9163b8dde1318b9e45dec2906d6
---
 gdb/ctfread.c | 40 +++++++++++++++++++++++++++++++++++-----
 1 file changed, 35 insertions(+), 5 deletions(-)

diff --git a/gdb/ctfread.c b/gdb/ctfread.c
index c8457a70cf46..ed4a7383427d 100644
--- a/gdb/ctfread.c
+++ b/gdb/ctfread.c
@@ -616,7 +616,14 @@ read_structure_type (struct ctf_context *ccp, ctf_id_t tid)
     type->set_code (TYPE_CODE_STRUCT);
 
   type->set_length (ctf_type_size (dict, tid));
-  set_type_align (type, ctf_type_align (dict, tid));
+
+  if (ssize_t align = ctf_type_align (dict, tid);
+      align >= 0)
+    set_type_align (type, align);
+  else
+    complaint (_("ctf_type_align read_structure_type failed - %s"),
+	       ctf_errmsg (ctf_errno (dict)));
+
 
   return set_tid_type (objfile, tid, type);
 }
@@ -673,7 +680,13 @@ read_func_kind_type (struct ctf_context *ccp, ctf_id_t tid)
     }
   rettype = fetch_tid_type (ccp, cfi.ctc_return);
   type->set_target_type (rettype);
-  set_type_align (type, ctf_type_align (dict, tid));
+
+  if (ssize_t align = ctf_type_align (dict, tid);
+      align >= 0)
+    set_type_align (type, align);
+  else
+    complaint (_("ctf_type_align read_func_kind_type failed - %s"),
+	       ctf_errmsg (ctf_errno (dict)));
 
   /* Set up function's arguments.  */
   argc = cfi.ctc_argc;
@@ -723,7 +736,13 @@ read_enum_type (struct ctf_context *ccp, ctf_id_t tid)
   type->set_length (ctf_type_size (dict, tid));
   /* Set the underlying type based on its ctf_type_size bits.  */
   type->set_target_type (objfile_int_type (objfile, type->length (), false));
-  set_type_align (type, ctf_type_align (dict, tid));
+
+  if (ssize_t align = ctf_type_align (dict, tid);
+      align >= 0)
+    set_type_align (type, align);
+  else
+    complaint (_("ctf_type_align read_enum_type failed - %s"),
+	       ctf_errmsg (ctf_errno (dict)));
 
   return set_tid_type (objfile, tid, type);
 }
@@ -814,7 +833,12 @@ read_array_type (struct ctf_context *ccp, ctf_id_t tid)
   else
     type->set_length (ctf_type_size (dict, tid));
 
-  set_type_align (type, ctf_type_align (dict, tid));
+  if (ssize_t align = ctf_type_align (dict, tid);
+      align >= 0)
+    set_type_align (type, align);
+  else
+    complaint (_("ctf_type_align read_array_type failed - %s"),
+	       ctf_errmsg (ctf_errno (dict)));
 
   return set_tid_type (objfile, tid, type);
 }
@@ -936,7 +960,13 @@ read_pointer_type (struct ctf_context *ccp, ctf_id_t tid, ctf_id_t btid)
     }
 
   type = lookup_pointer_type (target_type);
-  set_type_align (type, ctf_type_align (ccp->dict, tid));
+
+  if (ssize_t align = ctf_type_align (ccp->dict, tid);
+      align >= 0)
+    set_type_align (type, align);
+  else
+    complaint (_("ctf_type_align read_pointer_type failed - %s"),
+	       ctf_errmsg (ctf_errno (ccp->dict)));
 
   return set_tid_type (objfile, tid, type);
 }
-- 
2.53.0


^ permalink raw reply	[flat|nested] 52+ messages in thread

* [PATCH v2 6/9] gdb/ctf: add scoped_time_it in elfctf_build_psymtabs
  2026-02-17 19:50 ` [PATCH v2 0/9] " simon.marchi
                     ` (4 preceding siblings ...)
  2026-02-17 19:50   ` [PATCH v2 5/9] gdb/ctf: check return value of ctf_type_align simon.marchi
@ 2026-02-17 19:50   ` simon.marchi
  2026-02-17 19:50   ` [PATCH v2 7/9] gdb: make expanded_symbols_functions hold compunit symtabs simon.marchi
                     ` (3 subsequent siblings)
  9 siblings, 0 replies; 52+ messages in thread
From: simon.marchi @ 2026-02-17 19:50 UTC (permalink / raw)
  To: gdb-patches; +Cc: Simon Marchi

From: Simon Marchi <simon.marchi@polymtl.ca>

This will be useful to determine the impact on the startup time getting
rid of partial symtabs has.

I use it like so:

    $ ./gdb -q -nx --data-directory=data-directory -iex "maint set per-command time on" /home/simark/src/linux/vmlinux.unstripped -batch
    ...
    Time for "elfctf_build_psymtabs": wall 0.381, user 0.357, sys 0.015, user+sys 0.372, 97.6 % CPU

Change-Id: I021319212f27eee0bf0f6c230f4e7cdd9c3602c1
---
 gdb/ctfread.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/gdb/ctfread.c b/gdb/ctfread.c
index ed4a7383427d..251b1c7f1fce 100644
--- a/gdb/ctfread.c
+++ b/gdb/ctfread.c
@@ -79,6 +79,7 @@
 #include "complaints.h"
 #include "block.h"
 #include "ctfread.h"
+#include "maint.h"
 #include "psymtab.h"
 #include "cli/cli-cmds.h"
 
@@ -1576,6 +1577,8 @@ elfctf_build_psymtabs (objfile *objfile)
   bfd *abfd = objfile->obfd.get ();
   int err;
 
+  scoped_time_it time_it (__func__);
+
   CTF_SCOPED_DEBUG_START_END ("building psymtabs for %s",
 			      bfd_get_filename (abfd));
 
-- 
2.53.0


^ permalink raw reply	[flat|nested] 52+ messages in thread

* [PATCH v2 7/9] gdb: make expanded_symbols_functions hold compunit symtabs
  2026-02-17 19:50 ` [PATCH v2 0/9] " simon.marchi
                     ` (5 preceding siblings ...)
  2026-02-17 19:50   ` [PATCH v2 6/9] gdb/ctf: add scoped_time_it in elfctf_build_psymtabs simon.marchi
@ 2026-02-17 19:50   ` simon.marchi
  2026-02-17 19:50   ` [PATCH v2 8/9] gdb/ctf: don't use psymtabs, create symtabs directly simon.marchi
                     ` (2 subsequent siblings)
  9 siblings, 0 replies; 52+ messages in thread
From: simon.marchi @ 2026-02-17 19:50 UTC (permalink / raw)
  To: gdb-patches; +Cc: Simon Marchi

From: Simon Marchi <simon.marchi@polymtl.ca>

Change the expanded_symbols_functions quick functions type to hold and
use a list of compunit symtab to search.

Currently, an expanded_symbols_functions instance will search all the
compunits in the objfile.  This is not efficient if an
expanded_symbols_functions instance exists alongside another quick
functions object in an objfile, as the compunits belonging to that other
object will be unnecessarily searched.

And at worst, I think it could be a source of subtle bugs.  For
instance, if the order of quick functions determine the order in which
we want the search to happen (the comment in elf_symfile_read suggests
this is the case), then having expanded_symbols_functions search the
compunits from other quick functions objects would not respect that
ordering.

Update the expanded_symbols_functions constructor to accept a vector of
compunits and store this vector in a field.  Update
expanded_symbols_functions methods to use that vector instead of the
objfile's compunits.

Right now the sole user of expanded_symbols_functions is JIT.  Update it
to keep a vector of compunits as they are finalized, and pass this
vector to the expanded_symbols_functions object.

Change-Id: Idf8de18b25fd3f71766166d6f420184af3c26b7e
---
 gdb/expanded-symbol.c | 16 ++++++++--------
 gdb/expanded-symbol.h |  8 ++++++++
 gdb/jit.c             | 16 ++++++++++++----
 3 files changed, 28 insertions(+), 12 deletions(-)

diff --git a/gdb/expanded-symbol.c b/gdb/expanded-symbol.c
index 050608795f93..d885fe33fa84 100644
--- a/gdb/expanded-symbol.c
+++ b/gdb/expanded-symbol.c
@@ -28,10 +28,10 @@
 symtab *
 expanded_symbols_functions::find_last_source_symtab (objfile *objfile)
 {
-  if (objfile->compunit_symtabs.empty ())
+  if (m_compunit_symtabs.empty ())
     return nullptr;
   else
-    return objfile->compunit_symtabs.back ().primary_filetab ();
+    return m_compunit_symtabs.back ()->primary_filetab ();
 }
 
 /* See expanded-symbol.h.  */
@@ -61,15 +61,15 @@ expanded_symbols_functions::search
   /* This invariant is documented in quick-functions.h.  */
   gdb_assert (lookup_name != nullptr || symbol_matcher == nullptr);
 
-  for (compunit_symtab &cu : objfile->compunits ())
+  for (compunit_symtab *cu : m_compunit_symtabs)
     {
-      if (lang_matcher != nullptr && !lang_matcher (cu.language ()))
+      if (lang_matcher != nullptr && !lang_matcher (cu->language ()))
 	continue;
 
       if (file_matcher != nullptr)
 	{
 	  bool matched = false;
-	  for (auto st : cu.filetabs ())
+	  for (auto st : cu->filetabs ())
 	    {
 	      if (file_matcher (st->filename (), false))
 		{
@@ -92,7 +92,7 @@ expanded_symbols_functions::search
 	 consult lookup_name and symbol_matcher (if any).  This should be
 	 okay since i) all symtabs are already expanded and ii) listeners
 	 iterate over matching symbols themselves.  */
-      if (listener != nullptr && !listener (&cu))
+      if (listener != nullptr && !listener (cu))
 	return false;
     }
   return true;
@@ -104,9 +104,9 @@ symbol *
 expanded_symbols_functions::find_symbol_by_address (objfile *objfile,
 						    CORE_ADDR address)
 {
-  for (compunit_symtab &symtab : objfile->compunits ())
+  for (compunit_symtab *symtab : m_compunit_symtabs)
     {
-      symbol *sym = symtab.symbol_at_address (address);
+      symbol *sym = symtab->symbol_at_address (address);
       if (sym != nullptr)
 	return sym;
     }
diff --git a/gdb/expanded-symbol.h b/gdb/expanded-symbol.h
index c088d74f7e59..885390ccb124 100644
--- a/gdb/expanded-symbol.h
+++ b/gdb/expanded-symbol.h
@@ -29,6 +29,11 @@
 
 struct expanded_symbols_functions : public quick_symbol_functions
 {
+  explicit expanded_symbols_functions
+    (std::vector<compunit_symtab *> compunit_symtabs)
+    : m_compunit_symtabs (std::move (compunit_symtabs))
+  {}
+
   bool has_symbols (objfile *objfile) override
   {
     return true;
@@ -86,6 +91,9 @@ struct expanded_symbols_functions : public quick_symbol_functions
 			     bool need_fullname) override
   {
   }
+
+private:
+  std::vector<compunit_symtab *> m_compunit_symtabs;
 };
 
 
diff --git a/gdb/jit.c b/gdb/jit.c
index 21e8667a7af6..5fa3869316c3 100644
--- a/gdb/jit.c
+++ b/gdb/jit.c
@@ -513,9 +513,11 @@ jit_symtab_close_impl (struct gdb_symbol_callbacks *cb,
      ABI).  */
 }
 
-/* Transform STAB to a proper symtab, and add it it OBJFILE.  */
+/* Transform STAB to a proper symtab, and add it it OBJFILE.
 
-static void
+   Return the created symtab.  */
+
+static compunit_symtab *
 finalize_symtab (struct gdb_symtab *stab, struct objfile *objfile)
 {
   CORE_ADDR begin, end;
@@ -653,6 +655,8 @@ finalize_symtab (struct gdb_symtab *stab, struct objfile *objfile)
 
   /* Move just built blockvector over to CUST.  */
   cust->set_blockvector (std::move (bv));
+
+  return cust;
 }
 
 /* Called when closing a gdb_objfile.  Converts OBJ to a proper
@@ -673,10 +677,14 @@ jit_object_close_impl (struct gdb_symbol_callbacks *cb,
   objfile->section_offsets.push_back (0);
   objfile->sect_index_text = 0;
   objfile->per_bfd->gdbarch = priv_data->gdbarch;
-  objfile->qf.emplace_front (new expanded_symbols_functions);
+
+  std::vector<compunit_symtab *> compunit_symtabs;
 
   for (gdb_symtab &symtab : obj->symtabs)
-    finalize_symtab (&symtab, objfile);
+    compunit_symtabs.emplace_back (finalize_symtab (&symtab, objfile));
+
+  objfile->qf.emplace_front (std::make_unique<expanded_symbols_functions>
+			     (std::move (compunit_symtabs)));
 
   add_objfile_entry (objfile, priv_data->entry_addr,
 		     priv_data->entry.symfile_addr,
-- 
2.53.0


^ permalink raw reply	[flat|nested] 52+ messages in thread

* [PATCH v2 8/9] gdb/ctf: don't use psymtabs, create symtabs directly
  2026-02-17 19:50 ` [PATCH v2 0/9] " simon.marchi
                     ` (6 preceding siblings ...)
  2026-02-17 19:50   ` [PATCH v2 7/9] gdb: make expanded_symbols_functions hold compunit symtabs simon.marchi
@ 2026-02-17 19:50   ` simon.marchi
  2026-02-17 19:50   ` [PATCH v2 9/9] gdb: remove psymtab.{c,h} simon.marchi
  2026-02-28  3:51   ` [PATCH v3 0/9] Make CTF reader build full symtabs, get rid of psymtab Simon Marchi
  9 siblings, 0 replies; 52+ messages in thread
From: simon.marchi @ 2026-02-17 19:50 UTC (permalink / raw)
  To: gdb-patches; +Cc: Simon Marchi

From: Simon Marchi <simon.marchi@polymtl.ca>

The CTF debug info reader is the last user of partial symtabs.  Being a
fairly limited debug info format, CTF only uses a fraction of the
psymtab features.  So I see 3 ways forward:

 - keep psymtabs but trim them down, removing everything not useful for
   CTF

 - make the CTF reader implement its own index-like structure that
   implements the quick_symbol_functions interface (which would
   presumably be a small subset of partial symtabs)

 - make the CTF reader skip partial symtabs, create full symtabs
   directly

My hypothesis is that CTF debug info is typically small enough and fast
enough to process that it's not worth it to bother with an intermediate
step before full symbols.  But I will need help to see if this is true,
I'm not sure what representatively big C project I can build with CTF
debug info.  I tried to build the Linux kernel with -gctf, but I got
plenty of warnings like:

  ld: warning: orphan section `.ctf' from `vmlinux.o' being placed in section `.ctf'

GDB is still able to load the resulting ELF, and there are about 150k
calls to ctf_add_type_cb.  Before this patch, elfctf_build_psymtabs
takes anywhere between 300-350 ms.  With this patch, it's around 400 ms.

Implementation
--------------

This patch gets rid of the ctf_psymtab step, creating full symtabs from
the start.

The entry point elfctf_build_psymtabs gets renamed to
elfctf_build_symtabs.

Everything related to ctf_psymtab or partial symtabs is removed.

The build_ctf_archive_member function nows contains the code to build a
full symtab out of one CTF dict.  This code is not new for the most
part, it has been moved from other functions that used to be called when
expanding one symtab.

In order to access the symtabs, elfctf_build_symtabs installs the
expanded_symbols_functions quick_symbol_functions implementation, which
essentially searches in the existing symtabs.  I am pretty sure this is
not 100% correct, because this would search unrelated symtabs, if for
instance the CTF debug info co-existed with DWARF info.  But it's good
enough for a prototype.

Change-Id: I728c1ef35785218c178fb467b80db71d59269a6d
---
 gdb/ctfread.c | 440 +++++++++-----------------------------------------
 gdb/ctfread.h |   2 +-
 gdb/elfread.c |   8 +-
 3 files changed, 83 insertions(+), 367 deletions(-)

diff --git a/gdb/ctfread.c b/gdb/ctfread.c
index 251b1c7f1fce..dc8a32898e0e 100644
--- a/gdb/ctfread.c
+++ b/gdb/ctfread.c
@@ -79,9 +79,11 @@
 #include "complaints.h"
 #include "block.h"
 #include "ctfread.h"
-#include "maint.h"
-#include "psymtab.h"
 #include "cli/cli-cmds.h"
+#include "expanded-symbol.h"
+#include "maint.h"
+#include "objfiles.h"
+#include "progspace.h"
 
 /* When true, print debug messages related to CTF reading.  */
 static bool debug_ctf = false;
@@ -158,9 +160,6 @@ struct ctf_per_objfile
   /* Backlink to objfile.  */
   struct objfile *objfile;
 
-  /* Map from IDs to types.  */
-  ctf_type_map type_map;
-
   /* The archive and parent dictionary.  */
   ctf_archive_up archive;
   ctf_dict_up parent_dict;
@@ -174,26 +173,10 @@ struct ctf_context
 {
   ctf_per_objfile *per_objfile;
   ctf_dict_t *dict;
-  psymtab_storage *partial_symtabs;
-  partial_symtab *pst;
   struct buildsym_compunit *builder;
-};
-
-/* A partial symtab, specialized for this module.  */
-struct ctf_psymtab : public standard_psymtab
-{
-  ctf_psymtab (const char *filename,
-	       psymtab_storage *partial_symtabs,
-	       objfile_per_bfd_storage *objfile_per_bfd,
-	       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;
+  /* Map from IDs to types.  */
+  ctf_type_map type_map;
 };
 
 /* The routines that read and process fields/members of a C struct, union,
@@ -225,14 +208,6 @@ struct ctf_field_info
   std::vector<struct decl_field> nested_types_list;
 };
 
-/* Data held while using ctf_archive_iter to build psymtabs.  */
-
-struct ctf_archive_iter_psymtab_data
-{
-  ctf_per_objfile *per_objfile;
-  psymbol_functions *psf;
-};
-
 /* Local function prototypes */
 
 static int ctf_add_type_cb (ctf_id_t tid, void *arg);
@@ -261,11 +236,9 @@ static struct type *read_forward_type (struct ctf_context *cp, ctf_id_t tid);
 /* Set the type associated with TID to TYP.  */
 
 static struct type *
-set_tid_type (struct objfile *objfile, ctf_id_t tid, struct type *typ)
+set_tid_type (ctf_context *ccp, ctf_id_t tid, struct type *typ)
 {
-  ctf_per_objfile *per_objfile = ctf_per_objfile_key.get (objfile);
-  gdb_assert (per_objfile != nullptr);
-  per_objfile->type_map.emplace (tid, typ);
+  ccp->type_map.emplace (tid, typ);
   return typ;
 }
 
@@ -273,13 +246,10 @@ set_tid_type (struct objfile *objfile, ctf_id_t tid, struct type *typ)
    does not have a saved type.  */
 
 static struct type *
-get_tid_type (struct objfile *objfile, ctf_id_t tid)
+get_tid_type (ctf_context *ccp, ctf_id_t tid)
 {
-  ctf_per_objfile *per_objfile = ctf_per_objfile_key.get (objfile);
-  gdb_assert (per_objfile != nullptr);
-
-  auto iter = per_objfile->type_map.find (tid);
-  if (iter == per_objfile->type_map.end ())
+  auto iter = ccp->type_map.find (tid);
+  if (iter == ccp->type_map.end ())
     return nullptr;
   return iter->second;
 }
@@ -290,14 +260,13 @@ get_tid_type (struct objfile *objfile, ctf_id_t tid)
 static struct type *
 fetch_tid_type (struct ctf_context *ccp, ctf_id_t tid)
 {
-  struct objfile *objfile = ccp->per_objfile->objfile;
   struct type *typ;
 
-  typ = get_tid_type (objfile, tid);
+  typ = get_tid_type (ccp, tid);
   if (typ == nullptr)
     {
       ctf_add_type_cb (tid, ccp);
-      typ = get_tid_type (objfile, tid);
+      typ = get_tid_type (ccp, tid);
     }
 
   return typ;
@@ -410,7 +379,7 @@ ctf_add_member_cb (const char *name,
 	  objfile *objfile = ccp->per_objfile->objfile;
 	  complaint (_("ctf_add_member_cb: %s has NO type (%ld)"), name, tid);
 	  t = builtin_type (objfile)->builtin_error;
-	  set_tid_type (objfile, tid, t);
+	  set_tid_type (ccp, tid, t);
 	}
     }
 
@@ -577,7 +546,7 @@ read_base_type (struct ctf_context *ccp, ctf_id_t tid)
   if (name != nullptr && strcmp (name, "char") == 0)
     type->set_has_no_signedness (true);
 
-  return set_tid_type (objfile, tid, type);
+  return set_tid_type (ccp, tid, type);
 }
 
 static void
@@ -626,7 +595,7 @@ read_structure_type (struct ctf_context *ccp, ctf_id_t tid)
 	       ctf_errmsg (ctf_errno (dict)));
 
 
-  return set_tid_type (objfile, tid, type);
+  return set_tid_type (ccp, tid, type);
 }
 
 /* Given a tid of CTF_K_STRUCT or CTF_K_UNION, process all its members
@@ -714,7 +683,7 @@ read_func_kind_type (struct ctf_context *ccp, ctf_id_t tid)
 	}
     }
 
-  return set_tid_type (objfile, tid, type);
+  return set_tid_type (ccp, tid, type);
 }
 
 /* Given a TID of CTF_K_ENUM, process all the members of the
@@ -745,7 +714,7 @@ read_enum_type (struct ctf_context *ccp, ctf_id_t tid)
     complaint (_("ctf_type_align read_enum_type failed - %s"),
 	       ctf_errmsg (ctf_errno (dict)));
 
-  return set_tid_type (objfile, tid, type);
+  return set_tid_type (ccp, tid, type);
 }
 
 static void
@@ -793,7 +762,7 @@ add_array_cv_type (struct ctf_context *ccp,
   voltl |= TYPE_VOLATILE (el_type);
   inner_array->set_target_type (make_cv_type (cnst, voltl, el_type));
 
-  return set_tid_type (ccp->per_objfile->objfile, tid, base_type);
+  return set_tid_type (ccp, tid, base_type);
 }
 
 /* Read all information from a TID of CTF_K_ARRAY.  */
@@ -841,7 +810,7 @@ read_array_type (struct ctf_context *ccp, ctf_id_t tid)
     complaint (_("ctf_type_align read_array_type failed - %s"),
 	       ctf_errmsg (ctf_errno (dict)));
 
-  return set_tid_type (objfile, tid, type);
+  return set_tid_type (ccp, tid, type);
 }
 
 /* Read TID of kind CTF_K_CONST with base type BTID.  */
@@ -864,7 +833,7 @@ read_const_type (struct ctf_context *ccp, ctf_id_t tid, ctf_id_t btid)
     }
   cv_type = make_cv_type (1, TYPE_VOLATILE (base_type), base_type);
 
-  return set_tid_type (objfile, tid, cv_type);
+  return set_tid_type (ccp, tid, cv_type);
 }
 
 /* Read TID of kind CTF_K_VOLATILE with base type BTID.  */
@@ -891,7 +860,7 @@ read_volatile_type (struct ctf_context *ccp, ctf_id_t tid, ctf_id_t btid)
     return add_array_cv_type (ccp, tid, base_type, 0, 1);
   cv_type = make_cv_type (TYPE_CONST (base_type), 1, base_type);
 
-  return set_tid_type (objfile, tid, cv_type);
+  return set_tid_type (ccp, tid, cv_type);
 }
 
 /* Read TID of kind CTF_K_RESTRICT with base type BTID.  */
@@ -914,7 +883,7 @@ read_restrict_type (struct ctf_context *ccp, ctf_id_t tid, ctf_id_t btid)
     }
   cv_type = make_restrict_type (base_type);
 
-  return set_tid_type (objfile, tid, cv_type);
+  return set_tid_type (ccp, tid, cv_type);
 }
 
 /* Read TID of kind CTF_K_TYPEDEF with its NAME and base type BTID.  */
@@ -929,7 +898,7 @@ read_typedef_type (struct ctf_context *ccp, ctf_id_t tid,
   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);
+  set_tid_type (ccp, tid, this_type);
   target_type = fetch_tid_type (ccp, btid);
   if (target_type != this_type)
     this_type->set_target_type (target_type);
@@ -969,7 +938,7 @@ read_pointer_type (struct ctf_context *ccp, ctf_id_t tid, ctf_id_t btid)
     complaint (_("ctf_type_align read_pointer_type failed - %s"),
 	       ctf_errmsg (ctf_errno (ccp->dict)));
 
-  return set_tid_type (objfile, tid, type);
+  return set_tid_type (ccp, tid, type);
 }
 
 /* Read information from a TID of CTF_K_FORWARD.  */
@@ -997,7 +966,7 @@ read_forward_type (struct ctf_context *ccp, ctf_id_t tid)
   type->set_length (0);
   type->set_is_stub (true);
 
-  return set_tid_type (objfile, tid, type);
+  return set_tid_type (ccp, tid, type);
 }
 
 /* Read information associated with type TID.  */
@@ -1075,7 +1044,7 @@ ctf_add_type_cb (ctf_id_t tid, void *arg)
   uint32_t kind;
 
   /* Check if tid's type has already been defined.  */
-  type = get_tid_type (ccp->per_objfile->objfile, tid);
+  type = get_tid_type (ccp, tid);
   if (type != nullptr)
     {
       ctf_debug_printf ("tid=%ld already defined, skipping", tid);
@@ -1149,7 +1118,7 @@ ctf_add_var_cb (const char *name, ctf_id_t id, void *arg)
   uint32_t kind;
   objfile *objfile = ccp->per_objfile->objfile;
 
-  type = get_tid_type (objfile, id);
+  type = get_tid_type (ccp, id);
 
   kind = ctf_type_kind (ccp->dict, id);
 
@@ -1197,7 +1166,7 @@ add_stt_entries (struct ctf_context *ccp, int functions)
   while ((tid = ctf_symbol_next (ccp->dict, &i, &tname, functions)) != CTF_ERR)
     {
       objfile *objfile = ccp->per_objfile->objfile;
-      type = get_tid_type (objfile, tid);
+      type = get_tid_type (ccp, tid);
       if (type == nullptr)
 	{
 	  ctf_debug_printf ("skipping '%s' tid=0x%lx (no type found)", tname,
@@ -1248,338 +1217,90 @@ get_objfile_text_range (struct objfile *objfile, size_t *tsize)
   return objfile->text_section_offset ();
 }
 
-/* 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)
+struct ctf_archive_iter_data
 {
-  int val;
-  const char *ename;
-  ctf_next_t *i = nullptr;
-
-  while ((ename = ctf_enum_next (ccp->dict, 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->per_objfile->objfile);
-    }
-  if (ctf_errno (ccp->dict) != ECTF_NEXT_END)
-    complaint (_("ctf_enum_next ctf_psymtab_add_enums failed - %s"),
-	       ctf_errmsg (ctf_errno (ccp->dict)));
-}
-
-/* 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 *dict, ctf_psymtab *pst, int functions)
-{
-  ctf_next_t *i = nullptr;
-  ctf_id_t tid;
-  const char *tname;
-
-  while ((tid = ctf_symbol_next (dict, &i, &tname, functions)) != CTF_ERR)
-    {
-      uint32_t kind = ctf_type_kind (dict, tid);
-      location_class loc_class;
-      domain_enum tdomain = functions ? FUNCTION_DOMAIN : VAR_DOMAIN;
-
-      if (kind == CTF_K_FUNCTION)
-	loc_class = LOC_BLOCK;
-      else
-	loc_class = LOC_STATIC;
-
-      ctf_debug_printf ("adding %s psym '%s' tid=0x%lx kind=%s",
-			functions ? "function" : "object", tname, tid,
-			ctf_kind_str (kind));
-
-      pst->add_psymbol (tname, true, tdomain, loc_class, -1,
-			psymbol_placement::GLOBAL, unrelocated_addr (0),
-			language_c, pst->context.partial_symtabs,
-			pst->context.per_objfile->objfile);
-    }
-}
-
-/* Add entries in data objects section to psymtab.  */
-
-static void
-ctf_psymtab_add_stt_obj (ctf_dict_t *dict, ctf_psymtab *pst)
-{
-  ctf_psymtab_add_stt_entries (dict, pst, 0);
-}
-
-/* Add entries in function info section to psymtab.  */
-
-static void
-ctf_psymtab_add_stt_func (ctf_dict_t *dict, ctf_psymtab *pst)
-{
-  ctf_psymtab_add_stt_entries (dict, pst, 1);
-}
+  ctf_per_objfile &per_objfile;
+  std::vector<compunit_symtab *> compunit_symtabs;
+};
 
-/* Read in full symbols for PST, and anything it depends on.  */
+/* ctf_archive_iter callback to build the ssymtab for archive member NAME.  */
 
-void
-ctf_psymtab::expand_psymtab (struct objfile *objfile)
+static int
+build_ctf_archive_member (ctf_dict_t *dict, const char *name, void *arg)
 {
-  struct ctf_context *ccp;
-
-  CTF_SCOPED_DEBUG_START_END ("expanding psymtab");
-
-  gdb_assert (!readin);
-
-  ccp = &context;
-
-  /* Iterate over entries in data types section.  */
-  if (ctf_type_iter (ccp->dict, ctf_add_type_cb, ccp) == CTF_ERR)
-    complaint (_("ctf_type_iter psymtab_to_symtab failed - %s"),
-	       ctf_errmsg (ctf_errno (ccp->dict)));
-
-
-  /* Iterate over entries in variable info section.  */
-  if (ctf_variable_iter (ccp->dict, ctf_add_var_cb, ccp) == CTF_ERR)
-    complaint (_("ctf_variable_iter psymtab_to_symtab failed - %s"),
-	       ctf_errmsg (ctf_errno (ccp->dict)));
+  CTF_SCOPED_DEBUG_START_END ("name='%s'", name);
 
-  /* Add entries in data objects and function info sections.  */
-  add_stt_obj (ccp);
-  add_stt_func (ccp);
-
-  readin = true;
-}
+  auto *iter_data = static_cast<ctf_archive_iter_data *> (arg);
+  ctf_per_objfile &per_objfile = iter_data->per_objfile;
 
-/* Expand partial symbol table PST into a full symbol table.
-   PST is not NULL.  */
+  if (strcmp (name, ".ctf") != 0)
+    ctf_import (dict, per_objfile.parent_dict.get ());
 
-void
-ctf_psymtab::read_symtab (struct objfile *objfile)
-{
-  CTF_SCOPED_DEBUG_START_END ("reading symtab for '%s'", filename);
+  objfile *objfile = per_objfile.objfile;
 
-  if (readin)
-    warning (_("bug: psymtab for %s is already read in."), filename);
-  else
+  if (strcmp (name, ".ctf") == 0)
     {
-      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_debug_printf ("starting buildsym for '%s', offset=%s, tsize=%zu",
-			filename, hex_string (offset), tsize);
-
-      buildsym_compunit builder (objfile, this->filename, nullptr,
-				 language_c, offset);
-      builder.record_debugformat ("ctf");
-      scoped_restore store_builder
-	= make_scoped_restore (&context.builder, &builder);
-
-      expand_psymtab (objfile);
-
-      set_text_low (unrelocated_addr (0));
-      set_text_high (unrelocated_addr (tsize));
-      compunit_symtab = builder.end_compunit_symtab (offset + tsize);
-
-      /* Finish up the debug error message.  */
-      if (info_verbose)
-	gdb_printf (_("done.\n"));
+      name = bfd_get_filename (objfile->obfd.get ());
+      ctf_debug_printf ("is parent, using name='%s'", name);
     }
-}
-
-/* Allocate a new partial_symtab NAME.
-
-   Each source file that has not been fully read in is represented by
-   a partial_symtab.  This contains the information on where in the
-   executable the debugging symbols for a specific file are, and a
-   list of names of global symbols which are located in this file.
-   They are all chained on partial symtab lists.
-
-   Even after the source file has been read into a symtab, the
-   partial_symtab remains around.  They are allocated on an obstack,
-   objfile_obstack.  */
-
-static ctf_psymtab *
-create_partial_symtab (const char *name,
-		       ctf_dict_t *dict,
-		       psymtab_storage *partial_symtabs,
-		       ctf_per_objfile *per_objfile)
-{
-  ctf_psymtab *pst;
-
-  pst = new ctf_psymtab (name, partial_symtabs, per_objfile->objfile->per_bfd,
-			 unrelocated_addr (0));
-
-  pst->context.per_objfile = per_objfile;
-  pst->context.dict = dict;
-  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;
-  location_class loc_class = LOC_UNDEF;
-  kind = ctf_type_kind (ccp->dict, tid);
-  switch (kind)
+  if (info_verbose)
     {
-    case CTF_K_ENUM:
-      ctf_psymtab_add_enums (ccp, tid);
-      [[fallthrough]];
-    case CTF_K_STRUCT:
-    case CTF_K_UNION:
-      domain = STRUCT_DOMAIN;
-      loc_class = LOC_TYPEDEF;
-      break;
-    case CTF_K_FUNCTION:
-    case CTF_K_FORWARD:
-    case CTF_K_CONST:
-    case CTF_K_TYPEDEF:
-    case CTF_K_POINTER:
-    case CTF_K_VOLATILE:
-    case CTF_K_RESTRICT:
-    case CTF_K_INTEGER:
-    case CTF_K_FLOAT:
-    case CTF_K_ARRAY:
-      domain = TYPE_DOMAIN;
-      loc_class = LOC_TYPEDEF;
-      break;
-    case CTF_K_UNKNOWN:
-      return 0;
+      gdb_printf (_("Reading in CTF data for %s..."), name);
+      gdb_flush (gdb_stdout);
     }
 
-  const char *name = ctf_type_name_raw (ccp->dict, tid);
-  if (name == nullptr || *name == '\0')
-    return 0;
-
-  ctf_debug_printf ("adding type tid=0x%lx kind=%s name='%s'",
-		    tid, ctf_kind_str (kind), name);
-
-  ccp->pst->add_psymbol (name, false, domain, loc_class, section,
-			 psymbol_placement::GLOBAL, unrelocated_addr (0),
-			 language_c, ccp->partial_symtabs,
-			 ccp->per_objfile->objfile);
-
-  return 0;
-}
-
-/* Callback to add variable NAME with ID to partial symbol table.  */
+  /* Start and size of the text segment.  */
+  size_t tsize;
+  CORE_ADDR offset = get_objfile_text_range (objfile, &tsize);
 
-static int
-ctf_psymtab_var_cb (const char *name, ctf_id_t id, void *arg)
-{
-  struct ctf_context *ccp = (struct ctf_context *) arg;
-
-  uint32_t kind = ctf_type_kind (ccp->dict, id);
-
-  ctf_debug_printf ("adding variable name='%s' tid=0x%lx kind=%s",
-		    name, id, ctf_kind_str (kind));
+  ctf_debug_printf ("starting buildsym for '%s', offset=0x%s, tsize=%zu",
+		    name, hex_string (offset), tsize);
 
-  ccp->pst->add_psymbol (name, true,
-			 kind == CTF_K_FUNCTION ? FUNCTION_DOMAIN : VAR_DOMAIN,
-			 LOC_STATIC, -1, psymbol_placement::GLOBAL,
-			 unrelocated_addr (0), language_c,
-			 ccp->partial_symtabs, ccp->per_objfile->objfile);
-  return 0;
-}
+  buildsym_compunit builder (objfile, name, nullptr, language_c, offset);
+  builder.record_debugformat ("ctf");
 
-/* Setup partial_symtab's describing each source file for which
-   debugging information is available.  */
-
-static void
-scan_partial_symbols (ctf_dict_t *dict, psymtab_storage *partial_symtabs,
-		      ctf_per_objfile *per_objfile, const char *fname)
-{
-  objfile *objfile = per_objfile->objfile;
-  bool isparent = false;
-
-  CTF_SCOPED_DEBUG_START_END ("fname='%s'", fname);
-
-  if (strcmp (fname, ".ctf") == 0)
-    {
-      fname = bfd_get_filename (objfile->obfd.get ());
-      isparent = true;
-      ctf_debug_printf ("is parent, using fname='%s'", fname);
-    }
-
-  ctf_psymtab *pst = create_partial_symtab (fname, dict, partial_symtabs,
-					    per_objfile);
-
-  struct ctf_context *ccx = &pst->context;
-  if (isparent == false)
-    ccx->pst = pst;
-
-  if (ctf_type_iter (dict, ctf_psymtab_type_cb, ccx) == CTF_ERR)
-    complaint (_("ctf_type_iter scan_partial_symbols failed - %s"),
-	       ctf_errmsg (ctf_errno (dict)));
+  ctf_context ccx;
+  ccx.per_objfile = &per_objfile;
+  ccx.dict = dict;
+  ccx.builder = &builder;
 
-  if (ctf_variable_iter (dict, ctf_psymtab_var_cb, ccx) == CTF_ERR)
-    complaint (_("ctf_variable_iter scan_partial_symbols failed - %s"),
+  /* Iterate over entries in data types section.  */
+  if (ctf_type_iter (dict, ctf_add_type_cb, &ccx) == CTF_ERR)
+    complaint (_("ctf_type_iter failed - %s"),
 	       ctf_errmsg (ctf_errno (dict)));
 
-  /* 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 (dict, pst);
-  ctf_psymtab_add_stt_func (dict, pst);
-
-  pst->end ();
-}
 
-/* Callback to build the psymtab for archive member NAME.  */
+  /* Iterate over entries in variable info section.  */
+  if (ctf_variable_iter (dict, ctf_add_var_cb, &ccx) == CTF_ERR)
+    complaint (_("ctf_variable_iter failed - %s"),
+	       ctf_errmsg (ctf_errno (dict)));
 
-static int
-build_ctf_archive_member (ctf_dict_t *dict, const char *name, void *arg)
-{
-  auto iter_data = static_cast<ctf_archive_iter_psymtab_data *> (arg);
-  ctf_per_objfile *per_objfile = iter_data->per_objfile;
+  /* Add entries in data objects and function info sections.  */
+  add_stt_obj (&ccx);
+  add_stt_func (&ccx);
 
-  if (strcmp (name, ".ctf") != 0)
-    ctf_import (dict, per_objfile->parent_dict.get ());
+  iter_data->compunit_symtabs.push_back
+   (builder.end_compunit_symtab (offset + tsize));
 
+  /* Finish up the debug error message.  */
   if (info_verbose)
-    {
-      gdb_printf (_("Scanning archive member %s..."), name);
-      gdb_flush (gdb_stdout);
-    }
-
-  psymtab_storage *pss = iter_data->psf->get_partial_symtabs ().get ();
-  scan_partial_symbols (dict, pss, per_objfile, name);
+    gdb_printf (_("done.\n"));
 
   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.  */
+   called from elfread.c.  */
 
 void
-elfctf_build_psymtabs (objfile *objfile)
+elfctf_build_symtabs (objfile *objfile)
 {
   bfd *abfd = objfile->obfd.get ();
   int err;
-
   scoped_time_it time_it (__func__);
 
-  CTF_SCOPED_DEBUG_START_END ("building psymtabs for %s",
+  CTF_SCOPED_DEBUG_START_END ("building symtabs for %s",
 			      bfd_get_filename (abfd));
 
   ctf_archive_up archive (ctf_bfdopen (abfd, &err));
@@ -1595,17 +1316,16 @@ elfctf_build_psymtabs (objfile *objfile)
   ctf_per_objfile &per_objfile
     = ctf_per_objfile_key.emplace (objfile, objfile, std::move (archive),
 				   std::move (dict));
-  psymbol_functions *psf = new psymbol_functions ();
-
-  objfile->qf.emplace_front (psf);
-
-  ctf_archive_iter_psymtab_data iter_data { &per_objfile, psf };
+  ctf_archive_iter_data iter_data { per_objfile };
 
   if (ctf_archive_iter (per_objfile.archive.get (), build_ctf_archive_member,
 			&iter_data)
       < 0)
     error (_("ctf_archive_iter failed in input file %s: - %s"),
 	   bfd_get_filename (abfd), ctf_errmsg (err));
+
+  objfile->qf.emplace_front (std::make_unique<expanded_symbols_functions>
+			     (std::move (iter_data.compunit_symtabs)));
 }
 
 #else
diff --git a/gdb/ctfread.h b/gdb/ctfread.h
index 95aa7f632731..b87f78bba0df 100644
--- a/gdb/ctfread.h
+++ b/gdb/ctfread.h
@@ -20,6 +20,6 @@
 #ifndef GDB_CTFREAD_H
 #define GDB_CTFREAD_H
 
-extern void elfctf_build_psymtabs (struct objfile *objfile);
+extern void elfctf_build_symtabs (struct objfile *objfile);
 
 #endif /* GDB_CTFREAD_H */
diff --git a/gdb/elfread.c b/gdb/elfread.c
index 7e38f623d12d..db23788c13b1 100644
--- a/gdb/elfread.c
+++ b/gdb/elfread.c
@@ -1288,17 +1288,13 @@ elf_symfile_read (struct objfile *objfile, symfile_add_flags symfile_flags)
 
   /* Read the CTF section only if there is no DWARF info.  */
   if (always_read_ctf && ei.ctfsect)
-    {
-      elfctf_build_psymtabs (objfile);
-    }
+    elfctf_build_symtabs (objfile);
 
   bool has_dwarf2 = elf_symfile_read_dwarf2 (objfile, symfile_flags);
 
   /* Read the CTF section only if there is no DWARF info.  */
   if (!always_read_ctf && !has_dwarf2 && ei.ctfsect)
-    {
-      elfctf_build_psymtabs (objfile);
-    }
+    elfctf_build_symtabs (objfile);
 
   /* Copy relocations are used by some ABIs using the ELF format, so
      set the objfile flag indicating this fact.  */
-- 
2.53.0


^ permalink raw reply	[flat|nested] 52+ messages in thread

* [PATCH v2 9/9] gdb: remove psymtab.{c,h}
  2026-02-17 19:50 ` [PATCH v2 0/9] " simon.marchi
                     ` (7 preceding siblings ...)
  2026-02-17 19:50   ` [PATCH v2 8/9] gdb/ctf: don't use psymtabs, create symtabs directly simon.marchi
@ 2026-02-17 19:50   ` simon.marchi
  2026-02-28  3:51   ` [PATCH v3 0/9] Make CTF reader build full symtabs, get rid of psymtab Simon Marchi
  9 siblings, 0 replies; 52+ messages in thread
From: simon.marchi @ 2026-02-17 19:50 UTC (permalink / raw)
  To: gdb-patches; +Cc: Simon Marchi

From: Simon Marchi <simon.marchi@polymtl.ca>

The last user of psymtabs has been changed not to use them, remove them.

Change-Id: I58ae48c30e0303bcaa48298146d69fb8f059cb32
---
 gdb/Makefile.in |    2 -
 gdb/psymtab.c   | 1575 -----------------------------------------------
 gdb/psymtab.h   |  691 ---------------------
 3 files changed, 2268 deletions(-)
 delete mode 100644 gdb/psymtab.c
 delete mode 100644 gdb/psymtab.h

diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index 2aa95be968ac..ca9e6be47631 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -1177,7 +1177,6 @@ COMMON_SFILES = \
 	progspace.c \
 	progspace-and-thread.c \
 	prologue-value.c \
-	psymtab.c \
 	record.c \
 	record-btrace.c \
 	record-full.c \
@@ -1612,7 +1611,6 @@ HFILES_NO_SRCDIR = \
 	progspace-and-thread.h \
 	progspace.h \
 	prologue-value.h \
-	psymtab.h \
 	python/py-color.h \
 	python/py-event.h \
 	python/py-events.h \
diff --git a/gdb/psymtab.c b/gdb/psymtab.c
deleted file mode 100644
index 59059616c1aa..000000000000
--- a/gdb/psymtab.c
+++ /dev/null
@@ -1,1575 +0,0 @@
-/* Partial symbol tables.
-
-   Copyright (C) 2009-2026 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/>.  */
-
-#include "event-top.h"
-#include "symtab.h"
-#include "objfiles.h"
-#include "psymtab.h"
-#include "block.h"
-#include "filenames.h"
-#include "source.h"
-#include "gdbtypes.h"
-#include "ui-out.h"
-#include "command.h"
-#include "gdbsupport/gdb_regex.h"
-#include "dictionary.h"
-#include "language.h"
-#include "cp-support.h"
-#include "cli/cli-cmds.h"
-#include <algorithm>
-#include <set>
-#include "gdbsupport/buildargv.h"
-
-static const struct partial_symbol *lookup_partial_symbol
-     (struct objfile *, struct partial_symtab *, const lookup_name_info &,
-      int, domain_search_flags);
-
-static const char *psymtab_to_fullname (struct partial_symtab *ps);
-
-static const struct partial_symbol *find_pc_sect_psymbol
-     (struct objfile *, struct partial_symtab *, CORE_ADDR,
-      struct obj_section *);
-
-static struct compunit_symtab *psymtab_to_symtab (struct objfile *objfile,
-						  struct partial_symtab *pst);
-
-psymtab_storage::~psymtab_storage ()
-{
-  partial_symtab *iter = psymtabs;
-  while (iter != nullptr)
-    {
-      partial_symtab *next = iter->next;
-      delete iter;
-      iter = next;
-    }
-}
-
-/* See psymtab.h.  */
-
-void
-psymtab_storage::install_psymtab (partial_symtab *pst)
-{
-  pst->next = psymtabs;
-  psymtabs = pst;
-}
-
-\f
-
-/* See psymtab.h.  */
-
-psymtab_storage::partial_symtab_range
-psymbol_functions::partial_symbols (struct objfile *objfile)
-{
-  return m_partial_symtabs->range ();
-}
-
-/* Find which partial symtab contains PC and SECTION starting at psymtab PST.
-   We may find a different psymtab than PST.  See FIND_PC_SECT_PSYMTAB.  */
-
-static struct partial_symtab *
-find_pc_sect_psymtab_closer (struct objfile *objfile,
-			     CORE_ADDR pc, struct obj_section *section,
-			     struct partial_symtab *pst,
-			     bound_minimal_symbol msymbol)
-{
-  struct partial_symtab *tpst;
-  struct partial_symtab *best_pst = pst;
-  CORE_ADDR best_addr = pst->text_low (objfile);
-
-  /* An objfile that has its functions reordered might have
-     many partial symbol tables containing the PC, but
-     we want the partial symbol table that contains the
-     function containing the PC.  */
-  if (section == nullptr)
-    return pst;
-
-  if (msymbol.minsym == NULL)
-    return pst;
-
-  /* The code range of partial symtabs sometimes overlap, so, in
-     the loop below, we need to check all partial symtabs and
-     find the one that fits better for the given PC address.  We
-     select the partial symtab that contains a symbol whose
-     address is closest to the PC address.  By closest we mean
-     that find_pc_sect_symbol returns the symbol with address
-     that is closest and still less than the given PC.  */
-  for (tpst = pst; tpst != NULL; tpst = tpst->next)
-    {
-      if (pc >= tpst->text_low (objfile) && pc < tpst->text_high (objfile))
-	{
-	  const struct partial_symbol *p;
-	  CORE_ADDR this_addr;
-
-	  /* NOTE: This assumes that every psymbol has a
-	     corresponding msymbol, which is not necessarily
-	     true; the debug info might be much richer than the
-	     object's symbol table.  */
-	  p = find_pc_sect_psymbol (objfile, tpst, pc, section);
-	  if (p != NULL
-	      && (p->address (objfile) == msymbol.value_address ()))
-	    return tpst;
-
-	  /* Also accept the textlow value of a psymtab as a
-	     "symbol", to provide some support for partial
-	     symbol tables with line information but no debug
-	     symbols (e.g. those produced by an assembler).  */
-	  if (p != NULL)
-	    this_addr = p->address (objfile);
-	  else
-	    this_addr = tpst->text_low (objfile);
-
-	  /* Check whether it is closer than our current
-	     BEST_ADDR.  Since this symbol address is
-	     necessarily lower or equal to PC, the symbol closer
-	     to PC is the symbol which address is the highest.
-	     This way we return the psymtab which contains such
-	     best match symbol.  This can help in cases where the
-	     symbol information/debuginfo is not complete, like
-	     for instance on IRIX6 with gcc, where no debug info
-	     is emitted for statics.  (See also the nodebug.exp
-	     testcase.)  */
-	  if (this_addr > best_addr)
-	    {
-	      best_addr = this_addr;
-	      best_pst = tpst;
-	    }
-	}
-    }
-  return best_pst;
-}
-
-/* See psymtab.h.  */
-
-struct partial_symtab *
-psymbol_functions::find_pc_sect_psymtab (struct objfile *objfile,
-					 CORE_ADDR pc,
-					 struct obj_section *section,
-					 bound_minimal_symbol msymbol)
-{
-  for (partial_symtab *pst : partial_symbols (objfile))
-    if (pc >= pst->text_low (objfile) && pc < pst->text_high (objfile))
-      {
-	struct partial_symtab *best_pst;
-
-	best_pst = find_pc_sect_psymtab_closer (objfile, pc, section, pst,
-						msymbol);
-	if (best_pst != NULL)
-	  return best_pst;
-      }
-
-  return NULL;
-}
-
-/* Psymtab version of find_pc_sect_compunit_symtab.  See its definition in
-   the definition of quick_symbol_functions in symfile.h.  */
-
-struct compunit_symtab *
-psymbol_functions::find_pc_sect_compunit_symtab (struct objfile *objfile,
-						 bound_minimal_symbol msymbol,
-						 CORE_ADDR pc,
-						 struct obj_section *section,
-						 int warn_if_readin)
-{
-  struct partial_symtab *ps = find_pc_sect_psymtab (objfile,
-						    pc, section,
-						    msymbol);
-  if (ps != NULL)
-    {
-      if (warn_if_readin && ps->readin_p (objfile))
-	/* Might want to error() here (in case symtab is corrupt and
-	   will cause a core dump), but maybe we can successfully
-	   continue, so let's not.  */
-	warning (_("\
-(Internal error: pc %s in read in psymtab, but not in symtab.)\n"),
-		 paddress (objfile->arch (), pc));
-      psymtab_to_symtab (objfile, ps);
-      return ps->get_compunit_symtab (objfile);
-    }
-  return NULL;
-}
-
-/* Find which partial symbol within a psymtab matches PC and SECTION.
-   Return NULL if none.  */
-
-static const struct partial_symbol *
-find_pc_sect_psymbol (struct objfile *objfile,
-		      struct partial_symtab *psymtab, CORE_ADDR pc,
-		      struct obj_section *section)
-{
-  const struct partial_symbol *best = NULL;
-  CORE_ADDR best_pc;
-  const CORE_ADDR textlow = psymtab->text_low (objfile);
-
-  gdb_assert (psymtab != NULL);
-
-  /* Cope with programs that start at address 0.  */
-  best_pc = (textlow != 0) ? textlow - 1 : 0;
-
-  /* Search the global symbols as well as the static symbols, so that
-     find_pc_partial_function doesn't use a minimal symbol and thus
-     cache a bad endaddr.  */
-  for (const partial_symbol *p : psymtab->global_psymbols)
-    {
-      if (p->domain == VAR_DOMAIN
-	  && p->loc_class == LOC_BLOCK
-	  && pc >= p->address (objfile)
-	  && (p->address (objfile) > best_pc
-	      || (psymtab->text_low (objfile) == 0
-		  && best_pc == 0 && p->address (objfile) == 0)))
-	{
-	  if (section != NULL)  /* Match on a specific section.  */
-	    {
-	      if (!matching_obj_sections (p->obj_section (objfile),
-					  section))
-		continue;
-	    }
-	  best_pc = p->address (objfile);
-	  best = p;
-	}
-    }
-
-  for (const partial_symbol *p : psymtab->static_psymbols)
-    {
-      if (p->domain == VAR_DOMAIN
-	  && p->loc_class == LOC_BLOCK
-	  && pc >= p->address (objfile)
-	  && (p->address (objfile) > best_pc
-	      || (psymtab->text_low (objfile) == 0
-		  && best_pc == 0 && p->address (objfile) == 0)))
-	{
-	  if (section != NULL)  /* Match on a specific section.  */
-	    {
-	      if (!matching_obj_sections (p->obj_section (objfile),
-					  section))
-		continue;
-	    }
-	  best_pc = p->address (objfile);
-	  best = p;
-	}
-    }
-
-  return best;
-}
-
-/* Psymtab version of lookup_global_symbol_language.  See its definition in
-   the definition of quick_symbol_functions in symfile.h.  */
-
-enum language
-psymbol_functions::lookup_global_symbol_language (struct objfile *objfile,
-						  const char *name,
-						  domain_search_flags domain,
-						  bool *symbol_found_p)
-{
-  *symbol_found_p = false;
-  if (objfile->sf == NULL)
-    return language_unknown;
-
-  lookup_name_info lookup_name (name, symbol_name_match_type::FULL);
-
-  for (partial_symtab *ps : partial_symbols (objfile))
-    {
-      const struct partial_symbol *psym;
-      if (ps->readin_p (objfile))
-	continue;
-
-      psym = lookup_partial_symbol (objfile, ps, lookup_name, 1, domain);
-      if (psym)
-	{
-	  *symbol_found_p = true;
-	  return psym->ginfo.language ();
-	}
-    }
-
-  return language_unknown;
-}
-
-/* Returns true if PSYM matches LOOKUP_NAME.  */
-
-static bool
-psymbol_name_matches (const partial_symbol *psym,
-		      const lookup_name_info &lookup_name)
-{
-  const language_defn *lang = language_def (psym->ginfo.language ());
-  symbol_name_matcher_ftype *name_match
-    = lang->get_symbol_name_matcher (lookup_name);
-  return name_match (psym->ginfo.search_name (), lookup_name, NULL);
-}
-
-/* Look, in partial_symtab PST, for symbol whose natural name is
-   LOOKUP_NAME.  Check the global symbols if GLOBAL, the static
-   symbols if not.  */
-
-static const struct partial_symbol *
-lookup_partial_symbol (struct objfile *objfile,
-		       struct partial_symtab *pst,
-		       const lookup_name_info &lookup_name,
-		       int global, domain_search_flags domain)
-{
-  const struct partial_symbol **start, **psym;
-  const struct partial_symbol **top, **real_top, **bottom, **center;
-  int length = (global
-		? pst->global_psymbols.size ()
-		: pst->static_psymbols.size ());
-  int do_linear_search = 1;
-
-  if (length == 0)
-    return NULL;
-
-  start = (global ?
-	   &pst->global_psymbols[0] :
-	   &pst->static_psymbols[0]);
-
-  if (global)			/* This means we can use a binary search.  */
-    {
-      do_linear_search = 0;
-
-      /* Binary search.  This search is guaranteed to end with center
-	 pointing at the earliest partial symbol whose name might be
-	 correct.  At that point *all* partial symbols with an
-	 appropriate name will be checked against the correct
-	 domain.  */
-
-      bottom = start;
-      top = start + length - 1;
-      real_top = top;
-      while (top > bottom)
-	{
-	  center = bottom + (top - bottom) / 2;
-
-	  gdb_assert (center < top);
-
-	  if (strcmp_iw_ordered ((*center)->ginfo.search_name (),
-				 lookup_name.c_str ()) >= 0)
-	    {
-	      top = center;
-	    }
-	  else
-	    {
-	      bottom = center + 1;
-	    }
-	}
-
-      gdb_assert (top == bottom);
-
-      /* For `case_sensitivity == case_sensitive_off' strcmp_iw_ordered will
-	 search more exactly than what matches SYMBOL_MATCHES_SEARCH_NAME.  */
-      while (top >= start && symbol_matches_search_name (&(*top)->ginfo,
-							 lookup_name))
-	top--;
-
-      /* Fixup to have a symbol which matches SYMBOL_MATCHES_SEARCH_NAME.  */
-      top++;
-
-      while (top <= real_top && symbol_matches_search_name (&(*top)->ginfo,
-							    lookup_name))
-	{
-	  if (search_flags_matches (domain, (*top)->domain))
-	    return *top;
-	  top++;
-	}
-    }
-
-  /* Can't use a binary search or else we found during the binary search that
-     we should also do a linear search.  */
-
-  if (do_linear_search)
-    {
-      for (psym = start; psym < start + length; psym++)
-	{
-	  if (search_flags_matches (domain, (*psym)->domain)
-	      && symbol_matches_search_name (&(*psym)->ginfo, lookup_name))
-	    return *psym;
-	}
-    }
-
-  return NULL;
-}
-
-/* Get the symbol table that corresponds to a partial_symtab.
-   This is fast after the first time you do it.
-   The result will be NULL if the primary symtab has no symbols,
-   which can happen.  Otherwise the result is the primary symtab
-   that contains PST.  */
-
-static struct compunit_symtab *
-psymtab_to_symtab (struct objfile *objfile, struct partial_symtab *pst)
-{
-  /* If it is a shared psymtab, find an unshared psymtab that includes
-     it.  Any such psymtab will do.  */
-  while (pst->user != NULL)
-    pst = pst->user;
-
-  /* If it's been looked up before, return it.  */
-  if (pst->get_compunit_symtab (objfile))
-    return pst->get_compunit_symtab (objfile);
-
-  /* If it has not yet been read in, read it.  */
-  if (!pst->readin_p (objfile))
-    {
-      scoped_restore decrementer = increment_reading_symtab ();
-
-      if (info_verbose)
-	{
-	  gdb_printf (_("Reading in symbols for %s...\n"),
-		      pst->filename);
-	  gdb_flush (gdb_stdout);
-	}
-
-      pst->read_symtab (objfile);
-    }
-
-  return pst->get_compunit_symtab (objfile);
-}
-
-/* Psymtab version of find_last_source_symtab.  See its definition in
-   the definition of quick_symbol_functions in symfile.h.  */
-
-struct symtab *
-psymbol_functions::find_last_source_symtab (struct objfile *ofp)
-{
-  struct partial_symtab *cs_pst = NULL;
-
-  for (partial_symtab *ps : partial_symbols (ofp))
-    {
-      const char *name = ps->filename;
-      int len = strlen (name);
-
-      if (!(len > 2 && (strcmp (&name[len - 2], ".h") == 0
-			|| strcmp (name, "<<C++-namespaces>>") == 0)))
-	cs_pst = ps;
-    }
-
-  if (cs_pst)
-    {
-      if (cs_pst->readin_p (ofp))
-	{
-	  internal_error (_("select_source_symtab: "
-			  "readin pst found and no symtabs."));
-	}
-      else
-	{
-	  struct compunit_symtab *cust = psymtab_to_symtab (ofp, cs_pst);
-
-	  if (cust == NULL)
-	    return NULL;
-	  return cust->primary_filetab ();
-	}
-    }
-  return NULL;
-}
-
-/* Psymtab version of forget_cached_source_info.  See its definition in
-   the definition of quick_symbol_functions in symfile.h.  */
-
-void
-psymbol_functions::forget_cached_source_info (struct objfile *objfile)
-{
-  for (partial_symtab *pst : partial_symbols (objfile))
-    {
-      if (pst->fullname != NULL)
-	{
-	  xfree (pst->fullname);
-	  pst->fullname = NULL;
-	}
-    }
-}
-
-static void
-print_partial_symbols (struct gdbarch *gdbarch, struct objfile *objfile,
-		       const std::vector<const partial_symbol *> &symbols,
-		       const char *what, struct ui_file *outfile)
-{
-  gdb_printf (outfile, "  %s partial symbols:\n", what);
-  for (const partial_symbol *p : symbols)
-    {
-      QUIT;
-      gdb_printf (outfile, "    `%s'", p->ginfo.linkage_name ());
-      if (p->ginfo.demangled_name () != NULL)
-	{
-	  gdb_printf (outfile, "  `%s'",
-		      p->ginfo.demangled_name ());
-	}
-      gdb_puts (", ", outfile);
-      switch (p->domain)
-	{
-	case UNDEF_DOMAIN:
-	  gdb_puts ("undefined domain, ", outfile);
-	  break;
-	case VAR_DOMAIN:
-	  /* This is the usual thing -- don't print it.  */
-	  break;
-	case STRUCT_DOMAIN:
-	  gdb_puts ("struct domain, ", outfile);
-	  break;
-	case MODULE_DOMAIN:
-	  gdb_puts ("module domain, ", outfile);
-	  break;
-	case LABEL_DOMAIN:
-	  gdb_puts ("label domain, ", outfile);
-	  break;
-	case COMMON_BLOCK_DOMAIN:
-	  gdb_puts ("common block domain, ", outfile);
-	  break;
-	case TYPE_DOMAIN:
-	  gdb_puts ("type domain, ", outfile);
-	  break;
-	case FUNCTION_DOMAIN:
-	  gdb_puts ("function domain, ", outfile);
-	  break;
-	default:
-	  gdb_puts ("<invalid domain>, ", outfile);
-	  break;
-	}
-      switch (p->loc_class)
-	{
-	case LOC_UNDEF:
-	  gdb_puts ("undefined", outfile);
-	  break;
-	case LOC_CONST:
-	  gdb_puts ("constant int", outfile);
-	  break;
-	case LOC_STATIC:
-	  gdb_puts ("static", outfile);
-	  break;
-	case LOC_REGISTER:
-	  gdb_puts ("register", outfile);
-	  break;
-	case LOC_ARG:
-	  gdb_puts ("pass by value", outfile);
-	  break;
-	case LOC_REF_ARG:
-	  gdb_puts ("pass by reference", outfile);
-	  break;
-	case LOC_REGPARM_ADDR:
-	  gdb_puts ("register address parameter", outfile);
-	  break;
-	case LOC_LOCAL:
-	  gdb_puts ("stack parameter", outfile);
-	  break;
-	case LOC_TYPEDEF:
-	  gdb_puts ("type", outfile);
-	  break;
-	case LOC_LABEL:
-	  gdb_puts ("label", outfile);
-	  break;
-	case LOC_BLOCK:
-	  gdb_puts ("function", outfile);
-	  break;
-	case LOC_CONST_BYTES:
-	  gdb_puts ("constant bytes", outfile);
-	  break;
-	case LOC_UNRESOLVED:
-	  gdb_puts ("unresolved", outfile);
-	  break;
-	case LOC_OPTIMIZED_OUT:
-	  gdb_puts ("optimized out", outfile);
-	  break;
-	case LOC_COMPUTED:
-	  gdb_puts ("computed at runtime", outfile);
-	  break;
-	default:
-	  gdb_puts ("<invalid location>", outfile);
-	  break;
-	}
-      gdb_puts (", ", outfile);
-      gdb_puts (paddress (gdbarch, CORE_ADDR (p->unrelocated_address ())),
-		outfile);
-      gdb_printf (outfile, "\n");
-    }
-}
-
-static void
-dump_psymtab (struct objfile *objfile, struct partial_symtab *psymtab,
-	      struct ui_file *outfile)
-{
-  struct gdbarch *gdbarch = objfile->arch ();
-  int i;
-
-  if (psymtab->anonymous)
-    {
-      gdb_printf (outfile, "\nAnonymous partial symtab (%s) ",
-		  psymtab->filename);
-    }
-  else
-    {
-      gdb_printf (outfile, "\nPartial symtab for source file %s ",
-		  psymtab->filename);
-    }
-  gdb_printf (outfile, "(object %s)\n\n",
-	      host_address_to_string (psymtab));
-  gdb_printf (outfile, "  Read from object file %s (%s)\n",
-	      objfile_name (objfile),
-	      host_address_to_string (objfile));
-
-  if (psymtab->readin_p (objfile))
-    gdb_printf
-      (outfile,
-       "  Full symtab was read (at %s)\n",
-       host_address_to_string (psymtab->get_compunit_symtab (objfile)));
-
-  gdb_printf (outfile, "  Symbols cover text addresses ");
-  gdb_puts (paddress (gdbarch, psymtab->text_low (objfile)), outfile);
-  gdb_printf (outfile, "-");
-  gdb_puts (paddress (gdbarch, psymtab->text_high (objfile)), outfile);
-  gdb_printf (outfile, "\n");
-  gdb_printf (outfile, "  Depends on %d other partial symtabs.\n",
-	      psymtab->number_of_dependencies);
-  for (i = 0; i < psymtab->number_of_dependencies; i++)
-    gdb_printf (outfile, "    %d %s\n", i,
-		host_address_to_string (psymtab->dependencies[i]));
-  if (psymtab->user != NULL)
-    gdb_printf (outfile, "  Shared partial symtab with user %s\n",
-		host_address_to_string (psymtab->user));
-  if (!psymtab->global_psymbols.empty ())
-    {
-      print_partial_symbols
-	(gdbarch, objfile, psymtab->global_psymbols,
-	 "Global", outfile);
-    }
-  if (!psymtab->static_psymbols.empty ())
-    {
-      print_partial_symbols
-	(gdbarch, objfile, psymtab->static_psymbols,
-	 "Static", outfile);
-    }
-  gdb_printf (outfile, "\n");
-}
-
-/* Count the number of partial symbols in OBJFILE.  */
-
-int
-psymbol_functions::count_psyms ()
-{
-  int count = 0;
-  for (partial_symtab *pst : m_partial_symtabs->range ())
-    {
-      count += pst->global_psymbols.size ();
-      count += pst->static_psymbols.size ();
-    }
-  return count;
-}
-
-/* Psymtab version of print_stats.  See its definition in
-   the definition of quick_symbol_functions in symfile.h.  */
-
-void
-psymbol_functions::print_stats (struct objfile *objfile, bool print_bcache)
-{
-  int i;
-
-  if (!print_bcache)
-    {
-      int n_psyms = count_psyms ();
-      if (n_psyms > 0)
-	gdb_printf (_("  Number of \"partial\" symbols read: %d\n"),
-		    n_psyms);
-
-      i = 0;
-      for (partial_symtab *ps : partial_symbols (objfile))
-	{
-	  if (!ps->readin_p (objfile))
-	    i++;
-	}
-      gdb_printf (_("  Number of psym tables (not yet expanded): %d\n"),
-		  i);
-      gdb_printf (_("  Total memory used for psymbol cache: %d\n"),
-		  m_partial_symtabs->psymbol_cache.memory_used ());
-    }
-  else
-    {
-      gdb_printf (_("Psymbol byte cache statistics:\n"));
-      m_partial_symtabs->psymbol_cache.print_statistics
-	("partial symbol cache");
-    }
-}
-
-/* Psymtab version of dump.  See its definition in
-   the definition of quick_symbol_functions in symfile.h.  */
-
-void
-psymbol_functions::dump (struct objfile *objfile)
-{
-  struct partial_symtab *psymtab;
-
-  if (m_partial_symtabs->psymtabs)
-    {
-      gdb_printf ("Psymtabs:\n");
-      for (psymtab = m_partial_symtabs->psymtabs;
-	   psymtab != NULL;
-	   psymtab = psymtab->next)
-	gdb_printf ("%s at %s\n",
-		    psymtab->filename,
-		    host_address_to_string (psymtab));
-      gdb_printf ("\n\n");
-    }
-}
-
-/* Psymtab version of expand_all_symtabs.  See its definition in
-   the definition of quick_symbol_functions in symfile.h.  */
-
-void
-psymbol_functions::expand_all_symtabs (struct objfile *objfile)
-{
-  for (partial_symtab *psymtab : partial_symbols (objfile))
-    psymtab_to_symtab (objfile, psymtab);
-}
-
-/* Psymtab version of map_symbol_filenames.  See its definition in
-   the definition of quick_symbol_functions in symfile.h.  */
-
-void
-psymbol_functions::map_symbol_filenames (objfile *objfile,
-					 symbol_filename_listener fun,
-					 bool need_fullname)
-{
-  for (partial_symtab *ps : partial_symbols (objfile))
-    {
-      const char *fullname;
-
-      if (ps->readin_p (objfile))
-	continue;
-
-      /* We can skip shared psymtabs here, because any file name will be
-	 attached to the unshared psymtab.  */
-      if (ps->user != NULL)
-	continue;
-
-      /* Anonymous psymtabs don't have a file name.  */
-      if (ps->anonymous)
-	continue;
-
-      QUIT;
-      if (need_fullname)
-	fullname = psymtab_to_fullname (ps);
-      else
-	fullname = NULL;
-      fun (ps->filename, fullname);
-    }
-}
-
-/* Finds the fullname that a partial_symtab represents.
-
-   If this functions finds the fullname, it will save it in ps->fullname
-   and it will also return the value.
-
-   If this function fails to find the file that this partial_symtab represents,
-   NULL will be returned and ps->fullname will be set to NULL.  */
-
-static const char *
-psymtab_to_fullname (struct partial_symtab *ps)
-{
-  gdb_assert (!ps->anonymous);
-
-  /* Use cached copy if we have it.
-     We rely on forget_cached_source_info being called appropriately
-     to handle cases like the file being moved.  */
-  if (ps->fullname == NULL)
-    {
-      gdb::unique_xmalloc_ptr<char> fullname
-	= find_source_or_rewrite (ps->filename, ps->dirname);
-      ps->fullname = fullname.release ();
-    }
-
-  return ps->fullname;
-}
-
-/* A helper for psymbol_functions::search that handles searching
-   included psymtabs.  This returns true if a symbol is found, and
-   false otherwise.  It also updates the 'searched_flag' on the
-   various psymtabs that it searches.  */
-
-static bool
-recursively_search_psymtabs (partial_symtab *ps, objfile *objfile,
-			     block_search_flags search_flags,
-			     domain_search_flags domain,
-			     const lookup_name_info &lookup_name,
-			     search_symtabs_symbol_matcher sym_matcher)
-{
-  int keep_going = 1;
-  enum psymtab_search_status result = PST_SEARCHED_AND_NOT_FOUND;
-  int i;
-
-  if (ps->searched_flag != PST_NOT_SEARCHED)
-    return ps->searched_flag == PST_SEARCHED_AND_FOUND;
-
-  /* Recurse into shared psymtabs first, because they may have already
-     been searched, and this could save some time.  */
-  for (i = 0; i < ps->number_of_dependencies; ++i)
-    {
-      int r;
-
-      /* Skip non-shared dependencies, these are handled elsewhere.  */
-      if (ps->dependencies[i]->user == NULL)
-	continue;
-
-      r = recursively_search_psymtabs (ps->dependencies[i],
-				       objfile, search_flags, domain,
-				       lookup_name, sym_matcher);
-      if (r != 0)
-	{
-	  ps->searched_flag = PST_SEARCHED_AND_FOUND;
-	  return true;
-	}
-    }
-
-  const partial_symbol **gbound = (ps->global_psymbols.data ()
-				   + ps->global_psymbols.size ());
-  const partial_symbol **sbound = (ps->static_psymbols.data ()
-				   + ps->static_psymbols.size ());
-  const partial_symbol **bound = gbound;
-
-  /* Go through all of the symbols stored in a partial
-     symtab in one loop.  */
-  const partial_symbol **psym = ps->global_psymbols.data ();
-
-  if ((search_flags & SEARCH_GLOBAL_BLOCK) == 0)
-    {
-      if (ps->static_psymbols.empty ())
-	keep_going = 0;
-      else
-	{
-	  psym = ps->static_psymbols.data ();
-	  bound = sbound;
-	}
-    }
-
-  while (keep_going)
-    {
-      if (psym >= bound)
-	{
-	  if (bound == gbound && !ps->static_psymbols.empty ()
-	      && (search_flags & SEARCH_STATIC_BLOCK) != 0)
-	    {
-	      psym = ps->static_psymbols.data ();
-	      bound = sbound;
-	    }
-	  else
-	    keep_going = 0;
-	  continue;
-	}
-      else
-	{
-	  QUIT;
-
-	  if (search_flags_matches (domain, (*psym)->domain)
-	      && psymbol_name_matches (*psym, lookup_name)
-	      && (sym_matcher == NULL
-		  || sym_matcher ((*psym)->ginfo.search_name ())))
-	    {
-	      /* Found a match, so notify our caller.  */
-	      result = PST_SEARCHED_AND_FOUND;
-	      keep_going = 0;
-	    }
-	}
-      psym++;
-    }
-
-  ps->searched_flag = result;
-  return result == PST_SEARCHED_AND_FOUND;
-}
-
-/* Psymtab version of search.  See its definition in
-   the definition of quick_symbol_functions in symfile.h.  */
-
-bool
-psymbol_functions::search
-  (struct objfile *objfile,
-   search_symtabs_file_matcher file_matcher,
-   const lookup_name_info *lookup_name,
-   search_symtabs_symbol_matcher symbol_matcher,
-   search_symtabs_expansion_listener listener,
-   block_search_flags search_flags,
-   domain_search_flags domain,
-   search_symtabs_lang_matcher lang_matcher ATTRIBUTE_UNUSED)
-{
-  /* Clear the search flags.  */
-  for (partial_symtab *ps : partial_symbols (objfile))
-    ps->searched_flag = PST_NOT_SEARCHED;
-
-  std::optional<lookup_name_info> psym_lookup_name;
-  if (lookup_name != nullptr)
-    psym_lookup_name = lookup_name->make_ignore_params ();
-
-  /* This invariant is documented in quick-functions.h.  */
-  gdb_assert (lookup_name != nullptr || symbol_matcher == nullptr);
-
-  for (partial_symtab *ps : m_partial_symtabs->range ())
-    {
-      QUIT;
-
-      if (file_matcher)
-	{
-	  bool match;
-
-	  if (ps->anonymous)
-	    continue;
-
-	  match = file_matcher (ps->filename, false);
-	  if (!match)
-	    {
-	      /* Before we invoke realpath, which can get expensive when many
-		 files are involved, do a quick comparison of the basenames.  */
-	      if (basenames_may_differ
-		  || file_matcher (lbasename (ps->filename), true))
-		match = file_matcher (psymtab_to_fullname (ps), false);
-	    }
-	  if (!match)
-	    continue;
-	}
-
-      if (lookup_name == nullptr
-	  || recursively_search_psymtabs (ps, objfile, search_flags,
-					  domain, *psym_lookup_name,
-					  symbol_matcher))
-	{
-	  compunit_symtab *cust = psymtab_to_symtab (objfile, ps);
-
-	  if (cust != nullptr && listener != nullptr)
-	    if (!listener (cust))
-	      return false;
-	}
-    }
-
-  return true;
-}
-
-/* Psymtab version of has_symbols.  See its definition in
-   the definition of quick_symbol_functions in symfile.h.  */
-
-bool
-psymbol_functions::has_symbols (struct objfile *objfile)
-{
-  return m_partial_symtabs->psymtabs != NULL;
-}
-
-/* See quick_symbol_functions::has_unexpanded_symtabs in quick-symbol.h.  */
-
-bool
-psymbol_functions::has_unexpanded_symtabs (struct objfile *objfile)
-{
-  for (partial_symtab *psymtab : partial_symbols (objfile))
-    {
-      /* Is this already expanded?  */
-      if (psymtab->readin_p (objfile))
-	continue;
-
-      /* It has not yet been expanded.  */
-      return true;
-    }
-
-  return false;
-}
-
-\f
-
-/* Partially fill a partial symtab.  It will be completely filled at
-   the end of the symbol list.  */
-
-partial_symtab::partial_symtab (const char *filename,
-				psymtab_storage *partial_symtabs,
-				objfile_per_bfd_storage *objfile_per_bfd,
-				unrelocated_addr textlow)
-  : partial_symtab (filename, partial_symtabs, objfile_per_bfd)
-{
-  set_text_low (textlow);
-  set_text_high (unrelocated_text_low ()); /* default */
-}
-
-/* Perform "finishing up" operations of a partial symtab.  */
-
-void
-partial_symtab::end ()
-{
-  global_psymbols.shrink_to_fit ();
-  static_psymbols.shrink_to_fit ();
-
-  /* Sort the global list; don't sort the static list.  */
-  std::sort (global_psymbols.begin (),
-	     global_psymbols.end (),
-	     [] (const partial_symbol *s1, const partial_symbol *s2)
-    {
-      return strcmp_iw_ordered (s1->ginfo.search_name (),
-				s2->ginfo.search_name ()) < 0;
-    });
-}
-
-/* See psymtab.h.  */
-
-unsigned long
-psymbol_bcache::hash (const void *addr, int length)
-{
-  unsigned long h = 0;
-  struct partial_symbol *psymbol = (struct partial_symbol *) addr;
-  unsigned int lang = psymbol->ginfo.language ();
-  unsigned int domain = psymbol->domain;
-  unsigned int loc_class = psymbol->loc_class;
-
-  h = fast_hash (&psymbol->ginfo.m_value, sizeof (psymbol->ginfo.m_value), h);
-  h = fast_hash (&lang, sizeof (unsigned int), h);
-  h = fast_hash (&domain, sizeof (unsigned int), h);
-  h = fast_hash (&loc_class, sizeof (unsigned int), h);
-  /* Note that psymbol names are interned via compute_and_set_names, so
-     there's no need to hash the contents of the name here.  */
-  h = fast_hash (&psymbol->ginfo.m_name, sizeof (psymbol->ginfo.m_name), h);
-
-  return h;
-}
-
-/* See psymtab.h.  */
-
-int
-psymbol_bcache::compare (const void *addr1, const void *addr2, int length)
-{
-  struct partial_symbol *sym1 = (struct partial_symbol *) addr1;
-  struct partial_symbol *sym2 = (struct partial_symbol *) addr2;
-
-  return (memcmp (&sym1->ginfo.m_value, &sym2->ginfo.m_value,
-		  sizeof (sym1->ginfo.m_value)) == 0
-	  && sym1->ginfo.language () == sym2->ginfo.language ()
-	  && sym1->domain == sym2->domain
-	  && sym1->loc_class == sym2->loc_class
-	  /* Note that psymbol names are interned via
-	     compute_and_set_names, so there's no need to compare the
-	     contents of the name here.  */
-	  && sym1->ginfo.linkage_name () == sym2->ginfo.linkage_name ());
-}
-
-/* See psymtab.h.  */
-
-void
-partial_symtab::add_psymbol (const partial_symbol &psymbol,
-			     psymbol_placement where,
-			     psymtab_storage *partial_symtabs,
-			     struct objfile *objfile)
-{
-  bool added;
-
-  /* Stash the partial symbol away in the cache.  */
-  const partial_symbol *psym = partial_symtabs->psymbol_cache.insert (psymbol,
-								      &added);
-
-  /* Do not duplicate global partial symbols.  */
-  if (where == psymbol_placement::GLOBAL && !added)
-    return;
-
-  /* Save pointer to partial symbol in psymtab, growing symtab if needed.  */
-  std::vector<const partial_symbol *> &list
-    = (where == psymbol_placement::STATIC
-       ? static_psymbols
-       : global_psymbols);
-  list.push_back (psym);
-}
-
-/* See psymtab.h.  */
-
-void
-partial_symtab::add_psymbol (std::string_view name, bool copy_name,
-			     domain_enum domain,
-			     location_class loc_class,
-			     int section,
-			     psymbol_placement where,
-			     unrelocated_addr coreaddr,
-			     enum language language,
-			     psymtab_storage *partial_symtabs,
-			     struct objfile *objfile)
-{
-  struct partial_symbol psymbol;
-  memset (&psymbol, 0, sizeof (psymbol));
-
-  psymbol.set_unrelocated_address (coreaddr);
-  psymbol.ginfo.set_section_index (section);
-  psymbol.domain = domain;
-  psymbol.loc_class = loc_class;
-  psymbol.ginfo.set_language (language, partial_symtabs->obstack ());
-  psymbol.ginfo.compute_and_set_names (name, copy_name, objfile->per_bfd);
-
-  add_psymbol (psymbol, where, partial_symtabs, objfile);
-}
-
-/* See psymtab.h.  */
-
-partial_symtab::partial_symtab (const char *filename_,
-				psymtab_storage *partial_symtabs,
-				objfile_per_bfd_storage *objfile_per_bfd)
-  : searched_flag (PST_NOT_SEARCHED),
-    text_low_valid (0),
-    text_high_valid (0)
-{
-  partial_symtabs->install_psymtab (this);
-
-  filename = objfile_per_bfd->intern (filename_);
-
-  if (symtab_create_debug >= 1)
-    {
-      /* Be a bit clever with debugging messages, and don't print objfile
-	 every time, only when it changes.  */
-      static std::string last_bfd_name;
-      const char *this_bfd_name
-	= bfd_get_filename (objfile_per_bfd->get_bfd ());
-
-      if (last_bfd_name.empty () || last_bfd_name != this_bfd_name)
-	{
-	  last_bfd_name = this_bfd_name;
-
-	  symtab_create_debug_printf ("creating one or more psymtabs for %s",
-				      this_bfd_name);
-	}
-
-      symtab_create_debug_printf ("created psymtab %s for module %s",
-				  host_address_to_string (this), filename);
-    }
-}
-
-/* See psymtab.h.  */
-
-void
-partial_symtab::expand_dependencies (struct objfile *objfile)
-{
-  for (int i = 0; i < number_of_dependencies; ++i)
-    {
-      if (!dependencies[i]->readin_p (objfile)
-	  && dependencies[i]->user == NULL)
-	{
-	  /* Inform about additional files to be read in.  */
-	  if (info_verbose)
-	    {
-	      gdb_puts (" ");
-	      gdb_stdout->wrap_here (0);
-	      gdb_puts ("and ");
-	      gdb_stdout->wrap_here (0);
-	      gdb_printf ("%s...", dependencies[i]->filename);
-	      gdb_flush (gdb_stdout);
-	    }
-	  dependencies[i]->expand_psymtab (objfile);
-	}
-    }
-}
-
-
-void
-psymtab_storage::discard_psymtab (struct partial_symtab *pst)
-{
-  struct partial_symtab **prev_pst;
-
-  /* From dbxread.c:
-     Empty psymtabs happen as a result of header files which don't
-     have any symbols in them.  There can be a lot of them.  But this
-     check is wrong, in that a psymtab with N_SLINE entries but
-     nothing else is not empty, but we don't realize that.  Fixing
-     that without slowing things down might be tricky.  */
-
-  /* First, snip it out of the psymtab chain.  */
-
-  prev_pst = &psymtabs;
-  while ((*prev_pst) != pst)
-    prev_pst = &((*prev_pst)->next);
-  (*prev_pst) = pst->next;
-  delete pst;
-}
-
-\f
-
-static void
-maintenance_print_psymbols (const char *args, int from_tty)
-{
-  struct ui_file *outfile = gdb_stdout;
-  char *address_arg = NULL, *source_arg = NULL, *objfile_arg = NULL;
-  int i, outfile_idx, found;
-  CORE_ADDR pc = 0;
-  struct obj_section *section = NULL;
-
-  dont_repeat ();
-
-  gdb_argv argv (args);
-
-  for (i = 0; argv != NULL && argv[i] != NULL; ++i)
-    {
-      if (strcmp (argv[i], "-pc") == 0)
-	{
-	  if (argv[i + 1] == NULL)
-	    error (_("Missing pc value"));
-	  address_arg = argv[++i];
-	}
-      else if (strcmp (argv[i], "-source") == 0)
-	{
-	  if (argv[i + 1] == NULL)
-	    error (_("Missing source file"));
-	  source_arg = argv[++i];
-	}
-      else if (strcmp (argv[i], "-objfile") == 0)
-	{
-	  if (argv[i + 1] == NULL)
-	    error (_("Missing objfile name"));
-	  objfile_arg = argv[++i];
-	}
-      else if (strcmp (argv[i], "--") == 0)
-	{
-	  /* End of options.  */
-	  ++i;
-	  break;
-	}
-      else if (argv[i][0] == '-')
-	{
-	  /* Future proofing: Don't allow OUTFILE to begin with "-".  */
-	  error (_("Unknown option: %s"), argv[i]);
-	}
-      else
-	break;
-    }
-  outfile_idx = i;
-
-  if (address_arg != NULL && source_arg != NULL)
-    error (_("Must specify at most one of -pc and -source"));
-
-  stdio_file arg_outfile;
-
-  if (argv != NULL && argv[outfile_idx] != NULL)
-    {
-      if (argv[outfile_idx + 1] != NULL)
-	error (_("Junk at end of command"));
-      gdb::unique_xmalloc_ptr<char> outfile_name
-	= gdb_rl_tilde_expand (argv[outfile_idx]);
-      if (!arg_outfile.open (outfile_name.get (), FOPEN_WT))
-	perror_with_name (outfile_name.get ());
-      outfile = &arg_outfile;
-    }
-
-  if (address_arg != NULL)
-    {
-      pc = parse_and_eval_address (address_arg);
-      /* If we fail to find a section, that's ok, try the lookup anyway.  */
-      section = find_pc_section (pc);
-    }
-
-  found = 0;
-  for (objfile &objfile : current_program_space->objfiles ())
-    {
-      int printed_objfile_header = 0;
-      int print_for_objfile = 1;
-
-      QUIT;
-      if (objfile_arg != NULL)
-	print_for_objfile
-	  = compare_filenames_for_search (objfile_name (&objfile),
-					  objfile_arg);
-      if (!print_for_objfile)
-	continue;
-
-      for (const auto &iter : objfile.qf)
-	{
-	  psymbol_functions *psf
-	    = dynamic_cast<psymbol_functions *> (iter.get ());
-	  if (psf == nullptr)
-	    continue;
-
-	  if (address_arg != NULL)
-	    {
-	      bound_minimal_symbol msymbol;
-
-	      /* We don't assume each pc has a unique objfile (this is for
-		 debugging).  */
-	      struct partial_symtab *ps
-		= psf->find_pc_sect_psymtab (&objfile, pc, section, msymbol);
-	      if (ps != NULL)
-		{
-		  if (!printed_objfile_header)
-		    {
-		      outfile->printf ("\nPartial symtabs for objfile %s\n",
-				       objfile_name (&objfile));
-		      printed_objfile_header = 1;
-		    }
-		  dump_psymtab (&objfile, ps, outfile);
-		  found = 1;
-		}
-	    }
-	  else
-	    {
-	      for (partial_symtab *ps : psf->partial_symbols (&objfile))
-		{
-		  int print_for_source = 0;
-
-		  QUIT;
-		  if (source_arg != NULL)
-		    {
-		      print_for_source
-			= compare_filenames_for_search (ps->filename, source_arg);
-		      found = 1;
-		    }
-		  if (source_arg == NULL
-		      || print_for_source)
-		    {
-		      if (!printed_objfile_header)
-			{
-			  outfile->printf ("\nPartial symtabs for objfile %s\n",
-					   objfile_name (&objfile));
-			  printed_objfile_header = 1;
-			}
-		      dump_psymtab (&objfile, ps, outfile);
-		    }
-		}
-	    }
-	}
-    }
-
-  if (!found)
-    {
-      if (address_arg != NULL)
-	error (_("No partial symtab for address: %s"), address_arg);
-      if (source_arg != NULL)
-	error (_("No partial symtab for source file: %s"), source_arg);
-    }
-}
-
-/* List all the partial symbol tables whose names match REGEXP (optional).  */
-
-static void
-maintenance_info_psymtabs (const char *regexp, int from_tty)
-{
-  if (regexp)
-    re_comp (regexp);
-
-  for (struct program_space *pspace : program_spaces)
-    for (objfile &objfile : pspace->objfiles ())
-      {
-	struct gdbarch *gdbarch = objfile.arch ();
-
-	/* We don't want to print anything for this objfile until we
-	   actually find a symtab whose name matches.  */
-	int printed_objfile_start = 0;
-
-	for (const auto &iter : objfile.qf)
-	  {
-	    psymbol_functions *psf
-	      = dynamic_cast<psymbol_functions *> (iter.get ());
-	    if (psf == nullptr)
-	      continue;
-	    for (partial_symtab *psymtab : psf->partial_symbols (&objfile))
-	      {
-		QUIT;
-
-		if (! regexp
-		    || re_exec (psymtab->filename))
-		  {
-		    if (! printed_objfile_start)
-		      {
-			gdb_printf ("{ objfile %s ", objfile_name (&objfile));
-			gdb_stdout->wrap_here (2);
-			gdb_printf ("((struct objfile *) %s)\n",
-				    host_address_to_string (&objfile));
-			printed_objfile_start = 1;
-		      }
-
-		    gdb_printf ("  { psymtab %s ", psymtab->filename);
-		    gdb_stdout->wrap_here (4);
-		    gdb_printf ("((struct partial_symtab *) %s)\n",
-				host_address_to_string (psymtab));
-
-		    gdb_printf ("    readin %s\n",
-				psymtab->readin_p (&objfile) ? "yes" : "no");
-		    gdb_printf ("    fullname %s\n",
-				psymtab->fullname
-				? psymtab->fullname : "(null)");
-		    gdb_printf ("    text addresses ");
-		    gdb_puts (paddress (gdbarch,
-					psymtab->text_low (&objfile)));
-		    gdb_printf (" -- ");
-		    gdb_puts (paddress (gdbarch,
-					psymtab->text_high (&objfile)));
-		    gdb_printf ("\n");
-		    gdb_printf ("    globals ");
-		    if (!psymtab->global_psymbols.empty ())
-		      gdb_printf
-			("(* (struct partial_symbol **) %s @ %d)\n",
-			 host_address_to_string (psymtab->global_psymbols.data ()),
-			 (int) psymtab->global_psymbols.size ());
-		    else
-		      gdb_printf ("(none)\n");
-		    gdb_printf ("    statics ");
-		    if (!psymtab->static_psymbols.empty ())
-		      gdb_printf
-			("(* (struct partial_symbol **) %s @ %d)\n",
-			 host_address_to_string (psymtab->static_psymbols.data ()),
-			 (int) psymtab->static_psymbols.size ());
-		    else
-		      gdb_printf ("(none)\n");
-		    if (psymtab->user)
-		      gdb_printf ("    user %s "
-				  "((struct partial_symtab *) %s)\n",
-				  psymtab->user->filename,
-				  host_address_to_string (psymtab->user));
-		    gdb_printf ("    dependencies ");
-		    if (psymtab->number_of_dependencies)
-		      {
-			int i;
-
-			gdb_printf ("{\n");
-			for (i = 0; i < psymtab->number_of_dependencies; i++)
-			  {
-			    struct partial_symtab *dep = psymtab->dependencies[i];
-
-			    /* Note the string concatenation there --- no
-			       comma.  */
-			    gdb_printf ("      psymtab %s "
-					"((struct partial_symtab *) %s)\n",
-					dep->filename,
-					host_address_to_string (dep));
-			  }
-			gdb_printf ("    }\n");
-		      }
-		    else
-		      gdb_printf ("(none)\n");
-		    gdb_printf ("  }\n");
-		  }
-	      }
-	  }
-
-	if (printed_objfile_start)
-	  gdb_printf ("}\n");
-      }
-}
-
-/* Check consistency of currently expanded psymtabs vs symtabs.  */
-
-static void
-maintenance_check_psymtabs (const char *ignore, int from_tty)
-{
-  struct symbol *sym;
-  struct compunit_symtab *cust = NULL;
-  const struct blockvector *bv;
-  const struct block *b;
-
-  for (objfile &objfile : current_program_space->objfiles ())
-    {
-      for (const auto &iter : objfile.qf)
-	{
-	  psymbol_functions *psf
-	    = dynamic_cast<psymbol_functions *> (iter.get ());
-	  if (psf == nullptr)
-	    continue;
-
-	  for (partial_symtab *ps : psf->partial_symbols (&objfile))
-	    {
-	      struct gdbarch *gdbarch = objfile.arch ();
-
-	      /* We don't call psymtab_to_symtab here because that may cause symtab
-		 expansion.  When debugging a problem it helps if checkers leave
-		 things unchanged.  */
-	      cust = ps->get_compunit_symtab (&objfile);
-
-	      /* First do some checks that don't require the associated symtab.  */
-	      if (ps->text_high (&objfile) < ps->text_low (&objfile))
-		{
-		  gdb_printf ("Psymtab ");
-		  gdb_puts (ps->filename);
-		  gdb_printf (" covers bad range ");
-		  gdb_puts (paddress (gdbarch, ps->text_low (&objfile)));
-		  gdb_printf (" - ");
-		  gdb_puts (paddress (gdbarch, ps->text_high (&objfile)));
-		  gdb_printf ("\n");
-		  continue;
-		}
-
-	      /* Now do checks requiring the associated symtab.  */
-	      if (cust == NULL)
-		continue;
-	      bv = cust->blockvector ();
-	      b = bv->static_block ();
-	      for (const partial_symbol *psym : ps->static_psymbols)
-		{
-		  /* Skip symbols for inlined functions without address.  These may
-		     or may not have a match in the full symtab.  */
-		  if (psym->loc_class == LOC_BLOCK
-		      && psym->ginfo.value_address () == 0)
-		    continue;
-
-		  lookup_name_info lookup_name
-		    (psym->ginfo.search_name (), symbol_name_match_type::SEARCH_NAME);
-		  sym = block_lookup_symbol (b, lookup_name,
-					     to_search_flags (psym->domain));
-		  if (!sym)
-		    {
-		      gdb_printf ("Static symbol `");
-		      gdb_puts (psym->ginfo.linkage_name ());
-		      gdb_printf ("' only found in ");
-		      gdb_puts (ps->filename);
-		      gdb_printf (" psymtab\n");
-		    }
-		}
-	      b = bv->global_block ();
-	      for (const partial_symbol *psym : ps->global_psymbols)
-		{
-		  lookup_name_info lookup_name
-		    (psym->ginfo.search_name (), symbol_name_match_type::SEARCH_NAME);
-		  sym = block_lookup_symbol (b, lookup_name,
-					     to_search_flags (psym->domain));
-		  if (!sym)
-		    {
-		      gdb_printf ("Global symbol `");
-		      gdb_puts (psym->ginfo.linkage_name ());
-		      gdb_printf ("' only found in ");
-		      gdb_puts (ps->filename);
-		      gdb_printf (" psymtab\n");
-		    }
-		}
-	      if (ps->unrelocated_text_high () != unrelocated_addr (0)
-		  && (ps->text_low (&objfile) < b->start ()
-		      || ps->text_high (&objfile) > b->end ()))
-		{
-		  gdb_printf ("Psymtab ");
-		  gdb_puts (ps->filename);
-		  gdb_printf (" covers ");
-		  gdb_puts (paddress (gdbarch, ps->text_low (&objfile)));
-		  gdb_printf (" - ");
-		  gdb_puts (paddress (gdbarch, ps->text_high (&objfile)));
-		  gdb_printf (" but symtab covers only ");
-		  gdb_puts (paddress (gdbarch, b->start ()));
-		  gdb_printf (" - ");
-		  gdb_puts (paddress (gdbarch, b->end ()));
-		  gdb_printf ("\n");
-		}
-	    }
-	}
-    }
-}
-
-INIT_GDB_FILE (psymtab)
-{
-  add_cmd ("psymbols", class_maintenance, maintenance_print_psymbols, _("\
-Print dump of current partial symbol definitions.\n\
-Usage: mt print psymbols [-objfile OBJFILE] [-pc ADDRESS] [--] [OUTFILE]\n\
-       mt print psymbols [-objfile OBJFILE] [-source SOURCE] [--] [OUTFILE]\n\
-Entries in the partial symbol table are dumped to file OUTFILE,\n\
-or the terminal if OUTFILE is unspecified.\n\
-If ADDRESS is provided, dump only the symbols for the file\n\
-with code at that address.\n\
-If SOURCE is provided, dump only that file's symbols.\n\
-If OBJFILE is provided, dump only that object file's symbols."),
-	   &maintenanceprintlist);
-
-  add_cmd ("psymtabs", class_maintenance, maintenance_info_psymtabs, _("\
-List the partial symbol tables for all object files.\n\
-This does not include information about individual partial symbols,\n\
-just the symbol table structures themselves."),
-	   &maintenanceinfolist);
-
-  add_cmd ("psymtabs", class_maintenance, maintenance_check_psymtabs,
-	   _("\
-Check consistency of currently expanded psymtabs versus symtabs."),
-	   &maintenancechecklist);
-}
diff --git a/gdb/psymtab.h b/gdb/psymtab.h
deleted file mode 100644
index be4ed4262667..000000000000
--- a/gdb/psymtab.h
+++ /dev/null
@@ -1,691 +0,0 @@
-/* Public partial symbol table definitions.
-
-   Copyright (C) 2009-2026 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/>.  */
-
-#ifndef GDB_PSYMTAB_H
-#define GDB_PSYMTAB_H
-
-#include "objfiles.h"
-#include <string_view>
-#include "gdbsupport/gdb_obstack.h"
-#include "symfile.h"
-#include "gdbsupport/next-iterator.h"
-#include "bcache.h"
-
-/* Specialization of bcache to store partial symbols.  */
-
-struct psymbol_bcache : public gdb::bcache
-{
-  /* Calculate a hash code for the given partial symbol.  The hash is
-     calculated using the symbol's value, language, domain, class
-     and name.  These are the values which are set by
-     add_psymbol_to_bcache.  */
-  unsigned long hash (const void *addr, int length) override;
-
-  /* Returns true if the symbol LEFT equals the symbol RIGHT.
-     For the comparison this function uses a symbols value,
-     language, domain, class and name.  */
-  int compare (const void *left, const void *right, int length) override;
-};
-
-/* An instance of this class manages the partial symbol tables and
-   partial symbols for a given objfile.
-
-   The core psymtab functions -- those in psymtab.c -- arrange for
-   nearly all psymtab- and psymbol-related allocations to happen
-   either in the psymtab_storage object (either on its obstack or in
-   other memory managed by this class), or on the per-BFD object.  The
-   only link from the psymtab storage object back to the objfile (or
-   objfile_obstack) that is made by the core psymtab code is the
-   compunit_symtab member in the standard_psymtab -- and a given
-   symbol reader can avoid this by implementing its own subclasses of
-   partial_symtab.
-
-   However, it is up to each symbol reader to maintain this invariant
-   in other ways, if it wants to reuse psymtabs across multiple
-   objfiles.  The main issue here is ensuring that read_symtab_private
-   does not point into objfile_obstack.  */
-
-class psymtab_storage
-{
-public:
-  psymtab_storage () = default;
-  ~psymtab_storage ();
-
-  DISABLE_COPY_AND_ASSIGN (psymtab_storage);
-
-  /* Discard all partial symbol tables starting with "psymtabs" and
-     proceeding until "to" has been discarded.  */
-
-  void discard_psymtabs_to (struct partial_symtab *to)
-  {
-    while (psymtabs != to)
-      discard_psymtab (psymtabs);
-  }
-
-  /* Discard the partial symbol table.  */
-
-  void discard_psymtab (struct partial_symtab *pst);
-
-  /* Return the obstack that is used for storage by this object.  */
-
-  struct obstack *obstack ()
-  {
-    if (!m_obstack.has_value ())
-      m_obstack.emplace ();
-    return &*m_obstack;
-  }
-
-  /* Allocate storage for the "dependencies" field of a psymtab.
-     NUMBER says how many dependencies there are.  */
-
-  struct partial_symtab **allocate_dependencies (int number)
-  {
-    return OBSTACK_CALLOC (obstack (), number, struct partial_symtab *);
-  }
-
-  /* Install a psymtab on the psymtab list.  This transfers ownership
-     of PST to this object.  */
-
-  void install_psymtab (partial_symtab *pst);
-
-  using partial_symtab_range = next_range<partial_symtab>;
-
-  /* A range adapter that makes it possible to iterate over all
-     psymtabs in one objfile.  */
-
-  partial_symtab_range range ()
-  {
-    next_iterator<partial_symtab> begin (psymtabs);
-
-    return partial_symtab_range (std::move (begin));
-  }
-
-
-  /* Each objfile points to a linked list of partial symtabs derived from
-     this file, one partial symtab structure for each compilation unit
-     (source file).  */
-
-  struct partial_symtab *psymtabs = nullptr;
-
-  /* A byte cache where we can stash arbitrary "chunks" of bytes that
-     will not change.  */
-
-  psymbol_bcache psymbol_cache;
-
-private:
-
-  /* The obstack where allocations are made.  This is lazily allocated
-     so that we don't waste memory when there are no psymtabs.  */
-
-  std::optional<auto_obstack> m_obstack;
-};
-
-/* A partial_symbol records the name, domain, and address class of
-   symbols whose types we have not parsed yet.  For functions, it also
-   contains their memory address, so we can find them from a PC value.
-   Each partial_symbol sits in a partial_symtab, all of which are chained
-   on a  partial symtab list and which points to the corresponding
-   normal symtab once the partial_symtab has been referenced.  */
-
-/* This structure is space critical.  See space comments at the top of
-   symtab.h.  */
-
-struct partial_symbol
-{
-  /* Return the section for this partial symbol, or nullptr if no
-     section has been set.  */
-  struct obj_section *obj_section (struct objfile *objfile) const
-  {
-    return ginfo.obj_section (objfile);
-  }
-
-  /* Return the unrelocated address of this partial symbol.  */
-  unrelocated_addr unrelocated_address () const
-  {
-    return ginfo.unrelocated_address ();
-  }
-
-  /* Return the address of this partial symbol, relocated according to
-     the offsets provided in OBJFILE.  */
-  CORE_ADDR address (const struct objfile *objfile) const
-  {
-    return (CORE_ADDR (ginfo.unrelocated_address ())
-	    + objfile->section_offsets[ginfo.section_index ()]);
-  }
-
-  /* Set the address of this partial symbol.  The address must be
-     unrelocated.  */
-  void set_unrelocated_address (unrelocated_addr addr)
-  {
-    ginfo.set_unrelocated_address (addr);
-  }
-
-  /* Note that partial_symbol does not derive from general_symbol_info
-     due to the bcache.  See add_psymbol_to_bcache.  */
-
-  struct general_symbol_info ginfo;
-
-  /* Name space code.  */
-
-  ENUM_BITFIELD(domain_enum) domain : SYMBOL_DOMAIN_BITS;
-
-  /* Address class (for info_symbols).  Note that we don't allow
-     synthetic "loc_class" values here at present, simply because there's
-     no need.  */
-
-  ENUM_BITFIELD(location_class) loc_class : SYMBOL_LOC_CLASS_BITS;
-};
-
-/* A convenience enum to give names to some constants used when
-   searching psymtabs.  This is internal to psymtab and should not be
-   used elsewhere.  */
-
-enum psymtab_search_status
-  {
-    PST_NOT_SEARCHED,
-    PST_SEARCHED_AND_FOUND,
-    PST_SEARCHED_AND_NOT_FOUND
-  };
-
-/* Specify whether a partial psymbol should be allocated on the global
-   list or the static list.  */
-
-enum class psymbol_placement
-{
-  STATIC,
-  GLOBAL
-};
-
-/* 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.  */
-
-struct partial_symtab
-{
-  /* Allocate a new partial symbol table.
-
-     FILENAME (which must be non-NULL) is the filename of this partial
-     symbol table; it is copied into the appropriate storage.  The
-     partial symtab will also be installed using
-     psymtab_storage::install.  */
-
-  partial_symtab (const char *filename,
-		  psymtab_storage *partial_symtabs,
-		  objfile_per_bfd_storage *objfile_per_bfd)
-    ATTRIBUTE_NONNULL (2) ATTRIBUTE_NONNULL (3);
-
-  /* Like the above, but also sets the initial text low and text high
-     from the ADDR argument, and sets the global- and
-     static-offsets.  */
-
-  partial_symtab (const char *filename,
-		  psymtab_storage *partial_symtabs,
-		  objfile_per_bfd_storage *objfile_per_bfd,
-		  unrelocated_addr addr)
-    ATTRIBUTE_NONNULL (2) ATTRIBUTE_NONNULL (3);
-
-  virtual ~partial_symtab ()
-  {
-  }
-
-  /* Psymtab expansion is done in two steps:
-     - a call to read_symtab
-     - while that call is in progress, calls to expand_psymtab can be made,
-       both for this psymtab, and its dependencies.
-     This makes a distinction between a toplevel psymtab (for which both
-     read_symtab and expand_psymtab will be called) and a non-toplevel
-     psymtab (for which only expand_psymtab will be called). The
-     distinction can be used f.i. to do things before and after all
-     dependencies of a top-level psymtab have been expanded.
-
-     Read the full symbol table corresponding to this partial symbol
-     table.  Typically calls expand_psymtab.  */
-  virtual void read_symtab (struct objfile *) = 0;
-
-  /* Expand the full symbol table for this partial symbol table.  Typically
-     calls expand_dependencies.  */
-  virtual void expand_psymtab (struct objfile *) = 0;
-
-  /* Ensure that all the dependencies are read in.  Calls
-     expand_psymtab for each non-shared dependency.  */
-  void expand_dependencies (struct objfile *);
-
-  /* Return true if the symtab corresponding to this psymtab has been
-     read in in the context of this objfile.  */
-  virtual bool readin_p (struct objfile *) const = 0;
-
-  /* Return a pointer to the compunit allocated for this source file
-     in the context of this objfile.
-
-     Return nullptr if the compunit was not read in or if there was no
-     symtab.  */
-  virtual struct compunit_symtab *get_compunit_symtab
-    (struct objfile *) const = 0;
-
-  /* Return the unrelocated low text address of this
-     partial_symtab.  */
-  unrelocated_addr unrelocated_text_low () const
-  {
-    return m_text_low;
-  }
-
-  /* Return the unrelocated_addr high text address of this
-     partial_symtab.  */
-  unrelocated_addr unrelocated_text_high () const
-  {
-    return m_text_high;
-  }
-
-  /* Return the relocated low text address of this partial_symtab.  */
-  CORE_ADDR text_low (struct objfile *objfile) const
-  {
-    return CORE_ADDR (m_text_low) + objfile->text_section_offset ();
-  }
-
-  /* Return the relocated high text address of this partial_symtab.  */
-  CORE_ADDR text_high (struct objfile *objfile) const
-  {
-    return CORE_ADDR (m_text_high) + objfile->text_section_offset ();
-  }
-
-  /* Set the low text address of this partial_symtab.  */
-  void set_text_low (unrelocated_addr addr)
-  {
-    m_text_low = addr;
-    text_low_valid = 1;
-  }
-
-  /* Set the high text address of this partial_symtab.  */
-  void set_text_high (unrelocated_addr addr)
-  {
-    m_text_high = addr;
-    text_high_valid = 1;
-  }
-
-  /* Return true if this symtab is empty -- meaning that it contains
-     no symbols.  It may still have dependencies.  */
-  bool empty () const
-  {
-    return global_psymbols.empty () && static_psymbols.empty ();
-  }
-
-  /* Add a symbol to this partial symbol table of OBJFILE.
-
-     If COPY_NAME is true, make a copy of NAME, otherwise use the passed
-     reference.
-
-     LOC_CLASS is the type of symbol.
-
-     SECTION is the index of the section of OBJFILE in which the symbol is found.
-
-     WHERE determines whether the symbol goes in the list of static or global
-     partial symbols.
-
-     COREADDR is the address of the symbol.  For partial symbols that don't have
-     an address, zero is passed.
-
-     LANGUAGE is the language from which the symbol originates.  This will
-     influence, amongst other things, how the symbol name is demangled. */
-
-  void add_psymbol (std::string_view name,
-		    bool copy_name, domain_enum domain,
-		    location_class loc_class,
-		    int section,
-		    psymbol_placement where,
-		    unrelocated_addr coreaddr,
-		    enum language language,
-		    psymtab_storage *partial_symtabs,
-		    struct objfile *objfile);
-
-  /* Add a symbol to this partial symbol table of OBJFILE.  The psymbol
-     must be fully constructed, and the names must be set and intern'd
-     as appropriate.  */
-
-  void add_psymbol (const partial_symbol &psym,
-		    psymbol_placement where,
-		    psymtab_storage *partial_symtabs,
-		    struct objfile *objfile);
-
-
-  /* Indicate that this partial symtab is complete.  */
-
-  void end ();
-
-  /* Chain of all existing partial symtabs.  */
-
-  struct partial_symtab *next = nullptr;
-
-  /* Name of the source file which this partial_symtab defines,
-     or if the psymtab is anonymous then a descriptive name for
-     debugging purposes, or "".  It must not be NULL.  */
-
-  const char *filename = nullptr;
-
-  /* Full path of the source file.  NULL if not known.  */
-
-  char *fullname = nullptr;
-
-  /* Directory in which it was compiled, or NULL if we don't know.  */
-
-  const char *dirname = nullptr;
-
-  /* Range of text addresses covered by this file; texthigh is the
-     beginning of the next section.  Do not refer directly to these
-     fields.  Instead, use the accessors.  The validity of these
-     fields is determined by the text_low_valid and text_high_valid
-     fields; these are located later in this structure for better
-     packing.  */
-
-  unrelocated_addr m_text_low {};
-  unrelocated_addr m_text_high {};
-
-  /* If NULL, this is an ordinary partial symbol table.
-
-     If non-NULL, this holds a single includer of this partial symbol
-     table, and this partial symbol table is a shared one.
-
-     A shared psymtab is one that is referenced by multiple other
-     psymtabs, and which conceptually has its contents directly
-     included in those.
-
-     Shared psymtabs have special semantics.  When a search finds a
-     symbol in a shared table, we instead return one of the non-shared
-     tables that include this one.
-
-     A shared psymtabs can be referred to by other shared ones.
-
-     The psymtabs that refer to a shared psymtab will list the shared
-     psymtab in their 'dependencies' array.
-
-     In DWARF terms, a shared psymtab is a DW_TAG_partial_unit; but
-     of course using a name based on that would be too confusing, so
-     "shared" was chosen instead.
-
-     Only a single user is needed because, when expanding a shared
-     psymtab, we only need to expand its "canonical" non-shared user.
-     The choice of which one should be canonical is left to the
-     debuginfo reader; it can be arbitrary.  */
-
-  struct partial_symtab *user = nullptr;
-
-  /* Array of pointers to all of the partial_symtab's which this one
-     depends on.  Since this array can only be set to previous or
-     the current (?) psymtab, this dependency tree is guaranteed not
-     to have any loops.  "depends on" means that symbols must be read
-     for the dependencies before being read for this psymtab; this is
-     for type references in stabs, where if foo.c includes foo.h, declarations
-     in foo.h may use type numbers defined in foo.c.  For other debugging
-     formats there may be no need to use dependencies.  */
-
-  struct partial_symtab **dependencies = nullptr;
-
-  int number_of_dependencies = 0;
-
-  /* Global symbol list.  This list will be sorted after readin to
-     improve access.  Binary search will be the usual method of
-     finding a symbol within it.  */
-
-  std::vector<const partial_symbol *> global_psymbols;
-
-  /* Static symbol list.  This list will *not* be sorted after readin;
-     to find a symbol in it, exhaustive search must be used.  This is
-     reasonable because searches through this list will eventually
-     lead to either the read in of a files symbols for real (assumed
-     to take a *lot* of time; check) or an error (and we don't care
-     how long errors take).  */
-
-  std::vector<const partial_symbol *> static_psymbols;
-
-  /* True if the name of this partial symtab is not a source file name.  */
-
-  bool anonymous = false;
-
-  /* A flag that is temporarily used when searching psymtabs.  */
-
-  ENUM_BITFIELD (psymtab_search_status) searched_flag : 2;
-
-  /* Validity of the m_text_low and m_text_high fields.  */
-
-  unsigned int text_low_valid : 1;
-  unsigned int text_high_valid : 1;
-};
-
-/* A partial symtab that tracks the "readin" and "compunit_symtab"
-   information in the ordinary way -- by storing it directly in this
-   object.  */
-struct standard_psymtab : public partial_symtab
-{
-  standard_psymtab (const char *filename,
-		    psymtab_storage *partial_symtabs,
-		    objfile_per_bfd_storage *objfile_per_bfd)
-    : partial_symtab (filename, partial_symtabs, objfile_per_bfd)
-  {
-  }
-
-  standard_psymtab (const char *filename,
-		    psymtab_storage *partial_symtabs,
-		    objfile_per_bfd_storage *objfile_per_bfd,
-		    unrelocated_addr addr)
-    : partial_symtab (filename, partial_symtabs, objfile_per_bfd, addr)
-  {
-  }
-
-  bool readin_p (struct objfile *) const override
-  {
-    return readin;
-  }
-
-  struct compunit_symtab *get_compunit_symtab (struct objfile *) const override
-  {
-    return compunit_symtab;
-  }
-
-  /* True if the symtab corresponding to this psymtab has been
-     readin.  */
-
-  bool readin = false;
-
-  /* Pointer to compunit eventually allocated for this source file, 0 if
-     !readin or if we haven't looked for the symtab after it was readin.  */
-
-  struct compunit_symtab *compunit_symtab = nullptr;
-};
-
-/* A partial_symtab that works in the historical db way.  This should
-   not be used in new code, but exists to transition the somewhat
-   unmaintained "legacy" debug formats.  */
-
-struct legacy_psymtab : public standard_psymtab
-{
-  legacy_psymtab (const char *filename,
-		  psymtab_storage *partial_symtabs,
-		  objfile_per_bfd_storage *objfile_per_bfd)
-    : standard_psymtab (filename, partial_symtabs, objfile_per_bfd)
-  {
-  }
-
-  legacy_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 *objf) override
-  {
-    if (legacy_read_symtab)
-      (*legacy_read_symtab) (this, objf);
-  }
-
-  void expand_psymtab (struct objfile *objf) override
-  {
-    (*legacy_expand_psymtab) (this, objf);
-  }
-
-  /* Pointer to function which will read in the symtab corresponding to
-     this psymtab.  */
-
-  void (*legacy_read_symtab) (legacy_psymtab *, struct objfile *) = nullptr;
-
-  /* Pointer to function which will actually expand this psymtab into
-     a full symtab.  */
-
-  void (*legacy_expand_psymtab) (legacy_psymtab *, struct objfile *) = nullptr;
-
-  /* Information that lets read_symtab() locate the part of the symbol table
-     that this psymtab corresponds to.  This information is private to the
-     format-dependent symbol reading routines.  For further detail examine
-     the various symbol reading modules.  */
-
-  void *read_symtab_private = nullptr;
-};
-
-/* Used when recording partial symbol tables.  On destruction,
-   discards any partial symbol tables that have been built.  However,
-   the tables can be kept by calling the "keep" method.  */
-class psymtab_discarder
-{
- public:
-
-  psymtab_discarder (psymtab_storage *partial_symtabs)
-    : m_partial_symtabs (partial_symtabs),
-      m_psymtab (partial_symtabs->psymtabs)
-  {
-  }
-
-  ~psymtab_discarder ()
-  {
-    if (m_partial_symtabs != nullptr)
-      m_partial_symtabs->discard_psymtabs_to (m_psymtab);
-  }
-
-  /* Keep any partial symbol tables that were built.  */
-  void keep ()
-  {
-    m_partial_symtabs = nullptr;
-  }
-
- private:
-
-  /* The partial symbol storage object.  */
-  psymtab_storage *m_partial_symtabs;
-  /* How far back to free.  */
-  struct partial_symtab *m_psymtab;
-};
-
-/* An implementation of quick_symbol_functions, specialized for
-   partial symbols.  */
-struct psymbol_functions : public quick_symbol_functions
-{
-  explicit psymbol_functions (const std::shared_ptr<psymtab_storage> &storage)
-    : m_partial_symtabs (storage)
-  {
-  }
-
-  psymbol_functions ()
-    : m_partial_symtabs (new psymtab_storage)
-  {
-  }
-
-  bool has_symbols (struct objfile *objfile) override;
-
-  bool has_unexpanded_symtabs (struct objfile *objfile) override;
-
-  struct symtab *find_last_source_symtab (struct objfile *objfile) override;
-
-  void forget_cached_source_info (struct objfile *objfile) override;
-
-  enum language lookup_global_symbol_language (struct objfile *objfile,
-					       const char *name,
-					       domain_search_flags domain,
-					       bool *symbol_found_p) override;
-
-  void print_stats (struct objfile *objfile, bool print_bcache) override;
-
-  void dump (struct objfile *objfile) override;
-
-  void expand_all_symtabs (struct objfile *objfile) override;
-
-  bool search
-    (struct objfile *objfile,
-     search_symtabs_file_matcher file_matcher,
-     const lookup_name_info *lookup_name,
-     search_symtabs_symbol_matcher symbol_matcher,
-     search_symtabs_expansion_listener listener,
-     block_search_flags search_flags,
-     domain_search_flags kind,
-     search_symtabs_lang_matcher lang_matcher) override;
-
-  struct compunit_symtab *find_pc_sect_compunit_symtab
-    (struct objfile *objfile, bound_minimal_symbol msymbol, CORE_ADDR pc,
-     struct obj_section *section, int warn_if_readin) override;
-
-  struct symbol *find_symbol_by_address
-    (struct objfile *objfile, CORE_ADDR address) override
-  {
-    return nullptr;
-  }
-
-  void map_symbol_filenames (objfile *objfile, symbol_filename_listener fun,
-			     bool need_fullname) override;
-
-  /* Return a range adapter for the psymtabs.  */
-  psymtab_storage::partial_symtab_range partial_symbols
-       (struct objfile *objfile);
-
-  /* Return the partial symbol storage associated with this
-     object.  */
-  const std::shared_ptr<psymtab_storage> &get_partial_symtabs () const
-  {
-    return m_partial_symtabs;
-  }
-
-  /* Replace the partial symbol table storage in this object with
-     SYMS.  */
-  void set_partial_symtabs (const std::shared_ptr<psymtab_storage> &syms)
-  {
-    m_partial_symtabs = syms;
-  }
-
-  /* Find which partial symtab contains PC and SECTION.  Return NULL if
-     none.  We return the psymtab that contains a symbol whose address
-     exactly matches PC, or, if we cannot find an exact match, the
-     psymtab that contains a symbol whose address is closest to PC.  */
-
-  struct partial_symtab *find_pc_sect_psymtab (struct objfile *objfile,
-					       CORE_ADDR pc,
-					       struct obj_section *section,
-					       bound_minimal_symbol msymbol);
-
-private:
-
-  /* Count the number of partial symbols in *THIS.  */
-  int count_psyms ();
-
-  /* Storage for the partial symbols.  */
-  std::shared_ptr<psymtab_storage> m_partial_symtabs;
-};
-
-#endif /* GDB_PSYMTAB_H */
-- 
2.53.0


^ permalink raw reply	[flat|nested] 52+ messages in thread

* [PATCH v3 0/9] Make CTF reader build full symtabs, get rid of psymtab
  2026-02-17 19:50 ` [PATCH v2 0/9] " simon.marchi
                     ` (8 preceding siblings ...)
  2026-02-17 19:50   ` [PATCH v2 9/9] gdb: remove psymtab.{c,h} simon.marchi
@ 2026-02-28  3:51   ` Simon Marchi
  2026-02-28  3:51     ` [PATCH v3 1/9] gdb/ctf: add debug logging in ctfread.c Simon Marchi
                       ` (9 more replies)
  9 siblings, 10 replies; 52+ messages in thread
From: Simon Marchi @ 2026-02-28  3:51 UTC (permalink / raw)
  To: gdb-patches; +Cc: Simon Marchi

This is v3 of:

https://inbox.sourceware.org/gdb-patches/20260217195329.3833518-1-simon.marchi@polymtl.ca/

The change is that the last patch now includes necessary test changes
(to avoid regressions), plus doc and NEWS changes.


Simon Marchi (9):
  gdb/ctf: add debug logging in ctfread.c
  gdb/ctf: add unique_ptr types
  gdb/ctf: editorial renames
  gdb/ctf: use ctf_per_objfile in ctf_archive_iter_psymtab_data and
    ctf_context
  gdb/ctf: check return value of ctf_type_align
  gdb/ctf: add scoped_time_it in elfctf_build_psymtabs
  gdb: make expanded_symbols_functions hold compunit symtabs
  gdb/ctf: don't use psymtabs, create symtabs directly
  gdb: remove psymtab.{c,h}

 gdb/Makefile.in                          |    2 -
 gdb/NEWS                                 |   12 +
 gdb/ctfread.c                            |  737 ++++------
 gdb/ctfread.h                            |    2 +-
 gdb/doc/gdb.texinfo                      |  102 +-
 gdb/elfread.c                            |    8 +-
 gdb/expanded-symbol.c                    |   16 +-
 gdb/expanded-symbol.h                    |    8 +
 gdb/jit.c                                |   16 +-
 gdb/psymtab.c                            | 1575 ----------------------
 gdb/psymtab.h                            |  691 ----------
 gdb/testsuite/gdb.ada/maint_with_ada.exp |    2 -
 gdb/testsuite/gdb.base/check-psymtab.c   |   28 -
 gdb/testsuite/gdb.base/check-psymtab.exp |   26 -
 gdb/testsuite/gdb.base/main-psymtab.exp  |   38 -
 gdb/testsuite/gdb.base/maint.exp         |   96 +-
 gdb/testsuite/gdb.base/readnever.exp     |    4 -
 gdb/testsuite/lib/gdb.exp                |   22 -
 18 files changed, 375 insertions(+), 3010 deletions(-)
 delete mode 100644 gdb/psymtab.c
 delete mode 100644 gdb/psymtab.h
 delete mode 100644 gdb/testsuite/gdb.base/check-psymtab.c
 delete mode 100644 gdb/testsuite/gdb.base/check-psymtab.exp
 delete mode 100644 gdb/testsuite/gdb.base/main-psymtab.exp


base-commit: d7f532cb3a46527c56963a2c713e29cee4f64eee
-- 
2.53.0


^ permalink raw reply	[flat|nested] 52+ messages in thread

* [PATCH v3 1/9] gdb/ctf: add debug logging in ctfread.c
  2026-02-28  3:51   ` [PATCH v3 0/9] Make CTF reader build full symtabs, get rid of psymtab Simon Marchi
@ 2026-02-28  3:51     ` Simon Marchi
  2026-02-28 10:12       ` Eli Zaretskii
  2026-02-28  3:51     ` [PATCH v3 2/9] gdb/ctf: add unique_ptr types Simon Marchi
                       ` (8 subsequent siblings)
  9 siblings, 1 reply; 52+ messages in thread
From: Simon Marchi @ 2026-02-28  3:51 UTC (permalink / raw)
  To: gdb-patches; +Cc: Simon Marchi, Eli Zaretskii

From: Simon Marchi <simon.marchi@polymtl.ca>

Add some debug statements, to be able to visualize what is happening
when loading CTF debug info.  Add a new "set debug ctf" command, with
the usual logging macros.

Here's an example of the result, when reading the binary from test
gdb.ctf/cruss-tu-cyclic:

    [ctf] elfctf_build_psymtabs: start: building psymtabs for /home/simark/build/binutils-gdb/gdb/testsuite/outputs/gdb.ctf/cross-tu-cyclic/cross-tu-cyclic
      [ctf] scan_partial_symbols: start: fname='.ctf'
        [ctf] scan_partial_symbols: is parent, using fname='/home/simark/build/binutils-gdb/gdb/testsuite/outputs/gdb.ctf/cross-tu-cyclic/cross-tu-cyclic'
        [ctf] ctf_psymtab_type_cb: adding type tid=0x1 kind=INTEGER name='int'
        [ctf] ctf_psymtab_type_cb: adding type tid=0x2 kind=INTEGER name='long int'
        [ctf] ctf_psymtab_type_cb: adding type tid=0x3 kind=FORWARD name='B'
        [ctf] ctf_psymtab_type_cb: adding type tid=0x5 kind=FORWARD name='A'
        [ctf] ctf_psymtab_type_cb: adding type tid=0x8 kind=STRUCT name='C'
        [ctf] ctf_psymtab_add_stt_entries: adding function psym 'main' tid=0x7 kind=FUNCTION
      [ctf] scan_partial_symbols: end: fname='.ctf'
      [ctf] scan_partial_symbols: start: fname='/home/simark/src/binutils-gdb/gdb/testsuite/gdb.ctf/cross-tu-cyclic-1.c'
        [ctf] ctf_psymtab_type_cb: adding type tid=0x80000001 kind=STRUCT name='B'
        [ctf] ctf_psymtab_type_cb: adding type tid=0x80000002 kind=STRUCT name='A'
      [ctf] scan_partial_symbols: end: fname='/home/simark/src/binutils-gdb/gdb/testsuite/gdb.ctf/cross-tu-cyclic-1.c'
      [ctf] scan_partial_symbols: start: fname='/home/simark/src/binutils-gdb/gdb/testsuite/gdb.ctf/cross-tu-cyclic-2.c'
        [ctf] ctf_psymtab_type_cb: adding type tid=0x80000001 kind=STRUCT name='A'
      [ctf] scan_partial_symbols: end: fname='/home/simark/src/binutils-gdb/gdb/testsuite/gdb.ctf/cross-tu-cyclic-2.c'
      [ctf] scan_partial_symbols: start: fname='/home/simark/src/binutils-gdb/gdb/testsuite/gdb.ctf/cross-tu-cyclic-3.c'
        [ctf] ctf_psymtab_type_cb: adding type tid=0x80000001 kind=STRUCT name='A'
      [ctf] scan_partial_symbols: end: fname='/home/simark/src/binutils-gdb/gdb/testsuite/gdb.ctf/cross-tu-cyclic-3.c'
      [ctf] scan_partial_symbols: start: fname='/home/simark/src/binutils-gdb/gdb/testsuite/gdb.ctf/cross-tu-cyclic-4.c'
        [ctf] ctf_psymtab_type_cb: adding type tid=0x80000001 kind=STRUCT name='A'
        [ctf] ctf_psymtab_type_cb: adding type tid=0x80000002 kind=STRUCT name='B'
      [ctf] scan_partial_symbols: end: fname='/home/simark/src/binutils-gdb/gdb/testsuite/gdb.ctf/cross-tu-cyclic-4.c'
    [ctf] elfctf_build_psymtabs: end: building psymtabs for /home/simark/build/binutils-gdb/gdb/testsuite/outputs/gdb.ctf/cross-tu-cyclic/cross-tu-cyclic

Change-Id: If3800d14dd965ccefa67a24ef5c4481aef70ffa4
Reviewed-By: Eli Zaretskii <eliz@gnu.org>
---
 gdb/NEWS            |  4 ++
 gdb/ctfread.c       | 95 ++++++++++++++++++++++++++++++++++++++++++++-
 gdb/doc/gdb.texinfo |  7 ++++
 3 files changed, 104 insertions(+), 2 deletions(-)

diff --git a/gdb/NEWS b/gdb/NEWS
index d70147144e49..e83d1abd73b3 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -98,6 +98,10 @@ set debug gnu-ifunc on|off
 show debug gnu-ifunc
   Turn on or off debug messages related to GNU ifunc resolution.
 
+set debug ctf on|off
+show debug ctf
+  Turn on or off debug messages about CTF reading.
+
 set progress-bars enabled on|off
 show progress-bars enabled
   Allows the progress bars, used when debuginfod is downloading
diff --git a/gdb/ctfread.c b/gdb/ctfread.c
index e24d0ef60d02..141f51f621b0 100644
--- a/gdb/ctfread.c
+++ b/gdb/ctfread.c
@@ -80,12 +80,49 @@
 #include "block.h"
 #include "ctfread.h"
 #include "psymtab.h"
+#include "cli/cli-cmds.h"
+
+/* When true, print debug messages related to CTF reading.  */
+static bool debug_ctf = false;
+
+/* Print a "ctf" debug statement.  */
+
+#define ctf_debug_printf(fmt, ...) \
+  debug_prefixed_printf_cond (debug_ctf, "ctf", fmt, ##__VA_ARGS__)
+
+#define CTF_SCOPED_DEBUG_START_END(fmt, ...) \
+  scoped_debug_start_end (debug_ctf, "ctf", fmt, ##__VA_ARGS__)
 
 #if ENABLE_LIBCTF
 
 #include "ctf.h"
 #include "ctf-api.h"
 
+/* Return a string representation of a CTF type kind.  */
+
+static const char *
+ctf_kind_str (uint32_t kind)
+{
+  switch (kind)
+    {
+    case CTF_K_UNKNOWN: return "UNKNOWN";
+    case CTF_K_INTEGER: return "INTEGER";
+    case CTF_K_FLOAT: return "FLOAT";
+    case CTF_K_POINTER: return "POINTER";
+    case CTF_K_ARRAY: return "ARRAY";
+    case CTF_K_FUNCTION: return "FUNCTION";
+    case CTF_K_STRUCT: return "STRUCT";
+    case CTF_K_UNION: return "UNION";
+    case CTF_K_ENUM: return "ENUM";
+    case CTF_K_FORWARD: return "FORWARD";
+    case CTF_K_TYPEDEF: return "TYPEDEF";
+    case CTF_K_VOLATILE: return "VOLATILE";
+    case CTF_K_CONST: return "CONST";
+    case CTF_K_RESTRICT: return "RESTRICT";
+    default: return "???";
+    }
+}
+
 using ctf_type_map = gdb::unordered_map<ctf_id_t, struct type *>;
 
 struct ctf_dict_info
@@ -992,10 +1029,18 @@ ctf_add_type_cb (ctf_id_t tid, void *arg)
   /* Check if tid's type has already been defined.  */
   type = get_tid_type (ccp->of, tid);
   if (type != nullptr)
-    return 0;
+    {
+      ctf_debug_printf ("tid=%ld already defined, skipping", tid);
+      return 0;
+    }
 
   ctf_id_t btid = ctf_type_reference (ccp->dict, tid);
   kind = ctf_type_kind (ccp->dict, tid);
+
+  ctf_debug_printf ("processing tid=%ld kind=%s name='%s' btid=%ld",
+		    tid, ctf_kind_str (kind),
+		    ctf_type_name_raw (ccp->dict, tid) ? : "(null)", btid);
+
   switch (kind)
     {
       case CTF_K_STRUCT:
@@ -1059,6 +1104,9 @@ ctf_add_var_cb (const char *name, ctf_id_t id, void *arg)
 
   kind = ctf_type_kind (ccp->dict, id);
 
+  ctf_debug_printf ("adding variable name='%s' tid=%ld kind=%s",
+		    name, id, ctf_kind_str (kind));
+
   if (type == nullptr)
     {
       complaint (_("ctf_add_var_cb: %s has NO type (%ld)"), name, id);
@@ -1101,7 +1149,15 @@ add_stt_entries (struct ctf_context *ccp, int functions)
     {
       type = get_tid_type (ccp->of, tid);
       if (type == nullptr)
-	continue;
+	{
+	  ctf_debug_printf ("skipping '%s' tid=0x%lx (no type found)",
+			    tname, tid);
+	  continue;
+	}
+
+      ctf_debug_printf ("adding %s '%s' tid=0x%lx",
+			functions ? "function" : "object", tname, tid);
+
       sym = new (&ccp->of->objfile_obstack) symbol;
       OBJSTAT (ccp->of, n_syms++);
       sym->set_type (type);
@@ -1186,6 +1242,10 @@ ctf_psymtab_add_stt_entries (ctf_dict_t *dict, ctf_psymtab *pst,
       else
 	loc_class = LOC_STATIC;
 
+      ctf_debug_printf ("adding %s psym '%s' tid=0x%lx kind=%s",
+			functions ? "function" : "object", tname, tid,
+			ctf_kind_str (kind));
+
       pst->add_psymbol (tname, true,
 			tdomain, loc_class, -1,
 			psymbol_placement::GLOBAL,
@@ -1219,6 +1279,8 @@ ctf_psymtab::expand_psymtab (struct objfile *objfile)
 {
   struct ctf_context *ccp;
 
+  CTF_SCOPED_DEBUG_START_END ("expanding psymtab");
+
   gdb_assert (!readin);
 
   ccp = &context;
@@ -1247,6 +1309,8 @@ ctf_psymtab::expand_psymtab (struct objfile *objfile)
 void
 ctf_psymtab::read_symtab (struct objfile *objfile)
 {
+  CTF_SCOPED_DEBUG_START_END ("reading symtab for '%s'", filename);
+
   if (readin)
     warning (_("bug: psymtab for %s is already read in."), filename);
   else
@@ -1263,6 +1327,9 @@ ctf_psymtab::read_symtab (struct objfile *objfile)
 
       offset = get_objfile_text_range (objfile, &tsize);
 
+      ctf_debug_printf ("starting buildsym for '%s', offset=%s, tsize=%zu",
+			filename, hex_string (offset), tsize);
+
       buildsym_compunit builder (objfile, this->filename, nullptr,
 				 language_c, offset);
       builder.record_debugformat ("ctf");
@@ -1360,6 +1427,9 @@ ctf_psymtab_type_cb (ctf_id_t tid, void *arg)
   if (name == nullptr || *name == '\0')
     return 0;
 
+  ctf_debug_printf ("adding type tid=0x%lx kind=%s name='%s'",
+		    tid, ctf_kind_str (kind), name);
+
   ccp->pst->add_psymbol (name, false,
 			 domain, loc_class, section,
 			 psymbol_placement::GLOBAL,
@@ -1377,6 +1447,10 @@ ctf_psymtab_var_cb (const char *name, ctf_id_t id, void *arg)
   struct ctf_context *ccp = (struct ctf_context *) arg;
 
   uint32_t kind = ctf_type_kind (ccp->dict, id);
+
+  ctf_debug_printf ("adding variable name='%s' tid=0x%lx kind=%s",
+		    name, id, ctf_kind_str (kind));
+
   ccp->pst->add_psymbol (name, true,
 			 kind == CTF_K_FUNCTION
 			 ? FUNCTION_DOMAIN
@@ -1398,10 +1472,13 @@ scan_partial_symbols (ctf_dict_t *dict, psymtab_storage *partial_symtabs,
   struct objfile *of = tup->of;
   bool isparent = false;
 
+  CTF_SCOPED_DEBUG_START_END ("fname='%s'", fname);
+
   if (strcmp (fname, ".ctf") == 0)
     {
       fname = bfd_get_filename (of->obfd.get ());
       isparent = true;
+      ctf_debug_printf ("is parent, using fname='%s'", fname);
     }
 
   ctf_psymtab *pst = create_partial_symtab (fname, tup->arc, dict,
@@ -1462,6 +1539,9 @@ elfctf_build_psymtabs (struct objfile *of)
   bfd *abfd = of->obfd.get ();
   int err;
 
+  CTF_SCOPED_DEBUG_START_END ("building psymtabs for %s",
+			      bfd_get_filename (abfd));
+
   ctf_archive_t *arc = ctf_bfdopen (abfd, &err);
   if (arc == nullptr)
     error (_("ctf_bfdopen failed on %s - %s"),
@@ -1495,3 +1575,14 @@ elfctf_build_psymtabs (struct objfile *of)
 }
 
 #endif /* ENABLE_LIBCTF */
+
+INIT_GDB_FILE (_initialize_ctfread)
+{
+  add_setshow_boolean_cmd ("ctf", no_class, &debug_ctf,
+			   _("Set CTF reading debugging."),
+			   _("Show CTF reading debugging."),
+			   _("When true, print debug messages related to "
+			     "CTF reading."),
+			   nullptr, nullptr,
+			   &setdebuglist, &showdebuglist);
+}
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index c74c58c1d4a8..8561c04f26a0 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -29284,6 +29284,13 @@ exported symbols.  The default is off.
 Displays the current state of displaying debugging messages related to
 reading of COFF/PE exported symbols.
 
+@cindex CTF debug messages
+@item set debug ctf
+Turns on or off display of debugging messages related to reading CTF
+debug info.  The default is off.
+@item show debug ctf
+Displays the current state of CTF debug info reading messages.
+
 @item set debug dwarf-die
 @cindex DWARF DIEs
 Dump DWARF DIEs after they are read in.
-- 
2.53.0


^ permalink raw reply	[flat|nested] 52+ messages in thread

* [PATCH v3 2/9] gdb/ctf: add unique_ptr types
  2026-02-28  3:51   ` [PATCH v3 0/9] Make CTF reader build full symtabs, get rid of psymtab Simon Marchi
  2026-02-28  3:51     ` [PATCH v3 1/9] gdb/ctf: add debug logging in ctfread.c Simon Marchi
@ 2026-02-28  3:51     ` Simon Marchi
  2026-02-28  3:51     ` [PATCH v3 3/9] gdb/ctf: editorial renames Simon Marchi
                       ` (7 subsequent siblings)
  9 siblings, 0 replies; 52+ messages in thread
From: Simon Marchi @ 2026-02-28  3:51 UTC (permalink / raw)
  To: gdb-patches; +Cc: Simon Marchi

From: Simon Marchi <simon.marchi@polymtl.ca>

Add ctf_archive_up and ctf_dict_up to automatically manage the lifetime
of a ctf_archive_t or ctf_dict_t and use them.

Change-Id: I51b3548b1bb28941c7bad776a11a238eb25789e4
---
 gdb/ctfread.c | 56 ++++++++++++++++++++++++++++++++-------------------
 1 file changed, 35 insertions(+), 21 deletions(-)

diff --git a/gdb/ctfread.c b/gdb/ctfread.c
index 141f51f621b0..6c1bbebcf2c8 100644
--- a/gdb/ctfread.c
+++ b/gdb/ctfread.c
@@ -125,29 +125,41 @@ ctf_kind_str (uint32_t kind)
 
 using ctf_type_map = gdb::unordered_map<ctf_id_t, struct type *>;
 
+struct ctf_archive_closer
+{
+  void operator() (ctf_archive_t *arc) const noexcept
+  {
+    ctf_close (arc);
+  }
+};
+
+using ctf_archive_up = std::unique_ptr<ctf_archive_t, ctf_archive_closer>;
+
+struct ctf_dict_closer
+{
+  void operator() (ctf_dict_t *dict) const noexcept
+  {
+    ctf_dict_close (dict);
+  }
+};
+
+using ctf_dict_up = std::unique_ptr<ctf_dict_t, ctf_dict_closer>;
+
 struct ctf_dict_info
 {
-  explicit ctf_dict_info (ctf_dict_t *dict) : dict (dict) {}
-  ~ctf_dict_info ();
+  explicit ctf_dict_info (ctf_archive_up archive, ctf_dict_up dict)
+    : archive (std::move (archive)),
+      dict (std::move (dict))
+  {}
 
   /* Map from IDs to types.  */
   ctf_type_map type_map;
 
-  /* The dictionary.  */
-  ctf_dict_t *dict;
+  /* The archive and dictionary.  */
+  ctf_archive_up archive;
+  ctf_dict_up dict;
 };
 
-/* Cleanup function for the ctf_dict_key data.  */
-ctf_dict_info::~ctf_dict_info ()
-{
-  if (dict == nullptr)
-    return;
-
-  ctf_archive_t *arc = ctf_get_arc (dict);
-  ctf_dict_close (dict);
-  ctf_close (arc);
-}
-
 static const registry<objfile>::key<ctf_dict_info> ctf_dict_key;
 
 /* A CTF context consists of a file pointer and an objfile pointer.  */
@@ -1542,26 +1554,28 @@ elfctf_build_psymtabs (struct objfile *of)
   CTF_SCOPED_DEBUG_START_END ("building psymtabs for %s",
 			      bfd_get_filename (abfd));
 
-  ctf_archive_t *arc = ctf_bfdopen (abfd, &err);
+  ctf_archive_up 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 *dict = ctf_dict_open (arc, NULL, &err);
+  ctf_dict_up dict (ctf_dict_open (arc.get (), NULL, &err));
   if (dict == nullptr)
     error (_("ctf_dict_open failed on %s - %s"),
 	   bfd_get_filename (abfd), ctf_errmsg (err));
-  ctf_dict_key.emplace (of, dict);
 
-  pcu.dict = dict;
+  ctf_dict_info &dict_info
+    = ctf_dict_key.emplace (of, std::move (arc), std::move (dict));
+
+  pcu.dict = dict_info.dict.get ();
   pcu.of = of;
-  pcu.arc = arc;
+  pcu.arc = dict_info.archive.get ();
 
   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)
+  if (ctf_archive_iter (pcu.arc, build_ctf_archive_member, &pcu) < 0)
     error (_("ctf_archive_iter failed in input file %s: - %s"),
 	   bfd_get_filename (abfd), ctf_errmsg (err));
 }
-- 
2.53.0


^ permalink raw reply	[flat|nested] 52+ messages in thread

* [PATCH v3 3/9] gdb/ctf: editorial renames
  2026-02-28  3:51   ` [PATCH v3 0/9] Make CTF reader build full symtabs, get rid of psymtab Simon Marchi
  2026-02-28  3:51     ` [PATCH v3 1/9] gdb/ctf: add debug logging in ctfread.c Simon Marchi
  2026-02-28  3:51     ` [PATCH v3 2/9] gdb/ctf: add unique_ptr types Simon Marchi
@ 2026-02-28  3:51     ` Simon Marchi
  2026-02-28  3:51     ` [PATCH v3 4/9] gdb/ctf: use ctf_per_objfile in ctf_archive_iter_psymtab_data and ctf_context Simon Marchi
                       ` (6 subsequent siblings)
  9 siblings, 0 replies; 52+ messages in thread
From: Simon Marchi @ 2026-02-28  3:51 UTC (permalink / raw)
  To: gdb-patches; +Cc: Simon Marchi

From: Simon Marchi <simon.marchi@polymtl.ca>

Rename a few things to fit a bit more with how we typically name things,
or make the names more accurate.  I think this makes the code easier to
follow for anyone familiar with the GDB codebase (or at least, familiar
with the DWARF reader).  It's not super important, but it did help me
understand better the flow of the reader.

 - struct ctf_dict_info -> struct ctf_per_objfile
 - ctf_per_objfile::dict -> ctf_per_objfile::parent_dict
 - ctf_dict_key -> ctf_per_objfile_key
 - ctf_per_tu_data -> ctf_archive_iter_psymtab_data
 - ctf_archive_iter_psymtab_data::dict -> ctf_archive_iter_psymtab_data::parent_dict
 - of -> objfile
 - arc -> archive
 - In build_ctf_archive_member, ctf -> dict

Change-Id: I40f3cba8e40e4c9d006a96032a4c3856bd762ed5
---
 gdb/ctfread.c | 235 +++++++++++++++++++++++++-------------------------
 1 file changed, 119 insertions(+), 116 deletions(-)

diff --git a/gdb/ctfread.c b/gdb/ctfread.c
index 6c1bbebcf2c8..9b999c2560b9 100644
--- a/gdb/ctfread.c
+++ b/gdb/ctfread.c
@@ -145,29 +145,29 @@ struct ctf_dict_closer
 
 using ctf_dict_up = std::unique_ptr<ctf_dict_t, ctf_dict_closer>;
 
-struct ctf_dict_info
+struct ctf_per_objfile
 {
-  explicit ctf_dict_info (ctf_archive_up archive, ctf_dict_up dict)
+  explicit ctf_per_objfile (ctf_archive_up archive, ctf_dict_up dict)
     : archive (std::move (archive)),
-      dict (std::move (dict))
+      parent_dict (std::move (dict))
   {}
 
   /* Map from IDs to types.  */
   ctf_type_map type_map;
 
-  /* The archive and dictionary.  */
+  /* The archive and parent dictionary.  */
   ctf_archive_up archive;
-  ctf_dict_up dict;
+  ctf_dict_up parent_dict;
 };
 
-static const registry<objfile>::key<ctf_dict_info> ctf_dict_key;
+static const registry<objfile>::key<ctf_per_objfile> ctf_per_objfile_key;
 
 /* A CTF context consists of a file pointer and an objfile pointer.  */
 
 struct ctf_context
 {
   ctf_dict_t *dict;
-  struct objfile *of;
+  struct objfile *objfile;
   psymtab_storage *partial_symtabs;
   partial_symtab *pst;
   ctf_archive_t *arc;
@@ -220,13 +220,13 @@ struct ctf_field_info
   std::vector<struct decl_field> nested_types_list;
 };
 
-/* Data held for a translation unit.  */
+/* Data held while using ctf_archive_iter to build psymtabs.  */
 
-struct ctf_per_tu_data
+struct ctf_archive_iter_psymtab_data
 {
-  ctf_dict_t *dict;
-  struct objfile *of;
-  ctf_archive_t *arc;
+  ctf_dict_t *parent_dict;
+  struct objfile *objfile;
+  ctf_archive_t *archive;
   psymbol_functions *psf;
 };
 
@@ -258,11 +258,11 @@ static struct type *read_forward_type (struct ctf_context *cp, ctf_id_t 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)
+set_tid_type (struct objfile *objfile, ctf_id_t tid, struct type *typ)
 {
-  ctf_dict_info *info = ctf_dict_key.get (of);
-  gdb_assert (info != nullptr);
-  info->type_map.emplace (tid, typ);
+  ctf_per_objfile *per_objfile = ctf_per_objfile_key.get (objfile);
+  gdb_assert (per_objfile != nullptr);
+  per_objfile->type_map.emplace (tid, typ);
   return typ;
 }
 
@@ -270,13 +270,13 @@ set_tid_type (struct objfile *of, ctf_id_t tid, struct type *typ)
    does not have a saved type.  */
 
 static struct type *
-get_tid_type (struct objfile *of, ctf_id_t tid)
+get_tid_type (struct objfile *objfile, ctf_id_t tid)
 {
-  ctf_dict_info *info = ctf_dict_key.get (of);
-  gdb_assert (info != nullptr);
+  ctf_per_objfile *per_objfile = ctf_per_objfile_key.get (objfile);
+  gdb_assert (per_objfile != nullptr);
 
-  auto iter = info->type_map.find (tid);
-  if (iter == info->type_map.end ())
+  auto iter = per_objfile->type_map.find (tid);
+  if (iter == per_objfile->type_map.end ())
     return nullptr;
   return iter->second;
 }
@@ -287,14 +287,14 @@ get_tid_type (struct objfile *of, ctf_id_t tid)
 static struct type *
 fetch_tid_type (struct ctf_context *ccp, ctf_id_t tid)
 {
-  struct objfile *of = ccp->of;
+  struct objfile *objfile = ccp->objfile;
   struct type *typ;
 
-  typ = get_tid_type (of, tid);
+  typ = get_tid_type (objfile, tid);
   if (typ == nullptr)
     {
       ctf_add_type_cb (tid, ccp);
-      typ = get_tid_type (of, tid);
+      typ = get_tid_type (objfile, tid);
     }
 
   return typ;
@@ -319,10 +319,11 @@ get_bitsize (ctf_dict_t *dict, ctf_id_t tid, uint32_t kind)
 /* 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)
+set_symbol_address (struct objfile *objfile, struct symbol *sym,
+		    const char *name)
 {
   bound_minimal_symbol msym
-    = lookup_minimal_symbol (current_program_space, name, of);
+    = lookup_minimal_symbol (current_program_space, name, objfile);
   if (msym.minsym != NULL)
     {
       sym->set_value_address (msym.value_address ());
@@ -404,8 +405,8 @@ ctf_add_member_cb (const char *name,
       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);
+	  t = builtin_type (ccp->objfile)->builtin_error;
+	  set_tid_type (ccp->objfile, tid, t);
 	}
     }
 
@@ -440,11 +441,11 @@ ctf_add_enum_member_cb (const char *name, int enum_value, void *arg)
 
   if (name != nullptr && *name != '\0')
     {
-      struct symbol *sym = new (&ccp->of->objfile_obstack) symbol;
-      OBJSTAT (ccp->of, n_syms++);
+      struct symbol *sym = new (&ccp->objfile->objfile_obstack) symbol;
+      OBJSTAT (ccp->objfile, n_syms++);
 
-      sym->set_language (language_c, &ccp->of->objfile_obstack);
-      sym->compute_and_set_names (name, false, ccp->of->per_bfd);
+      sym->set_language (language_c, &ccp->objfile->objfile_obstack);
+      sym->compute_and_set_names (name, false, ccp->objfile->per_bfd);
       sym->set_loc_class_index (LOC_CONST);
       sym->set_domain (VAR_DOMAIN);
       sym->set_type (fip->ptype);
@@ -467,7 +468,7 @@ new_type_symbol (struct ctf_context *ccp, struct type *type, ctf_id_t tid)
   const char *name = ctf_type_name_raw (dict, tid);
   if (name != nullptr && *name != '\0')
     {
-      struct objfile *objfile = ccp->of;
+      struct objfile *objfile = ccp->objfile;
       struct symbol *sym = new (&objfile->objfile_obstack) symbol;
       OBJSTAT (objfile, n_syms++);
 
@@ -499,7 +500,7 @@ new_type_symbol (struct ctf_context *ccp, struct type *type, ctf_id_t tid)
 static struct type *
 read_base_type (struct ctf_context *ccp, ctf_id_t tid)
 {
-  struct objfile *of = ccp->of;
+  struct objfile *objfile = ccp->objfile;
   ctf_dict_t *dict = ccp->dict;
   ctf_encoding_t cet;
   struct type *type = nullptr;
@@ -522,12 +523,12 @@ read_base_type (struct ctf_context *ccp, ctf_id_t tid)
 		   ctf_errmsg (ctf_errno (dict)));
     }
 
-  type_allocator alloc (of, language_c);
+  type_allocator alloc (objfile, language_c);
   kind = ctf_type_kind (dict, tid);
   if (kind == CTF_K_INTEGER)
     {
       uint32_t issigned, ischar, isbool;
-      struct gdbarch *gdbarch = of->arch ();
+      struct gdbarch *gdbarch = objfile->arch ();
 
       issigned = cet.cte_format & CTF_INT_SIGNED;
       ischar = cet.cte_format & CTF_INT_CHAR;
@@ -554,11 +555,11 @@ read_base_type (struct ctf_context *ccp, ctf_id_t tid)
 		 || (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);
+	type = ctf_init_float_type (objfile, cet.cte_bits, name, name);
       else
 	{
 	  struct type *t
-	    = ctf_init_float_type (of, cet.cte_bits / 2, NULL, name);
+	    = ctf_init_float_type (objfile, cet.cte_bits / 2, NULL, name);
 	  type = init_complex_type (name, t);
 	}
     }
@@ -571,7 +572,7 @@ read_base_type (struct ctf_context *ccp, ctf_id_t tid)
   if (name != nullptr && strcmp (name, "char") == 0)
     type->set_has_no_signedness (true);
 
-  return set_tid_type (of, tid, type);
+  return set_tid_type (objfile, tid, type);
 }
 
 static void
@@ -593,12 +594,12 @@ process_base_type (struct ctf_context *ccp, ctf_id_t tid)
 static struct type *
 read_structure_type (struct ctf_context *ccp, ctf_id_t tid)
 {
-  struct objfile *of = ccp->of;
+  struct objfile *objfile = ccp->objfile;
   ctf_dict_t *dict = ccp->dict;
   struct type *type;
   uint32_t kind;
 
-  type = type_allocator (of, language_c).new_type ();
+  type = type_allocator (objfile, language_c).new_type ();
 
   const char *name = ctf_type_name_raw (dict, tid);
   if (name != nullptr && *name != '\0')
@@ -613,7 +614,7 @@ read_structure_type (struct ctf_context *ccp, ctf_id_t tid)
   type->set_length (ctf_type_size (dict, tid));
   set_type_align (type, ctf_type_align (dict, tid));
 
-  return set_tid_type (ccp->of, tid, type);
+  return set_tid_type (ccp->objfile, tid, type);
 }
 
 /* Given a tid of CTF_K_STRUCT or CTF_K_UNION, process all its members
@@ -651,13 +652,13 @@ process_structure_type (struct ctf_context *ccp, ctf_id_t tid)
 static struct type *
 read_func_kind_type (struct ctf_context *ccp, ctf_id_t tid)
 {
-  struct objfile *of = ccp->of;
+  struct objfile *objfile = ccp->objfile;
   ctf_dict_t *dict = ccp->dict;
   struct type *type, *rettype, *atype;
   ctf_funcinfo_t cfi;
   uint32_t argc;
 
-  type = type_allocator (of, language_c).new_type ();
+  type = type_allocator (objfile, language_c).new_type ();
 
   type->set_code (TYPE_CODE_FUNC);
   if (ctf_func_type_info (dict, tid, &cfi) < 0)
@@ -683,7 +684,7 @@ read_func_kind_type (struct ctf_context *ccp, ctf_id_t tid)
 	return nullptr;
 
       type->alloc_fields (argc);
-      struct type *void_type = builtin_type (of)->builtin_void;
+      struct type *void_type = builtin_type (objfile)->builtin_void;
       /* If failed to find the argument type, fill it with void_type.  */
       for (int iparam = 0; iparam < argc; iparam++)
 	{
@@ -695,7 +696,7 @@ read_func_kind_type (struct ctf_context *ccp, ctf_id_t tid)
 	}
     }
 
-  return set_tid_type (of, tid, type);
+  return set_tid_type (objfile, tid, type);
 }
 
 /* Given a TID of CTF_K_ENUM, process all the members of the
@@ -704,11 +705,11 @@ read_func_kind_type (struct ctf_context *ccp, ctf_id_t tid)
 static struct type *
 read_enum_type (struct ctf_context *ccp, ctf_id_t tid)
 {
-  struct objfile *of = ccp->of;
+  struct objfile *objfile = ccp->objfile;
   ctf_dict_t *dict = ccp->dict;
   struct type *type;
 
-  type = type_allocator (of, language_c).new_type ();
+  type = type_allocator (objfile, language_c).new_type ();
 
   const char *name = ctf_type_name_raw (dict, tid);
   if (name != nullptr && *name != '\0')
@@ -717,10 +718,10 @@ read_enum_type (struct ctf_context *ccp, ctf_id_t tid)
   type->set_code (TYPE_CODE_ENUM);
   type->set_length (ctf_type_size (dict, tid));
   /* Set the underlying type based on its ctf_type_size bits.  */
-  type->set_target_type (objfile_int_type (of, type->length (), false));
+  type->set_target_type (objfile_int_type (objfile, type->length (), false));
   set_type_align (type, ctf_type_align (dict, tid));
 
-  return set_tid_type (of, tid, type);
+  return set_tid_type (objfile, tid, type);
 }
 
 static void
@@ -768,7 +769,7 @@ add_array_cv_type (struct ctf_context *ccp,
   voltl |= TYPE_VOLATILE (el_type);
   inner_array->set_target_type (make_cv_type (cnst, voltl, el_type));
 
-  return set_tid_type (ccp->of, tid, base_type);
+  return set_tid_type (ccp->objfile, tid, base_type);
 }
 
 /* Read all information from a TID of CTF_K_ARRAY.  */
@@ -776,7 +777,7 @@ add_array_cv_type (struct ctf_context *ccp,
 static struct type *
 read_array_type (struct ctf_context *ccp, ctf_id_t tid)
 {
-  struct objfile *objfile = ccp->of;
+  struct objfile *objfile = ccp->objfile;
   ctf_dict_t *dict = ccp->dict;
   struct type *element_type, *range_type, *idx_type;
   struct type *type;
@@ -819,7 +820,7 @@ read_array_type (struct ctf_context *ccp, ctf_id_t tid)
 static struct type *
 read_const_type (struct ctf_context *ccp, ctf_id_t tid, ctf_id_t btid)
 {
-  struct objfile *objfile = ccp->of;
+  struct objfile *objfile = ccp->objfile;
   struct type *base_type, *cv_type;
 
   base_type = fetch_tid_type (ccp, btid);
@@ -842,7 +843,7 @@ read_const_type (struct ctf_context *ccp, ctf_id_t tid, ctf_id_t btid)
 static struct type *
 read_volatile_type (struct ctf_context *ccp, ctf_id_t tid, ctf_id_t btid)
 {
-  struct objfile *objfile = ccp->of;
+  struct objfile *objfile = ccp->objfile;
   ctf_dict_t *dict = ccp->dict;
   struct type *base_type, *cv_type;
 
@@ -869,7 +870,7 @@ read_volatile_type (struct ctf_context *ccp, ctf_id_t tid, ctf_id_t 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 objfile *objfile = ccp->objfile;
   struct type *base_type, *cv_type;
 
   base_type = fetch_tid_type (ccp, btid);
@@ -893,7 +894,7 @@ 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 objfile *objfile = ccp->objfile;
   struct type *this_type, *target_type;
 
   char *aname = obstack_strdup (&objfile->objfile_obstack, name);
@@ -916,7 +917,7 @@ read_typedef_type (struct ctf_context *ccp, ctf_id_t tid,
 static struct type *
 read_pointer_type (struct ctf_context *ccp, ctf_id_t tid, ctf_id_t btid)
 {
-  struct objfile *of = ccp->of;
+  struct objfile *objfile = ccp->objfile;
   struct type *target_type, *type;
 
   target_type = fetch_tid_type (ccp, btid);
@@ -926,14 +927,14 @@ read_pointer_type (struct ctf_context *ccp, ctf_id_t tid, ctf_id_t btid)
       if (target_type == nullptr)
 	{
 	  complaint (_("read_pointer_type: NULL target type (%ld)"), btid);
-	  target_type = builtin_type (ccp->of)->builtin_error;
+	  target_type = builtin_type (ccp->objfile)->builtin_error;
 	}
     }
 
   type = lookup_pointer_type (target_type);
   set_type_align (type, ctf_type_align (ccp->dict, tid));
 
-  return set_tid_type (of, tid, type);
+  return set_tid_type (objfile, tid, type);
 }
 
 /* Read information from a TID of CTF_K_FORWARD.  */
@@ -941,12 +942,12 @@ read_pointer_type (struct ctf_context *ccp, ctf_id_t tid, ctf_id_t btid)
 static struct type *
 read_forward_type (struct ctf_context *ccp, ctf_id_t tid)
 {
-  struct objfile *of = ccp->of;
+  struct objfile *objfile = ccp->objfile;
   ctf_dict_t *dict = ccp->dict;
   struct type *type;
   uint32_t kind;
 
-  type = type_allocator (of, language_c).new_type ();
+  type = type_allocator (objfile, language_c).new_type ();
 
   const char *name = ctf_type_name_raw (dict, tid);
   if (name != nullptr && *name != '\0')
@@ -961,7 +962,7 @@ read_forward_type (struct ctf_context *ccp, ctf_id_t tid)
   type->set_length (0);
   type->set_is_stub (true);
 
-  return set_tid_type (of, tid, type);
+  return set_tid_type (objfile, tid, type);
 }
 
 /* Read information associated with type TID.  */
@@ -1039,7 +1040,7 @@ ctf_add_type_cb (ctf_id_t tid, void *arg)
   uint32_t kind;
 
   /* Check if tid's type has already been defined.  */
-  type = get_tid_type (ccp->of, tid);
+  type = get_tid_type (ccp->objfile, tid);
   if (type != nullptr)
     {
       ctf_debug_printf ("tid=%ld already defined, skipping", tid);
@@ -1112,7 +1113,7 @@ ctf_add_var_cb (const char *name, ctf_id_t id, void *arg)
   struct type *type;
   uint32_t kind;
 
-  type = get_tid_type (ccp->of, id);
+  type = get_tid_type (ccp->objfile, id);
 
   kind = ctf_type_kind (ccp->dict, id);
 
@@ -1122,25 +1123,25 @@ ctf_add_var_cb (const char *name, ctf_id_t id, void *arg)
   if (type == nullptr)
     {
       complaint (_("ctf_add_var_cb: %s has NO type (%ld)"), name, id);
-      type = builtin_type (ccp->of)->builtin_error;
+      type = builtin_type (ccp->objfile)->builtin_error;
     }
-  sym = new (&ccp->of->objfile_obstack) symbol;
-  OBJSTAT (ccp->of, n_syms++);
+  sym = new (&ccp->objfile->objfile_obstack) symbol;
+  OBJSTAT (ccp->objfile, n_syms++);
   sym->set_type (type);
   sym->set_loc_class_index (LOC_OPTIMIZED_OUT);
-  sym->compute_and_set_names (name, false, ccp->of->per_bfd);
+  sym->compute_and_set_names (name, false, ccp->objfile->per_bfd);
 
   if (kind == CTF_K_FUNCTION)
     {
       sym->set_domain (FUNCTION_DOMAIN);
       if (name != nullptr && strcmp (name, "main") == 0)
-	set_objfile_main_name (ccp->of, name, language_c);
+	set_objfile_main_name (ccp->objfile, name, language_c);
     }
   else
     sym->set_domain (VAR_DOMAIN);
 
   add_symbol_to_list (sym, ccp->builder->get_global_symbols ());
-  set_symbol_address (ccp->of, sym, name);
+  set_symbol_address (ccp->objfile, sym, name);
 
   return 0;
 }
@@ -1159,7 +1160,7 @@ add_stt_entries (struct ctf_context *ccp, int functions)
 
   while ((tid = ctf_symbol_next (ccp->dict, &i, &tname, functions)) != CTF_ERR)
     {
-      type = get_tid_type (ccp->of, tid);
+      type = get_tid_type (ccp->objfile, tid);
       if (type == nullptr)
 	{
 	  ctf_debug_printf ("skipping '%s' tid=0x%lx (no type found)",
@@ -1170,14 +1171,14 @@ add_stt_entries (struct ctf_context *ccp, int functions)
       ctf_debug_printf ("adding %s '%s' tid=0x%lx",
 			functions ? "function" : "object", tname, tid);
 
-      sym = new (&ccp->of->objfile_obstack) symbol;
-      OBJSTAT (ccp->of, n_syms++);
+      sym = new (&ccp->objfile->objfile_obstack) symbol;
+      OBJSTAT (ccp->objfile, n_syms++);
       sym->set_type (type);
       sym->set_domain (functions ? FUNCTION_DOMAIN : VAR_DOMAIN);
       sym->set_loc_class_index (LOC_STATIC);
-      sym->compute_and_set_names (tname, false, ccp->of->per_bfd);
+      sym->compute_and_set_names (tname, false, ccp->objfile->per_bfd);
       add_symbol_to_list (sym, ccp->builder->get_global_symbols ());
-      set_symbol_address (ccp->of, sym, tname);
+      set_symbol_address (ccp->objfile, sym, tname);
     }
 }
 
@@ -1200,14 +1201,14 @@ add_stt_func (struct ctf_context *ccp)
 /* Get text section base for OBJFILE, TSIZE contains the size.  */
 
 static CORE_ADDR
-get_objfile_text_range (struct objfile *of, size_t *tsize)
+get_objfile_text_range (struct objfile *objfile, size_t *tsize)
 {
-  bfd *abfd = of->obfd.get ();
+  bfd *abfd = objfile->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 ();
+  return objfile->text_section_offset ();
 }
 
 /* Add all members of an enum with type TID to partial symbol table.  */
@@ -1225,7 +1226,7 @@ ctf_psymtab_add_enums (struct ctf_context *ccp, ctf_id_t tid)
 			     VAR_DOMAIN, LOC_CONST, -1,
 			     psymbol_placement::GLOBAL,
 			     unrelocated_addr (0),
-			     language_c, ccp->partial_symtabs, ccp->of);
+			     language_c, ccp->partial_symtabs, ccp->objfile);
     }
   if (ctf_errno (ccp->dict) != ECTF_NEXT_END)
     complaint (_("ctf_enum_next ctf_psymtab_add_enums failed - %s"),
@@ -1237,7 +1238,7 @@ ctf_psymtab_add_enums (struct ctf_context *ccp, ctf_id_t tid)
 
 static void
 ctf_psymtab_add_stt_entries (ctf_dict_t *dict, ctf_psymtab *pst,
-			     struct objfile *of, int functions)
+			     struct objfile *objfile, int functions)
 {
   ctf_next_t *i = nullptr;
   ctf_id_t tid;
@@ -1262,7 +1263,7 @@ ctf_psymtab_add_stt_entries (ctf_dict_t *dict, ctf_psymtab *pst,
 			tdomain, loc_class, -1,
 			psymbol_placement::GLOBAL,
 			unrelocated_addr (0),
-			language_c, pst->context.partial_symtabs, of);
+			language_c, pst->context.partial_symtabs, objfile);
     }
 }
 
@@ -1270,18 +1271,18 @@ ctf_psymtab_add_stt_entries (ctf_dict_t *dict, ctf_psymtab *pst,
 
 static void
 ctf_psymtab_add_stt_obj (ctf_dict_t *dict, ctf_psymtab *pst,
-			 struct objfile *of)
+			 struct objfile *objfile)
 {
-  ctf_psymtab_add_stt_entries (dict, pst, of, 0);
+  ctf_psymtab_add_stt_entries (dict, pst, objfile, 0);
 }
 
 /* Add entries in function info section to psymtab.  */
 
 static void
 ctf_psymtab_add_stt_func (ctf_dict_t *dict, ctf_psymtab *pst,
-			  struct objfile *of)
+			  struct objfile *objfile)
 {
-  ctf_psymtab_add_stt_entries (dict, pst, of, 1);
+  ctf_psymtab_add_stt_entries (dict, pst, objfile, 1);
 }
 
 /* Read in full symbols for PST, and anything it depends on.  */
@@ -1386,7 +1387,7 @@ create_partial_symtab (const char *name,
 
   pst->context.arc = arc;
   pst->context.dict = dict;
-  pst->context.of = objfile;
+  pst->context.objfile = objfile;
   pst->context.partial_symtabs = partial_symtabs;
   pst->context.pst = pst;
   pst->context.builder = nullptr;
@@ -1446,7 +1447,7 @@ ctf_psymtab_type_cb (ctf_id_t tid, void *arg)
 			 domain, loc_class, section,
 			 psymbol_placement::GLOBAL,
 			 unrelocated_addr (0),
-			 language_c, ccp->partial_symtabs, ccp->of);
+			 language_c, ccp->partial_symtabs, ccp->objfile);
 
   return 0;
 }
@@ -1470,7 +1471,7 @@ ctf_psymtab_var_cb (const char *name, ctf_id_t id, void *arg)
 			 LOC_STATIC, -1,
 			 psymbol_placement::GLOBAL,
 			 unrelocated_addr (0),
-			 language_c, ccp->partial_symtabs, ccp->of);
+			 language_c, ccp->partial_symtabs, ccp->objfile);
   return 0;
 }
 
@@ -1479,22 +1480,23 @@ ctf_psymtab_var_cb (const char *name, ctf_id_t id, void *arg)
 
 static void
 scan_partial_symbols (ctf_dict_t *dict, psymtab_storage *partial_symtabs,
-		      struct ctf_per_tu_data *tup, const char *fname)
+		      ctf_archive_iter_psymtab_data *iter_data,
+		      const char *fname)
 {
-  struct objfile *of = tup->of;
+  objfile *objfile = iter_data->objfile;
   bool isparent = false;
 
   CTF_SCOPED_DEBUG_START_END ("fname='%s'", fname);
 
   if (strcmp (fname, ".ctf") == 0)
     {
-      fname = bfd_get_filename (of->obfd.get ());
+      fname = bfd_get_filename (objfile->obfd.get ());
       isparent = true;
       ctf_debug_printf ("is parent, using fname='%s'", fname);
     }
 
-  ctf_psymtab *pst = create_partial_symtab (fname, tup->arc, dict,
-					    partial_symtabs, of);
+  ctf_psymtab *pst = create_partial_symtab (fname, iter_data->archive, dict,
+					    partial_symtabs, objfile);
 
   struct ctf_context *ccx = &pst->context;
   if (isparent == false)
@@ -1511,8 +1513,8 @@ scan_partial_symbols (ctf_dict_t *dict, psymtab_storage *partial_symtabs,
   /* 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 (dict, pst, of);
-  ctf_psymtab_add_stt_func (dict, pst, of);
+  ctf_psymtab_add_stt_obj (dict, pst, objfile);
+  ctf_psymtab_add_stt_func (dict, pst, objfile);
 
   pst->end ();
 }
@@ -1520,13 +1522,12 @@ scan_partial_symbols (ctf_dict_t *dict, psymtab_storage *partial_symtabs,
 /* Callback to build the psymtab for archive member NAME.  */
 
 static int
-build_ctf_archive_member (ctf_dict_t *ctf, const char *name, void *arg)
+build_ctf_archive_member (ctf_dict_t *dict, const char *name, void *arg)
 {
-  struct ctf_per_tu_data *tup = (struct ctf_per_tu_data *) arg;
-  ctf_dict_t *parent = tup->dict;
+  auto iter_data = static_cast<ctf_archive_iter_psymtab_data *> (arg);
 
   if (strcmp (name, ".ctf") != 0)
-    ctf_import (ctf, parent);
+    ctf_import (dict, iter_data->parent_dict);
 
   if (info_verbose)
     {
@@ -1534,8 +1535,8 @@ build_ctf_archive_member (ctf_dict_t *ctf, const char *name, void *arg)
       gdb_flush (gdb_stdout);
     }
 
-  psymtab_storage *pss = tup->psf->get_partial_symtabs ().get ();
-  scan_partial_symbols (ctf, pss, tup, name);
+  psymtab_storage *pss = iter_data->psf->get_partial_symtabs ().get ();
+  scan_partial_symbols (dict, pss, iter_data, name);
 
   return 0;
 }
@@ -1545,37 +1546,39 @@ build_ctf_archive_member (ctf_dict_t *ctf, const char *name, void *arg)
    .ctf section to set up the partial symbol table.  */
 
 void
-elfctf_build_psymtabs (struct objfile *of)
+elfctf_build_psymtabs (objfile *objfile)
 {
-  struct ctf_per_tu_data pcu;
-  bfd *abfd = of->obfd.get ();
+  bfd *abfd = objfile->obfd.get ();
   int err;
 
   CTF_SCOPED_DEBUG_START_END ("building psymtabs for %s",
 			      bfd_get_filename (abfd));
 
-  ctf_archive_up arc (ctf_bfdopen (abfd, &err));
-  if (arc == nullptr)
+  ctf_archive_up archive (ctf_bfdopen (abfd, &err));
+  if (archive == nullptr)
     error (_("ctf_bfdopen failed on %s - %s"),
 	   bfd_get_filename (abfd), ctf_errmsg (err));
 
-  ctf_dict_up dict (ctf_dict_open (arc.get (), NULL, &err));
+  ctf_dict_up dict (ctf_dict_open (archive.get (), NULL, &err));
   if (dict == nullptr)
     error (_("ctf_dict_open failed on %s - %s"),
 	   bfd_get_filename (abfd), ctf_errmsg (err));
 
-  ctf_dict_info &dict_info
-    = ctf_dict_key.emplace (of, std::move (arc), std::move (dict));
+  ctf_per_objfile &per_objfile
+    = ctf_per_objfile_key.emplace (objfile, std::move (archive),
+				   std::move (dict));
 
-  pcu.dict = dict_info.dict.get ();
-  pcu.of = of;
-  pcu.arc = dict_info.archive.get ();
+  ctf_archive_iter_psymtab_data iter_data;
+  iter_data.parent_dict = per_objfile.parent_dict.get ();
+  iter_data.objfile = objfile;
+  iter_data.archive = per_objfile.archive.get ();
 
   psymbol_functions *psf = new psymbol_functions ();
-  of->qf.emplace_front (psf);
-  pcu.psf = psf;
+  objfile->qf.emplace_front (psf);
+  iter_data.psf = psf;
 
-  if (ctf_archive_iter (pcu.arc, build_ctf_archive_member, &pcu) < 0)
+  if (ctf_archive_iter (iter_data.archive, build_ctf_archive_member, &iter_data)
+      < 0)
     error (_("ctf_archive_iter failed in input file %s: - %s"),
 	   bfd_get_filename (abfd), ctf_errmsg (err));
 }
@@ -1583,7 +1586,7 @@ elfctf_build_psymtabs (struct objfile *of)
 #else
 
 void
-elfctf_build_psymtabs (struct objfile *of)
+elfctf_build_psymtabs (struct objfile *objfile)
 {
   /* Nothing to do if CTF is disabled.  */
 }
-- 
2.53.0


^ permalink raw reply	[flat|nested] 52+ messages in thread

* [PATCH v3 4/9] gdb/ctf: use ctf_per_objfile in ctf_archive_iter_psymtab_data and ctf_context
  2026-02-28  3:51   ` [PATCH v3 0/9] Make CTF reader build full symtabs, get rid of psymtab Simon Marchi
                       ` (2 preceding siblings ...)
  2026-02-28  3:51     ` [PATCH v3 3/9] gdb/ctf: editorial renames Simon Marchi
@ 2026-02-28  3:51     ` Simon Marchi
  2026-02-28  3:51     ` [PATCH v3 5/9] gdb/ctf: check return value of ctf_type_align Simon Marchi
                       ` (5 subsequent siblings)
  9 siblings, 0 replies; 52+ messages in thread
From: Simon Marchi @ 2026-02-28  3:51 UTC (permalink / raw)
  To: gdb-patches; +Cc: Simon Marchi

From: Simon Marchi <simon.marchi@polymtl.ca>

This patch slightly reorganizes the data structures in ctfread.c to be a
bit more like in the DWARF reader.  That is, instead of duplicating the
information (for instance, the objfile pointer), keep the information
once in the most general object where in make sense (in the
ctf_per_objfile in this case) and have the more specific objects (like
ctf_context, ctf_archive_iter_psymtab_data) have a link to the more
general object.

Concretely, that means removing the archive and parent_dict fields from
ctf_archive_iter_psymtab_data and ctf_context (those are per-objfile
information), adding backlink to the ctf_per_objfile and using the
parent_dict and archive fields there.  Similarly, remove the objfile
fields from these and add a new objfile field in ctf_per_objfile.

Remove the objfile and dict parameters from the ctf_psymtab_add_stt_*
functions, since they can be obtained from the other parameters.

No functional changes expected.

Change-Id: I837264eece869f2bb962842998dede8cd7806bfe
---
 gdb/ctfread.c | 190 ++++++++++++++++++++++++--------------------------
 1 file changed, 91 insertions(+), 99 deletions(-)

diff --git a/gdb/ctfread.c b/gdb/ctfread.c
index 9b999c2560b9..c8457a70cf46 100644
--- a/gdb/ctfread.c
+++ b/gdb/ctfread.c
@@ -147,11 +147,16 @@ using ctf_dict_up = std::unique_ptr<ctf_dict_t, ctf_dict_closer>;
 
 struct ctf_per_objfile
 {
-  explicit ctf_per_objfile (ctf_archive_up archive, ctf_dict_up dict)
-    : archive (std::move (archive)),
+  ctf_per_objfile (struct objfile *objfile, ctf_archive_up archive,
+		   ctf_dict_up dict)
+    : objfile (objfile),
+      archive (std::move (archive)),
       parent_dict (std::move (dict))
   {}
 
+  /* Backlink to objfile.  */
+  struct objfile *objfile;
+
   /* Map from IDs to types.  */
   ctf_type_map type_map;
 
@@ -162,15 +167,14 @@ struct ctf_per_objfile
 
 static const registry<objfile>::key<ctf_per_objfile> ctf_per_objfile_key;
 
-/* A CTF context consists of a file pointer and an objfile pointer.  */
+/* Data passed around when creating symtabs.  */
 
 struct ctf_context
 {
+  ctf_per_objfile *per_objfile;
   ctf_dict_t *dict;
-  struct objfile *objfile;
   psymtab_storage *partial_symtabs;
   partial_symtab *pst;
-  ctf_archive_t *arc;
   struct buildsym_compunit *builder;
 };
 
@@ -224,9 +228,7 @@ struct ctf_field_info
 
 struct ctf_archive_iter_psymtab_data
 {
-  ctf_dict_t *parent_dict;
-  struct objfile *objfile;
-  ctf_archive_t *archive;
+  ctf_per_objfile *per_objfile;
   psymbol_functions *psf;
 };
 
@@ -287,7 +289,7 @@ get_tid_type (struct objfile *objfile, ctf_id_t tid)
 static struct type *
 fetch_tid_type (struct ctf_context *ccp, ctf_id_t tid)
 {
-  struct objfile *objfile = ccp->objfile;
+  struct objfile *objfile = ccp->per_objfile->objfile;
   struct type *typ;
 
   typ = get_tid_type (objfile, tid);
@@ -404,9 +406,10 @@ ctf_add_member_cb (const char *name,
       t = read_type_record (ccp, tid);
       if (t == nullptr)
 	{
+	  objfile *objfile = ccp->per_objfile->objfile;
 	  complaint (_("ctf_add_member_cb: %s has NO type (%ld)"), name, tid);
-	  t = builtin_type (ccp->objfile)->builtin_error;
-	  set_tid_type (ccp->objfile, tid, t);
+	  t = builtin_type (objfile)->builtin_error;
+	  set_tid_type (objfile, tid, t);
 	}
     }
 
@@ -441,11 +444,12 @@ ctf_add_enum_member_cb (const char *name, int enum_value, void *arg)
 
   if (name != nullptr && *name != '\0')
     {
-      struct symbol *sym = new (&ccp->objfile->objfile_obstack) symbol;
-      OBJSTAT (ccp->objfile, n_syms++);
+      objfile *objfile = ccp->per_objfile->objfile;
+      struct symbol *sym = new (&objfile->objfile_obstack) symbol;
+      OBJSTAT (objfile, n_syms++);
 
-      sym->set_language (language_c, &ccp->objfile->objfile_obstack);
-      sym->compute_and_set_names (name, false, ccp->objfile->per_bfd);
+      sym->set_language (language_c, &objfile->objfile_obstack);
+      sym->compute_and_set_names (name, false, objfile->per_bfd);
       sym->set_loc_class_index (LOC_CONST);
       sym->set_domain (VAR_DOMAIN);
       sym->set_type (fip->ptype);
@@ -468,7 +472,7 @@ new_type_symbol (struct ctf_context *ccp, struct type *type, ctf_id_t tid)
   const char *name = ctf_type_name_raw (dict, tid);
   if (name != nullptr && *name != '\0')
     {
-      struct objfile *objfile = ccp->objfile;
+      objfile *objfile = ccp->per_objfile->objfile;
       struct symbol *sym = new (&objfile->objfile_obstack) symbol;
       OBJSTAT (objfile, n_syms++);
 
@@ -500,7 +504,7 @@ new_type_symbol (struct ctf_context *ccp, struct type *type, ctf_id_t tid)
 static struct type *
 read_base_type (struct ctf_context *ccp, ctf_id_t tid)
 {
-  struct objfile *objfile = ccp->objfile;
+  objfile *objfile = ccp->per_objfile->objfile;
   ctf_dict_t *dict = ccp->dict;
   ctf_encoding_t cet;
   struct type *type = nullptr;
@@ -594,7 +598,7 @@ process_base_type (struct ctf_context *ccp, ctf_id_t tid)
 static struct type *
 read_structure_type (struct ctf_context *ccp, ctf_id_t tid)
 {
-  struct objfile *objfile = ccp->objfile;
+  objfile *objfile = ccp->per_objfile->objfile;
   ctf_dict_t *dict = ccp->dict;
   struct type *type;
   uint32_t kind;
@@ -614,7 +618,7 @@ read_structure_type (struct ctf_context *ccp, ctf_id_t tid)
   type->set_length (ctf_type_size (dict, tid));
   set_type_align (type, ctf_type_align (dict, tid));
 
-  return set_tid_type (ccp->objfile, tid, type);
+  return set_tid_type (objfile, tid, type);
 }
 
 /* Given a tid of CTF_K_STRUCT or CTF_K_UNION, process all its members
@@ -652,7 +656,7 @@ process_structure_type (struct ctf_context *ccp, ctf_id_t tid)
 static struct type *
 read_func_kind_type (struct ctf_context *ccp, ctf_id_t tid)
 {
-  struct objfile *objfile = ccp->objfile;
+  objfile *objfile = ccp->per_objfile->objfile;
   ctf_dict_t *dict = ccp->dict;
   struct type *type, *rettype, *atype;
   ctf_funcinfo_t cfi;
@@ -705,7 +709,7 @@ read_func_kind_type (struct ctf_context *ccp, ctf_id_t tid)
 static struct type *
 read_enum_type (struct ctf_context *ccp, ctf_id_t tid)
 {
-  struct objfile *objfile = ccp->objfile;
+  objfile *objfile = ccp->per_objfile->objfile;
   ctf_dict_t *dict = ccp->dict;
   struct type *type;
 
@@ -769,7 +773,7 @@ add_array_cv_type (struct ctf_context *ccp,
   voltl |= TYPE_VOLATILE (el_type);
   inner_array->set_target_type (make_cv_type (cnst, voltl, el_type));
 
-  return set_tid_type (ccp->objfile, tid, base_type);
+  return set_tid_type (ccp->per_objfile->objfile, tid, base_type);
 }
 
 /* Read all information from a TID of CTF_K_ARRAY.  */
@@ -777,7 +781,7 @@ add_array_cv_type (struct ctf_context *ccp,
 static struct type *
 read_array_type (struct ctf_context *ccp, ctf_id_t tid)
 {
-  struct objfile *objfile = ccp->objfile;
+  objfile *objfile = ccp->per_objfile->objfile;
   ctf_dict_t *dict = ccp->dict;
   struct type *element_type, *range_type, *idx_type;
   struct type *type;
@@ -820,7 +824,7 @@ read_array_type (struct ctf_context *ccp, ctf_id_t tid)
 static struct type *
 read_const_type (struct ctf_context *ccp, ctf_id_t tid, ctf_id_t btid)
 {
-  struct objfile *objfile = ccp->objfile;
+  objfile *objfile = ccp->per_objfile->objfile;
   struct type *base_type, *cv_type;
 
   base_type = fetch_tid_type (ccp, btid);
@@ -843,7 +847,7 @@ read_const_type (struct ctf_context *ccp, ctf_id_t tid, ctf_id_t btid)
 static struct type *
 read_volatile_type (struct ctf_context *ccp, ctf_id_t tid, ctf_id_t btid)
 {
-  struct objfile *objfile = ccp->objfile;
+  objfile *objfile = ccp->per_objfile->objfile;
   ctf_dict_t *dict = ccp->dict;
   struct type *base_type, *cv_type;
 
@@ -870,7 +874,7 @@ read_volatile_type (struct ctf_context *ccp, ctf_id_t tid, ctf_id_t btid)
 static struct type *
 read_restrict_type (struct ctf_context *ccp, ctf_id_t tid, ctf_id_t btid)
 {
-  struct objfile *objfile = ccp->objfile;
+  objfile *objfile = ccp->per_objfile->objfile;
   struct type *base_type, *cv_type;
 
   base_type = fetch_tid_type (ccp, btid);
@@ -894,7 +898,7 @@ 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->objfile;
+  objfile *objfile = ccp->per_objfile->objfile;
   struct type *this_type, *target_type;
 
   char *aname = obstack_strdup (&objfile->objfile_obstack, name);
@@ -917,7 +921,7 @@ read_typedef_type (struct ctf_context *ccp, ctf_id_t tid,
 static struct type *
 read_pointer_type (struct ctf_context *ccp, ctf_id_t tid, ctf_id_t btid)
 {
-  struct objfile *objfile = ccp->objfile;
+  objfile *objfile = ccp->per_objfile->objfile;
   struct type *target_type, *type;
 
   target_type = fetch_tid_type (ccp, btid);
@@ -927,7 +931,7 @@ read_pointer_type (struct ctf_context *ccp, ctf_id_t tid, ctf_id_t btid)
       if (target_type == nullptr)
 	{
 	  complaint (_("read_pointer_type: NULL target type (%ld)"), btid);
-	  target_type = builtin_type (ccp->objfile)->builtin_error;
+	  target_type = builtin_type (objfile)->builtin_error;
 	}
     }
 
@@ -942,7 +946,7 @@ read_pointer_type (struct ctf_context *ccp, ctf_id_t tid, ctf_id_t btid)
 static struct type *
 read_forward_type (struct ctf_context *ccp, ctf_id_t tid)
 {
-  struct objfile *objfile = ccp->objfile;
+  objfile *objfile = ccp->per_objfile->objfile;
   ctf_dict_t *dict = ccp->dict;
   struct type *type;
   uint32_t kind;
@@ -1040,7 +1044,7 @@ ctf_add_type_cb (ctf_id_t tid, void *arg)
   uint32_t kind;
 
   /* Check if tid's type has already been defined.  */
-  type = get_tid_type (ccp->objfile, tid);
+  type = get_tid_type (ccp->per_objfile->objfile, tid);
   if (type != nullptr)
     {
       ctf_debug_printf ("tid=%ld already defined, skipping", tid);
@@ -1112,8 +1116,9 @@ ctf_add_var_cb (const char *name, ctf_id_t id, void *arg)
   struct symbol *sym = nullptr;
   struct type *type;
   uint32_t kind;
+  objfile *objfile = ccp->per_objfile->objfile;
 
-  type = get_tid_type (ccp->objfile, id);
+  type = get_tid_type (objfile, id);
 
   kind = ctf_type_kind (ccp->dict, id);
 
@@ -1123,25 +1128,25 @@ ctf_add_var_cb (const char *name, ctf_id_t id, void *arg)
   if (type == nullptr)
     {
       complaint (_("ctf_add_var_cb: %s has NO type (%ld)"), name, id);
-      type = builtin_type (ccp->objfile)->builtin_error;
+      type = builtin_type (objfile)->builtin_error;
     }
-  sym = new (&ccp->objfile->objfile_obstack) symbol;
-  OBJSTAT (ccp->objfile, n_syms++);
+  sym = new (&objfile->objfile_obstack) symbol;
+  OBJSTAT (objfile, n_syms++);
   sym->set_type (type);
   sym->set_loc_class_index (LOC_OPTIMIZED_OUT);
-  sym->compute_and_set_names (name, false, ccp->objfile->per_bfd);
+  sym->compute_and_set_names (name, false, objfile->per_bfd);
 
   if (kind == CTF_K_FUNCTION)
     {
       sym->set_domain (FUNCTION_DOMAIN);
       if (name != nullptr && strcmp (name, "main") == 0)
-	set_objfile_main_name (ccp->objfile, name, language_c);
+	set_objfile_main_name (objfile, name, language_c);
     }
   else
     sym->set_domain (VAR_DOMAIN);
 
   add_symbol_to_list (sym, ccp->builder->get_global_symbols ());
-  set_symbol_address (ccp->objfile, sym, name);
+  set_symbol_address (objfile, sym, name);
 
   return 0;
 }
@@ -1160,25 +1165,26 @@ add_stt_entries (struct ctf_context *ccp, int functions)
 
   while ((tid = ctf_symbol_next (ccp->dict, &i, &tname, functions)) != CTF_ERR)
     {
-      type = get_tid_type (ccp->objfile, tid);
+      objfile *objfile = ccp->per_objfile->objfile;
+      type = get_tid_type (objfile, tid);
       if (type == nullptr)
 	{
-	  ctf_debug_printf ("skipping '%s' tid=0x%lx (no type found)",
-			    tname, tid);
+	  ctf_debug_printf ("skipping '%s' tid=0x%lx (no type found)", tname,
+			    tid);
 	  continue;
 	}
 
       ctf_debug_printf ("adding %s '%s' tid=0x%lx",
 			functions ? "function" : "object", tname, tid);
 
-      sym = new (&ccp->objfile->objfile_obstack) symbol;
-      OBJSTAT (ccp->objfile, n_syms++);
+      sym = new (&objfile->objfile_obstack) symbol;
+      OBJSTAT (objfile, n_syms++);
       sym->set_type (type);
       sym->set_domain (functions ? FUNCTION_DOMAIN : VAR_DOMAIN);
       sym->set_loc_class_index (LOC_STATIC);
-      sym->compute_and_set_names (tname, false, ccp->objfile->per_bfd);
+      sym->compute_and_set_names (tname, false, objfile->per_bfd);
       add_symbol_to_list (sym, ccp->builder->get_global_symbols ());
-      set_symbol_address (ccp->objfile, sym, tname);
+      set_symbol_address (objfile, sym, tname);
     }
 }
 
@@ -1222,11 +1228,10 @@ ctf_psymtab_add_enums (struct ctf_context *ccp, ctf_id_t tid)
 
   while ((ename = ctf_enum_next (ccp->dict, 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->objfile);
+      ccp->pst->add_psymbol (ename, true, VAR_DOMAIN, LOC_CONST, -1,
+			     psymbol_placement::GLOBAL, unrelocated_addr (0),
+			     language_c, ccp->partial_symtabs,
+			     ccp->per_objfile->objfile);
     }
   if (ctf_errno (ccp->dict) != ECTF_NEXT_END)
     complaint (_("ctf_enum_next ctf_psymtab_add_enums failed - %s"),
@@ -1237,8 +1242,7 @@ ctf_psymtab_add_enums (struct ctf_context *ccp, ctf_id_t tid)
    by FUNCTIONS, to psymtab.  */
 
 static void
-ctf_psymtab_add_stt_entries (ctf_dict_t *dict, ctf_psymtab *pst,
-			     struct objfile *objfile, int functions)
+ctf_psymtab_add_stt_entries (ctf_dict_t *dict, ctf_psymtab *pst, int functions)
 {
   ctf_next_t *i = nullptr;
   ctf_id_t tid;
@@ -1259,30 +1263,27 @@ ctf_psymtab_add_stt_entries (ctf_dict_t *dict, ctf_psymtab *pst,
 			functions ? "function" : "object", tname, tid,
 			ctf_kind_str (kind));
 
-      pst->add_psymbol (tname, true,
-			tdomain, loc_class, -1,
-			psymbol_placement::GLOBAL,
-			unrelocated_addr (0),
-			language_c, pst->context.partial_symtabs, objfile);
+      pst->add_psymbol (tname, true, tdomain, loc_class, -1,
+			psymbol_placement::GLOBAL, unrelocated_addr (0),
+			language_c, pst->context.partial_symtabs,
+			pst->context.per_objfile->objfile);
     }
 }
 
 /* Add entries in data objects section to psymtab.  */
 
 static void
-ctf_psymtab_add_stt_obj (ctf_dict_t *dict, ctf_psymtab *pst,
-			 struct objfile *objfile)
+ctf_psymtab_add_stt_obj (ctf_dict_t *dict, ctf_psymtab *pst)
 {
-  ctf_psymtab_add_stt_entries (dict, pst, objfile, 0);
+  ctf_psymtab_add_stt_entries (dict, pst, 0);
 }
 
 /* Add entries in function info section to psymtab.  */
 
 static void
-ctf_psymtab_add_stt_func (ctf_dict_t *dict, ctf_psymtab *pst,
-			  struct objfile *objfile)
+ctf_psymtab_add_stt_func (ctf_dict_t *dict, ctf_psymtab *pst)
 {
-  ctf_psymtab_add_stt_entries (dict, pst, objfile, 1);
+  ctf_psymtab_add_stt_entries (dict, pst, 1);
 }
 
 /* Read in full symbols for PST, and anything it depends on.  */
@@ -1375,19 +1376,17 @@ ctf_psymtab::read_symtab (struct objfile *objfile)
 
 static ctf_psymtab *
 create_partial_symtab (const char *name,
-		       ctf_archive_t *arc,
 		       ctf_dict_t *dict,
 		       psymtab_storage *partial_symtabs,
-		       struct objfile *objfile)
+		       ctf_per_objfile *per_objfile)
 {
   ctf_psymtab *pst;
 
-  pst = new ctf_psymtab (name, partial_symtabs, objfile->per_bfd,
+  pst = new ctf_psymtab (name, partial_symtabs, per_objfile->objfile->per_bfd,
 			 unrelocated_addr (0));
 
-  pst->context.arc = arc;
+  pst->context.per_objfile = per_objfile;
   pst->context.dict = dict;
-  pst->context.objfile = objfile;
   pst->context.partial_symtabs = partial_symtabs;
   pst->context.pst = pst;
   pst->context.builder = nullptr;
@@ -1443,11 +1442,10 @@ ctf_psymtab_type_cb (ctf_id_t tid, void *arg)
   ctf_debug_printf ("adding type tid=0x%lx kind=%s name='%s'",
 		    tid, ctf_kind_str (kind), name);
 
-  ccp->pst->add_psymbol (name, false,
-			 domain, loc_class, section,
-			 psymbol_placement::GLOBAL,
-			 unrelocated_addr (0),
-			 language_c, ccp->partial_symtabs, ccp->objfile);
+  ccp->pst->add_psymbol (name, false, domain, loc_class, section,
+			 psymbol_placement::GLOBAL, unrelocated_addr (0),
+			 language_c, ccp->partial_symtabs,
+			 ccp->per_objfile->objfile);
 
   return 0;
 }
@@ -1465,13 +1463,10 @@ ctf_psymtab_var_cb (const char *name, ctf_id_t id, void *arg)
 		    name, id, ctf_kind_str (kind));
 
   ccp->pst->add_psymbol (name, true,
-			 kind == CTF_K_FUNCTION
-			 ? FUNCTION_DOMAIN
-			 : VAR_DOMAIN,
-			 LOC_STATIC, -1,
-			 psymbol_placement::GLOBAL,
-			 unrelocated_addr (0),
-			 language_c, ccp->partial_symtabs, ccp->objfile);
+			 kind == CTF_K_FUNCTION ? FUNCTION_DOMAIN : VAR_DOMAIN,
+			 LOC_STATIC, -1, psymbol_placement::GLOBAL,
+			 unrelocated_addr (0), language_c,
+			 ccp->partial_symtabs, ccp->per_objfile->objfile);
   return 0;
 }
 
@@ -1480,10 +1475,9 @@ ctf_psymtab_var_cb (const char *name, ctf_id_t id, void *arg)
 
 static void
 scan_partial_symbols (ctf_dict_t *dict, psymtab_storage *partial_symtabs,
-		      ctf_archive_iter_psymtab_data *iter_data,
-		      const char *fname)
+		      ctf_per_objfile *per_objfile, const char *fname)
 {
-  objfile *objfile = iter_data->objfile;
+  objfile *objfile = per_objfile->objfile;
   bool isparent = false;
 
   CTF_SCOPED_DEBUG_START_END ("fname='%s'", fname);
@@ -1495,8 +1489,8 @@ scan_partial_symbols (ctf_dict_t *dict, psymtab_storage *partial_symtabs,
       ctf_debug_printf ("is parent, using fname='%s'", fname);
     }
 
-  ctf_psymtab *pst = create_partial_symtab (fname, iter_data->archive, dict,
-					    partial_symtabs, objfile);
+  ctf_psymtab *pst = create_partial_symtab (fname, dict, partial_symtabs,
+					    per_objfile);
 
   struct ctf_context *ccx = &pst->context;
   if (isparent == false)
@@ -1513,8 +1507,8 @@ scan_partial_symbols (ctf_dict_t *dict, psymtab_storage *partial_symtabs,
   /* 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 (dict, pst, objfile);
-  ctf_psymtab_add_stt_func (dict, pst, objfile);
+  ctf_psymtab_add_stt_obj (dict, pst);
+  ctf_psymtab_add_stt_func (dict, pst);
 
   pst->end ();
 }
@@ -1525,9 +1519,10 @@ static int
 build_ctf_archive_member (ctf_dict_t *dict, const char *name, void *arg)
 {
   auto iter_data = static_cast<ctf_archive_iter_psymtab_data *> (arg);
+  ctf_per_objfile *per_objfile = iter_data->per_objfile;
 
   if (strcmp (name, ".ctf") != 0)
-    ctf_import (dict, iter_data->parent_dict);
+    ctf_import (dict, per_objfile->parent_dict.get ());
 
   if (info_verbose)
     {
@@ -1536,7 +1531,7 @@ build_ctf_archive_member (ctf_dict_t *dict, const char *name, void *arg)
     }
 
   psymtab_storage *pss = iter_data->psf->get_partial_symtabs ().get ();
-  scan_partial_symbols (dict, pss, iter_data, name);
+  scan_partial_symbols (dict, pss, per_objfile, name);
 
   return 0;
 }
@@ -1565,19 +1560,16 @@ elfctf_build_psymtabs (objfile *objfile)
 	   bfd_get_filename (abfd), ctf_errmsg (err));
 
   ctf_per_objfile &per_objfile
-    = ctf_per_objfile_key.emplace (objfile, std::move (archive),
+    = ctf_per_objfile_key.emplace (objfile, objfile, std::move (archive),
 				   std::move (dict));
-
-  ctf_archive_iter_psymtab_data iter_data;
-  iter_data.parent_dict = per_objfile.parent_dict.get ();
-  iter_data.objfile = objfile;
-  iter_data.archive = per_objfile.archive.get ();
-
   psymbol_functions *psf = new psymbol_functions ();
-  objfile->qf.emplace_front (psf);
-  iter_data.psf = psf;
 
-  if (ctf_archive_iter (iter_data.archive, build_ctf_archive_member, &iter_data)
+  objfile->qf.emplace_front (psf);
+
+  ctf_archive_iter_psymtab_data iter_data { &per_objfile, psf };
+
+  if (ctf_archive_iter (per_objfile.archive.get (), build_ctf_archive_member,
+			&iter_data)
       < 0)
     error (_("ctf_archive_iter failed in input file %s: - %s"),
 	   bfd_get_filename (abfd), ctf_errmsg (err));
-- 
2.53.0


^ permalink raw reply	[flat|nested] 52+ messages in thread

* [PATCH v3 5/9] gdb/ctf: check return value of ctf_type_align
  2026-02-28  3:51   ` [PATCH v3 0/9] Make CTF reader build full symtabs, get rid of psymtab Simon Marchi
                       ` (3 preceding siblings ...)
  2026-02-28  3:51     ` [PATCH v3 4/9] gdb/ctf: use ctf_per_objfile in ctf_archive_iter_psymtab_data and ctf_context Simon Marchi
@ 2026-02-28  3:51     ` Simon Marchi
  2026-02-28  3:51     ` [PATCH v3 6/9] gdb/ctf: add scoped_time_it in elfctf_build_psymtabs Simon Marchi
                       ` (4 subsequent siblings)
  9 siblings, 0 replies; 52+ messages in thread
From: Simon Marchi @ 2026-02-28  3:51 UTC (permalink / raw)
  To: gdb-patches; +Cc: Simon Marchi

From: Simon Marchi <simon.marchi@polymtl.ca>

I tried to build the Linux kernel with -gctf.  I am not sure if the
result is good, because I got plenty of warnings like:

    ld: warning: orphan section `.ctf' from `vmlinux.o' being placed in section `.ctf'

Nevertheless, I tried to load it in GDB, and it didn't complain.
However, when doing "maint expand-symtabs", I did hit this assert:

    /home/simark/src/binutils-gdb/gdb/gdbtypes.c:3640: internal-error: set_type_align: Assertion `(align & (align - 1)) == 0' failed.

This is because ctf_type_align returns -1 for some types, which is an
indication of an error.  Update the code to check the return value of
ctf_type_align for errors, and emit complaints if it happens.

With this patch, if I enable the complaints, I see a bunch of messages
like this:

    During symbol reading: ctf_type_align read_structure_type failed - Type is not a complete type.

Change-Id: Ibed23e7f1490d9163b8dde1318b9e45dec2906d6
---
 gdb/ctfread.c | 40 +++++++++++++++++++++++++++++++++++-----
 1 file changed, 35 insertions(+), 5 deletions(-)

diff --git a/gdb/ctfread.c b/gdb/ctfread.c
index c8457a70cf46..ed4a7383427d 100644
--- a/gdb/ctfread.c
+++ b/gdb/ctfread.c
@@ -616,7 +616,14 @@ read_structure_type (struct ctf_context *ccp, ctf_id_t tid)
     type->set_code (TYPE_CODE_STRUCT);
 
   type->set_length (ctf_type_size (dict, tid));
-  set_type_align (type, ctf_type_align (dict, tid));
+
+  if (ssize_t align = ctf_type_align (dict, tid);
+      align >= 0)
+    set_type_align (type, align);
+  else
+    complaint (_("ctf_type_align read_structure_type failed - %s"),
+	       ctf_errmsg (ctf_errno (dict)));
+
 
   return set_tid_type (objfile, tid, type);
 }
@@ -673,7 +680,13 @@ read_func_kind_type (struct ctf_context *ccp, ctf_id_t tid)
     }
   rettype = fetch_tid_type (ccp, cfi.ctc_return);
   type->set_target_type (rettype);
-  set_type_align (type, ctf_type_align (dict, tid));
+
+  if (ssize_t align = ctf_type_align (dict, tid);
+      align >= 0)
+    set_type_align (type, align);
+  else
+    complaint (_("ctf_type_align read_func_kind_type failed - %s"),
+	       ctf_errmsg (ctf_errno (dict)));
 
   /* Set up function's arguments.  */
   argc = cfi.ctc_argc;
@@ -723,7 +736,13 @@ read_enum_type (struct ctf_context *ccp, ctf_id_t tid)
   type->set_length (ctf_type_size (dict, tid));
   /* Set the underlying type based on its ctf_type_size bits.  */
   type->set_target_type (objfile_int_type (objfile, type->length (), false));
-  set_type_align (type, ctf_type_align (dict, tid));
+
+  if (ssize_t align = ctf_type_align (dict, tid);
+      align >= 0)
+    set_type_align (type, align);
+  else
+    complaint (_("ctf_type_align read_enum_type failed - %s"),
+	       ctf_errmsg (ctf_errno (dict)));
 
   return set_tid_type (objfile, tid, type);
 }
@@ -814,7 +833,12 @@ read_array_type (struct ctf_context *ccp, ctf_id_t tid)
   else
     type->set_length (ctf_type_size (dict, tid));
 
-  set_type_align (type, ctf_type_align (dict, tid));
+  if (ssize_t align = ctf_type_align (dict, tid);
+      align >= 0)
+    set_type_align (type, align);
+  else
+    complaint (_("ctf_type_align read_array_type failed - %s"),
+	       ctf_errmsg (ctf_errno (dict)));
 
   return set_tid_type (objfile, tid, type);
 }
@@ -936,7 +960,13 @@ read_pointer_type (struct ctf_context *ccp, ctf_id_t tid, ctf_id_t btid)
     }
 
   type = lookup_pointer_type (target_type);
-  set_type_align (type, ctf_type_align (ccp->dict, tid));
+
+  if (ssize_t align = ctf_type_align (ccp->dict, tid);
+      align >= 0)
+    set_type_align (type, align);
+  else
+    complaint (_("ctf_type_align read_pointer_type failed - %s"),
+	       ctf_errmsg (ctf_errno (ccp->dict)));
 
   return set_tid_type (objfile, tid, type);
 }
-- 
2.53.0


^ permalink raw reply	[flat|nested] 52+ messages in thread

* [PATCH v3 6/9] gdb/ctf: add scoped_time_it in elfctf_build_psymtabs
  2026-02-28  3:51   ` [PATCH v3 0/9] Make CTF reader build full symtabs, get rid of psymtab Simon Marchi
                       ` (4 preceding siblings ...)
  2026-02-28  3:51     ` [PATCH v3 5/9] gdb/ctf: check return value of ctf_type_align Simon Marchi
@ 2026-02-28  3:51     ` Simon Marchi
  2026-02-28  3:51     ` [PATCH v3 7/9] gdb: make expanded_symbols_functions hold compunit symtabs Simon Marchi
                       ` (3 subsequent siblings)
  9 siblings, 0 replies; 52+ messages in thread
From: Simon Marchi @ 2026-02-28  3:51 UTC (permalink / raw)
  To: gdb-patches; +Cc: Simon Marchi

From: Simon Marchi <simon.marchi@polymtl.ca>

This will be useful to determine the impact on the startup time getting
rid of partial symtabs has.

I use it like so:

    $ ./gdb -q -nx --data-directory=data-directory -iex "maint set per-command time on" /home/simark/src/linux/vmlinux.unstripped -batch
    ...
    Time for "elfctf_build_psymtabs": wall 0.381, user 0.357, sys 0.015, user+sys 0.372, 97.6 % CPU

Change-Id: I021319212f27eee0bf0f6c230f4e7cdd9c3602c1
---
 gdb/ctfread.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/gdb/ctfread.c b/gdb/ctfread.c
index ed4a7383427d..251b1c7f1fce 100644
--- a/gdb/ctfread.c
+++ b/gdb/ctfread.c
@@ -79,6 +79,7 @@
 #include "complaints.h"
 #include "block.h"
 #include "ctfread.h"
+#include "maint.h"
 #include "psymtab.h"
 #include "cli/cli-cmds.h"
 
@@ -1576,6 +1577,8 @@ elfctf_build_psymtabs (objfile *objfile)
   bfd *abfd = objfile->obfd.get ();
   int err;
 
+  scoped_time_it time_it (__func__);
+
   CTF_SCOPED_DEBUG_START_END ("building psymtabs for %s",
 			      bfd_get_filename (abfd));
 
-- 
2.53.0


^ permalink raw reply	[flat|nested] 52+ messages in thread

* [PATCH v3 7/9] gdb: make expanded_symbols_functions hold compunit symtabs
  2026-02-28  3:51   ` [PATCH v3 0/9] Make CTF reader build full symtabs, get rid of psymtab Simon Marchi
                       ` (5 preceding siblings ...)
  2026-02-28  3:51     ` [PATCH v3 6/9] gdb/ctf: add scoped_time_it in elfctf_build_psymtabs Simon Marchi
@ 2026-02-28  3:51     ` Simon Marchi
  2026-03-04 19:21       ` Tom Tromey
  2026-02-28  3:51     ` [PATCH v3 8/9] gdb/ctf: don't use psymtabs, create symtabs directly Simon Marchi
                       ` (2 subsequent siblings)
  9 siblings, 1 reply; 52+ messages in thread
From: Simon Marchi @ 2026-02-28  3:51 UTC (permalink / raw)
  To: gdb-patches; +Cc: Simon Marchi

From: Simon Marchi <simon.marchi@polymtl.ca>

Change the expanded_symbols_functions quick functions type to hold and
use a list of compunit symtab to search.

Currently, an expanded_symbols_functions instance will search all the
compunits in the objfile.  This is not efficient if an
expanded_symbols_functions instance exists alongside another quick
functions object in an objfile, as the compunits belonging to that other
object will be unnecessarily searched.

And at worst, I think it could be a source of subtle bugs.  For
instance, if the order of quick functions determine the order in which
we want the search to happen (the comment in elf_symfile_read suggests
this is the case), then having expanded_symbols_functions search the
compunits from other quick functions objects would not respect that
ordering.

Update the expanded_symbols_functions constructor to accept a vector of
compunits and store this vector in a field.  Update
expanded_symbols_functions methods to use that vector instead of the
objfile's compunits.

Right now the sole user of expanded_symbols_functions is JIT.  Update it
to keep a vector of compunits as they are finalized, and pass this
vector to the expanded_symbols_functions object.

Change-Id: Idf8de18b25fd3f71766166d6f420184af3c26b7e
---
 gdb/expanded-symbol.c | 16 ++++++++--------
 gdb/expanded-symbol.h |  8 ++++++++
 gdb/jit.c             | 16 ++++++++++++----
 3 files changed, 28 insertions(+), 12 deletions(-)

diff --git a/gdb/expanded-symbol.c b/gdb/expanded-symbol.c
index 050608795f93..d885fe33fa84 100644
--- a/gdb/expanded-symbol.c
+++ b/gdb/expanded-symbol.c
@@ -28,10 +28,10 @@
 symtab *
 expanded_symbols_functions::find_last_source_symtab (objfile *objfile)
 {
-  if (objfile->compunit_symtabs.empty ())
+  if (m_compunit_symtabs.empty ())
     return nullptr;
   else
-    return objfile->compunit_symtabs.back ().primary_filetab ();
+    return m_compunit_symtabs.back ()->primary_filetab ();
 }
 
 /* See expanded-symbol.h.  */
@@ -61,15 +61,15 @@ expanded_symbols_functions::search
   /* This invariant is documented in quick-functions.h.  */
   gdb_assert (lookup_name != nullptr || symbol_matcher == nullptr);
 
-  for (compunit_symtab &cu : objfile->compunits ())
+  for (compunit_symtab *cu : m_compunit_symtabs)
     {
-      if (lang_matcher != nullptr && !lang_matcher (cu.language ()))
+      if (lang_matcher != nullptr && !lang_matcher (cu->language ()))
 	continue;
 
       if (file_matcher != nullptr)
 	{
 	  bool matched = false;
-	  for (auto st : cu.filetabs ())
+	  for (auto st : cu->filetabs ())
 	    {
 	      if (file_matcher (st->filename (), false))
 		{
@@ -92,7 +92,7 @@ expanded_symbols_functions::search
 	 consult lookup_name and symbol_matcher (if any).  This should be
 	 okay since i) all symtabs are already expanded and ii) listeners
 	 iterate over matching symbols themselves.  */
-      if (listener != nullptr && !listener (&cu))
+      if (listener != nullptr && !listener (cu))
 	return false;
     }
   return true;
@@ -104,9 +104,9 @@ symbol *
 expanded_symbols_functions::find_symbol_by_address (objfile *objfile,
 						    CORE_ADDR address)
 {
-  for (compunit_symtab &symtab : objfile->compunits ())
+  for (compunit_symtab *symtab : m_compunit_symtabs)
     {
-      symbol *sym = symtab.symbol_at_address (address);
+      symbol *sym = symtab->symbol_at_address (address);
       if (sym != nullptr)
 	return sym;
     }
diff --git a/gdb/expanded-symbol.h b/gdb/expanded-symbol.h
index c088d74f7e59..885390ccb124 100644
--- a/gdb/expanded-symbol.h
+++ b/gdb/expanded-symbol.h
@@ -29,6 +29,11 @@
 
 struct expanded_symbols_functions : public quick_symbol_functions
 {
+  explicit expanded_symbols_functions
+    (std::vector<compunit_symtab *> compunit_symtabs)
+    : m_compunit_symtabs (std::move (compunit_symtabs))
+  {}
+
   bool has_symbols (objfile *objfile) override
   {
     return true;
@@ -86,6 +91,9 @@ struct expanded_symbols_functions : public quick_symbol_functions
 			     bool need_fullname) override
   {
   }
+
+private:
+  std::vector<compunit_symtab *> m_compunit_symtabs;
 };
 
 
diff --git a/gdb/jit.c b/gdb/jit.c
index 21e8667a7af6..5fa3869316c3 100644
--- a/gdb/jit.c
+++ b/gdb/jit.c
@@ -513,9 +513,11 @@ jit_symtab_close_impl (struct gdb_symbol_callbacks *cb,
      ABI).  */
 }
 
-/* Transform STAB to a proper symtab, and add it it OBJFILE.  */
+/* Transform STAB to a proper symtab, and add it it OBJFILE.
 
-static void
+   Return the created symtab.  */
+
+static compunit_symtab *
 finalize_symtab (struct gdb_symtab *stab, struct objfile *objfile)
 {
   CORE_ADDR begin, end;
@@ -653,6 +655,8 @@ finalize_symtab (struct gdb_symtab *stab, struct objfile *objfile)
 
   /* Move just built blockvector over to CUST.  */
   cust->set_blockvector (std::move (bv));
+
+  return cust;
 }
 
 /* Called when closing a gdb_objfile.  Converts OBJ to a proper
@@ -673,10 +677,14 @@ jit_object_close_impl (struct gdb_symbol_callbacks *cb,
   objfile->section_offsets.push_back (0);
   objfile->sect_index_text = 0;
   objfile->per_bfd->gdbarch = priv_data->gdbarch;
-  objfile->qf.emplace_front (new expanded_symbols_functions);
+
+  std::vector<compunit_symtab *> compunit_symtabs;
 
   for (gdb_symtab &symtab : obj->symtabs)
-    finalize_symtab (&symtab, objfile);
+    compunit_symtabs.emplace_back (finalize_symtab (&symtab, objfile));
+
+  objfile->qf.emplace_front (std::make_unique<expanded_symbols_functions>
+			     (std::move (compunit_symtabs)));
 
   add_objfile_entry (objfile, priv_data->entry_addr,
 		     priv_data->entry.symfile_addr,
-- 
2.53.0


^ permalink raw reply	[flat|nested] 52+ messages in thread

* [PATCH v3 8/9] gdb/ctf: don't use psymtabs, create symtabs directly
  2026-02-28  3:51   ` [PATCH v3 0/9] Make CTF reader build full symtabs, get rid of psymtab Simon Marchi
                       ` (6 preceding siblings ...)
  2026-02-28  3:51     ` [PATCH v3 7/9] gdb: make expanded_symbols_functions hold compunit symtabs Simon Marchi
@ 2026-02-28  3:51     ` Simon Marchi
  2026-03-04 19:29       ` Tom Tromey
  2026-02-28  3:51     ` [PATCH v3 9/9] gdb: remove psymtab.{c,h} Simon Marchi
  2026-03-04 19:33     ` [PATCH v3 0/9] Make CTF reader build full symtabs, get rid of psymtab Tom Tromey
  9 siblings, 1 reply; 52+ messages in thread
From: Simon Marchi @ 2026-02-28  3:51 UTC (permalink / raw)
  To: gdb-patches; +Cc: Simon Marchi

From: Simon Marchi <simon.marchi@polymtl.ca>

The CTF debug info reader is the last user of partial symtabs.  Being a
fairly limited debug info format, CTF only uses a fraction of the
psymtab features.  So I see 3 ways forward:

 - keep psymtabs but trim them down, removing everything not useful for
   CTF

 - make the CTF reader implement its own index-like structure that
   implements the quick_symbol_functions interface (which would
   presumably be a small subset of partial symtabs)

 - make the CTF reader skip partial symtabs, create full symtabs
   directly

My hypothesis is that CTF debug info is typically small enough and fast
enough to process that it's not worth it to bother with an intermediate
step before full symbols.  But I will need help to see if this is true,
I'm not sure what representatively big C project I can build with CTF
debug info.  I tried to build the Linux kernel with -gctf, but I got
plenty of warnings like:

  ld: warning: orphan section `.ctf' from `vmlinux.o' being placed in section `.ctf'

GDB is still able to load the resulting ELF, and there are about 150k
calls to ctf_add_type_cb.  Before this patch, elfctf_build_psymtabs
takes anywhere between 300-350 ms.  With this patch, it's around 400 ms.

Implementation
--------------

This patch gets rid of the ctf_psymtab step, creating full symtabs from
the start.

The entry point elfctf_build_psymtabs gets renamed to
elfctf_build_symtabs.

Everything related to ctf_psymtab or partial symtabs is removed.

The build_ctf_archive_member function nows contains the code to build a
full symtab out of one CTF dict.  This code is not new for the most
part, it has been moved from other functions that used to be called when
expanding one symtab.

In order to access the symtabs, elfctf_build_symtabs installs the
expanded_symbols_functions quick_symbol_functions implementation, which
essentially searches in the existing symtabs.  I am pretty sure this is
not 100% correct, because this would search unrelated symtabs, if for
instance the CTF debug info co-existed with DWARF info.  But it's good
enough for a prototype.

Change-Id: I728c1ef35785218c178fb467b80db71d59269a6d
---
 gdb/ctfread.c | 462 ++++++++++----------------------------------------
 gdb/ctfread.h |   2 +-
 gdb/elfread.c |   8 +-
 3 files changed, 94 insertions(+), 378 deletions(-)

diff --git a/gdb/ctfread.c b/gdb/ctfread.c
index 251b1c7f1fce..dc8a32898e0e 100644
--- a/gdb/ctfread.c
+++ b/gdb/ctfread.c
@@ -79,9 +79,11 @@
 #include "complaints.h"
 #include "block.h"
 #include "ctfread.h"
-#include "maint.h"
-#include "psymtab.h"
 #include "cli/cli-cmds.h"
+#include "expanded-symbol.h"
+#include "maint.h"
+#include "objfiles.h"
+#include "progspace.h"
 
 /* When true, print debug messages related to CTF reading.  */
 static bool debug_ctf = false;
@@ -158,9 +160,6 @@ struct ctf_per_objfile
   /* Backlink to objfile.  */
   struct objfile *objfile;
 
-  /* Map from IDs to types.  */
-  ctf_type_map type_map;
-
   /* The archive and parent dictionary.  */
   ctf_archive_up archive;
   ctf_dict_up parent_dict;
@@ -174,26 +173,10 @@ struct ctf_context
 {
   ctf_per_objfile *per_objfile;
   ctf_dict_t *dict;
-  psymtab_storage *partial_symtabs;
-  partial_symtab *pst;
   struct buildsym_compunit *builder;
-};
 
-/* A partial symtab, specialized for this module.  */
-struct ctf_psymtab : public standard_psymtab
-{
-  ctf_psymtab (const char *filename,
-	       psymtab_storage *partial_symtabs,
-	       objfile_per_bfd_storage *objfile_per_bfd,
-	       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;
+  /* Map from IDs to types.  */
+  ctf_type_map type_map;
 };
 
 /* The routines that read and process fields/members of a C struct, union,
@@ -225,14 +208,6 @@ struct ctf_field_info
   std::vector<struct decl_field> nested_types_list;
 };
 
-/* Data held while using ctf_archive_iter to build psymtabs.  */
-
-struct ctf_archive_iter_psymtab_data
-{
-  ctf_per_objfile *per_objfile;
-  psymbol_functions *psf;
-};
-
 /* Local function prototypes */
 
 static int ctf_add_type_cb (ctf_id_t tid, void *arg);
@@ -261,11 +236,9 @@ static struct type *read_forward_type (struct ctf_context *cp, ctf_id_t tid);
 /* Set the type associated with TID to TYP.  */
 
 static struct type *
-set_tid_type (struct objfile *objfile, ctf_id_t tid, struct type *typ)
+set_tid_type (ctf_context *ccp, ctf_id_t tid, struct type *typ)
 {
-  ctf_per_objfile *per_objfile = ctf_per_objfile_key.get (objfile);
-  gdb_assert (per_objfile != nullptr);
-  per_objfile->type_map.emplace (tid, typ);
+  ccp->type_map.emplace (tid, typ);
   return typ;
 }
 
@@ -273,13 +246,10 @@ set_tid_type (struct objfile *objfile, ctf_id_t tid, struct type *typ)
    does not have a saved type.  */
 
 static struct type *
-get_tid_type (struct objfile *objfile, ctf_id_t tid)
+get_tid_type (ctf_context *ccp, ctf_id_t tid)
 {
-  ctf_per_objfile *per_objfile = ctf_per_objfile_key.get (objfile);
-  gdb_assert (per_objfile != nullptr);
-
-  auto iter = per_objfile->type_map.find (tid);
-  if (iter == per_objfile->type_map.end ())
+  auto iter = ccp->type_map.find (tid);
+  if (iter == ccp->type_map.end ())
     return nullptr;
   return iter->second;
 }
@@ -290,14 +260,13 @@ get_tid_type (struct objfile *objfile, ctf_id_t tid)
 static struct type *
 fetch_tid_type (struct ctf_context *ccp, ctf_id_t tid)
 {
-  struct objfile *objfile = ccp->per_objfile->objfile;
   struct type *typ;
 
-  typ = get_tid_type (objfile, tid);
+  typ = get_tid_type (ccp, tid);
   if (typ == nullptr)
     {
       ctf_add_type_cb (tid, ccp);
-      typ = get_tid_type (objfile, tid);
+      typ = get_tid_type (ccp, tid);
     }
 
   return typ;
@@ -410,7 +379,7 @@ ctf_add_member_cb (const char *name,
 	  objfile *objfile = ccp->per_objfile->objfile;
 	  complaint (_("ctf_add_member_cb: %s has NO type (%ld)"), name, tid);
 	  t = builtin_type (objfile)->builtin_error;
-	  set_tid_type (objfile, tid, t);
+	  set_tid_type (ccp, tid, t);
 	}
     }
 
@@ -577,7 +546,7 @@ read_base_type (struct ctf_context *ccp, ctf_id_t tid)
   if (name != nullptr && strcmp (name, "char") == 0)
     type->set_has_no_signedness (true);
 
-  return set_tid_type (objfile, tid, type);
+  return set_tid_type (ccp, tid, type);
 }
 
 static void
@@ -626,7 +595,7 @@ read_structure_type (struct ctf_context *ccp, ctf_id_t tid)
 	       ctf_errmsg (ctf_errno (dict)));
 
 
-  return set_tid_type (objfile, tid, type);
+  return set_tid_type (ccp, tid, type);
 }
 
 /* Given a tid of CTF_K_STRUCT or CTF_K_UNION, process all its members
@@ -714,7 +683,7 @@ read_func_kind_type (struct ctf_context *ccp, ctf_id_t tid)
 	}
     }
 
-  return set_tid_type (objfile, tid, type);
+  return set_tid_type (ccp, tid, type);
 }
 
 /* Given a TID of CTF_K_ENUM, process all the members of the
@@ -745,7 +714,7 @@ read_enum_type (struct ctf_context *ccp, ctf_id_t tid)
     complaint (_("ctf_type_align read_enum_type failed - %s"),
 	       ctf_errmsg (ctf_errno (dict)));
 
-  return set_tid_type (objfile, tid, type);
+  return set_tid_type (ccp, tid, type);
 }
 
 static void
@@ -793,7 +762,7 @@ add_array_cv_type (struct ctf_context *ccp,
   voltl |= TYPE_VOLATILE (el_type);
   inner_array->set_target_type (make_cv_type (cnst, voltl, el_type));
 
-  return set_tid_type (ccp->per_objfile->objfile, tid, base_type);
+  return set_tid_type (ccp, tid, base_type);
 }
 
 /* Read all information from a TID of CTF_K_ARRAY.  */
@@ -841,7 +810,7 @@ read_array_type (struct ctf_context *ccp, ctf_id_t tid)
     complaint (_("ctf_type_align read_array_type failed - %s"),
 	       ctf_errmsg (ctf_errno (dict)));
 
-  return set_tid_type (objfile, tid, type);
+  return set_tid_type (ccp, tid, type);
 }
 
 /* Read TID of kind CTF_K_CONST with base type BTID.  */
@@ -864,7 +833,7 @@ read_const_type (struct ctf_context *ccp, ctf_id_t tid, ctf_id_t btid)
     }
   cv_type = make_cv_type (1, TYPE_VOLATILE (base_type), base_type);
 
-  return set_tid_type (objfile, tid, cv_type);
+  return set_tid_type (ccp, tid, cv_type);
 }
 
 /* Read TID of kind CTF_K_VOLATILE with base type BTID.  */
@@ -891,7 +860,7 @@ read_volatile_type (struct ctf_context *ccp, ctf_id_t tid, ctf_id_t btid)
     return add_array_cv_type (ccp, tid, base_type, 0, 1);
   cv_type = make_cv_type (TYPE_CONST (base_type), 1, base_type);
 
-  return set_tid_type (objfile, tid, cv_type);
+  return set_tid_type (ccp, tid, cv_type);
 }
 
 /* Read TID of kind CTF_K_RESTRICT with base type BTID.  */
@@ -914,7 +883,7 @@ read_restrict_type (struct ctf_context *ccp, ctf_id_t tid, ctf_id_t btid)
     }
   cv_type = make_restrict_type (base_type);
 
-  return set_tid_type (objfile, tid, cv_type);
+  return set_tid_type (ccp, tid, cv_type);
 }
 
 /* Read TID of kind CTF_K_TYPEDEF with its NAME and base type BTID.  */
@@ -929,7 +898,7 @@ read_typedef_type (struct ctf_context *ccp, ctf_id_t tid,
   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);
+  set_tid_type (ccp, tid, this_type);
   target_type = fetch_tid_type (ccp, btid);
   if (target_type != this_type)
     this_type->set_target_type (target_type);
@@ -969,7 +938,7 @@ read_pointer_type (struct ctf_context *ccp, ctf_id_t tid, ctf_id_t btid)
     complaint (_("ctf_type_align read_pointer_type failed - %s"),
 	       ctf_errmsg (ctf_errno (ccp->dict)));
 
-  return set_tid_type (objfile, tid, type);
+  return set_tid_type (ccp, tid, type);
 }
 
 /* Read information from a TID of CTF_K_FORWARD.  */
@@ -997,7 +966,7 @@ read_forward_type (struct ctf_context *ccp, ctf_id_t tid)
   type->set_length (0);
   type->set_is_stub (true);
 
-  return set_tid_type (objfile, tid, type);
+  return set_tid_type (ccp, tid, type);
 }
 
 /* Read information associated with type TID.  */
@@ -1075,7 +1044,7 @@ ctf_add_type_cb (ctf_id_t tid, void *arg)
   uint32_t kind;
 
   /* Check if tid's type has already been defined.  */
-  type = get_tid_type (ccp->per_objfile->objfile, tid);
+  type = get_tid_type (ccp, tid);
   if (type != nullptr)
     {
       ctf_debug_printf ("tid=%ld already defined, skipping", tid);
@@ -1149,7 +1118,7 @@ ctf_add_var_cb (const char *name, ctf_id_t id, void *arg)
   uint32_t kind;
   objfile *objfile = ccp->per_objfile->objfile;
 
-  type = get_tid_type (objfile, id);
+  type = get_tid_type (ccp, id);
 
   kind = ctf_type_kind (ccp->dict, id);
 
@@ -1197,7 +1166,7 @@ add_stt_entries (struct ctf_context *ccp, int functions)
   while ((tid = ctf_symbol_next (ccp->dict, &i, &tname, functions)) != CTF_ERR)
     {
       objfile *objfile = ccp->per_objfile->objfile;
-      type = get_tid_type (objfile, tid);
+      type = get_tid_type (ccp, tid);
       if (type == nullptr)
 	{
 	  ctf_debug_printf ("skipping '%s' tid=0x%lx (no type found)", tname,
@@ -1248,338 +1217,90 @@ get_objfile_text_range (struct objfile *objfile, size_t *tsize)
   return objfile->text_section_offset ();
 }
 
-/* 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)
+struct ctf_archive_iter_data
 {
-  int val;
-  const char *ename;
-  ctf_next_t *i = nullptr;
+  ctf_per_objfile &per_objfile;
+  std::vector<compunit_symtab *> compunit_symtabs;
+};
 
-  while ((ename = ctf_enum_next (ccp->dict, 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->per_objfile->objfile);
-    }
-  if (ctf_errno (ccp->dict) != ECTF_NEXT_END)
-    complaint (_("ctf_enum_next ctf_psymtab_add_enums failed - %s"),
-	       ctf_errmsg (ctf_errno (ccp->dict)));
-}
-
-/* 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 *dict, ctf_psymtab *pst, int functions)
-{
-  ctf_next_t *i = nullptr;
-  ctf_id_t tid;
-  const char *tname;
-
-  while ((tid = ctf_symbol_next (dict, &i, &tname, functions)) != CTF_ERR)
-    {
-      uint32_t kind = ctf_type_kind (dict, tid);
-      location_class loc_class;
-      domain_enum tdomain = functions ? FUNCTION_DOMAIN : VAR_DOMAIN;
-
-      if (kind == CTF_K_FUNCTION)
-	loc_class = LOC_BLOCK;
-      else
-	loc_class = LOC_STATIC;
-
-      ctf_debug_printf ("adding %s psym '%s' tid=0x%lx kind=%s",
-			functions ? "function" : "object", tname, tid,
-			ctf_kind_str (kind));
-
-      pst->add_psymbol (tname, true, tdomain, loc_class, -1,
-			psymbol_placement::GLOBAL, unrelocated_addr (0),
-			language_c, pst->context.partial_symtabs,
-			pst->context.per_objfile->objfile);
-    }
-}
-
-/* Add entries in data objects section to psymtab.  */
-
-static void
-ctf_psymtab_add_stt_obj (ctf_dict_t *dict, ctf_psymtab *pst)
-{
-  ctf_psymtab_add_stt_entries (dict, pst, 0);
-}
-
-/* Add entries in function info section to psymtab.  */
-
-static void
-ctf_psymtab_add_stt_func (ctf_dict_t *dict, ctf_psymtab *pst)
-{
-  ctf_psymtab_add_stt_entries (dict, pst, 1);
-}
-
-/* Read in full symbols for PST, and anything it depends on.  */
-
-void
-ctf_psymtab::expand_psymtab (struct objfile *objfile)
-{
-  struct ctf_context *ccp;
-
-  CTF_SCOPED_DEBUG_START_END ("expanding psymtab");
-
-  gdb_assert (!readin);
-
-  ccp = &context;
-
-  /* Iterate over entries in data types section.  */
-  if (ctf_type_iter (ccp->dict, ctf_add_type_cb, ccp) == CTF_ERR)
-    complaint (_("ctf_type_iter psymtab_to_symtab failed - %s"),
-	       ctf_errmsg (ctf_errno (ccp->dict)));
-
-
-  /* Iterate over entries in variable info section.  */
-  if (ctf_variable_iter (ccp->dict, ctf_add_var_cb, ccp) == CTF_ERR)
-    complaint (_("ctf_variable_iter psymtab_to_symtab failed - %s"),
-	       ctf_errmsg (ctf_errno (ccp->dict)));
-
-  /* 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)
-{
-  CTF_SCOPED_DEBUG_START_END ("reading symtab for '%s'", filename);
-
-  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_debug_printf ("starting buildsym for '%s', offset=%s, tsize=%zu",
-			filename, hex_string (offset), tsize);
-
-      buildsym_compunit builder (objfile, this->filename, nullptr,
-				 language_c, offset);
-      builder.record_debugformat ("ctf");
-      scoped_restore store_builder
-	= make_scoped_restore (&context.builder, &builder);
-
-      expand_psymtab (objfile);
-
-      set_text_low (unrelocated_addr (0));
-      set_text_high (unrelocated_addr (tsize));
-      compunit_symtab = builder.end_compunit_symtab (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_dict_t *dict,
-		       psymtab_storage *partial_symtabs,
-		       ctf_per_objfile *per_objfile)
-{
-  ctf_psymtab *pst;
-
-  pst = new ctf_psymtab (name, partial_symtabs, per_objfile->objfile->per_bfd,
-			 unrelocated_addr (0));
-
-  pst->context.per_objfile = per_objfile;
-  pst->context.dict = dict;
-  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;
-  location_class loc_class = LOC_UNDEF;
-  kind = ctf_type_kind (ccp->dict, 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;
-      loc_class = LOC_TYPEDEF;
-      break;
-    case CTF_K_FUNCTION:
-    case CTF_K_FORWARD:
-    case CTF_K_CONST:
-    case CTF_K_TYPEDEF:
-    case CTF_K_POINTER:
-    case CTF_K_VOLATILE:
-    case CTF_K_RESTRICT:
-    case CTF_K_INTEGER:
-    case CTF_K_FLOAT:
-    case CTF_K_ARRAY:
-      domain = TYPE_DOMAIN;
-      loc_class = LOC_TYPEDEF;
-      break;
-    case CTF_K_UNKNOWN:
-      return 0;
-    }
-
-  const char *name = ctf_type_name_raw (ccp->dict, tid);
-  if (name == nullptr || *name == '\0')
-    return 0;
-
-  ctf_debug_printf ("adding type tid=0x%lx kind=%s name='%s'",
-		    tid, ctf_kind_str (kind), name);
-
-  ccp->pst->add_psymbol (name, false, domain, loc_class, section,
-			 psymbol_placement::GLOBAL, unrelocated_addr (0),
-			 language_c, ccp->partial_symtabs,
-			 ccp->per_objfile->objfile);
-
-  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;
-
-  uint32_t kind = ctf_type_kind (ccp->dict, id);
-
-  ctf_debug_printf ("adding variable name='%s' tid=0x%lx kind=%s",
-		    name, id, ctf_kind_str (kind));
-
-  ccp->pst->add_psymbol (name, true,
-			 kind == CTF_K_FUNCTION ? FUNCTION_DOMAIN : VAR_DOMAIN,
-			 LOC_STATIC, -1, psymbol_placement::GLOBAL,
-			 unrelocated_addr (0), language_c,
-			 ccp->partial_symtabs, ccp->per_objfile->objfile);
-  return 0;
-}
-
-/* Setup partial_symtab's describing each source file for which
-   debugging information is available.  */
-
-static void
-scan_partial_symbols (ctf_dict_t *dict, psymtab_storage *partial_symtabs,
-		      ctf_per_objfile *per_objfile, const char *fname)
-{
-  objfile *objfile = per_objfile->objfile;
-  bool isparent = false;
-
-  CTF_SCOPED_DEBUG_START_END ("fname='%s'", fname);
-
-  if (strcmp (fname, ".ctf") == 0)
-    {
-      fname = bfd_get_filename (objfile->obfd.get ());
-      isparent = true;
-      ctf_debug_printf ("is parent, using fname='%s'", fname);
-    }
-
-  ctf_psymtab *pst = create_partial_symtab (fname, dict, partial_symtabs,
-					    per_objfile);
-
-  struct ctf_context *ccx = &pst->context;
-  if (isparent == false)
-    ccx->pst = pst;
-
-  if (ctf_type_iter (dict, ctf_psymtab_type_cb, ccx) == CTF_ERR)
-    complaint (_("ctf_type_iter scan_partial_symbols failed - %s"),
-	       ctf_errmsg (ctf_errno (dict)));
-
-  if (ctf_variable_iter (dict, ctf_psymtab_var_cb, ccx) == CTF_ERR)
-    complaint (_("ctf_variable_iter scan_partial_symbols failed - %s"),
-	       ctf_errmsg (ctf_errno (dict)));
-
-  /* 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 (dict, pst);
-  ctf_psymtab_add_stt_func (dict, pst);
-
-  pst->end ();
-}
-
-/* Callback to build the psymtab for archive member NAME.  */
+/* ctf_archive_iter callback to build the ssymtab for archive member NAME.  */
 
 static int
 build_ctf_archive_member (ctf_dict_t *dict, const char *name, void *arg)
 {
-  auto iter_data = static_cast<ctf_archive_iter_psymtab_data *> (arg);
-  ctf_per_objfile *per_objfile = iter_data->per_objfile;
+  CTF_SCOPED_DEBUG_START_END ("name='%s'", name);
+
+  auto *iter_data = static_cast<ctf_archive_iter_data *> (arg);
+  ctf_per_objfile &per_objfile = iter_data->per_objfile;
 
   if (strcmp (name, ".ctf") != 0)
-    ctf_import (dict, per_objfile->parent_dict.get ());
+    ctf_import (dict, per_objfile.parent_dict.get ());
+
+  objfile *objfile = per_objfile.objfile;
+
+  if (strcmp (name, ".ctf") == 0)
+    {
+      name = bfd_get_filename (objfile->obfd.get ());
+      ctf_debug_printf ("is parent, using name='%s'", name);
+    }
 
   if (info_verbose)
     {
-      gdb_printf (_("Scanning archive member %s..."), name);
+      gdb_printf (_("Reading in CTF data for %s..."), name);
       gdb_flush (gdb_stdout);
     }
 
-  psymtab_storage *pss = iter_data->psf->get_partial_symtabs ().get ();
-  scan_partial_symbols (dict, pss, per_objfile, name);
+  /* Start and size of the text segment.  */
+  size_t tsize;
+  CORE_ADDR offset = get_objfile_text_range (objfile, &tsize);
+
+  ctf_debug_printf ("starting buildsym for '%s', offset=0x%s, tsize=%zu",
+		    name, hex_string (offset), tsize);
+
+  buildsym_compunit builder (objfile, name, nullptr, language_c, offset);
+  builder.record_debugformat ("ctf");
+
+  ctf_context ccx;
+  ccx.per_objfile = &per_objfile;
+  ccx.dict = dict;
+  ccx.builder = &builder;
+
+  /* Iterate over entries in data types section.  */
+  if (ctf_type_iter (dict, ctf_add_type_cb, &ccx) == CTF_ERR)
+    complaint (_("ctf_type_iter failed - %s"),
+	       ctf_errmsg (ctf_errno (dict)));
+
+
+  /* Iterate over entries in variable info section.  */
+  if (ctf_variable_iter (dict, ctf_add_var_cb, &ccx) == CTF_ERR)
+    complaint (_("ctf_variable_iter failed - %s"),
+	       ctf_errmsg (ctf_errno (dict)));
+
+  /* Add entries in data objects and function info sections.  */
+  add_stt_obj (&ccx);
+  add_stt_func (&ccx);
+
+  iter_data->compunit_symtabs.push_back
+   (builder.end_compunit_symtab (offset + tsize));
+
+  /* Finish up the debug error message.  */
+  if (info_verbose)
+    gdb_printf (_("done.\n"));
 
   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.  */
+   called from elfread.c.  */
 
 void
-elfctf_build_psymtabs (objfile *objfile)
+elfctf_build_symtabs (objfile *objfile)
 {
   bfd *abfd = objfile->obfd.get ();
   int err;
-
   scoped_time_it time_it (__func__);
 
-  CTF_SCOPED_DEBUG_START_END ("building psymtabs for %s",
+  CTF_SCOPED_DEBUG_START_END ("building symtabs for %s",
 			      bfd_get_filename (abfd));
 
   ctf_archive_up archive (ctf_bfdopen (abfd, &err));
@@ -1595,17 +1316,16 @@ elfctf_build_psymtabs (objfile *objfile)
   ctf_per_objfile &per_objfile
     = ctf_per_objfile_key.emplace (objfile, objfile, std::move (archive),
 				   std::move (dict));
-  psymbol_functions *psf = new psymbol_functions ();
-
-  objfile->qf.emplace_front (psf);
-
-  ctf_archive_iter_psymtab_data iter_data { &per_objfile, psf };
+  ctf_archive_iter_data iter_data { per_objfile };
 
   if (ctf_archive_iter (per_objfile.archive.get (), build_ctf_archive_member,
 			&iter_data)
       < 0)
     error (_("ctf_archive_iter failed in input file %s: - %s"),
 	   bfd_get_filename (abfd), ctf_errmsg (err));
+
+  objfile->qf.emplace_front (std::make_unique<expanded_symbols_functions>
+			     (std::move (iter_data.compunit_symtabs)));
 }
 
 #else
diff --git a/gdb/ctfread.h b/gdb/ctfread.h
index 95aa7f632731..b87f78bba0df 100644
--- a/gdb/ctfread.h
+++ b/gdb/ctfread.h
@@ -20,6 +20,6 @@
 #ifndef GDB_CTFREAD_H
 #define GDB_CTFREAD_H
 
-extern void elfctf_build_psymtabs (struct objfile *objfile);
+extern void elfctf_build_symtabs (struct objfile *objfile);
 
 #endif /* GDB_CTFREAD_H */
diff --git a/gdb/elfread.c b/gdb/elfread.c
index 7e38f623d12d..db23788c13b1 100644
--- a/gdb/elfread.c
+++ b/gdb/elfread.c
@@ -1288,17 +1288,13 @@ elf_symfile_read (struct objfile *objfile, symfile_add_flags symfile_flags)
 
   /* Read the CTF section only if there is no DWARF info.  */
   if (always_read_ctf && ei.ctfsect)
-    {
-      elfctf_build_psymtabs (objfile);
-    }
+    elfctf_build_symtabs (objfile);
 
   bool has_dwarf2 = elf_symfile_read_dwarf2 (objfile, symfile_flags);
 
   /* Read the CTF section only if there is no DWARF info.  */
   if (!always_read_ctf && !has_dwarf2 && ei.ctfsect)
-    {
-      elfctf_build_psymtabs (objfile);
-    }
+    elfctf_build_symtabs (objfile);
 
   /* Copy relocations are used by some ABIs using the ELF format, so
      set the objfile flag indicating this fact.  */
-- 
2.53.0


^ permalink raw reply	[flat|nested] 52+ messages in thread

* [PATCH v3 9/9] gdb: remove psymtab.{c,h}
  2026-02-28  3:51   ` [PATCH v3 0/9] Make CTF reader build full symtabs, get rid of psymtab Simon Marchi
                       ` (7 preceding siblings ...)
  2026-02-28  3:51     ` [PATCH v3 8/9] gdb/ctf: don't use psymtabs, create symtabs directly Simon Marchi
@ 2026-02-28  3:51     ` Simon Marchi
  2026-02-28 10:18       ` Eli Zaretskii
  2026-03-04 19:33     ` [PATCH v3 0/9] Make CTF reader build full symtabs, get rid of psymtab Tom Tromey
  9 siblings, 1 reply; 52+ messages in thread
From: Simon Marchi @ 2026-02-28  3:51 UTC (permalink / raw)
  To: gdb-patches; +Cc: Simon Marchi

From: Simon Marchi <simon.marchi@polymtl.ca>

The last user of psymtabs has been changed not to use them, remove them.

Update the tests minimally to avoid introducing failures (mostly due to
tests using the removed maintenance commands).  There are still a lot of
references to partial symtabs in the comments or test names.  There are
probably some tests that are just not relevant anymore.  It would be quite
difficult to do this job all at once, we can clean this up little by
little.

Update the docs to remove references to partial symbols/symtabs.

Mention the removal of the maintenance commands in NEWS.

Change-Id: I58ae48c30e0303bcaa48298146d69fb8f059cb32
---
 gdb/Makefile.in                          |    2 -
 gdb/NEWS                                 |    8 +
 gdb/doc/gdb.texinfo                      |   95 +-
 gdb/psymtab.c                            | 1575 ----------------------
 gdb/psymtab.h                            |  691 ----------
 gdb/testsuite/gdb.ada/maint_with_ada.exp |    2 -
 gdb/testsuite/gdb.base/check-psymtab.c   |   28 -
 gdb/testsuite/gdb.base/check-psymtab.exp |   26 -
 gdb/testsuite/gdb.base/main-psymtab.exp  |   38 -
 gdb/testsuite/gdb.base/maint.exp         |   96 +-
 gdb/testsuite/gdb.base/readnever.exp     |    4 -
 gdb/testsuite/lib/gdb.exp                |   22 -
 12 files changed, 38 insertions(+), 2549 deletions(-)
 delete mode 100644 gdb/psymtab.c
 delete mode 100644 gdb/psymtab.h
 delete mode 100644 gdb/testsuite/gdb.base/check-psymtab.c
 delete mode 100644 gdb/testsuite/gdb.base/check-psymtab.exp
 delete mode 100644 gdb/testsuite/gdb.base/main-psymtab.exp

diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index 2aa95be968ac..ca9e6be47631 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -1177,7 +1177,6 @@ COMMON_SFILES = \
 	progspace.c \
 	progspace-and-thread.c \
 	prologue-value.c \
-	psymtab.c \
 	record.c \
 	record-btrace.c \
 	record-full.c \
@@ -1612,7 +1611,6 @@ HFILES_NO_SRCDIR = \
 	progspace-and-thread.h \
 	progspace.h \
 	prologue-value.h \
-	psymtab.h \
 	python/py-color.h \
 	python/py-event.h \
 	python/py-events.h \
diff --git a/gdb/NEWS b/gdb/NEWS
index e83d1abd73b3..f260a0a85edc 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -133,6 +133,14 @@ New command class for help
   commands that we, as developers, believe would be close to a minimal
   set of commands for a new user of GDB.
 
+* Removed commands
+
+maint check psymtabs
+maint info psymtabs
+maint print psymbols
+  These commands have been removed, as GDB no longer uses partial
+  symbol tables internally.
+
 * Debugger Adapter Protocol changes
 
   ** Unhandled Ada exceptions can now be caught using the "unhandled"
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 8561c04f26a0..47a662efb8f4 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -20740,14 +20740,10 @@ entered from the keyboard causes symbol information to be loaded.
 @anchor{maint print symbols}
 @kindex maint print symbols
 @cindex symbol dump
-@kindex maint print psymbols
-@cindex partial symbol dump
 @kindex maint print msymbols
 @cindex minimal symbol dump
 @item maint print symbols @r{[}-pc @var{address}@r{]} @r{[}@var{filename}@r{]}
 @itemx maint print symbols @r{[}-objfile @var{objfile}@r{]} @r{[}-source @var{source}@r{]} @r{[}--@r{]} @r{[}@var{filename}@r{]}
-@itemx maint print psymbols @r{[}-objfile @var{objfile}@r{]} @r{[}-pc @var{address}@r{]} @r{[}--@r{]} @r{[}@var{filename}@r{]}
-@itemx maint print psymbols @r{[}-objfile @var{objfile}@r{]} @r{[}-source @var{source}@r{]} @r{[}--@r{]} @r{[}@var{filename}@r{]}
 @itemx maint print msymbols @r{[}-objfile @var{objfile}@r{]} @r{[}--@r{]} @r{[}@var{filename}@r{]}
 Write a dump of debugging symbol data into the file @var{filename} or
 the terminal if @var{filename} is unspecified.
@@ -20764,71 +20760,44 @@ These commands do not modify internal @value{GDBN} state, therefore
 @samp{maint print symbols} will only print symbols for already expanded symbol
 tables.
 You can use the command @code{info sources} to find out which files these are.
-If you use @samp{maint print psymbols} instead, the dump shows information
-about symbols that @value{GDBN} only knows partially---that is, symbols
-defined in files that @value{GDBN} has skimmed, but not yet read completely.
-Finally, @samp{maint print msymbols} just dumps ``minimal symbols'', e.g.,
+@samp{maint print msymbols} dumps ``minimal symbols'', e.g.,
 ``ELF symbols''.
 
 @xref{Files, ,Commands to Specify Files}, for a discussion of how
 @value{GDBN} reads symbols (in the description of @code{symbol-file}).
 
 @kindex maint info symtabs
-@kindex maint info psymtabs
 @cindex listing @value{GDBN}'s internal symbol tables
 @cindex symbol tables, listing @value{GDBN}'s internal
 @cindex full symbol tables, listing @value{GDBN}'s internal
-@cindex partial symbol tables, listing @value{GDBN}'s internal
 @item maint info symtabs @r{[} @var{regexp} @r{]}
-@itemx maint info psymtabs @r{[} @var{regexp} @r{]}
 
-List the @code{struct symtab} or @code{struct partial_symtab}
-structures whose names match @var{regexp}.  If @var{regexp} is not
-given, list them all.  The output includes expressions which you can
-copy into a @value{GDBN} debugging this one to examine a particular
-structure in more detail.  For example:
+List the @code{struct symtab} structures whose names match
+@var{regexp}.  If @var{regexp} is not given, list them all.  The
+output includes expressions which you can copy into a @value{GDBN}
+debugging this one to examine a particular structure in more detail.
+For example:
 
 @smallexample
-(@value{GDBP}) maint info psymtabs dwarf2read
-@{ objfile /home/gnu/build/gdb/gdb
-  ((struct objfile *) 0x82e69d0)
-  @{ psymtab /home/gnu/src/gdb/dwarf2read.c
-    ((struct partial_symtab *) 0x8474b10)
-    readin no
-    fullname (null)
-    text addresses 0x814d3c8 -- 0x8158074
-    globals (* (struct partial_symbol **) 0x8507a08 @@ 9)
-    statics (* (struct partial_symbol **) 0x40e95b78 @@ 2882)
-    dependencies (none)
+(@value{GDBP}) maint info symtabs
+@{ objfile /home/gnu/build/binutils-gdb/gdb/a.out ((struct objfile *) 0x7d48d1c92b80)
+  @{ ((struct compunit_symtab *) 0x7cd8d1be44b0)
+    debugformat DWARF 5
+    producer GNU C23 15.2.1 20260209 -mtune=generic -march=x86-64 -g3 -O0
+    name test.c
+    dirname /home/gnu/build/binutils-gdb/gdb
+    blockvector ((struct blockvector *) 0x7c48d1c1efc0)
+    user ((struct compunit_symtab *) (null))
+        @{ symtab test.c ((struct symtab *) 0x7df8d1d588a0)
+          fullname /home/gnu/build/binutils-gdb/gdb/test.c
+          linetable ((struct linetable *) 0x7df8d1d58cc0)
+        @}
+        @{ symtab /usr/include/stdc-predef.h ((struct symtab *) 0x7df8d1d588e0)
+          fullname (void)
+          linetable ((struct linetable *) 0x0)
+        @}
   @}
 @}
-(@value{GDBP}) maint info symtabs
-(@value{GDBP})
-@end smallexample
-@noindent
-We see that there is one partial symbol table whose filename contains
-the string @samp{dwarf2read}, belonging to the @samp{gdb} executable;
-and we see that @value{GDBN} has not read in any symtabs yet at all.
-If we set a breakpoint on a function, that will cause @value{GDBN} to
-read the symtab for the compilation unit containing that function:
-
-@smallexample
-(@value{GDBP}) break dwarf2_psymtab_to_symtab
-Breakpoint 1 at 0x814e5da: file /home/gnu/src/gdb/dwarf2read.c,
-line 1574.
-(@value{GDBP}) maint info symtabs
-@{ objfile /home/gnu/build/gdb/gdb
-  ((struct objfile *) 0x82e69d0)
-  @{ symtab /home/gnu/src/gdb/dwarf2read.c
-    ((struct symtab *) 0x86c1f38)
-    dirname (null)
-    fullname (null)
-    blockvector ((struct blockvector *) 0x86c1bd0) (primary)
-    linetable ((struct linetable *) 0x8370fa0)
-    debugformat DWARF 2
-  @}
-@}
-(@value{GDBP})
 @end smallexample
 
 @kindex maint info line-table
@@ -42109,11 +42078,6 @@ only if non-stop mode is active (@pxref{Non-Stop Mode}) and the target
 architecture supports displaced stepping.
 @end table
 
-@kindex maint check psymtabs
-@item maint check psymtabs
-Check the consistency of currently expanded psymtabs versus symtabs.
-Use this to check, for example, whether a symbol is in one but not the other.
-
 @kindex maint check symtabs
 @item maint check symtabs
 Check the consistency of currently expanded symtabs.
@@ -42602,7 +42566,7 @@ styling.  After flushing the cache any source code displayed by
 Print a dump of all known object files.
 If @var{regexp} is specified, only print object files whose names
 match @var{regexp}.  For each object file, this command prints its name,
-address in memory, and all of its psymtabs and symtabs.
+address in memory, and all of its symtabs.
 
 @kindex maint print user-registers
 @cindex user registers
@@ -42631,12 +42595,11 @@ and the full path if known.
 This command prints, for each object file in the program, various data
 about that object file followed by the byte cache (@dfn{bcache})
 statistics for the object file.  The objfile data includes the number
-of minimal, partial, and full, the number of types defined by the
-objfile, the number of as yet unexpanded psym tables, the number of
-line tables and string tables, and the amount of memory used by the
-various tables.  The bcache statistics include the counts, sizes, and
-counts of duplicates of all and unique objects, max, average, and
-median entry size, total memory used and its overhead and savings,
+of minimal symbols, of full symbols, of types defined by the
+objfile, of line tables and of string tables, and the amount of memory
+used by the various tables.  The bcache statistics include the counts,
+sizes, and counts of duplicates of all and unique objects, max, average,
+and median entry size, total memory used and its overhead and savings,
 and various measures of the hash table size and chain lengths.
 
 @kindex maint print target-stack
diff --git a/gdb/psymtab.c b/gdb/psymtab.c
deleted file mode 100644
index 59059616c1aa..000000000000
--- a/gdb/psymtab.c
+++ /dev/null
@@ -1,1575 +0,0 @@
-/* Partial symbol tables.
-
-   Copyright (C) 2009-2026 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/>.  */
-
-#include "event-top.h"
-#include "symtab.h"
-#include "objfiles.h"
-#include "psymtab.h"
-#include "block.h"
-#include "filenames.h"
-#include "source.h"
-#include "gdbtypes.h"
-#include "ui-out.h"
-#include "command.h"
-#include "gdbsupport/gdb_regex.h"
-#include "dictionary.h"
-#include "language.h"
-#include "cp-support.h"
-#include "cli/cli-cmds.h"
-#include <algorithm>
-#include <set>
-#include "gdbsupport/buildargv.h"
-
-static const struct partial_symbol *lookup_partial_symbol
-     (struct objfile *, struct partial_symtab *, const lookup_name_info &,
-      int, domain_search_flags);
-
-static const char *psymtab_to_fullname (struct partial_symtab *ps);
-
-static const struct partial_symbol *find_pc_sect_psymbol
-     (struct objfile *, struct partial_symtab *, CORE_ADDR,
-      struct obj_section *);
-
-static struct compunit_symtab *psymtab_to_symtab (struct objfile *objfile,
-						  struct partial_symtab *pst);
-
-psymtab_storage::~psymtab_storage ()
-{
-  partial_symtab *iter = psymtabs;
-  while (iter != nullptr)
-    {
-      partial_symtab *next = iter->next;
-      delete iter;
-      iter = next;
-    }
-}
-
-/* See psymtab.h.  */
-
-void
-psymtab_storage::install_psymtab (partial_symtab *pst)
-{
-  pst->next = psymtabs;
-  psymtabs = pst;
-}
-
-\f
-
-/* See psymtab.h.  */
-
-psymtab_storage::partial_symtab_range
-psymbol_functions::partial_symbols (struct objfile *objfile)
-{
-  return m_partial_symtabs->range ();
-}
-
-/* Find which partial symtab contains PC and SECTION starting at psymtab PST.
-   We may find a different psymtab than PST.  See FIND_PC_SECT_PSYMTAB.  */
-
-static struct partial_symtab *
-find_pc_sect_psymtab_closer (struct objfile *objfile,
-			     CORE_ADDR pc, struct obj_section *section,
-			     struct partial_symtab *pst,
-			     bound_minimal_symbol msymbol)
-{
-  struct partial_symtab *tpst;
-  struct partial_symtab *best_pst = pst;
-  CORE_ADDR best_addr = pst->text_low (objfile);
-
-  /* An objfile that has its functions reordered might have
-     many partial symbol tables containing the PC, but
-     we want the partial symbol table that contains the
-     function containing the PC.  */
-  if (section == nullptr)
-    return pst;
-
-  if (msymbol.minsym == NULL)
-    return pst;
-
-  /* The code range of partial symtabs sometimes overlap, so, in
-     the loop below, we need to check all partial symtabs and
-     find the one that fits better for the given PC address.  We
-     select the partial symtab that contains a symbol whose
-     address is closest to the PC address.  By closest we mean
-     that find_pc_sect_symbol returns the symbol with address
-     that is closest and still less than the given PC.  */
-  for (tpst = pst; tpst != NULL; tpst = tpst->next)
-    {
-      if (pc >= tpst->text_low (objfile) && pc < tpst->text_high (objfile))
-	{
-	  const struct partial_symbol *p;
-	  CORE_ADDR this_addr;
-
-	  /* NOTE: This assumes that every psymbol has a
-	     corresponding msymbol, which is not necessarily
-	     true; the debug info might be much richer than the
-	     object's symbol table.  */
-	  p = find_pc_sect_psymbol (objfile, tpst, pc, section);
-	  if (p != NULL
-	      && (p->address (objfile) == msymbol.value_address ()))
-	    return tpst;
-
-	  /* Also accept the textlow value of a psymtab as a
-	     "symbol", to provide some support for partial
-	     symbol tables with line information but no debug
-	     symbols (e.g. those produced by an assembler).  */
-	  if (p != NULL)
-	    this_addr = p->address (objfile);
-	  else
-	    this_addr = tpst->text_low (objfile);
-
-	  /* Check whether it is closer than our current
-	     BEST_ADDR.  Since this symbol address is
-	     necessarily lower or equal to PC, the symbol closer
-	     to PC is the symbol which address is the highest.
-	     This way we return the psymtab which contains such
-	     best match symbol.  This can help in cases where the
-	     symbol information/debuginfo is not complete, like
-	     for instance on IRIX6 with gcc, where no debug info
-	     is emitted for statics.  (See also the nodebug.exp
-	     testcase.)  */
-	  if (this_addr > best_addr)
-	    {
-	      best_addr = this_addr;
-	      best_pst = tpst;
-	    }
-	}
-    }
-  return best_pst;
-}
-
-/* See psymtab.h.  */
-
-struct partial_symtab *
-psymbol_functions::find_pc_sect_psymtab (struct objfile *objfile,
-					 CORE_ADDR pc,
-					 struct obj_section *section,
-					 bound_minimal_symbol msymbol)
-{
-  for (partial_symtab *pst : partial_symbols (objfile))
-    if (pc >= pst->text_low (objfile) && pc < pst->text_high (objfile))
-      {
-	struct partial_symtab *best_pst;
-
-	best_pst = find_pc_sect_psymtab_closer (objfile, pc, section, pst,
-						msymbol);
-	if (best_pst != NULL)
-	  return best_pst;
-      }
-
-  return NULL;
-}
-
-/* Psymtab version of find_pc_sect_compunit_symtab.  See its definition in
-   the definition of quick_symbol_functions in symfile.h.  */
-
-struct compunit_symtab *
-psymbol_functions::find_pc_sect_compunit_symtab (struct objfile *objfile,
-						 bound_minimal_symbol msymbol,
-						 CORE_ADDR pc,
-						 struct obj_section *section,
-						 int warn_if_readin)
-{
-  struct partial_symtab *ps = find_pc_sect_psymtab (objfile,
-						    pc, section,
-						    msymbol);
-  if (ps != NULL)
-    {
-      if (warn_if_readin && ps->readin_p (objfile))
-	/* Might want to error() here (in case symtab is corrupt and
-	   will cause a core dump), but maybe we can successfully
-	   continue, so let's not.  */
-	warning (_("\
-(Internal error: pc %s in read in psymtab, but not in symtab.)\n"),
-		 paddress (objfile->arch (), pc));
-      psymtab_to_symtab (objfile, ps);
-      return ps->get_compunit_symtab (objfile);
-    }
-  return NULL;
-}
-
-/* Find which partial symbol within a psymtab matches PC and SECTION.
-   Return NULL if none.  */
-
-static const struct partial_symbol *
-find_pc_sect_psymbol (struct objfile *objfile,
-		      struct partial_symtab *psymtab, CORE_ADDR pc,
-		      struct obj_section *section)
-{
-  const struct partial_symbol *best = NULL;
-  CORE_ADDR best_pc;
-  const CORE_ADDR textlow = psymtab->text_low (objfile);
-
-  gdb_assert (psymtab != NULL);
-
-  /* Cope with programs that start at address 0.  */
-  best_pc = (textlow != 0) ? textlow - 1 : 0;
-
-  /* Search the global symbols as well as the static symbols, so that
-     find_pc_partial_function doesn't use a minimal symbol and thus
-     cache a bad endaddr.  */
-  for (const partial_symbol *p : psymtab->global_psymbols)
-    {
-      if (p->domain == VAR_DOMAIN
-	  && p->loc_class == LOC_BLOCK
-	  && pc >= p->address (objfile)
-	  && (p->address (objfile) > best_pc
-	      || (psymtab->text_low (objfile) == 0
-		  && best_pc == 0 && p->address (objfile) == 0)))
-	{
-	  if (section != NULL)  /* Match on a specific section.  */
-	    {
-	      if (!matching_obj_sections (p->obj_section (objfile),
-					  section))
-		continue;
-	    }
-	  best_pc = p->address (objfile);
-	  best = p;
-	}
-    }
-
-  for (const partial_symbol *p : psymtab->static_psymbols)
-    {
-      if (p->domain == VAR_DOMAIN
-	  && p->loc_class == LOC_BLOCK
-	  && pc >= p->address (objfile)
-	  && (p->address (objfile) > best_pc
-	      || (psymtab->text_low (objfile) == 0
-		  && best_pc == 0 && p->address (objfile) == 0)))
-	{
-	  if (section != NULL)  /* Match on a specific section.  */
-	    {
-	      if (!matching_obj_sections (p->obj_section (objfile),
-					  section))
-		continue;
-	    }
-	  best_pc = p->address (objfile);
-	  best = p;
-	}
-    }
-
-  return best;
-}
-
-/* Psymtab version of lookup_global_symbol_language.  See its definition in
-   the definition of quick_symbol_functions in symfile.h.  */
-
-enum language
-psymbol_functions::lookup_global_symbol_language (struct objfile *objfile,
-						  const char *name,
-						  domain_search_flags domain,
-						  bool *symbol_found_p)
-{
-  *symbol_found_p = false;
-  if (objfile->sf == NULL)
-    return language_unknown;
-
-  lookup_name_info lookup_name (name, symbol_name_match_type::FULL);
-
-  for (partial_symtab *ps : partial_symbols (objfile))
-    {
-      const struct partial_symbol *psym;
-      if (ps->readin_p (objfile))
-	continue;
-
-      psym = lookup_partial_symbol (objfile, ps, lookup_name, 1, domain);
-      if (psym)
-	{
-	  *symbol_found_p = true;
-	  return psym->ginfo.language ();
-	}
-    }
-
-  return language_unknown;
-}
-
-/* Returns true if PSYM matches LOOKUP_NAME.  */
-
-static bool
-psymbol_name_matches (const partial_symbol *psym,
-		      const lookup_name_info &lookup_name)
-{
-  const language_defn *lang = language_def (psym->ginfo.language ());
-  symbol_name_matcher_ftype *name_match
-    = lang->get_symbol_name_matcher (lookup_name);
-  return name_match (psym->ginfo.search_name (), lookup_name, NULL);
-}
-
-/* Look, in partial_symtab PST, for symbol whose natural name is
-   LOOKUP_NAME.  Check the global symbols if GLOBAL, the static
-   symbols if not.  */
-
-static const struct partial_symbol *
-lookup_partial_symbol (struct objfile *objfile,
-		       struct partial_symtab *pst,
-		       const lookup_name_info &lookup_name,
-		       int global, domain_search_flags domain)
-{
-  const struct partial_symbol **start, **psym;
-  const struct partial_symbol **top, **real_top, **bottom, **center;
-  int length = (global
-		? pst->global_psymbols.size ()
-		: pst->static_psymbols.size ());
-  int do_linear_search = 1;
-
-  if (length == 0)
-    return NULL;
-
-  start = (global ?
-	   &pst->global_psymbols[0] :
-	   &pst->static_psymbols[0]);
-
-  if (global)			/* This means we can use a binary search.  */
-    {
-      do_linear_search = 0;
-
-      /* Binary search.  This search is guaranteed to end with center
-	 pointing at the earliest partial symbol whose name might be
-	 correct.  At that point *all* partial symbols with an
-	 appropriate name will be checked against the correct
-	 domain.  */
-
-      bottom = start;
-      top = start + length - 1;
-      real_top = top;
-      while (top > bottom)
-	{
-	  center = bottom + (top - bottom) / 2;
-
-	  gdb_assert (center < top);
-
-	  if (strcmp_iw_ordered ((*center)->ginfo.search_name (),
-				 lookup_name.c_str ()) >= 0)
-	    {
-	      top = center;
-	    }
-	  else
-	    {
-	      bottom = center + 1;
-	    }
-	}
-
-      gdb_assert (top == bottom);
-
-      /* For `case_sensitivity == case_sensitive_off' strcmp_iw_ordered will
-	 search more exactly than what matches SYMBOL_MATCHES_SEARCH_NAME.  */
-      while (top >= start && symbol_matches_search_name (&(*top)->ginfo,
-							 lookup_name))
-	top--;
-
-      /* Fixup to have a symbol which matches SYMBOL_MATCHES_SEARCH_NAME.  */
-      top++;
-
-      while (top <= real_top && symbol_matches_search_name (&(*top)->ginfo,
-							    lookup_name))
-	{
-	  if (search_flags_matches (domain, (*top)->domain))
-	    return *top;
-	  top++;
-	}
-    }
-
-  /* Can't use a binary search or else we found during the binary search that
-     we should also do a linear search.  */
-
-  if (do_linear_search)
-    {
-      for (psym = start; psym < start + length; psym++)
-	{
-	  if (search_flags_matches (domain, (*psym)->domain)
-	      && symbol_matches_search_name (&(*psym)->ginfo, lookup_name))
-	    return *psym;
-	}
-    }
-
-  return NULL;
-}
-
-/* Get the symbol table that corresponds to a partial_symtab.
-   This is fast after the first time you do it.
-   The result will be NULL if the primary symtab has no symbols,
-   which can happen.  Otherwise the result is the primary symtab
-   that contains PST.  */
-
-static struct compunit_symtab *
-psymtab_to_symtab (struct objfile *objfile, struct partial_symtab *pst)
-{
-  /* If it is a shared psymtab, find an unshared psymtab that includes
-     it.  Any such psymtab will do.  */
-  while (pst->user != NULL)
-    pst = pst->user;
-
-  /* If it's been looked up before, return it.  */
-  if (pst->get_compunit_symtab (objfile))
-    return pst->get_compunit_symtab (objfile);
-
-  /* If it has not yet been read in, read it.  */
-  if (!pst->readin_p (objfile))
-    {
-      scoped_restore decrementer = increment_reading_symtab ();
-
-      if (info_verbose)
-	{
-	  gdb_printf (_("Reading in symbols for %s...\n"),
-		      pst->filename);
-	  gdb_flush (gdb_stdout);
-	}
-
-      pst->read_symtab (objfile);
-    }
-
-  return pst->get_compunit_symtab (objfile);
-}
-
-/* Psymtab version of find_last_source_symtab.  See its definition in
-   the definition of quick_symbol_functions in symfile.h.  */
-
-struct symtab *
-psymbol_functions::find_last_source_symtab (struct objfile *ofp)
-{
-  struct partial_symtab *cs_pst = NULL;
-
-  for (partial_symtab *ps : partial_symbols (ofp))
-    {
-      const char *name = ps->filename;
-      int len = strlen (name);
-
-      if (!(len > 2 && (strcmp (&name[len - 2], ".h") == 0
-			|| strcmp (name, "<<C++-namespaces>>") == 0)))
-	cs_pst = ps;
-    }
-
-  if (cs_pst)
-    {
-      if (cs_pst->readin_p (ofp))
-	{
-	  internal_error (_("select_source_symtab: "
-			  "readin pst found and no symtabs."));
-	}
-      else
-	{
-	  struct compunit_symtab *cust = psymtab_to_symtab (ofp, cs_pst);
-
-	  if (cust == NULL)
-	    return NULL;
-	  return cust->primary_filetab ();
-	}
-    }
-  return NULL;
-}
-
-/* Psymtab version of forget_cached_source_info.  See its definition in
-   the definition of quick_symbol_functions in symfile.h.  */
-
-void
-psymbol_functions::forget_cached_source_info (struct objfile *objfile)
-{
-  for (partial_symtab *pst : partial_symbols (objfile))
-    {
-      if (pst->fullname != NULL)
-	{
-	  xfree (pst->fullname);
-	  pst->fullname = NULL;
-	}
-    }
-}
-
-static void
-print_partial_symbols (struct gdbarch *gdbarch, struct objfile *objfile,
-		       const std::vector<const partial_symbol *> &symbols,
-		       const char *what, struct ui_file *outfile)
-{
-  gdb_printf (outfile, "  %s partial symbols:\n", what);
-  for (const partial_symbol *p : symbols)
-    {
-      QUIT;
-      gdb_printf (outfile, "    `%s'", p->ginfo.linkage_name ());
-      if (p->ginfo.demangled_name () != NULL)
-	{
-	  gdb_printf (outfile, "  `%s'",
-		      p->ginfo.demangled_name ());
-	}
-      gdb_puts (", ", outfile);
-      switch (p->domain)
-	{
-	case UNDEF_DOMAIN:
-	  gdb_puts ("undefined domain, ", outfile);
-	  break;
-	case VAR_DOMAIN:
-	  /* This is the usual thing -- don't print it.  */
-	  break;
-	case STRUCT_DOMAIN:
-	  gdb_puts ("struct domain, ", outfile);
-	  break;
-	case MODULE_DOMAIN:
-	  gdb_puts ("module domain, ", outfile);
-	  break;
-	case LABEL_DOMAIN:
-	  gdb_puts ("label domain, ", outfile);
-	  break;
-	case COMMON_BLOCK_DOMAIN:
-	  gdb_puts ("common block domain, ", outfile);
-	  break;
-	case TYPE_DOMAIN:
-	  gdb_puts ("type domain, ", outfile);
-	  break;
-	case FUNCTION_DOMAIN:
-	  gdb_puts ("function domain, ", outfile);
-	  break;
-	default:
-	  gdb_puts ("<invalid domain>, ", outfile);
-	  break;
-	}
-      switch (p->loc_class)
-	{
-	case LOC_UNDEF:
-	  gdb_puts ("undefined", outfile);
-	  break;
-	case LOC_CONST:
-	  gdb_puts ("constant int", outfile);
-	  break;
-	case LOC_STATIC:
-	  gdb_puts ("static", outfile);
-	  break;
-	case LOC_REGISTER:
-	  gdb_puts ("register", outfile);
-	  break;
-	case LOC_ARG:
-	  gdb_puts ("pass by value", outfile);
-	  break;
-	case LOC_REF_ARG:
-	  gdb_puts ("pass by reference", outfile);
-	  break;
-	case LOC_REGPARM_ADDR:
-	  gdb_puts ("register address parameter", outfile);
-	  break;
-	case LOC_LOCAL:
-	  gdb_puts ("stack parameter", outfile);
-	  break;
-	case LOC_TYPEDEF:
-	  gdb_puts ("type", outfile);
-	  break;
-	case LOC_LABEL:
-	  gdb_puts ("label", outfile);
-	  break;
-	case LOC_BLOCK:
-	  gdb_puts ("function", outfile);
-	  break;
-	case LOC_CONST_BYTES:
-	  gdb_puts ("constant bytes", outfile);
-	  break;
-	case LOC_UNRESOLVED:
-	  gdb_puts ("unresolved", outfile);
-	  break;
-	case LOC_OPTIMIZED_OUT:
-	  gdb_puts ("optimized out", outfile);
-	  break;
-	case LOC_COMPUTED:
-	  gdb_puts ("computed at runtime", outfile);
-	  break;
-	default:
-	  gdb_puts ("<invalid location>", outfile);
-	  break;
-	}
-      gdb_puts (", ", outfile);
-      gdb_puts (paddress (gdbarch, CORE_ADDR (p->unrelocated_address ())),
-		outfile);
-      gdb_printf (outfile, "\n");
-    }
-}
-
-static void
-dump_psymtab (struct objfile *objfile, struct partial_symtab *psymtab,
-	      struct ui_file *outfile)
-{
-  struct gdbarch *gdbarch = objfile->arch ();
-  int i;
-
-  if (psymtab->anonymous)
-    {
-      gdb_printf (outfile, "\nAnonymous partial symtab (%s) ",
-		  psymtab->filename);
-    }
-  else
-    {
-      gdb_printf (outfile, "\nPartial symtab for source file %s ",
-		  psymtab->filename);
-    }
-  gdb_printf (outfile, "(object %s)\n\n",
-	      host_address_to_string (psymtab));
-  gdb_printf (outfile, "  Read from object file %s (%s)\n",
-	      objfile_name (objfile),
-	      host_address_to_string (objfile));
-
-  if (psymtab->readin_p (objfile))
-    gdb_printf
-      (outfile,
-       "  Full symtab was read (at %s)\n",
-       host_address_to_string (psymtab->get_compunit_symtab (objfile)));
-
-  gdb_printf (outfile, "  Symbols cover text addresses ");
-  gdb_puts (paddress (gdbarch, psymtab->text_low (objfile)), outfile);
-  gdb_printf (outfile, "-");
-  gdb_puts (paddress (gdbarch, psymtab->text_high (objfile)), outfile);
-  gdb_printf (outfile, "\n");
-  gdb_printf (outfile, "  Depends on %d other partial symtabs.\n",
-	      psymtab->number_of_dependencies);
-  for (i = 0; i < psymtab->number_of_dependencies; i++)
-    gdb_printf (outfile, "    %d %s\n", i,
-		host_address_to_string (psymtab->dependencies[i]));
-  if (psymtab->user != NULL)
-    gdb_printf (outfile, "  Shared partial symtab with user %s\n",
-		host_address_to_string (psymtab->user));
-  if (!psymtab->global_psymbols.empty ())
-    {
-      print_partial_symbols
-	(gdbarch, objfile, psymtab->global_psymbols,
-	 "Global", outfile);
-    }
-  if (!psymtab->static_psymbols.empty ())
-    {
-      print_partial_symbols
-	(gdbarch, objfile, psymtab->static_psymbols,
-	 "Static", outfile);
-    }
-  gdb_printf (outfile, "\n");
-}
-
-/* Count the number of partial symbols in OBJFILE.  */
-
-int
-psymbol_functions::count_psyms ()
-{
-  int count = 0;
-  for (partial_symtab *pst : m_partial_symtabs->range ())
-    {
-      count += pst->global_psymbols.size ();
-      count += pst->static_psymbols.size ();
-    }
-  return count;
-}
-
-/* Psymtab version of print_stats.  See its definition in
-   the definition of quick_symbol_functions in symfile.h.  */
-
-void
-psymbol_functions::print_stats (struct objfile *objfile, bool print_bcache)
-{
-  int i;
-
-  if (!print_bcache)
-    {
-      int n_psyms = count_psyms ();
-      if (n_psyms > 0)
-	gdb_printf (_("  Number of \"partial\" symbols read: %d\n"),
-		    n_psyms);
-
-      i = 0;
-      for (partial_symtab *ps : partial_symbols (objfile))
-	{
-	  if (!ps->readin_p (objfile))
-	    i++;
-	}
-      gdb_printf (_("  Number of psym tables (not yet expanded): %d\n"),
-		  i);
-      gdb_printf (_("  Total memory used for psymbol cache: %d\n"),
-		  m_partial_symtabs->psymbol_cache.memory_used ());
-    }
-  else
-    {
-      gdb_printf (_("Psymbol byte cache statistics:\n"));
-      m_partial_symtabs->psymbol_cache.print_statistics
-	("partial symbol cache");
-    }
-}
-
-/* Psymtab version of dump.  See its definition in
-   the definition of quick_symbol_functions in symfile.h.  */
-
-void
-psymbol_functions::dump (struct objfile *objfile)
-{
-  struct partial_symtab *psymtab;
-
-  if (m_partial_symtabs->psymtabs)
-    {
-      gdb_printf ("Psymtabs:\n");
-      for (psymtab = m_partial_symtabs->psymtabs;
-	   psymtab != NULL;
-	   psymtab = psymtab->next)
-	gdb_printf ("%s at %s\n",
-		    psymtab->filename,
-		    host_address_to_string (psymtab));
-      gdb_printf ("\n\n");
-    }
-}
-
-/* Psymtab version of expand_all_symtabs.  See its definition in
-   the definition of quick_symbol_functions in symfile.h.  */
-
-void
-psymbol_functions::expand_all_symtabs (struct objfile *objfile)
-{
-  for (partial_symtab *psymtab : partial_symbols (objfile))
-    psymtab_to_symtab (objfile, psymtab);
-}
-
-/* Psymtab version of map_symbol_filenames.  See its definition in
-   the definition of quick_symbol_functions in symfile.h.  */
-
-void
-psymbol_functions::map_symbol_filenames (objfile *objfile,
-					 symbol_filename_listener fun,
-					 bool need_fullname)
-{
-  for (partial_symtab *ps : partial_symbols (objfile))
-    {
-      const char *fullname;
-
-      if (ps->readin_p (objfile))
-	continue;
-
-      /* We can skip shared psymtabs here, because any file name will be
-	 attached to the unshared psymtab.  */
-      if (ps->user != NULL)
-	continue;
-
-      /* Anonymous psymtabs don't have a file name.  */
-      if (ps->anonymous)
-	continue;
-
-      QUIT;
-      if (need_fullname)
-	fullname = psymtab_to_fullname (ps);
-      else
-	fullname = NULL;
-      fun (ps->filename, fullname);
-    }
-}
-
-/* Finds the fullname that a partial_symtab represents.
-
-   If this functions finds the fullname, it will save it in ps->fullname
-   and it will also return the value.
-
-   If this function fails to find the file that this partial_symtab represents,
-   NULL will be returned and ps->fullname will be set to NULL.  */
-
-static const char *
-psymtab_to_fullname (struct partial_symtab *ps)
-{
-  gdb_assert (!ps->anonymous);
-
-  /* Use cached copy if we have it.
-     We rely on forget_cached_source_info being called appropriately
-     to handle cases like the file being moved.  */
-  if (ps->fullname == NULL)
-    {
-      gdb::unique_xmalloc_ptr<char> fullname
-	= find_source_or_rewrite (ps->filename, ps->dirname);
-      ps->fullname = fullname.release ();
-    }
-
-  return ps->fullname;
-}
-
-/* A helper for psymbol_functions::search that handles searching
-   included psymtabs.  This returns true if a symbol is found, and
-   false otherwise.  It also updates the 'searched_flag' on the
-   various psymtabs that it searches.  */
-
-static bool
-recursively_search_psymtabs (partial_symtab *ps, objfile *objfile,
-			     block_search_flags search_flags,
-			     domain_search_flags domain,
-			     const lookup_name_info &lookup_name,
-			     search_symtabs_symbol_matcher sym_matcher)
-{
-  int keep_going = 1;
-  enum psymtab_search_status result = PST_SEARCHED_AND_NOT_FOUND;
-  int i;
-
-  if (ps->searched_flag != PST_NOT_SEARCHED)
-    return ps->searched_flag == PST_SEARCHED_AND_FOUND;
-
-  /* Recurse into shared psymtabs first, because they may have already
-     been searched, and this could save some time.  */
-  for (i = 0; i < ps->number_of_dependencies; ++i)
-    {
-      int r;
-
-      /* Skip non-shared dependencies, these are handled elsewhere.  */
-      if (ps->dependencies[i]->user == NULL)
-	continue;
-
-      r = recursively_search_psymtabs (ps->dependencies[i],
-				       objfile, search_flags, domain,
-				       lookup_name, sym_matcher);
-      if (r != 0)
-	{
-	  ps->searched_flag = PST_SEARCHED_AND_FOUND;
-	  return true;
-	}
-    }
-
-  const partial_symbol **gbound = (ps->global_psymbols.data ()
-				   + ps->global_psymbols.size ());
-  const partial_symbol **sbound = (ps->static_psymbols.data ()
-				   + ps->static_psymbols.size ());
-  const partial_symbol **bound = gbound;
-
-  /* Go through all of the symbols stored in a partial
-     symtab in one loop.  */
-  const partial_symbol **psym = ps->global_psymbols.data ();
-
-  if ((search_flags & SEARCH_GLOBAL_BLOCK) == 0)
-    {
-      if (ps->static_psymbols.empty ())
-	keep_going = 0;
-      else
-	{
-	  psym = ps->static_psymbols.data ();
-	  bound = sbound;
-	}
-    }
-
-  while (keep_going)
-    {
-      if (psym >= bound)
-	{
-	  if (bound == gbound && !ps->static_psymbols.empty ()
-	      && (search_flags & SEARCH_STATIC_BLOCK) != 0)
-	    {
-	      psym = ps->static_psymbols.data ();
-	      bound = sbound;
-	    }
-	  else
-	    keep_going = 0;
-	  continue;
-	}
-      else
-	{
-	  QUIT;
-
-	  if (search_flags_matches (domain, (*psym)->domain)
-	      && psymbol_name_matches (*psym, lookup_name)
-	      && (sym_matcher == NULL
-		  || sym_matcher ((*psym)->ginfo.search_name ())))
-	    {
-	      /* Found a match, so notify our caller.  */
-	      result = PST_SEARCHED_AND_FOUND;
-	      keep_going = 0;
-	    }
-	}
-      psym++;
-    }
-
-  ps->searched_flag = result;
-  return result == PST_SEARCHED_AND_FOUND;
-}
-
-/* Psymtab version of search.  See its definition in
-   the definition of quick_symbol_functions in symfile.h.  */
-
-bool
-psymbol_functions::search
-  (struct objfile *objfile,
-   search_symtabs_file_matcher file_matcher,
-   const lookup_name_info *lookup_name,
-   search_symtabs_symbol_matcher symbol_matcher,
-   search_symtabs_expansion_listener listener,
-   block_search_flags search_flags,
-   domain_search_flags domain,
-   search_symtabs_lang_matcher lang_matcher ATTRIBUTE_UNUSED)
-{
-  /* Clear the search flags.  */
-  for (partial_symtab *ps : partial_symbols (objfile))
-    ps->searched_flag = PST_NOT_SEARCHED;
-
-  std::optional<lookup_name_info> psym_lookup_name;
-  if (lookup_name != nullptr)
-    psym_lookup_name = lookup_name->make_ignore_params ();
-
-  /* This invariant is documented in quick-functions.h.  */
-  gdb_assert (lookup_name != nullptr || symbol_matcher == nullptr);
-
-  for (partial_symtab *ps : m_partial_symtabs->range ())
-    {
-      QUIT;
-
-      if (file_matcher)
-	{
-	  bool match;
-
-	  if (ps->anonymous)
-	    continue;
-
-	  match = file_matcher (ps->filename, false);
-	  if (!match)
-	    {
-	      /* Before we invoke realpath, which can get expensive when many
-		 files are involved, do a quick comparison of the basenames.  */
-	      if (basenames_may_differ
-		  || file_matcher (lbasename (ps->filename), true))
-		match = file_matcher (psymtab_to_fullname (ps), false);
-	    }
-	  if (!match)
-	    continue;
-	}
-
-      if (lookup_name == nullptr
-	  || recursively_search_psymtabs (ps, objfile, search_flags,
-					  domain, *psym_lookup_name,
-					  symbol_matcher))
-	{
-	  compunit_symtab *cust = psymtab_to_symtab (objfile, ps);
-
-	  if (cust != nullptr && listener != nullptr)
-	    if (!listener (cust))
-	      return false;
-	}
-    }
-
-  return true;
-}
-
-/* Psymtab version of has_symbols.  See its definition in
-   the definition of quick_symbol_functions in symfile.h.  */
-
-bool
-psymbol_functions::has_symbols (struct objfile *objfile)
-{
-  return m_partial_symtabs->psymtabs != NULL;
-}
-
-/* See quick_symbol_functions::has_unexpanded_symtabs in quick-symbol.h.  */
-
-bool
-psymbol_functions::has_unexpanded_symtabs (struct objfile *objfile)
-{
-  for (partial_symtab *psymtab : partial_symbols (objfile))
-    {
-      /* Is this already expanded?  */
-      if (psymtab->readin_p (objfile))
-	continue;
-
-      /* It has not yet been expanded.  */
-      return true;
-    }
-
-  return false;
-}
-
-\f
-
-/* Partially fill a partial symtab.  It will be completely filled at
-   the end of the symbol list.  */
-
-partial_symtab::partial_symtab (const char *filename,
-				psymtab_storage *partial_symtabs,
-				objfile_per_bfd_storage *objfile_per_bfd,
-				unrelocated_addr textlow)
-  : partial_symtab (filename, partial_symtabs, objfile_per_bfd)
-{
-  set_text_low (textlow);
-  set_text_high (unrelocated_text_low ()); /* default */
-}
-
-/* Perform "finishing up" operations of a partial symtab.  */
-
-void
-partial_symtab::end ()
-{
-  global_psymbols.shrink_to_fit ();
-  static_psymbols.shrink_to_fit ();
-
-  /* Sort the global list; don't sort the static list.  */
-  std::sort (global_psymbols.begin (),
-	     global_psymbols.end (),
-	     [] (const partial_symbol *s1, const partial_symbol *s2)
-    {
-      return strcmp_iw_ordered (s1->ginfo.search_name (),
-				s2->ginfo.search_name ()) < 0;
-    });
-}
-
-/* See psymtab.h.  */
-
-unsigned long
-psymbol_bcache::hash (const void *addr, int length)
-{
-  unsigned long h = 0;
-  struct partial_symbol *psymbol = (struct partial_symbol *) addr;
-  unsigned int lang = psymbol->ginfo.language ();
-  unsigned int domain = psymbol->domain;
-  unsigned int loc_class = psymbol->loc_class;
-
-  h = fast_hash (&psymbol->ginfo.m_value, sizeof (psymbol->ginfo.m_value), h);
-  h = fast_hash (&lang, sizeof (unsigned int), h);
-  h = fast_hash (&domain, sizeof (unsigned int), h);
-  h = fast_hash (&loc_class, sizeof (unsigned int), h);
-  /* Note that psymbol names are interned via compute_and_set_names, so
-     there's no need to hash the contents of the name here.  */
-  h = fast_hash (&psymbol->ginfo.m_name, sizeof (psymbol->ginfo.m_name), h);
-
-  return h;
-}
-
-/* See psymtab.h.  */
-
-int
-psymbol_bcache::compare (const void *addr1, const void *addr2, int length)
-{
-  struct partial_symbol *sym1 = (struct partial_symbol *) addr1;
-  struct partial_symbol *sym2 = (struct partial_symbol *) addr2;
-
-  return (memcmp (&sym1->ginfo.m_value, &sym2->ginfo.m_value,
-		  sizeof (sym1->ginfo.m_value)) == 0
-	  && sym1->ginfo.language () == sym2->ginfo.language ()
-	  && sym1->domain == sym2->domain
-	  && sym1->loc_class == sym2->loc_class
-	  /* Note that psymbol names are interned via
-	     compute_and_set_names, so there's no need to compare the
-	     contents of the name here.  */
-	  && sym1->ginfo.linkage_name () == sym2->ginfo.linkage_name ());
-}
-
-/* See psymtab.h.  */
-
-void
-partial_symtab::add_psymbol (const partial_symbol &psymbol,
-			     psymbol_placement where,
-			     psymtab_storage *partial_symtabs,
-			     struct objfile *objfile)
-{
-  bool added;
-
-  /* Stash the partial symbol away in the cache.  */
-  const partial_symbol *psym = partial_symtabs->psymbol_cache.insert (psymbol,
-								      &added);
-
-  /* Do not duplicate global partial symbols.  */
-  if (where == psymbol_placement::GLOBAL && !added)
-    return;
-
-  /* Save pointer to partial symbol in psymtab, growing symtab if needed.  */
-  std::vector<const partial_symbol *> &list
-    = (where == psymbol_placement::STATIC
-       ? static_psymbols
-       : global_psymbols);
-  list.push_back (psym);
-}
-
-/* See psymtab.h.  */
-
-void
-partial_symtab::add_psymbol (std::string_view name, bool copy_name,
-			     domain_enum domain,
-			     location_class loc_class,
-			     int section,
-			     psymbol_placement where,
-			     unrelocated_addr coreaddr,
-			     enum language language,
-			     psymtab_storage *partial_symtabs,
-			     struct objfile *objfile)
-{
-  struct partial_symbol psymbol;
-  memset (&psymbol, 0, sizeof (psymbol));
-
-  psymbol.set_unrelocated_address (coreaddr);
-  psymbol.ginfo.set_section_index (section);
-  psymbol.domain = domain;
-  psymbol.loc_class = loc_class;
-  psymbol.ginfo.set_language (language, partial_symtabs->obstack ());
-  psymbol.ginfo.compute_and_set_names (name, copy_name, objfile->per_bfd);
-
-  add_psymbol (psymbol, where, partial_symtabs, objfile);
-}
-
-/* See psymtab.h.  */
-
-partial_symtab::partial_symtab (const char *filename_,
-				psymtab_storage *partial_symtabs,
-				objfile_per_bfd_storage *objfile_per_bfd)
-  : searched_flag (PST_NOT_SEARCHED),
-    text_low_valid (0),
-    text_high_valid (0)
-{
-  partial_symtabs->install_psymtab (this);
-
-  filename = objfile_per_bfd->intern (filename_);
-
-  if (symtab_create_debug >= 1)
-    {
-      /* Be a bit clever with debugging messages, and don't print objfile
-	 every time, only when it changes.  */
-      static std::string last_bfd_name;
-      const char *this_bfd_name
-	= bfd_get_filename (objfile_per_bfd->get_bfd ());
-
-      if (last_bfd_name.empty () || last_bfd_name != this_bfd_name)
-	{
-	  last_bfd_name = this_bfd_name;
-
-	  symtab_create_debug_printf ("creating one or more psymtabs for %s",
-				      this_bfd_name);
-	}
-
-      symtab_create_debug_printf ("created psymtab %s for module %s",
-				  host_address_to_string (this), filename);
-    }
-}
-
-/* See psymtab.h.  */
-
-void
-partial_symtab::expand_dependencies (struct objfile *objfile)
-{
-  for (int i = 0; i < number_of_dependencies; ++i)
-    {
-      if (!dependencies[i]->readin_p (objfile)
-	  && dependencies[i]->user == NULL)
-	{
-	  /* Inform about additional files to be read in.  */
-	  if (info_verbose)
-	    {
-	      gdb_puts (" ");
-	      gdb_stdout->wrap_here (0);
-	      gdb_puts ("and ");
-	      gdb_stdout->wrap_here (0);
-	      gdb_printf ("%s...", dependencies[i]->filename);
-	      gdb_flush (gdb_stdout);
-	    }
-	  dependencies[i]->expand_psymtab (objfile);
-	}
-    }
-}
-
-
-void
-psymtab_storage::discard_psymtab (struct partial_symtab *pst)
-{
-  struct partial_symtab **prev_pst;
-
-  /* From dbxread.c:
-     Empty psymtabs happen as a result of header files which don't
-     have any symbols in them.  There can be a lot of them.  But this
-     check is wrong, in that a psymtab with N_SLINE entries but
-     nothing else is not empty, but we don't realize that.  Fixing
-     that without slowing things down might be tricky.  */
-
-  /* First, snip it out of the psymtab chain.  */
-
-  prev_pst = &psymtabs;
-  while ((*prev_pst) != pst)
-    prev_pst = &((*prev_pst)->next);
-  (*prev_pst) = pst->next;
-  delete pst;
-}
-
-\f
-
-static void
-maintenance_print_psymbols (const char *args, int from_tty)
-{
-  struct ui_file *outfile = gdb_stdout;
-  char *address_arg = NULL, *source_arg = NULL, *objfile_arg = NULL;
-  int i, outfile_idx, found;
-  CORE_ADDR pc = 0;
-  struct obj_section *section = NULL;
-
-  dont_repeat ();
-
-  gdb_argv argv (args);
-
-  for (i = 0; argv != NULL && argv[i] != NULL; ++i)
-    {
-      if (strcmp (argv[i], "-pc") == 0)
-	{
-	  if (argv[i + 1] == NULL)
-	    error (_("Missing pc value"));
-	  address_arg = argv[++i];
-	}
-      else if (strcmp (argv[i], "-source") == 0)
-	{
-	  if (argv[i + 1] == NULL)
-	    error (_("Missing source file"));
-	  source_arg = argv[++i];
-	}
-      else if (strcmp (argv[i], "-objfile") == 0)
-	{
-	  if (argv[i + 1] == NULL)
-	    error (_("Missing objfile name"));
-	  objfile_arg = argv[++i];
-	}
-      else if (strcmp (argv[i], "--") == 0)
-	{
-	  /* End of options.  */
-	  ++i;
-	  break;
-	}
-      else if (argv[i][0] == '-')
-	{
-	  /* Future proofing: Don't allow OUTFILE to begin with "-".  */
-	  error (_("Unknown option: %s"), argv[i]);
-	}
-      else
-	break;
-    }
-  outfile_idx = i;
-
-  if (address_arg != NULL && source_arg != NULL)
-    error (_("Must specify at most one of -pc and -source"));
-
-  stdio_file arg_outfile;
-
-  if (argv != NULL && argv[outfile_idx] != NULL)
-    {
-      if (argv[outfile_idx + 1] != NULL)
-	error (_("Junk at end of command"));
-      gdb::unique_xmalloc_ptr<char> outfile_name
-	= gdb_rl_tilde_expand (argv[outfile_idx]);
-      if (!arg_outfile.open (outfile_name.get (), FOPEN_WT))
-	perror_with_name (outfile_name.get ());
-      outfile = &arg_outfile;
-    }
-
-  if (address_arg != NULL)
-    {
-      pc = parse_and_eval_address (address_arg);
-      /* If we fail to find a section, that's ok, try the lookup anyway.  */
-      section = find_pc_section (pc);
-    }
-
-  found = 0;
-  for (objfile &objfile : current_program_space->objfiles ())
-    {
-      int printed_objfile_header = 0;
-      int print_for_objfile = 1;
-
-      QUIT;
-      if (objfile_arg != NULL)
-	print_for_objfile
-	  = compare_filenames_for_search (objfile_name (&objfile),
-					  objfile_arg);
-      if (!print_for_objfile)
-	continue;
-
-      for (const auto &iter : objfile.qf)
-	{
-	  psymbol_functions *psf
-	    = dynamic_cast<psymbol_functions *> (iter.get ());
-	  if (psf == nullptr)
-	    continue;
-
-	  if (address_arg != NULL)
-	    {
-	      bound_minimal_symbol msymbol;
-
-	      /* We don't assume each pc has a unique objfile (this is for
-		 debugging).  */
-	      struct partial_symtab *ps
-		= psf->find_pc_sect_psymtab (&objfile, pc, section, msymbol);
-	      if (ps != NULL)
-		{
-		  if (!printed_objfile_header)
-		    {
-		      outfile->printf ("\nPartial symtabs for objfile %s\n",
-				       objfile_name (&objfile));
-		      printed_objfile_header = 1;
-		    }
-		  dump_psymtab (&objfile, ps, outfile);
-		  found = 1;
-		}
-	    }
-	  else
-	    {
-	      for (partial_symtab *ps : psf->partial_symbols (&objfile))
-		{
-		  int print_for_source = 0;
-
-		  QUIT;
-		  if (source_arg != NULL)
-		    {
-		      print_for_source
-			= compare_filenames_for_search (ps->filename, source_arg);
-		      found = 1;
-		    }
-		  if (source_arg == NULL
-		      || print_for_source)
-		    {
-		      if (!printed_objfile_header)
-			{
-			  outfile->printf ("\nPartial symtabs for objfile %s\n",
-					   objfile_name (&objfile));
-			  printed_objfile_header = 1;
-			}
-		      dump_psymtab (&objfile, ps, outfile);
-		    }
-		}
-	    }
-	}
-    }
-
-  if (!found)
-    {
-      if (address_arg != NULL)
-	error (_("No partial symtab for address: %s"), address_arg);
-      if (source_arg != NULL)
-	error (_("No partial symtab for source file: %s"), source_arg);
-    }
-}
-
-/* List all the partial symbol tables whose names match REGEXP (optional).  */
-
-static void
-maintenance_info_psymtabs (const char *regexp, int from_tty)
-{
-  if (regexp)
-    re_comp (regexp);
-
-  for (struct program_space *pspace : program_spaces)
-    for (objfile &objfile : pspace->objfiles ())
-      {
-	struct gdbarch *gdbarch = objfile.arch ();
-
-	/* We don't want to print anything for this objfile until we
-	   actually find a symtab whose name matches.  */
-	int printed_objfile_start = 0;
-
-	for (const auto &iter : objfile.qf)
-	  {
-	    psymbol_functions *psf
-	      = dynamic_cast<psymbol_functions *> (iter.get ());
-	    if (psf == nullptr)
-	      continue;
-	    for (partial_symtab *psymtab : psf->partial_symbols (&objfile))
-	      {
-		QUIT;
-
-		if (! regexp
-		    || re_exec (psymtab->filename))
-		  {
-		    if (! printed_objfile_start)
-		      {
-			gdb_printf ("{ objfile %s ", objfile_name (&objfile));
-			gdb_stdout->wrap_here (2);
-			gdb_printf ("((struct objfile *) %s)\n",
-				    host_address_to_string (&objfile));
-			printed_objfile_start = 1;
-		      }
-
-		    gdb_printf ("  { psymtab %s ", psymtab->filename);
-		    gdb_stdout->wrap_here (4);
-		    gdb_printf ("((struct partial_symtab *) %s)\n",
-				host_address_to_string (psymtab));
-
-		    gdb_printf ("    readin %s\n",
-				psymtab->readin_p (&objfile) ? "yes" : "no");
-		    gdb_printf ("    fullname %s\n",
-				psymtab->fullname
-				? psymtab->fullname : "(null)");
-		    gdb_printf ("    text addresses ");
-		    gdb_puts (paddress (gdbarch,
-					psymtab->text_low (&objfile)));
-		    gdb_printf (" -- ");
-		    gdb_puts (paddress (gdbarch,
-					psymtab->text_high (&objfile)));
-		    gdb_printf ("\n");
-		    gdb_printf ("    globals ");
-		    if (!psymtab->global_psymbols.empty ())
-		      gdb_printf
-			("(* (struct partial_symbol **) %s @ %d)\n",
-			 host_address_to_string (psymtab->global_psymbols.data ()),
-			 (int) psymtab->global_psymbols.size ());
-		    else
-		      gdb_printf ("(none)\n");
-		    gdb_printf ("    statics ");
-		    if (!psymtab->static_psymbols.empty ())
-		      gdb_printf
-			("(* (struct partial_symbol **) %s @ %d)\n",
-			 host_address_to_string (psymtab->static_psymbols.data ()),
-			 (int) psymtab->static_psymbols.size ());
-		    else
-		      gdb_printf ("(none)\n");
-		    if (psymtab->user)
-		      gdb_printf ("    user %s "
-				  "((struct partial_symtab *) %s)\n",
-				  psymtab->user->filename,
-				  host_address_to_string (psymtab->user));
-		    gdb_printf ("    dependencies ");
-		    if (psymtab->number_of_dependencies)
-		      {
-			int i;
-
-			gdb_printf ("{\n");
-			for (i = 0; i < psymtab->number_of_dependencies; i++)
-			  {
-			    struct partial_symtab *dep = psymtab->dependencies[i];
-
-			    /* Note the string concatenation there --- no
-			       comma.  */
-			    gdb_printf ("      psymtab %s "
-					"((struct partial_symtab *) %s)\n",
-					dep->filename,
-					host_address_to_string (dep));
-			  }
-			gdb_printf ("    }\n");
-		      }
-		    else
-		      gdb_printf ("(none)\n");
-		    gdb_printf ("  }\n");
-		  }
-	      }
-	  }
-
-	if (printed_objfile_start)
-	  gdb_printf ("}\n");
-      }
-}
-
-/* Check consistency of currently expanded psymtabs vs symtabs.  */
-
-static void
-maintenance_check_psymtabs (const char *ignore, int from_tty)
-{
-  struct symbol *sym;
-  struct compunit_symtab *cust = NULL;
-  const struct blockvector *bv;
-  const struct block *b;
-
-  for (objfile &objfile : current_program_space->objfiles ())
-    {
-      for (const auto &iter : objfile.qf)
-	{
-	  psymbol_functions *psf
-	    = dynamic_cast<psymbol_functions *> (iter.get ());
-	  if (psf == nullptr)
-	    continue;
-
-	  for (partial_symtab *ps : psf->partial_symbols (&objfile))
-	    {
-	      struct gdbarch *gdbarch = objfile.arch ();
-
-	      /* We don't call psymtab_to_symtab here because that may cause symtab
-		 expansion.  When debugging a problem it helps if checkers leave
-		 things unchanged.  */
-	      cust = ps->get_compunit_symtab (&objfile);
-
-	      /* First do some checks that don't require the associated symtab.  */
-	      if (ps->text_high (&objfile) < ps->text_low (&objfile))
-		{
-		  gdb_printf ("Psymtab ");
-		  gdb_puts (ps->filename);
-		  gdb_printf (" covers bad range ");
-		  gdb_puts (paddress (gdbarch, ps->text_low (&objfile)));
-		  gdb_printf (" - ");
-		  gdb_puts (paddress (gdbarch, ps->text_high (&objfile)));
-		  gdb_printf ("\n");
-		  continue;
-		}
-
-	      /* Now do checks requiring the associated symtab.  */
-	      if (cust == NULL)
-		continue;
-	      bv = cust->blockvector ();
-	      b = bv->static_block ();
-	      for (const partial_symbol *psym : ps->static_psymbols)
-		{
-		  /* Skip symbols for inlined functions without address.  These may
-		     or may not have a match in the full symtab.  */
-		  if (psym->loc_class == LOC_BLOCK
-		      && psym->ginfo.value_address () == 0)
-		    continue;
-
-		  lookup_name_info lookup_name
-		    (psym->ginfo.search_name (), symbol_name_match_type::SEARCH_NAME);
-		  sym = block_lookup_symbol (b, lookup_name,
-					     to_search_flags (psym->domain));
-		  if (!sym)
-		    {
-		      gdb_printf ("Static symbol `");
-		      gdb_puts (psym->ginfo.linkage_name ());
-		      gdb_printf ("' only found in ");
-		      gdb_puts (ps->filename);
-		      gdb_printf (" psymtab\n");
-		    }
-		}
-	      b = bv->global_block ();
-	      for (const partial_symbol *psym : ps->global_psymbols)
-		{
-		  lookup_name_info lookup_name
-		    (psym->ginfo.search_name (), symbol_name_match_type::SEARCH_NAME);
-		  sym = block_lookup_symbol (b, lookup_name,
-					     to_search_flags (psym->domain));
-		  if (!sym)
-		    {
-		      gdb_printf ("Global symbol `");
-		      gdb_puts (psym->ginfo.linkage_name ());
-		      gdb_printf ("' only found in ");
-		      gdb_puts (ps->filename);
-		      gdb_printf (" psymtab\n");
-		    }
-		}
-	      if (ps->unrelocated_text_high () != unrelocated_addr (0)
-		  && (ps->text_low (&objfile) < b->start ()
-		      || ps->text_high (&objfile) > b->end ()))
-		{
-		  gdb_printf ("Psymtab ");
-		  gdb_puts (ps->filename);
-		  gdb_printf (" covers ");
-		  gdb_puts (paddress (gdbarch, ps->text_low (&objfile)));
-		  gdb_printf (" - ");
-		  gdb_puts (paddress (gdbarch, ps->text_high (&objfile)));
-		  gdb_printf (" but symtab covers only ");
-		  gdb_puts (paddress (gdbarch, b->start ()));
-		  gdb_printf (" - ");
-		  gdb_puts (paddress (gdbarch, b->end ()));
-		  gdb_printf ("\n");
-		}
-	    }
-	}
-    }
-}
-
-INIT_GDB_FILE (psymtab)
-{
-  add_cmd ("psymbols", class_maintenance, maintenance_print_psymbols, _("\
-Print dump of current partial symbol definitions.\n\
-Usage: mt print psymbols [-objfile OBJFILE] [-pc ADDRESS] [--] [OUTFILE]\n\
-       mt print psymbols [-objfile OBJFILE] [-source SOURCE] [--] [OUTFILE]\n\
-Entries in the partial symbol table are dumped to file OUTFILE,\n\
-or the terminal if OUTFILE is unspecified.\n\
-If ADDRESS is provided, dump only the symbols for the file\n\
-with code at that address.\n\
-If SOURCE is provided, dump only that file's symbols.\n\
-If OBJFILE is provided, dump only that object file's symbols."),
-	   &maintenanceprintlist);
-
-  add_cmd ("psymtabs", class_maintenance, maintenance_info_psymtabs, _("\
-List the partial symbol tables for all object files.\n\
-This does not include information about individual partial symbols,\n\
-just the symbol table structures themselves."),
-	   &maintenanceinfolist);
-
-  add_cmd ("psymtabs", class_maintenance, maintenance_check_psymtabs,
-	   _("\
-Check consistency of currently expanded psymtabs versus symtabs."),
-	   &maintenancechecklist);
-}
diff --git a/gdb/psymtab.h b/gdb/psymtab.h
deleted file mode 100644
index be4ed4262667..000000000000
--- a/gdb/psymtab.h
+++ /dev/null
@@ -1,691 +0,0 @@
-/* Public partial symbol table definitions.
-
-   Copyright (C) 2009-2026 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/>.  */
-
-#ifndef GDB_PSYMTAB_H
-#define GDB_PSYMTAB_H
-
-#include "objfiles.h"
-#include <string_view>
-#include "gdbsupport/gdb_obstack.h"
-#include "symfile.h"
-#include "gdbsupport/next-iterator.h"
-#include "bcache.h"
-
-/* Specialization of bcache to store partial symbols.  */
-
-struct psymbol_bcache : public gdb::bcache
-{
-  /* Calculate a hash code for the given partial symbol.  The hash is
-     calculated using the symbol's value, language, domain, class
-     and name.  These are the values which are set by
-     add_psymbol_to_bcache.  */
-  unsigned long hash (const void *addr, int length) override;
-
-  /* Returns true if the symbol LEFT equals the symbol RIGHT.
-     For the comparison this function uses a symbols value,
-     language, domain, class and name.  */
-  int compare (const void *left, const void *right, int length) override;
-};
-
-/* An instance of this class manages the partial symbol tables and
-   partial symbols for a given objfile.
-
-   The core psymtab functions -- those in psymtab.c -- arrange for
-   nearly all psymtab- and psymbol-related allocations to happen
-   either in the psymtab_storage object (either on its obstack or in
-   other memory managed by this class), or on the per-BFD object.  The
-   only link from the psymtab storage object back to the objfile (or
-   objfile_obstack) that is made by the core psymtab code is the
-   compunit_symtab member in the standard_psymtab -- and a given
-   symbol reader can avoid this by implementing its own subclasses of
-   partial_symtab.
-
-   However, it is up to each symbol reader to maintain this invariant
-   in other ways, if it wants to reuse psymtabs across multiple
-   objfiles.  The main issue here is ensuring that read_symtab_private
-   does not point into objfile_obstack.  */
-
-class psymtab_storage
-{
-public:
-  psymtab_storage () = default;
-  ~psymtab_storage ();
-
-  DISABLE_COPY_AND_ASSIGN (psymtab_storage);
-
-  /* Discard all partial symbol tables starting with "psymtabs" and
-     proceeding until "to" has been discarded.  */
-
-  void discard_psymtabs_to (struct partial_symtab *to)
-  {
-    while (psymtabs != to)
-      discard_psymtab (psymtabs);
-  }
-
-  /* Discard the partial symbol table.  */
-
-  void discard_psymtab (struct partial_symtab *pst);
-
-  /* Return the obstack that is used for storage by this object.  */
-
-  struct obstack *obstack ()
-  {
-    if (!m_obstack.has_value ())
-      m_obstack.emplace ();
-    return &*m_obstack;
-  }
-
-  /* Allocate storage for the "dependencies" field of a psymtab.
-     NUMBER says how many dependencies there are.  */
-
-  struct partial_symtab **allocate_dependencies (int number)
-  {
-    return OBSTACK_CALLOC (obstack (), number, struct partial_symtab *);
-  }
-
-  /* Install a psymtab on the psymtab list.  This transfers ownership
-     of PST to this object.  */
-
-  void install_psymtab (partial_symtab *pst);
-
-  using partial_symtab_range = next_range<partial_symtab>;
-
-  /* A range adapter that makes it possible to iterate over all
-     psymtabs in one objfile.  */
-
-  partial_symtab_range range ()
-  {
-    next_iterator<partial_symtab> begin (psymtabs);
-
-    return partial_symtab_range (std::move (begin));
-  }
-
-
-  /* Each objfile points to a linked list of partial symtabs derived from
-     this file, one partial symtab structure for each compilation unit
-     (source file).  */
-
-  struct partial_symtab *psymtabs = nullptr;
-
-  /* A byte cache where we can stash arbitrary "chunks" of bytes that
-     will not change.  */
-
-  psymbol_bcache psymbol_cache;
-
-private:
-
-  /* The obstack where allocations are made.  This is lazily allocated
-     so that we don't waste memory when there are no psymtabs.  */
-
-  std::optional<auto_obstack> m_obstack;
-};
-
-/* A partial_symbol records the name, domain, and address class of
-   symbols whose types we have not parsed yet.  For functions, it also
-   contains their memory address, so we can find them from a PC value.
-   Each partial_symbol sits in a partial_symtab, all of which are chained
-   on a  partial symtab list and which points to the corresponding
-   normal symtab once the partial_symtab has been referenced.  */
-
-/* This structure is space critical.  See space comments at the top of
-   symtab.h.  */
-
-struct partial_symbol
-{
-  /* Return the section for this partial symbol, or nullptr if no
-     section has been set.  */
-  struct obj_section *obj_section (struct objfile *objfile) const
-  {
-    return ginfo.obj_section (objfile);
-  }
-
-  /* Return the unrelocated address of this partial symbol.  */
-  unrelocated_addr unrelocated_address () const
-  {
-    return ginfo.unrelocated_address ();
-  }
-
-  /* Return the address of this partial symbol, relocated according to
-     the offsets provided in OBJFILE.  */
-  CORE_ADDR address (const struct objfile *objfile) const
-  {
-    return (CORE_ADDR (ginfo.unrelocated_address ())
-	    + objfile->section_offsets[ginfo.section_index ()]);
-  }
-
-  /* Set the address of this partial symbol.  The address must be
-     unrelocated.  */
-  void set_unrelocated_address (unrelocated_addr addr)
-  {
-    ginfo.set_unrelocated_address (addr);
-  }
-
-  /* Note that partial_symbol does not derive from general_symbol_info
-     due to the bcache.  See add_psymbol_to_bcache.  */
-
-  struct general_symbol_info ginfo;
-
-  /* Name space code.  */
-
-  ENUM_BITFIELD(domain_enum) domain : SYMBOL_DOMAIN_BITS;
-
-  /* Address class (for info_symbols).  Note that we don't allow
-     synthetic "loc_class" values here at present, simply because there's
-     no need.  */
-
-  ENUM_BITFIELD(location_class) loc_class : SYMBOL_LOC_CLASS_BITS;
-};
-
-/* A convenience enum to give names to some constants used when
-   searching psymtabs.  This is internal to psymtab and should not be
-   used elsewhere.  */
-
-enum psymtab_search_status
-  {
-    PST_NOT_SEARCHED,
-    PST_SEARCHED_AND_FOUND,
-    PST_SEARCHED_AND_NOT_FOUND
-  };
-
-/* Specify whether a partial psymbol should be allocated on the global
-   list or the static list.  */
-
-enum class psymbol_placement
-{
-  STATIC,
-  GLOBAL
-};
-
-/* 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.  */
-
-struct partial_symtab
-{
-  /* Allocate a new partial symbol table.
-
-     FILENAME (which must be non-NULL) is the filename of this partial
-     symbol table; it is copied into the appropriate storage.  The
-     partial symtab will also be installed using
-     psymtab_storage::install.  */
-
-  partial_symtab (const char *filename,
-		  psymtab_storage *partial_symtabs,
-		  objfile_per_bfd_storage *objfile_per_bfd)
-    ATTRIBUTE_NONNULL (2) ATTRIBUTE_NONNULL (3);
-
-  /* Like the above, but also sets the initial text low and text high
-     from the ADDR argument, and sets the global- and
-     static-offsets.  */
-
-  partial_symtab (const char *filename,
-		  psymtab_storage *partial_symtabs,
-		  objfile_per_bfd_storage *objfile_per_bfd,
-		  unrelocated_addr addr)
-    ATTRIBUTE_NONNULL (2) ATTRIBUTE_NONNULL (3);
-
-  virtual ~partial_symtab ()
-  {
-  }
-
-  /* Psymtab expansion is done in two steps:
-     - a call to read_symtab
-     - while that call is in progress, calls to expand_psymtab can be made,
-       both for this psymtab, and its dependencies.
-     This makes a distinction between a toplevel psymtab (for which both
-     read_symtab and expand_psymtab will be called) and a non-toplevel
-     psymtab (for which only expand_psymtab will be called). The
-     distinction can be used f.i. to do things before and after all
-     dependencies of a top-level psymtab have been expanded.
-
-     Read the full symbol table corresponding to this partial symbol
-     table.  Typically calls expand_psymtab.  */
-  virtual void read_symtab (struct objfile *) = 0;
-
-  /* Expand the full symbol table for this partial symbol table.  Typically
-     calls expand_dependencies.  */
-  virtual void expand_psymtab (struct objfile *) = 0;
-
-  /* Ensure that all the dependencies are read in.  Calls
-     expand_psymtab for each non-shared dependency.  */
-  void expand_dependencies (struct objfile *);
-
-  /* Return true if the symtab corresponding to this psymtab has been
-     read in in the context of this objfile.  */
-  virtual bool readin_p (struct objfile *) const = 0;
-
-  /* Return a pointer to the compunit allocated for this source file
-     in the context of this objfile.
-
-     Return nullptr if the compunit was not read in or if there was no
-     symtab.  */
-  virtual struct compunit_symtab *get_compunit_symtab
-    (struct objfile *) const = 0;
-
-  /* Return the unrelocated low text address of this
-     partial_symtab.  */
-  unrelocated_addr unrelocated_text_low () const
-  {
-    return m_text_low;
-  }
-
-  /* Return the unrelocated_addr high text address of this
-     partial_symtab.  */
-  unrelocated_addr unrelocated_text_high () const
-  {
-    return m_text_high;
-  }
-
-  /* Return the relocated low text address of this partial_symtab.  */
-  CORE_ADDR text_low (struct objfile *objfile) const
-  {
-    return CORE_ADDR (m_text_low) + objfile->text_section_offset ();
-  }
-
-  /* Return the relocated high text address of this partial_symtab.  */
-  CORE_ADDR text_high (struct objfile *objfile) const
-  {
-    return CORE_ADDR (m_text_high) + objfile->text_section_offset ();
-  }
-
-  /* Set the low text address of this partial_symtab.  */
-  void set_text_low (unrelocated_addr addr)
-  {
-    m_text_low = addr;
-    text_low_valid = 1;
-  }
-
-  /* Set the high text address of this partial_symtab.  */
-  void set_text_high (unrelocated_addr addr)
-  {
-    m_text_high = addr;
-    text_high_valid = 1;
-  }
-
-  /* Return true if this symtab is empty -- meaning that it contains
-     no symbols.  It may still have dependencies.  */
-  bool empty () const
-  {
-    return global_psymbols.empty () && static_psymbols.empty ();
-  }
-
-  /* Add a symbol to this partial symbol table of OBJFILE.
-
-     If COPY_NAME is true, make a copy of NAME, otherwise use the passed
-     reference.
-
-     LOC_CLASS is the type of symbol.
-
-     SECTION is the index of the section of OBJFILE in which the symbol is found.
-
-     WHERE determines whether the symbol goes in the list of static or global
-     partial symbols.
-
-     COREADDR is the address of the symbol.  For partial symbols that don't have
-     an address, zero is passed.
-
-     LANGUAGE is the language from which the symbol originates.  This will
-     influence, amongst other things, how the symbol name is demangled. */
-
-  void add_psymbol (std::string_view name,
-		    bool copy_name, domain_enum domain,
-		    location_class loc_class,
-		    int section,
-		    psymbol_placement where,
-		    unrelocated_addr coreaddr,
-		    enum language language,
-		    psymtab_storage *partial_symtabs,
-		    struct objfile *objfile);
-
-  /* Add a symbol to this partial symbol table of OBJFILE.  The psymbol
-     must be fully constructed, and the names must be set and intern'd
-     as appropriate.  */
-
-  void add_psymbol (const partial_symbol &psym,
-		    psymbol_placement where,
-		    psymtab_storage *partial_symtabs,
-		    struct objfile *objfile);
-
-
-  /* Indicate that this partial symtab is complete.  */
-
-  void end ();
-
-  /* Chain of all existing partial symtabs.  */
-
-  struct partial_symtab *next = nullptr;
-
-  /* Name of the source file which this partial_symtab defines,
-     or if the psymtab is anonymous then a descriptive name for
-     debugging purposes, or "".  It must not be NULL.  */
-
-  const char *filename = nullptr;
-
-  /* Full path of the source file.  NULL if not known.  */
-
-  char *fullname = nullptr;
-
-  /* Directory in which it was compiled, or NULL if we don't know.  */
-
-  const char *dirname = nullptr;
-
-  /* Range of text addresses covered by this file; texthigh is the
-     beginning of the next section.  Do not refer directly to these
-     fields.  Instead, use the accessors.  The validity of these
-     fields is determined by the text_low_valid and text_high_valid
-     fields; these are located later in this structure for better
-     packing.  */
-
-  unrelocated_addr m_text_low {};
-  unrelocated_addr m_text_high {};
-
-  /* If NULL, this is an ordinary partial symbol table.
-
-     If non-NULL, this holds a single includer of this partial symbol
-     table, and this partial symbol table is a shared one.
-
-     A shared psymtab is one that is referenced by multiple other
-     psymtabs, and which conceptually has its contents directly
-     included in those.
-
-     Shared psymtabs have special semantics.  When a search finds a
-     symbol in a shared table, we instead return one of the non-shared
-     tables that include this one.
-
-     A shared psymtabs can be referred to by other shared ones.
-
-     The psymtabs that refer to a shared psymtab will list the shared
-     psymtab in their 'dependencies' array.
-
-     In DWARF terms, a shared psymtab is a DW_TAG_partial_unit; but
-     of course using a name based on that would be too confusing, so
-     "shared" was chosen instead.
-
-     Only a single user is needed because, when expanding a shared
-     psymtab, we only need to expand its "canonical" non-shared user.
-     The choice of which one should be canonical is left to the
-     debuginfo reader; it can be arbitrary.  */
-
-  struct partial_symtab *user = nullptr;
-
-  /* Array of pointers to all of the partial_symtab's which this one
-     depends on.  Since this array can only be set to previous or
-     the current (?) psymtab, this dependency tree is guaranteed not
-     to have any loops.  "depends on" means that symbols must be read
-     for the dependencies before being read for this psymtab; this is
-     for type references in stabs, where if foo.c includes foo.h, declarations
-     in foo.h may use type numbers defined in foo.c.  For other debugging
-     formats there may be no need to use dependencies.  */
-
-  struct partial_symtab **dependencies = nullptr;
-
-  int number_of_dependencies = 0;
-
-  /* Global symbol list.  This list will be sorted after readin to
-     improve access.  Binary search will be the usual method of
-     finding a symbol within it.  */
-
-  std::vector<const partial_symbol *> global_psymbols;
-
-  /* Static symbol list.  This list will *not* be sorted after readin;
-     to find a symbol in it, exhaustive search must be used.  This is
-     reasonable because searches through this list will eventually
-     lead to either the read in of a files symbols for real (assumed
-     to take a *lot* of time; check) or an error (and we don't care
-     how long errors take).  */
-
-  std::vector<const partial_symbol *> static_psymbols;
-
-  /* True if the name of this partial symtab is not a source file name.  */
-
-  bool anonymous = false;
-
-  /* A flag that is temporarily used when searching psymtabs.  */
-
-  ENUM_BITFIELD (psymtab_search_status) searched_flag : 2;
-
-  /* Validity of the m_text_low and m_text_high fields.  */
-
-  unsigned int text_low_valid : 1;
-  unsigned int text_high_valid : 1;
-};
-
-/* A partial symtab that tracks the "readin" and "compunit_symtab"
-   information in the ordinary way -- by storing it directly in this
-   object.  */
-struct standard_psymtab : public partial_symtab
-{
-  standard_psymtab (const char *filename,
-		    psymtab_storage *partial_symtabs,
-		    objfile_per_bfd_storage *objfile_per_bfd)
-    : partial_symtab (filename, partial_symtabs, objfile_per_bfd)
-  {
-  }
-
-  standard_psymtab (const char *filename,
-		    psymtab_storage *partial_symtabs,
-		    objfile_per_bfd_storage *objfile_per_bfd,
-		    unrelocated_addr addr)
-    : partial_symtab (filename, partial_symtabs, objfile_per_bfd, addr)
-  {
-  }
-
-  bool readin_p (struct objfile *) const override
-  {
-    return readin;
-  }
-
-  struct compunit_symtab *get_compunit_symtab (struct objfile *) const override
-  {
-    return compunit_symtab;
-  }
-
-  /* True if the symtab corresponding to this psymtab has been
-     readin.  */
-
-  bool readin = false;
-
-  /* Pointer to compunit eventually allocated for this source file, 0 if
-     !readin or if we haven't looked for the symtab after it was readin.  */
-
-  struct compunit_symtab *compunit_symtab = nullptr;
-};
-
-/* A partial_symtab that works in the historical db way.  This should
-   not be used in new code, but exists to transition the somewhat
-   unmaintained "legacy" debug formats.  */
-
-struct legacy_psymtab : public standard_psymtab
-{
-  legacy_psymtab (const char *filename,
-		  psymtab_storage *partial_symtabs,
-		  objfile_per_bfd_storage *objfile_per_bfd)
-    : standard_psymtab (filename, partial_symtabs, objfile_per_bfd)
-  {
-  }
-
-  legacy_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 *objf) override
-  {
-    if (legacy_read_symtab)
-      (*legacy_read_symtab) (this, objf);
-  }
-
-  void expand_psymtab (struct objfile *objf) override
-  {
-    (*legacy_expand_psymtab) (this, objf);
-  }
-
-  /* Pointer to function which will read in the symtab corresponding to
-     this psymtab.  */
-
-  void (*legacy_read_symtab) (legacy_psymtab *, struct objfile *) = nullptr;
-
-  /* Pointer to function which will actually expand this psymtab into
-     a full symtab.  */
-
-  void (*legacy_expand_psymtab) (legacy_psymtab *, struct objfile *) = nullptr;
-
-  /* Information that lets read_symtab() locate the part of the symbol table
-     that this psymtab corresponds to.  This information is private to the
-     format-dependent symbol reading routines.  For further detail examine
-     the various symbol reading modules.  */
-
-  void *read_symtab_private = nullptr;
-};
-
-/* Used when recording partial symbol tables.  On destruction,
-   discards any partial symbol tables that have been built.  However,
-   the tables can be kept by calling the "keep" method.  */
-class psymtab_discarder
-{
- public:
-
-  psymtab_discarder (psymtab_storage *partial_symtabs)
-    : m_partial_symtabs (partial_symtabs),
-      m_psymtab (partial_symtabs->psymtabs)
-  {
-  }
-
-  ~psymtab_discarder ()
-  {
-    if (m_partial_symtabs != nullptr)
-      m_partial_symtabs->discard_psymtabs_to (m_psymtab);
-  }
-
-  /* Keep any partial symbol tables that were built.  */
-  void keep ()
-  {
-    m_partial_symtabs = nullptr;
-  }
-
- private:
-
-  /* The partial symbol storage object.  */
-  psymtab_storage *m_partial_symtabs;
-  /* How far back to free.  */
-  struct partial_symtab *m_psymtab;
-};
-
-/* An implementation of quick_symbol_functions, specialized for
-   partial symbols.  */
-struct psymbol_functions : public quick_symbol_functions
-{
-  explicit psymbol_functions (const std::shared_ptr<psymtab_storage> &storage)
-    : m_partial_symtabs (storage)
-  {
-  }
-
-  psymbol_functions ()
-    : m_partial_symtabs (new psymtab_storage)
-  {
-  }
-
-  bool has_symbols (struct objfile *objfile) override;
-
-  bool has_unexpanded_symtabs (struct objfile *objfile) override;
-
-  struct symtab *find_last_source_symtab (struct objfile *objfile) override;
-
-  void forget_cached_source_info (struct objfile *objfile) override;
-
-  enum language lookup_global_symbol_language (struct objfile *objfile,
-					       const char *name,
-					       domain_search_flags domain,
-					       bool *symbol_found_p) override;
-
-  void print_stats (struct objfile *objfile, bool print_bcache) override;
-
-  void dump (struct objfile *objfile) override;
-
-  void expand_all_symtabs (struct objfile *objfile) override;
-
-  bool search
-    (struct objfile *objfile,
-     search_symtabs_file_matcher file_matcher,
-     const lookup_name_info *lookup_name,
-     search_symtabs_symbol_matcher symbol_matcher,
-     search_symtabs_expansion_listener listener,
-     block_search_flags search_flags,
-     domain_search_flags kind,
-     search_symtabs_lang_matcher lang_matcher) override;
-
-  struct compunit_symtab *find_pc_sect_compunit_symtab
-    (struct objfile *objfile, bound_minimal_symbol msymbol, CORE_ADDR pc,
-     struct obj_section *section, int warn_if_readin) override;
-
-  struct symbol *find_symbol_by_address
-    (struct objfile *objfile, CORE_ADDR address) override
-  {
-    return nullptr;
-  }
-
-  void map_symbol_filenames (objfile *objfile, symbol_filename_listener fun,
-			     bool need_fullname) override;
-
-  /* Return a range adapter for the psymtabs.  */
-  psymtab_storage::partial_symtab_range partial_symbols
-       (struct objfile *objfile);
-
-  /* Return the partial symbol storage associated with this
-     object.  */
-  const std::shared_ptr<psymtab_storage> &get_partial_symtabs () const
-  {
-    return m_partial_symtabs;
-  }
-
-  /* Replace the partial symbol table storage in this object with
-     SYMS.  */
-  void set_partial_symtabs (const std::shared_ptr<psymtab_storage> &syms)
-  {
-    m_partial_symtabs = syms;
-  }
-
-  /* Find which partial symtab contains PC and SECTION.  Return NULL if
-     none.  We return the psymtab that contains a symbol whose address
-     exactly matches PC, or, if we cannot find an exact match, the
-     psymtab that contains a symbol whose address is closest to PC.  */
-
-  struct partial_symtab *find_pc_sect_psymtab (struct objfile *objfile,
-					       CORE_ADDR pc,
-					       struct obj_section *section,
-					       bound_minimal_symbol msymbol);
-
-private:
-
-  /* Count the number of partial symbols in *THIS.  */
-  int count_psyms ();
-
-  /* Storage for the partial symbols.  */
-  std::shared_ptr<psymtab_storage> m_partial_symtabs;
-};
-
-#endif /* GDB_PSYMTAB_H */
diff --git a/gdb/testsuite/gdb.ada/maint_with_ada.exp b/gdb/testsuite/gdb.ada/maint_with_ada.exp
index 796b7ff26591..9f8f682ceaa1 100644
--- a/gdb/testsuite/gdb.ada/maint_with_ada.exp
+++ b/gdb/testsuite/gdb.ada/maint_with_ada.exp
@@ -34,6 +34,4 @@ gdb_breakpoint "adainit"
 gdb_breakpoint "Var_Arr_Typedef"
 gdb_breakpoint "Do_Nothing"
 
-gdb_test_no_output "maintenance check psymtabs"
-
 gdb_test_no_output "maintenance check symtabs"
diff --git a/gdb/testsuite/gdb.base/check-psymtab.c b/gdb/testsuite/gdb.base/check-psymtab.c
deleted file mode 100644
index a3f3581e7f1b..000000000000
--- a/gdb/testsuite/gdb.base/check-psymtab.c
+++ /dev/null
@@ -1,28 +0,0 @@
-/* This testcase is part of GDB, the GNU debugger.
-
-   Copyright 2020-2026 Free Software Foundation, Inc.
-
-   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/>.  */
-
-static inline int __attribute__((__always_inline__))
-foo (void)
-{
-  return 0;
-}
-
-int
-main (void)
-{
-  return foo ();
-}
diff --git a/gdb/testsuite/gdb.base/check-psymtab.exp b/gdb/testsuite/gdb.base/check-psymtab.exp
deleted file mode 100644
index 326a426f2fea..000000000000
--- a/gdb/testsuite/gdb.base/check-psymtab.exp
+++ /dev/null
@@ -1,26 +0,0 @@
-# Copyright 2020-2026 Free Software Foundation, Inc.
-
-# 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/>.  */
-
-standard_testfile
-
-if {[prepare_for_testing "failed to prepare" $testfile $srcfile]} {
-    return -1
-}
-
-gdb_test_no_output "maint expand-symtabs"
-
-# Check that we don't get:
-#   Static symbol `foo' only found in check-psymtab.c psymtab
-gdb_test_no_output "maint check psymtab"
diff --git a/gdb/testsuite/gdb.base/main-psymtab.exp b/gdb/testsuite/gdb.base/main-psymtab.exp
deleted file mode 100644
index a6bf2e1a24d7..000000000000
--- a/gdb/testsuite/gdb.base/main-psymtab.exp
+++ /dev/null
@@ -1,38 +0,0 @@
-# Copyright 2020-2026 Free Software Foundation, Inc.
-
-# 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/>.
-
-standard_testfile persistent-lang.cc
-
-set flags {}
-lappend flags debug
-lappend flags c++
-
-if {[build_executable "failed to prepare" $testfile $srcfile $flags]} {
-    return -1
-}
-
-clean_restart
-
-set auto_cpp \
-    {The current source language is "auto; currently c\+\+"\.}
-
-gdb_load ${binfile}
-gdb_test "show language" $auto_cpp \
-    "language auto/c++ after load"
-
-# Verify that partial symtab expansion has not taken place for
-# persistent-lang.cc
-
-verify_psymtab_expanded persistent-lang.cc no
diff --git a/gdb/testsuite/gdb.base/maint.exp b/gdb/testsuite/gdb.base/maint.exp
index c3de727a740f..87216181382f 100644
--- a/gdb/testsuite/gdb.base/maint.exp
+++ b/gdb/testsuite/gdb.base/maint.exp
@@ -20,7 +20,6 @@
 # source file used is break.c
 
 
-#maintenance check psymtabs -- Check consistency of psymtabs vs symtabs
 #maintenance check symtabs -- Check consistency of symtabs
 #maintenance expand-symtabs -- Expand symtabs matching a file regexp
 #maintenance set -- Set GDB internal variables used by the GDB maintainer
@@ -33,7 +32,6 @@
 #maintenance print dummy-frames -- Print the dummy frame stack
 #maintenance print statistics -- Print statistics about internal gdb state
 #maintenance print objfiles -- Print dump of current object file definitions
-#maintenance print psymbols -- Print dump of current partial symbol definitions
 #maintenance print msymbols -- Print dump of current minimal symbol definitions
 #maintenance print symbols -- Print dump of current symbol definitions
 #maintenance print type -- Print a type chain for a given symbol
@@ -151,60 +149,6 @@ if {![runto_main]} {
     return
 }
 
-# If we're using .gdb_index or .debug_names there will be no psymtabs.
-set have_gdb_index [ exec_has_index_section ${binfile} ]
-
-# There also won't be any psymtabs if we read the index from the index cache.
-# We can detect this by looking if the index-cache is enabled and if the number
-# of cache misses is 0.
-set index_cache_misses -1
-gdb_test_multiple "show index-cache stats" "check index cache stats" {
-    -re ".*Cache misses \\(this session\\): (\\d+)\r\n.*$gdb_prompt $" {
-	set index_cache_misses $expect_out(1,string)
-    }
-}
-
-set using_index_cache 0
-gdb_test_multiple "show index-cache enabled" "check index cache status" {
-    -re ".*is off.\r\n$gdb_prompt $" {
-	set using_index_cache 0
-    }
-    -re ".*is on.\r\n$gdb_prompt $" {
-	set using_index_cache 1
-    }
-}
-
-if { $index_cache_misses == 0 && $using_index_cache } {
-    set have_gdb_index 1
-}
-
-set have_psyms [expr {! ( $have_gdb_index || $readnow_p )}]
-
-#
-# this command does not produce any output
-# unless there is some problem with the symtabs and psymtabs
-# so that branch will really never be covered in this tests here!!
-#
-# When there is a problem, there may be loads of output, which can
-# overwhelm the expect buffer. Splitting it seems to fix those
-# issues.
-
-set seen_command false
-gdb_test_multiple "maint check psymtabs" "" {
-    -re "^maint check psymtabs\r\n" {
-	set seen_command true
-	exp_continue
-    }
-
-    -re "^$gdb_prompt $" {
-	gdb_assert { $seen_command } $gdb_test_name
-    }
-
-    -re "^\[^\r\n\]+\r\n" {
-	exp_continue
-    }
-}
-
 # This command does not produce any output unless there is some problem
 # with the symtabs, so that branch will really never be covered in the
 # tests here!!
@@ -236,10 +180,7 @@ set re \
 	 "  Number of symbol tables: $decimal" \
 	 "  Number of symbol tables with line tables: $decimal" \
 	 "  Number of symbol tables with blockvectors: $decimal" \
-	 "(  Number of \"partial\" symbols read: $decimal" \
-	 ")?(  Number of psym tables \\(not yet expanded\\): $decimal" \
-	 ")?(  Total memory used for psymbol cache: $decimal" \
-	 ")?(  Number of read units: $decimal" \
+	 "(  Number of read units: $decimal" \
 	 "  Number of unread units: $decimal" \
 	 "  Number of read top-level DIEs: $decimal" \
 	 ")?  Total memory used for objfile obstack: $decimal" \
@@ -260,7 +201,6 @@ gdb_test_no_output "maint print dummy-frames"
 # in the output, and stop when we've seen all of them.
 
 set header 0
-set psymtabs 0
 set cooked_index 0
 set symtabs 0
 set cmd "maint print objfiles"
@@ -274,10 +214,6 @@ gdb_test_multiple "$cmd $re" "$cmd" -lbl {
 	set cooked_index 1
 	exp_continue
     }
-    -re "\r\nPsymtabs:\[\r\t \]+" {
-	set psymtabs 1
-	exp_continue
-    }
     -re "\r\nSymtabs:\[\r\t \]+\n" {
 	set symtabs 1
 	exp_continue
@@ -292,37 +228,8 @@ proc maint_pass_if {val name} {
 }
 
 maint_pass_if $header   "maint print objfiles: header"
-if {$cooked_index} {
-    set have_psyms 0
-}
-if { $have_psyms } {
-    maint_pass_if $psymtabs "maint print objfiles: psymtabs"
-}
 maint_pass_if $symtabs  "maint print objfiles: symtabs"
 
-if { $have_psyms } {
-    set psymbols_output [standard_output_file psymbols_output]
-    set psymbols_output_re [string_to_regexp $psymbols_output]
-    set test_list [list \
-		       "maint print psymbols -source" \
-		       "maint print psymbols -source ${srcdir}/${subdir}/${srcfile} $psymbols_output" \
-		       "maint print psymbols -pc" \
-		       "maint print psymbols -pc main $psymbols_output"]
-    foreach { test_name command } $test_list {
-	gdb_test_no_output "$command" "collecting data for $test_name"
-	gdb_test_multiple "shell grep 'main.*function' $psymbols_output" "" {
-		-re -wrap ".main., function, $hex.*" {
-		    pass "$test_name (pattern 1)"
-		}
-		-re -wrap ".*main.  .., function, $hex.*" {
-		    pass "$test_name (pattern 2)"
-		}
-	}
-	gdb_test "shell rm -f $psymbols_output" ".*" \
-	    "${test_name}: shell rm -f psymbols_output"
-    }
-}
-
 
 set msymbols_output [standard_output_file msymbols_output]
 set msymbols_output_re [string_to_regexp $msymbols_output]
@@ -544,7 +451,6 @@ gdb_exit
 gdb_start
 gdb_test_no_output "maint print symbols"
 gdb_test_no_output "maint print msymbols"
-gdb_test_no_output "maint print psymbols"
 
 gdb_test "maint canonicalize int short" "canonical = short"
 gdb_test "maint canonicalize fn<ty<int>>" \
diff --git a/gdb/testsuite/gdb.base/readnever.exp b/gdb/testsuite/gdb.base/readnever.exp
index fac6233ac7a4..427b9a82c85d 100644
--- a/gdb/testsuite/gdb.base/readnever.exp
+++ b/gdb/testsuite/gdb.base/readnever.exp
@@ -49,8 +49,6 @@ gdb_test "backtrace" \
 
 gdb_test_no_output "maint info symtabs" \
     "maint info symtabs no output for --readnever"
-gdb_test_no_output "maint info psymtabs" \
-    "maint info psymtabs no output for --readnever"
 
 # Test invalid combination of flags.
 save_vars { GDBFLAGS } {
@@ -84,5 +82,3 @@ gdb_test "symbol-file ${binfile}0.o -readnever" \
 
 gdb_test_no_output "maint info symtabs" \
     "maint info symtabs no output for symbol-file -readnever"
-gdb_test_no_output "maint info psymtabs" \
-    "maint info psymtabs no output for symbol-file -readnever"
diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp
index 5f53bb6de2ca..dd12f665b98d 100644
--- a/gdb/testsuite/lib/gdb.exp
+++ b/gdb/testsuite/lib/gdb.exp
@@ -10582,28 +10582,6 @@ proc have_index { objfile } {
     }
 }
 
-# Verify that partial symtab expansion for $filename has state $readin.
-
-proc verify_psymtab_expanded { filename readin } {
-    global gdb_prompt
-
-    set cmd "maint info psymtab"
-    set test "$cmd: $filename: $readin"
-    set re [multi_line \
-		"  \{ psymtab \[^\r\n\]*$filename\[^\r\n\]*" \
-		"    readin $readin" \
-		".*"]
-
-    gdb_test_multiple $cmd $test {
-	-re "$cmd\r\n$gdb_prompt $" {
-	    unsupported $gdb_test_name
-	}
-	-re -wrap $re {
-	    pass $gdb_test_name
-	}
-    }
-}
-
 # Add a .gdb_index section to PROGRAM.
 # PROGRAM is assumed to be the output of standard_output_file.
 # Returns the 0 if there is a failure, otherwise 1.
-- 
2.53.0


^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH v3 1/9] gdb/ctf: add debug logging in ctfread.c
  2026-02-28  3:51     ` [PATCH v3 1/9] gdb/ctf: add debug logging in ctfread.c Simon Marchi
@ 2026-02-28 10:12       ` Eli Zaretskii
  2026-02-28 16:23         ` Simon Marchi
  0 siblings, 1 reply; 52+ messages in thread
From: Eli Zaretskii @ 2026-02-28 10:12 UTC (permalink / raw)
  To: Simon Marchi; +Cc: gdb-patches

> From: Simon Marchi <simon.marchi@efficios.com>
> Cc: Simon Marchi <simon.marchi@polymtl.ca>,
> 	Eli Zaretskii <eliz@gnu.org>
> Date: Fri, 27 Feb 2026 22:51:48 -0500
> 
> From: Simon Marchi <simon.marchi@polymtl.ca>
> 
> diff --git a/gdb/NEWS b/gdb/NEWS
> index d70147144e49..e83d1abd73b3 100644
> --- a/gdb/NEWS
> +++ b/gdb/NEWS
> @@ -98,6 +98,10 @@ set debug gnu-ifunc on|off
>  show debug gnu-ifunc
>    Turn on or off debug messages related to GNU ifunc resolution.
>  
> +set debug ctf on|off
> +show debug ctf
> +  Turn on or off debug messages about CTF reading.

This part is okay.

> --- a/gdb/doc/gdb.texinfo
> +++ b/gdb/doc/gdb.texinfo
> @@ -29284,6 +29284,13 @@ exported symbols.  The default is off.
>  Displays the current state of displaying debugging messages related to
>  reading of COFF/PE exported symbols.
>  
> +@cindex CTF debug messages
> +@item set debug ctf

This should have "[on | off]" appended to it, I think.  Okay with that
nit fixed.

Thanks.

Reviewed-By: Eli Zaretskii <eliz@gnu.org>

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH v3 9/9] gdb: remove psymtab.{c,h}
  2026-02-28  3:51     ` [PATCH v3 9/9] gdb: remove psymtab.{c,h} Simon Marchi
@ 2026-02-28 10:18       ` Eli Zaretskii
  0 siblings, 0 replies; 52+ messages in thread
From: Eli Zaretskii @ 2026-02-28 10:18 UTC (permalink / raw)
  To: Simon Marchi; +Cc: gdb-patches

> From: Simon Marchi <simon.marchi@efficios.com>
> Cc: Simon Marchi <simon.marchi@polymtl.ca>
> Date: Fri, 27 Feb 2026 22:51:56 -0500
> 
> From: Simon Marchi <simon.marchi@polymtl.ca>
> 
> The last user of psymtabs has been changed not to use them, remove them.
> 
> Update the tests minimally to avoid introducing failures (mostly due to
> tests using the removed maintenance commands).  There are still a lot of
> references to partial symtabs in the comments or test names.  There are
> probably some tests that are just not relevant anymore.  It would be quite
> difficult to do this job all at once, we can clean this up little by
> little.
> 
> Update the docs to remove references to partial symbols/symtabs.
> 
> Mention the removal of the maintenance commands in NEWS.
> 
> Change-Id: I58ae48c30e0303bcaa48298146d69fb8f059cb32
> ---
>  gdb/Makefile.in                          |    2 -
>  gdb/NEWS                                 |    8 +
>  gdb/doc/gdb.texinfo                      |   95 +-
>  gdb/psymtab.c                            | 1575 ----------------------
>  gdb/psymtab.h                            |  691 ----------
>  gdb/testsuite/gdb.ada/maint_with_ada.exp |    2 -
>  gdb/testsuite/gdb.base/check-psymtab.c   |   28 -
>  gdb/testsuite/gdb.base/check-psymtab.exp |   26 -
>  gdb/testsuite/gdb.base/main-psymtab.exp  |   38 -
>  gdb/testsuite/gdb.base/maint.exp         |   96 +-
>  gdb/testsuite/gdb.base/readnever.exp     |    4 -
>  gdb/testsuite/lib/gdb.exp                |   22 -
>  12 files changed, 38 insertions(+), 2549 deletions(-)
>  delete mode 100644 gdb/psymtab.c
>  delete mode 100644 gdb/psymtab.h
>  delete mode 100644 gdb/testsuite/gdb.base/check-psymtab.c
>  delete mode 100644 gdb/testsuite/gdb.base/check-psymtab.exp
>  delete mode 100644 gdb/testsuite/gdb.base/main-psymtab.exp

Thanks, the documentation parts are okay.

Reviewed-By: Eli Zaretskii <eliz@gnu.org>

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH v3 1/9] gdb/ctf: add debug logging in ctfread.c
  2026-02-28 10:12       ` Eli Zaretskii
@ 2026-02-28 16:23         ` Simon Marchi
  0 siblings, 0 replies; 52+ messages in thread
From: Simon Marchi @ 2026-02-28 16:23 UTC (permalink / raw)
  To: Eli Zaretskii, Simon Marchi; +Cc: gdb-patches



On 2026-02-28 05:12, Eli Zaretskii wrote:
>> From: Simon Marchi <simon.marchi@efficios.com>
>> Cc: Simon Marchi <simon.marchi@polymtl.ca>,
>> 	Eli Zaretskii <eliz@gnu.org>
>> Date: Fri, 27 Feb 2026 22:51:48 -0500
>>
>> From: Simon Marchi <simon.marchi@polymtl.ca>
>>
>> diff --git a/gdb/NEWS b/gdb/NEWS
>> index d70147144e49..e83d1abd73b3 100644
>> --- a/gdb/NEWS
>> +++ b/gdb/NEWS
>> @@ -98,6 +98,10 @@ set debug gnu-ifunc on|off
>>  show debug gnu-ifunc
>>    Turn on or off debug messages related to GNU ifunc resolution.
>>  
>> +set debug ctf on|off
>> +show debug ctf
>> +  Turn on or off debug messages about CTF reading.
> 
> This part is okay.
> 
>> --- a/gdb/doc/gdb.texinfo
>> +++ b/gdb/doc/gdb.texinfo
>> @@ -29284,6 +29284,13 @@ exported symbols.  The default is off.
>>  Displays the current state of displaying debugging messages related to
>>  reading of COFF/PE exported symbols.
>>  
>> +@cindex CTF debug messages
>> +@item set debug ctf
> 
> This should have "[on | off]" appended to it, I think.  Okay with that
> nit fixed.
> 
> Thanks.
> 
> Reviewed-By: Eli Zaretskii <eliz@gnu.org>

Fixed locally, thanks.

Simon

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH v3 7/9] gdb: make expanded_symbols_functions hold compunit symtabs
  2026-02-28  3:51     ` [PATCH v3 7/9] gdb: make expanded_symbols_functions hold compunit symtabs Simon Marchi
@ 2026-03-04 19:21       ` Tom Tromey
  2026-03-04 19:32         ` Tom Tromey
  2026-03-09 18:48         ` Simon Marchi
  0 siblings, 2 replies; 52+ messages in thread
From: Tom Tromey @ 2026-03-04 19:21 UTC (permalink / raw)
  To: Simon Marchi; +Cc: gdb-patches, Simon Marchi

>>>>> "Simon" == Simon Marchi <simon.marchi@efficios.com> writes:

Simon> Change the expanded_symbols_functions quick functions type to hold and
Simon> use a list of compunit symtab to search.

Simon> Right now the sole user of expanded_symbols_functions is JIT.  Update it
Simon> to keep a vector of compunits as they are finalized, and pass this
Simon> vector to the expanded_symbols_functions object.

I think this is a good direction but this patch isn't quite complete.
The issue is that there are still a handful of spots in gdb that loop
over all compunits.  But with this change, these spots will skip some
compunits.

Now, arguably some of these spots aren't really needed in the current
setup.  For instance, objfile relocation in practice is probably not
needed by the current expanded-symbols users (though it seems a little
less future-proof to assume this).

OTOH some of the spots should still work, e.g., is_addr_in_objfile or
the symbol-searching code (... which should be changed of course, but
currently hasn't been).

Tom

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH v3 8/9] gdb/ctf: don't use psymtabs, create symtabs directly
  2026-02-28  3:51     ` [PATCH v3 8/9] gdb/ctf: don't use psymtabs, create symtabs directly Simon Marchi
@ 2026-03-04 19:29       ` Tom Tromey
  2026-03-09 18:51         ` Simon Marchi
  0 siblings, 1 reply; 52+ messages in thread
From: Tom Tromey @ 2026-03-04 19:29 UTC (permalink / raw)
  To: Simon Marchi; +Cc: gdb-patches, Simon Marchi

>>>>> "Simon" == Simon Marchi <simon.marchi@efficios.com> writes:

Simon> My hypothesis is that CTF debug info is typically small enough and fast
Simon> enough to process that it's not worth it to bother with an intermediate
Simon> step before full symbols.  But I will need help to see if this is true,
Simon> I'm not sure what representatively big C project I can build with CTF
Simon> debug info.

Is there even a (source-available) pure C program bigger than the kernel?

Simon> GDB is still able to load the resulting ELF, and there are about 150k
Simon> calls to ctf_add_type_cb.  Before this patch, elfctf_build_psymtabs
Simon> takes anywhere between 300-350 ms.  With this patch, it's around 400 ms.

This seems completely acceptable to me.

Simon> In order to access the symtabs, elfctf_build_symtabs installs the
Simon> expanded_symbols_functions quick_symbol_functions implementation, which
Simon> essentially searches in the existing symtabs.  I am pretty sure this is
Simon> not 100% correct, because this would search unrelated symtabs, if for
Simon> instance the CTF debug info co-existed with DWARF info.  But it's good
Simon> enough for a prototype.

In light of patch #7 this paragraph is obsolete.

Tom

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH v3 7/9] gdb: make expanded_symbols_functions hold compunit symtabs
  2026-03-04 19:21       ` Tom Tromey
@ 2026-03-04 19:32         ` Tom Tromey
  2026-03-09 18:56           ` Simon Marchi
  2026-03-09 18:48         ` Simon Marchi
  1 sibling, 1 reply; 52+ messages in thread
From: Tom Tromey @ 2026-03-04 19:32 UTC (permalink / raw)
  To: Tom Tromey; +Cc: Simon Marchi, gdb-patches, Simon Marchi

Simon> Change the expanded_symbols_functions quick functions type to hold and
Simon> use a list of compunit symtab to search.

Simon> Right now the sole user of expanded_symbols_functions is JIT.  Update it
Simon> to keep a vector of compunits as they are finalized, and pass this
Simon> vector to the expanded_symbols_functions object.

Tom> I think this is a good direction but this patch isn't quite complete.
Tom> The issue is that there are still a handful of spots in gdb that loop
Tom> over all compunits.  But with this change, these spots will skip some
Tom> compunits.

It took me a while but I finally realized that the new vector is in
addition to the objfile's compunits.

This seems kind of ugly to me but OTOH it doesn't have the problems I
ascribed to it.

Tom

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH v3 0/9] Make CTF reader build full symtabs, get rid of psymtab
  2026-02-28  3:51   ` [PATCH v3 0/9] Make CTF reader build full symtabs, get rid of psymtab Simon Marchi
                       ` (8 preceding siblings ...)
  2026-02-28  3:51     ` [PATCH v3 9/9] gdb: remove psymtab.{c,h} Simon Marchi
@ 2026-03-04 19:33     ` Tom Tromey
  2026-03-09 18:57       ` Simon Marchi
  9 siblings, 1 reply; 52+ messages in thread
From: Tom Tromey @ 2026-03-04 19:33 UTC (permalink / raw)
  To: Simon Marchi; +Cc: gdb-patches

>>>>> "Simon" == Simon Marchi <simon.marchi@efficios.com> writes:

Simon> This is v3 of:
Simon> https://inbox.sourceware.org/gdb-patches/20260217195329.3833518-1-simon.marchi@polymtl.ca/

Simon> The change is that the last patch now includes necessary test changes
Simon> (to avoid regressions), plus doc and NEWS changes.

I read through these & I think this is fine.
There's one patch where the commit message should be updated.

Assuming I'm correct about the compunit issue -- that the new vector is
redundant in the sense that compunits also appear on the objfile -- then
I think this is ok, albeit somewhat unfortunate.

Approved-By: Tom Tromey <tom@tromey.com>

Tom

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH v3 7/9] gdb: make expanded_symbols_functions hold compunit symtabs
  2026-03-04 19:21       ` Tom Tromey
  2026-03-04 19:32         ` Tom Tromey
@ 2026-03-09 18:48         ` Simon Marchi
  2026-03-10 17:09           ` Tom Tromey
  1 sibling, 1 reply; 52+ messages in thread
From: Simon Marchi @ 2026-03-09 18:48 UTC (permalink / raw)
  To: Tom Tromey; +Cc: gdb-patches, Simon Marchi

On 3/4/26 2:21 PM, Tom Tromey wrote:
>>>>>> "Simon" == Simon Marchi <simon.marchi@efficios.com> writes:
> 
> Simon> Change the expanded_symbols_functions quick functions type to hold and
> Simon> use a list of compunit symtab to search.
> 
> Simon> Right now the sole user of expanded_symbols_functions is JIT.  Update it
> Simon> to keep a vector of compunits as they are finalized, and pass this
> Simon> vector to the expanded_symbols_functions object.
> 
> I think this is a good direction but this patch isn't quite complete.
> The issue is that there are still a handful of spots in gdb that loop
> over all compunits.  But with this change, these spots will skip some
> compunits.
> 
> Now, arguably some of these spots aren't really needed in the current
> setup.  For instance, objfile relocation in practice is probably not
> needed by the current expanded-symbols users (though it seems a little
> less future-proof to assume this).

I don't understand this.  If some code wants to iterate on all compunit
symtabs of a given objfile, it would use objfile::compunits.  Why would
changing expanded_symbols_functions affect that?

Simon

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH v3 8/9] gdb/ctf: don't use psymtabs, create symtabs directly
  2026-03-04 19:29       ` Tom Tromey
@ 2026-03-09 18:51         ` Simon Marchi
  0 siblings, 0 replies; 52+ messages in thread
From: Simon Marchi @ 2026-03-09 18:51 UTC (permalink / raw)
  To: Tom Tromey; +Cc: gdb-patches, Simon Marchi

On 3/4/26 2:29 PM, Tom Tromey wrote:
>>>>>> "Simon" == Simon Marchi <simon.marchi@efficios.com> writes:
> 
> Simon> My hypothesis is that CTF debug info is typically small enough and fast
> Simon> enough to process that it's not worth it to bother with an intermediate
> Simon> step before full symbols.  But I will need help to see if this is true,
> Simon> I'm not sure what representatively big C project I can build with CTF
> Simon> debug info.
> 
> Is there even a (source-available) pure C program bigger than the kernel?

No idea.

> Simon> GDB is still able to load the resulting ELF, and there are about 150k
> Simon> calls to ctf_add_type_cb.  Before this patch, elfctf_build_psymtabs
> Simon> takes anywhere between 300-350 ms.  With this patch, it's around 400 ms.
> 
> This seems completely acceptable to me.
> 
> Simon> In order to access the symtabs, elfctf_build_symtabs installs the
> Simon> expanded_symbols_functions quick_symbol_functions implementation, which
> Simon> essentially searches in the existing symtabs.  I am pretty sure this is
> Simon> not 100% correct, because this would search unrelated symtabs, if for
> Simon> instance the CTF debug info co-existed with DWARF info.  But it's good
> Simon> enough for a prototype.
> 
> In light of patch #7 this paragraph is obsolete.

Thanks, removed locally.

Simon

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH v3 7/9] gdb: make expanded_symbols_functions hold compunit symtabs
  2026-03-04 19:32         ` Tom Tromey
@ 2026-03-09 18:56           ` Simon Marchi
  0 siblings, 0 replies; 52+ messages in thread
From: Simon Marchi @ 2026-03-09 18:56 UTC (permalink / raw)
  To: Tom Tromey; +Cc: gdb-patches, Simon Marchi

On 3/4/26 2:32 PM, Tom Tromey wrote:
> Simon> Change the expanded_symbols_functions quick functions type to hold and
> Simon> use a list of compunit symtab to search.
> 
> Simon> Right now the sole user of expanded_symbols_functions is JIT.  Update it
> Simon> to keep a vector of compunits as they are finalized, and pass this
> Simon> vector to the expanded_symbols_functions object.
> 
> Tom> I think this is a good direction but this patch isn't quite complete.
> Tom> The issue is that there are still a handful of spots in gdb that loop
> Tom> over all compunits.  But with this change, these spots will skip some
> Tom> compunits.
> 
> It took me a while but I finally realized that the new vector is in
> addition to the objfile's compunits.
> 
> This seems kind of ugly to me but OTOH it doesn't have the problems I
> ascribed to it.

I just saw this reponse after sending my other email.

I don't really see how it could be less ugly, given that the
expanded_symbols_functions needs to know which compunits it is
responsible for.  An alternative would be for compunit_symtabs to have a
backlink to the quick_symbol_functions that is responsible for it, but
it would make iterating on all the compunits for which a
quick_symbol_functions is responsible for less efficient.

Simon

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH v3 0/9] Make CTF reader build full symtabs, get rid of psymtab
  2026-03-04 19:33     ` [PATCH v3 0/9] Make CTF reader build full symtabs, get rid of psymtab Tom Tromey
@ 2026-03-09 18:57       ` Simon Marchi
  0 siblings, 0 replies; 52+ messages in thread
From: Simon Marchi @ 2026-03-09 18:57 UTC (permalink / raw)
  To: Tom Tromey, Simon Marchi; +Cc: gdb-patches

On 3/4/26 2:33 PM, Tom Tromey wrote:
>>>>>> "Simon" == Simon Marchi <simon.marchi@efficios.com> writes:
> 
> Simon> This is v3 of:
> Simon> https://inbox.sourceware.org/gdb-patches/20260217195329.3833518-1-simon.marchi@polymtl.ca/
> 
> Simon> The change is that the last patch now includes necessary test changes
> Simon> (to avoid regressions), plus doc and NEWS changes.
> 
> I read through these & I think this is fine.
> There's one patch where the commit message should be updated.
> 
> Assuming I'm correct about the compunit issue -- that the new vector is
> redundant in the sense that compunits also appear on the objfile -- then
> I think this is ok, albeit somewhat unfortunate.
> 
> Approved-By: Tom Tromey <tom@tromey.com>

Ok, thanks.  I'll push the series, since it seems to be a step forward,
we can always adjust things later.

Simon

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH v3 7/9] gdb: make expanded_symbols_functions hold compunit symtabs
  2026-03-09 18:48         ` Simon Marchi
@ 2026-03-10 17:09           ` Tom Tromey
  0 siblings, 0 replies; 52+ messages in thread
From: Tom Tromey @ 2026-03-10 17:09 UTC (permalink / raw)
  To: Simon Marchi; +Cc: Tom Tromey, gdb-patches, Simon Marchi

>>>>> "Simon" == Simon Marchi <simon.marchi@efficios.com> writes:

>> Now, arguably some of these spots aren't really needed in the current
>> setup.  For instance, objfile relocation in practice is probably not
>> needed by the current expanded-symbols users (though it seems a little
>> less future-proof to assume this).

Simon> I don't understand this.  If some code wants to iterate on all compunit
Simon> symtabs of a given objfile, it would use objfile::compunits.  Why would
Simon> changing expanded_symbols_functions affect that?

That note was based on a misconception.  But anyway I think it would
be a better design for the 'quick' subclasses to own their own compunits.
Then it would be less possible to accidentally iterate over "other" compunits.

Generic code iterating over all compunits is often a bug.
Like, it's fine for dumping or for relocation.  But searches done this
way can be susceptible to the old expansion order problems.

Tom

^ permalink raw reply	[flat|nested] 52+ messages in thread

end of thread, other threads:[~2026-03-10 17:10 UTC | newest]

Thread overview: 52+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-02-03  6:45 [RFC PATCH 0/8] Make CTF reader build full symtabs, get rid of psymtab simon.marchi
2026-02-03  6:45 ` [RFC PATCH 1/8] gdb/ctf: add debug logging in ctfread.c simon.marchi
2026-02-03 12:40   ` Eli Zaretskii
2026-02-03 16:21     ` Simon Marchi
2026-02-03 16:37       ` Eli Zaretskii
2026-02-03 20:39         ` Simon Marchi
2026-02-03  6:45 ` [RFC PATCH 2/8] gdb/ctf: add unique_ptr types simon.marchi
2026-02-03  6:45 ` [RFC PATCH 3/8] gdb/ctf: editorial renames simon.marchi
2026-02-03  6:45 ` [RFC PATCH 4/8] gdb/ctf: use ctf_per_objfile in ctf_archive_iter_psymtab_data and ctf_context simon.marchi
2026-02-12 17:44   ` Tom Tromey
2026-02-12 18:35     ` Simon Marchi
2026-02-03  6:45 ` [RFC PATCH 5/8] gdb/ctf: check return value of ctf_type_align simon.marchi
2026-02-12 17:49   ` Tom Tromey
2026-02-12 18:37     ` Simon Marchi
2026-02-03  6:45 ` [RFC PATCH 6/8] gdb/ctf: add scoped_time_it in elfctf_build_psymtabs simon.marchi
2026-02-03  6:45 ` [RFC PATCH 7/8] gdb/ctf: don't use psymtabs, create symtabs directly simon.marchi
2026-02-12 17:54   ` Tom Tromey
2026-02-03  6:45 ` [RFC PATCH 8/8] gdb: remove psymtab.{c,h} simon.marchi
2026-02-12 17:58 ` [RFC PATCH 0/8] Make CTF reader build full symtabs, get rid of psymtab Tom Tromey
2026-02-12 18:47   ` Simon Marchi
2026-02-17 19:50 ` [PATCH v2 0/9] " simon.marchi
2026-02-17 19:50   ` [PATCH v2 1/9] gdb/ctf: add debug logging in ctfread.c simon.marchi
2026-02-17 19:50   ` [PATCH v2 2/9] gdb/ctf: add unique_ptr types simon.marchi
2026-02-17 19:50   ` [PATCH v2 3/9] gdb/ctf: editorial renames simon.marchi
2026-02-17 19:50   ` [PATCH v2 4/9] gdb/ctf: use ctf_per_objfile in ctf_archive_iter_psymtab_data and ctf_context simon.marchi
2026-02-17 19:50   ` [PATCH v2 5/9] gdb/ctf: check return value of ctf_type_align simon.marchi
2026-02-17 19:50   ` [PATCH v2 6/9] gdb/ctf: add scoped_time_it in elfctf_build_psymtabs simon.marchi
2026-02-17 19:50   ` [PATCH v2 7/9] gdb: make expanded_symbols_functions hold compunit symtabs simon.marchi
2026-02-17 19:50   ` [PATCH v2 8/9] gdb/ctf: don't use psymtabs, create symtabs directly simon.marchi
2026-02-17 19:50   ` [PATCH v2 9/9] gdb: remove psymtab.{c,h} simon.marchi
2026-02-28  3:51   ` [PATCH v3 0/9] Make CTF reader build full symtabs, get rid of psymtab Simon Marchi
2026-02-28  3:51     ` [PATCH v3 1/9] gdb/ctf: add debug logging in ctfread.c Simon Marchi
2026-02-28 10:12       ` Eli Zaretskii
2026-02-28 16:23         ` Simon Marchi
2026-02-28  3:51     ` [PATCH v3 2/9] gdb/ctf: add unique_ptr types Simon Marchi
2026-02-28  3:51     ` [PATCH v3 3/9] gdb/ctf: editorial renames Simon Marchi
2026-02-28  3:51     ` [PATCH v3 4/9] gdb/ctf: use ctf_per_objfile in ctf_archive_iter_psymtab_data and ctf_context Simon Marchi
2026-02-28  3:51     ` [PATCH v3 5/9] gdb/ctf: check return value of ctf_type_align Simon Marchi
2026-02-28  3:51     ` [PATCH v3 6/9] gdb/ctf: add scoped_time_it in elfctf_build_psymtabs Simon Marchi
2026-02-28  3:51     ` [PATCH v3 7/9] gdb: make expanded_symbols_functions hold compunit symtabs Simon Marchi
2026-03-04 19:21       ` Tom Tromey
2026-03-04 19:32         ` Tom Tromey
2026-03-09 18:56           ` Simon Marchi
2026-03-09 18:48         ` Simon Marchi
2026-03-10 17:09           ` Tom Tromey
2026-02-28  3:51     ` [PATCH v3 8/9] gdb/ctf: don't use psymtabs, create symtabs directly Simon Marchi
2026-03-04 19:29       ` Tom Tromey
2026-03-09 18:51         ` Simon Marchi
2026-02-28  3:51     ` [PATCH v3 9/9] gdb: remove psymtab.{c,h} Simon Marchi
2026-02-28 10:18       ` Eli Zaretskii
2026-03-04 19:33     ` [PATCH v3 0/9] Make CTF reader build full symtabs, get rid of psymtab Tom Tromey
2026-03-09 18:57       ` Simon Marchi

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox