pub trait ArchCodec:
Sync
+ Send
+ Debug {
Show 15 methods
// Required methods
fn name(&self) -> &'static str;
fn assemble_one(&self, text: &str, addr: u64) -> Result<Vec<u8>, ArchError>;
fn encode_jump(
&self,
source_ip: u64,
target: u64,
hints: EncodeHints,
) -> Result<Vec<u8>, ArchError>;
fn encode_call(
&self,
source_ip: u64,
target: u64,
hints: EncodeHints,
) -> Result<Vec<u8>, ArchError>;
fn encode_cond_jump(
&self,
cond_text: &str,
source_ip: u64,
target: u64,
hints: EncodeHints,
) -> Result<Vec<u8>, ArchError>;
fn encoded_jump_size(
&self,
source_ip: u64,
target: u64,
hints: EncodeHints,
) -> usize;
fn encoded_cond_jump_size(
&self,
source_ip: u64,
target: u64,
hints: EncodeHints,
) -> usize;
fn encoded_call_size(
&self,
source_ip: u64,
target: u64,
hints: EncodeHints,
) -> usize;
// Provided methods
fn desymbolize(&self, text: &str, _addr: u64) -> String { ... }
fn encode_cond_jump_with_code(
&self,
_cond_code: u8,
_source_ip: u64,
_target: u64,
_hints: EncodeHints,
) -> Result<Vec<u8>, ArchError> { ... }
fn encode_switch_dispatch(
&self,
_spec: &SwitchSpec<'_>,
) -> Result<Vec<u8>, ArchError> { ... }
fn direct_call_bytes_contain_call(&self) -> bool { ... }
fn encode_move(&self, _dst: &str, _src: &str) -> Result<Vec<u8>, ArchError> { ... }
fn encode_arith(
&self,
_dst: &str,
_op: &str,
_src: &str,
) -> Result<Vec<u8>, ArchError> { ... }
fn encode_return(&self, _value: Option<u64>) -> Result<Vec<u8>, ArchError> { ... }
}Expand description
The shared interface every arch backend implements.
Methods come in three classes:
- Always-supported: every arch must implement (
name,assemble_one,encode_jump,encode_call,encode_cond_jump, the three size queries). Trait users can call these unconditionally. - Optional with
Unsupporteddefault: methods that not every arch needs (encode_switch_dispatch,encode_move,encode_arith,encode_return,encode_cond_jump_with_code). Default impl returnsArchError::Unsupported. The decompile-side byte-drop pass and compile-side lower path both treatUnsupportedas “leave the pinned bytes alone.” - Optional with passthrough default:
desymbolize, which mapslabel_<hex>/sub_<hex>operands to numeric form. BPF overrides; default is identity.
Implementations must be Sync + Send so they can be stored
behind a Box<dyn ArchCodec> and shared across threads.
Required Methods§
Sourcefn name(&self) -> &'static str
fn name(&self) -> &'static str
Short stable identifier used in error messages and
ArchError::Unsupported.arch. Recommended forms:
"x86-64", "x86-32", "bpf-linux", "bpf-sbf-v1",
"bpf-sbf-v2", "aarch64", "6502".
Sourcefn assemble_one(&self, text: &str, addr: u64) -> Result<Vec<u8>, ArchError>
fn assemble_one(&self, text: &str, addr: u64) -> Result<Vec<u8>, ArchError>
Assemble one instruction’s text into bytes at addr.
addr matters only for arches whose instructions encode
the IP or whose symbolic operands need cursor context. Pass
0 when you don’t have a real address (e.g. unit tests).
Sourcefn encode_jump(
&self,
source_ip: u64,
target: u64,
hints: EncodeHints,
) -> Result<Vec<u8>, ArchError>
fn encode_jump( &self, source_ip: u64, target: u64, hints: EncodeHints, ) -> Result<Vec<u8>, ArchError>
Encode an unconditional jump from source_ip to target.
Sourcefn encode_call(
&self,
source_ip: u64,
target: u64,
hints: EncodeHints,
) -> Result<Vec<u8>, ArchError>
fn encode_call( &self, source_ip: u64, target: u64, hints: EncodeHints, ) -> Result<Vec<u8>, ArchError>
Encode a direct call from source_ip to target.
Sourcefn encode_cond_jump(
&self,
cond_text: &str,
source_ip: u64,
target: u64,
hints: EncodeHints,
) -> Result<Vec<u8>, ArchError>
fn encode_cond_jump( &self, cond_text: &str, source_ip: u64, target: u64, hints: EncodeHints, ) -> Result<Vec<u8>, ArchError>
Encode a conditional jump driven by a BPF-style text condition.
cond_text reads as “when this is true, the body runs”
(e.g. "r0 != 0x0"). The implementation typically inverts
internally to pick the underlying jcc that skips the
body. target is the address the jcc jumps to when the
condition is false (i.e. past the body).
Used by Stmt::IfBlock / Stmt::WhileBlock regen. Arches
whose If* Stmts carry a numeric cond_code instead use
Self::encode_cond_jump_with_code.
Sourcefn encoded_jump_size(
&self,
source_ip: u64,
target: u64,
hints: EncodeHints,
) -> usize
fn encoded_jump_size( &self, source_ip: u64, target: u64, hints: EncodeHints, ) -> usize
Predicted size of encode_jump’s output.
Sourcefn encoded_cond_jump_size(
&self,
source_ip: u64,
target: u64,
hints: EncodeHints,
) -> usize
fn encoded_cond_jump_size( &self, source_ip: u64, target: u64, hints: EncodeHints, ) -> usize
Predicted size of encode_cond_jump (text-driven).
Sourcefn encoded_call_size(
&self,
source_ip: u64,
target: u64,
hints: EncodeHints,
) -> usize
fn encoded_call_size( &self, source_ip: u64, target: u64, hints: EncodeHints, ) -> usize
Predicted size of encode_call’s output.
Provided Methods§
Sourcefn desymbolize(&self, text: &str, _addr: u64) -> String
fn desymbolize(&self, text: &str, _addr: u64) -> String
Resolve symbolic operands in text against addr. The
default is identity — arches with named-target operands
(BPF’s label_<hex> / sub_<hex>) override to substitute
numeric forms the assembler accepts.
Sourcefn encode_cond_jump_with_code(
&self,
_cond_code: u8,
_source_ip: u64,
_target: u64,
_hints: EncodeHints,
) -> Result<Vec<u8>, ArchError>
fn encode_cond_jump_with_code( &self, _cond_code: u8, _source_ip: u64, _target: u64, _hints: EncodeHints, ) -> Result<Vec<u8>, ArchError>
Encode a conditional jump driven by an x86-style numeric cond_code (the low nibble of the jcc opcode).
Used by Stmt::IfGoto / Stmt::IfReturn regen. Default
returns Unsupported.
Sourcefn encode_switch_dispatch(
&self,
_spec: &SwitchSpec<'_>,
) -> Result<Vec<u8>, ArchError>
fn encode_switch_dispatch( &self, _spec: &SwitchSpec<'_>, ) -> Result<Vec<u8>, ArchError>
Encode a jump-table dispatch. Default Unsupported.
Sourcefn direct_call_bytes_contain_call(&self) -> bool
fn direct_call_bytes_contain_call(&self) -> bool
Whether a Stmt::Call’s pinned bytes already
contains the call instruction itself (return true), or
bytes is just the arg-setup prefix and encode_call
regenerates the trailing call (return false).
- x86 strips the trailing 5 bytes of
call rel32and regenerates them at lower time so an edit that moves the function auto-resolves the new rel32. Returnsfalse(the default). - BPF has no separate “prefix” — the call IS the
single 8-byte instruction. Returns
true.
Used by the lower path’s Stmt::Call arm to decide
whether to append encode_call output after the
pinned bytes.
Sourcefn encode_move(&self, _dst: &str, _src: &str) -> Result<Vec<u8>, ArchError>
fn encode_move(&self, _dst: &str, _src: &str) -> Result<Vec<u8>, ArchError>
Encode dst = src as a single instruction. Default
Unsupported.
Both dst and src follow the arch’s text convention:
BPF accepts "r6", "0x5", "[r5 - 0xff8]", etc.; x86
would accept "rax", "0x5", "qword ptr [rbp-8]", etc.
Implementations return Unsupported for any shape they
don’t model.
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".