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

Message ID 12984ceb2361c14aeae01154fcb990ff4a3f608b.1766414210.git.aburgess@redhat.com
State New
Headers
Series Fixes related to misplaced symtabs originating from dwz files |

Commit Message

Andrew Burgess Dec. 22, 2025, 2:41 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           | 23 +++++++++++++++++++++++
 gdb/dwarf2/cu.h           |  3 +++
 gdb/dwarf2/line-program.c | 16 +---------------
 gdb/dwarf2/read.c         | 20 +++-----------------
 4 files changed, 30 insertions(+), 32 deletions(-)
  

Comments

Simon Marchi Dec. 24, 2025, 5:28 a.m. UTC | #1
On 2025-12-22 09:41, Andrew Burgess wrote:
> 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.

If we do this move, I wonder if dwarf2_start_subfile should become a
method of dwarf2_cu too, since it now looks like a helper to that new
method  (although it is also used elsewhere).

Simon
  

Patch

diff --git a/gdb/dwarf2/cu.c b/gdb/dwarf2/cu.c
index 6e5a41e2aec..93824c92e4c 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,25 @@  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 ();
+
+  struct line_header *lh = this->line_header;
+  for (file_entry &fe : lh->file_names ())
+    {
+      dwarf2_start_subfile (this, fe, *lh);
+      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 75c4a060a09..14e01f3a69f 100644
--- a/gdb/dwarf2/line-program.c
+++ b/gdb/dwarf2/line-program.c
@@ -703,19 +703,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 ();
-
-  struct line_header *lh = cu->line_header;
-  for (file_entry &fe : lh->file_names ())
-    {
-      dwarf2_start_subfile (cu, fe, *lh);
-      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 6fb76ddad9d..876fca8f69e 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, *line_header);
-	  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;
 	}
     }