asm

package
Version: v0.6.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 2, 2021 License: MIT Imports: 10 Imported by: 15

Documentation

Overview

Package asm is an assembler for eBPF bytecode.

Index

Examples

Constants

View Source
const (
	PseudoMapFD    = R1 // BPF_PSEUDO_MAP_FD
	PseudoMapValue = R2 // BPF_PSEUDO_MAP_VALUE
	PseudoCall     = R1 // BPF_PSEUDO_CALL
)

Pseudo registers used by 64bit loads and jumps

View Source
const InstructionSize = 8

InstructionSize is the size of a BPF instruction in bytes

Variables

This section is empty.

Functions

func IsUnreferencedSymbol

func IsUnreferencedSymbol(err error) bool

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

Types

type ALUOp

type ALUOp uint8

ALUOp are ALU / ALU64 operations

msb      lsb
+----+-+---+
|OP  |s|cls|
+----+-+---+
const (
	// InvalidALUOp is returned by getters when invoked
	// on non ALU OpCodes
	InvalidALUOp ALUOp = 0xff
	// Add - addition
	Add ALUOp = 0x00
	// Sub - subtraction
	Sub ALUOp = 0x10
	// Mul - multiplication
	Mul ALUOp = 0x20
	// Div - division
	Div ALUOp = 0x30
	// Or - bitwise or
	Or ALUOp = 0x40
	// And - bitwise and
	And ALUOp = 0x50
	// LSh - bitwise shift left
	LSh ALUOp = 0x60
	// RSh - bitwise shift right
	RSh ALUOp = 0x70
	// Neg - sign/unsign signing bit
	Neg ALUOp = 0x80
	// Mod - modulo
	Mod ALUOp = 0x90
	// Xor - bitwise xor
	Xor ALUOp = 0xa0
	// Mov - move value from one place to another
	Mov ALUOp = 0xb0
	// ArSh - arithmatic shift
	ArSh ALUOp = 0xc0
	// Swap - endian conversions
	Swap ALUOp = 0xd0
)

func (ALUOp) Imm

func (op ALUOp) Imm(dst Register, value int32) Instruction

Imm emits `dst (op) value`.

func (ALUOp) Imm32

func (op ALUOp) Imm32(dst Register, value int32) Instruction

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

func (ALUOp) Op

func (op ALUOp) Op(source Source) OpCode

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

func (ALUOp) Op32

func (op ALUOp) Op32(source Source) OpCode

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

func (ALUOp) Reg

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

Reg emits `dst (op) src`.

func (ALUOp) Reg32

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

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

func (ALUOp) String

func (i ALUOp) String() string

type BuiltinFunc

type BuiltinFunc int32

BuiltinFunc is a built-in eBPF function.

