Update gimli version; refactor debug data structures
This commit is contained in:
committed by
Dan Gohman
parent
adadf835f0
commit
efe9dd7b86
@@ -12,13 +12,12 @@ readme = "README.md"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
gimli = "0.17.0"
|
||||
gimli = "0.19.0"
|
||||
wasmparser = { version = "0.32.1" }
|
||||
cranelift-codegen = "0.33.0"
|
||||
cranelift-entity = "0.33.0"
|
||||
cranelift-wasm = "0.33.0"
|
||||
faerie = "0.10.1"
|
||||
wasmtime-environ = { path = "../wasmtime-environ", default-features = false }
|
||||
target-lexicon = { version = "0.4.0", default-features = false }
|
||||
failure = { version = "0.1.3", default-features = false }
|
||||
failure_derive = { version = "0.1.3", default-features = false }
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
use crate::read_debuginfo::WasmFileInfo;
|
||||
use crate::transform::ModuleAddressMap;
|
||||
use cranelift_entity::{EntityRef, PrimaryMap};
|
||||
use cranelift_wasm::DefinedFuncIndex;
|
||||
use gimli::write;
|
||||
use std::collections::BTreeMap;
|
||||
use std::ops::Bound::{Included, Unbounded};
|
||||
use std::vec::Vec;
|
||||
use wasmtime_environ::AddressTransforms;
|
||||
|
||||
pub type GeneratedAddress = usize;
|
||||
pub type WasmAddress = u64;
|
||||
@@ -32,7 +32,7 @@ pub struct AddressTransform {
|
||||
}
|
||||
|
||||
impl AddressTransform {
|
||||
pub fn new(at: &AddressTransforms, wasm_file: &WasmFileInfo) -> Self {
|
||||
pub fn new(at: &ModuleAddressMap, wasm_file: &WasmFileInfo) -> Self {
|
||||
let code_section_offset = wasm_file.code_section_offset;
|
||||
let function_offsets = &wasm_file.function_offsets_and_sizes;
|
||||
let mut lookup = BTreeMap::new();
|
||||
@@ -50,7 +50,7 @@ impl AddressTransform {
|
||||
(index, ft.body_offset, ft.body_offset),
|
||||
);
|
||||
let mut fn_map = Vec::new();
|
||||
for t in &ft.locations {
|
||||
for t in &ft.instructions {
|
||||
if t.srcloc.is_default() {
|
||||
// TODO extend some range if possible
|
||||
continue;
|
||||
@@ -90,7 +90,7 @@ impl AddressTransform {
|
||||
}
|
||||
let search = self.lookup.range((Unbounded, Included(addr)));
|
||||
if let Some((_, value)) = search.last() {
|
||||
return Some(write::Address::Relative {
|
||||
return Some(write::Address::Symbol {
|
||||
symbol: value.0,
|
||||
addend: value.1 as i64,
|
||||
});
|
||||
@@ -106,11 +106,11 @@ impl AddressTransform {
|
||||
return None;
|
||||
}
|
||||
if let (
|
||||
Some(write::Address::Relative {
|
||||
Some(write::Address::Symbol {
|
||||
symbol: s1,
|
||||
addend: a,
|
||||
}),
|
||||
Some(write::Address::Relative {
|
||||
Some(write::Address::Symbol {
|
||||
symbol: s2,
|
||||
addend: b,
|
||||
}),
|
||||
|
||||
@@ -4,12 +4,13 @@ use faerie::{Artifact, Decl};
|
||||
use failure::Error;
|
||||
use target_lexicon::{BinaryFormat, Triple};
|
||||
|
||||
pub use crate::read_debuginfo::{read_debuginfo, DebugInfoData};
|
||||
pub use crate::transform::transform_dwarf;
|
||||
pub use crate::read_debuginfo::{read_debuginfo, DebugInfoData, WasmFileInfo};
|
||||
pub use crate::transform::{
|
||||
transform_dwarf, FunctionAddressMap, InstructionAddressMap, ModuleAddressMap, ModuleVmctxInfo,
|
||||
ValueLabelsRanges,
|
||||
};
|
||||
pub use crate::write_debuginfo::{emit_dwarf, ResolvedSymbol, SymbolResolver};
|
||||
|
||||
use wasmtime_environ::AddressTransforms;
|
||||
|
||||
mod address_transform;
|
||||
mod read_debuginfo;
|
||||
mod transform;
|
||||
@@ -30,11 +31,11 @@ pub fn emit_debugsections(
|
||||
obj: &mut Artifact,
|
||||
target_config: &TargetFrontendConfig,
|
||||
debuginfo_data: &DebugInfoData,
|
||||
at: &AddressTransforms,
|
||||
at: &ModuleAddressMap,
|
||||
) -> Result<(), Error> {
|
||||
let dwarf = transform_dwarf(target_config, debuginfo_data, at)?;
|
||||
let resolver = FunctionRelocResolver {};
|
||||
emit_dwarf(obj, dwarf, &resolver);
|
||||
let dwarf = transform_dwarf(target_config, debuginfo_data, at)?;
|
||||
emit_dwarf(obj, dwarf, &resolver)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -53,7 +54,7 @@ pub fn emit_debugsections_image(
|
||||
triple: Triple,
|
||||
target_config: &TargetFrontendConfig,
|
||||
debuginfo_data: &DebugInfoData,
|
||||
at: &AddressTransforms,
|
||||
at: &ModuleAddressMap,
|
||||
funcs: &Vec<(*const u8, usize)>,
|
||||
) -> Result<Vec<u8>, Error> {
|
||||
let ref func_offsets = funcs
|
||||
@@ -61,8 +62,8 @@ pub fn emit_debugsections_image(
|
||||
.map(|(ptr, _)| *ptr as u64)
|
||||
.collect::<Vec<u64>>();
|
||||
let mut obj = Artifact::new(triple, String::from("module"));
|
||||
let dwarf = transform_dwarf(target_config, debuginfo_data, at)?;
|
||||
let resolver = ImageRelocResolver { func_offsets };
|
||||
let dwarf = transform_dwarf(target_config, debuginfo_data, at)?;
|
||||
|
||||
// Assuming all functions in the same code block, looking min/max of its range.
|
||||
assert!(funcs.len() > 0);
|
||||
@@ -76,7 +77,7 @@ pub fn emit_debugsections_image(
|
||||
let body = unsafe { ::std::slice::from_raw_parts(segment_body.0, segment_body.1) };
|
||||
obj.declare_with("all", Decl::function(), body.to_vec())?;
|
||||
|
||||
emit_dwarf(&mut obj, dwarf, &resolver);
|
||||
emit_dwarf(&mut obj, dwarf, &resolver)?;
|
||||
|
||||
// LLDB is too "magical" about mach-o, generating elf
|
||||
let mut bytes = obj.emit_as(BinaryFormat::Elf)?;
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
use crate::address_transform::AddressTransform;
|
||||
pub use crate::read_debuginfo::DebugInfoData;
|
||||
use cranelift_codegen::ir;
|
||||
use cranelift_codegen::isa::TargetFrontendConfig;
|
||||
use cranelift_entity::EntityRef;
|
||||
use cranelift_entity::{EntityRef, PrimaryMap};
|
||||
use cranelift_wasm::DefinedFuncIndex;
|
||||
use failure::Error;
|
||||
use std::collections::{BTreeMap, HashMap};
|
||||
use std::ops::Bound::{Included, Unbounded};
|
||||
@@ -24,14 +26,45 @@ impl<'input, Endian> Reader for gimli::EndianSlice<'input, Endian> where Endian:
|
||||
#[fail(display = "Debug info transform error: {}", _0)]
|
||||
pub struct TransformError(&'static str);
|
||||
|
||||
pub struct TransformedDwarf {
|
||||
pub encoding: gimli::Encoding,
|
||||
pub strings: write::StringTable,
|
||||
pub units: write::UnitTable,
|
||||
pub line_strings: write::LineStringTable,
|
||||
pub range_lists: write::RangeListTable,
|
||||
/// Single wasm source location to generated address mapping.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct InstructionAddressMap {
|
||||
/// Original source location.
|
||||
pub srcloc: ir::SourceLoc,
|
||||
|
||||
/// Generated instructions offset.
|
||||
pub code_offset: usize,
|
||||
|
||||
/// Generated instructions length.
|
||||
pub code_len: usize,
|
||||
}
|
||||
|
||||
/// Function and its instructions addresses mappings.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct FunctionAddressMap {
|
||||
/// Instructions maps.
|
||||
/// The array is sorted by the InstructionAddressMap::code_offset field.
|
||||
pub instructions: Vec<InstructionAddressMap>,
|
||||
|
||||
/// Generated function body offset if applicable, otherwise 0.
|
||||
pub body_offset: usize,
|
||||
|
||||
/// Generated function body length.
|
||||
pub body_len: usize,
|
||||
}
|
||||
|
||||
/// Module functions addresses mappings.
|
||||
pub type ModuleAddressMap = PrimaryMap<DefinedFuncIndex, FunctionAddressMap>;
|
||||
|
||||
/// Module `vmctx` related info.
|
||||
pub struct ModuleVmctxInfo {
|
||||
pub memory_offset: i64,
|
||||
pub stack_slots: PrimaryMap<DefinedFuncIndex, ir::StackSlots>,
|
||||
}
|
||||
|
||||
/// Value ranges for functions.
|
||||
pub type ValueLabelsRanges = PrimaryMap<DefinedFuncIndex, cranelift_codegen::ValueLabelsRanges>;
|
||||
|
||||
struct DebugInputContext<'a, R>
|
||||
where
|
||||
R: Reader,
|
||||
@@ -84,7 +117,7 @@ where
|
||||
write::AttributeValue::Udata(subprogram_range.unwrap().1)
|
||||
}
|
||||
AttributeValue::Addr(u) => {
|
||||
let addr = addr_tr.translate(u).unwrap_or(write::Address::Absolute(0));
|
||||
let addr = addr_tr.translate(u).unwrap_or(write::Address::Constant(0));
|
||||
if attr.name() == gimli::DW_AT_low_pc {
|
||||
low_pc = Some((u, addr));
|
||||
}
|
||||
@@ -370,7 +403,7 @@ where
|
||||
for (i, map) in addr_tr.map() {
|
||||
let symbol = i.index();
|
||||
let base_addr = map.offset;
|
||||
out_program.begin_sequence(Some(write::Address::Relative { symbol, addend: 0 }));
|
||||
out_program.begin_sequence(Some(write::Address::Symbol { symbol, addend: 0 }));
|
||||
// TODO track and place function declaration line here
|
||||
let mut last_address = None;
|
||||
for addr_map in map.addresses.iter() {
|
||||
@@ -440,9 +473,9 @@ where
|
||||
let low_pc = entry.attr_value(gimli::DW_AT_low_pc)?;
|
||||
if let Some(AttributeValue::Addr(addr)) = low_pc {
|
||||
let transformed = addr_tr.translate(addr);
|
||||
if let Some(write::Address::Relative { symbol, .. }) = transformed {
|
||||
if let Some(write::Address::Symbol { symbol, .. }) = transformed {
|
||||
let range = addr_tr.func_range(symbol);
|
||||
let addr = write::Address::Relative {
|
||||
let addr = write::Address::Symbol {
|
||||
symbol,
|
||||
addend: range.0 as i64,
|
||||
};
|
||||
@@ -580,8 +613,8 @@ where
|
||||
pub fn transform_dwarf(
|
||||
target_config: &TargetFrontendConfig,
|
||||
di: &DebugInfoData,
|
||||
at: &wasmtime_environ::AddressTransforms,
|
||||
) -> Result<TransformedDwarf, Error> {
|
||||
at: &ModuleAddressMap,
|
||||
) -> Result<write::Dwarf, Error> {
|
||||
let context = DebugInputContext {
|
||||
debug_abbrev: &di.dwarf.debug_abbrev,
|
||||
debug_str: &di.dwarf.debug_str,
|
||||
@@ -605,7 +638,6 @@ pub fn transform_dwarf(
|
||||
let mut out_strings = write::StringTable::default();
|
||||
let mut out_units = write::UnitTable::default();
|
||||
|
||||
let out_range_lists = write::RangeListTable::default();
|
||||
let out_line_strings = write::LineStringTable::default();
|
||||
|
||||
let mut iter = di.dwarf.debug_info.units();
|
||||
@@ -620,22 +652,10 @@ pub fn transform_dwarf(
|
||||
)?;
|
||||
}
|
||||
|
||||
// let unit_range_list = write::RangeList(Vec::new());
|
||||
// let unit_range_list_id = out_range_lists.add(unit_range_list.clone());
|
||||
// let unit = dwarf.units.get_mut(self.unit_id);
|
||||
// let root = unit.root();
|
||||
// let root = unit.get_mut(root);
|
||||
// root.set(
|
||||
// gimli::DW_AT_ranges,
|
||||
// AttributeValue::RangeListRef(unit_range_list_id),
|
||||
// );
|
||||
|
||||
//println!("{:?} \n====\n {:?}", di, at);
|
||||
Ok(TransformedDwarf {
|
||||
encoding: out_encoding,
|
||||
strings: out_strings,
|
||||
Ok(write::Dwarf {
|
||||
units: out_units,
|
||||
line_programs: vec![],
|
||||
line_strings: out_line_strings,
|
||||
range_lists: out_range_lists,
|
||||
strings: out_strings,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,14 +1,11 @@
|
||||
use crate::transform::TransformedDwarf;
|
||||
|
||||
use gimli::write::{
|
||||
Address, DebugAbbrev, DebugInfo, DebugLine, DebugLineStr, DebugRanges, DebugRngLists, DebugStr,
|
||||
EndianVec, Result, SectionId, Sections, Writer,
|
||||
};
|
||||
use gimli::RunTimeEndian;
|
||||
use gimli::write::{Address, Dwarf, EndianVec, Result, Sections, Writer};
|
||||
use gimli::{RunTimeEndian, SectionId};
|
||||
|
||||
use faerie::artifact::{Decl, SectionKind};
|
||||
use faerie::*;
|
||||
use std::result;
|
||||
|
||||
#[derive(Clone)]
|
||||
struct DebugReloc {
|
||||
offset: u32,
|
||||
size: u8,
|
||||
@@ -16,38 +13,6 @@ struct DebugReloc {
|
||||
addend: i64,
|
||||
}
|
||||
|
||||
macro_rules! decl_section {
|
||||
($artifact:ident . $section:ident = $name:expr) => {
|
||||
$artifact
|
||||
.declare_with(
|
||||
SectionId::$section.name(),
|
||||
Decl::section(SectionKind::Debug),
|
||||
$name.0.writer.into_vec(),
|
||||
)
|
||||
.unwrap();
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! sect_relocs {
|
||||
($artifact:ident . $section:ident = $name:expr) => {
|
||||
for reloc in $name.0.relocs {
|
||||
$artifact
|
||||
.link_with(
|
||||
faerie::Link {
|
||||
from: SectionId::$section.name(),
|
||||
to: &reloc.name,
|
||||
at: u64::from(reloc.offset),
|
||||
},
|
||||
faerie::Reloc::Debug {
|
||||
size: reloc.size,
|
||||
addend: reloc.addend as i32,
|
||||
},
|
||||
)
|
||||
.expect("faerie relocation error");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
pub enum ResolvedSymbol {
|
||||
PhysicalAddress(u64),
|
||||
Reloc { name: String, addend: i64 },
|
||||
@@ -59,75 +24,48 @@ pub trait SymbolResolver {
|
||||
|
||||
pub fn emit_dwarf(
|
||||
artifact: &mut Artifact,
|
||||
mut dwarf: TransformedDwarf,
|
||||
mut dwarf: Dwarf,
|
||||
symbol_resolver: &SymbolResolver,
|
||||
) {
|
||||
) -> result::Result<(), failure::Error> {
|
||||
let endian = RunTimeEndian::Little;
|
||||
let debug_abbrev = DebugAbbrev::from(WriterRelocate::new(endian, symbol_resolver));
|
||||
let debug_info = DebugInfo::from(WriterRelocate::new(endian, symbol_resolver));
|
||||
let debug_str = DebugStr::from(WriterRelocate::new(endian, symbol_resolver));
|
||||
let debug_line = DebugLine::from(WriterRelocate::new(endian, symbol_resolver));
|
||||
let debug_ranges = DebugRanges::from(WriterRelocate::new(endian, symbol_resolver));
|
||||
let debug_rnglists = DebugRngLists::from(WriterRelocate::new(endian, symbol_resolver));
|
||||
let debug_line_str = DebugLineStr::from(WriterRelocate::new(endian, symbol_resolver));
|
||||
|
||||
let mut sections = Sections {
|
||||
debug_abbrev,
|
||||
debug_info,
|
||||
debug_line,
|
||||
debug_line_str,
|
||||
debug_ranges,
|
||||
debug_rnglists,
|
||||
debug_str,
|
||||
};
|
||||
|
||||
let debug_str_offsets = dwarf.strings.write(&mut sections.debug_str).unwrap();
|
||||
let debug_line_str_offsets = dwarf
|
||||
.line_strings
|
||||
.write(&mut sections.debug_line_str)
|
||||
.unwrap();
|
||||
dwarf
|
||||
.units
|
||||
.write(&mut sections, &debug_line_str_offsets, &debug_str_offsets)
|
||||
.unwrap();
|
||||
|
||||
decl_section!(artifact.DebugAbbrev = sections.debug_abbrev);
|
||||
decl_section!(artifact.DebugInfo = sections.debug_info);
|
||||
decl_section!(artifact.DebugStr = sections.debug_str);
|
||||
decl_section!(artifact.DebugLine = sections.debug_line);
|
||||
|
||||
let debug_ranges_not_empty = !sections.debug_ranges.0.writer.slice().is_empty();
|
||||
if debug_ranges_not_empty {
|
||||
decl_section!(artifact.DebugRanges = sections.debug_ranges);
|
||||
let mut sections = Sections::new(WriterRelocate::new(endian, symbol_resolver));
|
||||
dwarf.write(&mut sections)?;
|
||||
sections.for_each_mut(|id, s| -> result::Result<(), failure::Error> {
|
||||
artifact.declare_with(
|
||||
id.name(),
|
||||
Decl::section(SectionKind::Debug),
|
||||
s.writer.take(),
|
||||
)
|
||||
})?;
|
||||
sections.for_each_mut(|id, s| -> result::Result<(), failure::Error> {
|
||||
for reloc in &s.relocs {
|
||||
artifact.link_with(
|
||||
faerie::Link {
|
||||
from: id.name(),
|
||||
to: &reloc.name,
|
||||
at: u64::from(reloc.offset),
|
||||
},
|
||||
faerie::Reloc::Debug {
|
||||
size: reloc.size,
|
||||
addend: reloc.addend as i32,
|
||||
},
|
||||
)?;
|
||||
}
|
||||
Ok(())
|
||||
})?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
let debug_rnglists_not_empty = !sections.debug_rnglists.0.writer.slice().is_empty();
|
||||
if debug_rnglists_not_empty {
|
||||
decl_section!(artifact.DebugRngLists = sections.debug_rnglists);
|
||||
}
|
||||
|
||||
sect_relocs!(artifact.DebugAbbrev = sections.debug_abbrev);
|
||||
sect_relocs!(artifact.DebugInfo = sections.debug_info);
|
||||
sect_relocs!(artifact.DebugStr = sections.debug_str);
|
||||
sect_relocs!(artifact.DebugLine = sections.debug_line);
|
||||
|
||||
if debug_ranges_not_empty {
|
||||
sect_relocs!(artifact.DebugRanges = sections.debug_ranges);
|
||||
}
|
||||
|
||||
if debug_rnglists_not_empty {
|
||||
sect_relocs!(artifact.DebugRngLists = sections.debug_rnglists);
|
||||
}
|
||||
}
|
||||
|
||||
struct WriterRelocate<'a> {
|
||||
#[derive(Clone)]
|
||||
pub struct WriterRelocate<'a> {
|
||||
relocs: Vec<DebugReloc>,
|
||||
writer: EndianVec<RunTimeEndian>,
|
||||
symbol_resolver: &'a SymbolResolver,
|
||||
}
|
||||
|
||||
impl<'a> WriterRelocate<'a> {
|
||||
fn new(endian: RunTimeEndian, symbol_resolver: &'a SymbolResolver) -> Self {
|
||||
pub fn new(endian: RunTimeEndian, symbol_resolver: &'a SymbolResolver) -> Self {
|
||||
WriterRelocate {
|
||||
relocs: Vec::new(),
|
||||
writer: EndianVec::new(endian),
|
||||
@@ -157,10 +95,10 @@ impl<'a> Writer for WriterRelocate<'a> {
|
||||
|
||||
fn write_address(&mut self, address: Address, size: u8) -> Result<()> {
|
||||
match address {
|
||||
Address::Absolute(val) => self.write_word(val, size),
|
||||
Address::Relative { symbol, addend } => {
|
||||
Address::Constant(val) => self.write_udata(val, size),
|
||||
Address::Symbol { symbol, addend } => {
|
||||
match self.symbol_resolver.resolve_symbol(symbol, addend as i64) {
|
||||
ResolvedSymbol::PhysicalAddress(addr) => self.write_word(addr, size),
|
||||
ResolvedSymbol::PhysicalAddress(addr) => self.write_udata(addr, size),
|
||||
ResolvedSymbol::Reloc { name, addend } => {
|
||||
let offset = self.len() as u64;
|
||||
self.relocs.push(DebugReloc {
|
||||
@@ -169,7 +107,7 @@ impl<'a> Writer for WriterRelocate<'a> {
|
||||
name,
|
||||
addend,
|
||||
});
|
||||
self.write_word(addend as u64, size)
|
||||
self.write_udata(addend as u64, size)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -185,7 +123,7 @@ impl<'a> Writer for WriterRelocate<'a> {
|
||||
name,
|
||||
addend: val as i64,
|
||||
});
|
||||
self.write_word(val as u64, size)
|
||||
self.write_udata(val as u64, size)
|
||||
}
|
||||
|
||||
fn write_offset_at(
|
||||
@@ -202,6 +140,6 @@ impl<'a> Writer for WriterRelocate<'a> {
|
||||
name,
|
||||
addend: val as i64,
|
||||
});
|
||||
self.write_word_at(offset, val as u64, size)
|
||||
self.write_udata_at(offset, val as u64, size)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ failure = { version = "0.1.3", default-features = false }
|
||||
failure_derive = { version = "0.1.3", default-features = false }
|
||||
indexmap = "1.0.2"
|
||||
rayon = "1.0"
|
||||
wasmtime-debug = { path = "../wasmtime-debug", default-features = false }
|
||||
|
||||
[features]
|
||||
default = ["std"]
|
||||
|
||||
@@ -8,6 +8,7 @@ use cranelift_entity::PrimaryMap;
|
||||
use cranelift_wasm::{DefinedFuncIndex, FuncIndex, WasmError};
|
||||
use std::ops::Range;
|
||||
use std::vec::Vec;
|
||||
use wasmtime_debug::ModuleAddressMap;
|
||||
|
||||
/// Compiled machine code: body and jump table offsets.
|
||||
#[derive(Debug, Clone)]
|
||||
@@ -139,35 +140,6 @@ pub enum CompileError {
|
||||
Codegen(CodegenError),
|
||||
}
|
||||
|
||||
/// Single address point transform.
|
||||
#[derive(Debug)]
|
||||
pub struct InstructionAddressTransform {
|
||||
/// Original source location.
|
||||
pub srcloc: ir::SourceLoc,
|
||||
|
||||
/// Generated instructions offset.
|
||||
pub code_offset: usize,
|
||||
|
||||
/// Generated instructions length.
|
||||
pub code_len: usize,
|
||||
}
|
||||
|
||||
/// Function and its instructions transforms.
|
||||
#[derive(Debug)]
|
||||
pub struct FunctionAddressTransform {
|
||||
/// Instructions transforms
|
||||
pub locations: Vec<InstructionAddressTransform>,
|
||||
|
||||
/// Generated function body offset if applicable, otherwise 0.
|
||||
pub body_offset: usize,
|
||||
|
||||
/// Generated function body length.
|
||||
pub body_len: usize,
|
||||
}
|
||||
|
||||
/// Function AddressTransforms collection.
|
||||
pub type AddressTransforms = PrimaryMap<DefinedFuncIndex, FunctionAddressTransform>;
|
||||
|
||||
/// An implementation of a compiler from parsed WebAssembly module to native code.
|
||||
pub trait Compiler {
|
||||
/// Compile a parsed module with the given `TargetIsa`.
|
||||
@@ -176,5 +148,5 @@ pub trait Compiler {
|
||||
function_body_inputs: PrimaryMap<DefinedFuncIndex, FunctionBodyData<'data>>,
|
||||
isa: &dyn isa::TargetIsa,
|
||||
generate_debug_info: bool,
|
||||
) -> Result<(Compilation, Relocations, AddressTransforms), CompileError>;
|
||||
) -> Result<(Compilation, Relocations, ModuleAddressMap), CompileError>;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
//! Support for compiling with Cranelift.
|
||||
|
||||
use crate::compilation::{
|
||||
AddressTransforms, CodeAndJTOffsets, Compilation, CompileError, FunctionAddressTransform,
|
||||
InstructionAddressTransform, Relocation, RelocationTarget, Relocations,
|
||||
CodeAndJTOffsets, Compilation, CompileError, Relocation, RelocationTarget, Relocations,
|
||||
};
|
||||
use crate::func_environ::{
|
||||
get_func_name, get_imported_memory32_grow_name, get_imported_memory32_size_name,
|
||||
@@ -19,6 +18,7 @@ use cranelift_entity::PrimaryMap;
|
||||
use cranelift_wasm::{DefinedFuncIndex, FuncIndex, FuncTranslator};
|
||||
use rayon::prelude::{IntoParallelRefIterator, ParallelIterator};
|
||||
use std::vec::Vec;
|
||||
use wasmtime_debug::{FunctionAddressMap, InstructionAddressMap, ModuleAddressMap};
|
||||
|
||||
/// Implementation of a relocation sink that just saves all the information for later
|
||||
pub struct RelocSink {
|
||||
@@ -89,10 +89,7 @@ impl RelocSink {
|
||||
}
|
||||
}
|
||||
|
||||
fn get_address_transform(
|
||||
context: &Context,
|
||||
isa: &isa::TargetIsa,
|
||||
) -> Vec<InstructionAddressTransform> {
|
||||
fn get_address_transform(context: &Context, isa: &isa::TargetIsa) -> Vec<InstructionAddressMap> {
|
||||
let mut result = Vec::new();
|
||||
|
||||
let func = &context.func;
|
||||
@@ -103,7 +100,7 @@ fn get_address_transform(
|
||||
for ebb in ebbs {
|
||||
for (offset, inst, size) in func.inst_offsets(ebb, &encinfo) {
|
||||
let srcloc = func.srclocs[inst];
|
||||
result.push(InstructionAddressTransform {
|
||||
result.push(InstructionAddressMap {
|
||||
srcloc,
|
||||
code_offset: offset as usize,
|
||||
code_len: size as usize,
|
||||
@@ -125,7 +122,7 @@ impl crate::compilation::Compiler for Cranelift {
|
||||
function_body_inputs: PrimaryMap<DefinedFuncIndex, FunctionBodyData<'data>>,
|
||||
isa: &dyn isa::TargetIsa,
|
||||
generate_debug_info: bool,
|
||||
) -> Result<(Compilation, Relocations, AddressTransforms), CompileError> {
|
||||
) -> Result<(Compilation, Relocations, ModuleAddressMap), CompileError> {
|
||||
let mut functions = PrimaryMap::with_capacity(function_body_inputs.len());
|
||||
let mut relocations = PrimaryMap::with_capacity(function_body_inputs.len());
|
||||
let mut address_transforms = PrimaryMap::with_capacity(function_body_inputs.len());
|
||||
@@ -162,8 +159,9 @@ impl crate::compilation::Compiler for Cranelift {
|
||||
let address_transform = if generate_debug_info {
|
||||
let body_len = code_buf.len();
|
||||
let at = get_address_transform(&context, isa);
|
||||
Some(FunctionAddressTransform {
|
||||
locations: at,
|
||||
|
||||
Some(FunctionAddressMap {
|
||||
instructions: at,
|
||||
body_offset: 0,
|
||||
body_len,
|
||||
})
|
||||
|
||||
@@ -49,8 +49,7 @@ pub mod cranelift;
|
||||
pub mod lightbeam;
|
||||
|
||||
pub use crate::compilation::{
|
||||
AddressTransforms, Compilation, CompileError, Compiler, InstructionAddressTransform,
|
||||
Relocation, RelocationTarget, Relocations,
|
||||
Compilation, CompileError, Compiler, Relocation, RelocationTarget, Relocations,
|
||||
};
|
||||
pub use crate::cranelift::Cranelift;
|
||||
#[cfg(feature = "lightbeam")]
|
||||
|
||||
Reference in New Issue
Block a user