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