From dfa9d1a9a5740e07243aa21f48fea771bc90f3ed Mon Sep 17 00:00:00 2001 From: Nick Zavaritsky Date: Wed, 5 Feb 2025 08:56:10 +0000 Subject: [PATCH] Replace internal.NativeEndian with stdlib Yet another attempt at replacing internal.NativeEndian with NativeEndian from "encoding/binary". The conversion is mostly a straight-forward replacement. The only challenge are checks whether a ByteOrder is Big/Little/NativeEndian. In stdlib, NativeEndian is a distinct type hence never compares equal to BigEndian or LittleEndian. Introduce internal.EqualByteOrder(bo1, bo2). It works by passing []byte{0x12, 0x34} through bo1.Uint16() and bo2.Uint16() and comparing the results. Signed-off-by: Nick Zavaritsky --- asm/instruction.go | 17 ++++------------- btf/btf.go | 2 +- btf/core.go | 3 ++- btf/core_test.go | 12 ++++++------ btf/ext_info.go | 12 ++++++------ btf/ext_info_test.go | 10 ++++------ btf/fuzz_test.go | 10 ++++------ btf/handle.go | 3 ++- btf/kernel.go | 5 +++-- btf/marshal.go | 4 ++-- btf/marshal_test.go | 19 +++++++++---------- collection.go | 3 +-- elf_reader_test.go | 4 ++-- info.go | 11 ++++++----- internal/endian.go | 19 +++++++++++++++++++ internal/endian_be.go | 9 --------- internal/endian_le.go | 9 --------- internal/epoll/poller.go | 5 +++-- internal/kconfig/kconfig.go | 10 +++++----- internal/kconfig/kconfig_test.go | 3 +-- internal/linux/auxv_test.go | 3 +-- internal/sysenc/marshal.go | 16 ++++++++-------- internal/sysenc/marshal_test.go | 8 +++----- linker.go | 3 +-- map.go | 3 ++- map_test.go | 21 +++++++++++---------- marshalers_test.go | 7 ++++--- perf/reader.go | 11 +++++------ perf/reader_test.go | 2 +- prog.go | 16 +++++++++------- prog_test.go | 4 ++-- syscalls.go | 5 +++-- 32 files changed, 130 insertions(+), 139 deletions(-) create mode 100644 internal/endian.go delete mode 100644 internal/endian_be.go delete mode 100644 internal/endian_le.go diff --git a/asm/instruction.go b/asm/instruction.go index 86b384c02..460b36b26 100644 --- a/asm/instruction.go +++ b/asm/instruction.go @@ -128,10 +128,7 @@ func (ins Instruction) Marshal(w io.Writer, bo binary.ByteOrder) (uint64, error) cons = int32(uint32(ins.Constant)) } - regs, err := newBPFRegisters(ins.Dst, ins.Src, bo) - if err != nil { - return 0, fmt.Errorf("can't marshal registers: %s", err) - } + regs := newBPFRegisters(ins.Dst, ins.Src, bo) if ins.OpCode.Class().IsALU() { newOffset := int16(0) @@ -933,15 +930,9 @@ func (iter *InstructionIterator) Next() bool { type bpfRegisters uint8 -func newBPFRegisters(dst, src Register, bo binary.ByteOrder) (bpfRegisters, error) { - switch bo { - case binary.LittleEndian: - return bpfRegisters((src << 4) | (dst & 0xF)), nil - case binary.BigEndian: - return bpfRegisters((dst << 4) | (src & 0xF)), nil - default: - return 0, fmt.Errorf("unrecognized ByteOrder %T", bo) - } +func newBPFRegisters(dst, src Register, bo binary.ByteOrder) bpfRegisters { + v := bo.Uint16([]byte{byte(dst), byte(src)}) + return bpfRegisters((v >> 4) | (v & 0xF)) } // IsUnreferencedSymbol returns true if err was caused by diff --git a/btf/btf.go b/btf/btf.go index 880c5ade0..6a6e60eb8 100644 --- a/btf/btf.go +++ b/btf/btf.go @@ -674,7 +674,7 @@ func (s *Spec) TypeByName(name string, typ interface{}) error { // Types from base are used to resolve references in the split BTF. // The returned Spec only contains types from the split BTF, not from the base. func LoadSplitSpecFromReader(r io.ReaderAt, base *Spec) (*Spec, error) { - return loadRawSpec(r, internal.NativeEndian, base) + return loadRawSpec(r, binary.NativeEndian, base) } // TypesIterator iterates over types of a given spec. diff --git a/btf/core.go b/btf/core.go index ee89f9833..3c677b045 100644 --- a/btf/core.go +++ b/btf/core.go @@ -11,6 +11,7 @@ import ( "strings" "github.com/cilium/ebpf/asm" + "github.com/cilium/ebpf/internal" ) // Code in this file is derived from libbpf, which is available under a BSD @@ -205,7 +206,7 @@ func CORERelocate(relos []*CORERelocation, targets []*Spec, bo binary.ByteOrder, resolveTargetTypeID := targets[0].TypeID for _, target := range targets { - if bo != target.imm.byteOrder { + if !internal.EqualByteOrder(bo, target.imm.byteOrder) { return nil, fmt.Errorf("can't relocate %s against %s", bo, target.imm.byteOrder) } } diff --git a/btf/core_test.go b/btf/core_test.go index 3d58355e8..29709346e 100644 --- a/btf/core_test.go +++ b/btf/core_test.go @@ -1,6 +1,7 @@ package btf import ( + "encoding/binary" "errors" "fmt" "os" @@ -10,7 +11,6 @@ import ( "github.com/google/go-cmp/cmp" - "github.com/cilium/ebpf/internal" "github.com/cilium/ebpf/internal/testutils" "github.com/go-quicktest/qt" @@ -588,7 +588,7 @@ func TestCOREReloFieldSigned(t *testing.T) { relo := &CORERelocation{ typ, coreAccessor{0}, reloFieldSigned, 0, } - fixup, err := coreCalculateFixup(relo, &Void{}, internal.NativeEndian, dummyTypeID) + fixup, err := coreCalculateFixup(relo, &Void{}, binary.NativeEndian, dummyTypeID) qt.Assert(t, qt.IsTrue(fixup.poison)) qt.Assert(t, qt.IsNil(err)) }) @@ -598,7 +598,7 @@ func TestCOREReloFieldSigned(t *testing.T) { relo := &CORERelocation{ &Array{}, coreAccessor{0}, reloFieldSigned, 0, } - _, err := coreCalculateFixup(relo, &Array{}, internal.NativeEndian, dummyTypeID) + _, err := coreCalculateFixup(relo, &Array{}, binary.NativeEndian, dummyTypeID) qt.Assert(t, qt.ErrorIs(err, errNoSignedness)) }) } @@ -615,7 +615,7 @@ func TestCOREReloFieldShiftU64(t *testing.T) { {typ, coreAccessor{0, 0}, reloFieldLShiftU64, 1}, } { t.Run(relo.kind.String(), func(t *testing.T) { - _, err := coreCalculateFixup(relo, typ, internal.NativeEndian, dummyTypeID) + _, err := coreCalculateFixup(relo, typ, binary.NativeEndian, dummyTypeID) qt.Assert(t, qt.ErrorIs(err, errUnsizedType)) }) } @@ -639,7 +639,7 @@ func TestCORERelosKmodTypeID(t *testing.T) { fixups, err := coreCalculateFixups( relos, []Type{a, b}, - internal.NativeEndian, + binary.NativeEndian, typeID, ) qt.Assert(t, qt.IsNil(err)) @@ -649,7 +649,7 @@ func TestCORERelosKmodTypeID(t *testing.T) { fixups, err = coreCalculateFixups( relos, []Type{b}, - internal.NativeEndian, + binary.NativeEndian, typeID, ) qt.Assert(t, qt.IsNil(err)) diff --git a/btf/ext_info.go b/btf/ext_info.go index 71dbba806..40e354eea 100644 --- a/btf/ext_info.go +++ b/btf/ext_info.go @@ -421,8 +421,8 @@ func (fi *FuncOffset) marshal(w *bytes.Buffer, b *Builder) error { TypeID: id, } buf := make([]byte, FuncInfoSize) - internal.NativeEndian.PutUint32(buf, bfi.InsnOff) - internal.NativeEndian.PutUint32(buf[4:], uint32(bfi.TypeID)) + binary.NativeEndian.PutUint32(buf, bfi.InsnOff) + binary.NativeEndian.PutUint32(buf[4:], uint32(bfi.TypeID)) _, err = w.Write(buf) return err } @@ -627,10 +627,10 @@ func (li *LineOffset) marshal(w *bytes.Buffer, b *Builder) error { } buf := make([]byte, LineInfoSize) - internal.NativeEndian.PutUint32(buf, bli.InsnOff) - internal.NativeEndian.PutUint32(buf[4:], bli.FileNameOff) - internal.NativeEndian.PutUint32(buf[8:], bli.LineOff) - internal.NativeEndian.PutUint32(buf[12:], bli.LineCol) + binary.NativeEndian.PutUint32(buf, bli.InsnOff) + binary.NativeEndian.PutUint32(buf[4:], bli.FileNameOff) + binary.NativeEndian.PutUint32(buf[8:], bli.LineOff) + binary.NativeEndian.PutUint32(buf[12:], bli.LineCol) _, err = w.Write(buf) return err } diff --git a/btf/ext_info_test.go b/btf/ext_info_test.go index 581231a4e..9246cac81 100644 --- a/btf/ext_info_test.go +++ b/btf/ext_info_test.go @@ -6,8 +6,6 @@ import ( "strings" "testing" - "github.com/cilium/ebpf/internal" - "github.com/go-quicktest/qt" ) @@ -18,11 +16,11 @@ func TestParseExtInfoBigRecordSize(t *testing.T) { t.Fatal(err) } - if _, err := parseFuncInfos(rd, internal.NativeEndian, table); err == nil { + if _, err := parseFuncInfos(rd, binary.NativeEndian, table); err == nil { t.Error("Parsing func info with large record size doesn't return an error") } - if _, err := parseLineInfos(rd, internal.NativeEndian, table); err == nil { + if _, err := parseLineInfos(rd, binary.NativeEndian, table); err == nil { t.Error("Parsing line info with large record size doesn't return an error") } } @@ -36,7 +34,7 @@ func BenchmarkParseLineInfoRecords(b *testing.B) { b.ResetTimer() for i := 0; i < b.N; i++ { - parseLineInfoRecords(bytes.NewReader(buf), internal.NativeEndian, size, count, true) + parseLineInfoRecords(bytes.NewReader(buf), binary.NativeEndian, size, count, true) } } @@ -46,7 +44,7 @@ func TestParseLineInfoRecordsAllocations(t *testing.T) { buf := make([]byte, size*count) allocs := testing.AllocsPerRun(5, func() { - parseLineInfoRecords(bytes.NewReader(buf), internal.NativeEndian, size, count, true) + parseLineInfoRecords(bytes.NewReader(buf), binary.NativeEndian, size, count, true) }) // 7 is the number of allocations on go 1.22 diff --git a/btf/fuzz_test.go b/btf/fuzz_test.go index 64ebe1098..d38edd2a0 100644 --- a/btf/fuzz_test.go +++ b/btf/fuzz_test.go @@ -6,13 +6,11 @@ import ( "fmt" "io" "testing" - - "github.com/cilium/ebpf/internal" ) func FuzzSpec(f *testing.F) { var buf bytes.Buffer - err := binary.Write(&buf, internal.NativeEndian, &btfHeader{ + err := binary.Write(&buf, binary.NativeEndian, &btfHeader{ Magic: btfMagic, Version: 1, HdrLen: uint32(binary.Size(btfHeader{})), @@ -26,7 +24,7 @@ func FuzzSpec(f *testing.F) { t.Skip("data is too short") } - spec, err := loadRawSpec(bytes.NewReader(data), internal.NativeEndian, nil) + spec, err := loadRawSpec(bytes.NewReader(data), binary.NativeEndian, nil) if err != nil { if spec != nil { t.Fatal("spec is not nil") @@ -47,7 +45,7 @@ func FuzzSpec(f *testing.F) { func FuzzExtInfo(f *testing.F) { var buf bytes.Buffer - err := binary.Write(&buf, internal.NativeEndian, &btfExtHeader{ + err := binary.Write(&buf, binary.NativeEndian, &btfExtHeader{ Magic: btfMagic, Version: 1, HdrLen: uint32(binary.Size(btfExtHeader{})), @@ -70,7 +68,7 @@ func FuzzExtInfo(f *testing.F) { emptySpec := specFromTypes(t, nil) emptySpec.strings = table - info, err := loadExtInfos(bytes.NewReader(data), internal.NativeEndian, emptySpec) + info, err := loadExtInfos(bytes.NewReader(data), binary.NativeEndian, emptySpec) if err != nil { if info != nil { t.Fatal("info is not nil") diff --git a/btf/handle.go b/btf/handle.go index adfa6fed4..53a22f3f6 100644 --- a/btf/handle.go +++ b/btf/handle.go @@ -2,6 +2,7 @@ package btf import ( "bytes" + "encoding/binary" "errors" "fmt" "math" @@ -143,7 +144,7 @@ func (h *Handle) Spec(base *Spec) (*Spec, error) { return nil, fmt.Errorf("missing base types") } - return loadRawSpec(bytes.NewReader(btfBuffer), internal.NativeEndian, base) + return loadRawSpec(bytes.NewReader(btfBuffer), binary.NativeEndian, base) } // Close destroys the handle. diff --git a/btf/kernel.go b/btf/kernel.go index 1a9321f05..e7d2ead2d 100644 --- a/btf/kernel.go +++ b/btf/kernel.go @@ -1,6 +1,7 @@ package btf import ( + "encoding/binary" "errors" "fmt" "os" @@ -97,7 +98,7 @@ func loadKernelSpec() (_ *Spec, fallback bool, _ error) { if err == nil { defer fh.Close() - spec, err := loadRawSpec(fh, internal.NativeEndian, nil) + spec, err := loadRawSpec(fh, binary.NativeEndian, nil) return spec, false, err } @@ -123,7 +124,7 @@ func loadKernelModuleSpec(module string, base *Spec) (*Spec, error) { } defer fh.Close() - return loadRawSpec(fh, internal.NativeEndian, base) + return loadRawSpec(fh, binary.NativeEndian, base) } // findVMLinux scans multiple well-known paths for vmlinux kernel images. diff --git a/btf/marshal.go b/btf/marshal.go index d7204e624..f634fefc8 100644 --- a/btf/marshal.go +++ b/btf/marshal.go @@ -31,7 +31,7 @@ type MarshalOptions struct { // KernelMarshalOptions will generate BTF suitable for the current kernel. func KernelMarshalOptions() *MarshalOptions { return &MarshalOptions{ - Order: internal.NativeEndian, + Order: binary.NativeEndian, StripFuncLinkage: haveFuncLinkage() != nil, ReplaceDeclTags: haveDeclTags() != nil, ReplaceTypeTags: haveTypeTags() != nil, @@ -160,7 +160,7 @@ func (b *Builder) Marshal(buf []byte, opts *MarshalOptions) ([]byte, error) { } if opts == nil { - opts = &MarshalOptions{Order: internal.NativeEndian} + opts = &MarshalOptions{Order: binary.NativeEndian} } // Reserve space for the BTF header. diff --git a/btf/marshal_test.go b/btf/marshal_test.go index e46bcbfcd..a73f5db7b 100644 --- a/btf/marshal_test.go +++ b/btf/marshal_test.go @@ -9,7 +9,6 @@ import ( "github.com/go-quicktest/qt" "github.com/google/go-cmp/cmp" - "github.com/cilium/ebpf/internal" "github.com/cilium/ebpf/internal/testutils" ) @@ -31,11 +30,11 @@ func TestBuilderMarshal(t *testing.T) { qt.Assert(t, qt.IsNil(err)) cpy := *b - buf, err := b.Marshal(nil, &MarshalOptions{Order: internal.NativeEndian}) + buf, err := b.Marshal(nil, &MarshalOptions{Order: binary.NativeEndian}) qt.Assert(t, qt.IsNil(err)) qt.Assert(t, qt.CmpEquals(b, &cpy, cmp.AllowUnexported(*b)), qt.Commentf("Marshaling should not change Builder state")) - have, err := loadRawSpec(bytes.NewReader(buf), internal.NativeEndian, nil) + have, err := loadRawSpec(bytes.NewReader(buf), binary.NativeEndian, nil) qt.Assert(t, qt.IsNil(err), qt.Commentf("Couldn't parse BTF")) qt.Assert(t, qt.DeepEquals(have.imm.types, want)) } @@ -124,12 +123,12 @@ func TestMarshalEnum64(t *testing.T) { b, err := NewBuilder([]Type{enum}) qt.Assert(t, qt.IsNil(err)) buf, err := b.Marshal(nil, &MarshalOptions{ - Order: internal.NativeEndian, + Order: binary.NativeEndian, ReplaceEnum64: true, }) qt.Assert(t, qt.IsNil(err)) - spec, err := loadRawSpec(bytes.NewReader(buf), internal.NativeEndian, nil) + spec, err := loadRawSpec(bytes.NewReader(buf), binary.NativeEndian, nil) qt.Assert(t, qt.IsNil(err)) var have *Union @@ -160,12 +159,12 @@ func TestMarshalDeclTags(t *testing.T) { b, err := NewBuilder(types) qt.Assert(t, qt.IsNil(err)) buf, err := b.Marshal(nil, &MarshalOptions{ - Order: internal.NativeEndian, + Order: binary.NativeEndian, ReplaceDeclTags: true, }) qt.Assert(t, qt.IsNil(err)) - spec, err := loadRawSpec(bytes.NewReader(buf), internal.NativeEndian, nil) + spec, err := loadRawSpec(bytes.NewReader(buf), binary.NativeEndian, nil) qt.Assert(t, qt.IsNil(err)) var td *Typedef @@ -191,12 +190,12 @@ func TestMarshalTypeTags(t *testing.T) { b, err := NewBuilder(types) qt.Assert(t, qt.IsNil(err)) buf, err := b.Marshal(nil, &MarshalOptions{ - Order: internal.NativeEndian, + Order: binary.NativeEndian, ReplaceTypeTags: true, }) qt.Assert(t, qt.IsNil(err)) - spec, err := loadRawSpec(bytes.NewReader(buf), internal.NativeEndian, nil) + spec, err := loadRawSpec(bytes.NewReader(buf), binary.NativeEndian, nil) qt.Assert(t, qt.IsNil(err)) var td *Typedef @@ -251,7 +250,7 @@ func specFromTypes(tb testing.TB, types []Type) *Spec { tb.Helper() btf := marshalNativeEndian(tb, types) - spec, err := loadRawSpec(bytes.NewReader(btf), internal.NativeEndian, nil) + spec, err := loadRawSpec(bytes.NewReader(btf), binary.NativeEndian, nil) qt.Assert(tb, qt.IsNil(err)) return spec diff --git a/collection.go b/collection.go index a7b6cb31b..708c9d9bb 100644 --- a/collection.go +++ b/collection.go @@ -9,7 +9,6 @@ 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" @@ -725,7 +724,7 @@ func resolveKconfig(m *MapSpec) error { if err != nil { return fmt.Errorf("getting kernel version: %w", err) } - internal.NativeEndian.PutUint32(data[vsi.Offset:], kv.Kernel()) + binary.NativeEndian.PutUint32(data[vsi.Offset:], kv.Kernel()) case "LINUX_HAS_SYSCALL_WRAPPER": integer, ok := v.Type.(*btf.Int) diff --git a/elf_reader_test.go b/elf_reader_test.go index 07711dd87..ecd2bcd6d 100644 --- a/elf_reader_test.go +++ b/elf_reader_test.go @@ -254,7 +254,7 @@ func TestLoadCollectionSpec(t *testing.T) { t.Errorf("MapSpec mismatch (-want +got):\n%s", diff) } - if have.ByteOrder != internal.NativeEndian { + if !internal.EqualByteOrder(have.ByteOrder, binary.NativeEndian) { return } @@ -445,7 +445,7 @@ func TestLoadInitializedBTFMap(t *testing.T) { } t.Run("NewCollection", func(t *testing.T) { - if coll.ByteOrder != internal.NativeEndian { + if !internal.EqualByteOrder(coll.ByteOrder, binary.NativeEndian) { t.Skipf("Skipping %s collection", coll.ByteOrder) } diff --git a/info.go b/info.go index 56a1f1e9a..d2912ddc9 100644 --- a/info.go +++ b/info.go @@ -3,6 +3,7 @@ package ebpf import ( "bufio" "bytes" + "encoding/binary" "encoding/hex" "errors" "fmt" @@ -480,7 +481,7 @@ func (pi *ProgramInfo) LineInfos() (btf.LineOffsets, error) { return btf.LoadLineInfos( bytes.NewReader(pi.lineInfos), - internal.NativeEndian, + binary.NativeEndian, pi.numLineInfos, spec, ) @@ -515,7 +516,7 @@ func (pi *ProgramInfo) Instructions() (asm.Instructions, error) { r := bytes.NewReader(pi.insns) var insns asm.Instructions - if err := insns.Unmarshal(r, internal.NativeEndian); err != nil { + if err := insns.Unmarshal(r, binary.NativeEndian); err != nil { return nil, fmt.Errorf("unmarshaling instructions: %w", err) } @@ -540,7 +541,7 @@ func (pi *ProgramInfo) Instructions() (asm.Instructions, error) { lineInfos, err := btf.LoadLineInfos( bytes.NewReader(pi.lineInfos), - internal.NativeEndian, + binary.NativeEndian, pi.numLineInfos, spec, ) @@ -550,7 +551,7 @@ func (pi *ProgramInfo) Instructions() (asm.Instructions, error) { funcInfos, err := btf.LoadFuncInfos( bytes.NewReader(pi.funcInfos), - internal.NativeEndian, + binary.NativeEndian, pi.numFuncInfos, spec, ) @@ -681,7 +682,7 @@ func (pi *ProgramInfo) FuncInfos() (btf.FuncOffsets, error) { return btf.LoadFuncInfos( bytes.NewReader(pi.funcInfos), - internal.NativeEndian, + binary.NativeEndian, pi.numFuncInfos, spec, ) diff --git a/internal/endian.go b/internal/endian.go new file mode 100644 index 000000000..2557bb1d9 --- /dev/null +++ b/internal/endian.go @@ -0,0 +1,19 @@ +package internal + +import "encoding/binary" + +func endianMark(bo binary.ByteOrder) uint16 { return bo.Uint16([]byte{0x12, 0x34}) } + +func EqualByteOrder(bo1, bo2 binary.ByteOrder) bool { + return endianMark(bo1) == endianMark(bo2) +} + +func NormalizeByteOrder(bo binary.ByteOrder) binary.ByteOrder { + if EqualByteOrder(bo, binary.BigEndian) { + return binary.BigEndian + } + if EqualByteOrder(bo, binary.LittleEndian) { + return binary.LittleEndian + } + return bo +} diff --git a/internal/endian_be.go b/internal/endian_be.go deleted file mode 100644 index a37777f21..000000000 --- a/internal/endian_be.go +++ /dev/null @@ -1,9 +0,0 @@ -//go:build armbe || arm64be || mips || mips64 || mips64p32 || ppc64 || s390 || s390x || sparc || sparc64 - -package internal - -import "encoding/binary" - -// NativeEndian is set to either binary.BigEndian or binary.LittleEndian, -// depending on the host's endianness. -var NativeEndian = binary.BigEndian diff --git a/internal/endian_le.go b/internal/endian_le.go deleted file mode 100644 index 6dcd916d5..000000000 --- a/internal/endian_le.go +++ /dev/null @@ -1,9 +0,0 @@ -//go:build 386 || amd64 || amd64p32 || arm || arm64 || loong64 || mipsle || mips64le || mips64p32le || ppc64le || riscv64 - -package internal - -import "encoding/binary" - -// NativeEndian is set to either binary.BigEndian or binary.LittleEndian, -// depending on the host's endianness. -var NativeEndian = binary.LittleEndian diff --git a/internal/epoll/poller.go b/internal/epoll/poller.go index 76bfa77e9..f0b4fcb6a 100644 --- a/internal/epoll/poller.go +++ b/internal/epoll/poller.go @@ -3,6 +3,7 @@ package epoll import ( + "encoding/binary" "errors" "fmt" "math" @@ -267,7 +268,7 @@ func (efd *eventFd) close() error { func (efd *eventFd) add(n uint64) error { var buf [8]byte - internal.NativeEndian.PutUint64(buf[:], n) + binary.NativeEndian.PutUint64(buf[:], n) _, err := efd.file.Write(buf[:]) return err } @@ -275,5 +276,5 @@ func (efd *eventFd) add(n uint64) error { func (efd *eventFd) read() (uint64, error) { var buf [8]byte _, err := efd.file.Read(buf[:]) - return internal.NativeEndian.Uint64(buf[:]), err + return binary.NativeEndian.Uint64(buf[:]), err } diff --git a/internal/kconfig/kconfig.go b/internal/kconfig/kconfig.go index 29c62b626..9c818ba6d 100644 --- a/internal/kconfig/kconfig.go +++ b/internal/kconfig/kconfig.go @@ -5,6 +5,7 @@ import ( "bufio" "bytes" "compress/gzip" + "encoding/binary" "fmt" "io" "math" @@ -12,7 +13,6 @@ import ( "strings" "github.com/cilium/ebpf/btf" - "github.com/cilium/ebpf/internal" ) // Parse parses the kconfig file for which a reader is given. @@ -162,7 +162,7 @@ func putValueTri(data []byte, typ btf.Type, value string) error { return fmt.Errorf("value %q is not supported for libbpf_tristate", value) } - internal.NativeEndian.PutUint32(data, uint32(tri)) + binary.NativeEndian.PutUint32(data, uint32(tri)) default: return fmt.Errorf("cannot add number value, expected btf.Int or btf.Enum, got: %T", v) } @@ -258,14 +258,14 @@ func PutInteger(data []byte, integer *btf.Int, n uint64) error { if integer.Encoding == btf.Signed && (int64(n) > math.MaxInt16 || int64(n) < math.MinInt16) { return fmt.Errorf("can't represent %d as a signed integer of size %d", int64(n), integer.Size) } - internal.NativeEndian.PutUint16(data, uint16(n)) + binary.NativeEndian.PutUint16(data, uint16(n)) case 4: if integer.Encoding == btf.Signed && (int64(n) > math.MaxInt32 || int64(n) < math.MinInt32) { return fmt.Errorf("can't represent %d as a signed integer of size %d", int64(n), integer.Size) } - internal.NativeEndian.PutUint32(data, uint32(n)) + binary.NativeEndian.PutUint32(data, uint32(n)) case 8: - internal.NativeEndian.PutUint64(data, uint64(n)) + binary.NativeEndian.PutUint64(data, uint64(n)) default: return fmt.Errorf("size (%d) is not valid, expected: 1, 2, 4 or 8", integer.Size) } diff --git a/internal/kconfig/kconfig_test.go b/internal/kconfig/kconfig_test.go index d9cd7192c..8a1d4ab62 100644 --- a/internal/kconfig/kconfig_test.go +++ b/internal/kconfig/kconfig_test.go @@ -7,7 +7,6 @@ import ( "testing" "github.com/cilium/ebpf/btf" - "github.com/cilium/ebpf/internal" "github.com/go-quicktest/qt" ) @@ -402,7 +401,7 @@ func TestPutValue(t *testing.T) { } var buf bytes.Buffer - err := binary.Write(&buf, internal.NativeEndian, c.expected) + err := binary.Write(&buf, binary.NativeEndian, c.expected) if err != nil { t.Fatal(err) } diff --git a/internal/linux/auxv_test.go b/internal/linux/auxv_test.go index 32bf0f6e0..4cc57b350 100644 --- a/internal/linux/auxv_test.go +++ b/internal/linux/auxv_test.go @@ -8,7 +8,6 @@ import ( "testing" "unsafe" - "github.com/cilium/ebpf/internal" "github.com/cilium/ebpf/internal/unix" ) @@ -67,7 +66,7 @@ func newAuxFileReader(path string, order binary.ByteOrder, uintptrIs32bits bool) func newDefaultAuxvFileReader() (auxvPairReader, error) { const uintptrIs32bits = unsafe.Sizeof((uintptr)(0)) == 4 - return newAuxFileReader("/proc/self/auxv", internal.NativeEndian, uintptrIs32bits) + return newAuxFileReader("/proc/self/auxv", binary.NativeEndian, uintptrIs32bits) } func TestAuxvBothSourcesEqual(t *testing.T) { diff --git a/internal/sysenc/marshal.go b/internal/sysenc/marshal.go index 0026af8f2..e1fe75dff 100644 --- a/internal/sysenc/marshal.go +++ b/internal/sysenc/marshal.go @@ -37,17 +37,17 @@ func Marshal(data any, size int) (Buffer, error) { case []byte: buf = value case int16: - buf = internal.NativeEndian.AppendUint16(make([]byte, 0, 2), uint16(value)) + buf = binary.NativeEndian.AppendUint16(make([]byte, 0, 2), uint16(value)) case uint16: - buf = internal.NativeEndian.AppendUint16(make([]byte, 0, 2), value) + buf = binary.NativeEndian.AppendUint16(make([]byte, 0, 2), value) case int32: - buf = internal.NativeEndian.AppendUint32(make([]byte, 0, 4), uint32(value)) + buf = binary.NativeEndian.AppendUint32(make([]byte, 0, 4), uint32(value)) case uint32: - buf = internal.NativeEndian.AppendUint32(make([]byte, 0, 4), value) + buf = binary.NativeEndian.AppendUint32(make([]byte, 0, 4), value) case int64: - buf = internal.NativeEndian.AppendUint64(make([]byte, 0, 8), uint64(value)) + buf = binary.NativeEndian.AppendUint64(make([]byte, 0, 8), uint64(value)) case uint64: - buf = internal.NativeEndian.AppendUint64(make([]byte, 0, 8), value) + buf = binary.NativeEndian.AppendUint64(make([]byte, 0, 8), value) default: if buf := unsafeBackingMemory(data); len(buf) == size { return newBuffer(buf), nil @@ -56,7 +56,7 @@ func Marshal(data any, size int) (Buffer, error) { wr := internal.NewBuffer(make([]byte, 0, size)) defer internal.PutBuffer(wr) - err = binary.Write(wr, internal.NativeEndian, value) + err = binary.Write(wr, binary.NativeEndian, value) buf = wr.Bytes() } if err != nil { @@ -105,7 +105,7 @@ func Unmarshal(data interface{}, buf []byte) error { rd.Reset(buf) - if err := binary.Read(rd, internal.NativeEndian, value); err != nil { + if err := binary.Read(rd, binary.NativeEndian, value); err != nil { return err } diff --git a/internal/sysenc/marshal_test.go b/internal/sysenc/marshal_test.go index 96b8a988d..3eff95f32 100644 --- a/internal/sysenc/marshal_test.go +++ b/internal/sysenc/marshal_test.go @@ -10,8 +10,6 @@ import ( "github.com/go-quicktest/qt" "github.com/google/go-cmp/cmp/cmpopts" - - "github.com/cilium/ebpf/internal" ) type testcase struct { @@ -61,7 +59,7 @@ func TestMarshal(t *testing.T) { value := test.new() t.Run(fmt.Sprintf("%T", value), func(t *testing.T) { var want bytes.Buffer - if err := binary.Write(&want, internal.NativeEndian, value); err != nil { + if err := binary.Write(&want, binary.NativeEndian, value); err != nil { t.Fatal(err) } @@ -148,7 +146,7 @@ func TestUnsafeBackingMemory(t *testing.T) { t.Helper() var buf bytes.Buffer - qt.Assert(t, qt.IsNil(binary.Write(&buf, internal.NativeEndian, data))) + qt.Assert(t, qt.IsNil(binary.Write(&buf, binary.NativeEndian, data))) return buf.Bytes() } @@ -295,7 +293,7 @@ func randomiseValue(tb testing.TB, value any) []byte { buf[i] = byte(i) } - err := binary.Read(bytes.NewReader(buf), internal.NativeEndian, value) + err := binary.Read(bytes.NewReader(buf), binary.NativeEndian, value) qt.Assert(tb, qt.IsNil(err)) return buf diff --git a/linker.go b/linker.go index 024b72bbc..af3123780 100644 --- a/linker.go +++ b/linker.go @@ -13,7 +13,6 @@ import ( "github.com/cilium/ebpf/asm" "github.com/cilium/ebpf/btf" - "github.com/cilium/ebpf/internal" "github.com/cilium/ebpf/internal/kallsyms" ) @@ -139,7 +138,7 @@ func applyRelocations(insns asm.Instructions, targets []*btf.Spec, kmodName stri } if bo == nil { - bo = internal.NativeEndian + bo = binary.NativeEndian } if len(targets) == 0 { diff --git a/map.go b/map.go index e5d8bd780..4f4eafd39 100644 --- a/map.go +++ b/map.go @@ -2,6 +2,7 @@ package ebpf import ( "bytes" + "encoding/binary" "errors" "fmt" "io" @@ -1616,7 +1617,7 @@ func marshalMap(m *Map, length int) ([]byte, error) { } buf := make([]byte, 4) - internal.NativeEndian.PutUint32(buf, m.fd.Uint()) + binary.NativeEndian.PutUint32(buf, m.fd.Uint()) return buf, nil } diff --git a/map_test.go b/map_test.go index a437a2648..895da6228 100644 --- a/map_test.go +++ b/map_test.go @@ -2,6 +2,7 @@ package ebpf import ( "bytes" + "encoding/binary" "errors" "fmt" "math" @@ -82,7 +83,7 @@ func TestMap(t *testing.T) { var slice []byte qt.Assert(t, qt.IsNil(m.Lookup(uint32(0), &slice))) - qt.Assert(t, qt.DeepEquals(slice, internal.NativeEndian.AppendUint32(nil, 42))) + qt.Assert(t, qt.DeepEquals(slice, binary.NativeEndian.AppendUint32(nil, 42))) var k uint32 if err := m.NextKey(uint32(0), &k); err != nil { @@ -1946,21 +1947,21 @@ type benchValue struct { type customBenchValue benchValue func (cbv *customBenchValue) UnmarshalBinary(buf []byte) error { - cbv.ID = internal.NativeEndian.Uint32(buf) - cbv.Val16 = internal.NativeEndian.Uint16(buf[4:]) - cbv.Val16_2 = internal.NativeEndian.Uint16(buf[6:]) + cbv.ID = binary.NativeEndian.Uint32(buf) + cbv.Val16 = binary.NativeEndian.Uint16(buf[4:]) + cbv.Val16_2 = binary.NativeEndian.Uint16(buf[6:]) copy(cbv.Name[:], buf[8:]) - cbv.LID = internal.NativeEndian.Uint64(buf[16:]) + cbv.LID = binary.NativeEndian.Uint64(buf[16:]) return nil } func (cbv *customBenchValue) MarshalBinary() ([]byte, error) { buf := make([]byte, 24) - internal.NativeEndian.PutUint32(buf, cbv.ID) - internal.NativeEndian.PutUint16(buf[4:], cbv.Val16) - internal.NativeEndian.PutUint16(buf[6:], cbv.Val16_2) + binary.NativeEndian.PutUint32(buf, cbv.ID) + binary.NativeEndian.PutUint16(buf[4:], cbv.Val16) + binary.NativeEndian.PutUint16(buf[6:], cbv.Val16_2) copy(buf[8:], cbv.Name[:]) - internal.NativeEndian.PutUint64(buf[16:], cbv.LID) + binary.NativeEndian.PutUint64(buf[16:], cbv.LID) return buf, nil } @@ -1970,7 +1971,7 @@ type benchKey struct { func (bk *benchKey) MarshalBinary() ([]byte, error) { buf := make([]byte, 8) - internal.NativeEndian.PutUint64(buf, bk.id) + binary.NativeEndian.PutUint64(buf, bk.id) return buf, nil } diff --git a/marshalers_test.go b/marshalers_test.go index 1351e7a9c..93eca060c 100644 --- a/marshalers_test.go +++ b/marshalers_test.go @@ -1,6 +1,7 @@ package ebpf import ( + "encoding/binary" "testing" "github.com/cilium/ebpf/internal" @@ -39,7 +40,7 @@ func TestMarshalBatchPerCPUValue(t *testing.T) { expected := make([]byte, sliceLen*internal.Align(elemLength, 8)) b := expected for _, elem := range slice { - internal.NativeEndian.PutUint32(b, elem) + binary.NativeEndian.PutUint32(b, elem) b = b[8:] } buf, err := marshalBatchPerCPUValue(slice, batchLen, elemLength) @@ -70,7 +71,7 @@ func TestUnmarshalBatchPerCPUValue(t *testing.T) { buf := make([]byte, batchLen*possibleCPU*internal.Align(elemLength, 8)) b := buf for _, elem := range expected { - internal.NativeEndian.PutUint32(b, elem) + binary.NativeEndian.PutUint32(b, elem) b = b[8:] } err := unmarshalBatchPerCPUValue(output, batchLen, elemLength, buf) @@ -106,7 +107,7 @@ func TestUnmarshalPerCPUValue(t *testing.T) { buf := make([]byte, possibleCPUs*internal.Align(elemLength, 8)) b := buf for _, elem := range expected { - internal.NativeEndian.PutUint32(b, elem) + binary.NativeEndian.PutUint32(b, elem) b = b[8:] } slice := make([]uint32, possibleCPUs) diff --git a/perf/reader.go b/perf/reader.go index 113148bb0..8ac3e039f 100644 --- a/perf/reader.go +++ b/perf/reader.go @@ -13,7 +13,6 @@ import ( "time" "github.com/cilium/ebpf" - "github.com/cilium/ebpf/internal" "github.com/cilium/ebpf/internal/epoll" "github.com/cilium/ebpf/internal/sys" "github.com/cilium/ebpf/internal/unix" @@ -68,9 +67,9 @@ func readRecord(rd io.Reader, rec *Record, buf []byte, overwritable bool) error } header := perfEventHeader{ - internal.NativeEndian.Uint32(buf[0:4]), - internal.NativeEndian.Uint16(buf[4:6]), - internal.NativeEndian.Uint16(buf[6:8]), + binary.NativeEndian.Uint32(buf[0:4]), + binary.NativeEndian.Uint16(buf[4:6]), + binary.NativeEndian.Uint16(buf[6:8]), } switch header.Type { @@ -97,7 +96,7 @@ func readLostRecords(rd io.Reader) (uint64, error) { Lost uint64 } - err := binary.Read(rd, internal.NativeEndian, &lostHeader) + err := binary.Read(rd, binary.NativeEndian, &lostHeader) if err != nil { return 0, fmt.Errorf("can't read lost records header: %v", err) } @@ -119,7 +118,7 @@ func readRawSample(rd io.Reader, buf, sampleBuf []byte) ([]byte, error) { } sample := perfEventSample{ - internal.NativeEndian.Uint32(buf), + binary.NativeEndian.Uint32(buf), } var data []byte diff --git a/perf/reader_test.go b/perf/reader_test.go index e19771037..ecb6223f3 100644 --- a/perf/reader_test.go +++ b/perf/reader_test.go @@ -464,7 +464,7 @@ func TestCreatePerfEvent(t *testing.T) { func TestReadRecord(t *testing.T) { var buf bytes.Buffer - err := binary.Write(&buf, internal.NativeEndian, &perfEventHeader{}) + err := binary.Write(&buf, binary.NativeEndian, &perfEventHeader{}) if err != nil { t.Fatal(err) } diff --git a/prog.go b/prog.go index 8fcae6a3f..48ce6b5af 100644 --- a/prog.go +++ b/prog.go @@ -162,7 +162,7 @@ func (ps *ProgramSpec) Copy() *ProgramSpec { // // Use asm.Instructions.Tag if you need to calculate for non-native endianness. func (ps *ProgramSpec) Tag() (string, error) { - return ps.Instructions.Tag(internal.NativeEndian) + return ps.Instructions.Tag(binary.NativeEndian) } // kernelModule returns the kernel module providing the symbol in @@ -263,8 +263,10 @@ func newProgramWithOptions(spec *ProgramSpec, opts ProgramOptions) (*Program, er return nil, errors.New("can't load program of unspecified type") } - if spec.ByteOrder != nil && spec.ByteOrder != internal.NativeEndian { - return nil, fmt.Errorf("can't load %s program on %s", spec.ByteOrder, internal.NativeEndian) + if spec.ByteOrder != nil && !internal.EqualByteOrder(spec.ByteOrder, binary.NativeEndian) { + return nil, fmt.Errorf("can't load %s program on %s", + internal.NormalizeByteOrder(spec.ByteOrder), + internal.NormalizeByteOrder(binary.NativeEndian)) } // Kernels before 5.0 (6c4fc209fcf9 "bpf: remove useless version check for prog load") @@ -376,7 +378,7 @@ func newProgramWithOptions(spec *ProgramSpec, opts ProgramOptions) (*Program, er } buf := bytes.NewBuffer(make([]byte, 0, insns.Size())) - err = insns.Marshal(buf, internal.NativeEndian) + err = insns.Marshal(buf, binary.NativeEndian) if err != nil { return nil, err } @@ -814,7 +816,7 @@ func (p *Program) run(opts *RunOptions) (uint32, time.Duration, error) { var ctxBytes []byte if opts.Context != nil { ctx := new(bytes.Buffer) - if err := binary.Write(ctx, internal.NativeEndian, opts.Context); err != nil { + if err := binary.Write(ctx, binary.NativeEndian, opts.Context); err != nil { return 0, 0, fmt.Errorf("cannot serialize context: %v", err) } ctxBytes = ctx.Bytes() @@ -888,7 +890,7 @@ retry: if len(ctxOut) != 0 { b := bytes.NewReader(ctxOut) - if err := binary.Read(b, internal.NativeEndian, opts.ContextOut); err != nil { + if err := binary.Read(b, binary.NativeEndian, opts.ContextOut); err != nil { return 0, 0, fmt.Errorf("failed to decode ContextOut: %v", err) } } @@ -918,7 +920,7 @@ func marshalProgram(p *Program, length int) ([]byte, error) { } buf := make([]byte, 4) - internal.NativeEndian.PutUint32(buf, p.fd.Uint()) + binary.NativeEndian.PutUint32(buf, p.fd.Uint()) return buf, nil } diff --git a/prog_test.go b/prog_test.go index 7781a0ca6..b77ac23fa 100644 --- a/prog_test.go +++ b/prog_test.go @@ -726,7 +726,7 @@ func TestProgramRejectIncorrectByteOrder(t *testing.T) { spec := socketFilterSpec.Copy() spec.ByteOrder = binary.BigEndian - if spec.ByteOrder == internal.NativeEndian { + if spec.ByteOrder == binary.NativeEndian { spec.ByteOrder = binary.LittleEndian } @@ -962,7 +962,7 @@ func TestProgramInstructions(t *testing.T) { t.Fatal(err) } - tagXlated, err := insns.Tag(internal.NativeEndian) + tagXlated, err := insns.Tag(binary.NativeEndian) if err != nil { t.Fatal(err) } diff --git a/syscalls.go b/syscalls.go index 25c84c3c5..d25713ac6 100644 --- a/syscalls.go +++ b/syscalls.go @@ -2,6 +2,7 @@ package ebpf import ( "bytes" + "encoding/binary" "errors" "fmt" "math" @@ -48,7 +49,7 @@ func invalidBPFObjNameChar(char rune) bool { func progLoad(insns asm.Instructions, typ ProgramType, license string) (*sys.FD, error) { buf := bytes.NewBuffer(make([]byte, 0, insns.Size())) - if err := insns.Marshal(buf, internal.NativeEndian); err != nil { + if err := insns.Marshal(buf, binary.NativeEndian); err != nil { return nil, err } bytecode := buf.Bytes() @@ -329,7 +330,7 @@ var haveProgramExtInfos = internal.NewFeatureTest("program ext_infos", func() er } buf := bytes.NewBuffer(make([]byte, 0, insns.Size())) - if err := insns.Marshal(buf, internal.NativeEndian); err != nil { + if err := insns.Marshal(buf, binary.NativeEndian); err != nil { return err } bytecode := buf.Bytes()