ep_capstone/arch/
mod.rs

1#[allow(dead_code, non_camel_case_types, non_snake_case)]
2pub(crate) mod generated;
3
4pub mod arm;
5pub mod arm64;
6pub mod evm;
7pub mod m680x;
8pub mod m68k;
9pub mod mips;
10pub mod mos65xx;
11pub mod ppc;
12pub mod sparc;
13pub mod sysz;
14pub mod tms320c64x;
15pub mod x86;
16pub mod xcore;
17
18use core::cmp::{Eq, PartialEq};
19
20bitflags::bitflags! {
21    /// Common instruction operand access types.
22    #[repr(transparent)]
23    pub struct Access: u8 {
24        const READ = 1 << 0;
25        const WRITE = 1 << 1;
26    }
27}
28
29/// A generic instruction ID that can be compared to any architecture specific
30/// instruction ID. Unlike [`InsnGroup`] and [`Reg`], this generic instruction ID
31/// can only be equal to one instruction ID from one architecture.
32#[derive(Copy, Clone, Hash, PartialEq, Eq)]
33pub enum InsnId {
34    X86(x86::InsnId),
35}
36
37impl InsnId {
38    #[inline]
39    pub(crate) fn to_c(self) -> libc::c_int {
40        match self {
41            InsnId::X86(id) => id.to_c(),
42        }
43    }
44}
45
46impl core::cmp::Ord for InsnId {
47    fn cmp(&self, other: &Self) -> core::cmp::Ordering {
48        self.to_c().cmp(&other.to_c())
49    }
50}
51
52impl core::cmp::PartialOrd for InsnId {
53    fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
54        self.to_c().partial_cmp(&other.to_c())
55    }
56}
57
58/// A generic group that can be compared to any architecture specific group.
59/// This group may be equal to multiple groups from different architectures but
60/// not to multiple groups from the same architecture. This can also be converted
61/// into an architecture specific group for any architecture.
62#[derive(Copy, Clone, PartialEq, Eq, Default, Hash)]
63#[repr(transparent)]
64pub struct InsnGroup(u8);
65
66impl InsnGroup {
67    #[allow(dead_code)]
68    pub(crate) fn to_primitive(self) -> u8 {
69        self.0
70    }
71}
72
73/// A generic register that can be compared to any architecture specific register.
74/// This register may be equal to multiple registers from different architectures
75/// but not to multiple registers of the same architecture. This can also be converted
76/// to an architecture specific register for any architecture.
77#[derive(Copy, Clone, PartialEq, Eq, Default, Hash)]
78#[repr(transparent)]
79pub struct Reg(u16);
80
81impl Reg {
82    pub(crate) fn to_primitive(self) -> u16 {
83        self.0
84    }
85}
86
87macro_rules! impl_arch {
88    ($ArchModuleName:ident, $ArchTypeName:ident, $ArchFnName:ident) => {
89        impl From<$ArchModuleName::InsnId> for InsnId {
90            #[inline]
91            fn from(id: $ArchModuleName::InsnId) -> InsnId {
92                InsnId::$ArchTypeName(id)
93            }
94        }
95
96        impl PartialEq<$ArchModuleName::InsnId> for InsnId {
97            #[inline]
98            fn eq(&self, other: &$ArchModuleName::InsnId) -> bool {
99                matches!(self, InsnId::$ArchTypeName(inner) if inner == other)
100            }
101        }
102
103        impl PartialEq<$ArchModuleName::InsnGroup> for InsnGroup {
104            #[inline]
105            fn eq(&self, other: &$ArchModuleName::InsnGroup) -> bool {
106                self.0 == other.to_primitive() as u8
107            }
108        }
109
110        impl PartialEq<InsnGroup> for $ArchModuleName::InsnGroup {
111            #[inline]
112            fn eq(&self, other: &InsnGroup) -> bool {
113                self.to_primitive() as u8 == other.0
114            }
115        }
116
117        impl core::convert::From<$ArchModuleName::InsnGroup> for InsnGroup {
118            #[inline]
119            fn from(arch_insn_group: $ArchModuleName::InsnGroup) -> Self {
120                InsnGroup(arch_insn_group.to_primitive() as u8)
121            }
122        }
123
124        impl core::convert::From<InsnGroup> for $ArchModuleName::InsnGroup {
125            #[inline]
126            fn from(generic: InsnGroup) -> $ArchModuleName::InsnGroup {
127                $ArchModuleName::InsnGroup::from_c(generic.0 as libc::c_int)
128                    .unwrap_or($ArchModuleName::InsnGroup::Invalid)
129            }
130        }
131
132        impl InsnGroup {
133            /// Convert a generic instruction group to an architecture specific instruction group.
134            #[inline]
135            pub fn $ArchFnName(self) -> $ArchModuleName::InsnGroup {
136                $ArchModuleName::InsnGroup::from_c(self.0 as libc::c_int)
137                    .unwrap_or($ArchModuleName::InsnGroup::Invalid)
138            }
139        }
140
141        impl PartialEq<$ArchModuleName::Reg> for Reg {
142            #[inline]
143            fn eq(&self, other: &$ArchModuleName::Reg) -> bool {
144                self.0 == other.to_primitive() as u16
145            }
146        }
147
148        impl PartialEq<Reg> for $ArchModuleName::Reg {
149            #[inline]
150            fn eq(&self, other: &Reg) -> bool {
151                self.to_primitive() as u16 == other.0
152            }
153        }
154
155        impl core::convert::From<$ArchModuleName::Reg> for Reg {
156            #[inline]
157            fn from(arch_reg: $ArchModuleName::Reg) -> Self {
158                Reg(arch_reg.to_primitive() as u16)
159            }
160        }
161
162        impl core::convert::From<Reg> for $ArchModuleName::Reg {
163            #[inline]
164            fn from(generic: Reg) -> $ArchModuleName::Reg {
165                $ArchModuleName::Reg::from_c(generic.0 as libc::c_int)
166                    .unwrap_or($ArchModuleName::Reg::Invalid)
167            }
168        }
169
170        impl Reg {
171            /// Convert a generic register to an architecture specific register.
172            #[inline]
173            pub fn $ArchFnName(self) -> $ArchModuleName::Reg {
174                $ArchModuleName::Reg::from_c(self.0 as libc::c_int)
175                    .unwrap_or($ArchModuleName::Reg::Invalid)
176            }
177        }
178    };
179}
180
181impl_arch!(x86, X86, x86);