btf

package
v0.0.0-...-a55c778 Latest Latest
Warning

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

Go to latest
Published: Jul 6, 2024 License: MIT Imports: 23 Imported by: 1

Documentation

Overview

Package btf handles data encoded according to the BPF Type Format.

The canonical documentation lives in the Linux kernel repository and is available at https://www.kernel.org/doc/html/latest/bpf/btf.html

Index

Examples

Constants

View Source
const COREBadRelocationSentinel = 0xbad2310

A constant used when CO-RE relocation has to remove instructions.

Taken from libbpf.

Variables

View Source
var (
	ErrNotSupported    = internal.ErrNotSupported
	ErrNotFound        = errors.New("not found")
	ErrNoExtendedInfo  = errors.New("no extended info")
	ErrMultipleMatches = errors.New("multiple matching types")
)

Errors returned by BTF functions.

View Source
var FuncInfoSize = uint32(binary.Size(bpfFuncInfo{}))

The size of a FuncInfo in BTF wire format.

View Source
var LineInfoSize = uint32(binary.Size(bpfLineInfo{}))

Functions

func As

func As[T Type](typ Type) (T, bool)

As returns typ if is of type T. Otherwise it peels qualifiers and Typedefs until it finds a T.

Returns the zero value and false if there is no T or if the type is nested too deeply.

Example

As can be used to strip qualifiers from a Type.

a := &Volatile{Type: &Pointer{Target: &Typedef{Name: "foo", Type: &Int{Size: 2}}}}
fmt.Println(As[*Pointer](a))
Output:

Pointer[target=Typedef:"foo"] true

func AssignMetadataToInstructions

func AssignMetadataToInstructions(
	insns asm.Instructions,
	funcInfos FuncInfos,
	lineInfos LineInfos,
	reloInfos CORERelocationInfos,
)

Assign per-instruction metadata to the instructions in insns.

func CheckTypeCompatibility

func CheckTypeCompatibility(localType Type, targetType Type) error

CheckTypeCompatibility checks local and target types for Compatibility according to CO-RE rules.

Only layout compatibility is checked, ignoring names of the root type.

func FlushKernelSpec

func FlushKernelSpec()

FlushKernelSpec removes any cached kernel type information.

func LoadSpecAndExtInfosFromReader

func LoadSpecAndExtInfosFromReader(rd io.ReaderAt) (*Spec, *ExtInfos, error)

LoadSpecAndExtInfosFromReader reads from an ELF.

ExtInfos may be nil if the ELF doesn't contain section metadata. Returns ErrNotFound if the ELF contains no BTF.

func MarshalExtInfos

func MarshalExtInfos(insns asm.Instructions, b *Builder) (funcInfos, lineInfos []byte, _ error)

MarshalExtInfos encodes function and line info embedded in insns into kernel wire format.

If an instruction has an asm.Comment, it will be synthesized into a mostly empty line info.

func MarshalMapKV

func MarshalMapKV(key, value Type) (_ *Handle, keyID, valueID TypeID, err error)

MarshalMapKV creates a BTF object containing a map key and value.

The function is intended for the use of the gbpf package and may be removed at any point in time.

func Sizeof

func Sizeof(typ Type) (int, error)

Sizeof returns the size of a type in bytes.

Returns an error if the size can't be computed.

func WithFuncMetadata

func WithFuncMetadata(ins asm.Instruction, fn *Func) asm.Instruction

WithFuncMetadata adds a btf.Func to the Metadata of asm.Instruction.

Types

type Array

type Array struct {
	Index  Type
	Type   Type
	Nelems uint32
}

Array is an array with a fixed number of elements.

func (*Array) Format

func (arr *Array) Format(fs fmt.State, verb rune)

func (*Array) TypeName

func (arr *Array) TypeName() string

type Bits

type Bits uint32

A value in bits.

func (Bits) Bytes

func (b Bits) Bytes() uint32

Bytes converts a bit value into bytes.

type Builder

type Builder struct {
	// contains filtered or unexported fields
}

Builder turns Types into raw BTF.

The default value may be used and represents an empty BTF blob. Void is added implicitly if necessary.

func NewBuilder

func NewBuilder(types []Type) (*Builder, error)

NewBuilder creates a Builder from a list of types.

It is more efficient than calling [Add] individually.

Returns an error if adding any of the types fails.

func (*Builder) Add

func (b *Builder) Add(typ Type) (TypeID, error)

Add a Type and allocate a stable ID for it.

Adding the identical Type multiple times is valid and will return the same ID.

See Type for details on identity.

func (*Builder) Empty

func (b *Builder) Empty() bool

Empty returns true if neither types nor strings have been added.

func (*Builder) Marshal

func (b *Builder) Marshal(buf []byte, opts *MarshalOptions) ([]byte, error)

Marshal encodes all types in the Marshaler into BTF wire format.

opts may be nil.

type COREFixup

type COREFixup struct {
	// contains filtered or unexported fields
}

COREFixup is the result of computing a CO-RE relocation for a target.

func CORERelocate

func CORERelocate(relos []*CORERelocation, targets []*Spec, bo binary.ByteOrder, resolveLocalTypeID func(Type) (TypeID, error)) ([]COREFixup, error)

CORERelocate calculates changes needed to adjust gBPF instructions for differences in types.

targets forms the set of types to relocate against. The first element has to be BTF for vmlinux, the following must be types for kernel modules.

resolveLocalTypeID is called for each local type which requires a stable TypeID. Calling the function with the same type multiple times must produce the same result. It is the callers responsibility to ensure that the relocated instructions are loaded with matching BTF.

Returns a list of fixups which can be applied to instructions to make them match the target type(s).

Fixups are returned in the order of relos, e.g. fixup[i] is the solution for relos[i].

func (*COREFixup) Apply

func (f *COREFixup) Apply(ins *asm.Instruction) error

func (*COREFixup) String

func (f *COREFixup) String() string

type CORERelocation

type CORERelocation struct {
	// contains filtered or unexported fields
}

func CORERelocationMetadata

func CORERelocationMetadata(ins *asm.Instruction) *CORERelocation

func (*CORERelocation) String

func (cr *CORERelocation) String() string

type CORERelocationInfos

type CORERelocationInfos struct {
	// contains filtered or unexported fields
}

CORERelocationInfos contains a sorted list of co:re relocation infos.

type Const

type Const struct {
	Type Type
}

Const is a qualifier.

func (*Const) Format

func (c *Const) Format(fs fmt.State, verb rune)

func (*Const) TypeName

func (c *Const) TypeName() string

type Datasec

type Datasec struct {
	Name string
	Size uint32
	Vars []VarSecinfo
}

Datasec is a global program section containing data.

func (*Datasec) Format

func (ds *Datasec) Format(fs fmt.State, verb rune)

func (*Datasec) TypeName

func (ds *Datasec) TypeName() string

type Enum

type Enum struct {
	Name string
	// Size of the enum value in bytes.
	Size uint32
	// True if the values should be interpreted as signed integers.
	Signed bool
	Values []EnumValue
}

Enum lists possible values.

func (*Enum) Format

func (e *Enum) Format(fs fmt.State, verb rune)

func (*Enum) TypeName

func (e *Enum) TypeName() string

type EnumValue

type EnumValue struct {
	Name  string
	Value uint64
}

EnumValue is part of an Enum

Is is not a valid Type

type ExtInfos

type ExtInfos struct {
	// contains filtered or unexported fields
}

ExtInfos contains ELF section metadata.

func (*ExtInfos) Assign

func (ei *ExtInfos) Assign(insns asm.Instructions, section string)

Assign per-section metadata from BTF to a section's instructions.

type Float

type Float struct {
	Name string

	// The size of the float in bytes.
	Size uint32
}

Float is a float of a given length.

func (*Float) Format

func (f *Float) Format(fs fmt.State, verb rune)

func (*Float) TypeName

func (f *Float) TypeName() string

type Func

type Func struct {
	Name    string
	Type    Type
	Linkage FuncLinkage
}

Func is a function definition.

func FuncMetadata

func FuncMetadata(ins *asm.Instruction) *Func

func (*Func) Format

func (f *Func) Format(fs fmt.State, verb rune)

func (*Func) TypeName

func (f *Func) TypeName() string

type FuncInfos

type FuncInfos struct {
	// contains filtered or unexported fields
}

FuncInfos contains a sorted list of func infos.

