Skip to content

Commit b8daf0b

Browse files
committed
Improve DWARF local variable offset calculation
1 parent 83e8981 commit b8daf0b

File tree

1 file changed

+13
-6
lines changed

1 file changed

+13
-6
lines changed

plugins/dwarf/dwarf_import/src/dwarfdebuginfo.rs

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -411,27 +411,34 @@ impl DebugInfoBuilder {
411411
.and_then(|block_ranges| {
412412
block_ranges
413413
.unsorted_iter()
414-
.find_map(|x| self.range_data_offsets.values_overlap(x.start).next())
414+
.find_map(|x| self.range_data_offsets.values_overlap(x.start).next().cloned())
415415
})
416416
.or_else(|| {
417-
// Try using the offset at the adjustment 4 bytes after the function start, in case the function starts with a stack adjustment
417+
// Try using the offset at the adjustment 5 bytes after the function start, in case the function starts with a stack adjustment
418+
// Calculate final offset as (offset after initial stack adjustment) - (entry offset)
418419
// TODO: This is a decent heuristic but not perfect, since further adjustments could still be made
419-
self.range_data_offsets.values_overlap(func_addr + 4).next()
420+
if let Some(offset_after_stack_adjust) = self.range_data_offsets.values_overlap(func_addr + 5).next() {
421+
if let Some(entry_offset) = self.range_data_offsets.values_overlap(func_addr).next() {
422+
return Some(offset_after_stack_adjust - entry_offset);
423+
}
424+
}
425+
// No entry offset or no initial stack adjustment, fall through
426+
None
420427
})
421428
.or_else(|| {
422429
// If all else fails, use the function start address
423-
self.range_data_offsets.values_overlap(func_addr).next()
430+
self.range_data_offsets.values_overlap(func_addr).next().cloned()
424431
})
425432
else {
426433
// Unknown why, but this is happening with MachO + external dSYM
427434
debug!("Refusing to add a local variable ({}@{}) to function at {} without a known CIE offset.", name, offset, func_addr);
428435
return;
429436
};
430437

431-
// TODO: handle non-sp frame bases
438+
// TODO: handle non-sp-based locations
432439
// TODO: if not in a lexical block these can be wrong, see https://github.com/Vector35/binaryninja-api/issues/5882#issuecomment-2406065057
433440
let adjusted_offset = if function.use_cfa {
434-
// Apply CFA offset to variable storage offset if DW_AT_frame_base is frame base is CFA
441+
// Apply CFA offset to variable storage offset if DW_AT_frame_base is DW_OP_call_frame_cfa
435442
offset + adjustment_at_variable_lifetime_start
436443
} else {
437444
// If it's using SP, we know the SP offset is <SP offset> + (<entry SP CFA offset> - <SP CFA offset>)

0 commit comments

Comments
 (0)