const (
	FnUnspec BuiltinFunc = iota
	FnMapLookupElem
	FnMapUpdateElem
	FnMapDeleteElem
	FnProbeRead
	FnKtimeGetNs
	FnTracePrintk
	FnGetPrandomU32
	FnGetSmpProcessorId
	FnSkbStoreBytes
	FnL3CsumReplace
	FnL4CsumReplace
	FnTailCall
	FnCloneRedirect
	FnGetCurrentPidTgid
	FnGetCurrentUidGid
	FnGetCurrentComm
	FnGetCgroupClassid
	FnSkbVlanPush
	FnSkbVlanPop
	FnSkbGetTunnelKey
	FnSkbSetTunnelKey
	FnPerfEventRead
	FnRedirect
	FnGetRouteRealm
	FnPerfEventOutput
	FnSkbLoadBytes
	FnGetStackid
	FnCsumDiff
	FnSkbGetTunnelOpt
	FnSkbSetTunnelOpt
	FnSkbChangeProto
	FnSkbChangeType
	FnSkbUnderCgroup
	FnGetHashRecalc
	FnGetCurrentTask
	FnProbeWriteUser
	FnCurrentTaskUnderCgroup
	FnSkbChangeTail
	FnSkbPullData
	FnCsumUpdate
	FnSetHashInvalid
	FnGetNumaNodeId
	FnSkbChangeHead
	FnXdpAdjustHead
	FnProbeReadStr
	FnGetSocketCookie
	FnGetSocketUid
	FnSetHash
	FnSetsockopt
	FnSkbAdjustRoom
	FnRedirectMap
	FnSkRedirectMap
	FnSockMapUpdate
	FnXdpAdjustMeta
	FnPerfEventReadValue
	FnPerfProgReadValue
	FnGetsockopt
	FnOverrideReturn
	FnSockOpsCbFlagsSet
	FnMsgRedirectMap
	FnMsgApplyBytes
	FnMsgCorkBytes
	FnMsgPullData
	FnBind
	FnXdpAdjustTail
	FnSkbGetXfrmState
	FnGetStack
	FnSkbLoadBytesRelative
	FnFibLookup
	FnSockHashUpdate
	FnMsgRedirectHash
	FnSkRedirectHash
	FnLwtPushEncap
	FnLwtSeg6StoreBytes
	FnLwtSeg6AdjustSrh
	FnLwtSeg6Action
	FnRcRepeat
	FnRcKeydown
	FnSkbCgroupId
	FnGetCurrentCgroupId
	FnGetLocalStorage
	FnSkSelectReuseport
	FnSkbAncestorCgroupId
	FnSkLookupTcp
	FnSkLookupUdp
	FnSkRelease
	FnMapPushElem
	FnMapPopElem
	FnMapPeekElem
	FnMsgPushData
	FnMsgPopData
	FnRcPointerRel
	FnSpinLock
	FnSpinUnlock
	FnSkFullsock
	FnTcpSock
	FnSkbEcnSetCe
	FnGetListenerSock
	FnSkcLookupTcp
	FnTcpCheckSyncookie
	FnSysctlGetName
	FnSysctlGetCurrentValue
	FnSysctlGetNewValue
	FnSysctlSetNewValue
	FnStrtol
	FnStrtoul
	FnSkStorageGet
	FnSkStorageDelete
	FnSendSignal
	FnTcpGenSyncookie
	FnSkbOutput
	FnProbeReadUser
	FnProbeReadKernel
	FnProbeReadUserStr
	FnProbeReadKernelStr
	FnTcpSendAck
	FnSendSignalThread
	FnJiffies64
	FnReadBranchRecords
	FnGetNsCurrentPidTgid
	FnXdpOutput
	FnGetNetnsCookie
	FnGetCurrentAncestorCgroupId
	FnSkAssign
	FnKtimeGetBootNs
	FnSeqPrintf
	FnSeqWrite
	FnSkCgroupId
	FnSkAncestorCgroupId
	FnRingbufOutput
	FnRingbufReserve
	FnRingbufSubmit
	FnRingbufDiscard
	FnRingbufQuery
	FnCsumLevel
	FnSkcToTcp6Sock
	FnSkcToTcpSock
	FnSkcToTcpTimewaitSock
	FnSkcToTcpRequestSock
	FnSkcToUdp6Sock
	FnGetTaskStack
	FnLoadHdrOpt
	FnStoreHdrOpt
	FnReserveHdrOpt
	FnInodeStorageGet
	FnInodeStorageDelete
	FnDPath
	FnCopyFromUser
	FnSnprintfBtf
	FnSeqPrintfBtf
	FnSkbCgroupClassid
	FnRedirectNeigh
	FnPerCpuPtr
	FnThisCpuPtr
	FnRedirectPeer
	FnTaskStorageGet
	FnTaskStorageDelete
	FnGetCurrentTaskBtf
	FnBprmOptsSet
	FnKtimeGetCoarseNs
	FnImaInodeHash
	FnSockFromFile
)

eBPF built-in functions

You can regenerate this list using the following gawk script:

/FN\(.+\),/ {
  match($1, /\((.+)\)/, r)
  split(r[1], p, "_")
  printf "Fn"
  for (i in p) {
    printf "%s%s", toupper(substr(p[i], 1, 1)), substr(p[i], 2)
  }
  print ""
}