func LoadFuncInfos

func LoadFuncInfos(reader io.Reader, bo binary.ByteOrder, recordNum uint32, spec *Spec) (FuncInfos, error)

LoadFuncInfos parses BTF func info in kernel wire format.

type FuncLinkage

type FuncLinkage int

FuncLinkage describes BTF function linkage metadata.

const (
	StaticFunc FuncLinkage = iota // static
	GlobalFunc                    // global
	ExternFunc                    // extern
)

Equivalent of enum btf_func_linkage.

func (FuncLinkage) String

func (i FuncLinkage) String() string

type FuncParam

type FuncParam struct {
	Name string
	Type Type
}

type FuncProto

type FuncProto struct {
	Return Type
	Params []FuncParam
}

FuncProto is a function declaration.

func (*FuncProto) Format

func (fp *FuncProto) Format(fs fmt.State, verb rune)

func (*FuncProto) TypeName

func (fp *FuncProto) TypeName() string

type Fwd

type Fwd struct {
	Name string
	Kind FwdKind
}

Fwd is a forward declaration of a Type.

func (*Fwd) Format

func (f *Fwd) Format(fs fmt.State, verb rune)

func (*Fwd) TypeName

func (f *Fwd) TypeName() string

type FwdKind

type FwdKind int

FwdKind is the type of forward declaration.

const (
	FwdStruct FwdKind = iota
	FwdUnion
)

Valid types of forward declaration.

func (FwdKind) String

func (fk FwdKind) String() string

type GoFormatter

type GoFormatter struct {

	// Types present in this map are referred to using the given name if they
	// are encountered when outputting another type.
	Names map[Type]string

	// Identifier is called for each field of struct-like types. By default the
	// field name is used as is.
	Identifier func(string) string

	// EnumIdentifier is called for each element of an enum. By default the
	// name of the enum type is concatenated with Identifier(element).
	EnumIdentifier func(name, element string) string
	// contains filtered or unexported fields
}

GoFormatter converts a Type to Go syntax.

A zero GoFormatter is valid to use.

func (*GoFormatter) TypeDeclaration

func (gf *GoFormatter) TypeDeclaration(name string, typ Type) (string, error)

TypeDeclaration generates a Go type declaration for a BTF type.

type Handle

type Handle struct {
	// contains filtered or unexported fields
}

Handle is a reference to BTF loaded into the kernel.

func FindHandle

func FindHandle(predicate func(info *HandleInfo) bool) (*Handle, error)

FindHandle returns the first handle for which predicate returns true.

Requires CAP_SYS_ADMIN.

Returns an error wrapping ErrNotFound if predicate never returns true or if there is no BTF loaded into the kernel.

func NewHandle

func NewHandle(b *Builder) (*Handle, error)

NewHandle loads the contents of a Builder into the kernel.

Returns an error wrapping ErrNotSupported if the kernel doesn't support BTF.

func NewHandleFromID

func NewHandleFromID(id ID) (*Handle, error)

NewHandleFromID returns the BTF handle for a given id.

Prefer calling [gbpf.Program.Handle] or [gbpf.Map.Handle] if possible.

Returns ErrNotExist, if there is no BTF with the given id.

Requires CAP_SYS_ADMIN.

func NewHandleFromRawBTF

func NewHandleFromRawBTF(btf []byte) (*Handle, error)

NewHandleFromRawBTF loads raw BTF into the kernel.

Returns an error wrapping ErrNotSupported if the kernel doesn't support BTF.

func (*Handle) Close

func (h *Handle) Close() error

Close destroys the handle.

Subsequent calls to FD will return an invalid value.

func (*Handle) FD

func (h *Handle) FD() int

FD returns the file descriptor for the handle.

func (*Handle) Info

func (h *Handle) Info() (*HandleInfo, error)

Info returns metadata about the handle.

func (*Handle) Spec

func (h *Handle) Spec(base *Spec) (*Spec, error)

Spec parses the kernel BTF into Go types.

base must contain type information for vmlinux if the handle is for a kernel module. It may be nil otherwise.

type HandleInfo

