wasmtime_internal_cranelift/debug/transform/
utils.rs

1use crate::debug::Reader;
2
3use super::address_transform::AddressTransform;
4use super::expression::{CompiledExpression, FunctionFrameInfo};
5use anyhow::Error;
6use cranelift_codegen::isa::TargetIsa;
7use gimli::{AttributeValue, DebuggingInformationEntry, Unit, write};
8
9pub(crate) fn append_vmctx_info(
10    comp_unit: &mut write::Unit,
11    parent_id: write::UnitEntryId,
12    vmctx_ptr_die_ref: write::Reference,
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
51pub fn resolve_die_ref<'a>(
52    unit: &'a Unit<Reader<'a>>,
53    die_ref: &'a AttributeValue<Reader<'a>>,
54) -> Result<Option<DebuggingInformationEntry<'a, 'a, Reader<'a>>>, Error> {
55    let die = match die_ref {
56        AttributeValue::UnitRef(unit_offs) => Some(unit.entry(*unit_offs)?),
57        // TODO-DebugInfo: support AttributeValue::DebugInfoRef. The trouble is that we don't have
58        // a fast way to go from a DI offset to a unit offset (which is needed to parse the DIE).
59        // We would likely need to maintain a cache.
60        _ => None,
61    };
62    Ok(die)
63}