From af7ef8df9adb48204c4caedc7bd4f9ba8f3f7113 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 10 Mar 2023 20:31:31 -0600 Subject: [PATCH] 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. --- crates/explorer/src/lib.rs | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/crates/explorer/src/lib.rs b/crates/explorer/src/lib.rs index 23c8cf28c8..5dab3e8475 100644 --- a/crates/explorer/src/lib.rs +++ b/crates/explorer/src/lib.rs @@ -111,9 +111,17 @@ fn annotate_asm( let mut address_map_iter = address_map.into_iter().peekable(); let mut current_entry = address_map_iter.next(); - let mut wasm_offset_for_address = |address: u32| -> Option { + let mut wasm_offset_for_address = |start: usize, address: u32| -> Option { + // 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| { - u32::try_from(next_entry.0).unwrap() < address + u32::try_from(next_entry.0).unwrap() <= address }) { current_entry = address_map_iter.next(); } @@ -126,7 +134,7 @@ fn annotate_asm( .map(|(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() .arm64() .mode(capstone::arch::arm64::ArchMode::Arm) @@ -150,6 +158,12 @@ fn annotate_asm( _ => 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 .disasm_all(body, start as u64) .map_err(|e| anyhow::anyhow!("{e}"))?; @@ -157,7 +171,7 @@ fn annotate_asm( .iter() .map(|inst| { 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 { wasm_offset, address,