type HandleInfo struct {
	// ID of this handle in the kernel. The ID is only valid as long as the
	// associated handle is kept alive.
	ID ID

	// Name is an identifying name for the BTF, currently only used by the
	// kernel.
	Name string

	// IsKernel is true if the BTF originated with the kernel and not
	// userspace.
	IsKernel bool
	// contains filtered or unexported fields
}

HandleInfo describes a Handle.

func (*HandleInfo) IsModule

func (i *HandleInfo) IsModule() bool

IsModule returns true if the BTF is for a kernel module.

func (*HandleInfo) IsVmlinux

func (i *HandleInfo) IsVmlinux() bool

IsVmlinux returns true if the BTF is for the kernel itself.

type HandleIterator

type HandleIterator struct {
	// The ID of the current handle. Only valid after a call to Next.
	ID ID
	// The current Handle. Only valid until a call to Next.
	// See Take if you want to retain the handle.
	Handle *Handle
	// contains filtered or unexported fields
}

HandleIterator allows enumerating BTF blobs loaded into the kernel.

Example
package main

import (
	"fmt"

	"github.com/khulnasoft/gbpf/btf"
)

func main() {
	it := new(btf.HandleIterator)
	defer it.Handle.Close()

	for it.Next() {
		info, err := it.Handle.Info()
		if err != nil {
			panic(err)
		}

		fmt.Printf("Found handle with ID %d and name %s\n", it.ID, info.Name)
	}
	if err := it.Err(); err != nil {
		panic(err)
	}
}
Output:

func (*HandleIterator) Err

func (it *HandleIterator) Err() error

Err returns an error if iteration failed for some reason.

func (*HandleIterator) Next

func (it *HandleIterator) Next() bool

Next retrieves a handle for the next BTF object.

Returns true if another BTF object was found. Call HandleIterator.Err after the function returns false.

func (*HandleIterator) Take

func (it *HandleIterator) Take() *Handle

Take the ownership of the current handle.

It's the callers responsibility to close the handle.

type ID

type ID = sys.BTFID

ID represents the unique ID of a BTF object.

type Int

type Int struct {
	Name string

	// The size of the integer in bytes.
	Size     uint32
	Encoding IntEncoding
}

Int is an integer of a given length.

See https://www.kernel.org/doc/html/latest/bpf/btf.html#btf-kind-int

func (*Int) Format

func (i *Int) Format(fs fmt.State, verb rune)

func (*Int) TypeName

func (i *Int) TypeName() string

type IntEncoding

type IntEncoding byte
const (
	Unsigned IntEncoding = 0
	Signed   IntEncoding = 1
	Char     IntEncoding = 2
	Bool     IntEncoding = 4
)

Valid IntEncodings.

These may look like they are flags, but they aren't.

func (IntEncoding) String

func (ie IntEncoding) String() string

type Line

type Line struct {
	// contains filtered or unexported fields
}

Line represents the location and contents of a single line of source code a BPF ELF was compiled from.

func (*Line) FileName

func (li *Line) FileName() string

func (*Line) Line

func (li *Line) Line() string

func (*Line) LineColumn

func (li *Line) LineColumn() uint32

func (*Line) LineNumber

func (li *Line) LineNumber() uint32

func (*Line) String

func (li *Line) String() string

type LineInfos

type LineInfos struct {
	// contains filtered or unexported fields
}

LineInfos contains a sorted list of line infos.

func LoadLineInfos

func LoadLineInfos(reader io.Reader, bo binary.ByteOrder, recordNum uint32, spec *Spec) (LineInfos, error)

LoadLineInfos parses BTF line info in kernel wire format.

type MarshalOptions

type MarshalOptions struct {
	// Target byte order. Defaults to the system's native endianness.
	Order binary.ByteOrder
	// Remove function linkage information for compatibility with <5.6 kernels.
	StripFuncLinkage bool
	// Replace Enum64 with a placeholder for compatibility with <6.0 kernels.
	ReplaceEnum64 bool
	// Prevent the "No type found" error when loading BTF without any types.
	PreventNoTypeFound bool
}

func KernelMarshalOptions

func KernelMarshalOptions() *MarshalOptions

KernelMarshalOptions will generate BTF suitable for the current kernel.

type Member

type Member struct {
	Name         string
	Type         Type
	Offset       Bits
	BitfieldSize Bits
}

Member is part of a Struct or Union.

