Skip to content

Commit deb3885

Browse files
Asphalttti-mo
andcommitted
info: expose func info from ProgramInfo
`bpf_prog_info` supports func info since commit torvalds/linux@838e96904ff3 ("bpf: Introduce bpf_func_info"). Signed-off-by: Leon Hwang <[email protected]> Co-authored-by: Timo Beckers <[email protected]>
1 parent 5e7babc commit deb3885

2 files changed

Lines changed: 60 additions & 0 deletions

File tree

info.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -531,6 +531,39 @@ func (pi *ProgramInfo) KsymAddrs() ([]uintptr, bool) {
531531
return addrs, pi.numKsymInfos > 0
532532
}
533533

534+
// FuncInfos returns the offset and function information of all (sub)programs in
535+
// a BPF program.
536+
//
537+
// Available from 5.0.
538+
//
539+
// Requires CAP_SYS_ADMIN or equivalent for reading BTF information. Returns
540+
// ErrNotSupported if the program was created without BTF or if the kernel
541+
// doesn't support the field.
542+
func (pi *ProgramInfo) FuncInfos() (btf.FuncOffsets, error) {
543+
id, ok := pi.BTFID()
544+
if pi.numFuncInfos == 0 || !ok {
545+
return nil, fmt.Errorf("program created without BTF or unsupported kernel: %w", ErrNotSupported)
546+
}
547+
548+
h, err := btf.NewHandleFromID(id)
549+
if err != nil {
550+
return nil, fmt.Errorf("get BTF handle: %w", err)
551+
}
552+
defer h.Close()
553+
554+
spec, err := h.Spec(nil)
555+
if err != nil {
556+
return nil, fmt.Errorf("get BTF spec: %w", err)
557+
}
558+
559+
return btf.LoadFuncInfos(
560+
bytes.NewReader(pi.funcInfos),
561+
internal.NativeEndian,
562+
pi.numFuncInfos,
563+
spec,
564+
)
565+
}
566+
534567
func scanFdInfo(fd *sys.FD, fields map[string]interface{}) error {
535568
fh, err := os.Open(fmt.Sprintf("/proc/self/fdinfo/%d", fd.Int()))
536569
if err != nil {

info_test.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -535,3 +535,30 @@ func TestProgInfoKsym(t *testing.T) {
535535
qt.Assert(t, qt.Not(qt.Equals(addr, 0)))
536536
}
537537
}
538+
539+
func TestProgInfoFuncInfos(t *testing.T) {
540+
testutils.SkipOnOldKernel(t, "5.0", "Program func info")
541+
542+
spec, err := LoadCollectionSpec(testutils.NativeFile(t, "testdata/loader-%s.elf"))
543+
qt.Assert(t, qt.IsNil(err))
544+
545+
var obj struct {
546+
Prog *Program `ebpf:"xdp_prog"`
547+
}
548+
err = spec.LoadAndAssign(&obj, nil)
549+
testutils.SkipIfNotSupported(t, err)
550+
qt.Assert(t, qt.IsNil(err))
551+
defer obj.Prog.Close()
552+
553+
info, err := obj.Prog.Info()
554+
qt.Assert(t, qt.IsNil(err))
555+
556+
funcs, err := info.FuncInfos()
557+
qt.Assert(t, qt.IsNil(err))
558+
559+
qt.Assert(t, qt.HasLen(funcs, 5))
560+
for _, fo := range funcs {
561+
qt.Assert(t, qt.IsNotNil(fo.Func))
562+
qt.Assert(t, qt.Not(qt.Equals(fo.Func.Name, "")))
563+
}
564+
}

0 commit comments

Comments
 (0)