Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package gdb for openSUSE:Factory checked in 
at 2023-12-19 23:15:32
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/gdb (Old)
 and      /work/SRC/openSUSE:Factory/.gdb.new.9037 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "gdb"

Tue Dec 19 23:15:32 2023 rev:174 rq:1133867 version:13.2

Changes:
--------
--- /work/SRC/openSUSE:Factory/gdb/gdb.changes  2023-11-17 20:48:27.526715412 
+0100
+++ /work/SRC/openSUSE:Factory/.gdb.new.9037/gdb.changes        2023-12-19 
23:15:40.425186751 +0100
@@ -1,0 +2,16 @@
+Wed Dec 13 14:58:14 UTC 2023 - Tom de Vries <[email protected]>
+
+- Patches added (backport from gdb-patches, swo#30728):
+  * gdb-symtab-refactor-condition-in-scan_attributes.patch
+  * gdb-symtab-factor-out-m_die_range_map-usage.patch
+  * gdb-symtab-handle-nullptr-parent-in-parent_map-set_p.patch
+  * gdb-symtab-factor-out-m_deferred_entries-usage.patch
+  * gdb-symtab-resolve-deferred-entries-inter-shard-case.patch
+  * gdb-symtab-keep-track-of-processed-dies-in-shard.patch
+  * gdb-symtab-resolve-deferred-entries-intra-shard-case.patch
+  * gdb-symtab-don-t-defer-backward-refs-inter-cu-intra-.patch
+  * gdb-symtab-recurse-into-c-dw_tag_subprogram-dies-for.patch
+  * gdb-symtab-keep-track-of-all-parents-for-cooked-inde.patch
+  * gdb-symtab-fix-dw_tag_inlined_subroutine-entries-in-.patch
+
+-------------------------------------------------------------------

New:
----
  gdb-symtab-don-t-defer-backward-refs-inter-cu-intra-.patch
  gdb-symtab-factor-out-m_deferred_entries-usage.patch
  gdb-symtab-factor-out-m_die_range_map-usage.patch
  gdb-symtab-fix-dw_tag_inlined_subroutine-entries-in-.patch
  gdb-symtab-handle-nullptr-parent-in-parent_map-set_p.patch
  gdb-symtab-keep-track-of-all-parents-for-cooked-inde.patch
  gdb-symtab-keep-track-of-processed-dies-in-shard.patch
  gdb-symtab-recurse-into-c-dw_tag_subprogram-dies-for.patch
  gdb-symtab-refactor-condition-in-scan_attributes.patch
  gdb-symtab-resolve-deferred-entries-inter-shard-case.patch
  gdb-symtab-resolve-deferred-entries-intra-shard-case.patch

BETA DEBUG BEGIN:
  New:  * gdb-symtab-resolve-deferred-entries-intra-shard-case.patch
  * gdb-symtab-don-t-defer-backward-refs-inter-cu-intra-.patch
  * gdb-symtab-recurse-into-c-dw_tag_subprogram-dies-for.patch
  New:  * gdb-symtab-handle-nullptr-parent-in-parent_map-set_p.patch
  * gdb-symtab-factor-out-m_deferred_entries-usage.patch
  * gdb-symtab-resolve-deferred-entries-inter-shard-case.patch
  New:  * gdb-symtab-refactor-condition-in-scan_attributes.patch
  * gdb-symtab-factor-out-m_die_range_map-usage.patch
  * gdb-symtab-handle-nullptr-parent-in-parent_map-set_p.patch
  New:  * gdb-symtab-keep-track-of-all-parents-for-cooked-inde.patch
  * gdb-symtab-fix-dw_tag_inlined_subroutine-entries-in-.patch
  New:  * gdb-symtab-factor-out-m_die_range_map-usage.patch
  * gdb-symtab-handle-nullptr-parent-in-parent_map-set_p.patch
  * gdb-symtab-factor-out-m_deferred_entries-usage.patch
  New:  * gdb-symtab-recurse-into-c-dw_tag_subprogram-dies-for.patch
  * gdb-symtab-keep-track-of-all-parents-for-cooked-inde.patch
  * gdb-symtab-fix-dw_tag_inlined_subroutine-entries-in-.patch
  New:  * gdb-symtab-resolve-deferred-entries-inter-shard-case.patch
  * gdb-symtab-keep-track-of-processed-dies-in-shard.patch
  * gdb-symtab-resolve-deferred-entries-intra-shard-case.patch
  New:  * gdb-symtab-don-t-defer-backward-refs-inter-cu-intra-.patch
  * gdb-symtab-recurse-into-c-dw_tag_subprogram-dies-for.patch
  * gdb-symtab-keep-track-of-all-parents-for-cooked-inde.patch
  New:- Patches added (backport from gdb-patches, swo#30728):
  * gdb-symtab-refactor-condition-in-scan_attributes.patch
  * gdb-symtab-factor-out-m_die_range_map-usage.patch
  New:  * gdb-symtab-factor-out-m_deferred_entries-usage.patch
  * gdb-symtab-resolve-deferred-entries-inter-shard-case.patch
  * gdb-symtab-keep-track-of-processed-dies-in-shard.patch
  New:  * gdb-symtab-keep-track-of-processed-dies-in-shard.patch
  * gdb-symtab-resolve-deferred-entries-intra-shard-case.patch
  * gdb-symtab-don-t-defer-backward-refs-inter-cu-intra-.patch
BETA DEBUG END:

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ gdb.spec ++++++
--- /var/tmp/diff_new_pack.ci5Dd5/_old  2023-12-19 23:15:43.357293525 +0100
+++ /var/tmp/diff_new_pack.ci5Dd5/_new  2023-12-19 23:15:43.357293525 +0100
@@ -369,6 +369,19 @@
 # https://sourceware.org/pipermail/gdb-patches/2023-November/203943.html
 Patch2109:      gdb-fix-segfault-in-for_each_block-part-1.patch
 
+# https://sourceware.org/pipermail/gdb-patches/2023-December/205054.html
+Patch2120:      gdb-symtab-refactor-condition-in-scan_attributes.patch
+Patch2121:      gdb-symtab-factor-out-m_die_range_map-usage.patch
+Patch2122:      gdb-symtab-handle-nullptr-parent-in-parent_map-set_p.patch
+Patch2123:      gdb-symtab-factor-out-m_deferred_entries-usage.patch
+Patch2124:      gdb-symtab-resolve-deferred-entries-inter-shard-case.patch
+Patch2125:      gdb-symtab-keep-track-of-processed-dies-in-shard.patch
+Patch2126:      gdb-symtab-resolve-deferred-entries-intra-shard-case.patch
+Patch2127:      gdb-symtab-don-t-defer-backward-refs-inter-cu-intra-.patch
+Patch2128:      gdb-symtab-recurse-into-c-dw_tag_subprogram-dies-for.patch
+Patch2129:      gdb-symtab-keep-track-of-all-parents-for-cooked-inde.patch
+Patch2130:      gdb-symtab-fix-dw_tag_inlined_subroutine-entries-in-.patch
+
 # Debug patches.
 
 #
@@ -814,6 +827,18 @@
 %patch2108 -p1
 %patch2109 -p1
 
+%patch2120 -p1
+%patch2121 -p1
+%patch2122 -p1
+%patch2123 -p1
+%patch2124 -p1
+%patch2125 -p1
+%patch2126 -p1
+%patch2127 -p1
+%patch2128 -p1
+%patch2129 -p1
+%patch2130 -p1
+
 #unpack libipt
 %if 0%{have_libipt}
 tar xzf %{SOURCE7}

++++++ gdb-symtab-don-t-defer-backward-refs-inter-cu-intra-.patch ++++++
>From 6d472b241c96f181f88867860e92f1dfe7364903 Mon Sep 17 00:00:00 2001
From: Tom de Vries <[email protected]>
Date: Sat, 16 Sep 2023 04:07:22 +0200
Subject: [PATCH 08/11] [gdb/symtab] Don't defer backward refs, inter-cu
 intra-shard case

In patch "[gdb/symtab] Resolve deferred entries, inter-shard case" we've
solved the generic case of handling deferred entries.

Add an optimization that doesn't defer inter-CU intra-shard dependencies that
are present in the shard's parent map.

Tested on x86_64-linux.
---
 gdb/dwarf2/read.c | 29 ++++++++++++++++++++++++++++-
 1 file changed, 28 insertions(+), 1 deletion(-)

diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 0ab3e1a1500..d2d50b5c9cc 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -6709,6 +6709,12 @@ class cooked_index_storage
     m_index->set_parent_valid (start, end);
   }
 
+  /* Return true if find_parents can be relied upon.  */
+  bool parent_valid (CORE_ADDR addr)
+  {
+    return m_index->parent_valid (addr);
+  }
+
 private:
 
   /* Hash function for a cutu_reader.  */
@@ -6857,6 +6863,12 @@ class cooked_indexer
   {
     m_index_storage->set_parent_valid (start, end);
   }
+
+  /* Return true if find_parents can be relied upon.  */
+  bool parent_valid (CORE_ADDR addr)
+  {
+    return m_index_storage->parent_valid (addr);
+  }
 };
 
 /* Subroutine of dwarf2_build_psymtabs_hard to simplify it.
@@ -18387,7 +18399,22 @@ cooked_indexer::scan_attributes (dwarf2_per_cu_data 
*scanning_per_cu,
              else
                {
                  /* Inter-CU case.  */