It is not a valid Type.

type Pointer

type Pointer struct {
	Target Type
}

Pointer is a pointer to another type.

func (*Pointer) Format

func (p *Pointer) Format(fs fmt.State, verb rune)

func (*Pointer) TypeName

func (p *Pointer) TypeName() string

type Restrict

type Restrict struct {
	Type Type
}

Restrict is a qualifier.

func (*Restrict) Format

func (r *Restrict) Format(fs fmt.State, verb rune)

func (*Restrict) TypeName

func (r *Restrict) TypeName() string

type Spec

type Spec struct {
	// contains filtered or unexported fields
}

Spec allows querying a set of Types and loading the set into the kernel.

func LoadKernelModuleSpec

func LoadKernelModuleSpec(module string) (*Spec, error)

LoadKernelModuleSpec returns the BTF information for the named kernel module.

Defaults to /sys/kernel/btf/<module>. Returns an error wrapping ErrNotSupported if BTF is not enabled. Returns an error wrapping fs.ErrNotExist if BTF for the specific module doesn't exist.

func LoadKernelSpec

func LoadKernelSpec() (*Spec, error)

LoadKernelSpec returns the current kernel's BTF information.

Defaults to /sys/kernel/btf/vmlinux and falls back to scanning the file system for vmlinux ELFs. Returns an error wrapping ErrNotSupported if BTF is not enabled.

func LoadSpec

func LoadSpec(file string) (*Spec, error)

LoadSpec opens file and calls LoadSpecFromReader on it.

func LoadSpecFromReader

func LoadSpecFromReader(rd io.ReaderAt) (*Spec, error)

LoadSpecFromReader reads from an ELF or a raw BTF blob.

Returns ErrNotFound if reading from an ELF which contains no BTF. ExtInfos may be nil.

func LoadSplitSpecFromReader

func LoadSplitSpecFromReader(r io.ReaderAt, base *Spec) (*Spec, error)

LoadSplitSpecFromReader loads split BTF from a reader.

Types from base are used to resolve references in the split BTF. The returned Spec only contains types from the split BTF, not from the base.

func (*Spec) AnyTypeByName

func (s *Spec) AnyTypeByName(name string) (Type, error)

AnyTypeByName returns a Type with the given name.

Returns an error if multiple types of that name exist.

func (*Spec) AnyTypesByName

func (s *Spec) AnyTypesByName(name string) ([]Type, error)

AnyTypesByName returns a list of BTF Types with the given name.

If the BTF blob describes multiple compilation units like vmlinux, multiple Types with the same name and kind can exist, but might not describe the same data structure.

Returns an error wrapping ErrNotFound if no matching Type exists in the Spec.

func (*Spec) Copy

func (s *Spec) Copy() *Spec

Copy creates a copy of Spec.

func (*Spec) Iterate

func (s *Spec) Iterate() *TypesIterator

Iterate returns the types iterator.

func (*Spec) TypeByID

func (s *Spec) TypeByID(id TypeID) (Type, error)

TypeByID returns the BTF Type with the given type ID.

Returns an error wrapping ErrNotFound if a Type with the given ID does not exist in the Spec.

func (*Spec) TypeByName

func (s *Spec) TypeByName(name string, typ interface{}) error

TypeByName searches for a Type with a specific name. Since multiple Types with the same name can exist, the parameter typ is taken to narrow down the search in case of a clash.

typ must be a non-nil pointer to an implementation of a Type. On success, the address of the found Type will be copied to typ.

Returns an error wrapping ErrNotFound if no matching Type exists in the Spec. Returns an error wrapping ErrMultipleTypes if multiple candidates are found.

Example
// Acquire a Spec via one of its constructors.
spec := new(Spec)

// Declare a variable of the desired type
var foo *Struct

if err := spec.TypeByName("foo", &foo); err != nil {
	// There is no struct with name foo, or there
	// are multiple possibilities.
}

// We've found struct foo
fmt.Println(foo.Name)
Output:

func (*Spec) TypeID

func (s *Spec) TypeID(typ Type) (TypeID, error)

TypeID returns the ID for a given Type.

Returns an error wrapping ErrNotFound if the type isn't part of the Spec.

type Struct

