aboutsummaryrefslogtreecommitdiff
path: root/gdb/dwarf2/read-gdb-index.c
diff options
context:
space:
mode:
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"