Merge pull request #1 from philipc/debug-loc
DWARF addresses are relative to the start of the code section
This commit is contained in:
commit
d7c5dc934b
|
@ -36,7 +36,7 @@ pub fn wasm_to_ir(bytes: &[u8]) -> Result<Module<'_>> {
|
||||||
gimli::LocationLists::new(extra_sections.debug_loc, extra_sections.debug_loclists);
|
gimli::LocationLists::new(extra_sections.debug_loc, extra_sections.debug_loclists);
|
||||||
dwarf.ranges =
|
dwarf.ranges =
|
||||||
gimli::RangeLists::new(extra_sections.debug_ranges, extra_sections.debug_rnglists);
|
gimli::RangeLists::new(extra_sections.debug_ranges, extra_sections.debug_rnglists);
|
||||||
let debug_map = DebugMap::from_dwarf(dwarf, &mut module.debug)?;
|
let debug_map = DebugMap::from_dwarf(dwarf, &mut module.debug, extra_sections.code_offset)?;
|
||||||
module.debug_map = debug_map;
|
module.debug_map = debug_map;
|
||||||
|
|
||||||
Ok(module)
|
Ok(module)
|
||||||
|
@ -74,6 +74,7 @@ struct ExtraSections<'a> {
|
||||||
debug_loclists: gimli::DebugLocLists<gimli::EndianSlice<'a, gimli::LittleEndian>>,
|
debug_loclists: gimli::DebugLocLists<gimli::EndianSlice<'a, gimli::LittleEndian>>,
|
||||||
debug_ranges: gimli::DebugRanges<gimli::EndianSlice<'a, gimli::LittleEndian>>,
|
debug_ranges: gimli::DebugRanges<gimli::EndianSlice<'a, gimli::LittleEndian>>,
|
||||||
debug_rnglists: gimli::DebugRngLists<gimli::EndianSlice<'a, gimli::LittleEndian>>,
|
debug_rnglists: gimli::DebugRngLists<gimli::EndianSlice<'a, gimli::LittleEndian>>,
|
||||||
|
code_offset: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_payload<'a>(
|
fn handle_payload<'a>(
|
||||||
|
@ -170,6 +171,9 @@ fn handle_payload<'a>(
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Payload::CodeSectionStart { range, .. } => {
|
||||||
|
extra_sections.code_offset = range.start as u32;
|
||||||
|
}
|
||||||
Payload::CodeSectionEntry(body) => {
|
Payload::CodeSectionEntry(body) => {
|
||||||
let func_idx = Func::new(*next_func);
|
let func_idx = Func::new(*next_func);
|
||||||
*next_func += 1;
|
*next_func += 1;
|
||||||
|
@ -285,7 +289,6 @@ fn handle_payload<'a>(
|
||||||
gimli::DebugRngLists::new(reader.data(), gimli::LittleEndian);
|
gimli::DebugRngLists::new(reader.data(), gimli::LittleEndian);
|
||||||
}
|
}
|
||||||
Payload::CustomSection(_) => {}
|
Payload::CustomSection(_) => {}
|
||||||
Payload::CodeSectionStart { .. } => {}
|
|
||||||
Payload::Version { .. } => {}
|
Payload::Version { .. } => {}
|
||||||
Payload::ElementSection(reader) => {
|
Payload::ElementSection(reader) => {
|
||||||
for element in reader {
|
for element in reader {
|
||||||
|
@ -358,19 +361,22 @@ fn handle_payload<'a>(
|
||||||
}
|
}
|
||||||
|
|
||||||
struct DebugLocReader<'a> {
|
struct DebugLocReader<'a> {
|
||||||
|
code_offset: u32,
|
||||||
locs: &'a [(u32, u32, SourceLoc)],
|
locs: &'a [(u32, u32, SourceLoc)],
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> DebugLocReader<'a> {
|
impl<'a> DebugLocReader<'a> {
|
||||||
fn new(module: &'a Module, func_offset_in_file: u32) -> Self {
|
fn new(module: &'a Module, func_offset_in_file: u32) -> Self {
|
||||||
|
let code_offset = module.debug_map.code_offset;
|
||||||
|
let func_address = func_offset_in_file - code_offset;
|
||||||
let start = match module
|
let start = match module
|
||||||
.debug_map
|
.debug_map
|
||||||
.tuples
|
.tuples
|
||||||
.binary_search_by(|&(start, len, _)| {
|
.binary_search_by(|&(start, len, _)| {
|
||||||
use std::cmp::Ordering::*;
|
use std::cmp::Ordering::*;
|
||||||
if start > func_offset_in_file {
|
if start > func_address {
|
||||||
Greater
|
Greater
|
||||||
} else if (start + len) <= func_offset_in_file {
|
} else if (start + len) <= func_address {
|
||||||
Less
|
Less
|
||||||
} else {
|
} else {
|
||||||
Equal
|
Equal
|
||||||
|
@ -380,21 +386,22 @@ impl<'a> DebugLocReader<'a> {
|
||||||
Err(idx) => idx,
|
Err(idx) => idx,
|
||||||
};
|
};
|
||||||
DebugLocReader {
|
DebugLocReader {
|
||||||
|
code_offset,
|
||||||
locs: &module.debug_map.tuples[start..],
|
locs: &module.debug_map.tuples[start..],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_loc(&mut self, offset: usize) -> SourceLoc {
|
fn get_loc(&mut self, offset: usize) -> SourceLoc {
|
||||||
let offset = u32::try_from(offset).unwrap();
|
let address = u32::try_from(offset).unwrap() - self.code_offset;
|
||||||
while self.locs.len() > 0 {
|
while self.locs.len() > 0 {
|
||||||
let (start, len, loc) = self.locs[0];
|
let (start, len, loc) = self.locs[0];
|
||||||
if offset < start {
|
if address < start {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if offset > (start + len) {
|
if address < start + len {
|
||||||
self.locs = &self.locs[1..];
|
return loc;
|
||||||
}
|
}
|
||||||
return loc;
|
self.locs = &self.locs[1..];
|
||||||
}
|
}
|
||||||
SourceLoc::invalid()
|
SourceLoc::invalid()
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,6 +48,8 @@ impl Debug {
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default)]
|
#[derive(Clone, Debug, Default)]
|
||||||
pub struct DebugMap {
|
pub struct DebugMap {
|
||||||
|
/// Offset of code section relative to the Wasm file start.
|
||||||
|
pub code_offset: u32,
|
||||||
/// Each tuple is `(start, len, loc)`. The `start` offset is
|
/// Each tuple is `(start, len, loc)`. The `start` offset is
|
||||||
/// relative to the code section.
|
/// relative to the code section.
|
||||||
pub tuples: Vec<(u32, u32, SourceLoc)>,
|
pub tuples: Vec<(u32, u32, SourceLoc)>,
|
||||||
|
@ -57,6 +59,7 @@ impl DebugMap {
|
||||||
pub(crate) fn from_dwarf<R: gimli::Reader>(
|
pub(crate) fn from_dwarf<R: gimli::Reader>(
|
||||||
dwarf: gimli::Dwarf<R>,
|
dwarf: gimli::Dwarf<R>,
|
||||||
debug: &mut Debug,
|
debug: &mut Debug,
|
||||||
|
code_offset: u32,
|
||||||
) -> anyhow::Result<DebugMap> {
|
) -> anyhow::Result<DebugMap> {
|
||||||
let ctx = addr2line::Context::from_dwarf(dwarf)?;
|
let ctx = addr2line::Context::from_dwarf(dwarf)?;
|
||||||
let mut tuples = vec![];
|
let mut tuples = vec![];
|
||||||
|
@ -79,6 +82,9 @@ impl DebugMap {
|
||||||
retain
|
retain
|
||||||
});
|
});
|
||||||
|
|
||||||
Ok(DebugMap { tuples })
|
Ok(DebugMap {
|
||||||
|
code_offset,
|
||||||
|
tuples,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue