Skip to content

Commit 432f010

Browse files
gamozolabsclaude
andcommitted
Fix DWARF void return type confidence
Previously, functions with missing DW_AT_type (void return) were assigned confidence 0, allowing Binary Ninja's analysis to override them with incorrect inferred types (e.g., uint64_t). Per DWARF spec section 3.3.2, a missing DW_AT_type on a subprogram means void, not "unknown". However, with minimal debug info (-g1), types are omitted entirely, so we can't distinguish void from unknown. This fix: - Uses MAX_CONFIDENCE for explicit return types (was 128), matching parameter confidence for consistency - Uses MAX_CONFIDENCE for void when full debug info is present (detected by checking if any type definitions exist in the compilation unit) - Keeps confidence 0 for minimal debug info (-g1) to allow analysis to infer Tested with C (-g1, -g2) and C++ (-g1, -g2) code to verify correct behavior across debug levels and languages (C uses DW_AT_prototyped, C++ doesn't). Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 56010d2 commit 432f010

1 file changed

Lines changed: 15 additions & 3 deletions

File tree

plugins/dwarf/dwarf_import/src/dwarfdebuginfo.rs

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ use binaryninja::{
3131

3232
use gimli::{DebuggingInformationEntry, Dwarf, Unit};
3333

34-
use binaryninja::confidence::Conf;
34+
use binaryninja::confidence::{Conf, MAX_CONFIDENCE};
3535
use binaryninja::variable::{Variable, VariableSourceType};
3636
use indexmap::{map::Values, IndexMap};
3737
use std::{cmp::Ordering, collections::HashMap, hash::Hash};
@@ -666,8 +666,20 @@ impl DebugInfoBuilder {
666666
let return_type = function
667667
.return_type
668668
.and_then(|return_type_id| self.get_type(return_type_id))
669-
.map(|t| Conf::new(t.ty.clone(), 128))
670-
.unwrap_or_else(|| Conf::new(Type::void(), 0));
669+
.map(|t| Conf::new(t.ty.clone(), MAX_CONFIDENCE))
670+
.unwrap_or_else(|| {
671+
// Per DWARF spec section 3.3.2: "If the subroutine or entry point is a function
672+
// that returns a value, then its debugging information entry has a DW_AT_type
673+
// attribute." A missing DW_AT_type means void, not unknown.
674+
//
675+
// To distinguish "void" from "unknown" (minimal -g1 debug info), we check if
676+
// the compilation unit has any type definitions. At -g2+, types are always
677+
// present (int, structs, etc.), so missing DW_AT_type definitively means void.
678+
// At -g1, no types exist, so we use low confidence to let analysis infer.
679+
let has_full_debug_info = !self.types.is_empty();
680+
let confidence = if has_full_debug_info { MAX_CONFIDENCE } else { 0 };
681+
Conf::new(Type::void(), confidence)
682+
});
671683

672684
let parameters: Vec<FunctionParameter> = function
673685
.parameters

0 commit comments

Comments
 (0)