1#![cfg_attr(not(test), no_std)]
64
65extern crate alloc;
66
67pub mod aarch64;
68pub mod core;
69pub mod masm;
70pub mod ppc;
71pub mod riscv;
72pub mod util;
73pub mod x86;
74
75use ::core::fmt;
76
77#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
78pub enum AsmError {
79 InvalidPrefix,
80 InvalidOperand,
81 InvalidInstruction,
82 OutOfMemory,
83 InvalidState,
84 TooManyHandles,
85 InvalidArgument,
86 FailedToOpenAnonymousMemory,
87 TooLarge,
88 X86(X86Error),
89 UnsupportedInstruction { reason: &'static str },
90}
91
92impl fmt::Display for AsmError {
93 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
94 match self {
95 AsmError::InvalidPrefix => write!(f, "invalid prefix"),
96 AsmError::InvalidOperand => write!(f, "invalid operand"),
97 AsmError::InvalidInstruction => write!(f, "invalid instruction"),
98 AsmError::OutOfMemory => write!(f, "out of memory"),
99 AsmError::InvalidState => write!(f, "invalid state"),
100 AsmError::TooManyHandles => write!(f, "too many handles"),
101 AsmError::InvalidArgument => write!(f, "invalid argument"),
102 AsmError::FailedToOpenAnonymousMemory => {
103 write!(f, "failed to open anonymous memory")
104 }
105 AsmError::TooLarge => write!(f, "too large"),
106 AsmError::X86(e) => write!(f, "x86 error: {}", e),
107 AsmError::UnsupportedInstruction { reason } => {
108 write!(f, "unsupported instruction: {}", reason)
109 }
110 }
111 }
112}
113
114#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
115pub enum X86Error {
116 InvalidPrefix {
117 prefix: u64,
118 reason: &'static str,
119 },
120 InvalidOperand {
121 operand_index: usize,
122 reason: &'static str,
123 },
124 InvalidInstruction {
125 opcode: u64,
126 reason: &'static str,
127 },
128 InvalidEncoding {
129 encoding: u8,
130 reason: &'static str,
131 },
132 InvalidModRM {
133 modrm: u8,
134 reason: &'static str,
135 },
136 InvalidSIB {
137 sib: u8,
138 reason: &'static str,
139 },
140 InvalidDisplacement {
141 value: i64,
142 size: usize,
143 reason: &'static str,
144 },
145 InvalidImmediate {
146 value: i64,
147 size: usize,
148 reason: &'static str,
149 },
150 InvalidRegister {
151 reg_id: u32,
152 reg_type: &'static str,
153 reason: &'static str,
154 },
155 InvalidMemoryOperand {
156 base: Option<u32>,
157 index: Option<u32>,
158 scale: u8,
159 offset: i64,
160 reason: &'static str,
161 },
162 InvalidVSIB {
163 index_reg: u32,
164 reason: &'static str,
165 },
166 InvalidMasking {
167 mask_reg: u32,
168 reason: &'static str,
169 },
170 InvalidBroadcast {
171 reason: &'static str,
172 },
173 InvalidRoundingControl {
174 rc: u64,
175 reason: &'static str,
176 },
177 InvalidEVEX {
178 field: &'static str,
179 reason: &'static str,
180 },
181 InvalidVEX {
182 field: &'static str,
183 reason: &'static str,
184 },
185 TooLongInstruction {
186 length: usize,
187 max_length: usize,
188 },
189 SegmentOverrideNotAllowed {
190 segment: u8,
191 reason: &'static str,
192 },
193 AddressSizeMismatch {
194 expected: usize,
195 actual: usize,
196 },
197 OperandSizeMismatch {
198 expected: usize,
199 actual: usize,
200 },
201 InvalidRIPRelative {
202 offset: i64,
203 reason: &'static str,
204 },
205 InvalidLabel {
206 label_id: u32,
207 reason: &'static str,
208 },
209 InvalidSymbol {
210 symbol_id: u32,
211 reason: &'static str,
212 },
213 InvalidRelocation {
214 reloc_type: &'static str,
215 reason: &'static str,
216 },
217 InvalidOperandCombination {
218 mnemonic: &'static str,
219 },
220}
221
222impl fmt::Display for X86Error {
223 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
224 match self {
225 X86Error::InvalidPrefix { prefix, reason } => {
226 write!(f, "invalid prefix 0x{:x}: {}", prefix, reason)
227 }
228 X86Error::InvalidOperand {
229 operand_index,
230 reason,
231 } => write!(f, "invalid operand {}: {}", operand_index, reason),
232 X86Error::InvalidInstruction { opcode, reason } => {
233 write!(f, "invalid instruction 0x{:x}: {}", opcode, reason)
234 }
235 X86Error::InvalidEncoding { encoding, reason } => {
236 write!(f, "invalid encoding {}: {}", encoding, reason)
237 }
238 X86Error::InvalidModRM { modrm, reason } => {
239 write!(f, "invalid ModRM byte 0x{:02x}: {}", modrm, reason)
240 }
241 X86Error::InvalidSIB { sib, reason } => {
242 write!(f, "invalid SIB byte 0x{:02x}: {}", sib, reason)
243 }
244 X86Error::InvalidDisplacement {
245 value,
246 size,
247 reason,
248 } => write!(
249 f,
250 "invalid displacement 0x{:x} (size {}): {}",
251 value, size, reason
252 ),
253 X86Error::InvalidImmediate {
254 value,
255 size,
256 reason,
257 } => {
258 write!(
259 f,
260 "invalid immediate 0x{:x} (size {}): {}",
261 value, size, reason
262 )
263 }
264 X86Error::InvalidRegister {
265 reg_id,
266 reg_type,
267 reason,
268 } => write!(
269 f,
270 "invalid register {} (type {}): {}",
271 reg_id, reg_type, reason
272 ),
273 X86Error::InvalidMemoryOperand {
274 base,
275 index,
276 scale,
277 offset,
278 reason,
279 } => write!(
280 f,
281 "invalid memory operand [base={:?}, index={:?}, scale={}, offset={}]: {}",
282 base, index, scale, offset, reason
283 ),
284 X86Error::InvalidVSIB { index_reg, reason } => {
285 write!(f, "invalid VSIB index register {}: {}", index_reg, reason)
286 }
287 X86Error::InvalidMasking { mask_reg, reason } => {
288 write!(f, "invalid mask register {}: {}", mask_reg, reason)
289 }
290 X86Error::InvalidBroadcast { reason } => {
291 write!(f, "invalid broadcast: {}", reason)
292 }
293 X86Error::InvalidRoundingControl { rc, reason } => {
294 write!(f, "invalid rounding control 0x{:x}: {}", rc, reason)
295 }
296 X86Error::InvalidEVEX { field, reason } => {
297 write!(f, "invalid EVEX field '{}': {}", field, reason)
298 }
299 X86Error::InvalidVEX { field, reason } => {
300 write!(f, "invalid VEX field '{}': {}", field, reason)
301 }
302 X86Error::TooLongInstruction { length, max_length } => write!(
303 f,
304 "instruction too long: {} bytes (max {})",
305 length, max_length
306 ),
307 X86Error::SegmentOverrideNotAllowed { segment, reason } => {
308 write!(f, "segment override {} not allowed: {}", segment, reason)
309 }
310 X86Error::AddressSizeMismatch { expected, actual } => write!(
311 f,
312 "address size mismatch: expected {} bytes, got {}",
313 expected, actual
314 ),
315 X86Error::OperandSizeMismatch { expected, actual } => write!(
316 f,
317 "operand size mismatch: expected {} bytes, got {}",
318 expected, actual
319 ),
320 X86Error::InvalidRIPRelative { offset, reason } => {
321 write!(f, "invalid RIP-relative offset {}: {}", offset, reason)
322 }
323 X86Error::InvalidLabel { label_id, reason } => {
324 write!(f, "invalid label {}: {}", label_id, reason)
325 }
326 X86Error::InvalidSymbol { symbol_id, reason } => {
327 write!(f, "invalid symbol {}: {}", symbol_id, reason)
328 }
329 X86Error::InvalidRelocation { reloc_type, reason } => {
330 write!(f, "invalid relocation {}: {}", reloc_type, reason)
331 }
332 X86Error::InvalidOperandCombination { mnemonic } => {
333 write!(
334 f,
335 "invalid operand combination for instruction `{}`",
336 mnemonic
337 )
338 }
339 }
340 }
341}