Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bytecodealliance
GitHub Repository: bytecodealliance/wasmtime
Path: blob/main/cranelift/src/disasm.rs
1690 views
1
use anyhow::Result;
2
use cfg_if::cfg_if;
3
use cranelift_codegen::ir::Function;
4
use cranelift_codegen::ir::function::FunctionParameters;
5
use cranelift_codegen::isa::TargetIsa;
6
use cranelift_codegen::{FinalizedMachReloc, MachTrap};
7
use std::fmt::Write;
8
9
fn print_relocs(func_params: &FunctionParameters, relocs: &[FinalizedMachReloc]) -> String {
10
let mut text = String::new();
11
for &FinalizedMachReloc {
12
kind,
13
offset,
14
ref target,
15
addend,
16
} in relocs
17
{
18
writeln!(
19
text,
20
"reloc_external: {} {} {} at {}",
21
kind,
22
target.display(Some(func_params)),
23
addend,
24
offset
25
)
26
.unwrap();
27
}
28
text
29
}
30
31
pub fn print_traps(traps: &[MachTrap]) -> String {
32
let mut text = String::new();
33
for &MachTrap { offset, code } in traps {
34
writeln!(text, "trap: {code} at {offset:#x}").unwrap();
35
}
36
text
37
}
38
39
cfg_if! {
40
if #[cfg(feature = "disas")] {
41
pub fn print_disassembly(func: &Function, isa: &dyn TargetIsa, mem: &[u8]) -> Result<()> {
42
#[cfg(feature = "pulley")]
43
let is_pulley = match isa.triple().architecture {
44
target_lexicon::Architecture::Pulley32 | target_lexicon::Architecture::Pulley64 => true,
45
_ => false,
46
};
47
println!("\nDisassembly of {} bytes <{}>:", mem.len(), func.name);
48
49
#[cfg(feature = "pulley")]
50
if is_pulley {
51
let mut disas = pulley_interpreter::disas::Disassembler::new(mem);
52
pulley_interpreter::decode::Decoder::decode_all(&mut disas)?;
53
println!("{}", disas.disas());
54
return Ok(());
55
}
56
let cs = isa.to_capstone().map_err(|e| anyhow::format_err!("{}", e))?;
57
58
let insns = cs.disasm_all(&mem, 0x0).unwrap();
59
for i in insns.iter() {
60
let mut line = String::new();
61
62
write!(&mut line, "{:4x}:\t", i.address()).unwrap();
63
64
let mut bytes_str = String::new();
65
let mut len = 0;
66
let mut first = true;
67
for b in i.bytes() {
68
if !first {
69
write!(&mut bytes_str, " ").unwrap();
70
}
71
write!(&mut bytes_str, "{b:02x}").unwrap();
72
len += 1;
73
first = false;
74
}
75
write!(&mut line, "{bytes_str:21}\t").unwrap();
76
if len > 8 {
77
write!(&mut line, "\n\t\t\t\t").unwrap();
78
}
79
80
if let Some(s) = i.mnemonic() {
81
write!(&mut line, "{s}\t").unwrap();
82
}
83
84
if let Some(s) = i.op_str() {
85
write!(&mut line, "{s}").unwrap();
86
}
87
88
println!("{line}");
89
}
90
Ok(())
91
}
92
} else {
93
pub fn print_disassembly(_: &Function, _: &dyn TargetIsa, _: &[u8]) -> Result<()> {
94
println!("\nNo disassembly available.");
95
Ok(())
96
}
97
}
98
}
99
100
pub fn print_all(
101
isa: &dyn TargetIsa,
102
func: &Function,
103
mem: &[u8],
104
code_size: u32,
105
print: bool,
106
relocs: &[FinalizedMachReloc],
107
traps: &[MachTrap],
108
) -> Result<()> {
109
print_bytes(&mem);
110
print_disassembly(func, isa, &mem[0..code_size as usize])?;
111
if print {
112
println!(
113
"\n{}\n{}",
114
print_relocs(&func.params, relocs),
115
print_traps(traps),
116
);
117
}
118
Ok(())
119
}
120
121
pub fn print_bytes(mem: &[u8]) {
122
print!(".byte ");
123
let mut first = true;
124
for byte in mem.iter() {
125
if first {
126
first = false;
127
} else {
128
print!(", ");
129
}
130
print!("{byte}");
131
}
132
println!();
133
}
134
135