Skip to content

Commit b0c8da3

Browse files
authored
Fix ARM64 and add fallback (#64)
Fix typo, LOL Add "/proc/self/auxv" fallback.
1 parent 43f4c41 commit b0c8da3

1 file changed

Lines changed: 51 additions & 3 deletions

File tree

os_linux_arm64.go

Lines changed: 51 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,18 @@
11
// Copyright (c) 2020 Klaus Post, released under MIT License. See LICENSE file.
22

3+
// Copyright 2018 The Go Authors. All rights reserved.
4+
// Use of this source code is governed by a BSD-style
5+
// license that can be found in the LICENSE file located
6+
// here https://github.com/golang/sys/blob/master/LICENSE
7+
38
//+build arm64
49
//+build linux android
510

611
package cpuid
712

813
import (
14+
"encoding/binary"
15+
"io/ioutil"
916
"runtime"
1017
_ "unsafe" //required for go:linkname
1118
)
@@ -38,14 +45,55 @@ const (
3845
hwcap_ASIMDFHM = 1 << 23
3946
)
4047

41-
//go:linkname hwcap interval/cpu.HWCap
48+
//go:linkname hwcap internal/cpu.HWCap
4249
var hwcap uint
4350

4451
func detectOS(c *CPUInfo) bool {
4552
if hwcap == 0 {
46-
// It may be wrong, allow unsafe if defined.
47-
return false
53+
// We did not get values from the runtime.
54+
// Try reading /proc/self/auxv
55+
56+
// From https://github.com/golang/sys
57+
const (
58+
_AT_HWCAP = 16
59+
_AT_HWCAP2 = 26
60+
61+
uintSize = int(32 << (^uint(0) >> 63))
62+
)
63+
64+
buf, err := ioutil.ReadFile("/proc/self/auxv")
65+
if err != nil {
66+
// e.g. on android /proc/self/auxv is not accessible, so silently
67+
// ignore the error and leave Initialized = false. On some
68+
// architectures (e.g. arm64) doinit() implements a fallback
69+
// readout and will set Initialized = true again.
70+
return false
71+
}
72+
bo := binary.LittleEndian
73+
for len(buf) >= 2*(uintSize/8) {
74+
var tag, val uint
75+
switch uintSize {
76+
case 32:
77+
tag = uint(bo.Uint32(buf[0:]))
78+
val = uint(bo.Uint32(buf[4:]))
79+
buf = buf[8:]
80+
case 64:
81+
tag = uint(bo.Uint64(buf[0:]))
82+
val = uint(bo.Uint64(buf[8:]))
83+
buf = buf[16:]
84+
}
85+
switch tag {
86+
case _AT_HWCAP:
87+
hwcap = val
88+
case _AT_HWCAP2:
89+
// Not used
90+
}
91+
}
92+
if hwcap == 0 {
93+
return false
94+
}
4895
}
96+
4997
// HWCap was populated by the runtime from the auxiliary vector.
5098
// Use HWCap information since reading aarch64 system registers
5199
// is not supported in user space on older linux kernels.

0 commit comments

Comments
 (0)