Selaa lähdekoodia

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 <mike.munday@ibm.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Tobias Klauser <tobias.klauser@gmail.com>
Michael Munday 6 vuotta sitten
vanhempi
commit
d0b11bdaac
2 muutettua tiedostoa jossa 39 lisäystä ja 15 poistoa
  1. 30 0
      cpu/byteorder.go
  2. 9 15
      cpu/cpu_linux.go

+ 30 - 0
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")
+}

+ 9 - 15
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: