Skip to content

Commit

Permalink
info: expose func info from ProgramInfo
Browse files Browse the repository at this point in the history
`bpf_prog_info` supports func info since commit
torvalds/linux@838e969.

Signed-off-by: Leon Hwang <hffilwlqm@gmail.com>
  • Loading branch information
Asphaltt committed Oct 4, 2024
1 parent c6be547 commit 03e5d62
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 0 deletions.
18 changes: 18 additions & 0 deletions info.go
Original file line number Diff line number Diff line change
Expand Up @@ -528,6 +528,24 @@ func (pi *ProgramInfo) KsymAddrs() ([]uint64, bool) {
return pi.ksymInfos, pi.numKsymInfos > 0
}

type ProgramFunctionInfo = sys.FuncInfo

// FuncInfos returns the function information of bpf programs, including
// subprograms, of current bpf program.
//
// Available from 5.0.
//
// The bool return value indicates whether this optional field is available.
func (pi *ProgramInfo) FuncInfos() ([]ProgramFunctionInfo, bool) {
if pi.numFuncInfos == 0 {
return nil, false
}

ptr := (*ProgramFunctionInfo)(unsafe.Pointer(&pi.funcInfos[0]))
funcs := unsafe.Slice(ptr, int(pi.numFuncInfos))
return funcs, true
}

func scanFdInfo(fd *sys.FD, fields map[string]interface{}) error {
fh, err := os.Open(fmt.Sprintf("/proc/self/fdinfo/%d", fd.Int()))
if err != nil {
Expand Down
77 changes: 77 additions & 0 deletions info_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -546,3 +546,80 @@ func TestProgInfoKsym(t *testing.T) {
}
}
}

func TestProgInfoFuncInfo(t *testing.T) {
testutils.SkipOnOldKernel(t, "5.0", "Program func info")

spec, err := LoadCollectionSpec(testutils.NativeFile(t, "testdata/loader-%s.elf"))
if err != nil {
t.Fatal(err)
}

var obj struct {
Main *Program `ebpf:"xdp_prog"`
}

err = spec.LoadAndAssign(&obj, nil)
testutils.SkipIfNotSupported(t, err)
if err != nil {
t.Fatal(err)
}
defer obj.Main.Close()

info, err := obj.Main.Info()
if err != nil {
t.Fatal(err)
}

funcs, ok := info.FuncInfos()
if !ok {
t.Fatalf("expected function info to be available")
}

expectedNumFuncInfos := uint32(5)
if info.numFuncInfos != expectedNumFuncInfos {
t.Fatalf("expected %d ksym infos, got %d", expectedNumFuncInfos, info.numFuncInfos)
}

handle, err := obj.Main.Handle()
if err != nil {
t.Fatalf("failed to get program handle: %v", err)
}
defer handle.Close()

btfSpec, err := handle.Spec(nil)
if err != nil {
t.Errorf("failed to get BTF spec: %v", err)
return
}

expectedFuncInfo := map[string]bool{
"xdp_prog": false,
"static_fn": false,
"global_fn": false,
"global_fn2": false,
"global_fn3": false,
}

for _, funcInfo := range funcs {
btfInfo, err := btfSpec.TypeByID(sys.TypeID(funcInfo.TypeId))
if err != nil {
t.Errorf("failed to get BTF type info: %v", err)
return
}

funcBtfInfo, ok := btfInfo.(*btf.Func)
if !ok {
t.Errorf("expected BTF type to be a function, got %T", btfInfo)
return
}

expectedFuncInfo[funcBtfInfo.Name] = true
}

for fn, found := range expectedFuncInfo {
if !found {
t.Errorf("func %q not found", fn)
}
}
}

0 comments on commit 03e5d62

Please sign in to comment.