The script expects include/uapi/linux/bpf.h as it's input.

func (BuiltinFunc) Call

func (fn BuiltinFunc) Call() Instruction

Call emits a function call.

func (BuiltinFunc) String

func (i BuiltinFunc) String() string

type Class

type Class uint8

Class of operations

msb      lsb
+---+--+---+
|  ??  |CLS|
+---+--+---+
const (
	// LdClass load memory
	LdClass Class = 0x00
	// LdXClass load memory from constant
	LdXClass Class = 0x01
	// StClass load register from memory
	StClass Class = 0x02
	// StXClass load register from constant
	StXClass Class = 0x03
	// ALUClass arithmetic operators
	ALUClass Class = 0x04
	// JumpClass jump operators
	JumpClass Class = 0x05
	// ALU64Class arithmetic in 64 bit mode
	ALU64Class Class = 0x07
)

func (Class) String

func (i Class) String() string

type Endianness

type Endianness uint8

The Endianness of a byte swap instruction.

const (
	InvalidEndian Endianness = 0xff
	// Convert to little endian
	LE Endianness = 0x00
	// Convert to big endian
	BE Endianness = 0x08
)

Endian flags

func (Endianness) String

func (i Endianness) String() string

type Instruction

type Instruction struct {
	OpCode    OpCode
	Dst       Register
	Src       Register
	Offset    int16
	Constant  int64
	Reference string
	Symbol    string
}

Instruction is a single eBPF instruction.

func HostTo

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

HostTo converts from host to another endianness.

func LoadAbs

func LoadAbs(offset int32, size Size) Instruction

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

func LoadImm

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

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

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

func LoadMapPtr

func LoadMapPtr(dst Register, fd int) Instruction

LoadMapPtr stores a pointer to a map in dst.

func LoadMapValue

func LoadMapValue(dst Register, fd int, offset uint32) Instruction

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

func LoadMem

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

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

func Return

func Return() Instruction

Return emits an exit instruction.

Requires a return value in R0.

func StoreImm

func StoreImm(dst Register, offset int16, value int64, size Size) Instruction

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

func StoreMem

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

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

func StoreXAdd

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

StoreXAdd atomically adds src to *dst.

func (Instruction) Format

func (ins Instruction) Format(f fmt.State, c rune)

Format implements fmt.Formatter.

func (*Instruction) IsConstantLoad added in v0.6.0

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

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

func (*Instruction) IsFunctionCall

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 (*Instruction) IsLoadFromMap added in v0.6.0

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 (*Instruction) MapPtr added in v0.6.0

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.

func (Instruction) Marshal

func (ins Instruction) Marshal(w io.Writer, bo binary.ByteOrder) (uint64, error)

Marshal encodes a BPF instruction.

func (*Instruction) RewriteMapOffset

func (ins *Instruction) RewriteMapOffset(offset uint32) error

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

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

func (*Instruction) RewriteMapPtr

func (ins *Instruction) RewriteMapPtr(fd int) error

RewriteMapPtr changes an instruction to use a new map fd.

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

func (Instruction) Sym

func (ins Instruction) Sym(name string) Instruction

Sym creates a symbol.

func (*Instruction) Unmarshal

func (ins *Instruction) Unmarshal(r io.Reader, bo binary.ByteOrder) (uint64, error)

Unmarshal decodes a BPF instruction.

type InstructionIterator

type InstructionIterator struct {

	// The instruction in question.
	Ins *Instruction
	// The index of the instruction in the original instruction slice.
	Index int
	// The offset of the instruction in raw BPF instructions. This accounts
	// for double-wide instructions.
	Offset RawInstructionOffset
	// contains filtered or unexported fields
}

InstructionIterator iterates over a BPF program.

func (*InstructionIterator) Next

func (iter *InstructionIterator) Next() bool

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

type Instructions

type Instructions []Instruction

Instructions is an eBPF program.

func (Instructions) Format

func (insns Instructions) Format(f fmt.State, c rune)

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.

Example

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

