cpu: get hwcap/auxv from the Go 1.21+ runtime

Depends on https://go.dev/cl/458256

This change only does Linux for now.

Updates golang/go#57336

Change-Id: I0659697c1bdc6e2577c6251b964a0df32047ee12
Reviewed-on: https://go-review.googlesource.com/c/sys/+/465295
Reviewed-by: Ian Lance Taylor <iant@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Michael Pratt <mpratt@google.com>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
This commit is contained in:
Brad Fitzpatrick
2023-02-04 06:58:22 -08:00
parent 4fee21c923
commit 2da1413846
4 changed files with 71 additions and 0 deletions

View File

@@ -24,6 +24,21 @@ var hwCap uint
var hwCap2 uint
func readHWCAP() error {
// For Go 1.21+, get auxv from the Go runtime.
if a := getAuxv(); len(a) > 0 {
for len(a) >= 2 {
tag, val := a[0], uint(a[1])
a = a[2:]
switch tag {
case _AT_HWCAP:
hwCap = val
case _AT_HWCAP2:
hwCap2 = val
}
}
return nil
}
buf, err := ioutil.ReadFile(procAuxv)
if err != nil {
// e.g. on android /proc/self/auxv is not accessible, so silently

16
cpu/runtime_auxv.go Normal file
View File

@@ -0,0 +1,16 @@
// Copyright 2023 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 cpu
// getAuxvFn is non-nil on Go 1.21+ (via runtime_auxv_go121.go init)
// on platforms that use auxv.
var getAuxvFn func() []uintptr
func getAuxv() []uintptr {
if getAuxvFn == nil {
return nil
}
return getAuxvFn()
}

19
cpu/runtime_auxv_go121.go Normal file
View File

@@ -0,0 +1,19 @@
// Copyright 2023 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
// +build go1.21
package cpu
import (
_ "unsafe" // for linkname
)
//go:linkname runtime_getAuxv runtime.getAuxv
func runtime_getAuxv() []uintptr
func init() {
getAuxvFn = runtime_getAuxv
}

View File

@@ -0,0 +1,21 @@
// Copyright 2023 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
// +build go1.21
package cpu
import (
"runtime"
"testing"
)
func TestAuxvFromRuntime(t *testing.T) {
got := getAuxv()
t.Logf("got: %v", got) // notably: we didn't panic
if runtime.GOOS == "linux" && len(got) == 0 {
t.Errorf("expected auxv on linux; got zero entries")
}
}