Fix some minor issues with the explorer command (#5988)
This commit fixes a few minor issues that Nick and I ran into walking through some code with the `wasmtime explore` command: * When a new function is reached the address map iterator is advanced past the prior function to avoid accidentally attributing instructions across functions. * A `<` comparison was changed to `<=` to fix some off-by-one attributions from instructions to wasm instructions. * The `skipdata` option is enabled in Capstone to avoid truncating AArch64 disassemblies too early.
This commit is contained in:
@@ -111,9 +111,17 @@ fn annotate_asm(
|
|||||||
|
|
||||||
let mut address_map_iter = address_map.into_iter().peekable();
|
let mut address_map_iter = address_map.into_iter().peekable();
|
||||||
let mut current_entry = address_map_iter.next();
|
let mut current_entry = address_map_iter.next();
|
||||||
let mut wasm_offset_for_address = |address: u32| -> Option<WasmOffset> {
|
let mut wasm_offset_for_address = |start: usize, address: u32| -> Option<WasmOffset> {
|
||||||
|
// Consume any entries that happened before the current function for the
|
||||||
|
// first instruction.
|
||||||
|
while current_entry.map_or(false, |cur| cur.0 < start) {
|
||||||
|
current_entry = address_map_iter.next();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Next advance the address map up to the current `address` specified,
|
||||||
|
// including it.
|
||||||
while address_map_iter.peek().map_or(false, |next_entry| {
|
while address_map_iter.peek().map_or(false, |next_entry| {
|
||||||
u32::try_from(next_entry.0).unwrap() < address
|
u32::try_from(next_entry.0).unwrap() <= address
|
||||||
}) {
|
}) {
|
||||||
current_entry = address_map_iter.next();
|
current_entry = address_map_iter.next();
|
||||||
}
|
}
|
||||||
@@ -126,7 +134,7 @@ fn annotate_asm(
|
|||||||
.map(|(start, len)| {
|
.map(|(start, len)| {
|
||||||
let body = &text[start..][..len];
|
let body = &text[start..][..len];
|
||||||
|
|
||||||
let cs = match target.architecture {
|
let mut cs = match target.architecture {
|
||||||
target_lexicon::Architecture::Aarch64(_) => capstone::Capstone::new()
|
target_lexicon::Architecture::Aarch64(_) => capstone::Capstone::new()
|
||||||
.arm64()
|
.arm64()
|
||||||
.mode(capstone::arch::arm64::ArchMode::Arm)
|
.mode(capstone::arch::arm64::ArchMode::Arm)
|
||||||
@@ -150,6 +158,12 @@ fn annotate_asm(
|
|||||||
_ => anyhow::bail!("Unsupported target: {target}"),
|
_ => anyhow::bail!("Unsupported target: {target}"),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// This tells capstone to skip over anything that looks like data,
|
||||||
|
// such as inline constant pools and things like that. This also
|
||||||
|
// additionally is required to skip over trapping instructions on
|
||||||
|
// AArch64.
|
||||||
|
cs.set_skipdata(true).unwrap();
|
||||||
|
|
||||||
let instructions = cs
|
let instructions = cs
|
||||||
.disasm_all(body, start as u64)
|
.disasm_all(body, start as u64)
|
||||||
.map_err(|e| anyhow::anyhow!("{e}"))?;
|
.map_err(|e| anyhow::anyhow!("{e}"))?;
|
||||||
@@ -157,7 +171,7 @@ fn annotate_asm(
|
|||||||
.iter()
|
.iter()
|
||||||
.map(|inst| {
|
.map(|inst| {
|
||||||
let address = u32::try_from(inst.address()).unwrap();
|
let address = u32::try_from(inst.address()).unwrap();
|
||||||
let wasm_offset = wasm_offset_for_address(address);
|
let wasm_offset = wasm_offset_for_address(start, address);
|
||||||
Ok(AnnotatedInstruction {
|
Ok(AnnotatedInstruction {
|
||||||
wasm_offset,
|
wasm_offset,
|
||||||
address,
|
address,
|
||||||
|
|||||||
Reference in New Issue
Block a user