summaryrefslogtreecommitdiff
path: root/vendor/github.com/cilium/ebpf/internal/vdso.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/cilium/ebpf/internal/vdso.go')
-rw-r--r--vendor/github.com/cilium/ebpf/internal/vdso.go150
1 files changed, 0 insertions, 150 deletions
diff --git a/vendor/github.com/cilium/ebpf/internal/vdso.go b/vendor/github.com/cilium/ebpf/internal/vdso.go
deleted file mode 100644
index ae4821de2..000000000
--- a/vendor/github.com/cilium/ebpf/internal/vdso.go
+++ /dev/null
@@ -1,150 +0,0 @@
-package internal
-
-import (
- "debug/elf"
- "encoding/binary"
- "errors"
- "fmt"
- "io"
- "math"
- "os"
-
- "github.com/cilium/ebpf/internal/unix"
-)
-
-var (
- errAuxvNoVDSO = errors.New("no vdso address found in auxv")
-)
-
-// vdsoVersion returns the LINUX_VERSION_CODE embedded in the vDSO library
-// linked into the current process image.
-func vdsoVersion() (uint32, error) {
- // Read data from the auxiliary vector, which is normally passed directly
- // to the process. Go does not expose that data, so we must read it from procfs.
- // https://man7.org/linux/man-pages/man3/getauxval.3.html
- av, err := os.Open("/proc/self/auxv")
- if err != nil {
- return 0, fmt.Errorf("opening auxv: %w", err)
- }
- defer av.Close()
-
- vdsoAddr, err := vdsoMemoryAddress(av)
- if err != nil {
- return 0, fmt.Errorf("finding vDSO memory address: %w", err)
- }
-
- // Use /proc/self/mem rather than unsafe.Pointer tricks.
- mem, err := os.Open("/proc/self/mem")
- if err != nil {
- return 0, fmt.Errorf("opening mem: %w", err)
- }
- defer mem.Close()
-
- // Open ELF at provided memory address, as offset into /proc/self/mem.
- c, err := vdsoLinuxVersionCode(io.NewSectionReader(mem, int64(vdsoAddr), math.MaxInt64))
- if err != nil {
- return 0, fmt.Errorf("reading linux version code: %w", err)
- }
-
- return c, nil
-}
-
-// vdsoMemoryAddress returns the memory address of the vDSO library
-// linked into the current process image. r is an io.Reader into an auxv blob.
-func vdsoMemoryAddress(r io.Reader) (uint64, error) {
- const (
- _AT_NULL = 0 // End of vector
- _AT_SYSINFO_EHDR = 33 // Offset to vDSO blob in process image
- )
-
- // Loop through all tag/value pairs in auxv until we find `AT_SYSINFO_EHDR`,
- // the address of a page containing the virtual Dynamic Shared Object (vDSO).
- aux := struct{ Tag, Val uint64 }{}
- for {
- if err := binary.Read(r, NativeEndian, &aux); err != nil {
- return 0, fmt.Errorf("reading auxv entry: %w", err)
- }
-
- switch aux.Tag {
- case _AT_SYSINFO_EHDR:
- if aux.Val != 0 {
- return aux.Val, nil
- }
- return 0, fmt.Errorf("invalid vDSO address in auxv")
- // _AT_NULL is always the last tag/val pair in the aux vector
- // and can be treated like EOF.
- case _AT_NULL:
- return 0, errAuxvNoVDSO
- }
- }
-}
-
-// format described at https://www.man7.org/linux/man-pages/man5/elf.5.html in section 'Notes (Nhdr)'
-type elfNoteHeader struct {
- NameSize int32
- DescSize int32
- Type int32
-}
-
-// 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 := NewSafeELFFile(r)
- if err != nil {
- return 0, fmt.Errorf("reading vDSO ELF: %w", err)
- }
-
- sections := hdr.SectionsByType(elf.SHT_NOTE)
- if len(sections) == 0 {
- return 0, fmt.Errorf("no note section found in vDSO ELF")
- }
-
- for _, sec := range sections {
- sr := sec.Open()
- var n elfNoteHeader
-
- // Read notes until we find one named 'Linux'.
- for {
- if err := binary.Read(sr, hdr.ByteOrder, &n); err != nil {
- if errors.Is(err, io.EOF) {
- // We looked at all the notes in this section
- break
- }
- return 0, fmt.Errorf("reading note header: %w", err)
- }
-
- // If a note name is defined, it follows the note header.
- var name string
- if n.NameSize > 0 {
- // Read the note name, aligned to 4 bytes.
- buf := make([]byte, Align(int(n.NameSize), 4))
- if err := binary.Read(sr, hdr.ByteOrder, &buf); err != nil {
- return 0, fmt.Errorf("reading note name: %w", err)
- }
-
- // Read nul-terminated string.
- name = unix.ByteSliceToString(buf[:n.NameSize])
- }
-
- // If a note descriptor is defined, it follows the name.
- // It is possible for a note to have a descriptor but not a name.
- if n.DescSize > 0 {
- // LINUX_VERSION_CODE is a uint32 value.
- if name == "Linux" && n.DescSize == 4 && n.Type == 0 {
- var version uint32
- if err := binary.Read(sr, hdr.ByteOrder, &version); err != nil {
- return 0, fmt.Errorf("reading note descriptor: %w", err)
- }
- return version, nil
- }
-
- // Discard the note descriptor if it exists but we're not interested in it.
- if _, err := io.CopyN(io.Discard, sr, int64(Align(int(n.DescSize), 4))); err != nil {
- return 0, err
- }
- }
- }
- }
-
- return 0, fmt.Errorf("no Linux note in ELF")
-}