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 
append_vmctx_info( comp_unit: &mut write::Unit, parent_id: write::UnitEntryId, vmctx_ptr_die_ref: write::DebugInfoRef, addr_tr: &AddressTransform, frame_info: Option<&FunctionFrameInfo>, scope_ranges: &[(u64, u64)], out_strings: &mut write::StringTable, isa: &dyn TargetIsa, ) -> Result<(), Error>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 
resolve_die_ref<'a, 'r>( unit: UnitRef<'a, Reader<'r>>, die_ref: &AttributeValue<Reader<'r>>, ) -> Result<Option<write::ConvertUnitEntry<'a, Reader<'r>>>, Error>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