diff options
author | Tom de Vries <tdevries@suse.de> | 2024-10-08 12:27:20 +0200 |
---|---|---|
committer | Tom de Vries <tdevries@suse.de> | 2024-10-08 12:27:20 +0200 |
commit | 42d385542f5f948e68db256b249662683057b288 (patch) | |
tree | 4f0afe17b4485ddd50da7a18ae1e77ce953d0529 /gdb | |
parent | e808bbbe37dda4a3ec5872ff990090cc746ad7ac (diff) | |
download | binutils-42d385542f5f948e68db256b249662683057b288.zip binutils-42d385542f5f948e68db256b249662683057b288.tar.gz binutils-42d385542f5f948e68db256b249662683057b288.tar.bz2 |
[gdb/symtab] Fix parent of enumerator
As mentioned in commit 489b82720f5 ('[gdb/symtab] Revert "Change handling of
DW_TAG_enumeration_type in DWARF scanner"'), when doing "maint print objfiles" in
test-case gdb.dwarf2/enum-type.exp, for val1 we get an entry without parent:
...
[27] ((cooked_index_entry *) 0x7fbbb4002ef0)
name: val1
canonical: val1
qualified: val1
DWARF tag: DW_TAG_enumerator
flags: 0x0 []
DIE offset: 0x124
parent: ((cooked_index_entry *) 0)
...
This happens here in cooked_indexer::index_dies:
...
info_ptr = recurse (reader, info_ptr,
is_enum_class ? this_entry : parent_entry,
fully);
...
when we're passing down a nullptr parent_entry, while the parent of this_entry
is deferred.
Fix this in cooked_indexer::index_dies by passing down a deffered parent
instead, such that we get:
...
[27] ((cooked_index_entry *) 0x7ff0e4002ef0)^M
name: val1^M
canonical: val1^M
qualified: ns::val1^M
DWARF tag: DW_TAG_enumerator^M
flags: 0x0 []^M
DIE offset: 0x124^M
parent: ((cooked_index_entry *) 0x7ff0e4002f20) [ns]^M
...
Tested on x86_64-linux.
Approved-By: Tom Tromey <tom@tromey.com>
Diffstat (limited to 'gdb')
-rw-r--r-- | gdb/dwarf2/read.c | 47 | ||||
-rw-r--r-- | gdb/testsuite/gdb.dwarf2/enum-type.exp | 15 |
2 files changed, 52 insertions, 10 deletions
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c index bf9eeef..95e7d6a 100644 --- a/gdb/dwarf2/read.c +++ b/gdb/dwarf2/read.c @@ -96,6 +96,7 @@ #include "run-on-main-thread.h" #include "dwarf2/parent-map.h" #include "dwarf2/error.h" +#include <variant> /* When == 1, print basic high level tracing messages. When > 1, be more verbose. @@ -4530,7 +4531,7 @@ private: bool is_dwz, bool for_scanning); - /* Index DIEs in the READER starting at INFO_PTR. PARENT_ENTRY is + /* Index DIEs in the READER starting at INFO_PTR. PARENT is the entry for the enclosing scope (nullptr at top level). FULLY is true when a full scan must be done -- in some languages, function scopes must be fully explored in order to find nested @@ -4538,7 +4539,8 @@ private: reading stopped. */ const gdb_byte *index_dies (cutu_reader *reader, const gdb_byte *info_ptr, - const cooked_index_entry *parent_entry, + std::variant<const cooked_index_entry *, + parent_map::addr_type> parent, bool fully); /* Scan the attributes for a given DIE and update the out @@ -4568,7 +4570,8 @@ private: m_die_range_map and then calling index_dies. */ const gdb_byte *recurse (cutu_reader *reader, const gdb_byte *info_ptr, - const cooked_index_entry *parent_entry, + std::variant<const cooked_index_entry *, + parent_map::addr_type> parent_entry, bool fully); /* The storage object, where the results are kept. */ @@ -16466,10 +16469,16 @@ cooked_indexer::index_imported_unit (cutu_reader *reader, const gdb_byte * cooked_indexer::recurse (cutu_reader *reader, const gdb_byte *info_ptr, - const cooked_index_entry *parent_entry, + std::variant<const cooked_index_entry *, + parent_map::addr_type> parent, bool fully) { - info_ptr = index_dies (reader, info_ptr, parent_entry, fully); + info_ptr = index_dies (reader, info_ptr, parent, fully); + + if (!std::holds_alternative<const cooked_index_entry *> (parent)) + return info_ptr; + const cooked_index_entry *parent_entry + = std::get<const cooked_index_entry *> (parent); if (parent_entry != nullptr) { @@ -16490,7 +16499,8 @@ cooked_indexer::recurse (cutu_reader *reader, const gdb_byte * cooked_indexer::index_dies (cutu_reader *reader, const gdb_byte *info_ptr, - const cooked_index_entry *parent_entry, + std::variant<const cooked_index_entry *, + parent_map::addr_type> parent, bool fully) { const gdb_byte *end_ptr = (reader->buffer @@ -16517,15 +16527,20 @@ cooked_indexer::index_dies (cutu_reader *reader, { info_ptr = skip_one_die (reader, info_ptr, abbrev, !fully); if (fully && abbrev->has_children) - info_ptr = index_dies (reader, info_ptr, parent_entry, fully); + info_ptr = index_dies (reader, info_ptr, parent, fully); continue; } const char *name = nullptr; const char *linkage_name = nullptr; parent_map::addr_type defer {}; + if (std::holds_alternative<parent_map::addr_type> (parent)) + defer = std::get<parent_map::addr_type> (parent); cooked_index_flag flags = IS_STATIC; sect_offset sibling {}; + const cooked_index_entry *parent_entry = nullptr; + if (std::holds_alternative<const cooked_index_entry *> (parent)) + parent_entry = std::get<const cooked_index_entry *> (parent); const cooked_index_entry *this_parent_entry = parent_entry; bool is_enum_class = false; @@ -16609,9 +16624,21 @@ cooked_indexer::index_dies (cutu_reader *reader, the enum itself as the parent, yielding names like "enum_class::enumerator"; otherwise we inject the names into our own parent scope. */ - info_ptr = recurse (reader, info_ptr, - is_enum_class ? this_entry : parent_entry, - fully); + { + std::variant<const cooked_index_entry *, + parent_map::addr_type> recurse_parent; + if (is_enum_class) + { + gdb_assert (this_entry != nullptr); + recurse_parent = this_entry; + } + else if (defer != 0) + recurse_parent = defer; + else + recurse_parent = parent_entry; + + info_ptr = recurse (reader, info_ptr, recurse_parent, fully); + } continue; case DW_TAG_module: diff --git a/gdb/testsuite/gdb.dwarf2/enum-type.exp b/gdb/testsuite/gdb.dwarf2/enum-type.exp index b2b3dc6..ec12db5 100644 --- a/gdb/testsuite/gdb.dwarf2/enum-type.exp +++ b/gdb/testsuite/gdb.dwarf2/enum-type.exp @@ -114,3 +114,18 @@ gdb_test "ptype enum EU" "type = enum EU {TWO = 2}" \ gdb_test_no_output "set lang c++" gdb_test "ptype enum EU" "type = enum EU : unsigned int {TWO = 2}" \ "ptype EU in C++" + +gdb_test "p ns::val1" \ + " = ns::val1" + +require !readnow +require {string equal [have_index $binfile] ""} + +set re_ws "\[ \t\]" + +gdb_test_lines "maint print objfiles" \ + "val1 has a parent" \ + [multi_line \ + "" \ + "$re_ws+qualified:$re_ws+ns::val1" \ + ".*"] |