1#![cfg_attr(not(test), no_std)]
93
94extern crate alloc;
95
96#[cfg(feature = "aarch64")]
97pub mod aarch64;
98pub(crate) mod core;
99#[cfg(feature = "riscv")]
100pub mod riscv;
101#[cfg(feature = "jit")]
102pub(crate) mod util;
103#[cfg(feature = "x86")]
104pub mod x86;
105
106#[cfg(feature = "jit")]
107pub use core::jit_allocator::{JitAllocator, JitAllocatorOptions, ResetPolicy, Span};
108#[cfg(feature = "aarch64")]
109pub use core::target::AArch64Feature;
110#[cfg(feature = "riscv")]
111pub use core::target::RiscVFeature;
112#[cfg(feature = "x86")]
113pub use core::target::X86Feature;
114pub use core::{
115 arch_traits::Arch,
116 buffer::{
117 Addend, AsmReloc, CodeBuffer, CodeBufferFinalized, CodeOffset, Constant, ConstantData,
118 ExternalName, LabelUse, Reloc, RelocDistance, RelocTarget, UserExternalName,
119 },
120 builder::{Builder, InstSink, Node},
121 globals::{CondCode, InstOptions},
122 inst::Inst,
123 linker::{LinkError, Linker},
124 operand::{
125 BaseMem, BaseReg, Imm, ImmType, Label, Operand, OperandCast, OperandSignature, OperandType,
126 RegGroup, RegMask, RegTraits, RegType, Sym, imm,
127 },
128 patch::{PatchBlock, PatchBlockId, PatchCatalog, PatchSite, PatchSiteId},
129 rwinfo::{
130 CpuRwFlags, INVALID_PHYS_ID, InstControlFlow, InstRwFlags, InstRwInfo, InstSameRegHint,
131 OpRwFlags, OpRwInfo,
132 },
133 section::{FinalizedSection, Section},
134 target::Environment,
135};
136#[cfg(feature = "jit")]
137pub use core::{buffer::LoadedRelocatedCode, patch::LoadedPatchableCode};
138
139use ::core::fmt;
140
141#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
147pub enum AsmError {
148 InvalidPrefix,
149 InvalidOperand,
150 InvalidImmediate,
151 InvalidInstruction,
152 OutOfMemory,
153 InvalidState,
154 TooManyHandles,
155 InvalidArgument,
156 InvalidArch,
158 NoCodeGenerated,
161 UnboundLabel,
164 FailedToOpenAnonymousMemory,
165 TooLarge,
166 Link(LinkError),
169 X86(X86Error),
170 MissingCpuFeature {
172 feature: &'static str,
173 },
174 UnsupportedInstruction {
175 reason: &'static str,
176 },
177}
178
179impl fmt::Display for AsmError {
180 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
181 match self {
182 AsmError::InvalidPrefix => write!(f, "invalid prefix"),
183 AsmError::InvalidOperand => write!(f, "invalid operand"),
184 AsmError::InvalidInstruction => write!(f, "invalid instruction"),
185 AsmError::OutOfMemory => write!(f, "out of memory"),
186 AsmError::InvalidState => write!(f, "invalid state"),
187 AsmError::TooManyHandles => write!(f, "too many handles"),
188 AsmError::InvalidArgument => write!(f, "invalid argument"),
189 AsmError::InvalidImmediate => write!(f, "invalid immediate"),
190 AsmError::InvalidArch => write!(f, "invalid or incompatible architecture"),
191 AsmError::NoCodeGenerated => write!(f, "no code generated"),
192 AsmError::UnboundLabel => write!(f, "unbound label"),
193 AsmError::FailedToOpenAnonymousMemory => {
194 write!(f, "failed to open anonymous memory")
195 }
196 AsmError::TooLarge => write!(f, "too large"),
197 AsmError::Link(error) => write!(f, "link error: {error}"),
198 AsmError::X86(e) => write!(f, "x86 error: {}", e),
199 AsmError::MissingCpuFeature { feature } => {
200 write!(f, "missing CPU feature: {}", feature)
201 }
202 AsmError::UnsupportedInstruction { reason } => {
203 write!(f, "unsupported instruction: {}", reason)
204 }
205 }
206 }
207}
208
209impl From<X86Error> for AsmError {
210 fn from(err: X86Error) -> Self {
211 AsmError::X86(err)
212 }
213}
214
215impl ::core::error::Error for AsmError {}
216
217#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
219pub enum X86Error {
220 InvalidPrefix {
221 prefix: u64,
222 reason: &'static str,
223 },
224 InvalidOperand {
225 operand_index: usize,
226 reason: &'static str,
227 },
228 InvalidInstruction {
229 opcode: u64,
230 reason: &'static str,
231 },
232 InvalidEncoding {
233 encoding: u8,
234 reason: &'static str,
235 },
236 InvalidModRM {
237 modrm: u8,
238 reason: &'static str,
239 },
240 InvalidSIB {
241 sib: u8,
242 reason: &'static str,
243 },
244 InvalidDisplacement {
245 value: i64,
246 size: usize,
247 reason: &'static str,
248 },
249 InvalidImmediate {
250 value: i64,
251 size: usize,
252 reason: &'static str,
253 },
254 InvalidRegister {
255 reg_id: u32,
256 reg_type: &'static str,
257 reason: &'static str,
258 },
259 InvalidMemoryOperand {
260 base: Option<u32>,
261 index: Option<u32>,
262 scale: u8,
263 offset: i64,
264 reason: &'static str,
265 },
266 InvalidVSIB {
267 index_reg: u32,
268 reason: &'static str,
269 },
270 InvalidMasking {
271 mask_reg: u32,
272 reason: &'static str,
273 },
274 InvalidBroadcast {
275 reason: &'static str,
276 },
277 InvalidRoundingControl {
278 rc: u64,
279 reason: &'static str,
280 },
281 InvalidEVEX {
282 field: &'static str,
283 reason: &'static str,
284 },
285 InvalidVEX {
286 field: &'static str,
287 reason: &'static str,
288 },
289 TooLongInstruction {
290 length: usize,
291 max_length: usize,
292 },
293 SegmentOverrideNotAllowed {
294 segment: u8,
295 reason: &'static str,
296 },
297 AddressSizeMismatch {
298 expected: usize,
299 actual: usize,
300 },
301 OperandSizeMismatch {
302 expected: usize,
303 actual: usize,
304 },
305 InvalidRIPRelative {
306 offset: i64,
307 reason: &'static str,
308 },
309 InvalidLabel {
310 label_id: u32,
311 reason: &'static str,
312 },
313 InvalidSymbol {
314 symbol_id: u32,
315 reason: &'static str,
316 },
317 InvalidRelocation {
318 reloc_type: &'static str,
319 reason: &'static str,
320 },
321 InvalidOperandCombination {
322 mnemonic: &'static str,
323 },
324}
325
326impl fmt::Display for X86Error {
327 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
328 match self {
329 X86Error::InvalidPrefix { prefix, reason } => {
330 write!(f, "invalid prefix 0x{:x}: {}", prefix, reason)
331 }
332 X86Error::InvalidOperand {
333 operand_index,
334 reason,
335 } => write!(f, "invalid operand {}: {}", operand_index, reason),
336 X86Error::InvalidInstruction { opcode, reason } => {
337 write!(f, "invalid instruction 0x{:x}: {}", opcode, reason)
338 }
339 X86Error::InvalidEncoding { encoding, reason } => {
340 write!(f, "invalid encoding {}: {}", encoding, reason)
341 }
342 X86Error::InvalidModRM { modrm, reason } => {
343 write!(f, "invalid ModRM byte 0x{:02x}: {}", modrm, reason)
344 }
345 X86Error::InvalidSIB { sib, reason } => {
346 write!(f, "invalid SIB byte 0x{:02x}: {}", sib, reason)
347 }
348 X86Error::InvalidDisplacement {
349 value,
350 size,
351 reason,
352 } => write!(
353 f,
354 "invalid displacement 0x{:x} (size {}): {}",
355 value, size, reason
356 ),
357 X86Error::InvalidImmediate {
358 value,
359 size,
360 reason,
361 } => {
362 write!(
363 f,
364 "invalid immediate 0x{:x} (size {}): {}",
365 value, size, reason
366 )
367 }
368 X86Error::InvalidRegister {
369 reg_id,
370 reg_type,
371 reason,
372 } => write!(
373 f,
374 "invalid register {} (type {}): {}",
375 reg_id, reg_type, reason
376 ),
377 X86Error::InvalidMemoryOperand {
378 base,
379 index,
380 scale,
381 offset,
382 reason,
383 } => write!(
384 f,
385 "invalid memory operand [base={:?}, index={:?}, scale={}, offset={}]: {}",
386 base, index, scale, offset, reason
387 ),
388 X86Error::InvalidVSIB { index_reg, reason } => {
389 write!(f, "invalid VSIB index register {}: {}", index_reg, reason)
390 }
391 X86Error::InvalidMasking { mask_reg, reason } => {
392 write!(f, "invalid mask register {}: {}", mask_reg, reason)
393 }
394 X86Error::InvalidBroadcast { reason } => {
395 write!(f, "invalid broadcast: {}", reason)
396 }
397 X86Error::InvalidRoundingControl { rc, reason } => {
398 write!(f, "invalid rounding control 0x{:x}: {}", rc, reason)
399 }
400 X86Error::InvalidEVEX { field, reason } => {
401 write!(f, "invalid EVEX field '{}': {}", field, reason)
402 }
403 X86Error::InvalidVEX { field, reason } => {
404 write!(f, "invalid VEX field '{}': {}", field, reason)
405 }
406 X86Error::TooLongInstruction { length, max_length } => write!(
407 f,
408 "instruction too long: {} bytes (max {})",
409 length, max_length
410 ),
411 X86Error::SegmentOverrideNotAllowed { segment, reason } => {
412 write!(f, "segment override {} not allowed: {}", segment, reason)
413 }
414 X86Error::AddressSizeMismatch { expected, actual } => write!(
415 f,
416 "address size mismatch: expected {} bytes, got {}",
417 expected, actual
418 ),
419 X86Error::OperandSizeMismatch { expected, actual } => write!(
420 f,
421 "operand size mismatch: expected {} bytes, got {}",
422 expected, actual
423 ),
424 X86Error::InvalidRIPRelative { offset, reason } => {
425 write!(f, "invalid RIP-relative offset {}: {}", offset, reason)
426 }
427 X86Error::InvalidLabel { label_id, reason } => {
428 write!(f, "invalid label {}: {}", label_id, reason)
429 }
430 X86Error::InvalidSymbol { symbol_id, reason } => {
431 write!(f, "invalid symbol {}: {}", symbol_id, reason)
432 }
433 X86Error::InvalidRelocation { reloc_type, reason } => {
434 write!(f, "invalid relocation {}: {}", reloc_type, reason)
435 }
436 X86Error::InvalidOperandCombination { mnemonic } => {
437 write!(
438 f,
439 "invalid operand combination for instruction `{}`",
440 mnemonic
441 )
442 }
443 }
444 }
445}
446
447impl ::core::error::Error for X86Error {}