aboutsummaryrefslogtreecommitdiff
path: root/gdb/dwarf2/read-gdb-index.c
diff options
context:
space:
mode:
authorTom de Vries <tdevries@suse.de>2025-10-07 10:25:57 +0200
committerTom de Vries <tdevries@suse.de>2025-10-07 10:25:57 +0200
commitae93841151eb133d6bee75544e15fc6c784b51e1 (patch)
tree1a7bdee5d464a9cdbb6b97f3ea3d43ecf5ad36cc /gdb/dwarf2/read-gdb-index.c
parent637f25e88675fa47e47f9cc5e2cf37384836b8a2 (diff)
downloadbinutils-ae93841151eb133d6bee75544e15fc6c784b51e1.zip
binutils-ae93841151eb133d6bee75544e15fc6c784b51e1.tar.gz
binutils-ae93841151eb133d6bee75544e15fc6c784b51e1.tar.bz2
[gdb/symtab] Improve invalid range check in create_addrmap_from_gdb_index
When running test-case gdb.tui/tui-missing-src.exp with target board gold-gdb-index (and likewise fission and fission-dwp) on aarch64-linux, I run into: ... FAIL: gdb.tui/tui-missing-src.exp: checking if inside f2 () ... Looking at the gold-gdb-index case, the problem is caused by the address table of the .gdb_index section: ... Address table: 000000000040066c 0000000000400694 0 000000000040053f 0000000000400563 1 ... The address range for f2 is [0x400694, 0x4006b8), but the address table says it's [0x40053f, 0x400563). The address 0x40053f is not even in a section: ... [Nr] Name Type Address Off Size ES Flg Lk Inf Al ... [12] .plt PROGBITS 00000000004004b8 0004b8 000050 10 AX 0 0 8 [13] .text PROGBITS 0000000000400540 000540 000178 00 AX 0 0 64 ... but part of the hole [0x400508, 0x400540) in between .plt and .text. Detect this in the invalid range check in create_addrmap_from_gdb_index. Tested on aarch64-linux. Approved-By: Simon Marchi <simon.marchi@efficios.com>
Diffstat (limited to 'gdb/dwarf2/read-gdb-index.c')
-rw-r--r--gdb/dwarf2/read-gdb-index.c56
1 files changed, 46 insertions, 10 deletions
diff --git a/gdb/dwarf2/read-gdb-index.c b/gdb/dwarf2/read-gdb-index.c
index 5354263..e02340f 100644
--- a/gdb/dwarf2/read-gdb-index.c
+++ b/gdb/dwarf2/read-gdb-index.c
@@ -597,13 +597,46 @@ static bool
create_addrmap_from_gdb_index (dwarf2_per_objfile *per_objfile,
mapped_gdb_index *index)
{
- const gdb_byte *iter, *end;
+ objfile *objfile = per_objfile->objfile;
addrmap_mutable mutable_map;
- iter = index->address_table.data ();
- end = iter + index->address_table.size ();
+ /* Build an unrelocated address map of the sections in this objfile. */
+ addrmap_mutable sect_map;
+ for (obj_section &s : objfile->sections ())
+ {
+ if (s.addr_unrel () >= s.endaddr_unrel ())
+ continue;
+
+ CORE_ADDR start = CORE_ADDR (s.addr_unrel ());
+ CORE_ADDR end_inclusive = CORE_ADDR (s.endaddr_unrel ()) - 1;
+ sect_map.set_empty (start, end_inclusive, &s);
+ }
+
+ auto find_section
+ = [&] (ULONGEST addr, struct obj_section *&cached_section)
+ {
+ if (cached_section != nullptr
+ && cached_section->contains (unrelocated_addr (addr)))
+ return cached_section;
+
+ cached_section = (struct obj_section *) sect_map.find (addr);
+ return cached_section;
+ };
+
+ auto invalid_range_warning = [&] (ULONGEST lo, ULONGEST hi)
+ {
+ warning (_(".gdb_index address table has invalid range (%s - %s),"
+ " ignoring .gdb_index"),
+ hex_string (lo), hex_string (hi));
+ return false;
+ };
+
+ /* Cache the section for possible re-use on the next entry. */
+ struct obj_section *prev_sect = nullptr;
+ const gdb_byte *iter = index->address_table.data ();
+ const gdb_byte *end = iter + index->address_table.size ();
while (iter < end)
{
ULONGEST hi, lo, cu_index;
@@ -615,12 +648,7 @@ create_addrmap_from_gdb_index (dwarf2_per_objfile *per_objfile,
iter += 4;
if (lo >= hi)
- {
- warning (_(".gdb_index address table has invalid range (%s - %s),"
- " ignoring .gdb_index"),
- hex_string (lo), hex_string (hi));
- return false;
- }
+ return invalid_range_warning (lo, hi);
if (cu_index >= index->units.size ())
{
@@ -630,8 +658,16 @@ create_addrmap_from_gdb_index (dwarf2_per_objfile *per_objfile,
return false;
}
+ /* Variable hi is the exclusive upper bound, get the inclusive one. */
+ CORE_ADDR hi_incl = hi - 1;
+
+ struct obj_section *lo_sect = find_section (lo, prev_sect);
+ struct obj_section *hi_sect = find_section (hi_incl, prev_sect);
+ if (lo_sect == nullptr || hi_sect == nullptr)
+ return invalid_range_warning (lo, hi);
+
bool full_range_p
- = mutable_map.set_empty (lo, hi - 1, index->units[cu_index]);
+ = mutable_map.set_empty (lo, hi_incl, index->units[cu_index]);
if (!full_range_p)
{
warning (_(".gdb_index address table has a range (%s - %s) that"