-                 *maybe_defer = addr;
+                 if (parent_valid (addr))
+                   {
+                     auto tmp = find_parent (addr);
+                     if (tmp == &parent_map::deferred)
+                       {
+                         /* Defer because origin is deferred.  */
+                         *maybe_defer = addr;
+                       }
+                     else
+                       *parent_entry = tmp;
+                   }
+                 else
+                   {
+                     /* Defer because origin is in other shard.  */
+                     *maybe_defer = addr;
+                   }
                }
            }
 
-- 
2.35.3


++++++ gdb-symtab-factor-out-m_deferred_entries-usage.patch ++++++
>From dac6c3b27a77589078add7e4e4586515ac85610d Mon Sep 17 00:00:00 2001
From: Tom de Vries <[email protected]>
Date: Fri, 15 Sep 2023 08:38:00 +0200
Subject: [PATCH 04/11] [gdb/symtab] Factor out m_deferred_entries usage

Factor out usage of cooked_indexer::m_deferred_entries in new member
functions defer_entry, handle_deferred_entries and resolve_deferred_entry.

Tested on x86_64-linux.
---
 gdb/dwarf2/read.c | 35 ++++++++++++++++++++++++++++-------
 1 file changed, 28 insertions(+), 7 deletions(-)

diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 1092cb1dca9..ff5be8e7dc5 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -6822,6 +6822,32 @@ class cooked_indexer
      we'll know the containing context of all the DIEs that we might
      have scanned.  This vector stores these deferred entries.  */
   std::vector<deferred_entry> m_deferred_entries;
+
+  /* Defer creating a cooked_index_entry corresponding to deferred_entry DE.  
*/
+  void defer_entry (const deferred_entry &de)
+  {
+    m_deferred_entries.push_back (de);
+  }
+
+  /* Create a cooked_index_entry corresponding to deferred_entry DE with
+     parent PARENT_ENTRY.  */
+  const cooked_index_entry *resolve_deferred_entry
+    (const deferred_entry &de, const cooked_index_entry *parent_entry)
+  {
+    return m_index_storage->add (de.die_offset, de.tag, de.flags, de.name,
+                                parent_entry, m_per_cu);
+  }
+
+  /* Create cooked_index_entries for the deferred entries.  */
+  void handle_deferred_entries ()
+  {
+    for (const auto &entry : m_deferred_entries)
+      {
+       const cooked_index_entry *parent_entry
+         = find_parent (entry.spec_offset);
+       resolve_deferred_entry (entry, parent_entry);
+      }
+  }
 };
 
 /* Subroutine of dwarf2_build_psymtabs_hard to simplify it.
@@ -18519,7 +18545,7 @@ cooked_indexer::index_dies (cutu_reader *reader,
       if (name != nullptr)
        {
          if (defer != 0)
-           m_deferred_entries.push_back ({
+           defer_entry ({
                this_die, name, defer, abbrev->tag, flags
              });
          else
@@ -18624,12 +18650,7 @@ cooked_indexer::make_index (cutu_reader *reader)
     return;
   index_dies (reader, reader->info_ptr, nullptr, false);
 
-  for (const auto &entry : m_deferred_entries)
-    {
-      const cooked_index_entry *parent = find_parent (entry.spec_offset);
-      m_index_storage->add (entry.die_offset, entry.tag, entry.flags,
-                           entry.name, parent, m_per_cu);
-    }
+  handle_deferred_entries ();
 }
 
 /* An implementation of quick_symbol_functions for the cooked DWARF
-- 
2.35.3


++++++ gdb-symtab-factor-out-m_die_range_map-usage.patch ++++++
>From 6ac3acf29782a059258fdfe21bd55f1716fc46ed Mon Sep 17 00:00:00 2001
From: Tom de Vries <[email protected]>
Date: Tue, 22 Aug 2023 13:17:47 +0200
Subject: [PATCH 02/11] [gdb/symtab] Factor out m_die_range_map usage

Factor out usage of cooked_indexer::m_die_range_map into new class parent_map
with member functions find_parent and set_parent, and static member function
form_addr.

Tested on x86_64-linux.
---
 gdb/dwarf2/cooked-index.h | 32 ++++++++++++++++++++++++++
 gdb/dwarf2/read.c         | 48 +++++++++++++++++++++------------------
 2 files changed, 58 insertions(+), 22 deletions(-)

diff --git a/gdb/dwarf2/cooked-index.h b/gdb/dwarf2/cooked-index.h
index 2ef1f4b27e9..1c967bdbf86 100644
--- a/gdb/dwarf2/cooked-index.h
+++ b/gdb/dwarf2/cooked-index.h
@@ -233,6 +233,38 @@ struct cooked_index_entry : public allocate_on_obstack
                    bool for_name) const;
 };
 
+class parent_map
+{
+public:
+  /* A helper function to turn a section offset into an address that
+     can be used in a parent_map.  */
+  static CORE_ADDR form_addr (sect_offset offset, bool is_dwz)
+  {
+    CORE_ADDR value = to_underlying (offset);
+    if (is_dwz)
+      value |= ((CORE_ADDR) 1) << (8 * sizeof (CORE_ADDR) - 1);
+    return value;
+  }
+
+  /* Find the parent of DIE LOOKUP.  */
+  const cooked_index_entry *find_parent (CORE_ADDR lookup) const
+  {
+    const void *obj = m_parent_map.find (lookup);
+    return static_cast<const cooked_index_entry *> (obj);
+  }
+
+  /* Set the parent of DIES in range [START, END] to PARENT_ENTRY.  */
+  void set_parent (CORE_ADDR start, CORE_ADDR end,
+                  const cooked_index_entry *parent_entry)
+  {
+    m_parent_map.set_empty (start, end, (void *)parent_entry);
+  }
+
+private:
+  /* An addrmap that maps from section offsets to cooked_index_entry *.  */
+  addrmap_mutable m_parent_map;
+};
+
 class cooked_index_vector;
 
 /* An index of interesting DIEs.  This is "cooked", in contrast to a
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 00471d20d41..1092cb1dca9 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -6722,16 +6722,6 @@ class cooked_indexer
 
 private:
 
-  /* A helper function to turn a section offset into an address that
-     can be used in an addrmap.  */
-  CORE_ADDR form_addr (sect_offset offset, bool is_dwz)
-  {
-    CORE_ADDR value = to_underlying (offset);
-    if (is_dwz)
-      value |= ((CORE_ADDR) 1) << (8 * sizeof (CORE_ADDR) - 1);
-    return value;
-  }
-
   /* A helper function to scan the PC bounds of READER and record them
      in the storage's addrmap.  */
   void check_bounds (cutu_reader *reader);