type Struct struct {
	Name string
	// The size of the struct including padding, in bytes
	Size    uint32
	Members []Member
}

Struct is a compound type of consecutive members.

func (*Struct) Format

func (s *Struct) Format(fs fmt.State, verb rune)

func (*Struct) TypeName

func (s *Struct) TypeName() string

type Type

type Type interface {
	// Type can be formatted using the %s and %v verbs. %s outputs only the
	// identity of the type, without any detail. %v outputs additional detail.
	//
	// Use the '+' flag to include the address of the type.
	//
	// Use the width to specify how many levels of detail to output, for example
	// %1v will output detail for the root type and a short description of its
	// children. %2v would output details of the root type and its children
	// as well as a short description of the grandchildren.
	fmt.Formatter

	// Name of the type, empty for anonymous types and types that cannot
	// carry a name, like Void and Pointer.
	TypeName() string
	// contains filtered or unexported methods
}

Type represents a type described by BTF.

Identity of Type follows the Go specification: two Types are considered equal if they have the same concrete type and the same dynamic value, aka they point at the same location in memory. This means that the following Types are considered distinct even though they have the same "shape".

a := &Int{Size: 1}
b := &Int{Size: 1}
a != b
Example (ValidTypes)

The following are valid Types.

There currently is no better way to document which types implement an interface.

var _ Type = &Void{}
var _ Type = &Int{}
var _ Type = &Pointer{}
var _ Type = &Array{}
var _ Type = &Struct{}
var _ Type = &Union{}
var _ Type = &Enum{}
var _ Type = &Fwd{}
var _ Type = &Typedef{}
var _ Type = &Volatile{}
var _ Type = &Const{}
var _ Type = &Restrict{}
var _ Type = &Func{}
var _ Type = &FuncProto{}
var _ Type = &Var{}
var _ Type = &Datasec{}
var _ Type = &Float{}
Output:

func Copy

func Copy(typ Type) Type

Copy a Type recursively.

typ may form a cycle.

func UnderlyingType

func UnderlyingType(typ Type) Type

UnderlyingType skips qualifiers and Typedefs.

type TypeID

type TypeID = sys.TypeID

TypeID identifies a type in a BTF section.

type Typedef

type Typedef struct {
	Name string
	Type Type
}

Typedef is an alias of a Type.

func (*Typedef) Format

func (td *Typedef) Format(fs fmt.State, verb rune)

func (*Typedef) TypeName

func (td *Typedef) TypeName() string

type TypesIterator

type TypesIterator struct {

	// The last visited type in the spec.
	Type Type
	// contains filtered or unexported fields
}

TypesIterator iterates over types of a given spec.

func (*TypesIterator) Next

func (iter *TypesIterator) Next() bool

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

type Union

type Union struct {
	Name string
	// The size of the union including padding, in bytes.
	Size    uint32
	Members []Member
}

Union is a compound type where members occupy the same memory.

func (*Union) Format

func (u *Union) Format(fs fmt.State, verb rune)

func (*Union) TypeName

func (u *Union) TypeName() string

type Var

type Var struct {
	Name    string
	Type    Type
	Linkage VarLinkage
}

Var is a global variable.

func (*Var) Format

func (v *Var) Format(fs fmt.State, verb rune)

func (*Var) TypeName

func (v *Var) TypeName() string

type VarLinkage

type VarLinkage int

VarLinkage describes BTF variable linkage metadata.

const (
	StaticVar VarLinkage = iota // static
	GlobalVar                   // global
	ExternVar                   // extern
)

func (VarLinkage) String

func (i VarLinkage) String() string

type VarSecinfo

type VarSecinfo struct {
	// Var or Func.
	Type   Type
	Offset uint32
	Size   uint32
}

VarSecinfo describes variable in a Datasec.

It is not a valid Type.

type Void

type Void struct{}

Void is the unit type of BTF.

func (*Void) Format

func (v *Void) Format(fs fmt.State, verb rune)

func (*Void) TypeName

func (v *Void) TypeName() string

type Volatile

type Volatile struct {
	Type Type
}

Volatile is a qualifier.

func (*Volatile) Format

func (v *Volatile) Format(fs fmt.State, verb rune)

func (*Volatile) TypeName

func (v *Volatile) TypeName() string

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL