eBPF instruction
encoding
64 bit fixed size instructions encoded in host byte order
63 31 15 11 7 0
+------------------------+----------------+----+----+--------+
|immediate |offset |src |dst |opcode |
+------------------------+----------------+----+----+--------+
from most significant bit to least significant bit
- 32 bit signed immediate
- 16 bit signed offset
- 4 bit source register
- 4 bit destination register
- 8 bit opcode
when field are not used, they should be zeroed
opcode
opcode has two different encodings
type 1 type 2
7 4 2 0 7 3 2 0
+----+----+-----+ +----+---+-----+
|mode|size|class| |op |src|class|
+----+----+-----+ +----+---+-----+
which can be distinguished by the class field
type 1
LD 0x0 // load
LDX 0x1
ST 0x2 // store
STX 0x3
type 2
ALU 0x4
JMP 0x5
JMP32 0x6
ALU64 0x7
type 1
type 1 instructions are generally related to memory access, with few specialized exceptions for accessing packet data, which is out of the scope of this document
the size
field specifies the size of memory to access
W 0x0 // 4 byte
H 0x1 // 2 byte
B 0x2 // 1 byte
DW 0x3 // 8 byte
the mode
field specifies the addressing mode
IMM 0x0 // immediate
ABS 0x1 // packet absolute offset
IND 0x2 // packet indirect (register) offset
MEM 0x3 // memory
LEN 0x4 // reserved
MSH 0x5 // reserved
XADD 0x6 // exclusive (atomic) add
type 2
type 2 instructions are for alu and control flow operations
the src
field specifies the source of operand
K 0x0 // immediate
X 0x1 // register
the op
field specifies the operation
for class
in ALU
or ALU64
BPF_ADD 0x00
BPF_SUB 0x10
BPF_MUL 0x20
BPF_DIV 0x30
BPF_OR 0x40
BPF_AND 0x50
BPF_LSH 0x60
BPF_RSH 0x70
BPF_NEG 0x80
BPF_MOD 0x90
BPF_XOR 0xa0
BPF_MOV 0xb0
BPF_ARSH 0xc0
BPF_END 0xd0 // endianness conversion
for class
in JMP
or JMP32
BPF_JA 0x00 // JMP only
BPF_JEQ 0x10
BPF_JGT 0x20
BPF_JGE 0x30
BPF_JSET 0x40
BPF_JNE 0x50
BPF_JSGT 0x60
BPF_JSGE 0x70
BPF_CALL 0x80 // JMP only, function call
BPF_EXIT 0x90 // JMP only, function return
BPF_JLT 0xa0
BPF_JLE 0xb0
BPF_JSLT 0xc0
BPF_JSLE 0xd0
JMP32
and ALU
instructions operate on the lower 32 bits of the registers, zeroing the upper half of destination register
double word load
there exists one special instruction that takes 128 bits: LD IMM DW
, it loads two 32 bit immediates from this and the next instruction into a single register, effectively loading a 64 bit immediate
implementation notes
for eBPF runtimes, there's no need to implement the full eBPF instruction set, a subset of which is more than enough for kernel instrumentation. a great reference is the llvm unit tests for eBPF target: llvm test eBPF