Skip to content

Commit 3422ee7

Browse files
committed
Make examples and benches compile
This commit contains changes that make existing examples and benches compile with the latest API design. Unit tests will be covered in later commits. The primary changes include: - Implement DetailArchInsn for ArchDetail. - Add ArchOperandIterator enum that iterates values of ArchOperand inside an ArchDetail. The enum is basically a wrapper that holds all available arch- specific operand iterators in different variants. This commit also contains some refactors and minor changes, including: - Rename ArchDetail to ArchInsnDetail as the old name is a bit confusing. - Fully add sysz support. - Update existing examples and benches. In most cases, to migrate these existing examples and benches, I just need to add a small number of generic type arguments (e.g. X86ArchTag, ArmArchTag, DynamicArchTag, etc.) and the code just compiles.
1 parent 061994f commit 3422ee7

21 files changed

+223
-111
lines changed

capstone-rs/benches/my_benchmark.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ extern crate capstone;
22
#[macro_use]
33
extern crate criterion;
44

5+
use capstone::arch::DynamicArchTag;
56
use capstone::prelude::*;
67
use capstone::{Arch, Endian, ExtraMode, Mode, NO_EXTRA_MODE};
78
use criterion::{black_box, Criterion};
@@ -17,8 +18,8 @@ fn arch_bench<T: Iterator<Item = ExtraMode>>(
1718
endian: Option<Endian>,
1819
detail: bool,
1920
) {
20-
let mut cs =
21-
Capstone::new_raw(arch, mode, extra_mode, endian).expect("failed to make capstone");
21+
let mut cs = Capstone::<DynamicArchTag>::new_raw(arch, mode, extra_mode, endian)
22+
.expect("failed to make capstone");
2223
cs.set_detail(detail).expect("failed to set detail");
2324

2425
let insns = cs.disasm_all(code, 0x1000).expect("failed to disassemble");

capstone-rs/examples/demo.rs

+16-18
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,42 @@
11
extern crate capstone;
22

3+
use capstone::arch::mips::MipsArchTag;
4+
use capstone::arch::x86::X86ArchTag;
5+
use capstone::arch::{ArchTag, DetailsArchInsn};
36
use capstone::prelude::*;
4-
use capstone::InsnDetail;
57

68
const MIPS_CODE: &[u8] = b"\x56\x34\x21\x34\xc2\x17\x01\x00";
79

810
const X86_CODE: &[u8] = b"\x55\x48\x8b\x05\xb8\x13\x00\x00\xe9\x14\x9e\x08\x00\x45\x31\xe4";
911

1012
#[cfg(feature = "full")]
1113
/// Print register names
12-
fn reg_names(cs: &Capstone, regs: &[RegId]) -> String {
14+
fn reg_names<A: ArchTag>(cs: &Capstone<A>, regs: &[A::RegId]) -> String {
1315
let names: Vec<String> = regs.iter().map(|&x| cs.reg_name(x).unwrap()).collect();
1416
names.join(", ")
1517
}
1618

1719
#[cfg(feature = "full")]
1820
/// Print instruction group names
19-
fn group_names(cs: &Capstone, regs: &[InsnGroupId]) -> String {
21+
fn group_names<A: ArchTag>(cs: &Capstone<A>, regs: &[A::InsnGroupId]) -> String {
2022
let names: Vec<String> = regs.iter().map(|&x| cs.group_name(x).unwrap()).collect();
2123
names.join(", ")
2224
}
2325

2426
/// Disassemble code and print information
25-
fn arch_example(cs: &mut Capstone, code: &[u8]) -> CsResult<()> {
27+
fn arch_example<A: ArchTag>(arch: &'static str, cs: &mut Capstone<A>, code: &[u8]) -> CsResult<()> {
28+
println!("\n*************************************");
29+
println!("Architecture {}:", arch);
30+
2631
let insns = cs.disasm_all(code, 0x1000)?;
2732
println!("Found {} instructions", insns.len());
2833
for i in insns.iter() {
2934
println!();
3035
println!("{}", i);
3136

32-
let detail: InsnDetail = cs.insn_detail(i)?;
33-
let arch_detail: ArchDetail = detail.arch_detail();
34-
let ops = arch_detail.operands();
37+
let detail = cs.insn_detail(i)?;
38+
let arch_detail = detail.arch_detail();
39+
let ops: Vec<_> = arch_detail.operands().collect();
3540

3641
#[cfg(feature = "full")]
3742
let output: &[(&str, String)] = &[
@@ -61,26 +66,19 @@ fn arch_example(cs: &mut Capstone, code: &[u8]) -> CsResult<()> {
6166
}
6267

6368
fn example() -> CsResult<()> {
64-
let cs_mips: Capstone = Capstone::new()
65-
.mips()
69+
let mut cs_mips = Capstone::<MipsArchTag>::new()
6670
.mode(arch::mips::ArchMode::Mips32R6)
6771
.detail(true)
6872
.build()?;
6973

70-
let cs_x86 = Capstone::new()
71-
.x86()
74+
let mut cs_x86 = Capstone::<X86ArchTag>::new()
7275
.mode(arch::x86::ArchMode::Mode64)
7376
.syntax(arch::x86::ArchSyntax::Att)
7477
.detail(true)
7578
.build()?;
7679

77-
let mut examples = [("MIPS", cs_mips, MIPS_CODE), ("X86", cs_x86, X86_CODE)];
78-
79-
for &mut (arch, ref mut cs, code) in examples.iter_mut() {
80-
println!("\n*************************************");
81-
println!("Architecture {}:", arch);
82-
arch_example(cs, code)?;
83-
}
80+
arch_example("MIPS", &mut cs_mips, MIPS_CODE)?;
81+
arch_example("X86", &mut cs_x86, X86_CODE)?;
8482

8583
Ok(())
8684
}

capstone-rs/examples/objdump.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
extern crate capstone;
22
extern crate macho;
33

4+
use capstone::arch::x86::X86ArchTag;
45
use capstone::prelude::*;
56
use std::env;
67
use std::fs;
78
use std::io::Read;
89
use std::process;
910

1011
fn main() {
11-
let cs = Capstone::new()
12-
.x86()
12+
let cs = Capstone::<X86ArchTag>::new()
1313
.mode(arch::x86::ArchMode::Mode64)
1414
.build()
1515
.expect("Failed to create capstone handle");

capstone-rs/examples/parallel.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@
33
//!
44
//! We shard the input by using parallel iterators from the rayon crate.
55
6+
use capstone::arch::x86::X86ArchTag;
67
use capstone::prelude::*;
78
use rayon::prelude::*;
89

910
fn main() -> CsResult<()> {
1011
// Closure to create `Capstone` instance
11-
let create_cs = || -> CsResult<Capstone> {
12-
let cs = Capstone::new()
13-
.x86()
12+
let create_cs = || -> CsResult<Capstone<X86ArchTag>> {
13+
let cs = Capstone::<X86ArchTag>::new()
1414
.mode(arch::x86::ArchMode::Mode64)
1515
.detail(true)
1616
.build()?;

capstone-rs/src/arch/arm.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
//! Contains arm-specific types
22
33
use core::convert::From;
4-
use core::{cmp, fmt, slice};
54

65
use capstone_sys::{
76
arm_op_mem, arm_op_type, cs_arm, cs_arm_op, arm_shifter,
@@ -274,7 +273,7 @@ impl_PartialEq_repr_fields!(ArmOpMem;
274273
base, index, scale, disp
275274
);
276275

277-
impl cmp::Eq for ArmOpMem {}
276+
impl Eq for ArmOpMem {}
278277

279278
impl Default for ArmOperand {
280279
fn default() -> Self {
@@ -310,7 +309,7 @@ def_arch_details_struct!(
310309
Operand = ArmOperand;
311310
OperandIterator = ArmOperandIterator;
312311
OperandIteratorLife = ArmOperandIterator<'a>;
313-
[ pub struct ArmOperandIterator<'a>(slice::Iter<'a, cs_arm_op>); ]
312+
[ pub struct ArmOperandIterator<'a>(core::slice::Iter<'a, cs_arm_op>); ]
314313
cs_arch_op = cs_arm_op;
315314
cs_arch = cs_arm;
316315
);

capstone-rs/src/arch/arm64.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//! Contains arm64-specific types
22
33
use core::convert::From;
4-
use core::{cmp, fmt, mem, slice};
4+
use core::{cmp, mem, slice};
55

66
use capstone_sys::{arm64_op_mem, arm64_op_type, cs_arm64, cs_arm64_op};
77
use libc::c_uint;

capstone-rs/src/arch/evm.rs

+15-14
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
//! Contains EVM-specific types
22
3-
use core::fmt;
3+
use core::fmt::{Debug, Formatter};
4+
use core::marker::PhantomData;
45

56
use capstone_sys::cs_evm;
67

@@ -73,53 +74,53 @@ pub struct EvmOperand(());
7374

7475
/// Iterates over instruction operands
7576
#[derive(Clone)]
76-
pub struct EvmOperandIterator(());
77+
pub struct EvmOperandIterator<'a>(PhantomData<&'a ()>);
7778

78-
impl EvmOperandIterator {
79-
fn new() -> EvmOperandIterator {
80-
EvmOperandIterator(())
79+
impl<'a> EvmOperandIterator<'a> {
80+
fn new() -> EvmOperandIterator<'a> {
81+
EvmOperandIterator(PhantomData::default())
8182
}
8283
}
8384

84-
impl Iterator for EvmOperandIterator {
85+
impl<'a> Iterator for EvmOperandIterator<'a> {
8586
type Item = EvmOperand;
8687

8788
fn next(&mut self) -> Option<Self::Item> {
8889
None
8990
}
9091
}
9192

92-
impl ExactSizeIterator for EvmOperandIterator {
93+
impl<'a> ExactSizeIterator for EvmOperandIterator<'a> {
9394
fn len(&self) -> usize {
9495
0
9596
}
9697
}
9798

98-
impl PartialEq for EvmOperandIterator {
99+
impl<'a> PartialEq for EvmOperandIterator<'a> {
99100
fn eq(&self, _other: &EvmOperandIterator) -> bool {
100101
false
101102
}
102103
}
103104

104-
impl fmt::Debug for EvmOperandIterator {
105-
fn fmt(&self, fmt: &mut fmt::Formatter) -> ::core::fmt::Result {
105+
impl<'a> Debug for EvmOperandIterator<'a> {
106+
fn fmt(&self, fmt: &mut Formatter) -> ::core::fmt::Result {
106107
fmt.debug_struct("EvmOperandIterator").finish()
107108
}
108109
}
109110

110-
impl<'a> fmt::Debug for EvmInsnDetail<'a> {
111-
fn fmt(&self, fmt: &mut fmt::Formatter) -> ::core::fmt::Result {
111+
impl<'a> Debug for EvmInsnDetail<'a> {
112+
fn fmt(&self, fmt: &mut Formatter) -> ::core::fmt::Result {
112113
fmt.debug_struct("EvmInsnDetail")
113114
.field("cs_evm", &(self.0 as *const cs_evm))
114115
.finish()
115116
}
116117
}
117118

118119
impl<'a> DetailsArchInsn for EvmInsnDetail<'a> {
119-
type OperandIterator = EvmOperandIterator;
120+
type OperandIterator = EvmOperandIterator<'a>;
120121
type Operand = EvmOperand;
121122

122-
fn operands(&self) -> EvmOperandIterator {
123+
fn operands(&self) -> EvmOperandIterator<'a> {
123124
EvmOperandIterator::new()
124125
}
125126
}

capstone-rs/src/arch/m680x.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
//! Contains m680x-specific types
22
33
use core::convert::From;
4-
use core::{fmt, slice};
54

65
use capstone_sys::{
76
cs_m680x, cs_m680x_op, m680x_op_ext, m680x_op_idx, m680x_op_rel, m680x_op_type,
@@ -268,7 +267,7 @@ def_arch_details_struct!(
268267
Operand = M680xOperand;
269268
OperandIterator = M680xOperandIterator;
270269
OperandIteratorLife = M680xOperandIterator<'a>;
271-
[ pub struct M680xOperandIterator<'a>(slice::Iter<'a, cs_m680x_op>); ]
270+
[ pub struct M680xOperandIterator<'a>(core::slice::Iter<'a, cs_m680x_op>); ]
272271
cs_arch_op = cs_m680x_op;
273272
cs_arch = cs_m680x;
274273
);

capstone-rs/src/arch/m68k.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
//! Contains m68k-specific types
22
33
use core::convert::From;
4-
use core::{cmp, fmt, slice};
54

65
use capstone_sys::{
76
cs_m68k, cs_m68k_op, cs_m68k_op__bindgen_ty_1, m68k_address_mode, m68k_cpu_size, m68k_fpu_size,
@@ -467,7 +466,7 @@ impl_PartialEq_repr_fields!(M68kOpMem;
467466
address_mode, extra_info
468467
);
469468

470-
impl cmp::Eq for M68kOpMem {}
469+
impl Eq for M68kOpMem {}
471470

472471
impl<'a> From<&'a cs_m68k_op> for M68kOperand {
473472
fn from(insn: &cs_m68k_op) -> M68kOperand {
@@ -480,7 +479,7 @@ def_arch_details_struct!(
480479
Operand = M68kOperand;
481480
OperandIterator = M68kOperandIterator;
482481
OperandIteratorLife = M68kOperandIterator<'a>;
483-
[ pub struct M68kOperandIterator<'a>(slice::Iter<'a, cs_m68k_op>); ]
482+
[ pub struct M68kOperandIterator<'a>(core::slice::Iter<'a, cs_m68k_op>); ]
484483
cs_arch_op = cs_m68k_op;
485484
cs_arch = cs_m68k;
486485
);

capstone-rs/src/arch/mips.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
//! Contains mips-specific types
22
33
use core::convert::From;
4-
use core::{cmp, fmt, slice};
54

65
use capstone_sys::{cs_mips, cs_mips_op, mips_op_mem, mips_op_type};
76

@@ -93,7 +92,7 @@ impl_PartialEq_repr_fields!(MipsOpMem;
9392
base, disp
9493
);
9594

96-
impl cmp::Eq for MipsOpMem {}
95+
impl Eq for MipsOpMem {}
9796

9897
impl<'a> From<&'a cs_mips_op> for MipsOperand {
9998
fn from(insn: &cs_mips_op) -> MipsOperand {
@@ -115,7 +114,7 @@ def_arch_details_struct!(
115114
Operand = MipsOperand;
116115
OperandIterator = MipsOperandIterator;
117116
OperandIteratorLife = MipsOperandIterator<'a>;
118-
[ pub struct MipsOperandIterator<'a>(slice::Iter<'a, cs_mips_op>); ]
117+
[ pub struct MipsOperandIterator<'a>(core::slice::Iter<'a, cs_mips_op>); ]
119118
cs_arch_op = cs_mips_op;
120119
cs_arch = cs_mips;
121120
);

0 commit comments

Comments
 (0)