From d0b11bdaac8adb652bff00e49bcacf992835621a Mon Sep 17 00:00:00 2001 From: Michael Munday Date: Fri, 15 Feb 2019 08:44:14 -0500 Subject: [PATCH] cpu: fix auxval parsing on big-endian systems The words in auxval are encoded in native byte order. I haven't added a test. This fix will be tested when s390x support is added to the package. Change-Id: I276f833660e6906c319995798faf9054ffc69461 Reviewed-on: https://go-review.googlesource.com/c/162902 Run-TryBot: Michael Munday TryBot-Result: Gobot Gobot Reviewed-by: Tobias Klauser --- cpu/byteorder.go | 30 ++++++++++++++++++++++++++++++ cpu/cpu_linux.go | 24 +++++++++--------------- 2 files changed, 39 insertions(+), 15 deletions(-) create mode 100644 cpu/byteorder.go diff --git a/cpu/byteorder.go b/cpu/byteorder.go new file mode 100644 index 00000000..da6b9e43 --- /dev/null +++ b/cpu/byteorder.go @@ -0,0 +1,30 @@ +// Copyright 2019 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 + +import ( + "encoding/binary" + "runtime" +) + +// hostByteOrder returns binary.LittleEndian on little-endian machines and +// binary.BigEndian on big-endian machines. +func hostByteOrder() binary.ByteOrder { + switch runtime.GOARCH { + case "386", "amd64", "amd64p32", + "arm", "arm64", + "mipsle", "mips64le", "mips64p32le", + "ppc64le", + "riscv", "riscv64": + return binary.LittleEndian + case "armbe", "arm64be", + "mips", "mips64", "mips64p32", + "ppc", "ppc64", + "s390", "s390x", + "sparc", "sparc64": + return binary.BigEndian + } + panic("unknown architecture") +} diff --git a/cpu/cpu_linux.go b/cpu/cpu_linux.go index a8452e09..5ed69644 100644 --- a/cpu/cpu_linux.go +++ b/cpu/cpu_linux.go @@ -7,9 +7,7 @@ package cpu import ( - "encoding/binary" "io/ioutil" - "runtime" ) const ( @@ -18,7 +16,7 @@ const ( procAuxv = "/proc/self/auxv" - uintSize uint = 32 << (^uint(0) >> 63) + uintSize = int(32 << (^uint(0) >> 63)) ) // For those platforms don't have a 'cpuid' equivalent we use HWCAP/HWCAP2 @@ -33,22 +31,18 @@ func init() { panic("read proc auxv failed: " + err.Error()) } - pb := int(uintSize / 8) - - for i := 0; i < len(buf)-pb*2; i += pb * 2 { + bo := hostByteOrder() + for len(buf) >= 2*(uintSize/8) { var tag, val uint switch uintSize { case 32: - tag = uint(binary.LittleEndian.Uint32(buf[i:])) - val = uint(binary.LittleEndian.Uint32(buf[i+pb:])) + tag = uint(bo.Uint32(buf[0:])) + val = uint(bo.Uint32(buf[4:])) + buf = buf[8:] case 64: - if runtime.GOARCH == "ppc64" { - tag = uint(binary.BigEndian.Uint64(buf[i:])) - val = uint(binary.BigEndian.Uint64(buf[i+pb:])) - } else { - tag = uint(binary.LittleEndian.Uint64(buf[i:])) - val = uint(binary.LittleEndian.Uint64(buf[i+pb:])) - } + tag = uint(bo.Uint64(buf[0:])) + val = uint(bo.Uint64(buf[8:])) + buf = buf[16:] } switch tag { case _AT_HWCAP: