Use capstone to validate precise-output tests (#5780)

Use the capstone library to disassemble precise-output tests, in addition to pretty-printing their vcode.
This commit is contained in:
Trevor Elliott
2023-02-15 16:35:10 -08:00
committed by GitHub
parent eabd43a178
commit f04decc4a1
277 changed files with 39340 additions and 98 deletions

View File

@@ -69,75 +69,8 @@ pub fn print_stack_maps(traps: &[MachStackMap]) -> String {
cfg_if! {
if #[cfg(feature = "disas")] {
use capstone::prelude::*;
use target_lexicon::Architecture;
fn get_disassembler(isa: &dyn TargetIsa) -> Result<Capstone> {
let cs = match isa.triple().architecture {
Architecture::X86_32(_) => Capstone::new()
.x86()
.mode(arch::x86::ArchMode::Mode32)
.build()
.map_err(map_caperr)?,
Architecture::X86_64 => Capstone::new()
.x86()
.mode(arch::x86::ArchMode::Mode64)
.build()
.map_err(map_caperr)?,
Architecture::Arm(arm) => {
if arm.is_thumb() {
Capstone::new()
.arm()
.mode(arch::arm::ArchMode::Thumb)
.build()
.map_err(map_caperr)?
} else {
Capstone::new()
.arm()
.mode(arch::arm::ArchMode::Arm)
.build()
.map_err(map_caperr)?
}
}
Architecture::Aarch64 {..} => {
let mut cs = Capstone::new()
.arm64()
.mode(arch::arm64::ArchMode::Arm)
.build()
.map_err(map_caperr)?;
// AArch64 uses inline constants rather than a separate constant pool right now.
// Without this option, Capstone will stop disassembling as soon as it sees
// an inline constant that is not also a valid instruction. With this option,
// Capstone will print a `.byte` directive with the bytes of the inline constant
// and continue to the next instruction.
cs.set_skipdata(true).map_err(map_caperr)?;
cs
}
Architecture::S390x {..} => Capstone::new()
.sysz()
.mode(arch::sysz::ArchMode::Default)
.build()
.map_err(map_caperr)?,
Architecture::Riscv64 {..} => {
let mut cs = Capstone::new()
.riscv()
.mode(arch::riscv::ArchMode::RiscV64)
.build()
.map_err(map_caperr)?;
// Similar to AArch64, RISC-V uses inline constants rather than a separate
// constant pool. We want to skip dissasembly over inline constants instead
// of stopping on invalid bytes.
cs.set_skipdata(true).map_err(map_caperr)?;
cs
}
_ => anyhow::bail!("Unknown ISA"),
};
Ok(cs)
}
pub fn print_disassembly(isa: &dyn TargetIsa, mem: &[u8]) -> Result<()> {
let cs = get_disassembler(isa)?;
let cs = isa.to_capstone().map_err(|e| anyhow::format_err!("{}", e))?;
println!("\nDisassembly of {} bytes:", mem.len());
let insns = cs.disasm_all(&mem, 0x0).unwrap();
@@ -174,10 +107,6 @@ cfg_if! {
}
Ok(())
}
fn map_caperr(err: capstone::Error) -> anyhow::Error{
anyhow::format_err!("{}", err)
}
} else {
pub fn print_disassembly(_: &dyn TargetIsa, _: &[u8]) -> Result<()> {
println!("\nNo disassembly available.");