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