@@ -6799,7 +6789,20 @@ class cooked_indexer
   /* An addrmap that maps from section offsets (see the form_addr
      method) to newly-created entries.  See m_deferred_entries to
      understand this.  */
-  addrmap_mutable m_die_range_map;
+  parent_map m_die_range_map;
+
+  /* Find the parent of DIE LOOKUP.  */
+  const cooked_index_entry *find_parent (CORE_ADDR lookup) const
+  {
+    return m_die_range_map.find_parent (lookup);
+  }
+
+  /* Set the parent of DIES in range [START, END] to PARENT_ENTRY.  */
+  void set_parent (CORE_ADDR start, CORE_ADDR end,
+                  const cooked_index_entry *parent_entry)
+  {
+    m_die_range_map.set_parent (start, end, parent_entry);
+  }
 
   /* A single deferred entry.  */
   struct deferred_entry
@@ -18317,15 +18320,13 @@ cooked_indexer::scan_attributes (dwarf2_per_cu_data 
*scanning_per_cu,
 
          if (*parent_entry == nullptr)
            {
-             CORE_ADDR addr = form_addr (origin_offset, origin_is_dwz);
+             CORE_ADDR addr
+               = parent_map::form_addr (origin_offset, origin_is_dwz);
              if (new_reader->cu == reader->cu
                  && new_info_ptr > watermark_ptr)
                *maybe_defer = addr;
              else
-               {
-                 void *obj = m_die_range_map.find (addr);
-                 *parent_entry = static_cast <cooked_index_entry *> (obj);
-               }
+               *parent_entry = find_parent (addr);
            }
 
          unsigned int bytes_read;
@@ -18444,11 +18445,15 @@ cooked_indexer::recurse (cutu_reader *reader,
 
   if (parent_entry != nullptr)
     {
-      CORE_ADDR start = form_addr (parent_entry->die_offset,
-                                  reader->cu->per_cu->is_dwz);
-      CORE_ADDR end = form_addr (sect_offset (info_ptr - 1 - reader->buffer),
+      /* Both start and end are inclusive, so use both "+ 1" and "- 1" to
+        limit the range to the children of parent_entry.  */
+      CORE_ADDR start
+       = parent_map::form_addr (parent_entry->die_offset + 1,
+                                reader->cu->per_cu->is_dwz);
+      CORE_ADDR end
+       = parent_map::form_addr (sect_offset (info_ptr - 1 - reader->buffer),
                                 reader->cu->per_cu->is_dwz);
-      m_die_range_map.set_empty (start, end, (void *) parent_entry);
+      set_parent (start, end, parent_entry);
     }
 
   return info_ptr;
@@ -18621,8 +18626,7 @@ cooked_indexer::make_index (cutu_reader *reader)
 
   for (const auto &entry : m_deferred_entries)
     {
-      void *obj = m_die_range_map.find (entry.spec_offset);
-      cooked_index_entry *parent = static_cast<cooked_index_entry *> (obj);
+      const cooked_index_entry *parent = find_parent (entry.spec_offset);
       m_index_storage->add (entry.die_offset, entry.tag, entry.flags,
                            entry.name, parent, m_per_cu);
     }
-- 
2.35.3


++++++ gdb-symtab-fix-dw_tag_inlined_subroutine-entries-in-.patch ++++++
>From 19185006cfe0901da907da4f09fbc197aba976a2 Mon Sep 17 00:00:00 2001
From: Tom de Vries <[email protected]>
Date: Fri, 11 Aug 2023 01:36:50 +0200
Subject: [PATCH 11/11] [gdb/symtab] Fix DW_TAG_inlined_subroutine entries in
 the cooked index

We get incorrect qualified names in the cooked index for
DW_TAG_inlined_subroutine DIEs with abstract origin, due to the fact that the
DIE parent is used instead of the abstract origin.

Fix this by preferring the abstract origin parent, if available.

Tested on x86_64-linux.

PR symtab/30728
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30728
---
 gdb/dwarf2/read.c | 67 ++++++++++++++++++++++-------------------------
 1 file changed, 32 insertions(+), 35 deletions(-)

diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index e2d4fe8cde6..418acaabc60 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -18369,52 +18369,49 @@ cooked_indexer::scan_attributes (dwarf2_per_cu_data 
*scanning_per_cu,
          const gdb_byte *new_info_ptr = (new_reader->buffer
                                          + to_underlying (origin_offset));
 
-         if (*parent_entry == nullptr)
+         gdb_assert (reader->cu->per_cu->is_debug_types
+                     == new_reader->cu->per_cu->is_debug_types);
+         CORE_ADDR addr
+           = parent_map::form_addr (origin_offset, origin_is_dwz,
+                                    reader->cu->per_cu->is_debug_types);
+         if (new_reader->cu == reader->cu)
            {
-             gdb_assert (reader->cu->per_cu->is_debug_types
-                         == new_reader->cu->per_cu->is_debug_types);
-             CORE_ADDR addr
-               = parent_map::form_addr (origin_offset, origin_is_dwz,
-                                        reader->cu->per_cu->is_debug_types);
-             if (new_reader->cu == reader->cu)
+             /* Intra-CU case.  */
+             if (new_info_ptr > watermark_ptr)
                {
-                 /* Intra-CU case.  */
-                 if (new_info_ptr > watermark_ptr)
-                   {
-                     /* Defer because origin is not read yet.  */
-                     *maybe_defer = addr;
-                   }
-                 else
-                   {
-                     auto tmp = find_parent (addr);
-                     if (tmp == &parent_map::deferred)
-                       {
-                         /* Defer because origin is deferred.  */
-                         *maybe_defer = addr;
-                       }
-                     else
-                       *parent_entry = tmp;
-                   }
+                 /* Defer because origin is not read yet.  */
+                 *maybe_defer = addr;
                }
              else
                {
-                 /* Inter-CU case.  */
-                 if (parent_valid (addr))
+                 auto tmp = find_parent (addr);
+                 if (tmp == &parent_map::deferred)
                    {
-                     auto tmp = find_parent (addr);
-                     if (tmp == &parent_map::deferred)
-                       {
-                         /* Defer because origin is deferred.  */
-                         *maybe_defer = addr;
-                       }
-                     else
-                       *parent_entry = tmp;
+                     /* Defer because origin is deferred.  */
+                     *maybe_defer = addr;
                    }
                  else
+                   *parent_entry = tmp;
+               }
+           }
+         else
+           {
+             /* Inter-CU case.  */
+             if (parent_valid (addr))
+               {
+                 auto tmp = find_parent (addr);
+                 if (tmp == &parent_map::deferred)
                    {
-                     /* Defer because origin is in other shard.  */
+                     /* Defer because origin is deferred.  */
                      *maybe_defer = addr;
                    }
+                 else
+                   *parent_entry = tmp;
+               }
+             else
+               {
+                 /* Defer because origin is in other shard.  */
+                 *maybe_defer = addr;
                }
            }
 
-- 
2.35.3


++++++ gdb-symtab-handle-nullptr-parent-in-parent_map-set_p.patch ++++++
>From 933f8ee225d4ccd3db9b81312dba76ae5a50b4ea Mon Sep 17 00:00:00 2001
From: Tom de Vries <[email protected]>
Date: Fri, 25 Aug 2023 09:30:54 +0200
Subject: [PATCH 03/11] [gdb/symtab] Handle nullptr parent in
 parent_map::set_parent

Set_parent uses m_die_range_map.set_empty, which doesn't allow
parent_entry == nullptr.

So it may be necessary to guard calls to set_parent with
"if (parent_entry != nullptr)".

Fix this by handling the parent_entry == nullptr case in set_parent.

Tested on x86_64-linux.
---
 gdb/dwarf2/cooked-index.h | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/gdb/dwarf2/cooked-index.h b/gdb/dwarf2/cooked-index.h
index 1c967bdbf86..f4abc7a974e 100644
--- a/gdb/dwarf2/cooked-index.h
+++ b/gdb/dwarf2/cooked-index.h
@@ -257,7 +257,9 @@ class parent_map
   void set_parent (CORE_ADDR start, CORE_ADDR end,
                   const cooked_index_entry *parent_entry)
   {
-    m_parent_map.set_empty (start, end, (void *)parent_entry);
+    /* Calling set_empty with nullptr is currently not allowed.  */
+    if (parent_entry != nullptr)
+      m_parent_map.set_empty (start, end, (void *)parent_entry);
   }
 
 private:
-- 
2.35.3


++++++ gdb-symtab-keep-track-of-all-parents-for-cooked-inde.patch ++++++
>From be9718e911aff34896dcf1c3dfa41bfe34e5a9f4 Mon Sep 17 00:00:00 2001
From: Tom de Vries <[email protected]>
Date: Thu, 7 Dec 2023 10:38:05 +0100
Subject: [PATCH 10/11] [gdb/symtab] Keep track of all parents for cooked index

Keep track of all parents for cooked index.

Tested on x86_64-linux.
---
 gdb/dwarf2/read.c | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 39f6e480e19..e2d4fe8cde6 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -18626,9 +18626,15 @@ cooked_indexer::index_dies (cutu_reader *reader,
                });
            }
          else
-           this_entry = m_index_storage->add (this_die, abbrev->tag, flags,
-                                              name, this_parent_entry,
-                                              m_per_cu);
+           {
+             CORE_ADDR addr
+               = parent_map::form_addr (this_die, reader->cu->per_cu->is_dwz,
+                                        reader->cu->per_cu->is_debug_types);
+             set_parent (addr, addr, this_parent_entry);
+             this_entry = m_index_storage->add (this_die, abbrev->tag, flags,
+                                                name, this_parent_entry,
+                                                m_per_cu);
+           }
        }
 
       if (linkage_name != nullptr)
-- 
2.35.3


++++++ gdb-symtab-keep-track-of-processed-dies-in-shard.patch ++++++
>From 439271c6fc28387ea7b6fb6e8bb07963e8b3fd7d Mon Sep 17 00:00:00 2001
From: Tom de Vries <[email protected]>
Date: Sun, 24 Sep 2023 11:41:39 +0200
Subject: [PATCH 06/11] [gdb/symtab] Keep track of processed DIEs in shard

For optimizations in two following patches, we keep track in each shard which
DIEs have been processed.

Tested on x86_64-linux.
---
 gdb/dwarf2/cooked-index.c |  1 +
 gdb/dwarf2/cooked-index.h | 15 +++++++++++++++
 gdb/dwarf2/read.c         | 24 ++++++++++++++++++++++++
 3 files changed, 40 insertions(+)

diff --git a/gdb/dwarf2/cooked-index.c b/gdb/dwarf2/cooked-index.c
index 4a0ccc78c5d..cef57a96384 100644
--- a/gdb/dwarf2/cooked-index.c
+++ b/gdb/dwarf2/cooked-index.c
@@ -541,6 +541,7 @@ cooked_index_vector::handle_deferred_entries ()
     {
       shard->m_die_range_map.reset (nullptr);
       shard->m_deferred_entries.reset (nullptr);
+      shard->m_die_range_map_valid.reset (nullptr);
     }
 }
 
