Path: blob/main/crates/cranelift/src/debug/transform/mod.rs
3068 views
use self::debug_transform_logging::dbi_log;1use self::simulate::generate_simulated_dwarf;2use self::unit::clone_unit;3use crate::debug::Compilation;4use crate::debug::gc::build_dependencies;5use cranelift_codegen::isa::TargetIsa;6use gimli::{DwarfPackage, LittleEndian, Section, write};7use std::collections::HashSet;8use synthetic::ModuleSyntheticUnit;9use wasmtime_environ::error::Error;10use wasmtime_environ::{11DefinedFuncIndex, ModuleTranslation, PrimaryMap, StaticModuleIndex, Tunables, prelude::*,12};1314pub use address_transform::AddressTransform;1516mod address_transform;17mod attr;18mod debug_transform_logging;19mod expression;20mod line_program;21mod range_info_builder;22mod simulate;23mod synthetic;24mod unit;25mod utils;2627impl<'a> Compilation<'a> {28fn function_frame_info(29&mut self,30module: StaticModuleIndex,31func: DefinedFuncIndex,32) -> expression::FunctionFrameInfo<'a> {33let (_, func) = self.function(module, func);3435expression::FunctionFrameInfo {36value_ranges: &func.value_labels_ranges,37memory_offset: self.module_memory_offsets[module].clone(),38}39}40}4142fn load_dwp<'data>(43translation: ModuleTranslation<'data>,44buffer: &'data [u8],45) -> Result<DwarfPackage<gimli::EndianSlice<'data, gimli::LittleEndian>>> {46let endian_slice = gimli::EndianSlice::new(buffer, LittleEndian);4748let dwarf_package = DwarfPackage::load(49|id| -> Result<_> {50let slice = match id {51gimli::SectionId::DebugAbbrev => {52translation.debuginfo.dwarf.debug_abbrev.reader().slice()53}54gimli::SectionId::DebugInfo => {55translation.debuginfo.dwarf.debug_info.reader().slice()56}57gimli::SectionId::DebugLine => {58translation.debuginfo.dwarf.debug_line.reader().slice()59}60gimli::SectionId::DebugStr => {61translation.debuginfo.dwarf.debug_str.reader().slice()62}63gimli::SectionId::DebugStrOffsets => translation64.debuginfo65.dwarf66.debug_str_offsets67.reader()68.slice(),69gimli::SectionId::DebugLoc => translation.debuginfo.debug_loc.reader().slice(),70gimli::SectionId::DebugLocLists => {71translation.debuginfo.debug_loclists.reader().slice()72}73gimli::SectionId::DebugRngLists => {74translation.debuginfo.debug_rnglists.reader().slice()75}76gimli::SectionId::DebugTypes => {77translation.debuginfo.dwarf.debug_types.reader().slice()78}79gimli::SectionId::DebugCuIndex => {80translation.debuginfo.debug_cu_index.reader().slice()81}82gimli::SectionId::DebugTuIndex => {83translation.debuginfo.debug_tu_index.reader().slice()84}85_ => &buffer,86};8788Ok(gimli::EndianSlice::new(slice, gimli::LittleEndian))89},90endian_slice,91)?;9293Ok(dwarf_package)94}9596/// Attempts to load a DWARF package using the passed bytes.97fn read_dwarf_package_from_bytes<'data>(98dwp_bytes: &'data [u8],99buffer: &'data [u8],100tunables: &Tunables,101) -> Option<DwarfPackage<gimli::EndianSlice<'data, gimli::LittleEndian>>> {102let mut validator = wasmparser::Validator::new();103let parser = wasmparser::Parser::new(0);104let mut types = wasmtime_environ::ModuleTypesBuilder::new(&validator);105let translation = match wasmtime_environ::ModuleEnvironment::new(106tunables,107&mut validator,108&mut types,109StaticModuleIndex::from_u32(0),110)111.translate(parser, dwp_bytes)112{113Ok(translation) => translation,114Err(e) => {115log::warn!("failed to parse wasm dwarf package: {e:?}");116return None;117}118};119120match load_dwp(translation, buffer) {121Ok(package) => Some(package),122Err(err) => {123log::warn!("Failed to load Dwarf package {err}");124None125}126}127}128129pub fn transform_dwarf(130isa: &dyn TargetIsa,131compilation: &mut Compilation<'_>,132) -> Result<write::Dwarf, Error> {133dbi_log!("Commencing DWARF transform for {:?}", compilation);134135let mut transforms = PrimaryMap::new();136for (i, _) in compilation.translations.iter() {137transforms.push(AddressTransform::new(compilation, i));138}139140let buffer = Vec::new();141142let dwarf_package = compilation143.dwarf_package_bytes144.map(145|bytes| -> Option<DwarfPackage<gimli::EndianSlice<'_, gimli::LittleEndian>>> {146read_dwarf_package_from_bytes(bytes, &buffer, compilation.tunables)147},148)149.flatten();150151let out_encoding = gimli::Encoding {152format: gimli::Format::Dwarf32,153version: 4, // TODO: this should be configurable154address_size: isa.pointer_bytes(),155};156let mut out_dwarf = write::Dwarf::default();157158let mut vmctx_ptr_die_refs = PrimaryMap::new();159160let mut translated = HashSet::new();161162for (module, translation) in compilation.translations.iter() {163dbi_log!("[== Transforming CUs for module #{} ==]", module.as_u32());164165let addr_tr = &transforms[module];166let di = &translation.debuginfo;167168let out_module_synthetic_unit = ModuleSyntheticUnit::new(169module,170compilation,171out_encoding,172&mut out_dwarf.units,173&mut out_dwarf.strings,174);175// TODO-DebugInfo-Cleanup: move the simulation code to be per-module and delete this map.176vmctx_ptr_die_refs.push(out_module_synthetic_unit.vmctx_ptr_die_ref());177178let mut filter = write::FilterUnitSection::new(&di.dwarf)?;179build_dependencies(&mut filter, addr_tr)?;180let mut convert = out_dwarf.convert_with_filter(filter)?;181while let Some((mut unit, root_entry)) = convert.read_unit()? {182if let Some(dwp) = dwarf_package.as_ref()183&& let Some(dwo_id) = unit.read_unit.dwo_id184&& let Ok(Some(split_dwarf)) = dwp.find_cu(dwo_id, unit.read_unit.dwarf)185{186let mut split_filter =187write::FilterUnitSection::new_split(&split_dwarf, unit.read_unit)?;188build_dependencies(&mut split_filter, addr_tr)?;189let mut convert_split = unit.convert_split_with_filter(split_filter)?;190let (mut split_unit, split_root_entry) = convert_split.read_unit()?;191split_unit.unit.set_encoding(out_encoding);192clone_unit(193compilation,194module,195&mut split_unit,196&split_root_entry,197Some(&root_entry),198&addr_tr,199&out_module_synthetic_unit,200&mut translated,201isa,202)?;203} else {204unit.unit.set_encoding(out_encoding);205clone_unit(206compilation,207module,208&mut unit,209&root_entry,210None,211&addr_tr,212&out_module_synthetic_unit,213&mut translated,214isa,215)?;216}217}218}219220generate_simulated_dwarf(221compilation,222&transforms,223&translated,224out_encoding,225&vmctx_ptr_die_refs,226&mut out_dwarf.units,227&mut out_dwarf.strings,228isa,229)?;230231Ok(out_dwarf)232}233234235