52 lines
1.3 KiB
Go
52 lines
1.3 KiB
Go
package btf
|
|
|
|
import (
|
|
"bytes"
|
|
|
|
"github.com/cilium/ebpf/internal"
|
|
"github.com/cilium/ebpf/internal/sys"
|
|
"github.com/cilium/ebpf/internal/unix"
|
|
)
|
|
|
|
// info describes a BTF object.
|
|
type info struct {
|
|
BTF *Spec
|
|
ID ID
|
|
// Name is an identifying name for the BTF, currently only used by the
|
|
// kernel.
|
|
Name string
|
|
// KernelBTF is true if the BTf originated with the kernel and not
|
|
// userspace.
|
|
KernelBTF bool
|
|
}
|
|
|
|
func newInfoFromFd(fd *sys.FD) (*info, error) {
|
|
// We invoke the syscall once with a empty BTF and name buffers to get size
|
|
// information to allocate buffers. Then we invoke it a second time with
|
|
// buffers to receive the data.
|
|
var btfInfo sys.BtfInfo
|
|
if err := sys.ObjInfo(fd, &btfInfo); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
btfBuffer := make([]byte, btfInfo.BtfSize)
|
|
nameBuffer := make([]byte, btfInfo.NameLen)
|
|
btfInfo.Btf, btfInfo.BtfSize = sys.NewSlicePointerLen(btfBuffer)
|
|
btfInfo.Name, btfInfo.NameLen = sys.NewSlicePointerLen(nameBuffer)
|
|
if err := sys.ObjInfo(fd, &btfInfo); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
spec, err := loadRawSpec(bytes.NewReader(btfBuffer), internal.NativeEndian, nil, nil)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &info{
|
|
BTF: spec,
|
|
ID: ID(btfInfo.Id),
|
|
Name: unix.ByteSliceToString(nameBuffer),
|
|
KernelBTF: btfInfo.KernelBtf != 0,
|
|
}, nil
|
|
}
|