[PATCHv4,4/7] gdb/dwarf: move subfile and symtab creation into dwarf2_cu method

Message ID 7832d2223c87b1712556a9de75cb6c2d1930ffd9.1767024363.git.aburgess@redhat.com
State New
Headers
Series Fixes related to misplaced symtabs originating from dwz files |

Commit Message

Andrew Burgess Dec. 29, 2025, 4:15 p.m. UTC
  There are two places in the dwarf2/ code where we create subfiles and
symtabs for the entries in a dwarf2_cu's line_header.  The code in
each location is basically the same.

Move this code into a new dwarf2_cu member function.

In dwarf2/read.c the existing code had an additional task; this is
left in dwarf2/read.c in its own loop immediately after the call to
the new member function.

There should be no user visible changes after this commit.
---
 gdb/dwarf2/cu.c           | 22 ++++++++++++++++++++++
 gdb/dwarf2/cu.h           |  3 +++
 gdb/dwarf2/line-program.c | 15 +--------------
 gdb/dwarf2/read.c         | 20 +++-----------------
 4 files changed, 29 insertions(+), 31 deletions(-)
  

Comments

Tom Tromey Jan. 5, 2026, 5:36 p.m. UTC | #1
>>>>> "Andrew" == Andrew Burgess <aburgess@redhat.com> writes:

Andrew> There are two places in the dwarf2/ code where we create subfiles and
Andrew> symtabs for the entries in a dwarf2_cu's line_header.  The code in
Andrew> each location is basically the same.

Andrew> Move this code into a new dwarf2_cu member function.

Andrew> In dwarf2/read.c the existing code had an additional task; this is
Andrew> left in dwarf2/read.c in its own loop immediately after the call to
Andrew> the new member function.

Thanks, makes sense.
Approved-By: Tom Tromey <tom@tromey.com>

Tom
  

Patch

diff --git a/gdb/dwarf2/cu.c b/gdb/dwarf2/cu.c
index 6e5a41e2aec..b4da4dfe248 100644
--- a/gdb/dwarf2/cu.c
+++ b/gdb/dwarf2/cu.c
@@ -23,6 +23,7 @@ 
 #include "filenames.h"
 #include "producer.h"
 #include "gdbsupport/pathstuff.h"
+#include "dwarf2/line-header.h"
 
 /* Initialize dwarf2_cu to read PER_CU, in the context of PER_OBJFILE.  */
 
@@ -238,3 +239,24 @@  dwarf2_cu::set_producer (const char *producer)
 
   m_checked_producer = true;
 }
+
+/* See dwarf2/cu.h.  */
+
+void
+dwarf2_cu::create_subfiles_and_symtabs ()
+{
+  buildsym_compunit *builder = this->get_builder ();
+  compunit_symtab *cust = builder->get_compunit_symtab ();
+
+  for (file_entry &fe : this->line_header->file_names ())
+    {
+      dwarf2_start_subfile (*this, fe);
+      subfile *sf = builder->get_current_subfile ();
+
+      if (sf->symtab == nullptr)
+	sf->symtab = allocate_symtab (cust, sf->name.c_str (),
+				      sf->name_for_id.c_str ());
+
+      fe.symtab = sf->symtab;
+    }
+}
diff --git a/gdb/dwarf2/cu.h b/gdb/dwarf2/cu.h
index 68010a060cc..d4a5ae65f3c 100644
--- a/gdb/dwarf2/cu.h
+++ b/gdb/dwarf2/cu.h
@@ -72,6 +72,9 @@  struct dwarf2_cu
 						 const char *comp_dir,
 						 CORE_ADDR low_pc);
 
+  /* Create a subfile and symtab for every entry in the line_header.  */
+  void create_subfiles_and_symtabs ();
+
   /* Reset the builder.  */
   void reset_builder () { m_builder.reset (); }
 
diff --git a/gdb/dwarf2/line-program.c b/gdb/dwarf2/line-program.c
index 46da4bf5a42..3e4e30fb227 100644
--- a/gdb/dwarf2/line-program.c
+++ b/gdb/dwarf2/line-program.c
@@ -699,18 +699,5 @@  dwarf_decode_lines (struct dwarf2_cu *cu, unrelocated_addr lowpc,
   /* Make sure a symtab is created for every file, even files
      which contain only variables (i.e. no code with associated
      line numbers).  */
-  buildsym_compunit *builder = cu->get_builder ();
-  struct compunit_symtab *cust = builder->get_compunit_symtab ();
-
-  for (file_entry &fe : cu->line_header->file_names ())
-    {
-      dwarf2_start_subfile (*cu, fe);
-      subfile *sf = builder->get_current_subfile ();
-
-      if (sf->symtab == nullptr)
-	sf->symtab = allocate_symtab (cust, sf->name.c_str (),
-				      sf->name_for_id.c_str ());
-
-      fe.symtab = sf->symtab;
-    }
+  cu->create_subfiles_and_symtabs ();
 }
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index f92d9b6eb42..09568c02715 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -6271,27 +6271,13 @@  dwarf2_cu::setup_type_unit_groups (struct die_info *die)
 	= XOBNEWVEC (&cust->objfile ()->objfile_obstack,
 		     struct symtab *, line_header->file_names_size ());
 
+      this->create_subfiles_and_symtabs ();
+
       auto &file_names = line_header->file_names ();
       for (i = 0; i < file_names.size (); ++i)
 	{
 	  file_entry &fe = file_names[i];
-	  dwarf2_start_subfile (*this, fe);
-	  buildsym_compunit *b = get_builder ();
-	  subfile *sf = b->get_current_subfile ();
-
-	  if (sf->symtab == nullptr)
-	    {
-	      /* NOTE: start_subfile will recognize when it's been
-		 passed a file it has already seen.  So we can't
-		 assume there's a simple mapping from
-		 cu->line_header->file_names to subfiles, plus
-		 cu->line_header->file_names may contain dups.  */
-	      const char *name = sf->name.c_str ();
-	      const char *name_for_id = sf->name_for_id.c_str ();
-	      sf->symtab = allocate_symtab (cust, name, name_for_id);
-	    }
-
-	  fe.symtab = b->get_current_subfile ()->symtab;
+	  gdb_assert (fe.symtab != nullptr);
 	  tug_unshare->symtabs[i] = fe.symtab;
 	}
     }