layout_audit/dwarf/
mod.rs1mod 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
11pub(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 AttributeValue::Sdata(v) if v >= 0 => Some(v as u64),
24 _ => None,
25 }
26}
27
28pub(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 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}
47
48#[cfg(test)]
49mod tests {
50 use super::*;
51 use gimli::{
52 DebugAbbrevOffset, DebugInfoOffset, Encoding, Format, UnitHeader, UnitSectionOffset,
53 UnitType,
54 };
55
56 #[test]
57 fn read_u64_from_attr_handles_encodings() {
58 assert_eq!(read_u64_from_attr(Some(AttributeValue::Data1(1))), Some(1));
59 assert_eq!(read_u64_from_attr(Some(AttributeValue::Data2(2))), Some(2));
60 assert_eq!(read_u64_from_attr(Some(AttributeValue::Data4(3))), Some(3));
61 assert_eq!(read_u64_from_attr(Some(AttributeValue::Data8(4))), Some(4));
62 assert_eq!(read_u64_from_attr(Some(AttributeValue::Udata(5))), Some(5));
63 assert_eq!(read_u64_from_attr(Some(AttributeValue::Sdata(-1))), None);
64 assert_eq!(read_u64_from_attr(Some(AttributeValue::Sdata(7))), Some(7));
65 assert_eq!(read_u64_from_attr(Some(AttributeValue::FileIndex(9))), Some(9));
66 }
67
68 #[test]
69 fn debug_info_ref_to_unit_offset_validates_unit() {
70 let encoding = Encoding { address_size: 8, format: Format::Dwarf32, version: 4 };
71 let unit_offset = UnitSectionOffset::DebugInfoOffset(DebugInfoOffset(0x100));
72 let header = UnitHeader::new(
73 encoding,
74 0,
75 UnitType::Compilation,
76 DebugAbbrevOffset(0),
77 unit_offset,
78 DwarfSlice::new(&[], gimli::RunTimeEndian::Little),
79 );
80
81 let within = debug_info_ref_to_unit_offset(DebugInfoOffset(0x100), &header);
82 assert_eq!(within, Some(UnitOffset(0)));
83
84 let outside = debug_info_ref_to_unit_offset(DebugInfoOffset(0x0ff), &header);
85 assert_eq!(outside, None);
86 }
87}