insns := Instructions{
	FnMapLookupElem.Call().Sym("my_func"),
	LoadImm(R0, 42, DWord),
	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:
	0: Call FnMapLookupElem
	1: LdImmDW dst: r0 imm: 42
	3: Exit

Don't indent instructions:
my_func:
0: Call FnMapLookupElem
1: LdImmDW dst: r0 imm: 42
3: Exit

Indent using spaces:
my_func:
 0: Call FnMapLookupElem
 1: LdImmDW dst: r0 imm: 42
 3: Exit

Control symbol indentation:
		my_func:
	0: Call FnMapLookupElem
	1: LdImmDW dst: r0 imm: 42
	3: Exit

func (Instructions) Iterate

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.

func (Instructions) Marshal

func (insns Instructions) Marshal(w io.Writer, bo binary.ByteOrder) error

Marshal encodes a BPF program into the kernel format.

func (Instructions) ReferenceOffsets

func (insns Instructions) ReferenceOffsets() map[string][]int

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

func (Instructions) RewriteMapPtr

func (insns Instructions) RewriteMapPtr(symbol string, fd int) error

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

Returns an error if the symbol isn't used, see IsUnreferencedSymbol.

func (Instructions) String

func (insns Instructions) String() string

func (Instructions) SymbolOffsets

func (insns Instructions) SymbolOffsets() (map[string]int, error)

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

func (Instructions) Tag added in v0.4.0

func (insns Instructions) Tag(bo binary.ByteOrder) (string, error)

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.

type JumpOp

type JumpOp uint8

JumpOp affect control flow.

msb      lsb
+----+-+---+
|OP  |s|cls|
+----+-+---+
const (
	// InvalidJumpOp is returned by getters when invoked
	// on non branch OpCodes
	InvalidJumpOp JumpOp = 0xff
	// Ja jumps by offset unconditionally
	Ja JumpOp = 0x00
	// JEq jumps by offset if r == imm
	JEq JumpOp = 0x10
	// JGT jumps by offset if r > imm
	JGT JumpOp = 0x20
	// JGE jumps by offset if r >= imm
	JGE JumpOp = 0x30
	// JSet jumps by offset if r & imm
	JSet JumpOp = 0x40
	// JNE jumps by offset if r != imm
	JNE JumpOp = 0x50
	// JSGT jumps by offset if signed r > signed imm
	JSGT JumpOp = 0x60
	// JSGE jumps by offset if signed r >= signed imm
	JSGE JumpOp = 0x70
	// Call builtin or user defined function from imm
	Call JumpOp = 0x80
	// Exit ends execution, with value in r0
	Exit JumpOp = 0x90
	// JLT jumps by offset if r < imm
	JLT JumpOp = 0xa0
	// JLE jumps by offset if r <= imm
	JLE JumpOp = 0xb0
	// JSLT jumps by offset if signed r < signed imm
	JSLT JumpOp = 0xc0
	// JSLE jumps by offset if signed r <= signed imm
	JSLE JumpOp = 0xd0
)

func (JumpOp) Imm

func (op JumpOp) Imm(dst Register, value int32, label string) Instruction

Imm compares dst to value, and adjusts PC by offset if the condition is fulfilled.

func (JumpOp) Label

func (op JumpOp) Label(label string) Instruction

Label adjusts PC to the address of the label.

func (JumpOp) Op

func (op JumpOp) Op(source Source) OpCode

Op returns the OpCode for a given jump source.

func (JumpOp) Reg

func (op JumpOp) Reg(dst, src Register, label string) Instruction

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

func (JumpOp) String

func (i JumpOp) String() string

type Mode

type Mode uint8

Mode for load and store operations

msb      lsb
+---+--+---+
|MDE|sz|cls|
+---+--+---+
const (
	// InvalidMode is returned by getters when invoked
	// on non load / store OpCodes
	InvalidMode Mode = 0xff
	// ImmMode - immediate value
	ImmMode Mode = 0x00
	// AbsMode - immediate value + offset
	AbsMode Mode = 0x20
	// IndMode - indirect (imm+src)
	IndMode Mode = 0x40
	// MemMode - load from memory
	MemMode Mode = 0x60
	// XAddMode - add atomically across processors.
	XAddMode Mode = 0xc0
)

func (Mode) String

func (i Mode) String() string

type OpCode

type OpCode uint8

OpCode is a packed eBPF opcode.

Its encoding is defined by a Class value:

msb      lsb
+----+-+---+
| ???? |CLS|
+----+-+---+
const InvalidOpCode OpCode = 0xff

InvalidOpCode is returned by setters on OpCode

func LoadAbsOp

func LoadAbsOp(size Size) OpCode

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

func LoadImmOp

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

func LoadIndOp(size Size) OpCode

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

func LoadMemOp

func LoadMemOp(size Size) OpCode

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

func StoreImmOp

func StoreImmOp(size Size) OpCode

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

func StoreMemOp

func StoreMemOp(size Size) OpCode

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

func StoreXAddOp

func StoreXAddOp(size Size) OpCode

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

func (OpCode) ALUOp

func (op OpCode) ALUOp() ALUOp

ALUOp returns the ALUOp.

func (OpCode) Class

func (op OpCode) Class() Class

Class returns the class of operation.

func (OpCode) Endianness

func (op OpCode) Endianness() Endianness

Endianness returns the Endianness for a byte swap instruction.

func (OpCode) IsDWordLoad added in v0.6.0

func (op OpCode) IsDWordLoad() bool

func (OpCode) JumpOp

func (op OpCode) JumpOp() JumpOp

JumpOp returns the JumpOp.

func (OpCode) Mode

func (op OpCode) Mode() Mode

Mode returns the mode for load and store operations.

func (OpCode) SetALUOp

func (op OpCode) SetALUOp(alu ALUOp) OpCode

SetALUOp sets the ALUOp on ALU operations.

Returns InvalidOpCode if op is of the wrong class.

func (OpCode) SetJumpOp

func (op OpCode) SetJumpOp(jump JumpOp) OpCode

SetJumpOp sets the JumpOp on jump operations.

Returns InvalidOpCode if op is of the wrong class.

func (OpCode) SetMode

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 (OpCode) SetSize

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 (OpCode) SetSource

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 (OpCode) Size

func (op OpCode) Size() Size

Size returns the size for load and store operations.

func (OpCode) Source

func (op OpCode) Source() Source

Source returns the source for branch and ALU operations.

func (OpCode) String

func (op OpCode) String() string

type RawInstructionOffset

type RawInstructionOffset uint64

RawInstructionOffset is an offset in units of raw BPF instructions.

func (RawInstructionOffset) Bytes

func (rio RawInstructionOffset) Bytes() uint64

Bytes returns the offset of an instruction in bytes.

type Register

type Register uint8

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.

const R0 Register = 0

R0 contains return values.

func (Register) String

func (r Register) String() string

type Size

type Size uint8

Size of load and store operations

msb      lsb
+---+--+---+
|mde|SZ|cls|
+---+--+---+
const (
	// InvalidSize is returned by getters when invoked
	// on non load / store OpCodes
	InvalidSize Size = 0xff
	// DWord - double word; 64 bits
	DWord Size = 0x18
	// Word - word; 32 bits
	Word Size = 0x00
	// Half - half-word; 16 bits
	Half Size = 0x08
	// Byte - byte; 8 bits
	Byte Size = 0x10
)

func (Size) Sizeof

func (s Size) Sizeof() int

Sizeof returns the size in bytes.

func (Size) String

func (i Size) String() string

type Source

type Source uint8

Source of ALU / ALU64 / Branch operations

msb      lsb
+----+-+---+
|op  |S|cls|
+----+-+---+
const (
	// InvalidSource is returned by getters when invoked
	// on non ALU / branch OpCodes.
	InvalidSource Source = 0xff
	// ImmSource src is from constant
	ImmSource Source = 0x00
	// RegSource src is from register
	RegSource Source = 0x08
)

Source bitmask

func (Source) String

func (i Source) String() string

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
t or T : Toggle theme light dark auto
y or Y : Canonical URL