diff --git a/btf/feature.go b/btf/feature.go index e71c707fe..5b427f5d3 100644 --- a/btf/feature.go +++ b/btf/feature.go @@ -146,7 +146,7 @@ func probeBTF(typ Type) error { } fd, err := sys.BtfLoad(&sys.BtfLoadAttr{ - Btf: sys.NewSlicePointer(buf), + Btf: sys.SlicePointer(buf), BtfSize: uint32(len(buf)), }) diff --git a/btf/handle.go b/btf/handle.go index adfa6fed4..1b4d6b34e 100644 --- a/btf/handle.go +++ b/btf/handle.go @@ -48,7 +48,7 @@ func NewHandleFromRawBTF(btf []byte) (*Handle, error) { } attr := &sys.BtfLoadAttr{ - Btf: sys.NewSlicePointer(btf), + Btf: sys.SlicePointer(btf), BtfSize: uint32(len(btf)), } @@ -91,7 +91,7 @@ func NewHandleFromRawBTF(btf []byte) (*Handle, error) { logBuf = make([]byte, logSize) attr.BtfLogSize = logSize - attr.BtfLogBuf = sys.NewSlicePointer(logBuf) + attr.BtfLogBuf = sys.SlicePointer(logBuf) attr.BtfLogLevel = 1 } @@ -133,7 +133,8 @@ func NewHandleFromID(id ID) (*Handle, error) { func (h *Handle) Spec(base *Spec) (*Spec, error) { var btfInfo sys.BtfInfo btfBuffer := make([]byte, h.size) - btfInfo.Btf, btfInfo.BtfSize = sys.NewSlicePointerLen(btfBuffer) + btfInfo.Btf = sys.SlicePointer(btfBuffer) + btfInfo.BtfSize = uint32(len(btfBuffer)) if err := sys.ObjInfo(h.fd, &btfInfo); err != nil { return nil, err @@ -204,7 +205,8 @@ func newHandleInfoFromFD(fd *sys.FD) (*HandleInfo, error) { btfInfo.BtfSize = 0 nameBuffer := make([]byte, btfInfo.NameLen) - btfInfo.Name, btfInfo.NameLen = sys.NewSlicePointerLen(nameBuffer) + btfInfo.Name = sys.SlicePointer(nameBuffer) + btfInfo.NameLen = uint32(len(nameBuffer)) if err := sys.ObjInfo(fd, &btfInfo); err != nil { return nil, err } diff --git a/info.go b/info.go index 676e8fa6e..c5f47e195 100644 --- a/info.go +++ b/info.go @@ -275,7 +275,7 @@ func newProgramInfoFromFd(fd *sys.FD) (*ProgramInfo, error) { if info.NrMapIds > 0 { pi.maps = make([]MapID, info.NrMapIds) info2.NrMapIds = info.NrMapIds - info2.MapIds = sys.NewSlicePointer(pi.maps) + info2.MapIds = sys.SlicePointer(pi.maps) makeSecondCall = true } else if haveProgramInfoMapIDs() == nil { // This program really has no associated maps. @@ -294,13 +294,13 @@ func newProgramInfoFromFd(fd *sys.FD) (*ProgramInfo, error) { if info.XlatedProgLen > 0 { pi.insns = make([]byte, info.XlatedProgLen) info2.XlatedProgLen = info.XlatedProgLen - info2.XlatedProgInsns = sys.NewSlicePointer(pi.insns) + info2.XlatedProgInsns = sys.SlicePointer(pi.insns) makeSecondCall = true } if info.NrLineInfo > 0 { pi.lineInfos = make([]byte, btf.LineInfoSize*info.NrLineInfo) - info2.LineInfo = sys.NewSlicePointer(pi.lineInfos) + info2.LineInfo = sys.SlicePointer(pi.lineInfos) info2.LineInfoRecSize = btf.LineInfoSize info2.NrLineInfo = info.NrLineInfo pi.numLineInfos = info.NrLineInfo @@ -309,7 +309,7 @@ func newProgramInfoFromFd(fd *sys.FD) (*ProgramInfo, error) { if info.NrFuncInfo > 0 { pi.funcInfos = make([]byte, btf.FuncInfoSize*info.NrFuncInfo) - info2.FuncInfo = sys.NewSlicePointer(pi.funcInfos) + info2.FuncInfo = sys.SlicePointer(pi.funcInfos) info2.FuncInfoRecSize = btf.FuncInfoSize info2.NrFuncInfo = info.NrFuncInfo pi.numFuncInfos = info.NrFuncInfo @@ -321,7 +321,7 @@ func newProgramInfoFromFd(fd *sys.FD) (*ProgramInfo, error) { pi.jitedInfo.numInsns = info.JitedProgLen pi.jitedInfo.insns = make([]byte, info.JitedProgLen) info2.JitedProgLen = info.JitedProgLen - info2.JitedProgInsns = sys.NewSlicePointer(pi.jitedInfo.insns) + info2.JitedProgInsns = sys.SlicePointer(pi.jitedInfo.insns) makeSecondCall = true } @@ -329,7 +329,7 @@ func newProgramInfoFromFd(fd *sys.FD) (*ProgramInfo, error) { pi.jitedInfo.numFuncLens = info.NrJitedFuncLens pi.jitedInfo.funcLens = make([]uint32, info.NrJitedFuncLens) info2.NrJitedFuncLens = info.NrJitedFuncLens - info2.JitedFuncLens = sys.NewSlicePointer(pi.jitedInfo.funcLens) + info2.JitedFuncLens = sys.SlicePointer(pi.jitedInfo.funcLens) makeSecondCall = true } @@ -337,7 +337,7 @@ func newProgramInfoFromFd(fd *sys.FD) (*ProgramInfo, error) { pi.jitedInfo.numLineInfos = info.NrJitedLineInfo pi.jitedInfo.lineInfos = make([]uint64, info.NrJitedLineInfo) info2.NrJitedLineInfo = info.NrJitedLineInfo - info2.JitedLineInfo = sys.NewSlicePointer(pi.jitedInfo.lineInfos) + info2.JitedLineInfo = sys.SlicePointer(pi.jitedInfo.lineInfos) info2.JitedLineInfoRecSize = info.JitedLineInfoRecSize makeSecondCall = true } @@ -345,7 +345,7 @@ func newProgramInfoFromFd(fd *sys.FD) (*ProgramInfo, error) { if info.NrJitedKsyms > 0 { pi.jitedInfo.numKsyms = info.NrJitedKsyms pi.jitedInfo.ksyms = make([]uint64, info.NrJitedKsyms) - info2.JitedKsyms = sys.NewSlicePointer(pi.jitedInfo.ksyms) + info2.JitedKsyms = sys.SlicePointer(pi.jitedInfo.ksyms) info2.NrJitedKsyms = info.NrJitedKsyms makeSecondCall = true } diff --git a/internal/cmd/gentypes/main.go b/internal/cmd/gentypes/main.go index fdd5d6f97..a16035c45 100644 --- a/internal/cmd/gentypes/main.go +++ b/internal/cmd/gentypes/main.go @@ -70,19 +70,44 @@ func run(args []string) error { func generateTypes(spec *btf.Spec) ([]byte, error) { objName := &btf.Array{Nelems: 16, Type: &btf.Int{Encoding: btf.Char, Size: 1}} + mapID := &btf.Int{Size: 4} + progID := &btf.Int{Size: 4} linkID := &btf.Int{Size: 4} btfID := &btf.Int{Size: 4} typeID := &btf.Int{Size: 4} - pointer := &btf.Int{Size: 8} + rawPointer := &btf.Int{Size: 8} + stringPointer := &btf.Int{Size: 8} + stringSlicePointer := &btf.Int{Size: 8} + bytePtr := &btf.Int{Size: 8} + int32Ptr := &btf.Int{Size: 8} + uint32Ptr := &btf.Int{Size: 8} + uint64Ptr := &btf.Int{Size: 8} + uintptrPointer := &btf.Int{Size: 8} + mapIDPtr := &btf.Int{Size: 8} + progIDPtr := &btf.Int{Size: 8} + linkIDPtr := &btf.Int{Size: 8} logLevel := &btf.Int{Size: 4} gf := &btf.GoFormatter{ Names: map[btf.Type]string{ - objName: internal.GoTypeName(sys.ObjName{}), - linkID: internal.GoTypeName(sys.LinkID(0)), - btfID: internal.GoTypeName(sys.BTFID(0)), - typeID: internal.GoTypeName(sys.TypeID(0)), - pointer: internal.GoTypeName(sys.Pointer{}), + objName: internal.GoTypeName(sys.ObjName{}), + mapID: internal.GoTypeName(sys.MapID(0)), + progID: internal.GoTypeName(sys.ProgramID(0)), + linkID: internal.GoTypeName(sys.LinkID(0)), + btfID: internal.GoTypeName(sys.BTFID(0)), + typeID: internal.GoTypeName(sys.TypeID(0)), + rawPointer: internal.GoTypeName(sys.Pointer{}), + stringPointer: internal.GoTypeName(sys.StringPointer{}), + stringSlicePointer: internal.GoTypeName(sys.StringSlicePointer{}), + bytePtr: internal.GoTypeName(sys.TypedPointer[byte]{}), + int32Ptr: internal.GoTypeName(sys.TypedPointer[int32]{}), + uint32Ptr: internal.GoTypeName(sys.TypedPointer[uint32]{}), + uint64Ptr: internal.GoTypeName(sys.TypedPointer[uint64]{}), + uintptrPointer: internal.GoTypeName(sys.TypedPointer[uintptr]{}), + mapIDPtr: internal.GoTypeName(sys.TypedPointer[sys.MapID]{}), + progIDPtr: internal.GoTypeName(sys.TypedPointer[sys.ProgramID]{}), + linkIDPtr: internal.GoTypeName(sys.TypedPointer[sys.LinkID]{}), + logLevel: internal.GoTypeName(sys.LogLevel(0)), }, Identifier: internal.Identifier, @@ -199,14 +224,14 @@ import ( "ProgInfo", "bpf_prog_info", []patch{ replace(objName, "name"), - replace(pointer, "jited_prog_insns"), - replace(pointer, "xlated_prog_insns"), - replace(pointer, "map_ids"), - replace(pointer, "line_info"), - replace(pointer, "jited_line_info"), - replace(pointer, "jited_ksyms"), - replace(pointer, "jited_func_lens"), - replace(pointer, "func_info"), + replace(bytePtr, "jited_prog_insns"), + replace(bytePtr, "xlated_prog_insns"), + replace(mapIDPtr, "map_ids"), + replace(bytePtr, "line_info"), + replace(uint64Ptr, "jited_line_info"), + replace(uint64Ptr, "jited_ksyms"), + replace(uint32Ptr, "jited_func_lens"), + replace(bytePtr, "func_info"), replace(btfID, "btf_id", "attach_btf_obj_id"), replace(typeID, "attach_btf_id"), }, @@ -214,6 +239,7 @@ import ( { "MapInfo", "bpf_map_info", []patch{ + replace(mapID, "id"), replace(objName, "name"), replace(typeID, "btf_vmlinux_value_type_id", "btf_key_type_id", "btf_value_type_id"), }, @@ -221,7 +247,7 @@ import ( { "BtfInfo", "bpf_btf_info", []patch{ - replace(pointer, "btf", "name"), + replace(bytePtr, "btf", "name"), replace(btfID, "id"), }, }, @@ -282,24 +308,24 @@ import ( }, { "MapLookupElem", retError, "map_elem", "BPF_MAP_LOOKUP_ELEM", - []patch{choose(2, "value"), replace(pointer, "key", "value")}, + []patch{choose(2, "value"), replace(rawPointer, "key", "value")}, }, { "MapLookupAndDeleteElem", retError, "map_elem", "BPF_MAP_LOOKUP_AND_DELETE_ELEM", - []patch{choose(2, "value"), replace(pointer, "key", "value")}, + []patch{choose(2, "value"), replace(rawPointer, "key", "value")}, }, { "MapUpdateElem", retError, "map_elem", "BPF_MAP_UPDATE_ELEM", - []patch{choose(2, "value"), replace(pointer, "key", "value")}, + []patch{choose(2, "value"), replace(rawPointer, "key", "value")}, }, { "MapDeleteElem", retError, "map_elem", "BPF_MAP_DELETE_ELEM", - []patch{choose(2, "value"), replace(pointer, "key", "value")}, + []patch{choose(2, "value"), replace(rawPointer, "key", "value")}, }, { "MapGetNextKey", retError, "map_elem", "BPF_MAP_GET_NEXT_KEY", []patch{ - choose(2, "next_key"), replace(pointer, "key", "next_key"), + choose(2, "next_key"), replace(rawPointer, "key", "next_key"), truncateAfter("next_key"), }, }, @@ -309,19 +335,19 @@ import ( }, { "MapLookupBatch", retError, "map_elem_batch", "BPF_MAP_LOOKUP_BATCH", - []patch{replace(pointer, "in_batch", "out_batch", "keys", "values")}, + []patch{replace(rawPointer, "in_batch", "out_batch", "keys", "values")}, }, { "MapLookupAndDeleteBatch", retError, "map_elem_batch", "BPF_MAP_LOOKUP_AND_DELETE_BATCH", - []patch{replace(pointer, "in_batch", "out_batch", "keys", "values")}, + []patch{replace(rawPointer, "in_batch", "out_batch", "keys", "values")}, }, { "MapUpdateBatch", retError, "map_elem_batch", "BPF_MAP_UPDATE_BATCH", - []patch{replace(pointer, "in_batch", "out_batch", "keys", "values")}, + []patch{replace(rawPointer, "in_batch", "out_batch", "keys", "values")}, }, { "MapDeleteBatch", retError, "map_elem_batch", "BPF_MAP_DELETE_BATCH", - []patch{replace(pointer, "in_batch", "out_batch", "keys", "values")}, + []patch{replace(rawPointer, "in_batch", "out_batch", "keys", "values")}, }, { "ProgLoad", retFd, "prog_load", "BPF_PROG_LOAD", @@ -330,15 +356,15 @@ import ( replace(enumTypes["ProgType"], "prog_type"), replace(enumTypes["AttachType"], "expected_attach_type"), replace(logLevel, "log_level"), - replace(pointer, - "insns", - "license", - "log_buf", + replace(bytePtr, "insns"), + replace(stringPointer, "license"), + replace(bytePtr, "log_buf"), + replace(bytePtr, "func_info", "line_info", - "fd_array", "core_relos", ), + replace(int32Ptr, "fd_array"), replace(typeID, "attach_btf_id"), choose(20, "attach_btf_obj_fd"), }, @@ -349,11 +375,11 @@ import ( }, { "ObjPin", retError, "obj_pin", "BPF_OBJ_PIN", - []patch{replace(pointer, "pathname")}, + []patch{replace(stringPointer, "pathname")}, }, { "ObjGet", retFd, "obj_pin", "BPF_OBJ_GET", - []patch{replace(pointer, "pathname")}, + []patch{replace(stringPointer, "pathname")}, }, { "ProgAttach", retError, "prog_attach", "BPF_PROG_ATTACH", @@ -375,7 +401,7 @@ import ( }, { "ProgRun", retError, "prog_run", "BPF_PROG_TEST_RUN", - []patch{replace(pointer, "data_in", "data_out", "ctx_in", "ctx_out")}, + []patch{replace(bytePtr, "data_in", "data_out", "ctx_in", "ctx_out")}, }, { "ProgGetNextId", retError, "obj_next_id", "BPF_PROG_GET_NEXT_ID", @@ -427,15 +453,15 @@ import ( }, { "ObjGetInfoByFd", retError, "info_by_fd", "BPF_OBJ_GET_INFO_BY_FD", - []patch{replace(pointer, "info")}, + []patch{replace(rawPointer, "info")}, }, { "RawTracepointOpen", retFd, "raw_tracepoint_open", "BPF_RAW_TRACEPOINT_OPEN", - []patch{replace(pointer, "name")}, + []patch{replace(stringPointer, "name")}, }, { "BtfLoad", retFd, "btf_load", "BPF_BTF_LOAD", - []patch{replace(pointer, "btf", "btf_log_buf")}, + []patch{replace(bytePtr, "btf", "btf_log_buf")}, }, { "LinkCreate", retFd, "link_create", "BPF_LINK_CREATE", @@ -451,7 +477,7 @@ import ( chooseNth(4, 1), replace(enumTypes["AttachType"], "attach_type"), flattenAnon, - replace(pointer, "iter_info"), + replace(rawPointer, "iter_info"), }, }, { @@ -471,9 +497,9 @@ import ( return rename("flags", "kprobe_multi_flags")(m.Type.(*btf.Struct)) }, "kprobe_multi"), flattenAnon, - replace(pointer, "cookies"), - replace(pointer, "addrs"), - replace(pointer, "syms"), + replace(uint64Ptr, "cookies"), + replace(uintptrPointer, "addrs"), + replace(stringSlicePointer, "syms"), rename("cnt", "count"), }, }, @@ -517,10 +543,10 @@ import ( return rename("flags", "uprobe_multi_flags")(m.Type.(*btf.Struct)) }, "uprobe_multi"), flattenAnon, - replace(pointer, "path"), - replace(pointer, "offsets"), - replace(pointer, "ref_ctr_offsets"), - replace(pointer, "cookies"), + replace(stringPointer, "path"), + replace(uint64Ptr, "offsets"), + replace(uint64Ptr, "ref_ctr_offsets"), + replace(uint64Ptr, "cookies"), rename("cnt", "count"), }, }, @@ -551,8 +577,8 @@ import ( "ProgQuery", retError, "prog_query", "BPF_PROG_QUERY", []patch{ replace(enumTypes["AttachType"], "attach_type"), - replace(pointer, "prog_ids", "prog_attach_flags"), - replace(pointer, "link_ids", "link_attach_flags"), + replace(progIDPtr, "prog_ids", "prog_attach_flags"), + replace(linkIDPtr, "link_ids", "link_attach_flags"), flattenAnon, rename("prog_cnt", "count"), rename("target_fd", "target_fd_or_ifindex"), @@ -630,7 +656,7 @@ import ( []patch{ choose(3, "iter"), flattenAnon, - replace(pointer, "target_name"), + replace(bytePtr, "target_name"), truncateAfter("target_name_len"), }, }, @@ -643,7 +669,7 @@ import ( {"RawTracepointLinkInfo", []patch{choose(3, "raw_tracepoint"), flattenAnon, - replace(pointer, "tp_name"), + replace(bytePtr, "tp_name"), }, }, {"TracingLinkInfo", @@ -683,7 +709,8 @@ import ( []patch{ choose(3, "kprobe_multi"), flattenAnon, - replace(pointer, "addrs"), + replace(uint64Ptr, "addrs"), + replace(uint64Ptr, "cookies"), }, }, {"PerfEventLinkInfo", @@ -703,7 +730,7 @@ import ( replace(enumTypes["PerfEventType"], "perf_event_type"), choose(4, "kprobe"), flattenAnon, - replace(pointer, "func_name"), + replace(bytePtr, "func_name"), }, }, } diff --git a/internal/output.go b/internal/output.go index dd6e6cbaf..bcbb6818d 100644 --- a/internal/output.go +++ b/internal/output.go @@ -92,6 +92,11 @@ func GoTypeName(t any) string { for rT.Kind() == reflect.Pointer { rT = rT.Elem() } - // Doesn't return the correct Name for generic types due to https://github.com/golang/go/issues/55924 - return rT.Name() + + name := rT.Name() + if pkgPath := rT.PkgPath(); pkgPath != "" { + name = strings.ReplaceAll(name, pkgPath+".", "") + } + + return name } diff --git a/internal/output_test.go b/internal/output_test.go index b2e6fcac6..a5ea90f63 100644 --- a/internal/output_test.go +++ b/internal/output_test.go @@ -29,13 +29,14 @@ func TestIdentifier(t *testing.T) { } } +type foo struct{} + func TestGoTypeName(t *testing.T) { - type foo struct{} type bar[T any] struct{} qt.Assert(t, qt.Equals(GoTypeName(foo{}), "foo")) qt.Assert(t, qt.Equals(GoTypeName(new(foo)), "foo")) qt.Assert(t, qt.Equals(GoTypeName(new(*foo)), "foo")) qt.Assert(t, qt.Equals(GoTypeName(bar[int]{}), "bar[int]")) - // Broken in the stdlib, see GoTypeName for details. - // qt.Assert(t, GoTypeName(bar[qt.C]{}), qt.Equals, "bar[quicktest.C]") + qt.Assert(t, qt.Equals(GoTypeName(bar[foo]{}), "bar[foo]")) + qt.Assert(t, qt.Equals(GoTypeName(bar[testing.T]{}), "bar[testing.T]")) } diff --git a/internal/sys/ptr.go b/internal/sys/ptr.go index af0c014e3..d29699e04 100644 --- a/internal/sys/ptr.go +++ b/internal/sys/ptr.go @@ -6,13 +6,13 @@ import ( "github.com/cilium/ebpf/internal/unix" ) -// NewPointer creates a 64-bit pointer from an unsafe Pointer. -func NewPointer(ptr unsafe.Pointer) Pointer { +// UnsafePointer creates a 64-bit pointer from an unsafe Pointer. +func UnsafePointer(ptr unsafe.Pointer) Pointer { return Pointer{ptr: ptr} } -// NewSlicePointer creates a 64-bit pointer from a slice. -func NewSlicePointer[T comparable](buf []T) Pointer { +// UnsafeSlicePointer creates an untyped [Pointer] from a slice. +func UnsafeSlicePointer[T comparable](buf []T) Pointer { if len(buf) == 0 { return Pointer{} } @@ -20,21 +20,39 @@ func NewSlicePointer[T comparable](buf []T) Pointer { return Pointer{ptr: unsafe.Pointer(unsafe.SliceData(buf))} } -// NewSlicePointerLen creates a 64-bit pointer from a byte slice. +// TypedPointer points to typed memory. // -// Useful to assign both the pointer and the length in one go. -func NewSlicePointerLen(buf []byte) (Pointer, uint32) { - return NewSlicePointer(buf), uint32(len(buf)) +// It is like a *T except that it accounts for the BPF syscall interface. +type TypedPointer[T any] struct { + _ [0]*T // prevent TypedPointer[a] to be convertible to TypedPointer[b] + ptr Pointer } -// NewStringPointer creates a 64-bit pointer from a string. -func NewStringPointer(str string) Pointer { +// SlicePointer creates a [TypedPointer] from a slice. +func SlicePointer[T comparable](s []T) TypedPointer[T] { + return TypedPointer[T]{ptr: UnsafeSlicePointer(s)} +} + +// StringPointer points to a null-terminated string. +type StringPointer struct { + _ [0]string + ptr Pointer +} + +// NewStringPointer creates a [StringPointer] from a string. +func NewStringPointer(str string) StringPointer { p, err := unix.BytePtrFromString(str) if err != nil { - return Pointer{} + return StringPointer{} } - return Pointer{ptr: unsafe.Pointer(p)} + return StringPointer{ptr: Pointer{ptr: unsafe.Pointer(p)}} +} + +// StringSlicePointer points to a slice of [StringPointer]. +type StringSlicePointer struct { + _ [0][]string + ptr Pointer } // NewStringSlicePointer allocates an array of Pointers to each string in the @@ -42,11 +60,11 @@ func NewStringPointer(str string) Pointer { // resulting array. // // Use this function to pass arrays of strings as syscall arguments. -func NewStringSlicePointer(strings []string) Pointer { - sp := make([]Pointer, 0, len(strings)) +func NewStringSlicePointer(strings []string) StringSlicePointer { + sp := make([]StringPointer, 0, len(strings)) for _, s := range strings { sp = append(sp, NewStringPointer(s)) } - return Pointer{ptr: unsafe.Pointer(&sp[0])} + return StringSlicePointer{ptr: Pointer{ptr: unsafe.Pointer(&sp[0])}} } diff --git a/internal/sys/ptr_test.go b/internal/sys/ptr_test.go new file mode 100644 index 000000000..50736bf98 --- /dev/null +++ b/internal/sys/ptr_test.go @@ -0,0 +1,31 @@ +package sys + +import ( + "fmt" + "reflect" + "testing" + "unsafe" + + "github.com/go-quicktest/qt" +) + +func TestTypedPointer(t *testing.T) { + ptrs := []any{ + TypedPointer[uint32]{}, + TypedPointer[complex128]{}, + StringPointer{}, + StringSlicePointer{}, + } + + for i, a := range ptrs { + qt.Assert(t, qt.Equals(unsafe.Alignof(a), unsafe.Alignof(unsafe.Pointer(nil)))) + + for _, b := range ptrs[i+1:] { + t.Run(fmt.Sprintf("%T %T", a, b), func(t *testing.T) { + typeOfA := reflect.TypeOf(a) + typeOfB := reflect.TypeOf(b) + qt.Assert(t, qt.IsFalse(typeOfA.ConvertibleTo(typeOfB))) + }) + } + } +} diff --git a/internal/sys/syscall.go b/internal/sys/syscall.go index 4fdb74c57..685e6154d 100644 --- a/internal/sys/syscall.go +++ b/internal/sys/syscall.go @@ -124,7 +124,7 @@ func ObjInfo(fd *FD, info Info) error { err := ObjGetInfoByFd(&ObjGetInfoByFdAttr{ BpfFd: fd.Uint(), InfoLen: len, - Info: NewPointer(ptr), + Info: UnsafePointer(ptr), }) runtime.KeepAlive(fd) return err @@ -150,6 +150,12 @@ const ( BPF_LOG_STATS ) +// MapID uniquely identifies a bpf_map. +type MapID uint32 + +// ProgramID uniquely identifies a bpf_map. +type ProgramID uint32 + // LinkID uniquely identifies a bpf_link. type LinkID uint32 diff --git a/internal/sys/types.go b/internal/sys/types.go index 61dafa2f6..a76d4a562 100644 --- a/internal/sys/types.go +++ b/internal/sys/types.go @@ -691,10 +691,10 @@ const ( type BtfInfo struct { structs.HostLayout - Btf Pointer + Btf TypedPointer[uint8] BtfSize uint32 Id BTFID - Name Pointer + Name TypedPointer[uint8] NameLen uint32 KernelBtf uint32 } @@ -725,7 +725,7 @@ type LinkInfo struct { type MapInfo struct { structs.HostLayout Type uint32 - Id uint32 + Id MapID KeySize uint32 ValueSize uint32 MaxEntries uint32 @@ -749,12 +749,12 @@ type ProgInfo struct { Tag [8]uint8 JitedProgLen uint32 XlatedProgLen uint32 - JitedProgInsns Pointer - XlatedProgInsns Pointer + JitedProgInsns TypedPointer[uint8] + XlatedProgInsns TypedPointer[uint8] LoadTime uint64 CreatedByUid uint32 NrMapIds uint32 - MapIds Pointer + MapIds TypedPointer[MapID] Name ObjName Ifindex uint32 _ [4]byte /* unsupported bitfield */ @@ -762,15 +762,15 @@ type ProgInfo struct { NetnsIno uint64 NrJitedKsyms uint32 NrJitedFuncLens uint32 - JitedKsyms Pointer - JitedFuncLens Pointer + JitedKsyms TypedPointer[uint64] + JitedFuncLens TypedPointer[uint32] BtfId BTFID FuncInfoRecSize uint32 - FuncInfo Pointer + FuncInfo TypedPointer[uint8] NrFuncInfo uint32 NrLineInfo uint32 - LineInfo Pointer - JitedLineInfo Pointer + LineInfo TypedPointer[uint8] + JitedLineInfo TypedPointer[uint64] NrJitedLineInfo uint32 LineInfoRecSize uint32 JitedLineInfoRecSize uint32 @@ -837,8 +837,8 @@ func BtfGetNextId(attr *BtfGetNextIdAttr) error { type BtfLoadAttr struct { structs.HostLayout - Btf Pointer - BtfLogBuf Pointer + Btf TypedPointer[uint8] + BtfLogBuf TypedPointer[uint8] BtfSize uint32 BtfLogSize uint32 BtfLogLevel uint32 @@ -927,9 +927,9 @@ type LinkCreateKprobeMultiAttr struct { Flags uint32 KprobeMultiFlags uint32 Count uint32 - Syms Pointer - Addrs Pointer - Cookies Pointer + Syms StringSlicePointer + Addrs TypedPointer[uintptr] + Cookies TypedPointer[uint64] _ [16]byte } @@ -1046,10 +1046,10 @@ type LinkCreateUprobeMultiAttr struct { TargetFd uint32 AttachType AttachType Flags uint32 - Path Pointer - Offsets Pointer - RefCtrOffsets Pointer - Cookies Pointer + Path StringPointer + Offsets TypedPointer[uint64] + RefCtrOffsets TypedPointer[uint64] + Cookies TypedPointer[uint64] Count uint32 UprobeMultiFlags uint32 Pid uint32 @@ -1302,7 +1302,7 @@ func MapUpdateElem(attr *MapUpdateElemAttr) error { type ObjGetAttr struct { structs.HostLayout - Pathname Pointer + Pathname StringPointer BpfFd uint32 FileFlags uint32 PathFd int32 @@ -1331,7 +1331,7 @@ func ObjGetInfoByFd(attr *ObjGetInfoByFdAttr) error { type ObjPinAttr struct { structs.HostLayout - Pathname Pointer + Pathname StringPointer BpfFd uint32 FileFlags uint32 PathFd int32 @@ -1415,11 +1415,11 @@ type ProgLoadAttr struct { structs.HostLayout ProgType ProgType InsnCnt uint32 - Insns Pointer - License Pointer + Insns TypedPointer[uint8] + License StringPointer LogLevel LogLevel LogSize uint32 - LogBuf Pointer + LogBuf TypedPointer[uint8] KernVersion uint32 ProgFlags uint32 ProgName ObjName @@ -1427,16 +1427,16 @@ type ProgLoadAttr struct { ExpectedAttachType AttachType ProgBtfFd uint32 FuncInfoRecSize uint32 - FuncInfo Pointer + FuncInfo TypedPointer[uint8] FuncInfoCnt uint32 LineInfoRecSize uint32 - LineInfo Pointer + LineInfo TypedPointer[uint8] LineInfoCnt uint32 AttachBtfId TypeID AttachBtfObjFd uint32 CoreReloCnt uint32 - FdArray Pointer - CoreRelos Pointer + FdArray TypedPointer[int32] + CoreRelos TypedPointer[uint8] CoreReloRecSize uint32 LogTrueSize uint32 ProgTokenFd int32 @@ -1457,12 +1457,12 @@ type ProgQueryAttr struct { AttachType AttachType QueryFlags uint32 AttachFlags uint32 - ProgIds Pointer + ProgIds TypedPointer[ProgramID] Count uint32 _ [4]byte - ProgAttachFlags Pointer - LinkIds Pointer - LinkAttachFlags Pointer + ProgAttachFlags TypedPointer[ProgramID] + LinkIds TypedPointer[LinkID] + LinkAttachFlags TypedPointer[LinkID] Revision uint64 } @@ -1477,14 +1477,14 @@ type ProgRunAttr struct { Retval uint32 DataSizeIn uint32 DataSizeOut uint32 - DataIn Pointer - DataOut Pointer + DataIn TypedPointer[uint8] + DataOut TypedPointer[uint8] Repeat uint32 Duration uint32 CtxSizeIn uint32 CtxSizeOut uint32 - CtxIn Pointer - CtxOut Pointer + CtxIn TypedPointer[uint8] + CtxOut TypedPointer[uint8] Flags uint32 Cpu uint32 BatchSize uint32 @@ -1498,7 +1498,7 @@ func ProgRun(attr *ProgRunAttr) error { type RawTracepointOpenAttr struct { structs.HostLayout - Name Pointer + Name StringPointer ProgFd uint32 _ [4]byte Cookie uint64 @@ -1529,7 +1529,7 @@ type IterLinkInfo struct { Id LinkID ProgId uint32 _ [4]byte - TargetName Pointer + TargetName TypedPointer[uint8] TargetNameLen uint32 } @@ -1541,7 +1541,7 @@ type KprobeLinkInfo struct { _ [4]byte PerfEventType PerfEventType _ [4]byte - FuncName Pointer + FuncName TypedPointer[uint8] NameLen uint32 Offset uint32 Addr uint64 @@ -1555,11 +1555,11 @@ type KprobeMultiLinkInfo struct { Id LinkID ProgId uint32 _ [4]byte - Addrs Pointer + Addrs TypedPointer[uint64] Count uint32 Flags uint32 Missed uint64 - Cookies uint64 + Cookies TypedPointer[uint64] _ [16]byte } @@ -1613,7 +1613,7 @@ type RawTracepointLinkInfo struct { Id LinkID ProgId uint32 _ [4]byte - TpName Pointer + TpName TypedPointer[uint8] TpNameLen uint32 _ [36]byte } diff --git a/internal/sysenc/buffer.go b/internal/sysenc/buffer.go index 1b4f052ee..62e483a1c 100644 --- a/internal/sysenc/buffer.go +++ b/internal/sysenc/buffer.go @@ -63,7 +63,7 @@ func (b Buffer) AppendTo(dst []byte) []byte { func (b Buffer) Pointer() sys.Pointer { // NB: This deliberately ignores b.length to support zero-copy // marshaling / unmarshaling using unsafe.Pointer. - return sys.NewPointer(b.ptr) + return sys.UnsafePointer(b.ptr) } // Unmarshal the buffer into the provided value. diff --git a/internal/sysenc/buffer_test.go b/internal/sysenc/buffer_test.go index 5918198d3..6be9acf58 100644 --- a/internal/sysenc/buffer_test.go +++ b/internal/sysenc/buffer_test.go @@ -23,6 +23,6 @@ func TestUnsafeBuffer(t *testing.T) { buf := sysenc.UnsafeBuffer(ptr) qt.Assert(t, qt.Equals(buf.CopyTo(make([]byte, 1)), 0)) - qt.Assert(t, qt.Equals(buf.Pointer(), sys.NewPointer(ptr))) + qt.Assert(t, qt.Equals(buf.Pointer(), sys.UnsafePointer(ptr))) qt.Assert(t, qt.IsNil(buf.Unmarshal(new(uint16)))) } diff --git a/link/iter.go b/link/iter.go index 0a39faef8..1cd406aaa 100644 --- a/link/iter.go +++ b/link/iter.go @@ -42,7 +42,7 @@ func AttachIter(opts IterOptions) (*Iter, error) { attr := sys.LinkCreateIterAttr{ ProgFd: uint32(progFd), AttachType: sys.AttachType(ebpf.AttachTraceIter), - IterInfo: sys.NewPointer(unsafe.Pointer(&info)), + IterInfo: sys.UnsafePointer(unsafe.Pointer(&info)), IterInfoLen: uint32(unsafe.Sizeof(info)), } diff --git a/link/kprobe_multi.go b/link/kprobe_multi.go index f19f9f4c7..9511991cc 100644 --- a/link/kprobe_multi.go +++ b/link/kprobe_multi.go @@ -4,7 +4,6 @@ import ( "errors" "fmt" "os" - "unsafe" "github.com/cilium/ebpf" "github.com/cilium/ebpf/asm" @@ -108,11 +107,11 @@ func kprobeMulti(prog *ebpf.Program, opts KprobeMultiOptions, flags uint32) (Lin case addrs != 0: attr.Count = addrs - attr.Addrs = sys.NewPointer(unsafe.Pointer(&opts.Addresses[0])) + attr.Addrs = sys.SlicePointer(opts.Addresses) } if cookies != 0 { - attr.Cookies = sys.NewPointer(unsafe.Pointer(&opts.Cookies[0])) + attr.Cookies = sys.SlicePointer(opts.Cookies) } fd, err := sys.LinkCreateKprobeMulti(attr) diff --git a/link/query.go b/link/query.go index fe534f8ef..714359b34 100644 --- a/link/query.go +++ b/link/query.go @@ -2,7 +2,6 @@ package link import ( "fmt" - "unsafe" "github.com/cilium/ebpf" "github.com/cilium/ebpf/internal/sys" @@ -84,13 +83,13 @@ func QueryPrograms(opts QueryOptions) (*QueryResult, error) { AttachType: sys.AttachType(opts.Attach), QueryFlags: opts.QueryFlags, Count: count, - ProgIds: sys.NewPointer(unsafe.Pointer(&progIds[0])), + ProgIds: sys.SlicePointer(progIds), } var linkIds []ID if haveLinkIDs { linkIds = make([]ID, count) - attr.LinkIds = sys.NewPointer(unsafe.Pointer(&linkIds[0])) + attr.LinkIds = sys.SlicePointer(linkIds) } if err := sys.ProgQuery(&attr); err != nil { diff --git a/link/uprobe_multi.go b/link/uprobe_multi.go index 49dc18b44..3779602e6 100644 --- a/link/uprobe_multi.go +++ b/link/uprobe_multi.go @@ -4,7 +4,6 @@ import ( "errors" "fmt" "os" - "unsafe" "github.com/cilium/ebpf" "github.com/cilium/ebpf/asm" @@ -84,15 +83,15 @@ func (ex *Executable) uprobeMulti(symbols []string, prog *ebpf.Program, opts *Up AttachType: sys.BPF_TRACE_UPROBE_MULTI, UprobeMultiFlags: flags, Count: uint32(addrs), - Offsets: sys.NewPointer(unsafe.Pointer(&addresses[0])), + Offsets: sys.SlicePointer(addresses), Pid: opts.PID, } if refCtrOffsets != 0 { - attr.RefCtrOffsets = sys.NewPointer(unsafe.Pointer(&opts.RefCtrOffsets[0])) + attr.RefCtrOffsets = sys.SlicePointer(opts.RefCtrOffsets) } if cookies != 0 { - attr.Cookies = sys.NewPointer(unsafe.Pointer(&opts.Cookies[0])) + attr.Cookies = sys.SlicePointer(opts.Cookies) } fd, err := sys.LinkCreateUprobeMulti(attr) @@ -201,7 +200,7 @@ var haveBPFLinkUprobeMulti = internal.NewFeatureTest("bpf_link_uprobe_multi", fu ProgFd: uint32(prog.FD()), AttachType: sys.BPF_TRACE_UPROBE_MULTI, Path: sys.NewStringPointer("/"), - Offsets: sys.NewPointer(unsafe.Pointer(&[]uint64{0})), + Offsets: sys.SlicePointer([]uint64{0}), Count: 1, }) switch { diff --git a/map.go b/map.go index e5d8bd780..e206b9eff 100644 --- a/map.go +++ b/map.go @@ -45,7 +45,7 @@ type MapOptions struct { } // MapID represents the unique ID of an eBPF map -type MapID uint32 +type MapID = sys.MapID // MapSpec defines a Map. type MapSpec struct { @@ -739,7 +739,7 @@ func (m *Map) LookupAndDeleteWithFlags(key, valueOut interface{}, flags MapLooku // Returns a nil value if a key doesn't exist. func (m *Map) LookupBytes(key interface{}) ([]byte, error) { valueBytes := make([]byte, m.fullValueSize) - valuePtr := sys.NewSlicePointer(valueBytes) + valuePtr := sys.UnsafeSlicePointer(valueBytes) err := m.lookup(key, valuePtr, 0) if errors.Is(err, ErrKeyNotExist) { @@ -755,7 +755,7 @@ func (m *Map) lookupPerCPU(key, valueOut any, flags MapLookupFlags) error { return err } valueBytes := make([]byte, m.fullValueSize) - if err := m.lookup(key, sys.NewSlicePointer(valueBytes), flags); err != nil { + if err := m.lookup(key, sys.UnsafeSlicePointer(valueBytes), flags); err != nil { return err } return unmarshalPerCPUValue(slice, int(m.valueSize), valueBytes) @@ -789,7 +789,7 @@ func (m *Map) lookupAndDeletePerCPU(key, valueOut any, flags MapLookupFlags) err return err } valueBytes := make([]byte, m.fullValueSize) - if err := m.lookupAndDelete(key, sys.NewSlicePointer(valueBytes), flags); err != nil { + if err := m.lookupAndDelete(key, sys.UnsafeSlicePointer(valueBytes), flags); err != nil { return err } return unmarshalPerCPUValue(slice, int(m.valueSize), valueBytes) @@ -966,7 +966,7 @@ func (m *Map) NextKey(key, nextKeyOut interface{}) error { // Returns nil if there are no more keys. func (m *Map) NextKeyBytes(key interface{}) ([]byte, error) { nextKey := make([]byte, m.keySize) - nextKeyPtr := sys.NewSlicePointer(nextKey) + nextKeyPtr := sys.UnsafeSlicePointer(nextKey) err := m.nextKey(key, nextKeyPtr) if errors.Is(err, ErrKeyNotExist) { @@ -1006,7 +1006,7 @@ func (m *Map) nextKey(key interface{}, nextKeyOut sys.Pointer) error { } // Retry the syscall with a valid non-existing key. - attr.Key = sys.NewSlicePointer(guessKey) + attr.Key = sys.UnsafeSlicePointer(guessKey) if err = sys.MapGetNextKey(&attr); err == nil { return nil } @@ -1032,7 +1032,7 @@ func (m *Map) guessNonExistentKey() ([]byte, error) { if err != nil { return nil, err } - valuePtr := sys.NewSlicePointer(page) + valuePtr := sys.UnsafeSlicePointer(page) randKey := make([]byte, int(m.keySize)) @@ -1159,7 +1159,7 @@ func (m *Map) batchLookupPerCPU(cmd sys.Cmd, cursor *MapBatchCursor, keysOut, va } valueBuf := make([]byte, count*int(m.fullValueSize)) - valuePtr := sys.NewSlicePointer(valueBuf) + valuePtr := sys.UnsafeSlicePointer(valueBuf) n, sysErr := m.batchLookupCmd(cmd, cursor, count, keysOut, valuePtr, opts) if sysErr != nil && !errors.Is(sysErr, unix.ENOENT) { @@ -1211,8 +1211,8 @@ func (m *Map) batchLookupCmd(cmd sys.Cmd, cursor *MapBatchCursor, count int, key Keys: keyBuf.Pointer(), Values: valuePtr, Count: uint32(count), - InBatch: sys.NewSlicePointer(inBatch), - OutBatch: sys.NewSlicePointer(cursor.opaque), + InBatch: sys.UnsafeSlicePointer(inBatch), + OutBatch: sys.UnsafeSlicePointer(cursor.opaque), } if opts != nil { @@ -1294,7 +1294,7 @@ func (m *Map) batchUpdatePerCPU(keys, values any, opts *BatchOptions) (int, erro return 0, err } - return m.batchUpdate(count, keys, sys.NewSlicePointer(valueBuf), opts) + return m.batchUpdate(count, keys, sys.UnsafeSlicePointer(valueBuf), opts) } // BatchDelete batch deletes entries in the map by keys. @@ -1483,7 +1483,7 @@ func (m *Map) marshalKey(data interface{}) (sys.Pointer, error) { if data == nil { if m.keySize == 0 { // Queues have a key length of zero, so passing nil here is valid. - return sys.NewPointer(nil), nil + return sys.UnsafePointer(nil), nil } return sys.Pointer{}, errors.New("can't use nil as key of map") } @@ -1518,7 +1518,7 @@ func (m *Map) marshalValue(data interface{}) (sys.Pointer, error) { return sys.Pointer{}, err } - return sys.NewSlicePointer(buf), nil + return sys.UnsafeSlicePointer(buf), nil } func (m *Map) unmarshalValue(value any, buf sysenc.Buffer) error { diff --git a/marshalers.go b/marshalers.go index 57a0a8e88..d4e719c60 100644 --- a/marshalers.go +++ b/marshalers.go @@ -20,7 +20,7 @@ import ( // unsafe.Pointer. func marshalMapSyscallInput(data any, length int) (sys.Pointer, error) { if ptr, ok := data.(unsafe.Pointer); ok { - return sys.NewPointer(ptr), nil + return sys.UnsafePointer(ptr), nil } buf, err := sysenc.Marshal(data, length) @@ -96,7 +96,7 @@ func marshalPerCPUValue(slice any, elemLength int) (sys.Pointer, error) { return sys.Pointer{}, err } - return sys.NewSlicePointer(buf), nil + return sys.UnsafeSlicePointer(buf), nil } // marshalBatchPerCPUValue encodes a batch-sized slice of slices containing diff --git a/prog.go b/prog.go index 8fcae6a3f..9bcf1c249 100644 --- a/prog.go +++ b/prog.go @@ -10,7 +10,6 @@ import ( "runtime" "strings" "time" - "unsafe" "github.com/cilium/ebpf/asm" "github.com/cilium/ebpf/btf" @@ -38,7 +37,7 @@ var errBadRelocation = errors.New("bad CO-RE relocation") var errUnknownKfunc = errors.New("unknown kfunc") // ProgramID represents the unique ID of an eBPF program. -type ProgramID uint32 +type ProgramID = sys.ProgramID const ( // Number of bytes to pad the output buffer for BPF_PROG_TEST_RUN. @@ -333,11 +332,11 @@ func newProgramWithOptions(spec *ProgramSpec, opts ProgramOptions) (*Program, er attr.FuncInfoRecSize = btf.FuncInfoSize attr.FuncInfoCnt = uint32(len(fib)) / btf.FuncInfoSize - attr.FuncInfo = sys.NewSlicePointer(fib) + attr.FuncInfo = sys.SlicePointer(fib) attr.LineInfoRecSize = btf.LineInfoSize attr.LineInfoCnt = uint32(len(lib)) / btf.LineInfoSize - attr.LineInfo = sys.NewSlicePointer(lib) + attr.LineInfo = sys.SlicePointer(lib) } if !b.Empty() { @@ -372,7 +371,7 @@ func newProgramWithOptions(spec *ProgramSpec, opts ProgramOptions) (*Program, er if len(handles) > 0 { fdArray := handles.fdArray() - attr.FdArray = sys.NewPointer(unsafe.Pointer(&fdArray[0])) + attr.FdArray = sys.SlicePointer(fdArray) } buf := bytes.NewBuffer(make([]byte, 0, insns.Size())) @@ -382,7 +381,7 @@ func newProgramWithOptions(spec *ProgramSpec, opts ProgramOptions) (*Program, er } bytecode := buf.Bytes() - attr.Insns = sys.NewSlicePointer(bytecode) + attr.Insns = sys.SlicePointer(bytecode) attr.InsnCnt = uint32(len(bytecode) / asm.InstructionSize) if spec.AttachTarget != nil { @@ -417,7 +416,7 @@ func newProgramWithOptions(spec *ProgramSpec, opts ProgramOptions) (*Program, er logBuf = make([]byte, logSize) attr.LogLevel = opts.LogLevel attr.LogSize = uint32(len(logBuf)) - attr.LogBuf = sys.NewSlicePointer(logBuf) + attr.LogBuf = sys.SlicePointer(logBuf) } for { @@ -461,7 +460,7 @@ func newProgramWithOptions(spec *ProgramSpec, opts ProgramOptions) (*Program, er logBuf = make([]byte, logSize) attr.LogSize = logSize - attr.LogBuf = sys.NewSlicePointer(logBuf) + attr.LogBuf = sys.SlicePointer(logBuf) } end := bytes.IndexByte(logBuf, 0) @@ -778,7 +777,7 @@ var haveProgRun = internal.NewFeatureTest("BPF_PROG_RUN", func() error { attr := sys.ProgRunAttr{ ProgFd: uint32(prog.FD()), DataSizeIn: uint32(len(in)), - DataIn: sys.NewSlicePointer(in), + DataIn: sys.SlicePointer(in), } err = sys.ProgRun(&attr) @@ -829,13 +828,13 @@ func (p *Program) run(opts *RunOptions) (uint32, time.Duration, error) { ProgFd: p.fd.Uint(), DataSizeIn: uint32(len(opts.Data)), DataSizeOut: uint32(len(opts.DataOut)), - DataIn: sys.NewSlicePointer(opts.Data), - DataOut: sys.NewSlicePointer(opts.DataOut), + DataIn: sys.SlicePointer(opts.Data), + DataOut: sys.SlicePointer(opts.DataOut), Repeat: uint32(opts.Repeat), CtxSizeIn: uint32(len(ctxBytes)), CtxSizeOut: uint32(len(ctxOut)), - CtxIn: sys.NewSlicePointer(ctxBytes), - CtxOut: sys.NewSlicePointer(ctxOut), + CtxIn: sys.SlicePointer(ctxBytes), + CtxOut: sys.SlicePointer(ctxOut), Flags: opts.Flags, Cpu: opts.CPU, } diff --git a/syscalls.go b/syscalls.go index 25c84c3c5..f057478cc 100644 --- a/syscalls.go +++ b/syscalls.go @@ -56,7 +56,7 @@ func progLoad(insns asm.Instructions, typ ProgramType, license string) (*sys.FD, return sys.ProgLoad(&sys.ProgLoadAttr{ ProgType: sys.ProgType(typ), License: sys.NewStringPointer(license), - Insns: sys.NewSlicePointer(bytecode), + Insns: sys.SlicePointer(bytecode), InsnCnt: uint32(len(bytecode) / asm.InstructionSize), }) } @@ -337,7 +337,7 @@ var haveProgramExtInfos = internal.NewFeatureTest("program ext_infos", func() er _, err := sys.ProgLoad(&sys.ProgLoadAttr{ ProgType: sys.ProgType(SocketFilter), License: sys.NewStringPointer("MIT"), - Insns: sys.NewSlicePointer(bytecode), + Insns: sys.SlicePointer(bytecode), InsnCnt: uint32(len(bytecode) / asm.InstructionSize), FuncInfoCnt: 1, ProgBtfFd: math.MaxUint32,