Repository: opencontainers/runc
Pull request #4610 (2025-02-01 00:19:49)

deps: roll back to cilium/ebpf v0.16.0
Also, exclude v0.17.x until there is a fix for runc issue #4594 / https://github.com/cilium/ebpf/pull/1660

Fixes: #4594.


Patch:
diff --git a/go.mod b/go.mod
index a25592b1..5fff44cc 100644
--- a/go.mod
+++ b/go.mod
@@ -9,7 +9,7 @@ toolchain go1.22.4
 
 require (
 	github.com/checkpoint-restore/go-criu/v6 v6.3.0
-	github.com/cilium/ebpf v0.17.1
+	github.com/cilium/ebpf v0.16.0
 	github.com/containerd/console v1.0.4
 	github.com/coreos/go-systemd/v22 v22.5.0
 	github.com/cyphar/filepath-securejoin v0.4.1
@@ -31,8 +31,16 @@ require (
 	google.golang.org/protobuf v1.36.4
 )
 
+// https://github.com/cilium/ebpf/pull/1660
+exclude (
+	github.com/cilium/ebpf v0.17.0
+	github.com/cilium/ebpf v0.17.1
+	github.com/cilium/ebpf v0.17.2
+)
+
 require (
 	github.com/cpuguy83/go-md2man/v2 v2.0.5 // indirect
 	github.com/russross/blackfriday/v2 v2.1.0 // indirect
 	github.com/vishvananda/netns v0.0.4 // indirect
+	golang.org/x/exp v0.0.0-20230224173230-c95f2b4c22f2 // indirect
 )
diff --git a/go.sum b/go.sum
index aa8a6429..b7b2d42c 100644
--- a/go.sum
+++ b/go.sum
@@ -1,8 +1,8 @@
 github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
 github.com/checkpoint-restore/go-criu/v6 v6.3.0 h1:mIdrSO2cPNWQY1truPg6uHLXyKHk3Z5Odx4wjKOASzA=
 github.com/checkpoint-restore/go-criu/v6 v6.3.0/go.mod h1:rrRTN/uSwY2X+BPRl/gkulo9gsKOSAeVp9/K2tv7xZI=
-github.com/cilium/ebpf v0.17.1 h1:G8mzU81R2JA1nE5/8SRubzqvBMmAmri2VL8BIZPWvV0=
-github.com/cilium/ebpf v0.17.1/go.mod h1:vay2FaYSmIlv3r8dNACd4mW/OCaZLJKJOo+IHBvCIO8=
+github.com/cilium/ebpf v0.16.0 h1:+BiEnHL6Z7lXnlGUsXQPPAE7+kenAd4ES8MQ5min0Ok=
+github.com/cilium/ebpf v0.16.0/go.mod h1:L7u2Blt2jMM/vLAVgjxluxtBKlz3/GWjB0dMOEngfwE=
 github.com/containerd/console v1.0.4 h1:F2g4+oChYvBTsASRTz8NP6iIAi97J3TtSAsLbIFn4ro=
 github.com/containerd/console v1.0.4/go.mod h1:YynlIjWYF8myEu6sdkwKIvGQq+cOckRm6So2avqoYAk=
 github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs=
@@ -81,6 +81,8 @@ github.com/vishvananda/netlink v1.3.0 h1:X7l42GfcV4S6E4vHTsw48qbrV+9PVojNfIhZcwQ
 github.com/vishvananda/netlink v1.3.0/go.mod h1:i6NetklAujEcC6fK0JPjT8qSwWyO0HLn4UKG+hGqeJs=
 github.com/vishvananda/netns v0.0.4 h1:Oeaw1EM2JMxD51g9uhtC0D7erkIjgmj8+JZc26m1YX8=
 github.com/vishvananda/netns v0.0.4/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM=
+golang.org/x/exp v0.0.0-20230224173230-c95f2b4c22f2 h1:Jvc7gsqn21cJHCmAWx0LiimpP18LZmUxkT5Mp7EZ1mI=
+golang.org/x/exp v0.0.0-20230224173230-c95f2b4c22f2/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
 golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0=
 golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k=
 golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
diff --git a/vendor/github.com/cilium/ebpf/.golangci.yaml b/vendor/github.com/cilium/ebpf/.golangci.yaml
index 366d4893..65f91b91 100644
--- a/vendor/github.com/cilium/ebpf/.golangci.yaml
+++ b/vendor/github.com/cilium/ebpf/.golangci.yaml
@@ -11,9 +11,3 @@ linters:
     - typecheck
     - unused
     - gofmt
-linters-settings:
-  goimports:
-    # A comma-separated list of prefixes, which, if set, checks import paths
-    # with the given prefixes are grouped after 3rd-party packages.
-    # Default: ""
-    local-prefixes: github.com/cilium/ebpf
diff --git a/vendor/github.com/cilium/ebpf/CODEOWNERS b/vendor/github.com/cilium/ebpf/CODEOWNERS
index 0f76dce8..ca65d23c 100644
--- a/vendor/github.com/cilium/ebpf/CODEOWNERS
+++ b/vendor/github.com/cilium/ebpf/CODEOWNERS
@@ -9,5 +9,3 @@ ringbuf/ @florianl
 btf/ @dylandreimerink
 
 cmd/bpf2go/ @mejedi
-
-docs/ @ti-mo
diff --git a/vendor/github.com/cilium/ebpf/Makefile b/vendor/github.com/cilium/ebpf/Makefile
index e0fe9749..d355eea7 100644
--- a/vendor/github.com/cilium/ebpf/Makefile
+++ b/vendor/github.com/cilium/ebpf/Makefile
@@ -39,18 +39,16 @@ TARGETS := \
 	testdata/subprog_reloc \
 	testdata/fwd_decl \
 	testdata/kconfig \
-	testdata/ksym \
+	testdata/kconfig_config \
 	testdata/kfunc \
 	testdata/invalid-kfunc \
 	testdata/kfunc-kmod \
 	testdata/constants \
 	testdata/errors \
-	testdata/variables \
 	btf/testdata/relocs \
 	btf/testdata/relocs_read \
 	btf/testdata/relocs_read_tgt \
 	btf/testdata/relocs_enum \
-	btf/testdata/tags \
 	cmd/bpf2go/testdata/minimal
 
 .PHONY: all clean container-all container-shell generate
@@ -59,7 +57,7 @@ TARGETS := \
 
 # Build all ELF binaries using a containerized LLVM toolchain.
 container-all:
-	+${CONTAINER_ENGINE} run --rm -ti ${CONTAINER_RUN_ARGS} \
+	+${CONTAINER_ENGINE} run --rm -t ${CONTAINER_RUN_ARGS} \
 		-v "${REPODIR}":/ebpf -w /ebpf --env MAKEFLAGS \
 		--env HOME="/tmp" \
 		--env BPF2GO_CC="$(CLANG)" \
diff --git a/vendor/github.com/cilium/ebpf/README.md b/vendor/github.com/cilium/ebpf/README.md
index 8238256c..85871db1 100644
--- a/vendor/github.com/cilium/ebpf/README.md
+++ b/vendor/github.com/cilium/ebpf/README.md
@@ -53,7 +53,6 @@ This library includes the following packages:
 * [rlimit](https://pkg.go.dev/github.com/cilium/ebpf/rlimit) provides a convenient API to lift
   the `RLIMIT_MEMLOCK` constraint on kernels before 5.11.
 * [btf](https://pkg.go.dev/github.com/cilium/ebpf/btf) allows reading the BPF Type Format.
-* [pin](https://pkg.go.dev/github.com/cilium/ebpf/pin) provides APIs for working with pinned objects on bpffs.
 
 ## Requirements
 
diff --git a/vendor/github.com/cilium/ebpf/asm/instruction.go b/vendor/github.com/cilium/ebpf/asm/instruction.go
index 86b384c0..67cd39d6 100644
--- a/vendor/github.com/cilium/ebpf/asm/instruction.go
+++ b/vendor/github.com/cilium/ebpf/asm/instruction.go
@@ -12,6 +12,7 @@ import (
 	"strings"
 
 	"github.com/cilium/ebpf/internal/sys"
+	"github.com/cilium/ebpf/internal/unix"
 )
 
 // InstructionSize is the size of a BPF instruction in bytes
@@ -803,7 +804,7 @@ func (insns Instructions) Tag(bo binary.ByteOrder) (string, error) {
 			return "", fmt.Errorf("instruction %d: %w", i, err)
 		}
 	}
-	return hex.EncodeToString(h.Sum(nil)[:sys.BPF_TAG_SIZE]), nil
+	return hex.EncodeToString(h.Sum(nil)[:unix.BPF_TAG_SIZE]), nil
 }
 
 // encodeFunctionReferences populates the Offset (or Constant, depending on
diff --git a/vendor/github.com/cilium/ebpf/btf/btf.go b/vendor/github.com/cilium/ebpf/btf/btf.go
index 880c5ade..671f680b 100644
--- a/vendor/github.com/cilium/ebpf/btf/btf.go
+++ b/vendor/github.com/cilium/ebpf/btf/btf.go
@@ -443,19 +443,13 @@ func fixupDatasec(types []Type, sectionSizes map[string]uint32, offsets map[symb
 		// Some Datasecs are virtual and don't have corresponding ELF sections.
 		switch name {
 		case ".ksyms":
-			// .ksyms describes forward declarations of kfunc signatures, as well as
-			// references to kernel symbols.
+			// .ksyms describes forward declarations of kfunc signatures.
 			// Nothing to fix up, all sizes and offsets are 0.
 			for _, vsi := range ds.Vars {
-				switch t := vsi.Type.(type) {
-				case *Func:
-					continue
-				case *Var:
-					if _, ok := t.Type.(*Void); !ok {
-						return fmt.Errorf("data section %s: expected %s to be *Void, not %T: %w", name, vsi.Type.TypeName(), vsi.Type, ErrNotSupported)
-					}
-				default:
-					return fmt.Errorf("data section %s: expected to be either *btf.Func or *btf.Var, not %T: %w", name, vsi.Type, ErrNotSupported)
+				_, ok := vsi.Type.(*Func)
+				if !ok {
+					// Only Funcs are supported in the .ksyms Datasec.
+					return fmt.Errorf("data section %s: expected *btf.Func, not %T: %w", name, vsi.Type, ErrNotSupported)
 				}
 			}
 
@@ -701,13 +695,5 @@ func (iter *TypesIterator) Next() bool {
 	iter.Type, ok = iter.spec.typeByID(iter.id)
 	iter.id++
 	iter.done = !ok
-	if !iter.done {
-		// Skip declTags, during unmarshaling declTags become `Tags` fields of other types.
-		// We keep them in the spec to avoid holes in the ID space, but for the purposes of
-		// iteration, they are not useful to the user.
-		if _, ok := iter.Type.(*declTag); ok {
-			return iter.Next()
-		}
-	}
 	return !iter.done
 }
diff --git a/vendor/github.com/cilium/ebpf/btf/btf_types.go b/vendor/github.com/cilium/ebpf/btf/btf_types.go
index 320311b3..f0e327ab 100644
--- a/vendor/github.com/cilium/ebpf/btf/btf_types.go
+++ b/vendor/github.com/cilium/ebpf/btf/btf_types.go
@@ -39,7 +39,6 @@ const (
 	kindFloat // Float
 	// Added 5.16
 	kindDeclTag // DeclTag
-	// Added 5.17
 	kindTypeTag // TypeTag
 	// Added 6.0
 	kindEnum64 // Enum64
diff --git a/vendor/github.com/cilium/ebpf/btf/ext_info.go b/vendor/github.com/cilium/ebpf/btf/ext_info.go
index 2c684fe2..eb9044ba 100644
--- a/vendor/github.com/cilium/ebpf/btf/ext_info.go
+++ b/vendor/github.com/cilium/ebpf/btf/ext_info.go
@@ -16,8 +16,8 @@ import (
 // ExtInfos contains ELF section metadata.
 type ExtInfos struct {
 	// The slices are sorted by offset in ascending order.
-	funcInfos       map[string]FuncOffsets
-	lineInfos       map[string]LineOffsets
+	funcInfos       map[string]FuncInfos
+	lineInfos       map[string]LineInfos
 	relocationInfos map[string]CORERelocationInfos
 }
 
@@ -58,9 +58,9 @@ func loadExtInfos(r io.ReaderAt, bo binary.ByteOrder, spec *Spec) (*ExtInfos, er
 		return nil, fmt.Errorf("parsing BTF function info: %w", err)
 	}
 
-	funcInfos := make(map[string]FuncOffsets, len(btfFuncInfos))
+	funcInfos := make(map[string]FuncInfos, len(btfFuncInfos))
 	for section, bfis := range btfFuncInfos {
-		funcInfos[section], err = newFuncOffsets(bfis, spec)
+		funcInfos[section], err = newFuncInfos(bfis, spec)
 		if err != nil {
 			return nil, fmt.Errorf("section %s: func infos: %w", section, err)
 		}
@@ -72,7 +72,7 @@ func loadExtInfos(r io.ReaderAt, bo binary.ByteOrder, spec *Spec) (*ExtInfos, er
 		return nil, fmt.Errorf("parsing BTF line info: %w", err)
 	}
 
-	lineInfos := make(map[string]LineOffsets, len(btfLineInfos))
+	lineInfos := make(map[string]LineInfos, len(btfLineInfos))
 	for section, blis := range btfLineInfos {
 		lineInfos[section], err = newLineInfos(blis, spec.strings)
 		if err != nil {
@@ -102,10 +102,8 @@ func loadExtInfos(r io.ReaderAt, bo binary.ByteOrder, spec *Spec) (*ExtInfos, er
 	return &ExtInfos{funcInfos, lineInfos, coreRelos}, nil
 }
 
-type (
-	funcInfoMeta       struct{}
-	coreRelocationMeta struct{}
-)
+type funcInfoMeta struct{}
+type coreRelocationMeta struct{}
 
 // Assign per-section metadata from BTF to a section's instructions.
 func (ei *ExtInfos) Assign(insns asm.Instructions, section string) {
@@ -119,20 +117,20 @@ func (ei *ExtInfos) Assign(insns asm.Instructions, section string) {
 // Assign per-instruction metadata to the instructions in insns.
 func AssignMetadataToInstructions(
 	insns asm.Instructions,
-	funcInfos FuncOffsets,
-	lineInfos LineOffsets,
+	funcInfos FuncInfos,
+	lineInfos LineInfos,
 	reloInfos CORERelocationInfos,
 ) {
 	iter := insns.Iterate()
 	for iter.Next() {
-		if len(funcInfos) > 0 && funcInfos[0].Offset == iter.Offset {
-			*iter.Ins = WithFuncMetadata(*iter.Ins, funcInfos[0].Func)
-			funcInfos = funcInfos[1:]
+		if len(funcInfos.infos) > 0 && funcInfos.infos[0].offset == iter.Offset {
+			*iter.Ins = WithFuncMetadata(*iter.Ins, funcInfos.infos[0].fn)
+			funcInfos.infos = funcInfos.infos[1:]
 		}
 
-		if len(lineInfos) > 0 && lineInfos[0].Offset == iter.Offset {
-			*iter.Ins = iter.Ins.WithSource(lineInfos[0].Line)
-			lineInfos = lineInfos[1:]
+		if len(lineInfos.infos) > 0 && lineInfos.infos[0].offset == iter.Offset {
+			*iter.Ins = iter.Ins.WithSource(lineInfos.infos[0].line)
+			lineInfos.infos = lineInfos.infos[1:]
 		}
 
 		if len(reloInfos.infos) > 0 && reloInfos.infos[0].offset == iter.Offset {
@@ -161,9 +159,9 @@ marshal:
 	var fiBuf, liBuf bytes.Buffer
 	for {
 		if fn := FuncMetadata(iter.Ins); fn != nil {
-			fi := &FuncOffset{
-				Func:   fn,
-				Offset: iter.Offset,
+			fi := &funcInfo{
+				fn:     fn,
+				offset: iter.Offset,
 			}
 			if err := fi.marshal(&fiBuf, b); err != nil {
 				return nil, nil, fmt.Errorf("write func info: %w", err)
@@ -180,9 +178,9 @@ marshal:
 				}
 			}
 
-			li := &LineOffset{
-				Offset: iter.Offset,
-				Line:   line,
+			li := &lineInfo{
+				line:   line,
+				offset: iter.Offset,
 			}
 			if err := li.marshal(&liBuf, b); err != nil {
 				return nil, nil, fmt.Errorf("write line info: %w", err)
@@ -335,17 +333,17 @@ func parseExtInfoRecordSize(r io.Reader, bo binary.ByteOrder) (uint32, error) {
 	return recordSize, nil
 }
 
-// FuncOffsets is a sorted slice of FuncOffset.
-type FuncOffsets []FuncOffset
+// FuncInfos contains a sorted list of func infos.
+type FuncInfos struct {
+	infos []funcInfo
+}
 
 // The size of a FuncInfo in BTF wire format.
 var FuncInfoSize = uint32(binary.Size(bpfFuncInfo{}))
 
-// FuncOffset represents a [btf.Func] and its raw instruction offset within a
-// BPF program.
-type FuncOffset struct {
-	Offset asm.RawInstructionOffset
-	Func   *Func
+type funcInfo struct {
+	fn     *Func
+	offset asm.RawInstructionOffset
 }
 
 type bpfFuncInfo struct {
@@ -354,7 +352,7 @@ type bpfFuncInfo struct {
 	TypeID  TypeID
 }
 
-func newFuncOffset(fi bpfFuncInfo, spec *Spec) (*FuncOffset, error) {
+func newFuncInfo(fi bpfFuncInfo, spec *Spec) (*funcInfo, error) {
 	typ, err := spec.TypeByID(fi.TypeID)
 	if err != nil {
 		return nil, err
@@ -370,32 +368,31 @@ func newFuncOffset(fi bpfFuncInfo, spec *Spec) (*FuncOffset, error) {
 		return nil, fmt.Errorf("func with type ID %d doesn't have a name", fi.TypeID)
 	}
 
-	return &FuncOffset{
-		asm.RawInstructionOffset(fi.InsnOff),
+	return &funcInfo{
 		fn,
+		asm.RawInstructionOffset(fi.InsnOff),
 	}, nil
 }
 
-func newFuncOffsets(bfis []bpfFuncInfo, spec *Spec) (FuncOffsets, error) {
-	fos := make(FuncOffsets, 0, len(bfis))
-
+func newFuncInfos(bfis []bpfFuncInfo, spec *Spec) (FuncInfos, error) {
+	fis := FuncInfos{
+		infos: make([]funcInfo, 0, len(bfis)),
+	}
 	for _, bfi := range bfis {
-		fi, err := newFuncOffset(bfi, spec)
+		fi, err := newFuncInfo(bfi, spec)
 		if err != nil {
-			return FuncOffsets{}, fmt.Errorf("offset %d: %w", bfi.InsnOff, err)
+			return FuncInfos{}, fmt.Errorf("offset %d: %w", bfi.InsnOff, err)
 		}
-		fos = append(fos, *fi)
+		fis.infos = append(fis.infos, *fi)
 	}
-	sort.Slice(fos, func(i, j int) bool {
-		return fos[i].Offset <= fos[j].Offset
+	sort.Slice(fis.infos, func(i, j int) bool {
+		return fis.infos[i].offset <= fis.infos[j].offset
 	})
-	return fos, nil
+	return fis, nil
 }
 
-// LoadFuncInfos parses BTF func info from kernel wire format into a
-// [FuncOffsets], a sorted slice of [btf.Func]s of (sub)programs within a BPF
-// program with their corresponding raw instruction offsets.
-func LoadFuncInfos(reader io.Reader, bo binary.ByteOrder, recordNum uint32, spec *Spec) (FuncOffsets, error) {
+// LoadFuncInfos parses BTF func info in kernel wire format.
+func LoadFuncInfos(reader io.Reader, bo binary.ByteOrder, recordNum uint32, spec *Spec) (FuncInfos, error) {
 	fis, err := parseFuncInfoRecords(
 		reader,
 		bo,
@@ -404,20 +401,20 @@ func LoadFuncInfos(reader io.Reader, bo binary.ByteOrder, recordNum uint32, spec
 		false,
 	)
 	if err != nil {
-		return FuncOffsets{}, fmt.Errorf("parsing BTF func info: %w", err)
+		return FuncInfos{}, fmt.Errorf("parsing BTF func info: %w", err)
 	}
 
-	return newFuncOffsets(fis, spec)
+	return newFuncInfos(fis, spec)
 }
 
 // marshal into the BTF wire format.
-func (fi *FuncOffset) marshal(w *bytes.Buffer, b *Builder) error {
-	id, err := b.Add(fi.Func)
+func (fi *funcInfo) marshal(w *bytes.Buffer, b *Builder) error {
+	id, err := b.Add(fi.fn)
 	if err != nil {
 		return err
 	}
 	bfi := bpfFuncInfo{
-		InsnOff: uint32(fi.Offset),
+		InsnOff: uint32(fi.offset),
 		TypeID:  id,
 	}
 	buf := make([]byte, FuncInfoSize)
@@ -518,13 +515,14 @@ func (li *Line) String() string {
 	return li.line
 }
 
-// LineOffsets contains a sorted list of line infos.
-type LineOffsets []LineOffset
+// LineInfos contains a sorted list of line infos.
+type LineInfos struct {
+	infos []lineInfo
+}
 
-// LineOffset represents a line info and its raw instruction offset.
-type LineOffset struct {
-	Offset asm.RawInstructionOffset
-	Line   *Line
+type lineInfo struct {
+	line   *Line
+	offset asm.RawInstructionOffset
 }
 
 // Constants for the format of bpfLineInfo.LineCol.
@@ -543,7 +541,7 @@ type bpfLineInfo struct {
 }
 
 // LoadLineInfos parses BTF line info in kernel wire format.
-func LoadLineInfos(reader io.Reader, bo binary.ByteOrder, recordNum uint32, spec *Spec) (LineOffsets, error) {
+func LoadLineInfos(reader io.Reader, bo binary.ByteOrder, recordNum uint32, spec *Spec) (LineInfos, error) {
 	lis, err := parseLineInfoRecords(
 		reader,
 		bo,
@@ -552,55 +550,57 @@ func LoadLineInfos(reader io.Reader, bo binary.ByteOrder, recordNum uint32, spec
 		false,
 	)
 	if err != nil {
-		return LineOffsets{}, fmt.Errorf("parsing BTF line info: %w", err)
+		return LineInfos{}, fmt.Errorf("parsing BTF line info: %w", err)
 	}
 
 	return newLineInfos(lis, spec.strings)
 }
 
-func newLineInfo(li bpfLineInfo, strings *stringTable) (LineOffset, error) {
+func newLineInfo(li bpfLineInfo, strings *stringTable) (lineInfo, error) {
 	line, err := strings.Lookup(li.LineOff)
 	if err != nil {
-		return LineOffset{}, fmt.Errorf("lookup of line: %w", err)
+		return lineInfo{}, fmt.Errorf("lookup of line: %w", err)
 	}
 
 	fileName, err := strings.Lookup(li.FileNameOff)
 	if err != nil {
-		return LineOffset{}, fmt.Errorf("lookup of filename: %w", err)
+		return lineInfo{}, fmt.Errorf("lookup of filename: %w", err)
 	}
 
 	lineNumber := li.LineCol >> bpfLineShift
 	lineColumn := li.LineCol & bpfColumnMax
 
-	return LineOffset{
-		asm.RawInstructionOffset(li.InsnOff),
+	return lineInfo{
 		&Line{
 			fileName,
 			line,
 			lineNumber,
 			lineColumn,
 		},
+		asm.RawInstructionOffset(li.InsnOff),
 	}, nil
 }
 
-func newLineInfos(blis []bpfLineInfo, strings *stringTable) (LineOffsets, error) {
-	lis := make([]LineOffset, 0, len(blis))
+func newLineInfos(blis []bpfLineInfo, strings *stringTable) (LineInfos, error) {
+	lis := LineInfos{
+		infos: make([]lineInfo, 0, len(blis)),
+	}
 	for _, bli := range blis {
 		li, err := newLineInfo(bli, strings)
 		if err != nil {
-			return LineOffsets{}, fmt.Errorf("offset %d: %w", bli.InsnOff, err)
+			return LineInfos{}, fmt.Errorf("offset %d: %w", bli.InsnOff, err)
 		}
-		lis = append(lis, li)
+		lis.infos = append(lis.infos, li)
 	}
-	sort.Slice(lis, func(i, j int) bool {
-		return lis[i].Offset <= lis[j].Offset
+	sort.Slice(lis.infos, func(i, j int) bool {
+		return lis.infos[i].offset <= lis.infos[j].offset
 	})
 	return lis, nil
 }
 
 // marshal writes the binary representation of the LineInfo to w.
-func (li *LineOffset) marshal(w *bytes.Buffer, b *Builder) error {
-	line := li.Line
+func (li *lineInfo) marshal(w *bytes.Buffer, b *Builder) error {
+	line := li.line
 	if line.lineNumber > bpfLineMax {
 		return fmt.Errorf("line %d exceeds %d", line.lineNumber, bpfLineMax)
 	}
@@ -620,7 +620,7 @@ func (li *LineOffset) marshal(w *bytes.Buffer, b *Builder) error {
 	}
 
 	bli := bpfLineInfo{
-		uint32(li.Offset),
+		uint32(li.offset),
 		fileNameOff,
 		lineOff,
 		(line.lineNumber << bpfLineShift) | line.lineColumn,
@@ -799,7 +799,7 @@ func parseCORERelos(r io.Reader, bo binary.ByteOrder, strings *stringTable) (map
 			return nil, err
 		}
 
-		records, err := parseCOREReloRecords(r, bo, infoHeader.NumInfo)
+		records, err := parseCOREReloRecords(r, bo, recordSize, infoHeader.NumInfo)
 		if err != nil {
 			return nil, fmt.Errorf("section %v: %w", secName, err)
 		}
@@ -811,7 +811,7 @@ func parseCORERelos(r io.Reader, bo binary.ByteOrder, strings *stringTable) (map
 // parseCOREReloRecords parses a stream of CO-RE relocation entries into a
 // coreRelos. These records appear after a btf_ext_info_sec header in the
 // core_relos sub-section of .BTF.ext.
-func parseCOREReloRecords(r io.Reader, bo binary.ByteOrder, recordNum uint32) ([]bpfCORERelo, error) {
+func parseCOREReloRecords(r io.Reader, bo binary.ByteOrder, recordSize uint32, recordNum uint32) ([]bpfCORERelo, error) {
 	var out []bpfCORERelo
 
 	var relo bpfCORERelo
diff --git a/vendor/github.com/cilium/ebpf/btf/feature.go b/vendor/github.com/cilium/ebpf/btf/feature.go
index e71c707f..6feb08df 100644
--- a/vendor/github.com/cilium/ebpf/btf/feature.go
+++ b/vendor/github.com/cilium/ebpf/btf/feature.go
@@ -11,19 +11,19 @@ import (
 
 // haveBTF attempts to load a BTF blob containing an Int. It should pass on any
 // kernel that supports BPF_BTF_LOAD.
-var haveBTF = internal.NewFeatureTest("BTF", func() error {
+var haveBTF = internal.NewFeatureTest("BTF", "4.18", func() error {
 	// 0-length anonymous integer
 	err := probeBTF(&Int{})
 	if errors.Is(err, unix.EINVAL) || errors.Is(err, unix.EPERM) {
 		return internal.ErrNotSupported
 	}
 	return err
-}, "4.18")
+})
 
 // haveMapBTF attempts to load a minimal BTF blob containing a Var. It is
 // used as a proxy for .bss, .data and .rodata map support, which generally
 // come with a Var and Datasec. These were introduced in Linux 5.2.
-var haveMapBTF = internal.NewFeatureTest("Map BTF (Var/Datasec)", func() error {
+var haveMapBTF = internal.NewFeatureTest("Map BTF (Var/Datasec)", "5.2", func() error {
 	if err := haveBTF(); err != nil {
 		return err
 	}
@@ -40,12 +40,12 @@ var haveMapBTF = internal.NewFeatureTest("Map BTF (Var/Datasec)", func() error {
 		return internal.ErrNotSupported
 	}
 	return err
-}, "5.2")
+})
 
 // haveProgBTF attempts to load a BTF blob containing a Func and FuncProto. It
 // is used as a proxy for ext_info (func_info) support, which depends on
 // Func(Proto) by definition.
-var haveProgBTF = internal.NewFeatureTest("Program BTF (func/line_info)", func() error {
+var haveProgBTF = internal.NewFeatureTest("Program BTF (func/line_info)", "5.0", func() error {
 	if err := haveBTF(); err != nil {
 		return err
 	}
@@ -60,9 +60,9 @@ var haveProgBTF = internal.NewFeatureTest("Program BTF (func/line_info)", func()
 		return internal.ErrNotSupported
 	}
 	return err
-}, "5.0")
+})
 
-var haveFuncLinkage = internal.NewFeatureTest("BTF func linkage", func() error {
+var haveFuncLinkage = internal.NewFeatureTest("BTF func linkage", "5.6", func() error {
 	if err := haveProgBTF(); err != nil {
 		return err
 	}
@@ -78,44 +78,9 @@ var haveFuncLinkage = internal.NewFeatureTest("BTF func linkage", func() error {
 		return internal.ErrNotSupported
 	}
 	return err
-}, "5.6")
+})
 
-var haveDeclTags = internal.NewFeatureTest("BTF decl tags", func() error {
-	if err := haveBTF(); err != nil {
-		return err
-	}
-
-	t := &Typedef{
-		Name: "a",
-		Type: &Int{},
-		Tags: []string{"a"},
-	}
-
-	err := probeBTF(t)
-	if errors.Is(err, unix.EINVAL) {
-		return internal.ErrNotSupported
-	}
-	return err
-}, "5.16")
-
-var haveTypeTags = internal.NewFeatureTest("BTF type tags", func() error {
-	if err := haveBTF(); err != nil {
-		return err
-	}
-
-	t := &TypeTag{
-		Type:  &Int{},
-		Value: "a",
-	}
-
-	err := probeBTF(t)
-	if errors.Is(err, unix.EINVAL) {
-		return internal.ErrNotSupported
-	}
-	return err
-}, "5.17")
-
-var haveEnum64 = internal.NewFeatureTest("ENUM64", func() error {
+var haveEnum64 = internal.NewFeatureTest("ENUM64", "6.0", func() error {
 	if err := haveBTF(); err != nil {
 		return err
 	}
@@ -132,7 +97,7 @@ var haveEnum64 = internal.NewFeatureTest("ENUM64", func() error {
 		return internal.ErrNotSupported
 	}
 	return err
-}, "6.0")
+})
 
 func probeBTF(typ Type) error {
 	b, err := NewBuilder([]Type{typ})
diff --git a/vendor/github.com/cilium/ebpf/btf/format.go b/vendor/github.com/cilium/ebpf/btf/format.go
index 3e0dedaa..5e581b4a 100644
--- a/vendor/github.com/cilium/ebpf/btf/format.go
+++ b/vendor/github.com/cilium/ebpf/btf/format.go
@@ -161,9 +161,6 @@ func (gf *GoFormatter) writeTypeLit(typ Type, depth int) error {
 	case *Datasec:
 		err = gf.writeDatasecLit(v, depth)
 
-	case *Var:
-		err = gf.writeTypeLit(v.Type, depth)
-
 	default:
 		return fmt.Errorf("type %T: %w", v, ErrNotSupported)
 	}
diff --git a/vendor/github.com/cilium/ebpf/btf/kernel.go b/vendor/github.com/cilium/ebpf/btf/kernel.go
index 1a9321f0..8584ebcb 100644
--- a/vendor/github.com/cilium/ebpf/btf/kernel.go
+++ b/vendor/github.com/cilium/ebpf/btf/kernel.go
@@ -8,7 +8,7 @@ import (
 	"sync"
 
 	"github.com/cilium/ebpf/internal"
-	"github.com/cilium/ebpf/internal/linux"
+	"github.com/cilium/ebpf/internal/kallsyms"
 )
 
 var kernelBTF = struct {
@@ -21,6 +21,8 @@ var kernelBTF = struct {
 
 // FlushKernelSpec removes any cached kernel type information.
 func FlushKernelSpec() {
+	kallsyms.FlushKernelModuleCache()
+
 	kernelBTF.Lock()
 	defer kernelBTF.Unlock()
 
@@ -128,7 +130,7 @@ func loadKernelModuleSpec(module string, base *Spec) (*Spec, error) {
 
 // findVMLinux scans multiple well-known paths for vmlinux kernel images.
 func findVMLinux() (*os.File, error) {
-	release, err := linux.KernelRelease()
+	release, err := internal.KernelRelease()
 	if err != nil {
 		return nil, err
 	}
diff --git a/vendor/github.com/cilium/ebpf/btf/marshal.go b/vendor/github.com/cilium/ebpf/btf/marshal.go
index d7204e62..f14cfa6e 100644
--- a/vendor/github.com/cilium/ebpf/btf/marshal.go
+++ b/vendor/github.com/cilium/ebpf/btf/marshal.go
@@ -18,10 +18,6 @@ type MarshalOptions struct {
 	Order binary.ByteOrder
 	// Remove function linkage information for compatibility with <5.6 kernels.
 	StripFuncLinkage bool
-	// Replace decl tags with a placeholder for compatibility with <5.16 kernels.
-	ReplaceDeclTags bool
-	// Replace TypeTags with a placeholder for compatibility with <5.17 kernels.
-	ReplaceTypeTags bool
 	// Replace Enum64 with a placeholder for compatibility with <6.0 kernels.
 	ReplaceEnum64 bool
 	// Prevent the "No type found" error when loading BTF without any types.
@@ -33,8 +29,6 @@ func KernelMarshalOptions() *MarshalOptions {
 	return &MarshalOptions{
 		Order:              internal.NativeEndian,
 		StripFuncLinkage:   haveFuncLinkage() != nil,
-		ReplaceDeclTags:    haveDeclTags() != nil,
-		ReplaceTypeTags:    haveTypeTags() != nil,
 		ReplaceEnum64:      haveEnum64() != nil,
 		PreventNoTypeFound: true, // All current kernels require this.
 	}
@@ -324,7 +318,15 @@ func (e *encoder) deflateType(typ Type) (err error) {
 		return errors.New("Void is implicit in BTF wire format")
 
 	case *Int:
-		e.deflateInt(&raw, v)
+		raw.SetKind(kindInt)
+		raw.SetSize(v.Size)
+
+		var bi btfInt
+		bi.SetEncoding(v.Encoding)
+		// We need to set bits in addition to size, since btf_type_int_is_regular
+		// otherwise flags this as a bitfield.
+		bi.SetBits(byte(v.Size) * 8)
+		raw.data = bi
 
 	case *Pointer:
 		raw.SetKind(kindPointer)
@@ -366,7 +368,8 @@ func (e *encoder) deflateType(typ Type) (err error) {
 		raw.SetType(e.id(v.Type))
 
 	case *Const:
-		e.deflateConst(&raw, v)
+		raw.SetKind(kindConst)
+		raw.SetType(e.id(v.Type))
 
 	case *Restrict:
 		raw.SetKind(kindRestrict)
@@ -401,10 +404,15 @@ func (e *encoder) deflateType(typ Type) (err error) {
 		raw.SetSize(v.Size)
 
 	case *declTag:
-		err = e.deflateDeclTag(&raw, v)
+		raw.SetKind(kindDeclTag)
+		raw.SetType(e.id(v.Type))
+		raw.data = &btfDeclTag{uint32(v.Index)}
+		raw.NameOff, err = e.strings.Add(v.Value)
 
-	case *TypeTag:
-		err = e.deflateTypeTag(&raw, v)
+	case *typeTag:
+		raw.SetKind(kindTypeTag)
+		raw.SetType(e.id(v.Type))
+		raw.NameOff, err = e.strings.Add(v.Value)
 
 	default:
 		return fmt.Errorf("don't know how to deflate %T", v)
@@ -417,57 +425,6 @@ func (e *encoder) deflateType(typ Type) (err error) {
 	return raw.Marshal(e.buf, e.Order)
 }
 
-func (e *encoder) deflateInt(raw *rawType, i *Int) {
-	raw.SetKind(kindInt)
-	raw.SetSize(i.Size)
-
-	var bi btfInt
-	bi.SetEncoding(i.Encoding)
-	// We need to set bits in addition to size, since btf_type_int_is_regular
-	// otherwise flags this as a bitfield.
-	bi.SetBits(byte(i.Size) * 8)
-	raw.data = bi
-}
-
-func (e *encoder) deflateDeclTag(raw *rawType, tag *declTag) (err error) {
-	// Replace a decl tag with an integer for compatibility with <5.16 kernels,
-	// following libbpf behaviour.
-	if e.ReplaceDeclTags {
-		typ := &Int{"decl_tag_placeholder", 1, Unsigned}
-		e.deflateInt(raw, typ)
-
-		// Add the placeholder type name to the string table. The encoder added the
-		// original type name before this call.
-		raw.NameOff, err = e.strings.Add(typ.TypeName())
-		return
-	}
-
-	raw.SetKind(kindDeclTag)
-	raw.SetType(e.id(tag.Type))
-	raw.data = &btfDeclTag{uint32(tag.Index)}
-	raw.NameOff, err = e.strings.Add(tag.Value)
-	return
-}
-
-func (e *encoder) deflateConst(raw *rawType, c *Const) {
-	raw.SetKind(kindConst)
-	raw.SetType(e.id(c.Type))
-}
-
-func (e *encoder) deflateTypeTag(raw *rawType, tag *TypeTag) (err error) {
-	// Replace a type tag with a const qualifier for compatibility with <5.17
-	// kernels, following libbpf behaviour.
-	if e.ReplaceTypeTags {
-		e.deflateConst(raw, &Const{tag.Type})
-		return
-	}
-
-	raw.SetKind(kindTypeTag)
-	raw.SetType(e.id(tag.Type))
-	raw.NameOff, err = e.strings.Add(tag.Value)
-	return
-}
-
 func (e *encoder) deflateUnion(raw *rawType, union *Union) (err error) {
 	raw.SetKind(kindUnion)
 	raw.SetSize(union.Size)
@@ -564,7 +521,7 @@ func (e *encoder) deflateEnum64(raw *rawType, enum *Enum) (err error) {
 			})
 		}
 
-		return e.deflateUnion(raw, &Union{enum.Name, enum.Size, members, nil})
+		return e.deflateUnion(raw, &Union{enum.Name, enum.Size, members})
 	}
 
 	raw.SetKind(kindEnum64)
diff --git a/vendor/github.com/cilium/ebpf/btf/traversal.go b/vendor/github.com/cilium/ebpf/btf/traversal.go
index 13647d93..c39dc66e 100644
--- a/vendor/github.com/cilium/ebpf/btf/traversal.go
+++ b/vendor/github.com/cilium/ebpf/btf/traversal.go
@@ -40,12 +40,9 @@ func children(typ Type, yield func(child *Type) bool) bool {
 	// Explicitly type switch on the most common types to allow the inliner to
 	// do its work. This avoids allocating intermediate slices from walk() on
 	// the heap.
-	var tags []string
 	switch v := typ.(type) {
-	case *Void, *Int, *Enum, *Fwd, *Float, *declTag:
+	case *Void, *Int, *Enum, *Fwd, *Float:
 		// No children to traverse.
-		// declTags is declared as a leaf type since it's parsed into .Tags fields of other types
-		// during unmarshaling.
 	case *Pointer:
 		if !yield(&v.Target) {
 			return false
@@ -62,32 +59,17 @@ func children(typ Type, yield func(child *Type) bool) bool {
 			if !yield(&v.Members[i].Type) {
 				return false
 			}
-			for _, t := range v.Members[i].Tags {
-				var tag Type = &declTag{v, t, i}
-				if !yield(&tag) {
-					return false
-				}
-			}
 		}
-		tags = v.Tags
 	case *Union:
 		for i := range v.Members {
 			if !yield(&v.Members[i].Type) {
 				return false
 			}
-			for _, t := range v.Members[i].Tags {
-				var tag Type = &declTag{v, t, i}
-				if !yield(&tag) {
-					return false
-				}
-			}
 		}
-		tags = v.Tags
 	case *Typedef:
 		if !yield(&v.Type) {
 			return false
 		}
-		tags = v.Tags
 	case *Volatile:
 		if !yield(&v.Type) {
 			return false
@@ -104,20 +86,6 @@ func children(typ Type, yield func(child *Type) bool) bool {
 		if !yield(&v.Type) {
 			return false
 		}
-		if fp, ok := v.Type.(*FuncProto); ok {
-			for i := range fp.Params {
-				if len(v.ParamTags) <= i {
-					continue
-				}
-				for _, t := range v.ParamTags[i] {
-					var tag Type = &declTag{v, t, i}
-					if !yield(&tag) {
-						return false
-					}
-				}
-			}
-		}
-		tags = v.Tags
 	case *FuncProto:
 		if !yield(&v.Return) {
 			return false
@@ -131,14 +99,17 @@ func children(typ Type, yield func(child *Type) bool) bool {
 		if !yield(&v.Type) {
 			return false
 		}
-		tags = v.Tags
 	case *Datasec:
 		for i := range v.Vars {
 			if !yield(&v.Vars[i].Type) {
 				return false
 			}
 		}
-	case *TypeTag:
+	case *declTag:
+		if !yield(&v.Type) {
+			return false
+		}
+	case *typeTag:
 		if !yield(&v.Type) {
 			return false
 		}
@@ -148,12 +119,5 @@ func children(typ Type, yield func(child *Type) bool) bool {
 		panic(fmt.Sprintf("don't know how to walk Type %T", v))
 	}
 
-	for _, t := range tags {
-		var tag Type = &declTag{typ, t, -1}
-		if !yield(&tag) {
-			return false
-		}
-	}
-
 	return true
 }
diff --git a/vendor/github.com/cilium/ebpf/btf/types.go b/vendor/github.com/cilium/ebpf/btf/types.go
index dbcdf9dd..a3397460 100644
--- a/vendor/github.com/cilium/ebpf/btf/types.go
+++ b/vendor/github.com/cilium/ebpf/btf/types.go
@@ -67,7 +67,7 @@ var (
 	_ Type = (*Datasec)(nil)
 	_ Type = (*Float)(nil)
 	_ Type = (*declTag)(nil)
-	_ Type = (*TypeTag)(nil)
+	_ Type = (*typeTag)(nil)
 	_ Type = (*cycle)(nil)
 )
 
@@ -169,7 +169,6 @@ type Struct struct {
 	// The size of the struct including padding, in bytes
 	Size    uint32
 	Members []Member
-	Tags    []string
 }
 
 func (s *Struct) Format(fs fmt.State, verb rune) {
@@ -183,7 +182,6 @@ func (s *Struct) size() uint32 { return s.Size }
 func (s *Struct) copy() Type {
 	cpy := *s
 	cpy.Members = copyMembers(s.Members)
-	cpy.Tags = copyTags(cpy.Tags)
 	return &cpy
 }
 
@@ -197,7 +195,6 @@ type Union struct {
 	// The size of the union including padding, in bytes.
 	Size    uint32
 	Members []Member
-	Tags    []string
 }
 
 func (u *Union) Format(fs fmt.State, verb rune) {
@@ -211,7 +208,6 @@ func (u *Union) size() uint32 { return u.Size }
 func (u *Union) copy() Type {
 	cpy := *u
 	cpy.Members = copyMembers(u.Members)
-	cpy.Tags = copyTags(cpy.Tags)
 	return &cpy
 }
 
@@ -222,18 +218,6 @@ func (u *Union) members() []Member {
 func copyMembers(orig []Member) []Member {
 	cpy := make([]Member, len(orig))
 	copy(cpy, orig)
-	for i, member := range cpy {
-		cpy[i].Tags = copyTags(member.Tags)
-	}
-	return cpy
-}
-
-func copyTags(orig []string) []string {
-	if orig == nil { // preserve nil vs zero-len slice distinction
-		return nil
-	}
-	cpy := make([]string, len(orig))
-	copy(cpy, orig)
 	return cpy
 }
 
@@ -263,7 +247,6 @@ type Member struct {
 	Type         Type
 	Offset       Bits
 	BitfieldSize Bits
-	Tags         []string
 }
 
 // Enum lists possible values.
@@ -351,7 +334,6 @@ func (f *Fwd) matches(typ Type) bool {
 type Typedef struct {
 	Name string
 	Type Type
-	Tags []string
 }
 
 func (td *Typedef) Format(fs fmt.State, verb rune) {
@@ -362,7 +344,6 @@ func (td *Typedef) TypeName() string { return td.Name }
 
 func (td *Typedef) copy() Type {
 	cpy := *td
-	cpy.Tags = copyTags(td.Tags)
 	return &cpy
 }
 
@@ -422,12 +403,6 @@ type Func struct {
 	Name    string
 	Type    Type
 	Linkage FuncLinkage
-	Tags    []string
-	// ParamTags holds a list of tags for each parameter of the FuncProto to which `Type` points.
-	// If no tags are present for any param, the outer slice will be nil/len(ParamTags)==0.
-	// If at least 1 param has a tag, the outer slice will have the same length as the number of params.
-	// The inner slice contains the tags and may be nil/len(ParamTags[i])==0 if no tags are present for that param.
-	ParamTags [][]string
 }
 
 func FuncMetadata(ins *asm.Instruction) *Func {
@@ -449,14 +424,6 @@ func (f *Func) TypeName() string { return f.Name }
 
 func (f *Func) copy() Type {
 	cpy := *f
-	cpy.Tags = copyTags(f.Tags)
-	if f.ParamTags != nil { // preserve nil vs zero-len slice distinction
-		ptCopy := make([][]string, len(f.ParamTags))
-		for i, tags := range f.ParamTags {
-			ptCopy[i] = copyTags(tags)
-		}
-		cpy.ParamTags = ptCopy
-	}
 	return &cpy
 }
 
@@ -489,7 +456,6 @@ type Var struct {
 	Name    string
 	Type    Type
 	Linkage VarLinkage
-	Tags    []string
 }
 
 func (v *Var) Format(fs fmt.State, verb rune) {
@@ -500,7 +466,6 @@ func (v *Var) TypeName() string { return v.Name }
 
 func (v *Var) copy() Type {
 	cpy := *v
-	cpy.Tags = copyTags(v.Tags)
 	return &cpy
 }
 
@@ -575,25 +540,19 @@ func (dt *declTag) copy() Type {
 	return &cpy
 }
 
-// TypeTag associates metadata with a pointer type. Tag types act as a custom
-// modifier(const, restrict, volatile) for the target type. Unlike declTags,
-// TypeTags are ordered so the order in which they are added matters.
-//
-// One of their uses is to mark pointers as `__kptr` meaning a pointer points
-// to kernel memory. Adding a `__kptr` to pointers in map values allows you
-// to store pointers to kernel memory in maps.
-type TypeTag struct {
+// typeTag associates metadata with a type.
+type typeTag struct {
 	Type  Type
 	Value string
 }
 
-func (tt *TypeTag) Format(fs fmt.State, verb rune) {
+func (tt *typeTag) Format(fs fmt.State, verb rune) {
 	formatType(fs, verb, tt, "type=", tt.Type, "value=", tt.Value)
 }
 
-func (tt *TypeTag) TypeName() string { return "" }
-func (tt *TypeTag) qualify() Type    { return tt.Type }
-func (tt *TypeTag) copy() Type {
+func (tt *typeTag) TypeName() string { return "" }
+func (tt *typeTag) qualify() Type    { return tt.Type }
+func (tt *typeTag) copy() Type {
 	cpy := *tt
 	return &cpy
 }
@@ -632,7 +591,7 @@ var (
 	_ qualifier = (*Const)(nil)
 	_ qualifier = (*Restrict)(nil)
 	_ qualifier = (*Volatile)(nil)
-	_ qualifier = (*TypeTag)(nil)
+	_ qualifier = (*typeTag)(nil)
 )
 
 var errUnsizedType = errors.New("type is unsized")
@@ -959,7 +918,7 @@ func readAndInflateTypes(r io.Reader, bo binary.ByteOrder, typeLen uint32, rawSt
 			if err != nil {
 				return nil, fmt.Errorf("struct %s (id %d): %w", name, id, err)
 			}
-			typ = &Struct{name, header.Size(), members, nil}
+			typ = &Struct{name, header.Size(), members}
 
 		case kindUnion:
 			vlen := header.Vlen()
@@ -976,7 +935,7 @@ func readAndInflateTypes(r io.Reader, bo binary.ByteOrder, typeLen uint32, rawSt
 			if err != nil {
 				return nil, fmt.Errorf("union %s (id %d): %w", name, id, err)
 			}
-			typ = &Union{name, header.Size(), members, nil}
+			typ = &Union{name, header.Size(), members}
 
 		case kindEnum:
 			vlen := header.Vlen()
@@ -1009,7 +968,7 @@ func readAndInflateTypes(r io.Reader, bo binary.ByteOrder, typeLen uint32, rawSt
 			typ = &Fwd{name, header.FwdKind()}
 
 		case kindTypedef:
-			typedef := &Typedef{name, nil, nil}
+			typedef := &Typedef{name, nil}
 			fixup(header.Type(), &typedef.Type)
 			typ = typedef
 
@@ -1029,7 +988,7 @@ func readAndInflateTypes(r io.Reader, bo binary.ByteOrder, typeLen uint32, rawSt
 			typ = restrict
 
 		case kindFunc:
-			fn := &Func{name, nil, header.Linkage(), nil, nil}
+			fn := &Func{name, nil, header.Linkage()}
 			fixup(header.Type(), &fn.Type)
 			typ = fn
 
@@ -1071,7 +1030,7 @@ func readAndInflateTypes(r io.Reader, bo binary.ByteOrder, typeLen uint32, rawSt
 				return nil, fmt.Errorf("can't read btfVariable, id: %d: %w", id, err)
 			}
 
-			v := &Var{name, nil, VarLinkage(bVariable.Linkage), nil}
+			v := &Var{name, nil, VarLinkage(bVariable.Linkage)}
 			fixup(header.Type(), &v.Type)
 			typ = v
 
@@ -1122,7 +1081,7 @@ func readAndInflateTypes(r io.Reader, bo binary.ByteOrder, typeLen uint32, rawSt
 			declTags = append(declTags, dt)
 
 		case kindTypeTag:
-			tt := &TypeTag{nil, name}
+			tt := &typeTag{nil, name}
 			fixup(header.Type(), &tt.Type)
 			typ = tt
 
@@ -1183,69 +1142,26 @@ func readAndInflateTypes(r io.Reader, bo binary.ByteOrder, typeLen uint32, rawSt
 
 	for _, dt := range declTags {
 		switch t := dt.Type.(type) {
-		case *Var:
-			if dt.Index != -1 {
-				return nil, fmt.Errorf("type %s: component idx %d is not -1", dt, dt.Index)
-			}
-			t.Tags = append(t.Tags, dt.Value)
-
-		case *Typedef:
+		case *Var, *Typedef:
 			if dt.Index != -1 {
-				return nil, fmt.Errorf("type %s: component idx %d is not -1", dt, dt.Index)
+				return nil, fmt.Errorf("type %s: index %d is not -1", dt, dt.Index)
 			}
-			t.Tags = append(t.Tags, dt.Value)
 
 		case composite:
-			if dt.Index >= 0 {
-				members := t.members()
-				if dt.Index >= len(members) {
-					return nil, fmt.Errorf("type %s: component idx %d exceeds members of %s", dt, dt.Index, t)
-				}
-
-				members[dt.Index].Tags = append(members[dt.Index].Tags, dt.Value)
-				continue
-			}
-
-			if dt.Index == -1 {
-				switch t2 := t.(type) {
-				case *Struct:
-					t2.Tags = append(t2.Tags, dt.Value)
-				case *Union:
-					t2.Tags = append(t2.Tags, dt.Value)
-				}
-
-				continue
+			if dt.Index >= len(t.members()) {
+				return nil, fmt.Errorf("type %s: index %d exceeds members of %s", dt, dt.Index, t)
 			}
 
-			return nil, fmt.Errorf("type %s: decl tag for type %s has invalid component idx", dt, t)
-
 		case *Func:
 			fp, ok := t.Type.(*FuncProto)
 			if !ok {
 				return nil, fmt.Errorf("type %s: %s is not a FuncProto", dt, t.Type)
 			}
 
-			// Ensure the number of argument tag lists equals the number of arguments
-			if len(t.ParamTags) == 0 {
-				t.ParamTags = make([][]string, len(fp.Params))
-			}
-
-			if dt.Index >= 0 {
-				if dt.Index >= len(fp.Params) {
-					return nil, fmt.Errorf("type %s: component idx %d exceeds params of %s", dt, dt.Index, t)
-				}
-
-				t.ParamTags[dt.Index] = append(t.ParamTags[dt.Index], dt.Value)
-				continue
+			if dt.Index >= len(fp.Params) {
+				return nil, fmt.Errorf("type %s: index %d exceeds params of %s", dt, dt.Index, t)
 			}
 
-			if dt.Index == -1 {
-				t.Tags = append(t.Tags, dt.Value)
-				continue
-			}
-
-			return nil, fmt.Errorf("type %s: decl tag for type %s has invalid component idx", dt, t)
-
 		default:
 			return nil, fmt.Errorf("type %s: decl tag for type %s is not supported", dt, t)
 		}
@@ -1291,20 +1207,6 @@ func UnderlyingType(typ Type) Type {
 	return &cycle{typ}
 }
 
-// QualifiedType returns the type with all qualifiers removed.
-func QualifiedType(typ Type) Type {
-	result := typ
-	for depth := 0; depth <= maxResolveDepth; depth++ {
-		switch v := (result).(type) {
-		case qualifier:
-			result = v.qualify()
-		default:
-			return result
-		}
-	}
-	return &cycle{typ}
-}
-
 // As returns typ if is of type T. Otherwise it peels qualifiers and Typedefs
 // until it finds a T.
 //
diff --git a/vendor/github.com/cilium/ebpf/btf/workarounds.go b/vendor/github.com/cilium/ebpf/btf/workarounds.go
index eb09047f..12a89b87 100644
--- a/vendor/github.com/cilium/ebpf/btf/workarounds.go
+++ b/vendor/github.com/cilium/ebpf/btf/workarounds.go
@@ -12,7 +12,7 @@ func datasecResolveWorkaround(b *Builder, ds *Datasec) error {
 		}
 
 		switch v.Type.(type) {
-		case *Typedef, *Volatile, *Const, *Restrict, *TypeTag:
+		case *Typedef, *Volatile, *Const, *Restrict, *typeTag:
 			// NB: We must never call Add on a Datasec, otherwise we risk
 			// infinite recursion.
 			_, err := b.Add(v.Type)
diff --git a/vendor/github.com/cilium/ebpf/collection.go b/vendor/github.com/cilium/ebpf/collection.go
index 1bda110a..b2cb214a 100644
--- a/vendor/github.com/cilium/ebpf/collection.go
+++ b/vendor/github.com/cilium/ebpf/collection.go
@@ -10,10 +10,8 @@ import (
 	"github.com/cilium/ebpf/asm"
 	"github.com/cilium/ebpf/btf"
 	"github.com/cilium/ebpf/internal"
-	"github.com/cilium/ebpf/internal/kallsyms"
 	"github.com/cilium/ebpf/internal/kconfig"
-	"github.com/cilium/ebpf/internal/linux"
-	"github.com/cilium/ebpf/internal/sys"
+	"github.com/cilium/ebpf/internal/sysenc"
 )
 
 // CollectionOptions control loading a collection into the kernel.
@@ -40,11 +38,6 @@ type CollectionSpec struct {
 	Maps     map[string]*MapSpec
 	Programs map[string]*ProgramSpec
 
-	// Variables refer to global variables declared in the ELF. They can be read
-	// and modified freely before loading the Collection. Modifying them after
-	// loading has no effect on a running eBPF program.
-	Variables map[string]*VariableSpec
-
 	// Types holds type information about Maps and Programs.
 	// Modifications to Types are currently undefined behaviour.
 	Types *btf.Spec
@@ -63,7 +56,6 @@ func (cs *CollectionSpec) Copy() *CollectionSpec {
 	cpy := CollectionSpec{
 		Maps:      make(map[string]*MapSpec, len(cs.Maps)),
 		Programs:  make(map[string]*ProgramSpec, len(cs.Programs)),
-		Variables: make(map[string]*VariableSpec, len(cs.Variables)),
 		ByteOrder: cs.ByteOrder,
 		Types:     cs.Types.Copy(),
 	}
@@ -76,10 +68,6 @@ func (cs *CollectionSpec) Copy() *CollectionSpec {
 		cpy.Programs[name] = spec.Copy()
 	}
 
-	for name, spec := range cs.Variables {
-		cpy.Variables[name] = spec.copy(&cpy)
-	}
-
 	return &cpy
 }
 
@@ -146,24 +134,65 @@ func (m *MissingConstantsError) Error() string {
 // From Linux 5.5 the verifier will use constants to eliminate dead code.
 //
 // Returns an error wrapping [MissingConstantsError] if a constant doesn't exist.
-//
-// Deprecated: Use [CollectionSpec.Variables] to interact with constants instead.
-// RewriteConstants is now a wrapper around the VariableSpec API.
 func (cs *CollectionSpec) RewriteConstants(consts map[string]interface{}) error {
-	var missing []string
-	for n, c := range consts {
-		v, ok := cs.Variables[n]
-		if !ok {
-			missing = append(missing, n)
+	replaced := make(map[string]bool)
+
+	for name, spec := range cs.Maps {
+		if !strings.HasPrefix(name, ".rodata") {
 			continue
 		}
 
-		if !v.Constant() {
-			return fmt.Errorf("variable %s is not a constant", n)
+		b, ds, err := spec.dataSection()
+		if errors.Is(err, errMapNoBTFValue) {
+			// Data sections without a BTF Datasec are valid, but don't support
+			// constant replacements.
+			continue
+		}
+		if err != nil {
+			return fmt.Errorf("map %s: %w", name, err)
 		}
 
-		if err := v.Set(c); err != nil {
-			return fmt.Errorf("rewriting constant %s: %w", n, err)
+		// MapSpec.Copy() performs a shallow copy. Fully copy the byte slice
+		// to avoid any changes affecting other copies of the MapSpec.
+		cpy := make([]byte, len(b))
+		copy(cpy, b)
+
+		for _, v := range ds.Vars {
+			vname := v.Type.TypeName()
+			replacement, ok := consts[vname]
+			if !ok {
+				continue
+			}
+
+			if _, ok := v.Type.(*btf.Var); !ok {
+				return fmt.Errorf("section %s: unexpected type %T for variable %s", name, v.Type, vname)
+			}
+
+			if replaced[vname] {
+				return fmt.Errorf("section %s: duplicate variable %s", name, vname)
+			}
+
+			if int(v.Offset+v.Size) > len(cpy) {
+				return fmt.Errorf("section %s: offset %d(+%d) for variable %s is out of bounds", name, v.Offset, v.Size, vname)
+			}
+
+			b, err := sysenc.Marshal(replacement, int(v.Size))
+			if err != nil {
+				return fmt.Errorf("marshaling constant replacement %s: %w", vname, err)
+			}
+
+			b.CopyTo(cpy[v.Offset : v.Offset+v.Size])
+
+			replaced[vname] = true
+		}
+
+		spec.Contents[0] = MapKV{Key: uint32(0), Value: cpy}
+	}
+
+	var missing []string
+	for c := range consts {
+		if !replaced[c] {
+			missing = append(missing, c)
 		}
 	}
 
@@ -181,23 +210,25 @@ func (cs *CollectionSpec) RewriteConstants(consts map[string]interface{}) error
 // if this sounds useful.
 //
 // 'to' must be a pointer to a struct. A field of the
-// struct is updated with values from Programs, Maps or Variables if it
-// has an `ebpf` tag and its type is *ProgramSpec, *MapSpec or *VariableSpec.
+// struct is updated with values from Programs or Maps if it
+// has an `ebpf` tag and its type is *ProgramSpec or *MapSpec.
 // The tag's value specifies the name of the program or map as
 // found in the CollectionSpec.
 //
 //	struct {
-//	    Foo     *ebpf.ProgramSpec  `ebpf:"xdp_foo"`
-//	    Bar     *ebpf.MapSpec      `ebpf:"bar_map"`
-//	    Var     *ebpf.VariableSpec `ebpf:"some_var"`
+//	    Foo     *ebpf.ProgramSpec `ebpf:"xdp_foo"`
+//	    Bar     *ebpf.MapSpec     `ebpf:"bar_map"`
 //	    Ignored int
 //	}
 //
 // Returns an error if any of the eBPF objects can't be found, or
-// if the same Spec is assigned multiple times.
+// if the same MapSpec or ProgramSpec is assigned multiple times.
 func (cs *CollectionSpec) Assign(to interface{}) error {
+	// Assign() only supports assigning ProgramSpecs and MapSpecs,
+	// so doesn't load any resources into the kernel.
 	getValue := func(typ reflect.Type, name string) (interface{}, error) {
 		switch typ {
+
 		case reflect.TypeOf((*ProgramSpec)(nil)):
 			if p := cs.Programs[name]; p != nil {
 				return p, nil
@@ -210,12 +241,6 @@ func (cs *CollectionSpec) Assign(to interface{}) error {
 			}
 			return nil, fmt.Errorf("missing map %q", name)
 
-		case reflect.TypeOf((*VariableSpec)(nil)):
-			if v := cs.Variables[name]; v != nil {
-				return v, nil
-			}
-			return nil, fmt.Errorf("missing variable %q", name)
-
 		default:
 			return nil, fmt.Errorf("unsupported type %s", typ)
 		}
@@ -261,7 +286,6 @@ func (cs *CollectionSpec) LoadAndAssign(to interface{}, opts *CollectionOptions)
 	// Support assigning Programs and Maps, lazy-loading the required objects.
 	assignedMaps := make(map[string]bool)
 	assignedProgs := make(map[string]bool)
-	assignedVars := make(map[string]bool)
 
 	getValue := func(typ reflect.Type, name string) (interface{}, error) {
 		switch typ {
@@ -274,10 +298,6 @@ func (cs *CollectionSpec) LoadAndAssign(to interface{}, opts *CollectionOptions)
 			assignedMaps[name] = true
 			return loader.loadMap(name)
 
-		case reflect.TypeOf((*Variable)(nil)):
-			assignedVars[name] = true
-			return loader.loadVariable(name)
-
 		default:
 			return nil, fmt.Errorf("unsupported type %s", typ)
 		}
@@ -318,22 +338,15 @@ func (cs *CollectionSpec) LoadAndAssign(to interface{}, opts *CollectionOptions)
 	for p := range assignedProgs {
 		delete(loader.programs, p)
 	}
-	for p := range assignedVars {
-		delete(loader.vars, p)
-	}
 
 	return nil
 }
 
-// Collection is a collection of live BPF resources present in the kernel.
+// Collection is a collection of Programs and Maps associated
+// with their symbols
 type Collection struct {
 	Programs map[string]*Program
 	Maps     map[string]*Map
-
-	// Variables contains global variables used by the Collection's program(s). On
-	// kernels older than 5.5, most interactions with Variables return
-	// [ErrNotSupported].
-	Variables map[string]*Variable
 }
 
 // NewCollection creates a Collection from the given spec, creating and
@@ -374,26 +387,19 @@ func NewCollectionWithOptions(spec *CollectionSpec, opts CollectionOptions) (*Co
 		}
 	}
 
-	for varName := range spec.Variables {
-		if _, err := loader.loadVariable(varName); err != nil {
-			return nil, err
-		}
-	}
-
 	// Maps can contain Program and Map stubs, so populate them after
 	// all Maps and Programs have been successfully loaded.
 	if err := loader.populateDeferredMaps(); err != nil {
 		return nil, err
 	}
 
-	// Prevent loader.cleanup from closing maps, programs and vars.
-	maps, progs, vars := loader.maps, loader.programs, loader.vars
-	loader.maps, loader.programs, loader.vars = nil, nil, nil
+	// Prevent loader.cleanup from closing maps and programs.
+	maps, progs := loader.maps, loader.programs
+	loader.maps, loader.programs = nil, nil
 
 	return &Collection{
 		progs,
 		maps,
-		vars,
 	}, nil
 }
 
@@ -402,7 +408,6 @@ type collectionLoader struct {
 	opts     *CollectionOptions
 	maps     map[string]*Map
 	programs map[string]*Program
-	vars     map[string]*Variable
 }
 
 func newCollectionLoader(coll *CollectionSpec, opts *CollectionOptions) (*collectionLoader, error) {
@@ -422,58 +427,14 @@ func newCollectionLoader(coll *CollectionSpec, opts *CollectionOptions) (*collec
 		}
 	}
 
-	if err := populateKallsyms(coll.Programs); err != nil {
-		return nil, fmt.Errorf("populating kallsyms caches: %w", err)
-	}
-
 	return &collectionLoader{
 		coll,
 		opts,
 		make(map[string]*Map),
 		make(map[string]*Program),
-		make(map[string]*Variable),
 	}, nil
 }
 
-// populateKallsyms populates kallsyms caches, making lookups cheaper later on
-// during individual program loading. Since we have less context available
-// at those stages, we batch the lookups here instead to avoid redundant work.
-func populateKallsyms(progs map[string]*ProgramSpec) error {
-	// Look up associated kernel modules for all symbols referenced by
-	// ProgramSpec.AttachTo for program types that support attaching to kmods.
-	mods := make(map[string]string)
-	for _, p := range progs {
-		if p.AttachTo != "" && p.targetsKernelModule() {
-			mods[p.AttachTo] = ""
-		}
-	}
-	if len(mods) != 0 {
-		if err := kallsyms.AssignModules(mods); err != nil {
-			return fmt.Errorf("getting modules from kallsyms: %w", err)
-		}
-	}
-
-	// Look up addresses of all kernel symbols referenced by all programs.
-	addrs := make(map[string]uint64)
-	for _, p := range progs {
-		iter := p.Instructions.Iterate()
-		for iter.Next() {
-			ins := iter.Ins
-			meta, _ := ins.Metadata.Get(ksymMetaKey{}).(*ksymMeta)
-			if meta != nil {
-				addrs[meta.Name] = 0
-			}
-		}
-	}
-	if len(addrs) != 0 {
-		if err := kallsyms.AssignAddresses(addrs); err != nil {
-			return fmt.Errorf("getting addresses from kallsyms: %w", err)
-		}
-	}
-
-	return nil
-}
-
 // close all resources left over in the collectionLoader.
 func (cl *collectionLoader) close() {
 	for _, m := range cl.maps {
@@ -505,13 +466,6 @@ func (cl *collectionLoader) loadMap(mapName string) (*Map, error) {
 		return m, nil
 	}
 
-	// Defer setting the mmapable flag on maps until load time. This avoids the
-	// MapSpec having different flags on some kernel versions. Also avoid running
-	// syscalls during ELF loading, so platforms like wasm can also parse an ELF.
-	if isDataSection(mapSpec.Name) && haveMmapableMaps() == nil {
-		mapSpec.Flags |= sys.BPF_F_MMAPABLE
-	}
-
 	m, err := newMapWithOptions(mapSpec, cl.opts.Maps)
 	if err != nil {
 		return nil, fmt.Errorf("map %s: %w", mapName, err)
@@ -583,58 +537,6 @@ func (cl *collectionLoader) loadProgram(progName string) (*Program, error) {
 	return prog, nil
 }
 
-func (cl *collectionLoader) loadVariable(varName string) (*Variable, error) {
-	if v := cl.vars[varName]; v != nil {
-		return v, nil
-	}
-
-	varSpec := cl.coll.Variables[varName]
-	if varSpec == nil {
-		return nil, fmt.Errorf("unknown variable %s", varName)
-	}
-
-	// Get the key of the VariableSpec's MapSpec in the CollectionSpec.
-	var mapName string
-	for n, ms := range cl.coll.Maps {
-		if ms == varSpec.m {
-			mapName = n
-			break
-		}
-	}
-	if mapName == "" {
-		return nil, fmt.Errorf("variable %s: underlying MapSpec %s was removed from CollectionSpec", varName, varSpec.m.Name)
-	}
-
-	m, err := cl.loadMap(mapName)
-	if err != nil {
-		return nil, fmt.Errorf("variable %s: %w", varName, err)
-	}
-
-	// If the kernel is too old or the underlying map was created without
-	// BPF_F_MMAPABLE, [Map.Memory] will return ErrNotSupported. In this case,
-	// emit a Variable with a nil Memory. This keeps Collection{Spec}.Variables
-	// consistent across systems with different feature sets without breaking
-	// LoadAndAssign.
-	mm, err := m.Memory()
-	if err != nil && !errors.Is(err, ErrNotSupported) {
-		return nil, fmt.Errorf("variable %s: getting memory for map %s: %w", varName, mapName, err)
-	}
-
-	v, err := newVariable(
-		varSpec.name,
-		varSpec.offset,
-		varSpec.size,
-		varSpec.t,
-		mm,
-	)
-	if err != nil {
-		return nil, fmt.Errorf("variable %s: %w", varName, err)
-	}
-
-	cl.vars[varName] = v
-	return v, nil
-}
-
 // populateDeferredMaps iterates maps holding programs or other maps and loads
 // any dependencies. Populates all maps in cl and freezes them if specified.
 func (cl *collectionLoader) populateDeferredMaps() error {
@@ -701,7 +603,6 @@ func resolveKconfig(m *MapSpec) error {
 
 	type configInfo struct {
 		offset uint32
-		size   uint32
 		typ    btf.Type
 	}
 
@@ -718,7 +619,7 @@ func resolveKconfig(m *MapSpec) error {
 				return fmt.Errorf("variable %s must be a 32 bits integer, got %s", n, v.Type)
 			}
 
-			kv, err := linux.KernelVersion()
+			kv, err := internal.KernelVersion()
 			if err != nil {
 				return fmt.Errorf("getting kernel version: %w", err)
 			}
@@ -743,7 +644,6 @@ func resolveKconfig(m *MapSpec) error {
 		default: // Catch CONFIG_*.
 			configs[n] = configInfo{
 				offset: vsi.Offset,
-				size:   vsi.Size,
 				typ:    v.Type,
 			}
 		}
@@ -751,7 +651,7 @@ func resolveKconfig(m *MapSpec) error {
 
 	// We only parse kconfig file if a CONFIG_* variable was found.
 	if len(configs) > 0 {
-		f, err := linux.FindKConfig()
+		f, err := kconfig.Find()
 		if err != nil {
 			return fmt.Errorf("cannot find a kconfig file: %w", err)
 		}
@@ -770,10 +670,10 @@ func resolveKconfig(m *MapSpec) error {
 		for n, info := range configs {
 			value, ok := kernelConfig[n]
 			if !ok {
-				return fmt.Errorf("config option %q does not exist on this kernel", n)
+				return fmt.Errorf("config option %q does not exists for this kernel", n)
 			}
 
-			err := kconfig.PutValue(data[info.offset:info.offset+info.size], info.typ, value)
+			err := kconfig.PutValue(data[info.offset:], info.typ, value)
 			if err != nil {
 				return fmt.Errorf("problem adding value for %s: %w", n, err)
 			}
@@ -823,7 +723,6 @@ func LoadCollection(file string) (*Collection, error) {
 func (coll *Collection) Assign(to interface{}) error {
 	assignedMaps := make(map[string]bool)
 	assignedProgs := make(map[string]bool)
-	assignedVars := make(map[string]bool)
 
 	// Assign() only transfers already-loaded Maps and Programs. No extra
 	// loading is done.
@@ -844,13 +743,6 @@ func (coll *Collection) Assign(to interface{}) error {
 			}
 			return nil, fmt.Errorf("missing map %q", name)
 
-		case reflect.TypeOf((*Variable)(nil)):
-			if v := coll.Variables[name]; v != nil {
-				assignedVars[name] = true
-				return v, nil
-			}
-			return nil, fmt.Errorf("missing variable %q", name)
-
 		default:
 			return nil, fmt.Errorf("unsupported type %s", typ)
 		}
@@ -867,9 +759,6 @@ func (coll *Collection) Assign(to interface{}) error {
 	for m := range assignedMaps {
 		delete(coll.Maps, m)
 	}
-	for s := range assignedVars {
-		delete(coll.Variables, s)
-	}
 
 	return nil
 }
diff --git a/vendor/github.com/cilium/ebpf/elf_reader.go b/vendor/github.com/cilium/ebpf/elf_reader.go
index 9e8dbc7a..620037d8 100644
--- a/vendor/github.com/cilium/ebpf/elf_reader.go
+++ b/vendor/github.com/cilium/ebpf/elf_reader.go
@@ -16,6 +16,7 @@ import (
 	"github.com/cilium/ebpf/btf"
 	"github.com/cilium/ebpf/internal"
 	"github.com/cilium/ebpf/internal/sys"
+	"github.com/cilium/ebpf/internal/unix"
 )
 
 type kconfigMetaKey struct{}
@@ -32,13 +33,6 @@ type kfuncMeta struct {
 	Func    *btf.Func
 }
 
-type ksymMetaKey struct{}
-
-type ksymMeta struct {
-	Binding elf.SymBind
-	Name    string
-}
-
 // elfCode is a convenience to reduce the amount of arguments that have to
 // be passed around explicitly. You should treat its contents as immutable.
 type elfCode struct {
@@ -49,9 +43,7 @@ type elfCode struct {
 	btf      *btf.Spec
 	extInfo  *btf.ExtInfos
 	maps     map[string]*MapSpec
-	vars     map[string]*VariableSpec
 	kfuncs   map[string]*btf.Func
-	ksyms    map[string]struct{}
 	kconfig  *MapSpec
 }
 
@@ -79,7 +71,7 @@ func LoadCollectionSpecFromReader(rd io.ReaderAt) (*CollectionSpec, error) {
 
 	// Checks if the ELF file is for BPF data.
 	// Old LLVM versions set e_machine to EM_NONE.
-	if f.File.Machine != elf.EM_NONE && f.File.Machine != elf.EM_BPF {
+	if f.File.Machine != unix.EM_NONE && f.File.Machine != elf.EM_BPF {
 		return nil, fmt.Errorf("unexpected machine type for BPF ELF: %s", f.File.Machine)
 	}
 
@@ -109,7 +101,7 @@ func LoadCollectionSpecFromReader(rd io.ReaderAt) (*CollectionSpec, error) {
 			sections[idx] = newElfSection(sec, mapSection)
 		case sec.Name == ".maps":
 			sections[idx] = newElfSection(sec, btfMapSection)
-		case isDataSection(sec.Name):
+		case sec.Name == ".bss" || sec.Name == ".data" || strings.HasPrefix(sec.Name, ".rodata"):
 			sections[idx] = newElfSection(sec, dataSection)
 		case sec.Type == elf.SHT_REL:
 			// Store relocations under the section index of the target
@@ -142,9 +134,7 @@ func LoadCollectionSpecFromReader(rd io.ReaderAt) (*CollectionSpec, error) {
 		btf:         btfSpec,
 		extInfo:     btfExtInfo,
 		maps:        make(map[string]*MapSpec),
-		vars:        make(map[string]*VariableSpec),
 		kfuncs:      make(map[string]*btf.Func),
-		ksyms:       make(map[string]struct{}),
 	}
 
 	symbols, err := f.Symbols()
@@ -184,7 +174,7 @@ func LoadCollectionSpecFromReader(rd io.ReaderAt) (*CollectionSpec, error) {
 		return nil, fmt.Errorf("load programs: %w", err)
 	}
 
-	return &CollectionSpec{ec.maps, progs, ec.vars, btfSpec, ec.ByteOrder}, nil
+	return &CollectionSpec{ec.maps, progs, btfSpec, ec.ByteOrder}, nil
 }
 
 func loadLicense(sec *elf.Section) (string, error) {
@@ -211,18 +201,6 @@ func loadVersion(sec *elf.Section, bo binary.ByteOrder) (uint32, error) {
 	return version, nil
 }
 
-func isDataSection(name string) bool {
-	return name == ".bss" || strings.HasPrefix(name, ".data") || strings.HasPrefix(name, ".rodata")
-}
-
-func isConstantDataSection(name string) bool {
-	return strings.HasPrefix(name, ".rodata")
-}
-
-func isKconfigSection(name string) bool {
-	return name == ".kconfig"
-}
-
 type elfSectionKind int
 
 const (
@@ -528,7 +506,7 @@ func (ec *elfCode) relocateInstruction(ins *asm.Instruction, rel elf.Symbol) err
 
 		case elf.STT_OBJECT:
 			// LLVM 9 emits OBJECT-LOCAL symbols for anonymous constants.
-			if bind != elf.STB_GLOBAL && bind != elf.STB_LOCAL && bind != elf.STB_WEAK {
+			if bind != elf.STB_GLOBAL && bind != elf.STB_LOCAL {
 				return fmt.Errorf("direct load: %s: %w: %s", name, errUnsupportedBinding, bind)
 			}
 
@@ -636,8 +614,6 @@ func (ec *elfCode) relocateInstruction(ins *asm.Instruction, rel elf.Symbol) err
 		}
 
 		kf := ec.kfuncs[name]
-		_, ks := ec.ksyms[name]
-
 		switch {
 		// If a Call / DWordLoad instruction is found and the datasec has a btf.Func with a Name
 		// that matches the symbol name we mark the instruction as a referencing a kfunc.
@@ -658,15 +634,6 @@ func (ec *elfCode) relocateInstruction(ins *asm.Instruction, rel elf.Symbol) err
 
 			ins.Constant = 0
 
-		case ks && ins.OpCode.IsDWordLoad():
-			if bind != elf.STB_GLOBAL && bind != elf.STB_WEAK {
-				return fmt.Errorf("asm relocation: %s: %w: %s", name, errUnsupportedBinding, bind)
-			}
-			ins.Metadata.Set(ksymMetaKey{}, &ksymMeta{
-				Binding: bind,
-				Name:    name,
-			})
-
 		// If no kconfig map is found, this must be a symbol reference from inline
 		// asm (see testdata/loader.c:asm_relocation()) or a call to a forward
 		// function declaration (see testdata/fwd_decl.c). Don't interfere, These
@@ -1013,13 +980,6 @@ func mapSpecFromBTF(es *elfSection, vs *btf.VarSecinfo, def *btf.Struct, spec *b
 		}
 	}
 
-	// Some maps don't support value sizes, but annotating their map definitions
-	// with __type macros can still be useful, especially to let bpf2go generate
-	// type definitions for them.
-	if value != nil && !mapType.canHaveValueSize() {
-		valueSize = 0
-	}
-
 	return &MapSpec{
 		Name:       SanitizeName(name, -1),
 		Type:       MapType(mapType),
@@ -1132,21 +1092,12 @@ func (ec *elfCode) loadDataSections() error {
 			continue
 		}
 
-		// If a section has no references, it will be freed as soon as the
-		// Collection closes, so creating and populating it is wasteful. If it has
-		// no symbols, it is likely an ephemeral section used during compilation
-		// that wasn't sanitized by the bpf linker. (like .rodata.str1.1)
-		//
-		// No symbols means no VariableSpecs can be generated from it, making it
-		// pointless to emit a data section for.
-		if sec.references == 0 && len(sec.symbols) == 0 {
+		if sec.references == 0 {
+			// Prune data sections which are not referenced by any
+			// instructions.
 			continue
 		}
 
-		if sec.Size > math.MaxUint32 {
-			return fmt.Errorf("data section %s: contents exceed maximum size", sec.Name)
-		}
-
 		mapSpec := &MapSpec{
 			Name:       SanitizeName(sec.Name, -1),
 			Type:       Array,
@@ -1155,10 +1106,6 @@ func (ec *elfCode) loadDataSections() error {
 			MaxEntries: 1,
 		}
 
-		if isConstantDataSection(sec.Name) {
-			mapSpec.Flags = sys.BPF_F_RDONLY_PROG
-		}
-
 		switch sec.Type {
 		// Only open the section if we know there's actual data to be read.
 		case elf.SHT_PROGBITS:
@@ -1166,56 +1113,20 @@ func (ec *elfCode) loadDataSections() error {
 			if err != nil {
 				return fmt.Errorf("data section %s: can't get contents: %w", sec.Name, err)
 			}
+
+			if uint64(len(data)) > math.MaxUint32 {
+				return fmt.Errorf("data section %s: contents exceed maximum size", sec.Name)
+			}
 			mapSpec.Contents = []MapKV{{uint32(0), data}}
 
 		case elf.SHT_NOBITS:
-			// NOBITS sections like .bss contain only zeroes and are not allocated in
-			// the ELF. Since data sections are Arrays, the kernel can preallocate
-			// them. Don't attempt reading zeroes from the ELF, instead allocate the
-			// zeroed memory to support getting and setting VariableSpecs for sections
-			// like .bss.
-			mapSpec.Contents = []MapKV{{uint32(0), make([]byte, sec.Size)}}
-
+			// NOBITS sections like .bss contain only zeroes, and since data sections
+			// are Arrays, the kernel already preallocates them. Skip reading zeroes
+			// from the ELF.
 		default:
 			return fmt.Errorf("data section %s: unknown section type %s", sec.Name, sec.Type)
 		}
 
-		for off, sym := range sec.symbols {
-			// Skip symbols marked with the 'hidden' attribute.
-			if elf.ST_VISIBILITY(sym.Other) == elf.STV_HIDDEN ||
-				elf.ST_VISIBILITY(sym.Other) == elf.STV_INTERNAL {
-				continue
-			}
-
-			// Only accept symbols with global or weak bindings. The common
-			// alternative is STB_LOCAL, which are either function-scoped or declared
-			// 'static'.
-			if elf.ST_BIND(sym.Info) != elf.STB_GLOBAL &&
-				elf.ST_BIND(sym.Info) != elf.STB_WEAK {
-				continue
-			}
-
-			if ec.vars[sym.Name] != nil {
-				return fmt.Errorf("data section %s: duplicate variable %s", sec.Name, sym.Name)
-			}
-
-			// Skip symbols starting with a dot, they are compiler-internal symbols
-			// emitted by clang 11 and earlier and are not cleaned up by the bpf
-			// compiler backend (e.g. symbols named .Lconstinit.1 in sections like
-			// .rodata.cst32). Variables in C cannot start with a dot, so filter these
-			// out.
-			if strings.HasPrefix(sym.Name, ".") {
-				continue
-			}
-
-			ec.vars[sym.Name] = &VariableSpec{
-				name:   sym.Name,
-				offset: off,
-				size:   sym.Size,
-				m:      mapSpec,
-			}
-		}
-
 		// It is possible for a data section to exist without a corresponding BTF Datasec
 		// if it only contains anonymous values like macro-defined arrays.
 		if ec.btf != nil {
@@ -1224,40 +1135,14 @@ func (ec *elfCode) loadDataSections() error {
 				// Assign the spec's key and BTF only if the Datasec lookup was successful.
 				mapSpec.Key = &btf.Void{}
 				mapSpec.Value = ds
-
-				// Populate VariableSpecs with type information, if available.
-				for _, v := range ds.Vars {
-					name := v.Type.TypeName()
-					if name == "" {
-						return fmt.Errorf("data section %s: anonymous variable %v", sec.Name, v)
-					}
-
-					vt, ok := v.Type.(*btf.Var)
-					if !ok {
-						return fmt.Errorf("data section %s: unexpected type %T for variable %s", sec.Name, v.Type, name)
-					}
-
-					ev := ec.vars[name]
-					if ev == nil {
-						// Hidden symbols appear in the BTF Datasec but don't receive a VariableSpec.
-						continue
-					}
-
-					if uint64(v.Offset) != ev.offset {
-						return fmt.Errorf("data section %s: variable %s datasec offset (%d) doesn't match ELF symbol offset (%d)", sec.Name, name, v.Offset, ev.offset)
-					}
-
-					if uint64(v.Size) != ev.size {
-						return fmt.Errorf("data section %s: variable %s size in datasec (%d) doesn't match ELF symbol size (%d)", sec.Name, name, v.Size, ev.size)
-					}
-
-					// Decouple the Var in the VariableSpec from the underlying DataSec in
-					// the MapSpec to avoid modifications from affecting map loads later on.
-					ev.t = btf.Copy(vt).(*btf.Var)
-				}
 			}
 		}
 
+		if strings.HasPrefix(sec.Name, ".rodata") {
+			mapSpec.Flags = unix.BPF_F_RDONLY_PROG
+			mapSpec.Freeze = true
+		}
+
 		ec.maps[sec.Name] = mapSpec
 	}
 
@@ -1290,7 +1175,8 @@ func (ec *elfCode) loadKconfigSection() error {
 		KeySize:    uint32(4),
 		ValueSize:  ds.Size,
 		MaxEntries: 1,
-		Flags:      sys.BPF_F_RDONLY_PROG,
+		Flags:      unix.BPF_F_RDONLY_PROG,
+		Freeze:     true,
 		Key:        &btf.Int{Size: 4},
 		Value:      ds,
 	}
@@ -1315,14 +1201,8 @@ func (ec *elfCode) loadKsymsSection() error {
 	}
 
 	for _, v := range ds.Vars {
-		switch t := v.Type.(type) {
-		case *btf.Func:
-			ec.kfuncs[t.TypeName()] = t
-		case *btf.Var:
-			ec.ksyms[t.TypeName()] = struct{}{}
-		default:
-			return fmt.Errorf("unexpected variable type in .ksyms: %T", v)
-		}
+		// we have already checked the .ksyms Datasec to only contain Func Vars.
+		ec.kfuncs[v.Type.TypeName()] = v.Type.(*btf.Func)
 	}
 
 	return nil
@@ -1386,10 +1266,10 @@ func getProgType(sectionName string) (ProgramType, AttachType, uint32, string) {
 
 		var flags uint32
 		if t.flags&_SEC_SLEEPABLE > 0 {
-			flags |= sys.BPF_F_SLEEPABLE
+			flags |= unix.BPF_F_SLEEPABLE
 		}
 		if t.flags&_SEC_XDP_FRAGS > 0 {
-			flags |= sys.BPF_F_XDP_HAS_FRAGS
+			flags |= unix.BPF_F_XDP_HAS_FRAGS
 		}
 		if t.flags&_SEC_EXP_ATTACH_OPT > 0 {
 			if programType == XDP {
diff --git a/vendor/github.com/cilium/ebpf/info.go b/vendor/github.com/cilium/ebpf/info.go
index 56a1f1e9..04c60c64 100644
--- a/vendor/github.com/cilium/ebpf/info.go
+++ b/vendor/github.com/cilium/ebpf/info.go
@@ -8,10 +8,10 @@ import (
 	"fmt"
 	"io"
 	"os"
-	"reflect"
 	"strings"
 	"syscall"
 	"time"
+	"unsafe"
 
 	"github.com/cilium/ebpf/asm"
 	"github.com/cilium/ebpf/btf"
@@ -39,83 +39,53 @@ import (
 
 // MapInfo describes a map.
 type MapInfo struct {
-	// Type of the map.
-	Type MapType
-	// KeySize is the size of the map key in bytes.
-	KeySize uint32
-	// ValueSize is the size of the map value in bytes.
-	ValueSize uint32
-	// MaxEntries is the maximum number of entries the map can hold. Its meaning
-	// is map-specific.
+	Type       MapType
+	id         MapID
+	KeySize    uint32
+	ValueSize  uint32
 	MaxEntries uint32
-	// Flags used during map creation.
-	Flags uint32
+	Flags      uint32
 	// Name as supplied by user space at load time. Available from 4.15.
 	Name string
 
-	id       MapID
-	btf      btf.ID
-	mapExtra uint64
-	memlock  uint64
-	frozen   bool
+	btf btf.ID
 }
 
-// newMapInfoFromFd queries map information about the given fd. [sys.ObjInfo] is
-// attempted first, supplementing any missing values with information from
-// /proc/self/fdinfo. Ignores EINVAL from ObjInfo as well as ErrNotSupported
-// from reading fdinfo (indicating the file exists, but no fields of interest
-// were found). If both fail, an error is always returned.
 func newMapInfoFromFd(fd *sys.FD) (*MapInfo, error) {
 	var info sys.MapInfo
-	err1 := sys.ObjInfo(fd, &info)
-	// EINVAL means the kernel doesn't support BPF_OBJ_GET_INFO_BY_FD. Continue
-	// with fdinfo if that's the case.
-	if err1 != nil && !errors.Is(err1, unix.EINVAL) {
-		return nil, fmt.Errorf("getting object info: %w", err1)
+	err := sys.ObjInfo(fd, &info)
+	if errors.Is(err, syscall.EINVAL) {
+		return newMapInfoFromProc(fd)
+	}
+	if err != nil {
+		return nil, err
 	}
 
-	mi := &MapInfo{
+	return &MapInfo{
 		MapType(info.Type),
+		MapID(info.Id),
 		info.KeySize,
 		info.ValueSize,
 		info.MaxEntries,
 		uint32(info.MapFlags),
 		unix.ByteSliceToString(info.Name[:]),
-		MapID(info.Id),
 		btf.ID(info.BtfId),
-		info.MapExtra,
-		0,
-		false,
-	}
-
-	// Supplement OBJ_INFO with data from /proc/self/fdinfo. It contains fields
-	// like memlock and frozen that are not present in OBJ_INFO.
-	err2 := readMapInfoFromProc(fd, mi)
-	if err2 != nil && !errors.Is(err2, ErrNotSupported) {
-		return nil, fmt.Errorf("getting map info from fdinfo: %w", err2)
-	}
-
-	if err1 != nil && err2 != nil {
-		return nil, fmt.Errorf("ObjInfo and fdinfo both failed: objinfo: %w, fdinfo: %w", err1, err2)
-	}
-
-	return mi, nil
+	}, nil
 }
 
-// readMapInfoFromProc queries map information about the given fd from
-// /proc/self/fdinfo. It only writes data into fields that have a zero value.
-func readMapInfoFromProc(fd *sys.FD, mi *MapInfo) error {
-	return scanFdInfo(fd, map[string]interface{}{
+func newMapInfoFromProc(fd *sys.FD) (*MapInfo, error) {
+	var mi MapInfo
+	err := scanFdInfo(fd, map[string]interface{}{
 		"map_type":    &mi.Type,
-		"map_id":      &mi.id,
 		"key_size":    &mi.KeySize,
 		"value_size":  &mi.ValueSize,
 		"max_entries": &mi.MaxEntries,
 		"map_flags":   &mi.Flags,
-		"map_extra":   &mi.mapExtra,
-		"memlock":     &mi.memlock,
-		"frozen":      &mi.frozen,
 	})
+	if err != nil {
+		return nil, err
+	}
+	return &mi, nil
 }
 
 // ID returns the map ID.
@@ -139,35 +109,6 @@ func (mi *MapInfo) BTFID() (btf.ID, bool) {
 	return mi.btf, mi.btf > 0
 }
 
-// MapExtra returns an opaque field whose meaning is map-specific.
-//
-// Available from 5.16.
-//
-// The bool return value indicates whether this optional field is available and
-// populated, if it was specified during Map creation.
-func (mi *MapInfo) MapExtra() (uint64, bool) {
-	return mi.mapExtra, mi.mapExtra > 0
-}
-
-// Memlock returns an approximate number of bytes allocated to this map.
-//
-// Available from 4.10.
-//
-// The bool return value indicates whether this optional field is available.
-func (mi *MapInfo) Memlock() (uint64, bool) {
-	return mi.memlock, mi.memlock > 0
-}
-
-// Frozen indicates whether [Map.Freeze] was called on this map. If true,
-// modifications from user space are not allowed.
-//
-// Available from 5.2. Requires access to procfs.
-//
-// If the kernel doesn't support map freezing, this field will always be false.
-func (mi *MapInfo) Frozen() bool {
-	return mi.frozen
-}
-
 // programStats holds statistics of a program.
 type programStats struct {
 	// Total accumulated runtime of the program ins ns.
@@ -179,40 +120,6 @@ type programStats struct {
 	recursionMisses uint64
 }
 
-// programJitedInfo holds information about JITed info of a program.
-type programJitedInfo struct {
-	// ksyms holds the ksym addresses of the BPF program, including those of its
-	// subprograms.
-	//
-	// Available from 4.18.
-	ksyms    []uintptr
-	numKsyms uint32
-
-	// insns holds the JITed machine native instructions of the program,
-	// including those of its subprograms.
-	//
-	// Available from 4.13.
-	insns    []byte
-	numInsns uint32
-
-	// lineInfos holds the JITed line infos, which are kernel addresses.
-	//
-	// Available from 5.0.
-	lineInfos    []uint64
-	numLineInfos uint32
-
-	// lineInfoRecSize is the size of a single line info record.
-	//
-	// Available from 5.0.
-	lineInfoRecSize uint32
-
-	// funcLens holds the insns length of each function.
-	//
-	// Available from 4.18.
-	funcLens    []uint32
-	numFuncLens uint32
-}
-
 // ProgramInfo describes a program.
 type ProgramInfo struct {
 	Type ProgramType
@@ -226,14 +133,9 @@ type ProgramInfo struct {
 	haveCreatedByUID bool
 	btf              btf.ID
 	stats            *programStats
-	loadTime         time.Duration
-
-	maps                 []MapID
-	insns                []byte
-	jitedSize            uint32
-	verifiedInstructions uint32
 
-	jitedInfo programJitedInfo
+	maps  []MapID
+	insns []byte
 
 	lineInfos    []byte
 	numLineInfos uint32
@@ -262,9 +164,6 @@ func newProgramInfoFromFd(fd *sys.FD) (*ProgramInfo, error) {
 			runCount:        info.RunCnt,
 			recursionMisses: info.RecursionMisses,
 		},
-		jitedSize:            info.JitedProgLen,
-		loadTime:             time.Duration(info.LoadTime),
-		verifiedInstructions: info.VerifiedInsns,
 	}
 
 	// Start with a clean struct for the second call, otherwise we may get EFAULT.
@@ -275,7 +174,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.NewPointer(unsafe.Pointer(&pi.maps[0]))
 		makeSecondCall = true
 	} else if haveProgramInfoMapIDs() == nil {
 		// This program really has no associated maps.
@@ -316,40 +215,6 @@ func newProgramInfoFromFd(fd *sys.FD) (*ProgramInfo, error) {
 		makeSecondCall = true
 	}
 
-	pi.jitedInfo.lineInfoRecSize = info.JitedLineInfoRecSize
-	if info.JitedProgLen > 0 {
-		pi.jitedInfo.numInsns = info.JitedProgLen
-		pi.jitedInfo.insns = make([]byte, info.JitedProgLen)
-		info2.JitedProgLen = info.JitedProgLen
-		info2.JitedProgInsns = sys.NewSlicePointer(pi.jitedInfo.insns)
-		makeSecondCall = true
-	}
-
-	if info.NrJitedFuncLens > 0 {
-		pi.jitedInfo.numFuncLens = info.NrJitedFuncLens
-		pi.jitedInfo.funcLens = make([]uint32, info.NrJitedFuncLens)
-		info2.NrJitedFuncLens = info.NrJitedFuncLens
-		info2.JitedFuncLens = sys.NewSlicePointer(pi.jitedInfo.funcLens)
-		makeSecondCall = true
-	}
-
-	if info.NrJitedLineInfo > 0 {
-		pi.jitedInfo.numLineInfos = info.NrJitedLineInfo
-		pi.jitedInfo.lineInfos = make([]uint64, info.NrJitedLineInfo)
-		info2.NrJitedLineInfo = info.NrJitedLineInfo
-		info2.JitedLineInfo = sys.NewSlicePointer(pi.jitedInfo.lineInfos)
-		info2.JitedLineInfoRecSize = info.JitedLineInfoRecSize
-		makeSecondCall = true
-	}
-
-	if info.NrJitedKsyms > 0 {
-		pi.jitedInfo.numKsyms = info.NrJitedKsyms
-		pi.jitedInfo.ksyms = make([]uintptr, info.NrJitedKsyms)
-		info2.JitedKsyms = sys.NewSlicePointer(pi.jitedInfo.ksyms)
-		info2.NrJitedKsyms = info.NrJitedKsyms
-		makeSecondCall = true
-	}
-
 	if makeSecondCall {
 		if err := sys.ObjInfo(fd, &info2); err != nil {
 			return nil, err
@@ -365,7 +230,7 @@ func newProgramInfoFromProc(fd *sys.FD) (*ProgramInfo, error) {
 		"prog_type": &info.Type,
 		"prog_tag":  &info.Tag,
 	})
-	if errors.Is(err, ErrNotSupported) {
+	if errors.Is(err, errMissingFields) {
 		return nil, &internal.UnsupportedFeatureError{
 			Name:           "reading program info from /proc/self/fdinfo",
 			MinimumVersion: internal.Version{4, 10, 0},
@@ -440,52 +305,6 @@ func (pi *ProgramInfo) RecursionMisses() (uint64, bool) {
 	return 0, false
 }
 
-// btfSpec returns the BTF spec associated with the program.
-func (pi *ProgramInfo) btfSpec() (*btf.Spec, error) {
-	id, ok := pi.BTFID()
-	if !ok {
-		return nil, fmt.Errorf("program created without BTF or unsupported kernel: %w", ErrNotSupported)
-	}
-
-	h, err := btf.NewHandleFromID(id)
-	if err != nil {
-		return nil, fmt.Errorf("get BTF handle: %w", err)
-	}
-	defer h.Close()
-
-	spec, err := h.Spec(nil)
-	if err != nil {
-		return nil, fmt.Errorf("get BTF spec: %w", err)
-	}
-
-	return spec, nil
-}
-
-// LineInfos returns the BTF line information of the program.
-//
-// Available from 5.0.
-//
-// Requires CAP_SYS_ADMIN or equivalent for reading BTF information. Returns
-// ErrNotSupported if the program was created without BTF or if the kernel
-// doesn't support the field.
-func (pi *ProgramInfo) LineInfos() (btf.LineOffsets, error) {
-	if len(pi.lineInfos) == 0 {
-		return nil, fmt.Errorf("insufficient permissions or unsupported kernel: %w", ErrNotSupported)
-	}
-
-	spec, err := pi.btfSpec()
-	if err != nil {
-		return nil, err
-	}
-
-	return btf.LoadLineInfos(
-		bytes.NewReader(pi.lineInfos),
-		internal.NativeEndian,
-		pi.numLineInfos,
-		spec,
-	)
-}
-
 // Instructions returns the 'xlated' instruction stream of the program
 // after it has been verified and rewritten by the kernel. These instructions
 // cannot be loaded back into the kernel as-is, this is mainly used for
@@ -572,29 +391,6 @@ func (pi *ProgramInfo) Instructions() (asm.Instructions, error) {
 	return insns, nil
 }
 
-// JitedSize returns the size of the program's JIT-compiled machine code in bytes, which is the
-// actual code executed on the host's CPU. This field requires the BPF JIT compiler to be enabled.
-//
-// Available from 4.13. Reading this metadata requires CAP_BPF or equivalent.
-func (pi *ProgramInfo) JitedSize() (uint32, error) {
-	if pi.jitedSize == 0 {
-		return 0, fmt.Errorf("insufficient permissions, unsupported kernel, or JIT compiler disabled: %w", ErrNotSupported)
-	}
-	return pi.jitedSize, nil
-}
-
-// TranslatedSize returns the size of the program's translated instructions in bytes, after it has
-// been verified and rewritten by the kernel.
-//
-// Available from 4.13. Reading this metadata requires CAP_BPF or equivalent.
-func (pi *ProgramInfo) TranslatedSize() (int, error) {
-	insns := len(pi.insns)
-	if insns == 0 {
-		return 0, fmt.Errorf("insufficient permissions or unsupported kernel: %w", ErrNotSupported)
-	}
-	return insns, nil
-}
-
 // MapIDs returns the maps related to the program.
 //
 // Available from 4.15.
@@ -604,89 +400,6 @@ func (pi *ProgramInfo) MapIDs() ([]MapID, bool) {
 	return pi.maps, pi.maps != nil
 }
 
-// LoadTime returns when the program was loaded since boot time.
-//
-// Available from 4.15.
-//
-// The bool return value indicates whether this optional field is available.
-func (pi *ProgramInfo) LoadTime() (time.Duration, bool) {
-	// loadTime and NrMapIds were introduced in the same kernel version.
-	return pi.loadTime, pi.loadTime > 0
-}
-
-// VerifiedInstructions returns the number verified instructions in the program.
-//
-// Available from 5.16.
-//
-// The bool return value indicates whether this optional field is available.
-func (pi *ProgramInfo) VerifiedInstructions() (uint32, bool) {
-	return pi.verifiedInstructions, pi.verifiedInstructions > 0
-}
-
-// JitedKsymAddrs returns the ksym addresses of the BPF program, including its
-// subprograms. The addresses correspond to their symbols in /proc/kallsyms.
-//
-// Available from 4.18. Note that before 5.x, this field can be empty for
-// programs without subprograms (bpf2bpf calls).
-//
-// The bool return value indicates whether this optional field is available.
-func (pi *ProgramInfo) JitedKsymAddrs() ([]uintptr, bool) {
-	return pi.jitedInfo.ksyms, len(pi.jitedInfo.ksyms) > 0
-}
-
-// JitedInsns returns the JITed machine native instructions of the program.
-//
-// Available from 4.13.
-//
-// The bool return value indicates whether this optional field is available.
-func (pi *ProgramInfo) JitedInsns() ([]byte, bool) {
-	return pi.jitedInfo.insns, len(pi.jitedInfo.insns) > 0
-}
-
-// JitedLineInfos returns the JITed line infos of the program.
-//
-// Available from 5.0.
-//
-// The bool return value indicates whether this optional field is available.
-func (pi *ProgramInfo) JitedLineInfos() ([]uint64, bool) {
-	return pi.jitedInfo.lineInfos, len(pi.jitedInfo.lineInfos) > 0
-}
-
-// JitedFuncLens returns the insns length of each function in the JITed program.
-//
-// Available from 4.18.
-//
-// The bool return value indicates whether this optional field is available.
-func (pi *ProgramInfo) JitedFuncLens() ([]uint32, bool) {
-	return pi.jitedInfo.funcLens, len(pi.jitedInfo.funcLens) > 0
-}
-
-// FuncInfos returns the offset and function information of all (sub)programs in
-// a BPF program.
-//
-// Available from 5.0.
-//
-// Requires CAP_SYS_ADMIN or equivalent for reading BTF information. Returns
-// ErrNotSupported if the program was created without BTF or if the kernel
-// doesn't support the field.
-func (pi *ProgramInfo) FuncInfos() (btf.FuncOffsets, error) {
-	if len(pi.funcInfos) == 0 {
-		return nil, fmt.Errorf("insufficient permissions or unsupported kernel: %w", ErrNotSupported)
-	}
-
-	spec, err := pi.btfSpec()
-	if err != nil {
-		return nil, err
-	}
-
-	return btf.LoadFuncInfos(
-		bytes.NewReader(pi.funcInfos),
-		internal.NativeEndian,
-		pi.numFuncInfos,
-		spec,
-	)
-}
-
 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 {
@@ -700,6 +413,8 @@ func scanFdInfo(fd *sys.FD, fields map[string]interface{}) error {
 	return nil
 }
 
+var errMissingFields = errors.New("missing fields")
+
 func scanFdInfoReader(r io.Reader, fields map[string]interface{}) error {
 	var (
 		scanner = bufio.NewScanner(r)
@@ -718,37 +433,26 @@ func scanFdInfoReader(r io.Reader, fields map[string]interface{}) error {
 			continue
 		}
 
-		// If field already contains a non-zero value, don't overwrite it with fdinfo.
-		if zero(field) {
-			if n, err := fmt.Sscanln(parts[1], field); err != nil || n != 1 {
-				return fmt.Errorf("can't parse field %s: %v", name, err)
-			}
+		if n, err := fmt.Sscanln(parts[1], field); err != nil || n != 1 {
+			return fmt.Errorf("can't parse field %s: %v", name, err)
 		}
 
 		scanned++
 	}
 
 	if err := scanner.Err(); err != nil {
-		return fmt.Errorf("scanning fdinfo: %w", err)
+		return err
 	}
 
 	if len(fields) > 0 && scanned == 0 {
 		return ErrNotSupported
 	}
 
-	return nil
-}
-
-func zero(arg any) bool {
-	v := reflect.ValueOf(arg)
-
-	// Unwrap pointers and interfaces.
-	for v.Kind() == reflect.Pointer ||
-		v.Kind() == reflect.Interface {
-		v = v.Elem()
+	if scanned != len(fields) {
+		return errMissingFields
 	}
 
-	return v.IsZero()
+	return nil
 }
 
 // EnableStats starts the measuring of the runtime
@@ -767,7 +471,7 @@ func EnableStats(which uint32) (io.Closer, error) {
 	return fd, nil
 }
 
-var haveProgramInfoMapIDs = internal.NewFeatureTest("map IDs in program info", func() error {
+var haveProgramInfoMapIDs = internal.NewFeatureTest("map IDs in program info", "4.15", func() error {
 	prog, err := progLoad(asm.Instructions{
 		asm.LoadImm(asm.R0, 0, asm.DWord),
 		asm.Return(),
@@ -792,4 +496,4 @@ var haveProgramInfoMapIDs = internal.NewFeatureTest("map IDs in program info", f
 	}
 
 	return err
-}, "4.15")
+})
diff --git a/vendor/github.com/cilium/ebpf/internal/linux/auxv.go b/vendor/github.com/cilium/ebpf/internal/auxv.go
similarity index 98%
rename from vendor/github.com/cilium/ebpf/internal/linux/auxv.go
rename to vendor/github.com/cilium/ebpf/internal/auxv.go
index 98bb5d83..45fd0d37 100644
--- a/vendor/github.com/cilium/ebpf/internal/linux/auxv.go
+++ b/vendor/github.com/cilium/ebpf/internal/auxv.go
@@ -1,4 +1,4 @@
-package linux
+package internal
 
 import (
 	"errors"
diff --git a/vendor/github.com/cilium/ebpf/internal/errors.go b/vendor/github.com/cilium/ebpf/internal/errors.go
index 19d5294c..83a371ad 100644
--- a/vendor/github.com/cilium/ebpf/internal/errors.go
+++ b/vendor/github.com/cilium/ebpf/internal/errors.go
@@ -23,7 +23,7 @@ func ErrorWithLog(source string, err error, log []byte) *VerifierError {
 
 	log = bytes.Trim(log, whitespace)
 	if len(log) == 0 {
-		return &VerifierError{source, err, nil}
+		return &VerifierError{source, err, nil, false}
 	}
 
 	logLines := bytes.Split(log, []byte{'\n'})
@@ -34,7 +34,7 @@ func ErrorWithLog(source string, err error, log []byte) *VerifierError {
 		lines = append(lines, string(bytes.TrimRight(line, whitespace)))
 	}
 
-	return &VerifierError{source, err, lines}
+	return &VerifierError{source, err, lines, false}
 }
 
 // VerifierError includes information from the eBPF verifier.
@@ -46,6 +46,8 @@ type VerifierError struct {
 	Cause error
 	// The verifier output split into lines.
 	Log []string
+	// Deprecated: the log is never truncated anymore.
+	Truncated bool
 }
 
 func (le *VerifierError) Unwrap() error {
diff --git a/vendor/github.com/cilium/ebpf/internal/feature.go b/vendor/github.com/cilium/ebpf/internal/feature.go
index 6399be08..2b856c73 100644
--- a/vendor/github.com/cilium/ebpf/internal/feature.go
+++ b/vendor/github.com/cilium/ebpf/internal/feature.go
@@ -3,25 +3,15 @@ package internal
 import (
 	"errors"
 	"fmt"
-	"runtime"
-	"strings"
 	"sync"
 )
 
-// ErrNotSupported indicates that a feature is not supported.
+// ErrNotSupported indicates that a feature is not supported by the current kernel.
 var ErrNotSupported = errors.New("not supported")
 
-// ErrNotSupportedOnOS indicates that a feature is not supported on the current
-// operating system.
-var ErrNotSupportedOnOS = fmt.Errorf("%w on %s", ErrNotSupported, runtime.GOOS)
-
 // UnsupportedFeatureError is returned by FeatureTest() functions.
 type UnsupportedFeatureError struct {
-	// The minimum version required for this feature.
-	//
-	// On Linux this refers to the mainline kernel version, on other platforms
-	// to the version of the runtime.
-	//
+	// The minimum Linux mainline version required for this feature.
 	// Used for the error string, and for sanity checking during testing.
 	MinimumVersion Version
 
@@ -68,44 +58,11 @@ type FeatureTest struct {
 type FeatureTestFn func() error
 
 // NewFeatureTest is a convenient way to create a single [FeatureTest].
-//
-// versions specifies in which version of a BPF runtime a feature appeared.
-// The format is "GOOS:Major.Minor[.Patch]". GOOS may be omitted when targeting
-// Linux. Returns [ErrNotSupportedOnOS] if there is no version specified for the
-// current OS.
-func NewFeatureTest(name string, fn FeatureTestFn, versions ...string) func() error {
-	const nativePrefix = runtime.GOOS + ":"
-
-	if len(versions) == 0 {
-		return func() error {
-			return fmt.Errorf("feature test %q: no versions specified", name)
-		}
-	}
-
+func NewFeatureTest(name, version string, fn FeatureTestFn) func() error {
 	ft := &FeatureTest{
-		Name: name,
-		Fn:   fn,
-	}
-
-	for _, version := range versions {
-		if strings.HasPrefix(version, nativePrefix) {
-			ft.Version = strings.TrimPrefix(version, nativePrefix)
-			break
-		}
-
-		if runtime.GOOS == "linux" && !strings.ContainsRune(version, ':') {
-			// Allow version numbers without a GOOS prefix on Linux.
-			ft.Version = version
-			break
-		}
-	}
-
-	if ft.Version == "" {
-		return func() error {
-			// We don't return an UnsupportedFeatureError here, since that will
-			// trigger version checks which don't make sense.
-			return fmt.Errorf("%s: %w", name, ErrNotSupportedOnOS)
-		}
+		Name:    name,
+		Version: version,
+		Fn:      fn,
 	}
 
 	return ft.execute
diff --git a/vendor/github.com/cilium/ebpf/internal/kallsyms/cache.go b/vendor/github.com/cilium/ebpf/internal/kallsyms/cache.go
deleted file mode 100644
index b7f3e0b7..00000000
--- a/vendor/github.com/cilium/ebpf/internal/kallsyms/cache.go
+++ /dev/null
@@ -1,20 +0,0 @@
-package kallsyms
-
-import "sync"
-
-type cache[K, V comparable] struct {
-	m sync.Map
-}
-
-func (c *cache[K, V]) Load(key K) (value V, _ bool) {
-	v, ok := c.m.Load(key)
-	if !ok {
-		return value, false
-	}
-	value = v.(V)
-	return value, true
-}
-
-func (c *cache[K, V]) Store(key K, value V) {
-	c.m.Store(key, value)
-}
diff --git a/vendor/github.com/cilium/ebpf/internal/kallsyms/kallsyms.go b/vendor/github.com/cilium/ebpf/internal/kallsyms/kallsyms.go
index f93d7858..776c7a10 100644
--- a/vendor/github.com/cilium/ebpf/internal/kallsyms/kallsyms.go
+++ b/vendor/github.com/cilium/ebpf/internal/kallsyms/kallsyms.go
@@ -1,277 +1,74 @@
 package kallsyms
 
 import (
-	"errors"
-	"fmt"
+	"bufio"
+	"bytes"
 	"io"
 	"os"
-	"slices"
-	"strconv"
-	"strings"
+	"sync"
 )
 
-var errAmbiguousKsym = errors.New("multiple kernel symbols with the same name")
-
-var symAddrs cache[string, uint64]
-var symModules cache[string, string]
-
-// Module returns the kernel module providing the given symbol in the kernel, if
-// any. Returns an empty string and no error if the symbol is not present in the
-// kernel. Only function symbols are considered. Returns an error if multiple
-// symbols with the same name were found.
-//
-// Consider [AssignModules] if you need to resolve multiple symbols, as it will
-// only perform one iteration over /proc/kallsyms.
-func Module(name string) (string, error) {
-	if name == "" {
-		return "", nil
-	}
-
-	if mod, ok := symModules.Load(name); ok {
-		return mod, nil
-	}
-
-	request := map[string]string{name: ""}
-	if err := AssignModules(request); err != nil {
-		return "", err
-	}
-
-	return request[name], nil
+var kernelModules struct {
+	sync.RWMutex
+	// function to kernel module mapping
+	kmods map[string]string
 }
 
-// AssignModules looks up the kernel module providing each given symbol, if any,
-// and assigns them to their corresponding values in the symbols map. Only
-// function symbols are considered. Results of all lookups are cached,
-// successful or otherwise.
-//
-// Any symbols missing in the kernel are ignored. Returns an error if multiple
-// symbols with a given name were found.
-func AssignModules(symbols map[string]string) error {
-	if len(symbols) == 0 {
-		return nil
-	}
+// KernelModule returns the kernel module, if any, a probe-able function is contained in.
+func KernelModule(fn string) (string, error) {
+	kernelModules.RLock()
+	kmods := kernelModules.kmods
+	kernelModules.RUnlock()
 
-	// Attempt to fetch symbols from cache.
-	request := make(map[string]string)
-	for name := range symbols {
-		if mod, ok := symModules.Load(name); ok {
-			symbols[name] = mod
-			continue
-		}
-
-		// Mark the symbol to be read from /proc/kallsyms.
-		request[name] = ""
+	if kmods == nil {
+		kernelModules.Lock()
+		defer kernelModules.Unlock()
+		kmods = kernelModules.kmods
 	}
-	if len(request) == 0 {
-		// All symbols satisfied from cache.
-		return nil
+
+	if kmods != nil {
+		return kmods[fn], nil
 	}
 
 	f, err := os.Open("/proc/kallsyms")
 	if err != nil {
-		return err
-	}
-
-	if err := assignModules(f, request); err != nil {
-		return fmt.Errorf("assigning symbol modules: %w", err)
-	}
-
-	// Update the cache with the new symbols. Cache all requested symbols, even if
-	// they're missing or don't belong to a module.
-	for name, mod := range request {
-		symModules.Store(name, mod)
-		symbols[name] = mod
-	}
-
-	return nil
-}
-
-// assignModules assigns kernel symbol modules read from f to values requested
-// by symbols. Always scans the whole input to make sure the user didn't request
-// an ambiguous symbol.
-func assignModules(f io.Reader, symbols map[string]string) error {
-	if len(symbols) == 0 {
-		return nil
-	}
-
-	found := make(map[string]struct{})
-	r := newReader(f)
-	for r.Line() {
-		// Only look for function symbols in the kernel's text section (tT).
-		s, err, skip := parseSymbol(r, []rune{'t', 'T'})
-		if err != nil {
-			return fmt.Errorf("parsing kallsyms line: %w", err)
-		}
-		if skip {
-			continue
-		}
-
-		if _, requested := symbols[s.name]; !requested {
-			continue
-		}
-
-		if _, ok := found[s.name]; ok {
-			// We've already seen this symbol. Return an error to avoid silently
-			// attaching to a symbol in the wrong module. libbpf also rejects
-			// referring to ambiguous symbols.
-			//
-			// We can't simply check if we already have a value for the given symbol,
-			// since many won't have an associated kernel module.
-			return fmt.Errorf("symbol %s: duplicate found at address 0x%x (module %q): %w",
-				s.name, s.addr, s.mod, errAmbiguousKsym)
-		}
-
-		symbols[s.name] = s.mod
-		found[s.name] = struct{}{}
+		return "", err
 	}
-	if err := r.Err(); err != nil {
-		return fmt.Errorf("reading kallsyms: %w", err)
+	defer f.Close()
+	kmods, err = loadKernelModuleMapping(f)
+	if err != nil {
+		return "", err
 	}
 
-	return nil
+	kernelModules.kmods = kmods
+	return kmods[fn], nil
 }
 
-// Address returns the address of the given symbol in the kernel. Returns 0 and
-// no error if the symbol is not present. Returns an error if multiple addresses
-// were found for a symbol.
-//
-// Consider [AssignAddresses] if you need to resolve multiple symbols, as it
-// will only perform one iteration over /proc/kallsyms.
-func Address(symbol string) (uint64, error) {
-	if symbol == "" {
-		return 0, nil
-	}
-
-	if addr, ok := symAddrs.Load(symbol); ok {
-		return addr, nil
-	}
-
-	request := map[string]uint64{symbol: 0}
-	if err := AssignAddresses(request); err != nil {
-		return 0, err
-	}
+// FlushKernelModuleCache removes any cached information about function to kernel module mapping.
+func FlushKernelModuleCache() {
+	kernelModules.Lock()
+	defer kernelModules.Unlock()
 
-	return request[symbol], nil
+	kernelModules.kmods = nil
 }
 
-// AssignAddresses looks up the addresses of the requested symbols in the kernel
-// and assigns them to their corresponding values in the symbols map. Results
-// of all lookups are cached, successful or otherwise.
-//
-// Any symbols missing in the kernel are ignored. Returns an error if multiple
-// addresses were found for a symbol.
-func AssignAddresses(symbols map[string]uint64) error {
-	if len(symbols) == 0 {
-		return nil
-	}
-
-	// Attempt to fetch symbols from cache.
-	request := make(map[string]uint64)
-	for name := range symbols {
-		if addr, ok := symAddrs.Load(name); ok {
-			symbols[name] = addr
+func loadKernelModuleMapping(f io.Reader) (map[string]string, error) {
+	mods := make(map[string]string)
+	scanner := bufio.NewScanner(f)
+	for scanner.Scan() {
+		fields := bytes.Fields(scanner.Bytes())
+		if len(fields) < 4 {
 			continue
 		}
-
-		// Mark the symbol to be read from /proc/kallsyms.
-		request[name] = 0
-	}
-	if len(request) == 0 {
-		// All symbols satisfied from cache.
-		return nil
-	}
-
-	f, err := os.Open("/proc/kallsyms")
-	if err != nil {
-		return err
-	}
-
-	if err := assignAddresses(f, request); err != nil {
-		return fmt.Errorf("loading symbol addresses: %w", err)
-	}
-
-	// Update the cache with the new symbols. Cache all requested symbols even if
-	// they weren't found, to avoid repeated lookups.
-	for name, addr := range request {
-		symAddrs.Store(name, addr)
-		symbols[name] = addr
-	}
-
-	return nil
-}
-
-// assignAddresses assigns kernel symbol addresses read from f to values
-// requested by symbols. Always scans the whole input to make sure the user
-// didn't request an ambiguous symbol.
-func assignAddresses(f io.Reader, symbols map[string]uint64) error {
-	if len(symbols) == 0 {
-		return nil
-	}
-	r := newReader(f)
-	for r.Line() {
-		s, err, skip := parseSymbol(r, nil)
-		if err != nil {
-			return fmt.Errorf("parsing kallsyms line: %w", err)
-		}
-		if skip {
+		switch string(fields[1]) {
+		case "t", "T":
+			mods[string(fields[2])] = string(bytes.Trim(fields[3], "[]"))
+		default:
 			continue
 		}
-
-		existing, requested := symbols[s.name]
-		if existing != 0 {
-			// Multiple addresses for a symbol have been found. Return a friendly
-			// error to avoid silently attaching to the wrong symbol. libbpf also
-			// rejects referring to ambiguous symbols.
-			return fmt.Errorf("symbol %s(0x%x): duplicate found at address 0x%x: %w", s.name, existing, s.addr, errAmbiguousKsym)
-		}
-		if requested {
-			symbols[s.name] = s.addr
-		}
 	}
-	if err := r.Err(); err != nil {
-		return fmt.Errorf("reading kallsyms: %w", err)
+	if scanner.Err() != nil {
+		return nil, scanner.Err()
 	}
-
-	return nil
-}
-
-type ksym struct {
-	addr uint64
-	name string
-	mod  string
-}
-
-// parseSymbol parses a line from /proc/kallsyms into an address, type, name and
-// module. Skip will be true if the symbol doesn't match any of the given symbol
-// types. See `man 1 nm` for all available types.
-//
-// Example line: `ffffffffc1682010 T nf_nat_init  [nf_nat]`
-func parseSymbol(r *reader, types []rune) (s ksym, err error, skip bool) {
-	for i := 0; r.Word(); i++ {
-		switch i {
-		// Address of the symbol.
-		case 0:
-			s.addr, err = strconv.ParseUint(r.Text(), 16, 64)
-			if err != nil {
-				return s, fmt.Errorf("parsing address: %w", err), false
-			}
-		// Type of the symbol. Assume the character is ASCII-encoded by converting
-		// it directly to a rune, since it's a fixed field controlled by the kernel.
-		case 1:
-			if len(types) > 0 && !slices.Contains(types, rune(r.Bytes()[0])) {
-				return s, nil, true
-			}
-		// Name of the symbol.
-		case 2:
-			s.name = r.Text()
-		// Kernel module the symbol is provided by.
-		case 3:
-			s.mod = strings.Trim(r.Text(), "[]")
-		// Ignore any future fields.
-		default:
-			break
-		}
-	}
-
-	return
+	return mods, nil
 }
diff --git a/vendor/github.com/cilium/ebpf/internal/kallsyms/reader.go b/vendor/github.com/cilium/ebpf/internal/kallsyms/reader.go
deleted file mode 100644
index 2bd4f8ea..00000000
--- a/vendor/github.com/cilium/ebpf/internal/kallsyms/reader.go
+++ /dev/null
@@ -1,118 +0,0 @@
-package kallsyms
-
-import (
-	"bufio"
-	"io"
-	"unicode"
-	"unicode/utf8"
-)
-
-// reader is a line and word-oriented reader built for reading /proc/kallsyms.
-// It takes an io.Reader and iterates its contents line by line, then word by
-// word.
-//
-// It's designed to allow partial reading of lines without paying the cost of
-// allocating objects that will never be accessed, resulting in less work for
-// the garbage collector.
-type reader struct {
-	s    *bufio.Scanner
-	line []byte
-	word []byte
-
-	err error
-}
-
-func newReader(r io.Reader) *reader {
-	return &reader{
-		s: bufio.NewScanner(r),
-	}
-}
-
-// Bytes returns the current word as a byte slice.
-func (r *reader) Bytes() []byte {
-	return r.word
-}
-
-// Text returns the output of Bytes as a string.
-func (r *reader) Text() string {
-	return string(r.Bytes())
-}
-
-// Line advances the reader to the next line in the input. Calling Line resets
-// the current word, making [reader.Bytes] and [reader.Text] return empty
-// values. Follow this up with a call to [reader.Word].
-//
-// Like [bufio.Scanner], [reader.Err] needs to be checked after Line returns
-// false to determine if an error occurred during reading.
-//
-// Returns true if Line can be called again. Returns false if all lines in the
-// input have been read.
-func (r *reader) Line() bool {
-	for r.s.Scan() {
-		line := r.s.Bytes()
-		if len(line) == 0 {
-			continue
-		}
-
-		r.line = line
-		r.word = nil
-
-		return true
-	}
-	if err := r.s.Err(); err != nil {
-		r.err = err
-	}
-
-	return false
-}
-
-// Word advances the reader to the next word in the current line.
-//
-// Returns true if a word is found and Word should be called again. Returns
-// false when all words on the line have been read.
-func (r *reader) Word() bool {
-	if len(r.line) == 0 {
-		return false
-	}
-
-	// Find next word start, skipping leading spaces.
-	start := 0
-	for width := 0; start < len(r.line); start += width {
-		var c rune
-		c, width = utf8.DecodeRune(r.line[start:])
-		if !unicode.IsSpace(c) {
-			break
-		}
-	}
-
-	// Whitespace scanning reached the end of the line due to trailing whitespace,
-	// meaning there are no more words to read
-	if start == len(r.line) {
-		return false
-	}
-
-	// Find next word end.
-	for width, i := 0, start; i < len(r.line); i += width {
-		var c rune
-		c, width = utf8.DecodeRune(r.line[i:])
-		if unicode.IsSpace(c) {
-			r.word = r.line[start:i]
-			r.line = r.line[i:]
-			return true
-		}
-	}
-
-	// The line contains data, but no end-of-word boundary was found. This is the
-	// last, unterminated word in the line.
-	if len(r.line) > start {
-		r.word = r.line[start:]
-		r.line = nil
-		return true
-	}
-
-	return false
-}
-
-func (r *reader) Err() error {
-	return r.err
-}
diff --git a/vendor/github.com/cilium/ebpf/internal/kconfig/kconfig.go b/vendor/github.com/cilium/ebpf/internal/kconfig/kconfig.go
index 29c62b62..1921e4f1 100644
--- a/vendor/github.com/cilium/ebpf/internal/kconfig/kconfig.go
+++ b/vendor/github.com/cilium/ebpf/internal/kconfig/kconfig.go
@@ -1,4 +1,3 @@
-// Package kconfig implements a parser for the format of Linux's .config file.
 package kconfig
 
 import (
@@ -8,6 +7,7 @@ import (
 	"fmt"
 	"io"
 	"math"
+	"os"
 	"strconv"
 	"strings"
 
@@ -15,6 +15,30 @@ import (
 	"github.com/cilium/ebpf/internal"
 )
 
+// Find find a kconfig file on the host.
+// It first reads from /boot/config- of the current running kernel and tries
+// /proc/config.gz if nothing was found in /boot.
+// If none of the file provide a kconfig, it returns an error.
+func Find() (*os.File, error) {
+	kernelRelease, err := internal.KernelRelease()
+	if err != nil {
+		return nil, fmt.Errorf("cannot get kernel release: %w", err)
+	}
+
+	path := "/boot/config-" + kernelRelease
+	f, err := os.Open(path)
+	if err == nil {
+		return f, nil
+	}
+
+	f, err = os.Open("/proc/config.gz")
+	if err == nil {
+		return f, nil
+	}
+
+	return nil, fmt.Errorf("neither %s nor /proc/config.gz provide a kconfig", path)
+}
+
 // Parse parses the kconfig file for which a reader is given.
 // All the CONFIG_* which are in filter and which are set set will be
 // put in the returned map as key with their corresponding value as map value.
@@ -103,13 +127,12 @@ func PutValue(data []byte, typ btf.Type, value string) error {
 	switch value {
 	case "y", "n", "m":
 		return putValueTri(data, typ, value)
+	default:
+		if strings.HasPrefix(value, `"`) {
+			return putValueString(data, typ, value)
+		}
+		return putValueNumber(data, typ, value)
 	}
-
-	if strings.HasPrefix(value, `"`) {
-		return putValueString(data, typ, value)
-	}
-
-	return putValueNumber(data, typ, value)
 }
 
 // Golang translation of libbpf_tristate enum:
@@ -146,10 +169,6 @@ func putValueTri(data []byte, typ btf.Type, value string) error {
 			return fmt.Errorf("cannot use enum %q, only libbpf_tristate is supported", v.Name)
 		}
 
-		if len(data) != 4 {
-			return fmt.Errorf("expected enum value to occupy 4 bytes in datasec, got: %d", len(data))
-		}
-
 		var tri triState
 		switch value {
 		case "y":
@@ -159,10 +178,10 @@ func putValueTri(data []byte, typ btf.Type, value string) error {
 		case "n":
 			tri = TriNo
 		default:
-			return fmt.Errorf("value %q is not supported for libbpf_tristate", value)
+			return fmt.Errorf("value %q is not support for libbpf_tristate", value)
 		}
 
-		internal.NativeEndian.PutUint32(data, uint32(tri))
+		internal.NativeEndian.PutUint64(data, uint64(tri))
 	default:
 		return fmt.Errorf("cannot add number value, expected btf.Int or btf.Enum, got: %T", v)
 	}
diff --git a/vendor/github.com/cilium/ebpf/internal/linux/doc.go b/vendor/github.com/cilium/ebpf/internal/linux/doc.go
deleted file mode 100644
index 064e7543..00000000
--- a/vendor/github.com/cilium/ebpf/internal/linux/doc.go
+++ /dev/null
@@ -1,2 +0,0 @@
-// Package linux contains OS specific wrappers around package unix.
-package linux
diff --git a/vendor/github.com/cilium/ebpf/internal/linux/kconfig.go b/vendor/github.com/cilium/ebpf/internal/linux/kconfig.go
deleted file mode 100644
index 1488ecb3..00000000
--- a/vendor/github.com/cilium/ebpf/internal/linux/kconfig.go
+++ /dev/null
@@ -1,31 +0,0 @@
-package linux
-
-import (
-	"fmt"
-	"os"
-)
-
-// FindKConfig searches for a kconfig file on the host.
-//
-// It first reads from /boot/config- of the current running kernel and tries
-// /proc/config.gz if nothing was found in /boot.
-// If none of the file provide a kconfig, it returns an error.
-func FindKConfig() (*os.File, error) {
-	kernelRelease, err := KernelRelease()
-	if err != nil {
-		return nil, fmt.Errorf("cannot get kernel release: %w", err)
-	}
-
-	path := "/boot/config-" + kernelRelease
-	f, err := os.Open(path)
-	if err == nil {
-		return f, nil
-	}
-
-	f, err = os.Open("/proc/config.gz")
-	if err == nil {
-		return f, nil
-	}
-
-	return nil, fmt.Errorf("neither %s nor /proc/config.gz provide a kconfig", path)
-}
diff --git a/vendor/github.com/cilium/ebpf/internal/linux/version.go b/vendor/github.com/cilium/ebpf/internal/linux/version.go
deleted file mode 100644
index 798dd3fe..00000000
--- a/vendor/github.com/cilium/ebpf/internal/linux/version.go
+++ /dev/null
@@ -1,34 +0,0 @@
-package linux
-
-import (
-	"fmt"
-	"sync"
-
-	"github.com/cilium/ebpf/internal"
-	"github.com/cilium/ebpf/internal/unix"
-)
-
-// KernelVersion returns the version of the currently running kernel.
-var KernelVersion = sync.OnceValues(detectKernelVersion)
-
-// detectKernelVersion returns the version of the running kernel.
-func detectKernelVersion() (internal.Version, error) {
-	vc, err := vdsoVersion()
-	if err != nil {
-		return internal.Version{}, err
-	}
-	return internal.NewVersionFromCode(vc), nil
-}
-
-// KernelRelease returns the release string of the running kernel.
-// Its format depends on the Linux distribution and corresponds to directory
-// names in /lib/modules by convention. Some examples are 5.15.17-1-lts and
-// 4.19.0-16-amd64.
-func KernelRelease() (string, error) {
-	var uname unix.Utsname
-	if err := unix.Uname(&uname); err != nil {
-		return "", fmt.Errorf("uname failed: %w", err)
-	}
-
-	return unix.ByteSliceToString(uname.Release[:]), nil
-}
diff --git a/vendor/github.com/cilium/ebpf/internal/math.go b/vendor/github.com/cilium/ebpf/internal/math.go
index 10cde668..e95c8efd 100644
--- a/vendor/github.com/cilium/ebpf/internal/math.go
+++ b/vendor/github.com/cilium/ebpf/internal/math.go
@@ -1,33 +1,13 @@
 package internal
 
+import "golang.org/x/exp/constraints"
+
 // Align returns 'n' updated to 'alignment' boundary.
-func Align[I Integer](n, alignment I) I {
+func Align[I constraints.Integer](n, alignment I) I {
 	return (n + alignment - 1) / alignment * alignment
 }
 
 // IsPow returns true if n is a power of two.
-func IsPow[I Integer](n I) bool {
+func IsPow[I constraints.Integer](n I) bool {
 	return n != 0 && (n&(n-1)) == 0
 }
-
-// Between returns the value clamped between a and b.
-func Between[I Integer](val, a, b I) I {
-	lower, upper := a, b
-	if lower > upper {
-		upper, lower = a, b
-	}
-
-	val = min(val, upper)
-	return max(val, lower)
-}
-
-// Integer represents all possible integer types.
-// Remove when x/exp/constraints is moved to the standard library.
-type Integer interface {
-	~int | ~int8 | ~int16 | ~int32 | ~int64 | ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr
-}
-
-// List of integer types known by the Go compiler. Used by TestIntegerConstraint
-// to warn if a new integer type is introduced. Remove when x/exp/constraints
-// is moved to the standard library.
-var integers = []string{"int", "int8", "int16", "int32", "int64", "uint", "uint8", "uint16", "uint32", "uint64", "uintptr"}
diff --git a/vendor/github.com/cilium/ebpf/internal/sys/pinning.go b/vendor/github.com/cilium/ebpf/internal/pinning.go
similarity index 77%
rename from vendor/github.com/cilium/ebpf/internal/sys/pinning.go
rename to vendor/github.com/cilium/ebpf/internal/pinning.go
index 9a4c6c7a..01d892f9 100644
--- a/vendor/github.com/cilium/ebpf/internal/sys/pinning.go
+++ b/vendor/github.com/cilium/ebpf/internal/pinning.go
@@ -1,4 +1,4 @@
-package sys
+package internal
 
 import (
 	"errors"
@@ -7,11 +7,11 @@ import (
 	"path/filepath"
 	"runtime"
 
-	"github.com/cilium/ebpf/internal/linux"
+	"github.com/cilium/ebpf/internal/sys"
 	"github.com/cilium/ebpf/internal/unix"
 )
 
-func Pin(currentPath, newPath string, fd *FD) error {
+func Pin(currentPath, newPath string, fd *sys.FD) error {
 	if newPath == "" {
 		return errors.New("given pinning path cannot be empty")
 	}
@@ -19,7 +19,7 @@ func Pin(currentPath, newPath string, fd *FD) error {
 		return nil
 	}
 
-	fsType, err := linux.FSType(filepath.Dir(newPath))
+	fsType, err := FSType(filepath.Dir(newPath))
 	if err != nil {
 		return err
 	}
@@ -30,8 +30,8 @@ func Pin(currentPath, newPath string, fd *FD) error {
 	defer runtime.KeepAlive(fd)
 
 	if currentPath == "" {
-		return ObjPin(&ObjPinAttr{
-			Pathname: NewStringPointer(newPath),
+		return sys.ObjPin(&sys.ObjPinAttr{
+			Pathname: sys.NewStringPointer(newPath),
 			BpfFd:    fd.Uint(),
 		})
 	}
@@ -47,8 +47,8 @@ func Pin(currentPath, newPath string, fd *FD) error {
 		return fmt.Errorf("unable to move pinned object to new path %v: %w", newPath, err)
 	}
 	// Internal state not in sync with the file system so let's fix it.
-	return ObjPin(&ObjPinAttr{
-		Pathname: NewStringPointer(newPath),
+	return sys.ObjPin(&sys.ObjPinAttr{
+		Pathname: sys.NewStringPointer(newPath),
 		BpfFd:    fd.Uint(),
 	})
 }
diff --git a/vendor/github.com/cilium/ebpf/internal/linux/platform.go b/vendor/github.com/cilium/ebpf/internal/platform.go
similarity index 97%
rename from vendor/github.com/cilium/ebpf/internal/linux/platform.go
rename to vendor/github.com/cilium/ebpf/internal/platform.go
index 39bdcc51..6e90f2ef 100644
--- a/vendor/github.com/cilium/ebpf/internal/linux/platform.go
+++ b/vendor/github.com/cilium/ebpf/internal/platform.go
@@ -1,4 +1,4 @@
-package linux
+package internal
 
 import (
 	"runtime"
diff --git a/vendor/github.com/cilium/ebpf/internal/linux/statfs.go b/vendor/github.com/cilium/ebpf/internal/statfs.go
similarity index 96%
rename from vendor/github.com/cilium/ebpf/internal/linux/statfs.go
rename to vendor/github.com/cilium/ebpf/internal/statfs.go
index e268c06f..44c02d67 100644
--- a/vendor/github.com/cilium/ebpf/internal/linux/statfs.go
+++ b/vendor/github.com/cilium/ebpf/internal/statfs.go
@@ -1,4 +1,4 @@
-package linux
+package internal
 
 import (
 	"unsafe"
diff --git a/vendor/github.com/cilium/ebpf/internal/sys/fd.go b/vendor/github.com/cilium/ebpf/internal/sys/fd.go
index e2ba43fd..941a56fb 100644
--- a/vendor/github.com/cilium/ebpf/internal/sys/fd.go
+++ b/vendor/github.com/cilium/ebpf/internal/sys/fd.go
@@ -4,12 +4,9 @@ import (
 	"fmt"
 	"math"
 	"os"
-	"path/filepath"
 	"runtime"
 	"strconv"
-	"strings"
 
-	"github.com/cilium/ebpf/internal/testutils/fdtrace"
 	"github.com/cilium/ebpf/internal/unix"
 )
 
@@ -20,7 +17,15 @@ type FD struct {
 }
 
 func newFD(value int) *FD {
-	fdtrace.TraceFD(value, 1)
+	if onLeakFD != nil {
+		// Attempt to store the caller's stack for the given fd value.
+		// Panic if fds contains an existing stack for the fd.
+		old, exist := fds.LoadOrStore(value, callersFrames())
+		if exist {
+			f := old.(*runtime.Frames)
+			panic(fmt.Sprintf("found existing stack for fd %d:\n%s", value, FormatFrames(f)))
+		}
+	}
 
 	fd := &FD{value}
 	runtime.SetFinalizer(fd, (*FD).finalize)
@@ -34,7 +39,13 @@ func (fd *FD) finalize() {
 		return
 	}
 
-	fdtrace.LeakFD(fd.raw)
+	// Invoke the fd leak callback. Calls LoadAndDelete to guarantee the callback
+	// is invoked at most once for one sys.FD allocation, runtime.Frames can only
+	// be unwound once.
+	f, ok := fds.LoadAndDelete(fd.Int())
+	if ok && onLeakFD != nil {
+		onLeakFD(f.(*runtime.Frames))
+	}
 
 	_ = fd.Close()
 }
@@ -81,15 +92,12 @@ func (fd *FD) Close() error {
 		return nil
 	}
 
-	return unix.Close(fd.Disown())
+	return unix.Close(fd.disown())
 }
 
-// Disown destroys the FD and returns its raw file descriptor without closing
-// it. After this call, the underlying fd is no longer tied to the FD's
-// lifecycle.
-func (fd *FD) Disown() int {
-	value := fd.raw
-	fdtrace.ForgetFD(value)
+func (fd *FD) disown() int {
+	value := int(fd.raw)
+	fds.Delete(int(value))
 	fd.raw = -1
 
 	runtime.SetFinalizer(fd, nil)
@@ -121,45 +129,5 @@ func (fd *FD) File(name string) *os.File {
 		return nil
 	}
 
-	return os.NewFile(uintptr(fd.Disown()), name)
-}
-
-// ObjGetTyped wraps [ObjGet] with a readlink call to extract the type of the
-// underlying bpf object.
-func ObjGetTyped(attr *ObjGetAttr) (*FD, ObjType, error) {
-	fd, err := ObjGet(attr)
-	if err != nil {
-		return nil, 0, err
-	}
-
-	typ, err := readType(fd)
-	if err != nil {
-		_ = fd.Close()
-		return nil, 0, fmt.Errorf("reading fd type: %w", err)
-	}
-
-	return fd, typ, nil
-}
-
-// readType returns the bpf object type of the file descriptor by calling
-// readlink(3). Returns an error if the file descriptor does not represent a bpf
-// object.
-func readType(fd *FD) (ObjType, error) {
-	s, err := os.Readlink(filepath.Join("/proc/self/fd/", fd.String()))
-	if err != nil {
-		return 0, fmt.Errorf("readlink fd %d: %w", fd.Int(), err)
-	}
-
-	s = strings.TrimPrefix(s, "anon_inode:")
-
-	switch s {
-	case "bpf-map":
-		return BPF_TYPE_MAP, nil
-	case "bpf-prog":
-		return BPF_TYPE_PROG, nil
-	case "bpf-link":
-		return BPF_TYPE_LINK, nil
-	}
-
-	return 0, fmt.Errorf("unknown type %s of fd %d", s, fd.Int())
+	return os.NewFile(uintptr(fd.disown()), name)
 }
diff --git a/vendor/github.com/cilium/ebpf/internal/sys/fd_trace.go b/vendor/github.com/cilium/ebpf/internal/sys/fd_trace.go
new file mode 100644
index 00000000..cd50dd1f
--- /dev/null
+++ b/vendor/github.com/cilium/ebpf/internal/sys/fd_trace.go
@@ -0,0 +1,93 @@
+package sys
+
+import (
+	"bytes"
+	"fmt"
+	"runtime"
+	"sync"
+)
+
+// OnLeakFD controls tracing [FD] lifetime to detect resources that are not
+// closed by Close().
+//
+// If fn is not nil, tracing is enabled for all FDs created going forward. fn is
+// invoked for all FDs that are closed by the garbage collector instead of an
+// explicit Close() by a caller. Calling OnLeakFD twice with a non-nil fn
+// (without disabling tracing in the meantime) will cause a panic.
+//
+// If fn is nil, tracing will be disabled. Any FDs that have not been closed are
+// considered to be leaked, fn will be invoked for them, and the process will be
+// terminated.
+//
+// fn will be invoked at most once for every unique sys.FD allocation since a
+// runtime.Frames can only be unwound once.
+func OnLeakFD(fn func(*runtime.Frames)) {
+	// Enable leak tracing if new fn is provided.
+	if fn != nil {
+		if onLeakFD != nil {
+			panic("OnLeakFD called twice with non-nil fn")
+		}
+
+		onLeakFD = fn
+		return
+	}
+
+	// fn is nil past this point.
+
+	if onLeakFD == nil {
+		return
+	}
+
+	// Call onLeakFD for all open fds.
+	if fs := flushFrames(); len(fs) != 0 {
+		for _, f := range fs {
+			onLeakFD(f)
+		}
+	}
+
+	onLeakFD = nil
+}
+
+var onLeakFD func(*runtime.Frames)
+
+// fds is a registry of all file descriptors wrapped into sys.fds that were
+// created while an fd tracer was active.
+var fds sync.Map // map[int]*runtime.Frames
+
+// flushFrames removes all elements from fds and returns them as a slice. This
+// deals with the fact that a runtime.Frames can only be unwound once using
+// Next().
+func flushFrames() []*runtime.Frames {
+	var frames []*runtime.Frames
+	fds.Range(func(key, value any) bool {
+		frames = append(frames, value.(*runtime.Frames))
+		fds.Delete(key)
+		return true
+	})
+	return frames
+}
+
+func callersFrames() *runtime.Frames {
+	c := make([]uintptr, 32)
+
+	// Skip runtime.Callers and this function.
+	i := runtime.Callers(2, c)
+	if i == 0 {
+		return nil
+	}
+
+	return runtime.CallersFrames(c)
+}
+
+// FormatFrames formats a runtime.Frames as a human-readable string.
+func FormatFrames(fs *runtime.Frames) string {
+	var b bytes.Buffer
+	for {
+		f, more := fs.Next()
+		b.WriteString(fmt.Sprintf("\t%s+%#x\n\t\t%s:%d\n", f.Function, f.PC-f.Entry, f.File, f.Line))
+		if !more {
+			break
+		}
+	}
+	return b.String()
+}
diff --git a/vendor/github.com/cilium/ebpf/internal/sys/mapflags_string.go b/vendor/github.com/cilium/ebpf/internal/sys/mapflags_string.go
new file mode 100644
index 00000000..d9fe2172
--- /dev/null
+++ b/vendor/github.com/cilium/ebpf/internal/sys/mapflags_string.go
@@ -0,0 +1,53 @@
+// Code generated by "stringer -type MapFlags"; DO NOT EDIT.
+
+package sys
+
+import "strconv"
+
+func _() {
+	// An "invalid array index" compiler error signifies that the constant values have changed.
+	// Re-run the stringer command to generate them again.
+	var x [1]struct{}
+	_ = x[BPF_F_NO_PREALLOC-1]
+	_ = x[BPF_F_NO_COMMON_LRU-2]
+	_ = x[BPF_F_NUMA_NODE-4]
+	_ = x[BPF_F_RDONLY-8]
+	_ = x[BPF_F_WRONLY-16]
+	_ = x[BPF_F_STACK_BUILD_ID-32]
+	_ = x[BPF_F_ZERO_SEED-64]
+	_ = x[BPF_F_RDONLY_PROG-128]
+	_ = x[BPF_F_WRONLY_PROG-256]
+	_ = x[BPF_F_CLONE-512]
+	_ = x[BPF_F_MMAPABLE-1024]
+	_ = x[BPF_F_PRESERVE_ELEMS-2048]
+	_ = x[BPF_F_INNER_MAP-4096]
+	_ = x[BPF_F_LINK-8192]
+	_ = x[BPF_F_PATH_FD-16384]
+}
+
+const _MapFlags_name = "BPF_F_NO_PREALLOCBPF_F_NO_COMMON_LRUBPF_F_NUMA_NODEBPF_F_RDONLYBPF_F_WRONLYBPF_F_STACK_BUILD_IDBPF_F_ZERO_SEEDBPF_F_RDONLY_PROGBPF_F_WRONLY_PROGBPF_F_CLONEBPF_F_MMAPABLEBPF_F_PRESERVE_ELEMSBPF_F_INNER_MAPBPF_F_LINKBPF_F_PATH_FD"
+
+var _MapFlags_map = map[MapFlags]string{
+	1:     _MapFlags_name[0:17],
+	2:     _MapFlags_name[17:36],
+	4:     _MapFlags_name[36:51],
+	8:     _MapFlags_name[51:63],
+	16:    _MapFlags_name[63:75],
+	32:    _MapFlags_name[75:95],
+	64:    _MapFlags_name[95:110],
+	128:   _MapFlags_name[110:127],
+	256:   _MapFlags_name[127:144],
+	512:   _MapFlags_name[144:155],
+	1024:  _MapFlags_name[155:169],
+	2048:  _MapFlags_name[169:189],
+	4096:  _MapFlags_name[189:204],
+	8192:  _MapFlags_name[204:214],
+	16384: _MapFlags_name[214:227],
+}
+
+func (i MapFlags) String() string {
+	if str, ok := _MapFlags_map[i]; ok {
+		return str
+	}
+	return "MapFlags(" + strconv.FormatInt(int64(i), 10) + ")"
+}
diff --git a/vendor/github.com/cilium/ebpf/internal/sys/ptr.go b/vendor/github.com/cilium/ebpf/internal/sys/ptr.go
index af0c014e..e9bb5905 100644
--- a/vendor/github.com/cilium/ebpf/internal/sys/ptr.go
+++ b/vendor/github.com/cilium/ebpf/internal/sys/ptr.go
@@ -11,13 +11,13 @@ func NewPointer(ptr unsafe.Pointer) Pointer {
 	return Pointer{ptr: ptr}
 }
 
-// NewSlicePointer creates a 64-bit pointer from a slice.
-func NewSlicePointer[T comparable](buf []T) Pointer {
+// NewSlicePointer creates a 64-bit pointer from a byte slice.
+func NewSlicePointer(buf []byte) Pointer {
 	if len(buf) == 0 {
 		return Pointer{}
 	}
 
-	return Pointer{ptr: unsafe.Pointer(unsafe.SliceData(buf))}
+	return Pointer{ptr: unsafe.Pointer(&buf[0])}
 }
 
 // NewSlicePointerLen creates a 64-bit pointer from a byte slice.
diff --git a/vendor/github.com/cilium/ebpf/internal/sys/syscall.go b/vendor/github.com/cilium/ebpf/internal/sys/syscall.go
index e37f4cf6..f6b6e934 100644
--- a/vendor/github.com/cilium/ebpf/internal/sys/syscall.go
+++ b/vendor/github.com/cilium/ebpf/internal/sys/syscall.go
@@ -133,12 +133,12 @@ func ObjInfo(fd *FD, info Info) error {
 
 // BPFObjName is a null-terminated string made up of
 // 'A-Za-z0-9_' characters.
-type ObjName [BPF_OBJ_NAME_LEN]byte
+type ObjName [unix.BPF_OBJ_NAME_LEN]byte
 
 // NewObjName truncates the result if it is too long.
 func NewObjName(name string) ObjName {
 	var result ObjName
-	copy(result[:BPF_OBJ_NAME_LEN-1], name)
+	copy(result[:unix.BPF_OBJ_NAME_LEN-1], name)
 	return result
 }
 
@@ -160,6 +160,29 @@ type BTFID uint32
 // TypeID identifies a type in a BTF blob.
 type TypeID uint32
 
+// MapFlags control map behaviour.
+type MapFlags uint32
+
+//go:generate go run golang.org/x/tools/cmd/stringer@latest -type MapFlags
+
+const (
+	BPF_F_NO_PREALLOC MapFlags = 1 << iota
+	BPF_F_NO_COMMON_LRU
+	BPF_F_NUMA_NODE
+	BPF_F_RDONLY
+	BPF_F_WRONLY
+	BPF_F_STACK_BUILD_ID
+	BPF_F_ZERO_SEED
+	BPF_F_RDONLY_PROG
+	BPF_F_WRONLY_PROG
+	BPF_F_CLONE
+	BPF_F_MMAPABLE
+	BPF_F_PRESERVE_ELEMS
+	BPF_F_INNER_MAP
+	BPF_F_LINK
+	BPF_F_PATH_FD
+)
+
 // Flags used by bpf_mprog.
 const (
 	BPF_F_REPLACE = 1 << (iota + 2)
@@ -169,16 +192,6 @@ const (
 	BPF_F_LINK_MPROG = 1 << 13 // aka BPF_F_LINK
 )
 
-// Flags used by BPF_PROG_LOAD.
-const (
-	BPF_F_SLEEPABLE          = 1 << 4
-	BPF_F_XDP_HAS_FRAGS      = 1 << 5
-	BPF_F_XDP_DEV_BOUND_ONLY = 1 << 6
-)
-
-const BPF_TAG_SIZE = 8
-const BPF_OBJ_NAME_LEN = 16
-
 // wrappedErrno wraps syscall.Errno to prevent direct comparisons with
 // syscall.E* or unix.E* constants.
 //
diff --git a/vendor/github.com/cilium/ebpf/internal/sys/types.go b/vendor/github.com/cilium/ebpf/internal/sys/types.go
index 88001c31..70e754de 100644
--- a/vendor/github.com/cilium/ebpf/internal/sys/types.go
+++ b/vendor/github.com/cilium/ebpf/internal/sys/types.go
@@ -6,170 +6,6 @@ import (
 	"unsafe"
 )
 
-const (
-	BPF_ADJ_ROOM_ENCAP_L2_MASK                 = 255
-	BPF_ADJ_ROOM_ENCAP_L2_SHIFT                = 56
-	BPF_ANY                                    = 0
-	BPF_CSUM_LEVEL_DEC                         = 2
-	BPF_CSUM_LEVEL_INC                         = 1
-	BPF_CSUM_LEVEL_QUERY                       = 0
-	BPF_CSUM_LEVEL_RESET                       = 3
-	BPF_EXIST                                  = 2
-	BPF_FIB_LKUP_RET_BLACKHOLE                 = 1
-	BPF_FIB_LKUP_RET_FRAG_NEEDED               = 8
-	BPF_FIB_LKUP_RET_FWD_DISABLED              = 5
-	BPF_FIB_LKUP_RET_NOT_FWDED                 = 4
-	BPF_FIB_LKUP_RET_NO_NEIGH                  = 7
-	BPF_FIB_LKUP_RET_NO_SRC_ADDR               = 9
-	BPF_FIB_LKUP_RET_PROHIBIT                  = 3
-	BPF_FIB_LKUP_RET_SUCCESS                   = 0
-	BPF_FIB_LKUP_RET_UNREACHABLE               = 2
-	BPF_FIB_LKUP_RET_UNSUPP_LWT                = 6
-	BPF_FIB_LOOKUP_DIRECT                      = 1
-	BPF_FIB_LOOKUP_OUTPUT                      = 2
-	BPF_FIB_LOOKUP_SKIP_NEIGH                  = 4
-	BPF_FIB_LOOKUP_SRC                         = 16
-	BPF_FIB_LOOKUP_TBID                        = 8
-	BPF_FLOW_DISSECTOR_F_PARSE_1ST_FRAG        = 1
-	BPF_FLOW_DISSECTOR_F_STOP_AT_ENCAP         = 4
-	BPF_FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL    = 2
-	BPF_F_ADJ_ROOM_DECAP_L3_IPV4               = 128
-	BPF_F_ADJ_ROOM_DECAP_L3_IPV6               = 256
-	BPF_F_ADJ_ROOM_ENCAP_L2_ETH                = 64
-	BPF_F_ADJ_ROOM_ENCAP_L3_IPV4               = 2
-	BPF_F_ADJ_ROOM_ENCAP_L3_IPV6               = 4
-	BPF_F_ADJ_ROOM_ENCAP_L4_GRE                = 8
-	BPF_F_ADJ_ROOM_ENCAP_L4_UDP                = 16
-	BPF_F_ADJ_ROOM_FIXED_GSO                   = 1
-	BPF_F_ADJ_ROOM_NO_CSUM_RESET               = 32
-	BPF_F_BPRM_SECUREEXEC                      = 1
-	BPF_F_BROADCAST                            = 8
-	BPF_F_CLONE                                = 512
-	BPF_F_CTXLEN_MASK                          = 4503595332403200
-	BPF_F_CURRENT_CPU                          = 4294967295
-	BPF_F_CURRENT_NETNS                        = 18446744073709551615
-	BPF_F_DONT_FRAGMENT                        = 4
-	BPF_F_EXCLUDE_INGRESS                      = 16
-	BPF_F_FAST_STACK_CMP                       = 512
-	BPF_F_GET_BRANCH_RECORDS_SIZE              = 1
-	BPF_F_HDR_FIELD_MASK                       = 15
-	BPF_F_INDEX_MASK                           = 4294967295
-	BPF_F_INGRESS                              = 1
-	BPF_F_INNER_MAP                            = 4096
-	BPF_F_INVALIDATE_HASH                      = 2
-	BPF_F_KPROBE_MULTI_RETURN                  = 1
-	BPF_F_LINK                                 = 8192
-	BPF_F_LOCK                                 = 4
-	BPF_F_MARK_ENFORCE                         = 64
-	BPF_F_MARK_MANGLED_0                       = 32
-	BPF_F_MMAPABLE                             = 1024
-	BPF_F_NEIGH                                = 2
-	BPF_F_NEXTHOP                              = 8
-	BPF_F_NO_COMMON_LRU                        = 2
-	BPF_F_NO_PREALLOC                          = 1
-	BPF_F_NO_TUNNEL_KEY                        = 16
-	BPF_F_NUMA_NODE                            = 4
-	BPF_F_PATH_FD                              = 16384
-	BPF_F_PEER                                 = 4
-	BPF_F_PRESERVE_ELEMS                       = 2048
-	BPF_F_PSEUDO_HDR                           = 16
-	BPF_F_RDONLY                               = 8
-	BPF_F_RDONLY_PROG                          = 128
-	BPF_F_RECOMPUTE_CSUM                       = 1
-	BPF_F_REUSE_STACKID                        = 1024
-	BPF_F_SEQ_NUMBER                           = 8
-	BPF_F_SKIP_FIELD_MASK                      = 255
-	BPF_F_STACK_BUILD_ID                       = 32
-	BPF_F_SYSCTL_BASE_NAME                     = 1
-	BPF_F_TIMER_ABS                            = 1
-	BPF_F_TIMER_CPU_PIN                        = 2
-	BPF_F_TUNINFO_FLAGS                        = 16
-	BPF_F_TUNINFO_IPV6                         = 1
-	BPF_F_UPROBE_MULTI_RETURN                  = 1
-	BPF_F_USER_BUILD_ID                        = 2048
-	BPF_F_USER_STACK                           = 256
-	BPF_F_WRONLY                               = 16
-	BPF_F_WRONLY_PROG                          = 256
-	BPF_F_ZERO_CSUM_TX                         = 2
-	BPF_F_ZERO_SEED                            = 64
-	BPF_LOAD_HDR_OPT_TCP_SYN                   = 1
-	BPF_LOCAL_STORAGE_GET_F_CREATE             = 1
-	BPF_MAX_LOOPS                              = 8388608
-	BPF_MAX_TRAMP_LINKS                        = 38
-	BPF_NOEXIST                                = 1
-	BPF_RB_AVAIL_DATA                          = 0
-	BPF_RB_CONS_POS                            = 2
-	BPF_RB_FORCE_WAKEUP                        = 2
-	BPF_RB_NO_WAKEUP                           = 1
-	BPF_RB_PROD_POS                            = 3
-	BPF_RB_RING_SIZE                           = 1
-	BPF_REG_0                                  = 0
-	BPF_REG_1                                  = 1
-	BPF_REG_10                                 = 10
-	BPF_REG_2                                  = 2
-	BPF_REG_3                                  = 3
-	BPF_REG_4                                  = 4
-	BPF_REG_5                                  = 5
-	BPF_REG_6                                  = 6
-	BPF_REG_7                                  = 7
-	BPF_REG_8                                  = 8
-	BPF_REG_9                                  = 9
-	BPF_RINGBUF_BUSY_BIT                       = 2147483648
-	BPF_RINGBUF_DISCARD_BIT                    = 1073741824
-	BPF_RINGBUF_HDR_SZ                         = 8
-	BPF_SKB_TSTAMP_DELIVERY_MONO               = 1
-	BPF_SKB_TSTAMP_UNSPEC                      = 0
-	BPF_SK_LOOKUP_F_NO_REUSEPORT               = 2
-	BPF_SK_LOOKUP_F_REPLACE                    = 1
-	BPF_SK_STORAGE_GET_F_CREATE                = 1
-	BPF_SOCK_OPS_ACTIVE_ESTABLISHED_CB         = 4
-	BPF_SOCK_OPS_ALL_CB_FLAGS                  = 127
-	BPF_SOCK_OPS_BASE_RTT                      = 7
-	BPF_SOCK_OPS_HDR_OPT_LEN_CB                = 14
-	BPF_SOCK_OPS_NEEDS_ECN                     = 6
-	BPF_SOCK_OPS_PARSE_ALL_HDR_OPT_CB_FLAG     = 16
-	BPF_SOCK_OPS_PARSE_HDR_OPT_CB              = 13
-	BPF_SOCK_OPS_PARSE_UNKNOWN_HDR_OPT_CB_FLAG = 32
-	BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB        = 5
-	BPF_SOCK_OPS_RETRANS_CB                    = 9
-	BPF_SOCK_OPS_RETRANS_CB_FLAG               = 2
-	BPF_SOCK_OPS_RTO_CB                        = 8
-	BPF_SOCK_OPS_RTO_CB_FLAG                   = 1
-	BPF_SOCK_OPS_RTT_CB                        = 12
-	BPF_SOCK_OPS_RTT_CB_FLAG                   = 8
-	BPF_SOCK_OPS_RWND_INIT                     = 2
-	BPF_SOCK_OPS_STATE_CB                      = 10
-	BPF_SOCK_OPS_STATE_CB_FLAG                 = 4
-	BPF_SOCK_OPS_TCP_CONNECT_CB                = 3
-	BPF_SOCK_OPS_TCP_LISTEN_CB                 = 11
-	BPF_SOCK_OPS_TIMEOUT_INIT                  = 1
-	BPF_SOCK_OPS_VOID                          = 0
-	BPF_SOCK_OPS_WRITE_HDR_OPT_CB              = 15
-	BPF_SOCK_OPS_WRITE_HDR_OPT_CB_FLAG         = 64
-	BPF_STRUCT_OPS_TYPE_bpf_dummy_ops          = 0
-	BPF_STRUCT_OPS_TYPE_tcp_congestion_ops     = 1
-	BPF_TASK_ITER_ALL_PROCS                    = 0
-	BPF_TASK_ITER_ALL_THREADS                  = 1
-	BPF_TASK_ITER_PROC_THREADS                 = 2
-	BPF_TCP_BOUND_INACTIVE                     = 13
-	BPF_TCP_CLOSE                              = 7
-	BPF_TCP_CLOSE_WAIT                         = 8
-	BPF_TCP_CLOSING                            = 11
-	BPF_TCP_ESTABLISHED                        = 1
-	BPF_TCP_FIN_WAIT1                          = 4
-	BPF_TCP_FIN_WAIT2                          = 5
-	BPF_TCP_LAST_ACK                           = 9
-	BPF_TCP_LISTEN                             = 10
-	BPF_TCP_MAX_STATES                         = 14
-	BPF_TCP_NEW_SYN_RECV                       = 12
-	BPF_TCP_SYN_RECV                           = 3
-	BPF_TCP_SYN_SENT                           = 2
-	BPF_TCP_TIME_WAIT                          = 6
-	BPF_WRITE_HDR_TCP_CURRENT_MSS              = 1
-	BPF_WRITE_HDR_TCP_SYNACK_COOKIE            = 2
-	BPF_XFRM_STATE_OPTS_SZ                     = 36
-)
-
 type AdjRoomMode uint32
 
 const (
@@ -566,15 +402,6 @@ const (
 	BPF_MAP_TYPE_CGRP_STORAGE                     MapType = 32
 )
 
-type ObjType uint32
-
-const (
-	BPF_TYPE_UNSPEC ObjType = 0
-	BPF_TYPE_PROG   ObjType = 1
-	BPF_TYPE_MAP    ObjType = 2
-	BPF_TYPE_LINK   ObjType = 3
-)
-
 type PerfEventType uint32
 
 const (
@@ -710,7 +537,7 @@ type MapInfo struct {
 	KeySize               uint32
 	ValueSize             uint32
 	MaxEntries            uint32
-	MapFlags              uint32
+	MapFlags              MapFlags
 	Name                  ObjName
 	Ifindex               uint32
 	BtfVmlinuxValueTypeId TypeID
@@ -729,7 +556,7 @@ type ProgInfo struct {
 	Tag                  [8]uint8
 	JitedProgLen         uint32
 	XlatedProgLen        uint32
-	JitedProgInsns       Pointer
+	JitedProgInsns       uint64
 	XlatedProgInsns      Pointer
 	LoadTime             uint64
 	CreatedByUid         uint32
@@ -742,15 +569,15 @@ type ProgInfo struct {
 	NetnsIno             uint64
 	NrJitedKsyms         uint32
 	NrJitedFuncLens      uint32
-	JitedKsyms           Pointer
-	JitedFuncLens        Pointer
+	JitedKsyms           uint64
+	JitedFuncLens        uint64
 	BtfId                BTFID
 	FuncInfoRecSize      uint32
 	FuncInfo             Pointer
 	NrFuncInfo           uint32
 	NrLineInfo           uint32
 	LineInfo             Pointer
-	JitedLineInfo        Pointer
+	JitedLineInfo        uint64
 	NrJitedLineInfo      uint32
 	LineInfoRecSize      uint32
 	JitedLineInfoRecSize uint32
@@ -1059,7 +886,7 @@ type MapCreateAttr struct {
 	KeySize               uint32
 	ValueSize             uint32
 	MaxEntries            uint32
-	MapFlags              uint32
+	MapFlags              MapFlags
 	InnerMapFd            uint32
 	NumaNode              uint32
 	MapName               ObjName
diff --git a/vendor/github.com/cilium/ebpf/internal/sysenc/buffer.go b/vendor/github.com/cilium/ebpf/internal/sysenc/buffer.go
index 1b4f052e..d184ea19 100644
--- a/vendor/github.com/cilium/ebpf/internal/sysenc/buffer.go
+++ b/vendor/github.com/cilium/ebpf/internal/sysenc/buffer.go
@@ -51,12 +51,12 @@ func SyscallOutput(dst any, size int) Buffer {
 //
 // Returns the number of copied bytes.
 func (b Buffer) CopyTo(dst []byte) int {
-	return copy(dst, b.Bytes())
+	return copy(dst, b.unsafeBytes())
 }
 
 // AppendTo appends the buffer onto dst.
 func (b Buffer) AppendTo(dst []byte) []byte {
-	return append(dst, b.Bytes()...)
+	return append(dst, b.unsafeBytes()...)
 }
 
 // Pointer returns the location where a syscall should write.
@@ -72,12 +72,10 @@ func (b Buffer) Unmarshal(data any) error {
 		return nil
 	}
 
-	return Unmarshal(data, b.Bytes())
+	return Unmarshal(data, b.unsafeBytes())
 }
 
-// Bytes returns the buffer as a byte slice. Returns nil if the Buffer was
-// created using UnsafeBuffer or by zero-copy unmarshaling.
-func (b Buffer) Bytes() []byte {
+func (b Buffer) unsafeBytes() []byte {
 	if b.size == syscallPointerOnly {
 		return nil
 	}
diff --git a/vendor/github.com/cilium/ebpf/internal/tracefs/kprobe.go b/vendor/github.com/cilium/ebpf/internal/tracefs/kprobe.go
index 062bef9e..897740fe 100644
--- a/vendor/github.com/cilium/ebpf/internal/tracefs/kprobe.go
+++ b/vendor/github.com/cilium/ebpf/internal/tracefs/kprobe.go
@@ -12,7 +12,6 @@ import (
 	"syscall"
 
 	"github.com/cilium/ebpf/internal"
-	"github.com/cilium/ebpf/internal/linux"
 	"github.com/cilium/ebpf/internal/unix"
 )
 
@@ -122,7 +121,7 @@ var getTracefsPath = sync.OnceValues(func() (string, error) {
 		// RHEL/CentOS
 		{"/sys/kernel/debug/tracing", unix.DEBUGFS_MAGIC},
 	} {
-		if fsType, err := linux.FSType(p.path); err == nil && fsType == p.fsType {
+		if fsType, err := internal.FSType(p.path); err == nil && fsType == p.fsType {
 			return p.path, nil
 		}
 	}
@@ -214,10 +213,7 @@ func NewEvent(args ProbeArgs) (*Event, error) {
 	if err == nil {
 		return nil, fmt.Errorf("trace event %s/%s: %w", args.Group, eventName, os.ErrExist)
 	}
-	if errors.Is(err, unix.EINVAL) {
-		return nil, fmt.Errorf("trace event %s/%s: %w (unknown symbol?)", args.Group, eventName, err)
-	}
-	if !errors.Is(err, os.ErrNotExist) {
+	if err != nil && !errors.Is(err, os.ErrNotExist) {
 		return nil, fmt.Errorf("checking trace event %s/%s: %w", args.Group, eventName, err)
 	}
 
diff --git a/vendor/github.com/cilium/ebpf/internal/unix/types_linux.go b/vendor/github.com/cilium/ebpf/internal/unix/types_linux.go
index 144e608d..d725cfaa 100644
--- a/vendor/github.com/cilium/ebpf/internal/unix/types_linux.go
+++ b/vendor/github.com/cilium/ebpf/internal/unix/types_linux.go
@@ -81,16 +81,15 @@ const (
 	SO_DETACH_BPF             = linux.SO_DETACH_BPF
 	SOL_SOCKET                = linux.SOL_SOCKET
 	SIGPROF                   = linux.SIGPROF
-	SIGUSR1                   = linux.SIGUSR1
 	SIG_BLOCK                 = linux.SIG_BLOCK
 	SIG_UNBLOCK               = linux.SIG_UNBLOCK
+	EM_NONE                   = linux.EM_NONE
+	EM_BPF                    = linux.EM_BPF
 	BPF_FS_MAGIC              = linux.BPF_FS_MAGIC
 	TRACEFS_MAGIC             = linux.TRACEFS_MAGIC
 	DEBUGFS_MAGIC             = linux.DEBUGFS_MAGIC
 	BPF_RB_NO_WAKEUP          = linux.BPF_RB_NO_WAKEUP
 	BPF_RB_FORCE_WAKEUP       = linux.BPF_RB_FORCE_WAKEUP
-	AF_UNSPEC                 = linux.AF_UNSPEC
-	IFF_UP                    = linux.IFF_UP
 )
 
 type Statfs_t = linux.Statfs_t
diff --git a/vendor/github.com/cilium/ebpf/internal/unix/types_other.go b/vendor/github.com/cilium/ebpf/internal/unix/types_other.go
index 06cc3a09..3ff89627 100644
--- a/vendor/github.com/cilium/ebpf/internal/unix/types_other.go
+++ b/vendor/github.com/cilium/ebpf/internal/unix/types_other.go
@@ -84,17 +84,16 @@ const (
 	SO_DETACH_BPF
 	SOL_SOCKET
 	SIGPROF
-	SIGUSR1
 	SIG_BLOCK
 	SIG_UNBLOCK
+	EM_NONE
+	EM_BPF
 	BPF_FS_MAGIC
 	TRACEFS_MAGIC
 	DEBUGFS_MAGIC
 	BPF_RB_NO_WAKEUP
 	BPF_RB_FORCE_WAKEUP
 	BPF_F_LOCK
-	AF_UNSPEC
-	IFF_UP
 )
 
 type Statfs_t struct {
diff --git a/vendor/github.com/cilium/ebpf/internal/linux/vdso.go b/vendor/github.com/cilium/ebpf/internal/vdso.go
similarity index 93%
rename from vendor/github.com/cilium/ebpf/internal/linux/vdso.go
rename to vendor/github.com/cilium/ebpf/internal/vdso.go
index 1d8d0ef6..10492785 100644
--- a/vendor/github.com/cilium/ebpf/internal/linux/vdso.go
+++ b/vendor/github.com/cilium/ebpf/internal/vdso.go
@@ -1,4 +1,4 @@
-package linux
+package internal
 
 import (
 	"debug/elf"
@@ -9,7 +9,6 @@ import (
 	"math"
 	"os"
 
-	"github.com/cilium/ebpf/internal"
 	"github.com/cilium/ebpf/internal/unix"
 )
 
@@ -83,7 +82,7 @@ type elfNoteHeader struct {
 // vdsoLinuxVersionCode returns the LINUX_VERSION_CODE embedded in
 // the ELF notes section of the binary provided by the reader.
 func vdsoLinuxVersionCode(r io.ReaderAt) (uint32, error) {
-	hdr, err := internal.NewSafeELFFile(r)
+	hdr, err := NewSafeELFFile(r)
 	if err != nil {
 		return 0, fmt.Errorf("reading vDSO ELF: %w", err)
 	}
@@ -111,7 +110,7 @@ func vdsoLinuxVersionCode(r io.ReaderAt) (uint32, error) {
 			var name string
 			if n.NameSize > 0 {
 				// Read the note name, aligned to 4 bytes.
-				buf := make([]byte, internal.Align(n.NameSize, 4))
+				buf := make([]byte, Align(n.NameSize, 4))
 				if err := binary.Read(sr, hdr.ByteOrder, &buf); err != nil {
 					return 0, fmt.Errorf("reading note name: %w", err)
 				}
@@ -133,7 +132,7 @@ func vdsoLinuxVersionCode(r io.ReaderAt) (uint32, error) {
 				}
 
 				// Discard the note descriptor if it exists but we're not interested in it.
-				if _, err := io.CopyN(io.Discard, sr, int64(internal.Align(n.DescSize, 4))); err != nil {
+				if _, err := io.CopyN(io.Discard, sr, int64(Align(n.DescSize, 4))); err != nil {
 					return 0, err
 				}
 			}
diff --git a/vendor/github.com/cilium/ebpf/internal/version.go b/vendor/github.com/cilium/ebpf/internal/version.go
index a230830b..acd4650a 100644
--- a/vendor/github.com/cilium/ebpf/internal/version.go
+++ b/vendor/github.com/cilium/ebpf/internal/version.go
@@ -2,6 +2,9 @@ package internal
 
 import (
 	"fmt"
+	"sync"
+
+	"github.com/cilium/ebpf/internal/unix"
 )
 
 const (
@@ -75,3 +78,30 @@ func (v Version) Kernel() uint32 {
 	// each other when overflowing 8 bits.
 	return uint32(uint8(v[0]))<<16 | uint32(uint8(v[1]))<<8 | uint32(uint8(s))
 }
+
+// KernelVersion returns the version of the currently running kernel.
+var KernelVersion = sync.OnceValues(func() (Version, error) {
+	return detectKernelVersion()
+})
+
+// detectKernelVersion returns the version of the running kernel.
+func detectKernelVersion() (Version, error) {
+	vc, err := vdsoVersion()
+	if err != nil {
+		return Version{}, err
+	}
+	return NewVersionFromCode(vc), nil
+}
+
+// KernelRelease returns the release string of the running kernel.
+// Its format depends on the Linux distribution and corresponds to directory
+// names in /lib/modules by convention. Some examples are 5.15.17-1-lts and
+// 4.19.0-16-amd64.
+func KernelRelease() (string, error) {
+	var uname unix.Utsname
+	if err := unix.Uname(&uname); err != nil {
+		return "", fmt.Errorf("uname failed: %w", err)
+	}
+
+	return unix.ByteSliceToString(uname.Release[:]), nil
+}
diff --git a/vendor/github.com/cilium/ebpf/link/kprobe.go b/vendor/github.com/cilium/ebpf/link/kprobe.go
index 6f93a27a..fe3f17c3 100644
--- a/vendor/github.com/cilium/ebpf/link/kprobe.go
+++ b/vendor/github.com/cilium/ebpf/link/kprobe.go
@@ -10,7 +10,6 @@ import (
 
 	"github.com/cilium/ebpf"
 	"github.com/cilium/ebpf/internal"
-	"github.com/cilium/ebpf/internal/linux"
 	"github.com/cilium/ebpf/internal/sys"
 	"github.com/cilium/ebpf/internal/tracefs"
 	"github.com/cilium/ebpf/internal/unix"
@@ -61,9 +60,6 @@ func (ko *KprobeOptions) cookie() uint64 {
 // platform's syscall prefix (e.g. __x64_) to support attaching to syscalls
 // in a portable fashion.
 //
-// On kernels 6.11 and later, setting a kprobe on a nonexistent symbol using
-// tracefs incorrectly returns [unix.EINVAL] instead of [os.ErrNotExist].
-//
 // The returned Link may implement [PerfEvent].
 func Kprobe(symbol string, prog *ebpf.Program, opts *KprobeOptions) (Link, error) {
 	k, err := kprobe(symbol, prog, opts, false)
@@ -95,7 +91,7 @@ func Kprobe(symbol string, prog *ebpf.Program, opts *KprobeOptions) (Link, error
 // in a portable fashion.
 //
 // On kernels 5.10 and earlier, setting a kretprobe on a nonexistent symbol
-// incorrectly returns [unix.EINVAL] instead of [os.ErrNotExist].
+// incorrectly returns unix.EINVAL instead of os.ErrNotExist.
 //
 // The returned Link may implement [PerfEvent].
 func Kretprobe(symbol string, prog *ebpf.Program, opts *KprobeOptions) (Link, error) {
@@ -173,7 +169,7 @@ func kprobe(symbol string, prog *ebpf.Program, opts *KprobeOptions, ret bool) (*
 	// Use kprobe PMU if the kernel has it available.
 	tp, err := pmuProbe(args)
 	if errors.Is(err, os.ErrNotExist) || errors.Is(err, unix.EINVAL) {
-		if prefix := linux.PlatformPrefix(); prefix != "" {
+		if prefix := internal.PlatformPrefix(); prefix != "" {
 			args.Symbol = prefix + symbol
 			tp, err = pmuProbe(args)
 		}
@@ -181,7 +177,7 @@ func kprobe(symbol string, prog *ebpf.Program, opts *KprobeOptions, ret bool) (*
 	if err == nil {
 		return tp, nil
 	}
-	if !errors.Is(err, ErrNotSupported) {
+	if err != nil && !errors.Is(err, ErrNotSupported) {
 		return nil, fmt.Errorf("creating perf_kprobe PMU (arch-specific fallback for %q): %w", symbol, err)
 	}
 
@@ -189,7 +185,7 @@ func kprobe(symbol string, prog *ebpf.Program, opts *KprobeOptions, ret bool) (*
 	args.Symbol = symbol
 	tp, err = tracefsProbe(args)
 	if errors.Is(err, os.ErrNotExist) || errors.Is(err, unix.EINVAL) {
-		if prefix := linux.PlatformPrefix(); prefix != "" {
+		if prefix := internal.PlatformPrefix(); prefix != "" {
 			args.Symbol = prefix + symbol
 			tp, err = tracefsProbe(args)
 		}
diff --git a/vendor/github.com/cilium/ebpf/link/kprobe_multi.go b/vendor/github.com/cilium/ebpf/link/kprobe_multi.go
index 094cb053..f7a8291f 100644
--- a/vendor/github.com/cilium/ebpf/link/kprobe_multi.go
+++ b/vendor/github.com/cilium/ebpf/link/kprobe_multi.go
@@ -60,7 +60,7 @@ func KprobeMulti(prog *ebpf.Program, opts KprobeMultiOptions) (Link, error) {
 //
 // Requires at least Linux 5.18.
 func KretprobeMulti(prog *ebpf.Program, opts KprobeMultiOptions) (Link, error) {
-	return kprobeMulti(prog, opts, sys.BPF_F_KPROBE_MULTI_RETURN)
+	return kprobeMulti(prog, opts, unix.BPF_F_KPROBE_MULTI_RETURN)
 }
 
 func kprobeMulti(prog *ebpf.Program, opts KprobeMultiOptions, flags uint32) (Link, error) {
@@ -126,7 +126,7 @@ type kprobeMultiLink struct {
 
 var _ Link = (*kprobeMultiLink)(nil)
 
-func (kml *kprobeMultiLink) Update(_ *ebpf.Program) error {
+func (kml *kprobeMultiLink) Update(prog *ebpf.Program) error {
 	return fmt.Errorf("update kprobe_multi: %w", ErrNotSupported)
 }
 
@@ -149,7 +149,7 @@ func (kml *kprobeMultiLink) Info() (*Info, error) {
 	}, nil
 }
 
-var haveBPFLinkKprobeMulti = internal.NewFeatureTest("bpf_link_kprobe_multi", func() error {
+var haveBPFLinkKprobeMulti = internal.NewFeatureTest("bpf_link_kprobe_multi", "5.18", func() error {
 	prog, err := ebpf.NewProgram(&ebpf.ProgramSpec{
 		Name: "probe_kpm_link",
 		Type: ebpf.Kprobe,
@@ -188,4 +188,4 @@ var haveBPFLinkKprobeMulti = internal.NewFeatureTest("bpf_link_kprobe_multi", fu
 	fd.Close()
 
 	return nil
-}, "5.18")
+})
diff --git a/vendor/github.com/cilium/ebpf/link/link.go b/vendor/github.com/cilium/ebpf/link/link.go
index 796769f8..9c34616c 100644
--- a/vendor/github.com/cilium/ebpf/link/link.go
+++ b/vendor/github.com/cilium/ebpf/link/link.go
@@ -78,9 +78,7 @@ func NewFromID(id ID) (Link, error) {
 	return wrapRawLink(&RawLink{fd, ""})
 }
 
-// LoadPinnedLink loads a Link from a pin (file) on the BPF virtual filesystem.
-//
-// Requires at least Linux 5.7.
+// LoadPinnedLink loads a link that was persisted into a bpffs.
 func LoadPinnedLink(fileName string, opts *ebpf.LoadPinOptions) (Link, error) {
 	raw, err := loadPinnedRawLink(fileName, opts)
 	if err != nil {
@@ -352,7 +350,7 @@ func AttachRawLink(opts RawLinkOptions) (*RawLink, error) {
 }
 
 func loadPinnedRawLink(fileName string, opts *ebpf.LoadPinOptions) (*RawLink, error) {
-	fd, typ, err := sys.ObjGetTyped(&sys.ObjGetAttr{
+	fd, err := sys.ObjGet(&sys.ObjGetAttr{
 		Pathname:  sys.NewStringPointer(fileName),
 		FileFlags: opts.Marshal(),
 	})
@@ -360,11 +358,6 @@ func loadPinnedRawLink(fileName string, opts *ebpf.LoadPinOptions) (*RawLink, er
 		return nil, fmt.Errorf("load pinned link: %w", err)
 	}
 
-	if typ != sys.BPF_TYPE_LINK {
-		_ = fd.Close()
-		return nil, fmt.Errorf("%s is not a Link", fileName)
-	}
-
 	return &RawLink{fd, fileName}, nil
 }
 
@@ -387,7 +380,7 @@ func (l *RawLink) Close() error {
 // Calling Close on a pinned Link will not break the link
 // until the pin is removed.
 func (l *RawLink) Pin(fileName string) error {
-	if err := sys.Pin(l.pinnedPath, fileName, l.fd); err != nil {
+	if err := internal.Pin(l.pinnedPath, fileName, l.fd); err != nil {
 		return err
 	}
 	l.pinnedPath = fileName
@@ -396,7 +389,7 @@ func (l *RawLink) Pin(fileName string) error {
 
 // Unpin implements the Link interface.
 func (l *RawLink) Unpin() error {
-	if err := sys.Unpin(l.pinnedPath); err != nil {
+	if err := internal.Unpin(l.pinnedPath); err != nil {
 		return err
 	}
 	l.pinnedPath = ""
diff --git a/vendor/github.com/cilium/ebpf/link/netfilter.go b/vendor/github.com/cilium/ebpf/link/netfilter.go
index 9436d11d..34be3908 100644
--- a/vendor/github.com/cilium/ebpf/link/netfilter.go
+++ b/vendor/github.com/cilium/ebpf/link/netfilter.go
@@ -63,7 +63,7 @@ func AttachNetfilter(opts NetfilterOptions) (Link, error) {
 	return &netfilterLink{RawLink{fd, ""}}, nil
 }
 
-func (*netfilterLink) Update(_ *ebpf.Program) error {
+func (*netfilterLink) Update(new *ebpf.Program) error {
 	return fmt.Errorf("netfilter update: %w", ErrNotSupported)
 }
 
diff --git a/vendor/github.com/cilium/ebpf/link/perf_event.go b/vendor/github.com/cilium/ebpf/link/perf_event.go
index 7440e8b2..1d8feb58 100644
--- a/vendor/github.com/cilium/ebpf/link/perf_event.go
+++ b/vendor/github.com/cilium/ebpf/link/perf_event.go
@@ -115,7 +115,7 @@ func (pl *perfEventLink) Close() error {
 	return nil
 }
 
-func (pl *perfEventLink) Update(_ *ebpf.Program) error {
+func (pl *perfEventLink) Update(prog *ebpf.Program) error {
 	return fmt.Errorf("perf event link update: %w", ErrNotSupported)
 }
 
@@ -185,7 +185,7 @@ func (pi *perfEventIoctl) isLink() {}
 //
 // Detaching a program from a perf event is currently not possible, so a
 // program replacement mechanism cannot be implemented for perf events.
-func (pi *perfEventIoctl) Update(_ *ebpf.Program) error {
+func (pi *perfEventIoctl) Update(prog *ebpf.Program) error {
 	return fmt.Errorf("perf event ioctl update: %w", ErrNotSupported)
 }
 
@@ -303,7 +303,7 @@ func openTracepointPerfEvent(tid uint64, pid int) (*sys.FD, error) {
 //
 // https://elixir.bootlin.com/linux/v5.16.8/source/kernel/bpf/syscall.c#L4307
 // https://github.com/torvalds/linux/commit/b89fbfbb854c9afc3047e8273cc3a694650b802e
-var haveBPFLinkPerfEvent = internal.NewFeatureTest("bpf_link_perf_event", func() error {
+var haveBPFLinkPerfEvent = internal.NewFeatureTest("bpf_link_perf_event", "5.15", func() error {
 	prog, err := ebpf.NewProgram(&ebpf.ProgramSpec{
 		Name: "probe_bpf_perf_link",
 		Type: ebpf.Kprobe,
@@ -329,4 +329,4 @@ var haveBPFLinkPerfEvent = internal.NewFeatureTest("bpf_link_perf_event", func()
 		return nil
 	}
 	return err
-}, "5.15")
+})
diff --git a/vendor/github.com/cilium/ebpf/link/syscalls.go b/vendor/github.com/cilium/ebpf/link/syscalls.go
index 25951b01..d09b5acb 100644
--- a/vendor/github.com/cilium/ebpf/link/syscalls.go
+++ b/vendor/github.com/cilium/ebpf/link/syscalls.go
@@ -30,7 +30,7 @@ const (
 	NetkitType        = sys.BPF_LINK_TYPE_NETKIT
 )
 
-var haveProgAttach = internal.NewFeatureTest("BPF_PROG_ATTACH", func() error {
+var haveProgAttach = internal.NewFeatureTest("BPF_PROG_ATTACH", "4.10", func() error {
 	prog, err := ebpf.NewProgram(&ebpf.ProgramSpec{
 		Type:    ebpf.CGroupSKB,
 		License: "MIT",
@@ -48,9 +48,9 @@ var haveProgAttach = internal.NewFeatureTest("BPF_PROG_ATTACH", func() error {
 	// have the syscall.
 	prog.Close()
 	return nil
-}, "4.10")
+})
 
-var haveProgAttachReplace = internal.NewFeatureTest("BPF_PROG_ATTACH atomic replacement of MULTI progs", func() error {
+var haveProgAttachReplace = internal.NewFeatureTest("BPF_PROG_ATTACH atomic replacement of MULTI progs", "5.5", func() error {
 	if err := haveProgAttach(); err != nil {
 		return err
 	}
@@ -90,9 +90,9 @@ var haveProgAttachReplace = internal.NewFeatureTest("BPF_PROG_ATTACH atomic repl
 		return nil
 	}
 	return err
-}, "5.5")
+})
 
-var haveBPFLink = internal.NewFeatureTest("bpf_link", func() error {
+var haveBPFLink = internal.NewFeatureTest("bpf_link", "5.7", func() error {
 	attr := sys.LinkCreateAttr{
 		// This is a hopefully invalid file descriptor, which triggers EBADF.
 		TargetFd:   ^uint32(0),
@@ -107,9 +107,9 @@ var haveBPFLink = internal.NewFeatureTest("bpf_link", func() error {
 		return nil
 	}
 	return err
-}, "5.7")
+})
 
-var haveProgQuery = internal.NewFeatureTest("BPF_PROG_QUERY", func() error {
+var haveProgQuery = internal.NewFeatureTest("BPF_PROG_QUERY", "4.15", func() error {
 	attr := sys.ProgQueryAttr{
 		// We rely on this being checked during the syscall.
 		// With an otherwise correct payload we expect EBADF here
@@ -127,9 +127,9 @@ var haveProgQuery = internal.NewFeatureTest("BPF_PROG_QUERY", func() error {
 		return ErrNotSupported
 	}
 	return errors.New("syscall succeeded unexpectedly")
-}, "4.15")
+})
 
-var haveTCX = internal.NewFeatureTest("tcx", func() error {
+var haveTCX = internal.NewFeatureTest("tcx", "6.6", func() error {
 	prog, err := ebpf.NewProgram(&ebpf.ProgramSpec{
 		Type:    ebpf.SchedCLS,
 		License: "MIT",
@@ -162,9 +162,9 @@ var haveTCX = internal.NewFeatureTest("tcx", func() error {
 		return ErrNotSupported
 	}
 	return errors.New("syscall succeeded unexpectedly")
-}, "6.6")
+})
 
-var haveNetkit = internal.NewFeatureTest("netkit", func() error {
+var haveNetkit = internal.NewFeatureTest("netkit", "6.7", func() error {
 	prog, err := ebpf.NewProgram(&ebpf.ProgramSpec{
 		Type:    ebpf.SchedCLS,
 		License: "MIT",
@@ -197,4 +197,4 @@ var haveNetkit = internal.NewFeatureTest("netkit", func() error {
 		return ErrNotSupported
 	}
 	return errors.New("syscall succeeded unexpectedly")
-}, "6.7")
+})
diff --git a/vendor/github.com/cilium/ebpf/link/tracing.go b/vendor/github.com/cilium/ebpf/link/tracing.go
index a461007f..9e570afc 100644
--- a/vendor/github.com/cilium/ebpf/link/tracing.go
+++ b/vendor/github.com/cilium/ebpf/link/tracing.go
@@ -14,7 +14,7 @@ type tracing struct {
 	RawLink
 }
 
-func (f *tracing) Update(_ *ebpf.Program) error {
+func (f *tracing) Update(new *ebpf.Program) error {
 	return fmt.Errorf("tracing update: %w", ErrNotSupported)
 }
 
diff --git a/vendor/github.com/cilium/ebpf/link/uprobe.go b/vendor/github.com/cilium/ebpf/link/uprobe.go
index 1852a3fa..194d1d31 100644
--- a/vendor/github.com/cilium/ebpf/link/uprobe.go
+++ b/vendor/github.com/cilium/ebpf/link/uprobe.go
@@ -16,7 +16,7 @@ var (
 	uprobeRefCtrOffsetPMUPath = "/sys/bus/event_source/devices/uprobe/format/ref_ctr_offset"
 	// elixir.bootlin.com/linux/v5.15-rc7/source/kernel/events/core.c#L9799
 	uprobeRefCtrOffsetShift = 32
-	haveRefCtrOffsetPMU     = internal.NewFeatureTest("RefCtrOffsetPMU", func() error {
+	haveRefCtrOffsetPMU     = internal.NewFeatureTest("RefCtrOffsetPMU", "4.20", func() error {
 		_, err := os.Stat(uprobeRefCtrOffsetPMUPath)
 		if errors.Is(err, os.ErrNotExist) {
 			return internal.ErrNotSupported
@@ -25,7 +25,7 @@ var (
 			return err
 		}
 		return nil
-	}, "4.20")
+	})
 
 	// ErrNoSymbol indicates that the given symbol was not found
 	// in the ELF symbols table.
@@ -321,7 +321,7 @@ func (ex *Executable) uprobe(symbol string, prog *ebpf.Program, opts *UprobeOpti
 	if err == nil {
 		return tp, nil
 	}
-	if !errors.Is(err, ErrNotSupported) {
+	if err != nil && !errors.Is(err, ErrNotSupported) {
 		return nil, fmt.Errorf("creating perf_uprobe PMU: %w", err)
 	}
 
diff --git a/vendor/github.com/cilium/ebpf/link/uprobe_multi.go b/vendor/github.com/cilium/ebpf/link/uprobe_multi.go
index 49dc18b4..aea807b3 100644
--- a/vendor/github.com/cilium/ebpf/link/uprobe_multi.go
+++ b/vendor/github.com/cilium/ebpf/link/uprobe_multi.go
@@ -47,7 +47,7 @@ func (ex *Executable) UretprobeMulti(symbols []string, prog *ebpf.Program, opts
 	// The return probe is not limited for symbols entry, so there's no special
 	// setup for return uprobes (other than the extra flag). The symbols, opts.Offsets
 	// and opts.Addresses arrays follow the same logic as for entry uprobes.
-	return ex.uprobeMulti(symbols, prog, opts, sys.BPF_F_UPROBE_MULTI_RETURN)
+	return ex.uprobeMulti(symbols, prog, opts, unix.BPF_F_UPROBE_MULTI_RETURN)
 }
 
 func (ex *Executable) uprobeMulti(symbols []string, prog *ebpf.Program, opts *UprobeMultiOptions, flags uint32) (Link, error) {
@@ -99,11 +99,8 @@ func (ex *Executable) uprobeMulti(symbols []string, prog *ebpf.Program, opts *Up
 	if errors.Is(err, unix.ESRCH) {
 		return nil, fmt.Errorf("%w (specified pid not found?)", os.ErrNotExist)
 	}
-	// Since Linux commit 46ba0e49b642 ("bpf: fix multi-uprobe PID filtering
-	// logic"), if the provided pid overflows MaxInt32 (turning it negative), the
-	// kernel will return EINVAL instead of ESRCH.
 	if errors.Is(err, unix.EINVAL) {
-		return nil, fmt.Errorf("%w (invalid pid, missing symbol or prog's AttachType not AttachTraceUprobeMulti?)", err)
+		return nil, fmt.Errorf("%w (missing symbol or prog's AttachType not AttachTraceUprobeMulti?)", err)
 	}
 
 	if err != nil {
@@ -171,11 +168,11 @@ type uprobeMultiLink struct {
 
 var _ Link = (*uprobeMultiLink)(nil)
 
-func (kml *uprobeMultiLink) Update(_ *ebpf.Program) error {
+func (kml *uprobeMultiLink) Update(prog *ebpf.Program) error {
 	return fmt.Errorf("update uprobe_multi: %w", ErrNotSupported)
 }
 
-var haveBPFLinkUprobeMulti = internal.NewFeatureTest("bpf_link_uprobe_multi", func() error {
+var haveBPFLinkUprobeMulti = internal.NewFeatureTest("bpf_link_uprobe_multi", "6.6", func() error {
 	prog, err := ebpf.NewProgram(&ebpf.ProgramSpec{
 		Name: "probe_upm_link",
 		Type: ebpf.Kprobe,
@@ -216,4 +213,4 @@ var haveBPFLinkUprobeMulti = internal.NewFeatureTest("bpf_link_uprobe_multi", fu
 	// should not happen
 	fd.Close()
 	return errors.New("successfully attached uprobe_multi to /, kernel bug?")
-}, "6.6")
+})
diff --git a/vendor/github.com/cilium/ebpf/linker.go b/vendor/github.com/cilium/ebpf/linker.go
index 6f97af27..788f21b7 100644
--- a/vendor/github.com/cilium/ebpf/linker.go
+++ b/vendor/github.com/cilium/ebpf/linker.go
@@ -9,12 +9,10 @@ import (
 	"io/fs"
 	"math"
 	"slices"
-	"strings"
 
 	"github.com/cilium/ebpf/asm"
 	"github.com/cilium/ebpf/btf"
 	"github.com/cilium/ebpf/internal"
-	"github.com/cilium/ebpf/internal/kallsyms"
 )
 
 // handles stores handle objects to avoid gc cleanup
@@ -459,42 +457,3 @@ func resolveKconfigReferences(insns asm.Instructions) (_ *Map, err error) {
 
 	return kconfig, nil
 }
-
-func resolveKsymReferences(insns asm.Instructions) error {
-	var missing []string
-
-	iter := insns.Iterate()
-	for iter.Next() {
-		ins := iter.Ins
-		meta, _ := ins.Metadata.Get(ksymMetaKey{}).(*ksymMeta)
-		if meta == nil {
-			continue
-		}
-
-		addr, err := kallsyms.Address(meta.Name)
-		if err != nil {
-			return fmt.Errorf("resolve ksym %s: %w", meta.Name, err)
-		}
-		if addr != 0 {
-			ins.Constant = int64(addr)
-			continue
-		}
-
-		if meta.Binding == elf.STB_WEAK {
-			// A weak ksym variable in eBPF C means its resolution is optional.
-			// Set a zero constant explicitly for clarity.
-			ins.Constant = 0
-			continue
-		}
-
-		if !slices.Contains(missing, meta.Name) {
-			missing = append(missing, meta.Name)
-		}
-	}
-
-	if len(missing) > 0 {
-		return fmt.Errorf("kernel is missing symbol: %s", strings.Join(missing, ","))
-	}
-
-	return nil
-}
diff --git a/vendor/github.com/cilium/ebpf/map.go b/vendor/github.com/cilium/ebpf/map.go
index e5d8bd78..0b62101c 100644
--- a/vendor/github.com/cilium/ebpf/map.go
+++ b/vendor/github.com/cilium/ebpf/map.go
@@ -66,13 +66,16 @@ type MapSpec struct {
 	Pinning PinType
 
 	// Specify numa node during map creation
-	// (effective only if sys.BPF_F_NUMA_NODE flag is set,
+	// (effective only if unix.BPF_F_NUMA_NODE flag is set,
 	// which can be imported from golang.org/x/sys/unix)
 	NumaNode uint32
 
 	// The initial contents of the map. May be nil.
 	Contents []MapKV
 
+	// Whether to freeze a map after setting its initial contents.
+	Freeze bool
+
 	// InnerMap is used as a template for ArrayOfMaps and HashOfMaps
 	InnerMap *MapSpec
 
@@ -158,17 +161,6 @@ func (spec *MapSpec) fixupMagicFields() (*MapSpec, error) {
 			// behaviour in the past.
 			spec.MaxEntries = n
 		}
-
-	case CPUMap:
-		n, err := PossibleCPU()
-		if err != nil {
-			return nil, fmt.Errorf("fixup cpu map: %w", err)
-		}
-
-		if n := uint32(n); spec.MaxEntries == 0 || spec.MaxEntries > n {
-			// Perform clamping similar to PerfEventArray.
-			spec.MaxEntries = n
-		}
 	}
 
 	return spec, nil
@@ -198,14 +190,6 @@ func (ms *MapSpec) dataSection() ([]byte, *btf.Datasec, error) {
 	return value, ds, nil
 }
 
-func (ms *MapSpec) readOnly() bool {
-	return (ms.Flags & sys.BPF_F_RDONLY_PROG) > 0
-}
-
-func (ms *MapSpec) writeOnly() bool {
-	return (ms.Flags & sys.BPF_F_WRONLY_PROG) > 0
-}
-
 // MapKV is used to initialize the contents of a Map.
 type MapKV struct {
 	Key   interface{}
@@ -238,7 +222,7 @@ func (ms *MapSpec) Compatible(m *Map) error {
 
 	// BPF_F_RDONLY_PROG is set unconditionally for devmaps. Explicitly allow this
 	// mismatch.
-	if !((ms.Type == DevMap || ms.Type == DevMapHash) && m.flags^ms.Flags == sys.BPF_F_RDONLY_PROG) &&
+	if !((ms.Type == DevMap || ms.Type == DevMapHash) && m.flags^ms.Flags == unix.BPF_F_RDONLY_PROG) &&
 		m.flags != ms.Flags {
 		diffs = append(diffs, fmt.Sprintf("Flags: %d changed to %d", m.flags, ms.Flags))
 	}
@@ -270,8 +254,6 @@ type Map struct {
 	pinnedPath string
 	// Per CPU maps return values larger than the size in the spec
 	fullValueSize int
-
-	memory *Memory
 }
 
 // NewMapFromFD creates a map from a raw fd.
@@ -377,7 +359,7 @@ func newMapWithOptions(spec *MapSpec, opts MapOptions) (_ *Map, err error) {
 			return nil, errors.New("inner maps cannot be pinned")
 		}
 
-		template, err := spec.InnerMap.createMap(nil)
+		template, err := spec.InnerMap.createMap(nil, opts)
 		if err != nil {
 			return nil, fmt.Errorf("inner map: %w", err)
 		}
@@ -389,7 +371,7 @@ func newMapWithOptions(spec *MapSpec, opts MapOptions) (_ *Map, err error) {
 		innerFd = template.fd
 	}
 
-	m, err := spec.createMap(innerFd)
+	m, err := spec.createMap(innerFd, opts)
 	if err != nil {
 		return nil, err
 	}
@@ -405,54 +387,9 @@ func newMapWithOptions(spec *MapSpec, opts MapOptions) (_ *Map, err error) {
 	return m, nil
 }
 
-// Memory returns a memory-mapped region for the Map. The Map must have been
-// created with the BPF_F_MMAPABLE flag. Repeated calls to Memory return the
-// same mapping. Callers are responsible for coordinating access to Memory.
-func (m *Map) Memory() (*Memory, error) {
-	if m.memory != nil {
-		return m.memory, nil
-	}
-
-	if m.flags&sys.BPF_F_MMAPABLE == 0 {
-		return nil, fmt.Errorf("Map was not created with the BPF_F_MMAPABLE flag: %w", ErrNotSupported)
-	}
-
-	size, err := m.memorySize()
-	if err != nil {
-		return nil, err
-	}
-
-	mm, err := newMemory(m.FD(), size)
-	if err != nil {
-		return nil, fmt.Errorf("creating new Memory: %w", err)
-	}
-
-	m.memory = mm
-
-	return mm, nil
-}
-
-func (m *Map) memorySize() (int, error) {
-	switch m.Type() {
-	case Array:
-		// In Arrays, values are always laid out on 8-byte boundaries regardless of
-		// architecture. Multiply by MaxEntries and align the result to the host's
-		// page size.
-		size := int(internal.Align(m.ValueSize(), 8) * m.MaxEntries())
-		size = internal.Align(size, os.Getpagesize())
-		return size, nil
-	case Arena:
-		// For Arenas, MaxEntries denotes the maximum number of pages available to
-		// the arena.
-		return int(m.MaxEntries()) * os.Getpagesize(), nil
-	}
-
-	return 0, fmt.Errorf("determine memory size of map type %s: %w", m.Type(), ErrNotSupported)
-}
-
 // createMap validates the spec's properties and creates the map in the kernel
 // using the given opts. It does not populate or freeze the map.
-func (spec *MapSpec) createMap(inner *sys.FD) (_ *Map, err error) {
+func (spec *MapSpec) createMap(inner *sys.FD, opts MapOptions) (_ *Map, err error) {
 	closeOnError := func(closer io.Closer) {
 		if err != nil {
 			closer.Close()
@@ -479,7 +416,7 @@ func (spec *MapSpec) createMap(inner *sys.FD) (_ *Map, err error) {
 		KeySize:    spec.KeySize,
 		ValueSize:  spec.ValueSize,
 		MaxEntries: spec.MaxEntries,
-		MapFlags:   spec.Flags,
+		MapFlags:   sys.MapFlags(spec.Flags),
 		NumaNode:   spec.NumaNode,
 	}
 
@@ -537,32 +474,32 @@ func handleMapCreateError(attr sys.MapCreateAttr, spec *MapSpec, err error) erro
 	if errors.Is(err, unix.EINVAL) && spec.Type == UnspecifiedMap {
 		return fmt.Errorf("map create: cannot use type %s", UnspecifiedMap)
 	}
-	if errors.Is(err, unix.EINVAL) && spec.Flags&sys.BPF_F_NO_PREALLOC > 0 {
+	if errors.Is(err, unix.EINVAL) && spec.Flags&unix.BPF_F_NO_PREALLOC > 0 {
 		return fmt.Errorf("map create: %w (noPrealloc flag may be incompatible with map type %s)", err, spec.Type)
 	}
 
-	if spec.Type.canStoreMap() {
+	switch spec.Type {
+	case ArrayOfMaps, HashOfMaps:
 		if haveFeatErr := haveNestedMaps(); haveFeatErr != nil {
 			return fmt.Errorf("map create: %w", haveFeatErr)
 		}
 	}
-
-	if spec.readOnly() || spec.writeOnly() {
+	if spec.Flags&(unix.BPF_F_RDONLY_PROG|unix.BPF_F_WRONLY_PROG) > 0 || spec.Freeze {
 		if haveFeatErr := haveMapMutabilityModifiers(); haveFeatErr != nil {
 			return fmt.Errorf("map create: %w", haveFeatErr)
 		}
 	}
-	if spec.Flags&sys.BPF_F_MMAPABLE > 0 {
+	if spec.Flags&unix.BPF_F_MMAPABLE > 0 {
 		if haveFeatErr := haveMmapableMaps(); haveFeatErr != nil {
 			return fmt.Errorf("map create: %w", haveFeatErr)
 		}
 	}
-	if spec.Flags&sys.BPF_F_INNER_MAP > 0 {
+	if spec.Flags&unix.BPF_F_INNER_MAP > 0 {
 		if haveFeatErr := haveInnerMaps(); haveFeatErr != nil {
 			return fmt.Errorf("map create: %w", haveFeatErr)
 		}
 	}
-	if spec.Flags&sys.BPF_F_NO_PREALLOC > 0 {
+	if spec.Flags&unix.BPF_F_NO_PREALLOC > 0 {
 		if haveFeatErr := haveNoPreallocMaps(); haveFeatErr != nil {
 			return fmt.Errorf("map create: %w", haveFeatErr)
 		}
@@ -593,7 +530,6 @@ func newMap(fd *sys.FD, name string, typ MapType, keySize, valueSize, maxEntries
 		flags,
 		"",
 		int(valueSize),
-		nil,
 	}
 
 	if !typ.hasPerCPUValue() {
@@ -641,12 +577,7 @@ func (m *Map) Flags() uint32 {
 	return m.flags
 }
 
-// Info returns metadata about the map. This was first introduced in Linux 4.5,
-// but newer kernels support more MapInfo fields with the introduction of more
-// features. See [MapInfo] and its methods for more details.
-//
-// Returns an error wrapping ErrNotSupported if the kernel supports neither
-// BPF_OBJ_GET_INFO_BY_FD nor reading map information from /proc/self/fdinfo.
+// Info returns metadata about the map.
 func (m *Map) Info() (*MapInfo, error) {
 	return newMapInfoFromFd(m.fd)
 }
@@ -673,7 +604,7 @@ func (m *Map) Handle() (*btf.Handle, error) {
 type MapLookupFlags uint64
 
 // LookupLock look up the value of a spin-locked map.
-const LookupLock MapLookupFlags = sys.BPF_F_LOCK
+const LookupLock MapLookupFlags = unix.BPF_F_LOCK
 
 // Lookup retrieves a value from a Map.
 //
@@ -1405,7 +1336,6 @@ func (m *Map) Clone() (*Map, error) {
 		m.flags,
 		"",
 		m.fullValueSize,
-		nil,
 	}, nil
 }
 
@@ -1419,7 +1349,7 @@ func (m *Map) Clone() (*Map, error) {
 // This requires bpffs to be mounted above fileName.
 // See https://docs.cilium.io/en/stable/network/kubernetes/configuration/#mounting-bpffs-with-systemd
 func (m *Map) Pin(fileName string) error {
-	if err := sys.Pin(m.pinnedPath, fileName, m.fd); err != nil {
+	if err := internal.Pin(m.pinnedPath, fileName, m.fd); err != nil {
 		return err
 	}
 	m.pinnedPath = fileName
@@ -1432,7 +1362,7 @@ func (m *Map) Pin(fileName string) error {
 //
 // Unpinning an unpinned Map returns nil.
 func (m *Map) Unpin() error {
-	if err := sys.Unpin(m.pinnedPath); err != nil {
+	if err := internal.Unpin(m.pinnedPath); err != nil {
 		return err
 	}
 	m.pinnedPath = ""
@@ -1470,7 +1400,7 @@ func (m *Map) finalize(spec *MapSpec) error {
 		}
 	}
 
-	if isConstantDataSection(spec.Name) || isKconfigSection(spec.Name) {
+	if spec.Freeze {
 		if err := m.Freeze(); err != nil {
 			return fmt.Errorf("freezing map: %w", err)
 		}
@@ -1571,11 +1501,9 @@ func (m *Map) unmarshalValue(value any, buf sysenc.Buffer) error {
 	return buf.Unmarshal(value)
 }
 
-// LoadPinnedMap opens a Map from a pin (file) on the BPF virtual filesystem.
-//
-// Requires at least Linux 4.5.
+// LoadPinnedMap loads a Map from a BPF file.
 func LoadPinnedMap(fileName string, opts *LoadPinOptions) (*Map, error) {
-	fd, typ, err := sys.ObjGetTyped(&sys.ObjGetAttr{
+	fd, err := sys.ObjGet(&sys.ObjGetAttr{
 		Pathname:  sys.NewStringPointer(fileName),
 		FileFlags: opts.Marshal(),
 	})
@@ -1583,11 +1511,6 @@ func LoadPinnedMap(fileName string, opts *LoadPinOptions) (*Map, error) {
 		return nil, err
 	}
 
-	if typ != sys.BPF_TYPE_MAP {
-		_ = fd.Close()
-		return nil, fmt.Errorf("%s is not a Map", fileName)
-	}
-
 	m, err := newMapFromFD(fd)
 	if err == nil {
 		m.pinnedPath = fileName
@@ -1607,10 +1530,6 @@ func unmarshalMap(buf sysenc.Buffer) (*Map, error) {
 
 // marshalMap marshals the fd of a map into a buffer in host endianness.
 func marshalMap(m *Map, length int) ([]byte, error) {
-	if m == nil {
-		return nil, errors.New("can't marshal a nil Map")
-	}
-
 	if length != 4 {
 		return nil, fmt.Errorf("can't marshal map to %d bytes", length)
 	}
diff --git a/vendor/github.com/cilium/ebpf/memory.go b/vendor/github.com/cilium/ebpf/memory.go
deleted file mode 100644
index 312c9671..00000000
--- a/vendor/github.com/cilium/ebpf/memory.go
+++ /dev/null
@@ -1,145 +0,0 @@
-package ebpf
-
-import (
-	"errors"
-	"fmt"
-	"io"
-	"runtime"
-
-	"github.com/cilium/ebpf/internal/unix"
-)
-
-// Memory is the building block for accessing the memory of specific bpf map
-// types (Array and Arena at the time of writing) without going through the bpf
-// syscall interface.
-//
-// Given the fd of a bpf map created with the BPF_F_MMAPABLE flag, a shared
-// 'file'-based memory-mapped region can be allocated in the process' address
-// space, exposing the bpf map's memory by simply accessing a memory location.
-
-var ErrReadOnly = errors.New("resource is read-only")
-
-// Memory implements accessing a Map's memory without making any syscalls.
-// Pay attention to the difference between Go and C struct alignment rules. Use
-// [structs.HostLayout] on supported Go versions to help with alignment.
-//
-// Note on memory coherence: avoid using packed structs in memory shared between
-// user space and eBPF C programs. This drops a struct's memory alignment to 1,
-// forcing the compiler to use single-byte loads and stores for field accesses.
-// This may lead to partially-written data to be observed from user space.
-//
-// On most architectures, the memmove implementation used by Go's copy() will
-// access data in word-sized chunks. If paired with a matching access pattern on
-// the eBPF C side (and if using default memory alignment), accessing shared
-// memory without atomics or other synchronization primitives should be sound
-// for individual values. For accesses beyond a single value, the usual
-// concurrent programming rules apply.
-type Memory struct {
-	b  []byte
-	ro bool
-}
-
-func newMemory(fd, size int) (*Memory, error) {
-	// Typically, maps created with BPF_F_RDONLY_PROG remain writable from user
-	// space until frozen. As a security precaution, the kernel doesn't allow
-	// mapping bpf map memory as read-write into user space if the bpf map was
-	// frozen, or if it was created using the RDONLY_PROG flag.
-	//
-	// The user would be able to write to the map after freezing (since the kernel
-	// can't change the protection mode of an already-mapped page), while the
-	// verifier assumes the contents to be immutable.
-	b, err := unix.Mmap(fd, 0, size, unix.PROT_READ|unix.PROT_WRITE, unix.MAP_SHARED)
-
-	// If the map is frozen when an rw mapping is requested, expect EPERM. If the
-	// map was created with BPF_F_RDONLY_PROG, expect EACCES.
-	var ro bool
-	if errors.Is(err, unix.EPERM) || errors.Is(err, unix.EACCES) {
-		ro = true
-		b, err = unix.Mmap(fd, 0, size, unix.PROT_READ, unix.MAP_SHARED)
-	}
-	if err != nil {
-		return nil, fmt.Errorf("setting up memory-mapped region: %w", err)
-	}
-
-	mm := &Memory{
-		b,
-		ro,
-	}
-	runtime.SetFinalizer(mm, (*Memory).close)
-
-	return mm, nil
-}
-
-func (mm *Memory) close() {
-	if err := unix.Munmap(mm.b); err != nil {
-		panic(fmt.Errorf("unmapping memory: %w", err))
-	}
-	mm.b = nil
-}
-
-// Size returns the size of the memory-mapped region in bytes.
-func (mm *Memory) Size() int {
-	return len(mm.b)
-}
-
-// ReadOnly returns true if the memory-mapped region is read-only.
-func (mm *Memory) ReadOnly() bool {
-	return mm.ro
-}
-
-// bounds returns true if an access at off of the given size is within bounds.
-func (mm *Memory) bounds(off uint64, size uint64) bool {
-	return off+size < uint64(len(mm.b))
-}
-
-// ReadAt implements [io.ReaderAt]. Useful for creating a new [io.OffsetWriter].
-//
-// See [Memory] for details around memory coherence.
-func (mm *Memory) ReadAt(p []byte, off int64) (int, error) {
-	if mm.b == nil {
-		return 0, fmt.Errorf("memory-mapped region closed")
-	}
-
-	if p == nil {
-		return 0, fmt.Errorf("input buffer p is nil")
-	}
-
-	if off < 0 || off >= int64(len(mm.b)) {
-		return 0, fmt.Errorf("read offset out of range")
-	}
-
-	n := copy(p, mm.b[off:])
-	if n < len(p) {
-		return n, io.EOF
-	}
-
-	return n, nil
-}
-
-// WriteAt implements [io.WriterAt]. Useful for creating a new
-// [io.SectionReader].
-//
-// See [Memory] for details around memory coherence.
-func (mm *Memory) WriteAt(p []byte, off int64) (int, error) {
-	if mm.b == nil {
-		return 0, fmt.Errorf("memory-mapped region closed")
-	}
-	if mm.ro {
-		return 0, fmt.Errorf("memory-mapped region not writable: %w", ErrReadOnly)
-	}
-
-	if p == nil {
-		return 0, fmt.Errorf("output buffer p is nil")
-	}
-
-	if off < 0 || off >= int64(len(mm.b)) {
-		return 0, fmt.Errorf("write offset out of range")
-	}
-
-	n := copy(mm.b[off:], p)
-	if n < len(p) {
-		return n, io.EOF
-	}
-
-	return n, nil
-}
diff --git a/vendor/github.com/cilium/ebpf/prog.go b/vendor/github.com/cilium/ebpf/prog.go
index 4f3ce43b..9bc6325f 100644
--- a/vendor/github.com/cilium/ebpf/prog.go
+++ b/vendor/github.com/cilium/ebpf/prog.go
@@ -16,7 +16,6 @@ import (
 	"github.com/cilium/ebpf/btf"
 	"github.com/cilium/ebpf/internal"
 	"github.com/cilium/ebpf/internal/kallsyms"
-	"github.com/cilium/ebpf/internal/linux"
 	"github.com/cilium/ebpf/internal/sys"
 	"github.com/cilium/ebpf/internal/sysenc"
 	"github.com/cilium/ebpf/internal/unix"
@@ -47,15 +46,14 @@ const (
 	outputPad = 256 + 2
 )
 
+// Deprecated: the correct log size is now detected automatically and this
+// constant is unused.
+const DefaultVerifierLogSize = 64 * 1024
+
 // minVerifierLogSize is the default number of bytes allocated for the
 // verifier log.
 const minVerifierLogSize = 64 * 1024
 
-// maxVerifierLogSize is the maximum size of verifier log buffer the kernel
-// will accept before returning EINVAL. May be increased to MaxUint32 in the
-// future, but avoid the unnecessary EINVAL for now.
-const maxVerifierLogSize = math.MaxUint32 >> 2
-
 // ProgramOptions control loading a program into the kernel.
 type ProgramOptions struct {
 	// Bitmap controlling the detail emitted by the kernel's eBPF verifier log.
@@ -75,10 +73,9 @@ type ProgramOptions struct {
 	// attempt at loading the program.
 	LogLevel LogLevel
 
-	// Starting size of the verifier log buffer. If the verifier log is larger
-	// than this size, the buffer will be grown to fit the entire log. Leave at
-	// its default value unless troubleshooting.
-	LogSizeStart uint32
+	// Deprecated: the correct log buffer size is determined automatically
+	// and this field is ignored.
+	LogSize int
 
 	// Disables the verifier log completely, regardless of other options.
 	LogDisabled bool
@@ -165,35 +162,26 @@ func (ps *ProgramSpec) Tag() (string, error) {
 	return ps.Instructions.Tag(internal.NativeEndian)
 }
 
-// kernelModule returns the kernel module providing the symbol in
-// ProgramSpec.AttachTo, if any. Returns an empty string if the symbol is not
-// present or not part of a kernel module.
-func (ps *ProgramSpec) kernelModule() (string, error) {
-	if ps.AttachTo == "" && ps.targetsKernelModule() {
-		return kallsyms.Module(ps.AttachTo)
-	}
-
-	return "", nil
-}
-
-// targetsKernelModule returns true if the program supports being attached to a
-// symbol provided by a kernel module.
-func (ps *ProgramSpec) targetsKernelModule() bool {
+// KernelModule returns the kernel module, if any, the AttachTo function is contained in.
+func (ps *ProgramSpec) KernelModule() (string, error) {
 	if ps.AttachTo == "" {
-		return false
+		return "", nil
 	}
 
 	switch ps.Type {
+	default:
+		return "", nil
 	case Tracing:
 		switch ps.AttachType {
-		case AttachTraceFEntry, AttachTraceFExit:
-			return true
+		default:
+			return "", nil
+		case AttachTraceFEntry:
+		case AttachTraceFExit:
 		}
+		fallthrough
 	case Kprobe:
-		return true
+		return kallsyms.KernelModule(ps.AttachTo)
 	}
-
-	return false
 }
 
 // VerifierError is returned by [NewProgram] and [NewProgramWithOptions] if a
@@ -273,7 +261,7 @@ func newProgramWithOptions(spec *ProgramSpec, opts ProgramOptions) (*Program, er
 	// Overwrite Kprobe program version if set to zero or the magic version constant.
 	kv := spec.KernelVersion
 	if spec.Type == Kprobe && (kv == 0 || kv == internal.MagicKernelVersion) {
-		v, err := linux.KernelVersion()
+		v, err := internal.KernelVersion()
 		if err != nil {
 			return nil, fmt.Errorf("detecting kernel version: %w", err)
 		}
@@ -295,7 +283,7 @@ func newProgramWithOptions(spec *ProgramSpec, opts ProgramOptions) (*Program, er
 	insns := make(asm.Instructions, len(spec.Instructions))
 	copy(insns, spec.Instructions)
 
-	kmodName, err := spec.kernelModule()
+	kmodName, err := spec.KernelModule()
 	if err != nil {
 		return nil, fmt.Errorf("kernel module search: %w", err)
 	}
@@ -356,10 +344,6 @@ func newProgramWithOptions(spec *ProgramSpec, opts ProgramOptions) (*Program, er
 	}
 	defer kconfig.Close()
 
-	if err := resolveKsymReferences(insns); err != nil {
-		return nil, fmt.Errorf("resolve .ksyms: %w", err)
-	}
-
 	if err := fixupAndValidate(insns); err != nil {
 		return nil, err
 	}
@@ -411,10 +395,9 @@ func newProgramWithOptions(spec *ProgramSpec, opts ProgramOptions) (*Program, er
 
 	// The caller requested a specific verifier log level. Set up the log buffer
 	// so that there is a chance of loading the program in a single shot.
-	logSize := internal.Between(opts.LogSizeStart, minVerifierLogSize, maxVerifierLogSize)
 	var logBuf []byte
 	if !opts.LogDisabled && opts.LogLevel != 0 {
-		logBuf = make([]byte, logSize)
+		logBuf = make([]byte, minVerifierLogSize)
 		attr.LogLevel = opts.LogLevel
 		attr.LogSize = uint32(len(logBuf))
 		attr.LogBuf = sys.NewSlicePointer(logBuf)
@@ -448,11 +431,12 @@ func newProgramWithOptions(spec *ProgramSpec, opts ProgramOptions) (*Program, er
 			attr.LogLevel = LogLevelBranch
 		}
 
-		// Make an educated guess how large the buffer should be by multiplying.
-		// Ensure the size doesn't overflow.
-		const factor = 2
-		logSize = internal.Between(logSize, minVerifierLogSize, maxVerifierLogSize/factor)
-		logSize *= factor
+		// Make an educated guess how large the buffer should be. Start
+		// at minVerifierLogSize and then double the size.
+		logSize := uint32(max(len(logBuf)*2, minVerifierLogSize))
+		if int(logSize) < len(logBuf) {
+			return nil, errors.New("overflow while probing log buffer size")
+		}
 
 		if attr.LogTrueSize != 0 {
 			// The kernel has given us a hint how large the log buffer has to be.
@@ -478,12 +462,6 @@ func newProgramWithOptions(spec *ProgramSpec, opts ProgramOptions) (*Program, er
 			return nil, fmt.Errorf("load program: %w (MEMLOCK may be too low, consider rlimit.RemoveMemlock)", err)
 		}
 
-	case errors.Is(err, unix.EFAULT):
-		// EFAULT is returned when the kernel hits a verifier bug, and always
-		// overrides ENOSPC, defeating the buffer growth strategy. Warn the user
-		// that they may need to increase the buffer size manually.
-		return nil, fmt.Errorf("load program: %w (hit verifier bug, increase LogSizeStart to fit the log and check dmesg)", err)
-
 	case errors.Is(err, unix.EINVAL):
 		if bytes.Contains(tail, coreBadCall) {
 			err = errBadRelocation
@@ -620,7 +598,7 @@ func (p *Program) Clone() (*Program, error) {
 // This requires bpffs to be mounted above fileName.
 // See https://docs.cilium.io/en/stable/network/kubernetes/configuration/#mounting-bpffs-with-systemd
 func (p *Program) Pin(fileName string) error {
-	if err := sys.Pin(p.pinnedPath, fileName, p.fd); err != nil {
+	if err := internal.Pin(p.pinnedPath, fileName, p.fd); err != nil {
 		return err
 	}
 	p.pinnedPath = fileName
@@ -633,7 +611,7 @@ func (p *Program) Pin(fileName string) error {
 //
 // Unpinning an unpinned Program returns nil.
 func (p *Program) Unpin() error {
-	if err := sys.Unpin(p.pinnedPath); err != nil {
+	if err := internal.Unpin(p.pinnedPath); err != nil {
 		return err
 	}
 	p.pinnedPath = ""
@@ -721,10 +699,6 @@ func (p *Program) Test(in []byte) (uint32, []byte, error) {
 //
 // Note: the same restrictions from Test apply.
 func (p *Program) Run(opts *RunOptions) (uint32, error) {
-	if opts == nil {
-		opts = &RunOptions{}
-	}
-
 	ret, _, err := p.run(opts)
 	if err != nil {
 		return ret, fmt.Errorf("run program: %w", err)
@@ -758,7 +732,7 @@ func (p *Program) Benchmark(in []byte, repeat int, reset func()) (uint32, time.D
 	return ret, total, nil
 }
 
-var haveProgRun = internal.NewFeatureTest("BPF_PROG_RUN", func() error {
+var haveProgRun = internal.NewFeatureTest("BPF_PROG_RUN", "4.12", func() error {
 	prog, err := NewProgram(&ProgramSpec{
 		// SocketFilter does not require privileges on newer kernels.
 		Type: SocketFilter,
@@ -800,7 +774,7 @@ var haveProgRun = internal.NewFeatureTest("BPF_PROG_RUN", func() error {
 	}
 
 	return err
-}, "4.12")
+})
 
 func (p *Program) run(opts *RunOptions) (uint32, time.Duration, error) {
 	if uint(len(opts.Data)) > math.MaxUint32 {
@@ -909,10 +883,6 @@ func unmarshalProgram(buf sysenc.Buffer) (*Program, error) {
 }
 
 func marshalProgram(p *Program, length int) ([]byte, error) {
-	if p == nil {
-		return nil, errors.New("can't marshal a nil Program")
-	}
-
 	if length != 4 {
 		return nil, fmt.Errorf("can't marshal program to %d bytes", length)
 	}
@@ -922,12 +892,11 @@ func marshalProgram(p *Program, length int) ([]byte, error) {
 	return buf, nil
 }
 
-// LoadPinnedProgram loads a Program from a pin (file) on the BPF virtual
-// filesystem.
+// LoadPinnedProgram loads a Program from a BPF file.
 //
 // Requires at least Linux 4.11.
 func LoadPinnedProgram(fileName string, opts *LoadPinOptions) (*Program, error) {
-	fd, typ, err := sys.ObjGetTyped(&sys.ObjGetAttr{
+	fd, err := sys.ObjGet(&sys.ObjGetAttr{
 		Pathname:  sys.NewStringPointer(fileName),
 		FileFlags: opts.Marshal(),
 	})
@@ -935,11 +904,6 @@ func LoadPinnedProgram(fileName string, opts *LoadPinOptions) (*Program, error)
 		return nil, err
 	}
 
-	if typ != sys.BPF_TYPE_PROG {
-		_ = fd.Close()
-		return nil, fmt.Errorf("%s is not a Program", fileName)
-	}
-
 	info, err := newProgramInfoFromFd(fd)
 	if err != nil {
 		_ = fd.Close()
diff --git a/vendor/github.com/cilium/ebpf/syscalls.go b/vendor/github.com/cilium/ebpf/syscalls.go
index 25c84c3c..4aef7fae 100644
--- a/vendor/github.com/cilium/ebpf/syscalls.go
+++ b/vendor/github.com/cilium/ebpf/syscalls.go
@@ -10,7 +10,6 @@ import (
 
 	"github.com/cilium/ebpf/asm"
 	"github.com/cilium/ebpf/internal"
-	"github.com/cilium/ebpf/internal/linux"
 	"github.com/cilium/ebpf/internal/sys"
 	"github.com/cilium/ebpf/internal/tracefs"
 	"github.com/cilium/ebpf/internal/unix"
@@ -61,7 +60,7 @@ func progLoad(insns asm.Instructions, typ ProgramType, license string) (*sys.FD,
 	})
 }
 
-var haveNestedMaps = internal.NewFeatureTest("nested maps", func() error {
+var haveNestedMaps = internal.NewFeatureTest("nested maps", "4.12", func() error {
 	_, err := sys.MapCreate(&sys.MapCreateAttr{
 		MapType:    sys.MapType(ArrayOfMaps),
 		KeySize:    4,
@@ -77,9 +76,9 @@ var haveNestedMaps = internal.NewFeatureTest("nested maps", func() error {
 		return nil
 	}
 	return err
-}, "4.12")
+})
 
-var haveMapMutabilityModifiers = internal.NewFeatureTest("read- and write-only maps", func() error {
+var haveMapMutabilityModifiers = internal.NewFeatureTest("read- and write-only maps", "5.2", func() error {
 	// This checks BPF_F_RDONLY_PROG and BPF_F_WRONLY_PROG. Since
 	// BPF_MAP_FREEZE appeared in 5.2 as well we don't do a separate check.
 	m, err := sys.MapCreate(&sys.MapCreateAttr{
@@ -87,39 +86,39 @@ var haveMapMutabilityModifiers = internal.NewFeatureTest("read- and write-only m
 		KeySize:    4,
 		ValueSize:  4,
 		MaxEntries: 1,
-		MapFlags:   sys.BPF_F_RDONLY_PROG,
+		MapFlags:   unix.BPF_F_RDONLY_PROG,
 	})
 	if err != nil {
 		return internal.ErrNotSupported
 	}
 	_ = m.Close()
 	return nil
-}, "5.2")
+})
 
-var haveMmapableMaps = internal.NewFeatureTest("mmapable maps", func() error {
+var haveMmapableMaps = internal.NewFeatureTest("mmapable maps", "5.5", func() error {
 	// This checks BPF_F_MMAPABLE, which appeared in 5.5 for array maps.
 	m, err := sys.MapCreate(&sys.MapCreateAttr{
 		MapType:    sys.MapType(Array),
 		KeySize:    4,
 		ValueSize:  4,
 		MaxEntries: 1,
-		MapFlags:   sys.BPF_F_MMAPABLE,
+		MapFlags:   unix.BPF_F_MMAPABLE,
 	})
 	if err != nil {
 		return internal.ErrNotSupported
 	}
 	_ = m.Close()
 	return nil
-}, "5.5")
+})
 
-var haveInnerMaps = internal.NewFeatureTest("inner maps", func() error {
+var haveInnerMaps = internal.NewFeatureTest("inner maps", "5.10", func() error {
 	// This checks BPF_F_INNER_MAP, which appeared in 5.10.
 	m, err := sys.MapCreate(&sys.MapCreateAttr{
 		MapType:    sys.MapType(Array),
 		KeySize:    4,
 		ValueSize:  4,
 		MaxEntries: 1,
-		MapFlags:   sys.BPF_F_INNER_MAP,
+		MapFlags:   unix.BPF_F_INNER_MAP,
 	})
 
 	if err != nil {
@@ -127,16 +126,16 @@ var haveInnerMaps = internal.NewFeatureTest("inner maps", func() error {
 	}
 	_ = m.Close()
 	return nil
-}, "5.10")
+})
 
-var haveNoPreallocMaps = internal.NewFeatureTest("prealloc maps", func() error {
+var haveNoPreallocMaps = internal.NewFeatureTest("prealloc maps", "4.6", func() error {
 	// This checks BPF_F_NO_PREALLOC, which appeared in 4.6.
 	m, err := sys.MapCreate(&sys.MapCreateAttr{
 		MapType:    sys.MapType(Hash),
 		KeySize:    4,
 		ValueSize:  4,
 		MaxEntries: 1,
-		MapFlags:   sys.BPF_F_NO_PREALLOC,
+		MapFlags:   unix.BPF_F_NO_PREALLOC,
 	})
 
 	if err != nil {
@@ -144,7 +143,7 @@ var haveNoPreallocMaps = internal.NewFeatureTest("prealloc maps", func() error {
 	}
 	_ = m.Close()
 	return nil
-}, "4.6")
+})
 
 func wrapMapError(err error) error {
 	if err == nil {
@@ -170,7 +169,7 @@ func wrapMapError(err error) error {
 	return err
 }
 
-var haveObjName = internal.NewFeatureTest("object names", func() error {
+var haveObjName = internal.NewFeatureTest("object names", "4.15", func() error {
 	attr := sys.MapCreateAttr{
 		MapType:    sys.MapType(Array),
 		KeySize:    4,
@@ -179,24 +178,16 @@ var haveObjName = internal.NewFeatureTest("object names", func() error {
 		MapName:    sys.NewObjName("feature_test"),
 	}
 
-	// Tolerate EPERM as this runs during ELF loading which is potentially
-	// unprivileged. Only EINVAL is conclusive, thrown from CHECK_ATTR.
 	fd, err := sys.MapCreate(&attr)
-	if errors.Is(err, unix.EPERM) {
-		return nil
-	}
-	if errors.Is(err, unix.EINVAL) {
-		return internal.ErrNotSupported
-	}
 	if err != nil {
-		return err
+		return internal.ErrNotSupported
 	}
 
 	_ = fd.Close()
 	return nil
-}, "4.15")
+})
 
-var objNameAllowsDot = internal.NewFeatureTest("dot in object names", func() error {
+var objNameAllowsDot = internal.NewFeatureTest("dot in object names", "5.2", func() error {
 	if err := haveObjName(); err != nil {
 		return err
 	}
@@ -209,25 +200,16 @@ var objNameAllowsDot = internal.NewFeatureTest("dot in object names", func() err
 		MapName:    sys.NewObjName(".test"),
 	}
 
-	// Tolerate EPERM, otherwise MapSpec.Name has its dots removed when run by
-	// unprivileged tools. (bpf2go, other code gen). Only EINVAL is conclusive,
-	// thrown from bpf_obj_name_cpy().
 	fd, err := sys.MapCreate(&attr)
-	if errors.Is(err, unix.EPERM) {
-		return nil
-	}
-	if errors.Is(err, unix.EINVAL) {
-		return internal.ErrNotSupported
-	}
 	if err != nil {
-		return err
+		return internal.ErrNotSupported
 	}
 
 	_ = fd.Close()
 	return nil
-}, "5.2")
+})
 
-var haveBatchAPI = internal.NewFeatureTest("map batch api", func() error {
+var haveBatchAPI = internal.NewFeatureTest("map batch api", "5.6", func() error {
 	var maxEntries uint32 = 2
 	attr := sys.MapCreateAttr{
 		MapType:    sys.MapType(Hash),
@@ -257,9 +239,9 @@ var haveBatchAPI = internal.NewFeatureTest("map batch api", func() error {
 		return internal.ErrNotSupported
 	}
 	return nil
-}, "5.6")
+})
 
-var haveProbeReadKernel = internal.NewFeatureTest("bpf_probe_read_kernel", func() error {
+var haveProbeReadKernel = internal.NewFeatureTest("bpf_probe_read_kernel", "5.5", func() error {
 	insns := asm.Instructions{
 		asm.Mov.Reg(asm.R1, asm.R10),
 		asm.Add.Imm(asm.R1, -8),
@@ -275,9 +257,9 @@ var haveProbeReadKernel = internal.NewFeatureTest("bpf_probe_read_kernel", func(
 	}
 	_ = fd.Close()
 	return nil
-}, "5.5")
+})
 
-var haveBPFToBPFCalls = internal.NewFeatureTest("bpf2bpf calls", func() error {
+var haveBPFToBPFCalls = internal.NewFeatureTest("bpf2bpf calls", "4.16", func() error {
 	insns := asm.Instructions{
 		asm.Call.Label("prog2").WithSymbol("prog1"),
 		asm.Return(),
@@ -291,10 +273,10 @@ var haveBPFToBPFCalls = internal.NewFeatureTest("bpf2bpf calls", func() error {
 	}
 	_ = fd.Close()
 	return nil
-}, "4.16")
+})
 
-var haveSyscallWrapper = internal.NewFeatureTest("syscall wrapper", func() error {
-	prefix := linux.PlatformPrefix()
+var haveSyscallWrapper = internal.NewFeatureTest("syscall wrapper", "4.17", func() error {
+	prefix := internal.PlatformPrefix()
 	if prefix == "" {
 		return fmt.Errorf("unable to find the platform prefix for (%s)", runtime.GOARCH)
 	}
@@ -320,9 +302,9 @@ var haveSyscallWrapper = internal.NewFeatureTest("syscall wrapper", func() error
 	}
 
 	return evt.Close()
-}, "4.17")
+})
 
-var haveProgramExtInfos = internal.NewFeatureTest("program ext_infos", func() error {
+var haveProgramExtInfos = internal.NewFeatureTest("program ext_infos", "5.0", func() error {
 	insns := asm.Instructions{
 		asm.Mov.Imm(asm.R0, 0),
 		asm.Return(),
@@ -352,4 +334,4 @@ var haveProgramExtInfos = internal.NewFeatureTest("program ext_infos", func() er
 	}
 
 	return err
-}, "5.0")
+})
diff --git a/vendor/github.com/cilium/ebpf/types.go b/vendor/github.com/cilium/ebpf/types.go
index 211b308b..542c2397 100644
--- a/vendor/github.com/cilium/ebpf/types.go
+++ b/vendor/github.com/cilium/ebpf/types.go
@@ -2,6 +2,7 @@ package ebpf
 
 import (
 	"github.com/cilium/ebpf/internal/sys"
+	"github.com/cilium/ebpf/internal/unix"
 )
 
 //go:generate go run golang.org/x/tools/cmd/stringer@latest -output types_string.go -type=MapType,ProgramType,PinType
@@ -94,14 +95,6 @@ const (
 	InodeStorage
 	// TaskStorage - Specialized local storage map for task_struct.
 	TaskStorage
-	// BloomFilter - Space-efficient data structure to quickly test whether an element exists in a set.
-	BloomFilter
-	// UserRingbuf - The reverse of RingBuf, used to send messages from user space to BPF programs.
-	UserRingbuf
-	// CgroupStorage - Store data keyed on a cgroup. If the cgroup disappears, the key is automatically removed.
-	CgroupStorage
-	// Arena - Sparse shared memory region between a BPF program and user space.
-	Arena
 )
 
 // hasPerCPUValue returns true if the Map stores a value per CPU.
@@ -127,21 +120,6 @@ func (mt MapType) canStoreProgram() bool {
 	return mt == ProgramArray
 }
 
-// canHaveValueSize returns true if the map type supports setting a value size.
-func (mt MapType) canHaveValueSize() bool {
-	switch mt {
-	case RingBuf, Arena:
-		return false
-
-	// Special-case perf events since they require a value size of either 0 or 4
-	// for historical reasons. Let the library fix this up later.
-	case PerfEventArray:
-		return false
-	}
-
-	return true
-}
-
 // ProgramType of the eBPF program
 type ProgramType uint32
 
@@ -285,10 +263,10 @@ func (lpo *LoadPinOptions) Marshal() uint32 {
 
 	flags := lpo.Flags
 	if lpo.ReadOnly {
-		flags |= sys.BPF_F_RDONLY
+		flags |= unix.BPF_F_RDONLY
 	}
 	if lpo.WriteOnly {
-		flags |= sys.BPF_F_WRONLY
+		flags |= unix.BPF_F_WRONLY
 	}
 	return flags
 }
diff --git a/vendor/github.com/cilium/ebpf/types_string.go b/vendor/github.com/cilium/ebpf/types_string.go
index f0668511..ee60b5be 100644
--- a/vendor/github.com/cilium/ebpf/types_string.go
+++ b/vendor/github.com/cilium/ebpf/types_string.go
@@ -38,15 +38,11 @@ func _() {
 	_ = x[RingBuf-27]
 	_ = x[InodeStorage-28]
 	_ = x[TaskStorage-29]
-	_ = x[BloomFilter-30]
-	_ = x[UserRingbuf-31]
-	_ = x[CgroupStorage-32]
-	_ = x[Arena-33]
 }
 
-const _MapType_name = "UnspecifiedMapHashArrayProgramArrayPerfEventArrayPerCPUHashPerCPUArrayStackTraceCGroupArrayLRUHashLRUCPUHashLPMTrieArrayOfMapsHashOfMapsDevMapSockMapCPUMapXSKMapSockHashCGroupStorageReusePortSockArrayPerCPUCGroupStorageQueueStackSkStorageDevMapHashStructOpsMapRingBufInodeStorageTaskStorageBloomFilterUserRingbufCgroupStorageArena"
+const _MapType_name = "UnspecifiedMapHashArrayProgramArrayPerfEventArrayPerCPUHashPerCPUArrayStackTraceCGroupArrayLRUHashLRUCPUHashLPMTrieArrayOfMapsHashOfMapsDevMapSockMapCPUMapXSKMapSockHashCGroupStorageReusePortSockArrayPerCPUCGroupStorageQueueStackSkStorageDevMapHashStructOpsMapRingBufInodeStorageTaskStorage"
 
-var _MapType_index = [...]uint16{0, 14, 18, 23, 35, 49, 59, 70, 80, 91, 98, 108, 115, 126, 136, 142, 149, 155, 161, 169, 182, 200, 219, 224, 229, 238, 248, 260, 267, 279, 290, 301, 312, 325, 330}
+var _MapType_index = [...]uint16{0, 14, 18, 23, 35, 49, 59, 70, 80, 91, 98, 108, 115, 126, 136, 142, 149, 155, 161, 169, 182, 200, 219, 224, 229, 238, 248, 260, 267, 279, 290}
 
 func (i MapType) String() string {
 	if i >= MapType(len(_MapType_index)-1) {
diff --git a/vendor/github.com/cilium/ebpf/variable.go b/vendor/github.com/cilium/ebpf/variable.go
deleted file mode 100644
index 288b173a..00000000
--- a/vendor/github.com/cilium/ebpf/variable.go
+++ /dev/null
@@ -1,230 +0,0 @@
-package ebpf
-
-import (
-	"fmt"
-	"io"
-
-	"github.com/cilium/ebpf/btf"
-	"github.com/cilium/ebpf/internal/sysenc"
-)
-
-// VariableSpec is a convenience wrapper for modifying global variables of a
-// CollectionSpec before loading it into the kernel.
-//
-// All operations on a VariableSpec's underlying MapSpec are performed in the
-// host's native endianness.
-type VariableSpec struct {
-	name   string
-	offset uint64
-	size   uint64
-
-	m *MapSpec
-	t *btf.Var
-}
-
-// Set sets the value of the VariableSpec to the provided input using the host's
-// native endianness.
-func (s *VariableSpec) Set(in any) error {
-	buf, err := sysenc.Marshal(in, int(s.size))
-	if err != nil {
-		return fmt.Errorf("marshaling value %s: %w", s.name, err)
-	}
-
-	b, _, err := s.m.dataSection()
-	if err != nil {
-		return fmt.Errorf("getting data section of map %s: %w", s.m.Name, err)
-	}
-
-	if int(s.offset+s.size) > len(b) {
-		return fmt.Errorf("offset %d(+%d) for variable %s is out of bounds", s.offset, s.size, s.name)
-	}
-
-	// MapSpec.Copy() performs a shallow copy. Fully copy the byte slice
-	// to avoid any changes affecting other copies of the MapSpec.
-	cpy := make([]byte, len(b))
-	copy(cpy, b)
-
-	buf.CopyTo(cpy[s.offset : s.offset+s.size])
-
-	s.m.Contents[0] = MapKV{Key: uint32(0), Value: cpy}
-
-	return nil
-}
-
-// Get writes the value of the VariableSpec to the provided output using the
-// host's native endianness.
-func (s *VariableSpec) Get(out any) error {
-	b, _, err := s.m.dataSection()
-	if err != nil {
-		return fmt.Errorf("getting data section of map %s: %w", s.m.Name, err)
-	}
-
-	if int(s.offset+s.size) > len(b) {
-		return fmt.Errorf("offset %d(+%d) for variable %s is out of bounds", s.offset, s.size, s.name)
-	}
-
-	if err := sysenc.Unmarshal(out, b[s.offset:s.offset+s.size]); err != nil {
-		return fmt.Errorf("unmarshaling value: %w", err)
-	}
-
-	return nil
-}
-
-// Size returns the size of the variable in bytes.
-func (s *VariableSpec) Size() uint64 {
-	return s.size
-}
-
-// MapName returns the name of the underlying MapSpec.
-func (s *VariableSpec) MapName() string {
-	return s.m.Name
-}
-
-// Offset returns the offset of the variable in the underlying MapSpec.
-func (s *VariableSpec) Offset() uint64 {
-	return s.offset
-}
-
-// Constant returns true if the VariableSpec represents a variable that is
-// read-only from the perspective of the BPF program.
-func (s *VariableSpec) Constant() bool {
-	return s.m.readOnly()
-}
-
-// Type returns the [btf.Var] representing the variable in its data section.
-// This is useful for inspecting the variable's decl tags and the type
-// information of the inner type.
-//
-// Returns nil if the original ELF object did not contain BTF information.
-func (s *VariableSpec) Type() *btf.Var {
-	return s.t
-}
-
-func (s *VariableSpec) String() string {
-	return fmt.Sprintf("%s (type=%v, map=%s, offset=%d, size=%d)", s.name, s.t, s.m.Name, s.offset, s.size)
-}
-
-// copy returns a new VariableSpec with the same values as the original,
-// but with a different underlying MapSpec. This is useful when copying a
-// CollectionSpec. Returns nil if a MapSpec with the same name is not found.
-func (s *VariableSpec) copy(cpy *CollectionSpec) *VariableSpec {
-	out := &VariableSpec{
-		name:   s.name,
-		offset: s.offset,
-		size:   s.size,
-	}
-	if s.t != nil {
-		out.t = btf.Copy(s.t).(*btf.Var)
-	}
-
-	// Attempt to find a MapSpec with the same name in the copied CollectionSpec.
-	for _, m := range cpy.Maps {
-		if m.Name == s.m.Name {
-			out.m = m
-			return out
-		}
-	}
-
-	return nil
-}
-
-// Variable is a convenience wrapper for modifying global variables of a
-// Collection after loading it into the kernel. Operations on a Variable are
-// performed using direct memory access, bypassing the BPF map syscall API.
-//
-// On kernels older than 5.5, most interactions with Variable return
-// [ErrNotSupported].
-type Variable struct {
-	name   string
-	offset uint64
-	size   uint64
-	t      *btf.Var
-
-	mm *Memory
-}
-
-func newVariable(name string, offset, size uint64, t *btf.Var, mm *Memory) (*Variable, error) {
-	if mm != nil {
-		if int(offset+size) > mm.Size() {
-			return nil, fmt.Errorf("offset %d(+%d) is out of bounds", offset, size)
-		}
-	}
-
-	return &Variable{
-		name:   name,
-		offset: offset,
-		size:   size,
-		t:      t,
-		mm:     mm,
-	}, nil
-}
-
-// Size returns the size of the variable.
-func (v *Variable) Size() uint64 {
-	return v.size
-}
-
-// ReadOnly returns true if the Variable represents a variable that is read-only
-// after loading the Collection into the kernel.
-//
-// On systems without BPF_F_MMAPABLE support, ReadOnly always returns true.
-func (v *Variable) ReadOnly() bool {
-	if v.mm == nil {
-		return true
-	}
-	return v.mm.ReadOnly()
-}
-
-// Type returns the [btf.Var] representing the variable in its data section.
-// This is useful for inspecting the variable's decl tags and the type
-// information of the inner type.
-//
-// Returns nil if the original ELF object did not contain BTF information.
-func (v *Variable) Type() *btf.Var {
-	return v.t
-}
-
-func (v *Variable) String() string {
-	return fmt.Sprintf("%s (type=%v)", v.name, v.t)
-}
-
-// Set the value of the Variable to the provided input. The input must marshal
-// to the same length as the size of the Variable.
-func (v *Variable) Set(in any) error {
-	if v.mm == nil {
-		return fmt.Errorf("variable %s: direct access requires Linux 5.5 or later: %w", v.name, ErrNotSupported)
-	}
-
-	if v.ReadOnly() {
-		return fmt.Errorf("variable %s: %w", v.name, ErrReadOnly)
-	}
-
-	buf, err := sysenc.Marshal(in, int(v.size))
-	if err != nil {
-		return fmt.Errorf("marshaling value %s: %w", v.name, err)
-	}
-
-	if _, err := v.mm.WriteAt(buf.Bytes(), int64(v.offset)); err != nil {
-		return fmt.Errorf("writing value to %s: %w", v.name, err)
-	}
-
-	return nil
-}
-
-// Get writes the value of the Variable to the provided output. The output must
-// be a pointer to a value whose size matches the Variable.
-func (v *Variable) Get(out any) error {
-	if v.mm == nil {
-		return fmt.Errorf("variable %s: direct access requires Linux 5.5 or later: %w", v.name, ErrNotSupported)
-	}
-
-	if !v.mm.bounds(v.offset, v.size) {
-		return fmt.Errorf("variable %s: access out of bounds: %w", v.name, io.EOF)
-	}
-
-	if err := sysenc.Unmarshal(out, v.mm.b[v.offset:v.offset+v.size]); err != nil {
-		return fmt.Errorf("unmarshaling value %s: %w", v.name, err)
-	}
-
-	return nil
-}
diff --git a/vendor/golang.org/x/exp/LICENSE b/vendor/golang.org/x/exp/LICENSE
new file mode 100644
index 00000000..6a66aea5
--- /dev/null
+++ b/vendor/golang.org/x/exp/LICENSE
@@ -0,0 +1,27 @@
+Copyright (c) 2009 The Go Authors. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+   * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+   * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+   * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/golang.org/x/exp/PATENTS b/vendor/golang.org/x/exp/PATENTS
new file mode 100644
index 00000000..73309904
--- /dev/null
+++ b/vendor/golang.org/x/exp/PATENTS
@@ -0,0 +1,22 @@
+Additional IP Rights Grant (Patents)
+
+"This implementation" means the copyrightable works distributed by
+Google as part of the Go project.
+
+Google hereby grants to You a perpetual, worldwide, non-exclusive,
+no-charge, royalty-free, irrevocable (except as stated in this section)
+patent license to make, have made, use, offer to sell, sell, import,
+transfer and otherwise run, modify and propagate the contents of this
+implementation of Go, where such license applies only to those patent
+claims, both currently owned or controlled by Google and acquired in
+the future, licensable by Google that are necessarily infringed by this
+implementation of Go.  This grant does not include claims that would be
+infringed only as a consequence of further modification of this
+implementation.  If you or your agent or exclusive licensee institute or
+order or agree to the institution of patent litigation against any
+entity (including a cross-claim or counterclaim in a lawsuit) alleging
+that this implementation of Go or any code incorporated within this
+implementation of Go constitutes direct or contributory patent
+infringement, or inducement of patent infringement, then any patent
+rights granted to you under this License for this implementation of Go
+shall terminate as of the date such litigation is filed.
diff --git a/vendor/golang.org/x/exp/constraints/constraints.go b/vendor/golang.org/x/exp/constraints/constraints.go
new file mode 100644
index 00000000..2c033dff
--- /dev/null
+++ b/vendor/golang.org/x/exp/constraints/constraints.go
@@ -0,0 +1,50 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package constraints defines a set of useful constraints to be used
+// with type parameters.
+package constraints
+
+// Signed is a constraint that permits any signed integer type.
+// If future releases of Go add new predeclared signed integer types,
+// this constraint will be modified to include them.
+type Signed interface {
+	~int | ~int8 | ~int16 | ~int32 | ~int64
+}
+
+// Unsigned is a constraint that permits any unsigned integer type.
+// If future releases of Go add new predeclared unsigned integer types,
+// this constraint will be modified to include them.
+type Unsigned interface {
+	~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr
+}
+
+// Integer is a constraint that permits any integer type.
+// If future releases of Go add new predeclared integer types,
+// this constraint will be modified to include them.
+type Integer interface {
+	Signed | Unsigned
+}
+
+// Float is a constraint that permits any floating-point type.
+// If future releases of Go add new predeclared floating-point types,
+// this constraint will be modified to include them.
+type Float interface {
+	~float32 | ~float64
+}
+
+// Complex is a constraint that permits any complex numeric type.
+// If future releases of Go add new predeclared complex numeric types,
+// this constraint will be modified to include them.
+type Complex interface {
+	~complex64 | ~complex128
+}
+
+// Ordered is a constraint that permits any ordered type: any type
+// that supports the operators < <= >= >.
+// If future releases of Go add new ordered types,
+// this constraint will be modified to include them.
+type Ordered interface {
+	Integer | Float | ~string
+}
diff --git a/vendor/modules.txt b/vendor/modules.txt
index e514f0ce..7037df9a 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -2,18 +2,16 @@
 ## explicit; go 1.16
 github.com/checkpoint-restore/go-criu/v6
 github.com/checkpoint-restore/go-criu/v6/rpc
-# github.com/cilium/ebpf v0.17.1
-## explicit; go 1.22
+# github.com/cilium/ebpf v0.16.0
+## explicit; go 1.21
 github.com/cilium/ebpf
 github.com/cilium/ebpf/asm
 github.com/cilium/ebpf/btf
 github.com/cilium/ebpf/internal
 github.com/cilium/ebpf/internal/kallsyms
 github.com/cilium/ebpf/internal/kconfig
-github.com/cilium/ebpf/internal/linux
 github.com/cilium/ebpf/internal/sys
 github.com/cilium/ebpf/internal/sysenc
-github.com/cilium/ebpf/internal/testutils/fdtrace
 github.com/cilium/ebpf/internal/tracefs
 github.com/cilium/ebpf/internal/unix
 github.com/cilium/ebpf/link
@@ -80,6 +78,9 @@ github.com/vishvananda/netlink/nl
 # github.com/vishvananda/netns v0.0.4
 ## explicit; go 1.17
 github.com/vishvananda/netns
+# golang.org/x/exp v0.0.0-20230224173230-c95f2b4c22f2
+## explicit; go 1.18
+golang.org/x/exp/constraints
 # golang.org/x/net v0.34.0
 ## explicit; go 1.18
 golang.org/x/net/bpf


Test patch:
diff --git a/vendor/github.com/cilium/ebpf/internal/testutils/fdtrace/fd_trace.go b/vendor/github.com/cilium/ebpf/internal/testutils/fdtrace/fd_trace.go
deleted file mode 100644
index 562df2cc..00000000
--- a/vendor/github.com/cilium/ebpf/internal/testutils/fdtrace/fd_trace.go
+++ /dev/null
@@ -1,103 +0,0 @@
-package fdtrace
-
-import (
-	"bytes"
-	"fmt"
-	"os"
-	"runtime"
-	"sync"
-	"sync/atomic"
-)
-
-// foundLeak is atomic since the GC may collect objects in parallel.
-var foundLeak atomic.Bool
-
-func onLeakFD(fs *runtime.Frames) {
-	foundLeak.Store(true)
-	fmt.Fprintln(os.Stderr, "leaked fd created at:")
-	fmt.Fprintln(os.Stderr, formatFrames(fs))
-}
-
-// fds is a registry of all file descriptors wrapped into sys.fds that were
-// created while an fd tracer was active.
-var fds *sync.Map // map[int]*runtime.Frames
-
-// TraceFD associates raw with the current execution stack.
-//
-// skip controls how many entries of the stack the function should skip.
-func TraceFD(raw int, skip int) {
-	if fds == nil {
-		return
-	}
-
-	// Attempt to store the caller's stack for the given fd value.
-	// Panic if fds contains an existing stack for the fd.
-	old, exist := fds.LoadOrStore(raw, callersFrames(skip))
-	if exist {
-		f := old.(*runtime.Frames)
-		panic(fmt.Sprintf("found existing stack for fd %d:\n%s", raw, formatFrames(f)))
-	}
-}
-
-// ForgetFD removes any existing association for raw.
-func ForgetFD(raw int) {
-	if fds != nil {
-		fds.Delete(raw)
-	}
-}
-
-// LeakFD indicates that raw was leaked.
-//
-// Calling the function with a value that was not passed to [TraceFD] before
-// is undefined.
-func LeakFD(raw int) {
-	if fds == nil {
-		return
-	}
-
-	// Invoke the fd leak callback. Calls LoadAndDelete to guarantee the callback
-	// is invoked at most once for one sys.FD allocation, runtime.Frames can only
-	// be unwound once.
-	f, ok := fds.LoadAndDelete(raw)
-	if ok {
-		onLeakFD(f.(*runtime.Frames))
-	}
-}
-
-// flushFrames removes all elements from fds and returns them as a slice. This
-// deals with the fact that a runtime.Frames can only be unwound once using
-// Next().
-func flushFrames() []*runtime.Frames {
-	var frames []*runtime.Frames
-	fds.Range(func(key, value any) bool {
-		frames = append(frames, value.(*runtime.Frames))
-		fds.Delete(key)
-		return true
-	})
-	return frames
-}
-
-func callersFrames(skip int) *runtime.Frames {
-	c := make([]uintptr, 32)
-
-	// Skip runtime.Callers and this function.
-	i := runtime.Callers(skip+2, c)
-	if i == 0 {
-		return nil
-	}
-
-	return runtime.CallersFrames(c)
-}
-
-// formatFrames formats a runtime.Frames as a human-readable string.
-func formatFrames(fs *runtime.Frames) string {
-	var b bytes.Buffer
-	for {
-		f, more := fs.Next()
-		b.WriteString(fmt.Sprintf("\t%s+%#x\n\t\t%s:%d\n", f.Function, f.PC-f.Entry, f.File, f.Line))
-		if !more {
-			break
-		}
-	}
-	return b.String()
-}
diff --git a/vendor/github.com/cilium/ebpf/internal/testutils/fdtrace/main.go b/vendor/github.com/cilium/ebpf/internal/testutils/fdtrace/main.go
deleted file mode 100644
index c1f7b42d..00000000
--- a/vendor/github.com/cilium/ebpf/internal/testutils/fdtrace/main.go
+++ /dev/null
@@ -1,31 +0,0 @@
-package fdtrace
-
-import (
-	"os"
-	"sync"
-)
-
-type testingM interface {
-	Run() int
-}
-
-// TestMain runs m with fd tracing enabled.
-//
-// The function calls [os.Exit] and does not return.
-func TestMain(m testingM) {
-	fds = new(sync.Map)
-
-	ret := m.Run()
-
-	if fs := flushFrames(); len(fs) != 0 {
-		for _, f := range fs {
-			onLeakFD(f)
-		}
-	}
-
-	if foundLeak.Load() {
-		ret = 99
-	}
-
-	os.Exit(ret)
-}