authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2020-01-25 14:06:46+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-01-25 16:12:11-05:00
log8516ee392c8e1e29b3968a7c9c8812013414004c
tree2e9ff7fb9619b0d2e118c4ebdba6ecc5fb280cea
parenta4a93306482c4f7c331a2e8b7ecd5a1e5c56bf69

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.

1 files changed, 15 insertions(+), 8 deletions(-)

lib/std/debug.zig+15-8
...@@ -1377,9 +1377,13 @@ pub const DwarfInfo = struct {...@@ -1377,9 +1377,13 @@ pub const DwarfInfo = struct {
1377 if (compile_unit.pc_range) |range| {1377 if (compile_unit.pc_range) |range| {
1378 if (target_address >= range.start and target_address < range.end) return compile_unit;1378 if (target_address >= range.start and target_address < range.end) return compile_unit;
1379 }1379 }
1380 if (compile_unit.die.getAttrSecOffset(DW.AT_ranges)) |ranges_offset| {1380 if (di.debug_ranges) |debug_ranges| {
1381 var base_address: usize = 0;1381 if (compile_unit.die.getAttrSecOffset(DW.AT_ranges)) |ranges_offset| {
1382 if (di.debug_ranges) |debug_ranges| {1382 // All the addresses in the list are relative to the value
1383 // specified by DW_AT_low_pc or to some other value encoded
1384 // in the list itself
1385 var base_address = try compile_unit.die.getAttrAddr(DW.AT_low_pc);
1386
1383 try di.dwarf_seekable_stream.seekTo(debug_ranges.offset + ranges_offset);1387 try di.dwarf_seekable_stream.seekTo(debug_ranges.offset + ranges_offset);
1384 while (true) {1388 while (true) {
1385 const begin_addr = try di.dwarf_in_stream.readIntLittle(usize);1389 const begin_addr = try di.dwarf_in_stream.readIntLittle(usize);
...@@ -1387,18 +1391,21 @@ pub const DwarfInfo = struct {...@@ -1387,18 +1391,21 @@ pub const DwarfInfo = struct {
1387 if (begin_addr == 0 and end_addr == 0) {1391 if (begin_addr == 0 and end_addr == 0) {
1388 break;1392 break;
1389 }1393 }
1394 // This entry selects a new value for the base address
1390 if (begin_addr == maxInt(usize)) {1395 if (begin_addr == maxInt(usize)) {
1391 base_address = begin_addr;1396 base_address = end_addr;
1392 continue;1397 continue;
1393 }1398 }
1394 if (target_address >= begin_addr and target_address < end_addr) {1399 if (target_address >= base_address + begin_addr and target_address < base_address + end_addr) {
1395 return compile_unit;1400 return compile_unit;
1396 }1401 }
1397 }1402 }
1403
1404 return error.InvalidDebugInfo;
1405 } else |err| {
1406 if (err != error.MissingDebugInfo) return err;
1407 continue;
1398 }1408 }
1399 } else |err| {
1400 if (err != error.MissingDebugInfo) return err;
1401 continue;
1402 }1409 }
1403 }1410 }
1404 return error.MissingDebugInfo;1411 return error.MissingDebugInfo;