diff --git a/crates/debug/src/gc.rs b/crates/debug/src/gc.rs index 9ac8ef7605..6d2ff7907e 100644 --- a/crates/debug/src/gc.rs +++ b/crates/debug/src/gc.rs @@ -170,6 +170,9 @@ fn has_valid_code_range>( } else if let Some(low_pc) = die.attr_value(constants::DW_AT_low_pc)? { if let read::AttributeValue::Addr(a) = low_pc { return Ok(at.can_translate_address(a)); + } else if let read::AttributeValue::DebugAddrIndex(i) = low_pc { + let a = dwarf.debug_addr.get_address(4, unit.addr_base, i)?; + return Ok(at.can_translate_address(a)); } } } diff --git a/crates/debug/src/read_debuginfo.rs b/crates/debug/src/read_debuginfo.rs index 9416799bc4..f1a0f149d6 100644 --- a/crates/debug/src/read_debuginfo.rs +++ b/crates/debug/src/read_debuginfo.rs @@ -61,47 +61,41 @@ fn convert_sections<'a>(sections: HashMap<&str, &'a [u8]>) -> Result> sections.get(".debug_line").unwrap_or(&EMPTY_SECTION), endian, ); + let debug_addr = DebugAddr::from(EndianSlice::new( + sections.get(".debug_addr").unwrap_or(&EMPTY_SECTION), + endian, + )); - if sections.contains_key(".debug_addr") { - bail!("Unexpected .debug_addr"); - } - - let debug_addr = DebugAddr::from(EndianSlice::new(EMPTY_SECTION, endian)); - - if sections.contains_key(".debug_line_str") { - bail!("Unexpected .debug_line_str"); - } - - let debug_line_str = DebugLineStr::from(EndianSlice::new(EMPTY_SECTION, endian)); + let debug_line_str = DebugLineStr::from(EndianSlice::new( + sections.get(".debug_line_str").unwrap_or(&EMPTY_SECTION), + endian, + )); let debug_str_sup = DebugStr::from(EndianSlice::new(EMPTY_SECTION, endian)); - if sections.contains_key(".debug_rnglists") { - bail!("Unexpected .debug_rnglists"); - } - let debug_ranges = match sections.get(".debug_ranges") { Some(section) => DebugRanges::new(section, endian), None => DebugRanges::new(EMPTY_SECTION, endian), }; - let debug_rnglists = DebugRngLists::new(EMPTY_SECTION, endian); + let debug_rnglists = match sections.get(".debug_rnglists") { + Some(section) => DebugRngLists::new(section, endian), + None => DebugRngLists::new(EMPTY_SECTION, endian), + }; let ranges = RangeLists::new(debug_ranges, debug_rnglists); - if sections.contains_key(".debug_loclists") { - bail!("Unexpected .debug_loclists"); - } - let debug_loc = match sections.get(".debug_loc") { Some(section) => DebugLoc::new(section, endian), None => DebugLoc::new(EMPTY_SECTION, endian), }; - let debug_loclists = DebugLocLists::new(EMPTY_SECTION, endian); + let debug_loclists = match sections.get(".debug_loclists") { + Some(section) => DebugLocLists::new(section, endian), + None => DebugLocLists::new(EMPTY_SECTION, endian), + }; let locations = LocationLists::new(debug_loc, debug_loclists); - if sections.contains_key(".debug_str_offsets") { - bail!("Unexpected .debug_str_offsets"); - } - - let debug_str_offsets = DebugStrOffsets::from(EndianSlice::new(EMPTY_SECTION, endian)); + let debug_str_offsets = DebugStrOffsets::from(EndianSlice::new( + sections.get(".debug_str_offsets").unwrap_or(&EMPTY_SECTION), + endian, + )); if sections.contains_key(".debug_types") { bail!("Unexpected .debug_types"); diff --git a/crates/debug/src/transform/attr.rs b/crates/debug/src/transform/attr.rs index 5bc3a8f9c0..0820a82b17 100644 --- a/crates/debug/src/transform/attr.rs +++ b/crates/debug/src/transform/attr.rs @@ -4,12 +4,20 @@ use super::range_info_builder::RangeInfoBuilder; use super::refs::{PendingDebugInfoRefs, PendingUnitRefs}; use super::{DebugInputContext, Reader, TransformError}; use anyhow::{bail, Error}; -use gimli::{write, AttributeValue, DebugLineOffset, DebugStr, DebuggingInformationEntry}; +use gimli::{ + write, AttributeValue, DebugLineOffset, DebugLineStr, DebugStr, DebugStrOffsets, + DebuggingInformationEntry, Unit, +}; use wasmtime_environ::isa::TargetIsa; +#[derive(Debug)] pub(crate) enum FileAttributeContext<'a> { Root(Option), - Children(&'a Vec, Option<&'a CompiledExpression<'a>>), + Children( + &'a Vec, + u64, + Option<&'a CompiledExpression<'a>>, + ), } fn is_exprloc_to_loclist_allowed(attr_name: gimli::constants::DwAt) -> bool { @@ -28,11 +36,11 @@ fn is_exprloc_to_loclist_allowed(attr_name: gimli::constants::DwAt) -> bool { } pub(crate) fn clone_die_attributes<'a, R>( + unit: &Unit, entry: &DebuggingInformationEntry, context: &DebugInputContext, addr_tr: &'a AddressTransform, frame_info: Option<&FunctionFrameInfo>, - unit_encoding: gimli::Encoding, out_unit: &mut write::Unit, current_scope_id: write::UnitEntryId, subprogram_range_builder: Option, @@ -49,23 +57,24 @@ where { let _tag = &entry.tag(); let endian = gimli::RunTimeEndian::Little; + let unit_encoding = unit.encoding(); let range_info = if let Some(subprogram_range_builder) = subprogram_range_builder { subprogram_range_builder - } else if entry.tag() == gimli::DW_TAG_compile_unit { - // FIXME currently address_transform operate on a single func range, - // once it is fixed we can properly set DW_AT_ranges attribute. - // Using for now DW_AT_low_pc = 0. - RangeInfoBuilder::Position(0) } else { - RangeInfoBuilder::from(entry, context, unit_encoding, cu_low_pc)? + // FIXME for CU: currently address_transform operate on a single + // function range, and when CU spans multiple ranges the + // transformation may be incomplete. + RangeInfoBuilder::from(unit, entry, context, cu_low_pc)? }; range_info.build(addr_tr, out_unit, current_scope_id); let mut attrs = entry.attrs(); while let Some(attr) = attrs.next()? { let attr_value = match attr.value() { - AttributeValue::Addr(_) if attr.name() == gimli::DW_AT_low_pc => { + AttributeValue::Addr(_) | AttributeValue::DebugAddrIndex(_) + if attr.name() == gimli::DW_AT_low_pc => + { continue; } AttributeValue::Udata(_) if attr.name() == gimli::DW_AT_high_pc => { @@ -77,11 +86,19 @@ where AttributeValue::Exprloc(_) if attr.name() == gimli::DW_AT_frame_base => { continue; } + AttributeValue::DebugAddrBase(_) | AttributeValue::DebugStrOffsetsBase(_) => { + continue; + } AttributeValue::Addr(u) => { let addr = addr_tr.translate(u).unwrap_or(write::Address::Constant(0)); write::AttributeValue::Address(addr) } + AttributeValue::DebugAddrIndex(i) => { + let u = context.debug_addr.get_address(4, unit.addr_base, i)?; + let addr = addr_tr.translate(u).unwrap_or(write::Address::Constant(0)); + write::AttributeValue::Address(addr) + } AttributeValue::Udata(u) => write::AttributeValue::Udata(u), AttributeValue::Data1(d) => write::AttributeValue::Data1(d), AttributeValue::Data2(d) => write::AttributeValue::Data2(d), @@ -99,8 +116,8 @@ where } } AttributeValue::FileIndex(i) => { - if let FileAttributeContext::Children(file_map, _) = file_context { - write::AttributeValue::FileIndex(Some(file_map[(i - 1) as usize])) + if let FileAttributeContext::Children(file_map, file_index_base, _) = file_context { + write::AttributeValue::FileIndex(Some(file_map[(i - file_index_base) as usize])) } else { return Err(TransformError("unexpected file index attribute").into()); } @@ -109,9 +126,17 @@ where let s = context.debug_str.get_str(str_offset)?.to_slice()?.to_vec(); write::AttributeValue::StringRef(out_strings.add(s)) } + AttributeValue::DebugStrOffsetsIndex(i) => { + let str_offset = context.debug_str_offsets.get_str_offset( + gimli::Format::Dwarf32, + unit.str_offsets_base, + i, + )?; + let s = context.debug_str.get_str(str_offset)?.to_slice()?.to_vec(); + write::AttributeValue::StringRef(out_strings.add(s)) + } AttributeValue::RangeListsRef(r) => { - let range_info = - RangeInfoBuilder::from_ranges_ref(r, context, unit_encoding, cu_low_pc)?; + let range_info = RangeInfoBuilder::from_ranges_ref(unit, r, context, cu_low_pc)?; let range_list_id = range_info.build_ranges(addr_tr, &mut out_unit.ranges); write::AttributeValue::RangeListRef(range_list_id) } @@ -122,14 +147,14 @@ where unit_encoding, low_pc, &context.debug_addr, - context.debug_addr_base, + unit.addr_base, )?; - let frame_base = if let FileAttributeContext::Children(_, frame_base) = file_context - { - frame_base - } else { - None - }; + let frame_base = + if let FileAttributeContext::Children(_, _, frame_base) = file_context { + frame_base + } else { + None + }; let mut result = None; while let Some(loc) = locs.next()? { if let Some(expr) = @@ -166,12 +191,12 @@ where write::AttributeValue::LocationListRef(list_id) } AttributeValue::Exprloc(ref expr) => { - let frame_base = if let FileAttributeContext::Children(_, frame_base) = file_context - { - frame_base - } else { - None - }; + let frame_base = + if let FileAttributeContext::Children(_, _, frame_base) = file_context { + frame_base + } else { + None + }; if let Some(expr) = compile_expression(expr, unit_encoding, frame_base, isa)? { if expr.is_simple() { if let Some(expr) = expr.build() { @@ -263,7 +288,10 @@ where pub(crate) fn clone_attr_string( attr_value: &AttributeValue, form: gimli::DwForm, + unit: &Unit, debug_str: &DebugStr, + debug_str_offsets: &DebugStrOffsets, + debug_line_str: &DebugLineStr, out_strings: &mut write::StringTable, ) -> Result where @@ -273,6 +301,17 @@ where AttributeValue::DebugStrRef(str_offset) => { debug_str.get_str(*str_offset)?.to_slice()?.to_vec() } + AttributeValue::DebugStrOffsetsIndex(i) => { + let str_offset = debug_str_offsets.get_str_offset( + gimli::Format::Dwarf32, + unit.str_offsets_base, + *i, + )?; + debug_str.get_str(str_offset)?.to_slice()?.to_vec() + } + AttributeValue::DebugLineStrRef(str_offset) => { + debug_line_str.get_str(*str_offset)?.to_slice()?.to_vec() + } AttributeValue::String(b) => b.to_slice()?.to_vec(), v => bail!("Unexpected attribute value: {:?}", v), }; diff --git a/crates/debug/src/transform/line_program.rs b/crates/debug/src/transform/line_program.rs index e5d0160aaa..b34df1d4b9 100644 --- a/crates/debug/src/transform/line_program.rs +++ b/crates/debug/src/transform/line_program.rs @@ -3,7 +3,8 @@ use super::attr::clone_attr_string; use super::{Reader, TransformError}; use anyhow::{Context, Error}; use gimli::{ - write, DebugLine, DebugLineOffset, DebugStr, DebuggingInformationEntry, LineEncoding, Unit, + write, DebugLine, DebugLineOffset, DebugLineStr, DebugStr, DebugStrOffsets, + DebuggingInformationEntry, LineEncoding, Unit, }; use more_asserts::assert_le; use wasmtime_environ::entity::EntityRef; @@ -46,9 +47,11 @@ pub(crate) fn clone_line_program( addr_tr: &AddressTransform, out_encoding: gimli::Encoding, debug_str: &DebugStr, + debug_str_offsets: &DebugStrOffsets, + debug_line_str: &DebugLineStr, debug_line: &DebugLine, out_strings: &mut write::StringTable, -) -> Result<(write::LineProgram, DebugLineOffset, Vec), Error> +) -> Result<(write::LineProgram, DebugLineOffset, Vec, u64), Error> where R: Reader, { @@ -63,13 +66,19 @@ where let out_comp_dir = clone_attr_string( comp_dir.as_ref().context("comp_dir")?, gimli::DW_FORM_strp, + unit, debug_str, + debug_str_offsets, + debug_line_str, out_strings, )?; let out_comp_name = clone_attr_string( comp_name.as_ref().context("comp_name")?, gimli::DW_FORM_strp, + unit, debug_str, + debug_str_offsets, + debug_line_str, out_strings, )?; @@ -81,7 +90,8 @@ where ); if let Ok(program) = program { let header = program.header(); - assert_le!(header.version(), 4, "not supported 5"); + let file_index_base = if header.version() < 5 { 1 } else { 0 }; + assert_le!(header.version(), 5, "not supported 6"); let line_encoding = LineEncoding { minimum_instruction_length: header.minimum_instruction_length(), maximum_operations_per_instruction: header.maximum_operations_per_instruction(), @@ -102,7 +112,10 @@ where let dir_id = out_program.add_directory(clone_attr_string( dir_attr, gimli::DW_FORM_string, + unit, debug_str, + debug_str_offsets, + debug_line_str, out_strings, )?); dirs.push(dir_id); @@ -114,7 +127,10 @@ where clone_attr_string( &file_entry.path_name(), gimli::DW_FORM_string, + unit, debug_str, + debug_str_offsets, + debug_line_str, out_strings, )?, dir_id, @@ -238,7 +254,7 @@ where }; out_program.row().address_offset = address_offset; out_program.row().op_index = *op_index; - out_program.row().file = files[(file_index - 1) as usize]; + out_program.row().file = files[(file_index - file_index_base) as usize]; out_program.row().line = *line; out_program.row().column = *column; out_program.row().discriminator = *discriminator; @@ -255,7 +271,7 @@ where let end_addr = (map.offset + map.len - 1) as u64; out_program.end_sequence(end_addr); } - Ok((out_program, offset, files)) + Ok((out_program, offset, files, file_index_base)) } else { Err(TransformError("Valid line program not found").into()) } diff --git a/crates/debug/src/transform/mod.rs b/crates/debug/src/transform/mod.rs index 2a1721fc2a..8d6c009e30 100644 --- a/crates/debug/src/transform/mod.rs +++ b/crates/debug/src/transform/mod.rs @@ -5,8 +5,8 @@ use crate::gc::build_dependencies; use crate::DebugInfoData; use anyhow::Error; use gimli::{ - write, DebugAddr, DebugAddrBase, DebugLine, DebugStr, LocationLists, RangeLists, - UnitSectionOffset, + write, DebugAddr, DebugLine, DebugLineStr, DebugStr, DebugStrOffsets, LocationLists, + RangeLists, UnitSectionOffset, }; use std::collections::HashSet; use thiserror::Error; @@ -38,9 +38,10 @@ where R: Reader, { debug_str: &'a DebugStr, + debug_str_offsets: &'a DebugStrOffsets, + debug_line_str: &'a DebugLineStr, debug_line: &'a DebugLine, debug_addr: &'a DebugAddr, - debug_addr_base: DebugAddrBase, rnglists: &'a RangeLists, loclists: &'a LocationLists, reachable: &'a HashSet, @@ -58,9 +59,10 @@ pub fn transform_dwarf( let context = DebugInputContext { debug_str: &di.dwarf.debug_str, + debug_str_offsets: &di.dwarf.debug_str_offsets, + debug_line_str: &di.dwarf.debug_line_str, debug_line: &di.dwarf.debug_line, debug_addr: &di.dwarf.debug_addr, - debug_addr_base: DebugAddrBase(0), rnglists: &di.dwarf.ranges, loclists: &di.dwarf.locations, reachable: &reachable, diff --git a/crates/debug/src/transform/range_info_builder.rs b/crates/debug/src/transform/range_info_builder.rs index 3043b01732..23c2b33e3d 100644 --- a/crates/debug/src/transform/range_info_builder.rs +++ b/crates/debug/src/transform/range_info_builder.rs @@ -1,7 +1,7 @@ use super::address_transform::AddressTransform; use super::{DebugInputContext, Reader}; use anyhow::Error; -use gimli::{write, AttributeValue, DebuggingInformationEntry, RangeListsOffset}; +use gimli::{write, AttributeValue, DebuggingInformationEntry, RangeListsOffset, Unit}; use more_asserts::assert_lt; use wasmtime_environ::entity::EntityRef; use wasmtime_environ::wasm::DefinedFuncIndex; @@ -15,21 +15,25 @@ pub(crate) enum RangeInfoBuilder { impl RangeInfoBuilder { pub(crate) fn from( + unit: &Unit, entry: &DebuggingInformationEntry, context: &DebugInputContext, - unit_encoding: gimli::Encoding, cu_low_pc: u64, ) -> Result where R: Reader, { if let Some(AttributeValue::RangeListsRef(r)) = entry.attr_value(gimli::DW_AT_ranges)? { - return RangeInfoBuilder::from_ranges_ref(r, context, unit_encoding, cu_low_pc); + return RangeInfoBuilder::from_ranges_ref(unit, r, context, cu_low_pc); }; let low_pc = if let Some(AttributeValue::Addr(addr)) = entry.attr_value(gimli::DW_AT_low_pc)? { addr + } else if let Some(AttributeValue::DebugAddrIndex(i)) = + entry.attr_value(gimli::DW_AT_low_pc)? + { + context.debug_addr.get_address(4, unit.addr_base, i)? } else { return Ok(RangeInfoBuilder::Undefined); }; @@ -44,20 +48,21 @@ impl RangeInfoBuilder { } pub(crate) fn from_ranges_ref( + unit: &Unit, ranges: RangeListsOffset, context: &DebugInputContext, - unit_encoding: gimli::Encoding, cu_low_pc: u64, ) -> Result where R: Reader, { + let unit_encoding = unit.encoding(); let mut ranges = context.rnglists.ranges( ranges, unit_encoding, cu_low_pc, &context.debug_addr, - context.debug_addr_base, + unit.addr_base, )?; let mut result = Vec::new(); while let Some(range) = ranges.next()? { @@ -75,18 +80,23 @@ impl RangeInfoBuilder { } pub(crate) fn from_subprogram_die( + unit: &Unit, entry: &DebuggingInformationEntry, context: &DebugInputContext, - unit_encoding: gimli::Encoding, addr_tr: &AddressTransform, cu_low_pc: u64, ) -> Result where R: Reader, { + let unit_encoding = unit.encoding(); let addr = if let Some(AttributeValue::Addr(addr)) = entry.attr_value(gimli::DW_AT_low_pc)? { addr + } else if let Some(AttributeValue::DebugAddrIndex(i)) = + entry.attr_value(gimli::DW_AT_low_pc)? + { + context.debug_addr.get_address(4, unit.addr_base, i)? } else if let Some(AttributeValue::RangeListsRef(r)) = entry.attr_value(gimli::DW_AT_ranges)? { @@ -95,7 +105,7 @@ impl RangeInfoBuilder { unit_encoding, cu_low_pc, &context.debug_addr, - context.debug_addr_base, + unit.addr_base, )?; if let Some(range) = ranges.next()? { range.begin diff --git a/crates/debug/src/transform/unit.rs b/crates/debug/src/transform/unit.rs index 68b3f209ca..c37788e5fa 100644 --- a/crates/debug/src/transform/unit.rs +++ b/crates/debug/src/transform/unit.rs @@ -246,18 +246,21 @@ where // Iterate over all of this compilation unit's entries. let mut entries = unit.entries(); - let (mut comp_unit, unit_id, file_map, cu_low_pc, wp_die_id, vmctx_die_id) = + let (mut comp_unit, unit_id, file_map, file_index_base, cu_low_pc, wp_die_id, vmctx_die_id) = if let Some((depth_delta, entry)) = entries.next_dfs()? { assert_eq!(depth_delta, 0); - let (out_line_program, debug_line_offset, file_map) = clone_line_program( - &unit, - entry, - addr_tr, - out_encoding, - context.debug_str, - context.debug_line, - out_strings, - )?; + let (out_line_program, debug_line_offset, file_map, file_index_base) = + clone_line_program( + &unit, + entry, + addr_tr, + out_encoding, + context.debug_str, + context.debug_str_offsets, + context.debug_line_str, + context.debug_line, + out_strings, + )?; if entry.tag() == gimli::DW_TAG_compile_unit { let unit_id = out_units.add(write::Unit::new(out_encoding, out_line_program)); @@ -270,17 +273,21 @@ where entry.attr_value(gimli::DW_AT_low_pc)? { addr + } else if let Some(AttributeValue::DebugAddrIndex(i)) = + entry.attr_value(gimli::DW_AT_low_pc)? + { + context.debug_addr.get_address(4, unit.addr_base, i)? } else { // FIXME? return Err(TransformError("No low_pc for unit header").into()); 0 }; clone_die_attributes( + &unit, entry, context, addr_tr, None, - unit.encoding(), comp_unit, root_id, None, @@ -301,6 +308,7 @@ where comp_unit, unit_id, file_map, + file_index_base, cu_low_pc, wp_die_id, vmctx_die_id, @@ -342,13 +350,8 @@ where current_scope_ranges.update(new_stack_len); current_value_range.update(new_stack_len); let range_builder = if entry.tag() == gimli::DW_TAG_subprogram { - let range_builder = RangeInfoBuilder::from_subprogram_die( - entry, - context, - unit.encoding(), - addr_tr, - cu_low_pc, - )?; + let range_builder = + RangeInfoBuilder::from_subprogram_die(&unit, entry, context, addr_tr, cu_low_pc)?; if let RangeInfoBuilder::Function(func_index) = range_builder { if let Some(frame_info) = get_function_frame_info(module_info, func_index, value_ranges) @@ -366,8 +369,7 @@ where let high_pc = entry.attr_value(gimli::DW_AT_high_pc)?; let ranges = entry.attr_value(gimli::DW_AT_ranges)?; if high_pc.is_some() || ranges.is_some() { - let range_builder = - RangeInfoBuilder::from(entry, context, unit.encoding(), cu_low_pc)?; + let range_builder = RangeInfoBuilder::from(&unit, entry, context, cu_low_pc)?; current_scope_ranges.push(new_stack_len, range_builder.get_ranges(addr_tr)); Some(range_builder) } else { @@ -417,11 +419,11 @@ where die_ref_map.insert(entry.offset(), die_id); clone_die_attributes( + &unit, entry, context, addr_tr, current_value_range.top(), - unit.encoding(), &mut comp_unit, die_id, range_builder, @@ -430,7 +432,7 @@ where out_strings, &mut pending_die_refs, &mut pending_di_refs, - FileAttributeContext::Children(&file_map, current_frame_base.top()), + FileAttributeContext::Children(&file_map, file_index_base, current_frame_base.top()), isa, )?; diff --git a/tests/all/debug/testsuite/fib-wasm-dwarf5.wasm b/tests/all/debug/testsuite/fib-wasm-dwarf5.wasm new file mode 100755 index 0000000000..797ca9d02c Binary files /dev/null and b/tests/all/debug/testsuite/fib-wasm-dwarf5.wasm differ diff --git a/tests/all/debug/testsuite/fib-wasm.c b/tests/all/debug/testsuite/fib-wasm.c index 20c06f5efa..3170af3e31 100644 --- a/tests/all/debug/testsuite/fib-wasm.c +++ b/tests/all/debug/testsuite/fib-wasm.c @@ -1,10 +1,13 @@ // Compile with: -// clang --target=wasm32 fib-wasm.c -o fib-wasm.wasm -g \ +// clang --target=wasm32 fib-wasm.c -o fib-wasm.wasm -gdwarf-4 \ +// -Wl,--no-entry,--export=fib -nostdlib -fdebug-prefix-map=$PWD=. +// +// clang --target=wasm32 fib-wasm.c -o fib-wasm-dwarf5.wasm -gdwarf-5 \ // -Wl,--no-entry,--export=fib -nostdlib -fdebug-prefix-map=$PWD=. int fib(int n) { - int i, t, a = 0, b = 1; - for (i = 0; i < n; i++) { + int t, a = 0, b = 1; + for (int i = 0; i < n; i++) { t = a; a = b; b += t; diff --git a/tests/all/debug/testsuite/fib-wasm.wasm b/tests/all/debug/testsuite/fib-wasm.wasm index 0a1ebac429..95c36a3016 100755 Binary files a/tests/all/debug/testsuite/fib-wasm.wasm and b/tests/all/debug/testsuite/fib-wasm.wasm differ diff --git a/tests/all/debug/translate.rs b/tests/all/debug/translate.rs index fd15b0f555..1fba1c35c4 100644 --- a/tests/all/debug/translate.rs +++ b/tests/all/debug/translate.rs @@ -41,17 +41,51 @@ check: DW_AT_name ("fib") # Accepts one parameter check: DW_TAG_formal_parameter check: DW_AT_name ("n") -check: DW_AT_decl_line (5) -# Has four locals: i, t, a, b -check: DW_TAG_variable -check: DW_AT_name ("i") -check: DW_AT_decl_line (6) +check: DW_AT_decl_line (8) +# Has four locals: t, a, b, i check: DW_TAG_variable check: DW_AT_name ("t") +check: DW_AT_decl_line (9) check: DW_TAG_variable check: DW_AT_name ("a") check: DW_TAG_variable check: DW_AT_name ("b") +check: DW_TAG_variable +check: DW_AT_name ("i") +check: DW_AT_decl_line (10) + "##, + ) +} + +#[test] +#[ignore] +#[cfg(all( + any(target_os = "linux", target_os = "macos"), + target_pointer_width = "64" +))] +fn test_debug_dwarf5_translate() -> Result<()> { + check_wasm( + "tests/debug/testsuite/fib-wasm-dwarf5.wasm", + r##" +check: DW_TAG_compile_unit +# We have "fib" function +check: DW_TAG_subprogram +check: DW_AT_name ("fib") +# Accepts one parameter +check: DW_TAG_formal_parameter +check: DW_AT_name ("n") +check: DW_AT_decl_line (8) +# Has four locals: t, a, b, i +check: DW_TAG_variable +check: DW_AT_name ("t") +check: DW_AT_decl_line (9) +check: DW_TAG_variable +check: DW_AT_name ("a") +check: DW_TAG_variable +check: DW_AT_name ("b") +check: DW_TAG_variable +check: DW_AT_name ("i") +check: DW_AT_decl_line (10) "##, ) } diff --git a/tests/debug/testsuite/fib-wasm-dwarf5.wasm b/tests/debug/testsuite/fib-wasm-dwarf5.wasm new file mode 100755 index 0000000000..4517916cb1 Binary files /dev/null and b/tests/debug/testsuite/fib-wasm-dwarf5.wasm differ