From: Tom Tromey <tom@tromey.com>
To: gdb-patches@sourceware.org
Cc: Tom de Vries <tdevries@suse.de>
Subject: [PATCH 4/7] Introduce class parent_map for DIE range map
Date: Wed, 17 Jan 2024 11:58:51 -0700 [thread overview]
Message-ID: <20240117-die-map-madness-v1-4-42fb435ad1ed@tromey.com> (raw)
In-Reply-To: <20240117-die-map-madness-v1-0-42fb435ad1ed@tromey.com>
This changes the DIE range map from a raw addrmap to a custom class.
A new type is used to represent the ranges, in an attempt to gain a
little type safety as well.
Note that the new code includes a map-of-maps type. This is not used
yet, but will be used in the next patch.
Co-Authored-By: Tom de Vries <tdevries@suse.de>
---
gdb/dwarf2/cooked-index.h | 7 +--
gdb/dwarf2/parent-map.h | 132 ++++++++++++++++++++++++++++++++++++++++++++++
gdb/dwarf2/read.c | 46 +++++++---------
3 files changed, 154 insertions(+), 31 deletions(-)
diff --git a/gdb/dwarf2/cooked-index.h b/gdb/dwarf2/cooked-index.h
index ebaed04753c..442ee9e14fd 100644
--- a/gdb/dwarf2/cooked-index.h
+++ b/gdb/dwarf2/cooked-index.h
@@ -35,6 +35,7 @@
#include "dwarf2/read.h"
#include "dwarf2/tag.h"
#include "dwarf2/abbrev-cache.h"
+#include "dwarf2/parent-map.h"
#include "gdbsupport/range-chain.h"
#include "gdbsupport/task-group.h"
#include "complaints.h"
@@ -74,7 +75,7 @@ DEF_ENUM_FLAGS_TYPE (enum cooked_index_flag_enum, cooked_index_flag);
union cooked_index_entry_ref
{
- cooked_index_entry_ref (CORE_ADDR deferred_)
+ cooked_index_entry_ref (parent_map::addr_type deferred_)
{
deferred = deferred_;
}
@@ -85,7 +86,7 @@ union cooked_index_entry_ref
}
const cooked_index_entry *resolved;
- CORE_ADDR deferred;
+ parent_map::addr_type deferred;
};
/* Return a string representation of FLAGS. */
@@ -265,7 +266,7 @@ struct cooked_index_entry : public allocate_on_obstack
}
/* Return deferred parent entry. */
- CORE_ADDR get_deferred_parent () const
+ parent_map::addr_type get_deferred_parent () const
{
gdb_assert ((flags & IS_PARENT_DEFERRED) != 0);
return m_parent_entry.deferred;
diff --git a/gdb/dwarf2/parent-map.h b/gdb/dwarf2/parent-map.h
new file mode 100644
index 00000000000..f070d505356
--- /dev/null
+++ b/gdb/dwarf2/parent-map.h
@@ -0,0 +1,132 @@
+/* DIE indexing
+
+ Copyright (C) 2024 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ 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/>. */
+
+#ifndef GDB_DWARF2_PARENT_MAP_H
+#define GDB_DWARF2_PARENT_MAP_H
+
+#include <algorithm>
+
+class cooked_index_entry;
+
+/* A class that handles mapping from a DIE range to a parent
+ entry.
+
+ 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. */
+class parent_map
+{
+public:
+
+ parent_map () = default;
+ ~parent_map () = default;
+
+ /* Move only. */
+ DISABLE_COPY_AND_ASSIGN (parent_map);
+ parent_map (parent_map &&) = default;
+ parent_map &operator= (parent_map &&) = default;
+
+ /* A reasonably opaque type that is used here to combine a section
+ offset and the 'dwz' flag into a single value. */
+ enum addr_type : CORE_ADDR { };
+
+ /* Turn a section offset into a value that can be used in a parent
+ map. */
+ static addr_type 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 addr_type (value);
+ }
+
+ /* Add a new entry to this map. DIEs from START to END, inclusive,
+ are mapped to PARENT. */
+ void add_entry (addr_type start, addr_type end,
+ const cooked_index_entry *parent)
+ {
+ gdb_assert (parent != nullptr);
+ m_map.set_empty (start, end, (void *) parent);
+ }
+
+ /* Look up an entry in this map. */
+ const cooked_index_entry *find (addr_type search) const
+ {
+ return static_cast<const cooked_index_entry *> (m_map.find (search));
+ }
+
+ /* Return a fixed addrmap that is equivalent to this map. */
+ addrmap_fixed *to_fixed (struct obstack *obstack) const
+ {
+ return new (obstack) addrmap_fixed (obstack, &m_map);
+ }
+
+private:
+
+ /* An addrmap that maps from section offsets to cooked_index_entry *. */
+ addrmap_mutable m_map;
+};
+
+/* Keep a collection of parent_map objects, and allow for lookups
+ across all of them. */
+class parent_map_map
+{
+public:
+
+ parent_map_map () = default;
+ ~parent_map_map () = default;
+
+ DISABLE_COPY_AND_ASSIGN (parent_map_map);
+
+ /* Add a parent_map to this map. */
+ void add_map (const parent_map &map)
+ {
+ m_maps.push_back (map.to_fixed (&m_storage));
+ }
+
+ /* Look up an entry in this map. */
+ const cooked_index_entry *find (parent_map::addr_type search) const
+ {
+ for (const auto &iter : m_maps)
+ {
+ const cooked_index_entry *result
+ = static_cast<const cooked_index_entry *> (iter->find (search));
+ if (result != nullptr)
+ return result;
+ }
+ return nullptr;
+ }
+
+private:
+
+ /* Storage for the convert maps. */
+ auto_obstack m_storage;
+
+ /* While conceptually this class is a combination of parent_maps, in
+ practice it is just a number of fixed maps. This is important
+ because we want to allow concurrent lookups, but a mutable
+ addrmap is based on a splay-tree, which is not thread-safe, even
+ for nominally read-only lookups. */
+ std::vector<addrmap_fixed *> m_maps;
+};
+
+#endif /* GDB_DWARF2_PARENT_MAP_H */
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index bf64d89ef3c..585c15212f8 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -96,6 +96,7 @@
#include "split-name.h"
#include "gdbsupport/thread-pool.h"
#include "run-on-main-thread.h"
+#include "dwarf2/parent-map.h"
/* When == 1, print basic high level tracing messages.
When > 1, be more verbose.
@@ -4473,16 +4474,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);
@@ -4520,7 +4511,7 @@ class cooked_indexer
cooked_index_flag *flags,
sect_offset *sibling_offset,
const cooked_index_entry **parent_entry,
- CORE_ADDR *maybe_defer,
+ parent_map::addr_type *maybe_defer,
bool for_specification);
/* Handle DW_TAG_imported_unit, by scanning the DIE to find
@@ -4547,10 +4538,9 @@ class cooked_indexer
/* The language that we're assuming when reading. */
enum language m_language;
- /* 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;
+ /* Map from DIE ranges to newly-created entries. See
+ m_deferred_entries to understand this. */
+ 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
@@ -16165,7 +16155,7 @@ cooked_indexer::scan_attributes (dwarf2_per_cu_data *scanning_per_cu,
cooked_index_flag *flags,
sect_offset *sibling_offset,
const cooked_index_entry **parent_entry,
- CORE_ADDR *maybe_defer,
+ parent_map::addr_type *maybe_defer,
bool for_specification)
{
bool origin_is_dwz = false;
@@ -16337,15 +16327,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);
+ parent_map::addr_type 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 = m_die_range_map.find (addr);
}
unsigned int bytes_read;
@@ -16463,11 +16451,13 @@ cooked_indexer::recurse (cutu_reader *reader,
{
/* 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 = form_addr (parent_entry->die_offset + 1,
- reader->cu->per_cu->is_dwz);
- CORE_ADDR end = form_addr (sect_offset (info_ptr - 1 - reader->buffer),
+ parent_map::addr_type start
+ = parent_map::form_addr (parent_entry->die_offset + 1,
+ reader->cu->per_cu->is_dwz);
+ parent_map::addr_type 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);
+ m_die_range_map.add_entry (start, end, parent_entry);
}
return info_ptr;
@@ -16509,7 +16499,7 @@ cooked_indexer::index_dies (cutu_reader *reader,
const char *name = nullptr;
const char *linkage_name = nullptr;
- CORE_ADDR defer = 0;
+ parent_map::addr_type defer {};
cooked_index_flag flags = IS_STATIC;
sect_offset sibling {};
const cooked_index_entry *this_parent_entry = parent_entry;
@@ -16645,8 +16635,8 @@ cooked_indexer::make_index (cutu_reader *reader)
for (const auto &entry : m_deferred_entries)
{
- void *obj = m_die_range_map.find (entry->get_deferred_parent ());
- cooked_index_entry *parent = static_cast<cooked_index_entry *> (obj);
+ const cooked_index_entry *parent
+ = m_die_range_map.find (entry->get_deferred_parent ());
entry->resolve_parent (parent);
}
}
--
2.43.0
next prev parent reply other threads:[~2024-01-17 18:59 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-01-17 18:58 [PATCH gdb/symtab 0/7] Compute DWARF entry parents across CUs Tom Tromey
2024-01-17 18:58 ` [PATCH gdb/symtab 1/7] Refactor condition in scan_attributes Tom Tromey
2024-01-17 18:58 ` [PATCH 2/7] Change handling of DW_TAG_enumeration_type in DWARF scanner Tom Tromey
2024-01-17 18:58 ` [PATCH 3/7] Add move operators for addrmap Tom Tromey
2024-01-17 18:58 ` Tom Tromey [this message]
2024-01-17 18:58 ` [PATCH 5/7] Correctly handle DIE parent computations Tom Tromey
2024-01-17 18:58 ` [PATCH gdb/testsuite 6/7] Add gdb.dwarf2/forward-spec-inter-cu.exp Tom Tromey
2024-01-17 18:58 ` [PATCH gdb/testsuite 7/7] Add gdb.dwarf2/backward-spec-inter-cu.exp Tom Tromey
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240117-die-map-madness-v1-4-42fb435ad1ed@tromey.com \
--to=tom@tromey.com \
--cc=gdb-patches@sourceware.org \
--cc=tdevries@suse.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).