Linux eBPF + Solana SBF (sBPFv1 / sBPFv2) decoder + minimal lifter.
Every BPF "slot" is 8 bytes: a 1-byte opcode, a 1-byte
pair of dst/src nibbles, a signed le16 offset, and a
signed le32 immediate. One special instruction — lddw
(load 64-bit immediate, opcode 0x18) — takes two
consecutive slots: the first carries bits [31:0] in imm,
the second has opcode 0 and bits [63:32] in its imm.
Solana SBF (classic / sBPFv1) and Agave sBPFv2 reuse the same encoding with a handful of extra opcodes:
CALL_REG(0x8d) — register-indexed dynamic call (added in sBPFv1).UDIV/SDIV/UREM/SREMPQR variants — sBPFv2 dedicated division/remainder ops (the Linux eBPF opcodes for these slots mean different things or are absent).- Explicit sign-extends (
SXH/SXW/SXD) — sBPFv2.
The decoder is variant-gated. Opcodes we know the mnemonic
for in the configured variant emit InsnKind::* with a
readable text rendering; opcodes we don't recognise emit
InsnKind::Unknown and the raw 8 bytes are preserved
verbatim — the round-trip property holds via byte identity
regardless of whether we can name the instruction.
References:
- Linux Kernel — eBPF Instruction Set, v6.5 docs.
- solana_rbpf — text format and SBF-specific opcode set.