Idiomatic Clojure DSL for BPF programming
Idiomatic Clojure DSL for BPF programming
(add dst imm)Add immediate to register (64-bit).
Example: (add :r0 10) ; r0 += 10
Add immediate to register (64-bit). Example: (add :r0 10) ; r0 += 10
(add-reg dst src)Add register to register (64-bit).
Example: (add-reg :r0 :r1) ; r0 += r1
Add register to register (64-bit). Example: (add-reg :r0 :r1) ; r0 += r1
(alu-imm op dst imm)ALU operation with immediate operand (64-bit).
Example: (alu-imm :add :r0 10) ; r0 += 10
ALU operation with immediate operand (64-bit). Example: (alu-imm :add :r0 10) ; r0 += 10
ALU operation codes (bits 4-7 of opcode)
ALU operation codes (bits 4-7 of opcode)
(alu-reg op dst src)ALU operation with register operand (64-bit).
Example: (alu-reg :add :r0 :r1) ; r0 += r1
ALU operation with register operand (64-bit). Example: (alu-reg :add :r0 :r1) ; r0 += r1
(alu32-imm op dst imm)ALU operation with immediate operand (32-bit).
Example: (alu32-imm :add :r0 10) ; r0 = (u32)(r0 + 10)
ALU operation with immediate operand (32-bit). Example: (alu32-imm :add :r0 10) ; r0 = (u32)(r0 + 10)
(alu32-reg op dst src)ALU operation with register operand (32-bit).
Example: (alu32-reg :add :r0 :r1) ; r0 = (u32)(r0 + r1)
ALU operation with register operand (32-bit). Example: (alu32-reg :add :r0 :r1) ; r0 = (u32)(r0 + r1)
(and dst src-or-imm)Bitwise AND operation (tutorial-compatible). Handles both immediate and register sources.
Example: (and :r0 0xFF) ; r0 &= 0xFF (immediate) (and :r0 :r1) ; r0 &= r1 (register)
Bitwise AND operation (tutorial-compatible). Handles both immediate and register sources. Example: (and :r0 0xFF) ; r0 &= 0xFF (immediate) (and :r0 :r1) ; r0 &= r1 (register)
(and-op dst imm)Bitwise AND with immediate (64-bit).
Example: (and-op :r0 0xFF) ; r0 &= 0xFF
Bitwise AND with immediate (64-bit). Example: (and-op :r0 0xFF) ; r0 &= 0xFF
(and-reg dst src)Bitwise AND with register (64-bit).
Example: (and-reg :r0 :r1) ; r0 &= r1
Bitwise AND with register (64-bit). Example: (and-reg :r0 :r1) ; r0 &= r1
(arsh dst imm)Arithmetic right shift by immediate (64-bit).
Example: (arsh :r0 8) ; r0 = (s64)r0 >> 8
Arithmetic right shift by immediate (64-bit). Example: (arsh :r0 8) ; r0 = (s64)r0 >> 8
(assemble instructions)Assemble a sequence of instructions into BPF bytecode.
Parameters:
Returns combined byte array.
Example: (assemble [(mov :r0 0) (exit-insn)])
Assemble a sequence of instructions into BPF bytecode.
Parameters:
- instructions: Sequence of instruction byte arrays
Returns combined byte array.
Example:
(assemble [(mov :r0 0)
(exit-insn)])(atomic-add size dst src)(atomic-add size dst src offset)Atomic add to memory location.
Performs: *dst[offset] += src
Parameters:
Example: (atomic-add :dw :r1 :r2 0) ; (u64)(r1+0) += r2
Atomic add to memory location. Performs: *dst[offset] += src Parameters: - size: :w (32-bit) or :dw (64-bit) - dst: Register containing memory address - src: Register containing value to add - offset: Memory offset (default 0) Example: (atomic-add :dw :r1 :r2 0) ; *(u64*)(r1+0) += r2
(atomic-and size dst src)(atomic-and size dst src offset)Atomic AND to memory location.
Performs: *dst[offset] &= src
Parameters:
Example: (atomic-and :dw :r1 :r2 0) ; (u64)(r1+0) &= r2
Atomic AND to memory location. Performs: *dst[offset] &= src Parameters: - size: :w (32-bit) or :dw (64-bit) - dst: Register containing memory address - src: Register containing value to AND - offset: Memory offset (default 0) Example: (atomic-and :dw :r1 :r2 0) ; *(u64*)(r1+0) &= r2
(atomic-clear-bit addr-reg bit)(atomic-clear-bit addr-reg bit offset)Generate code to atomically clear a bit.
Uses atomic-and with inverted bit mask.
Parameters:
Returns instruction sequence.
Example: (atomic-clear-bit :r1 5 0) ; Clear bit 5 in *r1
Generate code to atomically clear a bit. Uses atomic-and with inverted bit mask. Parameters: - addr-reg: Register containing memory address - bit: Bit number to clear (0-63) - offset: Memory offset (default 0) Returns instruction sequence. Example: (atomic-clear-bit :r1 5 0) ; Clear bit 5 in *r1
(atomic-cmpxchg size dst src)(atomic-cmpxchg size dst src offset)Atomic compare-and-exchange (CAS).
Performs:
Note: r0 is implicitly used as the comparison value.
Parameters:
Example: ;; Compare-and-swap pattern: (mov :r0 expected-value) (mov :r2 new-value) (atomic-cmpxchg :dw :r1 :r2 0) ;; r0 now contains original value ;; Memory updated only if original == expected-value
Atomic compare-and-exchange (CAS). Performs: - If *dst[offset] == r0, then *dst[offset] = src - r0 receives the original value of *dst[offset] Note: r0 is implicitly used as the comparison value. Parameters: - size: :w (32-bit) or :dw (64-bit) - dst: Register containing memory address - src: Register containing new value to write if comparison succeeds - offset: Memory offset (default 0) Example: ;; Compare-and-swap pattern: (mov :r0 expected-value) (mov :r2 new-value) (atomic-cmpxchg :dw :r1 :r2 0) ;; r0 now contains original value ;; Memory updated only if original == expected-value
(atomic-decrement addr-reg)(atomic-decrement addr-reg offset)Generate code to atomically decrement a counter.
Uses atomic-add with value -1.
Parameters:
Returns instruction sequence.
Example: (atomic-decrement :r1 0) ; (*r1)-- atomically
Generate code to atomically decrement a counter. Uses atomic-add with value -1. Parameters: - addr-reg: Register containing counter address - offset: Memory offset (default 0) Returns instruction sequence. Example: (atomic-decrement :r1 0) ; (*r1)-- atomically
(atomic-fetch-add size dst src)(atomic-fetch-add size dst src offset)Atomic fetch-and-add: returns old value, then adds.
Performs: src = *dst[offset]; *dst[offset] += src (Note: src receives the OLD value, not the new value)
Parameters:
Example: (atomic-fetch-add :dw :r1 :r2 0) ; r2 = *(r1+0); *(r1+0) += old_r2
Atomic fetch-and-add: returns old value, then adds. Performs: src = *dst[offset]; *dst[offset] += src (Note: src receives the OLD value, not the new value) Parameters: - size: :w (32-bit) or :dw (64-bit) - dst: Register containing memory address - src: Register containing value to add (receives old value) - offset: Memory offset (default 0) Example: (atomic-fetch-add :dw :r1 :r2 0) ; r2 = *(r1+0); *(r1+0) += old_r2
(atomic-fetch-and size dst src)(atomic-fetch-and size dst src offset)Atomic fetch-and-AND: returns old value, then ANDs.
Parameters:
Atomic fetch-and-AND: returns old value, then ANDs. Parameters: - size: :w (32-bit) or :dw (64-bit) - dst: Register containing memory address - src: Register containing value to AND (receives old value) - offset: Memory offset (default 0)
(atomic-fetch-or size dst src)(atomic-fetch-or size dst src offset)Atomic fetch-and-OR: returns old value, then ORs.
Parameters:
Atomic fetch-and-OR: returns old value, then ORs. Parameters: - size: :w (32-bit) or :dw (64-bit) - dst: Register containing memory address - src: Register containing value to OR (receives old value) - offset: Memory offset (default 0)
(atomic-fetch-xor size dst src)(atomic-fetch-xor size dst src offset)Atomic fetch-and-XOR: returns old value, then XORs.
Parameters:
Atomic fetch-and-XOR: returns old value, then XORs. Parameters: - size: :w (32-bit) or :dw (64-bit) - dst: Register containing memory address - src: Register containing value to XOR (receives old value) - offset: Memory offset (default 0)
(atomic-increment addr-reg)(atomic-increment addr-reg offset)Generate code to atomically increment a counter.
Uses atomic-fetch-add with value 1.
Parameters:
Returns instruction sequence.
Example: (atomic-increment :r1 0) ; (*r1)++ atomically
Generate code to atomically increment a counter. Uses atomic-fetch-add with value 1. Parameters: - addr-reg: Register containing counter address - offset: Memory offset (default 0) Returns instruction sequence. Example: (atomic-increment :r1 0) ; (*r1)++ atomically
(atomic-or size dst src)(atomic-or size dst src offset)Atomic OR to memory location.
Performs: *dst[offset] |= src
Parameters:
Example: (atomic-or :dw :r1 :r2 0) ; (u64)(r1+0) |= r2
Atomic OR to memory location. Performs: *dst[offset] |= src Parameters: - size: :w (32-bit) or :dw (64-bit) - dst: Register containing memory address - src: Register containing value to OR - offset: Memory offset (default 0) Example: (atomic-or :dw :r1 :r2 0) ; *(u64*)(r1+0) |= r2
(atomic-set-bit addr-reg bit)(atomic-set-bit addr-reg bit offset)Generate code to atomically set a bit.
Uses atomic-or to set the specified bit.
Parameters:
Returns instruction sequence.
Example: (atomic-set-bit :r1 5 0) ; Set bit 5 in *r1
Generate code to atomically set a bit. Uses atomic-or to set the specified bit. Parameters: - addr-reg: Register containing memory address - bit: Bit number to set (0-63) - offset: Memory offset (default 0) Returns instruction sequence. Example: (atomic-set-bit :r1 5 0) ; Set bit 5 in *r1
(atomic-toggle-bit addr-reg bit)(atomic-toggle-bit addr-reg bit offset)Generate code to atomically toggle (flip) a bit.
Uses atomic-xor with the bit mask.
Parameters:
Returns instruction sequence.
Example: (atomic-toggle-bit :r1 5 0) ; Toggle bit 5 in *r1
Generate code to atomically toggle (flip) a bit. Uses atomic-xor with the bit mask. Parameters: - addr-reg: Register containing memory address - bit: Bit number to toggle (0-63) - offset: Memory offset (default 0) Returns instruction sequence. Example: (atomic-toggle-bit :r1 5 0) ; Toggle bit 5 in *r1
(atomic-xchg size dst src)(atomic-xchg size dst src offset)Atomic exchange: swap register value with memory value.
Performs: src = xchg(*dst[offset], src) The old memory value is placed in src, and src's old value is written to memory.
Parameters:
Example: (atomic-xchg :dw :r1 :r2 0) ; r2 <=> *(r1+0)
Atomic exchange: swap register value with memory value. Performs: src = xchg(*dst[offset], src) The old memory value is placed in src, and src's old value is written to memory. Parameters: - size: :w (32-bit) or :dw (64-bit) - dst: Register containing memory address - src: Register to exchange with memory - offset: Memory offset (default 0) Example: (atomic-xchg :dw :r1 :r2 0) ; r2 <=> *(r1+0)
(atomic-xor size dst src)(atomic-xor size dst src offset)Atomic XOR to memory location.
Performs: *dst[offset] ^= src
Parameters:
Example: (atomic-xor :dw :r1 :r2 0) ; (u64)(r1+0) ^= r2
Atomic XOR to memory location. Performs: *dst[offset] ^= src Parameters: - size: :w (32-bit) or :dw (64-bit) - dst: Register containing memory address - src: Register containing value to XOR - offset: Memory offset (default 0) Example: (atomic-xor :dw :r1 :r2 0) ; *(u64*)(r1+0) ^= r2
(bounded-loop iterations callback-fn-reg)(bounded-loop iterations callback-fn-reg callback-ctx-reg)Generate code for a bounded loop using bpf_loop helper.
Executes callback function up to N times.
Parameters:
Returns instruction sequence.
Example: (bounded-loop 10 :r1 :r2) ;; Calls function at r1 up to 10 times with ctx r2
Generate code for a bounded loop using bpf_loop helper. Executes callback function up to N times. Parameters: - iterations: Number of iterations (immediate or register) - callback-fn-reg: Register containing callback function pointer - callback-ctx-reg: Register containing callback context (optional) Returns instruction sequence. Example: (bounded-loop 10 :r1 :r2) ;; Calls function at r1 up to 10 times with ctx r2
(call helper-id)Call BPF helper function.
Example: (call (:map-lookup-elem bpf-helpers)) ; call helper
Call BPF helper function. Example: (call (:map-lookup-elem bpf-helpers)) ; call helper
(cas-loop addr-reg expected-reg new-reg retry-offset)(cas-loop addr-reg expected-reg new-reg retry-offset offset)Generate a compare-and-swap loop pattern.
Attempts to atomically update a value from old to new. Retries if another CPU modified the value.
Parameters:
Returns instruction sequence.
Note: This is a template - actual implementation may need adjustment based on specific use case.
Example: ;; Load current value into r6 (ldx :dw :r6 :r1 0) ;; Prepare expected and new values (mov-reg :r0 :r6) ; r0 = expected (add-reg :r2 :r6) ; r2 = r6 + delta = new value ;; CAS (atomic-cmpxchg :dw :r1 :r2 0) ;; r0 now has original, compare with expected (jmp-reg :jne :r0 :r6 retry-offset) ; retry if changed
Generate a compare-and-swap loop pattern. Attempts to atomically update a value from old to new. Retries if another CPU modified the value. Parameters: - addr-reg: Register containing memory address - expected-reg: Register containing expected old value - new-reg: Register containing new value to write - retry-offset: Jump offset to retry location (negative) - offset: Memory offset (default 0) Returns instruction sequence. Note: This is a template - actual implementation may need adjustment based on specific use case. Example: ;; Load current value into r6 (ldx :dw :r6 :r1 0) ;; Prepare expected and new values (mov-reg :r0 :r6) ; r0 = expected (add-reg :r2 :r6) ; r2 = r6 + delta = new value ;; CAS (atomic-cmpxchg :dw :r1 :r2 0) ;; r0 now has original, compare with expected (jmp-reg :jne :r0 :r6 retry-offset) ; retry if changed
(compile-program & instructions)Compile DSL instructions into BPF bytecode at runtime.
Parameters:
Returns byte array.
Example: (compile-program (mov :r0 2) (exit-insn))
Compile DSL instructions into BPF bytecode at runtime.
Parameters:
- instructions: List of DSL instruction forms
Returns byte array.
Example:
(compile-program
(mov :r0 2)
(exit-insn))(core-enum-value dst enum-name value-name)Generate placeholder instruction for CO-RE enum value relocation.
Returns the integer value of an enum constant.
Parameters:
Returns instruction byte array.
Example: ;; Get value of TASK_RUNNING from task state enum (core-enum-value :r0 "task_state" "TASK_RUNNING")
Generate placeholder instruction for CO-RE enum value relocation. Returns the integer value of an enum constant. Parameters: - dst: Destination register - enum-name: Enum type name - value-name: Enum value name Returns instruction byte array. Example: ;; Get value of TASK_RUNNING from task state enum (core-enum-value :r0 "task_state" "TASK_RUNNING")
(core-field-exists dst struct-name field-name)Generate placeholder instruction for CO-RE field existence check.
Returns 1 if field exists in target kernel, 0 if not.
Parameters:
Returns instruction byte array.
Example: ;; Check if task_struct has 'pids' field (core-field-exists :r0 "task_struct" "pids")
Generate placeholder instruction for CO-RE field existence check. Returns 1 if field exists in target kernel, 0 if not. Parameters: - dst: Destination register - struct-name: Structure name - field-name: Field name Returns instruction byte array. Example: ;; Check if task_struct has 'pids' field (core-field-exists :r0 "task_struct" "pids")
(core-field-offset dst struct-name field-name)Generate placeholder instruction for CO-RE field offset relocation.
This generates a MOV instruction with a placeholder immediate value (0) that will be relocated at load time using BTF information to the correct field offset.
Note: Actual CO-RE relocation requires BTF data and relocation records that are typically handled by the ELF loader or program loader.
Parameters:
Returns instruction byte array with placeholder offset.
Example: ;; Load offset of task_struct->pid into r1 (core-field-offset :r1 "task_struct" "pid")
The placeholder value (0) would be replaced with the actual offset during program loading when CO-RE relocations are processed.
Generate placeholder instruction for CO-RE field offset relocation. This generates a MOV instruction with a placeholder immediate value (0) that will be relocated at load time using BTF information to the correct field offset. Note: Actual CO-RE relocation requires BTF data and relocation records that are typically handled by the ELF loader or program loader. Parameters: - dst: Destination register - struct-name: Structure name (for documentation/debugging) - field-name: Field name (for documentation/debugging) Returns instruction byte array with placeholder offset. Example: ;; Load offset of task_struct->pid into r1 (core-field-offset :r1 "task_struct" "pid") The placeholder value (0) would be replaced with the actual offset during program loading when CO-RE relocations are processed.
(core-field-size dst struct-name field-name)Generate placeholder instruction for CO-RE field size relocation.
Returns size of field in bytes.
Parameters:
Returns instruction byte array.
Example: ;; Get size of task_struct->comm field (core-field-size :r1 "task_struct" "comm")
Generate placeholder instruction for CO-RE field size relocation. Returns size of field in bytes. Parameters: - dst: Destination register - struct-name: Structure name - field-name: Field name Returns instruction byte array. Example: ;; Get size of task_struct->comm field (core-field-size :r1 "task_struct" "comm")
(core-type-exists dst type-name)Generate placeholder instruction for CO-RE type existence check.
Returns 1 if type exists in target kernel, 0 if not.
Parameters:
Returns instruction byte array.
Example: ;; Check if 'struct bpf_map' exists (core-type-exists :r0 "struct bpf_map")
Generate placeholder instruction for CO-RE type existence check. Returns 1 if type exists in target kernel, 0 if not. Parameters: - dst: Destination register - type-name: Type name to check Returns instruction byte array. Example: ;; Check if 'struct bpf_map' exists (core-type-exists :r0 "struct bpf_map")
(core-type-size dst type-name)Generate placeholder instruction for CO-RE type size relocation.
Returns size of type in bytes.
Parameters:
Returns instruction byte array.
Example: ;; Get size of task_struct (core-type-size :r1 "task_struct")
Generate placeholder instruction for CO-RE type size relocation. Returns size of type in bytes. Parameters: - dst: Destination register - type-name: Type name Returns instruction byte array. Example: ;; Get size of task_struct (core-type-size :r1 "task_struct")
(defbpf name & body)Define a BPF program using DSL.
Example: (defbpf my-program (mov :r0 0) (exit-insn))
Define a BPF program using DSL.
Example:
(defbpf my-program
(mov :r0 0)
(exit-insn))(div dst imm)Divide register by immediate (64-bit).
Example: (div :r0 2) ; r0 /= 2
Divide register by immediate (64-bit). Example: (div :r0 2) ; r0 /= 2
(div-reg dst src)Divide register by register (64-bit).
Example: (div-reg :r0 :r1) ; r0 /= r1
Divide register by register (64-bit). Example: (div-reg :r0 :r1) ; r0 /= r1
(end-to-be dst size)Convert register from host byte order to big-endian (network byte order).
size: Bit size - 16, 32, or 64
Example: (end-to-be :r0 16) ; r0 = htobe16(r0) (end-to-be :r1 32) ; r1 = htobe32(r1)
Convert register from host byte order to big-endian (network byte order). size: Bit size - 16, 32, or 64 Example: (end-to-be :r0 16) ; r0 = htobe16(r0) (end-to-be :r1 32) ; r1 = htobe32(r1)
(end-to-le dst size)Convert register from host byte order to little-endian.
size: Bit size - 16, 32, or 64
Note: On x86/x86_64 (little-endian), this is essentially a no-op. The instruction is provided for portability.
Example: (end-to-le :r0 16) ; r0 = htole16(r0) (end-to-le :r1 32) ; r1 = htole32(r1)
Convert register from host byte order to little-endian. size: Bit size - 16, 32, or 64 Note: On x86/x86_64 (little-endian), this is essentially a no-op. The instruction is provided for portability. Example: (end-to-le :r0 16) ; r0 = htole16(r0) (end-to-le :r1 32) ; r1 = htole32(r1)
(endian-be size dst)Convert to big-endian (tutorial-compatible alias for end-to-be).
Example: (endian-be :h :r5) ; Convert r5 to big-endian 16-bit
Convert to big-endian (tutorial-compatible alias for end-to-be). Example: (endian-be :h :r5) ; Convert r5 to big-endian 16-bit
(endian-le size dst)Convert to little-endian (tutorial-compatible alias for end-to-le).
Example: (endian-le :w :r5) ; Convert r5 to little-endian 32-bit
Convert to little-endian (tutorial-compatible alias for end-to-le). Example: (endian-le :w :r5) ; Convert r5 to little-endian 32-bit
(exit)Exit program (tutorial-compatible alias for exit-insn).
Exit program (tutorial-compatible alias for exit-insn).
(exit-insn)Exit BPF program.
Example: (exit-insn) ; return
Exit BPF program. Example: (exit-insn) ; return
(extract-gid uid-gid-reg gid-reg)Extract GID from combined UID/GID value.
Parameters:
Returns instruction sequence.
Example: (extract-gid :r0 :r1) ;; r1 = r0 >> 32
Extract GID from combined UID/GID value. Parameters: - uid-gid-reg: Register containing combined value - gid-reg: Register to receive GID Returns instruction sequence. Example: (extract-gid :r0 :r1) ;; r1 = r0 >> 32
(extract-pid pid-tgid-reg pid-reg)Extract PID from combined PID/TGID value.
Parameters:
Returns instruction sequence.
Example: (extract-pid :r0 :r1) ;; r1 = r0 & 0xFFFFFFFF
Extract PID from combined PID/TGID value. Parameters: - pid-tgid-reg: Register containing combined value - pid-reg: Register to receive PID Returns instruction sequence. Example: (extract-pid :r0 :r1) ;; r1 = r0 & 0xFFFFFFFF
(extract-tgid pid-tgid-reg tgid-reg)Extract TGID from combined PID/TGID value.
Parameters:
Returns instruction sequence.
Example: (extract-tgid :r0 :r1) ;; r1 = r0 >> 32
Extract TGID from combined PID/TGID value. Parameters: - pid-tgid-reg: Register containing combined value - tgid-reg: Register to receive TGID Returns instruction sequence. Example: (extract-tgid :r0 :r1) ;; r1 = r0 >> 32
(extract-uid uid-gid-reg uid-reg)Extract UID from combined UID/GID value.
Parameters:
Returns instruction sequence.
Example: (extract-uid :r0 :r1) ;; r1 = r0 & 0xFFFFFFFF
Extract UID from combined UID/GID value. Parameters: - uid-gid-reg: Register containing combined value - uid-reg: Register to receive UID Returns instruction sequence. Example: (extract-uid :r0 :r1) ;; r1 = r0 & 0xFFFFFFFF
(filter-by-pid target-pid skip-jump-offset)Generate code to filter by process ID.
Only continues if PID matches, otherwise jumps to offset.
Parameters:
Returns instruction sequence.
Example: (filter-by-pid 1234 20) ;; Jumps forward 20 instructions if current PID != 1234
Generate code to filter by process ID. Only continues if PID matches, otherwise jumps to offset. Parameters: - target-pid: PID to match (immediate value) - skip-jump-offset: Jump offset if PID doesn't match Returns instruction sequence. Example: (filter-by-pid 1234 20) ;; Jumps forward 20 instructions if current PID != 1234
(filter-by-uid target-uid skip-jump-offset)Generate code to filter by user ID.
Only continues if UID matches, otherwise jumps to offset.
Parameters:
Returns instruction sequence.
Example: (filter-by-uid 1000 20) ;; Jumps forward 20 instructions if current UID != 1000
Generate code to filter by user ID. Only continues if UID matches, otherwise jumps to offset. Parameters: - target-uid: UID to match (immediate value) - skip-jump-offset: Jump offset if UID doesn't match Returns instruction sequence. Example: (filter-by-uid 1000 20) ;; Jumps forward 20 instructions if current UID != 1000
(generate-core-read dst src field-spec)Generate BPF CO-RE read sequence for nested field access.
This generates a sequence of instructions to safely read a field from a structure with CO-RE relocations, including NULL pointer checks.
Pattern similar to BPF_CORE_READ macro in C.
Parameters:
Returns sequence of instruction byte arrays.
Example: ;; Read current->pid (generate-core-read :r0 :r1 {:struct-name "task_struct" :field-name "pid"})
Generate BPF CO-RE read sequence for nested field access.
This generates a sequence of instructions to safely read a field from
a structure with CO-RE relocations, including NULL pointer checks.
Pattern similar to BPF_CORE_READ macro in C.
Parameters:
- dst: Destination register for the result
- src: Source register containing pointer to structure
- field-spec: Map with :struct-name and :field-name
Returns sequence of instruction byte arrays.
Example:
;; Read current->pid
(generate-core-read :r0 :r1
{:struct-name "task_struct"
:field-name "pid"})(get-process-info pid-tgid-reg uid-gid-reg)(get-process-info pid-tgid-reg uid-gid-reg comm-buf-reg)(get-process-info pid-tgid-reg uid-gid-reg comm-buf-reg comm-size)Generate code to collect full process information.
Collects PID, TGID, UID, GID, and command name.
Parameters:
Returns instruction sequence.
Example: (get-process-info :r6 :r7 :r8) ;; r6 = (tgid << 32) | pid ;; r7 = (gid << 32) | uid ;; buffer at r8 = comm
Generate code to collect full process information. Collects PID, TGID, UID, GID, and command name. Parameters: - pid-tgid-reg: Register to store combined PID/TGID (default :r6) - uid-gid-reg: Register to store combined UID/GID (default :r7) - comm-buf-reg: Register containing comm buffer pointer (optional) - comm-size: Size of comm buffer (default 16) Returns instruction sequence. Example: (get-process-info :r6 :r7 :r8) ;; r6 = (tgid << 32) | pid ;; r7 = (gid << 32) | uid ;; buffer at r8 = comm
(helper-get-current-ancestor-cgroup-id ancestor-level-reg)Call bpf_get_current_ancestor_cgroup_id helper.
Get ancestor cgroup ID at specified level.
Parameters:
Returns ancestor cgroup ID in r0.
Example: (helper-get-current-ancestor-cgroup-id :r1)
Call bpf_get_current_ancestor_cgroup_id helper. Get ancestor cgroup ID at specified level. Parameters: - ancestor-level-reg: Register containing ancestor level Returns ancestor cgroup ID in r0. Example: (helper-get-current-ancestor-cgroup-id :r1)
(helper-get-current-cgroup-id)Call bpf_get_current_cgroup_id helper.
Get current cgroup ID.
Returns cgroup ID in r0.
Example: (helper-get-current-cgroup-id) ;; r0 = current cgroup ID
Call bpf_get_current_cgroup_id helper. Get current cgroup ID. Returns cgroup ID in r0. Example: (helper-get-current-cgroup-id) ;; r0 = current cgroup ID
(helper-get-current-comm buf-reg size-reg)Call bpf_get_current_comm helper.
Get current process command name.
Parameters:
Returns 0 on success, negative on error.
Example: (helper-get-current-comm :r1 :r2) ;; Fills buffer at r1 with command name
Call bpf_get_current_comm helper. Get current process command name. Parameters: - buf-reg: Register containing pointer to buffer (min 16 bytes) - size-reg: Register containing buffer size Returns 0 on success, negative on error. Example: (helper-get-current-comm :r1 :r2) ;; Fills buffer at r1 with command name
(helper-get-current-pid-tgid)Call bpf_get_current_pid_tgid helper.
Get current process PID and thread group ID.
Returns u64 in r0 where:
Example: (helper-get-current-pid-tgid) ;; r0 = (tgid << 32) | pid
Call bpf_get_current_pid_tgid helper. Get current process PID and thread group ID. Returns u64 in r0 where: - Upper 32 bits = TGID (process ID) - Lower 32 bits = PID (thread ID) Example: (helper-get-current-pid-tgid) ;; r0 = (tgid << 32) | pid
(helper-get-current-task)Call bpf_get_current_task helper.
Get pointer to current task_struct.
Returns pointer to task_struct in r0.
Example: (helper-get-current-task) ;; r0 = pointer to current task_struct
Call bpf_get_current_task helper. Get pointer to current task_struct. Returns pointer to task_struct in r0. Example: (helper-get-current-task) ;; r0 = pointer to current task_struct
(helper-get-current-task-btf)Call bpf_get_current_task_btf helper.
Get pointer to current task_struct with BTF type info.
Returns BTF pointer to task_struct in r0.
Call bpf_get_current_task_btf helper. Get pointer to current task_struct with BTF type info. Returns BTF pointer to task_struct in r0.
(helper-get-current-uid-gid)Call bpf_get_current_uid_gid helper.
Get current process UID and GID.
Returns u64 in r0 where:
Example: (helper-get-current-uid-gid) ;; r0 = (gid << 32) | uid
Call bpf_get_current_uid_gid helper. Get current process UID and GID. Returns u64 in r0 where: - Upper 32 bits = GID - Lower 32 bits = UID Example: (helper-get-current-uid-gid) ;; r0 = (gid << 32) | uid
(helper-get-numa-node-id)Call bpf_get_numa_node_id helper.
Get current NUMA node ID.
Returns NUMA node ID in r0.
Call bpf_get_numa_node_id helper. Get current NUMA node ID. Returns NUMA node ID in r0.
(helper-get-prandom-u32)Call bpf_get_prandom_u32 helper.
Get pseudo-random 32-bit number.
Returns random u32 in r0.
Example: (helper-get-prandom-u32) ;; r0 = random number
Call bpf_get_prandom_u32 helper. Get pseudo-random 32-bit number. Returns random u32 in r0. Example: (helper-get-prandom-u32) ;; r0 = random number
(helper-get-smp-processor-id)Call bpf_get_smp_processor_id helper.
Get current CPU number.
Returns CPU ID in r0.
Example: (helper-get-smp-processor-id) ;; r0 = current CPU number
Call bpf_get_smp_processor_id helper. Get current CPU number. Returns CPU ID in r0. Example: (helper-get-smp-processor-id) ;; r0 = current CPU number
(helper-get-stack ctx-reg buf-reg size-reg flags-reg)Call bpf_get_stack helper.
Get kernel or user stack trace.
Parameters:
Returns number of bytes written, or negative on error.
Example: (helper-get-stack :r1 :r2 :r3 :r4)
Call bpf_get_stack helper. Get kernel or user stack trace. Parameters: - ctx-reg: Register containing context pointer - buf-reg: Register containing buffer pointer - size-reg: Register containing buffer size - flags-reg: Register containing flags (kernel/user, skip frames, etc.) Returns number of bytes written, or negative on error. Example: (helper-get-stack :r1 :r2 :r3 :r4)
(helper-get-stackid ctx-reg map-reg flags-reg)Call bpf_get_stackid helper.
Get stack trace ID for current context.
Parameters:
Returns stack ID in r0 (>= 0), or negative on error.
Example: (helper-get-stackid :r1 :r2 :r3)
Call bpf_get_stackid helper. Get stack trace ID for current context. Parameters: - ctx-reg: Register containing context pointer - map-reg: Register containing stack trace map FD - flags-reg: Register containing flags Returns stack ID in r0 (>= 0), or negative on error. Example: (helper-get-stackid :r1 :r2 :r3)
(helper-get-task-stack task-reg buf-reg size-reg flags-reg)Call bpf_get_task_stack helper.
Get stack trace for a specific task.
Parameters:
Returns number of bytes written, or negative on error.
Call bpf_get_task_stack helper. Get stack trace for a specific task. Parameters: - task-reg: Register containing task_struct pointer - buf-reg: Register containing buffer pointer - size-reg: Register containing buffer size - flags-reg: Register containing flags Returns number of bytes written, or negative on error.
(helper-jiffies64)Call bpf_jiffies64 helper.
Get current jiffies64 value.
Returns jiffies64 value in r0.
Call bpf_jiffies64 helper. Get current jiffies64 value. Returns jiffies64 value in r0.
(helper-ktime-get-boot-ns)Call bpf_ktime_get_boot_ns helper.
Get monotonic time in nanoseconds including suspend time.
Returns nanosecond timestamp in r0.
Example: (helper-ktime-get-boot-ns) ;; r0 = timestamp including suspend
Call bpf_ktime_get_boot_ns helper. Get monotonic time in nanoseconds including suspend time. Returns nanosecond timestamp in r0. Example: (helper-ktime-get-boot-ns) ;; r0 = timestamp including suspend
(helper-ktime-get-coarse-ns)Call bpf_ktime_get_coarse_ns helper.
Get coarse-grained monotonic time (faster but less precise).
Returns nanosecond timestamp in r0.
Call bpf_ktime_get_coarse_ns helper. Get coarse-grained monotonic time (faster but less precise). Returns nanosecond timestamp in r0.
(helper-ktime-get-ns)Call bpf_ktime_get_ns helper.
Get monotonic time in nanoseconds since system boot.
Returns nanosecond timestamp in r0.
Example: (helper-ktime-get-ns) ;; r0 = timestamp in nanoseconds
Call bpf_ktime_get_ns helper. Get monotonic time in nanoseconds since system boot. Returns nanosecond timestamp in r0. Example: (helper-ktime-get-ns) ;; r0 = timestamp in nanoseconds
(helper-ktime-get-tai-ns)Call bpf_ktime_get_tai_ns helper.
Get TAI (International Atomic Time) in nanoseconds.
Returns TAI timestamp in r0.
Call bpf_ktime_get_tai_ns helper. Get TAI (International Atomic Time) in nanoseconds. Returns TAI timestamp in r0.
(helper-loop nr-loops-reg callback-fn-reg callback-ctx-reg flags-reg)Call bpf_loop helper.
Execute callback function in a bounded loop (up to nr-loops iterations).
Parameters:
Returns number of iterations completed.
Example: (helper-loop :r1 :r2 :r3 :r4)
Call bpf_loop helper. Execute callback function in a bounded loop (up to nr-loops iterations). Parameters: - nr-loops-reg: Register containing number of iterations - callback-fn-reg: Register containing callback function pointer - callback-ctx-reg: Register containing callback context pointer - flags-reg: Register containing flags Returns number of iterations completed. Example: (helper-loop :r1 :r2 :r3 :r4)
(helper-map-delete-elem map-reg key-reg)Call bpf_map_delete_elem helper.
Delete an element from a BPF map.
Parameters:
Returns 0 on success, negative error code on failure.
Example: (helper-map-delete-elem :r1 :r2) ;; r0 = 0 on success, < 0 on error
Call bpf_map_delete_elem helper. Delete an element from a BPF map. Parameters: - map-reg: Register containing map file descriptor - key-reg: Register containing pointer to key Returns 0 on success, negative error code on failure. Example: (helper-map-delete-elem :r1 :r2) ;; r0 = 0 on success, < 0 on error
(helper-map-lookup-elem map-reg key-reg)Call bpf_map_lookup_elem helper.
Look up an element in a BPF map by key.
Parameters:
Returns pointer to value in r0, or NULL if not found.
Example: (helper-map-lookup-elem :r1 :r2) ;; r0 will contain pointer to value or NULL
Call bpf_map_lookup_elem helper. Look up an element in a BPF map by key. Parameters: - map-reg: Register containing map file descriptor (or direct FD value) - key-reg: Register containing pointer to key Returns pointer to value in r0, or NULL if not found. Example: (helper-map-lookup-elem :r1 :r2) ;; r0 will contain pointer to value or NULL
(helper-map-update-elem map-reg key-reg value-reg flags-reg)Call bpf_map_update_elem helper.
Update or insert an element in a BPF map.
Parameters:
Returns 0 on success, negative error code on failure.
Example: (helper-map-update-elem :r1 :r2 :r3 :r4) ;; r0 = 0 on success, < 0 on error
Call bpf_map_update_elem helper. Update or insert an element in a BPF map. Parameters: - map-reg: Register containing map file descriptor - key-reg: Register containing pointer to key - value-reg: Register containing pointer to value - flags-reg: Register containing flags (BPF_ANY, BPF_NOEXIST, BPF_EXIST) Returns 0 on success, negative error code on failure. Example: (helper-map-update-elem :r1 :r2 :r3 :r4) ;; r0 = 0 on success, < 0 on error
(helper-perf-event-output ctx-reg map-reg flags-reg data-reg size-reg)Call bpf_perf_event_output helper.
Write data to perf event buffer.
Parameters:
Returns 0 on success, negative on error.
Example: (helper-perf-event-output :r1 :r2 :r3 :r4 :r5)
Call bpf_perf_event_output helper. Write data to perf event buffer. Parameters: - ctx-reg: Register containing context pointer - map-reg: Register containing perf event map FD - flags-reg: Register containing flags (usually CPU number) - data-reg: Register containing data pointer - size-reg: Register containing data size Returns 0 on success, negative on error. Example: (helper-perf-event-output :r1 :r2 :r3 :r4 :r5)
(helper-perf-event-read map-reg flags-reg)Call bpf_perf_event_read helper.
Read perf event counter value.
Parameters:
Returns counter value in r0.
Example: (helper-perf-event-read :r1 :r2)
Call bpf_perf_event_read helper. Read perf event counter value. Parameters: - map-reg: Register containing perf event array map FD - flags-reg: Register containing flags/index Returns counter value in r0. Example: (helper-perf-event-read :r1 :r2)
(helper-probe-read dst-reg size-reg src-reg)Call bpf_probe_read helper.
Read memory from an unsafe pointer (kernel or user).
Parameters:
Returns 0 on success, negative error code on failure.
Example: (helper-probe-read :r1 :r2 :r3) ;; Reads r2 bytes from r3 to r1
Call bpf_probe_read helper. Read memory from an unsafe pointer (kernel or user). Parameters: - dst-reg: Register containing destination buffer pointer - size-reg: Register containing size to read - src-reg: Register containing unsafe source pointer Returns 0 on success, negative error code on failure. Example: (helper-probe-read :r1 :r2 :r3) ;; Reads r2 bytes from r3 to r1
(helper-probe-read-kernel dst-reg size-reg src-reg)Call bpf_probe_read_kernel helper.
Read memory from kernel space pointer.
Parameters:
Returns 0 on success, negative error code on failure.
Example: (helper-probe-read-kernel :r1 :r2 :r3)
Call bpf_probe_read_kernel helper. Read memory from kernel space pointer. Parameters: - dst-reg: Register containing destination buffer pointer - size-reg: Register containing size to read - src-reg: Register containing kernel pointer Returns 0 on success, negative error code on failure. Example: (helper-probe-read-kernel :r1 :r2 :r3)
(helper-probe-read-kernel-str dst-reg size-reg src-reg)Call bpf_probe_read_kernel_str helper.
Read null-terminated string from kernel pointer.
Parameters:
Returns length of string (including NULL) on success, negative on error.
Call bpf_probe_read_kernel_str helper. Read null-terminated string from kernel pointer. Parameters: - dst-reg: Register containing destination buffer pointer - size-reg: Register containing max size to read - src-reg: Register containing kernel pointer Returns length of string (including NULL) on success, negative on error.
(helper-probe-read-str dst-reg size-reg src-reg)Call bpf_probe_read_str helper.
Read null-terminated string from unsafe pointer.
Parameters:
Returns length of string (including NULL) on success, negative on error.
Example: (helper-probe-read-str :r1 :r2 :r3)
Call bpf_probe_read_str helper. Read null-terminated string from unsafe pointer. Parameters: - dst-reg: Register containing destination buffer pointer - size-reg: Register containing max size to read - src-reg: Register containing unsafe source pointer Returns length of string (including NULL) on success, negative on error. Example: (helper-probe-read-str :r1 :r2 :r3)
(helper-probe-read-user dst-reg size-reg src-reg)Call bpf_probe_read_user helper.
Read memory from user space pointer.
Parameters:
Returns 0 on success, negative error code on failure.
Example: (helper-probe-read-user :r1 :r2 :r3)
Call bpf_probe_read_user helper. Read memory from user space pointer. Parameters: - dst-reg: Register containing destination buffer pointer - size-reg: Register containing size to read - src-reg: Register containing user pointer Returns 0 on success, negative error code on failure. Example: (helper-probe-read-user :r1 :r2 :r3)
(helper-probe-read-user-str dst-reg size-reg src-reg)Call bpf_probe_read_user_str helper.
Read null-terminated string from user pointer.
Parameters:
Returns length of string (including NULL) on success, negative on error.
Call bpf_probe_read_user_str helper. Read null-terminated string from user pointer. Parameters: - dst-reg: Register containing destination buffer pointer - size-reg: Register containing max size to read - src-reg: Register containing user pointer Returns length of string (including NULL) on success, negative on error.
(helper-ringbuf-discard data-reg flags-reg)Call bpf_ringbuf_discard helper.
Discard reserved ring buffer space without submitting.
Parameters:
No return value (void).
Example: (helper-ringbuf-discard :r1 :r2)
Call bpf_ringbuf_discard helper. Discard reserved ring buffer space without submitting. Parameters: - data-reg: Register containing pointer from bpf_ringbuf_reserve - flags-reg: Register containing flags No return value (void). Example: (helper-ringbuf-discard :r1 :r2)
(helper-ringbuf-output ringbuf-reg data-reg size-reg flags-reg)Call bpf_ringbuf_output helper.
Write data to ring buffer (simplified interface).
Parameters:
Returns 0 on success, negative on error.
Example: (helper-ringbuf-output :r1 :r2 :r3 :r4)
Call bpf_ringbuf_output helper. Write data to ring buffer (simplified interface). Parameters: - ringbuf-reg: Register containing ring buffer map FD - data-reg: Register containing data pointer - size-reg: Register containing data size - flags-reg: Register containing flags Returns 0 on success, negative on error. Example: (helper-ringbuf-output :r1 :r2 :r3 :r4)
(helper-ringbuf-reserve ringbuf-reg size-reg flags-reg)Call bpf_ringbuf_reserve helper.
Reserve space in ring buffer for writing.
Parameters:
Returns pointer to reserved space in r0, or NULL on failure.
Example: (helper-ringbuf-reserve :r1 :r2 :r3) ;; r0 = pointer to reserved space or NULL
Call bpf_ringbuf_reserve helper. Reserve space in ring buffer for writing. Parameters: - ringbuf-reg: Register containing ring buffer map FD - size-reg: Register containing size to reserve - flags-reg: Register containing flags Returns pointer to reserved space in r0, or NULL on failure. Example: (helper-ringbuf-reserve :r1 :r2 :r3) ;; r0 = pointer to reserved space or NULL
(helper-ringbuf-submit data-reg flags-reg)Call bpf_ringbuf_submit helper.
Submit reserved ring buffer data.
Parameters:
No return value (void).
Example: (helper-ringbuf-submit :r1 :r2)
Call bpf_ringbuf_submit helper. Submit reserved ring buffer data. Parameters: - data-reg: Register containing pointer from bpf_ringbuf_reserve - flags-reg: Register containing flags No return value (void). Example: (helper-ringbuf-submit :r1 :r2)
(helper-snprintf str-reg str-size-reg fmt-reg data-reg data-len-reg)Call bpf_snprintf helper.
Format string to buffer (printf-style).
Parameters:
Returns number of bytes written (excluding null terminator).
Example: (helper-snprintf :r1 :r2 :r3 :r4 :r5)
Call bpf_snprintf helper. Format string to buffer (printf-style). Parameters: - str-reg: Register containing destination buffer pointer - str-size-reg: Register containing buffer size - fmt-reg: Register containing format string pointer - data-reg: Register containing data pointer - data-len-reg: Register containing data length Returns number of bytes written (excluding null terminator). Example: (helper-snprintf :r1 :r2 :r3 :r4 :r5)
(helper-spin-lock lock-reg)Call bpf_spin_lock helper.
Acquire a spinlock.
Parameters:
No return value (void).
Example: (helper-spin-lock :r1)
Call bpf_spin_lock helper. Acquire a spinlock. Parameters: - lock-reg: Register containing pointer to bpf_spin_lock No return value (void). Example: (helper-spin-lock :r1)
(helper-spin-unlock lock-reg)Call bpf_spin_unlock helper.
Release a spinlock.
Parameters:
No return value (void).
Example: (helper-spin-unlock :r1)
Call bpf_spin_unlock helper. Release a spinlock. Parameters: - lock-reg: Register containing pointer to bpf_spin_lock No return value (void). Example: (helper-spin-unlock :r1)
(helper-strncmp s1-reg s1-len-reg s2-reg)Call bpf_strncmp helper.
Compare two strings.
Parameters:
Returns 0 if equal, < 0 if s1 < s2, > 0 if s1 > s2.
Example: (helper-strncmp :r1 :r2 :r3)
Call bpf_strncmp helper. Compare two strings. Parameters: - s1-reg: Register containing first string pointer - s1-len-reg: Register containing first string length - s2-reg: Register containing second string pointer Returns 0 if equal, < 0 if s1 < s2, > 0 if s1 > s2. Example: (helper-strncmp :r1 :r2 :r3)
(helper-tail-call ctx-reg prog-array-reg index-reg)Call bpf_tail_call helper.
Tail call to another BPF program. Never returns on success.
Parameters:
Never returns on success. Falls through on failure.
Example: (helper-tail-call :r1 :r2 :r3) ;; Program continues here only if tail call failed
Call bpf_tail_call helper. Tail call to another BPF program. Never returns on success. Parameters: - ctx-reg: Register containing context pointer - prog-array-reg: Register containing program array map FD - index-reg: Register containing program index Never returns on success. Falls through on failure. Example: (helper-tail-call :r1 :r2 :r3) ;; Program continues here only if tail call failed
(helper-trace-printk fmt-reg fmt-size-reg)(helper-trace-printk fmt-reg fmt-size-reg arg1-reg)(helper-trace-printk fmt-reg fmt-size-reg arg1-reg arg2-reg)(helper-trace-printk fmt-reg fmt-size-reg arg1-reg arg2-reg arg3-reg)Call bpf_trace_printk helper.
Print debug message to trace pipe (/sys/kernel/debug/tracing/trace_pipe). WARNING: Use only for debugging! Has performance overhead.
Parameters:
Returns number of bytes written, or negative on error.
Example: (helper-trace-printk :r1 :r2 :r3 :r4 :r5)
Call bpf_trace_printk helper. Print debug message to trace pipe (/sys/kernel/debug/tracing/trace_pipe). WARNING: Use only for debugging! Has performance overhead. Parameters: - fmt-reg: Register containing format string pointer - fmt-size-reg: Register containing format string size - arg1-reg: Register containing first argument (optional) - arg2-reg: Register containing second argument (optional) - arg3-reg: Register containing third argument (optional) Returns number of bytes written, or negative on error. Example: (helper-trace-printk :r1 :r2 :r3 :r4 :r5)
BPF instruction classes (3 LSB bits of opcode)
BPF instruction classes (3 LSB bits of opcode)
(ja offset)Unconditional jump.
Example: (ja label-offset) ; goto +offset
Unconditional jump. Example: (ja label-offset) ; goto +offset
(jmp offset)Unconditional jump (tutorial-compatible alias for ja). Note: offset is in instructions, not bytes.
Example: (jmp 5) ; Jump forward 5 instructions
Unconditional jump (tutorial-compatible alias for ja). Note: offset is in instructions, not bytes. Example: (jmp 5) ; Jump forward 5 instructions
(jmp-imm op dst imm offset)Jump if condition with immediate operand.
Example: (jmp-imm :jeq :r0 0 label-offset) ; if r0 == 0 goto +offset
Jump if condition with immediate operand. Example: (jmp-imm :jeq :r0 0 label-offset) ; if r0 == 0 goto +offset
Jump operation codes (bits 4-7 of opcode)
Jump operation codes (bits 4-7 of opcode)
(jmp-reg op dst src offset)Jump if condition with register operand.
Example: (jmp-reg :jeq :r0 :r1 label-offset) ; if r0 == r1 goto +offset
Jump if condition with register operand. Example: (jmp-reg :jeq :r0 :r1 label-offset) ; if r0 == r1 goto +offset
(ld-map-fd dst map-fd)Load map file descriptor into register (tutorial-compatible). Uses lddw with BPF_PSEUDO_MAP_FD source register marker.
Example: (ld-map-fd :r1 map-fd) ; r1 = map_fd (for helper calls)
Load map file descriptor into register (tutorial-compatible). Uses lddw with BPF_PSEUDO_MAP_FD source register marker. Example: (ld-map-fd :r1 map-fd) ; r1 = map_fd (for helper calls)
(lddw dst imm64)Load 64-bit immediate (wide instruction).
Example: (lddw :r0 0x123456789ABCDEF) ; r0 = 0x123456789ABCDEF
Load 64-bit immediate (wide instruction). Example: (lddw :r0 0x123456789ABCDEF) ; r0 = 0x123456789ABCDEF
(ldx size dst src offset)Load from memory into register.
Example: (ldx :dw :r0 :r1 4) ; r0 = (u64)(r1 + 4)
Load from memory into register. Example: (ldx :dw :r0 :r1 4) ; r0 = *(u64*)(r1 + 4)
(load-ctx size dst offset)Load from context pointer (alias for ldx with r1 as source). Commonly used to read fields from BPF program context.
Example: (load-ctx :dw :r2 0) ; r2 = (u64)(ctx + 0)
Load from context pointer (alias for ldx with r1 as source). Commonly used to read fields from BPF program context. Example: (load-ctx :dw :r2 0) ; r2 = *(u64*)(ctx + 0)
(load-mem size dst src offset)Load from memory into register (tutorial-compatible alias for ldx).
Example: (load-mem :dw :r0 :r1 4) ; r0 = (u64)(r1 + 4)
Load from memory into register (tutorial-compatible alias for ldx). Example: (load-mem :dw :r0 :r1 4) ; r0 = *(u64*)(r1 + 4)
Load/store mode modifiers (bits 5-7 of opcode)
Load/store mode modifiers (bits 5-7 of opcode)
Load/store size modifiers (bits 3-4 of opcode)
Load/store size modifiers (bits 3-4 of opcode)
(lsh dst imm)Left shift by immediate (64-bit).
Example: (lsh :r0 8) ; r0 <<= 8
Left shift by immediate (64-bit). Example: (lsh :r0 8) ; r0 <<= 8
(lsh-reg dst src)Left shift by register (64-bit).
Example: (lsh-reg :r0 :r1) ; r0 <<= r1
Left shift by register (64-bit). Example: (lsh-reg :r0 :r1) ; r0 <<= r1
(map-ref map-or-fd)Reference to a map for use in instructions. Returns the map-fd for use with ld-map-fd.
Example: (ld-map-fd :r1 (map-ref my-map))
Reference to a map for use in instructions. Returns the map-fd for use with ld-map-fd. Example: (ld-map-fd :r1 (map-ref my-map))
(mod dst imm)Modulo register by immediate (64-bit).
Example: (mod :r0 10) ; r0 %= 10
Modulo register by immediate (64-bit). Example: (mod :r0 10) ; r0 %= 10
(mod-reg dst src)Modulo register by register (64-bit).
Example: (mod-reg :r0 :r1) ; r0 %= r1
Modulo register by register (64-bit). Example: (mod-reg :r0 :r1) ; r0 %= r1
(mov dst imm)Move immediate to register (64-bit).
Example: (mov :r0 42) ; r0 = 42
Move immediate to register (64-bit). Example: (mov :r0 42) ; r0 = 42
(mov-reg dst src)Move register to register (64-bit).
Example: (mov-reg :r0 :r1) ; r0 = r1
Move register to register (64-bit). Example: (mov-reg :r0 :r1) ; r0 = r1
(mul dst imm)Multiply register by immediate (64-bit).
Example: (mul :r0 2) ; r0 *= 2
Multiply register by immediate (64-bit). Example: (mul :r0 2) ; r0 *= 2
(mul-reg dst src)Multiply register by register (64-bit).
Example: (mul-reg :r0 :r1) ; r0 *= r1
Multiply register by register (64-bit). Example: (mul-reg :r0 :r1) ; r0 *= r1
(neg-reg dst)Negate register (64-bit).
Example: (neg-reg :r0) ; r0 = -r0
Negate register (64-bit). Example: (neg-reg :r0) ; r0 = -r0
(or-op dst imm)Bitwise OR with immediate (64-bit).
Example: (or-op :r0 0x10) ; r0 |= 0x10
Bitwise OR with immediate (64-bit). Example: (or-op :r0 0x10) ; r0 |= 0x10
(or-reg dst src)Bitwise OR with register (64-bit).
Example: (or-reg :r0 :r1) ; r0 |= r1
Bitwise OR with register (64-bit). Example: (or-reg :r0 :r1) ; r0 |= r1
(ringbuf-output-event ringbuf-map-reg event-ptr-reg event-size)(ringbuf-output-event ringbuf-map-reg
event-ptr-reg
event-size
error-jump-offset)Generate code to output an event to ring buffer with error handling.
Combines helper call with error checking.
Parameters:
Returns instruction sequence.
Example: (ringbuf-output-event :r1 :r2 64 10) ;; Output 64 bytes from r2 to ringbuf r1 ;; Jump forward 10 instructions on error
Generate code to output an event to ring buffer with error handling. Combines helper call with error checking. Parameters: - ringbuf-map-reg: Register with ring buffer map FD - event-ptr-reg: Register with event data pointer - event-size: Size of event data (immediate or register) - error-jump-offset: Jump offset on error (optional) Returns instruction sequence. Example: (ringbuf-output-event :r1 :r2 64 10) ;; Output 64 bytes from r2 to ringbuf r1 ;; Jump forward 10 instructions on error
(rsh dst imm)Right shift (logical) by immediate (64-bit).
Example: (rsh :r0 8) ; r0 >>= 8
Right shift (logical) by immediate (64-bit). Example: (rsh :r0 8) ; r0 >>= 8
(rsh-reg dst src)Right shift (logical) by register (64-bit).
Example: (rsh-reg :r0 :r1) ; r0 >>= r1
Right shift (logical) by register (64-bit). Example: (rsh-reg :r0 :r1) ; r0 >>= r1
(safe-probe-read dst-reg size src-reg error-jump-offset)Generate safe probe read with error checking.
Reads from unsafe pointer and checks for errors.
Parameters:
Returns instruction sequence.
Example: (safe-probe-read :r1 4 :r2 10) ;; Reads 4 bytes from r2 to r1 ;; Jumps forward 10 instructions on error
Generate safe probe read with error checking. Reads from unsafe pointer and checks for errors. Parameters: - dst-reg: Destination buffer register - size: Size to read (immediate value) - src-reg: Source pointer register - error-jump-offset: Jump offset on error Returns instruction sequence. Example: (safe-probe-read :r1 4 :r2 10) ;; Reads 4 bytes from r2 to r1 ;; Jumps forward 10 instructions on error
(sample-one-in-n n skip-jump-offset)Generate code to sample 1 in N events.
Uses random number generation for probabilistic sampling.
Parameters:
Returns instruction sequence.
Example: (sample-one-in-n 100 20) ;; Drops ~99% of events, keeps ~1%
Generate code to sample 1 in N events. Uses random number generation for probabilistic sampling. Parameters: - n: Sample rate (keep 1 in N events) - skip-jump-offset: Jump offset if event should be dropped Returns instruction sequence. Example: (sample-one-in-n 100 20) ;; Drops ~99% of events, keeps ~1%
Source operand selector (bit 3 of opcode)
Source operand selector (bit 3 of opcode)
(st size dst offset imm)Store immediate to memory.
Example: (st :dw :r1 4 42) ; (u64)(r1 + 4) = 42
Store immediate to memory. Example: (st :dw :r1 4 42) ; *(u64*)(r1 + 4) = 42
(stack-allocate size ptr-reg)Generate code to allocate space on the BPF stack.
Adjusts r10 (frame pointer) to create stack space.
Parameters:
Returns instruction sequence.
Example: (stack-allocate 64 :r1) ;; r1 = pointer to 64 bytes on stack
Generate code to allocate space on the BPF stack. Adjusts r10 (frame pointer) to create stack space. Parameters: - size: Number of bytes to allocate - ptr-reg: Register to receive pointer to allocated space Returns instruction sequence. Example: (stack-allocate 64 :r1) ;; r1 = pointer to 64 bytes on stack
(store-mem size dst offset src)Store register to memory (tutorial-compatible alias). Note: Uses [size dst offset src] order for readability.
Example: (store-mem :dw :r10 -8 :r6) ; (u64)(r10 - 8) = r6
Store register to memory (tutorial-compatible alias). Note: Uses [size dst offset src] order for readability. Example: (store-mem :dw :r10 -8 :r6) ; *(u64*)(r10 - 8) = r6
(stx size dst src offset)Store register to memory.
Example: (stx :dw :r1 :r0 4) ; (u64)(r1 + 4) = r0
Store register to memory. Example: (stx :dw :r1 :r0 4) ; *(u64*)(r1 + 4) = r0
(sub dst imm)Subtract immediate from register (64-bit).
Example: (sub :r0 10) ; r0 -= 10
Subtract immediate from register (64-bit). Example: (sub :r0 10) ; r0 -= 10
(sub-reg dst src)Subtract register from register (64-bit).
Example: (sub-reg :r0 :r1) ; r0 -= r1
Subtract register from register (64-bit). Example: (sub-reg :r0 :r1) ; r0 -= r1
(time-delta start-time-reg)(time-delta start-time-reg delta-reg)Generate code to measure time delta between two points.
Uses ktime-get-ns to measure elapsed time.
Parameters:
Returns two instruction sequences:
Example: (let [[start end] (time-delta :r6 :r7)] (concat start ;; ... code to measure ... end)) ;; r6 = start time ;; r7 = end time - start time
Generate code to measure time delta between two points.
Uses ktime-get-ns to measure elapsed time.
Parameters:
- start-time-reg: Register to store start time
- delta-reg: Register to store time delta (optional, default :r0)
Returns two instruction sequences:
1. Start: Get start time
2. End: Calculate delta
Example:
(let [[start end] (time-delta :r6 :r7)]
(concat
start
;; ... code to measure ...
end))
;; r6 = start time
;; r7 = end time - start time(trace-println msg-reg msg-len)(trace-println msg-reg msg-len arg1)(trace-println msg-reg msg-len arg1 arg2)(trace-println msg-reg msg-len arg1 arg2 arg3)Generate code for simple trace printing (debug only).
Simplified interface for bpf_trace_printk with a string message.
Parameters:
Returns instruction sequence.
WARNING: Use only for debugging!
Example: (trace-println :r1 14) ; Just format string (trace-println :r1 14 :r2 :r3) ; With arguments
Generate code for simple trace printing (debug only). Simplified interface for bpf_trace_printk with a string message. Parameters: - msg-reg: Register containing format string pointer - msg-len: Length of format string - arg-regs: Optional argument registers (up to 3) Returns instruction sequence. WARNING: Use only for debugging! Example: (trace-println :r1 14) ; Just format string (trace-println :r1 14 :r2 :r3) ; With arguments
(with-map-lookup map-reg key-reg null-jump-offset)(with-map-lookup map-reg key-reg null-jump-offset result-reg)Generate map lookup with NULL check pattern.
Looks up a map element and jumps to the specified offset if NULL.
Parameters:
Returns instruction sequence. Result pointer is in result-reg.
Example: (with-map-lookup :r1 :r2 5 :r6) ;; r6 = map_lookup(r1, r2) ;; if (r6 == NULL) jump forward 5 instructions
Generate map lookup with NULL check pattern. Looks up a map element and jumps to the specified offset if NULL. Parameters: - map-reg: Register containing map FD - key-reg: Register containing key pointer - null-jump-offset: Jump offset if lookup returns NULL - result-reg: Register to store the result (default :r0) Returns instruction sequence. Result pointer is in result-reg. Example: (with-map-lookup :r1 :r2 5 :r6) ;; r6 = map_lookup(r1, r2) ;; if (r6 == NULL) jump forward 5 instructions
(with-spinlock lock-ptr-reg body-insns)Generate code to execute a critical section with spinlock protection.
Acquires lock, executes code, and releases lock.
Parameters:
Returns instruction sequence.
Example: (with-spinlock :r1 [(mov :r0 42) (exit-insn)]) ;; Acquires lock, sets r0=42, releases lock, exits
Generate code to execute a critical section with spinlock protection. Acquires lock, executes code, and releases lock. Parameters: - lock-ptr-reg: Register containing pointer to bpf_spin_lock - body-insns: Instruction sequence to execute while holding lock Returns instruction sequence. Example: (with-spinlock :r1 [(mov :r0 42) (exit-insn)]) ;; Acquires lock, sets r0=42, releases lock, exits
(xor-op dst imm)Bitwise XOR with immediate (64-bit).
Example: (xor-op :r0 0xFF) ; r0 ^= 0xFF
Bitwise XOR with immediate (64-bit). Example: (xor-op :r0 0xFF) ; r0 ^= 0xFF
(xor-reg dst src)Bitwise XOR with register (64-bit).
Example: (xor-reg :r0 :r1) ; r0 ^= r1
Bitwise XOR with register (64-bit). Example: (xor-reg :r0 :r1) ; r0 ^= r1
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |