diff options
author | Author: Tom Tromey <tom@tromey.com> | 2024-11-27 18:48:43 +0100 |
---|---|---|
committer | Tom de Vries <tdevries@suse.de> | 2024-11-27 18:48:43 +0100 |
commit | e33e55b6651f230762ccfe248037263e511b41b3 (patch) | |
tree | c8a97ae35a49bd9ba7df72dc8e0f50115bb02e29 /gdb | |
parent | [gdb/tdep] s390: Add arch15 record/replay support (diff) | |
download | binutils-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.h | 11 | ||||
-rw-r--r-- | gdb/dwarf2/read.c | 12 |
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); } |