This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[6/10] read PUs


This patch changes the DWARF reader to read PUs -- first as psymtabs,
and then, on expansion, as symtabs.

Initially I thought this patch would be sufficient.

However, one failing case is something like:

* Suppose you have 3 CUs.  They all define a type T, but one of the
  definitions is different.
* dwz merges the two identical copies of T into a new PU.
* Run the inferior and stop at a breakpoint in one of the CUs that
  reference the PU.
* ptype T.  This could conceivably pick up the wrong definition.

This was the motivating case for all the "included symtab" machinery.
These changes ensure that the last step will search the PUs associated
with the current CU first.

IIRC this patch also can cause crashes in isolation.

Tom

>From 5bb8e410339c181d9de1269aa062dd8dae7d59f7 Mon Sep 17 00:00:00 2001
From: Tom Tromey <tromey@redhat.com>
Date: Tue, 17 Apr 2012 05:20:56 -0600
Subject: [PATCH 06/10] make each partial unit into a psymtab and then a
 symtab

	* dwarf2read.c (struct dwarf2_per_cu_data) <psymtab>: Update
	comment.
	(struct partial_die_info) <locdesc>: Remove.
	<d>: New field.
	(process_psymtab_comp_unit): Add 'read_partial' argument.
	Update.
	(process_type_comp_unit, dwarf2_build_psymtabs_hard): Update.
	(scan_partial_symbols): Handle DW_TAG_imported_unit.
	(add_partial_symbol): Update.
	(process_die): Handle DW_TAG_partial_unit.
	(read_file_scope): Update comment.
	(load_partial_dies): Handle DW_TAG_imported_unit.
	(read_partial_die): Handle DW_TAG_partial_unit, DW_AT_import.
	(determine_prefix, dwarf2_name): Handle DW_TAG_partial_unit.
---
 gdb/dwarf2read.c |   74 ++++++++++++++++++++++++++++++++++++++++--------------
 1 files changed, 55 insertions(+), 19 deletions(-)

diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index c737d41..154d9b2 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -439,8 +439,7 @@ struct dwarf2_per_cu_data
   union
   {
     /* The partial symbol table associated with this compilation unit,
-       or NULL for partial units (which do not have an associated
-       symtab).  */
+       or NULL for unread partial units.  */
     struct partial_symtab *psymtab;
 
     /* Data needed by the "quick" functions.  */
@@ -571,8 +570,15 @@ struct partial_die_info
        when this compilation unit leaves the cache.  */
     char *scope;
 
-    /* The location description associated with this DIE, if any.  */
-    struct dwarf_block *locdesc;
+    /* Some data associated with the partial DIE.  The tag determines
+       which field is live.  */
+    union
+    {
+      /* The location description associated with this DIE, if any.  */
+      struct dwarf_block *locdesc;
+      /* The offset of an import, for DW_TAG_imported_unit.  */
+      sect_offset offset;
+    } d;
 
     /* If HAS_PC_INFO, the PC range associated with this DIE.  */
     CORE_ADDR lowpc;
@@ -3425,12 +3431,16 @@ dwarf2_find_base_address (struct die_info *die, struct dwarf2_cu *cu)
    to combine the common parts.
    Process compilation unit THIS_CU for a psymtab.
    SECTION is the section the CU/TU comes from,
-   either .debug_info or .debug_types.  */
+   either .debug_info or .debug_types.
+   READ_PARTIAL controls the handling of DW_TAG_partial_unit.  If we
+   see a partial unit, and READ_PARTIAL is zero, then we skip it
+   entirely.  */
 
 static void
 process_psymtab_comp_unit (struct dwarf2_per_cu_data *this_cu,
 			   struct dwarf2_section_info *section,
-			   int is_debug_types_section)
+			   int is_debug_types_section,
+			   int read_partial)
 {
   struct objfile *objfile = this_cu->objfile;
   bfd *abfd = objfile->obfd;
@@ -3493,7 +3503,7 @@ process_psymtab_comp_unit (struct dwarf2_per_cu_data *this_cu,
       gdb_assert (this_cu->offset.sect_off == cu.header.offset.sect_off);
       this_cu->length = cu.header.length + cu.header.initial_length_size;
     }
-  else if (comp_unit_die->tag == DW_TAG_partial_unit)
+  else if (comp_unit_die->tag == DW_TAG_partial_unit && !read_partial)
     {
       do_cleanups (back_to_inner);
       return;
@@ -3607,7 +3617,7 @@ process_type_comp_unit (void **slot, void *info)
   this_cu = &entry->per_cu;
 
   gdb_assert (this_cu->debug_types_section->readin);
-  process_psymtab_comp_unit (this_cu, this_cu->debug_types_section, 1);
+  process_psymtab_comp_unit (this_cu, this_cu->debug_types_section, 1, 0);
 
   return 1;
 }
@@ -3668,7 +3678,7 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile)
     {
       struct dwarf2_per_cu_data *per_cu = dw2_get_cu (i);
 
-      process_psymtab_comp_unit (per_cu, &dwarf2_per_objfile->info, 0);
+      process_psymtab_comp_unit (per_cu, &dwarf2_per_objfile->info, 0, 0);
     }
 
   objfile->psymtabs_addrmap = addrmap_create_fixed (objfile->psymtabs_addrmap,
@@ -3848,7 +3858,8 @@ scan_partial_symbols (struct partial_die_info *first_die, CORE_ADDR *lowpc,
 	 enums.  */
 
       if (pdi->name != NULL || pdi->tag == DW_TAG_namespace
-	  || pdi->tag == DW_TAG_module || pdi->tag == DW_TAG_enumeration_type)
+	  || pdi->tag == DW_TAG_module || pdi->tag == DW_TAG_enumeration_type
+	  || pdi->tag == DW_TAG_imported_unit)
 	{
 	  switch (pdi->tag)
 	    {
@@ -3888,6 +3899,19 @@ scan_partial_symbols (struct partial_die_info *first_die, CORE_ADDR *lowpc,
 	    case DW_TAG_module:
 	      add_partial_module (pdi, lowpc, highpc, need_pc, cu);
 	      break;
+	    case DW_TAG_imported_unit:
+	      {
+		struct dwarf2_per_cu_data *per_cu;
+
+		per_cu = dwarf2_find_containing_comp_unit (pdi->d.offset,
+							   cu->objfile);
+
+		/* Go read the partial unit, if needed.  */
+		if (per_cu->v.psymtab == NULL)
+		  process_psymtab_comp_unit (per_cu,
+					     &dwarf2_per_objfile->info, 0, 1);
+	      }
+	      break;
 	    default:
 	      break;
 	    }
@@ -4096,10 +4120,10 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu)
       }
       break;
     case DW_TAG_variable:
-      if (pdi->locdesc)
-	addr = decode_locdesc (pdi->locdesc, cu);
+      if (pdi->d.locdesc)
+	addr = decode_locdesc (pdi->d.locdesc, cu);
 
-      if (pdi->locdesc
+      if (pdi->d.locdesc
 	  && addr == 0
 	  && !dwarf2_per_objfile->has_section_at_zero)
 	{
@@ -4123,7 +4147,7 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu)
 	     used by GDB, but it comes in handy for debugging partial symbol
 	     table building.  */
 
-	  if (pdi->locdesc || pdi->has_type)
+	  if (pdi->d.locdesc || pdi->has_type)
 	    add_psymbol_to_list (actual_name, strlen (actual_name),
 				 built_actual_name,
 				 VAR_DOMAIN, LOC_STATIC,
@@ -4134,7 +4158,7 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu)
       else
 	{
 	  /* Static Variable.  Skip symbols without location descriptors.  */
-	  if (pdi->locdesc == NULL)
+	  if (pdi->d.locdesc == NULL)
 	    {
 	      if (built_actual_name)
 		xfree (actual_name);
@@ -4912,6 +4936,7 @@ process_die (struct die_info *die, struct dwarf2_cu *cu)
     case DW_TAG_padding:
       break;
     case DW_TAG_compile_unit:
+    case DW_TAG_partial_unit:
       read_file_scope (die, cu);
       break;
     case DW_TAG_type_unit:
@@ -5639,7 +5664,7 @@ handle_DW_AT_stmt_list (struct die_info *die, struct dwarf2_cu *cu,
     }
 }
 
-/* Process DW_TAG_compile_unit.  */
+/* Process DW_TAG_compile_unit or DW_TAG_partial_unit.  */
 
 static void
 read_file_scope (struct die_info *die, struct dwarf2_cu *cu)
@@ -9607,7 +9632,8 @@ load_partial_dies (bfd *abfd, gdb_byte *buffer, gdb_byte *info_ptr,
 	  && abbrev->tag != DW_TAG_variable
 	  && abbrev->tag != DW_TAG_namespace
 	  && abbrev->tag != DW_TAG_module
-	  && abbrev->tag != DW_TAG_member)
+	  && abbrev->tag != DW_TAG_member
+	  && abbrev->tag != DW_TAG_imported_unit)
 	{
 	  /* Otherwise we skip to the next sibling, if any.  */
 	  info_ptr = skip_one_die (buffer, info_ptr + bytes_read, abbrev, cu);
@@ -9823,6 +9849,7 @@ read_partial_die (struct partial_die_info *part_die,
 	  switch (part_die->tag)
 	    {
 	    case DW_TAG_compile_unit:
+	    case DW_TAG_partial_unit:
 	    case DW_TAG_type_unit:
 	      /* Compilation units have a DW_AT_name that is a filename, not
 		 a source language identifier.  */
@@ -9860,7 +9887,7 @@ read_partial_die (struct partial_die_info *part_die,
           /* Support the .debug_loc offsets.  */
           if (attr_form_is_block (&attr))
             {
-	       part_die->locdesc = DW_BLOCK (&attr);
+	       part_die->d.locdesc = DW_BLOCK (&attr);
             }
           else if (attr_form_is_section_offset (&attr))
             {
@@ -9929,6 +9956,12 @@ read_partial_die (struct partial_die_info *part_die,
 	      || DW_UNSND (&attr) == DW_INL_declared_inlined)
 	    part_die->may_be_inlined = 1;
 	  break;
+
+	case DW_AT_import:
+	  if (part_die->tag == DW_TAG_imported_unit)
+	    part_die->d.offset = dwarf2_get_ref_die_offset (&attr);
+	  break;
+
 	default:
 	  break;
 	}
@@ -12706,6 +12739,7 @@ determine_prefix (struct die_info *die, struct dwarf2_cu *cu)
 	     So it does not need a prefix.  */
 	  return "";
       case DW_TAG_compile_unit:
+      case DW_TAG_partial_unit:
 	/* gcc-4.5 -gdwarf-4 can drop the enclosing namespace.  Cope.  */
 	if (cu->language == language_cplus
 	    && !VEC_empty (dwarf2_section_info_def, dwarf2_per_objfile->types)
@@ -12826,6 +12860,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
   switch (die->tag)
     {
     case DW_TAG_compile_unit:
+    case DW_TAG_partial_unit:
       /* Compilation units have a DW_AT_name that is a filename, not
 	 a source language identifier.  */
     case DW_TAG_enumeration_type:
@@ -12859,7 +12894,8 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
 	      if (die->tag == DW_TAG_class_type)
 		return dwarf2_name (die, cu);
 	    }
-	  while (die->tag != DW_TAG_compile_unit);
+	  while (die->tag != DW_TAG_compile_unit
+		 && die->tag != DW_TAG_partial_unit);
 	}
       break;
 
-- 
1.7.7.6


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]