...
1 package btf
2
3 import (
4 "errors"
5 "fmt"
6 "os"
7
8 "github.com/cilium/ebpf/internal/sys"
9 "github.com/cilium/ebpf/internal/unix"
10 )
11
12
13 type HandleInfo struct {
14
15
16 ID ID
17
18
19
20 Name string
21
22
23
24 IsKernel bool
25
26
27 size uint32
28 }
29
30 func newHandleInfoFromFD(fd *sys.FD) (*HandleInfo, error) {
31
32
33
34 var btfInfo sys.BtfInfo
35 if err := sys.ObjInfo(fd, &btfInfo); err != nil {
36 return nil, fmt.Errorf("get BTF info for fd %s: %w", fd, err)
37 }
38
39 if btfInfo.NameLen > 0 {
40
41 btfInfo.NameLen++
42 }
43
44
45 btfSize := btfInfo.BtfSize
46 btfInfo.BtfSize = 0
47
48 nameBuffer := make([]byte, btfInfo.NameLen)
49 btfInfo.Name, btfInfo.NameLen = sys.NewSlicePointerLen(nameBuffer)
50 if err := sys.ObjInfo(fd, &btfInfo); err != nil {
51 return nil, err
52 }
53
54 return &HandleInfo{
55 ID: ID(btfInfo.Id),
56 Name: unix.ByteSliceToString(nameBuffer),
57 IsKernel: btfInfo.KernelBtf != 0,
58 size: btfSize,
59 }, nil
60 }
61
62
63 func (i *HandleInfo) IsVmlinux() bool {
64 return i.IsKernel && i.Name == "vmlinux"
65 }
66
67
68 func (i *HandleInfo) IsModule() bool {
69 return i.IsKernel && i.Name != "vmlinux"
70 }
71
72
73 type HandleIterator struct {
74
75 ID ID
76 err error
77 }
78
79
80
81
82
83
84
85 func (it *HandleIterator) Next(handle **Handle) bool {
86 if *handle != nil {
87 (*handle).Close()
88 *handle = nil
89 }
90
91 id := it.ID
92 for {
93 attr := &sys.BtfGetNextIdAttr{Id: id}
94 err := sys.BtfGetNextId(attr)
95 if errors.Is(err, os.ErrNotExist) {
96
97 return false
98 } else if err != nil {
99 it.err = fmt.Errorf("get next BTF ID: %w", err)
100 return false
101 }
102
103 id = attr.NextId
104 *handle, err = NewHandleFromID(id)
105 if errors.Is(err, os.ErrNotExist) {
106
107 continue
108 } else if err != nil {
109 it.err = fmt.Errorf("retrieve handle for ID %d: %w", id, err)
110 return false
111 }
112
113 it.ID = id
114 return true
115 }
116 }
117
118
119 func (it *HandleIterator) Err() error {
120 return it.err
121 }
122
View as plain text