Expand description
§asmkit
§Overview
asmkit is a portable assembler toolkit built around an AsmJit-style instruction-database
model. It is a small, efficient, no_std library for encoding machine code without being
tied to a specific platform. Key features include:
- Multi-Architecture Support: x86/x64, RISC-V, and AArch64. Each backend follows the
same uniform model: a dense
InstIdenum backed by generated instdb tables, and a single checked raw emit entry point. - Generated emitter traits: per-mnemonic traits (e.g.
MovEmitter) with impls for the sized register wrappers, so register constants and integer immediates are passed directly (asm.mov(RAX, 42)— no dereferencing). - Read/write effects:
query_rw_info(&Inst) -> InstRwInfoper architecture, over the architecture-taggedInst. - Deferred emission:
Builderrecords instructions and label binds and replays them into anyInstSink(implemented by every architecture’sAssembler). - Minimal Dependencies:
-
libc,intrusive-collections,errno- For JIT support.
-
paste,bitflags,cfgenius,num-traits- Utility crates that simplify repetitive arch-specific declarations.
-
smallvec- Avoids frequent heap allocation during code generation.
- Code Relocations: Provides a CodeBuffer interface to handle relocations, allowing the insertion of symbols into the API seamlessly.
- Portability: Built to run on any platform, with the architecture-specific parts of the library being independent of the platform on which asmkit is built.
§From assembly to execution
The API story mirrors AsmJit’s (CodeHolder → JitAllocator), with
CodeBuffer playing the CodeHolder role:
- Emit into a
CodeBufferthrough a backendAssembler. - Finalize with
CodeBuffer::finish, optionally combining several modules —Sections or plain buffers — into one image withLinker. - Load with [
CodeBufferFinalized::allocate] (no relocations),allocate_relocated, orallocate_resolved(external symbols resolved viaExternalName). - Find entry points with
CodeBufferFinalized::defined_symbol_offset/defined_symbol_strand call throughrx() + offset.
External names are either string ExternalName::Symbols or Cranelift-style
ExternalName::User namespace+index keys (extern_user / bind_symbol), so
hosts that do not use string symbols can still link and resolve.
Void mnemonic methods retain the first emission error in the CodeBuffer.
CodeBuffer::finish returns it, alongside finalization, linking, loading,
and patching errors, as AsmError.
§Usage
To use the library simply import the module for the architecture you want to emit code
for, e.g. use asmkit::x86::*;; this includes all the code required to generate code for
that platform.
Example:
use asmkit::{Arch, CodeBuffer, Environment, JitAllocator};
use asmkit::x86::*;
let mut buf = CodeBuffer::new(Environment::new(Arch::X64));
{
let mut asm = Assembler::new(&mut buf);
// Typed sized registers and plain integer immediates.
asm.mov(RAX, 5);
asm.add(RAX, 37);
asm.ret();
}
let result = buf.finish().expect("assembly failed");
let mut jit = JitAllocator::new(Default::default());
// you can also use jit.alloc + jit.write manually.
let span = result
.allocate(&mut jit)
.expect("failed to allocate JIT-code");
// JIT Allocator uses dual-mapping: it allocates two pages which map to same physical space
// and you write to executable code through `span.rw()` pointer while you can execute `span.rx()`.
let f: extern "C" fn() -> u64 = unsafe { std::mem::transmute(span.rx()) };
#[cfg(all(unix, target_arch = "x86_64"))] // can run only on x64 and on SystemV platforms.
assert_eq!(f(), 42);Modules§
Structs§
- AsmReloc
- A relocation resulting from emitting assembly.
- BaseMem
- BaseReg
- Builder
- Records instructions and label-bind points for deferred emission.
- Code
Buffer - A buffer of output to be produced, fixed up, and then emitted to a CodeSink in bulk.
- Code
Buffer Finalized - A
CodeBufferonce emission is completed: holds generated code and records, without fixups. This allows the type to be independent of the backend. - Constant
- A use of a constant by one or mroe assembly instructions.
- CpuRw
Flags - CPU read/write flags used by
InstRwInfo. - Environment
- Finalized
Section - A section whose buffer has been finalized, ready for linking.
- Imm
- Inst
- A generic instruction: id + options + extra register + inline operand array.
- Inst
Options - Inst
RwFlags - Flags used by
InstRwInfo. - Inst
RwInfo - Read/write information of an instruction.
- Label
- Linker
- Links finalized sections and buffers into one in-memory image.
- OpRw
Flags - Operand read/write flags describe how the operand is accessed and additional features.
- OpRw
Info - Read/write information related to a single operand, used by
InstRwInfo. - Operand
- Base struct representing an operand in asmkit.
- Operand
Signature - Patch
Block - Catalog entry for a rewritable byte range.
- Patch
Block Id - Catalog index for a patch block (linker / introspection).
- Patch
Catalog - Finalized patch metadata for validation and linker rebasing.
- Patch
Site - Catalog entry for a displacement field.
- Patch
Site Id - Catalog index for a patch site (linker / introspection).
- Patchable
Block - Self-describing handle for a rewritable code region (immediate or custom block).
- Patchable
Site - Self-describing handle for a patchable displacement (jump/call).
- Section
- A named section: its own code buffer plus an alignment requirement.
- Sym
- User
External Name - An external name in a user-defined symbol table.
Enums§
- AArch64
Feature - AArch64 architectural features present in the pinned AsmJit ISA metadata.
- Arch
- Instruction set architecture (ISA).
- AsmError
- Error type shared by all backends and the core code-management machinery.
- Cond
Code - Constant
Data - External
Name - Name of an external (or exported) symbol.
- ImmType
- Inst
Control Flow - Instruction control flow.
- Inst
Same RegHint - Hint used when two or more operands of an instruction are the same register.
- Label
Use - Link
Error - Context for an in-memory image-link failure.
- Node
- A node recorded by a
Builder. - Operand
Type - Operand type used by Operand
- RegGroup
- RegType
- Register type.
- Reloc
- Relocation kinds for every ISA
- Reloc
Distance - Reloc
Target - RiscV
Feature - RISC-V extension identifiers from the pinned riscv-opcodes input files.
- X86Error
- Detailed x86/x64 encoding error, wrapped by
AsmError::X86. - X86Feature
- X86 CPU feature identifiers (port of AsmJit’s
CpuFeatures::X86).
Constants§
- INVALID_
PHYS_ ID - Physical register id used when an operand is not tied to any specific physical register.
Traits§
- Inst
Sink - Sink that consumes replayed nodes — implemented by each architecture’s
Assembler. - Operand
Cast - A helper trait to help cast Operand to Architecture dependent operands and vice-versa.
- RegTraits
Functions§
Type Aliases§
- Addend
- Addend to add to the symbol value.
- Code
Offset - Offset in bytes from the beginning of the function.
- RegMask
- Register mask is a convenience typedef that describes a mask where each bit describes a physical register id in the same RegGroup. At the moment 32 bits are enough as asmkit doesn’t support any architecture that would provide more than 32 registers for a register group.