11c521e17SSingleAccretion use crate::{debug::Reader, translate::get_vmctx_value_label};
292cc0ad7SSingleAccretion use core::fmt;
390ac295eSAlex Crichton use cranelift_codegen::{LabelValueLoc, ValueLabelsRanges, ir::ValueLabel, isa::TargetIsa};
4*c4a38d67SPhilip Craig use gimli::{AttributeValue, LittleEndian, UnitRef, write};
592cc0ad7SSingleAccretion
61c521e17SSingleAccretion macro_rules! dbi_log_enabled {
71c521e17SSingleAccretion () => {
81c521e17SSingleAccretion cfg!(any(feature = "trace-log", debug_assertions))
91c521e17SSingleAccretion && ::log::log_enabled!(target: "debug-info-transform", ::log::Level::Trace)
101c521e17SSingleAccretion };
111c521e17SSingleAccretion }
1292cc0ad7SSingleAccretion macro_rules! dbi_log {
1392cc0ad7SSingleAccretion ($($tt:tt)*) => {
1492cc0ad7SSingleAccretion if cfg!(any(feature = "trace-log", debug_assertions)) {
1592cc0ad7SSingleAccretion ::log::trace!(target: "debug-info-transform", $($tt)*);
1692cc0ad7SSingleAccretion }
1792cc0ad7SSingleAccretion };
1892cc0ad7SSingleAccretion }
1992cc0ad7SSingleAccretion pub(crate) use dbi_log;
201c521e17SSingleAccretion pub(crate) use dbi_log_enabled;
2192cc0ad7SSingleAccretion
22bd7b59daSPhilip Craig pub struct CompileUnitSummary<'a, 'r> {
23bd7b59daSPhilip Craig unit: UnitRef<'a, Reader<'r>>,
2492cc0ad7SSingleAccretion }
2592cc0ad7SSingleAccretion
26bd7b59daSPhilip Craig impl<'a, 'r> fmt::Debug for CompileUnitSummary<'a, 'r> {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result2792cc0ad7SSingleAccretion fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2892cc0ad7SSingleAccretion let unit = self.unit;
297ee620a5SPhilip Craig write!(f, "0x{:08x} [", unit.header.offset().0)?;
3092cc0ad7SSingleAccretion let comp_dir = match unit.comp_dir {
3192cc0ad7SSingleAccretion Some(dir) => &dir.to_string_lossy(),
3292cc0ad7SSingleAccretion None => "None",
3392cc0ad7SSingleAccretion };
3492cc0ad7SSingleAccretion write!(f, "\"{comp_dir}\"")?;
3592cc0ad7SSingleAccretion let name = match unit.name {
3692cc0ad7SSingleAccretion Some(name) => &name.to_string_lossy(),
3792cc0ad7SSingleAccretion None => "None",
3892cc0ad7SSingleAccretion };
3992cc0ad7SSingleAccretion write!(f, ", \"{name}\"]")
4092cc0ad7SSingleAccretion }
4192cc0ad7SSingleAccretion }
4292cc0ad7SSingleAccretion
log_get_cu_summary<'a, 'r>(unit: UnitRef<'a, Reader<'r>>) -> CompileUnitSummary<'a, 'r>43bd7b59daSPhilip Craig pub fn log_get_cu_summary<'a, 'r>(unit: UnitRef<'a, Reader<'r>>) -> CompileUnitSummary<'a, 'r> {
4492cc0ad7SSingleAccretion CompileUnitSummary { unit }
4592cc0ad7SSingleAccretion }
4692cc0ad7SSingleAccretion
47bd7b59daSPhilip Craig pub struct DieRefSummary<'a, 'r> {
48*c4a38d67SPhilip Craig entry: &'a write::ConvertUnitEntry<'a, Reader<'r>>,
490b2c9d72SSingleAccretion }
500b2c9d72SSingleAccretion
51bd7b59daSPhilip Craig impl<'a, 'r> fmt::Debug for DieRefSummary<'a, 'r> {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result520b2c9d72SSingleAccretion fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
53*c4a38d67SPhilip Craig let section_offs = self
54*c4a38d67SPhilip Craig .entry
55*c4a38d67SPhilip Craig .offset
56*c4a38d67SPhilip Craig .to_unit_section_offset(&self.entry.read_unit);
577ee620a5SPhilip Craig write!(f, "0x{:08x}", section_offs.0)
580b2c9d72SSingleAccretion }
590b2c9d72SSingleAccretion }
600b2c9d72SSingleAccretion
log_get_die_ref<'a, 'r>( entry: &'a write::ConvertUnitEntry<'a, Reader<'r>>, ) -> DieRefSummary<'a, 'r>61bd7b59daSPhilip Craig pub fn log_get_die_ref<'a, 'r>(
62*c4a38d67SPhilip Craig entry: &'a write::ConvertUnitEntry<'a, Reader<'r>>,
63bd7b59daSPhilip Craig ) -> DieRefSummary<'a, 'r> {
64*c4a38d67SPhilip Craig DieRefSummary { entry }
650b2c9d72SSingleAccretion }
660b2c9d72SSingleAccretion
67bd7b59daSPhilip Craig struct DieDetailedSummary<'a, 'r> {
68*c4a38d67SPhilip Craig entry: &'a write::ConvertUnitEntry<'a, Reader<'r>>,
6992cc0ad7SSingleAccretion }
7092cc0ad7SSingleAccretion
log_begin_input_die<'a, 'r>(entry: &'a write::ConvertUnitEntry<'a, Reader<'r>>)71*c4a38d67SPhilip Craig pub fn log_begin_input_die<'a, 'r>(entry: &'a write::ConvertUnitEntry<'a, Reader<'r>>) {
7292cc0ad7SSingleAccretion dbi_log!(
730b2c9d72SSingleAccretion "=== Begin DIE at {:?} (depth = {}):\n{:?}",
74*c4a38d67SPhilip Craig log_get_die_ref(entry),
75*c4a38d67SPhilip Craig entry.depth,
76*c4a38d67SPhilip Craig DieDetailedSummary { entry }
7792cc0ad7SSingleAccretion );
7892cc0ad7SSingleAccretion }
7992cc0ad7SSingleAccretion
80bd7b59daSPhilip Craig impl<'a, 'r> fmt::Debug for DieDetailedSummary<'a, 'r> {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result8192cc0ad7SSingleAccretion fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
82*c4a38d67SPhilip Craig let unit = self.entry.read_unit;
83*c4a38d67SPhilip Craig write!(f, "{}\n", self.entry.tag)?;
8492cc0ad7SSingleAccretion
85*c4a38d67SPhilip Craig for attr in &self.entry.attrs {
8692cc0ad7SSingleAccretion write!(f, " {} (", attr.name())?;
8792cc0ad7SSingleAccretion let attr_value = attr.value();
8892cc0ad7SSingleAccretion match attr_value {
8992cc0ad7SSingleAccretion AttributeValue::Addr(addr) => {
9092cc0ad7SSingleAccretion write!(f, "{addr:08x}")
9192cc0ad7SSingleAccretion }
9292cc0ad7SSingleAccretion AttributeValue::DebugAddrIndex(index) => {
93bd7b59daSPhilip Craig if let Some(addr) = unit.address(index).ok() {
9492cc0ad7SSingleAccretion write!(f, "{addr:08x}")
9592cc0ad7SSingleAccretion } else {
9692cc0ad7SSingleAccretion write!(f, "<error reading address at index: {}>", index.0)
9792cc0ad7SSingleAccretion }
9892cc0ad7SSingleAccretion }
9992cc0ad7SSingleAccretion AttributeValue::Block(d) => write!(f, "{d:?}"),
10092cc0ad7SSingleAccretion AttributeValue::Udata(d) => write!(f, "{d}"),
10192cc0ad7SSingleAccretion AttributeValue::Data1(d) => write!(f, "{d}"),
10292cc0ad7SSingleAccretion AttributeValue::Data2(d) => write!(f, "{d}"),
10392cc0ad7SSingleAccretion AttributeValue::Data4(d) => write!(f, "{d}"),
10492cc0ad7SSingleAccretion AttributeValue::Data8(d) => write!(f, "{d}"),
10592cc0ad7SSingleAccretion AttributeValue::Sdata(d) => write!(f, "{d}"),
10692cc0ad7SSingleAccretion AttributeValue::Flag(d) => write!(f, "{d}"),
10792cc0ad7SSingleAccretion AttributeValue::DebugLineRef(offset) => write!(f, "0x{:08x}", offset.0),
10892cc0ad7SSingleAccretion AttributeValue::FileIndex(index) => write!(f, "0x{index:08x}"),
10992cc0ad7SSingleAccretion AttributeValue::String(_)
11092cc0ad7SSingleAccretion | AttributeValue::DebugStrRef(_)
11192cc0ad7SSingleAccretion | AttributeValue::DebugStrOffsetsIndex(_) => {
112bd7b59daSPhilip Craig if let Ok(s) = unit.attr_string(attr_value) {
11392cc0ad7SSingleAccretion write!(f, "\"{}\"", &s.to_string_lossy())
11492cc0ad7SSingleAccretion } else {
11592cc0ad7SSingleAccretion write!(f, "<error reading string>")
11692cc0ad7SSingleAccretion }
11792cc0ad7SSingleAccretion }
11892cc0ad7SSingleAccretion AttributeValue::RangeListsRef(_) | AttributeValue::DebugRngListsIndex(_) => {
119bd7b59daSPhilip Craig let _ = unit.attr_ranges_offset(attr_value);
12092cc0ad7SSingleAccretion write!(f, "<TODO: rnglist dump>")
12192cc0ad7SSingleAccretion }
12292cc0ad7SSingleAccretion AttributeValue::LocationListsRef(_) | AttributeValue::DebugLocListsIndex(_) => {
123bd7b59daSPhilip Craig let _ = unit.attr_locations_offset(attr_value);
12492cc0ad7SSingleAccretion write!(f, "<TODO: loclist dump>")
12592cc0ad7SSingleAccretion }
12692cc0ad7SSingleAccretion AttributeValue::Exprloc(_) => {
12792cc0ad7SSingleAccretion write!(f, "<TODO: exprloc dump>")
12892cc0ad7SSingleAccretion }
12992cc0ad7SSingleAccretion AttributeValue::Encoding(value) => write!(f, "{value}"),
13092cc0ad7SSingleAccretion AttributeValue::DecimalSign(value) => write!(f, "{value}"),
13192cc0ad7SSingleAccretion AttributeValue::Endianity(value) => write!(f, "{value}"),
13292cc0ad7SSingleAccretion AttributeValue::Accessibility(value) => write!(f, "{value}"),
13392cc0ad7SSingleAccretion AttributeValue::Visibility(value) => write!(f, "{value}"),
13492cc0ad7SSingleAccretion AttributeValue::Virtuality(value) => write!(f, "{value}"),
13592cc0ad7SSingleAccretion AttributeValue::Language(value) => write!(f, "{value}"),
13692cc0ad7SSingleAccretion AttributeValue::AddressClass(value) => write!(f, "{value}"),
13792cc0ad7SSingleAccretion AttributeValue::IdentifierCase(value) => write!(f, "{value}"),
13892cc0ad7SSingleAccretion AttributeValue::CallingConvention(value) => write!(f, "{value}"),
13992cc0ad7SSingleAccretion AttributeValue::Inline(value) => write!(f, "{value}"),
14092cc0ad7SSingleAccretion AttributeValue::Ordering(value) => write!(f, "{value}"),
14141ff8e7bSSingleAccretion AttributeValue::UnitRef(offset) => {
1427ee620a5SPhilip Craig write!(f, "0x{:08x}", offset.to_unit_section_offset(&unit).0)
14341ff8e7bSSingleAccretion }
14492cc0ad7SSingleAccretion AttributeValue::DebugInfoRef(offset) => write!(f, "0x{:08x}", offset.0),
14592cc0ad7SSingleAccretion unexpected_attr => write!(f, "<unexpected attr: {unexpected_attr:?}>"),
14692cc0ad7SSingleAccretion }?;
14792cc0ad7SSingleAccretion write!(f, ")\n")?;
14892cc0ad7SSingleAccretion }
14992cc0ad7SSingleAccretion Ok(())
15092cc0ad7SSingleAccretion }
15192cc0ad7SSingleAccretion }
15292cc0ad7SSingleAccretion
15392cc0ad7SSingleAccretion struct OutDieDetailedSummary<'a> {
15492cc0ad7SSingleAccretion die_id: write::UnitEntryId,
15592cc0ad7SSingleAccretion unit: &'a write::Unit,
15692cc0ad7SSingleAccretion strings: &'a write::StringTable,
15792cc0ad7SSingleAccretion }
15892cc0ad7SSingleAccretion
15992cc0ad7SSingleAccretion impl<'a> fmt::Debug for OutDieDetailedSummary<'a> {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result16092cc0ad7SSingleAccretion fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
16192cc0ad7SSingleAccretion let die = self.unit.get(self.die_id);
16292cc0ad7SSingleAccretion write!(f, "{}\n", die.tag())?;
16392cc0ad7SSingleAccretion for attr in die.attrs() {
16492cc0ad7SSingleAccretion write!(f, " {} (", attr.name())?;
16592cc0ad7SSingleAccretion let attr_value = attr.get();
16692cc0ad7SSingleAccretion match attr_value {
16792cc0ad7SSingleAccretion write::AttributeValue::Address(addr) => match addr {
16892cc0ad7SSingleAccretion write::Address::Constant(addr_value) => write!(f, "{addr_value:08x}"),
16992cc0ad7SSingleAccretion write::Address::Symbol { symbol, addend } => {
17092cc0ad7SSingleAccretion write!(f, "symbol #{symbol}+{addend}")
17192cc0ad7SSingleAccretion }
17292cc0ad7SSingleAccretion },
17392cc0ad7SSingleAccretion write::AttributeValue::Block(d) => {
17492cc0ad7SSingleAccretion write!(f, "{:?}", Reader::new(d.as_slice(), LittleEndian))
17592cc0ad7SSingleAccretion }
17692cc0ad7SSingleAccretion write::AttributeValue::Udata(d) => write!(f, "{d}"),
17792cc0ad7SSingleAccretion write::AttributeValue::Data1(d) => write!(f, "{d}"),
17892cc0ad7SSingleAccretion write::AttributeValue::Data2(d) => write!(f, "{d}"),
17992cc0ad7SSingleAccretion write::AttributeValue::Data4(d) => write!(f, "{d}"),
18092cc0ad7SSingleAccretion write::AttributeValue::Data8(d) => write!(f, "{d}"),
18192cc0ad7SSingleAccretion write::AttributeValue::Sdata(d) => write!(f, "{d}"),
18292cc0ad7SSingleAccretion write::AttributeValue::Flag(d) => write!(f, "{d}"),
18392cc0ad7SSingleAccretion write::AttributeValue::LineProgramRef => write!(f, "LineProgramRef"),
18492cc0ad7SSingleAccretion write::AttributeValue::FileIndex(index) => match index {
18592cc0ad7SSingleAccretion Some(id) => write!(f, "{id:?}"),
18692cc0ad7SSingleAccretion None => write!(f, "<file index missing>"),
18792cc0ad7SSingleAccretion },
18892cc0ad7SSingleAccretion write::AttributeValue::String(s) => {
18992cc0ad7SSingleAccretion write!(f, "\"{}\"", &String::from_utf8_lossy(s))
19092cc0ad7SSingleAccretion }
19192cc0ad7SSingleAccretion write::AttributeValue::StringRef(id) => {
19292cc0ad7SSingleAccretion write!(f, "\"{}\"", &String::from_utf8_lossy(self.strings.get(*id)))
19392cc0ad7SSingleAccretion }
19492cc0ad7SSingleAccretion write::AttributeValue::RangeListRef(_) => {
19592cc0ad7SSingleAccretion write!(f, "<TODO: out rnglist dump>")
19692cc0ad7SSingleAccretion }
19792cc0ad7SSingleAccretion write::AttributeValue::LocationListRef(_) => {
19892cc0ad7SSingleAccretion write!(f, "<TODO: out loclist dump>")
19992cc0ad7SSingleAccretion }
20092cc0ad7SSingleAccretion write::AttributeValue::Exprloc(_) => {
20192cc0ad7SSingleAccretion write!(f, "<TODO: out exprloc dump>")
20292cc0ad7SSingleAccretion }
20392cc0ad7SSingleAccretion write::AttributeValue::Encoding(value) => write!(f, "{value}"),
20492cc0ad7SSingleAccretion write::AttributeValue::DecimalSign(value) => write!(f, "{value}"),
20592cc0ad7SSingleAccretion write::AttributeValue::Endianity(value) => write!(f, "{value}"),
20692cc0ad7SSingleAccretion write::AttributeValue::Accessibility(value) => write!(f, "{value}"),
20792cc0ad7SSingleAccretion write::AttributeValue::Visibility(value) => write!(f, "{value}"),
20892cc0ad7SSingleAccretion write::AttributeValue::Virtuality(value) => write!(f, "{value}"),
20992cc0ad7SSingleAccretion write::AttributeValue::Language(value) => write!(f, "{value}"),
21092cc0ad7SSingleAccretion write::AttributeValue::AddressClass(value) => write!(f, "{value}"),
21192cc0ad7SSingleAccretion write::AttributeValue::IdentifierCase(value) => write!(f, "{value}"),
21292cc0ad7SSingleAccretion write::AttributeValue::CallingConvention(value) => write!(f, "{value}"),
21392cc0ad7SSingleAccretion write::AttributeValue::Inline(value) => write!(f, "{value}"),
21492cc0ad7SSingleAccretion write::AttributeValue::Ordering(value) => write!(f, "{value}"),
21592cc0ad7SSingleAccretion write::AttributeValue::UnitRef(unit_ref) => write!(f, "{unit_ref:?}>"),
21692cc0ad7SSingleAccretion write::AttributeValue::DebugInfoRef(reference) => match reference {
2177ee620a5SPhilip Craig write::DebugInfoRef::Symbol(index) => write!(f, "symbol #{index}>"),
2187ee620a5SPhilip Craig write::DebugInfoRef::Entry(unit_id, die_id) => {
21992cc0ad7SSingleAccretion write!(f, "{die_id:?} in {unit_id:?}>")
22092cc0ad7SSingleAccretion }
22192cc0ad7SSingleAccretion },
22292cc0ad7SSingleAccretion unexpected_attr => write!(f, "<unexpected attr: {unexpected_attr:?}>"),
22392cc0ad7SSingleAccretion }?;
22492cc0ad7SSingleAccretion write!(f, ")\n")?;
22592cc0ad7SSingleAccretion }
22692cc0ad7SSingleAccretion Ok(())
22792cc0ad7SSingleAccretion }
22892cc0ad7SSingleAccretion }
22992cc0ad7SSingleAccretion
log_end_output_die( die_id: write::UnitEntryId, entry: &write::ConvertUnitEntry<'_, Reader<'_>>, unit: &write::ConvertUnit<'_, Reader<'_>>, )23092cc0ad7SSingleAccretion pub fn log_end_output_die(
23192cc0ad7SSingleAccretion die_id: write::UnitEntryId,
232*c4a38d67SPhilip Craig entry: &write::ConvertUnitEntry<'_, Reader<'_>>,
233*c4a38d67SPhilip Craig unit: &write::ConvertUnit<'_, Reader<'_>>,
23492cc0ad7SSingleAccretion ) {
23592cc0ad7SSingleAccretion dbi_log!(
2360b2c9d72SSingleAccretion "=== End DIE at {:?} (depth = {}):\n{:?}",
237*c4a38d67SPhilip Craig log_get_die_ref(entry),
238*c4a38d67SPhilip Craig entry.depth,
23992cc0ad7SSingleAccretion OutDieDetailedSummary {
24092cc0ad7SSingleAccretion die_id,
241*c4a38d67SPhilip Craig unit: &unit.unit,
242*c4a38d67SPhilip Craig strings: &unit.strings,
24392cc0ad7SSingleAccretion }
24492cc0ad7SSingleAccretion );
24592cc0ad7SSingleAccretion }
24692cc0ad7SSingleAccretion
log_end_output_die_skipped(entry: &write::ConvertUnitEntry<'_, Reader<'_>>, reason: &str)247*c4a38d67SPhilip Craig pub fn log_end_output_die_skipped(entry: &write::ConvertUnitEntry<'_, Reader<'_>>, reason: &str) {
24892cc0ad7SSingleAccretion dbi_log!(
2490b2c9d72SSingleAccretion "=== End DIE at {:?} (depth = {}):\n Skipped as {}\n",
250*c4a38d67SPhilip Craig log_get_die_ref(entry),
251*c4a38d67SPhilip Craig entry.depth,
25292cc0ad7SSingleAccretion reason
25392cc0ad7SSingleAccretion );
25492cc0ad7SSingleAccretion }
255a126152dSSingleAccretion
log_get_value_name(value: ValueLabel) -> ValueNameSummary2561c521e17SSingleAccretion pub fn log_get_value_name(value: ValueLabel) -> ValueNameSummary {
2571c521e17SSingleAccretion ValueNameSummary { value }
2581c521e17SSingleAccretion }
2591c521e17SSingleAccretion
2601c521e17SSingleAccretion pub struct ValueNameSummary {
2611c521e17SSingleAccretion value: ValueLabel,
2621c521e17SSingleAccretion }
2631c521e17SSingleAccretion
2641c521e17SSingleAccretion impl fmt::Debug for ValueNameSummary {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result2651c521e17SSingleAccretion fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2661c521e17SSingleAccretion if self.value == get_vmctx_value_label() {
2671c521e17SSingleAccretion f.pad("VMCTX")
2681c521e17SSingleAccretion } else {
2691c521e17SSingleAccretion f.pad(&format!("L#{}", self.value.as_u32()))
2701c521e17SSingleAccretion }
2711c521e17SSingleAccretion }
2721c521e17SSingleAccretion }
2731c521e17SSingleAccretion
log_get_value_loc(loc: LabelValueLoc, isa: &dyn TargetIsa) -> ValueLocSummary<'_>2748a42768fSAlex Crichton pub fn log_get_value_loc(loc: LabelValueLoc, isa: &dyn TargetIsa) -> ValueLocSummary<'_> {
2751c521e17SSingleAccretion ValueLocSummary { loc, isa }
2761c521e17SSingleAccretion }
2771c521e17SSingleAccretion
2781c521e17SSingleAccretion pub struct ValueLocSummary<'a> {
2791c521e17SSingleAccretion loc: LabelValueLoc,
2801c521e17SSingleAccretion isa: &'a dyn TargetIsa,
2811c521e17SSingleAccretion }
2821c521e17SSingleAccretion
2831c521e17SSingleAccretion impl<'a> fmt::Debug for ValueLocSummary<'a> {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result2841c521e17SSingleAccretion fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2851c521e17SSingleAccretion if let LabelValueLoc::Reg(reg) = self.loc {
2861c521e17SSingleAccretion let reg_name = self.isa.pretty_print_reg(reg, self.isa.pointer_bytes());
2871c521e17SSingleAccretion return write!(f, "{reg_name}");
2881c521e17SSingleAccretion }
2891c521e17SSingleAccretion
2901c521e17SSingleAccretion write!(f, "{:?}", self.loc)
2911c521e17SSingleAccretion }
2921c521e17SSingleAccretion }
2931c521e17SSingleAccretion
log_get_value_ranges<'a>( ranges: Option<&'a ValueLabelsRanges>, isa: &'a dyn TargetIsa, ) -> ValueRangesSummary<'a>2941c521e17SSingleAccretion pub fn log_get_value_ranges<'a>(
2951c521e17SSingleAccretion ranges: Option<&'a ValueLabelsRanges>,
2961c521e17SSingleAccretion isa: &'a dyn TargetIsa,
2971c521e17SSingleAccretion ) -> ValueRangesSummary<'a> {
2981c521e17SSingleAccretion ValueRangesSummary { ranges, isa }
2991c521e17SSingleAccretion }
3001c521e17SSingleAccretion
3011c521e17SSingleAccretion pub struct ValueRangesSummary<'a> {
3021c521e17SSingleAccretion ranges: Option<&'a ValueLabelsRanges>,
3031c521e17SSingleAccretion isa: &'a dyn TargetIsa,
3041c521e17SSingleAccretion }
3051c521e17SSingleAccretion
3061c521e17SSingleAccretion impl<'a> fmt::Debug for ValueRangesSummary<'a> {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result3071c521e17SSingleAccretion fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3081c521e17SSingleAccretion if let Some(ranges) = self.ranges {
3091c521e17SSingleAccretion // Sort the output first for nicer display.
3101c521e17SSingleAccretion let mut locals = Vec::new();
3111c521e17SSingleAccretion for value in ranges {
3121c521e17SSingleAccretion locals.push(*value.0);
3131c521e17SSingleAccretion }
3141c521e17SSingleAccretion locals.sort_by_key(|n| n.as_u32());
3151c521e17SSingleAccretion
3161c521e17SSingleAccretion for i in 0..locals.len() {
3171c521e17SSingleAccretion let name = locals[i];
3181c521e17SSingleAccretion write!(f, "{:<6?}:", log_get_value_name(name))?;
3191c521e17SSingleAccretion for range in ranges.get(&name).unwrap() {
3201c521e17SSingleAccretion write!(f, " {:?}", log_get_value_loc(range.loc, self.isa))?;
3211c521e17SSingleAccretion write!(f, "@[{}..{})", range.start, range.end)?;
3221c521e17SSingleAccretion }
3231c521e17SSingleAccretion if i != locals.len() - 1 {
3241c521e17SSingleAccretion writeln!(f)?;
3251c521e17SSingleAccretion }
3261c521e17SSingleAccretion }
3271c521e17SSingleAccretion }
3281c521e17SSingleAccretion Ok(())
3291c521e17SSingleAccretion }
3301c521e17SSingleAccretion }
331