Skip to content

Commit 78074c5

Browse files
Asphalttti-mo
authored andcommitted
info: expose more prog jited info
Expose these prog jited info: 1. JITed machine native instructions torvalds/linux@1e2709769086 ("bpf: Add BPF_OBJ_GET_INFO_BY_FD") 2. JITed line info torvalds/linux@c454a46b5efd ("bpf: Add bpf_line_info support") 3. JITed image lengths torvalds/linux@815581c11cc2 ("bpf: get JITed image lengths of functions via syscall") Signed-off-by: Leon Hwang <hffilwlqm@gmail.com>
1 parent d7ebe64 commit 78074c5

File tree

3 files changed

+149
-24
lines changed

3 files changed

+149
-24
lines changed

info.go

+143-21
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,40 @@ type programStats struct {
179179
recursionMisses uint64
180180
}
181181

182+
// programJitedInfo holds information about JITed info of a program.
183+
type programJitedInfo struct {
184+
// ksyms holds the ksym addresses of the BPF program, including those of its
185+
// subprograms.
186+
//
187+
// Available from 4.18.
188+
ksyms []uintptr
189+
numKsyms uint32
190+
191+
// insns holds the JITed machine native instructions of the program,
192+
// including those of its subprograms.
193+
//
194+
// Available from 4.13.
195+
insns []byte
196+
numInsns uint32
197+
198+
// lineInfos holds the JITed line infos, which are kernel addresses.
199+
//
200+
// Available from 5.0.
201+
lineInfos []uint64
202+
numLineInfos uint32
203+
204+
// lineInfoRecSize is the size of a single line info record.
205+
//
206+
// Available from 5.0.
207+
lineInfoRecSize uint32
208+
209+
// funcLens holds the insns length of each function.
210+
//
211+
// Available from 4.18.
212+
funcLens []uint32
213+
numFuncLens uint32
214+
}
215+
182216
// ProgramInfo describes a program.
183217
type ProgramInfo struct {
184218
Type ProgramType
@@ -199,12 +233,12 @@ type ProgramInfo struct {
199233
jitedSize uint32
200234
verifiedInstructions uint32
201235

236+
jitedInfo programJitedInfo
237+
202238
lineInfos []byte
203239
numLineInfos uint32
204240
funcInfos []byte
205241
numFuncInfos uint32
206-
ksymInfos []uint64
207-
numKsymInfos uint32
208242
}
209243

210244
func newProgramInfoFromFd(fd *sys.FD) (*ProgramInfo, error) {
@@ -282,11 +316,37 @@ func newProgramInfoFromFd(fd *sys.FD) (*ProgramInfo, error) {
282316
makeSecondCall = true
283317
}
284318

319+
pi.jitedInfo.lineInfoRecSize = info.JitedLineInfoRecSize
320+
if info.JitedProgLen > 0 {
321+
pi.jitedInfo.numInsns = info.JitedProgLen
322+
pi.jitedInfo.insns = make([]byte, info.JitedProgLen)
323+
info2.JitedProgLen = info.JitedProgLen
324+
info2.JitedProgInsns = sys.NewSlicePointer(pi.jitedInfo.insns)
325+
makeSecondCall = true
326+
}
327+
328+
if info.NrJitedFuncLens > 0 {
329+
pi.jitedInfo.numFuncLens = info.NrJitedFuncLens
330+
pi.jitedInfo.funcLens = make([]uint32, info.NrJitedFuncLens)
331+
info2.NrJitedFuncLens = info.NrJitedFuncLens
332+
info2.JitedFuncLens = sys.NewSlicePointer(pi.jitedInfo.funcLens)
333+
makeSecondCall = true
334+
}
335+
336+
if info.NrJitedLineInfo > 0 {
337+
pi.jitedInfo.numLineInfos = info.NrJitedLineInfo
338+
pi.jitedInfo.lineInfos = make([]uint64, info.NrJitedLineInfo)
339+
info2.NrJitedLineInfo = info.NrJitedLineInfo
340+
info2.JitedLineInfo = sys.NewSlicePointer(pi.jitedInfo.lineInfos)
341+
info2.JitedLineInfoRecSize = info.JitedLineInfoRecSize
342+
makeSecondCall = true
343+
}
344+
285345
if info.NrJitedKsyms > 0 {
286-
pi.ksymInfos = make([]uint64, info.NrJitedKsyms)
287-
info2.JitedKsyms = sys.NewSlicePointer(pi.ksymInfos)
346+
pi.jitedInfo.numKsyms = info.NrJitedKsyms
347+
pi.jitedInfo.ksyms = make([]uintptr, info.NrJitedKsyms)
348+
info2.JitedKsyms = sys.NewSlicePointer(pi.jitedInfo.ksyms)
288349
info2.NrJitedKsyms = info.NrJitedKsyms
289-
pi.numKsymInfos = info.NrJitedKsyms
290350
makeSecondCall = true
291351
}
292352

@@ -380,6 +440,52 @@ func (pi *ProgramInfo) RecursionMisses() (uint64, bool) {
380440
return 0, false
381441
}
382442

443+
// btfSpec returns the BTF spec associated with the program.
444+
func (pi *ProgramInfo) btfSpec() (*btf.Spec, error) {
445+
id, ok := pi.BTFID()
446+
if !ok {
447+
return nil, fmt.Errorf("program created without BTF or unsupported kernel: %w", ErrNotSupported)
448+
}
449+
450+
h, err := btf.NewHandleFromID(id)
451+
if err != nil {
452+
return nil, fmt.Errorf("get BTF handle: %w", err)
453+
}
454+
defer h.Close()
455+
456+
spec, err := h.Spec(nil)
457+
if err != nil {
458+
return nil, fmt.Errorf("get BTF spec: %w", err)
459+
}
460+
461+
return spec, nil
462+
}
463+
464+
// LineInfos returns the BTF line information of the program.
465+
//
466+
// Available from 5.0.
467+
//
468+
// Requires CAP_SYS_ADMIN or equivalent for reading BTF information. Returns
469+
// ErrNotSupported if the program was created without BTF or if the kernel
470+
// doesn't support the field.
471+
func (pi *ProgramInfo) LineInfos() (btf.LineOffsets, error) {
472+
if len(pi.lineInfos) == 0 {
473+
return nil, fmt.Errorf("insufficient permissions or unsupported kernel: %w", ErrNotSupported)
474+
}
475+
476+
spec, err := pi.btfSpec()
477+
if err != nil {
478+
return nil, err
479+
}
480+
481+
return btf.LoadLineInfos(
482+
bytes.NewReader(pi.lineInfos),
483+
internal.NativeEndian,
484+
pi.numLineInfos,
485+
spec,
486+
)
487+
}
488+
383489
// Instructions returns the 'xlated' instruction stream of the program
384490
// after it has been verified and rewritten by the kernel. These instructions
385491
// cannot be loaded back into the kernel as-is, this is mainly used for
@@ -524,11 +630,34 @@ func (pi *ProgramInfo) VerifiedInstructions() (uint32, bool) {
524630
//
525631
// The bool return value indicates whether this optional field is available.
526632
func (pi *ProgramInfo) KsymAddrs() ([]uintptr, bool) {
527-
addrs := make([]uintptr, 0, len(pi.ksymInfos))
528-
for _, addr := range pi.ksymInfos {
529-
addrs = append(addrs, uintptr(addr))
530-
}
531-
return addrs, pi.numKsymInfos > 0
633+
return pi.jitedInfo.ksyms, len(pi.jitedInfo.ksyms) > 0
634+
}
635+
636+
// JitedInsns returns the JITed machine native instructions of the program.
637+
//
638+
// Available from 4.13.
639+
//
640+
// The bool return value indicates whether this optional field is available.
641+
func (pi *ProgramInfo) JitedInsns() ([]byte, bool) {
642+
return pi.jitedInfo.insns, len(pi.jitedInfo.insns) > 0
643+
}
644+
645+
// JitedLineInfos returns the JITed line infos of the program.
646+
//
647+
// Available from 5.0.
648+
//
649+
// The bool return value indicates whether this optional field is available.
650+
func (pi *ProgramInfo) JitedLineInfos() ([]uint64, bool) {
651+
return pi.jitedInfo.lineInfos, len(pi.jitedInfo.lineInfos) > 0
652+
}
653+
654+
// JitedFuncLens returns the insns length of each function in the JITed program.
655+
//
656+
// Available from 4.18.
657+
//
658+
// The bool return value indicates whether this optional field is available.
659+
func (pi *ProgramInfo) JitedFuncLens() ([]uint32, bool) {
660+
return pi.jitedInfo.funcLens, len(pi.jitedInfo.funcLens) > 0
532661
}
533662

534663
// FuncInfos returns the offset and function information of all (sub)programs in
@@ -540,20 +669,13 @@ func (pi *ProgramInfo) KsymAddrs() ([]uintptr, bool) {
540669
// ErrNotSupported if the program was created without BTF or if the kernel
541670
// doesn't support the field.
542671
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)
672+
if len(pi.funcInfos) == 0 {
673+
return nil, fmt.Errorf("insufficient permissions or unsupported kernel: %w", ErrNotSupported)
551674
}
552-
defer h.Close()
553675

554-
spec, err := h.Spec(nil)
676+
spec, err := pi.btfSpec()
555677
if err != nil {
556-
return nil, fmt.Errorf("get BTF spec: %w", err)
678+
return nil, err
557679
}
558680

559681
return btf.LoadFuncInfos(

internal/cmd/gentypes/main.go

+3
Original file line numberDiff line numberDiff line change
@@ -197,10 +197,13 @@ import (
197197
"ProgInfo", "bpf_prog_info",
198198
[]patch{
199199
replace(objName, "name"),
200+
replace(pointer, "jited_prog_insns"),
200201
replace(pointer, "xlated_prog_insns"),
201202
replace(pointer, "map_ids"),
202203
replace(pointer, "line_info"),
204+
replace(pointer, "jited_line_info"),
203205
replace(pointer, "jited_ksyms"),
206+
replace(pointer, "jited_func_lens"),
204207
replace(pointer, "func_info"),
205208
replace(btfID, "btf_id", "attach_btf_obj_id"),
206209
replace(typeID, "attach_btf_id"),

internal/sys/types.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -720,7 +720,7 @@ type ProgInfo struct {
720720
Tag [8]uint8
721721
JitedProgLen uint32
722722
XlatedProgLen uint32
723-
JitedProgInsns uint64
723+
JitedProgInsns Pointer
724724
XlatedProgInsns Pointer
725725
LoadTime uint64
726726
CreatedByUid uint32
@@ -734,14 +734,14 @@ type ProgInfo struct {
734734
NrJitedKsyms uint32
735735
NrJitedFuncLens uint32
736736
JitedKsyms Pointer
737-
JitedFuncLens uint64
737+
JitedFuncLens Pointer
738738
BtfId BTFID
739739
FuncInfoRecSize uint32
740740
FuncInfo Pointer
741741
NrFuncInfo uint32
742742
NrLineInfo uint32
743743
LineInfo Pointer
744-
JitedLineInfo uint64
744+
JitedLineInfo Pointer
745745
NrJitedLineInfo uint32
746746
LineInfoRecSize uint32
747747
JitedLineInfoRecSize uint32

0 commit comments

Comments
 (0)