asm package - github.com/cilium/ebpf/asm - Go Packages (original) (raw)

Package asm is an assembler for eBPF bytecode.

Built-in functions (Linux).

Built-in functions (Windows).

View Source

const ( PseudoMapFD = R1 PseudoMapValue = R2 PseudoCall = R1 PseudoFunc = R4 PseudoKfuncCall = R2 )

Pseudo registers used by 64bit loads and jumps

InstructionSize is the size of a BPF instruction in bytes

IsUnreferencedSymbol returns true if err was caused by an unreferenced symbol.

Deprecated: use errors.Is(err, asm.ErrUnreferencedSymbol).

ALUOp are ALU / ALU64 operations

msb lsb +-------+----+-+---+ | EXT | OP |s|cls| +-------+----+-+---+

const (

InvalidALUOp [ALUOp](#ALUOp) = 0xffff

Add [ALUOp](#ALUOp) = 0x0000

Sub [ALUOp](#ALUOp) = 0x0010

Mul [ALUOp](#ALUOp) = 0x0020

Div [ALUOp](#ALUOp) = 0x0030

SDiv [ALUOp](#ALUOp) = [Div](#Div) + 0x0100

Or [ALUOp](#ALUOp) = 0x0040

And [ALUOp](#ALUOp) = 0x0050

LSh [ALUOp](#ALUOp) = 0x0060

RSh [ALUOp](#ALUOp) = 0x0070

Neg [ALUOp](#ALUOp) = 0x0080

Mod [ALUOp](#ALUOp) = 0x0090

SMod [ALUOp](#ALUOp) = [Mod](#Mod) + 0x0100

Xor [ALUOp](#ALUOp) = 0x00a0

Mov [ALUOp](#ALUOp) = 0x00b0

MovSX8 [ALUOp](#ALUOp) = [Mov](#Mov) + 0x0100

MovSX16 [ALUOp](#ALUOp) = [Mov](#Mov) + 0x0200

MovSX32 [ALUOp](#ALUOp) = [Mov](#Mov) + 0x0300

ArSh [ALUOp](#ALUOp) = 0x00c0

Swap [ALUOp](#ALUOp) = 0x00d0

)

Imm emits `dst (op) value`.

Imm32 emits `dst (op) value`, zeroing the upper 32 bit of dst.

func (op ALUOp) Op(source Source) OpCode

Op returns the OpCode for an ALU operation with a given source.

func (op ALUOp) Op32(source Source) OpCode

Op32 returns the OpCode for a 32-bit ALU operation with a given source.

func (op ALUOp) Reg(dst, src Register) Instruction

Reg emits `dst (op) src`.

func (op ALUOp) Reg32(dst, src Register) Instruction

Reg32 emits `dst (op) src`, zeroing the upper 32 bit of dst.

const ( InvalidAtomic AtomicOp = 0xffff_ffff

AddAtomic [AtomicOp](#AtomicOp) = [AtomicOp](#AtomicOp)([Add](#Add)) << 8

FetchAdd [AtomicOp](#AtomicOp) = [AddAtomic](#AddAtomic) | fetch

AndAtomic [AtomicOp](#AtomicOp) = [AtomicOp](#AtomicOp)([And](#And)) << 8

FetchAnd [AtomicOp](#AtomicOp) = [AndAtomic](#AndAtomic) | fetch

OrAtomic [AtomicOp](#AtomicOp) = [AtomicOp](#AtomicOp)([Or](#Or)) << 8

FetchOr [AtomicOp](#AtomicOp) = [OrAtomic](#OrAtomic) | fetch

XorAtomic [AtomicOp](#AtomicOp) = [AtomicOp](#AtomicOp)([Xor](#Xor)) << 8

FetchXor [AtomicOp](#AtomicOp) = [XorAtomic](#XorAtomic) | fetch


Xchg [AtomicOp](#AtomicOp) = 0x0000_e000 | fetch


CmpXchg [AtomicOp](#AtomicOp) = 0x0000_f000 | fetch

)

func (op AtomicOp) Mem(dst, src Register, size Size, offset int16) Instruction

Mem emits `*(size *)(dst + offset) (op) src`.

func (op AtomicOp) OpCode(size Size) OpCode

BuiltinFunc is a built-in eBPF function.

BuiltinFuncForPlatform returns a platform specific function constant.

Use this if the library doesn't provide a constant yet.

func (fn BuiltinFunc) Call() Instruction

Call emits a function call.

Class of operations

msb lsb +---+--+---+ | ?? |CLS| +---+--+---+

const (

LdClass [Class](#Class) = 0x00

LdXClass [Class](#Class) = 0x01

StClass [Class](#Class) = 0x02

StXClass [Class](#Class) = 0x03

ALUClass [Class](#Class) = 0x04

JumpClass [Class](#Class) = 0x05


Jump32Class [Class](#Class) = 0x06

ALU64Class [Class](#Class) = 0x07

)

func (cls Class) IsALU() bool

IsALU checks if this is either ALUClass or ALU64Class.

func (cls Class) IsJump() bool

IsJump checks if this is either JumpClass or Jump32Class.

func (cls Class) IsLoad() bool

IsLoad checks if this is either LdClass or LdXClass.

func (cls Class) IsStore() bool

IsStore checks if this is either StClass or StXClass.

A Comment can be passed to Instruction.WithSource to add a comment to an instruction.

The Endianness of a byte swap instruction.

const ( InvalidEndian Endianness = 0xff

LE [Endianness](#Endianness) = 0x00

BE [Endianness](#Endianness) = 0x08

)

Endian flags

type FDer interface { FD() int }

FDer represents a resource tied to an underlying file descriptor. Used as a stand-in for e.g. ebpf.Map since that type cannot be imported here and FD() is the only method we rely on.

type Instruction struct { OpCode OpCode Dst Register Src Register Offset int16 Constant int64

Metadata [Metadata](#Metadata)

}

Instruction is a single eBPF instruction.

func BSwap(dst Register, size Size) Instruction

BSwap unconditionally reverses the order of bytes in a register.

func HostTo(endian Endianness, dst Register, size Size) Instruction

HostTo converts from host to another endianness.

func LoadAbs(offset int32, size Size) Instruction

LoadAbs emits `r0 = ntoh(*(size *)(((sk_buff *)R6)->data + offset))`.

func LoadAcquire(dst, src Register, size Size, offset int16) Instruction

Emits `lock-acquire dst = *(size *)(src + offset)`.

func LoadImm(dst Register, value int64, size Size) Instruction

LoadImm emits `dst = (size)value`.

As of kernel 4.20, only DWord size is accepted.

func LoadInd(dst, src Register, offset int32, size Size) Instruction

LoadInd emits `dst = ntoh(*(size *)(((sk_buff *)R6)->data + src + offset))`.

func LoadMapPtr(dst Register, fd int) Instruction

LoadMapPtr stores a pointer to a map in dst.

LoadMapValue stores a pointer to the value at a certain offset of a map.

func LoadMem(dst, src Register, offset int16, size Size) Instruction

LoadMem emits `dst = *(size *)(src + offset)`.

func LoadMemSX(dst, src Register, offset int16, size Size) Instruction

LoadMemSX emits `dst = *(size *)(src + offset)` but sign extends dst.

LongJump returns a jump always instruction with a range of [-2^31, 2^31 - 1].

func Return() Instruction

Return emits an exit instruction.

Requires a return value in R0.

StoreImm emits `*(size *)(dst + offset) = value`.

func StoreMem(dst Register, offset int16, src Register, size Size) Instruction

StoreMem emits `*(size *)(dst + offset) = src`

func StoreRelease(dst, src Register, size Size, offset int16) Instruction

Emits `lock-release *(size *)(dst + offset) = src`.

func StoreXAdd(dst, src Register, size Size) Instruction

StoreXAdd atomically adds src to *dst.

func (ins *Instruction) AssociateMap(m FDer) error

AssociateMap associates a Map with this Instruction.

Implicitly clears the Instruction's Reference field.

Returns an error if the Instruction is not a map load.

Format implements fmt.Formatter.

func (ins *Instruction) IsBuiltinCall() bool

IsBuiltinCall returns true if the instruction is a built-in call, i.e. BPF helper call.

func (ins *Instruction) IsConstantLoad(size Size) bool

IsConstantLoad returns true if the instruction loads a constant of the given size.

func (ins *Instruction) IsFunctionCall() bool

IsFunctionCall returns true if the instruction calls another BPF function.

This is not the same thing as a BPF helper call.

func (ins *Instruction) IsFunctionReference() bool

IsFunctionReference returns true if the instruction references another BPF function, either by invoking a Call jump operation or by loading a function pointer.

func (ins *Instruction) IsKfuncCall() bool

IsKfuncCall returns true if the instruction calls a kfunc.

This is not the same thing as a BPF helper call.

func (ins *Instruction) IsLoadFromMap() bool

IsLoadFromMap returns true if the instruction loads from a map.

This covers both loading the map pointer and direct map value loads.

func (ins *Instruction) IsLoadOfFunctionPointer() bool

IsLoadOfFunctionPointer returns true if the instruction loads a function pointer.

func (ins Instruction) Map() FDer

Map returns the Map referenced by ins, if any. An Instruction will contain a Map if e.g. it references an existing, pinned map that was opened during ELF loading.

func (ins *Instruction) MapPtr() int

MapPtr returns the map fd for this instruction.

The result is undefined if the instruction is not a load from a map, see IsLoadFromMap.

Deprecated: use Map() instead.

Marshal encodes a BPF instruction.

Reference returns the Symbol or map name referenced by ins, if any.

RewriteMapOffset changes the offset of a direct load from a map.

Returns an error if the instruction is not a direct load.

RewriteMapPtr changes an instruction to use a new map fd.

Returns an error if the instruction doesn't load a map.

Deprecated: use AssociateMap instead. If you cannot provide a Map, wrap an fd in a type implementing FDer.

Size returns the amount of bytes ins would occupy in binary form.

Source returns source information about the Instruction. The field is present when the compiler emits BTF line info about the Instruction and usually contains the line of source code responsible for it.

Sym creates a symbol.

Deprecated: use WithSymbol instead.

Symbol returns the value ins has been marked with using WithSymbol, otherwise returns an empty string. A symbol is often an Instruction at the start of a function body.

Unmarshal decodes a BPF instruction.

func (ins Instruction) WithMetadata(meta Metadata) Instruction

WithMetadata sets the given Metadata on the Instruction. e.g. to copy Metadata from another Instruction when replacing it.

WithReference makes ins reference another Symbol or map by name.

WithSource adds source information about the Instruction.

WithSymbol marks the Instruction as a Symbol, which other Instructions can point to using corresponding calls to WithReference.

type InstructionIterator struct {

Ins *[Instruction](#Instruction)

Index [int](/builtin#int)


Offset [RawInstructionOffset](#RawInstructionOffset)

}

InstructionIterator iterates over a BPF program.

Next returns true as long as there are any instructions remaining.

type Instructions []Instruction

Instructions is an eBPF program.

AppendInstructions decodes Instruction from r and appends them to insns.

AssociateMap updates all Instructions that Reference the given symbol to point to an existing Map m instead.

Returns ErrUnreferencedSymbol error if no references to symbol are found in insns. If symbol is anything else than the symbol name of map (e.g. a bpf2bpf subprogram), an error is returned.

Format implements fmt.Formatter.

You can control indentation of symbols by specifying a width. Setting a precision controls the indentation of instructions. The default character is a tab, which can be overridden by specifying the ' ' space flag.

You can use format flags to change the way an eBPF program is stringified.

insns := Instructions{ FnMapLookupElem.Call().WithSymbol("my_func").WithSource(Comment("bpf_map_lookup_elem()")), LoadImm(R0, 42, DWord).WithSource(Comment("abc = 42")), Return(), }

fmt.Println("Default format:") fmt.Printf("%v\n", insns)

fmt.Println("Don't indent instructions:") fmt.Printf("%.0v\n", insns)

fmt.Println("Indent using spaces:") fmt.Printf("% v\n", insns)

fmt.Println("Control symbol indentation:") fmt.Printf("%2v\n", insns)

Output:

Default format: my_func: ; bpf_map_lookup_elem() 0: Call FnMapLookupElem ; abc = 42 1: LdImmDW dst: r0 imm: 42 3: Exit

Don't indent instructions: my_func: ; bpf_map_lookup_elem() 0: Call FnMapLookupElem ; abc = 42 1: LdImmDW dst: r0 imm: 42 3: Exit

Indent using spaces: my_func: ; bpf_map_lookup_elem() 0: Call FnMapLookupElem ; abc = 42 1: LdImmDW dst: r0 imm: 42 3: Exit

Control symbol indentation: my_func: ; bpf_map_lookup_elem() 0: Call FnMapLookupElem ; abc = 42 1: LdImmDW dst: r0 imm: 42 3: Exit

func (insns Instructions) FunctionReferences() []string

FunctionReferences returns a set of symbol names these Instructions make bpf-to-bpf calls to.

func (insns Instructions) Iterate() *InstructionIterator

Iterate allows iterating a BPF program while keeping track of various offsets.

Modifying the instruction slice will lead to undefined behaviour.

Marshal encodes a BPF program into the kernel format.

insns may be modified if there are unresolved jumps or bpf2bpf calls.

Returns ErrUnsatisfiedProgramReference if there is a Reference Instruction without a matching Symbol Instruction within insns.

Name returns the name of the function insns belongs to, if any.

ReferenceOffsets returns the set of references and their offset in the instructions.

RewriteMapPtr rewrites all loads of a specific map pointer to a new fd.

Returns ErrUnreferencedSymbol if the symbol isn't used.

Deprecated: use AssociateMap instead.

Size returns the amount of bytes insns would occupy in binary form.

SymbolOffsets returns the set of symbols and their offset in the instructions.

Tag calculates the kernel tag for a series of instructions.

It mirrors bpf_prog_calc_tag in the kernel and so can be compared to ProgramInfo.Tag to figure out whether a loaded program matches certain instructions.

JumpOp affect control flow.

msb lsb +----+-+---+ |OP |s|cls| +----+-+---+

const (

InvalidJumpOp [JumpOp](#JumpOp) = 0xff

Ja [JumpOp](#JumpOp) = 0x00

JEq [JumpOp](#JumpOp) = 0x10

JGT [JumpOp](#JumpOp) = 0x20

JGE [JumpOp](#JumpOp) = 0x30

JSet [JumpOp](#JumpOp) = 0x40

JNE [JumpOp](#JumpOp) = 0x50

JSGT [JumpOp](#JumpOp) = 0x60

JSGE [JumpOp](#JumpOp) = 0x70

Call [JumpOp](#JumpOp) = 0x80

Exit [JumpOp](#JumpOp) = 0x90

JLT [JumpOp](#JumpOp) = 0xa0

JLE [JumpOp](#JumpOp) = 0xb0

JSLT [JumpOp](#JumpOp) = 0xc0

JSLE [JumpOp](#JumpOp) = 0xd0

)

Imm compares 64 bit dst to 64 bit value (sign extended), and adjusts PC by offset if the condition is fulfilled.

Imm32 compares 32 bit dst to 32 bit value, and adjusts PC by offset if the condition is fulfilled. Requires kernel 5.1.

Label adjusts PC to the address of the label.

func (op JumpOp) Op(source Source) OpCode

Op returns the OpCode for a given jump source.

Reg compares 64 bit dst to 64 bit src, and adjusts PC by offset if the condition is fulfilled.

Reg32 compares 32 bit dst to 32 bit src, and adjusts PC by offset if the condition is fulfilled. Requires kernel 5.1.

Metadata contains metadata about an instruction.

func (m *Metadata) Get(key interface{}) interface{}

Get the value of a key.

Returns nil if no value with the given key is present.

func (m *Metadata) Set(key, value interface{})

Set a key to a value.

If value is nil, the key is removed. Avoids modifying old metadata by copying if necessary.

Mode for load and store operations

msb lsb +---+--+---+ |MDE|sz|cls| +---+--+---+

const (

InvalidMode [Mode](#Mode) = 0xff

ImmMode [Mode](#Mode) = 0x00

AbsMode [Mode](#Mode) = 0x20

IndMode [Mode](#Mode) = 0x40

MemMode [Mode](#Mode) = 0x60

MemSXMode [Mode](#Mode) = 0x80

AtomicMode [Mode](#Mode) = 0xc0

)

OpCode represents a single operation. It is not a 1:1 mapping to real eBPF opcodes.

The encoding varies based on a 3-bit Class:

7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 ??? | CLS

For ALUClass and ALUCLass32:

7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 0 | OPC |S| CLS

For LdClass, LdXclass, StClass and StXClass:

7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 0 | MDE |SIZ| CLS

For StXClass where MDE == AtomicMode:

7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 0 | ATOMIC OP | MDE |SIZ| CLS

For JumpClass, Jump32Class:

7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 0 | OPC |S| CLS

const InvalidOpCode OpCode = 0xffff

InvalidOpCode is returned by setters on OpCode

func LoadAbsOp(size Size) OpCode

LoadAbsOp returns the OpCode for loading a value of given size from an sk_buff.

func LoadImmOp(size Size) OpCode

LoadImmOp returns the OpCode to load an immediate of given size.

As of kernel 4.20, only DWord size is accepted.

func LoadIndOp(size Size) OpCode

LoadIndOp returns the OpCode for loading a value of given size from an sk_buff.

func LoadMemOp(size Size) OpCode

LoadMemOp returns the OpCode to load a value of given size from memory.

func LoadMemSXOp(size Size) OpCode

LoadMemSXOp returns the OpCode to load a value of given size from memory sign extended.

func StoreImmOp(size Size) OpCode

StoreImmOp returns the OpCode for storing an immediate of given size in memory.

func StoreMemOp(size Size) OpCode

StoreMemOp returns the OpCode for storing a register of given size in memory.

func StoreXAddOp(size Size) OpCode

StoreXAddOp returns the OpCode to atomically add a register to a value in memory.

func (op OpCode) ALUOp() ALUOp

ALUOp returns the ALUOp.

func (op OpCode) AtomicOp() AtomicOp

AtomicOp returns the type of atomic operation.

func (op OpCode) Class() Class

Class returns the class of operation.

func (op OpCode) Endianness() Endianness

Endianness returns the Endianness for a byte swap instruction.

func (op OpCode) IsDWordLoad() bool

func (op OpCode) JumpOp() JumpOp

JumpOp returns the JumpOp. Returns InvalidJumpOp if it doesn't encode a jump.

func (op OpCode) Mode() Mode

Mode returns the mode for load and store operations.

func (op OpCode) SetALUOp(alu ALUOp) OpCode

SetALUOp sets the ALUOp on ALU operations.

Returns InvalidOpCode if op is of the wrong class.

func (op OpCode) SetAtomicOp(atomic AtomicOp) OpCode

func (op OpCode) SetJumpOp(jump JumpOp) OpCode

SetJumpOp sets the JumpOp on jump operations.

Returns InvalidOpCode if op is of the wrong class.

func (op OpCode) SetMode(mode Mode) OpCode

SetMode sets the mode on load and store operations.

Returns InvalidOpCode if op is of the wrong class.

func (op OpCode) SetSize(size Size) OpCode

SetSize sets the size on load and store operations.

Returns InvalidOpCode if op is of the wrong class.

func (op OpCode) SetSource(source Source) OpCode

SetSource sets the source on jump and ALU operations.

Returns InvalidOpCode if op is of the wrong class.

func (op OpCode) Size() Size

Size returns the size for load and store operations.

func (op OpCode) Source() Source

Source returns the source for branch and ALU operations.

type RawInstructionOffset uint64

RawInstructionOffset is an offset in units of raw BPF instructions.

Bytes returns the offset of an instruction in bytes.

Register is the source or destination of most operations.

const ( R1 Register = R0 + 1 + iota R2 R3 R4 R5 )

Registers for function arguments.

const ( R6 Register = R5 + 1 + iota R7 R8 R9 )

Callee saved registers preserved by function calls.

const ( R10 Register = R9 + 1 RFP = R10 )

Read-only frame pointer to access stack.

R0 contains return values.

Size of load and store operations

msb lsb +---+--+---+ |mde|SZ|cls| +---+--+---+

const (

InvalidSize [Size](#Size) = 0xff

DWord [Size](#Size) = 0x18

Word [Size](#Size) = 0x00

Half [Size](#Size) = 0x08

Byte [Size](#Size) = 0x10

)

func (s Size) Sizeof() int

Sizeof returns the size in bytes.

Source of ALU / ALU64 / Branch operations

msb lsb +------------+-+---+ | op |S|cls| +------------+-+---+

const (

InvalidSource [Source](#Source) = 0xffff

ImmSource [Source](#Source) = 0x0000

RegSource [Source](#Source) = 0x0008

)

Source bitmask