1 use crate::debug::Reader; 2 3 use super::address_transform::AddressTransform; 4 use super::expression::{CompiledExpression, FunctionFrameInfo}; 5 use cranelift_codegen::isa::TargetIsa; 6 use gimli::{AttributeValue, UnitRef, write}; 7 use wasmtime_environ::error::Error; 8 9 pub(crate) fn append_vmctx_info( 10 comp_unit: &mut write::Unit, 11 parent_id: write::UnitEntryId, 12 vmctx_ptr_die_ref: write::DebugInfoRef, 13 addr_tr: &AddressTransform, 14 frame_info: Option<&FunctionFrameInfo>, 15 scope_ranges: &[(u64, u64)], 16 out_strings: &mut write::StringTable, 17 isa: &dyn TargetIsa, 18 ) -> Result<(), Error> { 19 let loc = { 20 let expr = CompiledExpression::vmctx(); 21 let locs = expr 22 .build_with_locals(scope_ranges, addr_tr, frame_info, isa) 23 .expressions 24 .map(|i| { 25 i.map(|(begin, length, data)| write::Location::StartLength { 26 begin, 27 length, 28 data, 29 }) 30 }) 31 .collect::<Result<Vec<_>, _>>()?; 32 let list_id = comp_unit.locations.add(write::LocationList(locs)); 33 write::AttributeValue::LocationListRef(list_id) 34 }; 35 36 let var_die_id = comp_unit.add(parent_id, gimli::DW_TAG_variable); 37 let var_die = comp_unit.get_mut(var_die_id); 38 var_die.set( 39 gimli::DW_AT_name, 40 write::AttributeValue::StringRef(out_strings.add("__vmctx")), 41 ); 42 var_die.set( 43 gimli::DW_AT_type, 44 write::AttributeValue::DebugInfoRef(vmctx_ptr_die_ref), 45 ); 46 var_die.set(gimli::DW_AT_location, loc); 47 48 Ok(()) 49 } 50 51 pub fn resolve_die_ref<'a, 'r>( 52 unit: UnitRef<'a, Reader<'r>>, 53 die_ref: &AttributeValue<Reader<'r>>, 54 ) -> Result<Option<write::ConvertUnitEntry<'a, Reader<'r>>>, Error> { 55 let die = match die_ref { 56 AttributeValue::UnitRef(unit_offs) => { 57 Some(write::ConvertUnitEntry::read(unit, *unit_offs)?) 58 } 59 // TODO-DebugInfo: support AttributeValue::DebugInfoRef. The trouble is that we don't have 60 // a fast way to go from a DI offset to a unit offset (which is needed to parse the DIE). 61 // We would likely need to maintain a cache. 62 _ => None, 63 }; 64 Ok(die) 65 } 66