aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAustin Clements <austin@google.com>2016-04-14 12:12:45 -0400
committerAustin Clements <austin@google.com>2016-04-16 21:42:27 +0000
commitc955bb2040e601c474e547b8badbe44677c9fbdf (patch)
treee5ef0398f9f19324560a1b23aa4ac03f4f12e284 /src
parent26ecb42fb4c5ee1d8b64f12e5bb8df6549523d23 (diff)
downloadgo-c955bb2040e601c474e547b8badbe44677c9fbdf.tar.xz
runtime: common auxv parser
Currently several different Linux architectures have separate copies of the auxv parser. Bring these all together into a single copy of the parser that calls out to a per-arch handler for each tag/value pair. This is in preparation for handling common auxv tags in one place. For #9993. Change-Id: Iceebc3afad6b4133b70fca7003561ae370445c10 Reviewed-on: https://go-review.googlesource.com/22061 Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Michael Hudson-Doyle <michael.hudson@canonical.com>
Diffstat (limited to 'src')
-rw-r--r--src/runtime/os_linux.go23
-rw-r--r--src/runtime/os_linux_386.go24
-rw-r--r--src/runtime/os_linux_arm.go46
-rw-r--r--src/runtime/os_linux_arm64.go32
-rw-r--r--src/runtime/os_linux_noauxv.go10
-rw-r--r--src/runtime/vdso_linux_amd64.go52
-rw-r--r--src/runtime/vdso_none.go5
7 files changed, 80 insertions, 112 deletions
diff --git a/src/runtime/os_linux.go b/src/runtime/os_linux.go
index 7d8cc7e5c4..eeb30c7dd9 100644
--- a/src/runtime/os_linux.go
+++ b/src/runtime/os_linux.go
@@ -176,6 +176,29 @@ func newosproc0(stacksize uintptr, fn unsafe.Pointer) {
var failallocatestack = []byte("runtime: failed to allocate stack for the new OS thread\n")
var failthreadcreate = []byte("runtime: failed to create new OS thread\n")
+const (
+ _AT_NULL = 0 // End of vector
+)
+
+func sysargs(argc int32, argv **byte) {
+ n := argc + 1
+
+ // skip over argv, envp to get to auxv
+ for argv_index(argv, n) != nil {
+ n++
+ }
+
+ // skip NULL separator
+ n++
+
+ // now argv+n is auxv
+ auxv := (*[1 << 28]uintptr)(add(unsafe.Pointer(argv), uintptr(n)*sys.PtrSize))
+ for i := 0; auxv[i] != _AT_NULL; i += 2 {
+ tag, val := auxv[i], auxv[i+1]
+ archauxv(tag, val)
+ }
+}
+
func osinit() {
ncpu = getproccount()
}
diff --git a/src/runtime/os_linux_386.go b/src/runtime/os_linux_386.go
index 0f39cade3b..2383d962b2 100644
--- a/src/runtime/os_linux_386.go
+++ b/src/runtime/os_linux_386.go
@@ -4,30 +4,16 @@
package runtime
-import (
- "runtime/internal/sys"
- "unsafe"
-)
+import "unsafe"
const (
- _AT_NULL = 0
_AT_RANDOM = 25
_AT_SYSINFO = 32
)
-func sysargs(argc int32, argv **byte) {
- // skip over argv, envv to get to auxv
- n := argc + 1
- for argv_index(argv, n) != nil {
- n++
- }
- n++
- auxv := (*[1 << 28]uint32)(add(unsafe.Pointer(argv), uintptr(n)*sys.PtrSize))
-
- for i := 0; auxv[i] != _AT_NULL; i += 2 {
- switch auxv[i] {
- case _AT_RANDOM:
- startupRandomData = (*[16]byte)(unsafe.Pointer(uintptr(auxv[i+1])))[:]
- }
+func archauxv(tag, val uintptr) {
+ switch tag {
+ case _AT_RANDOM:
+ startupRandomData = (*[16]byte)(unsafe.Pointer(val))[:]
}
}
diff --git a/src/runtime/os_linux_arm.go b/src/runtime/os_linux_arm.go
index 8fdfb585ba..a61be916b6 100644
--- a/src/runtime/os_linux_arm.go
+++ b/src/runtime/os_linux_arm.go
@@ -4,13 +4,9 @@
package runtime
-import (
- "runtime/internal/sys"
- "unsafe"
-)
+import "unsafe"
const (
- _AT_NULL = 0
_AT_PLATFORM = 15 // introduced in at least 2.6.11
_AT_HWCAP = 16 // introduced in at least 2.6.11
_AT_RANDOM = 25 // introduced in 2.6.29
@@ -36,33 +32,23 @@ func checkgoarm() {
}
}
-func sysargs(argc int32, argv **byte) {
- // skip over argv, envv to get to auxv
- n := argc + 1
- for argv_index(argv, n) != nil {
- n++
- }
- n++
- auxv := (*[1 << 28]uint32)(add(unsafe.Pointer(argv), uintptr(n)*sys.PtrSize))
-
- for i := 0; auxv[i] != _AT_NULL; i += 2 {
- switch auxv[i] {
- case _AT_RANDOM: // kernel provides a pointer to 16-bytes worth of random data
- startupRandomData = (*[16]byte)(unsafe.Pointer(uintptr(auxv[i+1])))[:]
- // the pointer provided may not be word aligned, so we must treat it
- // as a byte array.
- randomNumber = uint32(startupRandomData[4]) | uint32(startupRandomData[5])<<8 |
- uint32(startupRandomData[6])<<16 | uint32(startupRandomData[7])<<24
+func archauxv(tag, val uintptr) {
+ switch tag {
+ case _AT_RANDOM: // kernel provides a pointer to 16-bytes worth of random data
+ startupRandomData = (*[16]byte)(unsafe.Pointer(val))[:]
+ // the pointer provided may not be word aligned, so we must treat it
+ // as a byte array.
+ randomNumber = uint32(startupRandomData[4]) | uint32(startupRandomData[5])<<8 |
+ uint32(startupRandomData[6])<<16 | uint32(startupRandomData[7])<<24
- case _AT_PLATFORM: // v5l, v6l, v7l
- t := *(*uint8)(unsafe.Pointer(uintptr(auxv[i+1] + 1)))
- if '5' <= t && t <= '7' {
- armArch = t - '0'
- }
-
- case _AT_HWCAP: // CPU capability bit flags
- hwcap = auxv[i+1]
+ case _AT_PLATFORM: // v5l, v6l, v7l
+ t := *(*uint8)(unsafe.Pointer(val + 1))
+ if '5' <= t && t <= '7' {
+ armArch = t - '0'
}
+
+ case _AT_HWCAP: // CPU capability bit flags
+ hwcap = uint32(val)
}
}
diff --git a/src/runtime/os_linux_arm64.go b/src/runtime/os_linux_arm64.go
index 57184b0d3a..aa9d4d9885 100644
--- a/src/runtime/os_linux_arm64.go
+++ b/src/runtime/os_linux_arm64.go
@@ -4,36 +4,22 @@
package runtime
-import (
- "runtime/internal/sys"
- "unsafe"
-)
+import "unsafe"
const (
- _AT_NULL = 0
_AT_RANDOM = 25 // introduced in 2.6.29
)
var randomNumber uint32
-func sysargs(argc int32, argv **byte) {
- // skip over argv, envv to get to auxv
- n := argc + 1
- for argv_index(argv, n) != nil {
- n++
- }
- n++
- auxv := (*[1 << 29]uint64)(add(unsafe.Pointer(argv), uintptr(n)*sys.PtrSize))
-
- for i := 0; auxv[i] != _AT_NULL; i += 2 {
- switch auxv[i] {
- case _AT_RANDOM: // kernel provides a pointer to 16-bytes worth of random data
- startupRandomData = (*[16]byte)(unsafe.Pointer(uintptr(auxv[i+1])))[:]
- // the pointer provided may not be word aligned, so we must treat it
- // as a byte array.
- randomNumber = uint32(startupRandomData[4]) | uint32(startupRandomData[5])<<8 |
- uint32(startupRandomData[6])<<16 | uint32(startupRandomData[7])<<24
- }
+func archauxv(tag, val uintptr) {
+ switch tag {
+ case _AT_RANDOM: // kernel provides a pointer to 16-bytes worth of random data
+ startupRandomData = (*[16]byte)(unsafe.Pointer(val))[:]
+ // the pointer provided may not be word aligned, so we must treat it
+ // as a byte array.
+ randomNumber = uint32(startupRandomData[4]) | uint32(startupRandomData[5])<<8 |
+ uint32(startupRandomData[6])<<16 | uint32(startupRandomData[7])<<24
}
}
diff --git a/src/runtime/os_linux_noauxv.go b/src/runtime/os_linux_noauxv.go
new file mode 100644
index 0000000000..d26c85bbb6
--- /dev/null
+++ b/src/runtime/os_linux_noauxv.go
@@ -0,0 +1,10 @@
+// Copyright 2014 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.
+
+// +build !386,!amd64,!arm,!arm64
+
+package runtime
+
+func archauxv(tag, val uintptr) {
+}
diff --git a/src/runtime/vdso_linux_amd64.go b/src/runtime/vdso_linux_amd64.go
index 42571e063c..1aae9b6570 100644
--- a/src/runtime/vdso_linux_amd64.go
+++ b/src/runtime/vdso_linux_amd64.go
@@ -4,10 +4,7 @@
package runtime
-import (
- "runtime/internal/sys"
- "unsafe"
-)
+import "unsafe"
// Look up symbols in the Linux vDSO.
@@ -23,7 +20,6 @@ import (
const (
_AT_RANDOM = 25
_AT_SYSINFO_EHDR = 33
- _AT_NULL = 0 /* End of vector */
_PT_LOAD = 1 /* Loadable program segment */
_PT_DYNAMIC = 2 /* Dynamic linking information */
@@ -294,37 +290,21 @@ func vdso_parse_symbols(info *vdso_info, version int32) {
}
}
-func sysargs(argc int32, argv **byte) {
- n := argc + 1
-
- // skip envp to get to ELF auxiliary vector.
- for argv_index(argv, n) != nil {
- n++
- }
-
- // skip NULL separator
- n++
-
- // now argv+n is auxv
- auxv := (*[1 << 32]elf64Auxv)(add(unsafe.Pointer(argv), uintptr(n)*sys.PtrSize))
-
- for i := 0; auxv[i].a_type != _AT_NULL; i++ {
- av := &auxv[i]
- switch av.a_type {
- case _AT_SYSINFO_EHDR:
- if av.a_val == 0 {
- // Something went wrong
- continue
- }
- var info vdso_info
- // TODO(rsc): I don't understand why the compiler thinks info escapes
- // when passed to the three functions below.
- info1 := (*vdso_info)(noescape(unsafe.Pointer(&info)))
- vdso_init_from_sysinfo_ehdr(info1, (*elf64Ehdr)(unsafe.Pointer(uintptr(av.a_val))))
- vdso_parse_symbols(info1, vdso_find_version(info1, &linux26))
-
- case _AT_RANDOM:
- startupRandomData = (*[16]byte)(unsafe.Pointer(uintptr(av.a_val)))[:]
+func archauxv(tag, val uintptr) {
+ switch tag {
+ case _AT_SYSINFO_EHDR:
+ if val == 0 {
+ // Something went wrong
+ return
}
+ var info vdso_info
+ // TODO(rsc): I don't understand why the compiler thinks info escapes
+ // when passed to the three functions below.
+ info1 := (*vdso_info)(noescape(unsafe.Pointer(&info)))
+ vdso_init_from_sysinfo_ehdr(info1, (*elf64Ehdr)(unsafe.Pointer(val)))
+ vdso_parse_symbols(info1, vdso_find_version(info1, &linux26))
+
+ case _AT_RANDOM:
+ startupRandomData = (*[16]byte)(unsafe.Pointer(val))[:]
}
}
diff --git a/src/runtime/vdso_none.go b/src/runtime/vdso_none.go
index e14e1a4707..efae23f6ee 100644
--- a/src/runtime/vdso_none.go
+++ b/src/runtime/vdso_none.go
@@ -2,10 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build !linux !amd64
-// +build !linux !386
-// +build !linux !arm
-// +build !linux !arm64
+// +build !linux
package runtime