From 103fe509165db4b2ba2f556df52c7c31769f7693 Mon Sep 17 00:00:00 2001 From: Philip Craig Date: Fri, 13 Mar 2026 13:21:38 +1000 Subject: [PATCH] chore: update gimli --- Cargo.lock | 35 +++++---- Cargo.toml | 2 +- ghostscope-dwarf/src/data/block_index.rs | 32 ++++---- .../src/data/on_demand_resolver.rs | 61 +++++++-------- ghostscope-dwarf/src/module/data.rs | 76 +++++++++---------- .../src/parser/detailed_parser.rs | 70 ++++++++--------- .../src/parser/expression_evaluator.rs | 4 +- ghostscope-dwarf/src/parser/fast_parser.rs | 52 ++++++------- .../src/parser/range_extractor.rs | 5 +- ghostscope-dwarf/src/planner.rs | 50 +++++------- 10 files changed, 178 insertions(+), 209 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3ce6968..1d96776 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8,7 +8,7 @@ version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" dependencies = [ - "gimli", + "gimli 0.31.1", ] [[package]] @@ -165,7 +165,7 @@ checksum = "c51b96c5a8ed8705b40d655273bc4212cbbf38d4e3be2788f36306f154523ec7" dependencies = [ "bytes", "core-error", - "hashbrown", + "hashbrown 0.15.5", "log", "object", "thiserror 1.0.69", @@ -556,12 +556,6 @@ dependencies = [ "windows-sys 0.60.2", ] -[[package]] -name = "fallible-iterator" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649" - [[package]] name = "fastrand" version = "2.3.0" @@ -773,7 +767,7 @@ dependencies = [ "ghostscope-platform", "ghostscope-process", "ghostscope-protocol", - "gimli", + "gimli 0.33.0", "libc", "memmap2", "num_cpus", @@ -832,7 +826,7 @@ dependencies = [ "aya-ebpf-bindings", "chrono", "ghostscope-platform", - "gimli", + "gimli 0.33.0", "serde", "serde_json", "tracing", @@ -860,8 +854,15 @@ name = "gimli" version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" + +[[package]] +name = "gimli" +version = "0.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf7f043f89559805f8c7cacc432749b2fa0d0a0a9ee46ce47164ed5ba7f126c" dependencies = [ - "fallible-iterator", + "fnv", + "hashbrown 0.16.1", "indexmap", "stable_deref_trait", ] @@ -877,6 +878,12 @@ dependencies = [ "foldhash", ] +[[package]] +name = "hashbrown" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" + [[package]] name = "heck" version = "0.5.0" @@ -926,7 +933,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2481980430f9f78649238835720ddccc57e52df14ffce1c6f37391d61b563e9" dependencies = [ "equivalent", - "hashbrown", + "hashbrown 0.15.5", ] [[package]] @@ -1085,7 +1092,7 @@ version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38" dependencies = [ - "hashbrown", + "hashbrown 0.15.5", ] [[package]] @@ -1170,7 +1177,7 @@ checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" dependencies = [ "crc32fast", "flate2", - "hashbrown", + "hashbrown 0.15.5", "indexmap", "memchr", "ruzstd", diff --git a/Cargo.toml b/Cargo.toml index 969aaf5..b15959e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -45,7 +45,7 @@ toml = "0.8" dirs = "5.0" object = "0.36" -gimli = "0.31.1" +gimli = "0.33.0" aya = "0.13.1" aya-obj = "0.2.1" aya-ebpf-bindings = "0.1.1" diff --git a/ghostscope-dwarf/src/data/block_index.rs b/ghostscope-dwarf/src/data/block_index.rs index 5ac43b2..c200052 100644 --- a/ghostscope-dwarf/src/data/block_index.rs +++ b/ghostscope-dwarf/src/data/block_index.rs @@ -201,11 +201,11 @@ impl<'a> BlockIndexBuilder<'a> { /// Build functions for a single CU offset pub fn build_for_unit(&self, cu_offset: gimli::DebugInfoOffset) -> Option> { - let header = self.dwarf.debug_info.header_from_offset(cu_offset).ok()?; + let header = self.dwarf.unit_header(cu_offset).ok()?; let unit = self.dwarf.unit(header).ok()?; let mut entries = unit.entries(); let mut out: Vec = Vec::new(); - while let Ok(Some((_depth, entry))) = entries.next_dfs() { + while let Ok(Some(entry)) = entries.next_dfs() { if entry.tag() == gimli::constants::DW_TAG_subprogram { let mut fb = FunctionBlocks::new(cu_offset, entry.offset()); if let Ok(ranges) = RangeExtractor::extract_all_ranges(entry, &unit, self.dwarf) { @@ -232,7 +232,7 @@ impl<'a> BlockIndexBuilder<'a> { cu_offset: gimli::DebugInfoOffset, die_offset: gimli::UnitOffset, ) -> Option { - let header = self.dwarf.debug_info.header_from_offset(cu_offset).ok()?; + let header = self.dwarf.unit_header(cu_offset).ok()?; let unit = self.dwarf.unit(header).ok()?; let entry = unit.entry(die_offset).ok()?; if entry.tag() != gimli::constants::DW_TAG_subprogram { @@ -282,8 +282,8 @@ impl<'a> BlockIndexBuilder<'a> { gimli::constants::DW_TAG_formal_parameter | gimli::constants::DW_TAG_variable => { // Only record DIE offsets; evaluation happens on demand let v = VarRef { - cu_offset: match unit.header.offset() { - gimli::UnitSectionOffset::DebugInfoOffset(off) => off, + cu_offset: match unit.header.debug_info_offset() { + Some(off) => off, _ => continue, }, die_offset: e.offset(), @@ -296,7 +296,7 @@ impl<'a> BlockIndexBuilder<'a> { if let Ok(ranges) = RangeExtractor::extract_all_ranges(e, unit, self.dwarf) { bn.ranges = ranges; } - if let Ok(Some(a)) = e.attr(gimli::constants::DW_AT_entry_pc) { + if let Some(a) = e.attr(gimli::constants::DW_AT_entry_pc) { if let gimli::AttributeValue::Addr(addr) = a.value() { bn.entry_pc = Some(addr); } @@ -315,11 +315,11 @@ impl<'a> BlockIndexBuilder<'a> { if let Ok(mut it) = unit.entries_at_offset(e.offset()) { // skip self let _ = it.next_entry(); - while let Ok(Some((depth, ce))) = it.next_dfs() { - if depth == 0 { + while let Ok(Some(ce)) = it.next_dfs() { + if ce.depth() <= 0 { break; } - if depth > 1 { + if ce.depth() > 1 { continue; } if ce.tag() == gimli::constants::DW_TAG_formal_parameter { @@ -329,25 +329,25 @@ impl<'a> BlockIndexBuilder<'a> { } } if !has_inline_params { - if let Ok(Some(attr)) = e.attr(gimli::constants::DW_AT_abstract_origin) - { + if let Some(attr) = e.attr(gimli::constants::DW_AT_abstract_origin) { if let gimli::AttributeValue::UnitRef(origin_off) = attr.value() { if let Ok(mut iter) = unit.entries_at_offset(origin_off) { // Skip the origin DIE itself let _ = iter.next_entry(); - while let Ok(Some((depth, ce))) = iter.next_dfs() { + while let Ok(Some(ce)) = iter.next_dfs() { // Only consider direct children of the origin DIE - if depth == 0 { + if ce.depth() <= 0 { break; } - if depth > 1 { + if ce.depth() > 1 { continue; } if ce.tag() == gimli::constants::DW_TAG_formal_parameter { let v = VarRef { - cu_offset: match unit.header.offset() { - gimli::UnitSectionOffset::DebugInfoOffset(off) => off, + cu_offset: match unit.header.debug_info_offset() + { + Some(off) => off, _ => continue, }, die_offset: ce.offset(), diff --git a/ghostscope-dwarf/src/data/on_demand_resolver.rs b/ghostscope-dwarf/src/data/on_demand_resolver.rs index 27fc1fd..2bbc7c6 100644 --- a/ghostscope-dwarf/src/data/on_demand_resolver.rs +++ b/ghostscope-dwarf/src/data/on_demand_resolver.rs @@ -66,7 +66,7 @@ impl OnDemandResolver { chain.base, chain.fields.len() ); - let header = self.dwarf.debug_info.header_from_offset(cu_offset)?; + let header = self.dwarf.unit_header(cu_offset)?; let unit = self.dwarf.unit(header)?; let var_entry = unit.entry(var_die)?; @@ -110,7 +110,7 @@ impl OnDemandResolver { let t2 = std::time::Instant::now(); let (fe, ftl, pctx) = planner.plan_chain_from_known( - cu_offset.into(), + cu_offset, type_die_off, current_eval, chain.fields, @@ -129,18 +129,13 @@ impl OnDemandResolver { if let Some(ftl) = final_type_loc { let t3 = std::time::Instant::now(); // Base: shallow resolve the resulting DIE's type - let mut shallow_final = match ftl.cu_off { - gimli::UnitSectionOffset::DebugInfoOffset(off) => { - let h = self.dwarf.debug_info.header_from_offset(off)?; - let u = self.dwarf.unit(h)?; - crate::parser::DetailedParser::resolve_type_shallow_at_offset( - &self.dwarf, - &u, - ftl.die_off, - ) - } - gimli::UnitSectionOffset::DebugTypesOffset(_off) => None, - }; + let h = self.dwarf.unit_header(ftl.cu_off)?; + let u = self.dwarf.unit(h)?; + let mut shallow_final = crate::parser::DetailedParser::resolve_type_shallow_at_offset( + &self.dwarf, + &u, + ftl.die_off, + ); tracing::info!( "DWARF:plan_from_var final_type_ms={}", t3.elapsed().as_millis() @@ -149,25 +144,23 @@ impl OnDemandResolver { // Minimal parent enrichment: if planner provided parent member context, // use parent's shallow members to capture bitfield wrapper and accurate member type. if let Some(ctx) = parent_ctx { - if let gimli::UnitSectionOffset::DebugInfoOffset(pcu) = ctx.parent_cu_off { - let h = self.dwarf.debug_info.header_from_offset(pcu)?; - let u = self.dwarf.unit(h)?; - if let Some( - crate::TypeInfo::StructType { members, .. } - | crate::TypeInfo::UnionType { members, .. }, - ) = crate::parser::DetailedParser::resolve_type_shallow_at_offset( - &self.dwarf, - &u, - ctx.parent_die_off, - ) { - if let Some(m) = members.iter().find(|m| m.name == ctx.member_name) { - tracing::info!( - "DWARF:parent_enrich member='{}' uses BitfieldType={}", - ctx.member_name, - matches!(m.member_type, crate::TypeInfo::BitfieldType { .. }) - ); - shallow_final = Some(m.member_type.clone()); - } + let h = self.dwarf.unit_header(ctx.parent_cu_off)?; + let u = self.dwarf.unit(h)?; + if let Some( + crate::TypeInfo::StructType { members, .. } + | crate::TypeInfo::UnionType { members, .. }, + ) = crate::parser::DetailedParser::resolve_type_shallow_at_offset( + &self.dwarf, + &u, + ctx.parent_die_off, + ) { + if let Some(m) = members.iter().find(|m| m.name == ctx.member_name) { + tracing::info!( + "DWARF:parent_enrich member='{}' uses BitfieldType={}", + ctx.member_name, + matches!(m.member_type, crate::TypeInfo::BitfieldType { .. }) + ); + shallow_final = Some(m.member_type.clone()); } } } @@ -209,7 +202,7 @@ impl OnDemandResolver { ) -> Result> { let mut vars = Vec::with_capacity(items.len()); for (cu_off, die_off) in items.iter().cloned() { - let header = self.dwarf.debug_info.header_from_offset(cu_off)?; + let header = self.dwarf.unit_header(cu_off)?; let unit = self.dwarf.unit(header)?; let entry = unit.entry(die_off)?; if let Some(v) = self.detailed_parser.parse_variable_entry_with_mode( diff --git a/ghostscope-dwarf/src/module/data.rs b/ghostscope-dwarf/src/module/data.rs index b46d9a0..4aed6a4 100644 --- a/ghostscope-dwarf/src/module/data.rs +++ b/ghostscope-dwarf/src/module/data.rs @@ -94,7 +94,7 @@ impl ModuleData { get_cfa: &dyn Fn(u64) -> Result>, ) { let dwarf = self.resolver.dwarf_ref(); - let header = match dwarf.debug_info.header_from_offset(func.cu_offset) { + let header = match dwarf.unit_header(func.cu_offset) { Ok(h) => h, Err(_) => return, }; @@ -112,7 +112,7 @@ impl ModuleData { } // Get abstract origin to determine parameter order and names let origin_off = match inline_die.attr_value(gimli::constants::DW_AT_abstract_origin) { - Ok(Some(gimli::AttributeValue::UnitRef(o))) => o, + Some(gimli::AttributeValue::UnitRef(o)) => o, _ => return, }; @@ -120,15 +120,15 @@ impl ModuleData { let mut origin_param_names: Vec = Vec::new(); if let Ok(mut it) = unit.entries_at_offset(origin_off) { let _ = it.next_entry(); - while let Ok(Some((depth, e))) = it.next_dfs() { - if depth == 0 { + while let Ok(Some(e)) = it.next_dfs() { + if e.depth() <= 0 { break; } - if depth > 1 { + if e.depth() > 1 { continue; } if e.tag() == gimli::constants::DW_TAG_formal_parameter { - if let Ok(Some(a)) = e.attr(gimli::constants::DW_AT_name) { + if let Some(a) = e.attr(gimli::constants::DW_AT_name) { if let Ok(s) = dwarf.attr_string(&unit, a.value()) { if let Ok(ss) = s.to_string_lossy() { origin_param_names.push(ss.into_owned()); @@ -147,11 +147,11 @@ impl ModuleData { vec![None; origin_param_names.len()]; if let Ok(mut it) = unit.entries_at_offset(node.die_offset.unwrap()) { let _ = it.next_entry(); - while let Ok(Some((depth, e))) = it.next_dfs() { - if depth == 0 { + while let Ok(Some(e)) = it.next_dfs() { + if e.depth() <= 0 { break; } - if depth > 1 { + if e.depth() > 1 { continue; } if e.tag() == gimli::constants::DW_TAG_call_site @@ -160,21 +160,18 @@ impl ModuleData { // Iterate its children for parameters if let Ok(mut pit) = unit.entries_at_offset(e.offset()) { let _ = pit.next_entry(); - while let Ok(Some((pdepth, pe))) = pit.next_dfs() { - if pdepth == 0 { + while let Ok(Some(pe)) = pit.next_dfs() { + if pe.depth() <= 0 { break; } - if pdepth > 1 { + if pe.depth() > 1 { continue; } if pe.tag() == gimli::constants::DW_TAG_call_site_parameter || pe.tag() == gimli::constants::DW_TAG_GNU_call_site_parameter { // Prefer DW_AT_location (exprloc); fallback to DW_AT_const_value - let loc_attr = pe - .attr_value(gimli::constants::DW_AT_location) - .ok() - .flatten(); + let loc_attr = pe.attr_value(gimli::constants::DW_AT_location); if let Some(gimli::AttributeValue::Exprloc(expr)) = loc_attr { if let Ok(ev) = ExpressionEvaluator::parse_expression( expr.0.to_slice().ok().as_deref().unwrap_or(&[]), @@ -188,7 +185,7 @@ impl ModuleData { *slot = Some(ev); } } - } else if let Ok(Some(cv)) = + } else if let Some(cv) = pe.attr_value(gimli::constants::DW_AT_const_value) { use crate::core::DirectValueResult as DV; @@ -292,10 +289,10 @@ impl ModuleData { // 2) Try typedef by name, then peel one layer to underlying type and shallow resolve if let Some(td) = self.type_name_index.find_typedef(name) { let dwarf = self.resolver.dwarf_ref(); - if let Ok(header) = dwarf.debug_info.header_from_offset(td.cu_offset) { + if let Ok(header) = dwarf.unit_header(td.cu_offset) { if let Ok(unit) = dwarf.unit(header) { if let Ok(entry) = unit.entry(td.die_offset) { - if let Ok(Some(gimli::AttributeValue::UnitRef(under))) = + if let Some(gimli::AttributeValue::UnitRef(under)) = entry.attr_value(gimli::DW_AT_type) { return self.detailed_shallow_type(td.cu_offset, under); @@ -328,10 +325,10 @@ impl ModuleData { if let Some(td) = self.type_name_index.find_typedef(name) { let dwarf = self.resolver.dwarf_ref(); - if let Ok(header) = dwarf.debug_info.header_from_offset(td.cu_offset) { + if let Ok(header) = dwarf.unit_header(td.cu_offset) { if let Ok(unit) = dwarf.unit(header) { if let Ok(entry) = unit.entry(td.die_offset) { - if let Ok(Some(gimli::AttributeValue::UnitRef(under))) = + if let Some(gimli::AttributeValue::UnitRef(under)) = entry.attr_value(gimli::DW_AT_type) { return self.detailed_shallow_type(td.cu_offset, under); @@ -363,10 +360,10 @@ impl ModuleData { if let Some(td) = self.type_name_index.find_typedef(name) { let dwarf = self.resolver.dwarf_ref(); - if let Ok(header) = dwarf.debug_info.header_from_offset(td.cu_offset) { + if let Ok(header) = dwarf.unit_header(td.cu_offset) { if let Ok(unit) = dwarf.unit(header) { if let Ok(entry) = unit.entry(td.die_offset) { - if let Ok(Some(gimli::AttributeValue::UnitRef(under))) = + if let Some(gimli::AttributeValue::UnitRef(under)) = entry.attr_value(gimli::DW_AT_type) { return self.detailed_shallow_type(td.cu_offset, under); @@ -807,7 +804,7 @@ impl ModuleData { for (idx, var_out) in vars.iter_mut().enumerate() { if var_out.dwarf_type.is_none() { let vr = &var_refs[idx]; - if let Ok(header) = dwarf_ref.debug_info.header_from_offset(vr.cu_offset) { + if let Ok(header) = dwarf_ref.unit_header(vr.cu_offset) { if let Ok(unit) = dwarf_ref.unit(header) { if let Ok(entry) = unit.entry(vr.die_offset) { let planner = crate::planner::AccessPlanner::new(dwarf_ref); @@ -934,7 +931,7 @@ impl ModuleData { // Find variable DIE by name among visible vars let dwarf = self.resolver.dwarf_ref(); - let header = dwarf.debug_info.header_from_offset(func.cu_offset)?; + let header = dwarf.unit_header(func.cu_offset)?; let unit = dwarf.unit(header)?; let candidates = func.variables_at_pc(address); tracing::info!( @@ -948,7 +945,7 @@ impl ModuleData { let mut cand_names: Vec = Vec::new(); for v in &candidates { let e = unit.entry(v.die_offset)?; - if let Some(attr) = e.attr(gimli::DW_AT_name)? { + if let Some(attr) = e.attr(gimli::DW_AT_name) { if let Ok(s) = dwarf.attr_string(&unit, attr.value()) { if let Ok(s_str) = s.to_string_lossy() { cand_names.push(s_str.into_owned()); @@ -960,7 +957,7 @@ impl ModuleData { for v in candidates { let e = unit.entry(v.die_offset)?; - if let Some(attr) = e.attr(gimli::DW_AT_name)? { + if let Some(attr) = e.attr(gimli::DW_AT_name) { if let Ok(s) = dwarf.attr_string(&unit, attr.value()) { if let Ok(n) = s.to_string_lossy() { if n == base_var || n.starts_with(&format!("{base_var}@")) { @@ -980,9 +977,7 @@ impl ModuleData { if var0.dwarf_type.is_none() { // Resolve base variable type strictly via DWARF type DIE let dwarf = self.resolver.dwarf_ref(); - let header = dwarf - .debug_info - .header_from_offset(func.cu_offset)?; + let header = dwarf.unit_header(func.cu_offset)?; let unit = dwarf.unit(header)?; let e = unit.entry(v.die_offset)?; let planner = crate::planner::AccessPlanner::new(dwarf); @@ -1156,7 +1151,7 @@ impl ModuleData { if let Some(inline_idx) = Self::find_innermost_inline_node(func, address) { // Verify the DIE tag is actually an inlined_subroutine let dwarf = self.resolver.dwarf_ref(); - if let Ok(header) = dwarf.debug_info.header_from_offset(func.cu_offset) { + if let Ok(header) = dwarf.unit_header(func.cu_offset) { if let Ok(unit) = dwarf.unit(header) { if let Some(off) = func.nodes[inline_idx].die_offset { if let Ok(entry) = unit.entry(off) { @@ -1643,15 +1638,14 @@ impl ModuleData { ) -> gimli::read::Result< Option>>, > { - if let Some(value) = entry.attr_value(attr)? { + if let Some(value) = entry.attr_value(attr) { return Ok(Some(value)); } for origin_attr in [ gimli::constants::DW_AT_abstract_origin, gimli::constants::DW_AT_specification, ] { - if let Some(gimli::AttributeValue::UnitRef(off)) = - entry.attr_value(origin_attr)? + if let Some(gimli::AttributeValue::UnitRef(off)) = entry.attr_value(origin_attr) { if visited.insert(off) { let origin = unit.entry(off)?; @@ -1667,7 +1661,7 @@ impl ModuleData { } let dwarf = self.resolver.dwarf_ref(); - let header = dwarf.debug_info.header_from_offset(func.cu_offset).ok()?; + let header = dwarf.unit_header(func.cu_offset).ok()?; let unit = dwarf.unit(header).ok()?; // From innermost block to outermost (root at 0) let path = func.block_path_for_pc(pc); @@ -1961,8 +1955,7 @@ impl ModuleData { fn function_uses_entry_value(&self, idx_entry: &crate::core::IndexEntry) -> Result { let dwarf = self.resolver.dwarf_ref(); let header = dwarf - .debug_info - .header_from_offset(idx_entry.unit_offset) + .unit_header(idx_entry.unit_offset) .map_err(|e| anyhow::anyhow!("unit header error: {}", e))?; let unit = dwarf .unit(header) @@ -1990,15 +1983,14 @@ impl ModuleData { ) -> gimli::read::Result< Option>>, > { - if let Some(v) = entry.attr_value(attr)? { + if let Some(v) = entry.attr_value(attr) { return Ok(Some(v)); } for origin_attr in [ gimli::constants::DW_AT_abstract_origin, gimli::constants::DW_AT_specification, ] { - if let Some(gimli::AttributeValue::UnitRef(off)) = - entry.attr_value(origin_attr)? + if let Some(gimli::AttributeValue::UnitRef(off)) = entry.attr_value(origin_attr) { if visited.insert(off) { let origin = unit.entry(off)?; @@ -2300,7 +2292,7 @@ impl ModuleData { die_off: gimli::UnitOffset, ) -> Option { let dwarf = self.resolver.dwarf_ref(); - let header = dwarf.debug_info.header_from_offset(cu_off).ok()?; + let header = dwarf.unit_header(cu_off).ok()?; let unit = dwarf.unit(header).ok()?; crate::parser::DetailedParser::resolve_type_shallow_at_offset(dwarf, &unit, die_off) } @@ -2312,7 +2304,7 @@ impl ModuleData { die_off: gimli::UnitOffset, ) -> Option { let dwarf = self.resolver.dwarf_ref(); - let header = dwarf.debug_info.header_from_offset(cu_off).ok()?; + let header = dwarf.unit_header(cu_off).ok()?; let unit = dwarf.unit(header).ok()?; let entry = unit.entry(die_off).ok()?; let planner = crate::planner::AccessPlanner::new(dwarf); diff --git a/ghostscope-dwarf/src/parser/detailed_parser.rs b/ghostscope-dwarf/src/parser/detailed_parser.rs index ce8902a..67f6ced 100644 --- a/ghostscope-dwarf/src/parser/detailed_parser.rs +++ b/ghostscope-dwarf/src/parser/detailed_parser.rs @@ -78,7 +78,7 @@ impl DetailedParser { let tag = entry.tag(); // Utility to read attr string name let mut entry_name: Option = None; - if let Ok(Some(a)) = entry.attr(DW_AT_NAME) { + if let Some(a) = entry.attr(DW_AT_NAME) { if let Ok(s) = dwarf.attr_string(unit, a.value()) { if let Ok(s_str) = s.to_string_lossy() { entry_name = Some(s_str.into_owned()); @@ -90,8 +90,7 @@ impl DetailedParser { if alias_name.is_none() { alias_name = entry_name.clone(); } - if let Ok(Some(gimli::AttributeValue::UnitRef(off))) = - entry.attr_value(DW_AT_TYPE) + if let Some(gimli::AttributeValue::UnitRef(off)) = entry.attr_value(DW_AT_TYPE) { type_offset = off; continue; @@ -106,8 +105,7 @@ impl DetailedParser { }); } DW_TAG_CONST_TYPE | DW_TAG_VOLATILE_TYPE | DW_TAG_RESTRICT_TYPE => { - if let Ok(Some(gimli::AttributeValue::UnitRef(off))) = - entry.attr_value(DW_AT_TYPE) + if let Some(gimli::AttributeValue::UnitRef(off)) = entry.attr_value(DW_AT_TYPE) { type_offset = off; continue; @@ -125,14 +123,14 @@ impl DetailedParser { let mut target: TypeInfo = TypeInfo::UnknownType { name: "void".to_string(), }; - if let Ok(Some(a)) = entry.attr(DW_AT_BYTE_SIZE) { + if let Some(a) = entry.attr(DW_AT_BYTE_SIZE) { if let gimli::AttributeValue::Udata(sz) = a.value() { byte_size = sz; } } // Very shallow pointee name resolution: unwrap typedef/qualifiers only, without recursion let mut pointee_name: Option = None; - if let Ok(Some(gimli::AttributeValue::UnitRef(mut toff))) = + if let Some(gimli::AttributeValue::UnitRef(mut toff)) = entry.attr_value(DW_AT_TYPE) { // Unwrap up to a small bound to avoid deep recursion/stack blowups on real-world code @@ -143,7 +141,7 @@ impl DetailedParser { | DW_TAG_RESTRICT_TYPE => { // Capture typedef name as a fallback pointee name if tentry.tag() == DW_TAG_TYPEDEF { - if let Ok(Some(na)) = tentry.attr(DW_AT_NAME) { + if let Some(na) = tentry.attr(DW_AT_NAME) { if let Ok(s) = dwarf.attr_string(unit, na.value()) { if pointee_name.is_none() { if let Ok(s_str) = s.to_string_lossy() { @@ -153,7 +151,7 @@ impl DetailedParser { } } } - if let Ok(Some(gimli::AttributeValue::UnitRef(next))) = + if let Some(gimli::AttributeValue::UnitRef(next)) = tentry.attr_value(DW_AT_TYPE) { toff = next; @@ -165,18 +163,18 @@ impl DetailedParser { // Construct BaseType with size+encoding let mut byte_size = 0u64; let mut encoding = gimli::constants::DW_ATE_unsigned; - if let Ok(Some(a)) = tentry.attr(DW_AT_BYTE_SIZE) { + if let Some(a) = tentry.attr(DW_AT_BYTE_SIZE) { if let gimli::AttributeValue::Udata(sz) = a.value() { byte_size = sz; } } - if let Ok(Some(a)) = tentry.attr(DW_AT_ENCODING) { + if let Some(a) = tentry.attr(DW_AT_ENCODING) { if let gimli::AttributeValue::Encoding(enc) = a.value() { encoding = enc; } } - let name = if let Ok(Some(na)) = tentry.attr(DW_AT_NAME) { + let name = if let Some(na) = tentry.attr(DW_AT_NAME) { if let Ok(s) = dwarf.attr_string(unit, na.value()) { s.to_string_lossy() .ok() @@ -201,7 +199,7 @@ impl DetailedParser { | DW_TAG_ENUMERATION_TYPE => { // Do NOT recursively resolve aggregates here to avoid cycles on self-referential types. // Only record the name; deref-time upgrade will use analyzer's shallow index safely. - if let Ok(Some(na)) = tentry.attr(DW_AT_NAME) { + if let Some(na) = tentry.attr(DW_AT_NAME) { if let Ok(s) = dwarf.attr_string(unit, na.value()) { if let Ok(s_str) = s.to_string_lossy() { let n = s_str.into_owned(); @@ -240,8 +238,7 @@ impl DetailedParser { let name = entry_name.unwrap_or_else(|| "".to_string()); let mut byte_size = 0u64; let mut encoding = gimli::constants::DW_ATE_unsigned; - let mut attrs = entry.attrs(); - while let Ok(Some(a)) = attrs.next() { + for a in entry.attrs() { match a.name() { DW_AT_BYTE_SIZE => { if let gimli::AttributeValue::Udata(sz) = a.value() { @@ -267,7 +264,7 @@ impl DetailedParser { entry_name.unwrap_or_else(|| "".to_string()) }); let mut byte_size = 0u64; - if let Ok(Some(a)) = entry.attr(DW_AT_BYTE_SIZE) { + if let Some(a) = entry.attr(DW_AT_BYTE_SIZE) { if let gimli::AttributeValue::Udata(sz) = a.value() { byte_size = sz; } @@ -282,7 +279,7 @@ impl DetailedParser { if ce.tag() == gimli::DW_TAG_member { // member name let mut m_name = String::new(); - if let Ok(Some(na)) = ce.attr(DW_AT_NAME) { + if let Some(na) = ce.attr(DW_AT_NAME) { if let Ok(s) = dwarf.attr_string(unit, na.value()) { if let Ok(s_str) = s.to_string_lossy() { m_name = s_str.into_owned(); @@ -293,7 +290,7 @@ impl DetailedParser { let mut m_type = TypeInfo::UnknownType { name: "unknown".to_string(), }; - if let Ok(Some(gimli::AttributeValue::UnitRef(toff))) = + if let Some(gimli::AttributeValue::UnitRef(toff)) = ce.attr_value(DW_AT_TYPE) { if let Some(ti) = @@ -304,8 +301,7 @@ impl DetailedParser { } // member offset (simple evaluation) let mut m_offset: u64 = 0; - if let Ok(Some(ml)) = ce.attr(gimli::DW_AT_data_member_location) - { + if let Some(ml) = ce.attr(gimli::DW_AT_data_member_location) { match ml.value() { gimli::AttributeValue::Udata(v) => m_offset = v, gimli::AttributeValue::Exprloc(expr) => { @@ -322,18 +318,18 @@ impl DetailedParser { // bit offsets/sizes (optional) let mut bit_offset: Option = None; let mut bit_size: Option = None; - if let Ok(Some(bo)) = ce.attr(gimli::DW_AT_bit_offset) { + if let Some(bo) = ce.attr(gimli::DW_AT_bit_offset) { if let gimli::AttributeValue::Udata(v) = bo.value() { bit_offset = u8::try_from(v).ok(); } } - if let Ok(Some(bs)) = ce.attr(gimli::DW_AT_data_bit_offset) { + if let Some(bs) = ce.attr(gimli::DW_AT_data_bit_offset) { if let gimli::AttributeValue::Udata(v) = bs.value() { bit_offset = u8::try_from(v % 8).ok(); m_offset = v / 8; } } - if let Ok(Some(bsz)) = ce.attr(gimli::DW_AT_bit_size) { + if let Some(bsz) = ce.attr(gimli::DW_AT_bit_size) { if let gimli::AttributeValue::Udata(v) = bsz.value() { bit_size = u8::try_from(v).ok(); } @@ -414,7 +410,7 @@ impl DetailedParser { entry_name.unwrap_or_else(|| "".to_string()) }); let mut byte_size = 0u64; - if let Ok(Some(a)) = entry.attr(DW_AT_BYTE_SIZE) { + if let Some(a) = entry.attr(DW_AT_BYTE_SIZE) { if let gimli::AttributeValue::Udata(sz) = a.value() { byte_size = sz; } @@ -427,7 +423,7 @@ impl DetailedParser { let ce = child.entry(); if ce.tag() == gimli::DW_TAG_member { let mut m_name = String::new(); - if let Ok(Some(na)) = ce.attr(gimli::DW_AT_name) { + if let Some(na) = ce.attr(gimli::DW_AT_name) { if let Ok(s) = dwarf.attr_string(unit, na.value()) { if let Ok(s_str) = s.to_string_lossy() { m_name = s_str.into_owned(); @@ -437,7 +433,7 @@ impl DetailedParser { let mut m_type = TypeInfo::UnknownType { name: "unknown".to_string(), }; - if let Ok(Some(gimli::AttributeValue::UnitRef(toff))) = + if let Some(gimli::AttributeValue::UnitRef(toff)) = ce.attr_value(DW_AT_TYPE) { if let Some(ti) = @@ -472,7 +468,7 @@ impl DetailedParser { .unwrap_or_else(|| entry_name.unwrap_or_else(|| "".to_string())); // Parse base type and size let mut byte_size = 0u64; - if let Ok(Some(a)) = entry.attr(DW_AT_BYTE_SIZE) { + if let Some(a) = entry.attr(DW_AT_BYTE_SIZE) { if let gimli::AttributeValue::Udata(sz) = a.value() { byte_size = sz; } @@ -484,8 +480,7 @@ impl DetailedParser { encoding: gimli::constants::DW_ATE_signed.0 as u16, }; // If DW_AT_type refers to a base type, resolve it shallowly - if let Ok(Some(gimli::AttributeValue::UnitRef(toff))) = - entry.attr_value(DW_AT_TYPE) + if let Some(gimli::AttributeValue::UnitRef(toff)) = entry.attr_value(DW_AT_TYPE) { if let Some(ti) = Self::resolve_type_shallow_at_offset(dwarf, unit, toff) { // Accept only base/qualified/typedef chain base type as enum underlying type @@ -506,7 +501,7 @@ impl DetailedParser { let ce = child.entry(); if ce.tag() == gimli::DW_TAG_enumerator { let mut v_name = String::new(); - if let Ok(Some(na)) = ce.attr(gimli::DW_AT_name) { + if let Some(na) = ce.attr(gimli::DW_AT_name) { if let Ok(s) = dwarf.attr_string(unit, na.value()) { if let Ok(s_str) = s.to_string_lossy() { v_name = s_str.into_owned(); @@ -514,7 +509,7 @@ impl DetailedParser { } } let mut v_val: i64 = 0; - if let Ok(Some(cv)) = ce.attr(gimli::DW_AT_const_value) { + if let Some(cv) = ce.attr(gimli::DW_AT_const_value) { let signed = match &base_type { TypeInfo::BaseType { encoding, .. } => { *encoding @@ -591,8 +586,7 @@ impl DetailedParser { DW_TAG_ARRAY_TYPE => { // element_type shallow + total_size if available + subrange element_count (one step deeper) let mut elem_type: Option = None; - if let Ok(Some(gimli::AttributeValue::UnitRef(eoff))) = - entry.attr_value(DW_AT_TYPE) + if let Some(gimli::AttributeValue::UnitRef(eoff)) = entry.attr_value(DW_AT_TYPE) { elem_type = Self::resolve_type_shallow_at_offset(dwarf, unit, eoff); } @@ -600,7 +594,7 @@ impl DetailedParser { name: "".to_string(), })); let mut total_size: Option = None; - if let Ok(Some(a)) = entry.attr(DW_AT_BYTE_SIZE) { + if let Some(a) = entry.attr(DW_AT_BYTE_SIZE) { if let gimli::AttributeValue::Udata(sz) = a.value() { total_size = Some(sz); } @@ -614,7 +608,7 @@ impl DetailedParser { let ce = child.entry(); if ce.tag() == gimli::DW_TAG_subrange_type { // Prefer DW_AT_count; fallback to upper_bound (+1) - if let Ok(Some(cv)) = ce.attr(gimli::DW_AT_count) { + if let Some(cv) = ce.attr(gimli::DW_AT_count) { match cv.value() { gimli::AttributeValue::Udata(u) => { element_count = Some(u); @@ -640,7 +634,7 @@ impl DetailedParser { } } if element_count.is_none() { - if let Ok(Some(ub)) = ce.attr(gimli::DW_AT_upper_bound) { + if let Some(ub) = ce.attr(gimli::DW_AT_upper_bound) { let ub_v: Option = match ub.value() { gimli::AttributeValue::Udata(u) => Some(u as i64), gimli::AttributeValue::Sdata(s) => Some(s), @@ -858,7 +852,7 @@ impl DetailedParser { attr: gimli::DwAt, visited: &mut HashSet, ) -> Result>>> { - if let Some(value) = entry.attr_value(attr)? { + if let Some(value) = entry.attr_value(attr) { return Ok(Some(value)); } @@ -866,7 +860,7 @@ impl DetailedParser { gimli::constants::DW_AT_abstract_origin, gimli::constants::DW_AT_specification, ] { - if let Some(gimli::AttributeValue::UnitRef(offset)) = entry.attr_value(origin_attr)? { + if let Some(gimli::AttributeValue::UnitRef(offset)) = entry.attr_value(origin_attr) { if visited.insert(offset) { let origin_entry = unit.entry(offset)?; if let Some(value) = diff --git a/ghostscope-dwarf/src/parser/expression_evaluator.rs b/ghostscope-dwarf/src/parser/expression_evaluator.rs index d04d155..7d9a651 100644 --- a/ghostscope-dwarf/src/parser/expression_evaluator.rs +++ b/ghostscope-dwarf/src/parser/expression_evaluator.rs @@ -31,14 +31,14 @@ impl ExpressionEvaluator { visited: &mut HashSet, ) -> gimli::read::Result>>> { - if let Some(value) = entry.attr_value(attr)? { + if let Some(value) = entry.attr_value(attr) { return Ok(Some(value)); } for origin_attr in [ gimli::constants::DW_AT_abstract_origin, gimli::constants::DW_AT_specification, ] { - if let Some(gimli::AttributeValue::UnitRef(off)) = entry.attr_value(origin_attr)? { + if let Some(gimli::AttributeValue::UnitRef(off)) = entry.attr_value(origin_attr) { if visited.insert(off) { let origin = unit.entry(off)?; if let Some(v) = resolve_attr_with_origins(&origin, unit, attr, visited)? { diff --git a/ghostscope-dwarf/src/parser/fast_parser.rs b/ghostscope-dwarf/src/parser/fast_parser.rs index 933a27f..adae9bb 100644 --- a/ghostscope-dwarf/src/parser/fast_parser.rs +++ b/ghostscope-dwarf/src/parser/fast_parser.rs @@ -114,8 +114,8 @@ impl<'a> DwarfParser<'a> { let mut entries = unit.entries(); let mut metadata_cache: HashMap = HashMap::new(); let mut tag_stack: Vec = Vec::new(); - while let Some((depth, entry)) = entries.next_dfs()? { - let d: usize = depth as usize; + while let Some(entry) = entries.next_dfs()? { + let d: usize = entry.depth() as usize; while tag_stack.len() > d { tag_stack.pop(); } @@ -369,7 +369,7 @@ impl<'a> DwarfParser<'a> { | gimli::constants::DW_TAG_enumeration_type | gimli::constants::DW_TAG_typedef => { if let Some(name) = self.extract_name(self.dwarf, unit, entry)? { - let is_decl = match entry.attr(gimli::constants::DW_AT_declaration)? { + let is_decl = match entry.attr(gimli::constants::DW_AT_declaration) { Some(attr) => matches!(attr.value(), gimli::AttributeValue::Flag(true)), None => false, }; @@ -422,7 +422,7 @@ impl<'a> DwarfParser<'a> { entry: &gimli::DebuggingInformationEntry>, ) -> Result> { // Prefer local DW_AT_name - if let Some(attr) = entry.attr(gimli::constants::DW_AT_name)? { + if let Some(attr) = entry.attr(gimli::constants::DW_AT_name) { if let Ok(name) = dwarf.attr_string(unit, attr.value()) { if let Ok(s_str) = name.to_string_lossy() { return Ok(Some(s_str.into_owned())); @@ -432,12 +432,12 @@ impl<'a> DwarfParser<'a> { // Fall back to DW_AT_specification / DW_AT_abstract_origin to resolve name // Common for globals defined in .c and declared in headers: definition DIE refers to declaration DIE for the name - if let Some(attr) = entry.attr(gimli::constants::DW_AT_specification)? { + if let Some(attr) = entry.attr(gimli::constants::DW_AT_specification) { if let Some(n) = Self::resolve_name_via_ref(dwarf, unit, attr.value())? { return Ok(Some(n)); } } - if let Some(attr) = entry.attr(gimli::constants::DW_AT_abstract_origin)? { + if let Some(attr) = entry.attr(gimli::constants::DW_AT_abstract_origin) { if let Some(n) = Self::resolve_name_via_ref(dwarf, unit, attr.value())? { return Ok(Some(n)); } @@ -454,7 +454,7 @@ impl<'a> DwarfParser<'a> { match value { gimli::AttributeValue::UnitRef(uoff) => { if let Ok(spec_entry) = unit.entry(uoff) { - if let Some(attr) = spec_entry.attr(gimli::constants::DW_AT_name)? { + if let Some(attr) = spec_entry.attr(gimli::constants::DW_AT_name) { if let Ok(name) = dwarf.attr_string(unit, attr.value()) { if let Ok(s_str) = name.to_string_lossy() { return Ok(Some(s_str.into_owned())); @@ -478,12 +478,12 @@ impl<'a> DwarfParser<'a> { unit: &gimli::Unit>, entry: &gimli::DebuggingInformationEntry>, ) -> Result> { - if let Some(attr) = entry.attr(gimli::constants::DW_AT_linkage_name)? { + if let Some(attr) = entry.attr(gimli::constants::DW_AT_linkage_name) { if let Some(name) = Self::extract_attr_string(dwarf, unit, attr.value())? { return Ok(Some((name, true))); } } - if let Some(attr) = entry.attr(gimli::constants::DW_AT_MIPS_linkage_name)? { + if let Some(attr) = entry.attr(gimli::constants::DW_AT_MIPS_linkage_name) { if let Some(name) = Self::extract_attr_string(dwarf, unit, attr.value())? { return Ok(Some((name, true))); } @@ -494,7 +494,7 @@ impl<'a> DwarfParser<'a> { fn extract_inline_flag( entry: &gimli::DebuggingInformationEntry>, ) -> Result { - if let Some(attr) = entry.attr(gimli::constants::DW_AT_inline)? { + if let Some(attr) = entry.attr(gimli::constants::DW_AT_inline) { if let gimli::AttributeValue::Inline(inline_attr) = attr.value() { return Ok(inline_attr == gimli::DW_INL_inlined || inline_attr == gimli::DW_INL_declared_inlined); @@ -530,7 +530,7 @@ impl<'a> DwarfParser<'a> { metadata.is_inline = Self::extract_inline_flag(entry)?; - if let Some(attr) = entry.attr(gimli::constants::DW_AT_external)? { + if let Some(attr) = entry.attr(gimli::constants::DW_AT_external) { if let gimli::AttributeValue::Flag(flag) = attr.value() { metadata.is_external = Some(flag); } @@ -556,7 +556,7 @@ impl<'a> DwarfParser<'a> { Ok(()) }; - if let Some(attr) = entry.attr(gimli::constants::DW_AT_abstract_origin)? { + if let Some(attr) = entry.attr(gimli::constants::DW_AT_abstract_origin) { match attr.value() { gimli::AttributeValue::UnitRef(unit_ref) => { merge_from_origin(unit_ref)?; @@ -570,7 +570,7 @@ impl<'a> DwarfParser<'a> { } } - if let Some(attr) = entry.attr(gimli::constants::DW_AT_specification)? { + if let Some(attr) = entry.attr(gimli::constants::DW_AT_specification) { match attr.value() { gimli::AttributeValue::UnitRef(unit_ref) => { merge_from_origin(unit_ref)?; @@ -593,7 +593,7 @@ impl<'a> DwarfParser<'a> { &self, entry: &gimli::DebuggingInformationEntry>, ) -> Result { - if let Some(attr) = entry.attr(gimli::constants::DW_AT_external)? { + if let Some(attr) = entry.attr(gimli::constants::DW_AT_external) { if let gimli::AttributeValue::Flag(is_external) = attr.value() { return Ok(!is_external); } @@ -604,7 +604,7 @@ impl<'a> DwarfParser<'a> { fn is_declaration( entry: &gimli::DebuggingInformationEntry>, ) -> Result { - if let Some(attr) = entry.attr(gimli::constants::DW_AT_declaration)? { + if let Some(attr) = entry.attr(gimli::constants::DW_AT_declaration) { if let gimli::AttributeValue::Flag(is_decl) = attr.value() { return Ok(is_decl); } @@ -631,7 +631,7 @@ impl<'a> DwarfParser<'a> { entry: &gimli::DebuggingInformationEntry>, unit: &gimli::Unit>, ) -> Result> { - if let Some(attr) = entry.attr(gimli::constants::DW_AT_location)? { + if let Some(attr) = entry.attr(gimli::constants::DW_AT_location) { match attr.value() { gimli::AttributeValue::Addr(a) => return Ok(Some(a)), gimli::AttributeValue::Exprloc(expr) => { @@ -716,7 +716,7 @@ impl<'a> DwarfParser<'a> { &self, entry: &gimli::DebuggingInformationEntry>, ) -> Result> { - if let Some(attr) = entry.attr(gimli::constants::DW_AT_entry_pc)? { + if let Some(attr) = entry.attr(gimli::constants::DW_AT_entry_pc) { if let gimli::AttributeValue::Addr(addr) = attr.value() { return Ok(Some(addr)); } @@ -733,7 +733,7 @@ impl<'a> DwarfParser<'a> { ) -> Result { // Check for DW_AT_main_subprogram attribute if entry - .attr(gimli::constants::DW_AT_main_subprogram)? + .attr(gimli::constants::DW_AT_main_subprogram) .is_some() { return Ok(true); @@ -750,9 +750,9 @@ impl<'a> DwarfParser<'a> { ) -> Option { // Try to get language from compilation unit let mut entries = unit.entries(); - if let Ok(Some((_, cu_entry))) = entries.next_dfs() { + if let Ok(Some(cu_entry)) = entries.next_dfs() { if cu_entry.tag() == gimli::constants::DW_TAG_compile_unit { - if let Ok(Some(lang_attr)) = cu_entry.attr(gimli::constants::DW_AT_language) { + if let Some(lang_attr) = cu_entry.attr(gimli::constants::DW_AT_language) { if let gimli::AttributeValue::Language(lang) = lang_attr.value() { return Some(lang); } @@ -916,8 +916,8 @@ impl<'a> DwarfParser<'a> { let shard_results: Vec> = headers .into_par_iter() .map(|header| -> Result { - match header.offset() { - gimli::UnitSectionOffset::DebugInfoOffset(unit_off) => { + match header.debug_info_offset() { + Some(unit_off) => { let unit = self.dwarf.unit(header)?; let cu_lang = self.extract_language(self.dwarf, &unit); self.process_unit_shard(&unit, unit_off, cu_lang) @@ -1078,9 +1078,9 @@ impl<'a> DwarfParser<'a> { unit: &gimli::Unit>, ) -> Option { let mut entries = unit.entries(); - let (_, entry) = entries.next_dfs().ok()??; + let entry = entries.next_dfs().ok()??; - if let Ok(Some(name_attr)) = entry.attr_value(gimli::constants::DW_AT_name) { + if let Some(name_attr) = entry.attr_value(gimli::constants::DW_AT_name) { if let Ok(name) = dwarf.attr_string(unit, name_attr) { if let Ok(s_str) = name.to_string_lossy() { return Some(s_str.into_owned()); @@ -1096,9 +1096,9 @@ impl<'a> DwarfParser<'a> { unit: &gimli::Unit>, ) -> Option { let mut entries = unit.entries(); - let (_, entry) = entries.next_dfs().ok()??; + let entry = entries.next_dfs().ok()??; - if let Ok(Some(comp_dir_attr)) = entry.attr_value(gimli::constants::DW_AT_comp_dir) { + if let Some(comp_dir_attr) = entry.attr_value(gimli::constants::DW_AT_comp_dir) { if let Ok(comp_dir) = dwarf.attr_string(unit, comp_dir_attr) { if let Ok(s_str) = comp_dir.to_string_lossy() { return Some(s_str.into_owned()); diff --git a/ghostscope-dwarf/src/parser/range_extractor.rs b/ghostscope-dwarf/src/parser/range_extractor.rs index f1a6479..ea239f5 100644 --- a/ghostscope-dwarf/src/parser/range_extractor.rs +++ b/ghostscope-dwarf/src/parser/range_extractor.rs @@ -47,8 +47,7 @@ impl RangeExtractor { let mut high_pc = None; let mut high_pc_offset = None; - let mut attrs = entry.attrs(); - while let Some(attr) = attrs.next()? { + for attr in entry.attrs() { match attr.name() { gimli::constants::DW_AT_low_pc => { if let gimli::AttributeValue::Addr(addr) = attr.value() { @@ -82,7 +81,7 @@ impl RangeExtractor { dwarf: &gimli::Dwarf>, ) -> Result>> { // Check for DW_AT_ranges attribute - let ranges_attr = match entry.attr(gimli::constants::DW_AT_ranges)? { + let ranges_attr = match entry.attr(gimli::constants::DW_AT_ranges) { Some(attr) => attr, None => return Ok(None), }; diff --git a/ghostscope-dwarf/src/planner.rs b/ghostscope-dwarf/src/planner.rs index 0bf4bca..20fbf06 100644 --- a/ghostscope-dwarf/src/planner.rs +++ b/ghostscope-dwarf/src/planner.rs @@ -17,14 +17,14 @@ pub struct AccessPlanner<'dwarf> { /// Location of a type within the DWARF (CU + DIE offset) #[derive(Debug, Clone, Copy)] pub struct TypeLoc { - pub cu_off: gimli::UnitSectionOffset, + pub cu_off: gimli::DebugInfoOffset, pub die_off: gimli::UnitOffset, } /// Parent struct/class context for the final matched member. #[derive(Debug, Clone)] pub struct MemberParentCtx { - pub parent_cu_off: gimli::UnitSectionOffset, + pub parent_cu_off: gimli::DebugInfoOffset, pub parent_die_off: gimli::UnitOffset, pub member_name: String, } @@ -64,14 +64,14 @@ impl<'dwarf> AccessPlanner<'dwarf> { visited: &mut std::collections::HashSet, ) -> crate::core::Result>>> { - if let Some(value) = entry.attr_value(attr)? { + if let Some(value) = entry.attr_value(attr) { return Ok(Some(value)); } for origin_attr in [ gimli::constants::DW_AT_abstract_origin, gimli::constants::DW_AT_specification, ] { - if let Some(gimli::AttributeValue::UnitRef(off)) = entry.attr_value(origin_attr)? { + if let Some(gimli::AttributeValue::UnitRef(off)) = entry.attr_value(origin_attr) { if visited.insert(off) { let origin = unit.entry(off)?; if let Some(v) = resolve_attr_with_origins(&origin, unit, attr, visited)? { @@ -131,10 +131,10 @@ impl<'dwarf> AccessPlanner<'dwarf> { &self, unit: &gimli::Unit>, die: &gimli::DebuggingInformationEntry>, - ) -> crate::core::Result<(Option, gimli::UnitOffset)> { + ) -> crate::core::Result<(Option, gimli::UnitOffset)> { // Check declaration flag or childless struct let mut is_decl = false; - if let Some(attr) = die.attr(gimli::DW_AT_declaration)? { + if let Some(attr) = die.attr(gimli::DW_AT_declaration) { if let gimli::AttributeValue::Flag(f) = attr.value() { is_decl = f; } @@ -145,7 +145,7 @@ impl<'dwarf> AccessPlanner<'dwarf> { (entries.next_dfs()?).is_some() }; - let name_opt = if let Some(attr) = die.attr(gimli::DW_AT_name)? { + let name_opt = if let Some(attr) = die.attr(gimli::DW_AT_name) { self.dwarf .attr_string(unit, attr.value()) .ok() @@ -159,7 +159,7 @@ impl<'dwarf> AccessPlanner<'dwarf> { let tag = die.tag(); if let Some(tix) = &self.type_index { if let Some(loc) = tix.find_aggregate_definition(&name, tag) { - return Ok((Some(loc.cu_offset.into()), loc.die_offset)); + return Ok((Some(loc.cu_offset), loc.die_offset)); } if self.strict_index { return Err(anyhow::anyhow!( @@ -199,26 +199,10 @@ impl<'dwarf> AccessPlanner<'dwarf> { } } - /// Helper: get UnitHeader from a UnitSectionOffset - fn header_from_cu_off( - &self, - cu_off: gimli::UnitSectionOffset, - ) -> crate::core::Result>> { - Ok(match cu_off { - gimli::UnitSectionOffset::DebugInfoOffset(off) => { - self.dwarf.debug_info.header_from_offset(off)? - } - gimli::UnitSectionOffset::DebugTypesOffset(_off) => { - // Currently we do not support .debug_types units in planner - return Err(anyhow::anyhow!("planner: .debug_types units not supported")); - } - }) - } - /// Start planning from a known variable (skip variable search) pub fn plan_chain_from_known( &self, - mut current_cu_off: gimli::UnitSectionOffset, + mut current_cu_off: gimli::DebugInfoOffset, mut type_die_off: gimli::UnitOffset, mut current_eval: EvaluationResult, chain: &[String], @@ -228,7 +212,7 @@ impl<'dwarf> AccessPlanner<'dwarf> { while idx < chain.len() { let field = &chain[idx]; // Reacquire current unit on each step - let header_now = self.header_from_cu_off(current_cu_off)?; + let header_now = self.dwarf.unit_header(current_cu_off)?; let unit_now = self.dwarf.unit(header_now)?; // Strip typedef/qualified @@ -261,7 +245,7 @@ impl<'dwarf> AccessPlanner<'dwarf> { current_cu_off = cu_off; } // Reacquire possibly switched unit and read the definition DIE - let header_now2 = self.header_from_cu_off(current_cu_off)?; + let header_now2 = self.dwarf.unit_header(current_cu_off)?; let unit_now2 = self.dwarf.unit(header_now2)?; let def_die = unit_now2.entry(def_off)?; // Scan members for the field @@ -269,16 +253,16 @@ impl<'dwarf> AccessPlanner<'dwarf> { let _ = entries.next_entry()?; // self let mut next_type: Option = None; let mut found_member = false; - while let Some((_, e)) = entries.next_dfs()? { + while let Some(e) = entries.next_dfs()? { if e.tag() == gimli::DW_TAG_member { - if let Some(attr) = e.attr(gimli::DW_AT_name)? { + if let Some(attr) = e.attr(gimli::DW_AT_name) { if let Ok(s) = self.dwarf.attr_string(&unit_now2, attr.value()) { if let Ok(s_str) = s.to_string_lossy() { if s_str == field.as_str() { // offset let mut off: Option = None; if let Some(a) = - e.attr(gimli::DW_AT_data_member_location)? + e.attr(gimli::DW_AT_data_member_location) { match a.value() { gimli::AttributeValue::Udata(v) => { @@ -292,7 +276,7 @@ impl<'dwarf> AccessPlanner<'dwarf> { } if off.is_none() { if let Some(a) = - e.attr(gimli::DW_AT_data_bit_offset)? + e.attr(gimli::DW_AT_data_bit_offset) { if let gimli::AttributeValue::Udata(v) = a.value() @@ -351,7 +335,7 @@ impl<'dwarf> AccessPlanner<'dwarf> { }; } // type - if let Some(a) = e.attr(gimli::DW_AT_type)? { + if let Some(a) = e.attr(gimli::DW_AT_type) { if let gimli::AttributeValue::UnitRef(u) = a.value() { next_type = Some(u); @@ -378,7 +362,7 @@ impl<'dwarf> AccessPlanner<'dwarf> { // Field not found on this aggregate — report an error instead of // silently returning the base aggregate. // Try to get a friendly type name for diagnostics - let type_name = if let Some(attr) = def_die.attr(gimli::DW_AT_name)? { + let type_name = if let Some(attr) = def_die.attr(gimli::DW_AT_name) { if let Ok(s) = self.dwarf.attr_string(&unit_now2, attr.value()) { s.to_string_lossy().ok().unwrap_or_default().into_owned() } else {