diff --git a/gdb/dwarf2/cooked-index.h b/gdb/dwarf2/cooked-index.h
index a06d99532ed..9d836379666 100644
--- a/gdb/dwarf2/cooked-index.h
+++ b/gdb/dwarf2/cooked-index.h
@@ -312,6 +312,7 @@ class cooked_index
   {
     m_die_range_map.reset (new parent_map);
     m_deferred_entries.reset (new std::vector<deferred_entry>);
+    m_die_range_map_valid.reset (new addrmap_mutable);
   }
 
   /* Create a new cooked_index_entry and register it with this object.
@@ -403,6 +404,18 @@ class cooked_index
   const cooked_index_entry *resolve_deferred_entry
     (const deferred_entry &entry, const cooked_index_entry *parent_entry);
 
+  /* Mark parents in range [START, END] as valid .  */
+  void set_parent_valid (CORE_ADDR start, CORE_ADDR end)
+  {
+    m_die_range_map_valid->set_empty (start, end, (void *) 1);
+  }
+
+  /* Return true if find_parents can be relied upon.  */
+  bool parent_valid (CORE_ADDR addr)
+  {
+    return m_die_range_map_valid->find (addr) != nullptr;
+  }
+
 private:
 
   /* Return the entry that is believed to represent the program's
@@ -466,6 +479,8 @@ class cooked_index
      understand this.  */
   std::unique_ptr<parent_map> m_die_range_map;
 
+  std::unique_ptr<addrmap> m_die_range_map_valid;
+
   /* The generated DWARF can sometimes have the declaration for a
      method in a class (or perhaps namespace) scope, with the
      definition appearing outside this scope... just one of the many
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 41fa8affcd0..ba21b6a14c9 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -6697,6 +6697,12 @@ class cooked_index_storage
     m_index->defer_entry (de);
   }
 
+  /* Mark parents in range [START, END] as valid .  */
+  void set_parent_valid (CORE_ADDR start, CORE_ADDR end)
+  {
+    m_index->set_parent_valid (start, end);
+  }
+
 private:
 
   /* Hash function for a cutu_reader.  */
@@ -6840,6 +6846,11 @@ class cooked_indexer
   {
     m_index_storage->defer_entry (de);
   }
+
+  void set_parent_valid (CORE_ADDR start, CORE_ADDR end)
+  {
+    m_index_storage->set_parent_valid (start, end);
+  }
 };
 
 /* Subroutine of dwarf2_build_psymtabs_hard to simplify it.
@@ -18512,6 +18523,11 @@ cooked_indexer::index_dies (cutu_reader *reader,
                             + to_underlying (reader->cu->header.sect_off)
                             + reader->cu->header.get_length ());
 
+  const CORE_ADDR start_cu
+    = parent_map::form_addr (sect_offset (info_ptr - reader->buffer),
+                            reader->cu->per_cu->is_dwz,
+                            reader->cu->per_cu->is_debug_types);
+
   while (info_ptr < end_ptr)
     {
       sect_offset this_die = (sect_offset) (info_ptr - reader->buffer);
@@ -18662,6 +18678,14 @@ cooked_indexer::index_dies (cutu_reader *reader,
        }
     }
 
+  {
+    CORE_ADDR end_prev_die
+      = parent_map::form_addr (sect_offset (info_ptr - reader->buffer - 1),
+                              reader->cu->per_cu->is_dwz,
+                              reader->cu->per_cu->is_debug_types);
+    set_parent_valid (start_cu, end_prev_die);
+  }
+
   return info_ptr;
 }
 
-- 
2.35.3


++++++ gdb-symtab-recurse-into-c-dw_tag_subprogram-dies-for.patch ++++++
>From 541d6970c278dc5a8e9e32246b7139261a687592 Mon Sep 17 00:00:00 2001
From: Tom de Vries <[email protected]>
Date: Thu, 7 Dec 2023 10:36:07 +0100
Subject: [PATCH 09/11] [gdb/symtab] Recurse into c++ DW_TAG_subprogram DIEs
 for cooked index

Recurse into c++ DW_TAG_subprogram DIEs for cooked index, to add
DW_TAG_inlined_subroutine entries.

Tested on x86_64-linux.
---
 gdb/dwarf2/read.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index d2d50b5c9cc..39f6e480e19 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -18689,7 +18689,8 @@ cooked_indexer::index_dies (cutu_reader *reader,
 
            case DW_TAG_subprogram:
              if ((m_language == language_fortran
-                  || m_language == language_ada)
+                  || m_language == language_ada
+                  || m_language == language_cplus)
                  && this_entry != nullptr)
                {
                  info_ptr = recurse (reader, info_ptr, this_entry, true);
-- 
2.35.3


++++++ gdb-symtab-refactor-condition-in-scan_attributes.patch ++++++
>From 0bba1c5bdbcb404327ba4d5f35254b96d2e48108 Mon Sep 17 00:00:00 2001
From: Tom de Vries <[email protected]>
Date: Mon, 11 Dec 2023 15:41:26 +0100
Subject: [PATCH 01/11] [gdb/symtab] Refactor condition in scan_attributes

In scan_attributes there's code:
...
          if (new_reader->cu == reader->cu
              && new_info_ptr > watermark_ptr
              && *parent_entry == nullptr)
            ...
          else if (*parent_entry == nullptr)
            ...
...
that uses the "*parent_entry == nullptr" condition twice.

Make this somewhat more readable by factoring out the condition:
...
          if (*parent_entry == nullptr)
            {
              if (new_reader->cu == reader->cu
                  && new_info_ptr > watermark_ptr)
                ...
              else
                ...
            }
...

This also allows us to factor out "form_addr (origin_offset, origin_is_dwz)".

Tested on x86_64-linux.
---
 gdb/dwarf2/read.c | 18 ++++++++++--------
 1 file changed, 10 insertions(+), 8 deletions(-)

diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 2339cceb829..00471d20d41 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -18315,15 +18315,17 @@ cooked_indexer::scan_attributes (dwarf2_per_cu_data 
*scanning_per_cu,
          const gdb_byte *new_info_ptr = (new_reader->buffer
                                          + to_underlying (origin_offset));
 
-         if (new_reader->cu == reader->cu
-             && new_info_ptr > watermark_ptr
-             && *parent_entry == nullptr)
-           *maybe_defer = form_addr (origin_offset, origin_is_dwz);
-         else if (*parent_entry == nullptr)
+         if (*parent_entry == nullptr)
            {
-             CORE_ADDR lookup = form_addr (origin_offset, origin_is_dwz);
-             *parent_entry
-               = (cooked_index_entry *) m_die_range_map.find (lookup);
+             CORE_ADDR addr = form_addr (origin_offset, origin_is_dwz);
+             if (new_reader->cu == reader->cu
+                 && new_info_ptr > watermark_ptr)
+               *maybe_defer = addr;
+             else
+               {
+                 void *obj = m_die_range_map.find (addr);
+                 *parent_entry = static_cast <cooked_index_entry *> (obj);
+               }
            }
 
          unsigned int bytes_read;

base-commit: d445b7300b129a4886132ec31a23c7c2c894fa75
-- 
2.35.3


++++++ gdb-symtab-resolve-deferred-entries-inter-shard-case.patch ++++++
>From 7464f06e1a7ccf4c5908e563e4cf684744919dac Mon Sep 17 00:00:00 2001
From: Tom de Vries <[email protected]>
Date: Tue, 22 Aug 2023 14:24:42 +0200
Subject: [PATCH 05/11] [gdb/symtab] Resolve deferred entries, inter-shard case

Generically solve the case of inter-CU dependencies, including inter-shard
dependencies:
- mark deferred entries in new data structure m_deferred,
- return &parent_map::deferred in find_parent for deferred entries,
- defer all intra-CU dependencies that depend on deferred entries,
- defer all inter-CU dependencies (note that two subsequent patches implement
  optimizations to deal with this more optimally),
- move m_die_range_map and m_deferred_dies to cooked_index_shard, and
- move handle_deferred_dies to the cooked_index, where it is called in the
  constructor, and update it to handle the intra-shard case.

Handling units from the .debug_info section alongside units from the
.debug_types section requires us to extend form_addr to take is_debug_types
into account.

Tested on x86_64-linux.

PR symtab/30846
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30846
---
 gdb/dwarf2/cooked-index.c |  77 +++++++++++++++++++++++
 gdb/dwarf2/cooked-index.h | 105 ++++++++++++++++++++++++++++++-
 gdb/dwarf2/read.c         | 128 ++++++++++++++++++++++----------------
 3 files changed, 254 insertions(+), 56 deletions(-)

diff --git a/gdb/dwarf2/cooked-index.c b/gdb/dwarf2/cooked-index.c
index 2b7f9054fe5..4a0ccc78c5d 100644
--- a/gdb/dwarf2/cooked-index.c
+++ b/gdb/dwarf2/cooked-index.c
@@ -200,6 +200,12 @@ cooked_index_entry::write_scope (struct obstack *storage,
 
 /* See cooked-index.h.  */
 
+cooked_index_entry parent_map::deferred((sect_offset)0, (dwarf_tag)0,
+                                       (cooked_index_flag)0, nullptr,
+                                       nullptr, nullptr);
+
+/* See cooked-index.h.  */
+
 const cooked_index_entry *
 cooked_index::add (sect_offset die_offset, enum dwarf_tag tag,
                   cooked_index_flag flags, const char *name,
@@ -402,6 +408,8 @@ cooked_index::find (const std::string &name, bool 
completing)
 cooked_index_vector::cooked_index_vector (vec_type &&vec)
   : m_vector (std::move (vec))
 {
+  handle_deferred_entries ();
+
   for (auto &idx : m_vector)
     idx->finalize ();
 }
@@ -467,6 +475,75 @@ cooked_index_vector::get_main () const
   return result;
 }
 
+/* See cooked-index.h.  */
+
+const cooked_index_entry *
+cooked_index::resolve_deferred_entry
+  (const deferred_entry &de, const cooked_index_entry *parent_entry)
+{
+  reset_parent_deferred (parent_map::form_addr (de.die_offset, 
de.per_cu_2->is_dwz,
+                                               de.per_cu_2->is_debug_types));
+  return add (de.die_offset, de.tag, de.flags, de.name,
+             parent_entry, de.per_cu);
+}
+
+/* See cooked-index.h.  */
+
+const cooked_index_entry *
+cooked_index_vector::find_parent_deferred_entry
+  (const cooked_index::deferred_entry &entry) const
+{
+  const cooked_index_entry *parent_entry = nullptr;
+  for (auto &parent_map_shard : m_vector)
+    {
+      auto res = parent_map_shard->find_parent (entry.spec_offset);
+      if (res != nullptr)
+       {
+         parent_entry = res;
+         break;
+       }
+    }
+
+  return parent_entry;
+}
+
+/* See cooked-index.h.  */
+
+void
+cooked_index_vector::handle_deferred_entries ()
+{
+  bool changed;
+  bool deferred;
+  do
+    {
+      deferred = false;
+      changed = false;
+      for (auto &shard : m_vector)
+       for (auto it = shard->m_deferred_entries->begin ();
+            it != shard->m_deferred_entries->end (); )
+         {
+           const cooked_index_entry *parent_entry
+             = find_parent_deferred_entry (*it);
+           if (parent_entry == &parent_map::deferred)
+             {
+               deferred = true;
+               it++;
+               continue;
+             }
+           shard->resolve_deferred_entry (*it, parent_entry);
+           it = shard->m_deferred_entries->erase (it);
+           changed = true;
+         }
+    }
+  while (changed && deferred);
+
+  for (auto &shard : m_vector)
+    {
+      shard->m_die_range_map.reset (nullptr);
+      shard->m_deferred_entries.reset (nullptr);
+    }
+}
+
 void _initialize_cooked_index ();
 void
 _initialize_cooked_index ()
diff --git a/gdb/dwarf2/cooked-index.h b/gdb/dwarf2/cooked-index.h
index f4abc7a974e..a06d99532ed 100644
--- a/gdb/dwarf2/cooked-index.h
+++ b/gdb/dwarf2/cooked-index.h
@@ -34,6 +34,7 @@
 #include "dwarf2/mapped-index.h"
 #include "dwarf2/tag.h"
 #include "gdbsupport/range-chain.h"
+#include <unordered_set>
 
 struct dwarf2_per_cu_data;
 
@@ -236,19 +237,29 @@ struct cooked_index_entry : public allocate_on_obstack
 class parent_map
 {
 public:
+  /* A dummy cooked_index_entry to mark that computing the parent has been
+     deferred.  */
+  static cooked_index_entry deferred;
+
   /* A helper function to turn a section offset into an address that
      can be used in a parent_map.  */
-  static CORE_ADDR form_addr (sect_offset offset, bool is_dwz)
+  static CORE_ADDR form_addr (sect_offset offset, bool is_dwz,
+                             bool is_debug_types)
   {
     CORE_ADDR value = to_underlying (offset);
     if (is_dwz)
       value |= ((CORE_ADDR) 1) << (8 * sizeof (CORE_ADDR) - 1);
+    if (is_debug_types)
+      value |= ((CORE_ADDR) 1) << (8 * sizeof (CORE_ADDR) - 2);
     return value;
   }
 
   /* Find the parent of DIE LOOKUP.  */
   const cooked_index_entry *find_parent (CORE_ADDR lookup) const
   {
+    if (m_deferred.find (lookup) != m_deferred.end ())
+      return &parent_map::deferred;
+
     const void *obj = m_parent_map.find (lookup);
     return static_cast<const cooked_index_entry *> (obj);
   }
@@ -259,12 +270,28 @@ class parent_map
   {
     /* Calling set_empty with nullptr is currently not allowed.  */
     if (parent_entry != nullptr)
-      m_parent_map.set_empty (start, end, (void *)parent_entry);
+      {
+       gdb_assert (parent_entry != &parent_map::deferred);
+       m_parent_map.set_empty (start, end, (void *)parent_entry);
+      }
+  }
+
+  void set_parent_deferred (CORE_ADDR addr)
+  {
+    m_deferred.emplace (addr);
+  }
+
+  void reset_parent_deferred (CORE_ADDR addr)
+  {
+    m_deferred.erase (addr);
   }
 
 private:
   /* An addrmap that maps from section offsets to cooked_index_entry *.  */
   addrmap_mutable m_parent_map;
+
+  /* DIEs that are deffered.  */
+  std::unordered_set<CORE_ADDR> m_deferred;
 };
 
 class cooked_index_vector;
@@ -279,9 +306,14 @@ class cooked_index_vector;
 class cooked_index
 {
 public:
-  cooked_index () = default;
   DISABLE_COPY_AND_ASSIGN (cooked_index);
 
+  cooked_index ()
+  {
+    m_die_range_map.reset (new parent_map);
+    m_deferred_entries.reset (new std::vector<deferred_entry>);
+  }
+
   /* Create a new cooked_index_entry and register it with this object.
      Entries are owned by this object.  The new item is returned.  */
   const cooked_index_entry *add (sect_offset die_offset, enum dwarf_tag tag,
@@ -325,6 +357,52 @@ class cooked_index
      for completion, will be returned.  */
   range find (const std::string &name, bool completing);
 
+  /* Find the parent of DIE LOOKUP.  */
+  const cooked_index_entry *
+  find_parent (CORE_ADDR lookup) const
+  {
+    return m_die_range_map->find_parent (lookup);
+  }
+
+  /* Set the parent of DIES in range [START, END] to PARENT_ENTRY.  */
+  void set_parent (CORE_ADDR start, CORE_ADDR end,
+                  const cooked_index_entry *parent_entry)
+  {
+    m_die_range_map->set_parent (start, end, parent_entry);
+  }
+
+  void set_parent_deferred (CORE_ADDR addr)
+  {
+    m_die_range_map->set_parent_deferred (addr);
+  }
+
+  void reset_parent_deferred (CORE_ADDR addr)
+  {
+    m_die_range_map->reset_parent_deferred (addr);
+  }
+
+  /* A single deferred entry.  See m_deferred_entries.  */
+  struct deferred_entry
+  {
+    sect_offset die_offset;
+    const char *name;
+    CORE_ADDR spec_offset;
+    dwarf_tag tag;
+    cooked_index_flag flags;
+    dwarf2_per_cu_data *per_cu;
+    dwarf2_per_cu_data *per_cu_2;
+  };
+
+  /* Defer creating a cooked_index_entry corresponding to DEFERRED.  */
+  void defer_entry (deferred_entry de)
+  {
+    m_deferred_entries->push_back (de);
+  }
+
+  /* Variant of add that takes a deferred_entry as parameter.  */
+  const cooked_index_entry *resolve_deferred_entry
+    (const deferred_entry &entry, const cooked_index_entry *parent_entry);
+
 private:
 
   /* Return the entry that is believed to represent the program's
@@ -382,6 +460,20 @@ class cooked_index
      that the 'get' method is never called on this future, only
      'wait'.  */
   gdb::future<void> m_future;
+
+  /* An addrmap that maps from section offsets (see the form_addr
+     method) to newly-created entries.  See m_deferred_entries to
+     understand this.  */
+  std::unique_ptr<parent_map> m_die_range_map;
+
+  /* The generated DWARF can sometimes have the declaration for a
+     method in a class (or perhaps namespace) scope, with the
+     definition appearing outside this scope... just one of the many
+     bad things about DWARF.  In order to handle this situation, we
+     defer certain entries until the end of scanning, at which point
+     we'll know the containing context of all the DIEs that we might
+     have scanned.  This vector stores these deferred entries.  */
+  std::unique_ptr<std::vector<deferred_entry>> m_deferred_entries;
 };
 
 /* The main index of DIEs.  The parallel DIE indexers create
@@ -459,6 +551,13 @@ class cooked_index_vector : public dwarf_scanner_base
 
 private:
 
+  /* Find the parent corresponding to deferred entry ENTRY.  */
+  const cooked_index_entry *find_parent_deferred_entry
+    (const cooked_index::deferred_entry &entry) const;
+
+  /* Create cooked_index_entries for the deferred entries.  */
+  void handle_deferred_entries ();
+
   /* The vector of cooked_index objects.  This is stored because the
      entries are stored on the obstacks in those objects.  */
   vec_type m_vector;
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index ff5be8e7dc5..41fa8affcd0 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -6672,6 +6672,31 @@ class cooked_index_storage
     return &m_addrmap;
   }
 
+  /* Find the parent of DIE LOOKUP.  */
+  const cooked_index_entry *find_parent (CORE_ADDR lookup)
+  {
+    return m_index->find_parent (lookup);
+  }
+
+  /* Set the parent of DIES in range [START, END] to PARENT_ENTRY.  */
+  void set_parent (CORE_ADDR start, CORE_ADDR end,
+                  const cooked_index_entry *parent_entry)
+  {
+    m_index->set_parent (start, end, parent_entry);
+  }
+
+  /* Set the parent of DIE at ADDR as deferred.  */
+  void set_parent_deferred (CORE_ADDR addr)
+  {
+    m_index->set_parent_deferred (addr);
+  }
+
+  /* Defer creating a cooked_index_entry corresponding to deferred_entry DE.  
*/
+  void defer_entry (cooked_index::deferred_entry de)
+  {
+    m_index->defer_entry (de);
+  }
+
 private:
 
   /* Hash function for a cutu_reader.  */
@@ -6794,59 +6819,26 @@ class cooked_indexer
   /* Find the parent of DIE LOOKUP.  */
   const cooked_index_entry *find_parent (CORE_ADDR lookup) const
   {
-    return m_die_range_map.find_parent (lookup);
+    return m_index_storage->find_parent (lookup);
   }
 
   /* Set the parent of DIES in range [START, END] to PARENT_ENTRY.  */
   void set_parent (CORE_ADDR start, CORE_ADDR end,
                   const cooked_index_entry *parent_entry)
   {
-    m_die_range_map.set_parent (start, end, parent_entry);
+    m_index_storage->set_parent (start, end, parent_entry);
   }
 
-  /* A single deferred entry.  */
-  struct deferred_entry
-  {
-    sect_offset die_offset;
-    const char *name;
-    CORE_ADDR spec_offset;
-    dwarf_tag tag;
-    cooked_index_flag flags;
-  };
-
-  /* The generated DWARF can sometimes have the declaration for a
-     method in a class (or perhaps namespace) scope, with the
-     definition appearing outside this scope... just one of the many
-     bad things about DWARF.  In order to handle this situation, we
-     defer certain entries until the end of scanning, at which point
-     we'll know the containing context of all the DIEs that we might
-     have scanned.  This vector stores these deferred entries.  */
-  std::vector<deferred_entry> m_deferred_entries;
-
-  /* Defer creating a cooked_index_entry corresponding to deferred_entry DE.  
*/
-  void defer_entry (const deferred_entry &de)
+  /* Set the parent of DIE at ADDR as deferred.  */
+  void set_parent_deferred (CORE_ADDR addr)
   {
-    m_deferred_entries.push_back (de);
+    m_index_storage->set_parent_deferred (addr);
   }
 
-  /* Create a cooked_index_entry corresponding to deferred_entry DE with
-     parent PARENT_ENTRY.  */
-  const cooked_index_entry *resolve_deferred_entry
-    (const deferred_entry &de, const cooked_index_entry *parent_entry)
-  {
-    return m_index_storage->add (de.die_offset, de.tag, de.flags, de.name,
-                                parent_entry, m_per_cu);
-  }
-
-  /* Create cooked_index_entries for the deferred entries.  */
-  void handle_deferred_entries ()
+  /* Defer creating a cooked_index_entry corresponding to deferred_entry DE.  
*/
+  void defer_entry (const cooked_index::deferred_entry &de)
   {
-    for (const auto &entry : m_deferred_entries)
-      {
-       const cooked_index_entry *parent_entry
-         = find_parent (entry.spec_offset);
-       resolve_deferred_entry (entry, parent_entry);
-      }
+    m_index_storage->defer_entry (de);
   }
 };
 
@@ -18346,13 +18338,36 @@ cooked_indexer::scan_attributes (dwarf2_per_cu_data 
*scanning_per_cu,
 
          if (*parent_entry == nullptr)
            {
+             gdb_assert (reader->cu->per_cu->is_debug_types
+                         == new_reader->cu->per_cu->is_debug_types);
              CORE_ADDR addr
-               = parent_map::form_addr (origin_offset, origin_is_dwz);
-             if (new_reader->cu == reader->cu
-                 && new_info_ptr > watermark_ptr)
-               *maybe_defer = addr;
+               = parent_map::form_addr (origin_offset, origin_is_dwz,
+                                        reader->cu->per_cu->is_debug_types);
+             if (new_reader->cu == reader->cu)
+               {
+                 /* Intra-CU case.  */
+                 if (new_info_ptr > watermark_ptr)
+                   {
+                     /* Defer because origin is not read yet.  */
+                     *maybe_defer = addr;
+                   }
+                 else
+                   {
+                     auto tmp = find_parent (addr);
+                     if (tmp == &parent_map::deferred)
+                       {
+                         /* Defer because origin is deferred.  */
+                         *maybe_defer = addr;
+                       }
+                     else
+                       *parent_entry = tmp;
+                   }
+               }
              else
-               *parent_entry = find_parent (addr);
+               {
+                 /* Inter-CU case.  */
+                 *maybe_defer = addr;
+               }
            }
 
          unsigned int bytes_read;
@@ -18475,10 +18490,12 @@ cooked_indexer::recurse (cutu_reader *reader,
         limit the range to the children of parent_entry.  */
       CORE_ADDR start
        = parent_map::form_addr (parent_entry->die_offset + 1,
-                                reader->cu->per_cu->is_dwz);
+                                reader->cu->per_cu->is_dwz,
+                                reader->cu->per_cu->is_debug_types);
       CORE_ADDR end
        = parent_map::form_addr (sect_offset (info_ptr - 1 - reader->buffer),
-                                reader->cu->per_cu->is_dwz);
+                                reader->cu->per_cu->is_dwz,
+                                reader->cu->per_cu->is_debug_types);
       set_parent (start, end, parent_entry);
     }
 
@@ -18545,9 +18562,16 @@ cooked_indexer::index_dies (cutu_reader *reader,
       if (name != nullptr)
        {
          if (defer != 0)
-           defer_entry ({
-               this_die, name, defer, abbrev->tag, flags
-             });
+           {
+             CORE_ADDR addr
+               = parent_map::form_addr (this_die, reader->cu->per_cu->is_dwz,
+                                        reader->cu->per_cu->is_debug_types);
+             set_parent_deferred (addr);
+             defer_entry ({
+                 this_die, name, defer, abbrev->tag, flags, m_per_cu,
+                 reader->cu->per_cu
+               });
+           }
          else
            this_entry = m_index_storage->add (this_die, abbrev->tag, flags,
                                               name, this_parent_entry,
@@ -18649,8 +18673,6 @@ cooked_indexer::make_index (cutu_reader *reader)
   if (!reader->comp_unit_die->has_children)
     return;
   index_dies (reader, reader->info_ptr, nullptr, false);
-
-  handle_deferred_entries ();
 }
 
 /* An implementation of quick_symbol_functions for the cooked DWARF
-- 
2.35.3


++++++ gdb-symtab-resolve-deferred-entries-intra-shard-case.patch ++++++
>From a4bf216accd43b25ea9b9b7507c93eb973872a82 Mon Sep 17 00:00:00 2001
From: Tom de Vries <[email protected]>
Date: Sun, 24 Sep 2023 11:43:24 +0200
Subject: [PATCH 07/11] [gdb/symtab] Resolve deferred entries, intra-shard case

In patch "[gdb/symtab] Resolve deferred entries, inter-shard case" we've
solved the generic case of handling deferred entries.

Now add an optimization that handles deferred entries with an intra-shard
dependency in the parallel for.

Tested on x86_64-linux.
---
 gdb/dwarf2/cooked-index.c | 35 +++++++++++++++++++++++++++++++++++
 gdb/dwarf2/cooked-index.h |  7 +++++++
 gdb/dwarf2/read.c         | 10 ++++++++++
 3 files changed, 52 insertions(+)

diff --git a/gdb/dwarf2/cooked-index.c b/gdb/dwarf2/cooked-index.c
index cef57a96384..d8a12bee265 100644
--- a/gdb/dwarf2/cooked-index.c
+++ b/gdb/dwarf2/cooked-index.c
@@ -408,6 +408,7 @@ cooked_index::find (const std::string &name, bool 
completing)
 cooked_index_vector::cooked_index_vector (vec_type &&vec)
   : m_vector (std::move (vec))
 {
+  /* Handle deferred entries, inter-cu case.  */
   handle_deferred_entries ();
 
   for (auto &idx : m_vector)
@@ -477,6 +478,40 @@ cooked_index_vector::get_main () const
 
 /* See cooked-index.h.  */
 
+const cooked_index_entry *
+cooked_index::find_parent_deferred_entry
+  (const cooked_index::deferred_entry &entry) const
+{
+  return find_parent (entry.spec_offset);
+}
+
+/* See cooked-index.h.  */
+
+void
+cooked_index::handle_deferred_entries ()
+{
+  for (auto it = m_deferred_entries->begin (); it != m_deferred_entries->end 
(); )
+    {
+      const deferred_entry & deferred_entry = *it;
+      if (!parent_valid (deferred_entry.spec_offset))
+       {
+         it++;
+         continue;
+       }
+      const cooked_index_entry *parent_entry
+       = find_parent_deferred_entry (deferred_entry);
+      if (parent_entry == &parent_map::deferred)
+       {
+         it++;
+         continue;
+       }
+      resolve_deferred_entry (deferred_entry, parent_entry);
+      it = m_deferred_entries->erase (it);
+    }
+}
+
+/* See cooked-index.h.  */
+
 const cooked_index_entry *
 cooked_index::resolve_deferred_entry
   (const deferred_entry &de, const cooked_index_entry *parent_entry)
diff --git a/gdb/dwarf2/cooked-index.h b/gdb/dwarf2/cooked-index.h
index 9d836379666..bda1ed1e155 100644
--- a/gdb/dwarf2/cooked-index.h
+++ b/gdb/dwarf2/cooked-index.h
@@ -404,6 +404,13 @@ class cooked_index
   const cooked_index_entry *resolve_deferred_entry
     (const deferred_entry &entry, const cooked_index_entry *parent_entry);
 
+  /* Find the parent entry for deferred_entry ENTRY.  */
+  const cooked_index_entry *find_parent_deferred_entry
+    (const cooked_index::deferred_entry &entry) const;
+
+  /* Create cooked_index_entries for the deferred entries.  */
+  void handle_deferred_entries ();
+
   /* Mark parents in range [START, END] as valid .  */
   void set_parent_valid (CORE_ADDR start, CORE_ADDR end)
   {
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index ba21b6a14c9..0ab3e1a1500 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -6697,6 +6697,12 @@ class cooked_index_storage
     m_index->defer_entry (de);
   }
 
+  /* Handle deferred entries, intra-cu case.  */
+  void handle_deferred_entries ()
+  {
+    m_index->handle_deferred_entries ();
+  }
+
   /* Mark parents in range [START, END] as valid .  */
   void set_parent_valid (CORE_ADDR start, CORE_ADDR end)
   {
@@ -7183,6 +7189,10 @@ dwarf2_build_psymtabs_hard (dwarf2_per_objfile 
*per_objfile)
                errors.push_back (std::move (except));
              }
          }
+
+       /* Handle deferred entries, intra-cu case.  */
+       thread_storage.handle_deferred_entries ();
+
        return result_type (thread_storage.release (), std::move (errors));
       }, task_size);
 
-- 
2.35.3

Reply via email to