layout_audit/dwarf/
mod.rs

1mod context;
2mod expr;
3mod types;
4
5pub use context::{DwarfContext, is_go_internal_type};
6pub use types::TypeResolver;
7
8use crate::loader::DwarfSlice;
9use gimli::{AttributeValue, DebugInfoOffset, UnitHeader, UnitOffset};
10
11/// Extract a u64 value from a DWARF attribute, handling various encoding forms.
12/// Returns None for negative Sdata values (invalid for offsets/sizes/indices).
13/// Used by both context.rs and types.rs to avoid duplication.
14pub(crate) fn read_u64_from_attr(attr: Option<AttributeValue<DwarfSlice<'_>>>) -> Option<u64> {
15    match attr? {
16        AttributeValue::FileIndex(idx) => Some(idx),
17        AttributeValue::Udata(v) => Some(v),
18        AttributeValue::Data1(v) => Some(v as u64),
19        AttributeValue::Data2(v) => Some(v as u64),
20        AttributeValue::Data4(v) => Some(v as u64),
21        AttributeValue::Data8(v) => Some(v),
22        // Negative Sdata values are invalid for offsets/sizes/indices - return None.
23        AttributeValue::Sdata(v) if v >= 0 => Some(v as u64),
24        _ => None,
25    }
26}
27
28/// Convert a DebugInfoRef (section offset) to a UnitOffset (unit-relative offset).
29/// Returns None if the reference is invalid (cross-unit or corrupted DWARF).
30/// Used by both types.rs and context.rs for consistent cross-unit reference handling.
31pub(crate) fn debug_info_ref_to_unit_offset<R: gimli::Reader>(
32    debug_info_offset: DebugInfoOffset<R::Offset>,
33    unit_header: &UnitHeader<R>,
34) -> Option<UnitOffset<R::Offset>>
35where
36    R::Offset: std::ops::Sub<Output = R::Offset>,
37{
38    let unit_debug_offset = unit_header.offset().as_debug_info_offset()?;
39    // Use checked arithmetic to detect invalid cross-unit references.
40    // If debug_info_offset < unit_debug_offset, this is corrupted DWARF.
41    if debug_info_offset.0 >= unit_debug_offset.0 {
42        Some(UnitOffset(debug_info_offset.0 - unit_debug_offset.0))
43    } else {
44        None
45    }
46}