Files
runc/vendor/github.com/cilium/ebpf/internal/sysenc/buffer.go
dependabot[bot] e809db842f build(deps): bump github.com/cilium/ebpf from 0.16.0 to 0.17.0
Bumps [github.com/cilium/ebpf](https://github.com/cilium/ebpf) from 0.16.0 to 0.17.0.
- [Release notes](https://github.com/cilium/ebpf/releases)
- [Commits](https://github.com/cilium/ebpf/compare/v0.16.0...v0.17.0)

---
updated-dependencies:
- dependency-name: github.com/cilium/ebpf
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-12-20 00:07:03 +00:00

86 lines
2.1 KiB
Go

package sysenc
import (
"unsafe"
"github.com/cilium/ebpf/internal/sys"
)
type Buffer struct {
ptr unsafe.Pointer
// Size of the buffer. syscallPointerOnly if created from UnsafeBuffer or when using
// zero-copy unmarshaling.
size int
}
const syscallPointerOnly = -1
func newBuffer(buf []byte) Buffer {
if len(buf) == 0 {
return Buffer{}
}
return Buffer{unsafe.Pointer(&buf[0]), len(buf)}
}
// UnsafeBuffer constructs a Buffer for zero-copy unmarshaling.
//
// [Pointer] is the only valid method to call on such a Buffer.
// Use [SyscallBuffer] instead if possible.
func UnsafeBuffer(ptr unsafe.Pointer) Buffer {
return Buffer{ptr, syscallPointerOnly}
}
// SyscallOutput prepares a Buffer for a syscall to write into.
//
// size is the length of the desired buffer in bytes.
// The buffer may point at the underlying memory of dst, in which case [Unmarshal]
// becomes a no-op.
//
// The contents of the buffer are undefined and may be non-zero.
func SyscallOutput(dst any, size int) Buffer {
if dstBuf := unsafeBackingMemory(dst); len(dstBuf) == size {
buf := newBuffer(dstBuf)
buf.size = syscallPointerOnly
return buf
}
return newBuffer(make([]byte, size))
}
// CopyTo copies the buffer into dst.
//
// Returns the number of copied bytes.
func (b Buffer) CopyTo(dst []byte) int {
return copy(dst, b.Bytes())
}
// AppendTo appends the buffer onto dst.
func (b Buffer) AppendTo(dst []byte) []byte {
return append(dst, b.Bytes()...)
}
// Pointer returns the location where a syscall should write.
func (b Buffer) Pointer() sys.Pointer {
// NB: This deliberately ignores b.length to support zero-copy
// marshaling / unmarshaling using unsafe.Pointer.
return sys.NewPointer(b.ptr)
}
// Unmarshal the buffer into the provided value.
func (b Buffer) Unmarshal(data any) error {
if b.size == syscallPointerOnly {
return nil
}
return Unmarshal(data, b.Bytes())
}
// 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 {
if b.size == syscallPointerOnly {
return nil
}
return unsafe.Slice((*byte)(b.ptr), b.size)
}