-
Notifications
You must be signed in to change notification settings - Fork 717
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
btf: fix NewHandleFromID for kernel modules
Kernel modules only expose split BTF when queried via BPF_OBJ_GET_INFO_BY_FD. NewHandleFromID therefore doesn't work when trying to obtain a handle for a kernel module BTF. At the same time, always parsing BTF when creating a handle from an ID is slow and wasteful. Change Handle.Spec to accept a base Spec to support split BTF from modules. This is a breaking change. Updates #705
- Loading branch information
Showing
5 changed files
with
143 additions
and
35 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,56 +1,65 @@ | ||
package btf | ||
|
||
import ( | ||
"bytes" | ||
"fmt" | ||
|
||
"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 | ||
// Info describes a Handle. | ||
type Info struct { | ||
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 | ||
|
||
// KernelBTF is true if the BTF originated with the kernel and not | ||
// userspace. | ||
KernelBTF bool | ||
|
||
// Size of the raw BTF in bytes. | ||
size uint32 | ||
} | ||
|
||
func newInfoFromFd(fd *sys.FD) (*info, error) { | ||
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 | ||
return nil, fmt.Errorf("get BTF info for fd %s: %w", fd, err) | ||
} | ||
|
||
if btfInfo.NameLen > 0 { | ||
// NameLen doesn't account for the terminating NUL. | ||
btfInfo.NameLen++ | ||
} | ||
|
||
btfBuffer := make([]byte, btfInfo.BtfSize) | ||
// Don't pull raw BTF by default, since it may be quite large. | ||
btfSize := btfInfo.BtfSize | ||
btfInfo.BtfSize = 0 | ||
|
||
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, | ||
return &Info{ | ||
ID: btfInfo.Id, | ||
Name: unix.ByteSliceToString(nameBuffer), | ||
KernelBTF: btfInfo.KernelBtf != 0, | ||
size: btfSize, | ||
}, nil | ||
} | ||
|
||
// IsModule returns true if the BTF is for the kernel itself. | ||
func (i *Info) IsVmlinux() bool { | ||
return i.KernelBTF && i.Name == "vmlinux" | ||
} | ||
|
||
// IsModule returns true if the BTF is for a kernel module. | ||
func (i *Info) IsModule() bool { | ||
return i.KernelBTF && i.Name != "vmlinux" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters