Skip to content

Commit 7d8ab8c

Browse files
authored
Merge 445e43a into 74ccb09
2 parents 74ccb09 + 445e43a commit 7d8ab8c

File tree

30 files changed

+7957
-3956
lines changed

30 files changed

+7957
-3956
lines changed

README.md

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,25 +31,33 @@ See the [`capstone-sys`](capstone-sys) page for the requirements and supported p
3131
```rust
3232
extern crate capstone;
3333

34+
use capstone::arch::x86::X86ArchTag;
3435
use capstone::prelude::*;
3536

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

3839
/// Print register names
39-
fn reg_names(cs: &Capstone, regs: &[RegId]) -> String {
40-
let names: Vec<String> = regs.iter().map(|&x| cs.reg_name(x).unwrap()).collect();
40+
fn reg_names<A, I>(cs: &Capstone<A>, regs: I) -> String
41+
where
42+
A: ArchTag,
43+
I: Iterator<Item = A::RegId>,
44+
{
45+
let names: Vec<String> = regs.map(|x| cs.reg_name(x).unwrap()).collect();
4146
names.join(", ")
4247
}
4348

4449
/// Print instruction group names
45-
fn group_names(cs: &Capstone, regs: &[InsnGroupId]) -> String {
46-
let names: Vec<String> = regs.iter().map(|&x| cs.group_name(x).unwrap()).collect();
50+
fn group_names<A, I>(cs: &Capstone<A>, regs: I) -> String
51+
where
52+
A: ArchTag,
53+
I: Iterator<Item = A::InsnGroupId>,
54+
{
55+
let names: Vec<String> = regs.map(|x| cs.group_name(x).unwrap()).collect();
4756
names.join(", ")
4857
}
4958

5059
fn main() {
51-
let cs = Capstone::new()
52-
.x86()
60+
let cs = Capstone::<X86ArchTag>::new()
5361
.mode(arch::x86::ArchMode::Mode64)
5462
.syntax(arch::x86::ArchSyntax::Att)
5563
.detail(true)
@@ -63,8 +71,8 @@ fn main() {
6371
println!();
6472
println!("{}", i);
6573

66-
let detail: InsnDetail = cs.insn_detail(&i).expect("Failed to get insn detail");
67-
let arch_detail: ArchDetail = detail.arch_detail();
74+
let detail = cs.insn_detail(&i).expect("Failed to get insn detail");
75+
let arch_detail = detail.arch_detail();
6876
let ops = arch_detail.operands();
6977

7078
let output: &[(&str, String)] = &[

capstone-rs/benches/my_benchmark.rs

Lines changed: 3 additions & 2 deletions
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

Lines changed: 26 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,50 @@
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 {
13-
let names: Vec<String> = regs.iter().map(|&x| cs.reg_name(x).unwrap()).collect();
14+
fn reg_names<A, I>(cs: &Capstone<A>, regs: I) -> String
15+
where
16+
A: ArchTag,
17+
I: Iterator<Item = A::RegId>,
18+
{
19+
let names: Vec<String> = regs.map(|x| cs.reg_name(x).unwrap()).collect();
1420
names.join(", ")
1521
}
1622

1723
#[cfg(feature = "full")]
1824
/// Print instruction group names
19-
fn group_names(cs: &Capstone, regs: &[InsnGroupId]) -> String {
20-
let names: Vec<String> = regs.iter().map(|&x| cs.group_name(x).unwrap()).collect();
25+
fn group_names<A, I>(cs: &Capstone<A>, regs: I) -> String
26+
where
27+
A: ArchTag,
28+
I: Iterator<Item = A::InsnGroupId>,
29+
{
30+
let names: Vec<String> = regs.map(|x| cs.group_name(x).unwrap()).collect();
2131
names.join(", ")
2232
}
2333

2434
/// Disassemble code and print information
25-
fn arch_example(cs: &mut Capstone, code: &[u8]) -> CsResult<()> {
35+
fn arch_example<A: ArchTag>(arch: &'static str, cs: &mut Capstone<A>, code: &[u8]) -> CsResult<()> {
36+
println!("\n*************************************");
37+
println!("Architecture {}:", arch);
38+
2639
let insns = cs.disasm_all(code, 0x1000)?;
2740
println!("Found {} instructions", insns.len());
2841
for i in insns.iter() {
2942
println!();
3043
println!("{}", i);
3144

32-
let detail: InsnDetail = cs.insn_detail(i)?;
33-
let arch_detail: ArchDetail = detail.arch_detail();
34-
let ops = arch_detail.operands();
45+
let detail = cs.insn_detail(i)?;
46+
let arch_detail = detail.arch_detail();
47+
let ops: Vec<_> = arch_detail.operands().collect();
3548

3649
#[cfg(feature = "full")]
3750
let output: &[(&str, String)] = &[
@@ -61,26 +74,19 @@ fn arch_example(cs: &mut Capstone, code: &[u8]) -> CsResult<()> {
6174
}
6275

6376
fn example() -> CsResult<()> {
64-
let cs_mips: Capstone = Capstone::new()
65-
.mips()
77+
let mut cs_mips = Capstone::<MipsArchTag>::new()
6678
.mode(arch::mips::ArchMode::Mips32R6)
6779
.detail(true)
6880
.build()?;
6981

70-
let cs_x86 = Capstone::new()
71-
.x86()
82+
let mut cs_x86 = Capstone::<X86ArchTag>::new()
7283
.mode(arch::x86::ArchMode::Mode64)
7384
.syntax(arch::x86::ArchSyntax::Att)
7485
.detail(true)
7586
.build()?;
7687

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-
}
88+
arch_example("MIPS", &mut cs_mips, MIPS_CODE)?;
89+
arch_example("X86", &mut cs_x86, X86_CODE)?;
8490

8591
Ok(())
8692
}

capstone-rs/examples/objdump.rs

Lines changed: 2 additions & 2 deletions
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

Lines changed: 3 additions & 3 deletions
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/fuzz/fuzz_targets/fuzz_target_disasm_x86_64.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,18 @@
33
extern crate libfuzzer_sys;
44
extern crate capstone;
55

6+
use capstone::arch::x86::X86ArchTag;
67
use capstone::prelude::*;
78

89
fuzz_target!(|data: &[u8]| {
9-
let mut cs = Capstone::new()
10-
.x86()
10+
let mut cs = Capstone::<X86ArchTag>::new()
1111
.mode(arch::x86::ArchMode::Mode64)
1212
.detail(true)
1313
.build()
1414
.unwrap();
1515
for i in cs.disasm_all(data, 0x1000).unwrap().iter() {
16-
let detail: InsnDetail = cs.insn_detail(&i).unwrap();
17-
let arch_detail: ArchDetail = detail.arch_detail();
16+
let detail = cs.insn_detail(&i).unwrap();
17+
let arch_detail = detail.arch_detail();
1818
arch_detail.operands().iter().for_each(drop);
1919
detail.regs_read().iter().for_each(drop);
2020
detail.regs_write().iter().for_each(drop);

capstone-rs/src/arch/arm.rs

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
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,
87
cs_arm_op__bindgen_ty_2};
98
use libc::c_uint;
109

1110
pub use crate::arch::arch_builder::arm::*;
12-
use crate::arch::DetailsArchInsn;
11+
use crate::arch::{ArchTag, DetailsArchInsn};
12+
use crate::arch::internal::ArchTagSealed;
1313
use crate::instruction::{RegId, RegIdInt};
14+
use crate::{Arch, InsnDetail};
1415

1516
pub use capstone_sys::arm_insn_group as ArmInsnGroup;
1617
pub use capstone_sys::arm_insn as ArmInsn;
@@ -22,9 +23,37 @@ pub use capstone_sys::arm_cc as ArmCC;
2223
pub use capstone_sys::arm_mem_barrier as ArmMemBarrier;
2324
pub use capstone_sys::arm_setend_type as ArmSetendType;
2425

26+
pub struct ArmArchTag;
27+
28+
impl ArchTagSealed for ArmArchTag {}
29+
30+
impl ArchTag for ArmArchTag {
31+
type Builder = ArchCapstoneBuilder;
32+
33+
type Mode = ArchMode;
34+
type ExtraMode = ArchExtraMode;
35+
type Syntax = ArchSyntax;
36+
37+
type RegId = ArmReg;
38+
type InsnId = ArmInsn;
39+
type InsnGroupId = ArmInsnGroup;
40+
41+
type InsnDetail<'a> = ArmInsnDetail<'a>;
42+
43+
fn support_arch(arch: Arch) -> bool {
44+
arch == Arch::ARM
45+
}
46+
}
47+
2548
/// Contains ARM-specific details for an instruction
2649
pub struct ArmInsnDetail<'a>(pub(crate) &'a cs_arm);
2750

51+
impl<'a, 'i> From<&'i InsnDetail<'a, ArmArchTag>> for ArmInsnDetail<'a> {
52+
fn from(value: &'i InsnDetail<'a, ArmArchTag>) -> Self {
53+
Self(unsafe { &value.0.__bindgen_anon_1.arm })
54+
}
55+
}
56+
2857
/// ARM shift amount
2958
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
3059
pub enum ArmShift {
@@ -221,12 +250,12 @@ impl_PartialEq_repr_fields!(ArmInsnDetail<'a> [ 'a ];
221250
impl ArmOpMem {
222251
/// Base register
223252
pub fn base(&self) -> RegId {
224-
RegId(self.0.base as RegIdInt)
253+
RegId(self.0.base.0 as RegIdInt)
225254
}
226255

227256
/// Index value
228257
pub fn index(&self) -> RegId {
229-
RegId(self.0.index as RegIdInt)
258+
RegId(self.0.index.0 as RegIdInt)
230259
}
231260

232261
/// Scale for index register (can be 1, or -1)
@@ -244,7 +273,7 @@ impl_PartialEq_repr_fields!(ArmOpMem;
244273
base, index, scale, disp
245274
);
246275

247-
impl cmp::Eq for ArmOpMem {}
276+
impl Eq for ArmOpMem {}
248277

249278
impl Default for ArmOperand {
250279
fn default() -> Self {
@@ -280,7 +309,7 @@ def_arch_details_struct!(
280309
Operand = ArmOperand;
281310
OperandIterator = ArmOperandIterator;
282311
OperandIteratorLife = ArmOperandIterator<'a>;
283-
[ pub struct ArmOperandIterator<'a>(slice::Iter<'a, cs_arm_op>); ]
312+
[ pub struct ArmOperandIterator<'a>(core::slice::Iter<'a, cs_arm_op>); ]
284313
cs_arch_op = cs_arm_op;
285314
cs_arch = cs_arm;
286315
);

0 commit comments

Comments
 (0)