@@ -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