aboutsummaryrefslogtreecommitdiff
path: root/gdb
diff options
context:
space:
mode:
authorAuthor: Tom Tromey <tom@tromey.com>2024-11-27 18:48:43 +0100
committerTom de Vries <tdevries@suse.de>2024-11-27 18:48:43 +0100
commite33e55b6651f230762ccfe248037263e511b41b3 (patch)
treec8a97ae35a49bd9ba7df72dc8e0f50115bb02e29 /gdb
parent[gdb/tdep] s390: Add arch15 record/replay support (diff)
downloadbinutils-gdb-e33e55b6651f230762ccfe248037263e511b41b3.tar.gz
binutils-gdb-e33e55b6651f230762ccfe248037263e511b41b3.tar.bz2
binutils-gdb-e33e55b6651f230762ccfe248037263e511b41b3.zip
[gdb/symtab] Fix parent map when handling .debug_info and .debug_types
Consider test-case: ... $ cat test.c namespace sp1 { class A { int i; const int f1 = 1; ... const int f29 = 1; }; } sp1::A a; void _start (void) {} $ cat test2.c namespace sp2 { class B { float f; const float f1 = 1; ... const float f29 = 1; }; } sp2::B b; ... compiled like this: ... $ g++ test.c -gdwarf-4 -c -g -fdebug-types-section $ g++ test2.c -gdwarf-5 -c -g -fdebug-types-section $ g++ -g test.o test2.o -nostdlib ... Using: ... $ gdb -q -batch -iex "maint set worker-threads 0" a.out -ex "maint print objfiles" ... we get a cooked index entry with incorrect parent: ... [29] ((cooked_index_entry *) 0x3c57d1a0) name: B canonical: B qualified: sp1::A::B DWARF tag: DW_TAG_class_type flags: 0x0 [] DIE offset: 0x154 parent: ((cooked_index_entry *) 0x3c57d110) [A] ... The problem is that the parent map assumes that all offsets are in the same section. Fix this by using dwarf2_section_info::buffer-relative addresses instead, which get us instead: ... [29] ((cooked_index_entry *) 0x3f0962b0) name: B canonical: B qualified: sp2::B DWARF tag: DW_TAG_class_type flags: 0x0 [] DIE offset: 0x154 parent: ((cooked_index_entry *) 0x3f096280) [sp2] ... Tested on x86_64-linux. PR symtab/32225 Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32225
Diffstat (limited to 'gdb')
-rw-r--r--gdb/dwarf2/parent-map.h11
-rw-r--r--gdb/dwarf2/read.c12
2 files changed, 9 insertions, 14 deletions
diff --git a/gdb/dwarf2/parent-map.h b/gdb/dwarf2/parent-map.h
index 6cff548a2a7..a9ea34ec08c 100644
--- a/gdb/dwarf2/parent-map.h
+++ b/gdb/dwarf2/parent-map.h
@@ -69,18 +69,15 @@ public:
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. */
+ /* A reasonably opaque type that is used as part of a DIE range. */
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)
+ static addr_type form_addr (const gdb_byte *info_ptr)
{
- CORE_ADDR value = to_underlying (offset);
- if (is_dwz)
- value |= ((CORE_ADDR) 1) << (8 * sizeof (CORE_ADDR) - 1);
- return addr_type (value);
+ static_assert (sizeof (addr_type) >= sizeof (uintptr_t));
+ return (addr_type) (uintptr_t) info_ptr;
}
/* Add a new entry to this map. DIEs from START to END, inclusive,
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 3f78b966620..583bd97ad02 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -16439,8 +16439,7 @@ cooked_indexer::scan_attributes (dwarf2_per_cu_data *scanning_per_cu,
with a NULL result when when we see a reference to a
DIE in another CU that we may or may not have
imported locally. */
- parent_map::addr_type addr
- = parent_map::form_addr (origin_offset, origin_is_dwz);
+ parent_map::addr_type addr = parent_map::form_addr (new_info_ptr);
if (new_reader->cu != reader->cu || new_info_ptr > watermark_ptr)
*maybe_defer = addr;
else
@@ -16579,11 +16578,10 @@ 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. */
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);
+ = parent_map::form_addr (reader->buffer
+ + to_underlying (parent_entry->die_offset)
+ + 1);
+ parent_map::addr_type end = parent_map::form_addr (info_ptr - 1);
m_die_range_map->add_entry (start, end, parent_entry);
}