192cc0ad7SSingleAccretion use self::debug_transform_logging::dbi_log;
287c33c29SAlex Crichton use self::simulate::generate_simulated_dwarf;
387c33c29SAlex Crichton use self::unit::clone_unit;
4*c4a38d67SPhilip Craig use crate::debug::Compilation;
590ac295eSAlex Crichton use crate::debug::gc::build_dependencies;
687c33c29SAlex Crichton use cranelift_codegen::isa::TargetIsa;
7*c4a38d67SPhilip Craig use gimli::{DwarfPackage, LittleEndian, Section, write};
8*c4a38d67SPhilip Craig use std::collections::HashSet;
9af476a51SSingleAccretion use synthetic::ModuleSyntheticUnit;
10c7cab275SNick Fitzgerald use wasmtime_environ::error::Error;
11dd8c48b3SAlex Crichton use wasmtime_environ::{
12b5272a5fSNick Fitzgerald DefinedFuncIndex, ModuleTranslation, PrimaryMap, StaticModuleIndex, Tunables, prelude::*,
13dd8c48b3SAlex Crichton };
1487c33c29SAlex Crichton
1587c33c29SAlex Crichton pub use address_transform::AddressTransform;
1687c33c29SAlex Crichton
1787c33c29SAlex Crichton mod address_transform;
1887c33c29SAlex Crichton mod attr;
1992cc0ad7SSingleAccretion mod debug_transform_logging;
2087c33c29SAlex Crichton mod expression;
2187c33c29SAlex Crichton mod line_program;
2287c33c29SAlex Crichton mod range_info_builder;
2387c33c29SAlex Crichton mod simulate;
24af476a51SSingleAccretion mod synthetic;
2587c33c29SAlex Crichton mod unit;
2687c33c29SAlex Crichton mod utils;
2787c33c29SAlex Crichton
28dd8c48b3SAlex Crichton impl<'a> Compilation<'a> {
function_frame_info( &mut self, module: StaticModuleIndex, func: DefinedFuncIndex, ) -> expression::FunctionFrameInfo<'a>29dd8c48b3SAlex Crichton fn function_frame_info(
30dd8c48b3SAlex Crichton &mut self,
31dd8c48b3SAlex Crichton module: StaticModuleIndex,
32dd8c48b3SAlex Crichton func: DefinedFuncIndex,
33dd8c48b3SAlex Crichton ) -> expression::FunctionFrameInfo<'a> {
34dd8c48b3SAlex Crichton let (_, func) = self.function(module, func);
35dd8c48b3SAlex Crichton
36dd8c48b3SAlex Crichton expression::FunctionFrameInfo {
37dd8c48b3SAlex Crichton value_ranges: &func.value_labels_ranges,
38dd8c48b3SAlex Crichton memory_offset: self.module_memory_offsets[module].clone(),
39dd8c48b3SAlex Crichton }
40dd8c48b3SAlex Crichton }
41dd8c48b3SAlex Crichton }
42dd8c48b3SAlex Crichton
load_dwp<'data>( translation: ModuleTranslation<'data>, buffer: &'data [u8], ) -> Result<DwarfPackage<gimli::EndianSlice<'data, gimli::LittleEndian>>>43fb4f4cd3Syowl fn load_dwp<'data>(
44fb4f4cd3Syowl translation: ModuleTranslation<'data>,
45fb4f4cd3Syowl buffer: &'data [u8],
46b5272a5fSNick Fitzgerald ) -> Result<DwarfPackage<gimli::EndianSlice<'data, gimli::LittleEndian>>> {
47fb4f4cd3Syowl let endian_slice = gimli::EndianSlice::new(buffer, LittleEndian);
48fb4f4cd3Syowl
49fb4f4cd3Syowl let dwarf_package = DwarfPackage::load(
50b5272a5fSNick Fitzgerald |id| -> Result<_> {
51fb4f4cd3Syowl let slice = match id {
52fb4f4cd3Syowl gimli::SectionId::DebugAbbrev => {
53fb4f4cd3Syowl translation.debuginfo.dwarf.debug_abbrev.reader().slice()
54fb4f4cd3Syowl }
55fb4f4cd3Syowl gimli::SectionId::DebugInfo => {
56fb4f4cd3Syowl translation.debuginfo.dwarf.debug_info.reader().slice()
57fb4f4cd3Syowl }
58fb4f4cd3Syowl gimli::SectionId::DebugLine => {
59fb4f4cd3Syowl translation.debuginfo.dwarf.debug_line.reader().slice()
60fb4f4cd3Syowl }
61fb4f4cd3Syowl gimli::SectionId::DebugStr => {
62fb4f4cd3Syowl translation.debuginfo.dwarf.debug_str.reader().slice()
63fb4f4cd3Syowl }
64fb4f4cd3Syowl gimli::SectionId::DebugStrOffsets => translation
65fb4f4cd3Syowl .debuginfo
66fb4f4cd3Syowl .dwarf
67fb4f4cd3Syowl .debug_str_offsets
68fb4f4cd3Syowl .reader()
69fb4f4cd3Syowl .slice(),
70fb4f4cd3Syowl gimli::SectionId::DebugLoc => translation.debuginfo.debug_loc.reader().slice(),
71fb4f4cd3Syowl gimli::SectionId::DebugLocLists => {
72fb4f4cd3Syowl translation.debuginfo.debug_loclists.reader().slice()
73fb4f4cd3Syowl }
74fb4f4cd3Syowl gimli::SectionId::DebugRngLists => {
75fb4f4cd3Syowl translation.debuginfo.debug_rnglists.reader().slice()
76fb4f4cd3Syowl }
77fb4f4cd3Syowl gimli::SectionId::DebugTypes => {
78fb4f4cd3Syowl translation.debuginfo.dwarf.debug_types.reader().slice()
79fb4f4cd3Syowl }
80fb4f4cd3Syowl gimli::SectionId::DebugCuIndex => {
81fb4f4cd3Syowl translation.debuginfo.debug_cu_index.reader().slice()
82fb4f4cd3Syowl }
83fb4f4cd3Syowl gimli::SectionId::DebugTuIndex => {
84fb4f4cd3Syowl translation.debuginfo.debug_tu_index.reader().slice()
85fb4f4cd3Syowl }
86fb4f4cd3Syowl _ => &buffer,
87fb4f4cd3Syowl };
88fb4f4cd3Syowl
89fb4f4cd3Syowl Ok(gimli::EndianSlice::new(slice, gimli::LittleEndian))
90fb4f4cd3Syowl },
91fb4f4cd3Syowl endian_slice,
92fb4f4cd3Syowl )?;
93fb4f4cd3Syowl
94fb4f4cd3Syowl Ok(dwarf_package)
95fb4f4cd3Syowl }
96fb4f4cd3Syowl
97fb4f4cd3Syowl /// Attempts to load a DWARF package using the passed bytes.
read_dwarf_package_from_bytes<'data>( dwp_bytes: &'data [u8], buffer: &'data [u8], tunables: &Tunables, ) -> Option<DwarfPackage<gimli::EndianSlice<'data, gimli::LittleEndian>>>98fb4f4cd3Syowl fn read_dwarf_package_from_bytes<'data>(
99fb4f4cd3Syowl dwp_bytes: &'data [u8],
100fb4f4cd3Syowl buffer: &'data [u8],
101fb4f4cd3Syowl tunables: &Tunables,
102fb4f4cd3Syowl ) -> Option<DwarfPackage<gimli::EndianSlice<'data, gimli::LittleEndian>>> {
103fb4f4cd3Syowl let mut validator = wasmparser::Validator::new();
104fb4f4cd3Syowl let parser = wasmparser::Parser::new(0);
105fb4f4cd3Syowl let mut types = wasmtime_environ::ModuleTypesBuilder::new(&validator);
106cfc05638SNick Fitzgerald let translation = match wasmtime_environ::ModuleEnvironment::new(
107cfc05638SNick Fitzgerald tunables,
108cfc05638SNick Fitzgerald &mut validator,
109cfc05638SNick Fitzgerald &mut types,
110cfc05638SNick Fitzgerald StaticModuleIndex::from_u32(0),
111cfc05638SNick Fitzgerald )
112fb4f4cd3Syowl .translate(parser, dwp_bytes)
113fb4f4cd3Syowl {
114fb4f4cd3Syowl Ok(translation) => translation,
115fb4f4cd3Syowl Err(e) => {
116fb4f4cd3Syowl log::warn!("failed to parse wasm dwarf package: {e:?}");
117fb4f4cd3Syowl return None;
118fb4f4cd3Syowl }
119fb4f4cd3Syowl };
120fb4f4cd3Syowl
121fb4f4cd3Syowl match load_dwp(translation, buffer) {
122fb4f4cd3Syowl Ok(package) => Some(package),
123fb4f4cd3Syowl Err(err) => {
1242bac6574SAlex Crichton log::warn!("Failed to load Dwarf package {err}");
125fb4f4cd3Syowl None
126fb4f4cd3Syowl }
127fb4f4cd3Syowl }
128fb4f4cd3Syowl }
129fb4f4cd3Syowl
transform_dwarf( isa: &dyn TargetIsa, compilation: &mut Compilation<'_>, ) -> Result<write::Dwarf, Error>130f676c176SAlex Crichton pub fn transform_dwarf(
13187c33c29SAlex Crichton isa: &dyn TargetIsa,
132dd8c48b3SAlex Crichton compilation: &mut Compilation<'_>,
13387c33c29SAlex Crichton ) -> Result<write::Dwarf, Error> {
13492cc0ad7SSingleAccretion dbi_log!("Commencing DWARF transform for {:?}", compilation);
13592cc0ad7SSingleAccretion
136dd8c48b3SAlex Crichton let mut transforms = PrimaryMap::new();
137dd8c48b3SAlex Crichton for (i, _) in compilation.translations.iter() {
138dd8c48b3SAlex Crichton transforms.push(AddressTransform::new(compilation, i));
139dd8c48b3SAlex Crichton }
140fb4f4cd3Syowl
141fb4f4cd3Syowl let buffer = Vec::new();
142fb4f4cd3Syowl
143dd8c48b3SAlex Crichton let dwarf_package = compilation
144dd8c48b3SAlex Crichton .dwarf_package_bytes
145fb4f4cd3Syowl .map(
146fb4f4cd3Syowl |bytes| -> Option<DwarfPackage<gimli::EndianSlice<'_, gimli::LittleEndian>>> {
147dd8c48b3SAlex Crichton read_dwarf_package_from_bytes(bytes, &buffer, compilation.tunables)
148fb4f4cd3Syowl },
149fb4f4cd3Syowl )
150fb4f4cd3Syowl .flatten();
151fb4f4cd3Syowl
15287c33c29SAlex Crichton let out_encoding = gimli::Encoding {
15387c33c29SAlex Crichton format: gimli::Format::Dwarf32,
154af476a51SSingleAccretion version: 4, // TODO: this should be configurable
15587c33c29SAlex Crichton address_size: isa.pointer_bytes(),
15687c33c29SAlex Crichton };
157*c4a38d67SPhilip Craig let mut out_dwarf = write::Dwarf::default();
15887c33c29SAlex Crichton
159af476a51SSingleAccretion let mut vmctx_ptr_die_refs = PrimaryMap::new();
16087c33c29SAlex Crichton
16187c33c29SAlex Crichton let mut translated = HashSet::new();
162dd8c48b3SAlex Crichton
163dd8c48b3SAlex Crichton for (module, translation) in compilation.translations.iter() {
16492cc0ad7SSingleAccretion dbi_log!("[== Transforming CUs for module #{} ==]", module.as_u32());
16592cc0ad7SSingleAccretion
166dd8c48b3SAlex Crichton let addr_tr = &transforms[module];
167dd8c48b3SAlex Crichton let di = &translation.debuginfo;
1684a722b89SPhilip Craig
169af476a51SSingleAccretion let out_module_synthetic_unit = ModuleSyntheticUnit::new(
170af476a51SSingleAccretion module,
171af476a51SSingleAccretion compilation,
172af476a51SSingleAccretion out_encoding,
173*c4a38d67SPhilip Craig &mut out_dwarf.units,
174*c4a38d67SPhilip Craig &mut out_dwarf.strings,
175af476a51SSingleAccretion );
1760b2c9d72SSingleAccretion // TODO-DebugInfo-Cleanup: move the simulation code to be per-module and delete this map.
177af476a51SSingleAccretion vmctx_ptr_die_refs.push(out_module_synthetic_unit.vmctx_ptr_die_ref());
178fb4f4cd3Syowl
179*c4a38d67SPhilip Craig let mut filter = write::FilterUnitSection::new(&di.dwarf)?;
180*c4a38d67SPhilip Craig build_dependencies(&mut filter, addr_tr)?;
181*c4a38d67SPhilip Craig let mut convert = out_dwarf.convert_with_filter(filter)?;
182*c4a38d67SPhilip Craig while let Some((mut unit, root_entry)) = convert.read_unit()? {
183*c4a38d67SPhilip Craig if let Some(dwp) = dwarf_package.as_ref()
184*c4a38d67SPhilip Craig && let Some(dwo_id) = unit.read_unit.dwo_id
185*c4a38d67SPhilip Craig && let Ok(Some(split_dwarf)) = dwp.find_cu(dwo_id, unit.read_unit.dwarf)
186fb4f4cd3Syowl {
187*c4a38d67SPhilip Craig let mut split_filter =
188*c4a38d67SPhilip Craig write::FilterUnitSection::new_split(&split_dwarf, unit.read_unit)?;
189*c4a38d67SPhilip Craig build_dependencies(&mut split_filter, addr_tr)?;
190*c4a38d67SPhilip Craig let mut convert_split = unit.convert_split_with_filter(split_filter)?;
191*c4a38d67SPhilip Craig let (mut split_unit, split_root_entry) = convert_split.read_unit()?;
192*c4a38d67SPhilip Craig split_unit.unit.set_encoding(out_encoding);
193*c4a38d67SPhilip Craig clone_unit(
194dd8c48b3SAlex Crichton compilation,
195dd8c48b3SAlex Crichton module,
196*c4a38d67SPhilip Craig &mut split_unit,
197*c4a38d67SPhilip Craig &split_root_entry,
198*c4a38d67SPhilip Craig Some(&root_entry),
19987c33c29SAlex Crichton &addr_tr,
200af476a51SSingleAccretion &out_module_synthetic_unit,
20187c33c29SAlex Crichton &mut translated,
20287c33c29SAlex Crichton isa,
203*c4a38d67SPhilip Craig )?;
204*c4a38d67SPhilip Craig } else {
205*c4a38d67SPhilip Craig unit.unit.set_encoding(out_encoding);
206*c4a38d67SPhilip Craig clone_unit(
207*c4a38d67SPhilip Craig compilation,
208*c4a38d67SPhilip Craig module,
209*c4a38d67SPhilip Craig &mut unit,
210*c4a38d67SPhilip Craig &root_entry,
211*c4a38d67SPhilip Craig None,
212*c4a38d67SPhilip Craig &addr_tr,
213*c4a38d67SPhilip Craig &out_module_synthetic_unit,
214*c4a38d67SPhilip Craig &mut translated,
215*c4a38d67SPhilip Craig isa,
216*c4a38d67SPhilip Craig )?;
21787c33c29SAlex Crichton }
21887c33c29SAlex Crichton }
219dd8c48b3SAlex Crichton }
22087c33c29SAlex Crichton
22187c33c29SAlex Crichton generate_simulated_dwarf(
222dd8c48b3SAlex Crichton compilation,
223dd8c48b3SAlex Crichton &transforms,
22487c33c29SAlex Crichton &translated,
22587c33c29SAlex Crichton out_encoding,
226af476a51SSingleAccretion &vmctx_ptr_die_refs,
227*c4a38d67SPhilip Craig &mut out_dwarf.units,
228*c4a38d67SPhilip Craig &mut out_dwarf.strings,
22987c33c29SAlex Crichton isa,
23087c33c29SAlex Crichton )?;
23187c33c29SAlex Crichton
232*c4a38d67SPhilip Craig Ok(out_dwarf)
233fb4f4cd3Syowl }
234