public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [PATCH v2 00/42] Share DWARF partial symtabs between objfiles
@ 2020-05-12 21:08 Simon Marchi
  2020-05-12 21:08 ` [PATCH v2 01/42] Introduce dwarf2_per_objfile::obstack Simon Marchi
                   ` (45 more replies)
  0 siblings, 46 replies; 92+ messages in thread
From: Simon Marchi @ 2020-05-12 21:08 UTC (permalink / raw)
  To: gdb-patches; +Cc: Simon Marchi

This is version 2 of this patchset originally written by Tom:

    https://sourceware.org/legacy-ml/gdb-patches/2020-02/msg00594.html

The current patchset therefore contains a mix of Tom's patches that I modified,
plus a few new patches.  I won't repeat everything that is said in the cover
letter of that patchset, please read that to understand the motivation behind
this change..

The big difference between v1 and v2 is how the split is done.  In v1, the
object structure looks like this:

    objfile -> dwarf2_per_objfile -> dwarf2_unshareable

where `dwarf2_per_objfile` is actually shared between objfiles (there is one
copy per BFD), and `dwarf2_unshareable` is not (there is one copy per objfile).
The dwarf2_per_objfile -> dwarf2_unshareable link is updated at all entry
points of the DWARF code based on what is the current objfile.

The current patchset (v2) proposes this structure instead, which in my opinion
is more natural:

    objfile -> dwarf2_per_objfile -> dwarf2_per_bfd

Where `dwarf2_per_objfile` is really per-objfile (there is one copy per
objfile) and `dwarf2_per_bfd` is per-bfd (there is one copy per-bfd).  There is
no link to update, whatever is shared between objfiles is put in
`dwarf2_per_bfd` and each `dwarf2_per_objfile` always points to one
`dwarf2_per_bfd`.

Since there were performance numbers with the original patchset, I made my own
here to see if the speedups were still there.  Like in the original patchset, I
set "maintenance time 1" and did "add-inferior -exec ./gdb" after "./gdb gdb".
I disabled any auto-loading to avoid loading gdb-gdb.{gdb,py}.  GDB is built
with -O2 and gcc 9, and it is running on an AMD EPYC 7351P.

Before: Command execution time: 1.213480 (cpu), 1.214268 (wall)
After: Command execution time: 0.001697 (cpu), 0.001694 (wall)

These are the times of one run, but all runs I did are very close.  The "after"
time is surpringly low compared to the original numbers, I hope it doesn't mean
I messed up something and we are skipping something important...

At some point I tested with all these boards and did not see any regression
(they helped very much to find some issues in the process though):

    unix cc-with-debug-names cc-with-dwz cc-with-dwz-m cc-with-gdb-index dwarf4-gdb-index fission-dwp fission readnow

I have since rebased the patchset and resolved conflicts, it's therefore
possible I messed something up.

Simon Marchi (35):
  Split dwarf2_per_objfile into dwarf2_per_objfile and dwarf2_per_bfd
  Remove symtab links from dwarf2_psymtab and dwarf2_per_cu_quick_data
  Move die_type_hash to dwarf2_per_objfile
  Add dwarf2_per_objfile field to dwarf2_cu
  Remove reference to dwarf2_per_cu_data::dwarf2_per_objfile in
    dw2_do_instantiate_symtab
  Remove dwarf2_cu->per_cu->dwarf2_per_objfile references
  Add dwarf2_per_bfd field to dwarf2_per_cu_data
  Make dwarf2_get_dwz_file take a dwarf2_per_bfd
  Use bfd_get_filename instead of objfile_name in lookup_dwo_unit
  Add dwarf2_per_objfile parameter to cutu_reader's constructors
  Make queue_and_load_dwo_tu receive a dwarf2_cu
  Remove dwarf2_per_cu_data::dwarf2_per_objfile reference in
    cutu_reader::keep
  Add dwarf2_per_objfile parameter to create_partial_symtab
  Add dwarf2_per_objfile parameter to recursively_compute_inclusions
  Add dwarf2_per_objfile parameter to process_full_{comp,type}_unit
  Pass dwarf2_cu objects to dwo-related functions, instead of
    dwarf2_per_cu_data
  Remove reference to dwarf2_per_cu_data::dwarf2_per_objfile in
    queue_and_load_all_dwo_tus
  Move int type methods out of dwarf2_per_cu_data
  Add dwarf2_per_objfile to dwarf_expr_context and dwarf2_frame_cache
  Remove dwarf2_per_cu_data::text_offset
  Add dwarf2_per_objfile parameter to dwarf2_read_addr_index
  Add dwarf2_per_objfile parameter to allocate_piece_closure
  Add dwarf2_per_objfile parameters to dwarf2_fetch_* functions
  Remove dwarf2_per_cu_data::objfile ()
  Add dwarf2_per_objfile parameter to free_one_cached_comp_unit
  Add dwarf2_per_objfile parameter to get_die_type_at_offset
  Remove leftover references to dwarf2_per_cu_data::dwarf2_per_objfile
  Remove dwarf2_per_cu_data::dwarf2_per_objfile
  Pass dwarf2_per_bfd instead of dwarf2_per_objfile to some
    index-related functions
  Pass dwarf2_cu to process_full_{comp,type}_unit
  Make load_cu return the loaded dwarf2_cu
  Add comp_unit_head to dwarf2_per_cu_data
  Pass existing_cu object to cutu_reader
  Replace dwarf2_per_cu_data::cu backlink with per-objfile map
  Make mapped_debug_names independent of objfile

Tom Tromey (7):
  Introduce dwarf2_per_objfile::obstack
  Add "objfile" parameter to two partial_symtab methods
  Add dwarf2_per_cu_data::index
  Add dwarf2_per_objfile member to DWARF batons
  Split type_unit_group
  Move signatured_type::type to unshareable object
  Share DWARF partial symtabs

 gdb/compile/compile-loc2c.c |   20 +-
 gdb/compile/compile.h       |   13 +-
 gdb/dwarf2/expr.c           |   11 +-
 gdb/dwarf2/expr.h           |   11 +-
 gdb/dwarf2/frame.c          |   67 +-
 gdb/dwarf2/index-cache.c    |    2 +-
 gdb/dwarf2/index-write.c    |   51 +-
 gdb/dwarf2/loc.c            |  289 ++--
 gdb/dwarf2/loc.h            |   11 +-
 gdb/dwarf2/macro.c          |   11 +-
 gdb/dwarf2/read.c           | 2490 ++++++++++++++++++-----------------
 gdb/dwarf2/read.h           |  298 +++--
 gdb/gdbtypes.h              |    8 +-
 gdb/objfiles.h              |    2 +-
 gdb/psympriv.h              |   19 +-
 gdb/psymtab.c               |   44 +-
 16 files changed, 1848 insertions(+), 1499 deletions(-)

-- 
2.26.2


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

* [PATCH v2 01/42] Introduce dwarf2_per_objfile::obstack
  2020-05-12 21:08 [PATCH v2 00/42] Share DWARF partial symtabs between objfiles Simon Marchi
@ 2020-05-12 21:08 ` Simon Marchi
  2020-05-12 21:08 ` [PATCH v2 02/42] Add "objfile" parameter to two partial_symtab methods Simon Marchi
                   ` (44 subsequent siblings)
  45 siblings, 0 replies; 92+ messages in thread
From: Simon Marchi @ 2020-05-12 21:08 UTC (permalink / raw)
  To: gdb-patches; +Cc: Tom Tromey

From: Tom Tromey <tom@tromey.com>

Currently much of the DWARF-related data is stored on the objfile
obstack.  This prevents sharing this data across objfiles, so this patch
adds a new obstack to dwarf2_per_objfile.  Note that the
dwarf2_per_objfile type is going to become "dwarf2_per_bfd" in a
subsequent patch, which is indeed going to be shared between objfiles.

One way to check whether this is correct is to look at the remaining
uses of objfile_obstack in the DWARF code and note that they all
appear in the "full CU" code paths.

The converse -- storing per-objfile data on the shared obstack -- is
not good, but it is just a memory leak, not a potential
use-after-free.  Double-checking this would also be useful, though.

2020-02-21  Tom Tromey  <tom@tromey.com>

	* dwarf2/read.h (struct dwarf2_per_objfile) <obstack>: New
	member.
	* dwarf2/read.c (delete_file_name_entry): Fix comment.
	(create_cu_from_index_list)
	(create_signatured_type_table_from_index)
	(create_signatured_type_table_from_debug_names)
	(dw2_get_file_names_reader, dwarf2_initialize_objfile)
	(dwarf2_create_include_psymtab)
	(create_debug_type_hash_table, add_type_unit)
	(create_type_unit_group, read_comp_units_from_section)
	(dwarf2_compute_name, create_cus_hash_table)
	(create_dwp_hash_table, create_dwo_unit_in_dwp_v1)
	(create_dwo_unit_in_dwp_v2, open_and_init_dwp_file): Use new
	obstack.
	(dw2_get_real_path): Likewise.  Change argument to
	dwarf2_per_objfile.
---
 gdb/dwarf2/read.c | 94 +++++++++++++++++++++--------------------------
 gdb/dwarf2/read.h |  5 +++
 2 files changed, 47 insertions(+), 52 deletions(-)

diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 27bf40a898d..0c28fd2cfc7 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -2276,8 +2276,8 @@ delete_file_name_entry (void *e)
 	xfree ((void*) file_data->real_names[i]);
     }
 
-  /* The space for the struct itself lives on objfile_obstack,
-     so we don't free it here.  */
+  /* The space for the struct itself lives on the obstack, so we don't
+     free it here.  */
 }
 
 /* Create a quick_file_names hash table.  */
@@ -2408,9 +2408,8 @@ dwarf2_per_objfile::get_tu (int index)
   return this->all_type_units[index];
 }
 
-/* Return a new dwarf2_per_cu_data allocated on OBJFILE's
-   objfile_obstack, and constructed with the specified field
-   values.  */
+/* Return a new dwarf2_per_cu_data allocated on the dwarf2_per_objfile
+   obstack, and constructed with the specified field values.  */
 
 static dwarf2_per_cu_data *
 create_cu_from_index_list (struct dwarf2_per_objfile *dwarf2_per_objfile,
@@ -2418,16 +2417,15 @@ create_cu_from_index_list (struct dwarf2_per_objfile *dwarf2_per_objfile,
                           int is_dwz,
                           sect_offset sect_off, ULONGEST length)
 {
-  struct objfile *objfile = dwarf2_per_objfile->objfile;
   dwarf2_per_cu_data *the_cu
-    = OBSTACK_ZALLOC (&objfile->objfile_obstack,
+    = OBSTACK_ZALLOC (&dwarf2_per_objfile->obstack,
                      struct dwarf2_per_cu_data);
   the_cu->sect_off = sect_off;
   the_cu->length = length;
   the_cu->dwarf2_per_objfile = dwarf2_per_objfile;
   the_cu->section = section;
-  the_cu->v.quick = OBSTACK_ZALLOC (&objfile->objfile_obstack,
-                                   struct dwarf2_per_cu_quick_data);
+  the_cu->v.quick = OBSTACK_ZALLOC (&dwarf2_per_objfile->obstack,
+				    struct dwarf2_per_cu_quick_data);
   the_cu->is_dwz = is_dwz;
   return the_cu;
 }
@@ -2489,8 +2487,6 @@ create_signatured_type_table_from_index
    const gdb_byte *bytes,
    offset_type elements)
 {
-  struct objfile *objfile = dwarf2_per_objfile->objfile;
-
   gdb_assert (dwarf2_per_objfile->all_type_units.empty ());
   dwarf2_per_objfile->all_type_units.reserve (elements / 3);
 
@@ -2512,7 +2508,7 @@ create_signatured_type_table_from_index
       signature = extract_unsigned_integer (bytes + 16, 8, BFD_ENDIAN_LITTLE);
       bytes += 3 * 8;
 
-      sig_type = OBSTACK_ZALLOC (&objfile->objfile_obstack,
+      sig_type = OBSTACK_ZALLOC (&dwarf2_per_objfile->obstack,
 				 struct signatured_type);
       sig_type->signature = signature;
       sig_type->type_offset_in_tu = type_offset_in_tu;
@@ -2521,7 +2517,7 @@ create_signatured_type_table_from_index
       sig_type->per_cu.sect_off = sect_off;
       sig_type->per_cu.dwarf2_per_objfile = dwarf2_per_objfile;
       sig_type->per_cu.v.quick
-	= OBSTACK_ZALLOC (&objfile->objfile_obstack,
+	= OBSTACK_ZALLOC (&dwarf2_per_objfile->obstack,
 			  struct dwarf2_per_cu_quick_data);
 
       slot = htab_find_slot (sig_types_hash.get (), sig_type, INSERT);
@@ -2569,7 +2565,7 @@ create_signatured_type_table_from_debug_names
 				     section->buffer + to_underlying (sect_off),
 				     rcuh_kind::TYPE);
 
-      sig_type = OBSTACK_ZALLOC (&objfile->objfile_obstack,
+      sig_type = OBSTACK_ZALLOC (&dwarf2_per_objfile->obstack,
 				 struct signatured_type);
       sig_type->signature = cu_header.signature;
       sig_type->type_offset_in_tu = cu_header.type_cu_offset_in_tu;
@@ -2578,7 +2574,7 @@ create_signatured_type_table_from_debug_names
       sig_type->per_cu.sect_off = sect_off;
       sig_type->per_cu.dwarf2_per_objfile = dwarf2_per_objfile;
       sig_type->per_cu.v.quick
-	= OBSTACK_ZALLOC (&objfile->objfile_obstack,
+	= OBSTACK_ZALLOC (&dwarf2_per_objfile->obstack,
 			  struct dwarf2_per_cu_quick_data);
 
       slot = htab_find_slot (sig_types_hash.get (), sig_type, INSERT);
@@ -3088,7 +3084,6 @@ dw2_get_file_names_reader (const struct die_reader_specs *reader,
   struct dwarf2_per_cu_data *this_cu = cu->per_cu;
   struct dwarf2_per_objfile *dwarf2_per_objfile
     = cu->per_cu->dwarf2_per_objfile;
-  struct objfile *objfile = dwarf2_per_objfile->objfile;
   struct dwarf2_per_cu_data *lh_cu;
   struct attribute *attr;
   void **slot;
@@ -3137,7 +3132,7 @@ dw2_get_file_names_reader (const struct die_reader_specs *reader,
       return;
     }
 
-  qfn = XOBNEW (&objfile->objfile_obstack, struct quick_file_names);
+  qfn = XOBNEW (&dwarf2_per_objfile->obstack, struct quick_file_names);
   qfn->hash.dwo_unit = cu->dwo_unit;
   qfn->hash.line_sect_off = line_offset;
   gdb_assert (slot != NULL);
@@ -3151,7 +3146,8 @@ dw2_get_file_names_reader (const struct die_reader_specs *reader,
 
   qfn->num_file_names = offset + lh->file_names_size ();
   qfn->file_names =
-    XOBNEWVEC (&objfile->objfile_obstack, const char *, qfn->num_file_names);
+    XOBNEWVEC (&dwarf2_per_objfile->obstack, const char *,
+	       qfn->num_file_names);
   if (offset != 0)
     qfn->file_names[0] = xstrdup (fnd.name);
   for (int i = 0; i < lh->file_names_size (); ++i)
@@ -3192,11 +3188,11 @@ dw2_get_file_names (struct dwarf2_per_cu_data *this_cu)
    real path for a given file name from the line table.  */
 
 static const char *
-dw2_get_real_path (struct objfile *objfile,
+dw2_get_real_path (struct dwarf2_per_objfile *dwarf2_per_objfile,
 		   struct quick_file_names *qfn, int index)
 {
   if (qfn->real_names == NULL)
-    qfn->real_names = OBSTACK_CALLOC (&objfile->objfile_obstack,
+    qfn->real_names = OBSTACK_CALLOC (&dwarf2_per_objfile->obstack,
 				      qfn->num_file_names, const char *);
 
   if (qfn->real_names[index] == NULL)
@@ -3316,7 +3312,8 @@ dw2_map_symtabs_matching_filename
 	      && FILENAME_CMP (lbasename (this_name), name_basename) != 0)
 	    continue;
 
-	  this_real_name = dw2_get_real_path (objfile, file_data, j);
+	  this_real_name = dw2_get_real_path (dwarf2_per_objfile,
+					      file_data, j);
 	  if (compare_filenames_for_search (this_real_name, name))
 	    {
 	      if (dw2_map_expand_apply (objfile, per_cu, name, real_path,
@@ -4563,8 +4560,6 @@ dw_expand_symtabs_matching_file_matcher
   if (file_matcher == NULL)
     return;
 
-  objfile *const objfile = dwarf2_per_objfile->objfile;
-
   htab_up visited_found (htab_create_alloc (10, htab_hash_pointer,
 					    htab_eq_pointer,
 					    NULL, xcalloc, xfree));
@@ -4614,7 +4609,8 @@ dw_expand_symtabs_matching_file_matcher
 				true))
 	    continue;
 
-	  this_real_name = dw2_get_real_path (objfile, file_data, j);
+	  this_real_name = dw2_get_real_path (dwarf2_per_objfile,
+					      file_data, j);
 	  if (file_matcher (this_real_name, false))
 	    {
 	      per_cu->v.quick->mark = 1;
@@ -5837,7 +5833,7 @@ dwarf2_initialize_objfile (struct objfile *objfile, dw_index_kind *index_kind)
 	{
 	  dwarf2_per_cu_data *per_cu = dwarf2_per_objfile->get_cutu (i);
 
-	  per_cu->v.quick = OBSTACK_ZALLOC (&objfile->objfile_obstack,
+	  per_cu->v.quick = OBSTACK_ZALLOC (&dwarf2_per_objfile->obstack,
 					    struct dwarf2_per_cu_quick_data);
 	}
 
@@ -6038,10 +6034,7 @@ dwarf2_create_include_psymtab (const char *name, dwarf2_psymtab *pst,
   dwarf2_include_psymtab *subpst = new dwarf2_include_psymtab (name, objfile);
 
   if (!IS_ABSOLUTE_PATH (subpst->filename))
-    {
-      /* It shares objfile->objfile_obstack.  */
-      subpst->dirname = pst->dirname;
-    }
+    subpst->dirname = pst->dirname;
 
   subpst->dependencies = objfile->partial_symtabs->allocate_dependencies (1);
   subpst->dependencies[0] = pst;
@@ -6199,7 +6192,7 @@ create_debug_type_hash_table (struct dwarf2_per_objfile *dwarf2_per_objfile,
       if (dwo_file)
 	{
 	  sig_type = NULL;
-	  dwo_tu = OBSTACK_ZALLOC (&objfile->objfile_obstack,
+	  dwo_tu = OBSTACK_ZALLOC (&dwarf2_per_objfile->obstack,
 				   struct dwo_unit);
 	  dwo_tu->dwo_file = dwo_file;
 	  dwo_tu->signature = header.signature;
@@ -6213,7 +6206,7 @@ create_debug_type_hash_table (struct dwarf2_per_objfile *dwarf2_per_objfile,
 	  /* N.B.: type_offset is not usable if this type uses a DWO file.
 	     The real type_offset is in the DWO file.  */
 	  dwo_tu = NULL;
-	  sig_type = OBSTACK_ZALLOC (&objfile->objfile_obstack,
+	  sig_type = OBSTACK_ZALLOC (&dwarf2_per_objfile->obstack,
 				     struct signatured_type);
 	  sig_type->signature = header.signature;
 	  sig_type->type_offset_in_tu = header.type_cu_offset_in_tu;
@@ -6325,13 +6318,11 @@ static struct signatured_type *
 add_type_unit (struct dwarf2_per_objfile *dwarf2_per_objfile, ULONGEST sig,
 	       void **slot)
 {
-  struct objfile *objfile = dwarf2_per_objfile->objfile;
-
   if (dwarf2_per_objfile->all_type_units.size ()
       == dwarf2_per_objfile->all_type_units.capacity ())
     ++dwarf2_per_objfile->tu_stats.nr_all_type_units_reallocs;
 
-  signatured_type *sig_type = OBSTACK_ZALLOC (&objfile->objfile_obstack,
+  signatured_type *sig_type = OBSTACK_ZALLOC (&dwarf2_per_objfile->obstack,
 					      struct signatured_type);
 
   dwarf2_per_objfile->all_type_units.push_back (sig_type);
@@ -6340,7 +6331,7 @@ add_type_unit (struct dwarf2_per_objfile *dwarf2_per_objfile, ULONGEST sig,
   if (dwarf2_per_objfile->using_index)
     {
       sig_type->per_cu.v.quick =
-	OBSTACK_ZALLOC (&objfile->objfile_obstack,
+	OBSTACK_ZALLOC (&dwarf2_per_objfile->obstack,
 			struct dwarf2_per_cu_quick_data);
     }
 
@@ -7198,18 +7189,17 @@ create_type_unit_group (struct dwarf2_cu *cu, sect_offset line_offset_struct)
 {
   struct dwarf2_per_objfile *dwarf2_per_objfile
     = cu->per_cu->dwarf2_per_objfile;
-  struct objfile *objfile = dwarf2_per_objfile->objfile;
   struct dwarf2_per_cu_data *per_cu;
   struct type_unit_group *tu_group;
 
-  tu_group = OBSTACK_ZALLOC (&objfile->objfile_obstack,
+  tu_group = OBSTACK_ZALLOC (&dwarf2_per_objfile->obstack,
 			     struct type_unit_group);
   per_cu = &tu_group->per_cu;
   per_cu->dwarf2_per_objfile = dwarf2_per_objfile;
 
   if (dwarf2_per_objfile->using_index)
     {
-      per_cu->v.quick = OBSTACK_ZALLOC (&objfile->objfile_obstack,
+      per_cu->v.quick = OBSTACK_ZALLOC (&dwarf2_per_objfile->obstack,
 					struct dwarf2_per_cu_quick_data);
     }
   else
@@ -7939,13 +7929,13 @@ read_comp_units_from_section (struct dwarf2_per_objfile *dwarf2_per_objfile,
       /* Save the compilation unit for later lookup.  */
       if (cu_header.unit_type != DW_UT_type)
 	{
-	  this_cu = XOBNEW (&objfile->objfile_obstack,
+	  this_cu = XOBNEW (&dwarf2_per_objfile->obstack,
 			    struct dwarf2_per_cu_data);
 	  memset (this_cu, 0, sizeof (*this_cu));
 	}
       else
 	{
-	  auto sig_type = XOBNEW (&objfile->objfile_obstack,
+	  auto sig_type = XOBNEW (&dwarf2_per_objfile->obstack,
 				  struct signatured_type);
 	  memset (sig_type, 0, sizeof (*sig_type));
 	  sig_type->signature = cu_header.signature;
@@ -10100,7 +10090,8 @@ dw2_linkage_name (struct die_info *die, struct dwarf2_cu *cu)
    For Ada, return the DIE's linkage name rather than the fully qualified
    name.  PHYSNAME is ignored..
 
-   The result is allocated on the objfile_obstack and canonicalized.  */
+   The result is allocated on the dwarf2_per_objfile obstack and
+   canonicalized.  */
 
 static const char *
 dwarf2_compute_name (const char *name,
@@ -11255,7 +11246,8 @@ create_cus_hash_table (struct dwarf2_per_objfile *dwarf2_per_objfile,
       if (cus_htab == NULL)
 	cus_htab = allocate_dwo_unit_table ();
 
-      dwo_unit = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct dwo_unit);
+      dwo_unit = OBSTACK_ZALLOC (&dwarf2_per_objfile->obstack,
+				 struct dwo_unit);
       *dwo_unit = read_unit;
       slot = htab_find_slot (cus_htab.get (), dwo_unit, INSERT);
       gdb_assert (slot != NULL);
@@ -11458,7 +11450,7 @@ create_dwp_hash_table (struct dwarf2_per_objfile *dwarf2_per_objfile,
 	     pulongest (nr_slots), dwp_file->name);
     }
 
-  htab = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct dwp_hash_table);
+  htab = OBSTACK_ZALLOC (&dwarf2_per_objfile->obstack, struct dwp_hash_table);
   htab->version = version;
   htab->nr_columns = nr_columns;
   htab->nr_units = nr_units;
@@ -11655,7 +11647,6 @@ create_dwo_unit_in_dwp_v1 (struct dwarf2_per_objfile *dwarf2_per_objfile,
 			   const char *comp_dir,
 			   ULONGEST signature, int is_debug_types)
 {
-  struct objfile *objfile = dwarf2_per_objfile->objfile;
   const struct dwp_hash_table *dwp_htab =
     is_debug_types ? dwp_file->tus : dwp_file->cus;
   bfd *dbfd = dwp_file->dbfd.get ();
@@ -11760,7 +11751,7 @@ create_dwo_unit_in_dwp_v1 (struct dwarf2_per_objfile *dwarf2_per_objfile,
 			      virtual_dwo_name.c_str ());
 	}
       dwo_file = new struct dwo_file;
-      dwo_file->dwo_name = objfile->intern (virtual_dwo_name);
+      dwo_file->dwo_name = dwarf2_per_objfile->objfile->intern (virtual_dwo_name);
       dwo_file->comp_dir = comp_dir;
       dwo_file->sections.abbrev = sections.abbrev;
       dwo_file->sections.line = sections.line;
@@ -11789,11 +11780,11 @@ create_dwo_unit_in_dwp_v1 (struct dwarf2_per_objfile *dwarf2_per_objfile,
       dwo_file = (struct dwo_file *) *dwo_file_slot;
     }
 
-  dwo_unit = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct dwo_unit);
+  dwo_unit = OBSTACK_ZALLOC (&dwarf2_per_objfile->obstack, struct dwo_unit);
   dwo_unit->dwo_file = dwo_file;
   dwo_unit->signature = signature;
   dwo_unit->section =
-    XOBNEW (&objfile->objfile_obstack, struct dwarf2_section_info);
+    XOBNEW (&dwarf2_per_objfile->obstack, struct dwarf2_section_info);
   *dwo_unit->section = sections.info_or_types;
   /* dwo_unit->{offset,length,type_offset_in_tu} are set later.  */
 
@@ -11854,7 +11845,6 @@ create_dwo_unit_in_dwp_v2 (struct dwarf2_per_objfile *dwarf2_per_objfile,
 			   const char *comp_dir,
 			   ULONGEST signature, int is_debug_types)
 {
-  struct objfile *objfile = dwarf2_per_objfile->objfile;
   const struct dwp_hash_table *dwp_htab =
     is_debug_types ? dwp_file->tus : dwp_file->cus;
   bfd *dbfd = dwp_file->dbfd.get ();
@@ -11955,7 +11945,7 @@ create_dwo_unit_in_dwp_v2 (struct dwarf2_per_objfile *dwarf2_per_objfile,
 			      virtual_dwo_name.c_str ());
 	}
       dwo_file = new struct dwo_file;
-      dwo_file->dwo_name = objfile->intern (virtual_dwo_name);
+      dwo_file->dwo_name = dwarf2_per_objfile->objfile->intern (virtual_dwo_name);
       dwo_file->comp_dir = comp_dir;
       dwo_file->sections.abbrev =
 	create_dwp_v2_section (dwarf2_per_objfile, &dwp_file->sections.abbrev,
@@ -11998,11 +11988,11 @@ create_dwo_unit_in_dwp_v2 (struct dwarf2_per_objfile *dwarf2_per_objfile,
       dwo_file = (struct dwo_file *) *dwo_file_slot;
     }
 
-  dwo_unit = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct dwo_unit);
+  dwo_unit = OBSTACK_ZALLOC (&dwarf2_per_objfile->obstack, struct dwo_unit);
   dwo_unit->dwo_file = dwo_file;
   dwo_unit->signature = signature;
   dwo_unit->section =
-    XOBNEW (&objfile->objfile_obstack, struct dwarf2_section_info);
+    XOBNEW (&dwarf2_per_objfile->obstack, struct dwarf2_section_info);
   *dwo_unit->section = create_dwp_v2_section (dwarf2_per_objfile,
 					      is_debug_types
 					      ? &dwp_file->sections.types
@@ -12508,7 +12498,7 @@ open_and_init_dwp_file (struct dwarf2_per_objfile *dwarf2_per_objfile)
 
   dwp_file->num_sections = elf_numsections (dwp_file->dbfd);
   dwp_file->elf_sections =
-    OBSTACK_CALLOC (&objfile->objfile_obstack,
+    OBSTACK_CALLOC (&dwarf2_per_objfile->obstack,
 		    dwp_file->num_sections, asection *);
 
   bfd_map_over_sections (dwp_file->dbfd.get (),
diff --git a/gdb/dwarf2/read.h b/gdb/dwarf2/read.h
index bd743acc715..8dbda90aa59 100644
--- a/gdb/dwarf2/read.h
+++ b/gdb/dwarf2/read.h
@@ -126,6 +126,11 @@ struct dwarf2_per_objfile
 			const dwarf2_debug_sections &names);
 
 public:
+  /* Objects that can be shared across objfiles are stored in this
+     obstack or on the psymtab obstack, while objects that are
+     objfile-specific are stored on the objfile obstack.  */
+  auto_obstack obstack;
+
   dwarf2_section_info info {};
   dwarf2_section_info abbrev {};
   dwarf2_section_info line {};
-- 
2.26.2


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

* [PATCH v2 02/42] Add "objfile" parameter to two partial_symtab methods
  2020-05-12 21:08 [PATCH v2 00/42] Share DWARF partial symtabs between objfiles Simon Marchi
  2020-05-12 21:08 ` [PATCH v2 01/42] Introduce dwarf2_per_objfile::obstack Simon Marchi
@ 2020-05-12 21:08 ` Simon Marchi
  2020-05-12 21:08 ` [PATCH v2 03/42] Add dwarf2_per_cu_data::index Simon Marchi
                   ` (43 subsequent siblings)
  45 siblings, 0 replies; 92+ messages in thread
From: Simon Marchi @ 2020-05-12 21:08 UTC (permalink / raw)
  To: gdb-patches; +Cc: Tom Tromey

From: Tom Tromey <tom@tromey.com>

This series will cause partial symtabs to be shared across objfiles.
However, full symtabs and symbols will still be objfile-dependent, so
will be expanded separately for each objfile.  So, a debug info reader
will need to know which objfile to consult when expanding a partial
symtab.

This patch adds an objfile parameter to the two relevant methods of
partial_symtab.  Current implementations simply ignore them.

2020-02-21  Tom Tromey  <tom@tromey.com>

	* psymtab.c (partial_map_expand_apply)
	(psym_find_pc_sect_compunit_symtab, psym_lookup_symbol)
	(psym_lookup_global_symbol_language)
	(psymtab_to_symtab, psym_find_last_source_symtab, dump_psymtab)
	(psym_print_stats, psym_expand_symtabs_for_function)
	(psym_map_symbol_filenames, psym_map_matching_symbols)
	(psym_expand_symtabs_matching)
	(partial_symtab::read_dependencies, maintenance_info_psymtabs)
	(maintenance_check_psymtabs): Update.
	* psympriv.h (struct partial_symtab) <readin_p,
	get_compunit_symtab>: Add objfile parameter.
	(struct standard_psymtab) <readin_p, get_compunit_symtab>:
	Likewise.
	* dwarf2/read.c (struct dwarf2_include_psymtab) <readin_p,
	get_compunit_symtab>: Likewise.
	(dwarf2_psymtab::expand_psymtab): Pass objfile argument.
---
 gdb/dwarf2/read.c |  8 ++++----
 gdb/psympriv.h    | 19 ++++++++++---------
 gdb/psymtab.c     | 44 ++++++++++++++++++++++----------------------
 3 files changed, 36 insertions(+), 35 deletions(-)

diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 0c28fd2cfc7..664520fbb4c 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -6004,12 +6004,12 @@ struct dwarf2_include_psymtab : public partial_symtab
     gdb_assert (false);
   }
 
-  bool readin_p () const override
+  bool readin_p (struct objfile *objfile) const override
   {
-    return includer ()->readin_p ();
+    return includer ()->readin_p (objfile);
   }
 
-  struct compunit_symtab *get_compunit_symtab () const override
+  compunit_symtab *get_compunit_symtab (struct objfile *objfile) const override
   {
     return nullptr;
   }
@@ -8951,7 +8951,7 @@ dwarf2_psymtab::expand_psymtab (struct objfile *objfile)
   expand_dependencies (objfile);
 
   dw2_do_instantiate_symtab (per_cu_data, false);
-  gdb_assert (get_compunit_symtab () != nullptr);
+  gdb_assert (get_compunit_symtab (objfile) != nullptr);
 }
 
 /* Trivial hash function for die_info: the hash value of a DIE
diff --git a/gdb/psympriv.h b/gdb/psympriv.h
index 6f0307e05b7..4622be389bd 100644
--- a/gdb/psympriv.h
+++ b/gdb/psympriv.h
@@ -147,13 +147,16 @@ struct partial_symtab
   void expand_dependencies (struct objfile *);
 
   /* Return true if the symtab corresponding to this psymtab has been
-     readin.  */
-  virtual bool readin_p () const = 0;
+     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.
-     Return nullptr if !readin or if there was no symtab.  */
-  virtual struct compunit_symtab *get_compunit_symtab () 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 raw low text address of this partial_symtab.  */
   CORE_ADDR raw_text_low () const
@@ -319,14 +322,12 @@ struct standard_psymtab : public partial_symtab
   {
   }
 
-  bool readin_p () const override
+  bool readin_p (struct objfile *) const override
   {
     return readin;
   }
 
-  /* Return a pointer to the compunit allocated for this source file.
-     Return nullptr if !readin or if there was no symtab.  */
-  struct compunit_symtab *get_compunit_symtab () const override
+  struct compunit_symtab *get_compunit_symtab (struct objfile *) const override
   {
     return compunit_symtab;
   }
diff --git a/gdb/psymtab.c b/gdb/psymtab.c
index 1fce7a39838..5960c593fcf 100644
--- a/gdb/psymtab.c
+++ b/gdb/psymtab.c
@@ -132,7 +132,7 @@ partial_map_expand_apply (struct objfile *objfile,
   gdb_assert (pst->user == NULL);
 
   /* Don't visit already-expanded psymtabs.  */
-  if (pst->readin_p ())
+  if (pst->readin_p (objfile))
     return 0;
 
   /* This may expand more than one symtab, and we want to iterate over
@@ -384,7 +384,7 @@ psym_find_pc_sect_compunit_symtab (struct objfile *objfile,
 						    msymbol);
   if (ps != NULL)
     {
-      if (warn_if_readin && ps->readin_p ())
+      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.  */
@@ -392,7 +392,7 @@ psym_find_pc_sect_compunit_symtab (struct objfile *objfile,
 (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 ();
+      return ps->get_compunit_symtab (objfile);
     }
   return NULL;
 }
@@ -485,9 +485,9 @@ psym_lookup_symbol (struct objfile *objfile,
 
   for (partial_symtab *ps : require_partial_symbols (objfile, true))
     {
-      if (!ps->readin_p () && lookup_partial_symbol (objfile, ps,
-						     psym_lookup_name,
-						     psymtab_index, domain))
+      if (!ps->readin_p (objfile)
+	  && lookup_partial_symbol (objfile, ps, psym_lookup_name,
+				    psymtab_index, domain))
 	{
 	  struct symbol *sym, *with_opaque = NULL;
 	  struct compunit_symtab *stab = psymtab_to_symtab (objfile, ps);
@@ -535,7 +535,7 @@ psym_lookup_global_symbol_language (struct objfile *objfile, const char *name,
   for (partial_symtab *ps : require_partial_symbols (objfile, true))
     {
       struct partial_symbol *psym;
-      if (ps->readin_p ())
+      if (ps->readin_p (objfile))
 	continue;
 
       psym = lookup_partial_symbol (objfile, ps, lookup_name, 1, domain);
@@ -748,11 +748,11 @@ psymtab_to_symtab (struct objfile *objfile, struct partial_symtab *pst)
     pst = pst->user;
 
   /* If it's been looked up before, return it.  */
-  if (pst->get_compunit_symtab ())
-    return pst->get_compunit_symtab ();
+  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 ())
+  if (!pst->readin_p (objfile))
     {
       scoped_restore decrementer = increment_reading_symtab ();
 
@@ -766,7 +766,7 @@ psymtab_to_symtab (struct objfile *objfile, struct partial_symtab *pst)
       pst->read_symtab (objfile);
     }
 
-  return pst->get_compunit_symtab ();
+  return pst->get_compunit_symtab (objfile);
 }
 
 /* Psymtab version of find_last_source_symtab.  See its definition in
@@ -789,7 +789,7 @@ psym_find_last_source_symtab (struct objfile *ofp)
 
   if (cs_pst)
     {
-      if (cs_pst->readin_p ())
+      if (cs_pst->readin_p (ofp))
 	{
 	  internal_error (__FILE__, __LINE__,
 			  _("select_source_symtab: "
@@ -946,11 +946,11 @@ dump_psymtab (struct objfile *objfile, struct partial_symtab *psymtab,
   gdb_print_host_address (objfile, outfile);
   fprintf_filtered (outfile, ")\n");
 
-  if (psymtab->readin_p ())
+  if (psymtab->readin_p (objfile))
     {
       fprintf_filtered (outfile,
 			"  Full symtab was read (at ");
-      gdb_print_host_address (psymtab->get_compunit_symtab (), outfile);
+      gdb_print_host_address (psymtab->get_compunit_symtab (objfile), outfile);
       fprintf_filtered (outfile, ")\n");
     }
 
@@ -1004,7 +1004,7 @@ psym_print_stats (struct objfile *objfile)
   i = 0;
   for (partial_symtab *ps : require_partial_symbols (objfile, true))
     {
-      if (!ps->readin_p ())
+      if (!ps->readin_p (objfile))
 	i++;
     }
   printf_filtered (_("  Number of psym tables (not yet expanded): %d\n"), i);
@@ -1047,7 +1047,7 @@ psym_expand_symtabs_for_function (struct objfile *objfile,
 
   for (partial_symtab *ps : require_partial_symbols (objfile, true))
     {
-      if (ps->readin_p ())
+      if (ps->readin_p (objfile))
 	continue;
 
       if ((lookup_partial_symbol (objfile, ps, lookup_name, 1, VAR_DOMAIN)
@@ -1102,7 +1102,7 @@ psym_map_symbol_filenames (struct objfile *objfile,
     {
       const char *fullname;
 
-      if (ps->readin_p ())
+      if (ps->readin_p (objfile))
 	continue;
 
       /* We can skip shared psymtabs here, because any file name will be
@@ -1182,7 +1182,7 @@ psym_map_matching_symbols
   for (partial_symtab *ps : require_partial_symbols (objfile, true))
     {
       QUIT;
-      if (ps->readin_p ()
+      if (ps->readin_p (objfile)
 	  || match_partial_symbol (objfile, ps, global, name, domain,
 				   ordered_compare))
 	{
@@ -1315,7 +1315,7 @@ psym_expand_symtabs_matching
     {
       QUIT;
 
-      if (ps->readin_p ())
+      if (ps->readin_p (objfile))
 	continue;
 
       /* We skip shared psymtabs because file-matching doesn't apply
@@ -1717,7 +1717,7 @@ partial_symtab::expand_dependencies (struct objfile *objfile)
 {
   for (int i = 0; i < number_of_dependencies; ++i)
     {
-      if (!dependencies[i]->readin_p ()
+      if (!dependencies[i]->readin_p (objfile)
 	  && dependencies[i]->user == NULL)
 	{
 	  /* Inform about additional files to be read in.  */
@@ -2028,7 +2028,7 @@ maintenance_info_psymtabs (const char *regexp, int from_tty)
 				 host_address_to_string (psymtab));
 
 		printf_filtered ("    readin %s\n",
-				 psymtab->readin_p () ? "yes" : "no");
+				 psymtab->readin_p (objfile) ? "yes" : "no");
 		printf_filtered ("    fullname %s\n",
 				 psymtab->fullname
 				 ? psymtab->fullname : "(null)");
@@ -2124,7 +2124,7 @@ maintenance_check_psymtabs (const char *ignore, int from_tty)
 	/* 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 ();
+	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))
-- 
2.26.2


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

* [PATCH v2 03/42] Add dwarf2_per_cu_data::index
  2020-05-12 21:08 [PATCH v2 00/42] Share DWARF partial symtabs between objfiles Simon Marchi
  2020-05-12 21:08 ` [PATCH v2 01/42] Introduce dwarf2_per_objfile::obstack Simon Marchi
  2020-05-12 21:08 ` [PATCH v2 02/42] Add "objfile" parameter to two partial_symtab methods Simon Marchi
@ 2020-05-12 21:08 ` Simon Marchi
  2020-05-12 21:08 ` [PATCH v2 04/42] Add dwarf2_per_objfile member to DWARF batons Simon Marchi
                   ` (42 subsequent siblings)
  45 siblings, 0 replies; 92+ messages in thread
From: Simon Marchi @ 2020-05-12 21:08 UTC (permalink / raw)
  To: gdb-patches; +Cc: Tom Tromey

From: Tom Tromey <tom@tromey.com>

Currently, a dwarf2_per_cu_data can hold a link to the corresponding
expanded compunit_symtab.  However, the dwarf2_per_cu_data objects are
shared across objfiles, a simple pointer won't work: each objfile
sharing the dwarf2_per_cu_data instance will have a corresponding
compunit_symtab.

Instead, this link will be stored in the dwarf2_per_objfile object
(which will contain the objfile-specific data).  To enable this, we add
an index to each dwarf2_per_cu_data and signatured_type.  The data
structure in the dwarf2_per_objfile will use this new index to map a
dwarf2_per_cu_data to its corresponding compunit_symtab, for this
objfile.

2020-02-21  Tom Tromey  <tom@tromey.com>

	* dwarf2/read.h (struct dwarf2_per_objfile) <allocate_per_cu,
	allocate_signatured_type>: Declare new methods.
	<m_num_psymtabs>: New member.
	(struct dwarf2_per_cu_data) <index>: New member.
	* dwarf2/read.c (dwarf2_per_objfile::allocate_per_cu)
	(dwarf2_per_objfile::allocate_signatured_type): New methods.
	(create_cu_from_index_list): Use allocate_per_cu.
	(create_signatured_type_table_from_index)
	(create_signatured_type_table_from_debug_names)
	(create_debug_type_hash_table, add_type_unit)
	(read_comp_units_from_section): Use allocate_signatured_type.
---
 gdb/dwarf2/read.c | 46 +++++++++++++++++++++++++++-------------------
 gdb/dwarf2/read.h | 19 +++++++++++++++++++
 2 files changed, 46 insertions(+), 19 deletions(-)

diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 664520fbb4c..9217f784b38 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -2408,6 +2408,26 @@ dwarf2_per_objfile::get_tu (int index)
   return this->all_type_units[index];
 }
 
+/* See read.h.  */
+
+dwarf2_per_cu_data *
+dwarf2_per_objfile::allocate_per_cu ()
+{
+  dwarf2_per_cu_data *result = OBSTACK_ZALLOC (&obstack, dwarf2_per_cu_data);
+  result->index = m_num_psymtabs++;
+  return result;
+}
+
+/* See read.h.  */
+
+signatured_type *
+dwarf2_per_objfile::allocate_signatured_type ()
+{
+  signatured_type *result = OBSTACK_ZALLOC (&obstack, signatured_type);
+  result->per_cu.index = m_num_psymtabs++;
+  return result;
+}
+
 /* Return a new dwarf2_per_cu_data allocated on the dwarf2_per_objfile
    obstack, and constructed with the specified field values.  */
 
@@ -2417,9 +2437,7 @@ create_cu_from_index_list (struct dwarf2_per_objfile *dwarf2_per_objfile,
                           int is_dwz,
                           sect_offset sect_off, ULONGEST length)
 {
-  dwarf2_per_cu_data *the_cu
-    = OBSTACK_ZALLOC (&dwarf2_per_objfile->obstack,
-                     struct dwarf2_per_cu_data);
+  dwarf2_per_cu_data *the_cu = dwarf2_per_objfile->allocate_per_cu ();
   the_cu->sect_off = sect_off;
   the_cu->length = length;
   the_cu->dwarf2_per_objfile = dwarf2_per_objfile;
@@ -2508,8 +2526,7 @@ create_signatured_type_table_from_index
       signature = extract_unsigned_integer (bytes + 16, 8, BFD_ENDIAN_LITTLE);
       bytes += 3 * 8;
 
-      sig_type = OBSTACK_ZALLOC (&dwarf2_per_objfile->obstack,
-				 struct signatured_type);
+      sig_type = dwarf2_per_objfile->allocate_signatured_type ();
       sig_type->signature = signature;
       sig_type->type_offset_in_tu = type_offset_in_tu;
       sig_type->per_cu.is_debug_types = 1;
@@ -2565,8 +2582,7 @@ create_signatured_type_table_from_debug_names
 				     section->buffer + to_underlying (sect_off),
 				     rcuh_kind::TYPE);
 
-      sig_type = OBSTACK_ZALLOC (&dwarf2_per_objfile->obstack,
-				 struct signatured_type);
+      sig_type = dwarf2_per_objfile->allocate_signatured_type ();
       sig_type->signature = cu_header.signature;
       sig_type->type_offset_in_tu = cu_header.type_cu_offset_in_tu;
       sig_type->per_cu.is_debug_types = 1;
@@ -6206,8 +6222,7 @@ create_debug_type_hash_table (struct dwarf2_per_objfile *dwarf2_per_objfile,
 	  /* N.B.: type_offset is not usable if this type uses a DWO file.
 	     The real type_offset is in the DWO file.  */
 	  dwo_tu = NULL;
-	  sig_type = OBSTACK_ZALLOC (&dwarf2_per_objfile->obstack,
-				     struct signatured_type);
+	  sig_type = dwarf2_per_objfile->allocate_signatured_type ();
 	  sig_type->signature = header.signature;
 	  sig_type->type_offset_in_tu = header.type_cu_offset_in_tu;
 	  sig_type->per_cu.dwarf2_per_objfile = dwarf2_per_objfile;
@@ -6322,8 +6337,7 @@ add_type_unit (struct dwarf2_per_objfile *dwarf2_per_objfile, ULONGEST sig,
       == dwarf2_per_objfile->all_type_units.capacity ())
     ++dwarf2_per_objfile->tu_stats.nr_all_type_units_reallocs;
 
-  signatured_type *sig_type = OBSTACK_ZALLOC (&dwarf2_per_objfile->obstack,
-					      struct signatured_type);
+  signatured_type *sig_type = dwarf2_per_objfile->allocate_signatured_type ();
 
   dwarf2_per_objfile->all_type_units.push_back (sig_type);
   sig_type->signature = sig;
@@ -7928,16 +7942,10 @@ read_comp_units_from_section (struct dwarf2_per_objfile *dwarf2_per_objfile,
 
       /* Save the compilation unit for later lookup.  */
       if (cu_header.unit_type != DW_UT_type)
-	{
-	  this_cu = XOBNEW (&dwarf2_per_objfile->obstack,
-			    struct dwarf2_per_cu_data);
-	  memset (this_cu, 0, sizeof (*this_cu));
-	}
+	this_cu = dwarf2_per_objfile->allocate_per_cu ();
       else
 	{
-	  auto sig_type = XOBNEW (&dwarf2_per_objfile->obstack,
-				  struct signatured_type);
-	  memset (sig_type, 0, sizeof (*sig_type));
+	  auto sig_type = dwarf2_per_objfile->allocate_signatured_type ();
 	  sig_type->signature = cu_header.signature;
 	  sig_type->type_offset_in_tu = cu_header.type_cu_offset_in_tu;
 	  this_cu = &sig_type->per_cu;
diff --git a/gdb/dwarf2/read.h b/gdb/dwarf2/read.h
index 8dbda90aa59..bbc4f96b7cf 100644
--- a/gdb/dwarf2/read.h
+++ b/gdb/dwarf2/read.h
@@ -111,6 +111,16 @@ struct dwarf2_per_objfile
   /* Free all cached compilation units.  */
   void free_cached_comp_units ();
 
+  /* A convenience function to allocate a dwarf2_per_cu_data.  The
+     returned object has its "index" field set properly.  The object
+     is allocated on the dwarf2_per_objfile obstack.  */
+  dwarf2_per_cu_data *allocate_per_cu ();
+
+  /* A convenience function to allocate a signatured_type.  The
+     returned object has its "index" field set properly.  The object
+     is allocated on the dwarf2_per_objfile obstack.  */
+  signatured_type *allocate_signatured_type ();
+
   /* Return pointer to string at .debug_line_str offset as read from BUF.
      BUF is assumed to be in a compilation unit described by CU_HEADER.
      Return *BYTES_READ_PTR count of bytes read from BUF.  */
@@ -249,6 +259,12 @@ struct dwarf2_per_objfile
 
   /* CUs that are queued to be read.  */
   std::queue<dwarf2_queue_item> queue;
+
+private:
+
+  /* The total number of per_cu and signatured_type objects that have
+     been created so far for this reader.  */
+  size_t m_num_psymtabs = 0;
 };
 
 /* Get the dwarf2_per_objfile associated to OBJFILE.  */
@@ -322,6 +338,9 @@ struct dwarf2_per_cu_data
      This flag is only valid if is_debug_types is true.  */
   unsigned int tu_read : 1;
 
+  /* Our index in the unshared "symtabs" vector.  */
+  unsigned index;
+
   /* The section this CU/TU lives in.
      If the DIE refers to a DWO file, this is always the original die,
      not the DWO file.  */
-- 
2.26.2


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

* [PATCH v2 04/42] Add dwarf2_per_objfile member to DWARF batons
  2020-05-12 21:08 [PATCH v2 00/42] Share DWARF partial symtabs between objfiles Simon Marchi
                   ` (2 preceding siblings ...)
  2020-05-12 21:08 ` [PATCH v2 03/42] Add dwarf2_per_cu_data::index Simon Marchi
@ 2020-05-12 21:08 ` Simon Marchi
  2020-05-12 21:08 ` [PATCH v2 05/42] Split dwarf2_per_objfile into dwarf2_per_objfile and dwarf2_per_bfd Simon Marchi
                   ` (41 subsequent siblings)
  45 siblings, 0 replies; 92+ messages in thread
From: Simon Marchi @ 2020-05-12 21:08 UTC (permalink / raw)
  To: gdb-patches; +Cc: Tom Tromey

From: Tom Tromey <tom@tromey.com>

Various DWARF callbacks expect to be able to fetch the objfile and / or
dwarf2_per_objfile from the DWARF CU object.  However, this won't be
possible once sharing is implemented.

Because these objects are related to full symbols (e.g., they are used
to implement location expressions), they can simply store the
dwarf2_per_objfile they need.

This patch adds a per_objfile member to the various "baton" structures
and arranges to set this value when constructing the baton.

YYYY-MM-DD  Tom Tromey  <tom@tromey.com>
YYYY-MM-DD  Simon Marchi  <simon.marchi@efficios.com>

	* dwarf2/loc.c (struct piece_closure) <per_objfile>: New member.
	(allocate_piece_closure): Set "per_objfile" member.
	(dwarf2_find_location_expression, dwarf2_locexpr_baton_eval)
	(locexpr_describe_location, loclist_describe_location): Use new
	member.
	* dwarf2/read.c (read_call_site_scope)
	(mark_common_block_symbol_computed, attr_to_dynamic_prop)
	(dwarf2_const_value_attr, dwarf2_fetch_die_loc_sect_off)
	(fill_in_loclist_baton, dwarf2_symbol_mark_computed): Set
	per_objfile member.
	* dwarf2/loc.h (struct dwarf2_locexpr_baton) <per_objfile>: New
	member.
	(struct dwarf2_loclist_baton) <per_objfile>: New member.
---
 gdb/dwarf2/loc.c  | 16 ++++++++++++----
 gdb/dwarf2/loc.h  |  8 +++++++-
 gdb/dwarf2/read.c | 24 +++++++++++++++++-------
 3 files changed, 36 insertions(+), 12 deletions(-)

diff --git a/gdb/dwarf2/loc.c b/gdb/dwarf2/loc.c
index 5b690ca9276..e4a9ee90311 100644
--- a/gdb/dwarf2/loc.c
+++ b/gdb/dwarf2/loc.c
@@ -317,7 +317,8 @@ const gdb_byte *
 dwarf2_find_location_expression (struct dwarf2_loclist_baton *baton,
 				 size_t *locexpr_length, CORE_ADDR pc)
 {
-  struct objfile *objfile = baton->per_cu->objfile ();
+  dwarf2_per_objfile *per_objfile = baton->per_objfile;
+  struct objfile *objfile = per_objfile->objfile;
   struct gdbarch *gdbarch = objfile->arch ();
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   unsigned int addr_size = baton->per_cu->addr_size ();
@@ -1552,6 +1553,9 @@ struct piece_closure
   /* Reference count.  */
   int refc = 0;
 
+  /* The objfile from which this closure's expression came.  */
+  dwarf2_per_objfile *per_objfile = nullptr;
+
   /* The CU from which this closure's expression came.  */
   struct dwarf2_per_cu_data *per_cu = NULL;
 
@@ -1574,6 +1578,8 @@ allocate_piece_closure (struct dwarf2_per_cu_data *per_cu,
   struct piece_closure *c = new piece_closure;
 
   c->refc = 1;
+  /* We must capture this here due to sharing of DWARF state.  */
+  c->per_objfile = per_cu->dwarf2_per_objfile;
   c->per_cu = per_cu;
   c->pieces = std::move (pieces);
   if (frame == NULL)
@@ -2454,7 +2460,7 @@ dwarf2_locexpr_baton_eval (const struct dwarf2_locexpr_baton *dlbaton,
       ctx.data_view = addr_stack->valaddr;
     }
 
-  objfile = dlbaton->per_cu->objfile ();
+  objfile = dlbaton->per_objfile->objfile;
 
   ctx.gdbarch = objfile->arch ();
   ctx.addr_size = dlbaton->per_cu->addr_size ();
@@ -4348,7 +4354,8 @@ locexpr_describe_location (struct symbol *symbol, CORE_ADDR addr,
 {
   struct dwarf2_locexpr_baton *dlbaton
     = (struct dwarf2_locexpr_baton *) SYMBOL_LOCATION_BATON (symbol);
-  struct objfile *objfile = dlbaton->per_cu->objfile ();
+  dwarf2_per_objfile *per_objfile = dlbaton->per_objfile;
+  struct objfile *objfile = per_objfile->objfile;
   unsigned int addr_size = dlbaton->per_cu->addr_size ();
   int offset_size = dlbaton->per_cu->offset_size ();
 
@@ -4485,7 +4492,8 @@ loclist_describe_location (struct symbol *symbol, CORE_ADDR addr,
   struct dwarf2_loclist_baton *dlbaton
     = (struct dwarf2_loclist_baton *) SYMBOL_LOCATION_BATON (symbol);
   const gdb_byte *loc_ptr, *buf_end;
-  struct objfile *objfile = dlbaton->per_cu->objfile ();
+  dwarf2_per_objfile *per_objfile = dlbaton->per_objfile;
+  struct objfile *objfile = per_objfile->objfile;
   struct gdbarch *gdbarch = objfile->arch ();
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   unsigned int addr_size = dlbaton->per_cu->addr_size ();
diff --git a/gdb/dwarf2/loc.h b/gdb/dwarf2/loc.h
index 9815368d625..51f242ec431 100644
--- a/gdb/dwarf2/loc.h
+++ b/gdb/dwarf2/loc.h
@@ -23,7 +23,7 @@
 #include "dwarf2/expr.h"
 
 struct symbol_computed_ops;
-struct objfile;
+struct dwarf2_per_objfile;
 struct dwarf2_per_cu_data;
 struct dwarf2_loclist_baton;
 struct agent_expr;
@@ -146,6 +146,9 @@ struct dwarf2_locexpr_baton
      directly.  */
   bool is_reference;
 
+  /* The objfile that was used when creating this.  */
+  dwarf2_per_objfile *per_objfile;
+
   /* The compilation unit containing the symbol whose location
      we're computing.  */
   struct dwarf2_per_cu_data *per_cu;
@@ -163,6 +166,9 @@ struct dwarf2_loclist_baton
   /* Length of the location list.  */
   size_t size;
 
+  /* The objfile that was used when creating this.  */
+  dwarf2_per_objfile *per_objfile;
+
   /* The compilation unit containing the symbol whose location
      we're computing.  */
   struct dwarf2_per_cu_data *per_cu;
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 9217f784b38..4699645c6fc 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -13199,7 +13199,8 @@ read_lexical_block_scope (struct die_info *die, struct dwarf2_cu *cu)
 static void
 read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
 {
-  struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+  dwarf2_per_objfile *per_objfile = cu->per_cu->dwarf2_per_objfile;
+  struct objfile *objfile = per_objfile->objfile;
   struct gdbarch *gdbarch = objfile->arch ();
   CORE_ADDR pc, baseaddr;
   struct attribute *attr;
@@ -13339,6 +13340,7 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
       dlbaton = XOBNEW (&objfile->objfile_obstack, struct dwarf2_locexpr_baton);
       dlbaton->data = DW_BLOCK (attr)->data;
       dlbaton->size = DW_BLOCK (attr)->size;
+      dlbaton->per_objfile = per_objfile;
       dlbaton->per_cu = cu->per_cu;
 
       SET_FIELD_DWARF_BLOCK (call_site->target, dlbaton);
@@ -16274,9 +16276,8 @@ mark_common_block_symbol_computed (struct symbol *sym,
 				   struct attribute *member_loc,
 				   struct dwarf2_cu *cu)
 {
-  struct dwarf2_per_objfile *dwarf2_per_objfile
-    = cu->per_cu->dwarf2_per_objfile;
-  struct objfile *objfile = dwarf2_per_objfile->objfile;
+  dwarf2_per_objfile *per_objfile = cu->per_cu->dwarf2_per_objfile;
+  struct objfile *objfile = per_objfile->objfile;
   struct dwarf2_locexpr_baton *baton;
   gdb_byte *ptr;
   unsigned int cu_off;
@@ -16289,6 +16290,7 @@ mark_common_block_symbol_computed (struct symbol *sym,
 	      || member_loc->form_is_constant ());
 
   baton = XOBNEW (&objfile->objfile_obstack, struct dwarf2_locexpr_baton);
+  baton->per_objfile = per_objfile;
   baton->per_cu = cu->per_cu;
   gdb_assert (baton->per_cu);
 
@@ -17412,8 +17414,9 @@ attr_to_dynamic_prop (const struct attribute *attr, struct die_info *die,
 		      struct type *default_type)
 {
   struct dwarf2_property_baton *baton;
-  struct obstack *obstack
-    = &cu->per_cu->dwarf2_per_objfile->objfile->objfile_obstack;
+  dwarf2_per_objfile *per_objfile = cu->per_cu->dwarf2_per_objfile;
+  struct objfile *objfile = per_objfile->objfile;
+  struct obstack *obstack = &objfile->objfile_obstack;
 
   gdb_assert (default_type != NULL);
 
@@ -17425,6 +17428,7 @@ attr_to_dynamic_prop (const struct attribute *attr, struct die_info *die,
       baton = XOBNEW (obstack, struct dwarf2_property_baton);
       baton->property_type = default_type;
       baton->locexpr.per_cu = cu->per_cu;
+      baton->locexpr.per_objfile = per_objfile;
       baton->locexpr.size = DW_BLOCK (attr)->size;
       baton->locexpr.data = DW_BLOCK (attr)->data;
       switch (attr->name)
@@ -17471,6 +17475,7 @@ attr_to_dynamic_prop (const struct attribute *attr, struct die_info *die,
 		baton = XOBNEW (obstack, struct dwarf2_property_baton);
 		baton->property_type = die_type (target_die, target_cu);
 		baton->locexpr.per_cu = cu->per_cu;
+		baton->locexpr.per_objfile = per_objfile;
 		baton->locexpr.size = DW_BLOCK (target_attr)->size;
 		baton->locexpr.data = DW_BLOCK (target_attr)->data;
 		baton->locexpr.is_reference = true;
@@ -21028,7 +21033,8 @@ dwarf2_const_value_attr (const struct attribute *attr, struct type *type,
 			 LONGEST *value, const gdb_byte **bytes,
 			 struct dwarf2_locexpr_baton **baton)
 {
-  struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+  dwarf2_per_objfile *per_objfile = cu->per_cu->dwarf2_per_objfile;
+  struct objfile *objfile = per_objfile->objfile;
   struct comp_unit_head *cu_header = &cu->header;
   struct dwarf_block *blk;
   enum bfd_endian byte_order = (bfd_big_endian (objfile->obfd) ?
@@ -21054,6 +21060,7 @@ dwarf2_const_value_attr (const struct attribute *attr, struct type *type,
 	   piggyback on the existing location code rather than writing
 	   a new implementation of symbol_computed_ops.  */
 	*baton = XOBNEW (obstack, struct dwarf2_locexpr_baton);
+	(*baton)->per_objfile = per_objfile;
 	(*baton)->per_cu = cu->per_cu;
 	gdb_assert ((*baton)->per_cu);
 
@@ -22291,6 +22298,7 @@ dwarf2_fetch_die_loc_sect_off (sect_offset sect_off,
       retval.data = DW_BLOCK (attr)->data;
       retval.size = DW_BLOCK (attr)->size;
     }
+  retval.per_objfile = dwarf2_per_objfile;
   retval.per_cu = cu->per_cu;
 
   age_cached_comp_units (dwarf2_per_objfile);
@@ -23140,6 +23148,7 @@ fill_in_loclist_baton (struct dwarf2_cu *cu,
 
   section->read (dwarf2_per_objfile->objfile);
 
+  baton->per_objfile = dwarf2_per_objfile;
   baton->per_cu = cu->per_cu;
   gdb_assert (baton->per_cu);
   /* We don't know how long the location list is, but make sure we
@@ -23188,6 +23197,7 @@ dwarf2_symbol_mark_computed (const struct attribute *attr, struct symbol *sym,
       struct dwarf2_locexpr_baton *baton;
 
       baton = XOBNEW (&objfile->objfile_obstack, struct dwarf2_locexpr_baton);
+      baton->per_objfile = dwarf2_per_objfile;
       baton->per_cu = cu->per_cu;
       gdb_assert (baton->per_cu);
 
-- 
2.26.2


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

* [PATCH v2 05/42] Split dwarf2_per_objfile into dwarf2_per_objfile and dwarf2_per_bfd
  2020-05-12 21:08 [PATCH v2 00/42] Share DWARF partial symtabs between objfiles Simon Marchi
                   ` (3 preceding siblings ...)
  2020-05-12 21:08 ` [PATCH v2 04/42] Add dwarf2_per_objfile member to DWARF batons Simon Marchi
@ 2020-05-12 21:08 ` Simon Marchi
  2020-05-12 21:08 ` [PATCH v2 06/42] Remove symtab links from dwarf2_psymtab and dwarf2_per_cu_quick_data Simon Marchi
                   ` (40 subsequent siblings)
  45 siblings, 0 replies; 92+ messages in thread
From: Simon Marchi @ 2020-05-12 21:08 UTC (permalink / raw)
  To: gdb-patches

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

This is the first step of splitting dwarf2_per_objfile in two, one
structure for objfile-independent data (dwarf2_per_bfd) and one for
objfile-dependent data (dwarf2_per_objfile).

The existing dwarf2_per_objfile is renamed dwarf2_per_bfd, and a new
dwarf2_per_objfile type is introduced, which sits "in between" the
objfile and dwarf2_per_bfd.

So where we had this before:

  objfile -> dwarf2_per_objfile (*)

we now have this:

  objfile -> dwarf2_per_objfile -> dwarf2_per_bfd (*)

(*) Note that the dwarf2_per_objfile in the former corresponds to
the dwarf2_per_bfd in the latter.

I've done the minimal amount of changes in this patch: following patches
will incrementally move things that are not actually shareable between
objfiles from dwarf2_per_bfd to dwarf2_per_objfile.

Most references to dwarf2_per_objfile objects are changed to
dwarf2_per_objfile->per_bfd.  To avoid many of these replacements, which
would have to be reverted later anyway, I've moved right away the
objfile backlink to the new dwarf2_per_objfile structure in this patch.
I've also moved the read_line_string method, since it references the
objfile backlink, and it's actually not difficult to move.

Once the moves are completed, multiple dwarf2_per_objfile sharing the
same BFD will point to the same single instance of dwarf2_per_bfd (as
long as they don't require relocation).

dwarf2_has_info, where we create these objects, is updated to the new
architecture.

I've had to change the get_gdb_index_contents_ftype typedef and related
functions.  The parameter type was changed from dwarf2_per_objfile to
dwarf2_per_bfd, otherwise the template wouldn't work.

Please excuse the terse ChangeLog entry, I have not listed all the
functions where dwarf2_per_objfile has been changed to
dwarf2_per_objfile->per_bfd.  It would take a considerable amount of
time and would not really be useful in the end.

gdb/ChangeLog:

	* dwarf2/read.h (dwarf2_per_objfile): Rename to dwarf2_per_bfd,
	then introduce a new dwarf2_per_objfile type.
	<read_line_string>: Move to the new dwarf2_per_objfile type.
	<objfile>: Likewise.
	(dwarf2_per_bfd): Rename dwarf2_per_objfile to this.
	* dwarf2/read.c: Replace references to dwarf2_per_objfile with
	dwarf2_per_objfile->per_bfd.
	(dwarf2_per_objfile::dwarf2_per_objfile): Rename to...
	(dwarf2_per_bfd::dwarf2_per_bfd): ... this.
	(dwarf2_per_objfile::free_cached_comp_units): Rename to...
	(dwarf2_per_bfd::free_cached_comp_units): ... this.
	(dwarf2_has_info): Allocate dwarf2_per_bfd.
	(dwarf2_per_objfile::locate_sections): Rename to...
	(dwarf2_per_bfd::locate_sections): ... this.
	(dwarf2_per_objfile::get_cutu): Rename to...
	(dwarf2_per_bfd::get_cutu): ... this.
	(dwarf2_per_objfile::get_cu): Rename to...
	(dwarf2_per_bfd::get_cu): ... this.
	(dwarf2_per_objfile::get_tu): Rename to...
	(dwarf2_per_bfd::get_tu): ... this.
	(dwarf2_per_objfile::allocate_per_cu): Rename to...
	(dwarf2_per_bfd::allocate_per_cu): ... this.
	(dwarf2_per_objfile::allocate_signatured_type): Rename to...
	(dwarf2_per_bfd::allocate_signatured_type): ... this.
	(get_gdb_index_contents_ftype): Change parameter from
	dwarf2_per_objfile to dwarf2_per_bfd.
	* dwarf2/macro.c, dwarf2/index-write.c: Replace references to
	dwarf2_per_objfile with dwarf2_per_objfile->per_bfd.
---
 gdb/dwarf2/index-write.c |  48 +--
 gdb/dwarf2/macro.c       |   6 +-
 gdb/dwarf2/read.c        | 618 +++++++++++++++++++--------------------
 gdb/dwarf2/read.h        |  69 +++--
 4 files changed, 380 insertions(+), 361 deletions(-)

diff --git a/gdb/dwarf2/index-write.c b/gdb/dwarf2/index-write.c
index eabfe5d682b..a9c665165c7 100644
--- a/gdb/dwarf2/index-write.c
+++ b/gdb/dwarf2/index-write.c
@@ -961,17 +961,17 @@ class debug_names
       : m_abfd (dwarf2_per_objfile->objfile->obfd),
 	m_dwarf2_per_objfile (dwarf2_per_objfile)
     {
-      dwarf2_per_objfile->str.read (dwarf2_per_objfile->objfile);
-      if (dwarf2_per_objfile->str.buffer == NULL)
+      dwarf2_per_objfile->per_bfd->str.read (dwarf2_per_objfile->objfile);
+      if (dwarf2_per_objfile->per_bfd->str.buffer == NULL)
 	return;
-      for (const gdb_byte *data = dwarf2_per_objfile->str.buffer;
-	   data < (dwarf2_per_objfile->str.buffer
-		   + dwarf2_per_objfile->str.size);)
+      for (const gdb_byte *data = dwarf2_per_objfile->per_bfd->str.buffer;
+	   data < (dwarf2_per_objfile->per_bfd->str.buffer
+		   + dwarf2_per_objfile->per_bfd->str.size);)
 	{
 	  const char *const s = reinterpret_cast<const char *> (data);
 	  const auto insertpair
 	    = m_str_table.emplace (c_str_view (s),
-				   data - dwarf2_per_objfile->str.buffer);
+				   data - dwarf2_per_objfile->per_bfd->str.buffer);
 	  if (!insertpair.second)
 	    complaint (_("Duplicate string \"%s\" in "
 			 ".debug_str section [in module %s]"),
@@ -988,7 +988,7 @@ class debug_names
       const auto it = m_str_table.find (c_str_view (s));
       if (it != m_str_table.end ())
 	return it->second;
-      const size_t offset = (m_dwarf2_per_objfile->str.size
+      const size_t offset = (m_dwarf2_per_objfile->per_bfd->str.size
 			     + m_str_add_buf.size ());
       m_str_table.emplace (c_str_view (s), offset);
       m_str_add_buf.append_cstr0 (s);
@@ -1296,12 +1296,12 @@ class debug_names
 static bool
 check_dwarf64_offsets (struct dwarf2_per_objfile *dwarf2_per_objfile)
 {
-  for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->all_comp_units)
+  for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->per_bfd->all_comp_units)
     {
       if (to_underlying (per_cu->sect_off) >= (static_cast<uint64_t> (1) << 32))
 	return true;
     }
-  for (const signatured_type *sigtype : dwarf2_per_objfile->all_type_units)
+  for (const signatured_type *sigtype : dwarf2_per_objfile->per_bfd->all_type_units)
     {
       const dwarf2_per_cu_data &per_cu = sigtype->per_cu;
 
@@ -1321,7 +1321,7 @@ static size_t
 psyms_seen_size (struct dwarf2_per_objfile *dwarf2_per_objfile)
 {
   size_t psyms_count = 0;
-  for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->all_comp_units)
+  for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->per_bfd->all_comp_units)
     {
       partial_symtab *psymtab = per_cu->v.psymtab;
 
@@ -1414,7 +1414,7 @@ write_gdbindex (struct dwarf2_per_objfile *dwarf2_per_objfile, FILE *out_file,
      in the index file).  This will later be needed to write the address
      table.  */
   psym_index_map cu_index_htab;
-  cu_index_htab.reserve (dwarf2_per_objfile->all_comp_units.size ());
+  cu_index_htab.reserve (dwarf2_per_objfile->per_bfd->all_comp_units.size ());
 
   /* The CU list is already sorted, so we don't need to do additional
      work here.  Also, the debug_types entries do not appear in
@@ -1422,10 +1422,10 @@ write_gdbindex (struct dwarf2_per_objfile *dwarf2_per_objfile, FILE *out_file,
 
   std::unordered_set<partial_symbol *> psyms_seen
     (psyms_seen_size (dwarf2_per_objfile));
-  for (int i = 0; i < dwarf2_per_objfile->all_comp_units.size (); ++i)
+  for (int i = 0; i < dwarf2_per_objfile->per_bfd->all_comp_units.size (); ++i)
     {
       struct dwarf2_per_cu_data *per_cu
-	= dwarf2_per_objfile->all_comp_units[i];
+	= dwarf2_per_objfile->per_bfd->all_comp_units[i];
       partial_symtab *psymtab = per_cu->v.psymtab;
 
       if (psymtab != NULL)
@@ -1453,15 +1453,15 @@ write_gdbindex (struct dwarf2_per_objfile *dwarf2_per_objfile, FILE *out_file,
 
   /* Write out the .debug_type entries, if any.  */
   data_buf types_cu_list;
-  if (dwarf2_per_objfile->signatured_types)
+  if (dwarf2_per_objfile->per_bfd->signatured_types)
     {
       signatured_type_index_data sig_data (types_cu_list,
 					   psyms_seen);
 
       sig_data.objfile = objfile;
       sig_data.symtab = &symtab;
-      sig_data.cu_index = dwarf2_per_objfile->all_comp_units.size ();
-      htab_traverse_noresize (dwarf2_per_objfile->signatured_types.get (),
+      sig_data.cu_index = dwarf2_per_objfile->per_bfd->all_comp_units.size ();
+      htab_traverse_noresize (dwarf2_per_objfile->per_bfd->signatured_types.get (),
 			      write_one_signatured_type, &sig_data);
     }
 
@@ -1505,9 +1505,9 @@ write_debug_names (struct dwarf2_per_objfile *dwarf2_per_objfile,
 			 dwarf5_byte_order);
   std::unordered_set<partial_symbol *>
     psyms_seen (psyms_seen_size (dwarf2_per_objfile));
-  for (int i = 0; i < dwarf2_per_objfile->all_comp_units.size (); ++i)
+  for (int i = 0; i < dwarf2_per_objfile->per_bfd->all_comp_units.size (); ++i)
     {
-      const dwarf2_per_cu_data *per_cu = dwarf2_per_objfile->all_comp_units[i];
+      const dwarf2_per_cu_data *per_cu = dwarf2_per_objfile->per_bfd->all_comp_units[i];
       partial_symtab *psymtab = per_cu->v.psymtab;
 
       /* CU of a shared file from 'dwz -m' may be unused by this main
@@ -1525,7 +1525,7 @@ write_debug_names (struct dwarf2_per_objfile *dwarf2_per_objfile,
 
   /* Write out the .debug_type entries, if any.  */
   data_buf types_cu_list;
-  if (dwarf2_per_objfile->signatured_types)
+  if (dwarf2_per_objfile->per_bfd->signatured_types)
     {
       debug_names::write_one_signatured_type_data sig_data (nametable,
 			signatured_type_index_data (types_cu_list, psyms_seen));
@@ -1534,7 +1534,7 @@ write_debug_names (struct dwarf2_per_objfile *dwarf2_per_objfile,
       /* It is used only for gdb_index.  */
       sig_data.info.symtab = nullptr;
       sig_data.info.cu_index = 0;
-      htab_traverse_noresize (dwarf2_per_objfile->signatured_types.get (),
+      htab_traverse_noresize (dwarf2_per_objfile->per_bfd->signatured_types.get (),
 			      debug_names::write_one_signatured_type,
 			      &sig_data);
     }
@@ -1574,12 +1574,12 @@ write_debug_names (struct dwarf2_per_objfile *dwarf2_per_objfile,
 
   /* comp_unit_count - The number of CUs in the CU list.  */
   header.append_uint (4, dwarf5_byte_order,
-		      dwarf2_per_objfile->all_comp_units.size ());
+		      dwarf2_per_objfile->per_bfd->all_comp_units.size ());
 
   /* local_type_unit_count - The number of TUs in the local TU
      list.  */
   header.append_uint (4, dwarf5_byte_order,
-		      dwarf2_per_objfile->all_type_units.size ());
+		      dwarf2_per_objfile->per_bfd->all_type_units.size ());
 
   /* foreign_type_unit_count - The number of TUs in the foreign TU
      list.  */
@@ -1676,10 +1676,10 @@ write_psymtabs_to_index (struct dwarf2_per_objfile *dwarf2_per_objfile,
 {
   struct objfile *objfile = dwarf2_per_objfile->objfile;
 
-  if (dwarf2_per_objfile->using_index)
+  if (dwarf2_per_objfile->per_bfd->using_index)
     error (_("Cannot use an index to create the index"));
 
-  if (dwarf2_per_objfile->types.size () > 1)
+  if (dwarf2_per_objfile->per_bfd->types.size () > 1)
     error (_("Cannot make an index when the file has multiple .debug_types sections"));
 
   if (!objfile->partial_symtabs->psymtabs
diff --git a/gdb/dwarf2/macro.c b/gdb/dwarf2/macro.c
index 6c2d2514652..c2580193205 100644
--- a/gdb/dwarf2/macro.c
+++ b/gdb/dwarf2/macro.c
@@ -512,9 +512,9 @@ dwarf_decode_macro_bytes (struct dwarf2_per_objfile *dwarf2_per_objfile,
 		    body = dwz->read_string (objfile, str_offset);
 		  }
 		else
-		  body = dwarf2_per_objfile->str.read_string (objfile,
-							      str_offset,
-							      "DW_FORM_strp");
+		  body = dwarf2_per_objfile->per_bfd->str.read_string (objfile,
+								       str_offset,
+								       "DW_FORM_strp");
 	      }
 
 	    is_define = (macinfo_type == DW_MACRO_define
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 4699645c6fc..0b16ec127f5 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -484,7 +484,7 @@ struct dwarf2_cu
   /* Header data from the line table, during full symbol processing.  */
   struct line_header *line_header = nullptr;
   /* Non-NULL if LINE_HEADER is owned by this DWARF_CU.  Otherwise,
-     it's owned by dwarf2_per_objfile::line_header_hash.  If non-NULL,
+     it's owned by dwarf2_per_bfd::line_header_hash.  If non-NULL,
      this is the DW_TAG_compile_unit die for this CU.  We'll hold on
      to the line header as long as this DIE is being processed.  See
      process_die_scope.  */
@@ -599,7 +599,7 @@ struct stmt_list_hash
   sect_offset line_sect_off;
 };
 
-/* Each element of dwarf2_per_objfile->type_unit_groups is a pointer to
+/* Each element of dwarf2_per_bfd->type_unit_groups is a pointer to
    an object of this type.  */
 
 struct type_unit_group
@@ -1602,7 +1602,7 @@ class dwarf2_queue_guard
   {
     /* Ensure that no memory is allocated by the queue.  */
     std::queue<dwarf2_queue_item> empty;
-    std::swap (m_per_objfile->queue, empty);
+    std::swap (m_per_objfile->per_bfd->queue, empty);
   }
 
   DISABLE_COPY_AND_ASSIGN (dwarf2_queue_guard);
@@ -1745,22 +1745,18 @@ line_header_eq_voidp (const void *item_lhs, const void *item_rhs)
 
 /* See declaration.  */
 
-dwarf2_per_objfile::dwarf2_per_objfile (struct objfile *objfile_,
-					const dwarf2_debug_sections *names,
-					bool can_copy_)
-  : objfile (objfile_),
-    can_copy (can_copy_)
+dwarf2_per_bfd::dwarf2_per_bfd (bfd *obfd, const dwarf2_debug_sections *names,
+				bool can_copy_)
+  : can_copy (can_copy_)
 {
   if (names == NULL)
     names = &dwarf2_elf_names;
 
-  bfd *obfd = objfile->obfd;
-
   for (asection *sec = obfd->sections; sec != NULL; sec = sec->next)
     locate_sections (obfd, sec, *names);
 }
 
-dwarf2_per_objfile::~dwarf2_per_objfile ()
+dwarf2_per_bfd::~dwarf2_per_bfd ()
 {
   /* Cached DIE trees use xmalloc and the comp_unit_obstack.  */
   free_cached_comp_units ();
@@ -1771,13 +1767,13 @@ dwarf2_per_objfile::~dwarf2_per_objfile ()
   for (signatured_type *sig_type : all_type_units)
     sig_type->per_cu.imported_symtabs_free ();
 
-  /* Everything else should be on the objfile obstack.  */
+  /* Everything else should be on this->obstack.  */
 }
 
 /* See declaration.  */
 
 void
-dwarf2_per_objfile::free_cached_comp_units ()
+dwarf2_per_bfd::free_cached_comp_units ()
 {
   dwarf2_per_cu_data *per_cu = read_in_chain;
   dwarf2_per_cu_data **last_chain = &read_in_chain;
@@ -1805,7 +1801,7 @@ class free_cached_comp_units
 
   ~free_cached_comp_units ()
   {
-    m_per_objfile->free_cached_comp_units ();
+    m_per_objfile->per_bfd->free_cached_comp_units ();
   }
 
   DISABLE_COPY_AND_ASSIGN (free_cached_comp_units);
@@ -1834,14 +1830,18 @@ dwarf2_has_info (struct objfile *objfile,
     = get_dwarf2_per_objfile (objfile);
 
   if (dwarf2_per_objfile == NULL)
-    dwarf2_per_objfile = dwarf2_objfile_data_key.emplace (objfile, objfile,
-							  names,
-							  can_copy);
+    {
+      /* For now, each dwarf2_per_objfile owns its own dwarf2_per_bfd (no
+         sharing yet).  */
+      dwarf2_per_bfd *per_bfd = new dwarf2_per_bfd (objfile->obfd, names, can_copy);
+
+      dwarf2_per_objfile = dwarf2_objfile_data_key.emplace (objfile, objfile, per_bfd);
+    }
 
-  return (!dwarf2_per_objfile->info.is_virtual
-	  && dwarf2_per_objfile->info.s.section != NULL
-	  && !dwarf2_per_objfile->abbrev.is_virtual
-	  && dwarf2_per_objfile->abbrev.s.section != NULL);
+  return (!dwarf2_per_objfile->per_bfd->info.is_virtual
+	  && dwarf2_per_objfile->per_bfd->info.s.section != NULL
+	  && !dwarf2_per_objfile->per_bfd->abbrev.is_virtual
+	  && dwarf2_per_objfile->per_bfd->abbrev.s.section != NULL);
 }
 
 /* When loading sections, we look either for uncompressed section or for
@@ -1863,8 +1863,8 @@ section_is_p (const char *section_name,
 /* See declaration.  */
 
 void
-dwarf2_per_objfile::locate_sections (bfd *abfd, asection *sectp,
-				     const dwarf2_debug_sections &names)
+dwarf2_per_bfd::locate_sections (bfd *abfd, asection *sectp,
+				 const dwarf2_debug_sections &names)
 {
   flagword aflag = bfd_section_flags (sectp);
 
@@ -2010,10 +2010,10 @@ dwarf2_get_section_info (struct objfile *objfile,
   switch (sect)
     {
     case DWARF2_DEBUG_FRAME:
-      info = &data->frame;
+      info = &data->per_bfd->frame;
       break;
     case DWARF2_EH_FRAME:
-      info = &data->eh_frame;
+      info = &data->per_bfd->eh_frame;
       break;
     default:
       gdb_assert_not_reached ("unexpected section");
@@ -2082,8 +2082,8 @@ dwarf2_get_dwz_file (struct dwarf2_per_objfile *dwarf2_per_objfile)
   size_t buildid_len;
   bfd_byte *buildid;
 
-  if (dwarf2_per_objfile->dwz_file != NULL)
-    return dwarf2_per_objfile->dwz_file.get ();
+  if (dwarf2_per_objfile->per_bfd->dwz_file != NULL)
+    return dwarf2_per_objfile->per_bfd->dwz_file.get ();
 
   bfd_set_error (bfd_error_no_error);
   gdb::unique_xmalloc_ptr<char> data
@@ -2160,8 +2160,8 @@ dwarf2_get_dwz_file (struct dwarf2_per_objfile *dwarf2_per_objfile)
 
   gdb_bfd_record_inclusion (dwarf2_per_objfile->objfile->obfd,
 			    result->dwz_bfd.get ());
-  dwarf2_per_objfile->dwz_file = std::move (result);
-  return dwarf2_per_objfile->dwz_file.get ();
+  dwarf2_per_objfile->per_bfd->dwz_file = std::move (result);
+  return dwarf2_per_objfile->per_bfd->dwz_file.get ();
 }
 \f
 /* DWARF quick_symbols_functions support.  */
@@ -2195,7 +2195,7 @@ struct dwarf2_per_cu_quick_data
 {
   /* The file table.  This can be NULL if there was no file table
      or it's currently not read in.
-     NOTE: This points into dwarf2_per_objfile->quick_file_names_table.  */
+     NOTE: This points into dwarf2_per_objfile->per_bfd->quick_file_names_table.  */
   struct quick_file_names *file_names;
 
   /* The corresponding symbol table.  This is NULL if symbols for this
@@ -2325,7 +2325,7 @@ dw2_do_instantiate_symtab (struct dwarf2_per_cu_data *per_cu, bool skip_partial)
      with the dwarf queue empty.  */
   dwarf2_queue_guard q_guard (dwarf2_per_objfile);
 
-  if (dwarf2_per_objfile->using_index
+  if (dwarf2_per_objfile->per_bfd->using_index
       ? per_cu->v.quick->compunit_symtab == NULL
       : (per_cu->v.psymtab == NULL || !per_cu->v.psymtab->readin))
     {
@@ -2338,8 +2338,8 @@ dw2_do_instantiate_symtab (struct dwarf2_per_cu_data *per_cu, bool skip_partial)
       if (!per_cu->is_debug_types
 	  && per_cu->cu != NULL
 	  && per_cu->cu->dwo_unit != NULL
-	  && dwarf2_per_objfile->index_table != NULL
-	  && dwarf2_per_objfile->index_table->version <= 7
+	  && dwarf2_per_objfile->per_bfd->index_table != NULL
+	  && dwarf2_per_objfile->per_bfd->index_table->version <= 7
 	  /* DWP files aren't supported yet.  */
 	  && get_dwp_file (dwarf2_per_objfile) == NULL)
 	queue_and_load_all_dwo_tus (per_cu);
@@ -2361,7 +2361,7 @@ dw2_instantiate_symtab (struct dwarf2_per_cu_data *per_cu, bool skip_partial)
 {
   struct dwarf2_per_objfile *dwarf2_per_objfile = per_cu->dwarf2_per_objfile;
 
-  gdb_assert (dwarf2_per_objfile->using_index);
+  gdb_assert (dwarf2_per_objfile->per_bfd->using_index);
   if (!per_cu->v.quick->compunit_symtab)
     {
       free_cached_comp_units freer (dwarf2_per_objfile);
@@ -2376,7 +2376,7 @@ dw2_instantiate_symtab (struct dwarf2_per_cu_data *per_cu, bool skip_partial)
 /* See declaration.  */
 
 dwarf2_per_cu_data *
-dwarf2_per_objfile::get_cutu (int index)
+dwarf2_per_bfd::get_cutu (int index)
 {
   if (index >= this->all_comp_units.size ())
     {
@@ -2391,7 +2391,7 @@ dwarf2_per_objfile::get_cutu (int index)
 /* See declaration.  */
 
 dwarf2_per_cu_data *
-dwarf2_per_objfile::get_cu (int index)
+dwarf2_per_bfd::get_cu (int index)
 {
   gdb_assert (index >= 0 && index < this->all_comp_units.size ());
 
@@ -2401,7 +2401,7 @@ dwarf2_per_objfile::get_cu (int index)
 /* See declaration.  */
 
 signatured_type *
-dwarf2_per_objfile::get_tu (int index)
+dwarf2_per_bfd::get_tu (int index)
 {
   gdb_assert (index >= 0 && index < this->all_type_units.size ());
 
@@ -2411,7 +2411,7 @@ dwarf2_per_objfile::get_tu (int index)
 /* See read.h.  */
 
 dwarf2_per_cu_data *
-dwarf2_per_objfile::allocate_per_cu ()
+dwarf2_per_bfd::allocate_per_cu ()
 {
   dwarf2_per_cu_data *result = OBSTACK_ZALLOC (&obstack, dwarf2_per_cu_data);
   result->index = m_num_psymtabs++;
@@ -2421,7 +2421,7 @@ dwarf2_per_objfile::allocate_per_cu ()
 /* See read.h.  */
 
 signatured_type *
-dwarf2_per_objfile::allocate_signatured_type ()
+dwarf2_per_bfd::allocate_signatured_type ()
 {
   signatured_type *result = OBSTACK_ZALLOC (&obstack, signatured_type);
   result->per_cu.index = m_num_psymtabs++;
@@ -2437,12 +2437,12 @@ create_cu_from_index_list (struct dwarf2_per_objfile *dwarf2_per_objfile,
                           int is_dwz,
                           sect_offset sect_off, ULONGEST length)
 {
-  dwarf2_per_cu_data *the_cu = dwarf2_per_objfile->allocate_per_cu ();
+  dwarf2_per_cu_data *the_cu = dwarf2_per_objfile->per_bfd->allocate_per_cu ();
   the_cu->sect_off = sect_off;
   the_cu->length = length;
   the_cu->dwarf2_per_objfile = dwarf2_per_objfile;
   the_cu->section = section;
-  the_cu->v.quick = OBSTACK_ZALLOC (&dwarf2_per_objfile->obstack,
+  the_cu->v.quick = OBSTACK_ZALLOC (&dwarf2_per_objfile->per_bfd->obstack,
 				    struct dwarf2_per_cu_quick_data);
   the_cu->is_dwz = is_dwz;
   return the_cu;
@@ -2469,7 +2469,7 @@ create_cus_from_index_list (struct dwarf2_per_objfile *dwarf2_per_objfile,
       dwarf2_per_cu_data *per_cu
 	= create_cu_from_index_list (dwarf2_per_objfile, section, is_dwz,
 				     sect_off, length);
-      dwarf2_per_objfile->all_comp_units.push_back (per_cu);
+      dwarf2_per_objfile->per_bfd->all_comp_units.push_back (per_cu);
     }
 }
 
@@ -2481,12 +2481,12 @@ create_cus_from_index (struct dwarf2_per_objfile *dwarf2_per_objfile,
 		       const gdb_byte *cu_list, offset_type cu_list_elements,
 		       const gdb_byte *dwz_list, offset_type dwz_elements)
 {
-  gdb_assert (dwarf2_per_objfile->all_comp_units.empty ());
-  dwarf2_per_objfile->all_comp_units.reserve
+  gdb_assert (dwarf2_per_objfile->per_bfd->all_comp_units.empty ());
+  dwarf2_per_objfile->per_bfd->all_comp_units.reserve
     ((cu_list_elements + dwz_elements) / 2);
 
   create_cus_from_index_list (dwarf2_per_objfile, cu_list, cu_list_elements,
-			      &dwarf2_per_objfile->info, 0);
+			      &dwarf2_per_objfile->per_bfd->info, 0);
 
   if (dwz_elements == 0)
     return;
@@ -2505,8 +2505,8 @@ create_signatured_type_table_from_index
    const gdb_byte *bytes,
    offset_type elements)
 {
-  gdb_assert (dwarf2_per_objfile->all_type_units.empty ());
-  dwarf2_per_objfile->all_type_units.reserve (elements / 3);
+  gdb_assert (dwarf2_per_objfile->per_bfd->all_type_units.empty ());
+  dwarf2_per_objfile->per_bfd->all_type_units.reserve (elements / 3);
 
   htab_up sig_types_hash = allocate_signatured_type_table ();
 
@@ -2526,7 +2526,7 @@ create_signatured_type_table_from_index
       signature = extract_unsigned_integer (bytes + 16, 8, BFD_ENDIAN_LITTLE);
       bytes += 3 * 8;
 
-      sig_type = dwarf2_per_objfile->allocate_signatured_type ();
+      sig_type = dwarf2_per_objfile->per_bfd->allocate_signatured_type ();
       sig_type->signature = signature;
       sig_type->type_offset_in_tu = type_offset_in_tu;
       sig_type->per_cu.is_debug_types = 1;
@@ -2534,16 +2534,16 @@ create_signatured_type_table_from_index
       sig_type->per_cu.sect_off = sect_off;
       sig_type->per_cu.dwarf2_per_objfile = dwarf2_per_objfile;
       sig_type->per_cu.v.quick
-	= OBSTACK_ZALLOC (&dwarf2_per_objfile->obstack,
+	= OBSTACK_ZALLOC (&dwarf2_per_objfile->per_bfd->obstack,
 			  struct dwarf2_per_cu_quick_data);
 
       slot = htab_find_slot (sig_types_hash.get (), sig_type, INSERT);
       *slot = sig_type;
 
-      dwarf2_per_objfile->all_type_units.push_back (sig_type);
+      dwarf2_per_objfile->per_bfd->all_type_units.push_back (sig_type);
     }
 
-  dwarf2_per_objfile->signatured_types = std::move (sig_types_hash);
+  dwarf2_per_objfile->per_bfd->signatured_types = std::move (sig_types_hash);
 }
 
 /* Create the signatured type hash table from .debug_names.  */
@@ -2560,8 +2560,8 @@ create_signatured_type_table_from_debug_names
   section->read (objfile);
   abbrev_section->read (objfile);
 
-  gdb_assert (dwarf2_per_objfile->all_type_units.empty ());
-  dwarf2_per_objfile->all_type_units.reserve (map.tu_count);
+  gdb_assert (dwarf2_per_objfile->per_bfd->all_type_units.empty ());
+  dwarf2_per_objfile->per_bfd->all_type_units.reserve (map.tu_count);
 
   htab_up sig_types_hash = allocate_signatured_type_table ();
 
@@ -2582,7 +2582,7 @@ create_signatured_type_table_from_debug_names
 				     section->buffer + to_underlying (sect_off),
 				     rcuh_kind::TYPE);
 
-      sig_type = dwarf2_per_objfile->allocate_signatured_type ();
+      sig_type = dwarf2_per_objfile->per_bfd->allocate_signatured_type ();
       sig_type->signature = cu_header.signature;
       sig_type->type_offset_in_tu = cu_header.type_cu_offset_in_tu;
       sig_type->per_cu.is_debug_types = 1;
@@ -2590,16 +2590,16 @@ create_signatured_type_table_from_debug_names
       sig_type->per_cu.sect_off = sect_off;
       sig_type->per_cu.dwarf2_per_objfile = dwarf2_per_objfile;
       sig_type->per_cu.v.quick
-	= OBSTACK_ZALLOC (&dwarf2_per_objfile->obstack,
+	= OBSTACK_ZALLOC (&dwarf2_per_objfile->per_bfd->obstack,
 			  struct dwarf2_per_cu_quick_data);
 
       slot = htab_find_slot (sig_types_hash.get (), sig_type, INSERT);
       *slot = sig_type;
 
-      dwarf2_per_objfile->all_type_units.push_back (sig_type);
+      dwarf2_per_objfile->per_bfd->all_type_units.push_back (sig_type);
     }
 
-  dwarf2_per_objfile->signatured_types = std::move (sig_types_hash);
+  dwarf2_per_objfile->per_bfd->signatured_types = std::move (sig_types_hash);
 }
 
 /* Read the address map data from the mapped index, and use it to
@@ -2641,7 +2641,7 @@ create_addrmap_from_index (struct dwarf2_per_objfile *dwarf2_per_objfile,
 	  continue;
 	}
 
-      if (cu_index >= dwarf2_per_objfile->all_comp_units.size ())
+      if (cu_index >= dwarf2_per_objfile->per_bfd->all_comp_units.size ())
 	{
 	  complaint (_(".gdb_index address table has invalid CU number %u"),
 		     (unsigned) cu_index);
@@ -2651,7 +2651,7 @@ create_addrmap_from_index (struct dwarf2_per_objfile *dwarf2_per_objfile,
       lo = gdbarch_adjust_dwarf2_addr (gdbarch, lo + baseaddr) - baseaddr;
       hi = gdbarch_adjust_dwarf2_addr (gdbarch, hi + baseaddr) - baseaddr;
       addrmap_set_empty (mutable_map, lo, hi - 1,
-			 dwarf2_per_objfile->get_cu (cu_index));
+			 dwarf2_per_objfile->per_bfd->get_cu (cu_index));
     }
 
   objfile->partial_symtabs->psymtabs_addrmap
@@ -2677,7 +2677,7 @@ create_addrmap_from_aranges (struct dwarf2_per_objfile *dwarf2_per_objfile,
 		     dwarf2_per_cu_data *,
 		     gdb::hash_enum<sect_offset>>
     debug_info_offset_to_per_cu;
-  for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->all_comp_units)
+  for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->per_bfd->all_comp_units)
     {
       const auto insertpair
 	= debug_info_offset_to_per_cu.emplace (per_cu->sect_off, per_cu);
@@ -2805,7 +2805,7 @@ create_addrmap_from_aranges (struct dwarf2_per_objfile *dwarf2_per_objfile,
 	  addr += address_size;
 	  if (start == 0 && length == 0)
 	    break;
-	  if (start == 0 && !dwarf2_per_objfile->has_section_at_zero)
+	  if (start == 0 && !dwarf2_per_objfile->per_bfd->has_section_at_zero)
 	    {
 	      /* Symbol was eliminated due to a COMDAT group.  */
 	      continue;
@@ -2998,7 +2998,7 @@ to use the section anyway."),
 /* Callback types for dwarf2_read_gdb_index.  */
 
 typedef gdb::function_view
-    <gdb::array_view<const gdb_byte>(objfile *, dwarf2_per_objfile *)>
+    <gdb::array_view<const gdb_byte>(objfile *, dwarf2_per_bfd *)>
     get_gdb_index_contents_ftype;
 typedef gdb::function_view
     <gdb::array_view<const gdb_byte>(objfile *, dwz_file *)>
@@ -3019,7 +3019,7 @@ dwarf2_read_gdb_index
   struct objfile *objfile = dwarf2_per_objfile->objfile;
 
   gdb::array_view<const gdb_byte> main_index_contents
-    = get_gdb_index_contents (objfile, dwarf2_per_objfile);
+    = get_gdb_index_contents (objfile, dwarf2_per_objfile->per_bfd);
 
   if (main_index_contents.empty ())
     return 0;
@@ -3070,10 +3070,10 @@ dwarf2_read_gdb_index
     {
       /* We can only handle a single .debug_types when we have an
 	 index.  */
-      if (dwarf2_per_objfile->types.size () != 1)
+      if (dwarf2_per_objfile->per_bfd->types.size () != 1)
 	return 0;
 
-      dwarf2_section_info *section = &dwarf2_per_objfile->types[0];
+      dwarf2_section_info *section = &dwarf2_per_objfile->per_bfd->types[0];
 
       create_signatured_type_table_from_index (dwarf2_per_objfile, section,
 					       types_list, types_list_elements);
@@ -3081,10 +3081,10 @@ dwarf2_read_gdb_index
 
   create_addrmap_from_index (dwarf2_per_objfile, map.get ());
 
-  dwarf2_per_objfile->index_table = std::move (map);
-  dwarf2_per_objfile->using_index = 1;
-  dwarf2_per_objfile->quick_file_names_table =
-    create_quick_file_names_table (dwarf2_per_objfile->all_comp_units.size ());
+  dwarf2_per_objfile->per_bfd->index_table = std::move (map);
+  dwarf2_per_objfile->per_bfd->using_index = 1;
+  dwarf2_per_objfile->per_bfd->quick_file_names_table =
+    create_quick_file_names_table (dwarf2_per_objfile->per_bfd->all_comp_units.size ());
 
   return 1;
 }
@@ -3132,7 +3132,7 @@ dw2_get_file_names_reader (const struct die_reader_specs *reader,
 	 If we have we're done.  */
       find_entry.hash.dwo_unit = cu->dwo_unit;
       find_entry.hash.line_sect_off = line_offset;
-      slot = htab_find_slot (dwarf2_per_objfile->quick_file_names_table.get (),
+      slot = htab_find_slot (dwarf2_per_objfile->per_bfd->quick_file_names_table.get (),
 			     &find_entry, INSERT);
       if (*slot != NULL)
 	{
@@ -3148,7 +3148,7 @@ dw2_get_file_names_reader (const struct die_reader_specs *reader,
       return;
     }
 
-  qfn = XOBNEW (&dwarf2_per_objfile->obstack, struct quick_file_names);
+  qfn = XOBNEW (&dwarf2_per_objfile->per_bfd->obstack, struct quick_file_names);
   qfn->hash.dwo_unit = cu->dwo_unit;
   qfn->hash.line_sect_off = line_offset;
   gdb_assert (slot != NULL);
@@ -3162,7 +3162,7 @@ dw2_get_file_names_reader (const struct die_reader_specs *reader,
 
   qfn->num_file_names = offset + lh->file_names_size ();
   qfn->file_names =
-    XOBNEWVEC (&dwarf2_per_objfile->obstack, const char *,
+    XOBNEWVEC (&dwarf2_per_objfile->per_bfd->obstack, const char *,
 	       qfn->num_file_names);
   if (offset != 0)
     qfn->file_names[0] = xstrdup (fnd.name);
@@ -3208,7 +3208,7 @@ dw2_get_real_path (struct dwarf2_per_objfile *dwarf2_per_objfile,
 		   struct quick_file_names *qfn, int index)
 {
   if (qfn->real_names == NULL)
-    qfn->real_names = OBSTACK_CALLOC (&dwarf2_per_objfile->obstack,
+    qfn->real_names = OBSTACK_CALLOC (&dwarf2_per_objfile->per_bfd->obstack,
 				      qfn->num_file_names, const char *);
 
   if (qfn->real_names[index] == NULL)
@@ -3222,7 +3222,7 @@ dw2_find_last_source_symtab (struct objfile *objfile)
 {
   struct dwarf2_per_objfile *dwarf2_per_objfile
     = get_dwarf2_per_objfile (objfile);
-  dwarf2_per_cu_data *dwarf_cu = dwarf2_per_objfile->all_comp_units.back ();
+  dwarf2_per_cu_data *dwarf_cu = dwarf2_per_objfile->per_bfd->all_comp_units.back ();
   compunit_symtab *cust = dw2_instantiate_symtab (dwarf_cu, false);
 
   if (cust == NULL)
@@ -3258,7 +3258,7 @@ dw2_forget_cached_source_info (struct objfile *objfile)
   struct dwarf2_per_objfile *dwarf2_per_objfile
     = get_dwarf2_per_objfile (objfile);
 
-  htab_traverse_noresize (dwarf2_per_objfile->quick_file_names_table.get (),
+  htab_traverse_noresize (dwarf2_per_objfile->per_bfd->quick_file_names_table.get (),
 			  dw2_free_cached_file_names, NULL);
 }
 
@@ -3299,7 +3299,7 @@ dw2_map_symtabs_matching_filename
   /* The rule is CUs specify all the files, including those used by
      any TU, so there's no need to scan TUs here.  */
 
-  for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->all_comp_units)
+  for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->per_bfd->all_comp_units)
     {
       /* We only need to look at symtabs not already expanded.  */
       if (per_cu->v.quick->compunit_symtab)
@@ -3397,7 +3397,7 @@ dw2_symtab_iter_init (struct dw2_symtab_iterator *iter,
   iter->next = 0;
   iter->global_seen = 0;
 
-  mapped_index *index = dwarf2_per_objfile->index_table.get ();
+  mapped_index *index = dwarf2_per_objfile->per_bfd->index_table.get ();
 
   /* index is NULL if OBJF_READNOW.  */
   if (index != NULL && find_slot_in_mapped_hash (index, name, &iter->vec))
@@ -3428,12 +3428,12 @@ dw2_symtab_iter_next (struct dw2_symtab_iterator *iter)
 	 and indices >= 7 may elide them for certain symbols
 	 (gold does this).  */
       int attrs_valid =
-	(dwarf2_per_objfile->index_table->version >= 7
+	(dwarf2_per_objfile->per_bfd->index_table->version >= 7
 	 && symbol_kind != GDB_INDEX_SYMBOL_KIND_NONE);
 
       /* Don't crash on bad data.  */
-      if (cu_index >= (dwarf2_per_objfile->all_comp_units.size ()
-		       + dwarf2_per_objfile->all_type_units.size ()))
+      if (cu_index >= (dwarf2_per_objfile->per_bfd->all_comp_units.size ()
+		       + dwarf2_per_objfile->per_bfd->all_type_units.size ()))
 	{
 	  complaint (_(".gdb_index entry has bad CU index"
 		       " [in module %s]"),
@@ -3441,7 +3441,7 @@ dw2_symtab_iter_next (struct dw2_symtab_iterator *iter)
 	  continue;
 	}
 
-      dwarf2_per_cu_data *per_cu = dwarf2_per_objfile->get_cutu (cu_index);
+      dwarf2_per_cu_data *per_cu = dwarf2_per_objfile->per_bfd->get_cutu (cu_index);
 
       /* Skip if already read in.  */
       if (per_cu->v.quick->compunit_symtab)
@@ -3551,13 +3551,13 @@ dw2_print_stats (struct objfile *objfile)
 {
   struct dwarf2_per_objfile *dwarf2_per_objfile
     = get_dwarf2_per_objfile (objfile);
-  int total = (dwarf2_per_objfile->all_comp_units.size ()
-	       + dwarf2_per_objfile->all_type_units.size ());
+  int total = (dwarf2_per_objfile->per_bfd->all_comp_units.size ()
+	       + dwarf2_per_objfile->per_bfd->all_type_units.size ());
   int count = 0;
 
   for (int i = 0; i < total; ++i)
     {
-      dwarf2_per_cu_data *per_cu = dwarf2_per_objfile->get_cutu (i);
+      dwarf2_per_cu_data *per_cu = dwarf2_per_objfile->per_bfd->get_cutu (i);
 
       if (!per_cu->v.quick->compunit_symtab)
 	++count;
@@ -3577,12 +3577,12 @@ dw2_dump (struct objfile *objfile)
   struct dwarf2_per_objfile *dwarf2_per_objfile
     = get_dwarf2_per_objfile (objfile);
 
-  gdb_assert (dwarf2_per_objfile->using_index);
+  gdb_assert (dwarf2_per_objfile->per_bfd->using_index);
   printf_filtered (".gdb_index:");
-  if (dwarf2_per_objfile->index_table != NULL)
+  if (dwarf2_per_objfile->per_bfd->index_table != NULL)
     {
       printf_filtered (" version %d\n",
-		       dwarf2_per_objfile->index_table->version);
+		       dwarf2_per_objfile->per_bfd->index_table->version);
     }
   else
     printf_filtered (" faked for \"readnow\"\n");
@@ -3611,12 +3611,12 @@ dw2_expand_all_symtabs (struct objfile *objfile)
 {
   struct dwarf2_per_objfile *dwarf2_per_objfile
     = get_dwarf2_per_objfile (objfile);
-  int total_units = (dwarf2_per_objfile->all_comp_units.size ()
-		     + dwarf2_per_objfile->all_type_units.size ());
+  int total_units = (dwarf2_per_objfile->per_bfd->all_comp_units.size ()
+		     + dwarf2_per_objfile->per_bfd->all_type_units.size ());
 
   for (int i = 0; i < total_units; ++i)
     {
-      dwarf2_per_cu_data *per_cu = dwarf2_per_objfile->get_cutu (i);
+      dwarf2_per_cu_data *per_cu = dwarf2_per_objfile->per_bfd->get_cutu (i);
 
       /* We don't want to directly expand a partial CU, because if we
 	 read it with the wrong language, then assertion failures can
@@ -3639,7 +3639,7 @@ dw2_expand_symtabs_with_fullname (struct objfile *objfile,
      There can be an order of magnitude (or more) more type units
      than comp units, and we avoid them if we can.  */
 
-  for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->all_comp_units)
+  for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->per_bfd->all_comp_units)
     {
       /* We only need to look at symtabs not already expanded.  */
       if (per_cu->v.quick->compunit_symtab)
@@ -3674,7 +3674,7 @@ dw2_map_matching_symbols
   struct dwarf2_per_objfile *dwarf2_per_objfile
     = get_dwarf2_per_objfile (objfile);
 
-  if (dwarf2_per_objfile->index_table != nullptr)
+  if (dwarf2_per_objfile->per_bfd->index_table != nullptr)
     {
       /* Ada currently doesn't support .gdb_index (see PR24713).  We can get
 	 here though if the current language is Ada for a non-Ada objfile
@@ -4492,7 +4492,7 @@ dw2_expand_marked_cus
 {
   offset_type *vec, vec_len, vec_idx;
   bool global_seen = false;
-  mapped_index &index = *dwarf2_per_objfile->index_table;
+  mapped_index &index = *dwarf2_per_objfile->per_bfd->index_table;
 
   vec = (offset_type *) (index.constant_pool
 			 + MAYBE_SWAP (index.symbol_table[idx].vec));
@@ -4549,8 +4549,8 @@ dw2_expand_marked_cus
 	}
 
       /* Don't crash on bad data.  */
-      if (cu_index >= (dwarf2_per_objfile->all_comp_units.size ()
-		       + dwarf2_per_objfile->all_type_units.size ()))
+      if (cu_index >= (dwarf2_per_objfile->per_bfd->all_comp_units.size ()
+		       + dwarf2_per_objfile->per_bfd->all_type_units.size ()))
 	{
 	  complaint (_(".gdb_index entry has bad CU index"
 		       " [in module %s]"),
@@ -4558,7 +4558,7 @@ dw2_expand_marked_cus
 	  continue;
 	}
 
-      dwarf2_per_cu_data *per_cu = dwarf2_per_objfile->get_cutu (cu_index);
+      dwarf2_per_cu_data *per_cu = dwarf2_per_objfile->per_bfd->get_cutu (cu_index);
       dw2_expand_symtabs_matching_one (per_cu, file_matcher,
 				       expansion_notify);
     }
@@ -4586,7 +4586,7 @@ dw_expand_symtabs_matching_file_matcher
   /* The rule is CUs specify all the files, including those used by
      any TU, so there's no need to scan TUs here.  */
 
-  for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->all_comp_units)
+  for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->per_bfd->all_comp_units)
     {
       QUIT;
 
@@ -4655,14 +4655,14 @@ dw2_expand_symtabs_matching
     = get_dwarf2_per_objfile (objfile);
 
   /* index_table is NULL if OBJF_READNOW.  */
-  if (!dwarf2_per_objfile->index_table)
+  if (!dwarf2_per_objfile->per_bfd->index_table)
     return;
 
   dw_expand_symtabs_matching_file_matcher (dwarf2_per_objfile, file_matcher);
 
   if (symbol_matcher == NULL && lookup_name == NULL)
     {
-      for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->all_comp_units)
+      for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->per_bfd->all_comp_units)
 	{
 	  QUIT;
 
@@ -4672,7 +4672,7 @@ dw2_expand_symtabs_matching
       return;
     }
 
-  mapped_index &index = *dwarf2_per_objfile->index_table;
+  mapped_index &index = *dwarf2_per_objfile->per_bfd->index_table;
 
   dw2_expand_symtabs_matching_symbol (index, *lookup_name,
 				      symbol_matcher,
@@ -4750,9 +4750,9 @@ dw2_map_symbol_filenames (struct objfile *objfile, symbol_filename_ftype *fun,
   struct dwarf2_per_objfile *dwarf2_per_objfile
     = get_dwarf2_per_objfile (objfile);
 
-  if (!dwarf2_per_objfile->filenames_cache)
+  if (!dwarf2_per_objfile->per_bfd->filenames_cache)
     {
-      dwarf2_per_objfile->filenames_cache.emplace ();
+      dwarf2_per_objfile->per_bfd->filenames_cache.emplace ();
 
       htab_up visited (htab_create_alloc (10,
 					  htab_hash_pointer, htab_eq_pointer,
@@ -4762,7 +4762,7 @@ dw2_map_symbol_filenames (struct objfile *objfile, symbol_filename_ftype *fun,
 	 by any TU, so there's no need to scan TUs here.  We can
 	 ignore file names coming from already-expanded CUs.  */
 
-      for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->all_comp_units)
+      for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->per_bfd->all_comp_units)
 	{
 	  if (per_cu->v.quick->compunit_symtab)
 	    {
@@ -4774,7 +4774,7 @@ dw2_map_symbol_filenames (struct objfile *objfile, symbol_filename_ftype *fun,
 	    }
 	}
 
-      for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->all_comp_units)
+      for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->per_bfd->all_comp_units)
 	{
 	  /* We only need to look at symtabs not already expanded.  */
 	  if (per_cu->v.quick->compunit_symtab)
@@ -4795,12 +4795,12 @@ dw2_map_symbol_filenames (struct objfile *objfile, symbol_filename_ftype *fun,
 	  for (int j = 0; j < file_data->num_file_names; ++j)
 	    {
 	      const char *filename = file_data->file_names[j];
-	      dwarf2_per_objfile->filenames_cache->seen (filename);
+	      dwarf2_per_objfile->per_bfd->filenames_cache->seen (filename);
 	    }
 	}
     }
 
-  dwarf2_per_objfile->filenames_cache->traverse ([&] (const char *filename)
+  dwarf2_per_objfile->per_bfd->filenames_cache->traverse ([&] (const char *filename)
     {
       gdb::unique_xmalloc_ptr<char> this_real_name;
 
@@ -5050,7 +5050,7 @@ create_cus_from_debug_names_list (struct dwarf2_per_objfile *dwarf2_per_objfile,
 	dwarf2_per_cu_data *per_cu
 	  = create_cu_from_index_list (dwarf2_per_objfile, &section, is_dwz,
 				       sect_off, 0);
-	dwarf2_per_objfile->all_comp_units.push_back (per_cu);
+	dwarf2_per_objfile->per_bfd->all_comp_units.push_back (per_cu);
       }
     }
 
@@ -5074,7 +5074,7 @@ create_cus_from_debug_names_list (struct dwarf2_per_objfile *dwarf2_per_objfile,
 	  dwarf2_per_cu_data *per_cu
 	    = create_cu_from_index_list (dwarf2_per_objfile, &section, is_dwz,
 					 sect_off_prev, length);
-	  dwarf2_per_objfile->all_comp_units.push_back (per_cu);
+	  dwarf2_per_objfile->per_bfd->all_comp_units.push_back (per_cu);
 	}
       sect_off_prev = sect_off_next;
     }
@@ -5088,11 +5088,11 @@ create_cus_from_debug_names (struct dwarf2_per_objfile *dwarf2_per_objfile,
 			     const mapped_debug_names &map,
 			     const mapped_debug_names &dwz_map)
 {
-  gdb_assert (dwarf2_per_objfile->all_comp_units.empty ());
-  dwarf2_per_objfile->all_comp_units.reserve (map.cu_count + dwz_map.cu_count);
+  gdb_assert (dwarf2_per_objfile->per_bfd->all_comp_units.empty ());
+  dwarf2_per_objfile->per_bfd->all_comp_units.reserve (map.cu_count + dwz_map.cu_count);
 
   create_cus_from_debug_names_list (dwarf2_per_objfile, map,
-				    dwarf2_per_objfile->info,
+				    dwarf2_per_objfile->per_bfd->info,
 				    false /* is_dwz */);
 
   if (dwz_map.cu_count == 0)
@@ -5115,7 +5115,7 @@ dwarf2_read_debug_names (struct dwarf2_per_objfile *dwarf2_per_objfile)
   struct objfile *objfile = dwarf2_per_objfile->objfile;
 
   if (!read_debug_names_from_section (objfile, objfile_name (objfile),
-				      &dwarf2_per_objfile->debug_names,
+				      &dwarf2_per_objfile->per_bfd->debug_names,
 				      *map))
     return false;
 
@@ -5144,22 +5144,22 @@ dwarf2_read_debug_names (struct dwarf2_per_objfile *dwarf2_per_objfile)
     {
       /* We can only handle a single .debug_types when we have an
 	 index.  */
-      if (dwarf2_per_objfile->types.size () != 1)
+      if (dwarf2_per_objfile->per_bfd->types.size () != 1)
 	return false;
 
-      dwarf2_section_info *section = &dwarf2_per_objfile->types[0];
+      dwarf2_section_info *section = &dwarf2_per_objfile->per_bfd->types[0];
 
       create_signatured_type_table_from_debug_names
-	(dwarf2_per_objfile, *map, section, &dwarf2_per_objfile->abbrev);
+	(dwarf2_per_objfile, *map, section, &dwarf2_per_objfile->per_bfd->abbrev);
     }
 
   create_addrmap_from_aranges (dwarf2_per_objfile,
-			       &dwarf2_per_objfile->debug_aranges);
+			       &dwarf2_per_objfile->per_bfd->debug_aranges);
 
-  dwarf2_per_objfile->debug_names_table = std::move (map);
-  dwarf2_per_objfile->using_index = 1;
-  dwarf2_per_objfile->quick_file_names_table =
-    create_quick_file_names_table (dwarf2_per_objfile->all_comp_units.size ());
+  dwarf2_per_objfile->per_bfd->debug_names_table = std::move (map);
+  dwarf2_per_objfile->per_bfd->using_index = 1;
+  dwarf2_per_objfile->per_bfd->quick_file_names_table =
+    create_quick_file_names_table (dwarf2_per_objfile->per_bfd->all_comp_units.size ());
 
   return true;
 }
@@ -5406,7 +5406,7 @@ dw2_debug_names_iterator::next ()
 	{
 	case DW_IDX_compile_unit:
 	  /* Don't crash on bad data.  */
-	  if (ull >= dwarf2_per_objfile->all_comp_units.size ())
+	  if (ull >= dwarf2_per_objfile->per_bfd->all_comp_units.size ())
 	    {
 	      complaint (_(".debug_names entry has bad CU index %s"
 			   " [in module %s]"),
@@ -5414,11 +5414,11 @@ dw2_debug_names_iterator::next ()
 			 objfile_name (dwarf2_per_objfile->objfile));
 	      continue;
 	    }
-	  per_cu = dwarf2_per_objfile->get_cutu (ull);
+	  per_cu = dwarf2_per_objfile->per_bfd->get_cutu (ull);
 	  break;
 	case DW_IDX_type_unit:
 	  /* Don't crash on bad data.  */
-	  if (ull >= dwarf2_per_objfile->all_type_units.size ())
+	  if (ull >= dwarf2_per_objfile->per_bfd->all_type_units.size ())
 	    {
 	      complaint (_(".debug_names entry has bad TU index %s"
 			   " [in module %s]"),
@@ -5426,13 +5426,13 @@ dw2_debug_names_iterator::next ()
 			 objfile_name (dwarf2_per_objfile->objfile));
 	      continue;
 	    }
-	  per_cu = &dwarf2_per_objfile->get_tu (ull)->per_cu;
+	  per_cu = &dwarf2_per_objfile->per_bfd->get_tu (ull)->per_cu;
 	  break;
 	case DW_IDX_die_offset:
 	  /* In a per-CU index (as opposed to a per-module index), index
 	     entries without CU attribute implicitly refer to the single CU.  */
 	  if (per_cu == NULL)
-	    per_cu = dwarf2_per_objfile->get_cu (0);
+	    per_cu = dwarf2_per_objfile->per_bfd->get_cu (0);
 	  break;
 	case DW_IDX_GNU_internal:
 	  if (!m_map.augmentation_is_gdb)
@@ -5565,7 +5565,7 @@ dw2_debug_names_lookup_symbol (struct objfile *objfile, block_enum block_index,
   struct dwarf2_per_objfile *dwarf2_per_objfile
     = get_dwarf2_per_objfile (objfile);
 
-  const auto &mapp = dwarf2_per_objfile->debug_names_table;
+  const auto &mapp = dwarf2_per_objfile->per_bfd->debug_names_table;
   if (!mapp)
     {
       /* index is NULL if OBJF_READNOW.  */
@@ -5615,9 +5615,9 @@ dw2_debug_names_dump (struct objfile *objfile)
   struct dwarf2_per_objfile *dwarf2_per_objfile
     = get_dwarf2_per_objfile (objfile);
 
-  gdb_assert (dwarf2_per_objfile->using_index);
+  gdb_assert (dwarf2_per_objfile->per_bfd->using_index);
   printf_filtered (".debug_names:");
-  if (dwarf2_per_objfile->debug_names_table)
+  if (dwarf2_per_objfile->per_bfd->debug_names_table)
     printf_filtered (" exists\n");
   else
     printf_filtered (" faked for \"readnow\"\n");
@@ -5631,10 +5631,10 @@ dw2_debug_names_expand_symtabs_for_function (struct objfile *objfile,
   struct dwarf2_per_objfile *dwarf2_per_objfile
     = get_dwarf2_per_objfile (objfile);
 
-  /* dwarf2_per_objfile->debug_names_table is NULL if OBJF_READNOW.  */
-  if (dwarf2_per_objfile->debug_names_table)
+  /* dwarf2_per_objfile->per_bfd->debug_names_table is NULL if OBJF_READNOW.  */
+  if (dwarf2_per_objfile->per_bfd->debug_names_table)
     {
-      const mapped_debug_names &map = *dwarf2_per_objfile->debug_names_table;
+      const mapped_debug_names &map = *dwarf2_per_objfile->per_bfd->debug_names_table;
 
       dw2_debug_names_iterator iter (map, {}, VAR_DOMAIN, func_name);
 
@@ -5656,10 +5656,10 @@ dw2_debug_names_map_matching_symbols
     = get_dwarf2_per_objfile (objfile);
 
   /* debug_names_table is NULL if OBJF_READNOW.  */
-  if (!dwarf2_per_objfile->debug_names_table)
+  if (!dwarf2_per_objfile->per_bfd->debug_names_table)
     return;
 
-  mapped_debug_names &map = *dwarf2_per_objfile->debug_names_table;
+  mapped_debug_names &map = *dwarf2_per_objfile->per_bfd->debug_names_table;
   const block_enum block_kind = global ? GLOBAL_BLOCK : STATIC_BLOCK;
 
   const char *match_name = name.ada ().lookup_name ().c_str ();
@@ -5687,7 +5687,7 @@ dw2_debug_names_map_matching_symbols
      dw2_expand_symtabs_matching_symbol callback, but that skips CUs
      that have already been expanded.  Instead, this loop matches what
      the psymtab code does.  */
-  for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->all_comp_units)
+  for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->per_bfd->all_comp_units)
     {
       struct compunit_symtab *cust = per_cu->v.quick->compunit_symtab;
       if (cust != nullptr)
@@ -5714,14 +5714,14 @@ dw2_debug_names_expand_symtabs_matching
     = get_dwarf2_per_objfile (objfile);
 
   /* debug_names_table is NULL if OBJF_READNOW.  */
-  if (!dwarf2_per_objfile->debug_names_table)
+  if (!dwarf2_per_objfile->per_bfd->debug_names_table)
     return;
 
   dw_expand_symtabs_matching_file_matcher (dwarf2_per_objfile, file_matcher);
 
   if (symbol_matcher == NULL && lookup_name == NULL)
     {
-      for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->all_comp_units)
+      for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->per_bfd->all_comp_units)
 	{
 	  QUIT;
 
@@ -5731,7 +5731,7 @@ dw2_debug_names_expand_symtabs_matching
       return;
     }
 
-  mapped_debug_names &map = *dwarf2_per_objfile->debug_names_table;
+  mapped_debug_names &map = *dwarf2_per_objfile->per_bfd->debug_names_table;
 
   dw2_expand_symtabs_matching_symbol (map, *lookup_name,
 				      symbol_matcher,
@@ -5770,7 +5770,7 @@ const struct quick_symbol_functions dwarf2_debug_names_functions =
 };
 
 /* Get the content of the .gdb_index section of OBJ.  SECTION_OWNER should point
-   to either a dwarf2_per_objfile or dwz_file object.  */
+   to either a dwarf2_per_bfd or dwz_file object.  */
 
 template <typename T>
 static gdb::array_view<const gdb_byte>
@@ -5801,14 +5801,14 @@ get_gdb_index_contents_from_section (objfile *obj, T *section_owner)
    DWARF2_OBJ.  */
 
 static gdb::array_view<const gdb_byte>
-get_gdb_index_contents_from_cache (objfile *obj, dwarf2_per_objfile *dwarf2_obj)
+get_gdb_index_contents_from_cache (objfile *obj, dwarf2_per_bfd *dwarf2_per_bfd)
 {
   const bfd_build_id *build_id = build_id_bfd_get (obj->obfd);
   if (build_id == nullptr)
     return {};
 
   return global_index_cache.lookup_gdb_index (build_id,
-					      &dwarf2_obj->index_cache_res);
+					      &dwarf2_per_bfd->index_cache_res);
 }
 
 /* Same as the above, but for DWZ.  */
@@ -5837,19 +5837,19 @@ dwarf2_initialize_objfile (struct objfile *objfile, dw_index_kind *index_kind)
      expanded anyway.  */
   if ((objfile->flags & OBJF_READNOW))
     {
-      dwarf2_per_objfile->using_index = 1;
+      dwarf2_per_objfile->per_bfd->using_index = 1;
       create_all_comp_units (dwarf2_per_objfile);
       create_all_type_units (dwarf2_per_objfile);
-      dwarf2_per_objfile->quick_file_names_table
+      dwarf2_per_objfile->per_bfd->quick_file_names_table
 	= create_quick_file_names_table
-	    (dwarf2_per_objfile->all_comp_units.size ());
+	    (dwarf2_per_objfile->per_bfd->all_comp_units.size ());
 
-      for (int i = 0; i < (dwarf2_per_objfile->all_comp_units.size ()
-			   + dwarf2_per_objfile->all_type_units.size ()); ++i)
+      for (int i = 0; i < (dwarf2_per_objfile->per_bfd->all_comp_units.size ()
+			   + dwarf2_per_objfile->per_bfd->all_type_units.size ()); ++i)
 	{
-	  dwarf2_per_cu_data *per_cu = dwarf2_per_objfile->get_cutu (i);
+	  dwarf2_per_cu_data *per_cu = dwarf2_per_objfile->per_bfd->get_cutu (i);
 
-	  per_cu->v.quick = OBSTACK_ZALLOC (&dwarf2_per_objfile->obstack,
+	  per_cu->v.quick = OBSTACK_ZALLOC (&dwarf2_per_objfile->per_bfd->obstack,
 					    struct dwarf2_per_cu_quick_data);
 	}
 
@@ -5867,7 +5867,7 @@ dwarf2_initialize_objfile (struct objfile *objfile, dw_index_kind *index_kind)
     }
 
   if (dwarf2_read_gdb_index (dwarf2_per_objfile,
-			     get_gdb_index_contents_from_section<struct dwarf2_per_objfile>,
+			     get_gdb_index_contents_from_section<struct dwarf2_per_bfd>,
 			     get_gdb_index_contents_from_section<dwz_file>))
     {
       *index_kind = dw_index_kind::GDB_INDEX;
@@ -5954,7 +5954,7 @@ get_abbrev_section_for_cu (struct dwarf2_per_cu_data *this_cu)
   if (this_cu->is_dwz)
     abbrev = &dwarf2_get_dwz_file (dwarf2_per_objfile)->abbrev;
   else
-    abbrev = &dwarf2_per_objfile->abbrev;
+    abbrev = &dwarf2_per_objfile->per_bfd->abbrev;
 
   return abbrev;
 }
@@ -6144,7 +6144,7 @@ create_debug_type_hash_table (struct dwarf2_per_objfile *dwarf2_per_objfile,
 
   abbrev_section = (dwo_file != NULL
 		    ? &dwo_file->sections.abbrev
-		    : &dwarf2_per_objfile->abbrev);
+		    : &dwarf2_per_objfile->per_bfd->abbrev);
 
   if (dwarf_read_debug)
     fprintf_unfiltered (gdb_stdlog, "Reading %s for %s:\n",
@@ -6208,7 +6208,7 @@ create_debug_type_hash_table (struct dwarf2_per_objfile *dwarf2_per_objfile,
       if (dwo_file)
 	{
 	  sig_type = NULL;
-	  dwo_tu = OBSTACK_ZALLOC (&dwarf2_per_objfile->obstack,
+	  dwo_tu = OBSTACK_ZALLOC (&dwarf2_per_objfile->per_bfd->obstack,
 				   struct dwo_unit);
 	  dwo_tu->dwo_file = dwo_file;
 	  dwo_tu->signature = header.signature;
@@ -6222,7 +6222,7 @@ create_debug_type_hash_table (struct dwarf2_per_objfile *dwarf2_per_objfile,
 	  /* N.B.: type_offset is not usable if this type uses a DWO file.
 	     The real type_offset is in the DWO file.  */
 	  dwo_tu = NULL;
-	  sig_type = dwarf2_per_objfile->allocate_signatured_type ();
+	  sig_type = dwarf2_per_objfile->per_bfd->allocate_signatured_type ();
 	  sig_type->signature = header.signature;
 	  sig_type->type_offset_in_tu = header.type_cu_offset_in_tu;
 	  sig_type->per_cu.dwarf2_per_objfile = dwarf2_per_objfile;
@@ -6302,30 +6302,30 @@ create_all_type_units (struct dwarf2_per_objfile *dwarf2_per_objfile)
   htab_up types_htab;
 
   create_debug_type_hash_table (dwarf2_per_objfile, NULL,
-				&dwarf2_per_objfile->info, types_htab,
+				&dwarf2_per_objfile->per_bfd->info, types_htab,
 				rcuh_kind::COMPILE);
   create_debug_types_hash_table (dwarf2_per_objfile, NULL,
-				 dwarf2_per_objfile->types, types_htab);
+				 dwarf2_per_objfile->per_bfd->types, types_htab);
   if (types_htab == NULL)
     {
-      dwarf2_per_objfile->signatured_types = NULL;
+      dwarf2_per_objfile->per_bfd->signatured_types = NULL;
       return 0;
     }
 
-  dwarf2_per_objfile->signatured_types = std::move (types_htab);
+  dwarf2_per_objfile->per_bfd->signatured_types = std::move (types_htab);
 
-  gdb_assert (dwarf2_per_objfile->all_type_units.empty ());
-  dwarf2_per_objfile->all_type_units.reserve
-    (htab_elements (dwarf2_per_objfile->signatured_types.get ()));
+  gdb_assert (dwarf2_per_objfile->per_bfd->all_type_units.empty ());
+  dwarf2_per_objfile->per_bfd->all_type_units.reserve
+    (htab_elements (dwarf2_per_objfile->per_bfd->signatured_types.get ()));
 
-  htab_traverse_noresize (dwarf2_per_objfile->signatured_types.get (),
+  htab_traverse_noresize (dwarf2_per_objfile->per_bfd->signatured_types.get (),
 			  add_signatured_type_cu_to_table,
-			  &dwarf2_per_objfile->all_type_units);
+			  &dwarf2_per_objfile->per_bfd->all_type_units);
 
   return 1;
 }
 
-/* Add an entry for signature SIG to dwarf2_per_objfile->signatured_types.
+/* Add an entry for signature SIG to dwarf2_per_objfile->per_bfd->signatured_types.
    If SLOT is non-NULL, it is the entry to use in the hash table.
    Otherwise we find one.  */
 
@@ -6333,25 +6333,25 @@ static struct signatured_type *
 add_type_unit (struct dwarf2_per_objfile *dwarf2_per_objfile, ULONGEST sig,
 	       void **slot)
 {
-  if (dwarf2_per_objfile->all_type_units.size ()
-      == dwarf2_per_objfile->all_type_units.capacity ())
-    ++dwarf2_per_objfile->tu_stats.nr_all_type_units_reallocs;
+  if (dwarf2_per_objfile->per_bfd->all_type_units.size ()
+      == dwarf2_per_objfile->per_bfd->all_type_units.capacity ())
+    ++dwarf2_per_objfile->per_bfd->tu_stats.nr_all_type_units_reallocs;
 
-  signatured_type *sig_type = dwarf2_per_objfile->allocate_signatured_type ();
+  signatured_type *sig_type = dwarf2_per_objfile->per_bfd->allocate_signatured_type ();
 
-  dwarf2_per_objfile->all_type_units.push_back (sig_type);
+  dwarf2_per_objfile->per_bfd->all_type_units.push_back (sig_type);
   sig_type->signature = sig;
   sig_type->per_cu.is_debug_types = 1;
-  if (dwarf2_per_objfile->using_index)
+  if (dwarf2_per_objfile->per_bfd->using_index)
     {
       sig_type->per_cu.v.quick =
-	OBSTACK_ZALLOC (&dwarf2_per_objfile->obstack,
+	OBSTACK_ZALLOC (&dwarf2_per_objfile->per_bfd->obstack,
 			struct dwarf2_per_cu_quick_data);
     }
 
   if (slot == NULL)
     {
-      slot = htab_find_slot (dwarf2_per_objfile->signatured_types.get (),
+      slot = htab_find_slot (dwarf2_per_objfile->per_bfd->signatured_types.get (),
 			     sig_type, INSERT);
     }
   gdb_assert (*slot == NULL);
@@ -6371,7 +6371,7 @@ fill_in_sig_entry_from_dwo_entry (struct dwarf2_per_objfile *dwarf2_per_objfile,
   /* Make sure we're not clobbering something we don't expect to.  */
   gdb_assert (! sig_entry->per_cu.queued);
   gdb_assert (sig_entry->per_cu.cu == NULL);
-  if (dwarf2_per_objfile->using_index)
+  if (dwarf2_per_objfile->per_bfd->using_index)
     {
       gdb_assert (sig_entry->per_cu.v.quick != NULL);
       gdb_assert (sig_entry->per_cu.v.quick->compunit_symtab == NULL);
@@ -6414,12 +6414,12 @@ lookup_dwo_signatured_type (struct dwarf2_cu *cu, ULONGEST sig)
   struct signatured_type find_sig_entry, *sig_entry;
   void **slot;
 
-  gdb_assert (cu->dwo_unit && dwarf2_per_objfile->using_index);
+  gdb_assert (cu->dwo_unit && dwarf2_per_objfile->per_bfd->using_index);
 
   /* If TU skeletons have been removed then we may not have read in any
      TUs yet.  */
-  if (dwarf2_per_objfile->signatured_types == NULL)
-    dwarf2_per_objfile->signatured_types = allocate_signatured_type_table ();
+  if (dwarf2_per_objfile->per_bfd->signatured_types == NULL)
+    dwarf2_per_objfile->per_bfd->signatured_types = allocate_signatured_type_table ();
 
   /* We only ever need to read in one copy of a signatured type.
      Use the global signatured_types array to do our own comdat-folding
@@ -6428,7 +6428,7 @@ lookup_dwo_signatured_type (struct dwarf2_cu *cu, ULONGEST sig)
      .gdb_index with this TU.  */
 
   find_sig_entry.signature = sig;
-  slot = htab_find_slot (dwarf2_per_objfile->signatured_types.get (),
+  slot = htab_find_slot (dwarf2_per_objfile->per_bfd->signatured_types.get (),
 			 &find_sig_entry, INSERT);
   sig_entry = (struct signatured_type *) *slot;
 
@@ -6481,16 +6481,16 @@ lookup_dwp_signatured_type (struct dwarf2_cu *cu, ULONGEST sig)
   struct signatured_type find_sig_entry, *sig_entry;
   void **slot;
 
-  gdb_assert (cu->dwo_unit && dwarf2_per_objfile->using_index);
+  gdb_assert (cu->dwo_unit && dwarf2_per_objfile->per_bfd->using_index);
   gdb_assert (dwp_file != NULL);
 
   /* If TU skeletons have been removed then we may not have read in any
      TUs yet.  */
-  if (dwarf2_per_objfile->signatured_types == NULL)
-    dwarf2_per_objfile->signatured_types = allocate_signatured_type_table ();
+  if (dwarf2_per_objfile->per_bfd->signatured_types == NULL)
+    dwarf2_per_objfile->per_bfd->signatured_types = allocate_signatured_type_table ();
 
   find_sig_entry.signature = sig;
-  slot = htab_find_slot (dwarf2_per_objfile->signatured_types.get (),
+  slot = htab_find_slot (dwarf2_per_objfile->per_bfd->signatured_types.get (),
 			 &find_sig_entry, INSERT);
   sig_entry = (struct signatured_type *) *slot;
 
@@ -6524,7 +6524,7 @@ lookup_signatured_type (struct dwarf2_cu *cu, ULONGEST sig)
     = cu->per_cu->dwarf2_per_objfile;
 
   if (cu->dwo_unit
-      && dwarf2_per_objfile->using_index)
+      && dwarf2_per_objfile->per_bfd->using_index)
     {
       /* We're in a DWO/DWP file, and we're using .gdb_index.
 	 These cases require special processing.  */
@@ -6537,11 +6537,11 @@ lookup_signatured_type (struct dwarf2_cu *cu, ULONGEST sig)
     {
       struct signatured_type find_entry, *entry;
 
-      if (dwarf2_per_objfile->signatured_types == NULL)
+      if (dwarf2_per_objfile->per_bfd->signatured_types == NULL)
 	return NULL;
       find_entry.signature = sig;
       entry = ((struct signatured_type *)
-	       htab_find (dwarf2_per_objfile->signatured_types.get (),
+	       htab_find (dwarf2_per_objfile->per_bfd->signatured_types.get (),
 			  &find_entry));
       return entry;
     }
@@ -7067,8 +7067,8 @@ cutu_reader::keep ()
       struct dwarf2_per_objfile *dwarf2_per_objfile
 	= m_this_cu->dwarf2_per_objfile;
       /* Link this CU into read_in_chain.  */
-      m_this_cu->cu->read_in_chain = dwarf2_per_objfile->read_in_chain;
-      dwarf2_per_objfile->read_in_chain = m_this_cu;
+      m_this_cu->cu->read_in_chain = dwarf2_per_objfile->per_bfd->read_in_chain;
+      dwarf2_per_objfile->per_bfd->read_in_chain = m_this_cu;
       /* The chain owns it now.  */
       m_new_cu.release ();
     }
@@ -7206,14 +7206,14 @@ create_type_unit_group (struct dwarf2_cu *cu, sect_offset line_offset_struct)
   struct dwarf2_per_cu_data *per_cu;
   struct type_unit_group *tu_group;
 
-  tu_group = OBSTACK_ZALLOC (&dwarf2_per_objfile->obstack,
+  tu_group = OBSTACK_ZALLOC (&dwarf2_per_objfile->per_bfd->obstack,
 			     struct type_unit_group);
   per_cu = &tu_group->per_cu;
   per_cu->dwarf2_per_objfile = dwarf2_per_objfile;
 
-  if (dwarf2_per_objfile->using_index)
+  if (dwarf2_per_objfile->per_bfd->using_index)
     {
-      per_cu->v.quick = OBSTACK_ZALLOC (&dwarf2_per_objfile->obstack,
+      per_cu->v.quick = OBSTACK_ZALLOC (&dwarf2_per_objfile->per_bfd->obstack,
 					struct dwarf2_per_cu_quick_data);
     }
   else
@@ -7247,14 +7247,14 @@ get_type_unit_group (struct dwarf2_cu *cu, const struct attribute *stmt_list)
 {
   struct dwarf2_per_objfile *dwarf2_per_objfile
     = cu->per_cu->dwarf2_per_objfile;
-  struct tu_stats *tu_stats = &dwarf2_per_objfile->tu_stats;
+  struct tu_stats *tu_stats = &dwarf2_per_objfile->per_bfd->tu_stats;
   struct type_unit_group *tu_group;
   void **slot;
   unsigned int line_offset;
   struct type_unit_group type_unit_group_for_lookup;
 
-  if (dwarf2_per_objfile->type_unit_groups == NULL)
-    dwarf2_per_objfile->type_unit_groups = allocate_type_unit_groups_table ();
+  if (dwarf2_per_objfile->per_bfd->type_unit_groups == NULL)
+    dwarf2_per_objfile->per_bfd->type_unit_groups = allocate_type_unit_groups_table ();
 
   /* Do we need to create a new group, or can we use an existing one?  */
 
@@ -7278,7 +7278,7 @@ get_type_unit_group (struct dwarf2_cu *cu, const struct attribute *stmt_list)
 
   type_unit_group_for_lookup.hash.dwo_unit = cu->dwo_unit;
   type_unit_group_for_lookup.hash.line_sect_off = (sect_offset) line_offset;
-  slot = htab_find_slot (dwarf2_per_objfile->type_unit_groups.get (),
+  slot = htab_find_slot (dwarf2_per_objfile->per_bfd->type_unit_groups.get (),
 			 &type_unit_group_for_lookup, INSERT);
   if (*slot != NULL)
     {
@@ -7577,7 +7577,7 @@ sort_tu_by_abbrev_offset (const struct tu_abbrev_offset &a,
    sharing 8K abbrev tables.
 
    The main purpose of this function is to support building the
-   dwarf2_per_objfile->type_unit_groups table.
+   dwarf2_per_objfile->per_bfd->type_unit_groups table.
    TUs typically share the DW_AT_stmt_list of the CU they came from, so we
    can collapse the search space by grouping them by stmt_list.
    The savings can be significant, in the same program from above the 200K TUs
@@ -7585,19 +7585,19 @@ sort_tu_by_abbrev_offset (const struct tu_abbrev_offset &a,
 
    FUNC is expected to call get_type_unit_group, which will create the
    struct type_unit_group if necessary and add it to
-   dwarf2_per_objfile->type_unit_groups.  */
+   dwarf2_per_objfile->per_bfd->type_unit_groups.  */
 
 static void
 build_type_psymtabs_1 (struct dwarf2_per_objfile *dwarf2_per_objfile)
 {
-  struct tu_stats *tu_stats = &dwarf2_per_objfile->tu_stats;
+  struct tu_stats *tu_stats = &dwarf2_per_objfile->per_bfd->tu_stats;
   abbrev_table_up abbrev_table;
   sect_offset abbrev_offset;
 
   /* It's up to the caller to not call us multiple times.  */
-  gdb_assert (dwarf2_per_objfile->type_unit_groups == NULL);
+  gdb_assert (dwarf2_per_objfile->per_bfd->type_unit_groups == NULL);
 
-  if (dwarf2_per_objfile->all_type_units.empty ())
+  if (dwarf2_per_objfile->per_bfd->all_type_units.empty ())
     return;
 
   /* TUs typically share abbrev tables, and there can be way more TUs than
@@ -7625,9 +7625,9 @@ build_type_psymtabs_1 (struct dwarf2_per_objfile *dwarf2_per_objfile)
   /* Sort in a separate table to maintain the order of all_type_units
      for .gdb_index: TU indices directly index all_type_units.  */
   std::vector<tu_abbrev_offset> sorted_by_abbrev;
-  sorted_by_abbrev.reserve (dwarf2_per_objfile->all_type_units.size ());
+  sorted_by_abbrev.reserve (dwarf2_per_objfile->per_bfd->all_type_units.size ());
 
-  for (signatured_type *sig_type : dwarf2_per_objfile->all_type_units)
+  for (signatured_type *sig_type : dwarf2_per_objfile->per_bfd->all_type_units)
     sorted_by_abbrev.emplace_back
       (sig_type, read_abbrev_offset (dwarf2_per_objfile,
 				     sig_type->per_cu.section,
@@ -7647,7 +7647,7 @@ build_type_psymtabs_1 (struct dwarf2_per_objfile *dwarf2_per_objfile)
 	  abbrev_offset = tu.abbrev_offset;
 	  abbrev_table =
 	    abbrev_table::read (dwarf2_per_objfile->objfile,
-				&dwarf2_per_objfile->abbrev,
+				&dwarf2_per_objfile->per_bfd->abbrev,
 				abbrev_offset);
 	  ++tu_stats->nr_uniq_abbrev_tables;
 	}
@@ -7665,11 +7665,11 @@ build_type_psymtabs_1 (struct dwarf2_per_objfile *dwarf2_per_objfile)
 static void
 print_tu_stats (struct dwarf2_per_objfile *dwarf2_per_objfile)
 {
-  struct tu_stats *tu_stats = &dwarf2_per_objfile->tu_stats;
+  struct tu_stats *tu_stats = &dwarf2_per_objfile->per_bfd->tu_stats;
 
   fprintf_unfiltered (gdb_stdlog, "Type unit statistics:\n");
   fprintf_unfiltered (gdb_stdlog, "  %zu TUs\n",
-		      dwarf2_per_objfile->all_type_units.size ());
+		      dwarf2_per_objfile->per_bfd->all_type_units.size ());
   fprintf_unfiltered (gdb_stdlog, "  %d uniq abbrev tables\n",
 		      tu_stats->nr_uniq_abbrev_tables);
   fprintf_unfiltered (gdb_stdlog, "  %d symtabs from stmt_list entries\n",
@@ -7740,11 +7740,11 @@ process_skeletonless_type_unit (void **slot, void *info)
 
   /* If this TU doesn't exist in the global table, add it and read it in.  */
 
-  if (dwarf2_per_objfile->signatured_types == NULL)
-    dwarf2_per_objfile->signatured_types = allocate_signatured_type_table ();
+  if (dwarf2_per_objfile->per_bfd->signatured_types == NULL)
+    dwarf2_per_objfile->per_bfd->signatured_types = allocate_signatured_type_table ();
 
   find_entry.signature = dwo_unit->signature;
-  slot = htab_find_slot (dwarf2_per_objfile->signatured_types.get (),
+  slot = htab_find_slot (dwarf2_per_objfile->per_bfd->signatured_types.get (),
 			 &find_entry, INSERT);
   /* If we've already seen this type there's nothing to do.  What's happening
      is we're doing our own version of comdat-folding here.  */
@@ -7789,9 +7789,9 @@ process_skeletonless_type_units (struct dwarf2_per_objfile *dwarf2_per_objfile)
 {
   /* Skeletonless TUs in DWP files without .gdb_index is not supported yet.  */
   if (get_dwp_file (dwarf2_per_objfile) == NULL
-      && dwarf2_per_objfile->dwo_files != NULL)
+      && dwarf2_per_objfile->per_bfd->dwo_files != NULL)
     {
-      htab_traverse_noresize (dwarf2_per_objfile->dwo_files.get (),
+      htab_traverse_noresize (dwarf2_per_objfile->per_bfd->dwo_files.get (),
 			      process_dwo_file_for_skeletonless_type_units,
 			      dwarf2_per_objfile);
     }
@@ -7802,7 +7802,7 @@ process_skeletonless_type_units (struct dwarf2_per_objfile *dwarf2_per_objfile)
 static void
 set_partial_user (struct dwarf2_per_objfile *dwarf2_per_objfile)
 {
-  for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->all_comp_units)
+  for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->per_bfd->all_comp_units)
     {
       dwarf2_psymtab *pst = per_cu->v.psymtab;
 
@@ -7833,10 +7833,10 @@ dwarf2_build_psymtabs_hard (struct dwarf2_per_objfile *dwarf2_per_objfile)
     }
 
   scoped_restore restore_reading_psyms
-    = make_scoped_restore (&dwarf2_per_objfile->reading_partial_symbols,
+    = make_scoped_restore (&dwarf2_per_objfile->per_bfd->reading_partial_symbols,
 			   true);
 
-  dwarf2_per_objfile->info.read (objfile);
+  dwarf2_per_objfile->per_bfd->info.read (objfile);
 
   /* Any cached compilation units will be linked by the per-objfile
      read_in_chain.  Make sure to free them when we're done.  */
@@ -7854,7 +7854,7 @@ dwarf2_build_psymtabs_hard (struct dwarf2_per_objfile *dwarf2_per_objfile)
     = make_scoped_restore (&objfile->partial_symtabs->psymtabs_addrmap,
 			   addrmap_create_mutable (&temp_obstack));
 
-  for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->all_comp_units)
+  for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->per_bfd->all_comp_units)
     {
       if (per_cu->v.psymtab != NULL)
 	/* In case a forward DW_TAG_imported_unit has read the CU already.  */
@@ -7866,9 +7866,9 @@ dwarf2_build_psymtabs_hard (struct dwarf2_per_objfile *dwarf2_per_objfile)
   process_skeletonless_type_units (dwarf2_per_objfile);
 
   /* Now that all TUs have been processed we can fill in the dependencies.  */
-  if (dwarf2_per_objfile->type_unit_groups != NULL)
+  if (dwarf2_per_objfile->per_bfd->type_unit_groups != NULL)
     {
-      htab_traverse_noresize (dwarf2_per_objfile->type_unit_groups.get (),
+      htab_traverse_noresize (dwarf2_per_objfile->per_bfd->type_unit_groups.get (),
 			      build_type_psymtab_dependencies, dwarf2_per_objfile);
     }
 
@@ -7942,10 +7942,10 @@ read_comp_units_from_section (struct dwarf2_per_objfile *dwarf2_per_objfile,
 
       /* Save the compilation unit for later lookup.  */
       if (cu_header.unit_type != DW_UT_type)
-	this_cu = dwarf2_per_objfile->allocate_per_cu ();
+	this_cu = dwarf2_per_objfile->per_bfd->allocate_per_cu ();
       else
 	{
-	  auto sig_type = dwarf2_per_objfile->allocate_signatured_type ();
+	  auto sig_type = dwarf2_per_objfile->per_bfd->allocate_signatured_type ();
 	  sig_type->signature = cu_header.signature;
 	  sig_type->type_offset_in_tu = cu_header.type_cu_offset_in_tu;
 	  this_cu = &sig_type->per_cu;
@@ -7957,7 +7957,7 @@ read_comp_units_from_section (struct dwarf2_per_objfile *dwarf2_per_objfile,
       this_cu->dwarf2_per_objfile = dwarf2_per_objfile;
       this_cu->section = section;
 
-      dwarf2_per_objfile->all_comp_units.push_back (this_cu);
+      dwarf2_per_objfile->per_bfd->all_comp_units.push_back (this_cu);
 
       info_ptr = info_ptr + this_cu->length;
     }
@@ -7969,9 +7969,9 @@ read_comp_units_from_section (struct dwarf2_per_objfile *dwarf2_per_objfile,
 static void
 create_all_comp_units (struct dwarf2_per_objfile *dwarf2_per_objfile)
 {
-  gdb_assert (dwarf2_per_objfile->all_comp_units.empty ());
-  read_comp_units_from_section (dwarf2_per_objfile, &dwarf2_per_objfile->info,
-				&dwarf2_per_objfile->abbrev, 0);
+  gdb_assert (dwarf2_per_objfile->per_bfd->all_comp_units.empty ());
+  read_comp_units_from_section (dwarf2_per_objfile, &dwarf2_per_objfile->per_bfd->info,
+				&dwarf2_per_objfile->per_bfd->abbrev, 0);
 
   dwz_file *dwz = dwarf2_get_dwz_file (dwarf2_per_objfile);
   if (dwz != NULL)
@@ -8309,7 +8309,7 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu)
 
       if (pdi->d.locdesc
 	  && addr == 0
-	  && !dwarf2_per_objfile->has_section_at_zero)
+	  && !dwarf2_per_objfile->per_bfd->has_section_at_zero)
 	{
 	  /* A global or static variable may also have been stripped
 	     out by the linker if unused, in which case its address
@@ -8811,8 +8811,8 @@ dwarf2_psymtab::read_symtab (struct objfile *objfile)
       struct dwarf2_per_objfile *dpo_backlink
 	= get_dwarf2_per_objfile (objfile->separate_debug_objfile_backlink);
 
-      dwarf2_per_objfile->has_section_at_zero
-	= dpo_backlink->has_section_at_zero;
+      dwarf2_per_objfile->per_bfd->has_section_at_zero
+	= dpo_backlink->per_bfd->has_section_at_zero;
     }
 
   expand_psymtab (objfile);
@@ -8829,7 +8829,7 @@ queue_comp_unit (struct dwarf2_per_cu_data *per_cu,
 		 enum language pretend_language)
 {
   per_cu->queued = 1;
-  per_cu->dwarf2_per_objfile->queue.emplace (per_cu, pretend_language);
+  per_cu->dwarf2_per_objfile->per_bfd->queue.emplace (per_cu, pretend_language);
 }
 
 /* If PER_CU is not yet queued, add it to the queue.
@@ -8849,7 +8849,7 @@ maybe_queue_comp_unit (struct dwarf2_cu *dependent_cu,
   /* We may arrive here during partial symbol reading, if we need full
      DIEs to process an unusual case (e.g. template arguments).  Do
      not queue PER_CU, just tell our caller to load its DIEs.  */
-  if (per_cu->dwarf2_per_objfile->reading_partial_symbols)
+  if (per_cu->dwarf2_per_objfile->per_bfd->reading_partial_symbols)
     {
       if (per_cu->cu == NULL || per_cu->cu->dies == NULL)
 	return 1;
@@ -8893,11 +8893,11 @@ process_queue (struct dwarf2_per_objfile *dwarf2_per_objfile)
 
   /* The queue starts out with one item, but following a DIE reference
      may load a new CU, adding it to the end of the queue.  */
-  while (!dwarf2_per_objfile->queue.empty ())
+  while (!dwarf2_per_objfile->per_bfd->queue.empty ())
     {
-      dwarf2_queue_item &item = dwarf2_per_objfile->queue.front ();
+      dwarf2_queue_item &item = dwarf2_per_objfile->per_bfd->queue.front ();
 
-      if ((dwarf2_per_objfile->using_index
+      if ((dwarf2_per_objfile->per_bfd->using_index
 	   ? !item.per_cu->v.quick->compunit_symtab
 	   : (item.per_cu->v.psymtab && !item.per_cu->v.psymtab->readin))
 	  /* Skip dummy CUs.  */
@@ -8939,7 +8939,7 @@ process_queue (struct dwarf2_per_objfile *dwarf2_per_objfile)
 	}
 
       item.per_cu->queued = 0;
-      dwarf2_per_objfile->queue.pop ();
+      dwarf2_per_objfile->per_bfd->queue.pop ();
     }
 
   if (dwarf_read_debug)
@@ -9505,7 +9505,7 @@ rust_union_quirks (struct dwarf2_cu *cu)
 static struct compunit_symtab *
 get_compunit_symtab (struct dwarf2_per_cu_data *per_cu)
 {
-  return (per_cu->dwarf2_per_objfile->using_index
+  return (per_cu->dwarf2_per_objfile->per_bfd->using_index
 	  ? per_cu->v.quick->compunit_symtab
 	  : per_cu->v.psymtab->compunit_symtab);
 }
@@ -9613,13 +9613,13 @@ compute_compunit_symtab_includes (struct dwarf2_per_cu_data *per_cu)
 static void
 process_cu_includes (struct dwarf2_per_objfile *dwarf2_per_objfile)
 {
-  for (dwarf2_per_cu_data *iter : dwarf2_per_objfile->just_read_cus)
+  for (dwarf2_per_cu_data *iter : dwarf2_per_objfile->per_bfd->just_read_cus)
     {
       if (! iter->is_debug_types)
 	compute_compunit_symtab_includes (iter);
     }
 
-  dwarf2_per_objfile->just_read_cus.clear ();
+  dwarf2_per_objfile->per_bfd->just_read_cus.clear ();
 }
 
 /* Generate full symbol information for PER_CU, whose DIEs have
@@ -9713,7 +9713,7 @@ process_full_comp_unit (struct dwarf2_per_cu_data *per_cu,
       cust->call_site_htab = cu->call_site_htab;
     }
 
-  if (dwarf2_per_objfile->using_index)
+  if (dwarf2_per_objfile->per_bfd->using_index)
     per_cu->v.quick->compunit_symtab = cust;
   else
     {
@@ -9723,7 +9723,7 @@ process_full_comp_unit (struct dwarf2_per_cu_data *per_cu,
     }
 
   /* Push it for inclusion processing later.  */
-  dwarf2_per_objfile->just_read_cus.push_back (per_cu);
+  dwarf2_per_objfile->per_bfd->just_read_cus.push_back (per_cu);
 
   /* Not needed any more.  */
   cu->reset_builder ();
@@ -9793,7 +9793,7 @@ process_full_type_unit (struct dwarf2_per_cu_data *per_cu,
       cust = sig_type->type_unit_group->compunit_symtab;
     }
 
-  if (dwarf2_per_objfile->using_index)
+  if (dwarf2_per_objfile->per_bfd->using_index)
     per_cu->v.quick->compunit_symtab = cust;
   else
     {
@@ -10098,7 +10098,7 @@ dw2_linkage_name (struct die_info *die, struct dwarf2_cu *cu)
    For Ada, return the DIE's linkage name rather than the fully qualified
    name.  PHYSNAME is ignored..
 
-   The result is allocated on the dwarf2_per_objfile obstack and
+   The result is allocated on the objfile->per_bfd's obstack and
    canonicalized.  */
 
 static const char *
@@ -10761,10 +10761,10 @@ handle_DW_AT_stmt_list (struct die_info *die, struct dwarf2_cu *cu,
      compile_unit, then use the line header hash table if it's already
      created, but don't create one just yet.  */
 
-  if (dwarf2_per_objfile->line_header_hash == NULL
+  if (dwarf2_per_objfile->per_bfd->line_header_hash == NULL
       && die->tag == DW_TAG_partial_unit)
     {
-      dwarf2_per_objfile->line_header_hash
+      dwarf2_per_objfile->per_bfd->line_header_hash
 	.reset (htab_create_alloc (127, line_header_hash_voidp,
 				   line_header_eq_voidp,
 				   free_line_header_voidp,
@@ -10774,9 +10774,9 @@ handle_DW_AT_stmt_list (struct die_info *die, struct dwarf2_cu *cu,
   line_header_local.sect_off = line_offset;
   line_header_local.offset_in_dwz = cu->per_cu->is_dwz;
   line_header_local_hash = line_header_hash (&line_header_local);
-  if (dwarf2_per_objfile->line_header_hash != NULL)
+  if (dwarf2_per_objfile->per_bfd->line_header_hash != NULL)
     {
-      slot = htab_find_slot_with_hash (dwarf2_per_objfile->line_header_hash.get (),
+      slot = htab_find_slot_with_hash (dwarf2_per_objfile->per_bfd->line_header_hash.get (),
 				       &line_header_local,
 				       line_header_local_hash, NO_INSERT);
 
@@ -10800,11 +10800,11 @@ handle_DW_AT_stmt_list (struct die_info *die, struct dwarf2_cu *cu,
   cu->line_header = lh.release ();
   cu->line_header_die_owner = die;
 
-  if (dwarf2_per_objfile->line_header_hash == NULL)
+  if (dwarf2_per_objfile->per_bfd->line_header_hash == NULL)
     slot = NULL;
   else
     {
-      slot = htab_find_slot_with_hash (dwarf2_per_objfile->line_header_hash.get (),
+      slot = htab_find_slot_with_hash (dwarf2_per_objfile->per_bfd->line_header_hash.get (),
 				       &line_header_local,
 				       line_header_local_hash, INSERT);
       gdb_assert (slot != NULL);
@@ -11121,12 +11121,12 @@ lookup_dwo_file_slot (struct dwarf2_per_objfile *dwarf2_per_objfile,
   struct dwo_file find_entry;
   void **slot;
 
-  if (dwarf2_per_objfile->dwo_files == NULL)
-    dwarf2_per_objfile->dwo_files = allocate_dwo_file_hash_table ();
+  if (dwarf2_per_objfile->per_bfd->dwo_files == NULL)
+    dwarf2_per_objfile->per_bfd->dwo_files = allocate_dwo_file_hash_table ();
 
   find_entry.dwo_name = dwo_name;
   find_entry.comp_dir = comp_dir;
-  slot = htab_find_slot (dwarf2_per_objfile->dwo_files.get (), &find_entry,
+  slot = htab_find_slot (dwarf2_per_objfile->per_bfd->dwo_files.get (), &find_entry,
 			 INSERT);
 
   return slot;
@@ -11254,7 +11254,7 @@ create_cus_hash_table (struct dwarf2_per_objfile *dwarf2_per_objfile,
       if (cus_htab == NULL)
 	cus_htab = allocate_dwo_unit_table ();
 
-      dwo_unit = OBSTACK_ZALLOC (&dwarf2_per_objfile->obstack,
+      dwo_unit = OBSTACK_ZALLOC (&dwarf2_per_objfile->per_bfd->obstack,
 				 struct dwo_unit);
       *dwo_unit = read_unit;
       slot = htab_find_slot (cus_htab.get (), dwo_unit, INSERT);
@@ -11458,7 +11458,7 @@ create_dwp_hash_table (struct dwarf2_per_objfile *dwarf2_per_objfile,
 	     pulongest (nr_slots), dwp_file->name);
     }
 
-  htab = OBSTACK_ZALLOC (&dwarf2_per_objfile->obstack, struct dwp_hash_table);
+  htab = OBSTACK_ZALLOC (&dwarf2_per_objfile->per_bfd->obstack, struct dwp_hash_table);
   htab->version = version;
   htab->nr_columns = nr_columns;
   htab->nr_units = nr_units;
@@ -11788,11 +11788,11 @@ create_dwo_unit_in_dwp_v1 (struct dwarf2_per_objfile *dwarf2_per_objfile,
       dwo_file = (struct dwo_file *) *dwo_file_slot;
     }
 
-  dwo_unit = OBSTACK_ZALLOC (&dwarf2_per_objfile->obstack, struct dwo_unit);
+  dwo_unit = OBSTACK_ZALLOC (&dwarf2_per_objfile->per_bfd->obstack, struct dwo_unit);
   dwo_unit->dwo_file = dwo_file;
   dwo_unit->signature = signature;
   dwo_unit->section =
-    XOBNEW (&dwarf2_per_objfile->obstack, struct dwarf2_section_info);
+    XOBNEW (&dwarf2_per_objfile->per_bfd->obstack, struct dwarf2_section_info);
   *dwo_unit->section = sections.info_or_types;
   /* dwo_unit->{offset,length,type_offset_in_tu} are set later.  */
 
@@ -11996,11 +11996,11 @@ create_dwo_unit_in_dwp_v2 (struct dwarf2_per_objfile *dwarf2_per_objfile,
       dwo_file = (struct dwo_file *) *dwo_file_slot;
     }
 
-  dwo_unit = OBSTACK_ZALLOC (&dwarf2_per_objfile->obstack, struct dwo_unit);
+  dwo_unit = OBSTACK_ZALLOC (&dwarf2_per_objfile->per_bfd->obstack, struct dwo_unit);
   dwo_unit->dwo_file = dwo_file;
   dwo_unit->signature = signature;
   dwo_unit->section =
-    XOBNEW (&dwarf2_per_objfile->obstack, struct dwarf2_section_info);
+    XOBNEW (&dwarf2_per_objfile->per_bfd->obstack, struct dwarf2_section_info);
   *dwo_unit->section = create_dwp_v2_section (dwarf2_per_objfile,
 					      is_debug_types
 					      ? &dwp_file->sections.types
@@ -12506,7 +12506,7 @@ open_and_init_dwp_file (struct dwarf2_per_objfile *dwarf2_per_objfile)
 
   dwp_file->num_sections = elf_numsections (dwp_file->dbfd);
   dwp_file->elf_sections =
-    OBSTACK_CALLOC (&dwarf2_per_objfile->obstack,
+    OBSTACK_CALLOC (&dwarf2_per_objfile->per_bfd->obstack,
 		    dwp_file->num_sections, asection *);
 
   bfd_map_over_sections (dwp_file->dbfd.get (),
@@ -12564,13 +12564,13 @@ open_and_init_dwp_file (struct dwarf2_per_objfile *dwarf2_per_objfile)
 static struct dwp_file *
 get_dwp_file (struct dwarf2_per_objfile *dwarf2_per_objfile)
 {
-  if (! dwarf2_per_objfile->dwp_checked)
+  if (! dwarf2_per_objfile->per_bfd->dwp_checked)
     {
-      dwarf2_per_objfile->dwp_file
+      dwarf2_per_objfile->per_bfd->dwp_file
 	= open_and_init_dwp_file (dwarf2_per_objfile);
-      dwarf2_per_objfile->dwp_checked = 1;
+      dwarf2_per_objfile->per_bfd->dwp_checked = 1;
     }
-  return dwarf2_per_objfile->dwp_file.get ();
+  return dwarf2_per_objfile->per_bfd->dwp_file.get ();
 }
 
 /* Subroutine of lookup_dwo_comp_unit, lookup_dwo_type_unit.
@@ -13567,7 +13567,7 @@ read_variable (struct die_info *die, struct dwarf2_cu *cu)
       struct die_info *origin_die
 	= follow_die_ref (die, abstract_origin, &origin_cu);
       dwarf2_per_objfile *dpo = cu->per_cu->dwarf2_per_objfile;
-      dpo->abstract_to_concrete[origin_die->sect_off].push_back (die->sect_off);
+      dpo->per_bfd->abstract_to_concrete[origin_die->sect_off].push_back (die->sect_off);
     }
 }
 
@@ -13595,14 +13595,14 @@ dwarf2_rnglists_process (unsigned offset, struct dwarf2_cu *cu,
 
   base = cu->base_address;
 
-  dwarf2_per_objfile->rnglists.read (objfile);
-  if (offset >= dwarf2_per_objfile->rnglists.size)
+  dwarf2_per_objfile->per_bfd->rnglists.read (objfile);
+  if (offset >= dwarf2_per_objfile->per_bfd->rnglists.size)
     {
       complaint (_("Offset %d out of bounds for DW_AT_ranges attribute"),
 		 offset);
       return false;
     }
-  buffer = dwarf2_per_objfile->rnglists.buffer + offset;
+  buffer = dwarf2_per_objfile->per_bfd->rnglists.buffer + offset;
 
   baseaddr = objfile->text_section_offset ();
 
@@ -13610,8 +13610,8 @@ dwarf2_rnglists_process (unsigned offset, struct dwarf2_cu *cu,
     {
       /* Initialize it due to a false compiler warning.  */
       CORE_ADDR range_beginning = 0, range_end = 0;
-      const gdb_byte *buf_end = (dwarf2_per_objfile->rnglists.buffer
-				 + dwarf2_per_objfile->rnglists.size);
+      const gdb_byte *buf_end = (dwarf2_per_objfile->per_bfd->rnglists.buffer
+				 + dwarf2_per_objfile->per_bfd->rnglists.size);
       unsigned int bytes_read;
 
       if (buffer == buf_end)
@@ -13713,7 +13713,7 @@ dwarf2_rnglists_process (unsigned offset, struct dwarf2_cu *cu,
       /* A not-uncommon case of bad debug info.
 	 Don't pollute the addrmap with bad data.  */
       if (range_beginning + baseaddr == 0
-	  && !dwarf2_per_objfile->has_section_at_zero)
+	  && !dwarf2_per_objfile->per_bfd->has_section_at_zero)
 	{
 	  complaint (_(".debug_rnglists entry has start address of zero"
 		       " [in module %s]"), objfile_name (objfile));
@@ -13762,14 +13762,14 @@ dwarf2_ranges_process (unsigned offset, struct dwarf2_cu *cu,
 
   base = cu->base_address;
 
-  dwarf2_per_objfile->ranges.read (objfile);
-  if (offset >= dwarf2_per_objfile->ranges.size)
+  dwarf2_per_objfile->per_bfd->ranges.read (objfile);
+  if (offset >= dwarf2_per_objfile->per_bfd->ranges.size)
     {
       complaint (_("Offset %d out of bounds for DW_AT_ranges attribute"),
 		 offset);
       return 0;
     }
-  buffer = dwarf2_per_objfile->ranges.buffer + offset;
+  buffer = dwarf2_per_objfile->per_bfd->ranges.buffer + offset;
 
   baseaddr = objfile->text_section_offset ();
 
@@ -13824,7 +13824,7 @@ dwarf2_ranges_process (unsigned offset, struct dwarf2_cu *cu,
       /* A not-uncommon case of bad debug info.
 	 Don't pollute the addrmap with bad data.  */
       if (range_beginning + baseaddr == 0
-	  && !dwarf2_per_objfile->has_section_at_zero)
+	  && !dwarf2_per_objfile->per_bfd->has_section_at_zero)
 	{
 	  complaint (_(".debug_ranges entry has start address of zero"
 		       " [in module %s]"), objfile_name (objfile));
@@ -13977,7 +13977,7 @@ dwarf2_get_pc_bounds (struct die_info *die, CORE_ADDR *lowpc,
      labels are not in the output, so the relocs get a value of 0.
      If this is a discarded function, mark the pc bounds as invalid,
      so that GDB will ignore it.  */
-  if (low == 0 && !dwarf2_per_objfile->has_section_at_zero)
+  if (low == 0 && !dwarf2_per_objfile->per_bfd->has_section_at_zero)
     return PC_BOUNDS_INVALID;
 
   *lowpc = low;
@@ -18515,7 +18515,7 @@ partial_die_info::read (const struct die_reader_specs *reader,
 	 labels are not in the output, so the relocs get a value of 0.
 	 If this is a discarded function, mark the pc bounds as invalid,
 	 so that GDB will ignore it.  */
-      if (lowpc == 0 && !dwarf2_per_objfile->has_section_at_zero)
+      if (lowpc == 0 && !dwarf2_per_objfile->per_bfd->has_section_at_zero)
 	{
 	  struct objfile *objfile = dwarf2_per_objfile->objfile;
 	  struct gdbarch *gdbarch = objfile->arch ();
@@ -18762,7 +18762,7 @@ partial_die_info::fixup (struct dwarf2_cu *cu)
      children, see if we can determine the namespace from their linkage
      name.  */
   if (cu->language == language_cplus
-      && !cu->per_cu->dwarf2_per_objfile->types.empty ()
+      && !cu->per_cu->dwarf2_per_objfile->per_bfd->types.empty ()
       && die_parent == NULL
       && has_children
       && (tag == DW_TAG_class_type
@@ -19219,8 +19219,8 @@ static const char *
 read_indirect_string_at_offset (struct dwarf2_per_objfile *dwarf2_per_objfile,
 				LONGEST str_offset)
 {
-  return dwarf2_per_objfile->str.read_string (dwarf2_per_objfile->objfile,
-					      str_offset, "DW_FORM_strp");
+  return dwarf2_per_objfile->per_bfd->str.read_string
+    (dwarf2_per_objfile->objfile, str_offset, "DW_FORM_strp");
 }
 
 /* Return pointer to string at .debug_str offset as read from BUF.
@@ -19242,13 +19242,13 @@ read_indirect_string (struct dwarf2_per_objfile *dwarf2_per_objfile, bfd *abfd,
 
 const char *
 dwarf2_per_objfile::read_line_string (const gdb_byte *buf,
-			   const struct comp_unit_head *cu_header,
-			   unsigned int *bytes_read_ptr)
+				      const struct comp_unit_head *cu_header,
+				      unsigned int *bytes_read_ptr)
 {
   bfd *abfd = objfile->obfd;
   LONGEST str_offset = cu_header->read_offset (abfd, buf, bytes_read_ptr);
 
-  return line_str.read_string (objfile, str_offset, "DW_FORM_line_strp");
+  return per_bfd->line_str.read_string (objfile, str_offset, "DW_FORM_line_strp");
 }
 
 /* Given index ADDR_INDEX in .debug_addr, fetch the value.
@@ -19265,16 +19265,16 @@ read_addr_index_1 (struct dwarf2_per_objfile *dwarf2_per_objfile,
   const gdb_byte *info_ptr;
   ULONGEST addr_base_or_zero = addr_base.has_value () ? *addr_base : 0;
 
-  dwarf2_per_objfile->addr.read (objfile);
-  if (dwarf2_per_objfile->addr.buffer == NULL)
+  dwarf2_per_objfile->per_bfd->addr.read (objfile);
+  if (dwarf2_per_objfile->per_bfd->addr.buffer == NULL)
     error (_("DW_FORM_addr_index used without .debug_addr section [in module %s]"),
 	   objfile_name (objfile));
   if (addr_base_or_zero + addr_index * addr_size
-      >= dwarf2_per_objfile->addr.size)
+      >= dwarf2_per_objfile->per_bfd->addr.size)
     error (_("DW_FORM_addr_index pointing outside of "
 	     ".debug_addr section [in module %s]"),
 	   objfile_name (objfile));
-  info_ptr = (dwarf2_per_objfile->addr.buffer
+  info_ptr = (dwarf2_per_objfile->per_bfd->addr.buffer
 	      + addr_base_or_zero + addr_index * addr_size);
   if (addr_size == 4)
     return bfd_get_32 (abfd, info_ptr);
@@ -19420,8 +19420,8 @@ read_stub_str_index (struct dwarf2_cu *cu, ULONGEST str_index)
 	   (long) cu->header.offset_size, objf_name);
 
   return read_str_index (cu,
-			 &cu->per_cu->dwarf2_per_objfile->str,
-			 &cu->per_cu->dwarf2_per_objfile->str_offsets,
+			 &cu->per_cu->dwarf2_per_objfile->per_bfd->str,
+			 &cu->per_cu->dwarf2_per_objfile->per_bfd->str_offsets,
 			 *cu->str_offsets_base, str_index);
 }
 
@@ -19641,7 +19641,7 @@ get_debug_line_section (struct dwarf2_cu *cu)
       section = &dwz->line;
     }
   else
-    section = &dwarf2_per_objfile->line;
+    section = &dwarf2_per_objfile->per_bfd->line;
 
   return section;
 }
@@ -20760,7 +20760,7 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
 
 	      if (SYMBOL_CLASS (sym) == LOC_STATIC
 		  && SYMBOL_VALUE_ADDRESS (sym) == 0
-		  && !dwarf2_per_objfile->has_section_at_zero)
+		  && !dwarf2_per_objfile->per_bfd->has_section_at_zero)
 		{
 		  /* When a static variable is eliminated by the linker,
 		     the corresponding debug information is not stripped
@@ -20771,7 +20771,7 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
 		{
 		  if (SYMBOL_CLASS (sym) == LOC_STATIC
 		      && (objfile->flags & OBJF_MAINLINE) == 0
-		      && dwarf2_per_objfile->can_copy)
+		      && dwarf2_per_objfile->per_bfd->can_copy)
 		    {
 		      /* A global static variable might be subject to
 			 copy relocation.  We first check for a local
@@ -21683,7 +21683,7 @@ determine_prefix (struct die_info *die, struct dwarf2_cu *cu)
       case DW_TAG_partial_unit:
 	/* gcc-4.5 -gdwarf-4 can drop the enclosing namespace.  Cope.  */
 	if (cu->language == language_cplus
-	    && !dwarf2_per_objfile->types.empty ()
+	    && !dwarf2_per_objfile->per_bfd->types.empty ()
 	    && die->child != NULL
 	    && (die->tag == DW_TAG_class_type
 		|| die->tag == DW_TAG_structure_type
@@ -22162,7 +22162,7 @@ follow_die_offset (sect_offset sect_off, int offset_in_dwz,
   else if (cu->dies == NULL)
     {
       /* We're loading full DIEs during partial symbol reading.  */
-      gdb_assert (dwarf2_per_objfile->reading_partial_symbols);
+      gdb_assert (dwarf2_per_objfile->per_bfd->reading_partial_symbols);
       load_full_comp_unit (cu->per_cu, false, language_minimal);
     }
 
@@ -22235,15 +22235,15 @@ dwarf2_fetch_die_loc_sect_off (sect_offset sect_off,
 
   attr = dwarf2_attr (die, DW_AT_location, cu);
   if (!attr && resolve_abstract_p
-      && (dwarf2_per_objfile->abstract_to_concrete.find (die->sect_off)
-	  != dwarf2_per_objfile->abstract_to_concrete.end ()))
+      && (dwarf2_per_objfile->per_bfd->abstract_to_concrete.find (die->sect_off)
+	  != dwarf2_per_objfile->per_bfd->abstract_to_concrete.end ()))
     {
       CORE_ADDR pc = (*get_frame_pc) (baton);
       CORE_ADDR baseaddr = objfile->text_section_offset ();
       struct gdbarch *gdbarch = objfile->arch ();
 
       for (const auto &cand_off
-	     : dwarf2_per_objfile->abstract_to_concrete[die->sect_off])
+	     : dwarf2_per_objfile->per_bfd->abstract_to_concrete[die->sect_off])
 	{
 	  struct dwarf2_cu *cand_cu = cu;
 	  struct die_info *cand
@@ -22535,8 +22535,8 @@ follow_die_sig_1 (struct die_info *src_die, struct signatured_type *sig_type,
 
       /* For .gdb_index version 7 keep track of included TUs.
 	 http://sourceware.org/bugzilla/show_bug.cgi?id=15021.  */
-      if (dwarf2_per_objfile->index_table != NULL
-	  && dwarf2_per_objfile->index_table->version <= 7)
+      if (dwarf2_per_objfile->per_bfd->index_table != NULL
+	  && dwarf2_per_objfile->per_bfd->index_table->version <= 7)
 	{
 	  (*ref_cu)->per_cu->imported_symtabs_push (sig_cu->per_cu);
 	}
@@ -23093,12 +23093,12 @@ dwarf_decode_macros (struct dwarf2_cu *cu, unsigned int offset,
     {
       if (section_is_gnu)
 	{
-	  section = &dwarf2_per_objfile->macro;
+	  section = &dwarf2_per_objfile->per_bfd->macro;
 	  section_name = ".debug_macro";
 	}
       else
 	{
-	  section = &dwarf2_per_objfile->macinfo;
+	  section = &dwarf2_per_objfile->per_bfd->macinfo;
 	  section_name = ".debug_macinfo";
 	}
     }
@@ -23131,8 +23131,8 @@ cu_debug_loc_section (struct dwarf2_cu *cu)
 
       return cu->header.version >= 5 ? &sections->loclists : &sections->loc;
     }
-  return (cu->header.version >= 5 ? &dwarf2_per_objfile->loclists
-				  : &dwarf2_per_objfile->loc);
+  return (cu->header.version >= 5 ? &dwarf2_per_objfile->per_bfd->loclists
+				  : &dwarf2_per_objfile->per_bfd->loc);
 }
 
 /* A helper function that fills in a dwarf2_loclist_baton.  */
@@ -23374,9 +23374,9 @@ dwarf2_find_containing_comp_unit (sect_offset sect_off,
 {
   int low
     = dwarf2_find_containing_comp_unit (sect_off, offset_in_dwz,
-					dwarf2_per_objfile->all_comp_units);
+					dwarf2_per_objfile->per_bfd->all_comp_units);
   struct dwarf2_per_cu_data *this_cu
-    = dwarf2_per_objfile->all_comp_units[low];
+    = dwarf2_per_objfile->per_bfd->all_comp_units[low];
 
   if (this_cu->is_dwz != offset_in_dwz || this_cu->sect_off > sect_off)
     {
@@ -23386,13 +23386,13 @@ dwarf2_find_containing_comp_unit (sect_offset sect_off,
 	       sect_offset_str (sect_off),
 	       bfd_get_filename (dwarf2_per_objfile->objfile->obfd));
 
-      gdb_assert (dwarf2_per_objfile->all_comp_units[low-1]->sect_off
+      gdb_assert (dwarf2_per_objfile->per_bfd->all_comp_units[low-1]->sect_off
 		  <= sect_off);
-      return dwarf2_per_objfile->all_comp_units[low-1];
+      return dwarf2_per_objfile->per_bfd->all_comp_units[low-1];
     }
   else
     {
-      if (low == dwarf2_per_objfile->all_comp_units.size () - 1
+      if (low == dwarf2_per_objfile->per_bfd->all_comp_units.size () - 1
 	  && sect_off >= this_cu->sect_off + this_cu->length)
 	error (_("invalid dwarf2 offset %s"), sect_offset_str (sect_off));
       gdb_assert (sect_off < this_cu->sect_off + this_cu->length);
@@ -23504,8 +23504,8 @@ age_cached_comp_units (struct dwarf2_per_objfile *dwarf2_per_objfile)
 {
   struct dwarf2_per_cu_data *per_cu, **last_chain;
 
-  dwarf2_clear_marks (dwarf2_per_objfile->read_in_chain);
-  per_cu = dwarf2_per_objfile->read_in_chain;
+  dwarf2_clear_marks (dwarf2_per_objfile->per_bfd->read_in_chain);
+  per_cu = dwarf2_per_objfile->per_bfd->read_in_chain;
   while (per_cu != NULL)
     {
       per_cu->cu->last_used ++;
@@ -23514,8 +23514,8 @@ age_cached_comp_units (struct dwarf2_per_objfile *dwarf2_per_objfile)
       per_cu = per_cu->cu->read_in_chain;
     }
 
-  per_cu = dwarf2_per_objfile->read_in_chain;
-  last_chain = &dwarf2_per_objfile->read_in_chain;
+  per_cu = dwarf2_per_objfile->per_bfd->read_in_chain;
+  last_chain = &dwarf2_per_objfile->per_bfd->read_in_chain;
   while (per_cu != NULL)
     {
       struct dwarf2_per_cu_data *next_cu;
@@ -23543,8 +23543,8 @@ free_one_cached_comp_unit (struct dwarf2_per_cu_data *target_per_cu)
   struct dwarf2_per_objfile *dwarf2_per_objfile
     = target_per_cu->dwarf2_per_objfile;
 
-  per_cu = dwarf2_per_objfile->read_in_chain;
-  last_chain = &dwarf2_per_objfile->read_in_chain;
+  per_cu = dwarf2_per_objfile->per_bfd->read_in_chain;
+  last_chain = &dwarf2_per_objfile->per_bfd->read_in_chain;
   while (per_cu != NULL)
     {
       struct dwarf2_per_cu_data *next_cu;
@@ -23691,8 +23691,8 @@ set_die_type (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
 			    cu->per_cu->addr_type ()))
     type->add_dyn_prop (DYN_PROP_DATA_LOCATION, prop);
 
-  if (dwarf2_per_objfile->die_type_hash == NULL)
-    dwarf2_per_objfile->die_type_hash
+  if (dwarf2_per_objfile->per_bfd->die_type_hash == NULL)
+    dwarf2_per_objfile->per_bfd->die_type_hash
       = htab_up (htab_create_alloc (127,
 				    per_cu_offset_and_type_hash,
 				    per_cu_offset_and_type_eq,
@@ -23702,7 +23702,7 @@ set_die_type (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
   ofs.sect_off = die->sect_off;
   ofs.type = type;
   slot = (struct dwarf2_per_cu_offset_and_type **)
-    htab_find_slot (dwarf2_per_objfile->die_type_hash.get (), &ofs, INSERT);
+    htab_find_slot (dwarf2_per_objfile->per_bfd->die_type_hash.get (), &ofs, INSERT);
   if (*slot)
     complaint (_("A problem internal to GDB: DIE %s has type already set"),
 	       sect_offset_str (die->sect_off));
@@ -23722,13 +23722,13 @@ get_die_type_at_offset (sect_offset sect_off,
   struct dwarf2_per_cu_offset_and_type *slot, ofs;
   struct dwarf2_per_objfile *dwarf2_per_objfile = per_cu->dwarf2_per_objfile;
 
-  if (dwarf2_per_objfile->die_type_hash == NULL)
+  if (dwarf2_per_objfile->per_bfd->die_type_hash == NULL)
     return NULL;
 
   ofs.per_cu = per_cu;
   ofs.sect_off = sect_off;
   slot = ((struct dwarf2_per_cu_offset_and_type *)
-	  htab_find (dwarf2_per_objfile->die_type_hash.get (), &ofs));
+	  htab_find (dwarf2_per_objfile->per_bfd->die_type_hash.get (), &ofs));
   if (slot)
     return slot->type;
   else
diff --git a/gdb/dwarf2/read.h b/gdb/dwarf2/read.h
index bbc4f96b7cf..4dc9496046f 100644
--- a/gdb/dwarf2/read.h
+++ b/gdb/dwarf2/read.h
@@ -66,32 +66,34 @@ struct dwarf2_queue_item
   enum language pretend_language;
 };
 
-/* Collection of data recorded per objfile.
-   This hangs off of dwarf2_objfile_data_key.  */
+/* Some DWARF data can be shared across objfiles who share the same BFD,
+   this data is stored in this object.
 
-struct dwarf2_per_objfile
+   Two dwarf2_per_objfile objects representing objfiles sharing the same BFD
+   will point to the same instance of dwarf2_per_bfd, unless the BFD requires
+   relocation.  */
+
+struct dwarf2_per_bfd
 {
-  /* Construct a dwarf2_per_objfile for OBJFILE.  NAMES points to the
+  /* Construct a dwarf2_per_bfd for OBFD.  NAMES points to the
      dwarf2 section names, or is NULL if the standard ELF names are
      used.  CAN_COPY is true for formats where symbol
      interposition is possible and so symbol values must follow copy
      relocation rules.  */
-  dwarf2_per_objfile (struct objfile *objfile,
-		      const dwarf2_debug_sections *names,
-		      bool can_copy);
+  dwarf2_per_bfd (bfd *obfd, const dwarf2_debug_sections *names, bool can_copy);
 
-  ~dwarf2_per_objfile ();
+  ~dwarf2_per_bfd ();
 
-  DISABLE_COPY_AND_ASSIGN (dwarf2_per_objfile);
+  DISABLE_COPY_AND_ASSIGN (dwarf2_per_bfd);
 
   /* Return the CU/TU given its index.
 
      This is intended for loops like:
 
-     for (i = 0; i < (dwarf2_per_objfile->n_comp_units
-		      + dwarf2_per_objfile->n_type_units); ++i)
+     for (i = 0; i < (dwarf2_per_bfd->n_comp_units
+		      + dwarf2_per_bfd->n_type_units); ++i)
        {
-         dwarf2_per_cu_data *per_cu = dwarf2_per_objfile->get_cutu (i);
+         dwarf2_per_cu_data *per_cu = dwarf2_per_bfd->get_cutu (i);
 
          ...;
        }
@@ -113,21 +115,14 @@ struct dwarf2_per_objfile
 
   /* A convenience function to allocate a dwarf2_per_cu_data.  The
      returned object has its "index" field set properly.  The object
-     is allocated on the dwarf2_per_objfile obstack.  */
+     is allocated on the dwarf2_per_bfd obstack.  */
   dwarf2_per_cu_data *allocate_per_cu ();
 
   /* A convenience function to allocate a signatured_type.  The
      returned object has its "index" field set properly.  The object
-     is allocated on the dwarf2_per_objfile obstack.  */
+     is allocated on the dwarf2_per_bfd obstack.  */
   signatured_type *allocate_signatured_type ();
 
-  /* Return pointer to string at .debug_line_str offset as read from BUF.
-     BUF is assumed to be in a compilation unit described by CU_HEADER.
-     Return *BYTES_READ_PTR count of bytes read from BUF.  */
-  const char *read_line_string (const gdb_byte *buf,
-				const struct comp_unit_head *cu_header,
-				unsigned int *bytes_read_ptr);
-
 private:
   /* This function is mapped across the sections and remembers the
      offset and size of each of the debugging sections we are
@@ -162,9 +157,6 @@ struct dwarf2_per_objfile
 
   std::vector<dwarf2_section_info> types;
 
-  /* Back link.  */
-  struct objfile *objfile = NULL;
-
   /* Table of all the compilation units.  This is used to locate
      the target compilation unit of a particular reference.  */
   std::vector<dwarf2_per_cu_data *> all_comp_units;
@@ -267,6 +259,33 @@ struct dwarf2_per_objfile
   size_t m_num_psymtabs = 0;
 };
 
+/* Collection of data recorded per objfile.
+   This hangs off of dwarf2_objfile_data_key.
+
+   Some DWARF data cannot (currently) be shared across objfiles.  Such
+   data is stored in this object.  */
+
+struct dwarf2_per_objfile
+{
+  dwarf2_per_objfile (struct objfile *objfile, dwarf2_per_bfd *per_bfd)
+    : objfile (objfile), per_bfd (per_bfd)
+  {}
+
+  /* Return pointer to string at .debug_line_str offset as read from BUF.
+     BUF is assumed to be in a compilation unit described by CU_HEADER.
+     Return *BYTES_READ_PTR count of bytes read from BUF.  */
+  const char *read_line_string (const gdb_byte *buf,
+				const struct comp_unit_head *cu_header,
+				unsigned int *bytes_read_ptr);
+
+  /* Back link.  */
+  struct objfile *objfile;
+
+  /* Pointer to the data that is (possibly) shared between this objfile and
+     other objfiles backed by the same BFD.  */
+  struct dwarf2_per_bfd *per_bfd;
+};
+
 /* Get the dwarf2_per_objfile associated to OBJFILE.  */
 
 dwarf2_per_objfile *get_dwarf2_per_objfile (struct objfile *objfile);
@@ -360,7 +379,7 @@ struct dwarf2_per_cu_data
   /* The corresponding dwarf2_per_objfile.  */
   struct dwarf2_per_objfile *dwarf2_per_objfile;
 
-  /* When dwarf2_per_objfile->using_index is true, the 'quick' field
+  /* When dwarf2_per_bfd::using_index is true, the 'quick' field
      is active.  Otherwise, the 'psymtab' field is active.  */
   union
   {
-- 
2.26.2


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

* [PATCH v2 06/42] Remove symtab links from dwarf2_psymtab and dwarf2_per_cu_quick_data
  2020-05-12 21:08 [PATCH v2 00/42] Share DWARF partial symtabs between objfiles Simon Marchi
                   ` (4 preceding siblings ...)
  2020-05-12 21:08 ` [PATCH v2 05/42] Split dwarf2_per_objfile into dwarf2_per_objfile and dwarf2_per_bfd Simon Marchi
@ 2020-05-12 21:08 ` Simon Marchi
  2020-05-12 21:08 ` [PATCH v2 07/42] Move die_type_hash to dwarf2_per_objfile Simon Marchi
                   ` (39 subsequent siblings)
  45 siblings, 0 replies; 92+ messages in thread
From: Simon Marchi @ 2020-05-12 21:08 UTC (permalink / raw)
  To: gdb-patches

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

The dwarf2_psymtab and dwarf2_per_cu_quick_data types contain a pointer
to a compunit_symtab, which is a pointer to the corresponding full
symtab.  The dwarf2_psymtab and dwarf2_per_cu_quick_data objects are
going to become objfile-independent, and possibly shared by multiple
objfiles, whereas compunit_symtab will stay objfile-dependent.  This
backlink to the compunit_symtab must therefore be removed.

This patch replaces them with a vector in the dwarf2_per_objfile type,
that serves as a mapping from dwarf2_per_cu_data objects to
compunit_symtab objects, for this particular objfile.  The vector is
indexed using the index assigned to the dwarf2_per_cu_data at its
creation.

I removed the get_compunit_symtab, as it appears to bring not much value
over calling dwarf2_per_objfile::get_symtab directly.

YYYY-MM-DD  Tom Tromey  <tom@tromey.com>
YYYY-MM-DD  Simon Marchi  <simon.marchi@efficios.com>

	* dwarf2/read.h (struct dwarf2_per_bfd) <num_psymtabs>: New
	method.
	(struct dwarf2_per_objfile) <resize_symtabs, symtab_set_p,
	get_symtab, set_symtab>: New methods.
	<m_symtabs>: New field.
	(struct dwarf2_psymtab): Derive from partial_symtab.
	<readin_p, get_compunit_symtab>: Declare methods.
	* dwarf2/read.c (dwarf2_per_objfile::symtab_set_p,
	dwarf2_per_objfile::get_symtab, dwarf2_per_objfile::set_symtab):
	New methods.
	(struct dwarf2_per_cu_quick_data) <compunit_symtab>: Remove.
	(dw2_do_instantiate_symtab, dw2_instantiate_symtab)
	(dw2_map_expand_apply, dw2_map_symtabs_matching_filename)
	(dw2_symtab_iter_next, dw2_print_stats)
	(dw2_expand_symtabs_with_fullname)
	(dw2_expand_symtabs_matching_one)
	(dw_expand_symtabs_matching_file_matcher)
	(dw2_find_pc_sect_compunit_symtab, dw2_map_symbol_filenames)
	(dw2_debug_names_iterator::next)
	(dw2_debug_names_map_matching_symbols)
	(fill_in_sig_entry_from_dwo_entry, dwarf2_psymtab::read_symtab)
	(process_queue, dwarf2_psymtab::expand_psymtab): Update.
	(dwarf2_psymtab::readin_p, dwarf2_psymtab::get_compunit_symtab):
	New methods.
	(get_compunit_symtab, process_full_comp_unit)
	(process_full_type_unit): Update.
	(dwarf2_build_psymtabs, dwarf2_initialize_objfile, add_type_unit): Call
---
 gdb/dwarf2/read.c | 162 +++++++++++++++++++++++++++-------------------
 gdb/dwarf2/read.h |  37 ++++++++++-
 2 files changed, 129 insertions(+), 70 deletions(-)

diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 0b16ec127f5..4dfa85ff0c7 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -1811,6 +1811,38 @@ class free_cached_comp_units
   dwarf2_per_objfile *m_per_objfile;
 };
 
+/* See read.h.  */
+
+bool
+dwarf2_per_objfile::symtab_set_p (const dwarf2_per_cu_data *per_cu) const
+{
+  gdb_assert (per_cu->index < this->m_symtabs.size ());
+
+  return this->m_symtabs[per_cu->index] != nullptr;
+}
+
+/* See read.h.  */
+
+compunit_symtab *
+dwarf2_per_objfile::get_symtab (const dwarf2_per_cu_data *per_cu) const
+{
+  gdb_assert (per_cu->index < this->m_symtabs.size ());
+
+  return this->m_symtabs[per_cu->index];
+}
+
+/* See read.h.  */
+
+void
+dwarf2_per_objfile::set_symtab (const dwarf2_per_cu_data *per_cu,
+				compunit_symtab *symtab)
+{
+  gdb_assert (per_cu->index < this->m_symtabs.size ());
+  gdb_assert (this->m_symtabs[per_cu->index] == nullptr);
+
+  this->m_symtabs[per_cu->index] = symtab;
+}
+
 /* Try to locate the sections we need for DWARF 2 debugging
    information and return true if we have enough to do something.
    NAMES points to the dwarf2 section names, or is NULL if the standard
@@ -2198,10 +2230,6 @@ struct dwarf2_per_cu_quick_data
      NOTE: This points into dwarf2_per_objfile->per_bfd->quick_file_names_table.  */
   struct quick_file_names *file_names;
 
-  /* The corresponding symbol table.  This is NULL if symbols for this
-     CU have not yet been read.  */
-  struct compunit_symtab *compunit_symtab;
-
   /* A temporary mark bit used when iterating over all CUs in
      expand_symtabs_matching.  */
   unsigned int mark : 1;
@@ -2325,9 +2353,7 @@ dw2_do_instantiate_symtab (struct dwarf2_per_cu_data *per_cu, bool skip_partial)
      with the dwarf queue empty.  */
   dwarf2_queue_guard q_guard (dwarf2_per_objfile);
 
-  if (dwarf2_per_objfile->per_bfd->using_index
-      ? per_cu->v.quick->compunit_symtab == NULL
-      : (per_cu->v.psymtab == NULL || !per_cu->v.psymtab->readin))
+  if (!dwarf2_per_objfile->symtab_set_p (per_cu))
     {
       queue_comp_unit (per_cu, language_minimal);
       load_cu (per_cu, skip_partial);
@@ -2362,7 +2388,8 @@ dw2_instantiate_symtab (struct dwarf2_per_cu_data *per_cu, bool skip_partial)
   struct dwarf2_per_objfile *dwarf2_per_objfile = per_cu->dwarf2_per_objfile;
 
   gdb_assert (dwarf2_per_objfile->per_bfd->using_index);
-  if (!per_cu->v.quick->compunit_symtab)
+
+  if (!dwarf2_per_objfile->symtab_set_p (per_cu))
     {
       free_cached_comp_units freer (dwarf2_per_objfile);
       scoped_restore decrementer = increment_reading_symtab ();
@@ -2370,7 +2397,7 @@ dw2_instantiate_symtab (struct dwarf2_per_cu_data *per_cu, bool skip_partial)
       process_cu_includes (dwarf2_per_objfile);
     }
 
-  return per_cu->v.quick->compunit_symtab;
+  return dwarf2_per_objfile->get_symtab (per_cu);
 }
 
 /* See declaration.  */
@@ -3274,7 +3301,8 @@ dw2_map_expand_apply (struct objfile *objfile,
   struct compunit_symtab *last_made = objfile->compunit_symtabs;
 
   /* Don't visit already-expanded CUs.  */
-  if (per_cu->v.quick->compunit_symtab)
+  dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile);
+  if (per_objfile->symtab_set_p (per_cu))
     return 0;
 
   /* This may expand more than one symtab, and we want to iterate over
@@ -3302,7 +3330,7 @@ dw2_map_symtabs_matching_filename
   for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->per_bfd->all_comp_units)
     {
       /* We only need to look at symtabs not already expanded.  */
-      if (per_cu->v.quick->compunit_symtab)
+      if (dwarf2_per_objfile->symtab_set_p (per_cu))
 	continue;
 
       quick_file_names *file_data = dw2_get_file_names (per_cu);
@@ -3444,7 +3472,7 @@ dw2_symtab_iter_next (struct dw2_symtab_iterator *iter)
       dwarf2_per_cu_data *per_cu = dwarf2_per_objfile->per_bfd->get_cutu (cu_index);
 
       /* Skip if already read in.  */
-      if (per_cu->v.quick->compunit_symtab)
+      if (dwarf2_per_objfile->symtab_set_p (per_cu))
 	continue;
 
       /* Check static vs global.  */
@@ -3559,7 +3587,7 @@ dw2_print_stats (struct objfile *objfile)
     {
       dwarf2_per_cu_data *per_cu = dwarf2_per_objfile->per_bfd->get_cutu (i);
 
-      if (!per_cu->v.quick->compunit_symtab)
+      if (!dwarf2_per_objfile->symtab_set_p (per_cu))
 	++count;
     }
   printf_filtered (_("  Number of read CUs: %d\n"), total - count);
@@ -3642,7 +3670,7 @@ dw2_expand_symtabs_with_fullname (struct objfile *objfile,
   for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->per_bfd->all_comp_units)
     {
       /* We only need to look at symtabs not already expanded.  */
-      if (per_cu->v.quick->compunit_symtab)
+      if (dwarf2_per_objfile->symtab_set_p (per_cu))
 	continue;
 
       quick_file_names *file_data = dw2_get_file_names (per_cu);
@@ -4467,15 +4495,14 @@ dw2_expand_symtabs_matching_one
 {
   if (file_matcher == NULL || per_cu->v.quick->mark)
     {
-      bool symtab_was_null
-	= (per_cu->v.quick->compunit_symtab == NULL);
+      dwarf2_per_objfile *per_objfile = per_cu->dwarf2_per_objfile;
+      bool symtab_was_null = !per_objfile->symtab_set_p (per_cu);
 
-      dw2_instantiate_symtab (per_cu, false);
+      compunit_symtab *symtab = dw2_instantiate_symtab (per_cu, false);
+      gdb_assert (symtab != nullptr);
 
-      if (expansion_notify != NULL
-	  && symtab_was_null
-	  && per_cu->v.quick->compunit_symtab != NULL)
-	expansion_notify (per_cu->v.quick->compunit_symtab);
+      if (expansion_notify != NULL && symtab_was_null)
+	expansion_notify (symtab);
     }
 }
 
@@ -4593,7 +4620,7 @@ dw_expand_symtabs_matching_file_matcher
       per_cu->v.quick->mark = 0;
 
       /* We only need to look at symtabs not already expanded.  */
-      if (per_cu->v.quick->compunit_symtab)
+      if (dwarf2_per_objfile->symtab_set_p (per_cu))
 	continue;
 
       quick_file_names *file_data = dw2_get_file_names (per_cu);
@@ -4731,7 +4758,8 @@ dw2_find_pc_sect_compunit_symtab (struct objfile *objfile,
   if (!data)
     return NULL;
 
-  if (warn_if_readin && data->v.quick->compunit_symtab)
+  dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile);
+  if (warn_if_readin && per_objfile->symtab_set_p (data))
     warning (_("(Internal error: pc %s in read in CU, but not in symtab.)"),
 	     paddress (objfile->arch (), pc));
 
@@ -4764,7 +4792,7 @@ dw2_map_symbol_filenames (struct objfile *objfile, symbol_filename_ftype *fun,
 
       for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->per_bfd->all_comp_units)
 	{
-	  if (per_cu->v.quick->compunit_symtab)
+	  if (dwarf2_per_objfile->symtab_set_p (per_cu))
 	    {
 	      void **slot = htab_find_slot (visited.get (),
 					    per_cu->v.quick->file_names,
@@ -4777,7 +4805,7 @@ dw2_map_symbol_filenames (struct objfile *objfile, symbol_filename_ftype *fun,
       for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->per_bfd->all_comp_units)
 	{
 	  /* We only need to look at symtabs not already expanded.  */
-	  if (per_cu->v.quick->compunit_symtab)
+	  if (dwarf2_per_objfile->symtab_set_p (per_cu))
 	    continue;
 
 	  quick_file_names *file_data = dw2_get_file_names (per_cu);
@@ -5448,7 +5476,7 @@ dw2_debug_names_iterator::next ()
     }
 
   /* Skip if already read in.  */
-  if (per_cu->v.quick->compunit_symtab)
+  if (dwarf2_per_objfile->symtab_set_p (per_cu))
     goto again;
 
   /* Check static vs global.  */
@@ -5689,11 +5717,11 @@ dw2_debug_names_map_matching_symbols
      the psymtab code does.  */
   for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->per_bfd->all_comp_units)
     {
-      struct compunit_symtab *cust = per_cu->v.quick->compunit_symtab;
-      if (cust != nullptr)
+      compunit_symtab *symtab = dwarf2_per_objfile->get_symtab (per_cu);
+      if (symtab != nullptr)
 	{
 	  const struct block *block
-	    = BLOCKVECTOR_BLOCK (COMPUNIT_BLOCKVECTOR (cust), block_kind);
+	    = BLOCKVECTOR_BLOCK (COMPUNIT_BLOCKVECTOR (symtab), block_kind);
 	  if (!iterate_over_symbols_terminated (block, name,
 						domain, callback))
 	    break;
@@ -5843,6 +5871,7 @@ dwarf2_initialize_objfile (struct objfile *objfile, dw_index_kind *index_kind)
       dwarf2_per_objfile->per_bfd->quick_file_names_table
 	= create_quick_file_names_table
 	    (dwarf2_per_objfile->per_bfd->all_comp_units.size ());
+      dwarf2_per_objfile->resize_symtabs ();
 
       for (int i = 0; i < (dwarf2_per_objfile->per_bfd->all_comp_units.size ()
 			   + dwarf2_per_objfile->per_bfd->all_type_units.size ()); ++i)
@@ -5863,6 +5892,7 @@ dwarf2_initialize_objfile (struct objfile *objfile, dw_index_kind *index_kind)
   if (dwarf2_read_debug_names (dwarf2_per_objfile))
     {
       *index_kind = dw_index_kind::DEBUG_NAMES;
+      dwarf2_per_objfile->resize_symtabs ();
       return true;
     }
 
@@ -5871,6 +5901,7 @@ dwarf2_initialize_objfile (struct objfile *objfile, dw_index_kind *index_kind)
 			     get_gdb_index_contents_from_section<dwz_file>))
     {
       *index_kind = dw_index_kind::GDB_INDEX;
+      dwarf2_per_objfile->resize_symtabs ();
       return true;
     }
 
@@ -5881,6 +5912,7 @@ dwarf2_initialize_objfile (struct objfile *objfile, dw_index_kind *index_kind)
     {
       global_index_cache.hit ();
       *index_kind = dw_index_kind::GDB_INDEX;
+      dwarf2_per_objfile->resize_symtabs ();
       return true;
     }
 
@@ -5909,6 +5941,8 @@ dwarf2_build_psymtabs (struct objfile *objfile)
       dwarf2_build_psymtabs_hard (dwarf2_per_objfile);
       psymtabs.keep ();
 
+      dwarf2_per_objfile->resize_symtabs ();
+
       /* (maybe) store an index in the cache.  */
       global_index_cache.store (dwarf2_per_objfile);
     }
@@ -6339,6 +6373,8 @@ add_type_unit (struct dwarf2_per_objfile *dwarf2_per_objfile, ULONGEST sig,
 
   signatured_type *sig_type = dwarf2_per_objfile->per_bfd->allocate_signatured_type ();
 
+  dwarf2_per_objfile->resize_symtabs ();
+
   dwarf2_per_objfile->per_bfd->all_type_units.push_back (sig_type);
   sig_type->signature = sig;
   sig_type->per_cu.is_debug_types = 1;
@@ -6374,7 +6410,7 @@ fill_in_sig_entry_from_dwo_entry (struct dwarf2_per_objfile *dwarf2_per_objfile,
   if (dwarf2_per_objfile->per_bfd->using_index)
     {
       gdb_assert (sig_entry->per_cu.v.quick != NULL);
-      gdb_assert (sig_entry->per_cu.v.quick->compunit_symtab == NULL);
+      gdb_assert (!dwarf2_per_objfile->symtab_set_p (&sig_entry->per_cu));
     }
   else
       gdb_assert (sig_entry->per_cu.v.psymtab == NULL);
@@ -8801,7 +8837,8 @@ dwarf2_psymtab::read_symtab (struct objfile *objfile)
   struct dwarf2_per_objfile *dwarf2_per_objfile
     = get_dwarf2_per_objfile (objfile);
 
-  gdb_assert (!readin);
+  gdb_assert (!dwarf2_per_objfile->symtab_set_p (per_cu_data));
+
   /* If this psymtab is constructed from a debug-only objfile, the
      has_section_at_zero flag will not necessarily be correct.  We
      can get the correct value for this flag by looking at the data
@@ -8897,9 +8934,7 @@ process_queue (struct dwarf2_per_objfile *dwarf2_per_objfile)
     {
       dwarf2_queue_item &item = dwarf2_per_objfile->per_bfd->queue.front ();
 
-      if ((dwarf2_per_objfile->per_bfd->using_index
-	   ? !item.per_cu->v.quick->compunit_symtab
-	   : (item.per_cu->v.psymtab && !item.per_cu->v.psymtab->readin))
+      if (!dwarf2_per_objfile->symtab_set_p (item.per_cu)
 	  /* Skip dummy CUs.  */
 	  && item.per_cu->cu != NULL)
 	{
@@ -8954,7 +8989,7 @@ process_queue (struct dwarf2_per_objfile *dwarf2_per_objfile)
 void
 dwarf2_psymtab::expand_psymtab (struct objfile *objfile)
 {
-  gdb_assert (!readin);
+  gdb_assert (!readin_p (objfile));
 
   expand_dependencies (objfile);
 
@@ -8962,6 +8997,24 @@ dwarf2_psymtab::expand_psymtab (struct objfile *objfile)
   gdb_assert (get_compunit_symtab (objfile) != nullptr);
 }
 
+/* See psympriv.h.  */
+
+bool
+dwarf2_psymtab::readin_p (struct objfile *objfile) const
+{
+  dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile);
+  return per_objfile->symtab_set_p (per_cu_data);
+}
+
+/* See psympriv.h.  */
+
+compunit_symtab *
+dwarf2_psymtab::get_compunit_symtab (struct objfile *objfile) const
+{
+  dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile);
+  return per_objfile->get_symtab (per_cu_data);
+}
+
 /* Trivial hash function for die_info: the hash value of a DIE
    is its offset in .debug_info for this objfile.  */
 
@@ -9499,17 +9552,6 @@ rust_union_quirks (struct dwarf2_cu *cu)
   cu->rust_unions.clear ();
 }
 
-/* Return the symtab for PER_CU.  This works properly regardless of
-   whether we're using the index or psymtabs.  */
-
-static struct compunit_symtab *
-get_compunit_symtab (struct dwarf2_per_cu_data *per_cu)
-{
-  return (per_cu->dwarf2_per_objfile->per_bfd->using_index
-	  ? per_cu->v.quick->compunit_symtab
-	  : per_cu->v.psymtab->compunit_symtab);
-}
-
 /* A helper function for computing the list of all symbol tables
    included by PER_CU.  */
 
@@ -9519,10 +9561,7 @@ recursively_compute_inclusions (std::vector<compunit_symtab *> *result,
 				struct dwarf2_per_cu_data *per_cu,
 				struct compunit_symtab *immediate_parent)
 {
-  void **slot;
-  struct compunit_symtab *cust;
-
-  slot = htab_find_slot (all_children, per_cu, INSERT);
+  void **slot = htab_find_slot (all_children, per_cu, INSERT);
   if (*slot != NULL)
     {
       /* This inclusion and its children have been processed.  */
@@ -9530,8 +9569,9 @@ recursively_compute_inclusions (std::vector<compunit_symtab *> *result,
     }
 
   *slot = per_cu;
+
   /* Only add a CU if it has a symbol table.  */
-  cust = get_compunit_symtab (per_cu);
+  compunit_symtab *cust = per_cu->dwarf2_per_objfile->get_symtab (per_cu);
   if (cust != NULL)
     {
       /* If this is a type unit only add its symbol table if we haven't
@@ -9576,7 +9616,7 @@ compute_compunit_symtab_includes (struct dwarf2_per_cu_data *per_cu)
       int len;
       std::vector<compunit_symtab *> result_symtabs;
       htab_t all_children, all_type_symtabs;
-      struct compunit_symtab *cust = get_compunit_symtab (per_cu);
+      compunit_symtab *cust = per_cu->dwarf2_per_objfile->get_symtab (per_cu);
 
       /* If we don't have a symtab, we can just skip this case.  */
       if (cust == NULL)
@@ -9713,14 +9753,7 @@ process_full_comp_unit (struct dwarf2_per_cu_data *per_cu,
       cust->call_site_htab = cu->call_site_htab;
     }
 
-  if (dwarf2_per_objfile->per_bfd->using_index)
-    per_cu->v.quick->compunit_symtab = cust;
-  else
-    {
-      dwarf2_psymtab *pst = per_cu->v.psymtab;
-      pst->compunit_symtab = cust;
-      pst->readin = true;
-    }
+  dwarf2_per_objfile->set_symtab (per_cu, cust);
 
   /* Push it for inclusion processing later.  */
   dwarf2_per_objfile->per_bfd->just_read_cus.push_back (per_cu);
@@ -9793,14 +9826,7 @@ process_full_type_unit (struct dwarf2_per_cu_data *per_cu,
       cust = sig_type->type_unit_group->compunit_symtab;
     }
 
-  if (dwarf2_per_objfile->per_bfd->using_index)
-    per_cu->v.quick->compunit_symtab = cust;
-  else
-    {
-      dwarf2_psymtab *pst = per_cu->v.psymtab;
-      pst->compunit_symtab = cust;
-      pst->readin = true;
-    }
+  dwarf2_per_objfile->set_symtab (per_cu, cust);
 
   /* Not needed any more.  */
   cu->reset_builder ();
diff --git a/gdb/dwarf2/read.h b/gdb/dwarf2/read.h
index 4dc9496046f..7631938edb0 100644
--- a/gdb/dwarf2/read.h
+++ b/gdb/dwarf2/read.h
@@ -123,6 +123,11 @@ struct dwarf2_per_bfd
      is allocated on the dwarf2_per_bfd obstack.  */
   signatured_type *allocate_signatured_type ();
 
+  /* Return the number of partial symtabs allocated with allocate_per_cu
+     and allocate_signatured_type so far.  */
+  int num_psymtabs () const
+  { return m_num_psymtabs; }
+
 private:
   /* This function is mapped across the sections and remembers the
      offset and size of each of the debugging sections we are
@@ -278,12 +283,38 @@ struct dwarf2_per_objfile
 				const struct comp_unit_head *cu_header,
 				unsigned int *bytes_read_ptr);
 
+  /* Resize the M_SYMTABS vector to the needed size (the number of partial
+     symtabs allocated by the per-bfd).  */
+  void resize_symtabs ()
+  {
+    /* The symtabs vector should only grow, not shrink.  */
+    gdb_assert (per_bfd->num_psymtabs () >= m_symtabs.size ());
+
+    m_symtabs.resize (per_bfd->num_psymtabs ());
+  }
+
+  /* Return true if the symtab corresponding to PER_CU has been set,
+     false otherwise.  */
+  bool symtab_set_p (const dwarf2_per_cu_data *per_cu) const;
+
+  /* Return the compunit_symtab associated to PER_CU, if it has been created.  */
+  compunit_symtab *get_symtab (const dwarf2_per_cu_data *per_cu) const;
+
+  /* Set the compunit_symtab associated to PER_CU.  */
+  void set_symtab (const dwarf2_per_cu_data *per_cu, compunit_symtab *symtab);
+
   /* Back link.  */
   struct objfile *objfile;
 
   /* Pointer to the data that is (possibly) shared between this objfile and
      other objfiles backed by the same BFD.  */
   struct dwarf2_per_bfd *per_bfd;
+
+private:
+  /* Hold the corresponding compunit_symtab for each CU or TU.  This
+     is indexed by dwarf2_per_cu_data::index.  A NULL value means
+     that the CU/TU has not been expanded yet.  */
+  std::vector<compunit_symtab *> m_symtabs;
 };
 
 /* Get the dwarf2_per_objfile associated to OBJFILE.  */
@@ -291,17 +322,19 @@ struct dwarf2_per_objfile
 dwarf2_per_objfile *get_dwarf2_per_objfile (struct objfile *objfile);
 
 /* A partial symtab specialized for DWARF.  */
-struct dwarf2_psymtab : public standard_psymtab
+struct dwarf2_psymtab : public partial_symtab
 {
   dwarf2_psymtab (const char *filename, struct objfile *objfile,
 		  dwarf2_per_cu_data *per_cu)
-    : standard_psymtab (filename, objfile, 0),
+    : partial_symtab (filename, objfile, 0),
       per_cu_data (per_cu)
   {
   }
 
   void read_symtab (struct objfile *) override;
   void expand_psymtab (struct objfile *) override;
+  bool readin_p (struct objfile *) const override;
+  compunit_symtab *get_compunit_symtab (struct objfile *) const override;
 
   struct dwarf2_per_cu_data *per_cu_data;
 };
-- 
2.26.2


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

* [PATCH v2 07/42] Move die_type_hash to dwarf2_per_objfile
  2020-05-12 21:08 [PATCH v2 00/42] Share DWARF partial symtabs between objfiles Simon Marchi
                   ` (5 preceding siblings ...)
  2020-05-12 21:08 ` [PATCH v2 06/42] Remove symtab links from dwarf2_psymtab and dwarf2_per_cu_quick_data Simon Marchi
@ 2020-05-12 21:08 ` Simon Marchi
  2020-05-12 21:08 ` [PATCH v2 08/42] Add dwarf2_per_objfile field to dwarf2_cu Simon Marchi
                   ` (38 subsequent siblings)
  45 siblings, 0 replies; 92+ messages in thread
From: Simon Marchi @ 2020-05-12 21:08 UTC (permalink / raw)
  To: gdb-patches; +Cc: Simon Marchi

The die_type_hash field can't be shared between multiple obfiles, as it
holds `struct type` objects, which are objfile-specific.  Move it from
dwarf2_per_bfd to dwarf2_per_objfile and update all references.

gdb/ChangeLog:

	* dwarf2/read.h (struct dwarf2_per_bfd) <die_type_hash>: Move to
	struct dwarf2_per_objfile.
	(struct dwarf2_per_objfile) <die_type_hash>: Move from struct
	dwarf2_per_bfd.
	* dwarf2/read.c (set_die_type): Update.
	(get_die_type_at_offset): Update.
---
 gdb/dwarf2/read.c | 10 +++++-----
 gdb/dwarf2/read.h | 10 +++++-----
 2 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 4dfa85ff0c7..c9617293284 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -23717,8 +23717,8 @@ set_die_type (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
 			    cu->per_cu->addr_type ()))
     type->add_dyn_prop (DYN_PROP_DATA_LOCATION, prop);
 
-  if (dwarf2_per_objfile->per_bfd->die_type_hash == NULL)
-    dwarf2_per_objfile->per_bfd->die_type_hash
+  if (dwarf2_per_objfile->die_type_hash == NULL)
+    dwarf2_per_objfile->die_type_hash
       = htab_up (htab_create_alloc (127,
 				    per_cu_offset_and_type_hash,
 				    per_cu_offset_and_type_eq,
@@ -23728,7 +23728,7 @@ set_die_type (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
   ofs.sect_off = die->sect_off;
   ofs.type = type;
   slot = (struct dwarf2_per_cu_offset_and_type **)
-    htab_find_slot (dwarf2_per_objfile->per_bfd->die_type_hash.get (), &ofs, INSERT);
+    htab_find_slot (dwarf2_per_objfile->die_type_hash.get (), &ofs, INSERT);
   if (*slot)
     complaint (_("A problem internal to GDB: DIE %s has type already set"),
 	       sect_offset_str (die->sect_off));
@@ -23748,13 +23748,13 @@ get_die_type_at_offset (sect_offset sect_off,
   struct dwarf2_per_cu_offset_and_type *slot, ofs;
   struct dwarf2_per_objfile *dwarf2_per_objfile = per_cu->dwarf2_per_objfile;
 
-  if (dwarf2_per_objfile->per_bfd->die_type_hash == NULL)
+  if (dwarf2_per_objfile->die_type_hash == NULL)
     return NULL;
 
   ofs.per_cu = per_cu;
   ofs.sect_off = sect_off;
   slot = ((struct dwarf2_per_cu_offset_and_type *)
-	  htab_find (dwarf2_per_objfile->per_bfd->die_type_hash.get (), &ofs));
+	  htab_find (dwarf2_per_objfile->die_type_hash.get (), &ofs));
   if (slot)
     return slot->type;
   else
diff --git a/gdb/dwarf2/read.h b/gdb/dwarf2/read.h
index 7631938edb0..2897ea6e601 100644
--- a/gdb/dwarf2/read.h
+++ b/gdb/dwarf2/read.h
@@ -229,11 +229,6 @@ struct dwarf2_per_bfd
      symbols.  */
   bool reading_partial_symbols = false;
 
-  /* Table mapping type DIEs to their struct type *.
-     This is NULL if not allocated yet.
-     The mapping is done via (CU/TU + DIE offset) -> type.  */
-  htab_up die_type_hash;
-
   /* The CUs we recently read.  */
   std::vector<dwarf2_per_cu_data *> just_read_cus;
 
@@ -310,6 +305,11 @@ struct dwarf2_per_objfile
      other objfiles backed by the same BFD.  */
   struct dwarf2_per_bfd *per_bfd;
 
+  /* Table mapping type DIEs to their struct type *.
+     This is nullptr if not allocated yet.
+     The mapping is done via (CU/TU + DIE offset) -> type.  */
+  htab_up die_type_hash;
+
 private:
   /* Hold the corresponding compunit_symtab for each CU or TU.  This
      is indexed by dwarf2_per_cu_data::index.  A NULL value means
-- 
2.26.2


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

* [PATCH v2 08/42] Add dwarf2_per_objfile field to dwarf2_cu
  2020-05-12 21:08 [PATCH v2 00/42] Share DWARF partial symtabs between objfiles Simon Marchi
                   ` (6 preceding siblings ...)
  2020-05-12 21:08 ` [PATCH v2 07/42] Move die_type_hash to dwarf2_per_objfile Simon Marchi
@ 2020-05-12 21:08 ` Simon Marchi
  2020-05-12 21:08 ` [PATCH v2 09/42] Remove reference to dwarf2_per_cu_data::dwarf2_per_objfile in dw2_do_instantiate_symtab Simon Marchi
                   ` (37 subsequent siblings)
  45 siblings, 0 replies; 92+ messages in thread
From: Simon Marchi @ 2020-05-12 21:08 UTC (permalink / raw)
  To: gdb-patches; +Cc: Simon Marchi

Subsequent patches will make dwarf2_per_cu_data objfile-independent.
This means that the dwarf2_per_cu_data::dwarf2_per_objfile field must
go.

The code using a dwarf2_cu structure currently accesses the current
dwarf2_per_objfile object through dwarf2_cu->per_cu->dwarf2_per_objfile.
Since it's ok for the dwarf2_cu to know about the current objfile (a
dwarf2_cu is always used in the context of a particular objfile), add a
dwarf2_per_objfile field to dwarf2_cu.  Upcoming patches will gradually
remove uses of dwarf2_per_cu_data::dwarf2_per_objfile in favor of
dwarf2_cu::dwarf2_per_objfile, until the former can be removed.

gdb/ChangeLog:

	* dwarf2/read.c (struct dwarf2_cu) <dwarf2_cu>: Add parameter.
	<per_objfile>: New member.
	(class cutu_reader) <init_tu_and_read_dwo_dies>: Add parameter.
	(cutu_reader::init_tu_and_read_dwo_dies): Add parameter, update
	call to dwarf2_cu.
	(cutu_reader::cutu_reader): Update.
	(dwarf2_cu::dwarf2_cu): Add parameter, initialize per_objfile.
---
 gdb/dwarf2/read.c | 28 ++++++++++++++++++----------
 1 file changed, 18 insertions(+), 10 deletions(-)

diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index c9617293284..096002219a3 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -399,7 +399,8 @@ struct delayed_method_info
 /* Internal state when decoding a particular compilation unit.  */
 struct dwarf2_cu
 {
-  explicit dwarf2_cu (struct dwarf2_per_cu_data *per_cu);
+  explicit dwarf2_cu (dwarf2_per_cu_data *per_cu,
+		      dwarf2_per_objfile *per_objfile);
   ~dwarf2_cu ();
 
   DISABLE_COPY_AND_ASSIGN (dwarf2_cu);
@@ -466,6 +467,9 @@ struct dwarf2_cu
   /* Backlink to our per_cu entry.  */
   struct dwarf2_per_cu_data *per_cu;
 
+  /* The dwarf2_per_objfile that owns this.  */
+  struct dwarf2_per_objfile *per_objfile;
+
   /* How many compilation units ago was this CU last referenced?  */
   int last_used = 0;
 
@@ -928,7 +932,8 @@ class cutu_reader : public die_reader_specs
   void keep ();
 
 private:
-  void init_tu_and_read_dwo_dies (struct dwarf2_per_cu_data *this_cu,
+  void init_tu_and_read_dwo_dies (dwarf2_per_cu_data *this_cu,
+				  dwarf2_per_objfile *per_objfile,
 				  int use_existing_cu);
 
   struct dwarf2_per_cu_data *m_this_cu;
@@ -6852,7 +6857,8 @@ lookup_dwo_unit (struct dwarf2_per_cu_data *this_cu,
    Read a TU directly from a DWO file, bypassing the stub.  */
 
 void
-cutu_reader::init_tu_and_read_dwo_dies (struct dwarf2_per_cu_data *this_cu,
+cutu_reader::init_tu_and_read_dwo_dies (dwarf2_per_cu_data *this_cu,
+					dwarf2_per_objfile *per_objfile,
 					int use_existing_cu)
 {
   struct signatured_type *sig_type;
@@ -6873,7 +6879,7 @@ cutu_reader::init_tu_and_read_dwo_dies (struct dwarf2_per_cu_data *this_cu,
     {
       /* If !use_existing_cu, this_cu->cu must be NULL.  */
       gdb_assert (this_cu->cu == NULL);
-      m_new_cu.reset (new dwarf2_cu (this_cu));
+      m_new_cu.reset (new dwarf2_cu (this_cu, per_objfile));
     }
 
   /* A future optimization, if needed, would be to use an existing
@@ -6934,7 +6940,7 @@ cutu_reader::cutu_reader (struct dwarf2_per_cu_data *this_cu,
       /* Narrow down the scope of possibilities to have to understand.  */
       gdb_assert (this_cu->is_debug_types);
       gdb_assert (abbrev_table == NULL);
-      init_tu_and_read_dwo_dies (this_cu, use_existing_cu);
+      init_tu_and_read_dwo_dies (this_cu, dwarf2_per_objfile, use_existing_cu);
       return;
     }
 
@@ -6961,7 +6967,7 @@ cutu_reader::cutu_reader (struct dwarf2_per_cu_data *this_cu,
     {
       /* If !use_existing_cu, this_cu->cu must be NULL.  */
       gdb_assert (this_cu->cu == NULL);
-      m_new_cu.reset (new dwarf2_cu (this_cu));
+      m_new_cu.reset (new dwarf2_cu (this_cu, dwarf2_per_objfile));
       cu = m_new_cu.get ();
     }
 
@@ -7153,7 +7159,7 @@ cutu_reader::cutu_reader (struct dwarf2_per_cu_data *this_cu,
   /* This is cheap if the section is already read in.  */
   section->read (objfile);
 
-  m_new_cu.reset (new dwarf2_cu (this_cu));
+  m_new_cu.reset (new dwarf2_cu (this_cu, dwarf2_per_objfile));
 
   begin_info_ptr = info_ptr = section->buffer + to_underlying (this_cu->sect_off);
   info_ptr = read_and_check_comp_unit_head (dwarf2_per_objfile,
@@ -23477,10 +23483,12 @@ run_test ()
 
 #endif /* GDB_SELF_TEST */
 
-/* Initialize dwarf2_cu CU, owned by PER_CU.  */
+/* Initialize dwarf2_cu to read PER_CU, in the context of PER_OBJFILE.  */
 
-dwarf2_cu::dwarf2_cu (struct dwarf2_per_cu_data *per_cu_)
-  : per_cu (per_cu_),
+dwarf2_cu::dwarf2_cu (dwarf2_per_cu_data *per_cu,
+		      dwarf2_per_objfile *per_objfile)
+  : per_cu (per_cu),
+    per_objfile (per_objfile),
     mark (false),
     has_loclist (false),
     checked_producer (false),
-- 
2.26.2


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

* [PATCH v2 09/42] Remove reference to dwarf2_per_cu_data::dwarf2_per_objfile in dw2_do_instantiate_symtab
  2020-05-12 21:08 [PATCH v2 00/42] Share DWARF partial symtabs between objfiles Simon Marchi
                   ` (7 preceding siblings ...)
  2020-05-12 21:08 ` [PATCH v2 08/42] Add dwarf2_per_objfile field to dwarf2_cu Simon Marchi
@ 2020-05-12 21:08 ` Simon Marchi
  2020-05-12 21:11 ` [PATCH v2 10/42] Remove dwarf2_cu->per_cu->dwarf2_per_objfile references Simon Marchi
                   ` (36 subsequent siblings)
  45 siblings, 0 replies; 92+ messages in thread
From: Simon Marchi @ 2020-05-12 21:08 UTC (permalink / raw)
  To: gdb-patches; +Cc: Simon Marchi

This patch begins by removing the per_cu->dwarf2_per_objfile reference
in dw2_do_instantiate_symtab, instead accepting a dwarf2_per_objfile
object as a parameter.  It then fixes the fallouts.  In this context,
the dwarf2_per_objfile is generally derived from an objfile passed to a
quick_symbol_functions callback.

gdb/ChangeLog:

	* dwarf2/read.c (dw2_do_instantiate_symtab): Add per_objfile
	parameter, don't use per_cu->dwarf2_per_objfile.
	(dw2_instantiate_symtab): Likewise.
	(dw2_find_last_source_symtab): Update.
	(dw2_map_expand_apply): Update.
	(dw2_lookup_symbol): Update.
	(dw2_expand_symtabs_for_function): Update.
	(dw2_expand_all_symtabs): Update.
	(dw2_expand_symtabs_with_fullname): Update.
	(dw2_expand_symtabs_matching_one): Add per_objfile parameter,
	don't use per_cu->dwarf2_per_objfile.
	(dw2_expand_marked_cus): Update.
	(dw2_find_pc_sect_compunit_symtab): Update.
	(dw2_debug_names_lookup_symbol): Update.
	(dw2_debug_names_expand_symtabs_for_function): Update.
	(dw2_debug_names_map_matching_symbols): Update.
	(dwarf2_psymtab::expand_psymtab): Update.
---
 gdb/dwarf2/read.c | 78 +++++++++++++++++++++++++----------------------
 1 file changed, 42 insertions(+), 36 deletions(-)

diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 096002219a3..983218ab15a 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -2341,13 +2341,13 @@ load_cu (struct dwarf2_per_cu_data *per_cu, bool skip_partial)
   dwarf2_find_base_address (per_cu->cu->dies, per_cu->cu);
 }
 
-/* Read in the symbols for PER_CU.  */
+/* Read in the symbols for PER_CU in the context of DWARF"_PER_OBJFILE.  */
 
 static void
-dw2_do_instantiate_symtab (struct dwarf2_per_cu_data *per_cu, bool skip_partial)
+dw2_do_instantiate_symtab (dwarf2_per_cu_data *per_cu,
+			   dwarf2_per_objfile *dwarf2_per_objfile,
+			   bool skip_partial)
 {
-  struct dwarf2_per_objfile *dwarf2_per_objfile = per_cu->dwarf2_per_objfile;
-
   /* Skip type_unit_groups, reading the type units they contain
      is handled elsewhere.  */
   if (per_cu->type_unit_group_p ())
@@ -2383,22 +2383,23 @@ dw2_do_instantiate_symtab (struct dwarf2_per_cu_data *per_cu, bool skip_partial)
   age_cached_comp_units (dwarf2_per_objfile);
 }
 
-/* Ensure that the symbols for PER_CU have been read in.  OBJFILE is
-   the objfile from which this CU came.  Returns the resulting symbol
-   table.  */
+/* Ensure that the symbols for PER_CU have been read in.  DWARF2_PER_OBJFILE is
+   the per-objfile for which this symtab is instantiated.
+
+   Returns the resulting symbol table.  */
 
 static struct compunit_symtab *
-dw2_instantiate_symtab (struct dwarf2_per_cu_data *per_cu, bool skip_partial)
+dw2_instantiate_symtab (dwarf2_per_cu_data *per_cu,
+			dwarf2_per_objfile *dwarf2_per_objfile,
+			bool skip_partial)
 {
-  struct dwarf2_per_objfile *dwarf2_per_objfile = per_cu->dwarf2_per_objfile;
-
   gdb_assert (dwarf2_per_objfile->per_bfd->using_index);
 
   if (!dwarf2_per_objfile->symtab_set_p (per_cu))
     {
       free_cached_comp_units freer (dwarf2_per_objfile);
       scoped_restore decrementer = increment_reading_symtab ();
-      dw2_do_instantiate_symtab (per_cu, skip_partial);
+      dw2_do_instantiate_symtab (per_cu, dwarf2_per_objfile, skip_partial);
       process_cu_includes (dwarf2_per_objfile);
     }
 
@@ -3255,7 +3256,8 @@ dw2_find_last_source_symtab (struct objfile *objfile)
   struct dwarf2_per_objfile *dwarf2_per_objfile
     = get_dwarf2_per_objfile (objfile);
   dwarf2_per_cu_data *dwarf_cu = dwarf2_per_objfile->per_bfd->all_comp_units.back ();
-  compunit_symtab *cust = dw2_instantiate_symtab (dwarf_cu, false);
+  compunit_symtab *cust
+    = dw2_instantiate_symtab (dwarf_cu, dwarf2_per_objfile, false);
 
   if (cust == NULL)
     return NULL;
@@ -3312,7 +3314,7 @@ dw2_map_expand_apply (struct objfile *objfile,
 
   /* This may expand more than one symtab, and we want to iterate over
      all of them.  */
-  dw2_instantiate_symtab (per_cu, false);
+  dw2_instantiate_symtab (per_cu, per_objfile, false);
 
   return iterate_over_some_symtabs (name, real_path, objfile->compunit_symtabs,
 				    last_made, callback);
@@ -3554,7 +3556,8 @@ dw2_lookup_symbol (struct objfile *objfile, block_enum block_index,
   while ((per_cu = dw2_symtab_iter_next (&iter)) != NULL)
     {
       struct symbol *sym, *with_opaque = NULL;
-      struct compunit_symtab *stab = dw2_instantiate_symtab (per_cu, false);
+      struct compunit_symtab *stab
+	= dw2_instantiate_symtab (per_cu, dwarf2_per_objfile, false);
       const struct blockvector *bv = COMPUNIT_BLOCKVECTOR (stab);
       const struct block *block = BLOCKVECTOR_BLOCK (bv, block_index);
 
@@ -3635,7 +3638,7 @@ dw2_expand_symtabs_for_function (struct objfile *objfile,
   dw2_symtab_iter_init (&iter, dwarf2_per_objfile, {}, VAR_DOMAIN, func_name);
 
   while ((per_cu = dw2_symtab_iter_next (&iter)) != NULL)
-    dw2_instantiate_symtab (per_cu, false);
+    dw2_instantiate_symtab (per_cu, dwarf2_per_objfile, false);
 
 }
 
@@ -3656,7 +3659,7 @@ dw2_expand_all_symtabs (struct objfile *objfile)
 	 be triggered later on.  See PR symtab/23010.  So, tell
 	 dw2_instantiate_symtab to skip partial CUs -- any important
 	 partial CU will be read via DW_TAG_imported_unit anyway.  */
-      dw2_instantiate_symtab (per_cu, true);
+      dw2_instantiate_symtab (per_cu, dwarf2_per_objfile, true);
     }
 }
 
@@ -3688,7 +3691,7 @@ dw2_expand_symtabs_with_fullname (struct objfile *objfile,
 
 	  if (filename_cmp (this_fullname, fullname) == 0)
 	    {
-	      dw2_instantiate_symtab (per_cu, false);
+	      dw2_instantiate_symtab (per_cu, dwarf2_per_objfile, false);
 	      break;
 	    }
 	}
@@ -4494,16 +4497,17 @@ run_test ()
 
 static void
 dw2_expand_symtabs_matching_one
-  (struct dwarf2_per_cu_data *per_cu,
+  (dwarf2_per_cu_data *per_cu,
+   dwarf2_per_objfile *per_objfile,
    gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher,
    gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify)
 {
   if (file_matcher == NULL || per_cu->v.quick->mark)
     {
-      dwarf2_per_objfile *per_objfile = per_cu->dwarf2_per_objfile;
       bool symtab_was_null = !per_objfile->symtab_set_p (per_cu);
 
-      compunit_symtab *symtab = dw2_instantiate_symtab (per_cu, false);
+      compunit_symtab *symtab
+	= dw2_instantiate_symtab (per_cu, per_objfile, false);
       gdb_assert (symtab != nullptr);
 
       if (expansion_notify != NULL && symtab_was_null)
@@ -4517,7 +4521,7 @@ dw2_expand_symtabs_matching_one
 
 static void
 dw2_expand_marked_cus
-  (struct dwarf2_per_objfile *dwarf2_per_objfile, offset_type idx,
+  (dwarf2_per_objfile *dwarf2_per_objfile, offset_type idx,
    gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher,
    gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify,
    search_domain kind)
@@ -4591,7 +4595,7 @@ dw2_expand_marked_cus
 	}
 
       dwarf2_per_cu_data *per_cu = dwarf2_per_objfile->per_bfd->get_cutu (cu_index);
-      dw2_expand_symtabs_matching_one (per_cu, file_matcher,
+      dw2_expand_symtabs_matching_one (per_cu, dwarf2_per_objfile, file_matcher,
 				       expansion_notify);
     }
 }
@@ -4698,8 +4702,8 @@ dw2_expand_symtabs_matching
 	{
 	  QUIT;
 
-	  dw2_expand_symtabs_matching_one (per_cu, file_matcher,
-					   expansion_notify);
+	  dw2_expand_symtabs_matching_one (per_cu, dwarf2_per_objfile,
+					   file_matcher, expansion_notify);
 	}
       return;
     }
@@ -4768,10 +4772,9 @@ dw2_find_pc_sect_compunit_symtab (struct objfile *objfile,
     warning (_("(Internal error: pc %s in read in CU, but not in symtab.)"),
 	     paddress (objfile->arch (), pc));
 
-  result
-    = recursively_find_pc_sect_compunit_symtab (dw2_instantiate_symtab (data,
-									false),
-						pc);
+  result = recursively_find_pc_sect_compunit_symtab
+    (dw2_instantiate_symtab (data, per_objfile, false), pc);
+
   gdb_assert (result != NULL);
   return result;
 }
@@ -5613,7 +5616,8 @@ dw2_debug_names_lookup_symbol (struct objfile *objfile, block_enum block_index,
   while ((per_cu = iter.next ()) != NULL)
     {
       struct symbol *sym, *with_opaque = NULL;
-      struct compunit_symtab *stab = dw2_instantiate_symtab (per_cu, false);
+      compunit_symtab *stab
+	= dw2_instantiate_symtab (per_cu, dwarf2_per_objfile, false);
       const struct blockvector *bv = COMPUNIT_BLOCKVECTOR (stab);
       const struct block *block = BLOCKVECTOR_BLOCK (bv, block_index);
 
@@ -5673,7 +5677,7 @@ dw2_debug_names_expand_symtabs_for_function (struct objfile *objfile,
 
       struct dwarf2_per_cu_data *per_cu;
       while ((per_cu = iter.next ()) != NULL)
-	dw2_instantiate_symtab (per_cu, false);
+	dw2_instantiate_symtab (per_cu, dwarf2_per_objfile, false);
     }
 }
 
@@ -5712,7 +5716,8 @@ dw2_debug_names_map_matching_symbols
 
       struct dwarf2_per_cu_data *per_cu;
       while ((per_cu = iter.next ()) != NULL)
-	dw2_expand_symtabs_matching_one (per_cu, nullptr, nullptr);
+	dw2_expand_symtabs_matching_one (per_cu, dwarf2_per_objfile, nullptr,
+					 nullptr);
       return true;
     });
 
@@ -5758,8 +5763,8 @@ dw2_debug_names_expand_symtabs_matching
 	{
 	  QUIT;
 
-	  dw2_expand_symtabs_matching_one (per_cu, file_matcher,
-					   expansion_notify);
+	  dw2_expand_symtabs_matching_one (per_cu, dwarf2_per_objfile,
+					   file_matcher, expansion_notify);
 	}
       return;
     }
@@ -5776,8 +5781,8 @@ dw2_debug_names_expand_symtabs_matching
 
       struct dwarf2_per_cu_data *per_cu;
       while ((per_cu = iter.next ()) != NULL)
-	dw2_expand_symtabs_matching_one (per_cu, file_matcher,
-					 expansion_notify);
+	dw2_expand_symtabs_matching_one (per_cu, dwarf2_per_objfile,
+					 file_matcher, expansion_notify);
       return true;
     });
 }
@@ -8999,7 +9004,8 @@ dwarf2_psymtab::expand_psymtab (struct objfile *objfile)
 
   expand_dependencies (objfile);
 
-  dw2_do_instantiate_symtab (per_cu_data, false);
+  dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile);
+  dw2_do_instantiate_symtab (per_cu_data, per_objfile, false);
   gdb_assert (get_compunit_symtab (objfile) != nullptr);
 }
 
-- 
2.26.2


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

* [PATCH v2 10/42] Remove dwarf2_cu->per_cu->dwarf2_per_objfile references
  2020-05-12 21:08 [PATCH v2 00/42] Share DWARF partial symtabs between objfiles Simon Marchi
                   ` (8 preceding siblings ...)
  2020-05-12 21:08 ` [PATCH v2 09/42] Remove reference to dwarf2_per_cu_data::dwarf2_per_objfile in dw2_do_instantiate_symtab Simon Marchi
@ 2020-05-12 21:11 ` Simon Marchi
  2020-05-12 21:11 ` [PATCH v2 11/42] Add dwarf2_per_bfd field to dwarf2_per_cu_data Simon Marchi
                   ` (35 subsequent siblings)
  45 siblings, 0 replies; 92+ messages in thread
From: Simon Marchi @ 2020-05-12 21:11 UTC (permalink / raw)
  To: gdb-patches; +Cc: Simon Marchi

Change spots that access the dwarf2_per_objfile object through this
pattern:

  dwarf2_cu->per_cu->dwarf2_per_objfile

to

  dwarf2_cu->per_objfile

This allows removing many references to
dwarf2_per_cu_data::dwarf2_per_objfile.

Again, I hope the following ChangeLog entry will be fine.  I'd rather not
list all the affected functions, as it would be time-consuming and a bit
pointless.

gdb/ChangeLog:

	* dwarf2/read.c: Replace
	dwarf2_cu->per_cu->dwarf2_per_objfile references with
	dwarf2_cu->per_objfile throughout.
---
 gdb/dwarf2/read.c | 280 ++++++++++++++++++++--------------------------
 1 file changed, 121 insertions(+), 159 deletions(-)

diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 983218ab15a..8b5e8800603 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -3131,8 +3131,7 @@ dw2_get_file_names_reader (const struct die_reader_specs *reader,
 {
   struct dwarf2_cu *cu = reader->cu;
   struct dwarf2_per_cu_data *this_cu = cu->per_cu;
-  struct dwarf2_per_objfile *dwarf2_per_objfile
-    = cu->per_cu->dwarf2_per_objfile;
+  struct dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
   struct dwarf2_per_cu_data *lh_cu;
   struct attribute *attr;
   void **slot;
@@ -6453,8 +6452,7 @@ fill_in_sig_entry_from_dwo_entry (struct dwarf2_per_objfile *dwarf2_per_objfile,
 static struct signatured_type *
 lookup_dwo_signatured_type (struct dwarf2_cu *cu, ULONGEST sig)
 {
-  struct dwarf2_per_objfile *dwarf2_per_objfile
-    = cu->per_cu->dwarf2_per_objfile;
+  struct dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
   struct dwo_file *dwo_file;
   struct dwo_unit find_dwo_entry, *dwo_entry;
   struct signatured_type find_sig_entry, *sig_entry;
@@ -6520,8 +6518,7 @@ lookup_dwo_signatured_type (struct dwarf2_cu *cu, ULONGEST sig)
 static struct signatured_type *
 lookup_dwp_signatured_type (struct dwarf2_cu *cu, ULONGEST sig)
 {
-  struct dwarf2_per_objfile *dwarf2_per_objfile
-    = cu->per_cu->dwarf2_per_objfile;
+  struct dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
   struct dwp_file *dwp_file = get_dwp_file (dwarf2_per_objfile);
   struct dwo_unit *dwo_entry;
   struct signatured_type find_sig_entry, *sig_entry;
@@ -6566,8 +6563,7 @@ lookup_dwp_signatured_type (struct dwarf2_cu *cu, ULONGEST sig)
 static struct signatured_type *
 lookup_signatured_type (struct dwarf2_cu *cu, ULONGEST sig)
 {
-  struct dwarf2_per_objfile *dwarf2_per_objfile
-    = cu->per_cu->dwarf2_per_objfile;
+  struct dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
 
   if (cu->dwo_unit
       && dwarf2_per_objfile->per_bfd->using_index)
@@ -7248,8 +7244,7 @@ allocate_type_unit_groups_table ()
 static struct type_unit_group *
 create_type_unit_group (struct dwarf2_cu *cu, sect_offset line_offset_struct)
 {
-  struct dwarf2_per_objfile *dwarf2_per_objfile
-    = cu->per_cu->dwarf2_per_objfile;
+  struct dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
   struct dwarf2_per_cu_data *per_cu;
   struct type_unit_group *tu_group;
 
@@ -7292,8 +7287,7 @@ create_type_unit_group (struct dwarf2_cu *cu, sect_offset line_offset_struct)
 static struct type_unit_group *
 get_type_unit_group (struct dwarf2_cu *cu, const struct attribute *stmt_list)
 {
-  struct dwarf2_per_objfile *dwarf2_per_objfile
-    = cu->per_cu->dwarf2_per_objfile;
+  struct dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
   struct tu_stats *tu_stats = &dwarf2_per_objfile->per_bfd->tu_stats;
   struct type_unit_group *tu_group;
   void **slot;
@@ -7375,7 +7369,7 @@ process_psymtab_comp_unit_reader (const struct die_reader_specs *reader,
 				  enum language pretend_language)
 {
   struct dwarf2_cu *cu = reader->cu;
-  struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+  struct objfile *objfile = cu->per_objfile->objfile;
   struct gdbarch *gdbarch = objfile->arch ();
   struct dwarf2_per_cu_data *per_cu = cu->per_cu;
   CORE_ADDR baseaddr;
@@ -7557,8 +7551,7 @@ build_type_psymtabs_reader (const struct die_reader_specs *reader,
 			    const gdb_byte *info_ptr,
 			    struct die_info *type_unit_die)
 {
-  struct dwarf2_per_objfile *dwarf2_per_objfile
-    = reader->cu->per_cu->dwarf2_per_objfile;
+  struct dwarf2_per_objfile *dwarf2_per_objfile = reader->cu->per_objfile;
   struct objfile *objfile = dwarf2_per_objfile->objfile;
   struct dwarf2_cu *cu = reader->cu;
   struct dwarf2_per_cu_data *per_cu = cu->per_cu;
@@ -8112,12 +8105,11 @@ scan_partial_symbols (struct partial_die_info *first_die, CORE_ADDR *lowpc,
 		  {
 		    error (_("Dwarf Error: DW_TAG_imported_unit is not"
 			     " supported in type units [in module %s]"),
-			   objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
+			   objfile_name (cu->per_objfile->objfile));
 		  }
 
 		per_cu = dwarf2_find_containing_comp_unit
-			   (pdi->d.sect_off, pdi->is_dwz,
-			    cu->per_cu->dwarf2_per_objfile);
+			   (pdi->d.sect_off, pdi->is_dwz, cu->per_objfile);
 
 		/* Go read the partial unit, if needed.  */
 		if (per_cu->v.psymtab == NULL)
@@ -8287,8 +8279,7 @@ partial_die_full_name (struct partial_die_info *pdi,
 static void
 add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu)
 {
-  struct dwarf2_per_objfile *dwarf2_per_objfile
-    = cu->per_cu->dwarf2_per_objfile;
+  struct dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
   struct objfile *objfile = dwarf2_per_objfile->objfile;
   struct gdbarch *gdbarch = objfile->arch ();
   CORE_ADDR addr = 0;
@@ -8538,7 +8529,7 @@ add_partial_subprogram (struct partial_die_info *pdi,
             *highpc = pdi->highpc;
 	  if (set_addrmap)
 	    {
-	      struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+	      struct objfile *objfile = cu->per_objfile->objfile;
 	      struct gdbarch *gdbarch = objfile->arch ();
 	      CORE_ADDR baseaddr;
 	      CORE_ADDR this_highpc;
@@ -8632,7 +8623,7 @@ peek_die_abbrev (const die_reader_specs &reader,
 		 const gdb_byte *info_ptr, unsigned int *bytes_read)
 {
   dwarf2_cu *cu = reader.cu;
-  bfd *abfd = cu->per_cu->dwarf2_per_objfile->objfile->obfd;
+  bfd *abfd = cu->per_objfile->objfile->obfd;
   unsigned int abbrev_number
     = read_unsigned_leb128 (abfd, info_ptr, bytes_read);
 
@@ -9213,8 +9204,7 @@ fixup_go_packaging (struct dwarf2_cu *cu)
 		package_name = std::move (this_package_name);
 	      else
 		{
-		  struct objfile *objfile
-		    = cu->per_cu->dwarf2_per_objfile->objfile;
+		  struct objfile *objfile = cu->per_objfile->objfile;
 		  if (strcmp (package_name.get (), this_package_name.get ()) != 0)
 		    complaint (_("Symtab %s has objects from two different Go packages: %s and %s"),
 			       (symbol_symtab (sym) != NULL
@@ -9229,7 +9219,7 @@ fixup_go_packaging (struct dwarf2_cu *cu)
 
   if (package_name != NULL)
     {
-      struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+      struct objfile *objfile = cu->per_objfile->objfile;
       const char *saved_package_name = objfile->intern (package_name.get ());
       struct type *type = init_type (objfile, TYPE_CODE_MODULE, 0,
 				     saved_package_name);
@@ -9559,7 +9549,7 @@ rust_union_quirks (struct dwarf2_cu *cu)
 {
   gdb_assert (cu->language == language_rust);
   for (type *type_ : cu->rust_unions)
-    quirk_rust_enum (type_, cu->per_cu->dwarf2_per_objfile->objfile);
+    quirk_rust_enum (type_, cu->per_objfile->objfile);
   /* We don't need this any more.  */
   cu->rust_unions.clear ();
 }
@@ -9856,7 +9846,7 @@ process_imported_unit_die (struct die_info *die, struct dwarf2_cu *cu)
     {
       error (_("Dwarf Error: DW_TAG_imported_unit is not"
 	       " supported in type units [in module %s]"),
-	     objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
+	     objfile_name (cu->per_objfile->objfile));
     }
 
   attr = dwarf2_attr (die, DW_AT_import, cu);
@@ -9865,8 +9855,7 @@ process_imported_unit_die (struct die_info *die, struct dwarf2_cu *cu)
       sect_offset sect_off = attr->get_ref_die_offset ();
       bool is_dwz = (attr->form == DW_FORM_GNU_ref_alt || cu->per_cu->is_dwz);
       dwarf2_per_cu_data *per_cu
-	= dwarf2_find_containing_comp_unit (sect_off, is_dwz,
-					    cu->per_cu->dwarf2_per_objfile);
+	= dwarf2_find_containing_comp_unit (sect_off, is_dwz, cu->per_objfile);
 
       /* We're importing a C++ compilation unit with tag DW_TAG_compile_unit
 	 into another compilation unit, at root level.  Regard this as a hint,
@@ -10144,7 +10133,7 @@ dwarf2_compute_name (const char *name,
 		     struct die_info *die, struct dwarf2_cu *cu,
 		     int physname)
 {
-  struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+  struct objfile *objfile = cu->per_objfile->objfile;
 
   if (name == NULL)
     name = dwarf2_name (die, cu);
@@ -10387,7 +10376,7 @@ dwarf2_full_name (const char *name, struct die_info *die, struct dwarf2_cu *cu)
 static const char *
 dwarf2_physname (const char *name, struct die_info *die, struct dwarf2_cu *cu)
 {
-  struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+  struct objfile *objfile = cu->per_objfile->objfile;
   const char *retval, *mangled = NULL, *canon = NULL;
   int need_copy = 1;
 
@@ -10557,7 +10546,7 @@ using_directives (struct dwarf2_cu *cu)
 static void
 read_import_statement (struct die_info *die, struct dwarf2_cu *cu)
 {
-  struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+  struct objfile *objfile = cu->per_objfile->objfile;
   struct attribute *import_attr;
   struct die_info *imported_die, *child_die;
   struct dwarf2_cu *imported_cu;
@@ -10777,8 +10766,7 @@ static void
 handle_DW_AT_stmt_list (struct die_info *die, struct dwarf2_cu *cu,
 			const char *comp_dir, CORE_ADDR lowpc) /* ARI: editCase function */
 {
-  struct dwarf2_per_objfile *dwarf2_per_objfile
-    = cu->per_cu->dwarf2_per_objfile;
+  struct dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
   struct attribute *attr;
   struct line_header line_header_local;
   hashval_t line_header_local_hash;
@@ -10874,8 +10862,7 @@ handle_DW_AT_stmt_list (struct die_info *die, struct dwarf2_cu *cu,
 static void
 read_file_scope (struct die_info *die, struct dwarf2_cu *cu)
 {
-  struct dwarf2_per_objfile *dwarf2_per_objfile
-    = cu->per_cu->dwarf2_per_objfile;
+  struct dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
   struct objfile *objfile = dwarf2_per_objfile->objfile;
   struct gdbarch *gdbarch = objfile->arch ();
   CORE_ADDR lowpc = ((CORE_ADDR) -1);
@@ -12956,7 +12943,7 @@ inherit_abstract_dies (struct die_info *die, struct dwarf2_cu *cu)
 static void
 read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
 {
-  struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+  struct objfile *objfile = cu->per_objfile->objfile;
   struct gdbarch *gdbarch = objfile->arch ();
   struct context_stack *newobj;
   CORE_ADDR lowpc;
@@ -13157,7 +13144,7 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
 static void
 read_lexical_block_scope (struct die_info *die, struct dwarf2_cu *cu)
 {
-  struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+  struct objfile *objfile = cu->per_objfile->objfile;
   struct gdbarch *gdbarch = objfile->arch ();
   CORE_ADDR lowpc, highpc;
   struct die_info *child_die;
@@ -13237,7 +13224,7 @@ read_lexical_block_scope (struct die_info *die, struct dwarf2_cu *cu)
 static void
 read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
 {
-  dwarf2_per_objfile *per_objfile = cu->per_cu->dwarf2_per_objfile;
+  dwarf2_per_objfile *per_objfile = cu->per_objfile;
   struct objfile *objfile = per_objfile->objfile;
   struct gdbarch *gdbarch = objfile->arch ();
   CORE_ADDR pc, baseaddr;
@@ -13389,7 +13376,7 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
       struct die_info *target_die;
 
       target_die = follow_die_ref (die, attr, &target_cu);
-      gdb_assert (target_cu->per_cu->dwarf2_per_objfile->objfile == objfile);
+      gdb_assert (target_cu->per_objfile->objfile == objfile);
       if (die_is_declaration (target_die, target_cu))
 	{
 	  const char *target_physname;
@@ -13582,7 +13569,7 @@ read_variable (struct die_info *die, struct dwarf2_cu *cu)
 
       if (containing_type != NULL)
 	{
-	  struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+	  struct objfile *objfile = cu->per_objfile->objfile;
 
 	  storage = new (&objfile->objfile_obstack) rust_vtable_symbol ();
 	  initialize_objfile_symbol (storage);
@@ -13604,8 +13591,9 @@ read_variable (struct die_info *die, struct dwarf2_cu *cu)
       struct dwarf2_cu *origin_cu = cu;
       struct die_info *origin_die
 	= follow_die_ref (die, abstract_origin, &origin_cu);
-      dwarf2_per_objfile *dpo = cu->per_cu->dwarf2_per_objfile;
-      dpo->per_bfd->abstract_to_concrete[origin_die->sect_off].push_back (die->sect_off);
+      dwarf2_per_objfile *per_objfile = cu->per_objfile;
+      per_objfile->per_bfd->abstract_to_concrete
+	[origin_die->sect_off].push_back (die->sect_off);
     }
 }
 
@@ -13621,8 +13609,7 @@ static bool
 dwarf2_rnglists_process (unsigned offset, struct dwarf2_cu *cu,
 			 Callback &&callback)
 {
-  struct dwarf2_per_objfile *dwarf2_per_objfile
-    = cu->per_cu->dwarf2_per_objfile;
+  struct dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
   struct objfile *objfile = dwarf2_per_objfile->objfile;
   bfd *obfd = objfile->obfd;
   /* Base address selection entry.  */
@@ -13782,9 +13769,8 @@ static int
 dwarf2_ranges_process (unsigned offset, struct dwarf2_cu *cu,
 		       Callback &&callback)
 {
-  struct dwarf2_per_objfile *dwarf2_per_objfile
-      = cu->per_cu->dwarf2_per_objfile;
-  struct objfile *objfile = dwarf2_per_objfile->objfile;
+  dwarf2_per_objfile *per_objfile = cu->per_objfile;
+  struct objfile *objfile = per_objfile->objfile;
   struct comp_unit_head *cu_header = &cu->header;
   bfd *obfd = objfile->obfd;
   unsigned int addr_size = cu_header->addr_size;
@@ -13800,14 +13786,14 @@ dwarf2_ranges_process (unsigned offset, struct dwarf2_cu *cu,
 
   base = cu->base_address;
 
-  dwarf2_per_objfile->per_bfd->ranges.read (objfile);
-  if (offset >= dwarf2_per_objfile->per_bfd->ranges.size)
+  per_objfile->per_bfd->ranges.read (objfile);
+  if (offset >= per_objfile->per_bfd->ranges.size)
     {
       complaint (_("Offset %d out of bounds for DW_AT_ranges attribute"),
 		 offset);
       return 0;
     }
-  buffer = dwarf2_per_objfile->per_bfd->ranges.buffer + offset;
+  buffer = per_objfile->per_bfd->ranges.buffer + offset;
 
   baseaddr = objfile->text_section_offset ();
 
@@ -13862,7 +13848,7 @@ dwarf2_ranges_process (unsigned offset, struct dwarf2_cu *cu,
       /* A not-uncommon case of bad debug info.
 	 Don't pollute the addrmap with bad data.  */
       if (range_beginning + baseaddr == 0
-	  && !dwarf2_per_objfile->per_bfd->has_section_at_zero)
+	  && !per_objfile->per_bfd->has_section_at_zero)
 	{
 	  complaint (_(".debug_ranges entry has start address of zero"
 		       " [in module %s]"), objfile_name (objfile));
@@ -13884,7 +13870,7 @@ dwarf2_ranges_read (unsigned offset, CORE_ADDR *low_return,
 		    CORE_ADDR *high_return, struct dwarf2_cu *cu,
 		    dwarf2_psymtab *ranges_pst)
 {
-  struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+  struct objfile *objfile = cu->per_objfile->objfile;
   struct gdbarch *gdbarch = objfile->arch ();
   const CORE_ADDR baseaddr = objfile->text_section_offset ();
   int low_set = 0;
@@ -13952,8 +13938,7 @@ dwarf2_get_pc_bounds (struct die_info *die, CORE_ADDR *lowpc,
 		      CORE_ADDR *highpc, struct dwarf2_cu *cu,
 		      dwarf2_psymtab *pst)
 {
-  struct dwarf2_per_objfile *dwarf2_per_objfile
-    = cu->per_cu->dwarf2_per_objfile;
+  struct dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
   struct attribute *attr;
   struct attribute *attr_high;
   CORE_ADDR low = 0;
@@ -14128,7 +14113,7 @@ static void
 dwarf2_record_block_ranges (struct die_info *die, struct block *block,
                             CORE_ADDR baseaddr, struct dwarf2_cu *cu)
 {
-  struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+  struct objfile *objfile = cu->per_objfile->objfile;
   struct gdbarch *gdbarch = objfile->arch ();
   struct attribute *attr;
   struct attribute *attr_high;
@@ -14363,7 +14348,7 @@ static void
 dwarf2_add_field (struct field_info *fip, struct die_info *die,
 		  struct dwarf2_cu *cu)
 {
-  struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+  struct objfile *objfile = cu->per_objfile->objfile;
   struct gdbarch *gdbarch = objfile->arch ();
   struct nextfield *new_field;
   struct attribute *attr;
@@ -14944,7 +14929,7 @@ static void
 dwarf2_add_member_fn (struct field_info *fip, struct die_info *die,
 		      struct type *type, struct dwarf2_cu *cu)
 {
-  struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+  struct objfile *objfile = cu->per_objfile->objfile;
   struct attribute *attr;
   int i;
   struct fnfieldlist *flp = nullptr;
@@ -15244,7 +15229,7 @@ get_alignment (struct dwarf2_cu *cu, struct die_info *die)
       complaint (_("DW_AT_alignment must have constant form"
 		   " - DIE at %s [in module %s]"),
 		 sect_offset_str (die->sect_off),
-		 objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
+		 objfile_name (cu->per_objfile->objfile));
       return 0;
     }
 
@@ -15257,7 +15242,7 @@ get_alignment (struct dwarf2_cu *cu, struct die_info *die)
 	  complaint (_("DW_AT_alignment value must not be negative"
 		       " - DIE at %s [in module %s]"),
 		     sect_offset_str (die->sect_off),
-		     objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
+		     objfile_name (cu->per_objfile->objfile));
 	  return 0;
 	}
       align = val;
@@ -15270,7 +15255,7 @@ get_alignment (struct dwarf2_cu *cu, struct die_info *die)
       complaint (_("DW_AT_alignment value must not be zero"
 		   " - DIE at %s [in module %s]"),
 		 sect_offset_str (die->sect_off),
-		 objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
+		 objfile_name (cu->per_objfile->objfile));
       return 0;
     }
   if ((align & (align - 1)) != 0)
@@ -15278,7 +15263,7 @@ get_alignment (struct dwarf2_cu *cu, struct die_info *die)
       complaint (_("DW_AT_alignment value must be a power of 2"
 		   " - DIE at %s [in module %s]"),
 		 sect_offset_str (die->sect_off),
-		 objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
+		 objfile_name (cu->per_objfile->objfile));
       return 0;
     }
 
@@ -15296,7 +15281,7 @@ maybe_set_alignment (struct dwarf2_cu *cu, struct die_info *die,
     complaint (_("DW_AT_alignment value too large"
 		 " - DIE at %s [in module %s]"),
 	       sect_offset_str (die->sect_off),
-	       objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
+	       objfile_name (cu->per_objfile->objfile));
 }
 
 /* Check if the given VALUE is a valid enum dwarf_calling_convention
@@ -15360,7 +15345,7 @@ is_valid_DW_AT_calling_convention_for_subroutine (ULONGEST value)
 static struct type *
 read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
 {
-  struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+  struct objfile *objfile = cu->per_objfile->objfile;
   struct type *type;
   struct attribute *attr;
   const char *name;
@@ -15564,7 +15549,7 @@ handle_variant (struct die_info *die, struct type *type,
       complaint (_("saw DW_TAG_variant outside DW_TAG_variant_part "
 		   "- DIE at %s [in module %s]"),
 		 sect_offset_str (die->sect_off),
-		 objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
+		 objfile_name (cu->per_objfile->objfile));
       return;
     }
   if (fi->current_variant_part->processing_variant)
@@ -15572,7 +15557,7 @@ handle_variant (struct die_info *die, struct type *type,
       complaint (_("nested DW_TAG_variant seen "
 		   "- DIE at %s [in module %s]"),
 		 sect_offset_str (die->sect_off),
-		 objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
+		 objfile_name (cu->per_objfile->objfile));
       return;
     }
 
@@ -15665,7 +15650,7 @@ handle_struct_member_die (struct die_info *child_die, struct type *type,
 static void
 process_structure_scope (struct die_info *die, struct dwarf2_cu *cu)
 {
-  struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+  struct objfile *objfile = cu->per_objfile->objfile;
   struct die_info *child_die;
   struct type *type;
 
@@ -15955,7 +15940,7 @@ update_enumeration_type_from_children (struct die_info *die,
 static struct type *
 read_enumeration_type (struct die_info *die, struct dwarf2_cu *cu)
 {
-  struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+  struct objfile *objfile = cu->per_objfile->objfile;
   struct type *type;
   struct attribute *attr;
   const char *name;
@@ -16107,7 +16092,7 @@ process_enumeration_scope (struct die_info *die, struct dwarf2_cu *cu)
 static struct type *
 read_array_type (struct die_info *die, struct dwarf2_cu *cu)
 {
-  struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+  struct objfile *objfile = cu->per_objfile->objfile;
   struct die_info *child_die;
   struct type *type;
   struct type *element_type, *range_type, *index_type;
@@ -16138,7 +16123,7 @@ read_array_type (struct die_info *die, struct dwarf2_cu *cu)
 	  complaint (_("unable to read array DW_AT_byte_stride "
 		       " - DIE at %s [in module %s]"),
 		     sect_offset_str (die->sect_off),
-		     objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
+		     objfile_name (cu->per_objfile->objfile));
 	  /* Ignore this attribute.  We will likely not be able to print
 	     arrays of this type correctly, but there is little we can do
 	     to help if we cannot read the attribute's value.  */
@@ -16314,7 +16299,7 @@ mark_common_block_symbol_computed (struct symbol *sym,
 				   struct attribute *member_loc,
 				   struct dwarf2_cu *cu)
 {
-  dwarf2_per_objfile *per_objfile = cu->per_cu->dwarf2_per_objfile;
+  dwarf2_per_objfile *per_objfile = cu->per_objfile;
   struct objfile *objfile = per_objfile->objfile;
   struct dwarf2_locexpr_baton *baton;
   gdb_byte *ptr;
@@ -16405,7 +16390,7 @@ read_common_block (struct die_info *die, struct dwarf2_cu *cu)
 
   if (die->child != NULL)
     {
-      struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+      struct objfile *objfile = cu->per_objfile->objfile;
       struct die_info *child_die;
       size_t n_entries = 0, size;
       struct common_block *common_block;
@@ -16476,7 +16461,7 @@ read_common_block (struct die_info *die, struct dwarf2_cu *cu)
 static struct type *
 read_namespace_type (struct die_info *die, struct dwarf2_cu *cu)
 {
-  struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+  struct objfile *objfile = cu->per_objfile->objfile;
   const char *previous_prefix, *name;
   int is_anonymous;
   struct type *type;
@@ -16515,7 +16500,7 @@ read_namespace_type (struct die_info *die, struct dwarf2_cu *cu)
 static void
 read_namespace (struct die_info *die, struct dwarf2_cu *cu)
 {
-  struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+  struct objfile *objfile = cu->per_objfile->objfile;
   int is_anonymous;
 
   /* Add a symbol associated to this if we haven't seen the namespace
@@ -16560,7 +16545,7 @@ read_namespace (struct die_info *die, struct dwarf2_cu *cu)
 static struct type *
 read_module_type (struct die_info *die, struct dwarf2_cu *cu)
 {
-  struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+  struct objfile *objfile = cu->per_objfile->objfile;
   const char *module_name;
   struct type *type;
 
@@ -16627,8 +16612,7 @@ namespace_name (struct die_info *die, int *is_anonymous, struct dwarf2_cu *cu)
 static struct type *
 read_tag_pointer_type (struct die_info *die, struct dwarf2_cu *cu)
 {
-  struct gdbarch *gdbarch
-    = cu->per_cu->dwarf2_per_objfile->objfile->arch ();
+  struct gdbarch *gdbarch = cu->per_objfile->objfile->arch ();
   struct comp_unit_head *cu_header = &cu->header;
   struct type *type;
   struct attribute *attr_byte_size;
@@ -16686,7 +16670,7 @@ read_tag_pointer_type (struct die_info *die, struct dwarf2_cu *cu)
 	  complaint (_("Invalid DW_AT_alignment"
 		       " - DIE at %s [in module %s]"),
 		     sect_offset_str (die->sect_off),
-		     objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
+		     objfile_name (cu->per_objfile->objfile));
 	}
       else
 	{
@@ -16721,8 +16705,7 @@ read_tag_ptr_to_member_type (struct die_info *die, struct dwarf2_cu *cu)
     type = lookup_methodptr_type (to_type);
   else if (TYPE_CODE (check_typedef (to_type)) == TYPE_CODE_FUNC)
     {
-      struct type *new_type
-	= alloc_type (cu->per_cu->dwarf2_per_objfile->objfile);
+      struct type *new_type = alloc_type (cu->per_objfile->objfile);
 
       smash_to_method_type (new_type, domain, TYPE_TARGET_TYPE (to_type),
 			    TYPE_FIELDS (to_type), TYPE_NFIELDS (to_type),
@@ -16886,7 +16869,7 @@ read_tag_atomic_type (struct die_info *die, struct dwarf2_cu *cu)
 static struct type *
 read_tag_string_type (struct die_info *die, struct dwarf2_cu *cu)
 {
-  struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+  struct objfile *objfile = cu->per_objfile->objfile;
   struct gdbarch *gdbarch = objfile->arch ();
   struct type *type, *range_type, *index_type, *char_type;
   struct attribute *attr;
@@ -17025,7 +17008,7 @@ prototyped_function_p (struct die_info *die, struct dwarf2_cu *cu)
 static struct type *
 read_subroutine_type (struct die_info *die, struct dwarf2_cu *cu)
 {
-  struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+  struct objfile *objfile = cu->per_objfile->objfile;
   struct type *type;		/* Type that this function returns.  */
   struct type *ftype;		/* Function that returns above type.  */
   struct attribute *attr;
@@ -17164,7 +17147,7 @@ read_subroutine_type (struct die_info *die, struct dwarf2_cu *cu)
 static struct type *
 read_typedef (struct die_info *die, struct dwarf2_cu *cu)
 {
-  struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+  struct objfile *objfile = cu->per_objfile->objfile;
   const char *name = NULL;
   struct type *this_type, *target_type;
 
@@ -17309,7 +17292,7 @@ dwarf2_init_complex_target_type (struct dwarf2_cu *cu,
 static struct type *
 read_base_type (struct die_info *die, struct dwarf2_cu *cu)
 {
-  struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+  struct objfile *objfile = cu->per_objfile->objfile;
   struct type *type;
   struct attribute *attr;
   int encoding = 0, bits = 0;
@@ -17366,7 +17349,7 @@ read_base_type (struct die_info *die, struct dwarf2_cu *cu)
 	    if (name == nullptr)
 	      {
 		struct obstack *obstack
-		  = &cu->per_cu->dwarf2_per_objfile->objfile->objfile_obstack;
+		  = &cu->per_objfile->objfile->objfile_obstack;
 		name = obconcat (obstack, "_Complex ", TYPE_NAME (type),
 				 nullptr);
 	      }
@@ -17452,7 +17435,7 @@ attr_to_dynamic_prop (const struct attribute *attr, struct die_info *die,
 		      struct type *default_type)
 {
   struct dwarf2_property_baton *baton;
-  dwarf2_per_objfile *per_objfile = cu->per_cu->dwarf2_per_objfile;
+  dwarf2_per_objfile *per_objfile = cu->per_objfile;
   struct objfile *objfile = per_objfile->objfile;
   struct obstack *obstack = &objfile->objfile_obstack;
 
@@ -17694,7 +17677,7 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
     complaint (_("Missing DW_AT_lower_bound "
 				      "- DIE at %s [in module %s]"),
 	       sect_offset_str (die->sect_off),
-	       objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
+	       objfile_name (cu->per_objfile->objfile));
 
   struct attribute *attr_ub, *attr_count;
   attr = attr_ub = dwarf2_attr (die, DW_AT_upper_bound, cu);
@@ -17715,12 +17698,12 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
 	    complaint (_("Unresolved DW_AT_upper_bound "
 			 "- DIE at %s [in module %s]"),
 		       sect_offset_str (die->sect_off),
-		       objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
+		       objfile_name (cu->per_objfile->objfile));
 	  if (attr_count != NULL)
 	    complaint (_("Unresolved DW_AT_count "
 			 "- DIE at %s [in module %s]"),
 		       sect_offset_str (die->sect_off),
-		       objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
+		       objfile_name (cu->per_objfile->objfile));
 	}
     }
 
@@ -17765,7 +17748,7 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
 	  complaint (_("Found DW_AT_bit_stride and DW_AT_byte_stride "
 		       "- DIE at %s [in module %s]"),
 		     sect_offset_str (die->sect_off),
-		     objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
+		     objfile_name (cu->per_objfile->objfile));
 	  attr_bit_stride = nullptr;
 	}
       else
@@ -17820,8 +17803,7 @@ read_unspecified_type (struct die_info *die, struct dwarf2_cu *cu)
 {
   struct type *type;
 
-  type = init_type (cu->per_cu->dwarf2_per_objfile->objfile, TYPE_CODE_VOID,0,
-		    NULL);
+  type = init_type (cu->per_objfile->objfile, TYPE_CODE_VOID, 0, NULL);
   TYPE_NAME (type) = dwarf2_name (die, cu);
 
   /* In Ada, an unspecified type is typically used when the description
@@ -18070,7 +18052,7 @@ load_partial_dies (const struct die_reader_specs *reader,
 		   const gdb_byte *info_ptr, int building_psymtab)
 {
   struct dwarf2_cu *cu = reader->cu;
-  struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+  struct objfile *objfile = cu->per_objfile->objfile;
   struct partial_die_info *parent_die, *last_die, *first_die = NULL;
   unsigned int bytes_read;
   unsigned int load_all = 0;
@@ -18344,8 +18326,7 @@ partial_die_info::read (const struct die_reader_specs *reader,
 			const struct abbrev_info &abbrev, const gdb_byte *info_ptr)
 {
   struct dwarf2_cu *cu = reader->cu;
-  struct dwarf2_per_objfile *dwarf2_per_objfile
-    = cu->per_cu->dwarf2_per_objfile;
+  struct dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
   unsigned int i;
   int has_low_pc_attr = 0;
   int has_high_pc_attr = 0;
@@ -18607,8 +18588,7 @@ dwarf2_cu::find_partial_die (sect_offset sect_off)
 static const struct cu_partial_die_info
 find_partial_die (sect_offset sect_off, int offset_in_dwz, struct dwarf2_cu *cu)
 {
-  struct dwarf2_per_objfile *dwarf2_per_objfile
-    = cu->per_cu->dwarf2_per_objfile;
+  struct dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
   struct objfile *objfile = dwarf2_per_objfile->objfile;
   struct dwarf2_per_cu_data *per_cu = NULL;
   struct partial_die_info *pd = NULL;
@@ -18714,7 +18694,7 @@ guess_partial_die_structure_name (struct partial_die_info *struct_pdi,
 						child_pdi->linkage_name));
 	  if (actual_class_name != NULL)
 	    {
-	      struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+	      struct objfile *objfile = cu->per_objfile->objfile;
 	      struct_pdi->name = objfile->intern (actual_class_name.get ());
 	    }
 	  break;
@@ -18800,7 +18780,7 @@ partial_die_info::fixup (struct dwarf2_cu *cu)
      children, see if we can determine the namespace from their linkage
      name.  */
   if (cu->language == language_cplus
-      && !cu->per_cu->dwarf2_per_objfile->per_bfd->types.empty ()
+      && !cu->per_objfile->per_bfd->types.empty ()
       && die_parent == NULL
       && has_children
       && (tag == DW_TAG_class_type
@@ -18831,7 +18811,7 @@ partial_die_info::fixup (struct dwarf2_cu *cu)
 	  else
 	    base = demangled.get ();
 
-	  struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+	  struct objfile *objfile = cu->per_objfile->objfile;
 	  name = objfile->intern (base);
 	}
     }
@@ -18886,8 +18866,7 @@ lookup_loclist_base (struct dwarf2_cu *cu)
 static CORE_ADDR
 read_loclist_index (struct dwarf2_cu *cu, ULONGEST loclist_index)
 {
-  struct dwarf2_per_objfile *dwarf2_per_objfile
-    = cu->per_cu->dwarf2_per_objfile;
+  struct dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
   struct objfile *objfile = dwarf2_per_objfile->objfile;
   bfd *abfd = objfile->obfd;
   ULONGEST loclist_base = lookup_loclist_base (cu);
@@ -18969,8 +18948,7 @@ read_attribute_value (const struct die_reader_specs *reader,
 		      bool *need_reprocess)
 {
   struct dwarf2_cu *cu = reader->cu;
-  struct dwarf2_per_objfile *dwarf2_per_objfile
-    = cu->per_cu->dwarf2_per_objfile;
+  struct dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
   struct objfile *objfile = dwarf2_per_objfile->objfile;
   bfd *abfd = reader->abfd;
   struct comp_unit_head *cu_header = &cu->header;
@@ -19325,7 +19303,7 @@ read_addr_index_1 (struct dwarf2_per_objfile *dwarf2_per_objfile,
 static CORE_ADDR
 read_addr_index (struct dwarf2_cu *cu, unsigned int addr_index)
 {
-  return read_addr_index_1 (cu->per_cu->dwarf2_per_objfile, addr_index,
+  return read_addr_index_1 (cu->per_objfile, addr_index,
 			    cu->addr_base, cu->header.addr_size);
 }
 
@@ -19335,7 +19313,7 @@ static CORE_ADDR
 read_addr_index_from_leb128 (struct dwarf2_cu *cu, const gdb_byte *info_ptr,
 			     unsigned int *bytes_read)
 {
-  bfd *abfd = cu->per_cu->dwarf2_per_objfile->objfile->obfd;
+  bfd *abfd = cu->per_objfile->objfile->obfd;
   unsigned int addr_index = read_unsigned_leb128 (abfd, info_ptr, bytes_read);
 
   return read_addr_index (cu, addr_index);
@@ -19393,8 +19371,7 @@ read_str_index (struct dwarf2_cu *cu,
 		struct dwarf2_section_info *str_offsets_section,
 		ULONGEST str_offsets_base, ULONGEST str_index)
 {
-  struct dwarf2_per_objfile *dwarf2_per_objfile
-    = cu->per_cu->dwarf2_per_objfile;
+  struct dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
   struct objfile *objfile = dwarf2_per_objfile->objfile;
   const char *objf_name = objfile_name (objfile);
   bfd *abfd = objfile->obfd;
@@ -19446,7 +19423,7 @@ read_dwo_str_index (const struct die_reader_specs *reader, ULONGEST str_index)
 static const char *
 read_stub_str_index (struct dwarf2_cu *cu, ULONGEST str_index)
 {
-  struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+  struct objfile *objfile = cu->per_objfile->objfile;
   const char *objf_name = objfile_name (objfile);
   static const char form_name[] = "DW_FORM_GNU_str_index";
   static const char str_offsets_attr_name[] = "DW_AT_str_offsets";
@@ -19458,8 +19435,8 @@ read_stub_str_index (struct dwarf2_cu *cu, ULONGEST str_index)
 	   (long) cu->header.offset_size, objf_name);
 
   return read_str_index (cu,
-			 &cu->per_cu->dwarf2_per_objfile->per_bfd->str,
-			 &cu->per_cu->dwarf2_per_objfile->per_bfd->str_offsets,
+			 &cu->per_objfile->per_bfd->str,
+			 &cu->per_objfile->per_bfd->str_offsets,
 			 *cu->str_offsets_base, str_index);
 }
 
@@ -19585,7 +19562,7 @@ dwarf2_string_attr (struct die_info *die, unsigned int name, struct dwarf2_cu *c
         complaint (_("string type expected for attribute %s for "
 		     "DIE at %s in module %s"),
 		   dwarf_attr_name (name), sect_offset_str (die->sect_off),
-		   objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
+		   objfile_name (cu->per_objfile->objfile));
     }
 
   return str;
@@ -19665,8 +19642,7 @@ static struct dwarf2_section_info *
 get_debug_line_section (struct dwarf2_cu *cu)
 {
   struct dwarf2_section_info *section;
-  struct dwarf2_per_objfile *dwarf2_per_objfile
-    = cu->per_cu->dwarf2_per_objfile;
+  struct dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
 
   /* For TUs in DWO files, the DW_AT_stmt_list attribute lives in the
      DWO file.  */
@@ -19698,8 +19674,7 @@ static line_header_up
 dwarf_decode_line_header (sect_offset sect_off, struct dwarf2_cu *cu)
 {
   struct dwarf2_section_info *section;
-  struct dwarf2_per_objfile *dwarf2_per_objfile
-    = cu->per_cu->dwarf2_per_objfile;
+  struct dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
 
   section = get_debug_line_section (cu);
   section->read (dwarf2_per_objfile->objfile);
@@ -20176,7 +20151,7 @@ lnp_state_machine::check_line_address (struct dwarf2_cu *cu,
       /* This line table is for a function which has been
 	 GCd by the linker.  Ignore it.  PR gdb/12528 */
 
-      struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+      struct objfile *objfile = cu->per_objfile->objfile;
       long line_offset = line_ptr - get_debug_line_section (cu)->buffer;
 
       complaint (_(".debug_line address at offset 0x%lx is 0 [in module %s]"),
@@ -20201,7 +20176,7 @@ dwarf_decode_lines_1 (struct line_header *lh, struct dwarf2_cu *cu,
   unsigned int bytes_read, extended_len;
   unsigned char op_code, extended_op;
   CORE_ADDR baseaddr;
-  struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+  struct objfile *objfile = cu->per_objfile->objfile;
   bfd *abfd = objfile->obfd;
   struct gdbarch *gdbarch = objfile->arch ();
   /* True if we're recording line info (as opposed to building partial
@@ -20430,7 +20405,7 @@ dwarf_decode_lines (struct line_header *lh, const char *comp_dir,
 		    struct dwarf2_cu *cu, dwarf2_psymtab *pst,
 		    CORE_ADDR lowpc, int decode_mapping)
 {
-  struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+  struct objfile *objfile = cu->per_objfile->objfile;
   const int decode_for_pst_p = (pst != NULL);
 
   if (decode_mapping)
@@ -20545,7 +20520,7 @@ static void
 var_decode_location (struct attribute *attr, struct symbol *sym,
 		     struct dwarf2_cu *cu)
 {
-  struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+  struct objfile *objfile = cu->per_objfile->objfile;
   struct comp_unit_head *cu_header = &cu->header;
 
   /* NOTE drow/2003-01-30: There used to be a comment and some special
@@ -20624,8 +20599,7 @@ static struct symbol *
 new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
 	    struct symbol *space)
 {
-  struct dwarf2_per_objfile *dwarf2_per_objfile
-    = cu->per_cu->dwarf2_per_objfile;
+  struct dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
   struct objfile *objfile = dwarf2_per_objfile->objfile;
   struct gdbarch *gdbarch = objfile->arch ();
   struct symbol *sym = NULL;
@@ -21036,7 +21010,7 @@ static gdb_byte *
 dwarf2_const_value_data (const struct attribute *attr, struct obstack *obstack,
 			 struct dwarf2_cu *cu, LONGEST *value, int bits)
 {
-  struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+  struct objfile *objfile = cu->per_objfile->objfile;
   enum bfd_endian byte_order = bfd_big_endian (objfile->obfd) ?
 				BFD_ENDIAN_BIG : BFD_ENDIAN_LITTLE;
   LONGEST l = DW_UNSND (attr);
@@ -21071,7 +21045,7 @@ dwarf2_const_value_attr (const struct attribute *attr, struct type *type,
 			 LONGEST *value, const gdb_byte **bytes,
 			 struct dwarf2_locexpr_baton **baton)
 {
-  dwarf2_per_objfile *per_objfile = cu->per_cu->dwarf2_per_objfile;
+  dwarf2_per_objfile *per_objfile = cu->per_objfile;
   struct objfile *objfile = per_objfile->objfile;
   struct comp_unit_head *cu_header = &cu->header;
   struct dwarf_block *blk;
@@ -21176,7 +21150,7 @@ static void
 dwarf2_const_value (const struct attribute *attr, struct symbol *sym,
 		    struct dwarf2_cu *cu)
 {
-  struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+  struct objfile *objfile = cu->per_objfile->objfile;
   LONGEST value;
   const gdb_byte *bytes;
   struct dwarf2_locexpr_baton *baton;
@@ -21213,7 +21187,7 @@ die_type (struct die_info *die, struct dwarf2_cu *cu)
   type_attr = dwarf2_attr (die, DW_AT_type, cu);
   if (!type_attr)
     {
-      struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+      struct objfile *objfile = cu->per_objfile->objfile;
       /* A missing DW_AT_type represents a void type.  */
       return objfile_type (objfile)->builtin_void;
     }
@@ -21272,7 +21246,7 @@ static struct type *
 die_containing_type (struct die_info *die, struct dwarf2_cu *cu)
 {
   struct attribute *type_attr;
-  struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+  struct objfile *objfile = cu->per_objfile->objfile;
 
   type_attr = dwarf2_attr (die, DW_AT_containing_type, cu);
   if (!type_attr)
@@ -21287,8 +21261,7 @@ die_containing_type (struct die_info *die, struct dwarf2_cu *cu)
 static struct type *
 build_error_marker_type (struct dwarf2_cu *cu, struct die_info *die)
 {
-  struct dwarf2_per_objfile *dwarf2_per_objfile
-    = cu->per_cu->dwarf2_per_objfile;
+  struct dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
   struct objfile *objfile = dwarf2_per_objfile->objfile;
   char *saved;
 
@@ -21311,8 +21284,7 @@ static struct type *
 lookup_die_type (struct die_info *die, const struct attribute *attr,
 		 struct dwarf2_cu *cu)
 {
-  struct dwarf2_per_objfile *dwarf2_per_objfile
-    = cu->per_cu->dwarf2_per_objfile;
+  struct dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
   struct objfile *objfile = dwarf2_per_objfile->objfile;
   struct type *this_type;
 
@@ -21495,7 +21467,7 @@ guess_full_die_structure_name (struct die_info *die, struct dwarf2_cu *cu)
   struct die_info *spec_die;
   struct dwarf2_cu *spec_cu;
   struct die_info *child;
-  struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+  struct objfile *objfile = cu->per_objfile->objfile;
 
   spec_cu = cu;
   spec_die = die_specification (die, &spec_cu);
@@ -21578,7 +21550,7 @@ anonymous_struct_prefix (struct die_info *die, struct dwarf2_cu *cu)
   if (base == NULL || base == DW_STRING (attr) || base[-1] != ':')
     return "";
 
-  struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+  struct objfile *objfile = cu->per_objfile->objfile;
   return obstack_strndup (&objfile->per_bfd->storage_obstack,
 			  DW_STRING (attr),
 			  &base[-1] - DW_STRING (attr));
@@ -21602,8 +21574,7 @@ anonymous_struct_prefix (struct die_info *die, struct dwarf2_cu *cu)
 static const char *
 determine_prefix (struct die_info *die, struct dwarf2_cu *cu)
 {
-  struct dwarf2_per_objfile *dwarf2_per_objfile
-    = cu->per_cu->dwarf2_per_objfile;
+  struct dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
   struct die_info *parent, *spec_die;
   struct dwarf2_cu *spec_cu;
   struct type *parent_type;
@@ -21846,7 +21817,7 @@ static const char *
 dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
 {
   struct attribute *attr;
-  struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+  struct objfile *objfile = cu->per_objfile->objfile;
 
   attr = dwarf2_attr (die, DW_AT_name, cu);
   if ((!attr || !DW_STRING (attr))
@@ -22151,7 +22122,7 @@ follow_die_ref_or_sig (struct die_info *src_die, const struct attribute *attr,
     {
       dump_die_for_error (src_die);
       error (_("Dwarf Error: Expected reference attribute [in module %s]"),
-	     objfile_name ((*ref_cu)->per_cu->dwarf2_per_objfile->objfile));
+	     objfile_name ((*ref_cu)->per_objfile->objfile));
     }
 
   return die;
@@ -22168,8 +22139,7 @@ follow_die_offset (sect_offset sect_off, int offset_in_dwz,
 {
   struct die_info temp_die;
   struct dwarf2_cu *target_cu, *cu = *ref_cu;
-  struct dwarf2_per_objfile *dwarf2_per_objfile
-    = cu->per_cu->dwarf2_per_objfile;
+  struct dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
 
   gdb_assert (cu->per_cu != NULL);
 
@@ -22235,7 +22205,7 @@ follow_die_ref (struct die_info *src_die, const struct attribute *attr,
     error (_("Dwarf Error: Cannot find DIE at %s referenced from DIE "
 	   "at %s [in module %s]"),
 	   sect_offset_str (sect_off), sect_offset_str (src_die->sect_off),
-	   objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
+	   objfile_name (cu->per_objfile->objfile));
 
   return die;
 }
@@ -22568,8 +22538,7 @@ follow_die_sig_1 (struct die_info *src_die, struct signatured_type *sig_type,
 						 to_underlying (temp_die.sect_off));
   if (die)
     {
-      struct dwarf2_per_objfile *dwarf2_per_objfile
-	= (*ref_cu)->per_cu->dwarf2_per_objfile;
+      struct dwarf2_per_objfile *dwarf2_per_objfile = (*ref_cu)->per_objfile;
 
       /* For .gdb_index version 7 keep track of included TUs.
 	 http://sourceware.org/bugzilla/show_bug.cgi?id=15021.  */
@@ -22613,7 +22582,7 @@ follow_die_sig (struct die_info *src_die, const struct attribute *attr,
       error (_("Dwarf Error: Cannot find signatured DIE %s referenced"
                " from DIE at %s [in module %s]"),
              hex_string (signature), sect_offset_str (src_die->sect_off),
-	     objfile_name ((*ref_cu)->per_cu->dwarf2_per_objfile->objfile));
+	     objfile_name ((*ref_cu)->per_objfile->objfile));
     }
 
   die = follow_die_sig_1 (src_die, sig_type, ref_cu);
@@ -22623,7 +22592,7 @@ follow_die_sig (struct die_info *src_die, const struct attribute *attr,
       error (_("Dwarf Error: Problem reading signatured DIE %s referenced"
 	       " from DIE at %s [in module %s]"),
 	     hex_string (signature), sect_offset_str (src_die->sect_off),
-	     objfile_name ((*ref_cu)->per_cu->dwarf2_per_objfile->objfile));
+	     objfile_name ((*ref_cu)->per_objfile->objfile));
     }
 
   return die;
@@ -22636,8 +22605,7 @@ static struct type *
 get_signatured_type (struct die_info *die, ULONGEST signature,
 		     struct dwarf2_cu *cu)
 {
-  struct dwarf2_per_objfile *dwarf2_per_objfile
-    = cu->per_cu->dwarf2_per_objfile;
+  struct dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
   struct signatured_type *sig_type;
   struct dwarf2_cu *type_cu;
   struct die_info *type_die;
@@ -22710,8 +22678,7 @@ get_DW_AT_signature_type (struct die_info *die, const struct attribute *attr,
     }
   else
     {
-      struct dwarf2_per_objfile *dwarf2_per_objfile
-	= cu->per_cu->dwarf2_per_objfile;
+      struct dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
 
       complaint (_("Dwarf Error: DW_AT_signature has bad form %s in DIE"
 		   " at %s [in module %s]"),
@@ -22803,7 +22770,7 @@ read_signatured_type (struct signatured_type *sig_type)
 static CORE_ADDR
 decode_locdesc (struct dwarf_block *blk, struct dwarf2_cu *cu, bool *computed)
 {
-  struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+  struct objfile *objfile = cu->per_objfile->objfile;
   size_t i;
   size_t size = blk->size;
   const gdb_byte *data = blk->data;
@@ -23106,8 +23073,7 @@ static void
 dwarf_decode_macros (struct dwarf2_cu *cu, unsigned int offset,
 		     int section_is_gnu)
 {
-  struct dwarf2_per_objfile *dwarf2_per_objfile
-    = cu->per_cu->dwarf2_per_objfile;
+  struct dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
   struct objfile *objfile = dwarf2_per_objfile->objfile;
   const struct line_header *lh = cu->line_header;
   unsigned int offset_size = cu->header.offset_size;
@@ -23160,8 +23126,7 @@ dwarf_decode_macros (struct dwarf2_cu *cu, unsigned int offset,
 static struct dwarf2_section_info *
 cu_debug_loc_section (struct dwarf2_cu *cu)
 {
-  struct dwarf2_per_objfile *dwarf2_per_objfile
-    = cu->per_cu->dwarf2_per_objfile;
+  struct dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
 
   if (cu->dwo_unit)
     {
@@ -23180,8 +23145,7 @@ fill_in_loclist_baton (struct dwarf2_cu *cu,
 		       struct dwarf2_loclist_baton *baton,
 		       const struct attribute *attr)
 {
-  struct dwarf2_per_objfile *dwarf2_per_objfile
-    = cu->per_cu->dwarf2_per_objfile;
+  struct dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
   struct dwarf2_section_info *section = cu_debug_loc_section (cu);
 
   section->read (dwarf2_per_objfile->objfile);
@@ -23204,8 +23168,7 @@ static void
 dwarf2_symbol_mark_computed (const struct attribute *attr, struct symbol *sym,
 			     struct dwarf2_cu *cu, int is_block)
 {
-  struct dwarf2_per_objfile *dwarf2_per_objfile
-    = cu->per_cu->dwarf2_per_objfile;
+  struct dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
   struct objfile *objfile = dwarf2_per_objfile->objfile;
   struct dwarf2_section_info *section = cu_debug_loc_section (cu);
 
@@ -23672,8 +23635,7 @@ per_cu_offset_and_type_eq (const void *item_lhs, const void *item_rhs)
 static struct type *
 set_die_type (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
 {
-  struct dwarf2_per_objfile *dwarf2_per_objfile
-    = cu->per_cu->dwarf2_per_objfile;
+  struct dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
   struct dwarf2_per_cu_offset_and_type **slot, ofs;
   struct objfile *objfile = dwarf2_per_objfile->objfile;
   struct attribute *attr;
-- 
2.26.2


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

* [PATCH v2 11/42] Add dwarf2_per_bfd field to dwarf2_per_cu_data
  2020-05-12 21:08 [PATCH v2 00/42] Share DWARF partial symtabs between objfiles Simon Marchi
                   ` (9 preceding siblings ...)
  2020-05-12 21:11 ` [PATCH v2 10/42] Remove dwarf2_cu->per_cu->dwarf2_per_objfile references Simon Marchi
@ 2020-05-12 21:11 ` Simon Marchi
  2020-05-12 21:11 ` [PATCH v2 12/42] Make dwarf2_get_dwz_file take a dwarf2_per_bfd Simon Marchi
                   ` (34 subsequent siblings)
  45 siblings, 0 replies; 92+ messages in thread
From: Simon Marchi @ 2020-05-12 21:11 UTC (permalink / raw)
  To: gdb-patches

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

Some code using dwarf2_per_cu_data objects accesses the corresponding
dwarf2_per_bfd using the following pattern:

    per_cu->dwarf2_per_objfile->per_bfd

Since dwarf2_per_cu_data objects are going to become
objfile-independent, the dwarf2_per_objfile link must go.  To replace
it, add a dwarf2_per_cu_data->per_bfd link.  It makes sense to have it
there because the dwarf2_per_cu_data objects belong to the
dwarf2_per_bfd, so this is essentially just a backlink to their owner.

gdb/ChangeLog:

	* dwarf2/read.h (struct dwarf2_per_cu_data) <per_bfd>: New
	member.
	* dwarf2/read.c (dwarf2_per_bfd::allocate_per_cu): Initialize
	dwarf2_per_cu_data::per_bfd.
	(dwarf2_per_bfd::allocate_signatured_type): Likewise.
	(create_type_unit_group): Likewise.
	(queue_comp_unit): Remove reference to
	per_cu->dwarf2_per_objfile.
	(maybe_queue_comp_unit): Likewise.
	(fill_in_sig_entry_from_dwo_entry): Assign new field.
	(create_cus_hash_table): Assign new field.
---
 gdb/dwarf2/read.c | 21 +++++++++++++++------
 gdb/dwarf2/read.h |  3 +++
 2 files changed, 18 insertions(+), 6 deletions(-)

diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 8b5e8800603..4817add89a7 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -2447,6 +2447,7 @@ dwarf2_per_cu_data *
 dwarf2_per_bfd::allocate_per_cu ()
 {
   dwarf2_per_cu_data *result = OBSTACK_ZALLOC (&obstack, dwarf2_per_cu_data);
+  result->per_bfd = this;
   result->index = m_num_psymtabs++;
   return result;
 }
@@ -2457,6 +2458,7 @@ signatured_type *
 dwarf2_per_bfd::allocate_signatured_type ()
 {
   signatured_type *result = OBSTACK_ZALLOC (&obstack, signatured_type);
+  result->per_cu.per_bfd = this;
   result->per_cu.index = m_num_psymtabs++;
   return result;
 }
@@ -6413,10 +6415,12 @@ fill_in_sig_entry_from_dwo_entry (struct dwarf2_per_objfile *dwarf2_per_objfile,
 				  struct signatured_type *sig_entry,
 				  struct dwo_unit *dwo_entry)
 {
+  dwarf2_per_bfd *per_bfd = dwarf2_per_objfile->per_bfd;
+
   /* Make sure we're not clobbering something we don't expect to.  */
   gdb_assert (! sig_entry->per_cu.queued);
   gdb_assert (sig_entry->per_cu.cu == NULL);
-  if (dwarf2_per_objfile->per_bfd->using_index)
+  if (per_bfd->using_index)
     {
       gdb_assert (sig_entry->per_cu.v.quick != NULL);
       gdb_assert (!dwarf2_per_objfile->symtab_set_p (&sig_entry->per_cu));
@@ -6433,6 +6437,7 @@ fill_in_sig_entry_from_dwo_entry (struct dwarf2_per_objfile *dwarf2_per_objfile,
   sig_entry->per_cu.length = dwo_entry->length;
   sig_entry->per_cu.reading_dwo_directly = 1;
   sig_entry->per_cu.dwarf2_per_objfile = dwarf2_per_objfile;
+  sig_entry->per_cu.per_bfd = per_bfd;
   sig_entry->type_offset_in_tu = dwo_entry->type_offset_in_tu;
   sig_entry->dwo_unit = dwo_entry;
 }
@@ -7245,6 +7250,7 @@ static struct type_unit_group *
 create_type_unit_group (struct dwarf2_cu *cu, sect_offset line_offset_struct)
 {
   struct dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
+  dwarf2_per_bfd *per_bfd = dwarf2_per_objfile->per_bfd;
   struct dwarf2_per_cu_data *per_cu;
   struct type_unit_group *tu_group;
 
@@ -7252,10 +7258,11 @@ create_type_unit_group (struct dwarf2_cu *cu, sect_offset line_offset_struct)
 			     struct type_unit_group);
   per_cu = &tu_group->per_cu;
   per_cu->dwarf2_per_objfile = dwarf2_per_objfile;
+  per_cu->per_bfd = per_bfd;
 
-  if (dwarf2_per_objfile->per_bfd->using_index)
+  if (per_bfd->using_index)
     {
-      per_cu->v.quick = OBSTACK_ZALLOC (&dwarf2_per_objfile->per_bfd->obstack,
+      per_cu->v.quick = OBSTACK_ZALLOC (&per_bfd->obstack,
 					struct dwarf2_per_cu_quick_data);
     }
   else
@@ -8868,7 +8875,7 @@ queue_comp_unit (struct dwarf2_per_cu_data *per_cu,
 		 enum language pretend_language)
 {
   per_cu->queued = 1;
-  per_cu->dwarf2_per_objfile->per_bfd->queue.emplace (per_cu, pretend_language);
+  per_cu->per_bfd->queue.emplace (per_cu, pretend_language);
 }
 
 /* If PER_CU is not yet queued, add it to the queue.
@@ -8888,7 +8895,7 @@ maybe_queue_comp_unit (struct dwarf2_cu *dependent_cu,
   /* We may arrive here during partial symbol reading, if we need full
      DIEs to process an unusual case (e.g. template arguments).  Do
      not queue PER_CU, just tell our caller to load its DIEs.  */
-  if (per_cu->dwarf2_per_objfile->per_bfd->reading_partial_symbols)
+  if (per_cu->per_bfd->reading_partial_symbols)
     {
       if (per_cu->cu == NULL || per_cu->cu->dies == NULL)
 	return 1;
@@ -11236,6 +11243,7 @@ create_cus_hash_table (struct dwarf2_per_objfile *dwarf2_per_objfile,
 		       dwarf2_section_info &section, htab_up &cus_htab)
 {
   struct objfile *objfile = dwarf2_per_objfile->objfile;
+  dwarf2_per_bfd *per_bfd = dwarf2_per_objfile->per_bfd;
   const gdb_byte *info_ptr, *end_ptr;
 
   section.read (objfile);
@@ -11262,6 +11270,7 @@ create_cus_hash_table (struct dwarf2_per_objfile *dwarf2_per_objfile,
 
       memset (&per_cu, 0, sizeof (per_cu));
       per_cu.dwarf2_per_objfile = dwarf2_per_objfile;
+      per_cu.per_bfd = per_bfd;
       per_cu.is_debug_types = 0;
       per_cu.sect_off = sect_offset (info_ptr - section.buffer);
       per_cu.section = &section;
@@ -11279,7 +11288,7 @@ create_cus_hash_table (struct dwarf2_per_objfile *dwarf2_per_objfile,
       if (cus_htab == NULL)
 	cus_htab = allocate_dwo_unit_table ();
 
-      dwo_unit = OBSTACK_ZALLOC (&dwarf2_per_objfile->per_bfd->obstack,
+      dwo_unit = OBSTACK_ZALLOC (&per_bfd->obstack,
 				 struct dwo_unit);
       *dwo_unit = read_unit;
       slot = htab_find_slot (cus_htab.get (), dwo_unit, INSERT);
diff --git a/gdb/dwarf2/read.h b/gdb/dwarf2/read.h
index 2897ea6e601..02478d1aa84 100644
--- a/gdb/dwarf2/read.h
+++ b/gdb/dwarf2/read.h
@@ -412,6 +412,9 @@ struct dwarf2_per_cu_data
   /* The corresponding dwarf2_per_objfile.  */
   struct dwarf2_per_objfile *dwarf2_per_objfile;
 
+  /* Backlink to the owner of this.  */
+  dwarf2_per_bfd *per_bfd;
+
   /* When dwarf2_per_bfd::using_index is true, the 'quick' field
      is active.  Otherwise, the 'psymtab' field is active.  */
   union
-- 
2.26.2


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

* [PATCH v2 12/42] Make dwarf2_get_dwz_file take a dwarf2_per_bfd
  2020-05-12 21:08 [PATCH v2 00/42] Share DWARF partial symtabs between objfiles Simon Marchi
                   ` (10 preceding siblings ...)
  2020-05-12 21:11 ` [PATCH v2 11/42] Add dwarf2_per_bfd field to dwarf2_per_cu_data Simon Marchi
@ 2020-05-12 21:11 ` Simon Marchi
  2020-05-12 21:11 ` [PATCH v2 13/42] Use bfd_get_filename instead of objfile_name in lookup_dwo_unit Simon Marchi
                   ` (33 subsequent siblings)
  45 siblings, 0 replies; 92+ messages in thread
From: Simon Marchi @ 2020-05-12 21:11 UTC (permalink / raw)
  To: gdb-patches

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

This allows removing a per_bfd->dwarf2_per_objfile reference in
get_abbrev_section_for_cu.

This requires saving the bfd in dwarf2_per_bfd.  The constructor of
dwarf2_per_bfd already accepts the bfd, so it's just a matter of saving
it in a field.

I replaced uses of objfile_name with bfd_get_filename, which should be
equivalent in this case.

gdb/ChangeLog:

	* dwarf2/read.h (struct dwarf2_per_bfd) <obfd>: New member.
	(dwarf2_get_dwz_file): Replace parameter with dwarf2_per_bfd.
	* dwarf2/read.c (dwarf2_per_bfd::dwarf2_per_bfd): Assign obfd
	field.
	(dwarf2_get_dwz_file): Replace parameter with dwarf2_per_bfd.
	(create_cus_from_index): Update.
	(dwarf2_read_gdb_index): Update.
	(create_cus_from_debug_names): Update.
	(dwarf2_read_debug_names): Update.
	(get_abbrev_section_for_cu): Update.
	(create_all_comp_units): Update.
	(read_attribute_value): Update.
	(get_debug_line_section): Update.
	* dwarf2/index-cache.c (index_cache::store): Update.
	* dwarf2/index-write.c (save_gdb_index_command): Update.
	* dwarf2/macro.c (dwarf_decode_macro_bytes): Update.
---
 gdb/dwarf2/index-cache.c |  2 +-
 gdb/dwarf2/index-write.c |  3 ++-
 gdb/dwarf2/macro.c       |  5 +++--
 gdb/dwarf2/read.c        | 44 ++++++++++++++++++++--------------------
 gdb/dwarf2/read.h        |  6 ++++--
 5 files changed, 32 insertions(+), 28 deletions(-)

diff --git a/gdb/dwarf2/index-cache.c b/gdb/dwarf2/index-cache.c
index 23e938b0102..6da4112529d 100644
--- a/gdb/dwarf2/index-cache.c
+++ b/gdb/dwarf2/index-cache.c
@@ -108,7 +108,7 @@ index_cache::store (struct dwarf2_per_objfile *dwarf2_per_objfile)
 
   /* Get build id of dwz file, if present.  */
   gdb::optional<std::string> dwz_build_id_str;
-  const dwz_file *dwz = dwarf2_get_dwz_file (dwarf2_per_objfile);
+  const dwz_file *dwz = dwarf2_get_dwz_file (dwarf2_per_objfile->per_bfd);
   const char *dwz_build_id_ptr = NULL;
 
   if (dwz != nullptr)
diff --git a/gdb/dwarf2/index-write.c b/gdb/dwarf2/index-write.c
index a9c665165c7..a113aa653a5 100644
--- a/gdb/dwarf2/index-write.c
+++ b/gdb/dwarf2/index-write.c
@@ -1761,7 +1761,8 @@ save_gdb_index_command (const char *arg, int from_tty)
 	  try
 	    {
 	      const char *basename = lbasename (objfile_name (objfile));
-	      const dwz_file *dwz = dwarf2_get_dwz_file (dwarf2_per_objfile);
+	      const dwz_file *dwz
+		= dwarf2_get_dwz_file (dwarf2_per_objfile->per_bfd);
 	      const char *dwz_basename = NULL;
 
 	      if (dwz != NULL)
diff --git a/gdb/dwarf2/macro.c b/gdb/dwarf2/macro.c
index c2580193205..a44e2c77035 100644
--- a/gdb/dwarf2/macro.c
+++ b/gdb/dwarf2/macro.c
@@ -507,7 +507,7 @@ dwarf_decode_macro_bytes (struct dwarf2_per_objfile *dwarf2_per_objfile,
 		    || section_is_dwz)
 		  {
 		    struct dwz_file *dwz
-		      = dwarf2_get_dwz_file (dwarf2_per_objfile);
+		      = dwarf2_get_dwz_file (dwarf2_per_objfile->per_bfd);
 
 		    body = dwz->read_string (objfile, str_offset);
 		  }
@@ -644,7 +644,8 @@ dwarf_decode_macro_bytes (struct dwarf2_per_objfile *dwarf2_per_objfile,
 
 	    if (macinfo_type == DW_MACRO_import_sup)
 	      {
-		struct dwz_file *dwz = dwarf2_get_dwz_file (dwarf2_per_objfile);
+		struct dwz_file *dwz
+		  = dwarf2_get_dwz_file (dwarf2_per_objfile->per_bfd);
 
 		dwz->macro.read (objfile);
 
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 4817add89a7..36c643413aa 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -1752,7 +1752,8 @@ line_header_eq_voidp (const void *item_lhs, const void *item_rhs)
 
 dwarf2_per_bfd::dwarf2_per_bfd (bfd *obfd, const dwarf2_debug_sections *names,
 				bool can_copy_)
-  : can_copy (can_copy_)
+  : obfd (obfd),
+    can_copy (can_copy_)
 {
   if (names == NULL)
     names = &dwarf2_elf_names;
@@ -2112,19 +2113,19 @@ locate_dwz_sections (bfd *abfd, asection *sectp, void *arg)
 /* See dwarf2read.h.  */
 
 struct dwz_file *
-dwarf2_get_dwz_file (struct dwarf2_per_objfile *dwarf2_per_objfile)
+dwarf2_get_dwz_file (dwarf2_per_bfd *per_bfd)
 {
   const char *filename;
   bfd_size_type buildid_len_arg;
   size_t buildid_len;
   bfd_byte *buildid;
 
-  if (dwarf2_per_objfile->per_bfd->dwz_file != NULL)
-    return dwarf2_per_objfile->per_bfd->dwz_file.get ();
+  if (per_bfd->dwz_file != NULL)
+    return per_bfd->dwz_file.get ();
 
   bfd_set_error (bfd_error_no_error);
   gdb::unique_xmalloc_ptr<char> data
-    (bfd_get_alt_debug_link_info (dwarf2_per_objfile->objfile->obfd,
+    (bfd_get_alt_debug_link_info (per_bfd->obfd,
 				  &buildid_len_arg, &buildid));
   if (data == NULL)
     {
@@ -2144,7 +2145,7 @@ dwarf2_get_dwz_file (struct dwarf2_per_objfile *dwarf2_per_objfile)
   if (!IS_ABSOLUTE_PATH (filename))
     {
       gdb::unique_xmalloc_ptr<char> abs
-	= gdb_realpath (objfile_name (dwarf2_per_objfile->objfile));
+	= gdb_realpath (bfd_get_filename (per_bfd->obfd));
 
       abs_storage = ldirname (abs.get ()) + SLASH_STRING + filename;
       filename = abs_storage.c_str ();
@@ -2165,7 +2166,7 @@ dwarf2_get_dwz_file (struct dwarf2_per_objfile *dwarf2_per_objfile)
   if (dwz_bfd == nullptr)
     {
       gdb::unique_xmalloc_ptr<char> alt_filename;
-      const char *origname = dwarf2_per_objfile->objfile->original_name;
+      const char *origname = bfd_get_filename (per_bfd->obfd);
 
       scoped_fd fd (debuginfod_debuginfo_query (buildid,
 						buildid_len,
@@ -2187,7 +2188,7 @@ dwarf2_get_dwz_file (struct dwarf2_per_objfile *dwarf2_per_objfile)
 
   if (dwz_bfd == NULL)
     error (_("could not find '.gnu_debugaltlink' file for %s"),
-	   objfile_name (dwarf2_per_objfile->objfile));
+	   bfd_get_filename (per_bfd->obfd));
 
   std::unique_ptr<struct dwz_file> result
     (new struct dwz_file (std::move (dwz_bfd)));
@@ -2195,10 +2196,9 @@ dwarf2_get_dwz_file (struct dwarf2_per_objfile *dwarf2_per_objfile)
   bfd_map_over_sections (result->dwz_bfd.get (), locate_dwz_sections,
 			 result.get ());
 
-  gdb_bfd_record_inclusion (dwarf2_per_objfile->objfile->obfd,
-			    result->dwz_bfd.get ());
-  dwarf2_per_objfile->per_bfd->dwz_file = std::move (result);
-  return dwarf2_per_objfile->per_bfd->dwz_file.get ();
+  gdb_bfd_record_inclusion (per_bfd->obfd, result->dwz_bfd.get ());
+  per_bfd->dwz_file = std::move (result);
+  return per_bfd->dwz_file.get ();
 }
 \f
 /* DWARF quick_symbols_functions support.  */
@@ -2526,7 +2526,7 @@ create_cus_from_index (struct dwarf2_per_objfile *dwarf2_per_objfile,
   if (dwz_elements == 0)
     return;
 
-  dwz_file *dwz = dwarf2_get_dwz_file (dwarf2_per_objfile);
+  dwz_file *dwz = dwarf2_get_dwz_file (dwarf2_per_objfile->per_bfd);
   create_cus_from_index_list (dwarf2_per_objfile, dwz_list, dwz_elements,
 			      &dwz->info, 1);
 }
@@ -3073,7 +3073,7 @@ dwarf2_read_gdb_index
 
   /* If there is a .dwz file, read it so we can get its CU list as
      well.  */
-  dwz = dwarf2_get_dwz_file (dwarf2_per_objfile);
+  dwz = dwarf2_get_dwz_file (dwarf2_per_objfile->per_bfd);
   if (dwz != NULL)
     {
       struct mapped_index dwz_map;
@@ -5135,7 +5135,7 @@ create_cus_from_debug_names (struct dwarf2_per_objfile *dwarf2_per_objfile,
   if (dwz_map.cu_count == 0)
     return;
 
-  dwz_file *dwz = dwarf2_get_dwz_file (dwarf2_per_objfile);
+  dwz_file *dwz = dwarf2_get_dwz_file (dwarf2_per_objfile->per_bfd);
   create_cus_from_debug_names_list (dwarf2_per_objfile, dwz_map, dwz->info,
 				    true /* is_dwz */);
 }
@@ -5162,7 +5162,7 @@ dwarf2_read_debug_names (struct dwarf2_per_objfile *dwarf2_per_objfile)
 
   /* If there is a .dwz file, read it so we can get its CU list as
      well.  */
-  dwz_file *dwz = dwarf2_get_dwz_file (dwarf2_per_objfile);
+  dwz_file *dwz = dwarf2_get_dwz_file (dwarf2_per_objfile->per_bfd);
   if (dwz != NULL)
     {
       if (!read_debug_names_from_section (objfile,
@@ -5994,12 +5994,12 @@ static struct dwarf2_section_info *
 get_abbrev_section_for_cu (struct dwarf2_per_cu_data *this_cu)
 {
   struct dwarf2_section_info *abbrev;
-  struct dwarf2_per_objfile *dwarf2_per_objfile = this_cu->dwarf2_per_objfile;
+  dwarf2_per_bfd *per_bfd = this_cu->per_bfd;
 
   if (this_cu->is_dwz)
-    abbrev = &dwarf2_get_dwz_file (dwarf2_per_objfile)->abbrev;
+    abbrev = &dwarf2_get_dwz_file (per_bfd)->abbrev;
   else
-    abbrev = &dwarf2_per_objfile->per_bfd->abbrev;
+    abbrev = &per_bfd->abbrev;
 
   return abbrev;
 }
@@ -8020,7 +8020,7 @@ create_all_comp_units (struct dwarf2_per_objfile *dwarf2_per_objfile)
   read_comp_units_from_section (dwarf2_per_objfile, &dwarf2_per_objfile->per_bfd->info,
 				&dwarf2_per_objfile->per_bfd->abbrev, 0);
 
-  dwz_file *dwz = dwarf2_get_dwz_file (dwarf2_per_objfile);
+  dwz_file *dwz = dwarf2_get_dwz_file (dwarf2_per_objfile->per_bfd);
   if (dwz != NULL)
     read_comp_units_from_section (dwarf2_per_objfile, &dwz->info, &dwz->abbrev,
 				  1);
@@ -19064,7 +19064,7 @@ read_attribute_value (const struct die_reader_specs *reader,
       /* FALLTHROUGH */
     case DW_FORM_GNU_strp_alt:
       {
-	struct dwz_file *dwz = dwarf2_get_dwz_file (dwarf2_per_objfile);
+	dwz_file *dwz = dwarf2_get_dwz_file (dwarf2_per_objfile->per_bfd);
 	LONGEST str_offset = cu_header->read_offset (abfd, info_ptr,
 						     &bytes_read);
 
@@ -19659,7 +19659,7 @@ get_debug_line_section (struct dwarf2_cu *cu)
     section = &cu->dwo_unit->dwo_file->sections.line;
   else if (cu->per_cu->is_dwz)
     {
-      struct dwz_file *dwz = dwarf2_get_dwz_file (dwarf2_per_objfile);
+      dwz_file *dwz = dwarf2_get_dwz_file (dwarf2_per_objfile->per_bfd);
 
       section = &dwz->line;
     }
diff --git a/gdb/dwarf2/read.h b/gdb/dwarf2/read.h
index 02478d1aa84..e9c74a40a87 100644
--- a/gdb/dwarf2/read.h
+++ b/gdb/dwarf2/read.h
@@ -136,6 +136,9 @@ struct dwarf2_per_bfd
 			const dwarf2_debug_sections &names);
 
 public:
+  /* The corresponding BFD.  */
+  bfd *obfd;
+
   /* Objects that can be shared across objfiles are stored in this
      obstack or on the psymtab obstack, while objects that are
      objfile-specific are stored on the objfile obstack.  */
@@ -578,8 +581,7 @@ struct signatured_type
    there is no .gnu_debugaltlink section in the file.  Error if there
    is such a section but the file cannot be found.  */
 
-extern struct dwz_file *dwarf2_get_dwz_file
-    (struct dwarf2_per_objfile *dwarf2_per_objfile);
+extern dwz_file *dwarf2_get_dwz_file (dwarf2_per_bfd *per_bfd);
 
 /* Return the type of the DIE at DIE_OFFSET in the CU named by
    PER_CU.  */
-- 
2.26.2


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

* [PATCH v2 13/42] Use bfd_get_filename instead of objfile_name in lookup_dwo_unit
  2020-05-12 21:08 [PATCH v2 00/42] Share DWARF partial symtabs between objfiles Simon Marchi
                   ` (11 preceding siblings ...)
  2020-05-12 21:11 ` [PATCH v2 12/42] Make dwarf2_get_dwz_file take a dwarf2_per_bfd Simon Marchi
@ 2020-05-12 21:11 ` Simon Marchi
  2020-05-12 21:11 ` [PATCH v2 14/42] Add dwarf2_per_objfile parameter to cutu_reader's constructors Simon Marchi
                   ` (32 subsequent siblings)
  45 siblings, 0 replies; 92+ messages in thread
From: Simon Marchi @ 2020-05-12 21:11 UTC (permalink / raw)
  To: gdb-patches; +Cc: Simon Marchi

There should be no functional difference, as objfile_name defers to
bfd_get_filename if objfile::obfd is non-NULL, which should be the case
here.  This allows to remove a reference to
dwarf2_per_cu_data::dwarf2_per_objfile.

gdb/ChangeLog:

	* dwarf2/read.c (lookup_dwo_unit): Use bfd_get_filename instead
	of objfile_name.
---
 gdb/dwarf2/read.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 36c643413aa..504a260338d 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -6850,7 +6850,7 @@ lookup_dwo_unit (struct dwarf2_per_cu_data *this_cu,
       if (!signature.has_value ())
 	error (_("Dwarf Error: missing dwo_id for dwo_name %s"
 		 " [in module %s]"),
-	       dwo_name, objfile_name (this_cu->dwarf2_per_objfile->objfile));
+	       dwo_name, bfd_get_filename (this_cu->per_bfd->obfd));
       dwo_unit = lookup_dwo_comp_unit (this_cu, dwo_name, comp_dir,
 				       *signature);
     }
-- 
2.26.2


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

* [PATCH v2 14/42] Add dwarf2_per_objfile parameter to cutu_reader's constructors
  2020-05-12 21:08 [PATCH v2 00/42] Share DWARF partial symtabs between objfiles Simon Marchi
                   ` (12 preceding siblings ...)
  2020-05-12 21:11 ` [PATCH v2 13/42] Use bfd_get_filename instead of objfile_name in lookup_dwo_unit Simon Marchi
@ 2020-05-12 21:11 ` Simon Marchi
  2020-05-12 21:11 ` [PATCH v2 15/42] Make queue_and_load_dwo_tu receive a dwarf2_cu Simon Marchi
                   ` (31 subsequent siblings)
  45 siblings, 0 replies; 92+ messages in thread
From: Simon Marchi @ 2020-05-12 21:11 UTC (permalink / raw)
  To: gdb-patches

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

The cutu_reader type is used for reading the CU represented by the
passed dwarf2_per_cu_data object.  This reading is done in the context
of a given obfile, which is currently the one associated to the passed
dwarf2_per_cu_data object.  Since the dwarf2_per_cu_data type will
become objfile-independent, we will need to pass the objfile separately.

This patch therefore adds a dwarf2_per_objfile parameter to the
cutu_reader constructors, as well as to their callers, up until the
point where we can get the dwarf2_per_objfile object from somewhere
else.  In the end, this allows removing the reference to
dwarf2_per_cu_data::dwarf2_per_objfile in cutu_reader::cutu_reader.

A few dwarf2_per_cu_data::dwarf2_per_objfile references are added (e.g.
in dwarf2_fetch_die_type_sect_off).  This is temporary, this will be
removed once these functions will get re-worked in subsequent patches.

gdb/ChangeLog:

	* dwarf2/read.c (class cutu_reader) <cutu_reader>: Add
	per_objfile parameter.
	(load_full_type_unit): Add per_objfile parameter.
	(read_signatured_type): Likewise.
	(load_full_comp_unit): Likewise.
	(load_cu): Likewise.
	(dw2_do_instantiate_symtab): Likewise.
	(dw2_get_file_names): Likewise.
	(dw2_map_symtabs_matching_filename): Update.
	(dw_expand_symtabs_matching_file_matcher): Update.
	(dw2_map_symbol_filenames): Update.
	(process_psymtab_comp_unit): Add per_objfile parameter.
	(build_type_psymtabs_1): Update.
	(process_skeletonless_type_unit): Update.
	(dwarf2_build_psymtabs_hard): Update.
	(load_partial_comp_unit): Add per_objfile parameter.
	(scan_partial_symbols): Update.
	(load_full_comp_unit): Add per_objfile parameter.
	(process_imported_unit_die): Update.
	(create_cus_hash_table): Update.
	(find_partial_die): Update.
	(dwarf2_read_addr_index): Update.
	(follow_die_offset): Update.
	(dwarf2_fetch_die_loc_sect_off): Update.
	(dwarf2_fetch_constant_bytes): Update.
	(dwarf2_fetch_die_type_sect_off): Update.
	(follow_die_sig_1): Update.
	(load_full_type_unit): Add per_objfile parameter.
	(read_signatured_type): Likewise.
---
 gdb/dwarf2/read.c | 121 +++++++++++++++++++++++++++-------------------
 1 file changed, 71 insertions(+), 50 deletions(-)

diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 504a260338d..2d6b9e1a73d 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -912,12 +912,14 @@ class cutu_reader : public die_reader_specs
 {
 public:
 
-  cutu_reader (struct dwarf2_per_cu_data *this_cu,
+  cutu_reader (dwarf2_per_cu_data *this_cu,
+	       dwarf2_per_objfile *per_objfile,
 	       struct abbrev_table *abbrev_table,
 	       int use_existing_cu,
 	       bool skip_partial);
 
   explicit cutu_reader (struct dwarf2_per_cu_data *this_cu,
+			dwarf2_per_objfile *per_objfile,
 			struct dwarf2_cu *parent_cu = nullptr,
 			struct dwo_file *dwo_file = nullptr);
 
@@ -1510,9 +1512,11 @@ static struct type *get_DW_AT_signature_type (struct die_info *,
 					      const struct attribute *,
 					      struct dwarf2_cu *);
 
-static void load_full_type_unit (struct dwarf2_per_cu_data *per_cu);
+static void load_full_type_unit (dwarf2_per_cu_data *per_cu,
+				 dwarf2_per_objfile *per_objfile);
 
-static void read_signatured_type (struct signatured_type *);
+static void read_signatured_type (signatured_type *sig_type,
+				  dwarf2_per_objfile *per_objfile);
 
 static int attr_to_dynamic_prop (const struct attribute *attr,
 				 struct die_info *die, struct dwarf2_cu *cu,
@@ -1562,8 +1566,10 @@ static void create_all_comp_units (struct dwarf2_per_objfile *dwarf2_per_objfile
 
 static int create_all_type_units (struct dwarf2_per_objfile *dwarf2_per_objfile);
 
-static void load_full_comp_unit (struct dwarf2_per_cu_data *, bool,
-				 enum language);
+static void load_full_comp_unit (dwarf2_per_cu_data *per_cu,
+				 dwarf2_per_objfile *per_objfile,
+				 bool skip_partial,
+				 enum language pretend_language);
 
 static void process_full_comp_unit (struct dwarf2_per_cu_data *,
 				    enum language);
@@ -2323,17 +2329,18 @@ create_quick_file_names_table (unsigned int nr_initial_entries)
 				     delete_file_name_entry, xcalloc, xfree));
 }
 
-/* Read in PER_CU->CU.  This function is unrelated to symtabs, symtab would
-   have to be created afterwards.  You should call age_cached_comp_units after
-   processing PER_CU->CU.  dw2_setup must have been already called.  */
+/* Read in CU (dwarf2_cu object) for PER_CU in the context of PER_OBJFILE.  This
+   function is unrelated to symtabs, symtab would have to be created afterwards.
+   You should call age_cached_comp_units after processing the CU.  */
 
 static void
-load_cu (struct dwarf2_per_cu_data *per_cu, bool skip_partial)
+load_cu (dwarf2_per_cu_data *per_cu, dwarf2_per_objfile *per_objfile,
+	 bool skip_partial)
 {
   if (per_cu->is_debug_types)
-    load_full_type_unit (per_cu);
+    load_full_type_unit (per_cu, per_objfile);
   else
-    load_full_comp_unit (per_cu, skip_partial, language_minimal);
+    load_full_comp_unit (per_cu, per_objfile, skip_partial, language_minimal);
 
   if (per_cu->cu == NULL)
     return;  /* Dummy CU.  */
@@ -2361,7 +2368,7 @@ dw2_do_instantiate_symtab (dwarf2_per_cu_data *per_cu,
   if (!dwarf2_per_objfile->symtab_set_p (per_cu))
     {
       queue_comp_unit (per_cu, language_minimal);
-      load_cu (per_cu, skip_partial);
+      load_cu (per_cu, dwarf2_per_objfile, skip_partial);
 
       /* If we just loaded a CU from a DWO, and we're working with an index
 	 that may badly handle TUs, load all the TUs in that DWO as well.
@@ -3212,7 +3219,8 @@ dw2_get_file_names_reader (const struct die_reader_specs *reader,
    table for THIS_CU.  */
 
 static struct quick_file_names *
-dw2_get_file_names (struct dwarf2_per_cu_data *this_cu)
+dw2_get_file_names (dwarf2_per_cu_data *this_cu,
+		    dwarf2_per_objfile *per_objfile)
 {
   /* This should never be called for TUs.  */
   gdb_assert (! this_cu->is_debug_types);
@@ -3225,7 +3233,7 @@ dw2_get_file_names (struct dwarf2_per_cu_data *this_cu)
   if (this_cu->v.quick->no_file_data)
     return NULL;
 
-  cutu_reader reader (this_cu);
+  cutu_reader reader (this_cu, per_objfile);
   if (!reader.dummy_p)
     dw2_get_file_names_reader (&reader, reader.info_ptr, reader.comp_unit_die);
 
@@ -3341,7 +3349,8 @@ dw2_map_symtabs_matching_filename
       if (dwarf2_per_objfile->symtab_set_p (per_cu))
 	continue;
 
-      quick_file_names *file_data = dw2_get_file_names (per_cu);
+      quick_file_names *file_data
+	= dw2_get_file_names (per_cu, dwarf2_per_objfile);
       if (file_data == NULL)
 	continue;
 
@@ -3682,7 +3691,8 @@ dw2_expand_symtabs_with_fullname (struct objfile *objfile,
       if (dwarf2_per_objfile->symtab_set_p (per_cu))
 	continue;
 
-      quick_file_names *file_data = dw2_get_file_names (per_cu);
+      quick_file_names *file_data
+	= dw2_get_file_names (per_cu, dwarf2_per_objfile);
       if (file_data == NULL)
 	continue;
 
@@ -4633,7 +4643,8 @@ dw_expand_symtabs_matching_file_matcher
       if (dwarf2_per_objfile->symtab_set_p (per_cu))
 	continue;
 
-      quick_file_names *file_data = dw2_get_file_names (per_cu);
+      quick_file_names *file_data
+	= dw2_get_file_names (per_cu, dwarf2_per_objfile);
       if (file_data == NULL)
 	continue;
 
@@ -4817,7 +4828,8 @@ dw2_map_symbol_filenames (struct objfile *objfile, symbol_filename_ftype *fun,
 	  if (dwarf2_per_objfile->symtab_set_p (per_cu))
 	    continue;
 
-	  quick_file_names *file_data = dw2_get_file_names (per_cu);
+	  quick_file_names *file_data
+	    = dw2_get_file_names (per_cu, dwarf2_per_objfile);
 	  if (file_data == NULL)
 	    continue;
 
@@ -6914,14 +6926,14 @@ cutu_reader::init_tu_and_read_dwo_dies (dwarf2_per_cu_data *this_cu,
    If USE_EXISTING_CU is non-zero, and THIS_CU->cu is non-NULL, then use it.
    Otherwise, a new CU is allocated with xmalloc.  */
 
-cutu_reader::cutu_reader (struct dwarf2_per_cu_data *this_cu,
+cutu_reader::cutu_reader (dwarf2_per_cu_data *this_cu,
+			  dwarf2_per_objfile *dwarf2_per_objfile,
 			  struct abbrev_table *abbrev_table,
 			  int use_existing_cu,
 			  bool skip_partial)
   : die_reader_specs {},
     m_this_cu (this_cu)
 {
-  struct dwarf2_per_objfile *dwarf2_per_objfile = this_cu->dwarf2_per_objfile;
   struct objfile *objfile = dwarf2_per_objfile->objfile;
   struct dwarf2_section_info *section = this_cu->section;
   bfd *abfd = section->get_bfd_owner ();
@@ -7138,13 +7150,13 @@ cutu_reader::keep ()
    When parent_cu is passed, it is used to provide a default value for
    str_offsets_base and addr_base from the parent.  */
 
-cutu_reader::cutu_reader (struct dwarf2_per_cu_data *this_cu,
+cutu_reader::cutu_reader (dwarf2_per_cu_data *this_cu,
+			  dwarf2_per_objfile *dwarf2_per_objfile,
 			  struct dwarf2_cu *parent_cu,
 			  struct dwo_file *dwo_file)
   : die_reader_specs {},
     m_this_cu (this_cu)
 {
-  struct dwarf2_per_objfile *dwarf2_per_objfile = this_cu->dwarf2_per_objfile;
   struct objfile *objfile = dwarf2_per_objfile->objfile;
   struct dwarf2_section_info *section = this_cu->section;
   bfd *abfd = section->get_bfd_owner ();
@@ -7506,7 +7518,8 @@ process_psymtab_comp_unit_reader (const struct die_reader_specs *reader,
    Process compilation unit THIS_CU for a psymtab.  */
 
 static void
-process_psymtab_comp_unit (struct dwarf2_per_cu_data *this_cu,
+process_psymtab_comp_unit (dwarf2_per_cu_data *this_cu,
+			   dwarf2_per_objfile *per_objfile,
 			   bool want_partial_unit,
 			   enum language pretend_language)
 {
@@ -7518,7 +7531,7 @@ process_psymtab_comp_unit (struct dwarf2_per_cu_data *this_cu,
   if (this_cu->cu != NULL)
     free_one_cached_comp_unit (this_cu);
 
-  cutu_reader reader (this_cu, NULL, 0, false);
+  cutu_reader reader (this_cu, per_objfile, NULL, 0, false);
 
   switch (reader.comp_unit_die->tag)
     {
@@ -7699,8 +7712,8 @@ build_type_psymtabs_1 (struct dwarf2_per_objfile *dwarf2_per_objfile)
 	  ++tu_stats->nr_uniq_abbrev_tables;
 	}
 
-      cutu_reader reader (&tu.sig_type->per_cu, abbrev_table.get (),
-			  0, false);
+      cutu_reader reader (&tu.sig_type->per_cu, dwarf2_per_objfile,
+			  abbrev_table.get (), 0, false);
       if (!reader.dummy_p)
 	build_type_psymtabs_reader (&reader, reader.info_ptr,
 				    reader.comp_unit_die);
@@ -7805,7 +7818,7 @@ process_skeletonless_type_unit (void **slot, void *info)
   *slot = entry;
 
   /* This does the job that build_type_psymtabs_1 would have done.  */
-  cutu_reader reader (&entry->per_cu, NULL, 0, false);
+  cutu_reader reader (&entry->per_cu, dwarf2_per_objfile, NULL, 0, false);
   if (!reader.dummy_p)
     build_type_psymtabs_reader (&reader, reader.info_ptr,
 				reader.comp_unit_die);
@@ -7906,7 +7919,8 @@ dwarf2_build_psymtabs_hard (struct dwarf2_per_objfile *dwarf2_per_objfile)
       if (per_cu->v.psymtab != NULL)
 	/* In case a forward DW_TAG_imported_unit has read the CU already.  */
 	continue;
-      process_psymtab_comp_unit (per_cu, false, language_minimal);
+      process_psymtab_comp_unit (per_cu, dwarf2_per_objfile, false,
+				 language_minimal);
     }
 
   /* This has to wait until we read the CUs, we need the list of DWOs.  */
@@ -7939,9 +7953,10 @@ dwarf2_build_psymtabs_hard (struct dwarf2_per_objfile *dwarf2_per_objfile)
    This is also used when rereading a primary CU with load_all_dies.  */
 
 static void
-load_partial_comp_unit (struct dwarf2_per_cu_data *this_cu)
+load_partial_comp_unit (dwarf2_per_cu_data *this_cu,
+			dwarf2_per_objfile *per_objfile)
 {
-  cutu_reader reader (this_cu, NULL, 1, false);
+  cutu_reader reader (this_cu, per_objfile, NULL, 1, false);
 
   if (!reader.dummy_p)
     {
@@ -8120,7 +8135,8 @@ scan_partial_symbols (struct partial_die_info *first_die, CORE_ADDR *lowpc,
 
 		/* Go read the partial unit, if needed.  */
 		if (per_cu->v.psymtab == NULL)
-		  process_psymtab_comp_unit (per_cu, true, cu->language);
+		  process_psymtab_comp_unit (per_cu, cu->per_objfile, true,
+					     cu->language);
 
 		cu->per_cu->imported_symtabs_push (per_cu);
 	      }
@@ -9051,13 +9067,14 @@ die_eq (const void *item_lhs, const void *item_rhs)
 /* Load the DIEs associated with PER_CU into memory.  */
 
 static void
-load_full_comp_unit (struct dwarf2_per_cu_data *this_cu,
+load_full_comp_unit (dwarf2_per_cu_data *this_cu,
+		     dwarf2_per_objfile *per_objfile,
 		     bool skip_partial,
 		     enum language pretend_language)
 {
   gdb_assert (! this_cu->is_debug_types);
 
-  cutu_reader reader (this_cu, NULL, 1, skip_partial);
+  cutu_reader reader (this_cu, per_objfile, NULL, 1, skip_partial);
   if (reader.dummy_p)
     return;
 
@@ -9861,8 +9878,9 @@ process_imported_unit_die (struct die_info *die, struct dwarf2_cu *cu)
     {
       sect_offset sect_off = attr->get_ref_die_offset ();
       bool is_dwz = (attr->form == DW_FORM_GNU_ref_alt || cu->per_cu->is_dwz);
+      dwarf2_per_objfile *per_objfile = cu->per_objfile;
       dwarf2_per_cu_data *per_cu
-	= dwarf2_find_containing_comp_unit (sect_off, is_dwz, cu->per_objfile);
+	= dwarf2_find_containing_comp_unit (sect_off, is_dwz, per_objfile);
 
       /* We're importing a C++ compilation unit with tag DW_TAG_compile_unit
 	 into another compilation unit, at root level.  Regard this as a hint,
@@ -9874,7 +9892,7 @@ process_imported_unit_die (struct die_info *die, struct dwarf2_cu *cu)
 
       /* If necessary, add it to the queue and load its DIEs.  */
       if (maybe_queue_comp_unit (cu, per_cu, cu->language))
-	load_full_comp_unit (per_cu, false, cu->language);
+	load_full_comp_unit (per_cu, per_objfile, false, cu->language);
 
       cu->per_cu->imported_symtabs_push (per_cu);
     }
@@ -11275,7 +11293,7 @@ create_cus_hash_table (struct dwarf2_per_objfile *dwarf2_per_objfile,
       per_cu.sect_off = sect_offset (info_ptr - section.buffer);
       per_cu.section = &section;
 
-      cutu_reader reader (&per_cu, cu, &dwo_file);
+      cutu_reader reader (&per_cu, dwarf2_per_objfile, cu, &dwo_file);
       if (!reader.dummy_p)
 	create_dwo_cu_reader (&reader, reader.info_ptr, reader.comp_unit_die,
 			      &dwo_file, &read_unit);
@@ -12787,7 +12805,7 @@ queue_and_load_dwo_tu (void **slot, void *info)
 	 a real dependency of PER_CU on SIG_TYPE.  That is detected later
 	 while processing PER_CU.  */
       if (maybe_queue_comp_unit (NULL, sig_cu, per_cu->cu->language))
-	load_full_type_unit (sig_cu);
+	load_full_type_unit (sig_cu, per_cu->cu->per_objfile);
       per_cu->imported_symtabs_push (sig_cu);
     }
 
@@ -18626,7 +18644,7 @@ find_partial_die (sect_offset sect_off, int offset_in_dwz, struct dwarf2_cu *cu)
 						 dwarf2_per_objfile);
 
       if (per_cu->cu == NULL || per_cu->cu->partial_dies == NULL)
-	load_partial_comp_unit (per_cu);
+	load_partial_comp_unit (per_cu, cu->per_objfile);
 
       per_cu->cu->last_used = 0;
       pd = per_cu->cu->find_partial_die (sect_off);
@@ -18645,7 +18663,7 @@ find_partial_die (sect_offset sect_off, int offset_in_dwz, struct dwarf2_cu *cu)
 	 DIEs alone (which can still be in use, e.g. in scan_partial_symbols),
 	 and clobber THIS_CU->cu->partial_dies with the hash table for the new
 	 set.  */
-      load_partial_comp_unit (per_cu);
+      load_partial_comp_unit (per_cu, cu->per_objfile);
 
       pd = per_cu->cu->find_partial_die (sect_off);
     }
@@ -19361,7 +19379,7 @@ dwarf2_read_addr_index (dwarf2_per_cu_data *per_cu, unsigned int addr_index)
     }
   else
     {
-      cutu_reader reader (per_cu, NULL, 0, false);
+      cutu_reader reader (per_cu, dwarf2_per_objfile, NULL, 0, false);
       addr_base = reader.cu->addr_base;
       addr_size = reader.cu->header.addr_size;
     }
@@ -22172,7 +22190,7 @@ follow_die_offset (sect_offset sect_off, int offset_in_dwz,
 
       /* If necessary, add it to the queue and load its DIEs.  */
       if (maybe_queue_comp_unit (cu, per_cu, cu->language))
-	load_full_comp_unit (per_cu, false, cu->language);
+	load_full_comp_unit (per_cu, dwarf2_per_objfile, false, cu->language);
 
       target_cu = per_cu->cu;
     }
@@ -22180,7 +22198,8 @@ follow_die_offset (sect_offset sect_off, int offset_in_dwz,
     {
       /* We're loading full DIEs during partial symbol reading.  */
       gdb_assert (dwarf2_per_objfile->per_bfd->reading_partial_symbols);
-      load_full_comp_unit (cu->per_cu, false, language_minimal);
+      load_full_comp_unit (cu->per_cu, dwarf2_per_objfile, false,
+			   language_minimal);
     }
 
   *ref_cu = target_cu;
@@ -22235,7 +22254,7 @@ dwarf2_fetch_die_loc_sect_off (sect_offset sect_off,
   struct objfile *objfile = dwarf2_per_objfile->objfile;
 
   if (per_cu->cu == NULL)
-    load_cu (per_cu, false);
+    load_cu (per_cu, dwarf2_per_objfile, false);
   cu = per_cu->cu;
   if (cu == NULL)
     {
@@ -22373,7 +22392,7 @@ dwarf2_fetch_constant_bytes (sect_offset sect_off,
   struct objfile *objfile = per_cu->dwarf2_per_objfile->objfile;
 
   if (per_cu->cu == NULL)
-    load_cu (per_cu, false);
+    load_cu (per_cu, per_cu->dwarf2_per_objfile, false);
   cu = per_cu->cu;
   if (cu == NULL)
     {
@@ -22495,7 +22514,7 @@ dwarf2_fetch_die_type_sect_off (sect_offset sect_off,
   struct die_info *die;
 
   if (per_cu->cu == NULL)
-    load_cu (per_cu, false);
+    load_cu (per_cu, per_cu->dwarf2_per_objfile, false);
   cu = per_cu->cu;
   if (!cu)
     return NULL;
@@ -22537,7 +22556,7 @@ follow_die_sig_1 (struct die_info *src_die, struct signatured_type *sig_type,
   /* If necessary, add it to the queue and load its DIEs.  */
 
   if (maybe_queue_comp_unit (*ref_cu, &sig_type->per_cu, language_minimal))
-    read_signatured_type (sig_type);
+    read_signatured_type (sig_type, (*ref_cu)->per_objfile);
 
   sig_cu = sig_type->per_cu.cu;
   gdb_assert (sig_cu != NULL);
@@ -22700,7 +22719,8 @@ get_DW_AT_signature_type (struct die_info *die, const struct attribute *attr,
 /* Load the DIEs associated with type unit PER_CU into memory.  */
 
 static void
-load_full_type_unit (struct dwarf2_per_cu_data *per_cu)
+load_full_type_unit (dwarf2_per_cu_data *per_cu,
+		     dwarf2_per_objfile *per_objfile)
 {
   struct signatured_type *sig_type;
 
@@ -22714,7 +22734,7 @@ load_full_type_unit (struct dwarf2_per_cu_data *per_cu)
 
   gdb_assert (per_cu->cu == NULL);
 
-  read_signatured_type (sig_type);
+  read_signatured_type (sig_type, per_objfile);
 
   gdb_assert (per_cu->cu != NULL);
 }
@@ -22724,14 +22744,15 @@ load_full_type_unit (struct dwarf2_per_cu_data *per_cu)
    read in the real type from the DWO file as well.  */
 
 static void
-read_signatured_type (struct signatured_type *sig_type)
+read_signatured_type (signatured_type *sig_type,
+		      dwarf2_per_objfile *per_objfile)
 {
   struct dwarf2_per_cu_data *per_cu = &sig_type->per_cu;
 
   gdb_assert (per_cu->is_debug_types);
   gdb_assert (per_cu->cu == NULL);
 
-  cutu_reader reader (per_cu, NULL, 0, false);
+  cutu_reader reader (per_cu, per_objfile, NULL, 0, false);
 
   if (!reader.dummy_p)
     {
-- 
2.26.2


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

* [PATCH v2 15/42] Make queue_and_load_dwo_tu receive a dwarf2_cu
  2020-05-12 21:08 [PATCH v2 00/42] Share DWARF partial symtabs between objfiles Simon Marchi
                   ` (13 preceding siblings ...)
  2020-05-12 21:11 ` [PATCH v2 14/42] Add dwarf2_per_objfile parameter to cutu_reader's constructors Simon Marchi
@ 2020-05-12 21:11 ` Simon Marchi
  2020-05-22 20:45   ` Tom Tromey
  2020-05-12 21:11 ` [PATCH v2 16/42] Remove dwarf2_per_cu_data::dwarf2_per_objfile reference in cutu_reader::keep Simon Marchi
                   ` (30 subsequent siblings)
  45 siblings, 1 reply; 92+ messages in thread
From: Simon Marchi @ 2020-05-12 21:11 UTC (permalink / raw)
  To: gdb-patches

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

queue_and_load_dwo_tu, used as a callback for htab_traverse_noresize,
currently receives a dwarf2_per_cu_data as its `info` user data.  It
accesses the current dwarf2_cu object through the dwarf2_per_cu_data::cu field.
This field will be removed, because the dwarf2_per_cu_data will become
objfile-independent, while dwarf_cu will remain objfile-dependent.

To remove references to this field, change queue_and_load_dwo_tu so
that it expects to receive a pointer to the dwarf2_cu as its info
parameter.

A reference to dwarf2_per_cu_data::cu needs to be added, but it will get
removed in a subsequent patch, when this function gets re-worked.

I kept this as a separate patch, because since there's no strong typing
here, it's easy to miss something.

gdb/ChangeLog:

	* dwarf2/read.c (queue_and_load_dwo_tu): Expect a dwarf2_cu as
	the info parameter.
	(queue_and_load_all_dwo_tus): Pass per_cu->cu.
---
 gdb/dwarf2/read.c | 13 ++++++-------
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 2d6b9e1a73d..3138e961bc9 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -12792,10 +12792,9 @@ static int
 queue_and_load_dwo_tu (void **slot, void *info)
 {
   struct dwo_unit *dwo_unit = (struct dwo_unit *) *slot;
-  struct dwarf2_per_cu_data *per_cu = (struct dwarf2_per_cu_data *) info;
+  dwarf2_cu *cu = (dwarf2_cu *) info;
   ULONGEST signature = dwo_unit->signature;
-  struct signatured_type *sig_type =
-    lookup_dwo_signatured_type (per_cu->cu, signature);
+  signatured_type *sig_type = lookup_dwo_signatured_type (cu, signature);
 
   if (sig_type != NULL)
     {
@@ -12804,9 +12803,9 @@ queue_and_load_dwo_tu (void **slot, void *info)
       /* We pass NULL for DEPENDENT_CU because we don't yet know if there's
 	 a real dependency of PER_CU on SIG_TYPE.  That is detected later
 	 while processing PER_CU.  */
-      if (maybe_queue_comp_unit (NULL, sig_cu, per_cu->cu->language))
-	load_full_type_unit (sig_cu, per_cu->cu->per_objfile);
-      per_cu->imported_symtabs_push (sig_cu);
+      if (maybe_queue_comp_unit (NULL, sig_cu, cu->language))
+	load_full_type_unit (sig_cu, cu->per_objfile);
+      cu->per_cu->imported_symtabs_push (sig_cu);
     }
 
   return 1;
@@ -12833,7 +12832,7 @@ queue_and_load_all_dwo_tus (struct dwarf2_per_cu_data *per_cu)
   dwo_file = dwo_unit->dwo_file;
   if (dwo_file->tus != NULL)
     htab_traverse_noresize (dwo_file->tus.get (), queue_and_load_dwo_tu,
-			    per_cu);
+			    per_cu->cu);
 }
 
 /* Read in various DIEs.  */
-- 
2.26.2


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

* [PATCH v2 16/42] Remove dwarf2_per_cu_data::dwarf2_per_objfile reference in cutu_reader::keep
  2020-05-12 21:08 [PATCH v2 00/42] Share DWARF partial symtabs between objfiles Simon Marchi
                   ` (14 preceding siblings ...)
  2020-05-12 21:11 ` [PATCH v2 15/42] Make queue_and_load_dwo_tu receive a dwarf2_cu Simon Marchi
@ 2020-05-12 21:11 ` Simon Marchi
  2020-05-12 21:11 ` [PATCH v2 17/42] Add dwarf2_per_objfile parameter to create_partial_symtab Simon Marchi
                   ` (29 subsequent siblings)
  45 siblings, 0 replies; 92+ messages in thread
From: Simon Marchi @ 2020-05-12 21:11 UTC (permalink / raw)
  To: gdb-patches; +Cc: Simon Marchi

Here, it should be safe to use dwarf2_per_cu_data->cu->per_objfile, as
we know that dwarf2_per_cu_data->cu will be set at this point.

Note that this adds a reference to dwarf2_per_cu_data::cu, which we'll
want to remove later, but the current focus is to remove references to
dwarf2_per_cu_data::dwarf2_per_objfile.  We'll deal with that in a
subsequent patch.

gdb/ChangeLog:

	* dwarf2/read.c (cutu_reader::keep): Access dwarf2_per_objfile
	object through m_this_cu->cu.
---
 gdb/dwarf2/read.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 3138e961bc9..d028e86c356 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -7124,8 +7124,11 @@ cutu_reader::keep ()
   gdb_assert (!dummy_p);
   if (m_new_cu != NULL)
     {
-      struct dwarf2_per_objfile *dwarf2_per_objfile
-	= m_this_cu->dwarf2_per_objfile;
+      /* We know that m_this_cu->cu is set, since we are in the process of
+         parsing the CU.  */
+      gdb_assert (m_this_cu->cu != nullptr);
+      dwarf2_per_objfile *dwarf2_per_objfile = m_this_cu->cu->per_objfile;
+
       /* Link this CU into read_in_chain.  */
       m_this_cu->cu->read_in_chain = dwarf2_per_objfile->per_bfd->read_in_chain;
       dwarf2_per_objfile->per_bfd->read_in_chain = m_this_cu;
-- 
2.26.2


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

* [PATCH v2 17/42] Add dwarf2_per_objfile parameter to create_partial_symtab
  2020-05-12 21:08 [PATCH v2 00/42] Share DWARF partial symtabs between objfiles Simon Marchi
                   ` (15 preceding siblings ...)
  2020-05-12 21:11 ` [PATCH v2 16/42] Remove dwarf2_per_cu_data::dwarf2_per_objfile reference in cutu_reader::keep Simon Marchi
@ 2020-05-12 21:11 ` Simon Marchi
  2020-05-12 21:11 ` [PATCH v2 18/42] Add dwarf2_per_objfile parameter to recursively_compute_inclusions Simon Marchi
                   ` (28 subsequent siblings)
  45 siblings, 0 replies; 92+ messages in thread
From: Simon Marchi @ 2020-05-12 21:11 UTC (permalink / raw)
  To: gdb-patches; +Cc: Simon Marchi

This allows removing a dwarf2_per_cu_data::dwarf2_per_objfile reference.

gdb/ChangeLog:

	* dwarf2/read.c (create_partial_symtab): Add dwarf2_per_objfile
	parameter.
	(create_type_unit_group): Update.
	(process_psymtab_comp_unit_reader): Update.
	(build_type_psymtabs_reader): Update.
---
 gdb/dwarf2/read.c | 18 +++++++++++-------
 1 file changed, 11 insertions(+), 7 deletions(-)

diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index d028e86c356..68e5d987443 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -1204,7 +1204,8 @@ static void dwarf2_find_base_address (struct die_info *die,
 				      struct dwarf2_cu *cu);
 
 static dwarf2_psymtab *create_partial_symtab
-  (struct dwarf2_per_cu_data *per_cu, const char *name);
+  (dwarf2_per_cu_data *per_cu, dwarf2_per_objfile *per_objfile,
+   const char *name);
 
 static void build_type_psymtabs_reader (const struct die_reader_specs *reader,
 					const gdb_byte *info_ptr,
@@ -7293,7 +7294,7 @@ create_type_unit_group (struct dwarf2_cu *cu, sect_offset line_offset_struct)
       else
 	name = string_printf ("<type_units_at_0x%x>", line_offset);
 
-      pst = create_partial_symtab (per_cu, name.c_str ());
+      pst = create_partial_symtab (per_cu, dwarf2_per_objfile, name.c_str ());
       pst->anonymous = true;
     }
 
@@ -7367,9 +7368,11 @@ get_type_unit_group (struct dwarf2_cu *cu, const struct attribute *stmt_list)
    dirname, textlow, texthigh.  */
 
 static dwarf2_psymtab *
-create_partial_symtab (struct dwarf2_per_cu_data *per_cu, const char *name)
+create_partial_symtab (dwarf2_per_cu_data *per_cu,
+		       dwarf2_per_objfile *per_objfile,
+		       const char *name)
 {
-  struct objfile *objfile = per_cu->dwarf2_per_objfile->objfile;
+  struct objfile *objfile = per_objfile->objfile;
   dwarf2_psymtab *pst;
 
   pst = new dwarf2_psymtab (name, objfile, per_cu);
@@ -7391,7 +7394,8 @@ process_psymtab_comp_unit_reader (const struct die_reader_specs *reader,
 				  enum language pretend_language)
 {
   struct dwarf2_cu *cu = reader->cu;
-  struct objfile *objfile = cu->per_objfile->objfile;
+  dwarf2_per_objfile *per_objfile = cu->per_objfile;
+  struct objfile *objfile = per_objfile->objfile;
   struct gdbarch *gdbarch = objfile->arch ();
   struct dwarf2_per_cu_data *per_cu = cu->per_cu;
   CORE_ADDR baseaddr;
@@ -7418,7 +7422,7 @@ process_psymtab_comp_unit_reader (const struct die_reader_specs *reader,
       filename = debug_filename.get ();
     }
 
-  pst = create_partial_symtab (per_cu, filename);
+  pst = create_partial_symtab (per_cu, per_objfile, filename);
 
   /* This must be done before calling dwarf2_build_include_psymtabs.  */
   pst->dirname = dwarf2_string_attr (comp_unit_die, DW_AT_comp_dir, cu);
@@ -7599,7 +7603,7 @@ build_type_psymtabs_reader (const struct die_reader_specs *reader,
   tu_group->tus->push_back (sig_type);
 
   prepare_one_comp_unit (cu, type_unit_die, language_minimal);
-  pst = create_partial_symtab (per_cu, "");
+  pst = create_partial_symtab (per_cu, dwarf2_per_objfile, "");
   pst->anonymous = true;
 
   first_die = load_partial_dies (reader, info_ptr, 1);
-- 
2.26.2


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

* [PATCH v2 18/42] Add dwarf2_per_objfile parameter to recursively_compute_inclusions
  2020-05-12 21:08 [PATCH v2 00/42] Share DWARF partial symtabs between objfiles Simon Marchi
                   ` (16 preceding siblings ...)
  2020-05-12 21:11 ` [PATCH v2 17/42] Add dwarf2_per_objfile parameter to create_partial_symtab Simon Marchi
@ 2020-05-12 21:11 ` Simon Marchi
  2020-05-12 21:11 ` [PATCH v2 19/42] Add dwarf2_per_objfile parameter to process_full_{comp, type}_unit Simon Marchi
                   ` (27 subsequent siblings)
  45 siblings, 0 replies; 92+ messages in thread
From: Simon Marchi @ 2020-05-12 21:11 UTC (permalink / raw)
  To: gdb-patches; +Cc: Simon Marchi

This allows removing dwarf2_per_cu_data::dwarf2_per_objfile references
in recursively_compute_inclusions and compute_compunit_symtab_includes.

gdb/ChangeLog:

	* dwarf2/read.c (recursively_compute_inclusions): Add
	dwarf2_per_objfile parameter.
	(compute_compunit_symtab_includes): Likewise.
	(process_cu_includes): Update.
---
 gdb/dwarf2/read.c | 18 +++++++++++-------
 1 file changed, 11 insertions(+), 7 deletions(-)

diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 68e5d987443..bf1bbe1fd99 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -9591,7 +9591,8 @@ rust_union_quirks (struct dwarf2_cu *cu)
 static void
 recursively_compute_inclusions (std::vector<compunit_symtab *> *result,
 				htab_t all_children, htab_t all_type_symtabs,
-				struct dwarf2_per_cu_data *per_cu,
+				dwarf2_per_cu_data *per_cu,
+				dwarf2_per_objfile *per_objfile,
 				struct compunit_symtab *immediate_parent)
 {
   void **slot = htab_find_slot (all_children, per_cu, INSERT);
@@ -9604,7 +9605,7 @@ recursively_compute_inclusions (std::vector<compunit_symtab *> *result,
   *slot = per_cu;
 
   /* Only add a CU if it has a symbol table.  */
-  compunit_symtab *cust = per_cu->dwarf2_per_objfile->get_symtab (per_cu);
+  compunit_symtab *cust = per_objfile->get_symtab (per_cu);
   if (cust != NULL)
     {
       /* If this is a type unit only add its symbol table if we haven't
@@ -9632,7 +9633,8 @@ recursively_compute_inclusions (std::vector<compunit_symtab *> *result,
     for (dwarf2_per_cu_data *ptr : *per_cu->imported_symtabs)
       {
 	recursively_compute_inclusions (result, all_children,
-					all_type_symtabs, ptr, cust);
+					all_type_symtabs, ptr, per_objfile,
+					cust);
       }
 }
 
@@ -9640,7 +9642,8 @@ recursively_compute_inclusions (std::vector<compunit_symtab *> *result,
    PER_CU.  */
 
 static void
-compute_compunit_symtab_includes (struct dwarf2_per_cu_data *per_cu)
+compute_compunit_symtab_includes (dwarf2_per_cu_data *per_cu,
+				  dwarf2_per_objfile *per_objfile)
 {
   gdb_assert (! per_cu->is_debug_types);
 
@@ -9649,7 +9652,7 @@ compute_compunit_symtab_includes (struct dwarf2_per_cu_data *per_cu)
       int len;
       std::vector<compunit_symtab *> result_symtabs;
       htab_t all_children, all_type_symtabs;
-      compunit_symtab *cust = per_cu->dwarf2_per_objfile->get_symtab (per_cu);
+      compunit_symtab *cust = per_objfile->get_symtab (per_cu);
 
       /* If we don't have a symtab, we can just skip this case.  */
       if (cust == NULL)
@@ -9663,7 +9666,8 @@ compute_compunit_symtab_includes (struct dwarf2_per_cu_data *per_cu)
       for (dwarf2_per_cu_data *ptr : *per_cu->imported_symtabs)
 	{
 	  recursively_compute_inclusions (&result_symtabs, all_children,
-					  all_type_symtabs, ptr, cust);
+					  all_type_symtabs, ptr, per_objfile,
+					  cust);
 	}
 
       /* Now we have a transitive closure of all the included symtabs.  */
@@ -9689,7 +9693,7 @@ process_cu_includes (struct dwarf2_per_objfile *dwarf2_per_objfile)
   for (dwarf2_per_cu_data *iter : dwarf2_per_objfile->per_bfd->just_read_cus)
     {
       if (! iter->is_debug_types)
-	compute_compunit_symtab_includes (iter);
+	compute_compunit_symtab_includes (iter, dwarf2_per_objfile);
     }
 
   dwarf2_per_objfile->per_bfd->just_read_cus.clear ();
-- 
2.26.2


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

* [PATCH v2 19/42] Add dwarf2_per_objfile parameter to process_full_{comp, type}_unit
  2020-05-12 21:08 [PATCH v2 00/42] Share DWARF partial symtabs between objfiles Simon Marchi
                   ` (17 preceding siblings ...)
  2020-05-12 21:11 ` [PATCH v2 18/42] Add dwarf2_per_objfile parameter to recursively_compute_inclusions Simon Marchi
@ 2020-05-12 21:11 ` Simon Marchi
  2020-05-12 21:12 ` [PATCH v2 20/42] Pass dwarf2_cu objects to dwo-related functions, instead of dwarf2_per_cu_data Simon Marchi
                   ` (26 subsequent siblings)
  45 siblings, 0 replies; 92+ messages in thread
From: Simon Marchi @ 2020-05-12 21:11 UTC (permalink / raw)
  To: gdb-patches; +Cc: Simon Marchi

This allows removing the dwarf2_per_cu_data::dwarf2_per_objfile
references in them.

gdb/ChangeLog:

	* dwarf2/read.c (process_full_comp_unit): Add dwarf2_per_objfile
	parameter.
	(process_full_type_unit): Likewise.
	(process_queue): Update.
---
 gdb/dwarf2/read.c | 24 ++++++++++++++----------
 1 file changed, 14 insertions(+), 10 deletions(-)

diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index bf1bbe1fd99..906a0ade2ce 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -1572,11 +1572,13 @@ static void load_full_comp_unit (dwarf2_per_cu_data *per_cu,
 				 bool skip_partial,
 				 enum language pretend_language);
 
-static void process_full_comp_unit (struct dwarf2_per_cu_data *,
-				    enum language);
+static void process_full_comp_unit (dwarf2_per_cu_data *per_cu,
+				    dwarf2_per_objfile *per_objfile,
+				    enum language pretend_language);
 
-static void process_full_type_unit (struct dwarf2_per_cu_data *,
-				    enum language);
+static void process_full_type_unit (dwarf2_per_cu_data *per_cu,
+				    dwarf2_per_objfile *per_objfile,
+				    enum language pretend_language);
 
 static void dwarf2_add_dependence (struct dwarf2_cu *,
 				   struct dwarf2_per_cu_data *);
@@ -8997,9 +8999,11 @@ process_queue (struct dwarf2_per_objfile *dwarf2_per_objfile)
 	    fprintf_unfiltered (gdb_stdlog, "Expanding symtab of %s\n", buf);
 
 	  if (per_cu->is_debug_types)
-	    process_full_type_unit (per_cu, item.pretend_language);
+	    process_full_type_unit (per_cu, dwarf2_per_objfile,
+				    item.pretend_language);
 	  else
-	    process_full_comp_unit (per_cu, item.pretend_language);
+	    process_full_comp_unit (per_cu, dwarf2_per_objfile,
+				    item.pretend_language);
 
 	  if (dwarf_read_debug >= debug_print_threshold)
 	    fprintf_unfiltered (gdb_stdlog, "Done expanding %s\n", buf);
@@ -9703,11 +9707,11 @@ process_cu_includes (struct dwarf2_per_objfile *dwarf2_per_objfile)
    already been loaded into memory.  */
 
 static void
-process_full_comp_unit (struct dwarf2_per_cu_data *per_cu,
+process_full_comp_unit (dwarf2_per_cu_data *per_cu,
+			dwarf2_per_objfile *dwarf2_per_objfile,
 			enum language pretend_language)
 {
   struct dwarf2_cu *cu = per_cu->cu;
-  struct dwarf2_per_objfile *dwarf2_per_objfile = per_cu->dwarf2_per_objfile;
   struct objfile *objfile = dwarf2_per_objfile->objfile;
   struct gdbarch *gdbarch = objfile->arch ();
   CORE_ADDR lowpc, highpc;
@@ -9803,11 +9807,11 @@ process_full_comp_unit (struct dwarf2_per_cu_data *per_cu,
    already been loaded into memory.  */
 
 static void
-process_full_type_unit (struct dwarf2_per_cu_data *per_cu,
+process_full_type_unit (dwarf2_per_cu_data *per_cu,
+			dwarf2_per_objfile *dwarf2_per_objfile,
 			enum language pretend_language)
 {
   struct dwarf2_cu *cu = per_cu->cu;
-  struct dwarf2_per_objfile *dwarf2_per_objfile = per_cu->dwarf2_per_objfile;
   struct objfile *objfile = dwarf2_per_objfile->objfile;
   struct compunit_symtab *cust;
   struct signatured_type *sig_type;
-- 
2.26.2


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

* [PATCH v2 20/42] Pass dwarf2_cu objects to dwo-related functions, instead of dwarf2_per_cu_data
  2020-05-12 21:08 [PATCH v2 00/42] Share DWARF partial symtabs between objfiles Simon Marchi
                   ` (18 preceding siblings ...)
  2020-05-12 21:11 ` [PATCH v2 19/42] Add dwarf2_per_objfile parameter to process_full_{comp, type}_unit Simon Marchi
@ 2020-05-12 21:12 ` Simon Marchi
  2020-05-12 21:12 ` [PATCH v2 21/42] Remove reference to dwarf2_per_cu_data::dwarf2_per_objfile in queue_and_load_all_dwo_tus Simon Marchi
                   ` (25 subsequent siblings)
  45 siblings, 0 replies; 92+ messages in thread
From: Simon Marchi @ 2020-05-12 21:12 UTC (permalink / raw)
  To: gdb-patches; +Cc: Simon Marchi

This allows removing references to the
dwarf2_per_cu_data::dwarf2_per_objfile field.

I am not too sure of the code flow here, but ultimately
open_and_init_dwo_file calls create_cus_hash_table, and passes it
per_cu->cu.  create_cus_hash_table requires a dwarf2_cu to pass to
cutu_reader, as the "parent_cu".

The dwarf2_per_cu_data::cu link is only set when in a certain context.
It's not easy to convince myself in which situations it's safe to use
it.  Instead, if a function is going to use a dwarf2_cu, I think it's
simpler if it takes that object directly.  If it needs access to the
corresponding dwarf2_per_cu_data object, then it can used the
dwarf2_cu::per_cu field, which we know is always set.

This patch adds some references to dwarf2_per_cu_data::cu in the
cutu_reader context.  In this context, we know this field will be set,
as it's cutu_reader that is responsible for instantiating the dwarf2_cu
and assigning the field.

gdb/ChangeLog:

	* dwarf2/read.c (lookup_dwo_comp_unit): Change
	dwarf2_per_cu_data parameter fo dwarf2_cu.
	(lookup_dwo_type_unit): Likewise.
	(read_cutu_die_from_dwo): Likewise.
	(lookup_dwo_unit): Likewise.
	(open_and_init_dwo_file): Likewise.
	(lookup_dwo_cutu): Likewise.
	(lookup_dwo_comp_unit): Likewise.
	(lookup_dwo_type_unit): Likewise.
	(cutu_reader::init_tu_and_read_dwo_dies): Update.
	(cutu_reader::cutu_reader): Update.
---
 gdb/dwarf2/read.c | 84 ++++++++++++++++++++++-------------------------
 1 file changed, 39 insertions(+), 45 deletions(-)

diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 906a0ade2ce..5dc8a350739 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -1672,10 +1672,11 @@ static struct dwp_file *get_dwp_file
   (struct dwarf2_per_objfile *dwarf2_per_objfile);
 
 static struct dwo_unit *lookup_dwo_comp_unit
-  (struct dwarf2_per_cu_data *, const char *, const char *, ULONGEST);
+  (dwarf2_cu *cu, const char *dwo_name, const char *comp_dir,
+   ULONGEST signature);
 
 static struct dwo_unit *lookup_dwo_type_unit
-  (struct signatured_type *, const char *, const char *);
+  (dwarf2_cu *cu, const char *dwo_name, const char *comp_dir);
 
 static void queue_and_load_all_dwo_tus (struct dwarf2_per_cu_data *);
 
@@ -6650,7 +6651,7 @@ init_cu_die_reader (struct die_reader_specs *reader,
    The result is non-zero if a valid (non-dummy) DIE was found.  */
 
 static int
-read_cutu_die_from_dwo (struct dwarf2_per_cu_data *this_cu,
+read_cutu_die_from_dwo (dwarf2_cu *cu,
 			struct dwo_unit *dwo_unit,
 			struct die_info *stub_comp_unit_die,
 			const char *stub_comp_dir,
@@ -6659,9 +6660,9 @@ read_cutu_die_from_dwo (struct dwarf2_per_cu_data *this_cu,
 			struct die_info **result_comp_unit_die,
 			abbrev_table_up *result_dwo_abbrev_table)
 {
-  struct dwarf2_per_objfile *dwarf2_per_objfile = this_cu->dwarf2_per_objfile;
+  struct dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
+  dwarf2_per_cu_data *per_cu = cu->per_cu;
   struct objfile *objfile = dwarf2_per_objfile->objfile;
-  struct dwarf2_cu *cu = this_cu->cu;
   bfd *abfd;
   const gdb_byte *begin_info_ptr, *info_ptr;
   struct attribute *comp_dir, *stmt_list, *low_pc, *high_pc, *ranges;
@@ -6690,7 +6691,7 @@ read_cutu_die_from_dwo (struct dwarf2_per_cu_data *this_cu,
     {
       /* For TUs in DWO files, the DW_AT_stmt_list attribute lives in the
 	 DWO file.  */
-      if (! this_cu->is_debug_types)
+      if (!per_cu->is_debug_types)
 	stmt_list = dwarf2_attr (stub_comp_unit_die, DW_AT_stmt_list, cu);
       low_pc = dwarf2_attr (stub_comp_unit_die, DW_AT_low_pc, cu);
       high_pc = dwarf2_attr (stub_comp_unit_die, DW_AT_high_pc, cu);
@@ -6723,9 +6724,9 @@ read_cutu_die_from_dwo (struct dwarf2_per_cu_data *this_cu,
 			       + to_underlying (dwo_unit->sect_off));
   dwo_abbrev_section = &dwo_unit->dwo_file->sections.abbrev;
 
-  if (this_cu->is_debug_types)
+  if (per_cu->is_debug_types)
     {
-      struct signatured_type *sig_type = (struct signatured_type *) this_cu;
+      signatured_type *sig_type = (struct signatured_type *) per_cu;
 
       info_ptr = read_and_check_comp_unit_head (dwarf2_per_objfile,
 						&cu->header, section,
@@ -6836,11 +6837,9 @@ lookup_dwo_id (struct dwarf2_cu *cu, struct die_info* comp_unit_die)
    Returns NULL if the specified DWO unit cannot be found.  */
 
 static struct dwo_unit *
-lookup_dwo_unit (struct dwarf2_per_cu_data *this_cu,
-		 struct die_info *comp_unit_die,
-		 const char *dwo_name)
+lookup_dwo_unit (dwarf2_cu *cu, die_info *comp_unit_die, const char *dwo_name)
 {
-  struct dwarf2_cu *cu = this_cu->cu;
+  dwarf2_per_cu_data *per_cu = cu->per_cu;
   struct dwo_unit *dwo_unit;
   const char *comp_dir;
 
@@ -6850,24 +6849,18 @@ lookup_dwo_unit (struct dwarf2_per_cu_data *this_cu,
   dwo_name = dwarf2_dwo_name (comp_unit_die, cu);
   comp_dir = dwarf2_string_attr (comp_unit_die, DW_AT_comp_dir, cu);
 
-  if (this_cu->is_debug_types)
-    {
-      struct signatured_type *sig_type;
-
-      /* Since this_cu is the first member of struct signatured_type,
-	 we can go from a pointer to one to a pointer to the other.  */
-      sig_type = (struct signatured_type *) this_cu;
-      dwo_unit = lookup_dwo_type_unit (sig_type, dwo_name, comp_dir);
-    }
+  if (per_cu->is_debug_types)
+    dwo_unit = lookup_dwo_type_unit (cu, dwo_name, comp_dir);
   else
     {
       gdb::optional<ULONGEST> signature = lookup_dwo_id (cu, comp_unit_die);
+
       if (!signature.has_value ())
 	error (_("Dwarf Error: missing dwo_id for dwo_name %s"
 		 " [in module %s]"),
-	       dwo_name, bfd_get_filename (this_cu->per_bfd->obfd));
-      dwo_unit = lookup_dwo_comp_unit (this_cu, dwo_name, comp_dir,
-				       *signature);
+	       dwo_name, bfd_get_filename (per_cu->per_bfd->obfd));
+
+      dwo_unit = lookup_dwo_comp_unit (cu, dwo_name, comp_dir, *signature);
     }
 
   return dwo_unit;
@@ -6907,7 +6900,7 @@ cutu_reader::init_tu_and_read_dwo_dies (dwarf2_per_cu_data *this_cu,
      abbrev table.  When reading DWOs with skeletonless TUs, all the TUs
      could share abbrev tables.  */
 
-  if (read_cutu_die_from_dwo (this_cu, sig_type->dwo_unit,
+  if (read_cutu_die_from_dwo (this_cu->cu, sig_type->dwo_unit,
 			      NULL /* stub_comp_unit_die */,
 			      sig_type->dwo_unit->dwo_file->comp_dir,
 			      this, &info_ptr,
@@ -7094,10 +7087,10 @@ cutu_reader::cutu_reader (dwarf2_per_cu_data *this_cu,
 		     sect_offset_str (this_cu->sect_off),
 		     bfd_get_filename (abfd));
 	}
-      dwo_unit = lookup_dwo_unit (this_cu, comp_unit_die, dwo_name);
+      dwo_unit = lookup_dwo_unit (cu, comp_unit_die, dwo_name);
       if (dwo_unit != NULL)
 	{
-	  if (read_cutu_die_from_dwo (this_cu, dwo_unit,
+	  if (read_cutu_die_from_dwo (cu, dwo_unit,
 				      comp_unit_die, NULL,
 				      this, &info_ptr,
 				      &dwo_comp_unit_die,
@@ -12325,10 +12318,10 @@ dwarf2_locate_dwo_sections (bfd *abfd, asection *sectp, void *dwo_sections_ptr)
    The result is NULL if DWO_NAME can't be found.  */
 
 static struct dwo_file *
-open_and_init_dwo_file (struct dwarf2_per_cu_data *per_cu,
-			const char *dwo_name, const char *comp_dir)
+open_and_init_dwo_file (dwarf2_cu *cu, const char *dwo_name,
+			const char *comp_dir)
 {
-  struct dwarf2_per_objfile *dwarf2_per_objfile = per_cu->dwarf2_per_objfile;
+  struct dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
 
   gdb_bfd_ref_ptr dbfd = open_dwo_file (dwarf2_per_objfile, dwo_name, comp_dir);
   if (dbfd == NULL)
@@ -12346,7 +12339,7 @@ open_and_init_dwo_file (struct dwarf2_per_cu_data *per_cu,
   bfd_map_over_sections (dwo_file->dbfd.get (), dwarf2_locate_dwo_sections,
 			 &dwo_file->sections);
 
-  create_cus_hash_table (dwarf2_per_objfile, per_cu->cu, *dwo_file,
+  create_cus_hash_table (dwarf2_per_objfile, cu, *dwo_file,
 			 dwo_file->sections.info, dwo_file->cus);
 
   create_debug_types_hash_table (dwarf2_per_objfile, dwo_file.get (),
@@ -12657,11 +12650,10 @@ get_dwp_file (struct dwarf2_per_objfile *dwarf2_per_objfile)
    (dwo_id mismatch or couldn't find the DWO/DWP file).  */
 
 static struct dwo_unit *
-lookup_dwo_cutu (struct dwarf2_per_cu_data *this_unit,
-		 const char *dwo_name, const char *comp_dir,
+lookup_dwo_cutu (dwarf2_cu *cu, const char *dwo_name, const char *comp_dir,
 		 ULONGEST signature, int is_debug_types)
 {
-  struct dwarf2_per_objfile *dwarf2_per_objfile = this_unit->dwarf2_per_objfile;
+  struct dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
   struct objfile *objfile = dwarf2_per_objfile->objfile;
   const char *kind = is_debug_types ? "TU" : "CU";
   void **dwo_file_slot;
@@ -12707,7 +12699,7 @@ lookup_dwo_cutu (struct dwarf2_per_cu_data *this_unit,
       if (*dwo_file_slot == NULL)
 	{
 	  /* Read in the file and build a table of the CUs/TUs it contains.  */
-	  *dwo_file_slot = open_and_init_dwo_file (this_unit, dwo_name, comp_dir);
+	  *dwo_file_slot = open_and_init_dwo_file (cu, dwo_name, comp_dir);
 	}
       /* NOTE: This will be NULL if unable to open the file.  */
       dwo_file = (struct dwo_file *) *dwo_file_slot;
@@ -12772,10 +12764,8 @@ lookup_dwo_cutu (struct dwarf2_per_cu_data *this_unit,
 
     warning (_("Could not find DWO %s %s(%s)%s referenced by %s at offset %s"
 	       " [in module %s]"),
-	     kind, dwo_name, hex_string (signature),
-	     dwp_text.c_str (),
-	     this_unit->is_debug_types ? "TU" : "CU",
-	     sect_offset_str (this_unit->sect_off), objfile_name (objfile));
+	     kind, dwo_name, hex_string (signature), dwp_text.c_str (), kind,
+	     sect_offset_str (cu->per_cu->sect_off), objfile_name (objfile));
   }
   return NULL;
 }
@@ -12784,21 +12774,25 @@ lookup_dwo_cutu (struct dwarf2_per_cu_data *this_unit,
    See lookup_dwo_cutu_unit for details.  */
 
 static struct dwo_unit *
-lookup_dwo_comp_unit (struct dwarf2_per_cu_data *this_cu,
-		      const char *dwo_name, const char *comp_dir,
+lookup_dwo_comp_unit (dwarf2_cu *cu, const char *dwo_name, const char *comp_dir,
 		      ULONGEST signature)
 {
-  return lookup_dwo_cutu (this_cu, dwo_name, comp_dir, signature, 0);
+  gdb_assert (!cu->per_cu->is_debug_types);
+
+  return lookup_dwo_cutu (cu, dwo_name, comp_dir, signature, 0);
 }
 
 /* Lookup the DWO TU DWO_NAME/SIGNATURE referenced from THIS_TU.
    See lookup_dwo_cutu_unit for details.  */
 
 static struct dwo_unit *
-lookup_dwo_type_unit (struct signatured_type *this_tu,
-		      const char *dwo_name, const char *comp_dir)
+lookup_dwo_type_unit (dwarf2_cu *cu, const char *dwo_name, const char *comp_dir)
 {
-  return lookup_dwo_cutu (&this_tu->per_cu, dwo_name, comp_dir, this_tu->signature, 1);
+  gdb_assert (cu->per_cu->is_debug_types);
+
+  signatured_type *sig_type = (signatured_type *) cu->per_cu;
+
+  return lookup_dwo_cutu (cu, dwo_name, comp_dir, sig_type->signature, 1);
 }
 
 /* Traversal function for queue_and_load_all_dwo_tus.  */
-- 
2.26.2


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

* [PATCH v2 21/42] Remove reference to dwarf2_per_cu_data::dwarf2_per_objfile in queue_and_load_all_dwo_tus
  2020-05-12 21:08 [PATCH v2 00/42] Share DWARF partial symtabs between objfiles Simon Marchi
                   ` (19 preceding siblings ...)
  2020-05-12 21:12 ` [PATCH v2 20/42] Pass dwarf2_cu objects to dwo-related functions, instead of dwarf2_per_cu_data Simon Marchi
@ 2020-05-12 21:12 ` Simon Marchi
  2020-05-12 21:12 ` [PATCH v2 22/42] Move int type methods out of dwarf2_per_cu_data Simon Marchi
                   ` (24 subsequent siblings)
  45 siblings, 0 replies; 92+ messages in thread
From: Simon Marchi @ 2020-05-12 21:12 UTC (permalink / raw)
  To: gdb-patches; +Cc: Simon Marchi

In this context, we know that per_cu->cu will be set, as there is this
assertion:

    gdb_assert (per_cu->cu != NULL)

So in order to remove the dwarf2_per_cu_data::dwarf2_per_objfile
reference in queue_and_load_all_dwo_tus, we can go through per_cu->cu.
This adds a reference to dwarf2_per_cu_data::cu, but it will get removed
eventually, in a subsequent patch.

gdb/ChangeLog:

	* dwarf2/read.c (queue_and_load_all_dwo_tus): Access per_objfile
	data through per_cu->cu.
---
 gdb/dwarf2/read.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 5dc8a350739..7470acef879 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -12832,8 +12832,8 @@ queue_and_load_all_dwo_tus (struct dwarf2_per_cu_data *per_cu)
   struct dwo_file *dwo_file;
 
   gdb_assert (!per_cu->is_debug_types);
-  gdb_assert (get_dwp_file (per_cu->dwarf2_per_objfile) == NULL);
   gdb_assert (per_cu->cu != NULL);
+  gdb_assert (get_dwp_file (per_cu->cu->per_objfile) == NULL);
 
   dwo_unit = per_cu->cu->dwo_unit;
   gdb_assert (dwo_unit != NULL);
-- 
2.26.2


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

* [PATCH v2 22/42] Move int type methods out of dwarf2_per_cu_data
  2020-05-12 21:08 [PATCH v2 00/42] Share DWARF partial symtabs between objfiles Simon Marchi
                   ` (20 preceding siblings ...)
  2020-05-12 21:12 ` [PATCH v2 21/42] Remove reference to dwarf2_per_cu_data::dwarf2_per_objfile in queue_and_load_all_dwo_tus Simon Marchi
@ 2020-05-12 21:12 ` Simon Marchi
  2020-05-12 21:12 ` [PATCH v2 23/42] Add dwarf2_per_objfile to dwarf_expr_context and dwarf2_frame_cache Simon Marchi
                   ` (23 subsequent siblings)
  45 siblings, 0 replies; 92+ messages in thread
From: Simon Marchi @ 2020-05-12 21:12 UTC (permalink / raw)
  To: gdb-patches; +Cc: Simon Marchi

These methods rely on the current objfile to create types based on it.
Since dwarf2_per_cu_data is to become objfile-independent, these methods
need to mvoe.

int_type can be in dwarf2_per_objfile, as it only requires knowing about
the objfile.

addr_sized_int_type and addr_type also need to know about the DWARF
address type size, which is CU-specific.  The dwarf2_cu objects seems
like a good place for it, as it knows both about the current objfile and
the current CU.

gdb/ChangeLog:

	* dwarf2/read.h (struct dwarf2_per_cu_data) <addr_type,
	addr_sized_int_type>: Move to dwarf2_cu.
	<int_type>: Move to dwarf2_per_objfile.
	(struct dwarf2_per_objfile) <int_type>: Move here.
	* dwarf2/read.c (struct dwarf2_cu) <addr_type,
	addr_sized_int_type>: Move here.
	(read_func_scope): Update.
	(read_array_type): Update.
	(read_tag_string_type): Update.
	(attr_to_dynamic_prop): Update.
	(dwarf2_per_cu_data::int_type): Rename to...
	(dwarf2_per_objfile::int_type): ... this.
	(dwarf2_per_cu_data::addr_sized_int_type): Rename to...
	(dwarf2_cu::addr_sized_int_type): ... this.
	(read_subrange_type): Update.
	(dwarf2_per_cu_data::addr_type): Rename to...
	(dwarf2_cu::addr_type): ... this.
	(set_die_type): Update.
---
 gdb/dwarf2/read.c | 49 +++++++++++++++++++++++++++--------------------
 gdb/dwarf2/read.h | 18 ++++-------------
 2 files changed, 32 insertions(+), 35 deletions(-)

diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 7470acef879..c9bced5d967 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -421,6 +421,16 @@ struct dwarf2_cu
   /* Reset the builder.  */
   void reset_builder () { m_builder.reset (); }
 
+  /* Return a type that is a generic pointer type, the size of which
+     matches the address size given in the compilation unit header for
+     this CU.  */
+  struct type *addr_type () const;
+
+  /* Find an integer type the same size as the address size given in
+     the compilation unit header for this CU.  UNSIGNED_P controls if
+     the integer is unsigned or not.  */
+  struct type *addr_sized_int_type (bool unsigned_p) const;
+
   /* The header of the compilation unit.  */
   struct comp_unit_head header {};
 
@@ -13069,7 +13079,7 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
       newobj->static_link
 	= XOBNEW (&objfile->objfile_obstack, struct dynamic_prop);
       attr_to_dynamic_prop (attr, die, cu, newobj->static_link,
-			    cu->per_cu->addr_type ());
+			    cu->addr_type ());
     }
 
   cu->list_in_scope = cu->get_builder ()->get_local_symbols ();
@@ -15461,8 +15471,7 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
       else
 	{
 	  struct dynamic_prop prop;
-	  if (attr_to_dynamic_prop (attr, die, cu, &prop,
-				    cu->per_cu->addr_type ()))
+	  if (attr_to_dynamic_prop (attr, die, cu, &prop, cu->addr_type ()))
 	    type->add_dyn_prop (DYN_PROP_BYTE_SIZE, prop);
           TYPE_LENGTH (type) = 0;
 	}
@@ -16147,7 +16156,7 @@ read_array_type (struct die_info *die, struct dwarf2_cu *cu)
   if (attr != NULL)
     {
       int stride_ok;
-      struct type *prop_type = cu->per_cu->addr_sized_int_type (false);
+      struct type *prop_type = cu->addr_sized_int_type (false);
 
       byte_stride_prop
 	= (struct dynamic_prop *) alloca (sizeof (struct dynamic_prop));
@@ -16947,13 +16956,13 @@ read_tag_string_type (struct die_info *die, struct dwarf2_cu *cu)
 	  /* Pass 0 as the default as we know this attribute is constant
 	     and the default value will not be returned.  */
 	  LONGEST sz = len->constant_value (0);
-	  prop_type = cu->per_cu->int_type (sz, true);
+	  prop_type = cu->per_objfile->int_type (sz, true);
 	}
       else
 	{
 	  /* If the size is not specified then we assume it is the size of
 	     an address on this target.  */
-	  prop_type = cu->per_cu->addr_sized_int_type (true);
+	  prop_type = cu->addr_sized_int_type (true);
 	}
 
       /* Convert the attribute into a dynamic property.  */
@@ -17583,9 +17592,8 @@ attr_to_dynamic_prop (const struct attribute *attr, struct die_info *die,
 /* See read.h.  */
 
 struct type *
-dwarf2_per_cu_data::int_type (int size_in_bytes, bool unsigned_p) const
+dwarf2_per_objfile::int_type (int size_in_bytes, bool unsigned_p) const
 {
-  struct objfile *objfile = dwarf2_per_objfile->objfile;
   struct type *int_type;
 
   /* Helper macro to examine the various builtin types.  */
@@ -17610,10 +17618,10 @@ dwarf2_per_cu_data::int_type (int size_in_bytes, bool unsigned_p) const
 /* See read.h.  */
 
 struct type *
-dwarf2_per_cu_data::addr_sized_int_type (bool unsigned_p) const
+dwarf2_cu::addr_sized_int_type (bool unsigned_p) const
 {
-  int addr_size = this->addr_size ();
-  return int_type (addr_size, unsigned_p);
+  int addr_size = this->per_cu->addr_size ();
+  return this->per_objfile->int_type (addr_size, unsigned_p);
 }
 
 /* Read the DW_AT_type attribute for a sub-range.  If this attribute is not
@@ -17638,7 +17646,7 @@ read_subrange_index_type (struct die_info *die, struct dwarf2_cu *cu)
      FIXME: muller/2010-05-28: Possible references to object for low bound,
      high bound or count are not yet handled by this code.  */
   if (TYPE_CODE (index_type) == TYPE_CODE_VOID)
-    index_type = cu->per_cu->addr_sized_int_type (false);
+    index_type = cu->addr_sized_int_type (false);
 
   return index_type;
 }
@@ -17768,7 +17776,7 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
   attribute *attr_byte_stride = dwarf2_attr (die, DW_AT_byte_stride, cu);
   if (attr_byte_stride != nullptr)
     {
-      struct type *prop_type = cu->per_cu->addr_sized_int_type (false);
+      struct type *prop_type = cu->addr_sized_int_type (false);
       attr_to_dynamic_prop (attr_byte_stride, die, cu, &byte_stride_prop,
 			    prop_type);
     }
@@ -17788,7 +17796,7 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
 	}
       else
 	{
-	  struct type *prop_type = cu->per_cu->addr_sized_int_type (false);
+	  struct type *prop_type = cu->addr_sized_int_type (false);
 	  attr_to_dynamic_prop (attr_bit_stride, die, cu, &bit_stride_prop,
 				prop_type);
 	}
@@ -23356,12 +23364,12 @@ dwarf2_per_cu_data::text_offset () const
 /* See read.h.  */
 
 struct type *
-dwarf2_per_cu_data::addr_type () const
+dwarf2_cu::addr_type () const
 {
-  struct objfile *objfile = dwarf2_per_objfile->objfile;
+  struct objfile *objfile = this->per_objfile->objfile;
   struct type *void_type = objfile_type (objfile)->builtin_void;
   struct type *addr_type = lookup_pointer_type (void_type);
-  int addr_size = this->addr_size ();
+  int addr_size = this->per_cu->addr_size ();
 
   if (TYPE_LENGTH (addr_type) == addr_size)
     return addr_type;
@@ -23699,7 +23707,7 @@ set_die_type (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
   attr = dwarf2_attr (die, DW_AT_allocated, cu);
   if (attr != NULL && attr->form_is_block ())
     {
-      struct type *prop_type = cu->per_cu->addr_sized_int_type (false);
+      struct type *prop_type = cu->addr_sized_int_type (false);
       if (attr_to_dynamic_prop (attr, die, cu, &prop, prop_type))
         type->add_dyn_prop (DYN_PROP_ALLOCATED, prop);
     }
@@ -23714,7 +23722,7 @@ set_die_type (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
   attr = dwarf2_attr (die, DW_AT_associated, cu);
   if (attr != NULL && attr->form_is_block ())
     {
-      struct type *prop_type = cu->per_cu->addr_sized_int_type (false);
+      struct type *prop_type = cu->addr_sized_int_type (false);
       if (attr_to_dynamic_prop (attr, die, cu, &prop, prop_type))
         type->add_dyn_prop (DYN_PROP_ASSOCIATED, prop);
     }
@@ -23727,8 +23735,7 @@ set_die_type (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
 
   /* Read DW_AT_data_location and set in type.  */
   attr = dwarf2_attr (die, DW_AT_data_location, cu);
-  if (attr_to_dynamic_prop (attr, die, cu, &prop,
-			    cu->per_cu->addr_type ()))
+  if (attr_to_dynamic_prop (attr, die, cu, &prop, cu->addr_type ()))
     type->add_dyn_prop (DYN_PROP_DATA_LOCATION, prop);
 
   if (dwarf2_per_objfile->die_type_hash == NULL)
diff --git a/gdb/dwarf2/read.h b/gdb/dwarf2/read.h
index e9c74a40a87..77c1f246db7 100644
--- a/gdb/dwarf2/read.h
+++ b/gdb/dwarf2/read.h
@@ -301,6 +301,10 @@ struct dwarf2_per_objfile
   /* Set the compunit_symtab associated to PER_CU.  */
   void set_symtab (const dwarf2_per_cu_data *per_cu, compunit_symtab *symtab);
 
+  /* Find an integer type SIZE_IN_BYTES bytes in size and return it.
+     UNSIGNED_P controls if the integer is unsigned or not.  */
+  struct type *int_type (int size_in_bytes, bool unsigned_p) const;
+
   /* Back link.  */
   struct objfile *objfile;
 
@@ -510,20 +514,6 @@ struct dwarf2_per_cu_data
      corresponding offset in the parent objfile.  */
   CORE_ADDR text_offset () const;
 
-  /* Return a type that is a generic pointer type, the size of which
-     matches the address size given in the compilation unit header for
-     this CU.  */
-  struct type *addr_type () const;
-
-  /* Find an integer type SIZE_IN_BYTES bytes in size and return it.
-     UNSIGNED_P controls if the integer is unsigned or not.  */
-  struct type *int_type (int size_in_bytes, bool unsigned_p) const;
-
-  /* Find an integer type the same size as the address size given in
-     the compilation unit header for this CU.  UNSIGNED_P controls if
-     the integer is unsigned or not.  */
-  struct type *addr_sized_int_type (bool unsigned_p) const;
-
   /* Return DWARF version number of this CU.  */
   short version () const
   {
-- 
2.26.2


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

* [PATCH v2 23/42] Add dwarf2_per_objfile to dwarf_expr_context and dwarf2_frame_cache
  2020-05-12 21:08 [PATCH v2 00/42] Share DWARF partial symtabs between objfiles Simon Marchi
                   ` (21 preceding siblings ...)
  2020-05-12 21:12 ` [PATCH v2 22/42] Move int type methods out of dwarf2_per_cu_data Simon Marchi
@ 2020-05-12 21:12 ` Simon Marchi
  2020-05-22 21:04   ` Tom Tromey
  2020-05-12 21:12 ` [PATCH v2 24/42] Remove dwarf2_per_cu_data::text_offset Simon Marchi
                   ` (22 subsequent siblings)
  45 siblings, 1 reply; 92+ messages in thread
From: Simon Marchi @ 2020-05-12 21:12 UTC (permalink / raw)
  To: gdb-patches; +Cc: Simon Marchi

Evaluating DWARF expressions (such as location expressions) requires
knowing about the current objfile.  For example, it may call functions
like dwarf2_fetch_die_loc_sect_off, which currently obtain the
dwarf2_per_objfile object it needs from the dwarf2_per_cu_data object.
However, since we are going to remove this
dwarf2_per_cu_data::dwarf2_per_objfile link, these functions will need
to obtain the current dwarf2_per_objfile by parmeter.

If we go up the stack, we see that the DWARF expression contexts
(dwarf_expr_context and the classes that derive from it) need to store
the dwarf2_per_objfile, to be able to pass it to those functions that
will need it.

This patch adds a constructor to all these dwarf_expr_context variants,
accepting a dwarf2_per_objfile parameter.  This dwarf2_per_objfile
generally comes from a symbol baton created earlier.

For frame-related expressions, the dwarf2_per_objfile object must be
passed through the dwarf2_frame_cache object.  This lead to the
dwarf2_frame_find_fde function returning (by parameter) a
dwarf2_per_objfile object.  I then realized that this made the existing
"out_offset" parameter redundant.  This offset is
`objfile->text_section_offset ()`, so it can be recomputed from the
dwarf2_per_objfile object at any time.  I therefore opted to remove this
output parameter, as well as the offset field of dwarf2_frame_cache.

*Note*, there's one spot I'm particularly unsure about.  In
dwarf_evaluate_loc_desc::push_dwarf_reg_entry_value, we would save and
overwrite the offset value in the context, along with a bunch of other
state.  This is because we might be about to evaluate something in a
different CU that the current one.  If the two CUs are in the same
objfile, then the text_offset is the same, as it's a property of the
objfile.  However, if the two CUs are possibly in different objfiles,
then it means the text_offsets are different.  It would also mean we
would need to save and restore the dwarf2_per_objfile in the context.
Is that even possible?

gdb/ChangeLog:

	* dwarf2/expr.h (struct dwarf_expr_context)
	<dwarf_expr_context>: Add dwarf2_per_objfile parameter.
	<offset>: Remove.
	<per_objfile>: New member.
	* dwarf2/expr.c (dwarf_expr_context::dwarf_expr_context): Add
	dwarf2_per_objfile parameter.  Don't set offset, set
	per_objfile.
	(dwarf_expr_context::execute_stack_op): Use offset from objfile.
	* dwarf2/frame.c (dwarf2_frame_find_fde): Return (by parameter)
	a dwarf2_per_objfile object instead of an offset.
	(class dwarf_expr_executor) <dwarf_expr_executor>: Add
	constructor.
	(execute_stack_op): Add dwarf2_per_objfile parameter, pass it
	to dwarf2_expr_executor constructor.  Don't set offset.
	(dwarf2_fetch_cfa_info): Update.
	(struct dwarf2_frame_cache) <text_offset>: Remove.
	<per_objfile>: New field.
	(dwarf2_frame_cache): Update.
	(dwarf2_frame_prev_register): Update.
	* dwarf2/loc.c (class dwarf_evaluate_loc_desc)
	<dwarf_evaluate_loc_desc>: Add constructor.
	(dwarf2_evaluate_loc_desc_full): Update.
	(dwarf2_locexpr_baton_eval): Update.
	(class symbol_needs_eval_context) <symbol_needs_eval_context>:
	Add constructor.
	(dwarf2_loc_desc_get_symbol_read_needs): Update.
---
 gdb/dwarf2/expr.c  | 11 ++++----
 gdb/dwarf2/expr.h  | 11 ++++----
 gdb/dwarf2/frame.c | 67 +++++++++++++++++++++++++++-------------------
 gdb/dwarf2/loc.c   | 33 ++++++++++++-----------
 4 files changed, 69 insertions(+), 53 deletions(-)

diff --git a/gdb/dwarf2/expr.c b/gdb/dwarf2/expr.c
index 243f493084b..802b34322f2 100644
--- a/gdb/dwarf2/expr.c
+++ b/gdb/dwarf2/expr.c
@@ -27,6 +27,7 @@
 #include "dwarf2.h"
 #include "dwarf2/expr.h"
 #include "dwarf2/loc.h"
+#include "dwarf2/read.h"
 #include "gdbsupport/underlying.h"
 #include "gdbarch.h"
 
@@ -88,17 +89,17 @@ dwarf_expr_context::address_type () const
 
 /* Create a new context for the expression evaluator.  */
 
-dwarf_expr_context::dwarf_expr_context ()
+dwarf_expr_context::dwarf_expr_context (dwarf2_per_objfile *per_objfile)
 : gdbarch (NULL),
   addr_size (0),
   ref_addr_size (0),
-  offset (0),
   recursion_depth (0),
   max_recursion_depth (0x100),
   location (DWARF_VALUE_MEMORY),
   len (0),
   data (NULL),
-  initialized (0)
+  initialized (0),
+  per_objfile (per_objfile)
 {
 }
 
@@ -631,7 +632,7 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
 	     index, not an address.  We don't support things like
 	     branching between the address and the TLS op.  */
 	  if (op_ptr >= op_end || *op_ptr != DW_OP_GNU_push_tls_address)
-	    result += this->offset;
+	    result += this->per_objfile->objfile->text_section_offset ();
 	  result_val = value_from_ulongest (address_type, result);
 	  break;
 
@@ -639,7 +640,7 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
 	case DW_OP_GNU_addr_index:
 	  op_ptr = safe_read_uleb128 (op_ptr, op_end, &uoffset);
 	  result = this->get_addr_index (uoffset);
-	  result += this->offset;
+	  result += this->per_objfile->objfile->text_section_offset ();
 	  result_val = value_from_ulongest (address_type, result);
 	  break;
 	case DW_OP_GNU_const_index:
diff --git a/gdb/dwarf2/expr.h b/gdb/dwarf2/expr.h
index 2f3d2ce042d..fd9c2bb6243 100644
--- a/gdb/dwarf2/expr.h
+++ b/gdb/dwarf2/expr.h
@@ -25,6 +25,8 @@
 #include "leb128.h"
 #include "gdbtypes.h"
 
+struct dwarf2_per_objfile;
+
 /* The location of a value.  */
 enum dwarf_value_location
 {
@@ -117,7 +119,7 @@ struct dwarf_stack_value
    its current state and its callbacks.  */
 struct dwarf_expr_context
 {
-  dwarf_expr_context ();
+  dwarf_expr_context (dwarf2_per_objfile *per_objfile);
   virtual ~dwarf_expr_context () = default;
 
   void push_address (CORE_ADDR value, bool in_stack_memory);
@@ -139,10 +141,6 @@ struct dwarf_expr_context
      context and operations depending on DW_FORM_ref_addr are not allowed.  */
   int ref_addr_size;
 
-  /* Offset used to relocate DW_OP_addr, DW_OP_addrx, and
-     DW_OP_GNU_addr_index arguments.  */
-  CORE_ADDR offset;
-
   /* The current depth of dwarf expression recursion, via DW_OP_call*,
      DW_OP_fbreg, DW_OP_push_object_address, etc., and the maximum
      depth we'll tolerate before raising an error.  */
@@ -185,6 +183,9 @@ struct dwarf_expr_context
      two cases need to be handled separately.)  */
   std::vector<dwarf_expr_piece> pieces;
 
+  /* We evaluate the expression in the context of this objfile.  */
+  dwarf2_per_objfile *per_objfile;
+
   /* Return the value of register number REGNUM (a DWARF register number),
      read as an address.  */
   virtual CORE_ADDR read_addr_from_reg (int regnum) = 0;
diff --git a/gdb/dwarf2/frame.c b/gdb/dwarf2/frame.c
index f7276d48ce7..5fe16a62b62 100644
--- a/gdb/dwarf2/frame.c
+++ b/gdb/dwarf2/frame.c
@@ -166,8 +166,8 @@ struct comp_unit
   auto_obstack obstack;
 };
 
-static struct dwarf2_fde *dwarf2_frame_find_fde (CORE_ADDR *pc,
-						 CORE_ADDR *out_offset);
+static struct dwarf2_fde *dwarf2_frame_find_fde
+  (CORE_ADDR *pc, dwarf2_per_objfile **out_per_objfile);
 
 static int dwarf2_frame_adjust_regnum (struct gdbarch *gdbarch, int regnum,
 				       int eh_frame_p);
@@ -237,7 +237,11 @@ register %s (#%d) at %s"),
 
 class dwarf_expr_executor : public dwarf_expr_context
 {
- public:
+public:
+
+  dwarf_expr_executor (dwarf2_per_objfile *per_objfile)
+    : dwarf_expr_context (per_objfile)
+  {}
 
   struct frame_info *this_frame;
 
@@ -311,19 +315,18 @@ class dwarf_expr_executor : public dwarf_expr_context
 
 static CORE_ADDR
 execute_stack_op (const gdb_byte *exp, ULONGEST len, int addr_size,
-		  CORE_ADDR offset, struct frame_info *this_frame,
-		  CORE_ADDR initial, int initial_in_stack_memory)
+		  struct frame_info *this_frame, CORE_ADDR initial,
+		  int initial_in_stack_memory, dwarf2_per_objfile *per_objfile)
 {
   CORE_ADDR result;
 
-  dwarf_expr_executor ctx;
+  dwarf_expr_executor ctx (per_objfile);
   scoped_value_mark free_values;
 
   ctx.this_frame = this_frame;
   ctx.gdbarch = get_frame_arch (this_frame);
   ctx.addr_size = addr_size;
   ctx.ref_addr_size = -1;
-  ctx.offset = offset;
 
   ctx.push_address (initial, initial_in_stack_memory);
   ctx.eval (exp, len);
@@ -883,14 +886,16 @@ dwarf2_fetch_cfa_info (struct gdbarch *gdbarch, CORE_ADDR pc,
 		       const gdb_byte **cfa_end_out)
 {
   struct dwarf2_fde *fde;
-  CORE_ADDR text_offset;
+  dwarf2_per_objfile *per_objfile;
   CORE_ADDR pc1 = pc;
 
   /* Find the correct FDE.  */
-  fde = dwarf2_frame_find_fde (&pc1, &text_offset);
+  fde = dwarf2_frame_find_fde (&pc1, &per_objfile);
   if (fde == NULL)
     error (_("Could not compute CFA; needed to translate this expression"));
 
+  gdb_assert (per_objfile != nullptr);
+
   dwarf2_frame_state fs (pc1, fde->cie);
 
   /* Check for "quirks" - known bugs in producers.  */
@@ -898,14 +903,15 @@ dwarf2_fetch_cfa_info (struct gdbarch *gdbarch, CORE_ADDR pc,
 
   /* First decode all the insns in the CIE.  */
   execute_cfa_program (fde, fde->cie->initial_instructions,
-		       fde->cie->end, gdbarch, pc, &fs, text_offset);
+		       fde->cie->end, gdbarch, pc, &fs,
+		       per_objfile->objfile->text_section_offset ());
 
   /* Save the initialized register set.  */
   fs.initial = fs.regs;
 
   /* Then decode the insns in the FDE up to our target PC.  */
   execute_cfa_program (fde, fde->instructions, fde->end, gdbarch, pc, &fs,
-		       text_offset);
+		       per_objfile->objfile->text_section_offset ());
 
   /* Calculate the CFA.  */
   switch (fs.regs.cfa_how)
@@ -923,7 +929,7 @@ dwarf2_fetch_cfa_info (struct gdbarch *gdbarch, CORE_ADDR pc,
       }
 
     case CFA_EXP:
-      *text_offset_out = text_offset;
+      *text_offset_out = per_objfile->objfile->text_section_offset ();
       *cfa_start_out = fs.regs.cfa_exp;
       *cfa_end_out = fs.regs.cfa_exp + fs.regs.cfa_exp_len;
       return 0;
@@ -956,8 +962,8 @@ struct dwarf2_frame_cache
   /* Target address size in bytes.  */
   int addr_size;
 
-  /* The .text offset.  */
-  CORE_ADDR text_offset;
+  /* The dwarf2_per_objfile from which this frame description came.  */
+  dwarf2_per_objfile *per_objfile;
 
   /* If not NULL then this frame is the bottom frame of a TAILCALL_FRAME
      sequence.  If NULL then it is a normal case with no TAILCALL_FRAME
@@ -1003,8 +1009,9 @@ dwarf2_frame_cache (struct frame_info *this_frame, void **this_cache)
   CORE_ADDR pc1 = get_frame_address_in_block (this_frame);
 
   /* Find the correct FDE.  */
-  fde = dwarf2_frame_find_fde (&pc1, &cache->text_offset);
+  fde = dwarf2_frame_find_fde (&pc1, &cache->per_objfile);
   gdb_assert (fde != NULL);
+  gdb_assert (cache->per_objfile != nullptr);
 
   /* Allocate and initialize the frame state.  */
   struct dwarf2_frame_state fs (pc1, fde->cie);
@@ -1018,7 +1025,7 @@ dwarf2_frame_cache (struct frame_info *this_frame, void **this_cache)
   execute_cfa_program (fde, fde->cie->initial_instructions,
 		       fde->cie->end, gdbarch,
 		       get_frame_address_in_block (this_frame), &fs,
-		       cache->text_offset);
+		       cache->per_objfile->objfile->text_section_offset ());
 
   /* Save the initialized register set.  */
   fs.initial = fs.regs;
@@ -1034,8 +1041,9 @@ dwarf2_frame_cache (struct frame_info *this_frame, void **this_cache)
       && entry_pc < fde->initial_location + fde->address_range)
     {
       /* Decode the insns in the FDE up to the entry PC.  */
-      instr = execute_cfa_program (fde, fde->instructions, fde->end, gdbarch,
-				   entry_pc, &fs, cache->text_offset);
+      instr = execute_cfa_program
+	(fde, fde->instructions, fde->end, gdbarch, entry_pc, &fs,
+	 cache->per_objfile->objfile->text_section_offset ());
 
       if (fs.regs.cfa_how == CFA_REG_OFFSET
 	  && (dwarf_reg_to_regnum (gdbarch, fs.regs.cfa_reg)
@@ -1051,7 +1059,7 @@ dwarf2_frame_cache (struct frame_info *this_frame, void **this_cache)
   /* Then decode the insns in the FDE up to our target PC.  */
   execute_cfa_program (fde, instr, fde->end, gdbarch,
 		       get_frame_address_in_block (this_frame), &fs,
-		       cache->text_offset);
+		       cache->per_objfile->objfile->text_section_offset ());
 
   try
     {
@@ -1069,8 +1077,8 @@ dwarf2_frame_cache (struct frame_info *this_frame, void **this_cache)
 	case CFA_EXP:
 	  cache->cfa =
 	    execute_stack_op (fs.regs.cfa_exp, fs.regs.cfa_exp_len,
-			      cache->addr_size, cache->text_offset,
-			      this_frame, 0, 0);
+			      cache->addr_size, this_frame, 0, 0,
+			      cache->per_objfile);
 	  break;
 
 	default:
@@ -1270,8 +1278,9 @@ dwarf2_frame_prev_register (struct frame_info *this_frame, void **this_cache,
     case DWARF2_FRAME_REG_SAVED_EXP:
       addr = execute_stack_op (cache->reg[regnum].loc.exp.start,
 			       cache->reg[regnum].loc.exp.len,
-			       cache->addr_size, cache->text_offset,
-			       this_frame, cache->cfa, 1);
+			       cache->addr_size,
+			       this_frame, cache->cfa, 1,
+			       cache->per_objfile);
       return frame_unwind_got_memory (this_frame, regnum, addr);
 
     case DWARF2_FRAME_REG_SAVED_VAL_OFFSET:
@@ -1281,8 +1290,9 @@ dwarf2_frame_prev_register (struct frame_info *this_frame, void **this_cache,
     case DWARF2_FRAME_REG_SAVED_VAL_EXP:
       addr = execute_stack_op (cache->reg[regnum].loc.exp.start,
 			       cache->reg[regnum].loc.exp.len,
-			       cache->addr_size, cache->text_offset,
-			       this_frame, cache->cfa, 1);
+			       cache->addr_size,
+			       this_frame, cache->cfa, 1,
+			       cache->per_objfile);
       return frame_unwind_got_constant (this_frame, regnum, addr);
 
     case DWARF2_FRAME_REG_UNSPECIFIED:
@@ -1650,7 +1660,7 @@ set_comp_unit (struct objfile *objfile, struct comp_unit *unit)
    initial location associated with it into *PC.  */
 
 static struct dwarf2_fde *
-dwarf2_frame_find_fde (CORE_ADDR *pc, CORE_ADDR *out_offset)
+dwarf2_frame_find_fde (CORE_ADDR *pc, dwarf2_per_objfile **out_per_objfile)
 {
   for (objfile *objfile : current_program_space->objfiles ())
     {
@@ -1682,8 +1692,9 @@ dwarf2_frame_find_fde (CORE_ADDR *pc, CORE_ADDR *out_offset)
       if (it != fde_table->end ())
         {
           *pc = (*it)->initial_location + offset;
-	  if (out_offset)
-	    *out_offset = offset;
+	  if (out_per_objfile != nullptr)
+	    *out_per_objfile = get_dwarf2_per_objfile (objfile);
+
           return *it;
         }
     }
diff --git a/gdb/dwarf2/loc.c b/gdb/dwarf2/loc.c
index e4a9ee90311..7f979bfa086 100644
--- a/gdb/dwarf2/loc.c
+++ b/gdb/dwarf2/loc.c
@@ -617,7 +617,10 @@ sect_variable_value (struct dwarf_expr_context *ctx, sect_offset sect_off,
 
 class dwarf_evaluate_loc_desc : public dwarf_expr_context
 {
- public:
+public:
+  dwarf_evaluate_loc_desc (dwarf2_per_objfile *per_objfile)
+    : dwarf_expr_context (per_objfile)
+  {}
 
   struct frame_info *frame;
   struct dwarf2_per_cu_data *per_cu;
@@ -733,8 +736,6 @@ class dwarf_evaluate_loc_desc : public dwarf_expr_context
     this->gdbarch = per_cu->objfile ()->arch ();
     scoped_restore save_addr_size = make_scoped_restore (&this->addr_size);
     this->addr_size = per_cu->addr_size ();
-    scoped_restore save_offset = make_scoped_restore (&this->offset);
-    this->offset = per_cu->text_offset ();
 
     this->eval (data_src, size);
   }
@@ -2191,7 +2192,8 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame,
   if (size == 0)
     return allocate_optimized_out_value (subobj_type);
 
-  dwarf_evaluate_loc_desc ctx;
+  dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile);
+  dwarf_evaluate_loc_desc ctx (per_objfile);
   ctx.frame = frame;
   ctx.per_cu = per_cu;
   ctx.obj_address = 0;
@@ -2201,7 +2203,6 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame,
   ctx.gdbarch = objfile->arch ();
   ctx.addr_size = per_cu->addr_size ();
   ctx.ref_addr_size = per_cu->ref_addr_size ();
-  ctx.offset = per_cu->text_offset ();
 
   try
     {
@@ -2398,6 +2399,10 @@ dwarf2_evaluate_loc_desc (struct type *type, struct frame_info *frame,
 
 struct evaluate_for_locexpr_baton : public dwarf_evaluate_loc_desc
 {
+  evaluate_for_locexpr_baton (dwarf2_per_objfile *per_objfile)
+    : dwarf_evaluate_loc_desc (per_objfile)
+  {}
+
   /* The data that was passed in.  */
   gdb::array_view<const gdb_byte> data_view;
 
@@ -2443,12 +2448,11 @@ dwarf2_locexpr_baton_eval (const struct dwarf2_locexpr_baton *dlbaton,
 			   CORE_ADDR *valp,
 			   bool push_initial_value)
 {
-  struct objfile *objfile;
-
   if (dlbaton == NULL || dlbaton->size == 0)
     return 0;
 
-  evaluate_for_locexpr_baton ctx;
+  dwarf2_per_objfile *per_objfile = dlbaton->per_objfile;
+  evaluate_for_locexpr_baton ctx (per_objfile);
 
   ctx.frame = frame;
   ctx.per_cu = dlbaton->per_cu;
@@ -2460,12 +2464,9 @@ dwarf2_locexpr_baton_eval (const struct dwarf2_locexpr_baton *dlbaton,
       ctx.data_view = addr_stack->valaddr;
     }
 
-  objfile = dlbaton->per_objfile->objfile;
-
-  ctx.gdbarch = objfile->arch ();
+  ctx.gdbarch = per_objfile->objfile->arch ();
   ctx.addr_size = dlbaton->per_cu->addr_size ();
   ctx.ref_addr_size = dlbaton->per_cu->ref_addr_size ();
-  ctx.offset = dlbaton->per_cu->text_offset ();
 
   if (push_initial_value)
     ctx.push_address (ctx.obj_address, false);
@@ -2675,7 +2676,10 @@ dwarf2_compile_property_to_c (string_file *stream,
 
 class symbol_needs_eval_context : public dwarf_expr_context
 {
- public:
+public:
+  symbol_needs_eval_context (dwarf2_per_objfile *per_objfile)
+    : dwarf_expr_context (per_objfile)
+  {}
 
   enum symbol_needs_kind needs;
   struct dwarf2_per_cu_data *per_cu;
@@ -2792,14 +2796,13 @@ dwarf2_loc_desc_get_symbol_read_needs (const gdb_byte *data, size_t size,
 
   scoped_value_mark free_values;
 
-  symbol_needs_eval_context ctx;
+  symbol_needs_eval_context ctx (get_dwarf2_per_objfile (objfile));
 
   ctx.needs = SYMBOL_NEEDS_NONE;
   ctx.per_cu = per_cu;
   ctx.gdbarch = objfile->arch ();
   ctx.addr_size = per_cu->addr_size ();
   ctx.ref_addr_size = per_cu->ref_addr_size ();
-  ctx.offset = per_cu->text_offset ();
 
   ctx.eval (data, size);
 
-- 
2.26.2


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

* [PATCH v2 24/42] Remove dwarf2_per_cu_data::text_offset
  2020-05-12 21:08 [PATCH v2 00/42] Share DWARF partial symtabs between objfiles Simon Marchi
                   ` (22 preceding siblings ...)
  2020-05-12 21:12 ` [PATCH v2 23/42] Add dwarf2_per_objfile to dwarf_expr_context and dwarf2_frame_cache Simon Marchi
@ 2020-05-12 21:12 ` Simon Marchi
  2020-05-12 21:12 ` [PATCH v2 25/42] Add dwarf2_per_objfile parameter to dwarf2_read_addr_index Simon Marchi
                   ` (21 subsequent siblings)
  45 siblings, 0 replies; 92+ messages in thread
From: Simon Marchi @ 2020-05-12 21:12 UTC (permalink / raw)
  To: gdb-patches; +Cc: Simon Marchi

This method simply returns the text offset of the objfile associated to
the dwarf2_per_cu_data object.  Since dwarf2_per_cu_data objects are
going to become objfile-independent, we can't keep this method.  This
patch removes it.

Existing callers need to figure out the in the context of which objfile
this is being used, and call text_offset on it.  Typically, this comes
from a symbol baton, where we store the corresponding
dwarf2_per_objfile.

gdb/ChangeLog:

	* dwarf2/read.h (struct dwarf2_per_cu_data) <text_offset>:
	Remove.
	* dwarf2/read.c (dwarf2_per_cu_data::text_offset): Remove.
	* dwarf2/loc.c (dwarf2_find_location_expression): Update.
	(dwarf2_compile_property_to_c): Update.
	(dwarf2_compile_expr_to_ax): Add dwarf2_per_objfile parameter,
	use text offset from objfile.
	(locexpr_tracepoint_var_ref): Update.
	(locexpr_generate_c_location): Update.
	(loclist_describe_location): Update.
	(loclist_tracepoint_var_ref): Update.
	* dwarf2/compile.h (compile_dwarf_bounds_to_c): Add
	dwarf2_per_objfile parameter.
	* dwarf2/loc2c.c (do_compile_dwarf_expr_to_c): Likewise,
	use text offset from objfile.
	(compile_dwarf_expr_to_c): Add dwarf2_per_objfile parameter.
---
 gdb/compile/compile-loc2c.c | 20 ++++++++++++--------
 gdb/compile/compile.h       | 13 +++++++++++--
 gdb/dwarf2/loc.c            | 34 +++++++++++++++++++++-------------
 gdb/dwarf2/read.c           | 10 ----------
 gdb/dwarf2/read.h           |  6 ------
 5 files changed, 44 insertions(+), 39 deletions(-)

diff --git a/gdb/compile/compile-loc2c.c b/gdb/compile/compile-loc2c.c
index 06a044de048..2fd1810759c 100644
--- a/gdb/compile/compile-loc2c.c
+++ b/gdb/compile/compile-loc2c.c
@@ -583,7 +583,8 @@ do_compile_dwarf_expr_to_c (int indent, string_file *stream,
 			    unsigned int addr_size,
 			    const gdb_byte *op_ptr, const gdb_byte *op_end,
 			    CORE_ADDR *initial,
-			    struct dwarf2_per_cu_data *per_cu)
+			    dwarf2_per_cu_data *per_cu,
+			    dwarf2_per_objfile *per_objfile)
 {
   /* We keep a counter so that labels and other objects we create have
      unique names.  */
@@ -719,7 +720,7 @@ do_compile_dwarf_expr_to_c (int indent, string_file *stream,
 	     index, not an address.  We don't support things like
 	     branching between the address and the TLS op.  */
 	  if (op_ptr >= op_end || *op_ptr != DW_OP_GNU_push_tls_address)
-	    uoffset += per_cu->text_offset ();
+	    uoffset += per_objfile->objfile->text_section_offset ();
 	  push (indent, stream, uoffset);
 	  break;
 
@@ -896,7 +897,7 @@ do_compile_dwarf_expr_to_c (int indent, string_file *stream,
 					sym, pc,
 					arch, registers_used, addr_size,
 					datastart, datastart + datalen,
-					NULL, per_cu);
+					NULL, per_cu, per_objfile);
 
 	    pushf (indent, stream, "%s + %s", fb_name, hex_string (offset));
 	  }
@@ -1077,7 +1078,7 @@ do_compile_dwarf_expr_to_c (int indent, string_file *stream,
 					    sym, pc, arch, registers_used,
 					    addr_size,
 					    cfa_start, cfa_end,
-					    &text_offset, per_cu);
+					    &text_offset, per_cu, per_objfile);
 		pushf (indent, stream, "%s", cfa_name);
 	      }
 	  }
@@ -1123,11 +1124,12 @@ compile_dwarf_expr_to_c (string_file *stream, const char *result_name,
 			 struct gdbarch *arch, unsigned char *registers_used,
 			 unsigned int addr_size,
 			 const gdb_byte *op_ptr, const gdb_byte *op_end,
-			 struct dwarf2_per_cu_data *per_cu)
+			 dwarf2_per_cu_data *per_cu,
+			 dwarf2_per_objfile *per_objfile)
 {
   do_compile_dwarf_expr_to_c (2, stream, GCC_UINTPTR, result_name, sym, pc,
 			      arch, registers_used, addr_size, op_ptr, op_end,
-			      NULL, per_cu);
+			      NULL, per_cu, per_objfile);
 }
 
 /* See compile.h.  */
@@ -1140,9 +1142,11 @@ compile_dwarf_bounds_to_c (string_file *stream,
 			   struct gdbarch *arch, unsigned char *registers_used,
 			   unsigned int addr_size,
 			   const gdb_byte *op_ptr, const gdb_byte *op_end,
-			   struct dwarf2_per_cu_data *per_cu)
+			   dwarf2_per_cu_data *per_cu,
+			   dwarf2_per_objfile *per_objfile)
 {
   do_compile_dwarf_expr_to_c (2, stream, "unsigned long ", result_name,
 			      sym, pc, arch, registers_used,
-			      addr_size, op_ptr, op_end, NULL, per_cu);
+			      addr_size, op_ptr, op_end, NULL, per_cu,
+			      per_objfile);
 }
diff --git a/gdb/compile/compile.h b/gdb/compile/compile.h
index 871031c356c..73f714ab230 100644
--- a/gdb/compile/compile.h
+++ b/gdb/compile/compile.h
@@ -21,6 +21,7 @@
 struct ui_file;
 struct gdbarch;
 struct dwarf2_per_cu_data;
+struct dwarf2_per_objfile;
 struct symbol;
 struct dynamic_prop;
 
@@ -53,6 +54,9 @@ extern void eval_compile_command (struct command_line *cmd,
    OPT_PTR and OP_END are the bounds of the DWARF expression.
 
    PER_CU is the per-CU object used for looking up various other
+   things.
+
+   PER_OBJFILE is the per-objfile object also used for looking up various other
    things.  */
 
 extern void compile_dwarf_expr_to_c (string_file *stream,
@@ -64,7 +68,8 @@ extern void compile_dwarf_expr_to_c (string_file *stream,
 				     unsigned int addr_size,
 				     const gdb_byte *op_ptr,
 				     const gdb_byte *op_end,
-				     struct dwarf2_per_cu_data *per_cu);
+				     dwarf2_per_cu_data *per_cu,
+				     dwarf2_per_objfile *per_objfile);
 
 /* Compile a DWARF bounds expression to C, suitable for use by the
    compiler.
@@ -88,6 +93,9 @@ extern void compile_dwarf_expr_to_c (string_file *stream,
    OPT_PTR and OP_END are the bounds of the DWARF expression.
 
    PER_CU is the per-CU object used for looking up various other
+   things.
+
+   PER_OBJFILE is the per-objfile object also used for looking up various other
    things.  */
 
 extern void compile_dwarf_bounds_to_c (string_file *stream,
@@ -99,7 +107,8 @@ extern void compile_dwarf_bounds_to_c (string_file *stream,
 				       unsigned int addr_size,
 				       const gdb_byte *op_ptr,
 				       const gdb_byte *op_end,
-				       struct dwarf2_per_cu_data *per_cu);
+				       dwarf2_per_cu_data *per_cu,
+				       dwarf2_per_objfile *per_objfile);
 
 extern void compile_print_value (struct value *val, void *data_voidp);
 
diff --git a/gdb/dwarf2/loc.c b/gdb/dwarf2/loc.c
index 7f979bfa086..f1c400821f9 100644
--- a/gdb/dwarf2/loc.c
+++ b/gdb/dwarf2/loc.c
@@ -324,7 +324,7 @@ dwarf2_find_location_expression (struct dwarf2_loclist_baton *baton,
   unsigned int addr_size = baton->per_cu->addr_size ();
   int signed_addr_p = bfd_get_sign_extend_vma (objfile->obfd);
   /* Adjust base_address for relocatable objects.  */
-  CORE_ADDR base_offset = baton->per_cu->text_offset ();
+  CORE_ADDR base_offset = baton->per_objfile->objfile->text_section_offset ();
   CORE_ADDR base_address = baton->base_address + base_offset;
   const gdb_byte *loc_ptr, *buf_end;
 
@@ -2649,13 +2649,15 @@ dwarf2_compile_property_to_c (string_file *stream,
     = (struct dwarf2_property_baton *) prop->data.baton;
   const gdb_byte *data;
   size_t size;
-  struct dwarf2_per_cu_data *per_cu;
+  dwarf2_per_cu_data *per_cu;
+  dwarf2_per_objfile *per_objfile;
 
   if (prop->kind == PROP_LOCEXPR)
     {
       data = baton->locexpr.data;
       size = baton->locexpr.size;
       per_cu = baton->locexpr.per_cu;
+      per_objfile = baton->locexpr.per_objfile;
     }
   else
     {
@@ -2663,12 +2665,13 @@ dwarf2_compile_property_to_c (string_file *stream,
 
       data = dwarf2_find_location_expression (&baton->loclist, &size, pc);
       per_cu = baton->loclist.per_cu;
+      per_objfile = baton->loclist.per_objfile;
     }
 
   compile_dwarf_bounds_to_c (stream, result_name, prop, sym, pc,
 			     gdbarch, registers_used,
 			     per_cu->addr_size (),
-			     data, data + size, per_cu);
+			     data, data + size, per_cu, per_objfile);
 }
 
 \f
@@ -2956,7 +2959,8 @@ static void
 dwarf2_compile_expr_to_ax (struct agent_expr *expr, struct axs_value *loc,
 			   unsigned int addr_size, const gdb_byte *op_ptr,
 			   const gdb_byte *op_end,
-			   struct dwarf2_per_cu_data *per_cu)
+			   dwarf2_per_cu_data *per_cu,
+			   dwarf2_per_objfile *per_objfile)
 {
   gdbarch *arch = expr->gdbarch;
   std::vector<int> dw_labels, patches;
@@ -3043,7 +3047,7 @@ dwarf2_compile_expr_to_ax (struct agent_expr *expr, struct axs_value *loc,
 	     index, not an address.  We don't support things like
 	     branching between the address and the TLS op.  */
 	  if (op_ptr >= op_end || *op_ptr != DW_OP_GNU_push_tls_address)
-	    uoffset += per_cu->text_offset ();
+	    uoffset += per_objfile->objfile->text_section_offset ();
 	  ax_const_l (expr, uoffset);
 	  break;
 
@@ -3234,7 +3238,8 @@ dwarf2_compile_expr_to_ax (struct agent_expr *expr, struct axs_value *loc,
 
 	    op_ptr = safe_read_sleb128 (op_ptr, op_end, &offset);
 	    dwarf2_compile_expr_to_ax (expr, loc, addr_size, datastart,
-				       datastart + datalen, per_cu);
+				       datastart + datalen, per_cu,
+				       per_objfile);
 	    if (loc->kind == axs_lvalue_register)
 	      require_rvalue (expr, loc);
 
@@ -3460,7 +3465,7 @@ dwarf2_compile_expr_to_ax (struct agent_expr *expr, struct axs_value *loc,
 		/* Another expression.  */
 		ax_const_l (expr, text_offset);
 		dwarf2_compile_expr_to_ax (expr, loc, addr_size, cfa_start,
-					   cfa_end, per_cu);
+					   cfa_end, per_cu, per_objfile);
 	      }
 
 	    loc->kind = axs_lvalue_memory;
@@ -3585,7 +3590,8 @@ dwarf2_compile_expr_to_ax (struct agent_expr *expr, struct axs_value *loc,
 	    gdb_assert (block.per_cu == per_cu);
 
 	    dwarf2_compile_expr_to_ax (expr, loc, addr_size, block.data,
-				       block.data + block.size, per_cu);
+				       block.data + block.size, per_cu,
+				       per_objfile);
 	  }
 	  break;
 
@@ -4383,7 +4389,8 @@ locexpr_tracepoint_var_ref (struct symbol *symbol, struct agent_expr *ax,
     value->optimized_out = 1;
   else
     dwarf2_compile_expr_to_ax (ax, value, addr_size, dlbaton->data,
-			       dlbaton->data + dlbaton->size, dlbaton->per_cu);
+			       dlbaton->data + dlbaton->size, dlbaton->per_cu,
+			       dlbaton->per_objfile);
 }
 
 /* symbol_computed_ops 'generate_c_location' method.  */
@@ -4404,7 +4411,7 @@ locexpr_generate_c_location (struct symbol *sym, string_file *stream,
   compile_dwarf_expr_to_c (stream, result_name,
 			   sym, pc, gdbarch, registers_used, addr_size,
 			   dlbaton->data, dlbaton->data + dlbaton->size,
-			   dlbaton->per_cu);
+			   dlbaton->per_cu, dlbaton->per_objfile);
 }
 
 /* The set of location functions used with the DWARF-2 expression
@@ -4503,7 +4510,7 @@ loclist_describe_location (struct symbol *symbol, CORE_ADDR addr,
   int offset_size = dlbaton->per_cu->offset_size ();
   int signed_addr_p = bfd_get_sign_extend_vma (objfile->obfd);
   /* Adjust base_address for relocatable objects.  */
-  CORE_ADDR base_offset = dlbaton->per_cu->text_offset ();
+  CORE_ADDR base_offset = objfile->text_section_offset ();
   CORE_ADDR base_address = dlbaton->base_address + base_offset;
   int done = 0;
 
@@ -4609,7 +4616,7 @@ loclist_tracepoint_var_ref (struct symbol *symbol, struct agent_expr *ax,
     value->optimized_out = 1;
   else
     dwarf2_compile_expr_to_ax (ax, value, addr_size, data, data + size,
-			       dlbaton->per_cu);
+			       dlbaton->per_cu, dlbaton->per_objfile);
 }
 
 /* symbol_computed_ops 'generate_c_location' method.  */
@@ -4633,7 +4640,8 @@ loclist_generate_c_location (struct symbol *sym, string_file *stream,
   compile_dwarf_expr_to_c (stream, result_name,
 			   sym, pc, gdbarch, registers_used, addr_size,
 			   data, data + size,
-			   dlbaton->per_cu);
+			   dlbaton->per_cu,
+			   dlbaton->per_objfile);
 }
 
 /* The set of location functions used with the DWARF-2 expression
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index c9bced5d967..79e8889d33f 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -23353,16 +23353,6 @@ dwarf2_per_cu_data::ref_addr_size () const
 
 /* See read.h.  */
 
-CORE_ADDR
-dwarf2_per_cu_data::text_offset () const
-{
-  struct objfile *objfile = dwarf2_per_objfile->objfile;
-
-  return objfile->text_section_offset ();
-}
-
-/* See read.h.  */
-
 struct type *
 dwarf2_cu::addr_type () const
 {
diff --git a/gdb/dwarf2/read.h b/gdb/dwarf2/read.h
index 77c1f246db7..15951f5221d 100644
--- a/gdb/dwarf2/read.h
+++ b/gdb/dwarf2/read.h
@@ -508,12 +508,6 @@ struct dwarf2_per_cu_data
      header for this CU.  */
   int ref_addr_size () const;
 
-  /* Return the text offset of the CU.  The returned offset comes from
-     this CU's objfile.  If this objfile came from a separate
-     debuginfo file, then the offset may be different from the
-     corresponding offset in the parent objfile.  */
-  CORE_ADDR text_offset () const;
-
   /* Return DWARF version number of this CU.  */
   short version () const
   {
-- 
2.26.2


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

* [PATCH v2 25/42] Add dwarf2_per_objfile parameter to dwarf2_read_addr_index
  2020-05-12 21:08 [PATCH v2 00/42] Share DWARF partial symtabs between objfiles Simon Marchi
                   ` (23 preceding siblings ...)
  2020-05-12 21:12 ` [PATCH v2 24/42] Remove dwarf2_per_cu_data::text_offset Simon Marchi
@ 2020-05-12 21:12 ` Simon Marchi
  2020-05-12 21:12 ` [PATCH v2 26/42] Add dwarf2_per_objfile parameter to allocate_piece_closure Simon Marchi
                   ` (20 subsequent siblings)
  45 siblings, 0 replies; 92+ messages in thread
From: Simon Marchi @ 2020-05-12 21:12 UTC (permalink / raw)
  To: gdb-patches; +Cc: Simon Marchi

Pass it all the way from the symbol batons.  This allows removing a
dwarf2_per_cu_data::dwarf2_per_objfile reference.

gdb/ChangeLog:

	* dwarf2/read.h (dwarf2_read_addr_index): Add dwarf2_per_objfile
	parameter.
	* dwarf2/read.c (dwarf2_read_addr_index): Likewise.
	* dwarf2/loc.c (decode_debug_loclists_addresses): Add
	dwarf2_per_objfile parameter.
	(decode_debug_loc_dwo_addresses): Likewise.
	(dwarf2_find_location_expression): Update.
	(class dwarf_evaluate_loc_desc) <get_addr_index>: Update.
	(locexpr_describe_location_piece): Add dwarf2_per_objfile
	parameter.
	(disassemble_dwarf_expression): Add dwarf2_per_objfile
	parameter.
	(locexpr_describe_location_1): Likewise.
	(locexpr_describe_location): Update.
---
 gdb/dwarf2/loc.c  | 60 +++++++++++++++++++++++++++--------------------
 gdb/dwarf2/read.c |  5 ++--
 gdb/dwarf2/read.h |  1 +
 3 files changed, 38 insertions(+), 28 deletions(-)

diff --git a/gdb/dwarf2/loc.c b/gdb/dwarf2/loc.c
index f1c400821f9..4c21a51fb5b 100644
--- a/gdb/dwarf2/loc.c
+++ b/gdb/dwarf2/loc.c
@@ -163,7 +163,8 @@ decode_debug_loc_addresses (const gdb_byte *loc_ptr, const gdb_byte *buf_end,
    The result indicates the kind of entry found.  */
 
 static enum debug_loc_kind
-decode_debug_loclists_addresses (struct dwarf2_per_cu_data *per_cu,
+decode_debug_loclists_addresses (dwarf2_per_cu_data *per_cu,
+				 dwarf2_per_objfile *per_objfile,
 				 const gdb_byte *loc_ptr,
 				 const gdb_byte *buf_end,
 				 const gdb_byte **new_ptr,
@@ -184,14 +185,14 @@ decode_debug_loclists_addresses (struct dwarf2_per_cu_data *per_cu,
       loc_ptr = gdb_read_uleb128 (loc_ptr, buf_end, &u64);
       if (loc_ptr == NULL)
 	 return DEBUG_LOC_BUFFER_OVERFLOW;
-      *high = dwarf2_read_addr_index (per_cu, u64);
+      *high = dwarf2_read_addr_index (per_cu, per_objfile, u64);
       *new_ptr = loc_ptr;
       return DEBUG_LOC_BASE_ADDRESS;
     case DW_LLE_startx_length:
       loc_ptr = gdb_read_uleb128 (loc_ptr, buf_end, &u64);
       if (loc_ptr == NULL)
 	 return DEBUG_LOC_BUFFER_OVERFLOW;
-      *low = dwarf2_read_addr_index (per_cu, u64);
+      *low = dwarf2_read_addr_index (per_cu, per_objfile, u64);
       *high = *low;
       loc_ptr = gdb_read_uleb128 (loc_ptr, buf_end, &u64);
       if (loc_ptr == NULL)
@@ -253,7 +254,8 @@ decode_debug_loclists_addresses (struct dwarf2_per_cu_data *per_cu,
    The result indicates the kind of entry found.  */
 
 static enum debug_loc_kind
-decode_debug_loc_dwo_addresses (struct dwarf2_per_cu_data *per_cu,
+decode_debug_loc_dwo_addresses (dwarf2_per_cu_data *per_cu,
+				dwarf2_per_objfile *per_objfile,
 				const gdb_byte *loc_ptr,
 				const gdb_byte *buf_end,
 				const gdb_byte **new_ptr,
@@ -275,25 +277,25 @@ decode_debug_loc_dwo_addresses (struct dwarf2_per_cu_data *per_cu,
       loc_ptr = gdb_read_uleb128 (loc_ptr, buf_end, &high_index);
       if (loc_ptr == NULL)
 	return DEBUG_LOC_BUFFER_OVERFLOW;
-      *high = dwarf2_read_addr_index (per_cu, high_index);
+      *high = dwarf2_read_addr_index (per_cu, per_objfile, high_index);
       *new_ptr = loc_ptr;
       return DEBUG_LOC_BASE_ADDRESS;
     case DW_LLE_GNU_start_end_entry:
       loc_ptr = gdb_read_uleb128 (loc_ptr, buf_end, &low_index);
       if (loc_ptr == NULL)
 	return DEBUG_LOC_BUFFER_OVERFLOW;
-      *low = dwarf2_read_addr_index (per_cu, low_index);
+      *low = dwarf2_read_addr_index (per_cu, per_objfile, low_index);
       loc_ptr = gdb_read_uleb128 (loc_ptr, buf_end, &high_index);
       if (loc_ptr == NULL)
 	return DEBUG_LOC_BUFFER_OVERFLOW;
-      *high = dwarf2_read_addr_index (per_cu, high_index);
+      *high = dwarf2_read_addr_index (per_cu, per_objfile, high_index);
       *new_ptr = loc_ptr;
       return DEBUG_LOC_START_END;
     case DW_LLE_GNU_start_length_entry:
       loc_ptr = gdb_read_uleb128 (loc_ptr, buf_end, &low_index);
       if (loc_ptr == NULL)
 	return DEBUG_LOC_BUFFER_OVERFLOW;
-      *low = dwarf2_read_addr_index (per_cu, low_index);
+      *low = dwarf2_read_addr_index (per_cu, per_objfile, low_index);
       if (loc_ptr + 4 > buf_end)
 	return DEBUG_LOC_BUFFER_OVERFLOW;
       *high = *low;
@@ -340,6 +342,7 @@ dwarf2_find_location_expression (struct dwarf2_loclist_baton *baton,
 
       if (baton->per_cu->version () < 5 && baton->from_dwo)
 	kind = decode_debug_loc_dwo_addresses (baton->per_cu,
+					       baton->per_objfile,
 					       loc_ptr, buf_end, &new_ptr,
 					       &low, &high, byte_order);
       else if (baton->per_cu->version () < 5)
@@ -349,6 +352,7 @@ dwarf2_find_location_expression (struct dwarf2_loclist_baton *baton,
 					   signed_addr_p);
       else
 	kind = decode_debug_loclists_addresses (baton->per_cu,
+						baton->per_objfile,
 						loc_ptr, buf_end, &new_ptr,
 						&low, &high, byte_order,
 						addr_size, signed_addr_p);
@@ -682,7 +686,7 @@ class dwarf_evaluate_loc_desc : public dwarf_expr_context
 
   CORE_ADDR get_addr_index (unsigned int index) override
   {
-    return dwarf2_read_addr_index (per_cu, index);
+    return dwarf2_read_addr_index (per_cu, per_objfile, index);
   }
 
   /* Callback function for get_object_address. Return the address of the VLA
@@ -3698,11 +3702,12 @@ locexpr_regname (struct gdbarch *gdbarch, int dwarf_regnum)
 
 static const gdb_byte *
 locexpr_describe_location_piece (struct symbol *symbol, struct ui_file *stream,
-				 CORE_ADDR addr, struct objfile *objfile,
-				 struct dwarf2_per_cu_data *per_cu,
+				 CORE_ADDR addr, dwarf2_per_cu_data *per_cu,
+				 dwarf2_per_objfile *per_objfile,
 				 const gdb_byte *data, const gdb_byte *end,
 				 unsigned int addr_size)
 {
+  objfile *objfile = per_objfile->objfile;
   struct gdbarch *gdbarch = objfile->arch ();
   size_t leb128_size;
 
@@ -3841,7 +3846,7 @@ locexpr_describe_location_piece (struct symbol *symbol, struct ui_file *stream,
       uint64_t offset;
 
       data = safe_read_uleb128 (data + 1, end, &offset);
-      offset = dwarf2_read_addr_index (per_cu, offset);
+      offset = dwarf2_read_addr_index (per_cu, per_objfile, offset);
       fprintf_filtered (stream, 
 			_("a thread-local variable at offset 0x%s "
 			  "in the thread-local storage for `%s'"),
@@ -3874,7 +3879,8 @@ disassemble_dwarf_expression (struct ui_file *stream,
 			      int offset_size, const gdb_byte *start,
 			      const gdb_byte *data, const gdb_byte *end,
 			      int indent, int all,
-			      struct dwarf2_per_cu_data *per_cu)
+			      dwarf2_per_cu_data *per_cu,
+			      dwarf2_per_objfile *per_objfile)
 {
   while (data < end
 	 && (all
@@ -4212,7 +4218,7 @@ disassemble_dwarf_expression (struct ui_file *stream,
 	  fputc_filtered ('\n', stream);
 	  disassemble_dwarf_expression (stream, arch, addr_size, offset_size,
 					start, data, data + ul, indent + 2,
-					all, per_cu);
+					all, per_cu, per_objfile);
 	  data += ul;
 	  continue;
 
@@ -4225,12 +4231,12 @@ disassemble_dwarf_expression (struct ui_file *stream,
 	case DW_OP_addrx:
 	case DW_OP_GNU_addr_index:
 	  data = safe_read_uleb128 (data, end, &ul);
-	  ul = dwarf2_read_addr_index (per_cu, ul);
+	  ul = dwarf2_read_addr_index (per_cu, per_objfile, ul);
 	  fprintf_filtered (stream, " 0x%s", phex_nz (ul, addr_size));
 	  break;
 	case DW_OP_GNU_const_index:
 	  data = safe_read_uleb128 (data, end, &ul);
-	  ul = dwarf2_read_addr_index (per_cu, ul);
+	  ul = dwarf2_read_addr_index (per_cu, per_objfile, ul);
 	  fprintf_filtered (stream, " %s", pulongest (ul));
 	  break;
 
@@ -4267,11 +4273,13 @@ static void
 locexpr_describe_location_1 (struct symbol *symbol, CORE_ADDR addr,
 			     struct ui_file *stream,
 			     const gdb_byte *data, size_t size,
-			     struct objfile *objfile, unsigned int addr_size,
-			     int offset_size, struct dwarf2_per_cu_data *per_cu)
+			     unsigned int addr_size,
+			     int offset_size, dwarf2_per_cu_data *per_cu,
+			     dwarf2_per_objfile *per_objfile)
 {
   const gdb_byte *end = data + size;
   int first_piece = 1, bad = 0;
+  objfile *objfile = per_objfile->objfile;
 
   while (data < end)
     {
@@ -4286,7 +4294,7 @@ locexpr_describe_location_1 (struct symbol *symbol, CORE_ADDR addr,
       if (!dwarf_always_disassemble)
 	{
 	  data = locexpr_describe_location_piece (symbol, stream,
-						  addr, objfile, per_cu,
+						  addr, per_cu, per_objfile,
 						  data, end, addr_size);
 	  /* If we printed anything, or if we have an empty piece,
 	     then don't disassemble.  */
@@ -4303,7 +4311,7 @@ locexpr_describe_location_1 (struct symbol *symbol, CORE_ADDR addr,
 					       addr_size, offset_size, data,
 					       data, end, 0,
 					       dwarf_always_disassemble,
-					       per_cu);
+					       per_cu, per_objfile);
 	}
 
       if (data < end)
@@ -4363,15 +4371,13 @@ locexpr_describe_location (struct symbol *symbol, CORE_ADDR addr,
 {
   struct dwarf2_locexpr_baton *dlbaton
     = (struct dwarf2_locexpr_baton *) SYMBOL_LOCATION_BATON (symbol);
-  dwarf2_per_objfile *per_objfile = dlbaton->per_objfile;
-  struct objfile *objfile = per_objfile->objfile;
   unsigned int addr_size = dlbaton->per_cu->addr_size ();
   int offset_size = dlbaton->per_cu->offset_size ();
 
   locexpr_describe_location_1 (symbol, addr, stream,
 			       dlbaton->data, dlbaton->size,
-			       objfile, addr_size, offset_size,
-			       dlbaton->per_cu);
+			       addr_size, offset_size,
+			       dlbaton->per_cu, dlbaton->per_objfile);
 }
 
 /* Describe the location of SYMBOL as an agent value in VALUE, generating
@@ -4529,6 +4535,7 @@ loclist_describe_location (struct symbol *symbol, CORE_ADDR addr,
 
       if (dlbaton->per_cu->version () < 5 && dlbaton->from_dwo)
 	kind = decode_debug_loc_dwo_addresses (dlbaton->per_cu,
+					       dlbaton->per_objfile,
 					       loc_ptr, buf_end, &new_ptr,
 					       &low, &high, byte_order);
       else if (dlbaton->per_cu->version () < 5)
@@ -4538,6 +4545,7 @@ loclist_describe_location (struct symbol *symbol, CORE_ADDR addr,
 					   signed_addr_p);
       else
 	kind = decode_debug_loclists_addresses (dlbaton->per_cu,
+						dlbaton->per_objfile,
 						loc_ptr, buf_end, &new_ptr,
 						&low, &high, byte_order,
 						addr_size, signed_addr_p);
@@ -4590,8 +4598,8 @@ loclist_describe_location (struct symbol *symbol, CORE_ADDR addr,
 
       /* Now describe this particular location.  */
       locexpr_describe_location_1 (symbol, low, stream, loc_ptr, length,
-				   objfile, addr_size, offset_size,
-				   dlbaton->per_cu);
+				   addr_size, offset_size,
+				   dlbaton->per_cu, dlbaton->per_objfile);
 
       fprintf_filtered (stream, "\n");
 
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 79e8889d33f..172e4f19e3b 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -19365,9 +19365,10 @@ read_addr_index_from_leb128 (struct dwarf2_cu *cu, const gdb_byte *info_ptr,
 /* See read.h.  */
 
 CORE_ADDR
-dwarf2_read_addr_index (dwarf2_per_cu_data *per_cu, unsigned int addr_index)
+dwarf2_read_addr_index (dwarf2_per_cu_data *per_cu,
+			dwarf2_per_objfile *dwarf2_per_objfile,
+			unsigned int addr_index)
 {
-  struct dwarf2_per_objfile *dwarf2_per_objfile = per_cu->dwarf2_per_objfile;
   struct dwarf2_cu *cu = per_cu->cu;
   gdb::optional<ULONGEST> addr_base;
   int addr_size;
diff --git a/gdb/dwarf2/read.h b/gdb/dwarf2/read.h
index 15951f5221d..68e322f8bbe 100644
--- a/gdb/dwarf2/read.h
+++ b/gdb/dwarf2/read.h
@@ -579,6 +579,7 @@ struct type *dwarf2_get_die_type (cu_offset die_offset,
    may no longer exist.  */
 
 CORE_ADDR dwarf2_read_addr_index (dwarf2_per_cu_data *per_cu,
+				  dwarf2_per_objfile *dwarf2_per_objfile,
 				  unsigned int addr_index);
 
 /* Return DWARF block referenced by DW_AT_location of DIE at SECT_OFF at PER_CU.
-- 
2.26.2


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

* [PATCH v2 26/42] Add dwarf2_per_objfile parameter to allocate_piece_closure
  2020-05-12 21:08 [PATCH v2 00/42] Share DWARF partial symtabs between objfiles Simon Marchi
                   ` (24 preceding siblings ...)
  2020-05-12 21:12 ` [PATCH v2 25/42] Add dwarf2_per_objfile parameter to dwarf2_read_addr_index Simon Marchi
@ 2020-05-12 21:12 ` Simon Marchi
  2020-05-12 21:12 ` [PATCH v2 27/42] Add dwarf2_per_objfile parameters to dwarf2_fetch_* functions Simon Marchi
                   ` (19 subsequent siblings)
  45 siblings, 0 replies; 92+ messages in thread
From: Simon Marchi @ 2020-05-12 21:12 UTC (permalink / raw)
  To: gdb-patches; +Cc: Simon Marchi

This allows removing a dwarf2_per_cu_data::dwarf2_per_objfile reference.

gdb/ChangeLog:

	* dwarf2/loc.c (allocate_piece_closure): Add dwarf2_per_objfile
	parameter.
	(dwarf2_evaluate_loc_desc_full): Update.
---
 gdb/dwarf2/loc.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/gdb/dwarf2/loc.c b/gdb/dwarf2/loc.c
index 4c21a51fb5b..4b320408ab1 100644
--- a/gdb/dwarf2/loc.c
+++ b/gdb/dwarf2/loc.c
@@ -1576,7 +1576,8 @@ struct piece_closure
    PIECES.  */
 
 static struct piece_closure *
-allocate_piece_closure (struct dwarf2_per_cu_data *per_cu,
+allocate_piece_closure (dwarf2_per_cu_data *per_cu,
+			dwarf2_per_objfile *per_objfile,
 			std::vector<dwarf_expr_piece> &&pieces,
 			struct frame_info *frame)
 {
@@ -1584,7 +1585,7 @@ allocate_piece_closure (struct dwarf2_per_cu_data *per_cu,
 
   c->refc = 1;
   /* We must capture this here due to sharing of DWARF state.  */
-  c->per_objfile = per_cu->dwarf2_per_objfile;
+  c->per_objfile = per_objfile;
   c->per_cu = per_cu;
   c->pieces = std::move (pieces);
   if (frame == NULL)
@@ -2245,7 +2246,8 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame,
       if (bit_size > 8 * TYPE_LENGTH (type))
 	invalid_synthetic_pointer ();
 
-      c = allocate_piece_closure (per_cu, std::move (ctx.pieces), frame);
+      c = allocate_piece_closure (per_cu, per_objfile, std::move (ctx.pieces),
+				  frame);
       /* We must clean up the value chain after creating the piece
 	 closure but before allocating the result.  */
       free_values.free_to_mark ();
-- 
2.26.2


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

* [PATCH v2 27/42] Add dwarf2_per_objfile parameters to dwarf2_fetch_* functions
  2020-05-12 21:08 [PATCH v2 00/42] Share DWARF partial symtabs between objfiles Simon Marchi
                   ` (25 preceding siblings ...)
  2020-05-12 21:12 ` [PATCH v2 26/42] Add dwarf2_per_objfile parameter to allocate_piece_closure Simon Marchi
@ 2020-05-12 21:12 ` Simon Marchi
  2020-05-12 21:12 ` [PATCH v2 28/42] Remove dwarf2_per_cu_data::objfile () Simon Marchi
                   ` (18 subsequent siblings)
  45 siblings, 0 replies; 92+ messages in thread
From: Simon Marchi @ 2020-05-12 21:12 UTC (permalink / raw)
  To: gdb-patches; +Cc: Simon Marchi

This allows removing dwarf2_per_cu_data references.

gdb/ChangeLog:

	* dwarf2/read.h (dwarf2_fetch_die_loc_sect_off,
	dwarf2_fetch_die_loc_cu_off, dwarf2_fetch_constant_bytes,
	dwarf2_fetch_die_type_sect_off): Add dwarf2_per_objfile
	parameter.
	* dwarf2/read.c (dwarf2_fetch_die_loc_sect_off,
	dwarf2_fetch_die_loc_cu_off, dwarf2_fetch_constant_bytes,
	dwarf2_fetch_die_type_sect_off): Add dwarf2_per_objfile
	parameter.
	* dwarf2/loc.c (indirect_synthetic_pointer, per_cu_dwarf_call,
	sect_variable_value): Add dwarf2_per_objfile parameter.
	(class dwarf_evaluate_loc_desc) <dwarf_call,
	dwarf_variable_value>: Update.
	(fetch_const_value_from_synthetic_pointer): Add
	dwarf2_per_objfile parameter.
	(fetch_const_value_from_synthetic_pointer): Update.
	(coerced_pieced_ref): Update.
	(class symbol_needs_eval_context) <dwarf_call,
	dwarf_variable_value>: Update.
	(dwarf2_compile_expr_to_ax): Update.
---
 gdb/dwarf2/loc.c  | 46 +++++++++++++++++++++++++++-------------------
 gdb/dwarf2/read.c | 16 ++++++++++------
 gdb/dwarf2/read.h |  8 ++++++--
 3 files changed, 43 insertions(+), 27 deletions(-)

diff --git a/gdb/dwarf2/loc.c b/gdb/dwarf2/loc.c
index 4b320408ab1..c1ccbda8235 100644
--- a/gdb/dwarf2/loc.c
+++ b/gdb/dwarf2/loc.c
@@ -63,7 +63,8 @@ static struct call_site_parameter *dwarf_expr_reg_to_entry_parameter
 
 static struct value *indirect_synthetic_pointer
   (sect_offset die, LONGEST byte_offset,
-   struct dwarf2_per_cu_data *per_cu,
+   dwarf2_per_cu_data *per_cu,
+   dwarf2_per_objfile *per_objfile,
    struct frame_info *frame,
    struct type *type, bool resolve_abstract_p = false);
 
@@ -581,11 +582,11 @@ get_frame_pc_for_per_cu_dwarf_call (void *baton)
 
 static void
 per_cu_dwarf_call (struct dwarf_expr_context *ctx, cu_offset die_offset,
-		   struct dwarf2_per_cu_data *per_cu)
+		   dwarf2_per_cu_data *per_cu, dwarf2_per_objfile *per_objfile)
 {
   struct dwarf2_locexpr_baton block;
 
-  block = dwarf2_fetch_die_loc_cu_off (die_offset, per_cu,
+  block = dwarf2_fetch_die_loc_cu_off (die_offset, per_cu, per_objfile,
 				       get_frame_pc_for_per_cu_dwarf_call,
 				       ctx);
 
@@ -601,9 +602,11 @@ per_cu_dwarf_call (struct dwarf_expr_context *ctx, cu_offset die_offset,
 
 static struct value *
 sect_variable_value (struct dwarf_expr_context *ctx, sect_offset sect_off,
-		     struct dwarf2_per_cu_data *per_cu)
+		     dwarf2_per_cu_data *per_cu,
+		     dwarf2_per_objfile *per_objfile)
 {
-  struct type *die_type = dwarf2_fetch_die_type_sect_off (sect_off, per_cu);
+  struct type *die_type
+    = dwarf2_fetch_die_type_sect_off (sect_off, per_cu, per_objfile);
 
   if (die_type == NULL)
     error (_("Bad DW_OP_GNU_variable_value DIE."));
@@ -616,7 +619,8 @@ sect_variable_value (struct dwarf_expr_context *ctx, sect_offset sect_off,
 
   struct type *type = lookup_pointer_type (die_type);
   struct frame_info *frame = get_selected_frame (_("No frame selected."));
-  return indirect_synthetic_pointer (sect_off, 0, per_cu, frame, type, true);
+  return indirect_synthetic_pointer (sect_off, 0, per_cu, per_objfile, frame,
+				     type, true);
 }
 
 class dwarf_evaluate_loc_desc : public dwarf_expr_context
@@ -660,7 +664,7 @@ class dwarf_evaluate_loc_desc : public dwarf_expr_context
 
   void dwarf_call (cu_offset die_offset) override
   {
-    per_cu_dwarf_call (this, die_offset, per_cu);
+    per_cu_dwarf_call (this, die_offset, per_cu, per_objfile);
   }
 
   /* Helper interface of sect_variable_value for
@@ -668,7 +672,7 @@ class dwarf_evaluate_loc_desc : public dwarf_expr_context
 
   struct value *dwarf_variable_value (sect_offset sect_off) override
   {
-    return sect_variable_value (this, sect_off, per_cu);
+    return sect_variable_value (this, sect_off, per_cu, per_objfile);
   }
 
   struct type *get_base_type (cu_offset die_offset, int size) override
@@ -1963,7 +1967,8 @@ get_frame_address_in_block_wrapper (void *baton)
 
 static struct value *
 fetch_const_value_from_synthetic_pointer (sect_offset die, LONGEST byte_offset,
-					  struct dwarf2_per_cu_data *per_cu,
+					  dwarf2_per_cu_data *per_cu,
+					  dwarf2_per_objfile *per_objfile,
 					  struct type *type)
 {
   struct value *result = NULL;
@@ -1971,7 +1976,8 @@ fetch_const_value_from_synthetic_pointer (sect_offset die, LONGEST byte_offset,
   LONGEST len;
 
   auto_obstack temp_obstack;
-  bytes = dwarf2_fetch_constant_bytes (die, per_cu, &temp_obstack, &len);
+  bytes = dwarf2_fetch_constant_bytes (die, per_cu, per_objfile,
+				       &temp_obstack, &len);
 
   if (bytes != NULL)
     {
@@ -1994,18 +2000,20 @@ fetch_const_value_from_synthetic_pointer (sect_offset die, LONGEST byte_offset,
 
 static struct value *
 indirect_synthetic_pointer (sect_offset die, LONGEST byte_offset,
-			    struct dwarf2_per_cu_data *per_cu,
+			    dwarf2_per_cu_data *per_cu,
+			    dwarf2_per_objfile *per_objfile,
 			    struct frame_info *frame, struct type *type,
 			    bool resolve_abstract_p)
 {
   /* Fetch the location expression of the DIE we're pointing to.  */
   struct dwarf2_locexpr_baton baton
-    = dwarf2_fetch_die_loc_sect_off (die, per_cu,
+    = dwarf2_fetch_die_loc_sect_off (die, per_cu, per_objfile,
 				     get_frame_address_in_block_wrapper, frame,
 				     resolve_abstract_p);
 
   /* Get type of pointed-to DIE.  */
-  struct type *orig_type = dwarf2_fetch_die_type_sect_off (die, per_cu);
+  struct type *orig_type = dwarf2_fetch_die_type_sect_off (die, per_cu,
+							   per_objfile);
   if (orig_type == NULL)
     invalid_synthetic_pointer ();
 
@@ -2019,7 +2027,7 @@ indirect_synthetic_pointer (sect_offset die, LONGEST byte_offset,
 					  byte_offset);
   else
     return fetch_const_value_from_synthetic_pointer (die, byte_offset, per_cu,
-						     type);
+						     per_objfile, type);
 }
 
 /* An implementation of an lval_funcs method to indirect through a
@@ -2096,7 +2104,7 @@ indirect_pieced_value (struct value *value)
 
   return indirect_synthetic_pointer (piece->v.ptr.die_sect_off,
 				     byte_offset, c->per_cu,
-				     frame, type);
+				     c->per_objfile, frame, type);
 }
 
 /* Implementation of the coerce_ref method of lval_funcs for synthetic C++
@@ -2123,7 +2131,7 @@ coerce_pieced_ref (const struct value *value)
       return indirect_synthetic_pointer
 	(closure->pieces[0].v.ptr.die_sect_off,
 	 closure->pieces[0].v.ptr.offset,
-	 closure->per_cu, frame, type);
+	 closure->per_cu, closure->per_objfile, frame, type);
     }
   else
     {
@@ -2752,7 +2760,7 @@ class symbol_needs_eval_context : public dwarf_expr_context
 
   void dwarf_call (cu_offset die_offset) override
   {
-    per_cu_dwarf_call (this, die_offset, per_cu);
+    per_cu_dwarf_call (this, die_offset, per_cu, per_objfile);
   }
 
   /* Helper interface of sect_variable_value for
@@ -2760,7 +2768,7 @@ class symbol_needs_eval_context : public dwarf_expr_context
 
   struct value *dwarf_variable_value (sect_offset sect_off) override
   {
-    return sect_variable_value (this, sect_off, per_cu);
+    return sect_variable_value (this, sect_off, per_cu, per_objfile);
   }
 
   /* DW_OP_entry_value accesses require a caller, therefore a
@@ -3589,7 +3597,7 @@ dwarf2_compile_expr_to_ax (struct agent_expr *expr, struct axs_value *loc,
 	    op_ptr += size;
 
 	    cu_offset cuoffset = (cu_offset) uoffset;
-	    block = dwarf2_fetch_die_loc_cu_off (cuoffset, per_cu,
+	    block = dwarf2_fetch_die_loc_cu_off (cuoffset, per_cu, per_objfile,
 						 get_ax_pc, expr);
 
 	    /* DW_OP_call_ref is currently not supported.  */
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 172e4f19e3b..d221d0148c0 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -22260,6 +22260,7 @@ follow_die_ref (struct die_info *src_die, const struct attribute *attr,
 struct dwarf2_locexpr_baton
 dwarf2_fetch_die_loc_sect_off (sect_offset sect_off,
 			       dwarf2_per_cu_data *per_cu,
+			       dwarf2_per_objfile *dwarf2_per_objfile,
 			       CORE_ADDR (*get_frame_pc) (void *baton),
 			       void *baton, bool resolve_abstract_p)
 {
@@ -22267,7 +22268,6 @@ dwarf2_fetch_die_loc_sect_off (sect_offset sect_off,
   struct die_info *die;
   struct attribute *attr;
   struct dwarf2_locexpr_baton retval;
-  struct dwarf2_per_objfile *dwarf2_per_objfile = per_cu->dwarf2_per_objfile;
   struct objfile *objfile = dwarf2_per_objfile->objfile;
 
   if (per_cu->cu == NULL)
@@ -22364,12 +22364,14 @@ dwarf2_fetch_die_loc_sect_off (sect_offset sect_off,
 struct dwarf2_locexpr_baton
 dwarf2_fetch_die_loc_cu_off (cu_offset offset_in_cu,
 			     dwarf2_per_cu_data *per_cu,
+			     dwarf2_per_objfile *per_objfile,
 			     CORE_ADDR (*get_frame_pc) (void *baton),
 			     void *baton)
 {
   sect_offset sect_off = per_cu->sect_off + to_underlying (offset_in_cu);
 
-  return dwarf2_fetch_die_loc_sect_off (sect_off, per_cu, get_frame_pc, baton);
+  return dwarf2_fetch_die_loc_sect_off (sect_off, per_cu, per_objfile,
+					get_frame_pc, baton);
 }
 
 /* Write a constant of a given type as target-ordered bytes into
@@ -22396,6 +22398,7 @@ write_constant_as_bytes (struct obstack *obstack,
 const gdb_byte *
 dwarf2_fetch_constant_bytes (sect_offset sect_off,
 			     dwarf2_per_cu_data *per_cu,
+			     dwarf2_per_objfile *per_objfile,
 			     obstack *obstack,
 			     LONGEST *len)
 {
@@ -22406,10 +22409,10 @@ dwarf2_fetch_constant_bytes (sect_offset sect_off,
   struct type *type;
   LONGEST value;
   enum bfd_endian byte_order;
-  struct objfile *objfile = per_cu->dwarf2_per_objfile->objfile;
+  struct objfile *objfile = per_objfile->objfile;
 
   if (per_cu->cu == NULL)
-    load_cu (per_cu, per_cu->dwarf2_per_objfile, false);
+    load_cu (per_cu, per_objfile, false);
   cu = per_cu->cu;
   if (cu == NULL)
     {
@@ -22525,13 +22528,14 @@ dwarf2_fetch_constant_bytes (sect_offset sect_off,
 
 struct type *
 dwarf2_fetch_die_type_sect_off (sect_offset sect_off,
-				dwarf2_per_cu_data *per_cu)
+				dwarf2_per_cu_data *per_cu,
+				dwarf2_per_objfile *per_objfile)
 {
   struct dwarf2_cu *cu;
   struct die_info *die;
 
   if (per_cu->cu == NULL)
-    load_cu (per_cu, per_cu->dwarf2_per_objfile, false);
+    load_cu (per_cu, per_objfile, false);
   cu = per_cu->cu;
   if (!cu)
     return NULL;
diff --git a/gdb/dwarf2/read.h b/gdb/dwarf2/read.h
index 68e322f8bbe..c6d236b4778 100644
--- a/gdb/dwarf2/read.h
+++ b/gdb/dwarf2/read.h
@@ -589,6 +589,7 @@ CORE_ADDR dwarf2_read_addr_index (dwarf2_per_cu_data *per_cu,
 
 struct dwarf2_locexpr_baton dwarf2_fetch_die_loc_sect_off
   (sect_offset sect_off, dwarf2_per_cu_data *per_cu,
+   dwarf2_per_objfile *per_objfile,
    CORE_ADDR (*get_frame_pc) (void *baton),
    void *baton, bool resolve_abstract_p = false);
 
@@ -597,6 +598,7 @@ struct dwarf2_locexpr_baton dwarf2_fetch_die_loc_sect_off
 
 struct dwarf2_locexpr_baton dwarf2_fetch_die_loc_cu_off
   (cu_offset offset_in_cu, dwarf2_per_cu_data *per_cu,
+   dwarf2_per_objfile *per_objfile,
    CORE_ADDR (*get_frame_pc) (void *baton),
    void *baton);
 
@@ -606,14 +608,16 @@ struct dwarf2_locexpr_baton dwarf2_fetch_die_loc_cu_off
    does not have a DW_AT_const_value, return NULL.  */
 
 extern const gdb_byte *dwarf2_fetch_constant_bytes
-  (sect_offset sect_off, dwarf2_per_cu_data *per_cu, obstack *obstack,
+  (sect_offset sect_off, dwarf2_per_cu_data *per_cu,
+   dwarf2_per_objfile *per_objfile, obstack *obstack,
    LONGEST *len);
 
 /* Return the type of the die at SECT_OFF in PER_CU.  Return NULL if no
    valid type for this die is found.  */
 
 struct type *dwarf2_fetch_die_type_sect_off
-  (sect_offset sect_off, dwarf2_per_cu_data *per_cu);
+  (sect_offset sect_off, dwarf2_per_cu_data *per_cu,
+   dwarf2_per_objfile *per_objfile);
 
 /* When non-zero, dump line number entries as they are read in.  */
 extern unsigned int dwarf_line_debug;
-- 
2.26.2


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

* [PATCH v2 28/42] Remove dwarf2_per_cu_data::objfile ()
  2020-05-12 21:08 [PATCH v2 00/42] Share DWARF partial symtabs between objfiles Simon Marchi
                   ` (26 preceding siblings ...)
  2020-05-12 21:12 ` [PATCH v2 27/42] Add dwarf2_per_objfile parameters to dwarf2_fetch_* functions Simon Marchi
@ 2020-05-12 21:12 ` Simon Marchi
  2020-05-27 16:27   ` Tom de Vries
  2020-05-12 21:12 ` [PATCH v2 29/42] Add dwarf2_per_objfile parameter to free_one_cached_comp_unit Simon Marchi
                   ` (17 subsequent siblings)
  45 siblings, 1 reply; 92+ messages in thread
From: Simon Marchi @ 2020-05-12 21:12 UTC (permalink / raw)
  To: gdb-patches; +Cc: Simon Marchi

Since dwarf2_per_cu_data objects are going to become
objfile-independent, the backlink from dwarf2_per_cu_data to one
particular objfile must be removed.  Instead, users of
dwarf2_per_cu_data that need an objfile must know from somewhere else in
the context of which objfile they are using this CU.

This also helps remove a dwarf2_per_cu_data::dwarf2_per_objfile
reference (from where the objfile was obtained).

Note that the dwarf2_per_cu_data::objfile method has a special case to
make sure to return the main objfile, if the objfile associated to the
dwarf2_per_cu_data is a separate debug objfile.  I don't really know if
this is necessary: I ignored that, and didn't see any regression when
testing with the various Dejagnu boards with separate debug info, so I
presume it wasn't needed.  If it turns out this was needed, then we can
have a helper method on the objfile type for that.

gdb/ChangeLog:

	* dwarf2/read.h (struct dwarf2_per_cu_data) <objfile>: Remove.
	* dwarf2/read.c (dwarf2_compute_name): Pass per_objfile down.
	(read_call_site_scope): Assign per_objfile.
	(dwarf2_per_cu_data::objfile): Remove.
	* gdbtypes.h (struct call_site) <per_objfile>: New member.
	* dwarf2/loc.h (dwarf2_evaluate_loc_desc): Add
	dwarf2_per_objfile parameter.
	* dwarf2/loc.c (dwarf2_evaluate_loc_desc_full): Add
	dwarf2_per_objfile parameter.
	(dwarf_expr_reg_to_entry_parameter): Add output
	dwarf2_per_objfile parameter.
	(locexpr_get_frame_base): Update.
	(class dwarf_evaluate_loc_desc) <get_tls_address>: Update.
	<push_dwarf_reg_entry_value>: Update.
	<call_site_to_target_addr>: Update.
	(dwarf_entry_parameter_to_value): Add dwarf2_per_objfile
	parameter.
	(value_of_dwarf_reg_entry): Update.
	(rw_pieced_value): Update.
	(indirect_synthetic_pointer): Update.
	(dwarf2_evaluate_property): Update.
	(dwarf2_loc_desc_get_symbol_read_needs): Add dwarf2_per_objfile
	parameter.
	(locexpr_read_variable): Update.
	(locexpr_get_symbol_read_needs): Update.
	(loclist_read_variable): Update.
---
 gdb/dwarf2/loc.c  | 94 ++++++++++++++++++++++++++---------------------
 gdb/dwarf2/loc.h  |  3 +-
 gdb/dwarf2/read.c | 19 ++--------
 gdb/dwarf2/read.h |  5 ---
 gdb/gdbtypes.h    |  8 +++-
 5 files changed, 65 insertions(+), 64 deletions(-)

diff --git a/gdb/dwarf2/loc.c b/gdb/dwarf2/loc.c
index c1ccbda8235..a4b7edf7bff 100644
--- a/gdb/dwarf2/loc.c
+++ b/gdb/dwarf2/loc.c
@@ -47,19 +47,17 @@
 #include "gdbsupport/underlying.h"
 #include "gdbsupport/byte-vector.h"
 
-static struct value *dwarf2_evaluate_loc_desc_full (struct type *type,
-						    struct frame_info *frame,
-						    const gdb_byte *data,
-						    size_t size,
-						    struct dwarf2_per_cu_data *per_cu,
-						    struct type *subobj_type,
-						    LONGEST subobj_byte_offset);
+static struct value *dwarf2_evaluate_loc_desc_full
+  (struct type *type, struct frame_info *frame, const gdb_byte *data,
+   size_t size, dwarf2_per_cu_data *per_cu, dwarf2_per_objfile *per_objfile,
+   struct type *subobj_type, LONGEST subobj_byte_offset);
 
 static struct call_site_parameter *dwarf_expr_reg_to_entry_parameter
     (struct frame_info *frame,
      enum call_site_parameter_kind kind,
      union call_site_parameter_u kind_u,
-     struct dwarf2_per_cu_data **per_cu_return);
+     dwarf2_per_cu_data **per_cu_return,
+     dwarf2_per_objfile **per_objfile_return);
 
 static struct value *indirect_synthetic_pointer
   (sect_offset die, LONGEST byte_offset,
@@ -476,7 +474,7 @@ locexpr_get_frame_base (struct symbol *framefunc, struct frame_info *frame)
   SYMBOL_BLOCK_OPS (framefunc)->find_frame_base_location
     (framefunc, get_frame_pc (frame), &start, &length);
   result = dwarf2_evaluate_loc_desc (type, frame, start, length,
-				     dlbaton->per_cu);
+				     dlbaton->per_cu, dlbaton->per_objfile);
 
   /* The DW_AT_frame_base attribute contains a location description which
      computes the base address itself.  However, the call to
@@ -533,7 +531,7 @@ loclist_get_frame_base (struct symbol *framefunc, struct frame_info *frame)
   SYMBOL_BLOCK_OPS (framefunc)->find_frame_base_location
     (framefunc, get_frame_pc (frame), &start, &length);
   result = dwarf2_evaluate_loc_desc (type, frame, start, length,
-				     dlbaton->per_cu);
+				     dlbaton->per_cu, dlbaton->per_objfile);
 
   /* The DW_AT_frame_base attribute contains a location description which
      computes the base address itself.  However, the call to
@@ -654,9 +652,7 @@ class dwarf_evaluate_loc_desc : public dwarf_expr_context
      current thread's thread-local storage with offset OFFSET.  */
   CORE_ADDR get_tls_address (CORE_ADDR offset) override
   {
-    struct objfile *objfile = per_cu->objfile ();
-
-    return target_translate_tls_address (objfile, offset);
+    return target_translate_tls_address (per_objfile->objfile, offset);
   }
 
   /* Helper interface of per_cu_dwarf_call for
@@ -716,7 +712,8 @@ class dwarf_evaluate_loc_desc : public dwarf_expr_context
 				   int deref_size) override
   {
     struct frame_info *caller_frame;
-    struct dwarf2_per_cu_data *caller_per_cu;
+    dwarf2_per_cu_data *caller_per_cu;
+    dwarf2_per_objfile *caller_per_objfile;
     struct call_site_parameter *parameter;
     const gdb_byte *data_src;
     size_t size;
@@ -724,10 +721,13 @@ class dwarf_evaluate_loc_desc : public dwarf_expr_context
     caller_frame = get_prev_frame (frame);
 
     parameter = dwarf_expr_reg_to_entry_parameter (frame, kind, kind_u,
-						   &caller_per_cu);
+						   &caller_per_cu,
+						   &caller_per_objfile);
     data_src = deref_size == -1 ? parameter->value : parameter->data_value;
     size = deref_size == -1 ? parameter->value_size : parameter->data_value_size;
 
+    gdb_assert (this->per_objfile == caller_per_objfile);
+
     /* DEREF_SIZE size is not verified here.  */
     if (data_src == NULL)
       throw_error (NO_ENTRY_VALUE_ERROR,
@@ -741,7 +741,7 @@ class dwarf_evaluate_loc_desc : public dwarf_expr_context
 							(CORE_ADDR) 0);
 
     scoped_restore save_arch = make_scoped_restore (&this->gdbarch);
-    this->gdbarch = per_cu->objfile ()->arch ();
+    this->gdbarch = this->per_objfile->objfile->arch ();
     scoped_restore save_addr_size = make_scoped_restore (&this->addr_size);
     this->addr_size = per_cu->addr_size ();
 
@@ -869,7 +869,8 @@ call_site_to_target_addr (struct gdbarch *call_site_gdbarch,
 	caller_core_addr_type = builtin_type (caller_arch)->builtin_func_ptr;
 	val = dwarf2_evaluate_loc_desc (caller_core_addr_type, caller_frame,
 					dwarf_block->data, dwarf_block->size,
-					dwarf_block->per_cu);
+					dwarf_block->per_cu,
+					dwarf_block->per_objfile);
 	/* DW_AT_call_target is a DWARF expression, not a DWARF location.  */
 	if (VALUE_LVAL (val) == lval_memory)
 	  return value_address (val);
@@ -1290,7 +1291,8 @@ static struct call_site_parameter *
 dwarf_expr_reg_to_entry_parameter (struct frame_info *frame,
 				   enum call_site_parameter_kind kind,
 				   union call_site_parameter_u kind_u,
-				   struct dwarf2_per_cu_data **per_cu_return)
+				   dwarf2_per_cu_data **per_cu_return,
+				   dwarf2_per_objfile **per_objfile_return)
 {
   CORE_ADDR func_addr, caller_pc;
   struct gdbarch *gdbarch;
@@ -1381,6 +1383,7 @@ dwarf_expr_reg_to_entry_parameter (struct frame_info *frame,
     }
 
   *per_cu_return = call_site->per_cu;
+  *per_objfile_return = call_site->per_objfile;
   return parameter;
 }
 
@@ -1398,7 +1401,8 @@ static struct value *
 dwarf_entry_parameter_to_value (struct call_site_parameter *parameter,
 				CORE_ADDR deref_size, struct type *type,
 				struct frame_info *caller_frame,
-				struct dwarf2_per_cu_data *per_cu)
+				dwarf2_per_cu_data *per_cu,
+				dwarf2_per_objfile *per_objfile)
 {
   const gdb_byte *data_src;
   gdb_byte *data;
@@ -1419,7 +1423,8 @@ dwarf_entry_parameter_to_value (struct call_site_parameter *parameter,
   memcpy (data, data_src, size);
   data[size] = DW_OP_stack_value;
 
-  return dwarf2_evaluate_loc_desc (type, caller_frame, data, size + 1, per_cu);
+  return dwarf2_evaluate_loc_desc (type, caller_frame, data, size + 1, per_cu,
+				   per_objfile);
 }
 
 /* VALUE must be of type lval_computed with entry_data_value_funcs.  Perform
@@ -1493,14 +1498,17 @@ value_of_dwarf_reg_entry (struct type *type, struct frame_info *frame,
   struct frame_info *caller_frame = get_prev_frame (frame);
   struct value *outer_val, *target_val, *val;
   struct call_site_parameter *parameter;
-  struct dwarf2_per_cu_data *caller_per_cu;
+  dwarf2_per_cu_data *caller_per_cu;
+  dwarf2_per_objfile *caller_per_objfile;
 
   parameter = dwarf_expr_reg_to_entry_parameter (frame, kind, kind_u,
-						 &caller_per_cu);
+						 &caller_per_cu,
+						 &caller_per_objfile);
 
   outer_val = dwarf_entry_parameter_to_value (parameter, -1 /* deref_size */,
 					      type, caller_frame,
-					      caller_per_cu);
+					      caller_per_cu,
+					      caller_per_objfile);
 
   /* Check if DW_AT_call_data_value cannot be used.  If it should be
      used and it is not available do not fall back to OUTER_VAL - dereferencing
@@ -1514,7 +1522,8 @@ value_of_dwarf_reg_entry (struct type *type, struct frame_info *frame,
   target_val = dwarf_entry_parameter_to_value (parameter,
 					       TYPE_LENGTH (target_type),
 					       target_type, caller_frame,
-					       caller_per_cu);
+					       caller_per_cu,
+					       caller_per_objfile);
 
   val = allocate_computed_value (type, &entry_data_value_funcs,
 				 release_value (target_val).release ());
@@ -1831,8 +1840,7 @@ rw_pieced_value (struct value *v, struct value *from)
 		break;
 	      }
 
-	    struct objfile *objfile = c->per_cu->objfile ();
-	    struct gdbarch *objfile_gdbarch = objfile->arch ();
+	    gdbarch *objfile_gdbarch = c->per_objfile->objfile->arch ();
 	    ULONGEST stack_value_size_bits
 	      = 8 * TYPE_LENGTH (value_type (p->v.value));
 
@@ -2023,6 +2031,7 @@ indirect_synthetic_pointer (sect_offset die, LONGEST byte_offset,
   if (baton.data != NULL)
     return dwarf2_evaluate_loc_desc_full (orig_type, frame, baton.data,
 					  baton.size, baton.per_cu,
+					  baton.per_objfile,
 					  TYPE_TARGET_TYPE (type),
 					  byte_offset);
   else
@@ -2187,12 +2196,12 @@ static const struct lval_funcs pieced_value_funcs = {
 static struct value *
 dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame,
 			       const gdb_byte *data, size_t size,
-			       struct dwarf2_per_cu_data *per_cu,
+			       dwarf2_per_cu_data *per_cu,
+			       dwarf2_per_objfile *per_objfile,
 			       struct type *subobj_type,
 			       LONGEST subobj_byte_offset)
 {
   struct value *retval;
-  struct objfile *objfile = per_cu->objfile ();
 
   if (subobj_type == NULL)
     {
@@ -2205,7 +2214,6 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame,
   if (size == 0)
     return allocate_optimized_out_value (subobj_type);
 
-  dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile);
   dwarf_evaluate_loc_desc ctx (per_objfile);
   ctx.frame = frame;
   ctx.per_cu = per_cu;
@@ -2213,7 +2221,7 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame,
 
   scoped_value_mark free_values;
 
-  ctx.gdbarch = objfile->arch ();
+  ctx.gdbarch = per_objfile->objfile->arch ();
   ctx.addr_size = per_cu->addr_size ();
   ctx.ref_addr_size = per_cu->ref_addr_size ();
 
@@ -2336,7 +2344,7 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame,
 	    size_t n = TYPE_LENGTH (value_type (value));
 	    size_t len = TYPE_LENGTH (subobj_type);
 	    size_t max = TYPE_LENGTH (type);
-	    struct gdbarch *objfile_gdbarch = objfile->arch ();
+	    gdbarch *objfile_gdbarch = per_objfile->objfile->arch ();
 
 	    if (subobj_byte_offset + len > max)
 	      invalid_synthetic_pointer ();
@@ -2399,10 +2407,11 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame,
 struct value *
 dwarf2_evaluate_loc_desc (struct type *type, struct frame_info *frame,
 			  const gdb_byte *data, size_t size,
-			  struct dwarf2_per_cu_data *per_cu)
+			  dwarf2_per_cu_data *per_cu,
+			  dwarf2_per_objfile *per_objfile)
 {
   return dwarf2_evaluate_loc_desc_full (type, frame, data, size, per_cu,
-					NULL, 0);
+					per_objfile, NULL, 0);
 }
 
 /* A specialization of dwarf_evaluate_loc_desc that is used by
@@ -2603,7 +2612,8 @@ dwarf2_evaluate_property (const struct dynamic_prop *prop,
 	if (data != NULL)
 	  {
 	    val = dwarf2_evaluate_loc_desc (baton->property_type, frame, data,
-					    size, baton->loclist.per_cu);
+					    size, baton->loclist.per_cu,
+					    baton->loclist.per_objfile);
 	    if (!value_optimized_out (val))
 	      {
 		*value = value_as_address (val);
@@ -2806,18 +2816,18 @@ class symbol_needs_eval_context : public dwarf_expr_context
 
 static enum symbol_needs_kind
 dwarf2_loc_desc_get_symbol_read_needs (const gdb_byte *data, size_t size,
-				       struct dwarf2_per_cu_data *per_cu)
+				       dwarf2_per_cu_data *per_cu,
+				       dwarf2_per_objfile *per_objfile)
 {
   int in_reg;
-  struct objfile *objfile = per_cu->objfile ();
 
   scoped_value_mark free_values;
 
-  symbol_needs_eval_context ctx (get_dwarf2_per_objfile (objfile));
+  symbol_needs_eval_context ctx (per_objfile);
 
   ctx.needs = SYMBOL_NEEDS_NONE;
   ctx.per_cu = per_cu;
-  ctx.gdbarch = objfile->arch ();
+  ctx.gdbarch = per_objfile->objfile->arch ();
   ctx.addr_size = per_cu->addr_size ();
   ctx.ref_addr_size = per_cu->ref_addr_size ();
 
@@ -3641,7 +3651,8 @@ locexpr_read_variable (struct symbol *symbol, struct frame_info *frame)
   struct value *val;
 
   val = dwarf2_evaluate_loc_desc (SYMBOL_TYPE (symbol), frame, dlbaton->data,
-				  dlbaton->size, dlbaton->per_cu);
+				  dlbaton->size, dlbaton->per_cu,
+				  dlbaton->per_objfile);
 
   return val;
 }
@@ -3670,7 +3681,8 @@ locexpr_get_symbol_read_needs (struct symbol *symbol)
     = (struct dwarf2_locexpr_baton *) SYMBOL_LOCATION_BATON (symbol);
 
   return dwarf2_loc_desc_get_symbol_read_needs (dlbaton->data, dlbaton->size,
-						dlbaton->per_cu);
+						dlbaton->per_cu,
+						dlbaton->per_objfile);
 }
 
 /* Return true if DATA points to the end of a piece.  END is one past
@@ -4460,7 +4472,7 @@ loclist_read_variable (struct symbol *symbol, struct frame_info *frame)
 
   data = dwarf2_find_location_expression (dlbaton, &size, pc);
   val = dwarf2_evaluate_loc_desc (SYMBOL_TYPE (symbol), frame, data, size,
-				  dlbaton->per_cu);
+				  dlbaton->per_cu, dlbaton->per_objfile);
 
   return val;
 }
diff --git a/gdb/dwarf2/loc.h b/gdb/dwarf2/loc.h
index 51f242ec431..907455b72c1 100644
--- a/gdb/dwarf2/loc.h
+++ b/gdb/dwarf2/loc.h
@@ -61,7 +61,8 @@ struct value *dwarf2_evaluate_loc_desc (struct type *type,
 					struct frame_info *frame,
 					const gdb_byte *data,
 					size_t size,
-					struct dwarf2_per_cu_data *per_cu);
+					dwarf2_per_cu_data *per_cu,
+					dwarf2_per_objfile *per_objfile);
 
 /* A chain of addresses that might be needed to resolve a dynamic
    property.  */
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index d221d0148c0..63449cf2c6f 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -10316,7 +10316,8 @@ dwarf2_compute_name (const char *name,
 			v = dwarf2_evaluate_loc_desc (type, NULL,
 						      baton->data,
 						      baton->size,
-						      baton->per_cu);
+						      baton->per_cu,
+						      baton->per_objfile);
 		      else if (bytes != NULL)
 			{
 			  v = allocate_value (type);
@@ -13460,6 +13461,7 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
 	       sect_offset_str (die->sect_off), objfile_name (objfile));
 
   call_site->per_cu = cu->per_cu;
+  call_site->per_objfile = per_objfile;
 
   for (child_die = die->child;
        child_die && child_die->tag;
@@ -23277,21 +23279,6 @@ dwarf2_symbol_mark_computed (const struct attribute *attr, struct symbol *sym,
     }
 }
 
-/* See read.h.  */
-
-struct objfile *
-dwarf2_per_cu_data::objfile () const
-{
-  struct objfile *objfile = dwarf2_per_objfile->objfile;
-
-  /* Return the master objfile, so that we can report and look up the
-     correct file containing this variable.  */
-  if (objfile->separate_debug_objfile_backlink)
-    objfile = objfile->separate_debug_objfile_backlink;
-
-  return objfile;
-}
-
 /* Return comp_unit_head for PER_CU, either already available in PER_CU->CU
    (CU_HEADERP is unused in such case) or prepare a temporary copy at
    CU_HEADERP first.  */
diff --git a/gdb/dwarf2/read.h b/gdb/dwarf2/read.h
index c6d236b4778..dda5ed71c4d 100644
--- a/gdb/dwarf2/read.h
+++ b/gdb/dwarf2/read.h
@@ -491,11 +491,6 @@ struct dwarf2_per_cu_data
     imported_symtabs = nullptr;
   }
 
-  /* Return the OBJFILE associated with this compilation unit.  If
-     this compilation unit came from a separate debuginfo file, then
-     the master objfile is returned.  */
-  struct objfile *objfile () const;
-
   /* Return the address size given in the compilation unit header for
      this CU.  */
   int addr_size () const;
diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h
index 7514bd27f7c..c8338f38495 100644
--- a/gdb/gdbtypes.h
+++ b/gdb/gdbtypes.h
@@ -58,6 +58,8 @@ struct field;
 struct block;
 struct value_print_options;
 struct language_defn;
+struct dwarf2_per_cu_data;
+struct dwarf2_per_objfile;
 
 /* These declarations are DWARF-specific as some of the gdbtypes.h data types
    are already DWARF-specific.  */
@@ -1333,7 +1335,11 @@ struct call_site
     /* * CU of the function where the call is located.  It gets used
        for DWARF blocks execution in the parameter array below.  */
 
-    struct dwarf2_per_cu_data *per_cu;
+    dwarf2_per_cu_data *per_cu;
+
+    /* objfile of the function where the call is located.  */
+
+    dwarf2_per_objfile *per_objfile;
 
     /* * Describe DW_TAG_call_site's DW_TAG_formal_parameter.  */
 
-- 
2.26.2


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

* [PATCH v2 29/42] Add dwarf2_per_objfile parameter to free_one_cached_comp_unit
  2020-05-12 21:08 [PATCH v2 00/42] Share DWARF partial symtabs between objfiles Simon Marchi
                   ` (27 preceding siblings ...)
  2020-05-12 21:12 ` [PATCH v2 28/42] Remove dwarf2_per_cu_data::objfile () Simon Marchi
@ 2020-05-12 21:12 ` Simon Marchi
  2020-05-12 21:17 ` [PATCH v2 30/42] Add dwarf2_per_objfile parameter to get_die_type_at_offset Simon Marchi
                   ` (16 subsequent siblings)
  45 siblings, 0 replies; 92+ messages in thread
From: Simon Marchi @ 2020-05-12 21:12 UTC (permalink / raw)
  To: gdb-patches; +Cc: Simon Marchi

This allows removing some references to
dwarf2_per_cu_data::dwarf2_per_objfile.

gdb/ChangeLog:

	* dwarf2/read.h (struct dwarf2_queue_item): Add
	dwarf2_per_objfile parameter, assign new parameter.
	<per_objfile>: New field.
	* dwarf2/read.c (free_one_cached_comp_unit): Add
	dwarf2_per_objfile parameter.
	(queue_comp_unit): Likewise.
	(dw2_do_instantiate_symtab): Update.
	(process_psymtab_comp_unit): Update.
	(maybe_queue_comp_unit): Add dwarf2_per_objfile parameter.
	(process_imported_unit_die): Update.
	(queue_and_load_dwo_tu): Update.
	(follow_die_offset): Update.
	(follow_die_sig_1): Update.
---
 gdb/dwarf2/read.c | 42 +++++++++++++++++++++++-------------------
 gdb/dwarf2/read.h |  7 +++++--
 2 files changed, 28 insertions(+), 21 deletions(-)

diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 63449cf2c6f..e8ba115fe4f 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -1568,7 +1568,8 @@ static void prepare_one_comp_unit (struct dwarf2_cu *cu,
 
 static void age_cached_comp_units (struct dwarf2_per_objfile *dwarf2_per_objfile);
 
-static void free_one_cached_comp_unit (struct dwarf2_per_cu_data *);
+static void free_one_cached_comp_unit (dwarf2_per_cu_data *target_per_cu,
+				       dwarf2_per_objfile *per_objfile);
 
 static struct type *set_die_type (struct die_info *, struct type *,
 				  struct dwarf2_cu *);
@@ -1602,7 +1603,8 @@ static struct type *get_die_type_at_offset (sect_offset,
 
 static struct type *get_die_type (struct die_info *die, struct dwarf2_cu *cu);
 
-static void queue_comp_unit (struct dwarf2_per_cu_data *per_cu,
+static void queue_comp_unit (dwarf2_per_cu_data *per_cu,
+			     dwarf2_per_objfile *per_objfile,
 			     enum language pretend_language);
 
 static void process_queue (struct dwarf2_per_objfile *dwarf2_per_objfile);
@@ -1642,7 +1644,7 @@ dwarf2_queue_item::~dwarf2_queue_item ()
   if (per_cu->queued)
     {
       if (per_cu->cu != NULL)
-	free_one_cached_comp_unit (per_cu);
+	free_one_cached_comp_unit (per_cu, per_objfile);
       per_cu->queued = 0;
     }
 }
@@ -2381,7 +2383,7 @@ dw2_do_instantiate_symtab (dwarf2_per_cu_data *per_cu,
 
   if (!dwarf2_per_objfile->symtab_set_p (per_cu))
     {
-      queue_comp_unit (per_cu, language_minimal);
+      queue_comp_unit (per_cu, dwarf2_per_objfile, language_minimal);
       load_cu (per_cu, dwarf2_per_objfile, skip_partial);
 
       /* If we just loaded a CU from a DWO, and we're working with an index
@@ -7541,7 +7543,7 @@ process_psymtab_comp_unit (dwarf2_per_cu_data *this_cu,
      read in the compilation unit (see load_partial_dies).
      This problem could be avoided, but the benefit is unclear.  */
   if (this_cu->cu != NULL)
-    free_one_cached_comp_unit (this_cu);
+    free_one_cached_comp_unit (this_cu, per_objfile);
 
   cutu_reader reader (this_cu, per_objfile, NULL, 0, false);
 
@@ -8899,11 +8901,12 @@ dwarf2_psymtab::read_symtab (struct objfile *objfile)
 /* Add PER_CU to the queue.  */
 
 static void
-queue_comp_unit (struct dwarf2_per_cu_data *per_cu,
+queue_comp_unit (dwarf2_per_cu_data *per_cu,
+		 dwarf2_per_objfile *per_objfile,
 		 enum language pretend_language)
 {
   per_cu->queued = 1;
-  per_cu->per_bfd->queue.emplace (per_cu, pretend_language);
+  per_cu->per_bfd->queue.emplace (per_cu, per_objfile, pretend_language);
 }
 
 /* If PER_CU is not yet queued, add it to the queue.
@@ -8917,7 +8920,8 @@ queue_comp_unit (struct dwarf2_per_cu_data *per_cu,
 
 static int
 maybe_queue_comp_unit (struct dwarf2_cu *dependent_cu,
-		       struct dwarf2_per_cu_data *per_cu,
+		       dwarf2_per_cu_data *per_cu,
+		       dwarf2_per_objfile *per_objfile,
 		       enum language pretend_language)
 {
   /* We may arrive here during partial symbol reading, if we need full
@@ -8948,7 +8952,7 @@ maybe_queue_comp_unit (struct dwarf2_cu *dependent_cu,
     }
 
   /* Add it to the queue.  */
-  queue_comp_unit (per_cu, pretend_language);
+  queue_comp_unit (per_cu, per_objfile,  pretend_language);
 
   return 1;
 }
@@ -9909,7 +9913,7 @@ process_imported_unit_die (struct die_info *die, struct dwarf2_cu *cu)
 	return;
 
       /* If necessary, add it to the queue and load its DIEs.  */
-      if (maybe_queue_comp_unit (cu, per_cu, cu->language))
+      if (maybe_queue_comp_unit (cu, per_cu, per_objfile, cu->language))
 	load_full_comp_unit (per_cu, per_objfile, false, cu->language);
 
       cu->per_cu->imported_symtabs_push (per_cu);
@@ -12823,7 +12827,7 @@ queue_and_load_dwo_tu (void **slot, void *info)
       /* We pass NULL for DEPENDENT_CU because we don't yet know if there's
 	 a real dependency of PER_CU on SIG_TYPE.  That is detected later
 	 while processing PER_CU.  */
-      if (maybe_queue_comp_unit (NULL, sig_cu, cu->language))
+      if (maybe_queue_comp_unit (NULL, sig_cu, cu->per_objfile, cu->language))
 	load_full_type_unit (sig_cu, cu->per_objfile);
       cu->per_cu->imported_symtabs_push (sig_cu);
     }
@@ -22208,7 +22212,7 @@ follow_die_offset (sect_offset sect_off, int offset_in_dwz,
 						 dwarf2_per_objfile);
 
       /* If necessary, add it to the queue and load its DIEs.  */
-      if (maybe_queue_comp_unit (cu, per_cu, cu->language))
+      if (maybe_queue_comp_unit (cu, per_cu, dwarf2_per_objfile, cu->language))
 	load_full_comp_unit (per_cu, dwarf2_per_objfile, false, cu->language);
 
       target_cu = per_cu->cu;
@@ -22571,6 +22575,8 @@ follow_die_sig_1 (struct die_info *src_die, struct signatured_type *sig_type,
   struct die_info temp_die;
   struct dwarf2_cu *sig_cu, *cu = *ref_cu;
   struct die_info *die;
+  dwarf2_per_objfile *dwarf2_per_objfile = (*ref_cu)->per_objfile;
+
 
   /* While it might be nice to assert sig_type->type == NULL here,
      we can get here for DW_AT_imported_declaration where we need
@@ -22578,8 +22584,9 @@ follow_die_sig_1 (struct die_info *src_die, struct signatured_type *sig_type,
 
   /* If necessary, add it to the queue and load its DIEs.  */
 
-  if (maybe_queue_comp_unit (*ref_cu, &sig_type->per_cu, language_minimal))
-    read_signatured_type (sig_type, (*ref_cu)->per_objfile);
+  if (maybe_queue_comp_unit (*ref_cu, &sig_type->per_cu, dwarf2_per_objfile,
+			     language_minimal))
+    read_signatured_type (sig_type, dwarf2_per_objfile);
 
   sig_cu = sig_type->per_cu.cu;
   gdb_assert (sig_cu != NULL);
@@ -22589,8 +22596,6 @@ follow_die_sig_1 (struct die_info *src_die, struct signatured_type *sig_type,
 						 to_underlying (temp_die.sect_off));
   if (die)
     {
-      struct dwarf2_per_objfile *dwarf2_per_objfile = (*ref_cu)->per_objfile;
-
       /* For .gdb_index version 7 keep track of included TUs.
 	 http://sourceware.org/bugzilla/show_bug.cgi?id=15021.  */
       if (dwarf2_per_objfile->per_bfd->index_table != NULL
@@ -23568,11 +23573,10 @@ age_cached_comp_units (struct dwarf2_per_objfile *dwarf2_per_objfile)
 /* Remove a single compilation unit from the cache.  */
 
 static void
-free_one_cached_comp_unit (struct dwarf2_per_cu_data *target_per_cu)
+free_one_cached_comp_unit (dwarf2_per_cu_data *target_per_cu,
+			   dwarf2_per_objfile *dwarf2_per_objfile)
 {
   struct dwarf2_per_cu_data *per_cu, **last_chain;
-  struct dwarf2_per_objfile *dwarf2_per_objfile
-    = target_per_cu->dwarf2_per_objfile;
 
   per_cu = dwarf2_per_objfile->per_bfd->read_in_chain;
   last_chain = &dwarf2_per_objfile->per_bfd->read_in_chain;
diff --git a/gdb/dwarf2/read.h b/gdb/dwarf2/read.h
index dda5ed71c4d..3dada4852d7 100644
--- a/gdb/dwarf2/read.h
+++ b/gdb/dwarf2/read.h
@@ -52,8 +52,10 @@ struct signatured_type;
    for.  */
 struct dwarf2_queue_item
 {
-  dwarf2_queue_item (dwarf2_per_cu_data *cu, enum language lang)
+  dwarf2_queue_item (dwarf2_per_cu_data *cu, dwarf2_per_objfile *per_objfile,
+		     enum language lang)
     : per_cu (cu),
+      per_objfile (per_objfile),
       pretend_language (lang)
   {
   }
@@ -62,7 +64,8 @@ struct dwarf2_queue_item
 
   DISABLE_COPY_AND_ASSIGN (dwarf2_queue_item);
 
-  struct dwarf2_per_cu_data *per_cu;
+  dwarf2_per_cu_data *per_cu;
+  dwarf2_per_objfile *per_objfile;
   enum language pretend_language;
 };
 
-- 
2.26.2


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

* [PATCH v2 30/42] Add dwarf2_per_objfile parameter to get_die_type_at_offset
  2020-05-12 21:08 [PATCH v2 00/42] Share DWARF partial symtabs between objfiles Simon Marchi
                   ` (28 preceding siblings ...)
  2020-05-12 21:12 ` [PATCH v2 29/42] Add dwarf2_per_objfile parameter to free_one_cached_comp_unit Simon Marchi
@ 2020-05-12 21:17 ` Simon Marchi
  2020-05-12 21:17 ` [PATCH v2 31/42] Remove leftover references to dwarf2_per_cu_data::dwarf2_per_objfile Simon Marchi
                   ` (15 subsequent siblings)
  45 siblings, 0 replies; 92+ messages in thread
From: Simon Marchi @ 2020-05-12 21:17 UTC (permalink / raw)
  To: gdb-patches

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

This allows removing some dwarf2_per_cu_data::dwarf2_per_objfile
references.

gdb/ChangeLog:

	* dwarf2/read.h (dwarf2_get_die_type): Add dwarf2_per_objfile
	parameter.
	* dwarf2/read.c (get_die_type_at_offset): Likewise.
	(read_namespace_alias): Update.
	(lookup_die_type): Update.
	(dwarf2_get_die_type): Add dwarf2_per_objfile parameter.
	* dwarf2/loc.c (class dwarf_evaluate_loc_desc) <get_base_type>:
	Update.
	(disassemble_dwarf_expression): Update.
---
 gdb/dwarf2/loc.c  | 10 +++++-----
 gdb/dwarf2/read.c | 21 ++++++++++++---------
 gdb/dwarf2/read.h |  3 ++-
 3 files changed, 19 insertions(+), 15 deletions(-)

diff --git a/gdb/dwarf2/loc.c b/gdb/dwarf2/loc.c
index a4b7edf7bff..cd304552575 100644
--- a/gdb/dwarf2/loc.c
+++ b/gdb/dwarf2/loc.c
@@ -673,7 +673,7 @@ class dwarf_evaluate_loc_desc : public dwarf_expr_context
 
   struct type *get_base_type (cu_offset die_offset, int size) override
   {
-    struct type *result = dwarf2_get_die_type (die_offset, per_cu);
+    struct type *result = dwarf2_get_die_type (die_offset, per_cu, per_objfile);
     if (result == NULL)
       error (_("Could not find type for DW_OP_const_type"));
     if (size != 0 && TYPE_LENGTH (result) != size)
@@ -4162,7 +4162,7 @@ disassemble_dwarf_expression (struct ui_file *stream,
 
 	    data = safe_read_uleb128 (data, end, &ul);
 	    cu_offset offset = (cu_offset) ul;
-	    type = dwarf2_get_die_type (offset, per_cu);
+	    type = dwarf2_get_die_type (offset, per_cu, per_objfile);
 	    fprintf_filtered (stream, "<");
 	    type_print (type, "", stream, -1);
 	    fprintf_filtered (stream, " [0x%s]> %d",
@@ -4178,7 +4178,7 @@ disassemble_dwarf_expression (struct ui_file *stream,
 
 	    data = safe_read_uleb128 (data, end, &ul);
 	    cu_offset type_die = (cu_offset) ul;
-	    type = dwarf2_get_die_type (type_die, per_cu);
+	    type = dwarf2_get_die_type (type_die, per_cu, per_objfile);
 	    fprintf_filtered (stream, "<");
 	    type_print (type, "", stream, -1);
 	    fprintf_filtered (stream, " [0x%s]>",
@@ -4202,7 +4202,7 @@ disassemble_dwarf_expression (struct ui_file *stream,
 	    data = safe_read_uleb128 (data, end, &ul);
 	    cu_offset type_die = (cu_offset) ul;
 
-	    type = dwarf2_get_die_type (type_die, per_cu);
+	    type = dwarf2_get_die_type (type_die, per_cu, per_objfile);
 	    fprintf_filtered (stream, "<");
 	    type_print (type, "", stream, -1);
 	    fprintf_filtered (stream, " [0x%s]> [$%s]",
@@ -4225,7 +4225,7 @@ disassemble_dwarf_expression (struct ui_file *stream,
 	      {
 		struct type *type;
 
-		type = dwarf2_get_die_type (type_die, per_cu);
+		type = dwarf2_get_die_type (type_die, per_cu, per_objfile);
 		fprintf_filtered (stream, "<");
 		type_print (type, "", stream, -1);
 		fprintf_filtered (stream, " [0x%s]>",
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index e8ba115fe4f..3e5f91583cb 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -1599,7 +1599,8 @@ static void dwarf2_mark (struct dwarf2_cu *);
 static void dwarf2_clear_marks (struct dwarf2_per_cu_data *);
 
 static struct type *get_die_type_at_offset (sect_offset,
-					    struct dwarf2_per_cu_data *);
+					    dwarf2_per_cu_data *per_cu,
+					    dwarf2_per_objfile *per_objfile);
 
 static struct type *get_die_type (struct die_info *die, struct dwarf2_cu *cu);
 
@@ -10556,7 +10557,7 @@ read_namespace_alias (struct die_info *die, struct dwarf2_cu *cu)
 	  struct type *type;
 	  sect_offset sect_off = attr->get_ref_die_offset ();
 
-	  type = get_die_type_at_offset (sect_off, cu->per_cu);
+	  type = get_die_type_at_offset (sect_off, cu->per_cu, cu->per_objfile);
 	  if (type != NULL && TYPE_CODE (type) == TYPE_CODE_NAMESPACE)
 	    {
 	      /* This declaration is a global namespace alias.  Add
@@ -21351,13 +21352,14 @@ lookup_die_type (struct die_info *die, const struct attribute *attr,
 
       per_cu = dwarf2_find_containing_comp_unit (sect_off, 1,
 						 dwarf2_per_objfile);
-      this_type = get_die_type_at_offset (sect_off, per_cu);
+      this_type = get_die_type_at_offset (sect_off, per_cu, dwarf2_per_objfile);
     }
   else if (attr->form_is_ref ())
     {
       sect_offset sect_off = attr->get_ref_die_offset ();
 
-      this_type = get_die_type_at_offset (sect_off, cu->per_cu);
+      this_type = get_die_type_at_offset (sect_off, cu->per_cu,
+					  dwarf2_per_objfile);
     }
   else if (attr->form == DW_FORM_ref_sig8)
     {
@@ -22557,10 +22559,11 @@ dwarf2_fetch_die_type_sect_off (sect_offset sect_off,
 
 struct type *
 dwarf2_get_die_type (cu_offset die_offset,
-		     struct dwarf2_per_cu_data *per_cu)
+		     dwarf2_per_cu_data *per_cu,
+		     dwarf2_per_objfile *per_objfile)
 {
   sect_offset die_offset_sect = per_cu->sect_off + to_underlying (die_offset);
-  return get_die_type_at_offset (die_offset_sect, per_cu);
+  return get_die_type_at_offset (die_offset_sect, per_cu, per_objfile);
 }
 
 /* Follow type unit SIG_TYPE referenced by SRC_DIE.
@@ -23750,10 +23753,10 @@ set_die_type (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
 
 static struct type *
 get_die_type_at_offset (sect_offset sect_off,
-			struct dwarf2_per_cu_data *per_cu)
+			dwarf2_per_cu_data *per_cu,
+			dwarf2_per_objfile *dwarf2_per_objfile)
 {
   struct dwarf2_per_cu_offset_and_type *slot, ofs;
-  struct dwarf2_per_objfile *dwarf2_per_objfile = per_cu->dwarf2_per_objfile;
 
   if (dwarf2_per_objfile->die_type_hash == NULL)
     return NULL;
@@ -23774,7 +23777,7 @@ get_die_type_at_offset (sect_offset sect_off,
 static struct type *
 get_die_type (struct die_info *die, struct dwarf2_cu *cu)
 {
-  return get_die_type_at_offset (die->sect_off, cu->per_cu);
+  return get_die_type_at_offset (die->sect_off, cu->per_cu, cu->per_objfile);
 }
 
 /* Add a dependence relationship from CU to REF_PER_CU.  */
diff --git a/gdb/dwarf2/read.h b/gdb/dwarf2/read.h
index 3dada4852d7..cc1fd914b6f 100644
--- a/gdb/dwarf2/read.h
+++ b/gdb/dwarf2/read.h
@@ -569,7 +569,8 @@ extern dwz_file *dwarf2_get_dwz_file (dwarf2_per_bfd *per_bfd);
    PER_CU.  */
 
 struct type *dwarf2_get_die_type (cu_offset die_offset,
-				  struct dwarf2_per_cu_data *per_cu);
+				  dwarf2_per_cu_data *per_cu,
+				  dwarf2_per_objfile *per_objfile);
 
 /* Given an index in .debug_addr, fetch the value.
    NOTE: This can be called during dwarf expression evaluation,
-- 
2.26.2


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

* [PATCH v2 31/42] Remove leftover references to dwarf2_per_cu_data::dwarf2_per_objfile
  2020-05-12 21:08 [PATCH v2 00/42] Share DWARF partial symtabs between objfiles Simon Marchi
                   ` (29 preceding siblings ...)
  2020-05-12 21:17 ` [PATCH v2 30/42] Add dwarf2_per_objfile parameter to get_die_type_at_offset Simon Marchi
@ 2020-05-12 21:17 ` Simon Marchi
  2020-05-12 21:17 ` [PATCH v2 32/42] Remove dwarf2_per_cu_data::dwarf2_per_objfile Simon Marchi
                   ` (14 subsequent siblings)
  45 siblings, 0 replies; 92+ messages in thread
From: Simon Marchi @ 2020-05-12 21:17 UTC (permalink / raw)
  To: gdb-patches; +Cc: Simon Marchi

This patch removes the remaining references to that field in obvious
ways (the same object is already available some other way in these
contexts).

gdb/ChangeLog:

	* dwarf2/read.c (process_psymtab_comp_unit): Remove reference to
	dwarf2_per_cu_data::dwarf2_per_objfile.
	(compute_compunit_symtab_includes): Likewise.
	(dwarf2_cu::start_symtab): Likewise.
---
 gdb/dwarf2/read.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 3e5f91583cb..0059e6466e5 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -7576,7 +7576,7 @@ process_psymtab_comp_unit (dwarf2_per_cu_data *this_cu,
   this_cu->lang = this_cu->cu->language;
 
   /* Age out any secondary CUs.  */
-  age_cached_comp_units (this_cu->dwarf2_per_objfile);
+  age_cached_comp_units (per_objfile);
 }
 
 /* Reader function for build_type_psymtabs.  */
@@ -9685,7 +9685,7 @@ compute_compunit_symtab_includes (dwarf2_per_cu_data *per_cu,
       /* Now we have a transitive closure of all the included symtabs.  */
       len = result_symtabs.size ();
       cust->includes
-	= XOBNEWVEC (&per_cu->dwarf2_per_objfile->objfile->objfile_obstack,
+	= XOBNEWVEC (&per_objfile->objfile->objfile_obstack,
 		     struct compunit_symtab *, len + 1);
       memcpy (cust->includes, result_symtabs.data (),
 	      len * sizeof (compunit_symtab *));
@@ -20554,7 +20554,7 @@ dwarf2_cu::start_symtab (const char *name, const char *comp_dir,
   gdb_assert (m_builder == nullptr);
 
   m_builder.reset (new struct buildsym_compunit
-		   (per_cu->dwarf2_per_objfile->objfile,
+		   (this->per_objfile->objfile,
 		    name, comp_dir, language, low_pc));
 
   list_in_scope = get_builder ()->get_file_symbols ();
-- 
2.26.2


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

* [PATCH v2 32/42] Remove dwarf2_per_cu_data::dwarf2_per_objfile
  2020-05-12 21:08 [PATCH v2 00/42] Share DWARF partial symtabs between objfiles Simon Marchi
                   ` (30 preceding siblings ...)
  2020-05-12 21:17 ` [PATCH v2 31/42] Remove leftover references to dwarf2_per_cu_data::dwarf2_per_objfile Simon Marchi
@ 2020-05-12 21:17 ` Simon Marchi
  2020-05-12 21:17 ` [PATCH v2 33/42] Split type_unit_group Simon Marchi
                   ` (13 subsequent siblings)
  45 siblings, 0 replies; 92+ messages in thread
From: Simon Marchi @ 2020-05-12 21:17 UTC (permalink / raw)
  To: gdb-patches; +Cc: Simon Marchi

Nothing references this field anymore, remove it.

gdb/ChangeLog:

	* dwarf2/read.h (struct dwarf2_per_cu_data):
	<dwarf2_per_objfile>: Remove.
	* dwarf2/read.c (create_cu_from_index_list): Don't assign
	dwarf2_per_objfile.
	(create_signatured_type_table_from_index): Likewise.
	(create_signatured_type_table_from_debug_names): Likewise.
	(create_debug_type_hash_table): Likewise.
	(fill_in_sig_entry_from_dwo_entry): Likewise.
	(create_type_unit_group): Likewise.
	(read_comp_units_from_section): Likewise.
	(create_cus_hash_table): Likewise.
---
 gdb/dwarf2/read.c | 17 ++++-------------
 gdb/dwarf2/read.h |  3 ---
 2 files changed, 4 insertions(+), 16 deletions(-)

diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 0059e6466e5..ac075396716 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -2499,7 +2499,6 @@ create_cu_from_index_list (struct dwarf2_per_objfile *dwarf2_per_objfile,
   dwarf2_per_cu_data *the_cu = dwarf2_per_objfile->per_bfd->allocate_per_cu ();
   the_cu->sect_off = sect_off;
   the_cu->length = length;
-  the_cu->dwarf2_per_objfile = dwarf2_per_objfile;
   the_cu->section = section;
   the_cu->v.quick = OBSTACK_ZALLOC (&dwarf2_per_objfile->per_bfd->obstack,
 				    struct dwarf2_per_cu_quick_data);
@@ -2591,7 +2590,6 @@ create_signatured_type_table_from_index
       sig_type->per_cu.is_debug_types = 1;
       sig_type->per_cu.section = section;
       sig_type->per_cu.sect_off = sect_off;
-      sig_type->per_cu.dwarf2_per_objfile = dwarf2_per_objfile;
       sig_type->per_cu.v.quick
 	= OBSTACK_ZALLOC (&dwarf2_per_objfile->per_bfd->obstack,
 			  struct dwarf2_per_cu_quick_data);
@@ -2647,7 +2645,6 @@ create_signatured_type_table_from_debug_names
       sig_type->per_cu.is_debug_types = 1;
       sig_type->per_cu.section = section;
       sig_type->per_cu.sect_off = sect_off;
-      sig_type->per_cu.dwarf2_per_objfile = dwarf2_per_objfile;
       sig_type->per_cu.v.quick
 	= OBSTACK_ZALLOC (&dwarf2_per_objfile->per_bfd->obstack,
 			  struct dwarf2_per_cu_quick_data);
@@ -6299,7 +6296,6 @@ create_debug_type_hash_table (struct dwarf2_per_objfile *dwarf2_per_objfile,
 	  sig_type = dwarf2_per_objfile->per_bfd->allocate_signatured_type ();
 	  sig_type->signature = header.signature;
 	  sig_type->type_offset_in_tu = header.type_cu_offset_in_tu;
-	  sig_type->per_cu.dwarf2_per_objfile = dwarf2_per_objfile;
 	  sig_type->per_cu.is_debug_types = 1;
 	  sig_type->per_cu.section = section;
 	  sig_type->per_cu.sect_off = sect_off;
@@ -6465,7 +6461,6 @@ fill_in_sig_entry_from_dwo_entry (struct dwarf2_per_objfile *dwarf2_per_objfile,
   sig_entry->per_cu.sect_off = dwo_entry->sect_off;
   sig_entry->per_cu.length = dwo_entry->length;
   sig_entry->per_cu.reading_dwo_directly = 1;
-  sig_entry->per_cu.dwarf2_per_objfile = dwarf2_per_objfile;
   sig_entry->per_cu.per_bfd = per_bfd;
   sig_entry->type_offset_in_tu = dwo_entry->type_offset_in_tu;
   sig_entry->dwo_unit = dwo_entry;
@@ -7281,7 +7276,6 @@ create_type_unit_group (struct dwarf2_cu *cu, sect_offset line_offset_struct)
   tu_group = OBSTACK_ZALLOC (&dwarf2_per_objfile->per_bfd->obstack,
 			     struct type_unit_group);
   per_cu = &tu_group->per_cu;
-  per_cu->dwarf2_per_objfile = dwarf2_per_objfile;
   per_cu->per_bfd = per_bfd;
 
   if (per_bfd->using_index)
@@ -8031,7 +8025,6 @@ read_comp_units_from_section (struct dwarf2_per_objfile *dwarf2_per_objfile,
       this_cu->sect_off = sect_off;
       this_cu->length = cu_header.length + cu_header.initial_length_size;
       this_cu->is_dwz = is_dwz;
-      this_cu->dwarf2_per_objfile = dwarf2_per_objfile;
       this_cu->section = section;
 
       dwarf2_per_objfile->per_bfd->all_comp_units.push_back (this_cu);
@@ -11311,7 +11304,6 @@ create_cus_hash_table (struct dwarf2_per_objfile *dwarf2_per_objfile,
       sect_offset sect_off = (sect_offset) (info_ptr - section.buffer);
 
       memset (&per_cu, 0, sizeof (per_cu));
-      per_cu.dwarf2_per_objfile = dwarf2_per_objfile;
       per_cu.per_bfd = per_bfd;
       per_cu.is_debug_types = 0;
       per_cu.sect_off = sect_offset (info_ptr - section.buffer);
@@ -14373,8 +14365,7 @@ handle_data_member_location (struct die_info *die, struct dwarf2_cu *cu,
 	    SET_FIELD_BITPOS (*field, offset * bits_per_byte);
 	  else
 	    {
-	      struct objfile *objfile
-		= cu->per_cu->dwarf2_per_objfile->objfile;
+	      struct objfile *objfile = cu->per_objfile->objfile;
 	      struct dwarf2_locexpr_baton *dlbaton
 		= XOBNEW (&objfile->objfile_obstack,
 			  struct dwarf2_locexpr_baton);
@@ -14820,7 +14811,7 @@ add_variant_property (struct field_info *fip, struct type *type,
   for (int i = 0; i < fip->fields.size (); ++i)
     offset_map[fip->fields[i].offset] = i;
 
-  struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+  struct objfile *objfile = cu->per_objfile->objfile;
   gdb::array_view<variant_part> parts
     = create_variant_parts (&objfile->objfile_obstack, offset_map, fip,
 			    fip->variant_parts);
@@ -15545,7 +15536,7 @@ handle_variant_part (struct die_info *die, struct type *type,
       complaint (_("nested DW_TAG_variant_part seen "
 		   "- DIE at %s [in module %s]"),
 		 sect_offset_str (die->sect_off),
-		 objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
+		 objfile_name (cu->per_objfile->objfile));
       return;
     }
   else
@@ -15577,7 +15568,7 @@ handle_variant_part (struct die_info *die, struct type *type,
       complaint (_("DW_AT_discr does not have DIE reference form"
 		   " - DIE at %s [in module %s]"),
 		 sect_offset_str (die->sect_off),
-		 objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
+		 objfile_name (cu->per_objfile->objfile));
     }
 
   for (die_info *child_die = die->child;
diff --git a/gdb/dwarf2/read.h b/gdb/dwarf2/read.h
index cc1fd914b6f..0a94036f4e9 100644
--- a/gdb/dwarf2/read.h
+++ b/gdb/dwarf2/read.h
@@ -419,9 +419,6 @@ struct dwarf2_per_cu_data
   /* The language of this CU.  */
   enum language lang;
 
-  /* The corresponding dwarf2_per_objfile.  */
-  struct dwarf2_per_objfile *dwarf2_per_objfile;
-
   /* Backlink to the owner of this.  */
   dwarf2_per_bfd *per_bfd;
 
-- 
2.26.2


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

* [PATCH v2 33/42] Split type_unit_group
  2020-05-12 21:08 [PATCH v2 00/42] Share DWARF partial symtabs between objfiles Simon Marchi
                   ` (31 preceding siblings ...)
  2020-05-12 21:17 ` [PATCH v2 32/42] Remove dwarf2_per_cu_data::dwarf2_per_objfile Simon Marchi
@ 2020-05-12 21:17 ` Simon Marchi
  2020-05-13  9:54   ` Tom de Vries
  2020-05-12 21:17 ` [PATCH v2 34/42] Move signatured_type::type to unshareable object Simon Marchi
                   ` (12 subsequent siblings)
  45 siblings, 1 reply; 92+ messages in thread
From: Simon Marchi @ 2020-05-12 21:17 UTC (permalink / raw)
  To: gdb-patches; +Cc: Tom Tromey

From: Tom Tromey <tom@tromey.com>

type_unit_group has links to the compunit_symtab and other symtabs.
However, once this object is shared across objfiles, this will no
longer be ok.

This patch introduces a new type_unit_group_unshareable and arranges to
store a map from type unit groups to type_unit_group_unshareable objects
in dwarf2_per_objfile.

YYYY-MM-DD  Tom Tromey  <tom@tromey.com>
YYYY-MM-DD  Simon Marchi  <simon.marchi@efficios.com>

	* dwarf2/read.h (struct type_unit_group_unshareable): New.
	(struct dwarf2_per_objfile) <type_units>: New member.
	<get_type_unit_group_unshareable>: New method.
	* dwarf2/read.c (struct type_unit_group) <compunit_symtab,
	num_symtabs, symtabs>: Remove; move to
	type_unit_group_unshareable.
	(dwarf2_per_objfile::get_type_unit_group_unshareable): New.
	(process_full_type_unit, dwarf2_cu::setup_type_unit_groups)
	(dwarf2_cu::setup_type_unit_groups): Use type_unit_group_unshareable.
---
 gdb/dwarf2/read.c | 58 ++++++++++++++++++++++++++---------------------
 gdb/dwarf2/read.h | 38 +++++++++++++++++++++++++++++++
 2 files changed, 70 insertions(+), 26 deletions(-)

diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index ac075396716..9a9fd05ec26 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -614,7 +614,9 @@ struct stmt_list_hash
 };
 
 /* Each element of dwarf2_per_bfd->type_unit_groups is a pointer to
-   an object of this type.  */
+   an object of this type.  This contains elements of type unit groups
+   that can be shared across objfiles.  The non-shareable parts are in 
+   type_unit_group_unshareable.  */
 
 struct type_unit_group
 {
@@ -629,23 +631,8 @@ struct type_unit_group
      and is deleted afterwards and not used again.  */
   std::vector<signatured_type *> *tus;
 
-  /* The compunit symtab.
-     Type units in a group needn't all be defined in the same source file,
-     so we create an essentially anonymous symtab as the compunit symtab.  */
-  struct compunit_symtab *compunit_symtab;
-
   /* The data used to construct the hash key.  */
   struct stmt_list_hash hash;
-
-  /* The symbol tables for this TU (obtained from the files listed in
-     DW_AT_stmt_list).
-     WARNING: The order of entries here must match the order of entries
-     in the line header.  After the first TU using this type_unit_group, the
-     line header for the subsequent TUs is recreated from this.  This is done
-     because we need to use the same symtabs for each TU using the same
-     DW_AT_stmt_list value.  Also note that symtabs may be repeated here,
-     there's no guarantee the line header doesn't have duplicate entries.  */
-  struct symtab **symtabs;
 };
 
 /* These sections are what may appear in a (real or virtual) DWO file.  */
@@ -9590,6 +9577,21 @@ rust_union_quirks (struct dwarf2_cu *cu)
   cu->rust_unions.clear ();
 }
 
+/* See read.h.  */
+
+type_unit_group_unshareable *
+dwarf2_per_objfile::get_type_unit_group_unshareable (type_unit_group *tu_group)
+{
+  auto iter = this->m_type_units.find (tu_group);
+  if (iter != this->m_type_units.end ())
+    return iter->second.get ();
+
+  type_unit_group_unshareable_up uniq (new type_unit_group_unshareable);
+  type_unit_group_unshareable *result = uniq.get ();
+  this->m_type_units[tu_group] = std::move (uniq);
+  return result;
+}
+
 /* A helper function for computing the list of all symbol tables
    included by PER_CU.  */
 
@@ -9845,11 +9847,13 @@ process_full_type_unit (dwarf2_per_cu_data *per_cu,
      If this is the first TU to use this symtab, complete the construction
      of it with end_expandable_symtab.  Otherwise, complete the addition of
      this TU's symbols to the existing symtab.  */
-  if (sig_type->type_unit_group->compunit_symtab == NULL)
+  type_unit_group_unshareable *tug_unshare =
+    dwarf2_per_objfile->get_type_unit_group_unshareable (sig_type->type_unit_group);
+  if (tug_unshare->compunit_symtab == NULL)
     {
       buildsym_compunit *builder = cu->get_builder ();
       cust = builder->end_expandable_symtab (0, SECT_OFF_TEXT (objfile));
-      sig_type->type_unit_group->compunit_symtab = cust;
+      tug_unshare->compunit_symtab = cust;
 
       if (cust != NULL)
 	{
@@ -9865,7 +9869,7 @@ process_full_type_unit (dwarf2_per_cu_data *per_cu,
   else
     {
       cu->get_builder ()->augment_type_symtab ();
-      cust = sig_type->type_unit_group->compunit_symtab;
+      cust = tug_unshare->compunit_symtab;
     }
 
   dwarf2_per_objfile->set_symtab (per_cu, cust);
@@ -11004,7 +11008,9 @@ dwarf2_cu::setup_type_unit_groups (struct die_info *die)
      do it again, we could fake it and just recreate the part we need
      (file name,index -> symtab mapping).  If data shows this optimization
      is useful we can do it then.  */
-  first_time = tu_group->compunit_symtab == NULL;
+  type_unit_group_unshareable *tug_unshare
+    = per_objfile->get_type_unit_group_unshareable (tu_group);
+  first_time = tug_unshare->compunit_symtab == NULL;
 
   /* We have to handle the case of both a missing DW_AT_stmt_list or bad
      debug info.  */
@@ -11020,9 +11026,9 @@ dwarf2_cu::setup_type_unit_groups (struct die_info *die)
 	start_symtab ("", NULL, 0);
       else
 	{
-	  gdb_assert (tu_group->symtabs == NULL);
+	  gdb_assert (tug_unshare->symtabs == NULL);
 	  gdb_assert (m_builder == nullptr);
-	  struct compunit_symtab *cust = tu_group->compunit_symtab;
+	  struct compunit_symtab *cust = tug_unshare->compunit_symtab;
 	  m_builder.reset (new struct buildsym_compunit
 			   (COMPUNIT_OBJFILE (cust), "",
 			    COMPUNIT_DIRNAME (cust),
@@ -11045,7 +11051,7 @@ dwarf2_cu::setup_type_unit_groups (struct die_info *die)
 	 process_full_type_unit still needs to know if this is the first
 	 time.  */
 
-      tu_group->symtabs
+      tug_unshare->symtabs
 	= XOBNEWVEC (&COMPUNIT_OBJFILE (cust)->objfile_obstack,
 		     struct symtab *, line_header->file_names_size ());
 
@@ -11068,13 +11074,13 @@ dwarf2_cu::setup_type_unit_groups (struct die_info *die)
 	    }
 
 	  fe.symtab = b->get_current_subfile ()->symtab;
-	  tu_group->symtabs[i] = fe.symtab;
+	  tug_unshare->symtabs[i] = fe.symtab;
 	}
     }
   else
     {
       gdb_assert (m_builder == nullptr);
-      struct compunit_symtab *cust = tu_group->compunit_symtab;
+      struct compunit_symtab *cust = tug_unshare->compunit_symtab;
       m_builder.reset (new struct buildsym_compunit
 		       (COMPUNIT_OBJFILE (cust), "",
 			COMPUNIT_DIRNAME (cust),
@@ -11086,7 +11092,7 @@ dwarf2_cu::setup_type_unit_groups (struct die_info *die)
       for (i = 0; i < file_names.size (); ++i)
 	{
 	  file_entry &fe = file_names[i];
-	  fe.symtab = tu_group->symtabs[i];
+	  fe.symtab = tug_unshare->symtabs[i];
 	}
     }
 
diff --git a/gdb/dwarf2/read.h b/gdb/dwarf2/read.h
index 0a94036f4e9..13d31a97d3d 100644
--- a/gdb/dwarf2/read.h
+++ b/gdb/dwarf2/read.h
@@ -47,6 +47,7 @@ struct dwarf2_per_cu_data;
 struct mapped_index;
 struct mapped_debug_names;
 struct signatured_type;
+struct type_unit_group;
 
 /* One item on the queue of compilation units to read in full symbols
    for.  */
@@ -265,6 +266,30 @@ struct dwarf2_per_bfd
   size_t m_num_psymtabs = 0;
 };
 
+/* This is the per-objfile data associated with a type_unit_group.  */
+
+struct type_unit_group_unshareable
+{
+  /* The compunit symtab.
+     Type units in a group needn't all be defined in the same source file,
+     so we create an essentially anonymous symtab as the compunit symtab.  */
+  struct compunit_symtab *compunit_symtab = nullptr;
+
+  /* The number of symtabs from the line header.
+     The value here must match line_header.num_file_names.  */
+  unsigned int num_symtabs = 0;
+
+  /* The symbol tables for this TU (obtained from the files listed in
+     DW_AT_stmt_list).
+     WARNING: The order of entries here must match the order of entries
+     in the line header.  After the first TU using this type_unit_group, the
+     line header for the subsequent TUs is recreated from this.  This is done
+     because we need to use the same symtabs for each TU using the same
+     DW_AT_stmt_list value.  Also note that symtabs may be repeated here,
+     there's no guarantee the line header doesn't have duplicate entries.  */
+  struct symtab **symtabs = nullptr;
+};
+
 /* Collection of data recorded per objfile.
    This hangs off of dwarf2_objfile_data_key.
 
@@ -304,6 +329,11 @@ struct dwarf2_per_objfile
   /* Set the compunit_symtab associated to PER_CU.  */
   void set_symtab (const dwarf2_per_cu_data *per_cu, compunit_symtab *symtab);
 
+/* Get the type_unit_group_unshareable corresponding to TU_GROUP.  If one
+   does not exist, create it.  */
+  type_unit_group_unshareable *get_type_unit_group_unshareable
+    (type_unit_group *tu_group);
+
   /* Find an integer type SIZE_IN_BYTES bytes in size and return it.
      UNSIGNED_P controls if the integer is unsigned or not.  */
   struct type *int_type (int size_in_bytes, bool unsigned_p) const;
@@ -325,6 +355,14 @@ struct dwarf2_per_objfile
      is indexed by dwarf2_per_cu_data::index.  A NULL value means
      that the CU/TU has not been expanded yet.  */
   std::vector<compunit_symtab *> m_symtabs;
+
+  /* Map from a type unit group to the corresponding unshared
+     structure.  */
+  typedef std::unique_ptr<type_unit_group_unshareable>
+    type_unit_group_unshareable_up;
+
+  std::unordered_map<type_unit_group *, type_unit_group_unshareable_up>
+    m_type_units;
 };
 
 /* Get the dwarf2_per_objfile associated to OBJFILE.  */
-- 
2.26.2


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

* [PATCH v2 34/42] Move signatured_type::type to unshareable object
  2020-05-12 21:08 [PATCH v2 00/42] Share DWARF partial symtabs between objfiles Simon Marchi
                   ` (32 preceding siblings ...)
  2020-05-12 21:17 ` [PATCH v2 33/42] Split type_unit_group Simon Marchi
@ 2020-05-12 21:17 ` Simon Marchi
  2020-05-12 21:17 ` [PATCH v2 35/42] Pass dwarf2_per_bfd instead of dwarf2_per_objfile to some index-related functions Simon Marchi
                   ` (11 subsequent siblings)
  45 siblings, 0 replies; 92+ messages in thread
From: Simon Marchi @ 2020-05-12 21:17 UTC (permalink / raw)
  To: gdb-patches; +Cc: Tom Tromey

From: Tom Tromey <tom@tromey.com>

signatured_type has a link to the "struct type".  However, types are
inherently objfile-specific, so once sharing is implemented, this will
be incorrect.

This patch moves the type to a new map in the DWARF unshareable
object.

YYYY-MM-DD  Tom Tromey  <tom@tromey.com>
YYYY-MM-DD  Simon Marchi  <simon.marchi@efficios.com>

	* dwarf2/read.h (struct dwarf2_per_objfile)
	<get_type_for_signatured_type, set_type_for_signatured_type>:
	New methods.
	<m_type_map>: New member.
	(struct signatured_type) <type>: Remove.
	* dwarf2/read.c
	(dwarf2_per_objfile::get_type_for_signatured_type,
	dwarf2_per_objfile::set_type_for_signatured_type): New.
	(get_signatured_type): Use new methods.
---
 gdb/dwarf2/read.c | 27 ++++++++++++++++++++++++---
 gdb/dwarf2/read.h | 17 ++++++++++-------
 2 files changed, 34 insertions(+), 10 deletions(-)

diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 9a9fd05ec26..853dd5884a4 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -9592,6 +9592,25 @@ dwarf2_per_objfile::get_type_unit_group_unshareable (type_unit_group *tu_group)
   return result;
 }
 
+struct type *
+dwarf2_per_objfile::get_type_for_signatured_type
+  (signatured_type *sig_type) const
+{
+  auto iter = this->m_type_map.find (sig_type);
+  if (iter == this->m_type_map.end ())
+    return nullptr;
+
+  return iter->second;
+}
+
+void dwarf2_per_objfile::set_type_for_signatured_type
+  (signatured_type *sig_type, struct type *type)
+{
+  gdb_assert (this->m_type_map.find (sig_type) == this->m_type_map.end ());
+
+  this->m_type_map[sig_type] = type;
+}
+
 /* A helper function for computing the list of all symbol tables
    included by PER_CU.  */
 
@@ -22680,8 +22699,9 @@ get_signatured_type (struct die_info *die, ULONGEST signature,
     }
 
   /* If we already know the type we're done.  */
-  if (sig_type->type != NULL)
-    return sig_type->type;
+  type = dwarf2_per_objfile->get_type_for_signatured_type (sig_type);
+  if (type != nullptr)
+    return type;
 
   type_cu = cu;
   type_die = follow_die_sig_1 (die, sig_type, &type_cu);
@@ -22708,7 +22728,8 @@ get_signatured_type (struct die_info *die, ULONGEST signature,
 		 objfile_name (dwarf2_per_objfile->objfile));
       type = build_error_marker_type (cu, die);
     }
-  sig_type->type = type;
+
+  dwarf2_per_objfile->set_type_for_signatured_type (sig_type, type);
 
   return type;
 }
diff --git a/gdb/dwarf2/read.h b/gdb/dwarf2/read.h
index 13d31a97d3d..3500b0e7ba9 100644
--- a/gdb/dwarf2/read.h
+++ b/gdb/dwarf2/read.h
@@ -329,11 +329,16 @@ struct dwarf2_per_objfile
   /* Set the compunit_symtab associated to PER_CU.  */
   void set_symtab (const dwarf2_per_cu_data *per_cu, compunit_symtab *symtab);
 
-/* Get the type_unit_group_unshareable corresponding to TU_GROUP.  If one
-   does not exist, create it.  */
+  /* Get the type_unit_group_unshareable corresponding to TU_GROUP.  If one
+     does not exist, create it.  */
   type_unit_group_unshareable *get_type_unit_group_unshareable
     (type_unit_group *tu_group);
 
+  struct type *get_type_for_signatured_type (signatured_type *sig_type) const;
+
+  void set_type_for_signatured_type (signatured_type *sig_type,
+				     struct type *type);
+
   /* Find an integer type SIZE_IN_BYTES bytes in size and return it.
      UNSIGNED_P controls if the integer is unsigned or not.  */
   struct type *int_type (int size_in_bytes, bool unsigned_p) const;
@@ -363,6 +368,9 @@ struct dwarf2_per_objfile
 
   std::unordered_map<type_unit_group *, type_unit_group_unshareable_up>
     m_type_units;
+
+  /* Map from signatured types to the corresponding struct type.  */
+  std::unordered_map<signatured_type *, struct type *> m_type_map;
 };
 
 /* Get the dwarf2_per_objfile associated to OBJFILE.  */
@@ -584,11 +592,6 @@ struct signatured_type
      can share them.  This points to the containing symtab.  */
   struct type_unit_group *type_unit_group;
 
-  /* The type.
-     The first time we encounter this type we fully read it in and install it
-     in the symbol tables.  Subsequent times we only need the type.  */
-  struct type *type;
-
   /* Containing DWO unit.
      This field is valid iff per_cu.reading_dwo_directly.  */
   struct dwo_unit *dwo_unit;
-- 
2.26.2


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

* [PATCH v2 35/42] Pass dwarf2_per_bfd instead of dwarf2_per_objfile to some index-related functions
  2020-05-12 21:08 [PATCH v2 00/42] Share DWARF partial symtabs between objfiles Simon Marchi
                   ` (33 preceding siblings ...)
  2020-05-12 21:17 ` [PATCH v2 34/42] Move signatured_type::type to unshareable object Simon Marchi
@ 2020-05-12 21:17 ` Simon Marchi
  2020-05-12 21:17 ` [PATCH v2 36/42] Pass dwarf2_cu to process_full_{comp,type}_unit Simon Marchi
                   ` (10 subsequent siblings)
  45 siblings, 0 replies; 92+ messages in thread
From: Simon Marchi @ 2020-05-12 21:17 UTC (permalink / raw)
  To: gdb-patches

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

All these functions actually only need to receive a dwarf2_per_bfd, pass
that instead of dwarf2_per_objfile.

gdb/ChangeLog:

	* dwarf2/read.c (create_cu_from_index_list): Replace
	dwarf2_per_objfile parameter with dwarf2_per_bfd.
	(create_cus_from_index_list): Likewise.
	(create_cus_from_index): Likewise.
	(create_signatured_type_table_from_index): Likewise.
	(create_cus_from_debug_names_list): Likewise.
	(create_cus_from_debug_names): Likewise.
	(dwarf2_read_gdb_index): Update.
	(dwarf2_read_debug_names): Update.
---
 gdb/dwarf2/read.c | 90 ++++++++++++++++++++++-------------------------
 1 file changed, 43 insertions(+), 47 deletions(-)

diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 853dd5884a4..5eb32a162b6 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -2474,20 +2474,20 @@ dwarf2_per_bfd::allocate_signatured_type ()
   return result;
 }
 
-/* Return a new dwarf2_per_cu_data allocated on the dwarf2_per_objfile
+/* Return a new dwarf2_per_cu_data allocated on the per-bfd
    obstack, and constructed with the specified field values.  */
 
 static dwarf2_per_cu_data *
-create_cu_from_index_list (struct dwarf2_per_objfile *dwarf2_per_objfile,
-                          struct dwarf2_section_info *section,
-                          int is_dwz,
-                          sect_offset sect_off, ULONGEST length)
+create_cu_from_index_list (dwarf2_per_bfd *per_bfd,
+			   struct dwarf2_section_info *section,
+			   int is_dwz,
+			   sect_offset sect_off, ULONGEST length)
 {
-  dwarf2_per_cu_data *the_cu = dwarf2_per_objfile->per_bfd->allocate_per_cu ();
+  dwarf2_per_cu_data *the_cu = per_bfd->allocate_per_cu ();
   the_cu->sect_off = sect_off;
   the_cu->length = length;
   the_cu->section = section;
-  the_cu->v.quick = OBSTACK_ZALLOC (&dwarf2_per_objfile->per_bfd->obstack,
+  the_cu->v.quick = OBSTACK_ZALLOC (&per_bfd->obstack,
 				    struct dwarf2_per_cu_quick_data);
   the_cu->is_dwz = is_dwz;
   return the_cu;
@@ -2497,7 +2497,7 @@ create_cu_from_index_list (struct dwarf2_per_objfile *dwarf2_per_objfile,
    CUs.  */
 
 static void
-create_cus_from_index_list (struct dwarf2_per_objfile *dwarf2_per_objfile,
+create_cus_from_index_list (dwarf2_per_bfd *per_bfd,
 			    const gdb_byte *cu_list, offset_type n_elements,
 			    struct dwarf2_section_info *section,
 			    int is_dwz)
@@ -2512,32 +2512,31 @@ create_cus_from_index_list (struct dwarf2_per_objfile *dwarf2_per_objfile,
       cu_list += 2 * 8;
 
       dwarf2_per_cu_data *per_cu
-	= create_cu_from_index_list (dwarf2_per_objfile, section, is_dwz,
-				     sect_off, length);
-      dwarf2_per_objfile->per_bfd->all_comp_units.push_back (per_cu);
+	= create_cu_from_index_list (per_bfd, section, is_dwz, sect_off,
+				     length);
+      per_bfd->all_comp_units.push_back (per_cu);
     }
 }
 
 /* Read the CU list from the mapped index, and use it to create all
-   the CU objects for this objfile.  */
+   the CU objects for PER_BFD.  */
 
 static void
-create_cus_from_index (struct dwarf2_per_objfile *dwarf2_per_objfile,
+create_cus_from_index (dwarf2_per_bfd *per_bfd,
 		       const gdb_byte *cu_list, offset_type cu_list_elements,
 		       const gdb_byte *dwz_list, offset_type dwz_elements)
 {
-  gdb_assert (dwarf2_per_objfile->per_bfd->all_comp_units.empty ());
-  dwarf2_per_objfile->per_bfd->all_comp_units.reserve
-    ((cu_list_elements + dwz_elements) / 2);
+  gdb_assert (per_bfd->all_comp_units.empty ());
+  per_bfd->all_comp_units.reserve ((cu_list_elements + dwz_elements) / 2);
 
-  create_cus_from_index_list (dwarf2_per_objfile, cu_list, cu_list_elements,
-			      &dwarf2_per_objfile->per_bfd->info, 0);
+  create_cus_from_index_list (per_bfd, cu_list, cu_list_elements,
+			      &per_bfd->info, 0);
 
   if (dwz_elements == 0)
     return;
 
-  dwz_file *dwz = dwarf2_get_dwz_file (dwarf2_per_objfile->per_bfd);
-  create_cus_from_index_list (dwarf2_per_objfile, dwz_list, dwz_elements,
+  dwz_file *dwz = dwarf2_get_dwz_file (per_bfd);
+  create_cus_from_index_list (per_bfd, dwz_list, dwz_elements,
 			      &dwz->info, 1);
 }
 
@@ -2545,13 +2544,11 @@ create_cus_from_index (struct dwarf2_per_objfile *dwarf2_per_objfile,
 
 static void
 create_signatured_type_table_from_index
-  (struct dwarf2_per_objfile *dwarf2_per_objfile,
-   struct dwarf2_section_info *section,
-   const gdb_byte *bytes,
-   offset_type elements)
+  (dwarf2_per_bfd *per_bfd, struct dwarf2_section_info *section,
+   const gdb_byte *bytes, offset_type elements)
 {
-  gdb_assert (dwarf2_per_objfile->per_bfd->all_type_units.empty ());
-  dwarf2_per_objfile->per_bfd->all_type_units.reserve (elements / 3);
+  gdb_assert (per_bfd->all_type_units.empty ());
+  per_bfd->all_type_units.reserve (elements / 3);
 
   htab_up sig_types_hash = allocate_signatured_type_table ();
 
@@ -2571,23 +2568,23 @@ create_signatured_type_table_from_index
       signature = extract_unsigned_integer (bytes + 16, 8, BFD_ENDIAN_LITTLE);
       bytes += 3 * 8;
 
-      sig_type = dwarf2_per_objfile->per_bfd->allocate_signatured_type ();
+      sig_type = per_bfd->allocate_signatured_type ();
       sig_type->signature = signature;
       sig_type->type_offset_in_tu = type_offset_in_tu;
       sig_type->per_cu.is_debug_types = 1;
       sig_type->per_cu.section = section;
       sig_type->per_cu.sect_off = sect_off;
       sig_type->per_cu.v.quick
-	= OBSTACK_ZALLOC (&dwarf2_per_objfile->per_bfd->obstack,
+	= OBSTACK_ZALLOC (&per_bfd->obstack,
 			  struct dwarf2_per_cu_quick_data);
 
       slot = htab_find_slot (sig_types_hash.get (), sig_type, INSERT);
       *slot = sig_type;
 
-      dwarf2_per_objfile->per_bfd->all_type_units.push_back (sig_type);
+      per_bfd->all_type_units.push_back (sig_type);
     }
 
-  dwarf2_per_objfile->per_bfd->signatured_types = std::move (sig_types_hash);
+  per_bfd->signatured_types = std::move (sig_types_hash);
 }
 
 /* Create the signatured type hash table from .debug_names.  */
@@ -3106,7 +3103,7 @@ dwarf2_read_gdb_index
 	}
     }
 
-  create_cus_from_index (dwarf2_per_objfile, cu_list, cu_list_elements,
+  create_cus_from_index (dwarf2_per_objfile->per_bfd, cu_list, cu_list_elements,
 			 dwz_list, dwz_list_elements);
 
   if (types_list_elements)
@@ -3118,8 +3115,9 @@ dwarf2_read_gdb_index
 
       dwarf2_section_info *section = &dwarf2_per_objfile->per_bfd->types[0];
 
-      create_signatured_type_table_from_index (dwarf2_per_objfile, section,
-					       types_list, types_list_elements);
+      create_signatured_type_table_from_index (dwarf2_per_objfile->per_bfd,
+					       section, types_list,
+					       types_list_elements);
     }
 
   create_addrmap_from_index (dwarf2_per_objfile, map.get ());
@@ -5079,7 +5077,7 @@ read_debug_names_from_section (struct objfile *objfile,
    list.  */
 
 static void
-create_cus_from_debug_names_list (struct dwarf2_per_objfile *dwarf2_per_objfile,
+create_cus_from_debug_names_list (dwarf2_per_bfd *per_bfd,
 				  const mapped_debug_names &map,
 				  dwarf2_section_info &section,
 				  bool is_dwz)
@@ -5098,9 +5096,8 @@ create_cus_from_debug_names_list (struct dwarf2_per_objfile *dwarf2_per_objfile,
 	   the next CU as end of this CU.  We create the CUs here with length 0,
 	   and in cutu_reader::cutu_reader we'll fill in the actual length.  */
 	dwarf2_per_cu_data *per_cu
-	  = create_cu_from_index_list (dwarf2_per_objfile, &section, is_dwz,
-				       sect_off, 0);
-	dwarf2_per_objfile->per_bfd->all_comp_units.push_back (per_cu);
+	  = create_cu_from_index_list (per_bfd, &section, is_dwz, sect_off, 0);
+	per_bfd->all_comp_units.push_back (per_cu);
       }
     }
 
@@ -5122,9 +5119,9 @@ create_cus_from_debug_names_list (struct dwarf2_per_objfile *dwarf2_per_objfile,
 	{
 	  const ULONGEST length = sect_off_next - sect_off_prev;
 	  dwarf2_per_cu_data *per_cu
-	    = create_cu_from_index_list (dwarf2_per_objfile, &section, is_dwz,
+	    = create_cu_from_index_list (per_bfd, &section, is_dwz,
 					 sect_off_prev, length);
-	  dwarf2_per_objfile->per_bfd->all_comp_units.push_back (per_cu);
+	  per_bfd->all_comp_units.push_back (per_cu);
 	}
       sect_off_prev = sect_off_next;
     }
@@ -5134,22 +5131,21 @@ create_cus_from_debug_names_list (struct dwarf2_per_objfile *dwarf2_per_objfile,
    the CU objects for this dwarf2_per_objfile.  */
 
 static void
-create_cus_from_debug_names (struct dwarf2_per_objfile *dwarf2_per_objfile,
+create_cus_from_debug_names (dwarf2_per_bfd *per_bfd,
 			     const mapped_debug_names &map,
 			     const mapped_debug_names &dwz_map)
 {
-  gdb_assert (dwarf2_per_objfile->per_bfd->all_comp_units.empty ());
-  dwarf2_per_objfile->per_bfd->all_comp_units.reserve (map.cu_count + dwz_map.cu_count);
+  gdb_assert (per_bfd->all_comp_units.empty ());
+  per_bfd->all_comp_units.reserve (map.cu_count + dwz_map.cu_count);
 
-  create_cus_from_debug_names_list (dwarf2_per_objfile, map,
-				    dwarf2_per_objfile->per_bfd->info,
+  create_cus_from_debug_names_list (per_bfd, map, per_bfd->info,
 				    false /* is_dwz */);
 
   if (dwz_map.cu_count == 0)
     return;
 
-  dwz_file *dwz = dwarf2_get_dwz_file (dwarf2_per_objfile->per_bfd);
-  create_cus_from_debug_names_list (dwarf2_per_objfile, dwz_map, dwz->info,
+  dwz_file *dwz = dwarf2_get_dwz_file (per_bfd);
+  create_cus_from_debug_names_list (per_bfd, dwz_map, dwz->info,
 				    true /* is_dwz */);
 }
 
@@ -5188,7 +5184,7 @@ dwarf2_read_debug_names (struct dwarf2_per_objfile *dwarf2_per_objfile)
 	}
     }
 
-  create_cus_from_debug_names (dwarf2_per_objfile, *map, dwz_map);
+  create_cus_from_debug_names (dwarf2_per_objfile->per_bfd, *map, dwz_map);
 
   if (map->tu_count != 0)
     {
-- 
2.26.2


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

* [PATCH v2 36/42] Pass dwarf2_cu to process_full_{comp,type}_unit
  2020-05-12 21:08 [PATCH v2 00/42] Share DWARF partial symtabs between objfiles Simon Marchi
                   ` (34 preceding siblings ...)
  2020-05-12 21:17 ` [PATCH v2 35/42] Pass dwarf2_per_bfd instead of dwarf2_per_objfile to some index-related functions Simon Marchi
@ 2020-05-12 21:17 ` Simon Marchi
  2020-05-12 21:17 ` [PATCH v2 37/42] Make load_cu return the loaded dwarf2_cu Simon Marchi
                   ` (9 subsequent siblings)
  45 siblings, 0 replies; 92+ messages in thread
From: Simon Marchi @ 2020-05-12 21:17 UTC (permalink / raw)
  To: gdb-patches

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

These two functions work on a dwarf2_cu.  It is currently obtained from
the per_cu->cu link, which we want to remove.  Make them accept the
dwarf2_cu directly as a parameter.  This moves the per_cu->cu references
one level up, but that one will be removed too in a subsequent patch.

gdb/ChangeLog:

	* dwarf2/read.c (process_full_comp_unit,
	process_full_type_unit): Remove per_cu, per_objfile paramters.
	Add dwarf2_cu parameter.
	(process_queue): Update.
---
 gdb/dwarf2/read.c | 37 +++++++++++++++----------------------
 1 file changed, 15 insertions(+), 22 deletions(-)

diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 5eb32a162b6..68d7efaf549 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -1570,12 +1570,10 @@ static void load_full_comp_unit (dwarf2_per_cu_data *per_cu,
 				 bool skip_partial,
 				 enum language pretend_language);
 
-static void process_full_comp_unit (dwarf2_per_cu_data *per_cu,
-				    dwarf2_per_objfile *per_objfile,
+static void process_full_comp_unit (dwarf2_cu *cu,
 				    enum language pretend_language);
 
-static void process_full_type_unit (dwarf2_per_cu_data *per_cu,
-				    dwarf2_per_objfile *per_objfile,
+static void process_full_type_unit (dwarf2_cu *cu,
 				    enum language pretend_language);
 
 static void dwarf2_add_dependence (struct dwarf2_cu *,
@@ -8983,11 +8981,9 @@ process_queue (struct dwarf2_per_objfile *dwarf2_per_objfile)
 	    fprintf_unfiltered (gdb_stdlog, "Expanding symtab of %s\n", buf);
 
 	  if (per_cu->is_debug_types)
-	    process_full_type_unit (per_cu, dwarf2_per_objfile,
-				    item.pretend_language);
+	    process_full_type_unit (per_cu->cu, item.pretend_language);
 	  else
-	    process_full_comp_unit (per_cu, dwarf2_per_objfile,
-				    item.pretend_language);
+	    process_full_comp_unit (per_cu->cu, item.pretend_language);
 
 	  if (dwarf_read_debug >= debug_print_threshold)
 	    fprintf_unfiltered (gdb_stdlog, "Done expanding %s\n", buf);
@@ -9721,15 +9717,13 @@ process_cu_includes (struct dwarf2_per_objfile *dwarf2_per_objfile)
   dwarf2_per_objfile->per_bfd->just_read_cus.clear ();
 }
 
-/* Generate full symbol information for PER_CU, whose DIEs have
+/* Generate full symbol information for CU, whose DIEs have
    already been loaded into memory.  */
 
 static void
-process_full_comp_unit (dwarf2_per_cu_data *per_cu,
-			dwarf2_per_objfile *dwarf2_per_objfile,
-			enum language pretend_language)
+process_full_comp_unit (dwarf2_cu *cu, enum language pretend_language)
 {
-  struct dwarf2_cu *cu = per_cu->cu;
+  dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
   struct objfile *objfile = dwarf2_per_objfile->objfile;
   struct gdbarch *gdbarch = objfile->arch ();
   CORE_ADDR lowpc, highpc;
@@ -9812,30 +9806,29 @@ process_full_comp_unit (dwarf2_per_cu_data *per_cu,
       cust->call_site_htab = cu->call_site_htab;
     }
 
-  dwarf2_per_objfile->set_symtab (per_cu, cust);
+  dwarf2_per_objfile->set_symtab (cu->per_cu, cust);
 
   /* Push it for inclusion processing later.  */
-  dwarf2_per_objfile->per_bfd->just_read_cus.push_back (per_cu);
+  dwarf2_per_objfile->per_bfd->just_read_cus.push_back (cu->per_cu);
 
   /* Not needed any more.  */
   cu->reset_builder ();
 }
 
-/* Generate full symbol information for type unit PER_CU, whose DIEs have
+/* Generate full symbol information for type unit CU, whose DIEs have
    already been loaded into memory.  */
 
 static void
-process_full_type_unit (dwarf2_per_cu_data *per_cu,
-			dwarf2_per_objfile *dwarf2_per_objfile,
+process_full_type_unit (dwarf2_cu *cu,
 			enum language pretend_language)
 {
-  struct dwarf2_cu *cu = per_cu->cu;
+  dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
   struct objfile *objfile = dwarf2_per_objfile->objfile;
   struct compunit_symtab *cust;
   struct signatured_type *sig_type;
 
-  gdb_assert (per_cu->is_debug_types);
-  sig_type = (struct signatured_type *) per_cu;
+  gdb_assert (cu->per_cu->is_debug_types);
+  sig_type = (struct signatured_type *) cu->per_cu;
 
   /* Clear the list here in case something was left over.  */
   cu->method_list.clear ();
@@ -9887,7 +9880,7 @@ process_full_type_unit (dwarf2_per_cu_data *per_cu,
       cust = tug_unshare->compunit_symtab;
     }
 
-  dwarf2_per_objfile->set_symtab (per_cu, cust);
+  dwarf2_per_objfile->set_symtab (cu->per_cu, cust);
 
   /* Not needed any more.  */
   cu->reset_builder ();
-- 
2.26.2


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

* [PATCH v2 37/42] Make load_cu return the loaded dwarf2_cu
  2020-05-12 21:08 [PATCH v2 00/42] Share DWARF partial symtabs between objfiles Simon Marchi
                   ` (35 preceding siblings ...)
  2020-05-12 21:17 ` [PATCH v2 36/42] Pass dwarf2_cu to process_full_{comp,type}_unit Simon Marchi
@ 2020-05-12 21:17 ` Simon Marchi
  2020-05-12 21:17 ` [PATCH v2 38/42] Add comp_unit_head to dwarf2_per_cu_data Simon Marchi
                   ` (8 subsequent siblings)
  45 siblings, 0 replies; 92+ messages in thread
From: Simon Marchi @ 2020-05-12 21:17 UTC (permalink / raw)
  To: gdb-patches

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

In a subsequent patch, the dwarf2_per_cu_data::cu link will be removed.
dwarf2_cu objects will instead need to be looked up from a per-objfile
map, using the dwarf2_per_cu_data object as the key.

To make it easier for some callers, this patch makes load_cu return the
dwarf2_cu it creates.  If the caller needs to use the created dwarf2_cu,
it will have it available right away, rather than having to do a map
lookup.

At the same time, this allows changing queue_and_load_all_dwo_tus to
take a dwarf2_cu instead of a dwarf2_per_cu_data.

gdb/ChangeLog:

	* dwarf2/read.c (load_cu): Return dwarf2_cu.
	(dw2_do_instantiate_symtab): Update.
	(queue_and_load_all_dwo_tus): Change parameter from
	dwarf2_per_cu_data to dwarf2_cu.
	(dwarf2_fetch_die_loc_sect_off): Update.
	(dwarf2_fetch_constant_bytes): Update.
	(dwarf2_fetch_die_type_sect_off): Update.
---
 gdb/dwarf2/read.c | 65 ++++++++++++++++++++++++-----------------------
 1 file changed, 33 insertions(+), 32 deletions(-)

diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 68d7efaf549..ad4eae3fe60 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -1676,7 +1676,7 @@ static struct dwo_unit *lookup_dwo_comp_unit
 static struct dwo_unit *lookup_dwo_type_unit
   (dwarf2_cu *cu, const char *dwo_name, const char *comp_dir);
 
-static void queue_and_load_all_dwo_tus (struct dwarf2_per_cu_data *);
+static void queue_and_load_all_dwo_tus (dwarf2_cu *cu);
 
 /* A unique pointer to a dwo_file.  */
 
@@ -2335,7 +2335,7 @@ create_quick_file_names_table (unsigned int nr_initial_entries)
    function is unrelated to symtabs, symtab would have to be created afterwards.
    You should call age_cached_comp_units after processing the CU.  */
 
-static void
+static dwarf2_cu *
 load_cu (dwarf2_per_cu_data *per_cu, dwarf2_per_objfile *per_objfile,
 	 bool skip_partial)
 {
@@ -2344,10 +2344,12 @@ load_cu (dwarf2_per_cu_data *per_cu, dwarf2_per_objfile *per_objfile,
   else
     load_full_comp_unit (per_cu, per_objfile, skip_partial, language_minimal);
 
-  if (per_cu->cu == NULL)
-    return;  /* Dummy CU.  */
+  if (per_cu->cu == nullptr)
+    return nullptr;  /* Dummy CU.  */
 
   dwarf2_find_base_address (per_cu->cu->dies, per_cu->cu);
+
+  return per_cu->cu;
 }
 
 /* Read in the symbols for PER_CU in the context of DWARF"_PER_OBJFILE.  */
@@ -2370,19 +2372,19 @@ dw2_do_instantiate_symtab (dwarf2_per_cu_data *per_cu,
   if (!dwarf2_per_objfile->symtab_set_p (per_cu))
     {
       queue_comp_unit (per_cu, dwarf2_per_objfile, language_minimal);
-      load_cu (per_cu, dwarf2_per_objfile, skip_partial);
+      dwarf2_cu *cu = load_cu (per_cu, dwarf2_per_objfile, skip_partial);
 
       /* If we just loaded a CU from a DWO, and we're working with an index
 	 that may badly handle TUs, load all the TUs in that DWO as well.
 	 http://sourceware.org/bugzilla/show_bug.cgi?id=15021  */
       if (!per_cu->is_debug_types
-	  && per_cu->cu != NULL
-	  && per_cu->cu->dwo_unit != NULL
+	  && cu != NULL
+	  && cu->dwo_unit != NULL
 	  && dwarf2_per_objfile->per_bfd->index_table != NULL
 	  && dwarf2_per_objfile->per_bfd->index_table->version <= 7
 	  /* DWP files aren't supported yet.  */
 	  && get_dwp_file (dwarf2_per_objfile) == NULL)
-	queue_and_load_all_dwo_tus (per_cu);
+	queue_and_load_all_dwo_tus (cu);
     }
 
   process_queue (dwarf2_per_objfile);
@@ -12842,28 +12844,27 @@ queue_and_load_dwo_tu (void **slot, void *info)
   return 1;
 }
 
-/* Queue all TUs contained in the DWO of PER_CU to be read in.
+/* Queue all TUs contained in the DWO of CU to be read in.
    The DWO may have the only definition of the type, though it may not be
    referenced anywhere in PER_CU.  Thus we have to load *all* its TUs.
    http://sourceware.org/bugzilla/show_bug.cgi?id=15021  */
 
 static void
-queue_and_load_all_dwo_tus (struct dwarf2_per_cu_data *per_cu)
+queue_and_load_all_dwo_tus (dwarf2_cu *cu)
 {
   struct dwo_unit *dwo_unit;
   struct dwo_file *dwo_file;
 
-  gdb_assert (!per_cu->is_debug_types);
-  gdb_assert (per_cu->cu != NULL);
-  gdb_assert (get_dwp_file (per_cu->cu->per_objfile) == NULL);
+  gdb_assert (cu != nullptr);
+  gdb_assert (!cu->per_cu->is_debug_types);
+  gdb_assert (get_dwp_file (cu->per_objfile) == nullptr);
 
-  dwo_unit = per_cu->cu->dwo_unit;
+  dwo_unit = cu->dwo_unit;
   gdb_assert (dwo_unit != NULL);
 
   dwo_file = dwo_unit->dwo_file;
   if (dwo_file->tus != NULL)
-    htab_traverse_noresize (dwo_file->tus.get (), queue_and_load_dwo_tu,
-			    per_cu->cu);
+    htab_traverse_noresize (dwo_file->tus.get (), queue_and_load_dwo_tu, cu);
 }
 
 /* Read in various DIEs.  */
@@ -22277,16 +22278,16 @@ dwarf2_fetch_die_loc_sect_off (sect_offset sect_off,
 			       CORE_ADDR (*get_frame_pc) (void *baton),
 			       void *baton, bool resolve_abstract_p)
 {
-  struct dwarf2_cu *cu;
   struct die_info *die;
   struct attribute *attr;
   struct dwarf2_locexpr_baton retval;
   struct objfile *objfile = dwarf2_per_objfile->objfile;
 
-  if (per_cu->cu == NULL)
-    load_cu (per_cu, dwarf2_per_objfile, false);
-  cu = per_cu->cu;
-  if (cu == NULL)
+  dwarf2_cu *cu = per_cu->cu;
+  if (cu == nullptr)
+    cu = load_cu (per_cu, dwarf2_per_objfile, false);
+
+  if (cu == nullptr)
     {
       /* We shouldn't get here for a dummy CU, but don't crash on the user.
 	 Instead just throw an error, not much else we can do.  */
@@ -22415,7 +22416,6 @@ dwarf2_fetch_constant_bytes (sect_offset sect_off,
 			     obstack *obstack,
 			     LONGEST *len)
 {
-  struct dwarf2_cu *cu;
   struct die_info *die;
   struct attribute *attr;
   const gdb_byte *result = NULL;
@@ -22424,10 +22424,11 @@ dwarf2_fetch_constant_bytes (sect_offset sect_off,
   enum bfd_endian byte_order;
   struct objfile *objfile = per_objfile->objfile;
 
-  if (per_cu->cu == NULL)
-    load_cu (per_cu, per_objfile, false);
-  cu = per_cu->cu;
-  if (cu == NULL)
+  dwarf2_cu *cu = per_cu->cu;
+  if (cu == nullptr)
+    cu = load_cu (per_cu, per_objfile, false);
+
+  if (cu == nullptr)
     {
       /* We shouldn't get here for a dummy CU, but don't crash on the user.
 	 Instead just throw an error, not much else we can do.  */
@@ -22544,14 +22545,14 @@ dwarf2_fetch_die_type_sect_off (sect_offset sect_off,
 				dwarf2_per_cu_data *per_cu,
 				dwarf2_per_objfile *per_objfile)
 {
-  struct dwarf2_cu *cu;
   struct die_info *die;
 
-  if (per_cu->cu == NULL)
-    load_cu (per_cu, per_objfile, false);
-  cu = per_cu->cu;
-  if (!cu)
-    return NULL;
+  dwarf2_cu *cu = per_cu->cu;
+  if (cu == nullptr)
+    cu = load_cu (per_cu, per_objfile, false);
+
+  if (cu == nullptr)
+    return nullptr;
 
   die = follow_die_offset (sect_off, per_cu->is_dwz, &cu);
   if (!die)
-- 
2.26.2


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

* [PATCH v2 38/42] Add comp_unit_head to dwarf2_per_cu_data
  2020-05-12 21:08 [PATCH v2 00/42] Share DWARF partial symtabs between objfiles Simon Marchi
                   ` (36 preceding siblings ...)
  2020-05-12 21:17 ` [PATCH v2 37/42] Make load_cu return the loaded dwarf2_cu Simon Marchi
@ 2020-05-12 21:17 ` Simon Marchi
  2020-05-12 21:17 ` [PATCH v2 39/42] Pass existing_cu object to cutu_reader Simon Marchi
                   ` (7 subsequent siblings)
  45 siblings, 0 replies; 92+ messages in thread
From: Simon Marchi @ 2020-05-12 21:17 UTC (permalink / raw)
  To: gdb-patches

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

The per_cu_header_read_in function allows obtaining a filled
comp_unit_head object for a given dwarf2_per_cu_data object.  If a
dwarf2_cu object exists for this dwarf2_per_cu_data, then it just
returns a pointer to the comp_unit_head from that dwarf2_cu.  Otherwise,
it reads the header into a temporary buffer provided by the caller, and
returns a pointer to that.

Since the dwarf2_per_cu_data::cu link is going to be removed
(dwarf2_per_cu_data will become objfile-independent while dwarf2_cu
stays objfile-dependent), we cannot rely anymore on returning the header
from the dwarf2_cu object.

The not too complex solution implemented by this patch is to keep a copy
of the header in the dwarf2_per_cu_data object, independent from the
copy in dwarf2_cu.  The new copy is only used in the addr_size,
offset_size and ref_addr_size methods of dwarf2_per_cu_data.

There's nothing intrinsic to the comp_unit_head object that prevents it
to be shared between two dwarf2_cu objects (belonging to different
objfiles) representing the same CU.  In other words, I think we could
eventually get rid of the copy in dwarf2_cu to only keep the one in
dwarf2_per_cu_data.  It is not trivial, however, so I have decided not
to do it for the moment.

gdb/ChangeLog:

	* dwarf2/read.h (struct dwarf2_per_cu_data) <m_header,
	m_header_read_in>: New fields.
	<get_header>: New method.
	* dwarf2/read.c (per_cu_header_read_in): Remove.
	(dwarf2_per_cu_data::get_header): New.
	(dwarf2_per_cu_data::addr_size): Update.
	(dwarf2_per_cu_data::offset_size): Update.
	(dwarf2_per_cu_data::ref_addr_size): Update.
---
 gdb/dwarf2/read.c | 52 ++++++++++++++++-------------------------------
 gdb/dwarf2/read.h | 19 +++++++++++++++++
 2 files changed, 37 insertions(+), 34 deletions(-)

diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index ad4eae3fe60..dc72b6320a8 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -23295,26 +23295,23 @@ dwarf2_symbol_mark_computed (const struct attribute *attr, struct symbol *sym,
     }
 }
 
-/* Return comp_unit_head for PER_CU, either already available in PER_CU->CU
-   (CU_HEADERP is unused in such case) or prepare a temporary copy at
-   CU_HEADERP first.  */
+/* See read.h.  */
 
-static const struct comp_unit_head *
-per_cu_header_read_in (struct comp_unit_head *cu_headerp,
-		       const struct dwarf2_per_cu_data *per_cu)
+const comp_unit_head *
+dwarf2_per_cu_data::get_header () const
 {
-  const gdb_byte *info_ptr;
-
-  if (per_cu->cu)
-    return &per_cu->cu->header;
+  if (!m_header_read_in)
+    {
+      const gdb_byte *info_ptr
+	= this->section->buffer + to_underlying (this->sect_off);
 
-  info_ptr = per_cu->section->buffer + to_underlying (per_cu->sect_off);
+      memset (&m_header, 0, sizeof (m_header));
 
-  memset (cu_headerp, 0, sizeof (*cu_headerp));
-  read_comp_unit_head (cu_headerp, info_ptr, per_cu->section,
-		       rcuh_kind::COMPILE);
+      read_comp_unit_head (&m_header, info_ptr, this->section,
+			   rcuh_kind::COMPILE);
+    }
 
-  return cu_headerp;
+  return &m_header;
 }
 
 /* See read.h.  */
@@ -23322,12 +23319,7 @@ per_cu_header_read_in (struct comp_unit_head *cu_headerp,
 int
 dwarf2_per_cu_data::addr_size () const
 {
-  struct comp_unit_head cu_header_local;
-  const struct comp_unit_head *cu_headerp;
-
-  cu_headerp = per_cu_header_read_in (&cu_header_local, this);
-
-  return cu_headerp->addr_size;
+  return this->get_header ()->addr_size;
 }
 
 /* See read.h.  */
@@ -23335,12 +23327,7 @@ dwarf2_per_cu_data::addr_size () const
 int
 dwarf2_per_cu_data::offset_size () const
 {
-  struct comp_unit_head cu_header_local;
-  const struct comp_unit_head *cu_headerp;
-
-  cu_headerp = per_cu_header_read_in (&cu_header_local, this);
-
-  return cu_headerp->offset_size;
+  return this->get_header ()->offset_size;
 }
 
 /* See read.h.  */
@@ -23348,15 +23335,12 @@ dwarf2_per_cu_data::offset_size () const
 int
 dwarf2_per_cu_data::ref_addr_size () const
 {
-  struct comp_unit_head cu_header_local;
-  const struct comp_unit_head *cu_headerp;
-
-  cu_headerp = per_cu_header_read_in (&cu_header_local, this);
+  const comp_unit_head *header = this->get_header ();
 
-  if (cu_headerp->version == 2)
-    return cu_headerp->addr_size;
+  if (header->version == 2)
+    return header->addr_size;
   else
-    return cu_headerp->offset_size;
+    return header->offset_size;
 }
 
 /* See read.h.  */
diff --git a/gdb/dwarf2/read.h b/gdb/dwarf2/read.h
index 3500b0e7ba9..b75be312217 100644
--- a/gdb/dwarf2/read.h
+++ b/gdb/dwarf2/read.h
@@ -22,6 +22,7 @@
 
 #include <queue>
 #include <unordered_map>
+#include "dwarf2/comp-unit.h"
 #include "dwarf2/index-cache.h"
 #include "dwarf2/section.h"
 #include "filename-seen-cache.h"
@@ -468,6 +469,21 @@ struct dwarf2_per_cu_data
   /* Backlink to the owner of this.  */
   dwarf2_per_bfd *per_bfd;
 
+  /* DWARF header of this CU.  Note that dwarf2_cu reads its own version of the
+     header, which may differ from this one, since it may pass rcuh_kind::TYPE
+     to read_comp_unit_head, whereas for dwarf2_per_cu_data we always pass
+     rcuh_kind::COMPILE.
+
+     Don't access this field directly, use the get_header method instead.  It
+     should be private, but we can't make it private at the moment.  */
+  mutable comp_unit_head m_header;
+
+  /* True if HEADER has been read in.
+
+     Don't access this field directly.  It should be private, but we can't make
+     it private at the moment.  */
+  mutable bool m_header_read_in;
+
   /* When dwarf2_per_bfd::using_index is true, the 'quick' field
      is active.  Otherwise, the 'psymtab' field is active.  */
   union
@@ -537,6 +553,9 @@ struct dwarf2_per_cu_data
     imported_symtabs = nullptr;
   }
 
+  /* Get the header of this per_cu, reading it if necessary.  */
+  const comp_unit_head *get_header () const;
+
   /* Return the address size given in the compilation unit header for
      this CU.  */
   int addr_size () const;
-- 
2.26.2


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

* [PATCH v2 39/42] Pass existing_cu object to cutu_reader
  2020-05-12 21:08 [PATCH v2 00/42] Share DWARF partial symtabs between objfiles Simon Marchi
                   ` (37 preceding siblings ...)
  2020-05-12 21:17 ` [PATCH v2 38/42] Add comp_unit_head to dwarf2_per_cu_data Simon Marchi
@ 2020-05-12 21:17 ` Simon Marchi
  2020-05-22 20:57   ` Tom Tromey
  2020-05-12 21:18 ` [PATCH v2 40/42] Replace dwarf2_per_cu_data::cu backlink with per-objfile map Simon Marchi
                   ` (6 subsequent siblings)
  45 siblings, 1 reply; 92+ messages in thread
From: Simon Marchi @ 2020-05-12 21:17 UTC (permalink / raw)
  To: gdb-patches; +Cc: Simon Marchi

It is possible, seemingly for a special case described in
find_partial_die, for cutu_reader to re-use an existing dwarf2_cu
instead of creating a new one.  This happens
---
 gdb/dwarf2/read.c | 53 +++++++++++++++++++++++++++--------------------
 1 file changed, 30 insertions(+), 23 deletions(-)

diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index dc72b6320a8..acc148a87d5 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -912,7 +912,7 @@ class cutu_reader : public die_reader_specs
   cutu_reader (dwarf2_per_cu_data *this_cu,
 	       dwarf2_per_objfile *per_objfile,
 	       struct abbrev_table *abbrev_table,
-	       int use_existing_cu,
+	       dwarf2_cu *existing_cu,
 	       bool skip_partial);
 
   explicit cutu_reader (struct dwarf2_per_cu_data *this_cu,
@@ -933,7 +933,7 @@ class cutu_reader : public die_reader_specs
 private:
   void init_tu_and_read_dwo_dies (dwarf2_per_cu_data *this_cu,
 				  dwarf2_per_objfile *per_objfile,
-				  int use_existing_cu);
+				  dwarf2_cu *existing_cu);
 
   struct dwarf2_per_cu_data *m_this_cu;
   std::unique_ptr<dwarf2_cu> m_new_cu;
@@ -6864,7 +6864,7 @@ lookup_dwo_unit (dwarf2_cu *cu, die_info *comp_unit_die, const char *dwo_name)
 void
 cutu_reader::init_tu_and_read_dwo_dies (dwarf2_per_cu_data *this_cu,
 					dwarf2_per_objfile *per_objfile,
-					int use_existing_cu)
+					dwarf2_cu *existing_cu)
 {
   struct signatured_type *sig_type;
 
@@ -6874,24 +6874,28 @@ cutu_reader::init_tu_and_read_dwo_dies (dwarf2_per_cu_data *this_cu,
   sig_type = (struct signatured_type *) this_cu;
   gdb_assert (sig_type->dwo_unit != NULL);
 
-  if (use_existing_cu && this_cu->cu != NULL)
+  dwarf2_cu *cu;
+
+  if (existing_cu != nullptr)
     {
-      gdb_assert (this_cu->cu->dwo_unit == sig_type->dwo_unit);
+      cu = existing_cu;
+      gdb_assert (cu->dwo_unit == sig_type->dwo_unit);
       /* There's no need to do the rereading_dwo_cu handling that
 	 cutu_reader does since we don't read the stub.  */
     }
   else
     {
-      /* If !use_existing_cu, this_cu->cu must be NULL.  */
+      /* If and existing_cu is provided, this_cu->cu must be NULL.  */
       gdb_assert (this_cu->cu == NULL);
       m_new_cu.reset (new dwarf2_cu (this_cu, per_objfile));
+      cu = m_new_cu.get ();
     }
 
   /* A future optimization, if needed, would be to use an existing
      abbrev table.  When reading DWOs with skeletonless TUs, all the TUs
      could share abbrev tables.  */
 
-  if (read_cutu_die_from_dwo (this_cu->cu, sig_type->dwo_unit,
+  if (read_cutu_die_from_dwo (cu, sig_type->dwo_unit,
 			      NULL /* stub_comp_unit_die */,
 			      sig_type->dwo_unit->dwo_file->comp_dir,
 			      this, &info_ptr,
@@ -6916,7 +6920,7 @@ cutu_reader::init_tu_and_read_dwo_dies (dwarf2_per_cu_data *this_cu,
 cutu_reader::cutu_reader (dwarf2_per_cu_data *this_cu,
 			  dwarf2_per_objfile *dwarf2_per_objfile,
 			  struct abbrev_table *abbrev_table,
-			  int use_existing_cu,
+			  dwarf2_cu *existing_cu,
 			  bool skip_partial)
   : die_reader_specs {},
     m_this_cu (this_cu)
@@ -6924,7 +6928,6 @@ cutu_reader::cutu_reader (dwarf2_per_cu_data *this_cu,
   struct objfile *objfile = dwarf2_per_objfile->objfile;
   struct dwarf2_section_info *section = this_cu->section;
   bfd *abfd = section->get_bfd_owner ();
-  struct dwarf2_cu *cu;
   const gdb_byte *begin_info_ptr;
   struct signatured_type *sig_type = NULL;
   struct dwarf2_section_info *abbrev_section;
@@ -6945,7 +6948,7 @@ cutu_reader::cutu_reader (dwarf2_per_cu_data *this_cu,
       /* Narrow down the scope of possibilities to have to understand.  */
       gdb_assert (this_cu->is_debug_types);
       gdb_assert (abbrev_table == NULL);
-      init_tu_and_read_dwo_dies (this_cu, dwarf2_per_objfile, use_existing_cu);
+      init_tu_and_read_dwo_dies (this_cu, dwarf2_per_objfile, existing_cu);
       return;
     }
 
@@ -6956,9 +6959,11 @@ cutu_reader::cutu_reader (dwarf2_per_cu_data *this_cu,
 
   abbrev_section = get_abbrev_section_for_cu (this_cu);
 
-  if (use_existing_cu && this_cu->cu != NULL)
+  dwarf2_cu *cu;
+
+  if (existing_cu != nullptr)
     {
-      cu = this_cu->cu;
+      cu = existing_cu;
       /* If this CU is from a DWO file we need to start over, we need to
 	 refetch the attributes from the skeleton CU.
 	 This could be optimized by retrieving those attributes from when we
@@ -6970,7 +6975,7 @@ cutu_reader::cutu_reader (dwarf2_per_cu_data *this_cu,
     }
   else
     {
-      /* If !use_existing_cu, this_cu->cu must be NULL.  */
+      /* If an existing_cu is provided, this_cu->cu must be NULL.  */
       gdb_assert (this_cu->cu == NULL);
       m_new_cu.reset (new dwarf2_cu (this_cu, dwarf2_per_objfile));
       cu = m_new_cu.get ();
@@ -7523,7 +7528,7 @@ process_psymtab_comp_unit (dwarf2_per_cu_data *this_cu,
   if (this_cu->cu != NULL)
     free_one_cached_comp_unit (this_cu, per_objfile);
 
-  cutu_reader reader (this_cu, per_objfile, NULL, 0, false);
+  cutu_reader reader (this_cu, per_objfile, nullptr, nullptr, false);
 
   switch (reader.comp_unit_die->tag)
     {
@@ -7705,7 +7710,7 @@ build_type_psymtabs_1 (struct dwarf2_per_objfile *dwarf2_per_objfile)
 	}
 
       cutu_reader reader (&tu.sig_type->per_cu, dwarf2_per_objfile,
-			  abbrev_table.get (), 0, false);
+			  abbrev_table.get (), nullptr, false);
       if (!reader.dummy_p)
 	build_type_psymtabs_reader (&reader, reader.info_ptr,
 				    reader.comp_unit_die);
@@ -7810,7 +7815,8 @@ process_skeletonless_type_unit (void **slot, void *info)
   *slot = entry;
 
   /* This does the job that build_type_psymtabs_1 would have done.  */
-  cutu_reader reader (&entry->per_cu, dwarf2_per_objfile, NULL, 0, false);
+  cutu_reader reader (&entry->per_cu, dwarf2_per_objfile, nullptr, nullptr,
+		      false);
   if (!reader.dummy_p)
     build_type_psymtabs_reader (&reader, reader.info_ptr,
 				reader.comp_unit_die);
@@ -7946,9 +7952,10 @@ dwarf2_build_psymtabs_hard (struct dwarf2_per_objfile *dwarf2_per_objfile)
 
 static void
 load_partial_comp_unit (dwarf2_per_cu_data *this_cu,
-			dwarf2_per_objfile *per_objfile)
+			dwarf2_per_objfile *per_objfile,
+			dwarf2_cu *existing_cu)
 {
-  cutu_reader reader (this_cu, per_objfile, NULL, 1, false);
+  cutu_reader reader (this_cu, per_objfile, nullptr, existing_cu, false);
 
   if (!reader.dummy_p)
     {
@@ -9067,7 +9074,7 @@ load_full_comp_unit (dwarf2_per_cu_data *this_cu,
 {
   gdb_assert (! this_cu->is_debug_types);
 
-  cutu_reader reader (this_cu, per_objfile, NULL, 1, skip_partial);
+  cutu_reader reader (this_cu, per_objfile, NULL, this_cu->cu, skip_partial);
   if (reader.dummy_p)
     return;
 
@@ -18673,7 +18680,7 @@ find_partial_die (sect_offset sect_off, int offset_in_dwz, struct dwarf2_cu *cu)
 						 dwarf2_per_objfile);
 
       if (per_cu->cu == NULL || per_cu->cu->partial_dies == NULL)
-	load_partial_comp_unit (per_cu, cu->per_objfile);
+	load_partial_comp_unit (per_cu, cu->per_objfile, nullptr);
 
       per_cu->cu->last_used = 0;
       pd = per_cu->cu->find_partial_die (sect_off);
@@ -18692,7 +18699,7 @@ find_partial_die (sect_offset sect_off, int offset_in_dwz, struct dwarf2_cu *cu)
 	 DIEs alone (which can still be in use, e.g. in scan_partial_symbols),
 	 and clobber THIS_CU->cu->partial_dies with the hash table for the new
 	 set.  */
-      load_partial_comp_unit (per_cu, cu->per_objfile);
+      load_partial_comp_unit (per_cu, cu->per_objfile, cu);
 
       pd = per_cu->cu->find_partial_die (sect_off);
     }
@@ -19409,7 +19416,7 @@ dwarf2_read_addr_index (dwarf2_per_cu_data *per_cu,
     }
   else
     {
-      cutu_reader reader (per_cu, dwarf2_per_objfile, NULL, 0, false);
+      cutu_reader reader (per_cu, dwarf2_per_objfile, nullptr, nullptr, false);
       addr_base = reader.cu->addr_base;
       addr_size = reader.cu->header.addr_size;
     }
@@ -22791,7 +22798,7 @@ read_signatured_type (signatured_type *sig_type,
   gdb_assert (per_cu->is_debug_types);
   gdb_assert (per_cu->cu == NULL);
 
-  cutu_reader reader (per_cu, per_objfile, NULL, 0, false);
+  cutu_reader reader (per_cu, per_objfile, nullptr, nullptr, false);
 
   if (!reader.dummy_p)
     {
-- 
2.26.2


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

* [PATCH v2 40/42] Replace dwarf2_per_cu_data::cu backlink with per-objfile map
  2020-05-12 21:08 [PATCH v2 00/42] Share DWARF partial symtabs between objfiles Simon Marchi
                   ` (38 preceding siblings ...)
  2020-05-12 21:17 ` [PATCH v2 39/42] Pass existing_cu object to cutu_reader Simon Marchi
@ 2020-05-12 21:18 ` Simon Marchi
  2020-05-12 21:18 ` [PATCH v2 41/42] Make mapped_debug_names independent of objfile Simon Marchi
                   ` (5 subsequent siblings)
  45 siblings, 0 replies; 92+ messages in thread
From: Simon Marchi @ 2020-05-12 21:18 UTC (permalink / raw)
  To: gdb-patches; +Cc: Simon Marchi

The dwarf2_per_cu_data type is going to become objfile-independent,
while the dwarf2_cu type will stay object-dependent.  This patch removes
the backlink from dwarf2_per_cu_data to dwarf2_cu, in favor of the
dwarf2_per_objfile::m_dwarf2_cus map.  It maps dwarf2_per_cu_data
objects to the corresponding dwarf2_cu objects for this objfile.  If a
CU has been read in in the context of this objfile, then an entry will
be present in the map.

The dwarf2_cu objects that are read in are currently kept in a linked
list rooted in the dwarf2_per_bfd.  Except that the dwarf2_cu objects
are not simply linked together, they are interleaved with their
corresponding dwarf2_per_cu_data objects.  So if we have CUs A and B
read in, the dwarf2_per_bfd::read_in_chain will point to a chain like
this (DPCD == dwarf2_per_cu_data, DC == dwarf2_cu):

 DPCD A -> DC A -> DPCD B -> DC B

Obviously, this can't stay as is, since a same CU can be read in for an
objfile but not read in for another objfile sharing the same BFD, and
the dwarf2_per_cu_data::cu link is removed.   This is all replaced by
the dwarf2_per_objfile::m_dwarf2_cus map.

gdb/ChangeLog:

	* dwarf2/read.h (struct dwarf2_cu): Forward-declare.
	(struct dwarf2_per_bfd) <free_cached_comp_units>: Remove,
	move to dwarf2_per_objfile.
	<read_in_chain>: Remove.
	(struct dwarf2_per_objfile) <get_cu, set_cu, remove_cu,
	remove_all_cus, age_comp_units>: New methods.
	<m_dwarf2_cus>: New member.
	(struct dwarf2_per_cu_data) <cu>: Remove.
	* dwarf2/read.c (struct dwarf2_cu) <read_in_chain>: Remove.
	(age_cached_comp_units, free_one_cached_comp_unit): Remove,
	moved to methods of dwarf2_per_objfile.
	(dwarf2_clear_marks): Remove.
	(dwarf2_queue_item::~dwarf2_queue_item): Update.
	(dwarf2_per_bfd::~dwarf2_per_bfd): Don't free dwarf2_cus.
	(dwarf2_per_bfd::free_cached_comp_units): Remove.
	(dwarf2_per_objfile::remove_all_cus): New.
	(class free_cached_comp_units) <~free_cached_comp_units>:
	Update.
	(load_cu): Update.
	(dw2_do_instantiate_symtab): Adjust.
	(fill_in_sig_entry_from_dwo_entry): Adjust.
	(cutu_reader::init_tu_and_read_dwo_dies): Update.
	(cutu_reader::cutu_reader): Likewise.
	(cutu_reader::keep): Use dwarf2_per_objfile::set_cu.
	(cutu_reader::cutu_reader): Use dwarf2_per_objfile::get_cu.
	(process_psymtab_comp_unit): Use dwarf2_per_objfile::remove_cu
	and dwarf2_per_objfile::age_comp_units.
	(load_partial_comp_unit): Update.
	(maybe_queue_comp_unit): Use dwarf2_per_objfile::get_cu.
	(process_queue): Likewise.
	(find_partial_die): Use dwarf2_per_objfile::get_cu instead of cu
	backlink.
	(dwarf2_read_addr_index): Likewise.
	(follow_die_offset): Likewise.
	(dwarf2_fetch_die_loc_sect_off): Likewise.
	(dwarf2_fetch_constant_bytes): Likewise.
	(dwarf2_fetch_die_type_sect_off): Likewise.
	(follow_die_sig_1): Likewise.
	(load_full_type_unit): Likewise.
	(read_signatured_type): Likewise.
	(dwarf2_cu::dwarf2_cu): Don't set cu field.
	(dwarf2_cu::~dwarf2_cu): Remove.
	(dwarf2_per_objfile::get_cu): New.
	(dwarf2_per_objfile::set_cu): New.
	(age_cached_comp_units): Rename to...
	(dwarf2_per_objfile::age_comp_units): ... this.  Adjust
	to std::unordered_map.
	(free_one_cached_comp_unit): Rename to...
	(dwarf2_per_objfile::remove_cu): ... this.  Adjust
	to std::unordered_map.
	(dwarf2_per_objfile::~dwarf2_per_objfile): New.
	(dwarf2_mark_helper): Use dwarf2_per_objfile::get_cu, expect
	a dwarf2_per_objfile in data.
	(dwarf2_mark): Pass dwarf2_per_objfile in data to htab_traverse.
	(dwarf2_clear_marks): Remove.
---
 gdb/dwarf2/read.c | 355 ++++++++++++++++++++++------------------------
 gdb/dwarf2/read.h |  35 +++--
 2 files changed, 189 insertions(+), 201 deletions(-)

diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index acc148a87d5..9bc19a089b0 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -401,7 +401,6 @@ struct dwarf2_cu
 {
   explicit dwarf2_cu (dwarf2_per_cu_data *per_cu,
 		      dwarf2_per_objfile *per_objfile);
-  ~dwarf2_cu ();
 
   DISABLE_COPY_AND_ASSIGN (dwarf2_cu);
 
@@ -468,12 +467,6 @@ struct dwarf2_cu
      unit, including partial DIEs.  */
   auto_obstack comp_unit_obstack;
 
-  /* When multiple dwarf2_cu structures are living in memory, this field
-     chains them all together, so that they can be released efficiently.
-     We will probably also want a generation counter so that most-recently-used
-     compilation units are cached...  */
-  struct dwarf2_per_cu_data *read_in_chain = nullptr;
-
   /* Backlink to our per_cu entry.  */
   struct dwarf2_per_cu_data *per_cu;
 
@@ -1553,11 +1546,6 @@ static void prepare_one_comp_unit (struct dwarf2_cu *cu,
 				   struct die_info *comp_unit_die,
 				   enum language pretend_language);
 
-static void age_cached_comp_units (struct dwarf2_per_objfile *dwarf2_per_objfile);
-
-static void free_one_cached_comp_unit (dwarf2_per_cu_data *target_per_cu,
-				       dwarf2_per_objfile *per_objfile);
-
 static struct type *set_die_type (struct die_info *, struct type *,
 				  struct dwarf2_cu *);
 
@@ -1581,8 +1569,6 @@ static void dwarf2_add_dependence (struct dwarf2_cu *,
 
 static void dwarf2_mark (struct dwarf2_cu *);
 
-static void dwarf2_clear_marks (struct dwarf2_per_cu_data *);
-
 static struct type *get_die_type_at_offset (sect_offset,
 					    dwarf2_per_cu_data *per_cu,
 					    dwarf2_per_objfile *per_objfile);
@@ -1629,8 +1615,7 @@ dwarf2_queue_item::~dwarf2_queue_item ()
      inconsistent state, so discard it.  */
   if (per_cu->queued)
     {
-      if (per_cu->cu != NULL)
-	free_one_cached_comp_unit (per_cu, per_objfile);
+      per_objfile->remove_cu (per_cu);
       per_cu->queued = 0;
     }
 }
@@ -1772,9 +1757,6 @@ dwarf2_per_bfd::dwarf2_per_bfd (bfd *obfd, const dwarf2_debug_sections *names,
 
 dwarf2_per_bfd::~dwarf2_per_bfd ()
 {
-  /* Cached DIE trees use xmalloc and the comp_unit_obstack.  */
-  free_cached_comp_units ();
-
   for (dwarf2_per_cu_data *per_cu : all_comp_units)
     per_cu->imported_symtabs_free ();
 
@@ -1784,21 +1766,15 @@ dwarf2_per_bfd::~dwarf2_per_bfd ()
   /* Everything else should be on this->obstack.  */
 }
 
-/* See declaration.  */
+/* See read.h.  */
 
 void
-dwarf2_per_bfd::free_cached_comp_units ()
+dwarf2_per_objfile::remove_all_cus ()
 {
-  dwarf2_per_cu_data *per_cu = read_in_chain;
-  dwarf2_per_cu_data **last_chain = &read_in_chain;
-  while (per_cu != NULL)
-    {
-      dwarf2_per_cu_data *next_cu = per_cu->cu->read_in_chain;
+  for (auto pair : m_dwarf2_cus)
+    delete pair.second;
 
-      delete per_cu->cu;
-      *last_chain = next_cu;
-      per_cu = next_cu;
-    }
+  m_dwarf2_cus.clear ();
 }
 
 /* A helper class that calls free_cached_comp_units on
@@ -1815,7 +1791,7 @@ class free_cached_comp_units
 
   ~free_cached_comp_units ()
   {
-    m_per_objfile->per_bfd->free_cached_comp_units ();
+    m_per_objfile->remove_all_cus ();
   }
 
   DISABLE_COPY_AND_ASSIGN (free_cached_comp_units);
@@ -2344,12 +2320,13 @@ load_cu (dwarf2_per_cu_data *per_cu, dwarf2_per_objfile *per_objfile,
   else
     load_full_comp_unit (per_cu, per_objfile, skip_partial, language_minimal);
 
-  if (per_cu->cu == nullptr)
+  dwarf2_cu *cu = per_objfile->get_cu (per_cu);
+  if (cu == nullptr)
     return nullptr;  /* Dummy CU.  */
 
-  dwarf2_find_base_address (per_cu->cu->dies, per_cu->cu);
+  dwarf2_find_base_address (cu->dies, cu);
 
-  return per_cu->cu;
+  return cu;
 }
 
 /* Read in the symbols for PER_CU in the context of DWARF"_PER_OBJFILE.  */
@@ -2391,7 +2368,7 @@ dw2_do_instantiate_symtab (dwarf2_per_cu_data *per_cu,
 
   /* Age the cache, releasing compilation units that have not
      been used recently.  */
-  age_cached_comp_units (dwarf2_per_objfile);
+  dwarf2_per_objfile->age_comp_units ();
 }
 
 /* Ensure that the symbols for PER_CU have been read in.  DWARF2_PER_OBJFILE is
@@ -6427,7 +6404,7 @@ fill_in_sig_entry_from_dwo_entry (struct dwarf2_per_objfile *dwarf2_per_objfile,
 
   /* Make sure we're not clobbering something we don't expect to.  */
   gdb_assert (! sig_entry->per_cu.queued);
-  gdb_assert (sig_entry->per_cu.cu == NULL);
+  gdb_assert (dwarf2_per_objfile->get_cu (&sig_entry->per_cu) == NULL);
   if (per_bfd->using_index)
     {
       gdb_assert (sig_entry->per_cu.v.quick != NULL);
@@ -6885,8 +6862,9 @@ cutu_reader::init_tu_and_read_dwo_dies (dwarf2_per_cu_data *this_cu,
     }
   else
     {
-      /* If and existing_cu is provided, this_cu->cu must be NULL.  */
-      gdb_assert (this_cu->cu == NULL);
+      /* If an existing_cu is provided, a dwarf2_cu must not exist for this_cu
+         in per_objfile yet.  */
+      gdb_assert (per_objfile->get_cu (this_cu) == nullptr);
       m_new_cu.reset (new dwarf2_cu (this_cu, per_objfile));
       cu = m_new_cu.get ();
     }
@@ -6975,8 +6953,9 @@ cutu_reader::cutu_reader (dwarf2_per_cu_data *this_cu,
     }
   else
     {
-      /* If an existing_cu is provided, this_cu->cu must be NULL.  */
-      gdb_assert (this_cu->cu == NULL);
+      /* If an existing_cu is provided, a dwarf2_cu must not exist for this_cu
+         in per_objfile yet.  */
+      gdb_assert (dwarf2_per_objfile->get_cu (this_cu) == nullptr);
       m_new_cu.reset (new dwarf2_cu (this_cu, dwarf2_per_objfile));
       cu = m_new_cu.get ();
     }
@@ -7116,16 +7095,10 @@ cutu_reader::keep ()
   gdb_assert (!dummy_p);
   if (m_new_cu != NULL)
     {
-      /* We know that m_this_cu->cu is set, since we are in the process of
-         parsing the CU.  */
-      gdb_assert (m_this_cu->cu != nullptr);
-      dwarf2_per_objfile *dwarf2_per_objfile = m_this_cu->cu->per_objfile;
-
-      /* Link this CU into read_in_chain.  */
-      m_this_cu->cu->read_in_chain = dwarf2_per_objfile->per_bfd->read_in_chain;
-      dwarf2_per_objfile->per_bfd->read_in_chain = m_this_cu;
-      /* The chain owns it now.  */
-      m_new_cu.release ();
+      /* Save this dwarf2_cu in the per_objfile.  The per_objfile owns it
+         now.  */
+      dwarf2_per_objfile *per_objfile = m_new_cu->per_objfile;
+      per_objfile->set_cu (m_this_cu, m_new_cu.release ());
     }
 }
 
@@ -7163,7 +7136,7 @@ cutu_reader::cutu_reader (dwarf2_per_cu_data *this_cu,
 			this_cu->is_debug_types ? "type" : "comp",
 			sect_offset_str (this_cu->sect_off));
 
-  gdb_assert (this_cu->cu == NULL);
+  gdb_assert (dwarf2_per_objfile->get_cu (this_cu) == nullptr);
 
   abbrev_section = (dwo_file != NULL
 		    ? &dwo_file->sections.abbrev
@@ -7525,8 +7498,7 @@ process_psymtab_comp_unit (dwarf2_per_cu_data *this_cu,
      necessary because we skipped some symbols when we first
      read in the compilation unit (see load_partial_dies).
      This problem could be avoided, but the benefit is unclear.  */
-  if (this_cu->cu != NULL)
-    free_one_cached_comp_unit (this_cu, per_objfile);
+  per_objfile->remove_cu (this_cu);
 
   cutu_reader reader (this_cu, per_objfile, nullptr, nullptr, false);
 
@@ -7555,10 +7527,10 @@ process_psymtab_comp_unit (dwarf2_per_cu_data *this_cu,
 				      reader.comp_unit_die,
 				      pretend_language);
 
-  this_cu->lang = this_cu->cu->language;
+  this_cu->lang = reader.cu->language;
 
   /* Age out any secondary CUs.  */
-  age_cached_comp_units (per_objfile);
+  per_objfile->age_comp_units ();
 }
 
 /* Reader function for build_type_psymtabs.  */
@@ -8913,7 +8885,9 @@ maybe_queue_comp_unit (struct dwarf2_cu *dependent_cu,
      not queue PER_CU, just tell our caller to load its DIEs.  */
   if (per_cu->per_bfd->reading_partial_symbols)
     {
-      if (per_cu->cu == NULL || per_cu->cu->dies == NULL)
+      dwarf2_cu *cu = per_objfile->get_cu (per_cu);
+
+      if (cu == NULL || cu->dies == NULL)
 	return 1;
       return 0;
     }
@@ -8929,9 +8903,10 @@ maybe_queue_comp_unit (struct dwarf2_cu *dependent_cu,
 
   /* If the compilation unit is already loaded, just mark it as
      used.  */
-  if (per_cu->cu != NULL)
+  dwarf2_cu *cu = per_objfile->get_cu (per_cu);
+  if (cu != nullptr)
     {
-      per_cu->cu->last_used = 0;
+      cu->last_used = 0;
       return 0;
     }
 
@@ -8958,47 +8933,51 @@ process_queue (struct dwarf2_per_objfile *dwarf2_per_objfile)
   while (!dwarf2_per_objfile->per_bfd->queue.empty ())
     {
       dwarf2_queue_item &item = dwarf2_per_objfile->per_bfd->queue.front ();
+      dwarf2_per_cu_data *per_cu = item.per_cu;
 
-      if (!dwarf2_per_objfile->symtab_set_p (item.per_cu)
-	  /* Skip dummy CUs.  */
-	  && item.per_cu->cu != NULL)
+      if (!dwarf2_per_objfile->symtab_set_p (per_cu))
 	{
-	  struct dwarf2_per_cu_data *per_cu = item.per_cu;
-	  unsigned int debug_print_threshold;
-	  char buf[100];
+	  dwarf2_cu *cu = dwarf2_per_objfile->get_cu (per_cu);
 
-	  if (per_cu->is_debug_types)
-	    {
-	      struct signatured_type *sig_type =
-		(struct signatured_type *) per_cu;
-
-	      sprintf (buf, "TU %s at offset %s",
-		       hex_string (sig_type->signature),
-		       sect_offset_str (per_cu->sect_off));
-	      /* There can be 100s of TUs.
-		 Only print them in verbose mode.  */
-	      debug_print_threshold = 2;
-	    }
-	  else
+	  /* Skip dummy CUs.  */
+	  if (cu != nullptr)
 	    {
-	      sprintf (buf, "CU at offset %s",
-		       sect_offset_str (per_cu->sect_off));
-	      debug_print_threshold = 1;
-	    }
+	      unsigned int debug_print_threshold;
+	      char buf[100];
+
+	      if (per_cu->is_debug_types)
+		{
+		  struct signatured_type *sig_type =
+		    (struct signatured_type *) per_cu;
+
+		  sprintf (buf, "TU %s at offset %s",
+			   hex_string (sig_type->signature),
+			   sect_offset_str (per_cu->sect_off));
+		  /* There can be 100s of TUs.
+		     Only print them in verbose mode.  */
+		  debug_print_threshold = 2;
+		}
+	      else
+		{
+		  sprintf (buf, "CU at offset %s",
+			   sect_offset_str (per_cu->sect_off));
+		  debug_print_threshold = 1;
+		}
 
-	  if (dwarf_read_debug >= debug_print_threshold)
-	    fprintf_unfiltered (gdb_stdlog, "Expanding symtab of %s\n", buf);
+	      if (dwarf_read_debug >= debug_print_threshold)
+		fprintf_unfiltered (gdb_stdlog, "Expanding symtab of %s\n", buf);
 
-	  if (per_cu->is_debug_types)
-	    process_full_type_unit (per_cu->cu, item.pretend_language);
-	  else
-	    process_full_comp_unit (per_cu->cu, item.pretend_language);
+	      if (per_cu->is_debug_types)
+		process_full_type_unit (cu, item.pretend_language);
+	      else
+		process_full_comp_unit (cu, item.pretend_language);
 
-	  if (dwarf_read_debug >= debug_print_threshold)
-	    fprintf_unfiltered (gdb_stdlog, "Done expanding %s\n", buf);
+	      if (dwarf_read_debug >= debug_print_threshold)
+		fprintf_unfiltered (gdb_stdlog, "Done expanding %s\n", buf);
+	    }
 	}
 
-      item.per_cu->queued = 0;
+      per_cu->queued = 0;
       dwarf2_per_objfile->per_bfd->queue.pop ();
     }
 
@@ -9074,7 +9053,8 @@ load_full_comp_unit (dwarf2_per_cu_data *this_cu,
 {
   gdb_assert (! this_cu->is_debug_types);
 
-  cutu_reader reader (this_cu, per_objfile, NULL, this_cu->cu, skip_partial);
+  dwarf2_cu *existing_cu = per_objfile->get_cu (this_cu);
+  cutu_reader reader (this_cu, per_objfile, NULL, existing_cu, skip_partial);
   if (reader.dummy_p)
     return;
 
@@ -18653,7 +18633,6 @@ find_partial_die (sect_offset sect_off, int offset_in_dwz, struct dwarf2_cu *cu)
 {
   struct dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
   struct objfile *objfile = dwarf2_per_objfile->objfile;
-  struct dwarf2_per_cu_data *per_cu = NULL;
   struct partial_die_info *pd = NULL;
 
   if (offset_in_dwz == cu->per_cu->is_dwz
@@ -18664,7 +18643,6 @@ find_partial_die (sect_offset sect_off, int offset_in_dwz, struct dwarf2_cu *cu)
 	return { cu, pd };
       /* We missed recording what we needed.
 	 Load all dies and try again.  */
-      per_cu = cu->per_cu;
     }
   else
     {
@@ -18676,22 +18654,26 @@ find_partial_die (sect_offset sect_off, int offset_in_dwz, struct dwarf2_cu *cu)
 		 sect_offset_str (cu->header.sect_off), sect_offset_str (sect_off),
 		 bfd_get_filename (objfile->obfd));
 	}
-      per_cu = dwarf2_find_containing_comp_unit (sect_off, offset_in_dwz,
-						 dwarf2_per_objfile);
+      dwarf2_per_cu_data *per_cu
+	= dwarf2_find_containing_comp_unit (sect_off, offset_in_dwz,
+					    dwarf2_per_objfile);
 
-      if (per_cu->cu == NULL || per_cu->cu->partial_dies == NULL)
-	load_partial_comp_unit (per_cu, cu->per_objfile, nullptr);
+      cu = dwarf2_per_objfile->get_cu (per_cu);
+      if (cu == NULL || cu->partial_dies == NULL)
+	load_partial_comp_unit (per_cu, dwarf2_per_objfile, nullptr);
 
-      per_cu->cu->last_used = 0;
-      pd = per_cu->cu->find_partial_die (sect_off);
+      cu = dwarf2_per_objfile->get_cu (per_cu);
+
+      cu->last_used = 0;
+      pd = cu->find_partial_die (sect_off);
     }
 
   /* If we didn't find it, and not all dies have been loaded,
      load them all and try again.  */
 
-  if (pd == NULL && per_cu->load_all_dies == 0)
+  if (pd == NULL && cu->per_cu->load_all_dies == 0)
     {
-      per_cu->load_all_dies = 1;
+      cu->per_cu->load_all_dies = 1;
 
       /* This is nasty.  When we reread the DIEs, somewhere up the call chain
 	 THIS_CU->cu may already be in use.  So we can't just free it and
@@ -18699,9 +18681,9 @@ find_partial_die (sect_offset sect_off, int offset_in_dwz, struct dwarf2_cu *cu)
 	 DIEs alone (which can still be in use, e.g. in scan_partial_symbols),
 	 and clobber THIS_CU->cu->partial_dies with the hash table for the new
 	 set.  */
-      load_partial_comp_unit (per_cu, cu->per_objfile, cu);
+      load_partial_comp_unit (cu->per_cu, dwarf2_per_objfile, cu);
 
-      pd = per_cu->cu->find_partial_die (sect_off);
+      pd = cu->find_partial_die (sect_off);
     }
 
   if (pd == NULL)
@@ -18709,7 +18691,7 @@ find_partial_die (sect_offset sect_off, int offset_in_dwz, struct dwarf2_cu *cu)
 		    _("could not find partial DIE %s "
 		      "in cache [from module %s]\n"),
 		    sect_offset_str (sect_off), bfd_get_filename (objfile->obfd));
-  return { per_cu->cu, pd };
+  return { cu, pd };
 }
 
 /* See if we can figure out if the class lives in a namespace.  We do
@@ -19389,7 +19371,7 @@ dwarf2_read_addr_index (dwarf2_per_cu_data *per_cu,
 			dwarf2_per_objfile *dwarf2_per_objfile,
 			unsigned int addr_index)
 {
-  struct dwarf2_cu *cu = per_cu->cu;
+  struct dwarf2_cu *cu = dwarf2_per_objfile->get_cu (per_cu);
   gdb::optional<ULONGEST> addr_base;
   int addr_size;
 
@@ -22230,7 +22212,7 @@ follow_die_offset (sect_offset sect_off, int offset_in_dwz,
       if (maybe_queue_comp_unit (cu, per_cu, dwarf2_per_objfile, cu->language))
 	load_full_comp_unit (per_cu, dwarf2_per_objfile, false, cu->language);
 
-      target_cu = per_cu->cu;
+      target_cu = dwarf2_per_objfile->get_cu (per_cu);
     }
   else if (cu->dies == NULL)
     {
@@ -22290,7 +22272,7 @@ dwarf2_fetch_die_loc_sect_off (sect_offset sect_off,
   struct dwarf2_locexpr_baton retval;
   struct objfile *objfile = dwarf2_per_objfile->objfile;
 
-  dwarf2_cu *cu = per_cu->cu;
+  dwarf2_cu *cu = dwarf2_per_objfile->get_cu (per_cu);
   if (cu == nullptr)
     cu = load_cu (per_cu, dwarf2_per_objfile, false);
 
@@ -22375,7 +22357,7 @@ dwarf2_fetch_die_loc_sect_off (sect_offset sect_off,
   retval.per_objfile = dwarf2_per_objfile;
   retval.per_cu = cu->per_cu;
 
-  age_cached_comp_units (dwarf2_per_objfile);
+  dwarf2_per_objfile->age_comp_units ();
 
   return retval;
 }
@@ -22431,7 +22413,7 @@ dwarf2_fetch_constant_bytes (sect_offset sect_off,
   enum bfd_endian byte_order;
   struct objfile *objfile = per_objfile->objfile;
 
-  dwarf2_cu *cu = per_cu->cu;
+  dwarf2_cu *cu = per_objfile->get_cu (per_cu);
   if (cu == nullptr)
     cu = load_cu (per_cu, per_objfile, false);
 
@@ -22554,7 +22536,7 @@ dwarf2_fetch_die_type_sect_off (sect_offset sect_off,
 {
   struct die_info *die;
 
-  dwarf2_cu *cu = per_cu->cu;
+  dwarf2_cu *cu = per_objfile->get_cu (per_cu);
   if (cu == nullptr)
     cu = load_cu (per_cu, per_objfile, false);
 
@@ -22604,7 +22586,7 @@ follow_die_sig_1 (struct die_info *src_die, struct signatured_type *sig_type,
 			     language_minimal))
     read_signatured_type (sig_type, dwarf2_per_objfile);
 
-  sig_cu = sig_type->per_cu.cu;
+  sig_cu = dwarf2_per_objfile->get_cu (&sig_type->per_cu);
   gdb_assert (sig_cu != NULL);
   gdb_assert (to_underlying (sig_type->type_offset_in_section) != 0);
   temp_die.sect_off = sig_type->type_offset_in_section;
@@ -22778,11 +22760,11 @@ load_full_type_unit (dwarf2_per_cu_data *per_cu,
   gdb_assert (per_cu->is_debug_types);
   sig_type = (struct signatured_type *) per_cu;
 
-  gdb_assert (per_cu->cu == NULL);
+  gdb_assert (per_objfile->get_cu (per_cu) == nullptr);
 
   read_signatured_type (sig_type, per_objfile);
 
-  gdb_assert (per_cu->cu != NULL);
+  gdb_assert (per_objfile->get_cu (per_cu) != nullptr);
 }
 
 /* Read in a signatured type and build its CU and DIEs.
@@ -22796,7 +22778,7 @@ read_signatured_type (signatured_type *sig_type,
   struct dwarf2_per_cu_data *per_cu = &sig_type->per_cu;
 
   gdb_assert (per_cu->is_debug_types);
-  gdb_assert (per_cu->cu == NULL);
+  gdb_assert (per_objfile->get_cu (per_cu) == nullptr);
 
   cutu_reader reader (per_cu, per_objfile, nullptr, nullptr, false);
 
@@ -23503,14 +23485,6 @@ dwarf2_cu::dwarf2_cu (dwarf2_per_cu_data *per_cu,
     producer_is_codewarrior (false),
     processing_has_namespace_info (false)
 {
-  per_cu->cu = this;
-}
-
-/* Destroy a dwarf2_cu.  */
-
-dwarf2_cu::~dwarf2_cu ()
-{
-  per_cu->cu = NULL;
 }
 
 /* Initialize basic fields of dwarf_cu CU according to DIE COMP_UNIT_DIE.  */
@@ -23534,72 +23508,80 @@ prepare_one_comp_unit (struct dwarf2_cu *cu, struct die_info *comp_unit_die,
   cu->producer = dwarf2_string_attr (comp_unit_die, DW_AT_producer, cu);
 }
 
-/* Increase the age counter on each cached compilation unit, and free
-   any that are too old.  */
+/* See read.h.  */
 
-static void
-age_cached_comp_units (struct dwarf2_per_objfile *dwarf2_per_objfile)
+dwarf2_cu *
+dwarf2_per_objfile::get_cu (dwarf2_per_cu_data *per_cu)
 {
-  struct dwarf2_per_cu_data *per_cu, **last_chain;
+  auto it = m_dwarf2_cus.find (per_cu);
+  if (it == m_dwarf2_cus.end ())
+    return nullptr;
 
-  dwarf2_clear_marks (dwarf2_per_objfile->per_bfd->read_in_chain);
-  per_cu = dwarf2_per_objfile->per_bfd->read_in_chain;
-  while (per_cu != NULL)
+  return it->second;
+}
+
+/* See read.h.  */
+
+void
+dwarf2_per_objfile::set_cu (dwarf2_per_cu_data *per_cu, dwarf2_cu *cu)
+{
+  gdb_assert (this->get_cu (per_cu) == nullptr);
+
+  m_dwarf2_cus[per_cu] = cu;
+}
+
+/* See read.h.  */
+
+void
+dwarf2_per_objfile::age_comp_units ()
+{
+  /* Start by clearing all marks.  */
+  for (auto pair : m_dwarf2_cus)
+    pair.second->mark = false;
+
+  /* Traverse all CUs, mark them and their dependencies if used recently
+     enough.  */
+  for (auto pair : m_dwarf2_cus)
     {
-      per_cu->cu->last_used ++;
-      if (per_cu->cu->last_used <= dwarf_max_cache_age)
-	dwarf2_mark (per_cu->cu);
-      per_cu = per_cu->cu->read_in_chain;
+      dwarf2_cu *cu = pair.second;
+
+      cu->last_used++;
+      if (cu->last_used <= dwarf_max_cache_age)
+	dwarf2_mark (cu);
     }
 
-  per_cu = dwarf2_per_objfile->per_bfd->read_in_chain;
-  last_chain = &dwarf2_per_objfile->per_bfd->read_in_chain;
-  while (per_cu != NULL)
+  /* Delete all CUs still not marked.  */
+  for (auto it = m_dwarf2_cus.begin (); it != m_dwarf2_cus.end ();)
     {
-      struct dwarf2_per_cu_data *next_cu;
+      dwarf2_cu *cu = it->second;
 
-      next_cu = per_cu->cu->read_in_chain;
-
-      if (!per_cu->cu->mark)
+      if (!cu->mark)
 	{
-	  delete per_cu->cu;
-	  *last_chain = next_cu;
+	  delete cu;
+	  it = m_dwarf2_cus.erase (it);
 	}
       else
-	last_chain = &per_cu->cu->read_in_chain;
-
-      per_cu = next_cu;
+	it++;
     }
 }
 
-/* Remove a single compilation unit from the cache.  */
+/* See read.h.  */
 
-static void
-free_one_cached_comp_unit (dwarf2_per_cu_data *target_per_cu,
-			   dwarf2_per_objfile *dwarf2_per_objfile)
+void
+dwarf2_per_objfile::remove_cu (dwarf2_per_cu_data *per_cu)
 {
-  struct dwarf2_per_cu_data *per_cu, **last_chain;
-
-  per_cu = dwarf2_per_objfile->per_bfd->read_in_chain;
-  last_chain = &dwarf2_per_objfile->per_bfd->read_in_chain;
-  while (per_cu != NULL)
-    {
-      struct dwarf2_per_cu_data *next_cu;
+  auto it = m_dwarf2_cus.find (per_cu);
+  if (it == m_dwarf2_cus.end ())
+    return;
 
-      next_cu = per_cu->cu->read_in_chain;
+  delete it->second;
 
-      if (per_cu == target_per_cu)
-	{
-	  delete per_cu->cu;
-	  per_cu->cu = NULL;
-	  *last_chain = next_cu;
-	  break;
-	}
-      else
-	last_chain = &per_cu->cu->read_in_chain;
+  m_dwarf2_cus.erase (it);
+}
 
-      per_cu = next_cu;
-    }
+dwarf2_per_objfile::~dwarf2_per_objfile ()
+{
+  remove_all_cus ();
 }
 
 /* A set of CU "per_cu" pointer, DIE offset, and GDB type pointer.
@@ -23801,27 +23783,30 @@ dwarf2_add_dependence (struct dwarf2_cu *cu,
 
 /* Subroutine of dwarf2_mark to pass to htab_traverse.
    Set the mark field in every compilation unit in the
-   cache that we must keep because we are keeping CU.  */
+   cache that we must keep because we are keeping CU.
+
+   DATA is the dwarf2_per_objfile object in which to look up CUs.  */
 
 static int
 dwarf2_mark_helper (void **slot, void *data)
 {
-  struct dwarf2_per_cu_data *per_cu;
-
-  per_cu = (struct dwarf2_per_cu_data *) *slot;
+  dwarf2_per_cu_data *per_cu = (dwarf2_per_cu_data *) *slot;
+  dwarf2_per_objfile *per_objfile = (dwarf2_per_objfile *) data;
+  dwarf2_cu *cu = per_objfile->get_cu (per_cu);
 
   /* cu->dependencies references may not yet have been ever read if QUIT aborts
      reading of the chain.  As such dependencies remain valid it is not much
      useful to track and undo them during QUIT cleanups.  */
-  if (per_cu->cu == NULL)
+  if (cu == nullptr)
     return 1;
 
-  if (per_cu->cu->mark)
+  if (cu->mark)
     return 1;
-  per_cu->cu->mark = true;
 
-  if (per_cu->cu->dependencies != NULL)
-    htab_traverse (per_cu->cu->dependencies, dwarf2_mark_helper, NULL);
+  cu->mark = true;
+
+  if (cu->dependencies != nullptr)
+    htab_traverse (cu->dependencies, dwarf2_mark_helper, per_objfile);
 
   return 1;
 }
@@ -23834,19 +23819,11 @@ dwarf2_mark (struct dwarf2_cu *cu)
 {
   if (cu->mark)
     return;
+
   cu->mark = true;
-  if (cu->dependencies != NULL)
-    htab_traverse (cu->dependencies, dwarf2_mark_helper, NULL);
-}
 
-static void
-dwarf2_clear_marks (struct dwarf2_per_cu_data *per_cu)
-{
-  while (per_cu)
-    {
-      per_cu->cu->mark = false;
-      per_cu = per_cu->cu->read_in_chain;
-    }
+  if (cu->dependencies != nullptr)
+    htab_traverse (cu->dependencies, dwarf2_mark_helper, cu->per_objfile);
 }
 
 /* Trivial hash function for partial_die_info: the hash value of a DIE
diff --git a/gdb/dwarf2/read.h b/gdb/dwarf2/read.h
index b75be312217..996cf55af22 100644
--- a/gdb/dwarf2/read.h
+++ b/gdb/dwarf2/read.h
@@ -43,6 +43,7 @@ struct tu_stats
   int nr_all_type_units_reallocs;
 };
 
+struct dwarf2_cu;
 struct dwarf2_debug_sections;
 struct dwarf2_per_cu_data;
 struct mapped_index;
@@ -115,9 +116,6 @@ struct dwarf2_per_bfd
      TU.  */
   signatured_type *get_tu (int index);
 
-  /* Free all cached compilation units.  */
-  void free_cached_comp_units ();
-
   /* A convenience function to allocate a dwarf2_per_cu_data.  The
      returned object has its "index" field set properly.  The object
      is allocated on the dwarf2_per_bfd obstack.  */
@@ -189,10 +187,6 @@ struct dwarf2_per_bfd
      are doing.  */
   struct tu_stats tu_stats {};
 
-  /* A chain of compilation units that are currently read in, so that
-     they can be freed later.  */
-  dwarf2_per_cu_data *read_in_chain = NULL;
-
   /* A table mapping DW_AT_dwo_name values to struct dwo_file objects.
      This is NULL if the table hasn't been allocated yet.  */
   htab_up dwo_files;
@@ -303,6 +297,8 @@ struct dwarf2_per_objfile
     : objfile (objfile), per_bfd (per_bfd)
   {}
 
+  ~dwarf2_per_objfile ();
+
   /* Return pointer to string at .debug_line_str offset as read from BUF.
      BUF is assumed to be in a compilation unit described by CU_HEADER.
      Return *BYTES_READ_PTR count of bytes read from BUF.  */
@@ -344,6 +340,22 @@ struct dwarf2_per_objfile
      UNSIGNED_P controls if the integer is unsigned or not.  */
   struct type *int_type (int size_in_bytes, bool unsigned_p) const;
 
+  /* Get the dwarf2_cu matching PER_CU for this objfile.  */
+  dwarf2_cu *get_cu (dwarf2_per_cu_data *per_cu);
+
+  /* Set the dwarf2_cu matching PER_CU for this objfile.  */
+  void set_cu (dwarf2_per_cu_data *per_cu, dwarf2_cu *cu);
+
+  /* Remove/free the dwarf2_cu matching PER_CU for this objfile.  */
+  void remove_cu (dwarf2_per_cu_data *per_cu);
+
+  /* Free all cached compilation units.  */
+  void remove_all_cus ();
+
+  /* Increase the age counter on each CU compilation unit and free
+     any that are too old.  */
+  void age_comp_units ();
+
   /* Back link.  */
   struct objfile *objfile;
 
@@ -372,6 +384,10 @@ struct dwarf2_per_objfile
 
   /* Map from signatured types to the corresponding struct type.  */
   std::unordered_map<signatured_type *, struct type *> m_type_map;
+
+  /* Map from the objfile-independent dwarf2_per_cu_data instances to the
+     corresponding objfile-dependent dwarf2_cu instances.  */
+  std::unordered_map<dwarf2_per_cu_data *, dwarf2_cu *> m_dwarf2_cus;
 };
 
 /* Get the dwarf2_per_objfile associated to OBJFILE.  */
@@ -455,11 +471,6 @@ struct dwarf2_per_cu_data
      not the DWO file.  */
   struct dwarf2_section_info *section;
 
-  /* Set to non-NULL iff this CU is currently loaded.  When it gets freed out
-     of the CU cache it gets reset to NULL again.  This is left as NULL for
-     dummy CUs (a CU header, but nothing else).  */
-  struct dwarf2_cu *cu;
-
   /* The unit type of this CU.  */
   enum dwarf_unit_type unit_type;
 
-- 
2.26.2


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

* [PATCH v2 41/42] Make mapped_debug_names independent of objfile
  2020-05-12 21:08 [PATCH v2 00/42] Share DWARF partial symtabs between objfiles Simon Marchi
                   ` (39 preceding siblings ...)
  2020-05-12 21:18 ` [PATCH v2 40/42] Replace dwarf2_per_cu_data::cu backlink with per-objfile map Simon Marchi
@ 2020-05-12 21:18 ` Simon Marchi
  2020-05-22 21:01   ` Tom Tromey
  2020-05-12 21:18 ` [PATCH v2 42/42] Share DWARF partial symtabs Simon Marchi
                   ` (4 subsequent siblings)
  45 siblings, 1 reply; 92+ messages in thread
From: Simon Marchi @ 2020-05-12 21:18 UTC (permalink / raw)
  To: gdb-patches; +Cc: Simon Marchi

mapped_debug_names currently has a dwarf2_per_objfile field.  Since we
want it to become objfile-independent, this field must be removed.

This patch removes it, and then arranges for all methods that needed it
to accept a dwarf2_per_objfile parameter.  This trickles down at various
places, like the dw2_debug_names_iterator type.

Ultimately, the objfile only seems to be needed because we might need to
read a string from the string section.  For that, we might need to read
in the section, and if it's a relocatable section, the objfile is needed
in order to do the relocation.  This pattern happens often (that we to
pass an objfile only because a section might be read).  I think it's a
bit ugly, but I don't have a good alternative right now.

gdb/ChangeLog:

	* dwarf2/read.c (struct mapped_index_base) <symbol_name_at,
	build_name_components, find_name_components_bounds>:
	Add per_objfile parameter.
	(struct mapped_index) <symbol_name_at>: Likewise.
	(struct mapped_debug_names): Remove constructor.
	<dwarf2_per_objfile>: Remove field.
	<namei_to_name, symbol_name_at>: Add per_objfile parameter.
	(mapped_index_base::find_name_components_bounds,
	mapped_index_base::build_name_components,
	dw2_expand_symtabs_matching_symbol): Likewise.
	(class mock_mapped_index) <symbol_name_at>: Likewise.
	(check_match): Likewise.
	(check_find_bounds_finds): Likewise.
	(test_mapped_index_find_name_component_bounds): Update.
	(CHECK_MATCH): Update.
	(dw2_expand_symtabs_matching): Update.
	(class dw2_debug_names_iterator) <dw2_debug_names_iterator>: Add
	per_objfile parameter.
	<find_vec_in_debug_names>: Likewise.
	<m_per_objfile>: New field.
	(mapped_debug_names::namei_to_name): Add dwarf2_per_objfile
	parameter.
	(dw2_debug_names_iterator::find_vec_in_debug_names): Likewise.
	(dw2_debug_names_iterator::next): Update.
	(dw2_debug_names_lookup_symbol): Update.
	(dw2_debug_names_expand_symtabs_for_function): Update.
	(dw2_debug_names_map_matching_symbols): Update.
	(dw2_debug_names_expand_symtabs_matching): Update.
	(dwarf2_read_debug_names): Update.
---
 gdb/dwarf2/read.c | 163 ++++++++++++++++++++++++++--------------------
 1 file changed, 91 insertions(+), 72 deletions(-)

diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 9bc19a089b0..3f93a51381f 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -164,7 +164,8 @@ struct mapped_index_base
   virtual size_t symbol_name_count () const = 0;
 
   /* Get the name of the symbol at IDX in the symbol table.  */
-  virtual const char *symbol_name_at (offset_type idx) const = 0;
+  virtual const char *symbol_name_at
+    (offset_type idx, dwarf2_per_objfile *per_objfile) const = 0;
 
   /* Return whether the name at IDX in the symbol table should be
      ignored.  */
@@ -175,7 +176,7 @@ struct mapped_index_base
 
   /* Build the symbol name component sorted vector, if we haven't
      yet.  */
-  void build_name_components ();
+  void build_name_components (dwarf2_per_objfile *per_objfile);
 
   /* Returns the lower (inclusive) and upper (exclusive) bounds of the
      possible matches for LN_NO_PARAMS in the name component
@@ -183,7 +184,8 @@ struct mapped_index_base
   std::pair<std::vector<name_component>::const_iterator,
 	    std::vector<name_component>::const_iterator>
     find_name_components_bounds (const lookup_name_info &ln_no_params,
-				 enum language lang) const;
+				 enum language lang,
+				 dwarf2_per_objfile *per_objfile) const;
 
   /* Prevent deleting/destroying via a base class pointer.  */
 protected:
@@ -221,7 +223,8 @@ struct mapped_index final : public mapped_index_base
 
   /* Convenience method to get at the name of the symbol at IDX in the
      symbol table.  */
-  const char *symbol_name_at (offset_type idx) const override
+  const char *symbol_name_at
+    (offset_type idx, dwarf2_per_objfile *per_objfile) const override
   { return this->constant_pool + MAYBE_SWAP (this->symbol_table[idx].name); }
 
   size_t symbol_name_count () const override
@@ -232,11 +235,6 @@ struct mapped_index final : public mapped_index_base
    Uninitialized map has CU_COUNT 0.  */
 struct mapped_debug_names final : public mapped_index_base
 {
-  mapped_debug_names (struct dwarf2_per_objfile *dwarf2_per_objfile_)
-  : dwarf2_per_objfile (dwarf2_per_objfile_)
-  {}
-
-  struct dwarf2_per_objfile *dwarf2_per_objfile;
   bfd_endian dwarf5_byte_order;
   bool dwarf5_is_dwarf64;
   bool augmentation_is_gdb;
@@ -268,13 +266,15 @@ struct mapped_debug_names final : public mapped_index_base
 
   std::unordered_map<ULONGEST, index_val> abbrev_map;
 
-  const char *namei_to_name (uint32_t namei) const;
+  const char *namei_to_name
+    (uint32_t namei, dwarf2_per_objfile *per_objfile) const;
 
   /* Implementation of the mapped_index_base virtual interface, for
      the name_components cache.  */
 
-  const char *symbol_name_at (offset_type idx) const override
-  { return namei_to_name (idx); }
+  const char *symbol_name_at
+    (offset_type idx, dwarf2_per_objfile *per_objfile) const override
+  { return namei_to_name (idx, per_objfile); }
 
   size_t symbol_name_count () const override
   { return this->name_count; }
@@ -3802,7 +3802,8 @@ make_sort_after_prefix_name (const char *search_name)
 std::pair<std::vector<name_component>::const_iterator,
 	  std::vector<name_component>::const_iterator>
 mapped_index_base::find_name_components_bounds
-  (const lookup_name_info &lookup_name_without_params, language lang) const
+  (const lookup_name_info &lookup_name_without_params, language lang,
+   dwarf2_per_objfile *per_objfile) const
 {
   auto *name_cmp
     = this->name_components_casing == case_sensitive_on ? strcmp : strcasecmp;
@@ -3815,7 +3816,7 @@ mapped_index_base::find_name_components_bounds
   auto lookup_compare_lower = [&] (const name_component &elem,
 				   const char *name)
     {
-      const char *elem_qualified = this->symbol_name_at (elem.idx);
+      const char *elem_qualified = this->symbol_name_at (elem.idx, per_objfile);
       const char *elem_name = elem_qualified + elem.name_offset;
       return name_cmp (elem_name, name) < 0;
     };
@@ -3825,7 +3826,7 @@ mapped_index_base::find_name_components_bounds
   auto lookup_compare_upper = [&] (const char *name,
 				   const name_component &elem)
     {
-      const char *elem_qualified = this->symbol_name_at (elem.idx);
+      const char *elem_qualified = this->symbol_name_at (elem.idx, per_objfile);
       const char *elem_name = elem_qualified + elem.name_offset;
       return name_cmp (name, elem_name) < 0;
     };
@@ -3874,7 +3875,7 @@ mapped_index_base::find_name_components_bounds
 /* See declaration.  */
 
 void
-mapped_index_base::build_name_components ()
+mapped_index_base::build_name_components (dwarf2_per_objfile *per_objfile)
 {
   if (!this->name_components.empty ())
     return;
@@ -3892,7 +3893,7 @@ mapped_index_base::build_name_components ()
       if (this->symbol_name_slot_invalid (idx))
 	continue;
 
-      const char *name = this->symbol_name_at (idx);
+      const char *name = this->symbol_name_at (idx, per_objfile);
 
       /* Add each name component to the name component table.  */
       unsigned int previous_len = 0;
@@ -3930,8 +3931,10 @@ mapped_index_base::build_name_components ()
   auto name_comp_compare = [&] (const name_component &left,
 				const name_component &right)
     {
-      const char *left_qualified = this->symbol_name_at (left.idx);
-      const char *right_qualified = this->symbol_name_at (right.idx);
+      const char *left_qualified
+	= this->symbol_name_at (left.idx, per_objfile);
+      const char *right_qualified
+	= this->symbol_name_at (right.idx, per_objfile);
 
       const char *left_name = left_qualified + left.name_offset;
       const char *right_name = right_qualified + right.name_offset;
@@ -3957,14 +3960,15 @@ dw2_expand_symtabs_matching_symbol
    const lookup_name_info &lookup_name_in,
    gdb::function_view<expand_symtabs_symbol_matcher_ftype> symbol_matcher,
    enum search_domain kind,
-   gdb::function_view<bool (offset_type)> match_callback)
+   gdb::function_view<bool (offset_type)> match_callback,
+   dwarf2_per_objfile *per_objfile)
 {
   lookup_name_info lookup_name_without_params
     = lookup_name_in.make_ignore_params ();
 
   /* Build the symbol name component sorted vector, if we haven't
      yet.  */
-  index.build_name_components ();
+  index.build_name_components (per_objfile);
 
   /* The same symbol may appear more than once in the range though.
      E.g., if we're looking for symbols that complete "w", and we have
@@ -4014,14 +4018,15 @@ dw2_expand_symtabs_matching_symbol
 
       auto bounds
 	= index.find_name_components_bounds (lookup_name_without_params,
-					     lang_e);
+					     lang_e, per_objfile);
 
       /* Now for each symbol name in range, check to see if we have a name
 	 match, and if so, call the MATCH_CALLBACK callback.  */
 
       for (; bounds.first != bounds.second; ++bounds.first)
 	{
-	  const char *qualified = index.symbol_name_at (bounds.first->idx);
+	  const char *qualified
+	    = index.symbol_name_at (bounds.first->idx, per_objfile);
 
 	  if (!name_matcher (qualified, lookup_name_without_params, NULL)
 	      || (symbol_matcher != NULL && !symbol_matcher (qualified)))
@@ -4074,7 +4079,8 @@ class mock_mapped_index : public mapped_index_base
   }
 
   /* Get the name of the symbol at IDX in the symbol table.  */
-  const char *symbol_name_at (offset_type idx) const override
+  const char *symbol_name_at
+    (offset_type idx, dwarf2_per_objfile *per_objfile) const override
   {
     return m_symbol_table[idx];
   }
@@ -4104,7 +4110,8 @@ check_match (const char *file, int line,
 	     mock_mapped_index &mock_index,
 	     const char *name, symbol_name_match_type match_type,
 	     bool completion_mode,
-	     std::initializer_list<const char *> expected_list)
+	     std::initializer_list<const char *> expected_list,
+	     dwarf2_per_objfile *per_objfile)
 {
   lookup_name_info lookup_name (name, match_type, completion_mode);
 
@@ -4129,14 +4136,14 @@ check_match (const char *file, int line,
 				      NULL, ALL_DOMAIN,
 				      [&] (offset_type idx)
   {
-    const char *matched_name = mock_index.symbol_name_at (idx);
+    const char *matched_name = mock_index.symbol_name_at (idx, per_objfile);
     const char *expected_str
       = expected_it == expected_end ? NULL : *expected_it++;
 
     if (expected_str == NULL || strcmp (expected_str, matched_name) != 0)
       mismatch (expected_str, matched_name);
     return true;
-  });
+  }, per_objfile);
 
   const char *expected_str
   = expected_it == expected_end ? NULL : *expected_it++;
@@ -4197,13 +4204,15 @@ static const char *test_symbols[] = {
 static bool
 check_find_bounds_finds (mapped_index_base &index,
 			 const char *search_name,
-			 gdb::array_view<const char *> expected_syms)
+			 gdb::array_view<const char *> expected_syms,
+			 dwarf2_per_objfile *per_objfile)
 {
   lookup_name_info lookup_name (search_name,
 				symbol_name_match_type::FULL, true);
 
   auto bounds = index.find_name_components_bounds (lookup_name,
-						   language_cplus);
+						   language_cplus,
+						   per_objfile);
 
   size_t distance = std::distance (bounds.first, bounds.second);
   if (distance != expected_syms.size ())
@@ -4212,7 +4221,7 @@ check_find_bounds_finds (mapped_index_base &index,
   for (size_t exp_elem = 0; exp_elem < distance; exp_elem++)
     {
       auto nc_elem = bounds.first + exp_elem;
-      const char *qualified = index.symbol_name_at (nc_elem->idx);
+      const char *qualified = index.symbol_name_at (nc_elem->idx, per_objfile);
       if (strcmp (qualified, expected_syms[exp_elem]) != 0)
 	return false;
     }
@@ -4228,7 +4237,7 @@ test_mapped_index_find_name_component_bounds ()
 {
   mock_mapped_index mock_index (test_symbols);
 
-  mock_index.build_name_components ();
+  mock_index.build_name_components (NULL /* per_objfile */);
 
   /* Test the lower-level mapped_index::find_name_component_bounds
      method in completion mode.  */
@@ -4238,8 +4247,9 @@ test_mapped_index_find_name_component_bounds ()
       "t1_func1",
     };
 
-    SELF_CHECK (check_find_bounds_finds (mock_index,
-					 "t1_func", expected_syms));
+    SELF_CHECK (check_find_bounds_finds
+		  (mock_index, "t1_func", expected_syms,
+		   NULL /* per_objfile */));
   }
 
   /* Check that the increment-last-char in the name matching algorithm
@@ -4249,14 +4259,15 @@ test_mapped_index_find_name_component_bounds ()
       "\377",
       "\377\377123",
     };
-    SELF_CHECK (check_find_bounds_finds (mock_index,
-					 "\377", expected_syms1));
+    SELF_CHECK (check_find_bounds_finds
+		  (mock_index, "\377", expected_syms1, NULL /* per_objfile */));
 
     static const char *expected_syms2[] = {
       "\377\377123",
     };
-    SELF_CHECK (check_find_bounds_finds (mock_index,
-					 "\377\377", expected_syms2));
+    SELF_CHECK (check_find_bounds_finds
+		  (mock_index, "\377\377", expected_syms2,
+		   NULL /* per_objfile */));
   }
 }
 
@@ -4282,7 +4293,7 @@ test_dw2_expand_symtabs_matching_symbol ()
   any_mismatch |= !check_match (__FILE__, __LINE__,			\
 				mock_index,				\
 				NAME, MATCH_TYPE, COMPLETION_MODE,	\
-				EXPECTED_LIST)
+				EXPECTED_LIST, NULL)
 
   /* Identity checks.  */
   for (const char *sym : test_symbols)
@@ -4705,7 +4716,7 @@ dw2_expand_symtabs_matching
       dw2_expand_marked_cus (dwarf2_per_objfile, idx, file_matcher,
 			     expansion_notify, kind);
       return true;
-    });
+    }, dwarf2_per_objfile);
 }
 
 /* A helper for dw2_find_pc_sect_compunit_symtab which finds the most specific
@@ -5132,9 +5143,8 @@ create_cus_from_debug_names (dwarf2_per_bfd *per_bfd,
 static bool
 dwarf2_read_debug_names (struct dwarf2_per_objfile *dwarf2_per_objfile)
 {
-  std::unique_ptr<mapped_debug_names> map
-    (new mapped_debug_names (dwarf2_per_objfile));
-  mapped_debug_names dwz_map (dwarf2_per_objfile);
+  std::unique_ptr<mapped_debug_names> map (new mapped_debug_names);
+  mapped_debug_names dwz_map;
   struct objfile *objfile = dwarf2_per_objfile->objfile;
 
   if (!read_debug_names_from_section (objfile, objfile_name (objfile),
@@ -5196,23 +5206,26 @@ class dw2_debug_names_iterator
   dw2_debug_names_iterator (const mapped_debug_names &map,
 			    gdb::optional<block_enum> block_index,
 			    domain_enum domain,
-			    const char *name)
+			    const char *name, dwarf2_per_objfile *per_objfile)
     : m_map (map), m_block_index (block_index), m_domain (domain),
-      m_addr (find_vec_in_debug_names (map, name))
+      m_addr (find_vec_in_debug_names (map, name, per_objfile)),
+      m_per_objfile (per_objfile)
   {}
 
   dw2_debug_names_iterator (const mapped_debug_names &map,
-			    search_domain search, uint32_t namei)
+			    search_domain search, uint32_t namei, dwarf2_per_objfile *per_objfile)
     : m_map (map),
       m_search (search),
-      m_addr (find_vec_in_debug_names (map, namei))
+      m_addr (find_vec_in_debug_names (map, namei, per_objfile)),
+      m_per_objfile (per_objfile)
   {}
 
   dw2_debug_names_iterator (const mapped_debug_names &map,
 			    block_enum block_index, domain_enum domain,
-			    uint32_t namei)
+			    uint32_t namei, dwarf2_per_objfile *per_objfile)
     : m_map (map), m_block_index (block_index), m_domain (domain),
-      m_addr (find_vec_in_debug_names (map, namei))
+      m_addr (find_vec_in_debug_names (map, namei, per_objfile)),
+      m_per_objfile (per_objfile)
   {}
 
   /* Return the next matching CU or NULL if there are no more.  */
@@ -5220,9 +5233,9 @@ class dw2_debug_names_iterator
 
 private:
   static const gdb_byte *find_vec_in_debug_names (const mapped_debug_names &map,
-						  const char *name);
+						  const char *name, dwarf2_per_objfile *per_objfile);
   static const gdb_byte *find_vec_in_debug_names (const mapped_debug_names &map,
-						  uint32_t namei);
+						  uint32_t namei, dwarf2_per_objfile *per_objfile);
 
   /* The internalized form of .debug_names.  */
   const mapped_debug_names &m_map;
@@ -5238,10 +5251,13 @@ class dw2_debug_names_iterator
   /* The list of CUs from the index entry of the symbol, or NULL if
      not found.  */
   const gdb_byte *m_addr;
+
+  dwarf2_per_objfile *m_per_objfile;
 };
 
 const char *
-mapped_debug_names::namei_to_name (uint32_t namei) const
+mapped_debug_names::namei_to_name
+  (uint32_t namei, dwarf2_per_objfile *dwarf2_per_objfile) const
 {
   const ULONGEST namei_string_offs
     = extract_unsigned_integer ((name_table_string_offs_reordered
@@ -5258,7 +5274,7 @@ mapped_debug_names::namei_to_name (uint32_t namei) const
 
 const gdb_byte *
 dw2_debug_names_iterator::find_vec_in_debug_names
-  (const mapped_debug_names &map, const char *name)
+  (const mapped_debug_names &map, const char *name, dwarf2_per_objfile *per_objfile)
 {
   int (*cmp) (const char *, const char *);
 
@@ -5294,7 +5310,7 @@ dw2_debug_names_iterator::find_vec_in_debug_names
       complaint (_("Wrong .debug_names with name index %u but name_count=%u "
 		   "[in module %s]"),
 		 namei, map.name_count,
-		 objfile_name (map.dwarf2_per_objfile->objfile));
+		 objfile_name (per_objfile->objfile));
       return NULL;
     }
 
@@ -5309,7 +5325,7 @@ dw2_debug_names_iterator::find_vec_in_debug_names
 
       if (full_hash == namei_full_hash)
 	{
-	  const char *const namei_string = map.namei_to_name (namei);
+	  const char *const namei_string = map.namei_to_name (namei, per_objfile);
 
 #if 0 /* An expensive sanity check.  */
 	  if (namei_full_hash != dwarf5_djb_hash (namei_string))
@@ -5339,14 +5355,14 @@ dw2_debug_names_iterator::find_vec_in_debug_names
 
 const gdb_byte *
 dw2_debug_names_iterator::find_vec_in_debug_names
-  (const mapped_debug_names &map, uint32_t namei)
+  (const mapped_debug_names &map, uint32_t namei, dwarf2_per_objfile *per_objfile)
 {
   if (namei >= map.name_count)
     {
       complaint (_("Wrong .debug_names with name index %u but name_count=%u "
 		   "[in module %s]"),
 		 namei, map.name_count,
-		 objfile_name (map.dwarf2_per_objfile->objfile));
+		 objfile_name (per_objfile->objfile));
       return NULL;
     }
 
@@ -5365,8 +5381,8 @@ dw2_debug_names_iterator::next ()
   if (m_addr == NULL)
     return NULL;
 
-  struct dwarf2_per_objfile *dwarf2_per_objfile = m_map.dwarf2_per_objfile;
-  struct objfile *objfile = dwarf2_per_objfile->objfile;
+  dwarf2_per_bfd *per_bfd = m_per_objfile->per_bfd;
+  struct objfile *objfile = m_per_objfile->objfile;
   bfd *const abfd = objfile->obfd;
 
  again:
@@ -5429,33 +5445,33 @@ dw2_debug_names_iterator::next ()
 	{
 	case DW_IDX_compile_unit:
 	  /* Don't crash on bad data.  */
-	  if (ull >= dwarf2_per_objfile->per_bfd->all_comp_units.size ())
+	  if (ull >= m_per_objfile->per_bfd->all_comp_units.size ())
 	    {
 	      complaint (_(".debug_names entry has bad CU index %s"
 			   " [in module %s]"),
 			 pulongest (ull),
-			 objfile_name (dwarf2_per_objfile->objfile));
+			 objfile_name (objfile));
 	      continue;
 	    }
-	  per_cu = dwarf2_per_objfile->per_bfd->get_cutu (ull);
+	  per_cu = per_bfd->get_cutu (ull);
 	  break;
 	case DW_IDX_type_unit:
 	  /* Don't crash on bad data.  */
-	  if (ull >= dwarf2_per_objfile->per_bfd->all_type_units.size ())
+	  if (ull >= per_bfd->all_type_units.size ())
 	    {
 	      complaint (_(".debug_names entry has bad TU index %s"
 			   " [in module %s]"),
 			 pulongest (ull),
-			 objfile_name (dwarf2_per_objfile->objfile));
+			 objfile_name (objfile));
 	      continue;
 	    }
-	  per_cu = &dwarf2_per_objfile->per_bfd->get_tu (ull)->per_cu;
+	  per_cu = &per_bfd->get_tu (ull)->per_cu;
 	  break;
 	case DW_IDX_die_offset:
 	  /* In a per-CU index (as opposed to a per-module index), index
 	     entries without CU attribute implicitly refer to the single CU.  */
 	  if (per_cu == NULL)
-	    per_cu = dwarf2_per_objfile->per_bfd->get_cu (0);
+	    per_cu = per_bfd->get_cu (0);
 	  break;
 	case DW_IDX_GNU_internal:
 	  if (!m_map.augmentation_is_gdb)
@@ -5471,7 +5487,7 @@ dw2_debug_names_iterator::next ()
     }
 
   /* Skip if already read in.  */
-  if (dwarf2_per_objfile->symtab_set_p (per_cu))
+  if (m_per_objfile->symtab_set_p (per_cu))
     goto again;
 
   /* Check static vs global.  */
@@ -5596,7 +5612,8 @@ dw2_debug_names_lookup_symbol (struct objfile *objfile, block_enum block_index,
     }
   const auto &map = *mapp;
 
-  dw2_debug_names_iterator iter (map, block_index, domain, name);
+  dw2_debug_names_iterator iter (map, block_index, domain, name,
+				 dwarf2_per_objfile);
 
   struct compunit_symtab *stab_best = NULL;
   struct dwarf2_per_cu_data *per_cu;
@@ -5660,7 +5677,8 @@ dw2_debug_names_expand_symtabs_for_function (struct objfile *objfile,
     {
       const mapped_debug_names &map = *dwarf2_per_objfile->per_bfd->debug_names_table;
 
-      dw2_debug_names_iterator iter (map, {}, VAR_DOMAIN, func_name);
+      dw2_debug_names_iterator iter (map, {}, VAR_DOMAIN, func_name,
+				     dwarf2_per_objfile);
 
       struct dwarf2_per_cu_data *per_cu;
       while ((per_cu = iter.next ()) != NULL)
@@ -5699,14 +5717,15 @@ dw2_debug_names_map_matching_symbols
     {
       /* The name was matched, now expand corresponding CUs that were
 	 marked.  */
-      dw2_debug_names_iterator iter (map, block_kind, domain, namei);
+      dw2_debug_names_iterator iter (map, block_kind, domain, namei,
+				     dwarf2_per_objfile);
 
       struct dwarf2_per_cu_data *per_cu;
       while ((per_cu = iter.next ()) != NULL)
 	dw2_expand_symtabs_matching_one (per_cu, dwarf2_per_objfile, nullptr,
 					 nullptr);
       return true;
-    });
+    }, dwarf2_per_objfile);
 
   /* It's a shame we couldn't do this inside the
      dw2_expand_symtabs_matching_symbol callback, but that skips CUs
@@ -5764,14 +5783,14 @@ dw2_debug_names_expand_symtabs_matching
     {
       /* The name was matched, now expand corresponding CUs that were
 	 marked.  */
-      dw2_debug_names_iterator iter (map, kind, namei);
+      dw2_debug_names_iterator iter (map, kind, namei, dwarf2_per_objfile);
 
       struct dwarf2_per_cu_data *per_cu;
       while ((per_cu = iter.next ()) != NULL)
 	dw2_expand_symtabs_matching_one (per_cu, dwarf2_per_objfile,
 					 file_matcher, expansion_notify);
       return true;
-    });
+    }, dwarf2_per_objfile);
 }
 
 const struct quick_symbol_functions dwarf2_debug_names_functions =
-- 
2.26.2


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

* [PATCH v2 42/42] Share DWARF partial symtabs
  2020-05-12 21:08 [PATCH v2 00/42] Share DWARF partial symtabs between objfiles Simon Marchi
                   ` (40 preceding siblings ...)
  2020-05-12 21:18 ` [PATCH v2 41/42] Make mapped_debug_names independent of objfile Simon Marchi
@ 2020-05-12 21:18 ` Simon Marchi
  2020-05-13 10:17 ` [PATCH v2 00/42] Share DWARF partial symtabs between objfiles Tom de Vries
                   ` (3 subsequent siblings)
  45 siblings, 0 replies; 92+ messages in thread
From: Simon Marchi @ 2020-05-12 21:18 UTC (permalink / raw)
  To: gdb-patches; +Cc: Tom Tromey

From: Tom Tromey <tom@tromey.com>

This changes the DWARF reader to share partial symtabs (or indices if
they are available) across objfiles.  This has a few parts.

* If multiple objfiles backed by the same BFD can share partial symtabs
  (see below), a single dwarf2_per_bfd is created.  It is stored in the
  per-bfd `dwarf2_per_bfd_bfd_data_key` registry.  Multiple
  dwarf2_per_objfile objects will point to the same instance.  The
  lifetime of these dwarf2_per_bfd objects is naturally handled.  When
  all the objfiles using the BFD are destroyed, the BFD's refount drops
  to 0, which triggers the removal of the corresponding dwarf2_per_bfd
  object from the registry and its destruction.

* If multiple objfiles backed by the same BFD can't share partial
  symtabs (see below), one dwarf2_per_bfd object is created for each
  objfile.  Each dwarf2_per_objfile will point to their own instance of
  dwarf2_per_bfd.  These instances of dwarf2_per_bfd are kept in a
  per-objfile registry, meaning that when the objfile gets destroyed,
  the dwarf2_per_bfd instance gets destroyed as well.

* objfile::partial_symtabs is changed to be a shared_ptr again.  This
  lets us stash a second reference in dwarf2_per_bfd; if the DWARF
  data is being shared, we can simply copy this value to the new
  objfile.

* Two dwarf2_per_objfile objects backed by the same BFD may share a
  dwarf2_per_bfd instance if:

  * No other symbol reader has found symbols, and
  * No BFD section rqeuires relocation

YYYY-MM-DD  Tom Tromey  <tom@tromey.com>
YYYY-MM-DD  Simon Marchi  <simon.marchi@efficios.com>

	* objfiles.h (struct objfile) <partial_symtabs>: Now a
	shared_ptr.
	* dwarf2/read.h (struct dwarf2_per_objfile) <partial_symtabs>: New
	member.
	* dwarf2/read.c (dwarf2_per_bfd_bfd_data_key,
	dwarf2_per_bfd_objfile_data_key>: New globals.
	(dwarf2_has_info): Use shared dwarf2_per_bfd if possible.
	(dwarf2_get_section_info): Use get_dwarf2_per_objfile.
	(dwarf2_initialize_objfile): Consider cases where per_bfd can be
	shared.
	(dwarf2_build_psymtabs): Set objfile::partial_symtabs and
	short-circuit when sharing.
	(dwarf2_build_psymtabs): Set dwarf2_per_objfile::partial_symtabs.
	(dwarf2_psymtab::expand_psymtab): Use free_cached_comp_units.
---
 gdb/dwarf2/read.c | 105 +++++++++++++++++++++++++++++++++++++++-------
 gdb/dwarf2/read.h |   5 +++
 gdb/objfiles.h    |   2 +-
 3 files changed, 97 insertions(+), 15 deletions(-)

diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 3f93a51381f..2de4ead004f 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -105,7 +105,19 @@ static bool check_physname = false;
 /* When true, do not reject deprecated .gdb_index sections.  */
 static bool use_deprecated_index_sections = false;
 
-static const struct objfile_key<dwarf2_per_objfile> dwarf2_objfile_data_key;
+/* This is used to store the data that is always per objfile.  */
+static const objfile_key<dwarf2_per_objfile> dwarf2_objfile_data_key;
+
+/* These are used to store the dwarf2_per_bfd objects.
+
+   objfiles having the same BFD, which doesn't require relocations, are going to
+   share a dwarf2_per_bfd object, which is held in the _bfd_data_key version.
+
+   Other objfiles are not going to share a dwarf2_per_bfd with any other
+   objfiles, so they'll have their own version kept in the _objfile_data_key
+   version.  */
+static const struct bfd_key<dwarf2_per_bfd> dwarf2_per_bfd_bfd_data_key;
+static const struct objfile_key<dwarf2_per_bfd> dwarf2_per_bfd_objfile_data_key;
 
 /* The "aclass" indices for various kinds of computed DWARF symbols.  */
 
@@ -1853,9 +1865,30 @@ dwarf2_has_info (struct objfile *objfile,
 
   if (dwarf2_per_objfile == NULL)
     {
-      /* For now, each dwarf2_per_objfile owns its own dwarf2_per_bfd (no
-         sharing yet).  */
-      dwarf2_per_bfd *per_bfd = new dwarf2_per_bfd (objfile->obfd, names, can_copy);
+      dwarf2_per_bfd *per_bfd;
+
+      /* We can share a "dwarf2_per_bfd" with other objfiles if the BFD
+         doesn't require relocations and if there aren't partial symbols
+	 from some other reader.  */
+      if (!objfile_has_partial_symbols (objfile)
+	  && !gdb_bfd_requires_relocations (objfile->obfd))
+	{
+	  /* See if one has been created for this BFD yet.  */
+	  per_bfd = dwarf2_per_bfd_bfd_data_key.get (objfile->obfd);
+
+	  if (per_bfd == nullptr)
+	    {
+	      /* No, create it now.  */
+	      per_bfd = new dwarf2_per_bfd (objfile->obfd, names, can_copy);
+	      dwarf2_per_bfd_bfd_data_key.set (objfile->obfd, per_bfd);
+	    }
+	}
+      else
+	{
+	  /* No sharing possible, create one specifically for this objfile.  */
+	  per_bfd = new dwarf2_per_bfd (objfile->obfd, names, can_copy);
+	  dwarf2_per_bfd_objfile_data_key.set (objfile, per_bfd);
+	}
 
       dwarf2_per_objfile = dwarf2_objfile_data_key.emplace (objfile, objfile, per_bfd);
     }
@@ -2017,7 +2050,7 @@ dwarf2_get_section_info (struct objfile *objfile,
                          asection **sectp, const gdb_byte **bufp,
                          bfd_size_type *sizep)
 {
-  struct dwarf2_per_objfile *data = dwarf2_objfile_data_key.get (objfile);
+  struct dwarf2_per_objfile *data = get_dwarf2_per_objfile (objfile);
   struct dwarf2_section_info *info;
 
   /* We may see an objfile without any DWARF, in which case we just
@@ -5874,6 +5907,7 @@ dwarf2_initialize_objfile (struct objfile *objfile, dw_index_kind *index_kind)
 {
   struct dwarf2_per_objfile *dwarf2_per_objfile
     = get_dwarf2_per_objfile (objfile);
+  dwarf2_per_bfd *per_bfd = dwarf2_per_objfile->per_bfd;
 
   /* If we're about to read full symbols, don't bother with the
      indices.  In this case we also don't care if some other debug
@@ -5881,20 +5915,28 @@ dwarf2_initialize_objfile (struct objfile *objfile, dw_index_kind *index_kind)
      expanded anyway.  */
   if ((objfile->flags & OBJF_READNOW))
     {
-      dwarf2_per_objfile->per_bfd->using_index = 1;
+      /* When using READNOW, the using_index flag (set below) indicates that
+	 PER_BFD was already initialized, when we loaded some other objfile.  */
+      if (per_bfd->using_index)
+	{
+	  *index_kind = dw_index_kind::GDB_INDEX;
+	  dwarf2_per_objfile->resize_symtabs ();
+	  return true;
+	}
+
+      per_bfd->using_index = 1;
       create_all_comp_units (dwarf2_per_objfile);
       create_all_type_units (dwarf2_per_objfile);
-      dwarf2_per_objfile->per_bfd->quick_file_names_table
-	= create_quick_file_names_table
-	    (dwarf2_per_objfile->per_bfd->all_comp_units.size ());
+      per_bfd->quick_file_names_table
+	= create_quick_file_names_table (per_bfd->all_comp_units.size ());
       dwarf2_per_objfile->resize_symtabs ();
 
-      for (int i = 0; i < (dwarf2_per_objfile->per_bfd->all_comp_units.size ()
-			   + dwarf2_per_objfile->per_bfd->all_type_units.size ()); ++i)
+      for (int i = 0; i < (per_bfd->all_comp_units.size ()
+			   + per_bfd->all_type_units.size ()); ++i)
 	{
-	  dwarf2_per_cu_data *per_cu = dwarf2_per_objfile->per_bfd->get_cutu (i);
+	  dwarf2_per_cu_data *per_cu = per_bfd->get_cutu (i);
 
-	  per_cu->v.quick = OBSTACK_ZALLOC (&dwarf2_per_objfile->per_bfd->obstack,
+	  per_cu->v.quick = OBSTACK_ZALLOC (&per_bfd->obstack,
 					    struct dwarf2_per_cu_quick_data);
 	}
 
@@ -5905,6 +5947,24 @@ dwarf2_initialize_objfile (struct objfile *objfile, dw_index_kind *index_kind)
       return true;
     }
 
+  /* Was a debug names index already read when we processed an objfile sharing
+     PER_BFD?  */
+  if (per_bfd->debug_names_table != nullptr)
+    {
+      *index_kind = dw_index_kind::DEBUG_NAMES;
+      dwarf2_per_objfile->resize_symtabs ();
+      return true;
+    }
+
+  /* Was a GDB index already read when we processed an objfile sharing
+     PER_BFD?  */
+  if (per_bfd->index_table != nullptr)
+    {
+      *index_kind = dw_index_kind::GDB_INDEX;
+      dwarf2_per_objfile->resize_symtabs ();
+      return true;
+    }
+
   if (dwarf2_read_debug_names (dwarf2_per_objfile))
     {
       *index_kind = dw_index_kind::DEBUG_NAMES;
@@ -5945,6 +6005,16 @@ dwarf2_build_psymtabs (struct objfile *objfile)
 {
   struct dwarf2_per_objfile *dwarf2_per_objfile
     = get_dwarf2_per_objfile (objfile);
+  dwarf2_per_bfd *per_bfd = dwarf2_per_objfile->per_bfd;
+
+  if (per_bfd->partial_symtabs != nullptr)
+    {
+      /* Partial symbols were already read, so now we can simply
+	 attach them.  */
+      objfile->partial_symtabs = per_bfd->partial_symtabs;
+      dwarf2_per_objfile->resize_symtabs ();
+      return;
+    }
 
   init_psymbol_list (objfile, 1024);
 
@@ -5966,6 +6036,12 @@ dwarf2_build_psymtabs (struct objfile *objfile)
     {
       exception_print (gdb_stderr, except);
     }
+
+  /* Finish by setting the local reference to partial symtabs, so that
+     we don't try to read them again if reading another objfile with the same
+     BFD.  If we can't in fact share, this won't make a difference anyway as
+     the dwarf2_per_bfd object won't be shared.  */
+  per_bfd->partial_symtabs = objfile->partial_symtabs;
 }
 
 /* Find the base address of the compilation unit for range lists and
@@ -9014,9 +9090,10 @@ dwarf2_psymtab::expand_psymtab (struct objfile *objfile)
 {
   gdb_assert (!readin_p (objfile));
 
+  dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile);
+  free_cached_comp_units freer (per_objfile);
   expand_dependencies (objfile);
 
-  dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile);
   dw2_do_instantiate_symtab (per_cu_data, per_objfile, false);
   gdb_assert (get_compunit_symtab (objfile) != nullptr);
 }
diff --git a/gdb/dwarf2/read.h b/gdb/dwarf2/read.h
index 996cf55af22..53f0c7361a3 100644
--- a/gdb/dwarf2/read.h
+++ b/gdb/dwarf2/read.h
@@ -254,6 +254,11 @@ struct dwarf2_per_bfd
   /* CUs that are queued to be read.  */
   std::queue<dwarf2_queue_item> queue;
 
+  /* We keep a separate reference to the partial symtabs, in case we
+     are sharing them between objfiles.  This is only set after
+     partial symbols have been read the first time.  */
+  std::shared_ptr<psymtab_storage> partial_symtabs;
+
 private:
 
   /* The total number of per_cu and signatured_type objects that have
diff --git a/gdb/objfiles.h b/gdb/objfiles.h
index 0b47bd0c1e2..56ff52119dc 100644
--- a/gdb/objfiles.h
+++ b/gdb/objfiles.h
@@ -576,7 +576,7 @@ struct objfile
 
   /* The partial symbol tables.  */
 
-  std::unique_ptr<psymtab_storage> partial_symtabs;
+  std::shared_ptr<psymtab_storage> partial_symtabs;
 
   /* The object file's BFD.  Can be null if the objfile contains only
      minimal symbols, e.g. the run time common symbols for SunOS4.  */
-- 
2.26.2


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

* Re: [PATCH v2 33/42] Split type_unit_group
  2020-05-12 21:17 ` [PATCH v2 33/42] Split type_unit_group Simon Marchi
@ 2020-05-13  9:54   ` Tom de Vries
  2020-05-13 15:06     ` Simon Marchi
  0 siblings, 1 reply; 92+ messages in thread
From: Tom de Vries @ 2020-05-13  9:54 UTC (permalink / raw)
  To: Simon Marchi, gdb-patches; +Cc: Tom Tromey

On 12-05-2020 23:17, Simon Marchi via Gdb-patches wrote:
> +   that can be shared across objfiles.  The non-shareable parts are in 

Hi,

FYI during applying I got:
...
Applying: Split type_unit_group
.git/rebase-apply/patch:16: trailing whitespace.
   that can be shared across objfiles.  The non-shareable parts are in
warning: 1 line adds whitespace errors.
...

Thanks,
- Tom

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

* Re: [PATCH v2 00/42] Share DWARF partial symtabs between objfiles
  2020-05-12 21:08 [PATCH v2 00/42] Share DWARF partial symtabs between objfiles Simon Marchi
                   ` (41 preceding siblings ...)
  2020-05-12 21:18 ` [PATCH v2 42/42] Share DWARF partial symtabs Simon Marchi
@ 2020-05-13 10:17 ` Tom de Vries
  2020-05-13 15:46   ` Simon Marchi
  2020-05-13 14:52 ` Simon Marchi
                   ` (2 subsequent siblings)
  45 siblings, 1 reply; 92+ messages in thread
From: Tom de Vries @ 2020-05-13 10:17 UTC (permalink / raw)
  To: Simon Marchi, gdb-patches

On 12-05-2020 23:08, Simon Marchi via Gdb-patches wrote:
> This is version 2 of this patchset originally written by Tom:
> 
>     https://sourceware.org/legacy-ml/gdb-patches/2020-02/msg00594.html
> 
> The current patchset therefore contains a mix of Tom's patches that I modified,
> plus a few new patches.  I won't repeat everything that is said in the cover
> letter of that patchset, please read that to understand the motivation behind
> this change..
> 
> The big difference between v1 and v2 is how the split is done.  In v1, the
> object structure looks like this:
> 
>     objfile -> dwarf2_per_objfile -> dwarf2_unshareable
> 
> where `dwarf2_per_objfile` is actually shared between objfiles (there is one
> copy per BFD), and `dwarf2_unshareable` is not (there is one copy per objfile).
> The dwarf2_per_objfile -> dwarf2_unshareable link is updated at all entry
> points of the DWARF code based on what is the current objfile.
> 
> The current patchset (v2) proposes this structure instead, which in my opinion
> is more natural:
> 
>     objfile -> dwarf2_per_objfile -> dwarf2_per_bfd
> 
> Where `dwarf2_per_objfile` is really per-objfile (there is one copy per
> objfile) and `dwarf2_per_bfd` is per-bfd (there is one copy per-bfd).  There is
> no link to update, whatever is shared between objfiles is put in
> `dwarf2_per_bfd` and each `dwarf2_per_objfile` always points to one
> `dwarf2_per_bfd`.
> 
> Since there were performance numbers with the original patchset, I made my own
> here to see if the speedups were still there.  Like in the original patchset, I
> set "maintenance time 1" and did "add-inferior -exec ./gdb" after "./gdb gdb".
> I disabled any auto-loading to avoid loading gdb-gdb.{gdb,py}.  GDB is built
> with -O2 and gcc 9, and it is running on an AMD EPYC 7351P.
> 
> Before: Command execution time: 1.213480 (cpu), 1.214268 (wall)
> After: Command execution time: 0.001697 (cpu), 0.001694 (wall)
> 
> These are the times of one run, but all runs I did are very close.  The "after"
> time is surpringly low compared to the original numbers, I hope it doesn't mean
> I messed up something and we are skipping something important...
> 
> At some point I tested with all these boards and did not see any regression
> (they helped very much to find some issues in the process though):
> 
>     unix cc-with-debug-names cc-with-dwz cc-with-dwz-m cc-with-gdb-index dwarf4-gdb-index fission-dwp fission readnow
> 
> I have since rebased the patchset and resolved conflicts, it's therefore
> possible I messed something up.
> 

Hi, I applied the patch series on top of commit 90d00bbd9c "Sync config
and libiberty with GCC", and ran into the following:
...
(gdb) PASS: gdb.ada/variant.exp: scenario=minimal: print nav1
print nav2^M
ERROR: GDB process no longer exists
GDB process exited with wait status 8901 exp9 0 0 CHILDKILLED SIGABRT
SIGABRT
UNRESOLVED: gdb.ada/variant.exp: scenario=minimal: print nav2
...

Reproduced on command line using:
...
$ gdb -batch ./outputs/gdb.ada/variant/pkg \
  -ex 'break pkg.adb:40' \
  -ex run \
  -ex 'print nav2'
Breakpoint 1 at 0x403047: file gdb/testsuite/gdb.ada/variant/pkg.adb,
line 40.

Breakpoint 1, pkg () at gdb/testsuite/gdb.ada/variant/pkg.adb:40
40         null; -- STOP
Aborted (core dumped)
...

Using gdb, we get more info:
...
Thread 1 "gdb" received signal SIGSEGV, Segmentation fault.
0x00000000005b9d02 in dwarf2_locexpr_baton_eval (dlbaton=0x7fffffffc608,
frame=0x15c75f0,
    addr_stack=0x7fffffffc790, valp=0x7fffffffc638, push_initial_value=true)
    at /data/gdb_versions/devel/src/gdb/dwarf2/loc.c:2490
2490      ctx.gdbarch = per_objfile->objfile->arch ();
...

The problem seems to be:
...
(gdb) p per_objfile
$1 = (dwarf2_per_objfile *) 0xffffffffffffffff
...

Backtrace:
...
(gdb) bt
#0  0x00000000005b9d02 in dwarf2_locexpr_baton_eval
(dlbaton=0x7fffffffc608, frame=0x15c75f0,
    addr_stack=0x7fffffffc790, valp=0x7fffffffc638, push_initial_value=true)
    at /data/gdb_versions/devel/src/gdb/dwarf2/loc.c:2490
#1  0x00000000005ba007 in dwarf2_evaluate_property (prop=0x7fffffffc640,
frame=0x15c75f0,
    addr_stack=0x7fffffffc790, value=0x7fffffffc638,
push_initial_value=true)
    at /data/gdb_versions/devel/src/gdb/dwarf2/loc.c:2562
#2  0x0000000000672aff in resolve_dynamic_struct (type=0x1b25660,
addr_stack=0x7fffffffc790)
    at /data/gdb_versions/devel/src/gdb/gdbtypes.c:2480
#3  0x000000000067309c in resolve_dynamic_type_internal (type=0x1b25660,
addr_stack=0x7fffffffc790, top_level=1)
    at /data/gdb_versions/devel/src/gdb/gdbtypes.c:2613
#4  0x0000000000673225 in resolve_dynamic_type (type=0x1b25660,
valaddr=..., addr=4255376)
    at /data/gdb_versions/devel/src/gdb/gdbtypes.c:2649
#5  0x00000000009b1918 in value_from_contents_and_address
(type=0x1b25660, valaddr=0x0, address=4255376)
    at /data/gdb_versions/devel/src/gdb/value.c:3483
#6  0x0000000000999f9c in get_value_at (type=0x1b25660, addr=4255376,
lazy=1)
    at /data/gdb_versions/devel/src/gdb/valops.c:899
#7  0x000000000099a00a in value_at_lazy (type=0x1b25660, addr=4255376)
    at /data/gdb_versions/devel/src/gdb/valops.c:936
#8  0x000000000064dc01 in default_read_var_value (var=0x1b256c0,
var_block=0x1b25760, frame=0x0)
    at /data/gdb_versions/devel/src/gdb/findvar.c:800
#9  0x000000000043a2f2 in ada_read_var_value (var=0x1b256c0,
var_block=0x1b25760, frame=0x0)
    at /data/gdb_versions/devel/src/gdb/ada-lang.c:14061
#10 0x000000000064dccd in read_var_value (var=0x1b256c0,
var_block=0x1b25760, frame=0x0)
    at /data/gdb_versions/devel/src/gdb/findvar.c:815
#11 0x000000000099acf3 in value_of_variable (var=0x1b256c0, b=0x1b25760)
--Type <RET> for more, q to quit, c to continue without paging--
    at /data/gdb_versions/devel/src/gdb/valops.c:1293
#12 0x000000000062ddd8 in evaluate_var_value
(noside=EVAL_AVOID_SIDE_EFFECTS, blk=0x1b25760, var=0x1b256c0)
    at /data/gdb_versions/devel/src/gdb/eval.c:716
#13 0x000000000062f4e3 in evaluate_subexp_standard (expect_type=0x0,
exp=0x1bcf8c0, pos=0x7fffffffd1c4,
    noside=EVAL_AVOID_SIDE_EFFECTS) at
/data/gdb_versions/devel/src/gdb/eval.c:1319
#14 0x000000000043232e in ada_evaluate_subexp (expect_type=0x0,
exp=0x1bcf8c0, pos=0x7fffffffd1c4,
    noside=EVAL_AVOID_SIDE_EFFECTS) at
/data/gdb_versions/devel/src/gdb/ada-lang.c:10656
#15 0x000000000062ca12 in evaluate_subexp (expect_type=0x0,
exp=0x1bcf8c0, pos=0x7fffffffd1c4,
    noside=EVAL_AVOID_SIDE_EFFECTS) at
/data/gdb_versions/devel/src/gdb/eval.c:77
#16 0x000000000042f787 in evaluate_subexp_type (exp=0x1bcf8c0,
pos=0x7fffffffd1c4)
    at /data/gdb_versions/devel/src/gdb/ada-lang.c:9417
#17 0x0000000000423e80 in resolve_subexp (expp=0x7fffffffd418,
pos=0x7fffffffd1c4, deprocedure_p=1,
    context_type=0x0, parse_completion=0, tracker=0x7fffffffd2f0)
    at /data/gdb_versions/devel/src/gdb/ada-lang.c:3826
#18 0x0000000000422fd2 in resolve (expp=0x7fffffffd418,
void_context_p=0, parse_completion=0,
    tracker=0x7fffffffd2f0) at
/data/gdb_versions/devel/src/gdb/ada-lang.c:3463
#19 0x00000000007bd06c in parse_exp_in_context
(stringptr=0x7fffffffd3d0, pc=0, block=0x0, comma=0,
    void_context_p=0, out_subexp=0x0, tracker=0x7fffffffd2f0, cstate=0x0)
    at /data/gdb_versions/devel/src/gdb/parse.c:1149
#20 0x00000000007bcd28 in parse_exp_1 (stringptr=0x7fffffffd3d0, pc=0,
block=0x0, comma=0, tracker=0x0)
    at /data/gdb_versions/devel/src/gdb/parse.c:1031
#21 0x00000000007bd1cf in parse_expression (string=0x7fffffffe0fb
"nav2", tracker=0x0)
    at /data/gdb_versions/devel/src/gdb/parse.c:1167
#22 0x00000000007c04b6 in print_command_1 (args=0x7fffffffe0fb "nav2",
voidprint=1)
    at /data/gdb_versions/devel/src/gdb/printcmd.c:1214
--Type <RET> for more, q to quit, c to continue without paging--
#23 0x00000000007c062c in print_command (exp=0x7fffffffe0fb "nav2",
from_tty=0)
    at /data/gdb_versions/devel/src/gdb/printcmd.c:1244
#24 0x00000000004fdf16 in do_const_cfunc (c=0x19cca60,
args=0x7fffffffe0fb "nav2", from_tty=0)
    at /data/gdb_versions/devel/src/gdb/cli/cli-decode.c:107
#25 0x000000000050103f in cmd_func (cmd=0x19cca60, args=0x7fffffffe0fb
"nav2", from_tty=0)
    at /data/gdb_versions/devel/src/gdb/cli/cli-decode.c:2004
#26 0x000000000091bcf5 in execute_command (p=0x7fffffffe0fe "2", from_tty=0)
    at /data/gdb_versions/devel/src/gdb/top.c:655
#27 0x0000000000746633 in catch_command_errors (command=0x91b889
<execute_command(char const*, int)>,
    arg=0x7fffffffe0f5 "print nav2", from_tty=0) at
/data/gdb_versions/devel/src/gdb/main.c:457
#28 0x0000000000747a1b in captured_main_1 (context=0x7fffffffd9e0)
    at /data/gdb_versions/devel/src/gdb/main.c:1219
#29 0x0000000000747c10 in captured_main (data=0x7fffffffd9e0) at
/data/gdb_versions/devel/src/gdb/main.c:1244
#30 0x0000000000747c7b in gdb_main (args=0x7fffffffd9e0) at
/data/gdb_versions/devel/src/gdb/main.c:1269
#31 0x000000000041520e in main (argc=14, argv=0x7fffffffdae8) at
/data/gdb_versions/devel/src/gdb/gdb.c:32
...

Thanks,
- Tom

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

* Re: [PATCH v2 00/42] Share DWARF partial symtabs between objfiles
  2020-05-12 21:08 [PATCH v2 00/42] Share DWARF partial symtabs between objfiles Simon Marchi
                   ` (42 preceding siblings ...)
  2020-05-13 10:17 ` [PATCH v2 00/42] Share DWARF partial symtabs between objfiles Tom de Vries
@ 2020-05-13 14:52 ` Simon Marchi
  2020-05-22 21:07 ` Tom Tromey
  2020-05-27 14:50 ` [PATCH v2 41.5/42] Move line_header_hash to dwarf2_per_objfile Simon Marchi
  45 siblings, 0 replies; 92+ messages in thread
From: Simon Marchi @ 2020-05-13 14:52 UTC (permalink / raw)
  To: Simon Marchi, gdb-patches

On 2020-05-12 5:08 p.m., Simon Marchi via Gdb-patches wrote:
> This is version 2 of this patchset originally written by Tom:
> 
>     https://sourceware.org/legacy-ml/gdb-patches/2020-02/msg00594.html
> 
> The current patchset therefore contains a mix of Tom's patches that I modified,
> plus a few new patches.  I won't repeat everything that is said in the cover
> letter of that patchset, please read that to understand the motivation behind
> this change..
> 
> The big difference between v1 and v2 is how the split is done.  In v1, the
> object structure looks like this:
> 
>     objfile -> dwarf2_per_objfile -> dwarf2_unshareable
> 
> where `dwarf2_per_objfile` is actually shared between objfiles (there is one
> copy per BFD), and `dwarf2_unshareable` is not (there is one copy per objfile).
> The dwarf2_per_objfile -> dwarf2_unshareable link is updated at all entry
> points of the DWARF code based on what is the current objfile.
> 
> The current patchset (v2) proposes this structure instead, which in my opinion
> is more natural:
> 
>     objfile -> dwarf2_per_objfile -> dwarf2_per_bfd
> 
> Where `dwarf2_per_objfile` is really per-objfile (there is one copy per
> objfile) and `dwarf2_per_bfd` is per-bfd (there is one copy per-bfd).  There is
> no link to update, whatever is shared between objfiles is put in
> `dwarf2_per_bfd` and each `dwarf2_per_objfile` always points to one
> `dwarf2_per_bfd`.
> 
> Since there were performance numbers with the original patchset, I made my own
> here to see if the speedups were still there.  Like in the original patchset, I
> set "maintenance time 1" and did "add-inferior -exec ./gdb" after "./gdb gdb".
> I disabled any auto-loading to avoid loading gdb-gdb.{gdb,py}.  GDB is built
> with -O2 and gcc 9, and it is running on an AMD EPYC 7351P.
> 
> Before: Command execution time: 1.213480 (cpu), 1.214268 (wall)
> After: Command execution time: 0.001697 (cpu), 0.001694 (wall)
> 
> These are the times of one run, but all runs I did are very close.  The "after"
> time is surpringly low compared to the original numbers, I hope it doesn't mean
> I messed up something and we are skipping something important...
> 
> At some point I tested with all these boards and did not see any regression
> (they helped very much to find some issues in the process though):
> 
>     unix cc-with-debug-names cc-with-dwz cc-with-dwz-m cc-with-gdb-index dwarf4-gdb-index fission-dwp fission readnow
> 
> I have since rebased the patchset and resolved conflicts, it's therefore
> possible I messed something up.
> 
> Simon Marchi (35):
>   Split dwarf2_per_objfile into dwarf2_per_objfile and dwarf2_per_bfd
>   Remove symtab links from dwarf2_psymtab and dwarf2_per_cu_quick_data
>   Move die_type_hash to dwarf2_per_objfile
>   Add dwarf2_per_objfile field to dwarf2_cu
>   Remove reference to dwarf2_per_cu_data::dwarf2_per_objfile in
>     dw2_do_instantiate_symtab
>   Remove dwarf2_cu->per_cu->dwarf2_per_objfile references
>   Add dwarf2_per_bfd field to dwarf2_per_cu_data
>   Make dwarf2_get_dwz_file take a dwarf2_per_bfd
>   Use bfd_get_filename instead of objfile_name in lookup_dwo_unit
>   Add dwarf2_per_objfile parameter to cutu_reader's constructors
>   Make queue_and_load_dwo_tu receive a dwarf2_cu
>   Remove dwarf2_per_cu_data::dwarf2_per_objfile reference in
>     cutu_reader::keep
>   Add dwarf2_per_objfile parameter to create_partial_symtab
>   Add dwarf2_per_objfile parameter to recursively_compute_inclusions
>   Add dwarf2_per_objfile parameter to process_full_{comp,type}_unit
>   Pass dwarf2_cu objects to dwo-related functions, instead of
>     dwarf2_per_cu_data
>   Remove reference to dwarf2_per_cu_data::dwarf2_per_objfile in
>     queue_and_load_all_dwo_tus
>   Move int type methods out of dwarf2_per_cu_data
>   Add dwarf2_per_objfile to dwarf_expr_context and dwarf2_frame_cache
>   Remove dwarf2_per_cu_data::text_offset
>   Add dwarf2_per_objfile parameter to dwarf2_read_addr_index
>   Add dwarf2_per_objfile parameter to allocate_piece_closure
>   Add dwarf2_per_objfile parameters to dwarf2_fetch_* functions
>   Remove dwarf2_per_cu_data::objfile ()
>   Add dwarf2_per_objfile parameter to free_one_cached_comp_unit
>   Add dwarf2_per_objfile parameter to get_die_type_at_offset
>   Remove leftover references to dwarf2_per_cu_data::dwarf2_per_objfile
>   Remove dwarf2_per_cu_data::dwarf2_per_objfile
>   Pass dwarf2_per_bfd instead of dwarf2_per_objfile to some
>     index-related functions
>   Pass dwarf2_cu to process_full_{comp,type}_unit
>   Make load_cu return the loaded dwarf2_cu
>   Add comp_unit_head to dwarf2_per_cu_data
>   Pass existing_cu object to cutu_reader
>   Replace dwarf2_per_cu_data::cu backlink with per-objfile map
>   Make mapped_debug_names independent of objfile
> 
> Tom Tromey (7):
>   Introduce dwarf2_per_objfile::obstack
>   Add "objfile" parameter to two partial_symtab methods
>   Add dwarf2_per_cu_data::index
>   Add dwarf2_per_objfile member to DWARF batons
>   Split type_unit_group
>   Move signatured_type::type to unshareable object
>   Share DWARF partial symtabs
> 
>  gdb/compile/compile-loc2c.c |   20 +-
>  gdb/compile/compile.h       |   13 +-
>  gdb/dwarf2/expr.c           |   11 +-
>  gdb/dwarf2/expr.h           |   11 +-
>  gdb/dwarf2/frame.c          |   67 +-
>  gdb/dwarf2/index-cache.c    |    2 +-
>  gdb/dwarf2/index-write.c    |   51 +-
>  gdb/dwarf2/loc.c            |  289 ++--
>  gdb/dwarf2/loc.h            |   11 +-
>  gdb/dwarf2/macro.c          |   11 +-
>  gdb/dwarf2/read.c           | 2490 ++++++++++++++++++-----------------
>  gdb/dwarf2/read.h           |  298 +++--
>  gdb/gdbtypes.h              |    8 +-
>  gdb/objfiles.h              |    2 +-
>  gdb/psympriv.h              |   19 +-
>  gdb/psymtab.c               |   44 +-
>  16 files changed, 1848 insertions(+), 1499 deletions(-)
> 
> -- 
> 2.26.2
> 

For convenience, I pushed this series on user branch `users/simark/submit/share-dwarf-partial-symtabs-v2`:

  https://sourceware.org/git/?p=binutils-gdb.git;a=shortlog;h=refs/heads/users/simark/submit/share-dwarf-partial-symtabs-v2

Simon

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

* Re: [PATCH v2 33/42] Split type_unit_group
  2020-05-13  9:54   ` Tom de Vries
@ 2020-05-13 15:06     ` Simon Marchi
  0 siblings, 0 replies; 92+ messages in thread
From: Simon Marchi @ 2020-05-13 15:06 UTC (permalink / raw)
  To: Tom de Vries, Simon Marchi, gdb-patches; +Cc: Tom Tromey

On 2020-05-13 5:54 a.m., Tom de Vries wrote:
> On 12-05-2020 23:17, Simon Marchi via Gdb-patches wrote:
>> +   that can be shared across objfiles.  The non-shareable parts are in 
> 
> Hi,
> 
> FYI during applying I got:
> ...
> Applying: Split type_unit_group
> .git/rebase-apply/patch:16: trailing whitespace.
>    that can be shared across objfiles.  The non-shareable parts are in
> warning: 1 line adds whitespace errors.
> ...
> 
> Thanks,
> - Tom
> 

Thanks, fixed.

Simon

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

* Re: [PATCH v2 00/42] Share DWARF partial symtabs between objfiles
  2020-05-13 10:17 ` [PATCH v2 00/42] Share DWARF partial symtabs between objfiles Tom de Vries
@ 2020-05-13 15:46   ` Simon Marchi
  2020-05-22 21:02     ` Tom Tromey
  0 siblings, 1 reply; 92+ messages in thread
From: Simon Marchi @ 2020-05-13 15:46 UTC (permalink / raw)
  To: Tom de Vries, Simon Marchi, gdb-patches

On 2020-05-13 6:17 a.m., Tom de Vries wrote:
> On 12-05-2020 23:08, Simon Marchi via Gdb-patches wrote:
>> This is version 2 of this patchset originally written by Tom:
>>
>>     https://sourceware.org/legacy-ml/gdb-patches/2020-02/msg00594.html
>>
>> The current patchset therefore contains a mix of Tom's patches that I modified,
>> plus a few new patches.  I won't repeat everything that is said in the cover
>> letter of that patchset, please read that to understand the motivation behind
>> this change..
>>
>> The big difference between v1 and v2 is how the split is done.  In v1, the
>> object structure looks like this:
>>
>>     objfile -> dwarf2_per_objfile -> dwarf2_unshareable
>>
>> where `dwarf2_per_objfile` is actually shared between objfiles (there is one
>> copy per BFD), and `dwarf2_unshareable` is not (there is one copy per objfile).
>> The dwarf2_per_objfile -> dwarf2_unshareable link is updated at all entry
>> points of the DWARF code based on what is the current objfile.
>>
>> The current patchset (v2) proposes this structure instead, which in my opinion
>> is more natural:
>>
>>     objfile -> dwarf2_per_objfile -> dwarf2_per_bfd
>>
>> Where `dwarf2_per_objfile` is really per-objfile (there is one copy per
>> objfile) and `dwarf2_per_bfd` is per-bfd (there is one copy per-bfd).  There is
>> no link to update, whatever is shared between objfiles is put in
>> `dwarf2_per_bfd` and each `dwarf2_per_objfile` always points to one
>> `dwarf2_per_bfd`.
>>
>> Since there were performance numbers with the original patchset, I made my own
>> here to see if the speedups were still there.  Like in the original patchset, I
>> set "maintenance time 1" and did "add-inferior -exec ./gdb" after "./gdb gdb".
>> I disabled any auto-loading to avoid loading gdb-gdb.{gdb,py}.  GDB is built
>> with -O2 and gcc 9, and it is running on an AMD EPYC 7351P.
>>
>> Before: Command execution time: 1.213480 (cpu), 1.214268 (wall)
>> After: Command execution time: 0.001697 (cpu), 0.001694 (wall)
>>
>> These are the times of one run, but all runs I did are very close.  The "after"
>> time is surpringly low compared to the original numbers, I hope it doesn't mean
>> I messed up something and we are skipping something important...
>>
>> At some point I tested with all these boards and did not see any regression
>> (they helped very much to find some issues in the process though):
>>
>>     unix cc-with-debug-names cc-with-dwz cc-with-dwz-m cc-with-gdb-index dwarf4-gdb-index fission-dwp fission readnow
>>
>> I have since rebased the patchset and resolved conflicts, it's therefore
>> possible I messed something up.
>>
> 
> Hi, I applied the patch series on top of commit 90d00bbd9c "Sync config
> and libiberty with GCC", and ran into the following:
> ...
> (gdb) PASS: gdb.ada/variant.exp: scenario=minimal: print nav1
> print nav2^M
> ERROR: GDB process no longer exists
> GDB process exited with wait status 8901 exp9 0 0 CHILDKILLED SIGABRT
> SIGABRT
> UNRESOLVED: gdb.ada/variant.exp: scenario=minimal: print nav2
> ...
> 
> Reproduced on command line using:
> ...
> $ gdb -batch ./outputs/gdb.ada/variant/pkg \
>   -ex 'break pkg.adb:40' \
>   -ex run \
>   -ex 'print nav2'
> Breakpoint 1 at 0x403047: file gdb/testsuite/gdb.ada/variant/pkg.adb,
> line 40.
> 
> Breakpoint 1, pkg () at gdb/testsuite/gdb.ada/variant/pkg.adb:40
> 40         null; -- STOP
> Aborted (core dumped)
> ...
> 
> Using gdb, we get more info:
> ...
> Thread 1 "gdb" received signal SIGSEGV, Segmentation fault.
> 0x00000000005b9d02 in dwarf2_locexpr_baton_eval (dlbaton=0x7fffffffc608,
> frame=0x15c75f0,
>     addr_stack=0x7fffffffc790, valp=0x7fffffffc638, push_initial_value=true)
>     at /data/gdb_versions/devel/src/gdb/dwarf2/loc.c:2490
> 2490      ctx.gdbarch = per_objfile->objfile->arch ();
> ...
> 
> The problem seems to be:
> ...
> (gdb) p per_objfile
> $1 = (dwarf2_per_objfile *) 0xffffffffffffffff
> ...
> 
> Backtrace:
> ...
> (gdb) bt
> #0  0x00000000005b9d02 in dwarf2_locexpr_baton_eval
> (dlbaton=0x7fffffffc608, frame=0x15c75f0,
>     addr_stack=0x7fffffffc790, valp=0x7fffffffc638, push_initial_value=true)
>     at /data/gdb_versions/devel/src/gdb/dwarf2/loc.c:2490
> #1  0x00000000005ba007 in dwarf2_evaluate_property (prop=0x7fffffffc640,
> frame=0x15c75f0,
>     addr_stack=0x7fffffffc790, value=0x7fffffffc638,
> push_initial_value=true)
>     at /data/gdb_versions/devel/src/gdb/dwarf2/loc.c:2562
> #2  0x0000000000672aff in resolve_dynamic_struct (type=0x1b25660,
> addr_stack=0x7fffffffc790)
>     at /data/gdb_versions/devel/src/gdb/gdbtypes.c:2480
> #3  0x000000000067309c in resolve_dynamic_type_internal (type=0x1b25660,
> addr_stack=0x7fffffffc790, top_level=1)
>     at /data/gdb_versions/devel/src/gdb/gdbtypes.c:2613
> #4  0x0000000000673225 in resolve_dynamic_type (type=0x1b25660,
> valaddr=..., addr=4255376)
>     at /data/gdb_versions/devel/src/gdb/gdbtypes.c:2649
> #5  0x00000000009b1918 in value_from_contents_and_address
> (type=0x1b25660, valaddr=0x0, address=4255376)
>     at /data/gdb_versions/devel/src/gdb/value.c:3483
> #6  0x0000000000999f9c in get_value_at (type=0x1b25660, addr=4255376,
> lazy=1)
>     at /data/gdb_versions/devel/src/gdb/valops.c:899
> #7  0x000000000099a00a in value_at_lazy (type=0x1b25660, addr=4255376)
>     at /data/gdb_versions/devel/src/gdb/valops.c:936
> #8  0x000000000064dc01 in default_read_var_value (var=0x1b256c0,
> var_block=0x1b25760, frame=0x0)
>     at /data/gdb_versions/devel/src/gdb/findvar.c:800
> #9  0x000000000043a2f2 in ada_read_var_value (var=0x1b256c0,
> var_block=0x1b25760, frame=0x0)
>     at /data/gdb_versions/devel/src/gdb/ada-lang.c:14061
> #10 0x000000000064dccd in read_var_value (var=0x1b256c0,
> var_block=0x1b25760, frame=0x0)
>     at /data/gdb_versions/devel/src/gdb/findvar.c:815
> #11 0x000000000099acf3 in value_of_variable (var=0x1b256c0, b=0x1b25760)
> --Type <RET> for more, q to quit, c to continue without paging--
>     at /data/gdb_versions/devel/src/gdb/valops.c:1293
> #12 0x000000000062ddd8 in evaluate_var_value
> (noside=EVAL_AVOID_SIDE_EFFECTS, blk=0x1b25760, var=0x1b256c0)
>     at /data/gdb_versions/devel/src/gdb/eval.c:716
> #13 0x000000000062f4e3 in evaluate_subexp_standard (expect_type=0x0,
> exp=0x1bcf8c0, pos=0x7fffffffd1c4,
>     noside=EVAL_AVOID_SIDE_EFFECTS) at
> /data/gdb_versions/devel/src/gdb/eval.c:1319
> #14 0x000000000043232e in ada_evaluate_subexp (expect_type=0x0,
> exp=0x1bcf8c0, pos=0x7fffffffd1c4,
>     noside=EVAL_AVOID_SIDE_EFFECTS) at
> /data/gdb_versions/devel/src/gdb/ada-lang.c:10656
> #15 0x000000000062ca12 in evaluate_subexp (expect_type=0x0,
> exp=0x1bcf8c0, pos=0x7fffffffd1c4,
>     noside=EVAL_AVOID_SIDE_EFFECTS) at
> /data/gdb_versions/devel/src/gdb/eval.c:77
> #16 0x000000000042f787 in evaluate_subexp_type (exp=0x1bcf8c0,
> pos=0x7fffffffd1c4)
>     at /data/gdb_versions/devel/src/gdb/ada-lang.c:9417
> #17 0x0000000000423e80 in resolve_subexp (expp=0x7fffffffd418,
> pos=0x7fffffffd1c4, deprocedure_p=1,
>     context_type=0x0, parse_completion=0, tracker=0x7fffffffd2f0)
>     at /data/gdb_versions/devel/src/gdb/ada-lang.c:3826
> #18 0x0000000000422fd2 in resolve (expp=0x7fffffffd418,
> void_context_p=0, parse_completion=0,
>     tracker=0x7fffffffd2f0) at
> /data/gdb_versions/devel/src/gdb/ada-lang.c:3463
> #19 0x00000000007bd06c in parse_exp_in_context
> (stringptr=0x7fffffffd3d0, pc=0, block=0x0, comma=0,
>     void_context_p=0, out_subexp=0x0, tracker=0x7fffffffd2f0, cstate=0x0)
>     at /data/gdb_versions/devel/src/gdb/parse.c:1149
> #20 0x00000000007bcd28 in parse_exp_1 (stringptr=0x7fffffffd3d0, pc=0,
> block=0x0, comma=0, tracker=0x0)
>     at /data/gdb_versions/devel/src/gdb/parse.c:1031
> #21 0x00000000007bd1cf in parse_expression (string=0x7fffffffe0fb
> "nav2", tracker=0x0)
>     at /data/gdb_versions/devel/src/gdb/parse.c:1167
> #22 0x00000000007c04b6 in print_command_1 (args=0x7fffffffe0fb "nav2",
> voidprint=1)
>     at /data/gdb_versions/devel/src/gdb/printcmd.c:1214
> --Type <RET> for more, q to quit, c to continue without paging--
> #23 0x00000000007c062c in print_command (exp=0x7fffffffe0fb "nav2",
> from_tty=0)
>     at /data/gdb_versions/devel/src/gdb/printcmd.c:1244
> #24 0x00000000004fdf16 in do_const_cfunc (c=0x19cca60,
> args=0x7fffffffe0fb "nav2", from_tty=0)
>     at /data/gdb_versions/devel/src/gdb/cli/cli-decode.c:107
> #25 0x000000000050103f in cmd_func (cmd=0x19cca60, args=0x7fffffffe0fb
> "nav2", from_tty=0)
>     at /data/gdb_versions/devel/src/gdb/cli/cli-decode.c:2004
> #26 0x000000000091bcf5 in execute_command (p=0x7fffffffe0fe "2", from_tty=0)
>     at /data/gdb_versions/devel/src/gdb/top.c:655
> #27 0x0000000000746633 in catch_command_errors (command=0x91b889
> <execute_command(char const*, int)>,
>     arg=0x7fffffffe0f5 "print nav2", from_tty=0) at
> /data/gdb_versions/devel/src/gdb/main.c:457
> #28 0x0000000000747a1b in captured_main_1 (context=0x7fffffffd9e0)
>     at /data/gdb_versions/devel/src/gdb/main.c:1219
> #29 0x0000000000747c10 in captured_main (data=0x7fffffffd9e0) at
> /data/gdb_versions/devel/src/gdb/main.c:1244
> #30 0x0000000000747c7b in gdb_main (args=0x7fffffffd9e0) at
> /data/gdb_versions/devel/src/gdb/main.c:1269
> #31 0x000000000041520e in main (argc=14, argv=0x7fffffffdae8) at
> /data/gdb_versions/devel/src/gdb/gdb.c:32

Thanks for the report.  We were missing assigning dlbaton->per_objfile in
handle_data_member_location.  This is some recent code on which I rebased
just before sending the series.  Good thing I included that disclaimer :).

I fixed it in patch 4, "Add dwarf2_per_objfile member to DWARF batons".

Simon

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

* Re: [PATCH v2 15/42] Make queue_and_load_dwo_tu receive a dwarf2_cu
  2020-05-12 21:11 ` [PATCH v2 15/42] Make queue_and_load_dwo_tu receive a dwarf2_cu Simon Marchi
@ 2020-05-22 20:45   ` Tom Tromey
  2020-05-25 19:10     ` Simon Marchi
  0 siblings, 1 reply; 92+ messages in thread
From: Tom Tromey @ 2020-05-22 20:45 UTC (permalink / raw)
  To: Simon Marchi via Gdb-patches; +Cc: Simon Marchi

>>>>> "Simon" == Simon Marchi via Gdb-patches <gdb-patches@sourceware.org> writes:

Simon> I kept this as a separate patch, because since there's no strong typing
Simon> here, it's easy to miss something.

Good idea.

This is another area where (1) a variant of the GCC hash table would be
nice, and (2) where I wish at least the libiberty hash table had
external iteration.  (For (2), I know some code in GCC used to do this,
but that always seemed like a bit of an abstraction violation to me.)

Tom

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

* Re: [PATCH v2 39/42] Pass existing_cu object to cutu_reader
  2020-05-12 21:17 ` [PATCH v2 39/42] Pass existing_cu object to cutu_reader Simon Marchi
@ 2020-05-22 20:57   ` Tom Tromey
  2020-05-25 19:10     ` Simon Marchi
  0 siblings, 1 reply; 92+ messages in thread
From: Tom Tromey @ 2020-05-22 20:57 UTC (permalink / raw)
  To: Simon Marchi via Gdb-patches; +Cc: Simon Marchi

>>>>> "Simon" == Simon Marchi via Gdb-patches <gdb-patches@sourceware.org> writes:

Simon> It is possible, seemingly for a special case described in
Simon> find_partial_die, for cutu_reader to re-use an existing dwarf2_cu
Simon> instead of creating a new one.  This happens
Simon> ---

The description got cut off here, and there's no ChangeLog entry.

Tom

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

* Re: [PATCH v2 41/42] Make mapped_debug_names independent of objfile
  2020-05-12 21:18 ` [PATCH v2 41/42] Make mapped_debug_names independent of objfile Simon Marchi
@ 2020-05-22 21:01   ` Tom Tromey
  2020-05-25 19:53     ` Simon Marchi
  0 siblings, 1 reply; 92+ messages in thread
From: Tom Tromey @ 2020-05-22 21:01 UTC (permalink / raw)
  To: Simon Marchi via Gdb-patches; +Cc: Simon Marchi

>>>>> "Simon" == Simon Marchi via Gdb-patches <gdb-patches@sourceware.org> writes:

Simon> Ultimately, the objfile only seems to be needed because we might need to
Simon> read a string from the string section.  For that, we might need to read
Simon> in the section, and if it's a relocatable section, the objfile is needed
Simon> in order to do the relocation.  This pattern happens often (that we to
Simon> pass an objfile only because a section might be read).  I think it's a
Simon> bit ugly, but I don't have a good alternative right now.

A long time ago, I changed the DWARF reader to read all the sections
lazily.  Off and on I've wondered whether that was actually a mistake.
For one thing, it requires passing stuff like this around.  Also, it can
slow down hot paths, since they need to call the method to make sure the
section is mapped.  There's also at least one bug in bugzilla related to
this (if you unlink a .so, gdb can be unhappy).

For my threading project, I removed this lazy reading.  We should
consider doing this sooner, perhaps.  The idea here is just that, if gdb
is going to read the debuginfo anyway, then loading at least the
sections needed to read .debug_info makes sense.

Tom

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

* Re: [PATCH v2 00/42] Share DWARF partial symtabs between objfiles
  2020-05-13 15:46   ` Simon Marchi
@ 2020-05-22 21:02     ` Tom Tromey
  2020-05-25 19:53       ` Simon Marchi
  0 siblings, 1 reply; 92+ messages in thread
From: Tom Tromey @ 2020-05-22 21:02 UTC (permalink / raw)
  To: Simon Marchi; +Cc: Tom de Vries, Simon Marchi, gdb-patches

>>>>> "Simon" == Simon Marchi <simark@simark.ca> writes:

Simon> Thanks for the report.  We were missing assigning dlbaton->per_objfile in
Simon> handle_data_member_location.

I've been bit by this kind of thing, too.
Probably these batons should have constructors.

Tom

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

* Re: [PATCH v2 23/42] Add dwarf2_per_objfile to dwarf_expr_context and dwarf2_frame_cache
  2020-05-12 21:12 ` [PATCH v2 23/42] Add dwarf2_per_objfile to dwarf_expr_context and dwarf2_frame_cache Simon Marchi
@ 2020-05-22 21:04   ` Tom Tromey
  2020-05-25 19:50     ` Simon Marchi
  0 siblings, 1 reply; 92+ messages in thread
From: Tom Tromey @ 2020-05-22 21:04 UTC (permalink / raw)
  To: Simon Marchi via Gdb-patches; +Cc: Simon Marchi

>>>>> "Simon" == Simon Marchi via Gdb-patches <gdb-patches@sourceware.org> writes:

Simon> *Note*, there's one spot I'm particularly unsure about.  In
Simon> dwarf_evaluate_loc_desc::push_dwarf_reg_entry_value, we would save and
Simon> overwrite the offset value in the context, along with a bunch of other
Simon> state.  This is because we might be about to evaluate something in a
Simon> different CU that the current one.  If the two CUs are in the same
Simon> objfile, then the text_offset is the same, as it's a property of the
Simon> objfile.  However, if the two CUs are possibly in different objfiles,
Simon> then it means the text_offsets are different.  It would also mean we
Simon> would need to save and restore the dwarf2_per_objfile in the context.
Simon> Is that even possible?

Unfortunately I don't know for sure.
However, call_site_for_pc doesn't distinguish between objfiles.  So, I
suppose I would assume it is possible.

Tom

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

* Re: [PATCH v2 00/42] Share DWARF partial symtabs between objfiles
  2020-05-12 21:08 [PATCH v2 00/42] Share DWARF partial symtabs between objfiles Simon Marchi
                   ` (43 preceding siblings ...)
  2020-05-13 14:52 ` Simon Marchi
@ 2020-05-22 21:07 ` Tom Tromey
  2020-05-23 12:24   ` Pedro Alves
  2020-05-27 14:50 ` [PATCH v2 41.5/42] Move line_header_hash to dwarf2_per_objfile Simon Marchi
  45 siblings, 1 reply; 92+ messages in thread
From: Tom Tromey @ 2020-05-22 21:07 UTC (permalink / raw)
  To: Simon Marchi via Gdb-patches; +Cc: Simon Marchi

>>>>> "Simon" == Simon Marchi via Gdb-patches <gdb-patches@sourceware.org> writes:

Simon> The big difference between v1 and v2 is how the split is done.
[...]

Thank you so much for doing this.  This is a big improvement over the
approach I took.

I read through the patches.  It was difficult to do without glazing over
a bit, so I'm not sure I really did a good job.  However, I'm
comfortable with the direction you've taken here.

Simon> Before: Command execution time: 1.213480 (cpu), 1.214268 (wall)
Simon> After: Command execution time: 0.001697 (cpu), 0.001694 (wall)

Simon> These are the times of one run, but all runs I did are very close.  The "after"
Simon> time is surpringly low compared to the original numbers, I hope it doesn't mean
Simon> I messed up something and we are skipping something important...

I doubt it, more like with the new approach, there just isn't much work
to be done in this case.

Simon> At some point I tested with all these boards and did not see any regression
Simon> (they helped very much to find some issues in the process though):

Simon>     unix cc-with-debug-names cc-with-dwz cc-with-dwz-m cc-with-gdb-index dwarf4-gdb-index fission-dwp fission readnow

Stellar.

Tom

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

* Re: [PATCH v2 00/42] Share DWARF partial symtabs between objfiles
  2020-05-22 21:07 ` Tom Tromey
@ 2020-05-23 12:24   ` Pedro Alves
  2020-05-25 19:56     ` Simon Marchi
  0 siblings, 1 reply; 92+ messages in thread
From: Pedro Alves @ 2020-05-23 12:24 UTC (permalink / raw)
  To: Tom Tromey, Simon Marchi via Gdb-patches; +Cc: Simon Marchi

On 5/22/20 10:07 PM, Tom Tromey wrote:
>>>>>> "Simon" == Simon Marchi via Gdb-patches <gdb-patches@sourceware.org> writes:
> 
> Simon> The big difference between v1 and v2 is how the split is done.
> [...]
> 
> Thank you so much for doing this.  This is a big improvement over the
> approach I took.
> 
> I read through the patches.  It was difficult to do without glazing over
> a bit, so I'm not sure I really did a good job.  However, I'm
> comfortable with the direction you've taken here.

I skimmed through the patches, glazing over a lot.  The direction seems
good to me too, FWIW.  

Just wanted to say, kudos for continuing this effort, and thanks for all
the work.

Pedro Alves


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

* Re: [PATCH v2 39/42] Pass existing_cu object to cutu_reader
  2020-05-22 20:57   ` Tom Tromey
@ 2020-05-25 19:10     ` Simon Marchi
  0 siblings, 0 replies; 92+ messages in thread
From: Simon Marchi @ 2020-05-25 19:10 UTC (permalink / raw)
  To: Tom Tromey, Simon Marchi via Gdb-patches; +Cc: Simon Marchi

On 2020-05-22 4:57 p.m., Tom Tromey wrote:
>>>>>> "Simon" == Simon Marchi via Gdb-patches <gdb-patches@sourceware.org> writes:
> 
> Simon> It is possible, seemingly for a special case described in
> Simon> find_partial_die, for cutu_reader to re-use an existing dwarf2_cu
> Simon> instead of creating a new one.  This happens
> Simon> ---
> 
> The description got cut off here, and there's no ChangeLog entry.
> 
> Tom
> 

Oops, I messed up, not sure what happened.

Here's the full version:

From 3d20153d73373a0c2281d2dd9a6ffe505f6346bc Mon Sep 17 00:00:00 2001
From: Simon Marchi <simon.marchi@efficios.com>
Date: Thu, 9 Apr 2020 13:46:41 -0400
Subject: [PATCH] Pass existing_cu object to cutu_reader

It is possible, seemingly for a special case described in
find_partial_die, for cutu_reader to re-use an existing dwarf2_cu
instead of creating a new one.  This happens when running this test, for
example:

    make check TESTS="gdb.dwarf2/fission-reread.exp"

Right now the, `use_existing_cu` flag tells cutu_reader to use the
dwarf2_cu object at dwarf2_per_cu_data::cu.  However, we'll remove that
field, so we need to find another solution.

This situation arises when some caller up the stack has already created
the dwarf2_cu to read a dwarf2_per_cu_data, but needs to re-read it with
some other parameters.  Therefore, it's possible to just have that
caller pass down the dwarf2_cu object to use as a `existing_cu`
parameter.  If `existing_cu` is NULL, it tells cutu_reader that it needs
to instantiate a new one.

gdb/ChangeLog:

	* dwarf2/read.c (class cutu_reader) <cutu_reader>: Replace
	`int use_existing_cu` parameter with `dwarf2_cu *existing_cu`.
	(init_tu_and_read_dwo_dies): Likewise.
	(cutu_reader::init_tu_and_read_dwo_dies): Likewise.
	(cutu_reader::cutu_reader): Likewise.
	(load_partial_comp_unit): Likewise.
	(process_psymtab_comp_unit): Update.
	(build_type_psymtabs_1): Update.
	(process_skeletonless_type_unit): Update.
	(load_full_comp_unit): Update.
	(find_partial_die): Update.
	(dwarf2_read_addr_index): Update.
	(read_signatured_type): Update.
---
 gdb/dwarf2/read.c | 57 ++++++++++++++++++++++++++---------------------
 1 file changed, 32 insertions(+), 25 deletions(-)

diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index a6b7f2c6d25..c2dc34477f7 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -912,7 +912,7 @@ class cutu_reader : public die_reader_specs
   cutu_reader (dwarf2_per_cu_data *this_cu,
 	       dwarf2_per_objfile *per_objfile,
 	       struct abbrev_table *abbrev_table,
-	       int use_existing_cu,
+	       dwarf2_cu *existing_cu,
 	       bool skip_partial);

   explicit cutu_reader (struct dwarf2_per_cu_data *this_cu,
@@ -933,7 +933,7 @@ class cutu_reader : public die_reader_specs
 private:
   void init_tu_and_read_dwo_dies (dwarf2_per_cu_data *this_cu,
 				  dwarf2_per_objfile *per_objfile,
-				  int use_existing_cu);
+				  dwarf2_cu *existing_cu);

   struct dwarf2_per_cu_data *m_this_cu;
   std::unique_ptr<dwarf2_cu> m_new_cu;
@@ -6902,7 +6902,7 @@ lookup_dwo_unit (dwarf2_cu *cu, die_info *comp_unit_die, const char *dwo_name)
 void
 cutu_reader::init_tu_and_read_dwo_dies (dwarf2_per_cu_data *this_cu,
 					dwarf2_per_objfile *per_objfile,
-					int use_existing_cu)
+					dwarf2_cu *existing_cu)
 {
   struct signatured_type *sig_type;

@@ -6912,24 +6912,28 @@ cutu_reader::init_tu_and_read_dwo_dies (dwarf2_per_cu_data *this_cu,
   sig_type = (struct signatured_type *) this_cu;
   gdb_assert (sig_type->dwo_unit != NULL);

-  if (use_existing_cu && this_cu->cu != NULL)
+  dwarf2_cu *cu;
+
+  if (existing_cu != nullptr)
     {
-      gdb_assert (this_cu->cu->dwo_unit == sig_type->dwo_unit);
+      cu = existing_cu;
+      gdb_assert (cu->dwo_unit == sig_type->dwo_unit);
       /* There's no need to do the rereading_dwo_cu handling that
 	 cutu_reader does since we don't read the stub.  */
     }
   else
     {
-      /* If !use_existing_cu, this_cu->cu must be NULL.  */
+      /* If an existing_cu is provided, this_cu->cu must be NULL.  */
       gdb_assert (this_cu->cu == NULL);
       m_new_cu.reset (new dwarf2_cu (this_cu, per_objfile));
+      cu = m_new_cu.get ();
     }

   /* A future optimization, if needed, would be to use an existing
      abbrev table.  When reading DWOs with skeletonless TUs, all the TUs
      could share abbrev tables.  */

-  if (read_cutu_die_from_dwo (this_cu->cu, sig_type->dwo_unit,
+  if (read_cutu_die_from_dwo (cu, sig_type->dwo_unit,
 			      NULL /* stub_comp_unit_die */,
 			      sig_type->dwo_unit->dwo_file->comp_dir,
 			      this, &info_ptr,
@@ -6948,13 +6952,13 @@ cutu_reader::init_tu_and_read_dwo_dies (dwarf2_per_cu_data *this_cu,
    Otherwise the table specified in the comp unit header is read in and used.
    This is an optimization for when we already have the abbrev table.

-   If USE_EXISTING_CU is non-zero, and THIS_CU->cu is non-NULL, then use it.
-   Otherwise, a new CU is allocated with xmalloc.  */
+   If EXISTING_CU is non-NULL, then use it.  Otherwise, a new CU is
+   allocated.  */

 cutu_reader::cutu_reader (dwarf2_per_cu_data *this_cu,
 			  dwarf2_per_objfile *dwarf2_per_objfile,
 			  struct abbrev_table *abbrev_table,
-			  int use_existing_cu,
+			  dwarf2_cu *existing_cu,
 			  bool skip_partial)
   : die_reader_specs {},
     m_this_cu (this_cu)
@@ -6962,7 +6966,6 @@ cutu_reader::cutu_reader (dwarf2_per_cu_data *this_cu,
   struct objfile *objfile = dwarf2_per_objfile->objfile;
   struct dwarf2_section_info *section = this_cu->section;
   bfd *abfd = section->get_bfd_owner ();
-  struct dwarf2_cu *cu;
   const gdb_byte *begin_info_ptr;
   struct signatured_type *sig_type = NULL;
   struct dwarf2_section_info *abbrev_section;
@@ -6983,7 +6986,7 @@ cutu_reader::cutu_reader (dwarf2_per_cu_data *this_cu,
       /* Narrow down the scope of possibilities to have to understand.  */
       gdb_assert (this_cu->is_debug_types);
       gdb_assert (abbrev_table == NULL);
-      init_tu_and_read_dwo_dies (this_cu, dwarf2_per_objfile, use_existing_cu);
+      init_tu_and_read_dwo_dies (this_cu, dwarf2_per_objfile, existing_cu);
       return;
     }

@@ -6994,9 +6997,11 @@ cutu_reader::cutu_reader (dwarf2_per_cu_data *this_cu,

   abbrev_section = get_abbrev_section_for_cu (this_cu);

-  if (use_existing_cu && this_cu->cu != NULL)
+  dwarf2_cu *cu;
+
+  if (existing_cu != nullptr)
     {
-      cu = this_cu->cu;
+      cu = existing_cu;
       /* If this CU is from a DWO file we need to start over, we need to
 	 refetch the attributes from the skeleton CU.
 	 This could be optimized by retrieving those attributes from when we
@@ -7008,7 +7013,7 @@ cutu_reader::cutu_reader (dwarf2_per_cu_data *this_cu,
     }
   else
     {
-      /* If !use_existing_cu, this_cu->cu must be NULL.  */
+      /* If an existing_cu is provided, this_cu->cu must be NULL.  */
       gdb_assert (this_cu->cu == NULL);
       m_new_cu.reset (new dwarf2_cu (this_cu, dwarf2_per_objfile));
       cu = m_new_cu.get ();
@@ -7561,7 +7566,7 @@ process_psymtab_comp_unit (dwarf2_per_cu_data *this_cu,
   if (this_cu->cu != NULL)
     free_one_cached_comp_unit (this_cu, per_objfile);

-  cutu_reader reader (this_cu, per_objfile, NULL, 0, false);
+  cutu_reader reader (this_cu, per_objfile, nullptr, nullptr, false);

   switch (reader.comp_unit_die->tag)
     {
@@ -7743,7 +7748,7 @@ build_type_psymtabs_1 (struct dwarf2_per_objfile *dwarf2_per_objfile)
 	}

       cutu_reader reader (&tu.sig_type->per_cu, dwarf2_per_objfile,
-			  abbrev_table.get (), 0, false);
+			  abbrev_table.get (), nullptr, false);
       if (!reader.dummy_p)
 	build_type_psymtabs_reader (&reader, reader.info_ptr,
 				    reader.comp_unit_die);
@@ -7848,7 +7853,8 @@ process_skeletonless_type_unit (void **slot, void *info)
   *slot = entry;

   /* This does the job that build_type_psymtabs_1 would have done.  */
-  cutu_reader reader (&entry->per_cu, dwarf2_per_objfile, NULL, 0, false);
+  cutu_reader reader (&entry->per_cu, dwarf2_per_objfile, nullptr, nullptr,
+		      false);
   if (!reader.dummy_p)
     build_type_psymtabs_reader (&reader, reader.info_ptr,
 				reader.comp_unit_die);
@@ -7984,9 +7990,10 @@ dwarf2_build_psymtabs_hard (struct dwarf2_per_objfile *dwarf2_per_objfile)

 static void
 load_partial_comp_unit (dwarf2_per_cu_data *this_cu,
-			dwarf2_per_objfile *per_objfile)
+			dwarf2_per_objfile *per_objfile,
+			dwarf2_cu *existing_cu)
 {
-  cutu_reader reader (this_cu, per_objfile, NULL, 1, false);
+  cutu_reader reader (this_cu, per_objfile, nullptr, existing_cu, false);

   if (!reader.dummy_p)
     {
@@ -9105,7 +9112,7 @@ load_full_comp_unit (dwarf2_per_cu_data *this_cu,
 {
   gdb_assert (! this_cu->is_debug_types);

-  cutu_reader reader (this_cu, per_objfile, NULL, 1, skip_partial);
+  cutu_reader reader (this_cu, per_objfile, NULL, this_cu->cu, skip_partial);
   if (reader.dummy_p)
     return;

@@ -18713,7 +18720,7 @@ find_partial_die (sect_offset sect_off, int offset_in_dwz, struct dwarf2_cu *cu)
 						 dwarf2_per_objfile);

       if (per_cu->cu == NULL || per_cu->cu->partial_dies == NULL)
-	load_partial_comp_unit (per_cu, cu->per_objfile);
+	load_partial_comp_unit (per_cu, cu->per_objfile, nullptr);

       per_cu->cu->last_used = 0;
       pd = per_cu->cu->find_partial_die (sect_off);
@@ -18732,7 +18739,7 @@ find_partial_die (sect_offset sect_off, int offset_in_dwz, struct dwarf2_cu *cu)
 	 DIEs alone (which can still be in use, e.g. in scan_partial_symbols),
 	 and clobber THIS_CU->cu->partial_dies with the hash table for the new
 	 set.  */
-      load_partial_comp_unit (per_cu, cu->per_objfile);
+      load_partial_comp_unit (per_cu, cu->per_objfile, cu);

       pd = per_cu->cu->find_partial_die (sect_off);
     }
@@ -19449,7 +19456,7 @@ dwarf2_read_addr_index (dwarf2_per_cu_data *per_cu,
     }
   else
     {
-      cutu_reader reader (per_cu, dwarf2_per_objfile, NULL, 0, false);
+      cutu_reader reader (per_cu, dwarf2_per_objfile, nullptr, nullptr, false);
       addr_base = reader.cu->addr_base;
       addr_size = reader.cu->header.addr_size;
     }
@@ -22831,7 +22838,7 @@ read_signatured_type (signatured_type *sig_type,
   gdb_assert (per_cu->is_debug_types);
   gdb_assert (per_cu->cu == NULL);

-  cutu_reader reader (per_cu, per_objfile, NULL, 0, false);
+  cutu_reader reader (per_cu, per_objfile, nullptr, nullptr, false);

   if (!reader.dummy_p)
     {
-- 
2.26.2


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

* Re: [PATCH v2 15/42] Make queue_and_load_dwo_tu receive a dwarf2_cu
  2020-05-22 20:45   ` Tom Tromey
@ 2020-05-25 19:10     ` Simon Marchi
  0 siblings, 0 replies; 92+ messages in thread
From: Simon Marchi @ 2020-05-25 19:10 UTC (permalink / raw)
  To: Tom Tromey, Simon Marchi via Gdb-patches; +Cc: Simon Marchi

On 2020-05-22 4:45 p.m., Tom Tromey wrote:
>>>>>> "Simon" == Simon Marchi via Gdb-patches <gdb-patches@sourceware.org> writes:
> 
> Simon> I kept this as a separate patch, because since there's no strong typing
> Simon> here, it's easy to miss something.
> 
> Good idea.
> 
> This is another area where (1) a variant of the GCC hash table would be
> nice, and (2) where I wish at least the libiberty hash table had
> external iteration.  (For (2), I know some code in GCC used to do this,
> but that always seemed like a bit of an abstraction violation to me.)
> 
> Tom
> 

Agreed :).

Simon

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

* Re: [PATCH v2 23/42] Add dwarf2_per_objfile to dwarf_expr_context and dwarf2_frame_cache
  2020-05-22 21:04   ` Tom Tromey
@ 2020-05-25 19:50     ` Simon Marchi
  2020-05-28  1:44       ` Simon Marchi
  0 siblings, 1 reply; 92+ messages in thread
From: Simon Marchi @ 2020-05-25 19:50 UTC (permalink / raw)
  To: Tom Tromey, Simon Marchi via Gdb-patches; +Cc: Simon Marchi

On 2020-05-22 5:04 p.m., Tom Tromey wrote:
>>>>>> "Simon" == Simon Marchi via Gdb-patches <gdb-patches@sourceware.org> writes:
> 
> Simon> *Note*, there's one spot I'm particularly unsure about.  In
> Simon> dwarf_evaluate_loc_desc::push_dwarf_reg_entry_value, we would save and
> Simon> overwrite the offset value in the context, along with a bunch of other
> Simon> state.  This is because we might be about to evaluate something in a
> Simon> different CU that the current one.  If the two CUs are in the same
> Simon> objfile, then the text_offset is the same, as it's a property of the
> Simon> objfile.  However, if the two CUs are possibly in different objfiles,
> Simon> then it means the text_offsets are different.  It would also mean we
> Simon> would need to save and restore the dwarf2_per_objfile in the context.
> Simon> Is that even possible?
> 
> Unfortunately I don't know for sure.
> However, call_site_for_pc doesn't distinguish between objfiles.  So, I
> suppose I would assume it is possible.
> 
> Tom

In practice, I'm not sure how that can happen.  Can DWARF info in an objfile
refer to the DWARF info in another objfile?  Can there be a subprogram described
in one and a call site of that subprogram described in another objfile?  If we
are quite sure it can't happen, I would rather not include code for it, that's
just unnecessary complexity.

A further patch (28/42) happens to tie call sites with an objfile, and adds a
gdb_assert here making sure that the call site's objfile is the same as the
callee's objfile.

So I would propose to leave that gdb_assert there, if we are wrong then we'll
fix that function.

Simon


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

* Re: [PATCH v2 41/42] Make mapped_debug_names independent of objfile
  2020-05-22 21:01   ` Tom Tromey
@ 2020-05-25 19:53     ` Simon Marchi
  0 siblings, 0 replies; 92+ messages in thread
From: Simon Marchi @ 2020-05-25 19:53 UTC (permalink / raw)
  To: Tom Tromey, Simon Marchi via Gdb-patches

On 2020-05-22 5:01 p.m., Tom Tromey wrote:
>>>>>> "Simon" == Simon Marchi via Gdb-patches <gdb-patches@sourceware.org> writes:
> 
> Simon> Ultimately, the objfile only seems to be needed because we might need to
> Simon> read a string from the string section.  For that, we might need to read
> Simon> in the section, and if it's a relocatable section, the objfile is needed
> Simon> in order to do the relocation.  This pattern happens often (that we to
> Simon> pass an objfile only because a section might be read).  I think it's a
> Simon> bit ugly, but I don't have a good alternative right now.
> 
> A long time ago, I changed the DWARF reader to read all the sections
> lazily.  Off and on I've wondered whether that was actually a mistake.
> For one thing, it requires passing stuff like this around.  Also, it can
> slow down hot paths, since they need to call the method to make sure the
> section is mapped.  There's also at least one bug in bugzilla related to
> this (if you unlink a .so, gdb can be unhappy).
> 
> For my threading project, I removed this lazy reading.  We should
> consider doing this sooner, perhaps.  The idea here is just that, if gdb
> is going to read the debuginfo anyway, then loading at least the
> sections needed to read .debug_info makes sense.

I think it would be interesting indeed.  Can we try to revive it after the
current patchset is merged?

Simon

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

* Re: [PATCH v2 00/42] Share DWARF partial symtabs between objfiles
  2020-05-22 21:02     ` Tom Tromey
@ 2020-05-25 19:53       ` Simon Marchi
  0 siblings, 0 replies; 92+ messages in thread
From: Simon Marchi @ 2020-05-25 19:53 UTC (permalink / raw)
  To: Tom Tromey, Simon Marchi; +Cc: Tom de Vries, gdb-patches

On 2020-05-22 5:02 p.m., Tom Tromey wrote:
>>>>>> "Simon" == Simon Marchi <simark@simark.ca> writes:
> 
> Simon> Thanks for the report.  We were missing assigning dlbaton->per_objfile in
> Simon> handle_data_member_location.
> 
> I've been bit by this kind of thing, too.
> Probably these batons should have constructors.

I'll look into it as a subsequent improvement.

Simon

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

* Re: [PATCH v2 00/42] Share DWARF partial symtabs between objfiles
  2020-05-23 12:24   ` Pedro Alves
@ 2020-05-25 19:56     ` Simon Marchi
  2020-05-26 11:17       ` Pedro Alves
  0 siblings, 1 reply; 92+ messages in thread
From: Simon Marchi @ 2020-05-25 19:56 UTC (permalink / raw)
  To: Pedro Alves, Tom Tromey, Simon Marchi via Gdb-patches

On 2020-05-23 8:24 a.m., Pedro Alves wrote:
> On 5/22/20 10:07 PM, Tom Tromey wrote:
>>>>>>> "Simon" == Simon Marchi via Gdb-patches <gdb-patches@sourceware.org> writes:
>>
>> Simon> The big difference between v1 and v2 is how the split is done.
>> [...]
>>
>> Thank you so much for doing this.  This is a big improvement over the
>> approach I took.
>>
>> I read through the patches.  It was difficult to do without glazing over
>> a bit, so I'm not sure I really did a good job.  However, I'm
>> comfortable with the direction you've taken here.
> 
> I skimmed through the patches, glazing over a lot.  The direction seems
> good to me too, FWIW.  
> 
> Just wanted to say, kudos for continuing this effort, and thanks for all
> the work.
> 
> Pedro Alves
> 

I posted the complete version of patch 15/42 (it was missing the commit
message).

Other than that, does any of you have further comments?  I've done the
small suggested fixups, but I don't think there was anything big
requiring another round, is there?

Simon

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

* Re: [PATCH v2 00/42] Share DWARF partial symtabs between objfiles
  2020-05-25 19:56     ` Simon Marchi
@ 2020-05-26 11:17       ` Pedro Alves
  2020-05-26 15:35         ` Simon Marchi
  0 siblings, 1 reply; 92+ messages in thread
From: Pedro Alves @ 2020-05-26 11:17 UTC (permalink / raw)
  To: Simon Marchi, Tom Tromey, Simon Marchi via Gdb-patches

On 5/25/20 8:56 PM, Simon Marchi wrote:

> Other than that, does any of you have further comments?  I've done the
> small suggested fixups, but I don't think there was anything big
> requiring another round, is there?

No further comments from me.

Thanks,
Pedro Alves


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

* Re: [PATCH v2 00/42] Share DWARF partial symtabs between objfiles
  2020-05-26 11:17       ` Pedro Alves
@ 2020-05-26 15:35         ` Simon Marchi
  2020-05-26 21:34           ` Simon Marchi
  0 siblings, 1 reply; 92+ messages in thread
From: Simon Marchi @ 2020-05-26 15:35 UTC (permalink / raw)
  To: Pedro Alves, Simon Marchi, Tom Tromey, Simon Marchi via Gdb-patches

On 2020-05-26 7:17 a.m., Pedro Alves via Gdb-patches wrote:
> On 5/25/20 8:56 PM, Simon Marchi wrote:
> 
>> Other than that, does any of you have further comments?  I've done the
>> small suggested fixups, but I don't think there was anything big
>> requiring another round, is there?
> 
> No further comments from me.
> 
> Thanks,
> Pedro Alves
> 

Ok, since I needed to do some non-trivial rebase, I'm giving it another round
of testing and I'll push it if it's all good.

Simon

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

* Re: [PATCH v2 00/42] Share DWARF partial symtabs between objfiles
  2020-05-26 15:35         ` Simon Marchi
@ 2020-05-26 21:34           ` Simon Marchi
  2020-05-27  5:08             ` Simon Marchi
  0 siblings, 1 reply; 92+ messages in thread
From: Simon Marchi @ 2020-05-26 21:34 UTC (permalink / raw)
  To: Pedro Alves, Simon Marchi, Tom Tromey, Simon Marchi via Gdb-patches

On 2020-05-26 11:35 a.m., Simon Marchi wrote:
> On 2020-05-26 7:17 a.m., Pedro Alves via Gdb-patches wrote:
>> On 5/25/20 8:56 PM, Simon Marchi wrote:
>>
>>> Other than that, does any of you have further comments?  I've done the
>>> small suggested fixups, but I don't think there was anything big
>>> requiring another round, is there?
>>
>> No further comments from me.
>>
>> Thanks,
>> Pedro Alves
>>
> 
> Ok, since I needed to do some non-trivial rebase, I'm giving it another round
> of testing and I'll push it if it's all good.
> 
> Simon
> 

Hmmm with the series applied, this triggers ASan:

$ make check TESTS="gdb.base/printcmds.exp" RUNTESTFLAGS="--target_board='cc-with-dwz-m'"

I still haven't found the issue, I'll have to check that later.

Also, tests gdb.base/infcall-nested-structs-c++.exp and gdb.base/infcall-nested-structs-c.exp
seemed to regress with boards fission-dwp / fission, I'll have to check that as well.

Simon

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

* Re: [PATCH v2 00/42] Share DWARF partial symtabs between objfiles
  2020-05-26 21:34           ` Simon Marchi
@ 2020-05-27  5:08             ` Simon Marchi
  2020-05-27 14:53               ` Simon Marchi
  0 siblings, 1 reply; 92+ messages in thread
From: Simon Marchi @ 2020-05-27  5:08 UTC (permalink / raw)
  To: Pedro Alves, Simon Marchi, Tom Tromey, Simon Marchi via Gdb-patches

On 2020-05-26 5:34 p.m., Simon Marchi wrote:
> On 2020-05-26 11:35 a.m., Simon Marchi wrote:
>> On 2020-05-26 7:17 a.m., Pedro Alves via Gdb-patches wrote:
>>> On 5/25/20 8:56 PM, Simon Marchi wrote:
>>>
>>>> Other than that, does any of you have further comments?  I've done the
>>>> small suggested fixups, but I don't think there was anything big
>>>> requiring another round, is there?
>>>
>>> No further comments from me.
>>>
>>> Thanks,
>>> Pedro Alves
>>>
>>
>> Ok, since I needed to do some non-trivial rebase, I'm giving it another round
>> of testing and I'll push it if it's all good.
>>
>> Simon
>>
> 
> Hmmm with the series applied, this triggers ASan:
> 
> $ make check TESTS="gdb.base/printcmds.exp" RUNTESTFLAGS="--target_board='cc-with-dwz-m'"
> 
> I still haven't found the issue, I'll have to check that later.

Ok, I think I have found the issue with this one.  Here's a brain dump before I go to bed
so I remember tomorrow:

- Things go wrong in this test because we load the same file twice
- Two objfiles representing the same binary are therefore created during the lifetime of GDB
- I noticed that some symbol belonging to the second objfile had a backlink to a symtab
  belonging to the first objfile
- The field dwarf_per_bfd::line_header_hash contains some "struct line_header" objects
- "struct line_header" contains "file_entry" objects, in its m_file_names field
- a "file_entry" object contains a pointer to the symtab that was created based on it
- If you go up the chain, it's then clear that file_entry and line_header are
  objfile-specific, so the field line_header_hash should not be in dwarf_per_bfd.

Simon



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

* [PATCH v2 41.5/42] Move line_header_hash to dwarf2_per_objfile
  2020-05-12 21:08 [PATCH v2 00/42] Share DWARF partial symtabs between objfiles Simon Marchi
                   ` (44 preceding siblings ...)
  2020-05-22 21:07 ` Tom Tromey
@ 2020-05-27 14:50 ` Simon Marchi
  2020-05-27 15:07   ` Tom Tromey
  45 siblings, 1 reply; 92+ messages in thread
From: Simon Marchi @ 2020-05-27 14:50 UTC (permalink / raw)
  To: Simon Marchi, gdb-patches

Here's another patch, inserted between 41 and 42.


From 5b16dc91567e370a5eaffc27bf2a35eafd46ca93 Mon Sep 17 00:00:00 2001
From: Simon Marchi <simon.marchi@efficios.com>
Date: Wed, 27 May 2020 01:20:50 -0400
Subject: [PATCH] Move line_header_hash to dwarf2_per_objfile

The `line_header_hash` field of `struct dwarf2_per_bfd` contains some
`struct line_header` objects.  A `struct line_header` objects contains
some `file_entry` objects.  A `file_entry` object contains a pointer to
the `symtab` object created from it.  The `line_header_hash` is
therefore ultimately objfile-dependent and can't be shared as-is between
objfiles.

Move it from `dwarf2_per_bfd` to `dwarf2_per_objfile`.

gdb/ChangeLog:

	* dwarf2/read.h (struct dwarf2_per_bfd) <line_header_hash>: Move
	to...
	(struct dwarf2_per_objfile) <line_header_hash>: ... here.
	* dwarf2/read.c (handle_DW_AT_stmt_list): Update.
---
 gdb/dwarf2/read.c | 12 ++++++------
 gdb/dwarf2/read.h |  6 +++---
 2 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index df15068269c..c77c3562123 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -10888,10 +10888,10 @@ handle_DW_AT_stmt_list (struct die_info *die, struct dwarf2_cu *cu,
      compile_unit, then use the line header hash table if it's already
      created, but don't create one just yet.  */

-  if (dwarf2_per_objfile->per_bfd->line_header_hash == NULL
+  if (dwarf2_per_objfile->line_header_hash == NULL
       && die->tag == DW_TAG_partial_unit)
     {
-      dwarf2_per_objfile->per_bfd->line_header_hash
+      dwarf2_per_objfile->line_header_hash
 	.reset (htab_create_alloc (127, line_header_hash_voidp,
 				   line_header_eq_voidp,
 				   free_line_header_voidp,
@@ -10901,9 +10901,9 @@ handle_DW_AT_stmt_list (struct die_info *die, struct dwarf2_cu *cu,
   line_header_local.sect_off = line_offset;
   line_header_local.offset_in_dwz = cu->per_cu->is_dwz;
   line_header_local_hash = line_header_hash (&line_header_local);
-  if (dwarf2_per_objfile->per_bfd->line_header_hash != NULL)
+  if (dwarf2_per_objfile->line_header_hash != NULL)
     {
-      slot = htab_find_slot_with_hash (dwarf2_per_objfile->per_bfd->line_header_hash.get (),
+      slot = htab_find_slot_with_hash (dwarf2_per_objfile->line_header_hash.get (),
 				       &line_header_local,
 				       line_header_local_hash, NO_INSERT);

@@ -10927,11 +10927,11 @@ handle_DW_AT_stmt_list (struct die_info *die, struct dwarf2_cu *cu,
   cu->line_header = lh.release ();
   cu->line_header_die_owner = die;

-  if (dwarf2_per_objfile->per_bfd->line_header_hash == NULL)
+  if (dwarf2_per_objfile->line_header_hash == NULL)
     slot = NULL;
   else
     {
-      slot = htab_find_slot_with_hash (dwarf2_per_objfile->per_bfd->line_header_hash.get (),
+      slot = htab_find_slot_with_hash (dwarf2_per_objfile->line_header_hash.get (),
 				       &line_header_local,
 				       line_header_local_hash, INSERT);
       gdb_assert (slot != NULL);
diff --git a/gdb/dwarf2/read.h b/gdb/dwarf2/read.h
index 996cf55af22..b53aab7be63 100644
--- a/gdb/dwarf2/read.h
+++ b/gdb/dwarf2/read.h
@@ -234,9 +234,6 @@ struct dwarf2_per_bfd
   /* The CUs we recently read.  */
   std::vector<dwarf2_per_cu_data *> just_read_cus;

-  /* Table containing line_header indexed by offset and offset_in_dwz.  */
-  htab_up line_header_hash;
-
   /* Table containing all filenames.  This is an optional because the
      table is lazily constructed on first access.  */
   gdb::optional<filename_seen_cache> filenames_cache;
@@ -368,6 +365,9 @@ struct dwarf2_per_objfile
      The mapping is done via (CU/TU + DIE offset) -> type.  */
   htab_up die_type_hash;

+  /* Table containing line_header indexed by offset and offset_in_dwz.  */
+  htab_up line_header_hash;
+
 private:
   /* Hold the corresponding compunit_symtab for each CU or TU.  This
      is indexed by dwarf2_per_cu_data::index.  A NULL value means
-- 
2.26.2



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

* Re: [PATCH v2 00/42] Share DWARF partial symtabs between objfiles
  2020-05-27  5:08             ` Simon Marchi
@ 2020-05-27 14:53               ` Simon Marchi
  2020-05-27 15:51                 ` Simon Marchi
  0 siblings, 1 reply; 92+ messages in thread
From: Simon Marchi @ 2020-05-27 14:53 UTC (permalink / raw)
  To: Pedro Alves, Simon Marchi, Tom Tromey, Simon Marchi via Gdb-patches

On 2020-05-27 1:08 a.m., Simon Marchi wrote:
> On 2020-05-26 5:34 p.m., Simon Marchi wrote:
>> On 2020-05-26 11:35 a.m., Simon Marchi wrote:
>>> On 2020-05-26 7:17 a.m., Pedro Alves via Gdb-patches wrote:
>>>> On 5/25/20 8:56 PM, Simon Marchi wrote:
>>>>
>>>>> Other than that, does any of you have further comments?  I've done the
>>>>> small suggested fixups, but I don't think there was anything big
>>>>> requiring another round, is there?
>>>>
>>>> No further comments from me.
>>>>
>>>> Thanks,
>>>> Pedro Alves
>>>>
>>>
>>> Ok, since I needed to do some non-trivial rebase, I'm giving it another round
>>> of testing and I'll push it if it's all good.
>>>
>>> Simon
>>>
>>
>> Hmmm with the series applied, this triggers ASan:
>>
>> $ make check TESTS="gdb.base/printcmds.exp" RUNTESTFLAGS="--target_board='cc-with-dwz-m'"
>>
>> I still haven't found the issue, I'll have to check that later.
> 
> Ok, I think I have found the issue with this one.  Here's a brain dump before I go to bed
> so I remember tomorrow:
> 
> - Things go wrong in this test because we load the same file twice
> - Two objfiles representing the same binary are therefore created during the lifetime of GDB
> - I noticed that some symbol belonging to the second objfile had a backlink to a symtab
>   belonging to the first objfile
> - The field dwarf_per_bfd::line_header_hash contains some "struct line_header" objects
> - "struct line_header" contains "file_entry" objects, in its m_file_names field
> - a "file_entry" object contains a pointer to the symtab that was created based on it
> - If you go up the chain, it's then clear that file_entry and line_header are
>   objfile-specific, so the field line_header_hash should not be in dwarf_per_bfd.

I added another patch to the series, see here:

  https://sourceware.org/pipermail/gdb-patches/2020-May/169065.html

The gdb.base/infcall-nested-structs-c.exp / gdb.base/infcall-nested-structs-c++.exp failures
just appeared to be intermittent failures in the end.  So I think that with this last patch,
the series would be good to go.

Simon

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

* Re: [PATCH v2 41.5/42] Move line_header_hash to dwarf2_per_objfile
  2020-05-27 14:50 ` [PATCH v2 41.5/42] Move line_header_hash to dwarf2_per_objfile Simon Marchi
@ 2020-05-27 15:07   ` Tom Tromey
  2020-05-27 15:10     ` Simon Marchi
  0 siblings, 1 reply; 92+ messages in thread
From: Tom Tromey @ 2020-05-27 15:07 UTC (permalink / raw)
  To: Simon Marchi; +Cc: Simon Marchi, gdb-patches

>>>>> "Simon" == Simon Marchi <simark@simark.ca> writes:

Simon> The `line_header_hash` field of `struct dwarf2_per_bfd` contains some
Simon> `struct line_header` objects.  A `struct line_header` objects contains
Simon> some `file_entry` objects.  A `file_entry` object contains a pointer to
Simon> the `symtab` object created from it.  The `line_header_hash` is
Simon> therefore ultimately objfile-dependent and can't be shared as-is between
Simon> objfiles.

Simon> Move it from `dwarf2_per_bfd` to `dwarf2_per_objfile`.

This patch looks good.

I wonder how hard it would be to remove this symtab link and share these
across objfiles.  However, I don't think this is worth delaying the
series for.

Tom

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

* Re: [PATCH v2 41.5/42] Move line_header_hash to dwarf2_per_objfile
  2020-05-27 15:07   ` Tom Tromey
@ 2020-05-27 15:10     ` Simon Marchi
  0 siblings, 0 replies; 92+ messages in thread
From: Simon Marchi @ 2020-05-27 15:10 UTC (permalink / raw)
  To: Tom Tromey, Simon Marchi; +Cc: gdb-patches

On 2020-05-27 11:07 a.m., Tom Tromey wrote:
>>>>>> "Simon" == Simon Marchi <simark@simark.ca> writes:
> 
> Simon> The `line_header_hash` field of `struct dwarf2_per_bfd` contains some
> Simon> `struct line_header` objects.  A `struct line_header` objects contains
> Simon> some `file_entry` objects.  A `file_entry` object contains a pointer to
> Simon> the `symtab` object created from it.  The `line_header_hash` is
> Simon> therefore ultimately objfile-dependent and can't be shared as-is between
> Simon> objfiles.
> 
> Simon> Move it from `dwarf2_per_bfd` to `dwarf2_per_objfile`.
> 
> This patch looks good.
> 
> I wonder how hard it would be to remove this symtab link and share these
> across objfiles.  However, I don't think this is worth delaying the
> series for.

Same.  I went for the obvious fix here, but once it's merged we can spend as much
time as we want to try to migrate stuff from dwarf2_per_objfile to dwarf2_per_bfd.

Thanks for the reviews!

Simon

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

* Re: [PATCH v2 00/42] Share DWARF partial symtabs between objfiles
  2020-05-27 14:53               ` Simon Marchi
@ 2020-05-27 15:51                 ` Simon Marchi
  2020-05-29 10:23                   ` Tom de Vries
  0 siblings, 1 reply; 92+ messages in thread
From: Simon Marchi @ 2020-05-27 15:51 UTC (permalink / raw)
  To: Pedro Alves, Simon Marchi, Tom Tromey, Simon Marchi via Gdb-patches

On 2020-05-27 10:53 a.m., Simon Marchi wrote:
> I added another patch to the series, see here:
> 
>   https://sourceware.org/pipermail/gdb-patches/2020-May/169065.html
> 
> The gdb.base/infcall-nested-structs-c.exp / gdb.base/infcall-nested-structs-c++.exp failures
> just appeared to be intermittent failures in the end.  So I think that with this last patch,
> the series would be good to go.
> 
> Simon
> 

All right, the series is now pushed!  With such a change, I do expect some things to break,
please let me know if you see some unexpected behavior chgange following this.

Simon

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

* Re: [PATCH v2 28/42] Remove dwarf2_per_cu_data::objfile ()
  2020-05-12 21:12 ` [PATCH v2 28/42] Remove dwarf2_per_cu_data::objfile () Simon Marchi
@ 2020-05-27 16:27   ` Tom de Vries
  2020-05-27 16:52     ` Tom de Vries
  2020-05-27 20:03     ` Simon Marchi
  0 siblings, 2 replies; 92+ messages in thread
From: Tom de Vries @ 2020-05-27 16:27 UTC (permalink / raw)
  To: Simon Marchi, gdb-patches

On 12-05-2020 23:12, Simon Marchi via Gdb-patches wrote:
> @@ -724,10 +721,13 @@ class dwarf_evaluate_loc_desc : public dwarf_expr_context
>      caller_frame = get_prev_frame (frame);
>  
>      parameter = dwarf_expr_reg_to_entry_parameter (frame, kind, kind_u,
> -						   &caller_per_cu);
> +						   &caller_per_cu,
> +						   &caller_per_objfile);
>      data_src = deref_size == -1 ? parameter->value : parameter->data_value;
>      size = deref_size == -1 ? parameter->value_size : parameter->data_value_size;
>  
> +    gdb_assert (this->per_objfile == caller_per_objfile);
> +

Hi,

I'm running into this assert here:
...
(gdb) PASS: gdb.base/catch-load.exp: plain load: catch load
continue^M
Continuing.^M
^M
Catchpoint 3^M
  Inferior loaded
/data/gdb_versions/devel/build/gdb/testsuite/outputs/gdb.base/catch-load/catch-load-so.so^M
dl_open_worker (/data/gdb_versions/devel/src/gdb/dwarf2/loc.c:729:
internal-error: virtual void
dwarf_evaluate_loc_desc::push_dwarf_reg_entry_value(call_site_parameter_kind,
call_site_parameter_u, int): Assertion `this->per_objfile ==
caller_per_objfile' failed.^M
A problem internal to GDB has been detected,^M
further debugging may prove unreliable.^M
Quit this debugging session? (y or n) FAIL: gdb.base/catch-load.exp:
plain load: continue (GDB internal error)
...

Minimal reproducer:
...
$ gdb -batch outputs/gdb.base/catch-load/catch-load \
    -ex start \
    -ex "catch load" \
    -ex continue
...

Actual values at assert:
...
729         gdb_assert (this->per_objfile == caller_per_objfile);
(gdb) p this->per_objfile
$1 = (dwarf2_per_objfile *) 0x1b2f940
(gdb) p caller_per_objfile
$2 = (dwarf2_per_objfile *) 0x1e53da0
(gdb) p *caller_per_objfile
$3 = {objfile = 0x1e53b60, per_bfd = 0x1f0d880, die_type_hash =
std::unique_ptr<htab> = {get() = 0x2054790},
  line_header_hash = std::unique_ptr<htab> = {get() = 0x0},
  m_symtabs = std::vector of length 1605, capacity 1605 = {0x0,
0x1e3f3a0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
    0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
    0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
    0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
    0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
    0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
    0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
    0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
    0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
    0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
    0x0, 0x0...}, m_type_units = std::unordered_map with 0 elements,
  m_type_map = std::unordered_map with 0 elements, m_dwarf2_cus =
std::unordered_map with 0 elements}
(gdb) p *this->per_objfile
$4 = {objfile = 0x1a6a010, per_bfd = 0x1b4a230, die_type_hash =
std::unique_ptr<htab> = {get() = 0x1c8a570},
  line_header_hash = std::unique_ptr<htab> = {get() = 0x0}, m_symtabs =
std::vector of length 83, capacity 83 = {
    0x1b3c090, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
    0x200dcb0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x210e350, 0x0, 0x0, 0x0, 0x0, 0x0,
    0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
    0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
    0x0, 0x0, 0x0}, m_type_units = std::unordered_map with 0 elements,
  m_type_map = std::unordered_map with 0 elements, m_dwarf2_cus =
std::unordered_map with 0 elements}
...

Backtrace:
...
(gdb) bt
#0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
#1  0x00007ffff4f60b01 in __GI_abort () at abort.c:79
#2  0x000000000099247e in dump_core () at
/data/gdb_versions/devel/src/gdb/utils.c:204
#3  0x0000000000992990 in internal_vproblem(internal_problem *, const
char *, int, const char *, typedef __va_list_tag __va_list_tag *)
(problem=0x11ea140 <internal_error_problem>,
    file=0xba6060 "/data/gdb_versions/devel/src/gdb/dwarf2/loc.c",
line=729,
    fmt=0xba60c8 "%s: Assertion `%s' failed.", ap=0x7fffffffc128) at
/data/gdb_versions/devel/src/gdb/utils.c:414
#4  0x0000000000992a58 in internal_verror (file=0xba6060
"/data/gdb_versions/devel/src/gdb/dwarf2/loc.c",
    line=729, fmt=0xba60c8 "%s: Assertion `%s' failed.", ap=0x7fffffffc128)
    at /data/gdb_versions/devel/src/gdb/utils.c:439
#5  0x0000000000b083ff in internal_error (file=0xba6060
"/data/gdb_versions/devel/src/gdb/dwarf2/loc.c",
    line=729, fmt=0xba60c8 "%s: Assertion `%s' failed.") at
/data/gdb_versions/devel/src/gdbsupport/errors.cc:55
#6  0x00000000005bfb30 in
dwarf_evaluate_loc_desc::push_dwarf_reg_entry_value (this=0x7fffffffc550,
    kind=CALL_SITE_PARAMETER_DWARF_REG, kind_u=..., deref_size=-1)
    at /data/gdb_versions/devel/src/gdb/dwarf2/loc.c:729
#7  0x000000000058aa15 in dwarf_expr_context::execute_stack_op
(this=0x7fffffffc550,
    op_ptr=0x7ffff00425b3 "\237\245\016", op_end=0x7ffff00425b4 "\245\016")
    at /data/gdb_versions/devel/src/gdb/dwarf2/expr.c:1292
#8  0x00000000005886b6 in dwarf_expr_context::eval (this=0x7fffffffc550,
    addr=0x7ffff00425b0 "\363\001U\237\245\016", len=4) at
/data/gdb_versions/devel/src/gdb/dwarf2/expr.c:303
#9  0x00000000005ba36c in dwarf2_evaluate_loc_desc_full (type=0x1c890c0,
frame=0x2006570,
    data=0x7ffff00425b0 "\363\001U\237\245\016", size=4,
per_cu=0x1b80fb0, per_objfile=0x1b2f940,
    subobj_type=0x1c890c0, subobj_byte_offset=0) at
/data/gdb_versions/devel/src/gdb/dwarf2/loc.c:2230
#10 0x00000000005baa55 in dwarf2_evaluate_loc_desc (type=0x1c890c0,
frame=0x2006570,
    data=0x7ffff00425b0 "\363\001U\237\245\016", size=4,
per_cu=0x1b80fb0, per_objfile=0x1b2f940)
--Type <RET> for more, q to quit, c to continue without paging--
    at /data/gdb_versions/devel/src/gdb/dwarf2/loc.c:2414
#11 0x00000000005befe4 in loclist_read_variable (symbol=0x20f7460,
frame=0x2006570)
    at /data/gdb_versions/devel/src/gdb/dwarf2/loc.c:4474
#12 0x000000000065001b in default_read_var_value (var=0x20f7460,
var_block=0x0, frame=0x2006570)
    at /data/gdb_versions/devel/src/gdb/findvar.c:610
#13 0x0000000000650b57 in read_var_value (var=0x20f7460, var_block=0x0,
frame=0x2006570)
    at /data/gdb_versions/devel/src/gdb/findvar.c:815
#14 0x00000000008a7051 in read_frame_arg (fp_opts=..., sym=0x20f7460,
frame=0x2006570, argp=0x7fffffffc970,
    entryargp=0x7fffffffc990) at
/data/gdb_versions/devel/src/gdb/stack.c:542
#15 0x00000000008a7c28 in print_frame_args (fp_opts=..., func=0x20f73e0,
frame=0x2006570, num=-1,
    stream=0x1ab1f20) at /data/gdb_versions/devel/src/gdb/stack.c:884
#16 0x00000000008a8e3d in print_frame (fp_opts=..., frame=0x2006570,
print_level=0, print_what=SRC_AND_LOC,
    print_args=1, sal=...) at /data/gdb_versions/devel/src/gdb/stack.c:1388
#17 0x00000000008a84f5 in print_frame_info (fp_opts=...,
frame=0x2006570, print_level=0, print_what=SRC_AND_LOC,
    print_args=1, set_current_sal=1) at
/data/gdb_versions/devel/src/gdb/stack.c:1113
#18 0x00000000008a6882 in print_stack_frame (frame=0x2006570,
print_level=0, print_what=SRC_AND_LOC,
    set_current_sal=1) at /data/gdb_versions/devel/src/gdb/stack.c:366
#19 0x00000000006eed37 in print_stop_location (ws=0x7fffffffcec0)
    at /data/gdb_versions/devel/src/gdb/infrun.c:8352
#20 0x00000000006eed95 in print_stop_event (uiout=0x1ab3380, displays=true)
    at /data/gdb_versions/devel/src/gdb/infrun.c:8368
#21 0x0000000000948783 in tui_on_normal_stop (bs=0x2054b90, print_frame=1)
    at /data/gdb_versions/devel/src/gdb/tui/tui-interp.c:98
#22 0x0000000000448abf in std::_Function_handler<void (bpstats*, int),
void (*)(bpstats*, int)>::_M_invoke(std::_Any_data const&, bpstats*&&,
int&&) (__functor=..., __args#0=@0x7fffffffcfd0: 0x2054b90,
--Type <RET> for more, q to quit, c to continue without paging--
    __args#1=@0x7fffffffcfcc: 1) at
/usr/include/c++/7/bits/std_function.h:316
#23 0x00000000006f3ce2 in std::function<void (bpstats*,
int)>::operator()(bpstats*, int) const (this=0x133ae70,
    __args#0=0x2054b90, __args#1=1) at
/usr/include/c++/7/bits/std_function.h:706
#24 0x00000000006f2ffc in gdb::observers::observable<bpstats*,
int>::notify (
    this=0x1211260 <gdb::observers::normal_stop>, args#0=0x2054b90,
args#1=1)
    at /data/gdb_versions/devel/src/gdb/../gdbsupport/observable.h:106
#25 0x00000000006ef530 in normal_stop () at
/data/gdb_versions/devel/src/gdb/infrun.c:8646
#26 0x00000000006e53e9 in fetch_inferior_event (client_data=0x0)
    at /data/gdb_versions/devel/src/gdb/infrun.c:4065
#27 0x00000000006caa9d in inferior_event_handler
(event_type=INF_REG_EVENT, client_data=0x0)
    at /data/gdb_versions/devel/src/gdb/inf-loop.c:43
#28 0x0000000000724581 in handle_target_event (error=0, client_data=0x0)
    at /data/gdb_versions/devel/src/gdb/linux-nat.c:4235
#29 0x0000000000b09018 in handle_file_event (file_ptr=0x1afb810,
ready_mask=1)
    at /data/gdb_versions/devel/src/gdbsupport/event-loop.cc:548
#30 0x0000000000b095a0 in gdb_wait_for_event (block=0)
    at /data/gdb_versions/devel/src/gdbsupport/event-loop.cc:673
#31 0x0000000000b08533 in gdb_do_one_event () at
/data/gdb_versions/devel/src/gdbsupport/event-loop.cc:190
#32 0x0000000000920c72 in wait_sync_command_done () at
/data/gdb_versions/devel/src/gdb/top.c:526
#33 0x0000000000920cea in maybe_wait_sync_command_done (was_sync=0) at
/data/gdb_versions/devel/src/gdb/top.c:543
#34 0x0000000000921179 in execute_command (p=0x7fffffffe117 "", from_tty=0)
    at /data/gdb_versions/devel/src/gdb/top.c:657
#35 0x000000000074a197 in catch_command_errors (command=0x920d03
<execute_command(char const*, int)>,
    arg=0x7fffffffe10f "continue", from_tty=0) at
/data/gdb_versions/devel/src/gdb/main.c:457
#36 0x000000000074b57f in captured_main_1 (context=0x7fffffffda00)
--Type <RET> for more, q to quit, c to continue without paging--
    at /data/gdb_versions/devel/src/gdb/main.c:1219
#37 0x000000000074b774 in captured_main (data=0x7fffffffda00) at
/data/gdb_versions/devel/src/gdb/main.c:1244
#38 0x000000000074b7df in gdb_main (args=0x7fffffffda00) at
/data/gdb_versions/devel/src/gdb/main.c:1269
#39 0x000000000041515e in main (argc=14, argv=0x7fffffffdb08) at
/data/gdb_versions/devel/src/gdb/gdb.c:32
...

Thanks,
- Tom

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

* Re: [PATCH v2 28/42] Remove dwarf2_per_cu_data::objfile ()
  2020-05-27 16:27   ` Tom de Vries
@ 2020-05-27 16:52     ` Tom de Vries
  2020-05-27 20:03     ` Simon Marchi
  1 sibling, 0 replies; 92+ messages in thread
From: Tom de Vries @ 2020-05-27 16:52 UTC (permalink / raw)
  To: Simon Marchi, gdb-patches

On 27-05-2020 18:27, Tom de Vries wrote:
> On 12-05-2020 23:12, Simon Marchi via Gdb-patches wrote:
>> @@ -724,10 +721,13 @@ class dwarf_evaluate_loc_desc : public dwarf_expr_context
>>      caller_frame = get_prev_frame (frame);
>>  
>>      parameter = dwarf_expr_reg_to_entry_parameter (frame, kind, kind_u,
>> -						   &caller_per_cu);
>> +						   &caller_per_cu,
>> +						   &caller_per_objfile);
>>      data_src = deref_size == -1 ? parameter->value : parameter->data_value;
>>      size = deref_size == -1 ? parameter->value_size : parameter->data_value_size;
>>  
>> +    gdb_assert (this->per_objfile == caller_per_objfile);
>> +
> 
> Hi,
> 
> I'm running into this assert here:
> ...
> (gdb) PASS: gdb.base/catch-load.exp: plain load: catch load
> continue^M
> Continuing.^M
> ^M
> Catchpoint 3^M
>   Inferior loaded
> /data/gdb_versions/devel/build/gdb/testsuite/outputs/gdb.base/catch-load/catch-load-so.so^M
> dl_open_worker (/data/gdb_versions/devel/src/gdb/dwarf2/loc.c:729:
> internal-error: virtual void
> dwarf_evaluate_loc_desc::push_dwarf_reg_entry_value(call_site_parameter_kind,
> call_site_parameter_u, int): Assertion `this->per_objfile ==
> caller_per_objfile' failed.^M
> A problem internal to GDB has been detected,^M
> further debugging may prove unreliable.^M
> Quit this debugging session? (y or n) FAIL: gdb.base/catch-load.exp:
> plain load: continue (GDB internal error)
> ...
> 
> Minimal reproducer:
> ...
> $ gdb -batch outputs/gdb.base/catch-load/catch-load \
>     -ex start \
>     -ex "catch load" \
>     -ex continue
> ...
> 

By disabling the assert, the test passes, and with the minimal
reproducer, we have:
...
$ gdb -batch outputs/gdb.base/catch-load/catch-load \
    -ex start \
    -ex "catch load"
    -ex continue
Temporary breakpoint 1 at 0x40058f: file
/data/gdb_versions/devel/src/gdb/testsuite/gdb.base/catch-load.c, line 36.

Temporary breakpoint 1, main () at
/data/gdb_versions/devel/src/gdb/testsuite/gdb.base/catch-load.c:36
36        h = dlopen (libname, RTLD_LAZY);
Catchpoint 2 (load)

Catchpoint 2
  Inferior loaded
/data/gdb_versions/devel/build/gdb/testsuite/outputs/gdb.base/catch-load/catch-load-so.so
dl_open_worker (a=a@entry=0x7fffffffd880) at dl-open.c:509
509         LIBC_PROBE (reloc_complete, 3, args->nsid, r, new);
...

Thanks,
- Tom

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

* Re: [PATCH v2 28/42] Remove dwarf2_per_cu_data::objfile ()
  2020-05-27 16:27   ` Tom de Vries
  2020-05-27 16:52     ` Tom de Vries
@ 2020-05-27 20:03     ` Simon Marchi
  2020-05-27 21:08       ` Tom de Vries
  1 sibling, 1 reply; 92+ messages in thread
From: Simon Marchi @ 2020-05-27 20:03 UTC (permalink / raw)
  To: Tom de Vries, Simon Marchi, gdb-patches

On 2020-05-27 12:27 p.m., Tom de Vries wrote:
> On 12-05-2020 23:12, Simon Marchi via Gdb-patches wrote:
>> @@ -724,10 +721,13 @@ class dwarf_evaluate_loc_desc : public dwarf_expr_context
>>      caller_frame = get_prev_frame (frame);
>>  
>>      parameter = dwarf_expr_reg_to_entry_parameter (frame, kind, kind_u,
>> -						   &caller_per_cu);
>> +						   &caller_per_cu,
>> +						   &caller_per_objfile);
>>      data_src = deref_size == -1 ? parameter->value : parameter->data_value;
>>      size = deref_size == -1 ? parameter->value_size : parameter->data_value_size;
>>  
>> +    gdb_assert (this->per_objfile == caller_per_objfile);
>> +
> 
> Hi,
> 
> I'm running into this assert here:
> ...
> (gdb) PASS: gdb.base/catch-load.exp: plain load: catch load
> continue^M
> Continuing.^M
> ^M
> Catchpoint 3^M
>   Inferior loaded
> /data/gdb_versions/devel/build/gdb/testsuite/outputs/gdb.base/catch-load/catch-load-so.so^M
> dl_open_worker (/data/gdb_versions/devel/src/gdb/dwarf2/loc.c:729:
> internal-error: virtual void
> dwarf_evaluate_loc_desc::push_dwarf_reg_entry_value(call_site_parameter_kind,
> call_site_parameter_u, int): Assertion `this->per_objfile ==
> caller_per_objfile' failed.^M
> A problem internal to GDB has been detected,^M
> further debugging may prove unreliable.^M
> Quit this debugging session? (y or n) FAIL: gdb.base/catch-load.exp:
> plain load: continue (GDB internal error)

I don't see this failure.  Is it with a particular board file?  Or maybe
gcc-version specific?

It looks related to what we have discussed here:

https://sourceware.org/pipermail/gdb-patches/2020-May/168906.html

I think the fix would be to temporarily override this->per_objfile to be
caller_per_objfile (with a scoped_restore).  But I'd like to be able to
reproduce it to understand what's happening.

Simon

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

* Re: [PATCH v2 28/42] Remove dwarf2_per_cu_data::objfile ()
  2020-05-27 20:03     ` Simon Marchi
@ 2020-05-27 21:08       ` Tom de Vries
  2020-05-27 21:55         ` Simon Marchi
  0 siblings, 1 reply; 92+ messages in thread
From: Tom de Vries @ 2020-05-27 21:08 UTC (permalink / raw)
  To: Simon Marchi, Simon Marchi, gdb-patches

On 27-05-2020 22:03, Simon Marchi wrote:
> On 2020-05-27 12:27 p.m., Tom de Vries wrote:
>> On 12-05-2020 23:12, Simon Marchi via Gdb-patches wrote:
>>> @@ -724,10 +721,13 @@ class dwarf_evaluate_loc_desc : public dwarf_expr_context
>>>      caller_frame = get_prev_frame (frame);
>>>  
>>>      parameter = dwarf_expr_reg_to_entry_parameter (frame, kind, kind_u,
>>> -						   &caller_per_cu);
>>> +						   &caller_per_cu,
>>> +						   &caller_per_objfile);
>>>      data_src = deref_size == -1 ? parameter->value : parameter->data_value;
>>>      size = deref_size == -1 ? parameter->value_size : parameter->data_value_size;
>>>  
>>> +    gdb_assert (this->per_objfile == caller_per_objfile);
>>> +
>>
>> Hi,
>>
>> I'm running into this assert here:
>> ...
>> (gdb) PASS: gdb.base/catch-load.exp: plain load: catch load
>> continue^M
>> Continuing.^M
>> ^M
>> Catchpoint 3^M
>>   Inferior loaded
>> /data/gdb_versions/devel/build/gdb/testsuite/outputs/gdb.base/catch-load/catch-load-so.so^M
>> dl_open_worker (/data/gdb_versions/devel/src/gdb/dwarf2/loc.c:729:
>> internal-error: virtual void
>> dwarf_evaluate_loc_desc::push_dwarf_reg_entry_value(call_site_parameter_kind,
>> call_site_parameter_u, int): Assertion `this->per_objfile ==
>> caller_per_objfile' failed.^M
>> A problem internal to GDB has been detected,^M
>> further debugging may prove unreliable.^M
>> Quit this debugging session? (y or n) FAIL: gdb.base/catch-load.exp:
>> plain load: continue (GDB internal error)
> 
> I don't see this failure.  Is it with a particular board file?  Or maybe
> gcc-version specific?
> 

No, this is with native, and reproduced with gcc 7.5.0, gcc 4.8.5, gcc
10.1.1 and clang 5.0.2.

> It looks related to what we have discussed here:
> 
> https://sourceware.org/pipermail/gdb-patches/2020-May/168906.html
> 
> I think the fix would be to temporarily override this->per_objfile to be
> caller_per_objfile (with a scoped_restore).  But I'd like to be able to
> reproduce it to understand what's happening.

I think maybe installing debug info for glibc and building with
--with-separate-debug-dir=/usr/lib/debug may do the trick.

Thanks,
- Tom


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

* Re: [PATCH v2 28/42] Remove dwarf2_per_cu_data::objfile ()
  2020-05-27 21:08       ` Tom de Vries
@ 2020-05-27 21:55         ` Simon Marchi
  2020-05-27 22:16           ` Simon Marchi
  0 siblings, 1 reply; 92+ messages in thread
From: Simon Marchi @ 2020-05-27 21:55 UTC (permalink / raw)
  To: Tom de Vries, Simon Marchi, gdb-patches

On 2020-05-27 5:08 p.m., Tom de Vries wrote:
>> I don't see this failure.  Is it with a particular board file?  Or maybe
>> gcc-version specific?
>>
> 
> No, this is with native, and reproduced with gcc 7.5.0, gcc 4.8.5, gcc
> 10.1.1 and clang 5.0.2.
> 
>> It looks related to what we have discussed here:
>>
>> https://sourceware.org/pipermail/gdb-patches/2020-May/168906.html
>>
>> I think the fix would be to temporarily override this->per_objfile to be
>> caller_per_objfile (with a scoped_restore).  But I'd like to be able to
>> reproduce it to understand what's happening.
> 
> I think maybe installing debug info for glibc and building with
> --with-separate-debug-dir=/usr/lib/debug may do the trick.
> 
> Thanks,
> - Tom
> 

I do have debug info for glibc and it is found:

(gdb) info shared
From                To                  Syms Read   Shared Object Library
0x00007ffff7dd7ac0  0x00007ffff7df5790  Yes         /lib64/ld-linux-x86-64.so.2
0x00007ffff7bd3da0  0x00007ffff7bd498e  Yes         /lib/x86_64-linux-gnu/libdl.so.2
0x00007ffff78288b0  0x00007ffff797bb04  Yes         /lib/x86_64-linux-gnu/libc.so.6

I tested with these two gccs:

$ gcc --version
gcc (Ubuntu 5.5.0-12ubuntu1~16.04) 5.5.0 20171010
$ gcc-9 --version
gcc-9 (Ubuntu 9.3.0-10ubuntu2~16.04) 9.3.0

I will give a shot at building GDB in an opensuse container [1], we'll see.

Simon

[1] https://hub.docker.com/r/opensuse/leap

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

* Re: [PATCH v2 28/42] Remove dwarf2_per_cu_data::objfile ()
  2020-05-27 21:55         ` Simon Marchi
@ 2020-05-27 22:16           ` Simon Marchi
  2020-05-28  2:00             ` Simon Marchi
  0 siblings, 1 reply; 92+ messages in thread
From: Simon Marchi @ 2020-05-27 22:16 UTC (permalink / raw)
  To: Simon Marchi, Tom de Vries, gdb-patches

On 2020-05-27 5:55 p.m., Simon Marchi wrote:
> On 2020-05-27 5:08 p.m., Tom de Vries wrote:
>>> I don't see this failure.  Is it with a particular board file?  Or maybe
>>> gcc-version specific?
>>>
>>
>> No, this is with native, and reproduced with gcc 7.5.0, gcc 4.8.5, gcc
>> 10.1.1 and clang 5.0.2.
>>
>>> It looks related to what we have discussed here:
>>>
>>> https://sourceware.org/pipermail/gdb-patches/2020-May/168906.html
>>>
>>> I think the fix would be to temporarily override this->per_objfile to be
>>> caller_per_objfile (with a scoped_restore).  But I'd like to be able to
>>> reproduce it to understand what's happening.
>>
>> I think maybe installing debug info for glibc and building with
>> --with-separate-debug-dir=/usr/lib/debug may do the trick.
>>
>> Thanks,
>> - Tom
>>
> 
> I do have debug info for glibc and it is found:
> 
> (gdb) info shared
> From                To                  Syms Read   Shared Object Library
> 0x00007ffff7dd7ac0  0x00007ffff7df5790  Yes         /lib64/ld-linux-x86-64.so.2
> 0x00007ffff7bd3da0  0x00007ffff7bd498e  Yes         /lib/x86_64-linux-gnu/libdl.so.2
> 0x00007ffff78288b0  0x00007ffff797bb04  Yes         /lib/x86_64-linux-gnu/libc.so.6
> 
> I tested with these two gccs:
> 
> $ gcc --version
> gcc (Ubuntu 5.5.0-12ubuntu1~16.04) 5.5.0 20171010
> $ gcc-9 --version
> gcc-9 (Ubuntu 9.3.0-10ubuntu2~16.04) 9.3.0
> 
> I will give a shot at building GDB in an opensuse container [1], we'll see.
> 
> Simon
> 
> [1] https://hub.docker.com/r/opensuse/leap
> 

Ok, I reproduced it with opensuse/tumbleweed, after installing glibc's debug info.  I'll
look into it.

Simon

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

* Re: [PATCH v2 23/42] Add dwarf2_per_objfile to dwarf_expr_context and dwarf2_frame_cache
  2020-05-25 19:50     ` Simon Marchi
@ 2020-05-28  1:44       ` Simon Marchi
  0 siblings, 0 replies; 92+ messages in thread
From: Simon Marchi @ 2020-05-28  1:44 UTC (permalink / raw)
  To: Tom Tromey, Simon Marchi via Gdb-patches; +Cc: Simon Marchi

On 2020-05-25 3:50 p.m., Simon Marchi wrote:
> On 2020-05-22 5:04 p.m., Tom Tromey wrote:
>>>>>>> "Simon" == Simon Marchi via Gdb-patches <gdb-patches@sourceware.org> writes:
>>
>> Simon> *Note*, there's one spot I'm particularly unsure about.  In
>> Simon> dwarf_evaluate_loc_desc::push_dwarf_reg_entry_value, we would save and
>> Simon> overwrite the offset value in the context, along with a bunch of other
>> Simon> state.  This is because we might be about to evaluate something in a
>> Simon> different CU that the current one.  If the two CUs are in the same
>> Simon> objfile, then the text_offset is the same, as it's a property of the
>> Simon> objfile.  However, if the two CUs are possibly in different objfiles,
>> Simon> then it means the text_offsets are different.  It would also mean we
>> Simon> would need to save and restore the dwarf2_per_objfile in the context.
>> Simon> Is that even possible?
>>
>> Unfortunately I don't know for sure.
>> However, call_site_for_pc doesn't distinguish between objfiles.  So, I
>> suppose I would assume it is possible.
>>
>> Tom
> 
> In practice, I'm not sure how that can happen.  Can DWARF info in an objfile
> refer to the DWARF info in another objfile?  Can there be a subprogram described
> in one and a call site of that subprogram described in another objfile?  If we
> are quite sure it can't happen, I would rather not include code for it, that's
> just unnecessary complexity.
> 
> A further patch (28/42) happens to tie call sites with an objfile, and adds a
> gdb_assert here making sure that the call site's objfile is the same as the
> callee's objfile.
> 
> So I would propose to leave that gdb_assert there, if we are wrong then we'll
> fix that function.

So it turns out that it wasn't there for nothing!  Call sites can refer to another
objfile in some occasions.  See the follow up in this thread:

https://sourceware.org/pipermail/gdb-patches/2020-May/169077.html

Simon

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

* Re: [PATCH v2 28/42] Remove dwarf2_per_cu_data::objfile ()
  2020-05-27 22:16           ` Simon Marchi
@ 2020-05-28  2:00             ` Simon Marchi
  2020-05-28 13:05               ` Tom de Vries
  0 siblings, 1 reply; 92+ messages in thread
From: Simon Marchi @ 2020-05-28  2:00 UTC (permalink / raw)
  To: Simon Marchi, Tom de Vries, gdb-patches

On 2020-05-27 6:16 p.m., Simon Marchi via Gdb-patches wrote:
> Ok, I reproduced it with opensuse/tumbleweed, after installing glibc's debug info.  I'll
> look into it.

Quick update to say that I understand a bit more what happens.  It turns out that call sites
can refer indirectly to other objfiles.  Here, we deal with an indirect call (through a function
pointer probably).  In that case, the call site doesn't know at compile time what it calls.  It
provides a DWARF expression to compute the called address. The DIE corresponding to the call site
is:

0x0091aa10:     DW_TAG_GNU_call_site
                  DW_AT_low_pc [DW_FORM_addr]   (0x00000000001398e0)
                  DW_AT_GNU_call_site_target [DW_FORM_exprloc]  (DW_OP_fbreg -272, DW_OP_deref)
                  DW_AT_sibling [DW_FORM_ref4]  (0x0091aa2b)

This call site is in the _dl_catch_exception function of libc (which indeed takes a function pointer
as argument).  In our case, the function pointer is a function in ld-linux.so.  So this is how the
two objfiles can be different.

For comparison, when the function being called is known at compile time, the call site DIE will refer
directly to the function being called, like in this case:

0x0091a9f2:     DW_TAG_GNU_call_site
                  DW_AT_low_pc [DW_FORM_addr]   (0x00000000001398cd)
                  DW_AT_abstract_origin [DW_FORM_ref4]  (0x0091ad45 "__GI___sigsetjmp")
                  DW_AT_sibling [DW_FORM_ref4]  (0x0091aa10)

In that case, I presume that it's not really possible for the caller and calle to be in different
objfiles (this is the scenarion I had in my mind, I didn't know that indirect call sites could be
described as well).

See the patch below (still missing the commit message).  I think we only need to put and restore the
caller's per_objfile in this->per_objfile.  Alternatively, we could maybe just create a new
dwarf_evaluate_loc_desc local object, instead of setting and restoring all the fields.  I'll try that
tomorrow.

Simon


From 2381d562b3130b94ad8e266dd034431f80275c8b Mon Sep 17 00:00:00 2001
From: Simon Marchi <simon.marchi@efficios.com>
Date: Wed, 27 May 2020 21:54:45 -0400
Subject: [PATCH] gdb: use caller objfile in
 dwarf_evaluate_loc_desc::push_dwarf_reg_entry_value

Change-Id: Ib227d767ce525c10607ab6621a373aaae982c67a
---
 gdb/dwarf2/loc.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/gdb/dwarf2/loc.c b/gdb/dwarf2/loc.c
index 7953361adeed..1aab1a4f51bc 100644
--- a/gdb/dwarf2/loc.c
+++ b/gdb/dwarf2/loc.c
@@ -726,8 +726,6 @@ class dwarf_evaluate_loc_desc : public dwarf_expr_context
     data_src = deref_size == -1 ? parameter->value : parameter->data_value;
     size = deref_size == -1 ? parameter->value_size : parameter->data_value_size;

-    gdb_assert (this->per_objfile == caller_per_objfile);
-
     /* DEREF_SIZE size is not verified here.  */
     if (data_src == NULL)
       throw_error (NO_ENTRY_VALUE_ERROR,
@@ -739,11 +737,13 @@ class dwarf_evaluate_loc_desc : public dwarf_expr_context
 						      caller_per_cu);
     scoped_restore save_obj_addr = make_scoped_restore (&this->obj_address,
 							(CORE_ADDR) 0);
+    scoped_restore save_per_objfile = make_scoped_restore (&this->per_objfile,
+							   caller_per_objfile);

     scoped_restore save_arch = make_scoped_restore (&this->gdbarch);
     this->gdbarch = this->per_objfile->objfile->arch ();
     scoped_restore save_addr_size = make_scoped_restore (&this->addr_size);
-    this->addr_size = per_cu->addr_size ();
+    this->addr_size = this->per_cu->addr_size ();

     this->eval (data_src, size);
   }
-- 
2.26.2


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

* Re: [PATCH v2 28/42] Remove dwarf2_per_cu_data::objfile ()
  2020-05-28  2:00             ` Simon Marchi
@ 2020-05-28 13:05               ` Tom de Vries
  2020-05-28 15:33                 ` Simon Marchi
  0 siblings, 1 reply; 92+ messages in thread
From: Tom de Vries @ 2020-05-28 13:05 UTC (permalink / raw)
  To: Simon Marchi, Simon Marchi, gdb-patches

On 28-05-2020 04:00, Simon Marchi wrote:
> On 2020-05-27 6:16 p.m., Simon Marchi via Gdb-patches wrote:
>> Ok, I reproduced it with opensuse/tumbleweed, after installing glibc's debug info.  I'll
>> look into it.
> 
> Quick update to say that I understand a bit more what happens.  It turns out that call sites
> can refer indirectly to other objfiles.  Here, we deal with an indirect call (through a function
> pointer probably).  In that case, the call site doesn't know at compile time what it calls.  It
> provides a DWARF expression to compute the called address. The DIE corresponding to the call site
> is:
> 
> 0x0091aa10:     DW_TAG_GNU_call_site
>                   DW_AT_low_pc [DW_FORM_addr]   (0x00000000001398e0)
>                   DW_AT_GNU_call_site_target [DW_FORM_exprloc]  (DW_OP_fbreg -272, DW_OP_deref)
>                   DW_AT_sibling [DW_FORM_ref4]  (0x0091aa2b)
> 
> This call site is in the _dl_catch_exception function of libc (which indeed takes a function pointer
> as argument).  In our case, the function pointer is a function in ld-linux.so.  So this is how the
> two objfiles can be different.
> 
> For comparison, when the function being called is known at compile time, the call site DIE will refer
> directly to the function being called, like in this case:
> 
> 0x0091a9f2:     DW_TAG_GNU_call_site
>                   DW_AT_low_pc [DW_FORM_addr]   (0x00000000001398cd)
>                   DW_AT_abstract_origin [DW_FORM_ref4]  (0x0091ad45 "__GI___sigsetjmp")
>                   DW_AT_sibling [DW_FORM_ref4]  (0x0091aa10)
> 
> In that case, I presume that it's not really possible for the caller and calle to be in different
> objfiles (this is the scenarion I had in my mind, I didn't know that indirect call sites could be
> described as well).
> 
> See the patch below (still missing the commit message). 

Hi,

thanks for looking into this.

I tried out the patch, and it fixes all regressions for me.

Thanks,
- Tom

> I think we only need to put and restore the
> caller's per_objfile in this->per_objfile.  Alternatively, we could maybe just create a new
> dwarf_evaluate_loc_desc local object, instead of setting and restoring all the fields.  I'll try that
> tomorrow.
> 
> Simon
> 
> 
> From 2381d562b3130b94ad8e266dd034431f80275c8b Mon Sep 17 00:00:00 2001
> From: Simon Marchi <simon.marchi@efficios.com>
> Date: Wed, 27 May 2020 21:54:45 -0400
> Subject: [PATCH] gdb: use caller objfile in
>  dwarf_evaluate_loc_desc::push_dwarf_reg_entry_value
> 
> Change-Id: Ib227d767ce525c10607ab6621a373aaae982c67a
> ---
>  gdb/dwarf2/loc.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/gdb/dwarf2/loc.c b/gdb/dwarf2/loc.c
> index 7953361adeed..1aab1a4f51bc 100644
> --- a/gdb/dwarf2/loc.c
> +++ b/gdb/dwarf2/loc.c
> @@ -726,8 +726,6 @@ class dwarf_evaluate_loc_desc : public dwarf_expr_context
>      data_src = deref_size == -1 ? parameter->value : parameter->data_value;
>      size = deref_size == -1 ? parameter->value_size : parameter->data_value_size;
> 
> -    gdb_assert (this->per_objfile == caller_per_objfile);
> -
>      /* DEREF_SIZE size is not verified here.  */
>      if (data_src == NULL)
>        throw_error (NO_ENTRY_VALUE_ERROR,
> @@ -739,11 +737,13 @@ class dwarf_evaluate_loc_desc : public dwarf_expr_context
>  						      caller_per_cu);
>      scoped_restore save_obj_addr = make_scoped_restore (&this->obj_address,
>  							(CORE_ADDR) 0);
> +    scoped_restore save_per_objfile = make_scoped_restore (&this->per_objfile,
> +							   caller_per_objfile);
> 
>      scoped_restore save_arch = make_scoped_restore (&this->gdbarch);
>      this->gdbarch = this->per_objfile->objfile->arch ();
>      scoped_restore save_addr_size = make_scoped_restore (&this->addr_size);
> -    this->addr_size = per_cu->addr_size ();
> +    this->addr_size = this->per_cu->addr_size ();
> 
>      this->eval (data_src, size);
>    }
> 

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

* Re: [PATCH v2 28/42] Remove dwarf2_per_cu_data::objfile ()
  2020-05-28 13:05               ` Tom de Vries
@ 2020-05-28 15:33                 ` Simon Marchi
  2020-05-28 16:24                   ` Christian Biesinger
  0 siblings, 1 reply; 92+ messages in thread
From: Simon Marchi @ 2020-05-28 15:33 UTC (permalink / raw)
  To: Tom de Vries, Simon Marchi, gdb-patches

On 2020-05-28 9:05 a.m., Tom de Vries wrote:
> Hi,
> 
> thanks for looking into this.
> 
> I tried out the patch, and it fixes all regressions for me.
> 
> Thanks,
> - Tom

Thanks, I pushed it with the following commit message.

Simon


From 44486dcf19b62708ad49bbb6094e065a223dea99 Mon Sep 17 00:00:00 2001
From: Simon Marchi <simon.marchi@efficios.com>
Date: Thu, 28 May 2020 11:30:11 -0400
Subject: [PATCH] gdb: use caller objfile in
 dwarf_evaluate_loc_desc::push_dwarf_reg_entry_value

In commit

    89b07335fe ("Add dwarf2_per_objfile to dwarf_expr_context and dwarf2_frame_cache")

I replaced the offset property of dwarf_expr_context by a per_objfile
property (since we can get the text offset from the objfile).  The
previous code in dwarf_evaluate_loc_desc::push_dwarf_reg_entry_value
(dwarf_evaluate_loc_desc derives from dwarf_expr_context) did
temporarily override the offset property while evaluating a DWARF
sub-expression.  I speculated that this sub-expression always came from
the same objfile as the outer expression, so I didn't see the need to
temporarily override the per_objfile property in the new code.  A later
commit:

    9f47c70716 ("Remove dwarf2_per_cu_data::objfile ()")

added the following assertion to verify this:

    gdb_assert (this->per_objfile == caller_per_objfile);

It turns out that this is not true.  Call sites can refer to function in
another objfile, and therefore the caller's objfile can be different
from the callee's objfile.  This can happen when the call site DIE in the
DWARF represents a function call done through a function pointer.  The
DIE can't describe statically which function is being called, since it's
variable and not known at compile time.  Instead, it provides an
expression that evaluates to the address of the function being called.
In this case, the called function can very well be in a separate
objfile.

Fix this by overriding the per_objfile property while evaluating the
sub-expression.

This was exposed by the gdb.base/catch-load.exp test failing on openSUSE
Tumbleweed with the glibc debug info installed.  It was also reported to
fail on Fedora.

When I investigated the problem, the particular call site on which we
did hit the assert was coming from this DIE, in
/usr/lib/debug/lib64/libc-2.31.so-2.31-5.1.x86_64.debug on openSUSE
Tumbleweed:

    0x0091aa10:     DW_TAG_GNU_call_site
                      DW_AT_low_pc [DW_FORM_addr]   (0x00000000001398e0)
                      DW_AT_GNU_call_site_target [DW_FORM_exprloc]  (DW_OP_fbreg -272, DW_OP_deref)
                      DW_AT_sibling [DW_FORM_ref4]  (0x0091aa2b)

And for you curious out there, this call site is found in this function:

    0x0091a91d:   DW_TAG_subprogram
                    DW_AT_external [DW_FORM_flag_present]   (true)
                    DW_AT_name [DW_FORM_strp]       ("_dl_catch_exception")
                    DW_AT_decl_file [DW_FORM_data1] ("/usr/src/debug/glibc-2.31-5.1.x86_64/elf/dl-error-skeleton.c")
                    ...

Which is a function that indeed uses a function pointer.

gdb/ChangeLog:

	* dwarf2/loc.c (class dwarf_evaluate_loc_desc)
	<push_dwarf_reg_entry_value>: Remove assert.  Override
	per_objfile with caller_per_objfile.

Change-Id: Ib227d767ce525c10607ab6621a373aaae982c67a
---
 gdb/ChangeLog    | 6 ++++++
 gdb/dwarf2/loc.c | 6 +++---
 2 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 593ff01cc9d0..e5b4019dd646 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,9 @@
+2020-05-28  Simon Marchi  <simon.marchi@efficios.com>
+
+	* dwarf2/loc.c (class dwarf_evaluate_loc_desc)
+	<push_dwarf_reg_entry_value>: Remove assert.  Override
+	per_objfile with caller_per_objfile.
+
 2020-05-28  Tom de Vries  <tdevries@suse.de>

 	* dwarf2/read.c	(dw2_symtab_iter_next, dw2_expand_marked_cus): Limit
diff --git a/gdb/dwarf2/loc.c b/gdb/dwarf2/loc.c
index 7953361adeed..1aab1a4f51bc 100644
--- a/gdb/dwarf2/loc.c
+++ b/gdb/dwarf2/loc.c
@@ -726,8 +726,6 @@ class dwarf_evaluate_loc_desc : public dwarf_expr_context
     data_src = deref_size == -1 ? parameter->value : parameter->data_value;
     size = deref_size == -1 ? parameter->value_size : parameter->data_value_size;

-    gdb_assert (this->per_objfile == caller_per_objfile);
-
     /* DEREF_SIZE size is not verified here.  */
     if (data_src == NULL)
       throw_error (NO_ENTRY_VALUE_ERROR,
@@ -739,11 +737,13 @@ class dwarf_evaluate_loc_desc : public dwarf_expr_context
 						      caller_per_cu);
     scoped_restore save_obj_addr = make_scoped_restore (&this->obj_address,
 							(CORE_ADDR) 0);
+    scoped_restore save_per_objfile = make_scoped_restore (&this->per_objfile,
+							   caller_per_objfile);

     scoped_restore save_arch = make_scoped_restore (&this->gdbarch);
     this->gdbarch = this->per_objfile->objfile->arch ();
     scoped_restore save_addr_size = make_scoped_restore (&this->addr_size);
-    this->addr_size = per_cu->addr_size ();
+    this->addr_size = this->per_cu->addr_size ();

     this->eval (data_src, size);
   }
-- 
2.26.2


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

* Re: [PATCH v2 28/42] Remove dwarf2_per_cu_data::objfile ()
  2020-05-28 15:33                 ` Simon Marchi
@ 2020-05-28 16:24                   ` Christian Biesinger
  2020-05-28 16:52                     ` Simon Marchi
  0 siblings, 1 reply; 92+ messages in thread
From: Christian Biesinger @ 2020-05-28 16:24 UTC (permalink / raw)
  To: Simon Marchi; +Cc: Tom de Vries, Simon Marchi, gdb-patches

On Thu, May 28, 2020 at 10:33 AM Simon Marchi <simark@simark.ca> wrote:
>
> On 2020-05-28 9:05 a.m., Tom de Vries wrote:
> > Hi,
> >
> > thanks for looking into this.
> >
> > I tried out the patch, and it fixes all regressions for me.
> >
> > Thanks,
> > - Tom
>
> Thanks, I pushed it with the following commit message.

Maybe add a comment describing this case, so that future developers
looking at the code know why the two objfiles can be different?

> From 44486dcf19b62708ad49bbb6094e065a223dea99 Mon Sep 17 00:00:00 2001
> From: Simon Marchi <simon.marchi@efficios.com>
> Date: Thu, 28 May 2020 11:30:11 -0400
> Subject: [PATCH] gdb: use caller objfile in
>  dwarf_evaluate_loc_desc::push_dwarf_reg_entry_value
>
> In commit
>
>     89b07335fe ("Add dwarf2_per_objfile to dwarf_expr_context and dwarf2_frame_cache")
>
> I replaced the offset property of dwarf_expr_context by a per_objfile
> property (since we can get the text offset from the objfile).  The
> previous code in dwarf_evaluate_loc_desc::push_dwarf_reg_entry_value
> (dwarf_evaluate_loc_desc derives from dwarf_expr_context) did
> temporarily override the offset property while evaluating a DWARF
> sub-expression.  I speculated that this sub-expression always came from
> the same objfile as the outer expression, so I didn't see the need to
> temporarily override the per_objfile property in the new code.  A later
> commit:
>
>     9f47c70716 ("Remove dwarf2_per_cu_data::objfile ()")
>
> added the following assertion to verify this:
>
>     gdb_assert (this->per_objfile == caller_per_objfile);
>
> It turns out that this is not true.  Call sites can refer to function in
> another objfile, and therefore the caller's objfile can be different
> from the callee's objfile.  This can happen when the call site DIE in the
> DWARF represents a function call done through a function pointer.  The
> DIE can't describe statically which function is being called, since it's
> variable and not known at compile time.  Instead, it provides an
> expression that evaluates to the address of the function being called.
> In this case, the called function can very well be in a separate
> objfile.
>
> Fix this by overriding the per_objfile property while evaluating the
> sub-expression.
>
> This was exposed by the gdb.base/catch-load.exp test failing on openSUSE
> Tumbleweed with the glibc debug info installed.  It was also reported to
> fail on Fedora.
>
> When I investigated the problem, the particular call site on which we
> did hit the assert was coming from this DIE, in
> /usr/lib/debug/lib64/libc-2.31.so-2.31-5.1.x86_64.debug on openSUSE
> Tumbleweed:
>
>     0x0091aa10:     DW_TAG_GNU_call_site
>                       DW_AT_low_pc [DW_FORM_addr]   (0x00000000001398e0)
>                       DW_AT_GNU_call_site_target [DW_FORM_exprloc]  (DW_OP_fbreg -272, DW_OP_deref)
>                       DW_AT_sibling [DW_FORM_ref4]  (0x0091aa2b)
>
> And for you curious out there, this call site is found in this function:
>
>     0x0091a91d:   DW_TAG_subprogram
>                     DW_AT_external [DW_FORM_flag_present]   (true)
>                     DW_AT_name [DW_FORM_strp]       ("_dl_catch_exception")
>                     DW_AT_decl_file [DW_FORM_data1] ("/usr/src/debug/glibc-2.31-5.1.x86_64/elf/dl-error-skeleton.c")
>                     ...
>
> Which is a function that indeed uses a function pointer.
>
> gdb/ChangeLog:
>
>         * dwarf2/loc.c (class dwarf_evaluate_loc_desc)
>         <push_dwarf_reg_entry_value>: Remove assert.  Override
>         per_objfile with caller_per_objfile.
>
> Change-Id: Ib227d767ce525c10607ab6621a373aaae982c67a
> ---
>  gdb/ChangeLog    | 6 ++++++
>  gdb/dwarf2/loc.c | 6 +++---
>  2 files changed, 9 insertions(+), 3 deletions(-)
>
> diff --git a/gdb/ChangeLog b/gdb/ChangeLog
> index 593ff01cc9d0..e5b4019dd646 100644
> --- a/gdb/ChangeLog
> +++ b/gdb/ChangeLog
> @@ -1,3 +1,9 @@
> +2020-05-28  Simon Marchi  <simon.marchi@efficios.com>
> +
> +       * dwarf2/loc.c (class dwarf_evaluate_loc_desc)
> +       <push_dwarf_reg_entry_value>: Remove assert.  Override
> +       per_objfile with caller_per_objfile.
> +
>  2020-05-28  Tom de Vries  <tdevries@suse.de>
>
>         * dwarf2/read.c (dw2_symtab_iter_next, dw2_expand_marked_cus): Limit
> diff --git a/gdb/dwarf2/loc.c b/gdb/dwarf2/loc.c
> index 7953361adeed..1aab1a4f51bc 100644
> --- a/gdb/dwarf2/loc.c
> +++ b/gdb/dwarf2/loc.c
> @@ -726,8 +726,6 @@ class dwarf_evaluate_loc_desc : public dwarf_expr_context
>      data_src = deref_size == -1 ? parameter->value : parameter->data_value;
>      size = deref_size == -1 ? parameter->value_size : parameter->data_value_size;
>
> -    gdb_assert (this->per_objfile == caller_per_objfile);
> -
>      /* DEREF_SIZE size is not verified here.  */
>      if (data_src == NULL)
>        throw_error (NO_ENTRY_VALUE_ERROR,
> @@ -739,11 +737,13 @@ class dwarf_evaluate_loc_desc : public dwarf_expr_context
>                                                       caller_per_cu);
>      scoped_restore save_obj_addr = make_scoped_restore (&this->obj_address,
>                                                         (CORE_ADDR) 0);
> +    scoped_restore save_per_objfile = make_scoped_restore (&this->per_objfile,
> +                                                          caller_per_objfile);
>
>      scoped_restore save_arch = make_scoped_restore (&this->gdbarch);
>      this->gdbarch = this->per_objfile->objfile->arch ();
>      scoped_restore save_addr_size = make_scoped_restore (&this->addr_size);
> -    this->addr_size = per_cu->addr_size ();
> +    this->addr_size = this->per_cu->addr_size ();
>
>      this->eval (data_src, size);
>    }
> --
> 2.26.2
>

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

* Re: [PATCH v2 28/42] Remove dwarf2_per_cu_data::objfile ()
  2020-05-28 16:24                   ` Christian Biesinger
@ 2020-05-28 16:52                     ` Simon Marchi
  2020-05-28 19:49                       ` Simon Marchi
  0 siblings, 1 reply; 92+ messages in thread
From: Simon Marchi @ 2020-05-28 16:52 UTC (permalink / raw)
  To: Christian Biesinger; +Cc: Tom de Vries, Simon Marchi, gdb-patches

On 2020-05-28 12:24 p.m., Christian Biesinger wrote:
> On Thu, May 28, 2020 at 10:33 AM Simon Marchi <simark@simark.ca> wrote:
>>
>> On 2020-05-28 9:05 a.m., Tom de Vries wrote:
>>> Hi,
>>>
>>> thanks for looking into this.
>>>
>>> I tried out the patch, and it fixes all regressions for me.
>>>
>>> Thanks,
>>> - Tom
>>
>> Thanks, I pushed it with the following commit message.
> 
> Maybe add a comment describing this case, so that future developers
> looking at the code know why the two objfiles can be different?

I am the first one to ask others to comment their code and not assume that everybody
is a domain expert, so yes :)

I would add this:

From 54c8c8f45b2196538a6c87c4cc7d498a8a5ade36 Mon Sep 17 00:00:00 2001
From: Simon Marchi <simon.marchi@polymtl.ca>
Date: Thu, 28 May 2020 12:38:03 -0400
Subject: [PATCH] gdb: add comment in
 dwarf_evaluate_loc_desc::push_dwarf_reg_entry_value

Add a comment to clarify why we temporarily override some of the
context's fields, and especially the per_objfile field.  A longer
explanation can be found in this previous commit

    44486dcf19b ("gdb: use caller objfile in dwarf_evaluate_loc_desc::push_dwarf_reg_entry_value")

gdb/ChangeLog:

	* dwarf2/loc.c (class dwarf_evaluate_loc_desc)
	<push_dwarf_reg_entry_value>: Add comment.

Change-Id: I60c6e1062799f729b30a9db78bcb6448783324b4
---
 gdb/dwarf2/loc.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/gdb/dwarf2/loc.c b/gdb/dwarf2/loc.c
index 1aab1a4f51bc..400bb4d16fc7 100644
--- a/gdb/dwarf2/loc.c
+++ b/gdb/dwarf2/loc.c
@@ -731,6 +731,12 @@ class dwarf_evaluate_loc_desc : public dwarf_expr_context
       throw_error (NO_ENTRY_VALUE_ERROR,
 		   _("Cannot resolve DW_AT_call_data_value"));

+    /* We are about to evaluate an expression in the context of the caller
+       of the current frame.  This evaluation context may be different from
+       the current (callee's) context), so temporarily set the caller's context.
+
+       It is possible for the caller to be from a different objfile from the
+       callee if the call is made through a function pointer.  */
     scoped_restore save_frame = make_scoped_restore (&this->frame,
 						     caller_frame);
     scoped_restore save_per_cu = make_scoped_restore (&this->per_cu,
-- 
2.26.2


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

* Re: [PATCH v2 28/42] Remove dwarf2_per_cu_data::objfile ()
  2020-05-28 16:52                     ` Simon Marchi
@ 2020-05-28 19:49                       ` Simon Marchi
  0 siblings, 0 replies; 92+ messages in thread
From: Simon Marchi @ 2020-05-28 19:49 UTC (permalink / raw)
  To: Christian Biesinger; +Cc: Simon Marchi, gdb-patches

On 2020-05-28 12:52 p.m., Simon Marchi wrote:
> On 2020-05-28 12:24 p.m., Christian Biesinger wrote:
>> On Thu, May 28, 2020 at 10:33 AM Simon Marchi <simark@simark.ca> wrote:
>>>
>>> On 2020-05-28 9:05 a.m., Tom de Vries wrote:
>>>> Hi,
>>>>
>>>> thanks for looking into this.
>>>>
>>>> I tried out the patch, and it fixes all regressions for me.
>>>>
>>>> Thanks,
>>>> - Tom
>>>
>>> Thanks, I pushed it with the following commit message.
>>
>> Maybe add a comment describing this case, so that future developers
>> looking at the code know why the two objfiles can be different?
> 
> I am the first one to ask others to comment their code and not assume that everybody
> is a domain expert, so yes :)
> 
> I would add this:
> 
> From 54c8c8f45b2196538a6c87c4cc7d498a8a5ade36 Mon Sep 17 00:00:00 2001
> From: Simon Marchi <simon.marchi@polymtl.ca>
> Date: Thu, 28 May 2020 12:38:03 -0400
> Subject: [PATCH] gdb: add comment in
>  dwarf_evaluate_loc_desc::push_dwarf_reg_entry_value
> 
> Add a comment to clarify why we temporarily override some of the
> context's fields, and especially the per_objfile field.  A longer
> explanation can be found in this previous commit
> 
>     44486dcf19b ("gdb: use caller objfile in dwarf_evaluate_loc_desc::push_dwarf_reg_entry_value")
> 
> gdb/ChangeLog:
> 
> 	* dwarf2/loc.c (class dwarf_evaluate_loc_desc)
> 	<push_dwarf_reg_entry_value>: Add comment.
> 
> Change-Id: I60c6e1062799f729b30a9db78bcb6448783324b4
> ---
>  gdb/dwarf2/loc.c | 6 ++++++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/gdb/dwarf2/loc.c b/gdb/dwarf2/loc.c
> index 1aab1a4f51bc..400bb4d16fc7 100644
> --- a/gdb/dwarf2/loc.c
> +++ b/gdb/dwarf2/loc.c
> @@ -731,6 +731,12 @@ class dwarf_evaluate_loc_desc : public dwarf_expr_context
>        throw_error (NO_ENTRY_VALUE_ERROR,
>  		   _("Cannot resolve DW_AT_call_data_value"));
> 
> +    /* We are about to evaluate an expression in the context of the caller
> +       of the current frame.  This evaluation context may be different from
> +       the current (callee's) context), so temporarily set the caller's context.
> +
> +       It is possible for the caller to be from a different objfile from the
> +       callee if the call is made through a function pointer.  */
>      scoped_restore save_frame = make_scoped_restore (&this->frame,
>  						     caller_frame);
>      scoped_restore save_per_cu = make_scoped_restore (&this->per_cu,
> -- 
> 2.26.2
> 

I pushed this.

Simon

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

* Re: [PATCH v2 00/42] Share DWARF partial symtabs between objfiles
  2020-05-27 15:51                 ` Simon Marchi
@ 2020-05-29 10:23                   ` Tom de Vries
  2020-05-29 12:55                     ` Tom de Vries
  2020-05-31  4:16                     ` Simon Marchi
  0 siblings, 2 replies; 92+ messages in thread
From: Tom de Vries @ 2020-05-29 10:23 UTC (permalink / raw)
  To: Simon Marchi, Pedro Alves, Simon Marchi, Tom Tromey,
	Simon Marchi via Gdb-patches

On 27-05-2020 17:51, Simon Marchi wrote:
> On 2020-05-27 10:53 a.m., Simon Marchi wrote:
>> I added another patch to the series, see here:
>>
>>   https://sourceware.org/pipermail/gdb-patches/2020-May/169065.html
>>
>> The gdb.base/infcall-nested-structs-c.exp / gdb.base/infcall-nested-structs-c++.exp failures
>> just appeared to be intermittent failures in the end.  So I think that with this last patch,
>> the series would be good to go.
>>
>> Simon
>>
> 
> All right, the series is now pushed!  With such a change, I do expect some things to break,
> please let me know if you see some unexpected behavior chgange following this.
> 

Hi Simon,

I'm working on enabling the .gdb_index for ada, and after rebasing that
patch series to recent master I ran into a failure with target board
cc-with-gdb-index I thought I hadn't seen before, in
gdb.ada/mi_catch_assert.exp and a few more similar ada test-case.

I managed to minimize and de-mi the failure to:
...
$ cat cmd.gdb
file
/data/gdb_versions/devel/build/gdb/testsuite/outputs/gdb.ada/mi_catch_assert/bla
file
/data/gdb_versions/devel/build/gdb/testsuite/outputs/gdb.ada/mi_catch_assert/bla
tbreak main
run
catch assert
cond 2 Global_Var = 2
continue
$ gdb -batch -ex "set sysroot" -x=cmd.gdb
Temporary breakpoint 1 at 0x401f39: file
/data/gdb_versions/devel/build/gdb/testsuite/outputs/gdb.ada/mi_catch_assert/b~bla.adb,
line 132.

Temporary breakpoint 1, main (argc=1, argv=0x7fffffffdb98,
envp=0x7fffffffdba8) at
/data/gdb_versions/devel/build/gdb/testsuite/outputs/gdb.ada/mi_catch_assert/b~bla.adb:132
132           Ensure_Reference : aliased System.Address :=
Ada_Main_Program_Name'Address;
Catchpoint 2: failed Ada assertions

Catchpoint 2, failed assertion at <__gnat_debug_raise_assert_failure> ()
at s-excdeb.adb:64
64      s-excdeb.adb: Bestand of map bestaat niet.
...
while the expected output is:
...
Catchpoint 2, failed assertion at 0x000000000040200a in bla () at
/data/gdb_versions/devel/binutils-gdb.git/gdb/testsuite/gdb.ada/mi_catch_assert/bla.adb:32
32            pragma Assert (Global_Var = 1, "Error #2"); -- STOP
...

Seeing the repetition of file command in the cmd.gdb file (and how
commenting out one of them made the test pass), I started suspecting
this patch series, and wondered if I could reproduce the same or similar
problems on master using a test-suite hack:
...
diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp
index 444cea01c3..fa2a999525 100644
--- a/gdb/testsuite/lib/gdb.exp
+++ b/gdb/testsuite/lib/gdb.exp
@@ -4823,7 +4823,12 @@ proc gdb_load_shlib { file } {
 #
 proc gdb_load { arg } {
     if { $arg != "" } {
-       return [gdb_file_cmd $arg]
+       set res [gdb_file_cmd $arg]
+       if { $res != 0 } {
+           return $res
+       }
+       set res [gdb_file_cmd $arg]
+       return $res
     }
     return 0
 }
...

And indeed, quite a few failures showed up.  I picked one:
gdb.base/langs.exp.

So, on master, after this patch series, with target board
cc-with-gdb-index, we have:
...
Running /data/gdb_versions/devel/src/gdb/testsuite/gdb.base/langs.exp ...
FAIL: gdb.base/langs.exp: up to foo in langs.exp
FAIL: gdb.base/langs.exp: show language at foo in langs.exp
FAIL: gdb.base/langs.exp: up to cppsub_ in langs.exp
FAIL: gdb.base/langs.exp: show language at cppsub_ in langs.exp
FAIL: gdb.base/langs.exp: up to fsub in langs.exp
FAIL: gdb.base/langs.exp: show language at fsub in langs.exp

                === gdb Summary ===

# of expected passes            10
# of unexpected failures        6
...
while with native we have:
...
Running /data/gdb_versions/devel/src/gdb/testsuite/gdb.base/langs.exp ...

                === gdb Summary ===

# of expected passes            16
...

Before this patch series, the test-case passes without any FAILs with
target board cc-with-gdb-index.

Thanks,
- Tom

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

* Re: [PATCH v2 00/42] Share DWARF partial symtabs between objfiles
  2020-05-29 10:23                   ` Tom de Vries
@ 2020-05-29 12:55                     ` Tom de Vries
  2020-05-31  4:16                     ` Simon Marchi
  1 sibling, 0 replies; 92+ messages in thread
From: Tom de Vries @ 2020-05-29 12:55 UTC (permalink / raw)
  To: Simon Marchi, Pedro Alves, Simon Marchi, Tom Tromey,
	Simon Marchi via Gdb-patches

On 29-05-2020 12:23, Tom de Vries wrote:
> On 27-05-2020 17:51, Simon Marchi wrote:
>> On 2020-05-27 10:53 a.m., Simon Marchi wrote:
>>> I added another patch to the series, see here:
>>>
>>>   https://sourceware.org/pipermail/gdb-patches/2020-May/169065.html
>>>
>>> The gdb.base/infcall-nested-structs-c.exp / gdb.base/infcall-nested-structs-c++.exp failures
>>> just appeared to be intermittent failures in the end.  So I think that with this last patch,
>>> the series would be good to go.
>>>
>>> Simon
>>>
>>
>> All right, the series is now pushed!  With such a change, I do expect some things to break,
>> please let me know if you see some unexpected behavior chgange following this.
>>
> 
> Hi Simon,
> 
> I'm working on enabling the .gdb_index for ada, and after rebasing that
> patch series to recent master I ran into a failure with target board
> cc-with-gdb-index I thought I hadn't seen before, in
> gdb.ada/mi_catch_assert.exp and a few more similar ada test-case.
> 
> I managed to minimize and de-mi the failure to:
> ...
> $ cat cmd.gdb
> file
> /data/gdb_versions/devel/build/gdb/testsuite/outputs/gdb.ada/mi_catch_assert/bla
> file
> /data/gdb_versions/devel/build/gdb/testsuite/outputs/gdb.ada/mi_catch_assert/bla
> tbreak main
> run
> catch assert
> cond 2 Global_Var = 2
> continue
> $ gdb -batch -ex "set sysroot" -x=cmd.gdb
> Temporary breakpoint 1 at 0x401f39: file
> /data/gdb_versions/devel/build/gdb/testsuite/outputs/gdb.ada/mi_catch_assert/b~bla.adb,
> line 132.
> 
> Temporary breakpoint 1, main (argc=1, argv=0x7fffffffdb98,
> envp=0x7fffffffdba8) at
> /data/gdb_versions/devel/build/gdb/testsuite/outputs/gdb.ada/mi_catch_assert/b~bla.adb:132
> 132           Ensure_Reference : aliased System.Address :=
> Ada_Main_Program_Name'Address;
> Catchpoint 2: failed Ada assertions
> 
> Catchpoint 2, failed assertion at <__gnat_debug_raise_assert_failure> ()
> at s-excdeb.adb:64
> 64      s-excdeb.adb: Bestand of map bestaat niet.
> ...
> while the expected output is:
> ...
> Catchpoint 2, failed assertion at 0x000000000040200a in bla () at
> /data/gdb_versions/devel/binutils-gdb.git/gdb/testsuite/gdb.ada/mi_catch_assert/bla.adb:32
> 32            pragma Assert (Global_Var = 1, "Error #2"); -- STOP
> ...
> 
> Seeing the repetition of file command in the cmd.gdb file (and how
> commenting out one of them made the test pass), I started suspecting
> this patch series, and wondered if I could reproduce the same or similar
> problems on master using a test-suite hack:
> ...
> diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp
> index 444cea01c3..fa2a999525 100644
> --- a/gdb/testsuite/lib/gdb.exp
> +++ b/gdb/testsuite/lib/gdb.exp
> @@ -4823,7 +4823,12 @@ proc gdb_load_shlib { file } {
>  #
>  proc gdb_load { arg } {
>      if { $arg != "" } {
> -       return [gdb_file_cmd $arg]
> +       set res [gdb_file_cmd $arg]
> +       if { $res != 0 } {
> +           return $res
> +       }
> +       set res [gdb_file_cmd $arg]
> +       return $res
>      }
>      return 0
>  }
> ...
> 
> And indeed, quite a few failures showed up.  I picked one:
> gdb.base/langs.exp.
> 
> So, on master, after this patch series, with target board
> cc-with-gdb-index, we have:
> ...
> Running /data/gdb_versions/devel/src/gdb/testsuite/gdb.base/langs.exp ...
> FAIL: gdb.base/langs.exp: up to foo in langs.exp
> FAIL: gdb.base/langs.exp: show language at foo in langs.exp
> FAIL: gdb.base/langs.exp: up to cppsub_ in langs.exp
> FAIL: gdb.base/langs.exp: show language at cppsub_ in langs.exp
> FAIL: gdb.base/langs.exp: up to fsub in langs.exp
> FAIL: gdb.base/langs.exp: show language at fsub in langs.exp
> 
>                 === gdb Summary ===
> 
> # of expected passes            10
> # of unexpected failures        6
> ...
> while with native we have:
> ...
> Running /data/gdb_versions/devel/src/gdb/testsuite/gdb.base/langs.exp ...
> 
>                 === gdb Summary ===
> 
> # of expected passes            16
> ...
> 
> Before this patch series, the test-case passes without any FAILs with
> target board cc-with-gdb-index.

With the same test-suite hack in place, we have on master with native:
...
Running
/data/gdb_versions/devel/src/gdb/testsuite/gdb.base/index-cache.exp ...
ERROR: Couldn't load
/data/gdb_versions/devel/build/gdb/testsuite/outputs/gdb.base/index-cache/index-cache,
other program already loaded (timeout).
FAIL: gdb.base/index-cache.exp: test_cache_enabled_miss: check
index-cache stats (GDB internal error)
ERROR: Couldn't load
/data/gdb_versions/devel/build/gdb/testsuite/outputs/gdb.base/index-cache/index-cache,
other program already loaded (timeout).
...

First sign of trouble, an assert:
...
(gdb) kill^M
The program is not being run.^M
(gdb) file
/data/gdb_versions/devel/build/gdb/testsuite/outputs/gdb.base/index-cache/index-cache^M
Reading symbols from
/data/gdb_versions/devel/build/gdb/testsuite/outputs/gdb.base/index-cache/index-cache...^M
(gdb) kill^M
The program is not being run.^M
(gdb) file
/data/gdb_versions/devel/build/gdb/testsuite/outputs/gdb.base/index-cache/index-cache^M
Load new symbol table from
"/data/gdb_versions/devel/build/gdb/testsuite/outputs/gdb.base/index-cache/index-cache"?
(y or n) y^M
Reading symbols from
/data/gdb_versions/devel/build/gdb/testsuite/outputs/gdb.base/index-cache/index-cache...^M
/data/gdb_versions/devel/src/gdb/dwarf2/read.c:2546: internal-error:
void create_cus_from_index(dwarf2_per_bfd*, const gdb_byte*,
offset_type, const gdb_byte*, offset_type): Assertion
`per_bfd->all_comp_units.empty ()' failed.^M
...

Thanks,
- Tom

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

* Re: [PATCH v2 00/42] Share DWARF partial symtabs between objfiles
  2020-05-29 10:23                   ` Tom de Vries
  2020-05-29 12:55                     ` Tom de Vries
@ 2020-05-31  4:16                     ` Simon Marchi
  2020-05-31 14:22                       ` Tom de Vries
  1 sibling, 1 reply; 92+ messages in thread
From: Simon Marchi @ 2020-05-31  4:16 UTC (permalink / raw)
  To: Tom de Vries, Pedro Alves, Simon Marchi, Tom Tromey,
	Simon Marchi via Gdb-patches

On 2020-05-29 6:23 a.m., Tom de Vries wrote:
> Seeing the repetition of file command in the cmd.gdb file (and how
> commenting out one of them made the test pass), I started suspecting
> this patch series, and wondered if I could reproduce the same or similar
> problems on master using a test-suite hack:
> ...
> diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp
> index 444cea01c3..fa2a999525 100644
> --- a/gdb/testsuite/lib/gdb.exp
> +++ b/gdb/testsuite/lib/gdb.exp
> @@ -4823,7 +4823,12 @@ proc gdb_load_shlib { file } {
>  #
>  proc gdb_load { arg } {
>      if { $arg != "" } {
> -       return [gdb_file_cmd $arg]
> +       set res [gdb_file_cmd $arg]
> +       if { $res != 0 } {
> +           return $res
> +       }
> +       set res [gdb_file_cmd $arg]
> +       return $res
>      }
>      return 0
>  }
> ...
> 
> And indeed, quite a few failures showed up.  I picked one:
> gdb.base/langs.exp.
> 
> So, on master, after this patch series, with target board
> cc-with-gdb-index, we have:
> ...
> Running /data/gdb_versions/devel/src/gdb/testsuite/gdb.base/langs.exp ...
> FAIL: gdb.base/langs.exp: up to foo in langs.exp
> FAIL: gdb.base/langs.exp: show language at foo in langs.exp
> FAIL: gdb.base/langs.exp: up to cppsub_ in langs.exp
> FAIL: gdb.base/langs.exp: show language at cppsub_ in langs.exp
> FAIL: gdb.base/langs.exp: up to fsub in langs.exp
> FAIL: gdb.base/langs.exp: show language at fsub in langs.exp

I'm looking at this failure right now because it's easier to tackle.  I think I
see the problem.  In the index case, we never set per_bfd->partial_symtabs, like
we do at the end of dwarf2_build_psymtabs for the non-index case.  Then, for the
second objfile using the same BFD, we never take that per_bfd->partial_symtabs
to install it in objfile->partial_symtabs, like we do in the beginning of
dwarf2_build_psymtabs.  So objfile->partial_symtabs->psymtabs_addrmap stays NULL,
and all pc -> symbol lookups fail.

See this proof of concept fix, which sets per_bfd->partial_symtabs in
dwarf2_read_gdb_index (when parsing the first objfile), and reads it back
in dwarf2_initialize_objfile (when parsing the second objfile).

The same will need to be done for debug_names.


From d5334c2c61408c4cd815eb54898f442502d5fd66 Mon Sep 17 00:00:00 2001
From: Simon Marchi <simon.marchi@efficios.com>
Date: Sun, 31 May 2020 00:10:33 -0400
Subject: [PATCH] the fix

---
 gdb/dwarf2/read.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 4724738363b..85fd41745f4 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -3068,6 +3068,7 @@ dwarf2_read_gdb_index
   offset_type cu_list_elements, types_list_elements, dwz_list_elements = 0;
   struct dwz_file *dwz;
   struct objfile *objfile = per_objfile->objfile;
+  dwarf2_per_bfd *per_bfd = per_objfile->per_bfd;

   gdb::array_view<const gdb_byte> main_index_contents
     = get_gdb_index_contents (objfile, per_objfile->per_bfd);
@@ -3138,6 +3139,9 @@ dwarf2_read_gdb_index
   per_objfile->per_bfd->quick_file_names_table =
     create_quick_file_names_table (per_objfile->per_bfd->all_comp_units.size ());

+  gdb_assert (per_bfd->partial_symtabs == nullptr);
+  per_bfd->partial_symtabs = objfile->partial_symtabs;
+
   return 1;
 }

@@ -5981,6 +5985,7 @@ dwarf2_initialize_objfile (struct objfile *objfile, dw_index_kind *index_kind)
   if (per_bfd->index_table != nullptr)
     {
       *index_kind = dw_index_kind::GDB_INDEX;
+      per_objfile->objfile->partial_symtabs = per_bfd->partial_symtabs;
       per_objfile->resize_symtabs ();
       return true;
     }
-- 
2.26.2

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

* Re: [PATCH v2 00/42] Share DWARF partial symtabs between objfiles
  2020-05-31  4:16                     ` Simon Marchi
@ 2020-05-31 14:22                       ` Tom de Vries
  2020-06-02 21:27                         ` Simon Marchi
  0 siblings, 1 reply; 92+ messages in thread
From: Tom de Vries @ 2020-05-31 14:22 UTC (permalink / raw)
  To: Simon Marchi, Pedro Alves, Simon Marchi, Tom Tromey,
	Simon Marchi via Gdb-patches

On 31-05-2020 06:16, Simon Marchi wrote:
> See this proof of concept fix, which sets per_bfd->partial_symtabs in
> dwarf2_read_gdb_index (when parsing the first objfile), and reads it back
> in dwarf2_initialize_objfile (when parsing the second objfile).

I've tested this patch with the test-suite file-twice hack and target
board cc-with-gdb-index, and it fixes all regressions.

Also, I've tested it with my ada .gdb_index patch series, and also there
it fixes the regressions.

Thanks,
- Tom

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

* Re: [PATCH v2 00/42] Share DWARF partial symtabs between objfiles
  2020-05-31 14:22                       ` Tom de Vries
@ 2020-06-02 21:27                         ` Simon Marchi
  2020-06-04 17:55                           ` Tom de Vries
  0 siblings, 1 reply; 92+ messages in thread
From: Simon Marchi @ 2020-06-02 21:27 UTC (permalink / raw)
  To: Tom de Vries, Simon Marchi, Pedro Alves, Tom Tromey,
	Simon Marchi via Gdb-patches

On 2020-05-31 10:22 a.m., Tom de Vries wrote:
> On 31-05-2020 06:16, Simon Marchi wrote:
>> See this proof of concept fix, which sets per_bfd->partial_symtabs in
>> dwarf2_read_gdb_index (when parsing the first objfile), and reads it back
>> in dwarf2_initialize_objfile (when parsing the second objfile).
> 
> I've tested this patch with the test-suite file-twice hack and target
> board cc-with-gdb-index, and it fixes all regressions.
> 
> Also, I've tested it with my ada .gdb_index patch series, and also there
> it fixes the regressions.
> 
> Thanks,
> - Tom
> 

Ok, thanks for testing.  Here's a somewhat more complete patch.


From 0b342d014459b86027aa9c877233caccac8d9446 Mon Sep 17 00:00:00 2001
From: Simon Marchi <simon.marchi@efficios.com>
Date: Sun, 31 May 2020 00:10:33 -0400
Subject: [PATCH] gdb: really share partial symtabs when using .gdb_index or
 .debug_names

Fix/follow-up to commit 17ee85fc2a ("Share DWARF partial symtabs").

In the non-index case, where GDB builds partial symbols from scratch,
two objfiles around the same BFD correctly share partial symtabs.  The
first objfile, which has to do all the work, saves a reference to the
created partial symtabs in the shared per_bfd object (at the end of
dwarf2_build_psymtabs).  The second objfile, when it reaches
dwarf2_build_psymtabs, sees that there are already partial symtabs built
for this BFD and just uses it.

However, that commit missed implementing the same sharing for cases
where GDB uses .gdb_index or .debug_names to build the partial symtabs.

This patch fixes it by having the first objfile to use the BFD set
per_bfd->partial_symtabs at the end of dwarf2_read_gdb_index /
dwarf2_read_debug_names.  For the subsequent objfiles using that BFD,
the partial symtabs are then picked up in dwarf2_initialize_objfile.

This patch adds a test that mimics how the issue was originally
triggered:

  1. Load the test file twice, such that the second objfile re-uses the
     per_bfd object created for the first objfile.
  2. Run to some point where in the backtrace there is a frame for a
     function that's in a CU that's not yet read in.
  3. Check that this frame's information is complete in the "backtrace"
     output.

Step 2 requires an address -> symbol lookup which uses the addrmap at
objfile->partial_symtabs->psymtabs_addrmap.  If the
objfile->partial_symtabs link is not properly setup (as is the case
before this patch), the symbol for that frame won't be found and we'll
get a frame with incomplete information.

The test fails without the fix when using boards "cc-with-gdb-index" and
"cc-with-debug-names".

gdb/ChangeLog:

	* dwarf2/read.c (dwarf2_read_gdb_index): Save partial_symtabs in
	the per_bfd object.
	(dwarf2_read_debug_names): Likewise.
	(dwarf2_initialize_objfile): Use partial_symtabs from per_bfd
	object when re-using a per_bfd object with an index.

gdb/testsuite/ChangeLog:

	* gdb.dwarf2/share-psymtabs-bt.exp: New file.
	* gdb.dwarf2/share-psymtabs-bt.c: New file.
	* gdb.dwarf2/share-psymtabs-bt-2.c: New file.

Change-Id: Ibb26210e2dfc03b80ba9fa56b875ba4cc58c0352
---
 gdb/dwarf2/read.c                            | 56 +++++++++++--------
 gdb/testsuite/gdb.base/share-psymtabs-bt-2.c | 24 +++++++++
 gdb/testsuite/gdb.base/share-psymtabs-bt.c   | 29 ++++++++++
 gdb/testsuite/gdb.base/share-psymtabs-bt.exp | 57 ++++++++++++++++++++
 4 files changed, 144 insertions(+), 22 deletions(-)
 create mode 100644 gdb/testsuite/gdb.base/share-psymtabs-bt-2.c
 create mode 100644 gdb/testsuite/gdb.base/share-psymtabs-bt.c
 create mode 100644 gdb/testsuite/gdb.base/share-psymtabs-bt.exp

diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index e6566f9649f8..f04bdd1ce58e 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -3068,9 +3068,10 @@ dwarf2_read_gdb_index
   offset_type cu_list_elements, types_list_elements, dwz_list_elements = 0;
   struct dwz_file *dwz;
   struct objfile *objfile = per_objfile->objfile;
+  dwarf2_per_bfd *per_bfd = per_objfile->per_bfd;

   gdb::array_view<const gdb_byte> main_index_contents
-    = get_gdb_index_contents (objfile, per_objfile->per_bfd);
+    = get_gdb_index_contents (objfile, per_bfd);

   if (main_index_contents.empty ())
     return 0;
@@ -3089,7 +3090,7 @@ dwarf2_read_gdb_index

   /* If there is a .dwz file, read it so we can get its CU list as
      well.  */
-  dwz = dwarf2_get_dwz_file (per_objfile->per_bfd);
+  dwz = dwarf2_get_dwz_file (per_bfd);
   if (dwz != NULL)
     {
       struct mapped_index dwz_map;
@@ -3114,29 +3115,33 @@ dwarf2_read_gdb_index
 	}
     }

-  create_cus_from_index (per_objfile->per_bfd, cu_list, cu_list_elements,
-			 dwz_list, dwz_list_elements);
+  create_cus_from_index (per_bfd, cu_list, cu_list_elements, dwz_list,
+			 dwz_list_elements);

   if (types_list_elements)
     {
       /* We can only handle a single .debug_types when we have an
 	 index.  */
-      if (per_objfile->per_bfd->types.size () != 1)
+      if (per_bfd->types.size () != 1)
 	return 0;

-      dwarf2_section_info *section = &per_objfile->per_bfd->types[0];
+      dwarf2_section_info *section = &per_bfd->types[0];

-      create_signatured_type_table_from_index (per_objfile->per_bfd,
-					       section, types_list,
+      create_signatured_type_table_from_index (per_bfd, section, types_list,
 					       types_list_elements);
     }

   create_addrmap_from_index (per_objfile, map.get ());

-  per_objfile->per_bfd->index_table = std::move (map);
-  per_objfile->per_bfd->using_index = 1;
-  per_objfile->per_bfd->quick_file_names_table =
-    create_quick_file_names_table (per_objfile->per_bfd->all_comp_units.size ());
+  per_bfd->index_table = std::move (map);
+  per_bfd->using_index = 1;
+  per_bfd->quick_file_names_table =
+    create_quick_file_names_table (per_bfd->all_comp_units.size ());
+
+  /* Save partial symtabs in the per_bfd object, for the benefit of subsequent
+     objfiles using the same BFD.  */
+  gdb_assert (per_bfd->partial_symtabs == nullptr);
+  per_bfd->partial_symtabs = objfile->partial_symtabs;

   return 1;
 }
@@ -5205,6 +5210,7 @@ dwarf2_read_debug_names (dwarf2_per_objfile *per_objfile)
   std::unique_ptr<mapped_debug_names> map (new mapped_debug_names);
   mapped_debug_names dwz_map;
   struct objfile *objfile = per_objfile->objfile;
+  dwarf2_per_bfd *per_bfd = per_objfile->per_bfd;

   if (!read_debug_names_from_section (objfile, objfile_name (objfile),
 				      &per_objfile->per_bfd->debug_names, *map))
@@ -5216,7 +5222,7 @@ dwarf2_read_debug_names (dwarf2_per_objfile *per_objfile)

   /* If there is a .dwz file, read it so we can get its CU list as
      well.  */
-  dwz_file *dwz = dwarf2_get_dwz_file (per_objfile->per_bfd);
+  dwz_file *dwz = dwarf2_get_dwz_file (per_bfd);
   if (dwz != NULL)
     {
       if (!read_debug_names_from_section (objfile,
@@ -5229,29 +5235,33 @@ dwarf2_read_debug_names (dwarf2_per_objfile *per_objfile)
 	}
     }

-  create_cus_from_debug_names (per_objfile->per_bfd, *map, dwz_map);
+  create_cus_from_debug_names (per_bfd, *map, dwz_map);

   if (map->tu_count != 0)
     {
       /* We can only handle a single .debug_types when we have an
 	 index.  */
-      if (per_objfile->per_bfd->types.size () != 1)
+      if (per_bfd->types.size () != 1)
 	return false;

-      dwarf2_section_info *section = &per_objfile->per_bfd->types[0];
+      dwarf2_section_info *section = &per_bfd->types[0];

       create_signatured_type_table_from_debug_names
-	(per_objfile, *map, section, &per_objfile->per_bfd->abbrev);
+	(per_objfile, *map, section, &per_bfd->abbrev);
     }

-  create_addrmap_from_aranges (per_objfile,
-			       &per_objfile->per_bfd->debug_aranges);
+  create_addrmap_from_aranges (per_objfile, &per_bfd->debug_aranges);

-  per_objfile->per_bfd->debug_names_table = std::move (map);
-  per_objfile->per_bfd->using_index = 1;
-  per_objfile->per_bfd->quick_file_names_table =
+  per_bfd->debug_names_table = std::move (map);
+  per_bfd->using_index = 1;
+  per_bfd->quick_file_names_table =
     create_quick_file_names_table (per_objfile->per_bfd->all_comp_units.size ());

+  /* Save partial symtabs in the per_bfd object, for the benefit of subsequent
+     objfiles using the same BFD.  */
+  gdb_assert (per_bfd->partial_symtabs == nullptr);
+  per_bfd->partial_symtabs = objfile->partial_symtabs;
+
   return true;
 }

@@ -5972,6 +5982,7 @@ dwarf2_initialize_objfile (struct objfile *objfile, dw_index_kind *index_kind)
   if (per_bfd->debug_names_table != nullptr)
     {
       *index_kind = dw_index_kind::DEBUG_NAMES;
+      per_objfile->objfile->partial_symtabs = per_bfd->partial_symtabs;
       per_objfile->resize_symtabs ();
       return true;
     }
@@ -5981,6 +5992,7 @@ dwarf2_initialize_objfile (struct objfile *objfile, dw_index_kind *index_kind)
   if (per_bfd->index_table != nullptr)
     {
       *index_kind = dw_index_kind::GDB_INDEX;
+      per_objfile->objfile->partial_symtabs = per_bfd->partial_symtabs;
       per_objfile->resize_symtabs ();
       return true;
     }
diff --git a/gdb/testsuite/gdb.base/share-psymtabs-bt-2.c b/gdb/testsuite/gdb.base/share-psymtabs-bt-2.c
new file mode 100644
index 000000000000..c713eb22693c
--- /dev/null
+++ b/gdb/testsuite/gdb.base/share-psymtabs-bt-2.c
@@ -0,0 +1,24 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2020 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/>.  */
+
+void bar (int x);
+
+void
+foo (int x)
+{
+  bar (x);
+}
diff --git a/gdb/testsuite/gdb.base/share-psymtabs-bt.c b/gdb/testsuite/gdb.base/share-psymtabs-bt.c
new file mode 100644
index 000000000000..97ad3457905b
--- /dev/null
+++ b/gdb/testsuite/gdb.base/share-psymtabs-bt.c
@@ -0,0 +1,29 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2020 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/>.  */
+
+void
+bar (int x)
+{}
+
+void foo (int x);
+
+int
+main (void)
+{
+  foo (12345);
+  return 0;
+}
diff --git a/gdb/testsuite/gdb.base/share-psymtabs-bt.exp b/gdb/testsuite/gdb.base/share-psymtabs-bt.exp
new file mode 100644
index 000000000000..f4ca58e30b96
--- /dev/null
+++ b/gdb/testsuite/gdb.base/share-psymtabs-bt.exp
@@ -0,0 +1,57 @@
+# Copyright 2020 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/>.
+
+# Test that a backtrace is shown correctly for an objfile that uses partial
+# symtabs created by another objfile sharing the same BFD.
+#
+# It mimics how a bug with psymtab sharing was initially found:
+#
+#  1. Load the test file twice, such that the second objfile re-uses the
+#     per_bfd object created for the first objfile.
+#  2. Run to some point where in the backtrace there is a frame for a
+#     function that's in a CU that's not yet read in.
+#  3. Check that this frame's information is complete in the "backtrace"
+#     output.
+
+standard_testfile share-psymtabs-bt.c share-psymtabs-bt-2.c
+
+set sources [list \
+    "${srcdir}/${subdir}/${srcfile}" \
+    "${srcdir}/${subdir}/${srcfile2}" \
+]
+
+if { [gdb_compile $sources $binfile executable {debug}] != "" } {
+    untested "failed to compile"
+    return -1
+}
+
+clean_restart $binfile
+
+# Load $binfile a second time.  The second created objfile will re-use the
+# partial symtabs created by the first one.
+if { [gdb_file_cmd $binfile] != 0 } {
+    fail "file command failed"
+    return -1
+}
+
+gdb_breakpoint "bar"
+if { ![runto "bar"] } {
+    fail "failed to run to bar"
+    return -1
+}
+
+# A buggy GDB would fail to find the full symbol associated to this frame's
+# address, so would just show "foo ()" (from the minimal symbol).
+gdb_test "bt" "foo \\(x=12345\\).*"
-- 
2.26.2


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

* Re: [PATCH v2 00/42] Share DWARF partial symtabs between objfiles
  2020-06-02 21:27                         ` Simon Marchi
@ 2020-06-04 17:55                           ` Tom de Vries
  2020-06-04 18:04                             ` Simon Marchi
  0 siblings, 1 reply; 92+ messages in thread
From: Tom de Vries @ 2020-06-04 17:55 UTC (permalink / raw)
  To: Simon Marchi, Simon Marchi, Pedro Alves, Tom Tromey,
	Simon Marchi via Gdb-patches

On 02-06-2020 23:27, Simon Marchi wrote:
> On 2020-05-31 10:22 a.m., Tom de Vries wrote:
>> On 31-05-2020 06:16, Simon Marchi wrote:
>>> See this proof of concept fix, which sets per_bfd->partial_symtabs in
>>> dwarf2_read_gdb_index (when parsing the first objfile), and reads it back
>>> in dwarf2_initialize_objfile (when parsing the second objfile).
>>
>> I've tested this patch with the test-suite file-twice hack and target
>> board cc-with-gdb-index, and it fixes all regressions.
>>
>> Also, I've tested it with my ada .gdb_index patch series, and also there
>> it fixes the regressions.
>>
>> Thanks,
>> - Tom
>>
> 
> Ok, thanks for testing.  Here's a somewhat more complete patch.
> 
> 
> From 0b342d014459b86027aa9c877233caccac8d9446 Mon Sep 17 00:00:00 2001
> From: Simon Marchi <simon.marchi@efficios.com>
> Date: Sun, 31 May 2020 00:10:33 -0400
> Subject: [PATCH] gdb: really share partial symtabs when using .gdb_index or
>  .debug_names
> 
> Fix/follow-up to commit 17ee85fc2a ("Share DWARF partial symtabs").
> 
> In the non-index case, where GDB builds partial symbols from scratch,
> two objfiles around the same BFD correctly share partial symtabs.  The
> first objfile, which has to do all the work, saves a reference to the
> created partial symtabs in the shared per_bfd object (at the end of
> dwarf2_build_psymtabs).  The second objfile, when it reaches
> dwarf2_build_psymtabs, sees that there are already partial symtabs built
> for this BFD and just uses it.
> 
> However, that commit missed implementing the same sharing for cases
> where GDB uses .gdb_index or .debug_names to build the partial symtabs.
> 
> This patch fixes it by having the first objfile to use the BFD set
> per_bfd->partial_symtabs at the end of dwarf2_read_gdb_index /
> dwarf2_read_debug_names.  For the subsequent objfiles using that BFD,
> the partial symtabs are then picked up in dwarf2_initialize_objfile.
> 
> This patch adds a test that mimics how the issue was originally
> triggered:
> 
>   1. Load the test file twice, such that the second objfile re-uses the
>      per_bfd object created for the first objfile.
>   2. Run to some point where in the backtrace there is a frame for a
>      function that's in a CU that's not yet read in.
>   3. Check that this frame's information is complete in the "backtrace"
>      output.
> 
> Step 2 requires an address -> symbol lookup which uses the addrmap at
> objfile->partial_symtabs->psymtabs_addrmap.  If the
> objfile->partial_symtabs link is not properly setup (as is the case
> before this patch), the symbol for that frame won't be found and we'll
> get a frame with incomplete information.
> 
> The test fails without the fix when using boards "cc-with-gdb-index" and
> "cc-with-debug-names".
> 

I've also tested this with the gdb_cmd_file-twice patch with these two
target boards, and everything looks good.

[ FWIW, the gdb.base/index-cache.exp with the gdb_cmd_file-twice patch
and native is still there. ]

Some comments on the test-case below...

> gdb/ChangeLog:
> 
> 	* dwarf2/read.c (dwarf2_read_gdb_index): Save partial_symtabs in
> 	the per_bfd object.
> 	(dwarf2_read_debug_names): Likewise.
> 	(dwarf2_initialize_objfile): Use partial_symtabs from per_bfd
> 	object when re-using a per_bfd object with an index.
> 
> gdb/testsuite/ChangeLog:
> 
> 	* gdb.dwarf2/share-psymtabs-bt.exp: New file.
> 	* gdb.dwarf2/share-psymtabs-bt.c: New file.
> 	* gdb.dwarf2/share-psymtabs-bt-2.c: New file.
> 
> Change-Id: Ibb26210e2dfc03b80ba9fa56b875ba4cc58c0352
> ---
>  gdb/dwarf2/read.c                            | 56 +++++++++++--------
>  gdb/testsuite/gdb.base/share-psymtabs-bt-2.c | 24 +++++++++
>  gdb/testsuite/gdb.base/share-psymtabs-bt.c   | 29 ++++++++++
>  gdb/testsuite/gdb.base/share-psymtabs-bt.exp | 57 ++++++++++++++++++++
>  4 files changed, 144 insertions(+), 22 deletions(-)
>  create mode 100644 gdb/testsuite/gdb.base/share-psymtabs-bt-2.c
>  create mode 100644 gdb/testsuite/gdb.base/share-psymtabs-bt.c
>  create mode 100644 gdb/testsuite/gdb.base/share-psymtabs-bt.exp
> 
> diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
> index e6566f9649f8..f04bdd1ce58e 100644
> --- a/gdb/dwarf2/read.c
> +++ b/gdb/dwarf2/read.c
> @@ -3068,9 +3068,10 @@ dwarf2_read_gdb_index
>    offset_type cu_list_elements, types_list_elements, dwz_list_elements = 0;
>    struct dwz_file *dwz;
>    struct objfile *objfile = per_objfile->objfile;
> +  dwarf2_per_bfd *per_bfd = per_objfile->per_bfd;
> 
>    gdb::array_view<const gdb_byte> main_index_contents
> -    = get_gdb_index_contents (objfile, per_objfile->per_bfd);
> +    = get_gdb_index_contents (objfile, per_bfd);
> 
>    if (main_index_contents.empty ())
>      return 0;
> @@ -3089,7 +3090,7 @@ dwarf2_read_gdb_index
> 
>    /* If there is a .dwz file, read it so we can get its CU list as
>       well.  */
> -  dwz = dwarf2_get_dwz_file (per_objfile->per_bfd);
> +  dwz = dwarf2_get_dwz_file (per_bfd);
>    if (dwz != NULL)
>      {
>        struct mapped_index dwz_map;
> @@ -3114,29 +3115,33 @@ dwarf2_read_gdb_index
>  	}
>      }
> 
> -  create_cus_from_index (per_objfile->per_bfd, cu_list, cu_list_elements,
> -			 dwz_list, dwz_list_elements);
> +  create_cus_from_index (per_bfd, cu_list, cu_list_elements, dwz_list,
> +			 dwz_list_elements);
> 
>    if (types_list_elements)
>      {
>        /* We can only handle a single .debug_types when we have an
>  	 index.  */
> -      if (per_objfile->per_bfd->types.size () != 1)
> +      if (per_bfd->types.size () != 1)
>  	return 0;
> 
> -      dwarf2_section_info *section = &per_objfile->per_bfd->types[0];
> +      dwarf2_section_info *section = &per_bfd->types[0];
> 
> -      create_signatured_type_table_from_index (per_objfile->per_bfd,
> -					       section, types_list,
> +      create_signatured_type_table_from_index (per_bfd, section, types_list,
>  					       types_list_elements);
>      }
> 
>    create_addrmap_from_index (per_objfile, map.get ());
> 
> -  per_objfile->per_bfd->index_table = std::move (map);
> -  per_objfile->per_bfd->using_index = 1;
> -  per_objfile->per_bfd->quick_file_names_table =
> -    create_quick_file_names_table (per_objfile->per_bfd->all_comp_units.size ());
> +  per_bfd->index_table = std::move (map);
> +  per_bfd->using_index = 1;
> +  per_bfd->quick_file_names_table =
> +    create_quick_file_names_table (per_bfd->all_comp_units.size ());
> +
> +  /* Save partial symtabs in the per_bfd object, for the benefit of subsequent
> +     objfiles using the same BFD.  */
> +  gdb_assert (per_bfd->partial_symtabs == nullptr);
> +  per_bfd->partial_symtabs = objfile->partial_symtabs;
> 
>    return 1;
>  }
> @@ -5205,6 +5210,7 @@ dwarf2_read_debug_names (dwarf2_per_objfile *per_objfile)
>    std::unique_ptr<mapped_debug_names> map (new mapped_debug_names);
>    mapped_debug_names dwz_map;
>    struct objfile *objfile = per_objfile->objfile;
> +  dwarf2_per_bfd *per_bfd = per_objfile->per_bfd;
> 
>    if (!read_debug_names_from_section (objfile, objfile_name (objfile),
>  				      &per_objfile->per_bfd->debug_names, *map))
> @@ -5216,7 +5222,7 @@ dwarf2_read_debug_names (dwarf2_per_objfile *per_objfile)
> 
>    /* If there is a .dwz file, read it so we can get its CU list as
>       well.  */
> -  dwz_file *dwz = dwarf2_get_dwz_file (per_objfile->per_bfd);
> +  dwz_file *dwz = dwarf2_get_dwz_file (per_bfd);
>    if (dwz != NULL)
>      {
>        if (!read_debug_names_from_section (objfile,
> @@ -5229,29 +5235,33 @@ dwarf2_read_debug_names (dwarf2_per_objfile *per_objfile)
>  	}
>      }
> 
> -  create_cus_from_debug_names (per_objfile->per_bfd, *map, dwz_map);
> +  create_cus_from_debug_names (per_bfd, *map, dwz_map);
> 
>    if (map->tu_count != 0)
>      {
>        /* We can only handle a single .debug_types when we have an
>  	 index.  */
> -      if (per_objfile->per_bfd->types.size () != 1)
> +      if (per_bfd->types.size () != 1)
>  	return false;
> 
> -      dwarf2_section_info *section = &per_objfile->per_bfd->types[0];
> +      dwarf2_section_info *section = &per_bfd->types[0];
> 
>        create_signatured_type_table_from_debug_names
> -	(per_objfile, *map, section, &per_objfile->per_bfd->abbrev);
> +	(per_objfile, *map, section, &per_bfd->abbrev);
>      }
> 
> -  create_addrmap_from_aranges (per_objfile,
> -			       &per_objfile->per_bfd->debug_aranges);
> +  create_addrmap_from_aranges (per_objfile, &per_bfd->debug_aranges);
> 
> -  per_objfile->per_bfd->debug_names_table = std::move (map);
> -  per_objfile->per_bfd->using_index = 1;
> -  per_objfile->per_bfd->quick_file_names_table =
> +  per_bfd->debug_names_table = std::move (map);
> +  per_bfd->using_index = 1;
> +  per_bfd->quick_file_names_table =
>      create_quick_file_names_table (per_objfile->per_bfd->all_comp_units.size ());
> 
> +  /* Save partial symtabs in the per_bfd object, for the benefit of subsequent
> +     objfiles using the same BFD.  */
> +  gdb_assert (per_bfd->partial_symtabs == nullptr);
> +  per_bfd->partial_symtabs = objfile->partial_symtabs;
> +
>    return true;
>  }
> 
> @@ -5972,6 +5982,7 @@ dwarf2_initialize_objfile (struct objfile *objfile, dw_index_kind *index_kind)
>    if (per_bfd->debug_names_table != nullptr)
>      {
>        *index_kind = dw_index_kind::DEBUG_NAMES;
> +      per_objfile->objfile->partial_symtabs = per_bfd->partial_symtabs;
>        per_objfile->resize_symtabs ();
>        return true;
>      }
> @@ -5981,6 +5992,7 @@ dwarf2_initialize_objfile (struct objfile *objfile, dw_index_kind *index_kind)
>    if (per_bfd->index_table != nullptr)
>      {
>        *index_kind = dw_index_kind::GDB_INDEX;
> +      per_objfile->objfile->partial_symtabs = per_bfd->partial_symtabs;
>        per_objfile->resize_symtabs ();
>        return true;
>      }
> diff --git a/gdb/testsuite/gdb.base/share-psymtabs-bt-2.c b/gdb/testsuite/gdb.base/share-psymtabs-bt-2.c
> new file mode 100644
> index 000000000000..c713eb22693c
> --- /dev/null
> +++ b/gdb/testsuite/gdb.base/share-psymtabs-bt-2.c
> @@ -0,0 +1,24 @@
> +/* This testcase is part of GDB, the GNU debugger.
> +
> +   Copyright 2020 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/>.  */
> +
> +void bar (int x);
> +
> +void
> +foo (int x)
> +{
> +  bar (x);
> +}
> diff --git a/gdb/testsuite/gdb.base/share-psymtabs-bt.c b/gdb/testsuite/gdb.base/share-psymtabs-bt.c
> new file mode 100644
> index 000000000000..97ad3457905b
> --- /dev/null
> +++ b/gdb/testsuite/gdb.base/share-psymtabs-bt.c
> @@ -0,0 +1,29 @@
> +/* This testcase is part of GDB, the GNU debugger.
> +
> +   Copyright 2020 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/>.  */
> +
> +void
> +bar (int x)
> +{}
> +
> +void foo (int x);
> +
> +int
> +main (void)
> +{
> +  foo (12345);
> +  return 0;
> +}
> diff --git a/gdb/testsuite/gdb.base/share-psymtabs-bt.exp b/gdb/testsuite/gdb.base/share-psymtabs-bt.exp
> new file mode 100644
> index 000000000000..f4ca58e30b96
> --- /dev/null
> +++ b/gdb/testsuite/gdb.base/share-psymtabs-bt.exp
> @@ -0,0 +1,57 @@
> +# Copyright 2020 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/>.
> +
> +# Test that a backtrace is shown correctly for an objfile that uses partial
> +# symtabs created by another objfile sharing the same BFD.
> +#
> +# It mimics how a bug with psymtab sharing was initially found:
> +#
> +#  1. Load the test file twice, such that the second objfile re-uses the
> +#     per_bfd object created for the first objfile.
> +#  2. Run to some point where in the backtrace there is a frame for a
> +#     function that's in a CU that's not yet read in.
> +#  3. Check that this frame's information is complete in the "backtrace"
> +#     output.
> +
> +standard_testfile share-psymtabs-bt.c share-psymtabs-bt-2.c
> +
> +set sources [list \
> +    "${srcdir}/${subdir}/${srcfile}" \
> +    "${srcdir}/${subdir}/${srcfile2}" \
> +]
> +
> +if { [gdb_compile $sources $binfile executable {debug}] != "" } {
> +    untested "failed to compile"
> +    return -1
> +}
> +
> +clean_restart $binfile
> +

That looks more elaborate than necessary, how about:
...
diff --git a/gdb/testsuite/gdb.base/share-psymtabs-bt.exp
b/gdb/testsuite/gdb.base/share-psymtabs-bt.exp
index f4ca58e30b..65ea728f66 100644
--- a/gdb/testsuite/gdb.base/share-psymtabs-bt.exp
+++ b/gdb/testsuite/gdb.base/share-psymtabs-bt.exp
@@ -25,20 +25,14 @@
 #  3. Check that this frame's information is complete in the "backtrace"
 #     output.

-standard_testfile share-psymtabs-bt.c share-psymtabs-bt-2.c
+standard_testfile .c share-psymtabs-bt-2.c

-set sources [list \
-    "${srcdir}/${subdir}/${srcfile}" \
-    "${srcdir}/${subdir}/${srcfile2}" \
-]
-
-if { [gdb_compile $sources $binfile executable {debug}] != "" } {
+if { [prepare_for_testing "failed to prepare" $testfile "$srcfile
$srcfile2" \
+         {debug}] } {
     untested "failed to compile"
     return -1
 }

-clean_restart $binfile
-
 # Load $binfile a second time.  The second created objfile will re-use the
 # partial symtabs created by the first one.
 if { [gdb_file_cmd $binfile] != 0 } {
...
?

Thanks,
- Tom

> +# Load $binfile a second time.  The second created objfile will re-use the
> +# partial symtabs created by the first one.
> +if { [gdb_file_cmd $binfile] != 0 } {
> +    fail "file command failed"
> +    return -1
> +}
> +
> +gdb_breakpoint "bar"
> +if { ![runto "bar"] } {
> +    fail "failed to run to bar"
> +    return -1
> +}
> +
> +# A buggy GDB would fail to find the full symbol associated to this frame's
> +# address, so would just show "foo ()" (from the minimal symbol).
> +gdb_test "bt" "foo \\(x=12345\\).*"
> 

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

* Re: [PATCH v2 00/42] Share DWARF partial symtabs between objfiles
  2020-06-04 17:55                           ` Tom de Vries
@ 2020-06-04 18:04                             ` Simon Marchi
  2020-06-10  3:43                               ` Simon Marchi
  0 siblings, 1 reply; 92+ messages in thread
From: Simon Marchi @ 2020-06-04 18:04 UTC (permalink / raw)
  To: Tom de Vries, Simon Marchi, Pedro Alves, Tom Tromey,
	Simon Marchi via Gdb-patches

On 2020-06-04 1:55 p.m., Tom de Vries wrote:
> I've also tested this with the gdb_cmd_file-twice patch with these two
> target boards, and everything looks good.

Thanks for testing.
> [ FWIW, the gdb.base/index-cache.exp with the gdb_cmd_file-twice patch
> and native is still there. ]

I'll take a look at that now.

> That looks more elaborate than necessary, how about:
> ...
> diff --git a/gdb/testsuite/gdb.base/share-psymtabs-bt.exp
> b/gdb/testsuite/gdb.base/share-psymtabs-bt.exp
> index f4ca58e30b..65ea728f66 100644
> --- a/gdb/testsuite/gdb.base/share-psymtabs-bt.exp
> +++ b/gdb/testsuite/gdb.base/share-psymtabs-bt.exp
> @@ -25,20 +25,14 @@
>  #  3. Check that this frame's information is complete in the "backtrace"
>  #     output.
> 
> -standard_testfile share-psymtabs-bt.c share-psymtabs-bt-2.c
> +standard_testfile .c share-psymtabs-bt-2.c
> 
> -set sources [list \
> -    "${srcdir}/${subdir}/${srcfile}" \
> -    "${srcdir}/${subdir}/${srcfile2}" \
> -]
> -
> -if { [gdb_compile $sources $binfile executable {debug}] != "" } {
> +if { [prepare_for_testing "failed to prepare" $testfile "$srcfile
> $srcfile2" \
> +         {debug}] } {
>      untested "failed to compile"
>      return -1
>  }
> 
> -clean_restart $binfile
> -
>  # Load $binfile a second time.  The second created objfile will re-use the
>  # partial symtabs created by the first one.
>  if { [gdb_file_cmd $binfile] != 0 } {
> ...
> ?

Thanks, I pushed the patch after integrating your suggestion.

Simon

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

* Re: [PATCH v2 00/42] Share DWARF partial symtabs between objfiles
  2020-06-04 18:04                             ` Simon Marchi
@ 2020-06-10  3:43                               ` Simon Marchi
  2020-06-12  3:25                                 ` Tom Tromey
  0 siblings, 1 reply; 92+ messages in thread
From: Simon Marchi @ 2020-06-10  3:43 UTC (permalink / raw)
  To: Tom de Vries, Simon Marchi, Pedro Alves, Tom Tromey,
	Simon Marchi via Gdb-patches

On 2020-06-04 2:04 p.m., Simon Marchi wrote:
> On 2020-06-04 1:55 p.m., Tom de Vries wrote:
>> I've also tested this with the gdb_cmd_file-twice patch with these two
>> target boards, and everything looks good.
> 
> Thanks for testing.
>> [ FWIW, the gdb.base/index-cache.exp with the gdb_cmd_file-twice patch
>> and native is still there. ]
> 
> I'll take a look at that now.

Just an update.  I haven't had much time to take a look, but the problem seems simple.

The sequence of events is:

1. Load binary, create psymtabs, fill per-bfd
2. Because index-cache is on, generate index in the cache
3. Load binary a second time, in dwarf2_initialize_objfile we check: was an index
   already loaded for this BFD?  No, so we try to read the index and fill the per-bfd.
   However, the per-bfd's comp units vector was already filled when creating psymtabs.
   The assert is there because it doesn't make sense to read an index for a per_bfd
   that already has comp units, it means either some psymtabs were created for it or
   another index was already read.

So this is a situation I hadn't accounted for: a BFD for which we have built the partial
symtabs the first time, but has an index the second time.  We probably just need a check
for psymtabs in dwarf2_initialize_objfile, something like the patch below.  I included
the change to lib/gdb.exp just to make it easier to test / reproduce the issue, but it
won't be included in the final patch, a proper test will be included instead.


From a3d0d98961fb26fa8582efeb0f078e6231269380 Mon Sep 17 00:00:00 2001
From: Simon Marchi <simon.marchi@polymtl.ca>
Date: Tue, 9 Jun 2020 23:38:00 -0400
Subject: [PATCH] gdb: fix loading file twice with index-cache on

Change-Id: I458c6f05abb1a05fd3d177e9c9002225e0deee0c
---
 gdb/dwarf2/read.c         | 7 +++++++
 gdb/testsuite/lib/gdb.exp | 7 ++++++-
 2 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 97d1771a6295..27ce9092cd31 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -5997,6 +5997,13 @@ dwarf2_initialize_objfile (struct objfile *objfile, dw_index_kind *index_kind)
       return true;
     }

+  if (per_bfd->partial_symtabs != nullptr)
+    {
+      /* Partial symbols were already read, the objfile/per_objfile
+	 initialization will be completed in dwarf2_build_psymtabs.  */
+      return false;
+    }
+
   if (dwarf2_read_debug_names (per_objfile))
     {
       *index_kind = dw_index_kind::DEBUG_NAMES;
diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp
index 9a0620a2bf18..103e883ed417 100644
--- a/gdb/testsuite/lib/gdb.exp
+++ b/gdb/testsuite/lib/gdb.exp
@@ -4820,7 +4820,12 @@ proc gdb_load_shlib { file } {
 #
 proc gdb_load { arg } {
     if { $arg != "" } {
-	return [gdb_file_cmd $arg]
+           set res [gdb_file_cmd $arg]
+           if { $res != 0 } {
+               return $res
+           }
+           set res [gdb_file_cmd $arg]
+           return $res
     }
     return 0
 }
-- 
2.27.0




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

* Re: [PATCH v2 00/42] Share DWARF partial symtabs between objfiles
  2020-06-10  3:43                               ` Simon Marchi
@ 2020-06-12  3:25                                 ` Tom Tromey
  0 siblings, 0 replies; 92+ messages in thread
From: Tom Tromey @ 2020-06-12  3:25 UTC (permalink / raw)
  To: Simon Marchi
  Cc: Tom de Vries, Simon Marchi, Pedro Alves, Tom Tromey,
	Simon Marchi via Gdb-patches

>>>>> "Simon" == Simon Marchi <simark@simark.ca> writes:

Simon> So this is a situation I hadn't accounted for: a BFD for which we have built the partial
Simon> symtabs the first time, but has an index the second time.  We probably just need a check
Simon> for psymtabs in dwarf2_initialize_objfile, something like the
Simon> patch below.

This makes sense to me.  Thank you for dealing with this bug & the other
sharing bugs that have cropped up.

Tom

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

end of thread, other threads:[~2020-06-12  3:25 UTC | newest]

Thread overview: 92+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-05-12 21:08 [PATCH v2 00/42] Share DWARF partial symtabs between objfiles Simon Marchi
2020-05-12 21:08 ` [PATCH v2 01/42] Introduce dwarf2_per_objfile::obstack Simon Marchi
2020-05-12 21:08 ` [PATCH v2 02/42] Add "objfile" parameter to two partial_symtab methods Simon Marchi
2020-05-12 21:08 ` [PATCH v2 03/42] Add dwarf2_per_cu_data::index Simon Marchi
2020-05-12 21:08 ` [PATCH v2 04/42] Add dwarf2_per_objfile member to DWARF batons Simon Marchi
2020-05-12 21:08 ` [PATCH v2 05/42] Split dwarf2_per_objfile into dwarf2_per_objfile and dwarf2_per_bfd Simon Marchi
2020-05-12 21:08 ` [PATCH v2 06/42] Remove symtab links from dwarf2_psymtab and dwarf2_per_cu_quick_data Simon Marchi
2020-05-12 21:08 ` [PATCH v2 07/42] Move die_type_hash to dwarf2_per_objfile Simon Marchi
2020-05-12 21:08 ` [PATCH v2 08/42] Add dwarf2_per_objfile field to dwarf2_cu Simon Marchi
2020-05-12 21:08 ` [PATCH v2 09/42] Remove reference to dwarf2_per_cu_data::dwarf2_per_objfile in dw2_do_instantiate_symtab Simon Marchi
2020-05-12 21:11 ` [PATCH v2 10/42] Remove dwarf2_cu->per_cu->dwarf2_per_objfile references Simon Marchi
2020-05-12 21:11 ` [PATCH v2 11/42] Add dwarf2_per_bfd field to dwarf2_per_cu_data Simon Marchi
2020-05-12 21:11 ` [PATCH v2 12/42] Make dwarf2_get_dwz_file take a dwarf2_per_bfd Simon Marchi
2020-05-12 21:11 ` [PATCH v2 13/42] Use bfd_get_filename instead of objfile_name in lookup_dwo_unit Simon Marchi
2020-05-12 21:11 ` [PATCH v2 14/42] Add dwarf2_per_objfile parameter to cutu_reader's constructors Simon Marchi
2020-05-12 21:11 ` [PATCH v2 15/42] Make queue_and_load_dwo_tu receive a dwarf2_cu Simon Marchi
2020-05-22 20:45   ` Tom Tromey
2020-05-25 19:10     ` Simon Marchi
2020-05-12 21:11 ` [PATCH v2 16/42] Remove dwarf2_per_cu_data::dwarf2_per_objfile reference in cutu_reader::keep Simon Marchi
2020-05-12 21:11 ` [PATCH v2 17/42] Add dwarf2_per_objfile parameter to create_partial_symtab Simon Marchi
2020-05-12 21:11 ` [PATCH v2 18/42] Add dwarf2_per_objfile parameter to recursively_compute_inclusions Simon Marchi
2020-05-12 21:11 ` [PATCH v2 19/42] Add dwarf2_per_objfile parameter to process_full_{comp, type}_unit Simon Marchi
2020-05-12 21:12 ` [PATCH v2 20/42] Pass dwarf2_cu objects to dwo-related functions, instead of dwarf2_per_cu_data Simon Marchi
2020-05-12 21:12 ` [PATCH v2 21/42] Remove reference to dwarf2_per_cu_data::dwarf2_per_objfile in queue_and_load_all_dwo_tus Simon Marchi
2020-05-12 21:12 ` [PATCH v2 22/42] Move int type methods out of dwarf2_per_cu_data Simon Marchi
2020-05-12 21:12 ` [PATCH v2 23/42] Add dwarf2_per_objfile to dwarf_expr_context and dwarf2_frame_cache Simon Marchi
2020-05-22 21:04   ` Tom Tromey
2020-05-25 19:50     ` Simon Marchi
2020-05-28  1:44       ` Simon Marchi
2020-05-12 21:12 ` [PATCH v2 24/42] Remove dwarf2_per_cu_data::text_offset Simon Marchi
2020-05-12 21:12 ` [PATCH v2 25/42] Add dwarf2_per_objfile parameter to dwarf2_read_addr_index Simon Marchi
2020-05-12 21:12 ` [PATCH v2 26/42] Add dwarf2_per_objfile parameter to allocate_piece_closure Simon Marchi
2020-05-12 21:12 ` [PATCH v2 27/42] Add dwarf2_per_objfile parameters to dwarf2_fetch_* functions Simon Marchi
2020-05-12 21:12 ` [PATCH v2 28/42] Remove dwarf2_per_cu_data::objfile () Simon Marchi
2020-05-27 16:27   ` Tom de Vries
2020-05-27 16:52     ` Tom de Vries
2020-05-27 20:03     ` Simon Marchi
2020-05-27 21:08       ` Tom de Vries
2020-05-27 21:55         ` Simon Marchi
2020-05-27 22:16           ` Simon Marchi
2020-05-28  2:00             ` Simon Marchi
2020-05-28 13:05               ` Tom de Vries
2020-05-28 15:33                 ` Simon Marchi
2020-05-28 16:24                   ` Christian Biesinger
2020-05-28 16:52                     ` Simon Marchi
2020-05-28 19:49                       ` Simon Marchi
2020-05-12 21:12 ` [PATCH v2 29/42] Add dwarf2_per_objfile parameter to free_one_cached_comp_unit Simon Marchi
2020-05-12 21:17 ` [PATCH v2 30/42] Add dwarf2_per_objfile parameter to get_die_type_at_offset Simon Marchi
2020-05-12 21:17 ` [PATCH v2 31/42] Remove leftover references to dwarf2_per_cu_data::dwarf2_per_objfile Simon Marchi
2020-05-12 21:17 ` [PATCH v2 32/42] Remove dwarf2_per_cu_data::dwarf2_per_objfile Simon Marchi
2020-05-12 21:17 ` [PATCH v2 33/42] Split type_unit_group Simon Marchi
2020-05-13  9:54   ` Tom de Vries
2020-05-13 15:06     ` Simon Marchi
2020-05-12 21:17 ` [PATCH v2 34/42] Move signatured_type::type to unshareable object Simon Marchi
2020-05-12 21:17 ` [PATCH v2 35/42] Pass dwarf2_per_bfd instead of dwarf2_per_objfile to some index-related functions Simon Marchi
2020-05-12 21:17 ` [PATCH v2 36/42] Pass dwarf2_cu to process_full_{comp,type}_unit Simon Marchi
2020-05-12 21:17 ` [PATCH v2 37/42] Make load_cu return the loaded dwarf2_cu Simon Marchi
2020-05-12 21:17 ` [PATCH v2 38/42] Add comp_unit_head to dwarf2_per_cu_data Simon Marchi
2020-05-12 21:17 ` [PATCH v2 39/42] Pass existing_cu object to cutu_reader Simon Marchi
2020-05-22 20:57   ` Tom Tromey
2020-05-25 19:10     ` Simon Marchi
2020-05-12 21:18 ` [PATCH v2 40/42] Replace dwarf2_per_cu_data::cu backlink with per-objfile map Simon Marchi
2020-05-12 21:18 ` [PATCH v2 41/42] Make mapped_debug_names independent of objfile Simon Marchi
2020-05-22 21:01   ` Tom Tromey
2020-05-25 19:53     ` Simon Marchi
2020-05-12 21:18 ` [PATCH v2 42/42] Share DWARF partial symtabs Simon Marchi
2020-05-13 10:17 ` [PATCH v2 00/42] Share DWARF partial symtabs between objfiles Tom de Vries
2020-05-13 15:46   ` Simon Marchi
2020-05-22 21:02     ` Tom Tromey
2020-05-25 19:53       ` Simon Marchi
2020-05-13 14:52 ` Simon Marchi
2020-05-22 21:07 ` Tom Tromey
2020-05-23 12:24   ` Pedro Alves
2020-05-25 19:56     ` Simon Marchi
2020-05-26 11:17       ` Pedro Alves
2020-05-26 15:35         ` Simon Marchi
2020-05-26 21:34           ` Simon Marchi
2020-05-27  5:08             ` Simon Marchi
2020-05-27 14:53               ` Simon Marchi
2020-05-27 15:51                 ` Simon Marchi
2020-05-29 10:23                   ` Tom de Vries
2020-05-29 12:55                     ` Tom de Vries
2020-05-31  4:16                     ` Simon Marchi
2020-05-31 14:22                       ` Tom de Vries
2020-06-02 21:27                         ` Simon Marchi
2020-06-04 17:55                           ` Tom de Vries
2020-06-04 18:04                             ` Simon Marchi
2020-06-10  3:43                               ` Simon Marchi
2020-06-12  3:25                                 ` Tom Tromey
2020-05-27 14:50 ` [PATCH v2 41.5/42] Move line_header_hash to dwarf2_per_objfile Simon Marchi
2020-05-27 15:07   ` Tom Tromey
2020-05-27 15:10     ` Simon Marchi

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).