Line data Source code
1 : use lief_ffi as ffi;
2 :
3 : use crate::common::FromFFI;
4 :
5 : pub mod immediate;
6 : pub mod memory;
7 : pub mod pc_relative;
8 : pub mod register;
9 :
10 : #[doc(inline)]
11 : pub use register::Register;
12 :
13 : #[doc(inline)]
14 : pub use pc_relative::PCRelative;
15 :
16 : #[doc(inline)]
17 : pub use immediate::Immediate;
18 :
19 : #[doc(inline)]
20 : pub use memory::Memory;
21 :
22 : /// Trait shared by **all** [`Operands`]
23 : pub trait Operand {
24 : #[doc(hidden)]
25 : fn as_generic(&self) -> &ffi::asm_x86_Operand;
26 :
27 : /// Pretty representation of the operand
28 0 : fn to_string(&self) -> String {
29 0 : self.as_generic().to_string().to_string()
30 0 : }
31 : }
32 :
33 : /// This enum represents the different kind of operands associated with [`super::Instruction`]
34 : pub enum Operands {
35 : /// A register operand (e.g. `RIP`)
36 : Reg(Register),
37 :
38 : /// A RIP/EIP-relative operand
39 : PCRelative(PCRelative),
40 :
41 : /// An immediate value
42 : Imm(Immediate),
43 :
44 : /// A memory operand
45 : Mem(Memory),
46 :
47 : /// Operand that is not correctly supported
48 : Unknown(Unknown),
49 : }
50 :
51 : impl FromFFI<ffi::asm_x86_Operand> for Operands {
52 0 : fn from_ffi(ptr: cxx::UniquePtr<ffi::asm_x86_Operand>) -> Self {
53 0 : unsafe {
54 0 : let op_ref = ptr.as_ref().unwrap();
55 0 : if ffi::asm_x86_operands_Memory::classof(op_ref) {
56 0 : let raw = {
57 0 : type From = cxx::UniquePtr<ffi::asm_x86_Operand>;
58 0 : type To = cxx::UniquePtr<ffi::asm_x86_operands_Memory>;
59 0 : std::mem::transmute::<From, To>(ptr)
60 0 : };
61 0 : return Operands::Mem(Memory::from_ffi(raw));
62 0 : } else if ffi::asm_x86_operands_Register::classof(op_ref) {
63 0 : let raw = {
64 0 : type From = cxx::UniquePtr<ffi::asm_x86_Operand>;
65 0 : type To = cxx::UniquePtr<ffi::asm_x86_operands_Register>;
66 0 : std::mem::transmute::<From, To>(ptr)
67 0 : };
68 0 : return Operands::Reg(Register::from_ffi(raw));
69 0 : } else if ffi::asm_x86_operands_Immediate::classof(op_ref) {
70 0 : let raw = {
71 0 : type From = cxx::UniquePtr<ffi::asm_x86_Operand>;
72 0 : type To = cxx::UniquePtr<ffi::asm_x86_operands_Immediate>;
73 0 : std::mem::transmute::<From, To>(ptr)
74 0 : };
75 0 : return Operands::Imm(Immediate::from_ffi(raw));
76 0 : } else if ffi::asm_x86_operands_PCRelative::classof(op_ref) {
77 0 : let raw = {
78 0 : type From = cxx::UniquePtr<ffi::asm_x86_Operand>;
79 0 : type To = cxx::UniquePtr<ffi::asm_x86_operands_PCRelative>;
80 0 : std::mem::transmute::<From, To>(ptr)
81 0 : };
82 0 : return Operands::PCRelative(PCRelative::from_ffi(raw));
83 0 : }
84 0 : Operands::Unknown(Unknown::from_ffi(ptr))
85 : }
86 0 : }
87 : }
88 :
89 : impl Operand for Operands {
90 : #[doc(hidden)]
91 0 : fn as_generic(&self) -> &ffi::asm_x86_Operand {
92 0 : match &self {
93 0 : Operands::Reg(op) => op.as_generic(),
94 :
95 0 : Operands::Imm(op) => op.as_generic(),
96 :
97 0 : Operands::Mem(op) => op.as_generic(),
98 :
99 0 : Operands::PCRelative(op) => op.as_generic(),
100 :
101 0 : Operands::Unknown(op) => op.as_generic(),
102 : }
103 0 : }
104 : }
105 :
106 : pub struct Unknown {
107 : ptr: cxx::UniquePtr<ffi::asm_x86_Operand>,
108 : }
109 :
110 : impl FromFFI<ffi::asm_x86_Operand> for Unknown {
111 0 : fn from_ffi(ptr: cxx::UniquePtr<ffi::asm_x86_Operand>) -> Self {
112 0 : Self { ptr }
113 0 : }
114 : }
115 :
116 : impl Operand for Unknown {
117 : #[doc(hidden)]
118 0 : fn as_generic(&self) -> &ffi::asm_x86_Operand {
119 0 : self.ptr.as_ref().unwrap()
120 0 : }
121 : }
|