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_aarch64_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. `X0`)
36 : Reg(Register),
37 :
38 : /// A PC-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_aarch64_Operand> for Operands {
52 0 : fn from_ffi(ptr: cxx::UniquePtr<ffi::asm_aarch64_Operand>) -> Self {
53 0 : unsafe {
54 0 : let op_ref = ptr.as_ref().unwrap();
55 0 : if ffi::asm_aarch64_operands_Memory::classof(op_ref) {
56 0 : let raw = {
57 0 : type From = cxx::UniquePtr<ffi::asm_aarch64_Operand>;
58 0 : type To = cxx::UniquePtr<ffi::asm_aarch64_operands_Memory>;
59 0 : std::mem::transmute::<From, To>(ptr)
60 0 : };
61 0 : return Operands::Mem(Memory::from_ffi(raw));
62 : }
63 0 : else if ffi::asm_aarch64_operands_Register::classof(op_ref) {
64 0 : let raw = {
65 0 : type From = cxx::UniquePtr<ffi::asm_aarch64_Operand>;
66 0 : type To = cxx::UniquePtr<ffi::asm_aarch64_operands_Register>;
67 0 : std::mem::transmute::<From, To>(ptr)
68 0 : };
69 0 : return Operands::Reg(Register::from_ffi(raw));
70 : }
71 0 : else if ffi::asm_aarch64_operands_Immediate::classof(op_ref) {
72 0 : let raw = {
73 0 : type From = cxx::UniquePtr<ffi::asm_aarch64_Operand>;
74 0 : type To = cxx::UniquePtr<ffi::asm_aarch64_operands_Immediate>;
75 0 : std::mem::transmute::<From, To>(ptr)
76 0 : };
77 0 : return Operands::Imm(Immediate::from_ffi(raw));
78 : }
79 0 : else if ffi::asm_aarch64_operands_PCRelative::classof(op_ref) {
80 0 : let raw = {
81 0 : type From = cxx::UniquePtr<ffi::asm_aarch64_Operand>;
82 0 : type To = cxx::UniquePtr<ffi::asm_aarch64_operands_PCRelative>;
83 0 : std::mem::transmute::<From, To>(ptr)
84 0 : };
85 0 : return Operands::PCRelative(PCRelative::from_ffi(raw));
86 0 : }
87 0 : return Operands::Unknown(Unknown::from_ffi(ptr));
88 : }
89 0 : }
90 : }
91 :
92 : impl Operand for Operands {
93 : #[doc(hidden)]
94 0 : fn as_generic(&self) -> &ffi::asm_aarch64_Operand {
95 0 : match &self {
96 0 : Operands::Reg(op) => {
97 0 : op.as_generic()
98 : }
99 :
100 0 : Operands::Imm(op) => {
101 0 : op.as_generic()
102 : }
103 :
104 0 : Operands::Mem(op) => {
105 0 : op.as_generic()
106 : }
107 :
108 0 : Operands::PCRelative(op) => {
109 0 : op.as_generic()
110 : }
111 :
112 0 : Operands::Unknown(op) => {
113 0 : op.as_generic()
114 : }
115 : }
116 0 : }
117 : }
118 :
119 : pub struct Unknown {
120 : ptr: cxx::UniquePtr<ffi::asm_aarch64_Operand>,
121 : }
122 :
123 : impl FromFFI<ffi::asm_aarch64_Operand> for Unknown {
124 0 : fn from_ffi(ptr: cxx::UniquePtr<ffi::asm_aarch64_Operand>) -> Self {
125 0 : Self {
126 0 : ptr,
127 0 : }
128 0 : }
129 : }
130 :
131 : impl Operand for Unknown {
132 : #[doc(hidden)]
133 0 : fn as_generic(&self) -> &ffi::asm_aarch64_Operand {
134 0 : self.ptr.as_ref().unwrap()
135 0 : }
136 : }
137 :
138 :
139 :
|