#![cfg_attr(not(test), no_std)]
extern crate alloc;
#[cfg(feature = "aarch64")]
pub mod aarch64;
pub mod core;
pub mod ppc;
#[cfg(feature = "riscv")]
pub mod riscv;
pub mod util;
#[cfg(feature = "x86")]
pub mod x86;
use ::core::fmt;
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
pub enum AsmError {
InvalidPrefix,
InvalidOperand,
InvalidImmediate,
InvalidInstruction,
OutOfMemory,
InvalidState,
TooManyHandles,
InvalidArgument,
FailedToOpenAnonymousMemory,
TooLarge,
X86(X86Error),
UnsupportedInstruction { reason: &'static str },
}
impl fmt::Display for AsmError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
AsmError::InvalidPrefix => write!(f, "invalid prefix"),
AsmError::InvalidOperand => write!(f, "invalid operand"),
AsmError::InvalidInstruction => write!(f, "invalid instruction"),
AsmError::OutOfMemory => write!(f, "out of memory"),
AsmError::InvalidState => write!(f, "invalid state"),
AsmError::TooManyHandles => write!(f, "too many handles"),
AsmError::InvalidArgument => write!(f, "invalid argument"),
AsmError::InvalidImmediate => write!(f, "invalid immediate"),
AsmError::FailedToOpenAnonymousMemory => {
write!(f, "failed to open anonymous memory")
}
AsmError::TooLarge => write!(f, "too large"),
AsmError::X86(e) => write!(f, "x86 error: {}", e),
AsmError::UnsupportedInstruction { reason } => {
write!(f, "unsupported instruction: {}", reason)
}
}
}
}
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
pub enum X86Error {
InvalidPrefix {
prefix: u64,
reason: &'static str,
},
InvalidOperand {
operand_index: usize,
reason: &'static str,
},
InvalidInstruction {
opcode: u64,
reason: &'static str,
},
InvalidEncoding {
encoding: u8,
reason: &'static str,
},
InvalidModRM {
modrm: u8,
reason: &'static str,
},
InvalidSIB {
sib: u8,
reason: &'static str,
},
InvalidDisplacement {
value: i64,
size: usize,
reason: &'static str,
},
InvalidImmediate {
value: i64,
size: usize,
reason: &'static str,
},
InvalidRegister {
reg_id: u32,
reg_type: &'static str,
reason: &'static str,
},
InvalidMemoryOperand {
base: Option<u32>,
index: Option<u32>,
scale: u8,
offset: i64,
reason: &'static str,
},
InvalidVSIB {
index_reg: u32,
reason: &'static str,
},
InvalidMasking {
mask_reg: u32,
reason: &'static str,
},
InvalidBroadcast {
reason: &'static str,
},
InvalidRoundingControl {
rc: u64,
reason: &'static str,
},
InvalidEVEX {
field: &'static str,
reason: &'static str,
},
InvalidVEX {
field: &'static str,
reason: &'static str,
},
TooLongInstruction {
length: usize,
max_length: usize,
},
SegmentOverrideNotAllowed {
segment: u8,
reason: &'static str,
},
AddressSizeMismatch {
expected: usize,
actual: usize,
},
OperandSizeMismatch {
expected: usize,
actual: usize,
},
InvalidRIPRelative {
offset: i64,
reason: &'static str,
},
InvalidLabel {
label_id: u32,
reason: &'static str,
},
InvalidSymbol {
symbol_id: u32,
reason: &'static str,
},
InvalidRelocation {
reloc_type: &'static str,
reason: &'static str,
},
InvalidOperandCombination {
mnemonic: &'static str,
},
}
impl fmt::Display for X86Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
X86Error::InvalidPrefix { prefix, reason } => {
write!(f, "invalid prefix 0x{:x}: {}", prefix, reason)
}
X86Error::InvalidOperand {
operand_index,
reason,
} => write!(f, "invalid operand {}: {}", operand_index, reason),
X86Error::InvalidInstruction { opcode, reason } => {
write!(f, "invalid instruction 0x{:x}: {}", opcode, reason)
}
X86Error::InvalidEncoding { encoding, reason } => {
write!(f, "invalid encoding {}: {}", encoding, reason)
}
X86Error::InvalidModRM { modrm, reason } => {
write!(f, "invalid ModRM byte 0x{:02x}: {}", modrm, reason)
}
X86Error::InvalidSIB { sib, reason } => {
write!(f, "invalid SIB byte 0x{:02x}: {}", sib, reason)
}
X86Error::InvalidDisplacement {
value,
size,
reason,
} => write!(
f,
"invalid displacement 0x{:x} (size {}): {}",
value, size, reason
),
X86Error::InvalidImmediate {
value,
size,
reason,
} => {
write!(
f,
"invalid immediate 0x{:x} (size {}): {}",
value, size, reason
)
}
X86Error::InvalidRegister {
reg_id,
reg_type,
reason,
} => write!(
f,
"invalid register {} (type {}): {}",
reg_id, reg_type, reason
),
X86Error::InvalidMemoryOperand {
base,
index,
scale,
offset,
reason,
} => write!(
f,
"invalid memory operand [base={:?}, index={:?}, scale={}, offset={}]: {}",
base, index, scale, offset, reason
),
X86Error::InvalidVSIB { index_reg, reason } => {
write!(f, "invalid VSIB index register {}: {}", index_reg, reason)
}
X86Error::InvalidMasking { mask_reg, reason } => {
write!(f, "invalid mask register {}: {}", mask_reg, reason)
}
X86Error::InvalidBroadcast { reason } => {
write!(f, "invalid broadcast: {}", reason)
}
X86Error::InvalidRoundingControl { rc, reason } => {
write!(f, "invalid rounding control 0x{:x}: {}", rc, reason)
}
X86Error::InvalidEVEX { field, reason } => {
write!(f, "invalid EVEX field '{}': {}", field, reason)
}
X86Error::InvalidVEX { field, reason } => {
write!(f, "invalid VEX field '{}': {}", field, reason)
}
X86Error::TooLongInstruction { length, max_length } => write!(
f,
"instruction too long: {} bytes (max {})",
length, max_length
),
X86Error::SegmentOverrideNotAllowed { segment, reason } => {
write!(f, "segment override {} not allowed: {}", segment, reason)
}
X86Error::AddressSizeMismatch { expected, actual } => write!(
f,
"address size mismatch: expected {} bytes, got {}",
expected, actual
),
X86Error::OperandSizeMismatch { expected, actual } => write!(
f,
"operand size mismatch: expected {} bytes, got {}",
expected, actual
),
X86Error::InvalidRIPRelative { offset, reason } => {
write!(f, "invalid RIP-relative offset {}: {}", offset, reason)
}
X86Error::InvalidLabel { label_id, reason } => {
write!(f, "invalid label {}: {}", label_id, reason)
}
X86Error::InvalidSymbol { symbol_id, reason } => {
write!(f, "invalid symbol {}: {}", symbol_id, reason)
}
X86Error::InvalidRelocation { reloc_type, reason } => {
write!(f, "invalid relocation {}: {}", reloc_type, reason)
}
X86Error::InvalidOperandCombination { mnemonic } => {
write!(
f,
"invalid operand combination for instruction `{}`",
mnemonic
)
}
}
}
}