wasm_debug/transform/
mod.rs1use crate::gc::build_dependencies;
2use crate::types::{ModuleAddressMap, ModuleVmctxInfo, ValueLabelsRanges};
3use crate::DebugInfoData;
4use anyhow::Error;
5use gimli::{
6 write, DebugAddr, DebugAddrBase, DebugLine, DebugStr, LocationLists, RangeLists,
7 UnitSectionOffset,
8};
9use simulate::generate_simulated_dwarf;
10use std::collections::HashSet;
11use thiserror::Error;
12use unit::clone_unit;
13
14pub use address_transform::AddressTransform;
15
16mod address_transform;
17mod attr;
18mod expression;
19mod line_program;
20mod range_info_builder;
21mod simulate;
22mod unit;
23mod utils;
24
25pub(crate) trait Reader: gimli::Reader<Offset = usize> {}
26
27impl<'input, Endian> Reader for gimli::EndianSlice<'input, Endian> where Endian: gimli::Endianity {}
28
29#[derive(Error, Debug)]
30#[error("Debug info transform error: {0}")]
31pub struct TransformError(&'static str);
32
33pub(crate) struct DebugInputContext<'a, R>
34where
35 R: Reader,
36{
37 debug_str: &'a DebugStr<R>,
38 debug_line: &'a DebugLine<R>,
39 debug_addr: &'a DebugAddr<R>,
40 debug_addr_base: DebugAddrBase<R::Offset>,
41 rnglists: &'a RangeLists<R>,
42 loclists: &'a LocationLists<R>,
43 reachable: &'a HashSet<UnitSectionOffset>,
44}
45
46pub fn transform_dwarf(
47 pointer_width_bytes: u8,
48 di: &DebugInfoData,
49 at: &ModuleAddressMap,
50 vmctx_info: &ModuleVmctxInfo,
51 ranges: &ValueLabelsRanges,
52) -> Result<write::Dwarf, Error> {
53 let addr_tr = AddressTransform::new(at, &di.wasm_file);
54 let reachable = build_dependencies(&di.dwarf, &addr_tr)?.get_reachable();
55
56 let context = DebugInputContext {
57 debug_str: &di.dwarf.debug_str,
58 debug_line: &di.dwarf.debug_line,
59 debug_addr: &di.dwarf.debug_addr,
60 debug_addr_base: DebugAddrBase(0),
61 rnglists: &di.dwarf.ranges,
62 loclists: &di.dwarf.locations,
63 reachable: &reachable,
64 };
65
66 let out_encoding = gimli::Encoding {
67 format: gimli::Format::Dwarf32,
68 version: 3,
71 address_size: pointer_width_bytes,
72 };
73
74 let mut out_strings = write::StringTable::default();
75 let mut out_units = write::UnitTable::default();
76
77 let out_line_strings = write::LineStringTable::default();
78
79 let mut translated = HashSet::new();
80 let mut iter = di.dwarf.debug_info.units();
81 while let Some(unit) = iter.next().unwrap_or(None) {
82 let unit = di.dwarf.unit(unit)?;
83 clone_unit(
84 unit,
85 &context,
86 &addr_tr,
87 &ranges,
88 out_encoding,
89 &vmctx_info,
90 &mut out_units,
91 &mut out_strings,
92 &mut translated,
93 )?;
94 }
95
96 generate_simulated_dwarf(
97 &addr_tr,
98 di,
99 &vmctx_info,
100 &ranges,
101 &translated,
102 out_encoding,
103 &mut out_units,
104 &mut out_strings,
105 )?;
106
107 Ok(write::Dwarf {
108 units: out_units,
109 line_programs: vec![],
110 line_strings: out_line_strings,
111 strings: out_strings,
112 })
113}