Fix parsing of DW_AT_Ranges debug entry

Follow the specification about what the base address is and how it can
be changed by some entries in the list itself.
This commit is contained in:
LemonBoy 2020-01-25 14:06:46 +01:00 committed by Andrew Kelley
parent a4a9330648
commit 8516ee392c

View File

@ -1377,9 +1377,13 @@ pub const DwarfInfo = struct {
if (compile_unit.pc_range) |range| {
if (target_address >= range.start and target_address < range.end) return compile_unit;
}
if (compile_unit.die.getAttrSecOffset(DW.AT_ranges)) |ranges_offset| {
var base_address: usize = 0;
if (di.debug_ranges) |debug_ranges| {
if (di.debug_ranges) |debug_ranges| {
if (compile_unit.die.getAttrSecOffset(DW.AT_ranges)) |ranges_offset| {
// All the addresses in the list are relative to the value
// specified by DW_AT_low_pc or to some other value encoded
// in the list itself
var base_address = try compile_unit.die.getAttrAddr(DW.AT_low_pc);
try di.dwarf_seekable_stream.seekTo(debug_ranges.offset + ranges_offset);
while (true) {
const begin_addr = try di.dwarf_in_stream.readIntLittle(usize);
@ -1387,18 +1391,21 @@ pub const DwarfInfo = struct {
if (begin_addr == 0 and end_addr == 0) {
break;
}
// This entry selects a new value for the base address
if (begin_addr == maxInt(usize)) {
base_address = begin_addr;
base_address = end_addr;
continue;
}
if (target_address >= begin_addr and target_address < end_addr) {
if (target_address >= base_address + begin_addr and target_address < base_address + end_addr) {
return compile_unit;
}
}
return error.InvalidDebugInfo;
} else |err| {
if (err != error.MissingDebugInfo) return err;
continue;
}
} else |err| {
if (err != error.MissingDebugInfo) return err;
continue;
}
}
return error.MissingDebugInfo;