From 4d4692e1b078ef608f533de23ece0464d8f9e182 Mon Sep 17 00:00:00 2001 From: Florian Lehner Date: Sat, 25 Jan 2025 13:08:06 +0100 Subject: [PATCH] unix: add Auxv Fixes golang/go#67839 Change-Id: I3af38d21159f7cac3786b49ac17657d314fbc178 Reviewed-on: https://go-review.googlesource.com/c/sys/+/644295 Reviewed-by: Tobias Klauser LUCI-TryBot-Result: Go LUCI Reviewed-by: Carlos Amedee Reviewed-by: Ian Lance Taylor Auto-Submit: Ian Lance Taylor --- unix/auxv.go | 36 ++++++++++++++++++++++++++++++++++++ unix/auxv_linux_test.go | 23 +++++++++++++++++++++++ unix/auxv_unsupported.go | 13 +++++++++++++ 3 files changed, 72 insertions(+) create mode 100644 unix/auxv.go create mode 100644 unix/auxv_linux_test.go create mode 100644 unix/auxv_unsupported.go diff --git a/unix/auxv.go b/unix/auxv.go new file mode 100644 index 000000000..37a82528f --- /dev/null +++ b/unix/auxv.go @@ -0,0 +1,36 @@ +// Copyright 2025 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. + +//go:build go1.21 && (aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos) + +package unix + +import ( + "syscall" + "unsafe" +) + +//go:linkname runtime_getAuxv runtime.getAuxv +func runtime_getAuxv() []uintptr + +// Auxv returns the ELF auxiliary vector as a sequence of key/value pairs. +// The returned slice is always a fresh copy, owned by the caller. +// It returns an error on non-ELF platforms, or if the auxiliary vector cannot be accessed, +// which happens in some locked-down environments and build modes. +func Auxv() ([][2]uintptr, error) { + vec := runtime_getAuxv() + vecLen := len(vec) + + if vecLen == 0 { + return nil, syscall.ENOENT + } + + if vecLen%2 != 0 { + return nil, syscall.EINVAL + } + + result := make([]uintptr, vecLen) + copy(result, vec) + return unsafe.Slice((*[2]uintptr)(unsafe.Pointer(&result[0])), vecLen/2), nil +} diff --git a/unix/auxv_linux_test.go b/unix/auxv_linux_test.go new file mode 100644 index 000000000..928f3c972 --- /dev/null +++ b/unix/auxv_linux_test.go @@ -0,0 +1,23 @@ +// Copyright 2025 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. + +//go:build go1.21 && linux + +package unix_test + +import ( + "testing" + + "golang.org/x/sys/unix" +) + +func TestAuxv(t *testing.T) { + vec, err := unix.Auxv() + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if len(vec) == 0 { + t.Errorf("got zero auxv entries on linux, expected > 0") + } +} diff --git a/unix/auxv_unsupported.go b/unix/auxv_unsupported.go new file mode 100644 index 000000000..1200487f2 --- /dev/null +++ b/unix/auxv_unsupported.go @@ -0,0 +1,13 @@ +// Copyright 2025 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. + +//go:build !go1.21 && (aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos) + +package unix + +import "syscall" + +func Auxv() ([][2]uintptr, error) { + return nil, syscall.ENOTSUP +}