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