Skip to content

Commit c33a989

Browse files
committed
Integrate built-in disassemblers, drop capstone dependency
Replace capstone with pure-Rust disassemblers for x86_64 and aarch64. The disasm feature flag is kept to control compilation in release builds but no longer pulls in any external dependency.
1 parent b3ac891 commit c33a989

3 files changed

Lines changed: 38 additions & 34 deletions

File tree

zjit/Cargo.toml

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,6 @@ rust-version = "1.85.0" # Minimally supported rust version
66
publish = false # Don't publish to crates.io
77

88
[dependencies]
9-
# No required dependencies to simplify build process.
10-
# Optional For development and testing purposes.
11-
capstone = { version = "0.14.0", optional = true }
129
jit = { version = "0.1.0", path = "../jit" }
1310

1411
[dev-dependencies]
@@ -18,7 +15,7 @@ rand = "0.9"
1815
# NOTE: Development builds select a set of these via configure.ac
1916
# For debugging, `make V=1` shows exact cargo invocation.
2017
[features]
21-
# Support --yjit-dump-disasm and RubyVM::YJIT.disasm using libcapstone.
22-
disasm = ["capstone"]
18+
# Support --zjit-dump-disasm using built-in disassembler.
19+
disasm = []
2320
runtime_checks = []
2421
stats_allocator = []

zjit/src/disasm.rs

Lines changed: 32 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -23,49 +23,52 @@ pub fn dump_disasm_addr_range(cb: &CodeBlock, start_addr: CodePtr, end_addr: Cod
2323
pub fn disasm_addr_range(cb: &CodeBlock, start_addr: usize, end_addr: usize) -> String {
2424
use std::fmt::Write;
2525

26-
let mut out = String::from("");
26+
let mut out = String::new();
2727

28-
// Initialize capstone
29-
use capstone::prelude::*;
30-
31-
#[cfg(target_arch = "x86_64")]
32-
let mut cs = Capstone::new()
33-
.x86()
34-
.mode(arch::x86::ArchMode::Mode64)
35-
.syntax(arch::x86::ArchSyntax::Intel)
36-
.build()
37-
.unwrap();
38-
#[cfg(target_arch = "aarch64")]
39-
let mut cs = Capstone::new()
40-
.arm64()
41-
.mode(arch::arm64::ArchMode::Arm)
42-
.detail(true)
43-
.build()
44-
.unwrap();
45-
46-
cs.set_skipdata(true).unwrap();
47-
48-
// Disassemble the instructions
4928
let code_size = end_addr - start_addr;
50-
let code_slice = unsafe { std::slice::from_raw_parts(start_addr as _, code_size) };
29+
let code_slice = unsafe { std::slice::from_raw_parts(start_addr as *const u8, code_size) };
5130
// Stabilize output for cargo test
5231
#[cfg(test)]
5332
let start_addr = 0;
54-
let insns = cs.disasm_all(code_slice, start_addr as u64).unwrap();
5533

5634
let colors = crate::ttycolors::get_colors();
5735
let bold_begin = colors.bold_begin;
5836
let bold_end = colors.bold_end;
5937

60-
// For each instruction in this block
61-
for insn in insns.as_ref() {
62-
// Comments for this block
63-
if let Some(comment_list) = cb.comments_at(insn.address() as usize) {
38+
let mut offset = 0;
39+
while offset < code_size {
40+
let addr = start_addr + offset;
41+
42+
// Comments for this address
43+
if let Some(comment_list) = cb.comments_at(addr) {
6444
for comment in comment_list {
6545
writeln!(&mut out, " {bold_begin}# {comment}{bold_end}").unwrap();
6646
}
6747
}
68-
writeln!(&mut out, " {}", format!("{insn}").trim()).unwrap();
48+
49+
// Decode one instruction
50+
#[cfg(target_arch = "x86_64")]
51+
let (text, len) = crate::disasm_x86_64::disassemble_one(&code_slice[offset..], addr);
52+
#[cfg(target_arch = "aarch64")]
53+
let (text, len) = {
54+
if code_slice.len() - offset < 4 {
55+
("(truncated)".to_string(), code_slice.len() - offset)
56+
} else {
57+
let word = u32::from_le_bytes([
58+
code_slice[offset],
59+
code_slice[offset + 1],
60+
code_slice[offset + 2],
61+
code_slice[offset + 3],
62+
]);
63+
(crate::disasm_aarch64::disassemble_instruction(word), 4)
64+
}
65+
};
66+
67+
writeln!(&mut out, " 0x{addr:x}: {text}").unwrap();
68+
if len == 0 {
69+
break;
70+
}
71+
offset += len;
6972
}
7073

7174
out

zjit/src/lib.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ mod virtualmem;
2323
mod asm;
2424
mod backend;
2525
#[cfg(feature = "disasm")]
26+
mod disasm_x86_64;
27+
#[cfg(feature = "disasm")]
28+
mod disasm_aarch64;
29+
#[cfg(feature = "disasm")]
2630
mod disasm;
2731
mod options;
2832
mod profile;

0 commit comments

Comments
 (0)