1use crate::State;
2use crate::common::{Expr, Jump, Size, Stmt, Value};
3
4use std::fmt::{self, Debug};
5
6pub mod x64;
7pub trait Arch: Debug + Send {
10 fn name(&self) -> &str;
11 fn set_features(&mut self, features: &[String]);
12 fn handle_static_reloc(&self, stmts: &mut Vec<Stmt>, reloc: Jump, size: Size);
13 fn default_align(&self) -> u8;
14}
15
16pub trait BasicExprBuilder {
21 fn push(&mut self, _: Stmt);
23 fn emit_error_at(&mut self, _: ErrorSpan, _: fmt::Arguments);
26 fn bit_or(&mut self, _: Expr, _: Value) -> Option<Expr>;
28 fn bit_and(&mut self, _: Expr, _: Value) -> Option<Expr>;
30 fn bit_xor(&mut self, _: Expr, _: Value) -> Option<Expr>;
32 fn add(&mut self, _: Expr, _: Value) -> Option<Expr>;
34 fn mul(&mut self, _: Expr, _: Value) -> Option<Expr>;
36 fn neg(&mut self, _: Expr) -> Option<Expr>;
38 fn log2(&mut self, _: Expr) -> Option<Expr>;
40 fn mask_shift(&mut self, val: Expr, mask: u64, shift: i8) -> Option<Expr>;
42}
43
44#[derive(Debug, Clone)]
45pub enum Error {
46 BadArgument {
47 message: String,
48 },
49 BadExprCombinator {
51 expr: Expr,
53 },
54 #[deprecated]
56 UndiagnosedError,
57}
58
59#[derive(Debug, Clone, Copy)]
61pub enum ErrorSpan {
62 InstructionPart {
63 idx: usize,
64 },
65 Argument {
66 idx: usize,
67 },
68}
69
70impl ErrorSpan {
71 pub fn instruction_part(idx: usize) -> Self {
72 ErrorSpan::InstructionPart { idx }
73 }
74
75 pub fn argument(idx: usize) -> Self {
76 ErrorSpan::Argument { idx }
77 }
78}
79
80impl From<&'static str> for Error {
81 fn from(message: &'_ str) -> Self {
82 message.to_string().into()
83 }
84}
85
86impl From<String> for Error {
87 fn from(message: String) -> Self {
88 Error::BadArgument { message }
89 }
90}
91
92impl From<Option<String>> for Error {
93 fn from(arg: Option<String>) -> Self {
94 match arg {
95 Some(message) => Error::BadArgument { message },
96 #[allow(deprecated)]
97 None => Error::UndiagnosedError,
98 }
99 }
100}
101
102pub trait BasicExprBuilderExt: BasicExprBuilder {
103 fn bit_or_else_err(&mut self, a: Expr, b: Value) -> Result<Expr, Error> {
104 self.bit_or(a, b).ok_or_else(|| Error::BadExprCombinator { expr: a })
105 }
106
107 fn bit_and_else_err(&mut self, a: Expr, b: Value) -> Result<Expr, Error> {
108 self.bit_and(a, b).ok_or_else(|| Error::BadExprCombinator { expr: a })
109 }
110
111 fn bit_xor_else_err(&mut self, a: Expr, b: Value) -> Result<Expr, Error> {
112 self.bit_xor(a, b).ok_or_else(|| Error::BadExprCombinator { expr: a })
113 }
114
115 fn neg_else_err(&mut self, a: Expr) -> Result<Expr, Error> {
116 self.neg(a).ok_or_else(|| Error::BadExprCombinator { expr: a })
117 }
118
119 fn add_else_err(&mut self, a: Expr, b: Value) -> Result<Expr, Error> {
120 self.add(a, b).ok_or_else(|| Error::BadExprCombinator { expr: a })
121 }
122
123 fn mul_else_err(&mut self, a: Expr, b: Value) -> Result<Expr, Error> {
124 self.mul(a, b).ok_or_else(|| Error::BadExprCombinator { expr: a })
125 }
126
127 fn add_many(&mut self, iter: impl IntoIterator<Item=Expr>) -> Option<Value> {
128 let mut res = Value::Byte(0);
129 for expr in iter {
130 res = self.add(expr, res)?.into();
131 }
132 Some(res)
133 }
134
135 fn add_many_else_err(&mut self, iter: impl IntoIterator<Item=Expr>) -> Result<Value, Error> {
136 let mut res = Value::Byte(0);
137 for expr in iter {
138 res = self.add_else_err(expr, res)?.into();
139 }
140 Ok(res)
141 }
142
143 fn mask_shift_or(&mut self, reg: Value, val: Expr, mask: u64, shift: i8) -> Option<Expr> {
146 let operand = self.mask_shift(val, mask, shift)?;
147 self.bit_or(operand, reg)
148 }
149
150 fn mask_shift_or_else_err(&mut self, reg: Value, val: Expr, mask: u64, shift: i8) -> Result<Expr, Error> {
152 let operand = self.mask_shift_else_err(val, mask, shift)?;
153 self.bit_or_else_err(operand, reg)
154 }
155
156 fn mask_shift_inverted_and(&mut self, reg: Value, val: Expr, mask: u64, shift: i8) -> Option<Expr> {
159 let operand = self.mask_shift(val, mask, shift)?;
160 let operand = self.neg(operand)?;
161 self.bit_and(operand, reg)
162 }
163
164 fn mask_shift_inverted_and_else_err(&mut self, reg: Value, val: Expr, mask: u64, shift: i8) -> Result<Expr, Error> {
166 let operand = self.mask_shift_else_err(val, mask, shift)?;
167 let operand = self.neg_else_err(operand)?;
168 self.bit_and_else_err(operand, reg)
169 }
170
171 fn log2_else_err(&mut self, a: Expr) -> Result<Expr, Error> {
172 self.log2(a).ok_or_else(|| Error::BadExprCombinator { expr: a })
173 }
174
175 fn dynscale(&mut self, _: Expr, _: Value) -> Result<(Expr, Expr), Error> {
176 unimplemented!()
177 }
178
179 fn mask_shift_else_err(&mut self, val: Expr, mask: u64, shift: i8) -> Result<Expr, Error> {
180 self.mask_shift(val, mask, shift).ok_or_else(|| Error::BadExprCombinator { expr: val })
181 }
182}
183
184impl<T: BasicExprBuilder + ?Sized> BasicExprBuilderExt for T { }
185
186#[derive(Clone, Debug)]
187pub struct DummyArch {
188 name: &'static str
189}
190
191impl DummyArch {
192 fn new(name: &'static str) -> DummyArch {
193 DummyArch { name }
194 }
195}
196
197impl Arch for DummyArch {
198 fn name(&self) -> &str {
199 self.name
200 }
201
202 fn set_features(&mut self, features: &[String]) {
203 if let Some(feature) = features.first() {
204 eprintln!("Cannot set features when the assembling architecture is undefined. Define it using a .arch directive");
205 }
206 }
207
208 fn handle_static_reloc(&self, _stmts: &mut Vec<Stmt>, _reloc: Jump, _size: Size) {
209 eprintln!("Current assembling architecture is undefined. Define it using a .arch directive");
210 }
211
212 fn default_align(&self) -> u8 {
213 0
214 }
215}
216
217impl BasicExprBuilder for State<'_> {
222 fn push(&mut self, stmt: Stmt) {
223 self.stmts.push(stmt)
224 }
225
226 fn emit_error_at(&mut self, _: ErrorSpan, args: fmt::Arguments) {
228 eprintln!("{}", args);
229 }
230
231 fn bit_or(&mut self, _: Expr, _: Value) -> Option<Expr> {
232 None
233 }
234
235 fn bit_and(&mut self, _: Expr, _: Value) -> Option<Expr> {
236 None
237 }
238
239 fn bit_xor(&mut self, _: Expr, _: Value) -> Option<Expr> {
240 None
241 }
242
243 fn add(&mut self, _: Expr, _: Value) -> Option<Expr> {
244 None
245 }
246
247 fn mul(&mut self, _: Expr, _: Value) -> Option<Expr> {
248 None
249 }
250
251 fn neg(&mut self, _: Expr) -> Option<Expr> {
252 None
253 }
254
255 fn log2(&mut self, _: Expr) -> Option<Expr> {
256 None
257 }
258
259 fn mask_shift(&mut self, _: Expr, _: u64, _: i8) -> Option<Expr> {
260 None
261 }
262}
263
264pub(crate) fn from_str(s: &str) -> Option<Box<dyn Arch>> {
265 match s {
266 "x64" => Some(Box::new(x64::Archx64::default())),
267 "x86" => Some(Box::new(x64::Archx86::default())),
268 "unknown" => Some(Box::new(DummyArch::new("unknown"))),
270 _ => None
271 }
272}
273
274#[cfg(target_arch="x86_64")]
275pub const CURRENT_ARCH: &str = "x64";
276#[cfg(target_arch="x86")]
277pub const CURRENT_ARCH: &str = "x86";
278#[cfg(target_arch="aarch64")]
279pub const CURRENT_ARCH: &str = "aarch64";
280#[cfg(not(any(target_arch="x86", target_arch="x86_64", target_arch="aarch64")))]
281pub const CURRENT_ARCH: &str = "unknown";