Skip to content

Commit

Permalink
Update gimli version; refactor debug data structures
Browse files Browse the repository at this point in the history
  • Loading branch information
yurydelendik committed Jul 8, 2019
1 parent 210e959 commit 252f78b
Show file tree
Hide file tree
Showing 9 changed files with 120 additions and 192 deletions.
3 changes: 1 addition & 2 deletions wasmtime-debug/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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.32.0"
cranelift-entity = "0.32.0"
cranelift-wasm = "0.32.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 }
Expand Down
12 changes: 6 additions & 6 deletions wasmtime-debug/src/address_transform.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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();
Expand All @@ -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;
Expand Down Expand Up @@ -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,
});
Expand All @@ -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,
}),
Expand Down
21 changes: 11 additions & 10 deletions wasmtime-debug/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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(())
}

Expand All @@ -53,16 +54,16 @@ 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
.iter()
.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);
Expand All @@ -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)?;
Expand Down
78 changes: 49 additions & 29 deletions wasmtime-debug/src/transform.rs
Original file line number Diff line number Diff line change
@@ -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};
Expand All @@ -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,
Expand Down Expand Up @@ -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));
}
Expand Down Expand Up @@ -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() {
Expand Down Expand Up @@ -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,
};
Expand Down Expand Up @@ -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,
Expand All @@ -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();
Expand All @@ -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,
})
}
Loading

0 comments on commit 252f78b

Please sign in to comment.