Commit c955bb20 authored by Austin Clements's avatar Austin Clements

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: default avatarBrad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarMichael Hudson-Doyle <michael.hudson@canonical.com>
parent 26ecb42f
...@@ -176,6 +176,29 @@ func newosproc0(stacksize uintptr, fn unsafe.Pointer) { ...@@ -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 failallocatestack = []byte("runtime: failed to allocate stack for the new OS thread\n")
var failthreadcreate = []byte("runtime: failed to create 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() { func osinit() {
ncpu = getproccount() ncpu = getproccount()
} }
......
...@@ -4,30 +4,16 @@ ...@@ -4,30 +4,16 @@
package runtime package runtime
import ( import "unsafe"
"runtime/internal/sys"
"unsafe"
)
const ( const (
_AT_NULL = 0
_AT_RANDOM = 25 _AT_RANDOM = 25
_AT_SYSINFO = 32 _AT_SYSINFO = 32
) )
func sysargs(argc int32, argv **byte) { func archauxv(tag, val uintptr) {
// skip over argv, envv to get to auxv switch tag {
n := argc + 1 case _AT_RANDOM:
for argv_index(argv, n) != nil { startupRandomData = (*[16]byte)(unsafe.Pointer(val))[:]
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])))[:]
}
} }
} }
...@@ -4,13 +4,9 @@ ...@@ -4,13 +4,9 @@
package runtime package runtime
import ( import "unsafe"
"runtime/internal/sys"
"unsafe"
)
const ( const (
_AT_NULL = 0
_AT_PLATFORM = 15 // introduced in at least 2.6.11 _AT_PLATFORM = 15 // introduced in at least 2.6.11
_AT_HWCAP = 16 // 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 _AT_RANDOM = 25 // introduced in 2.6.29
...@@ -36,33 +32,23 @@ func checkgoarm() { ...@@ -36,33 +32,23 @@ func checkgoarm() {
} }
} }
func sysargs(argc int32, argv **byte) { func archauxv(tag, val uintptr) {
// skip over argv, envv to get to auxv switch tag {
n := argc + 1 case _AT_RANDOM: // kernel provides a pointer to 16-bytes worth of random data
for argv_index(argv, n) != nil { startupRandomData = (*[16]byte)(unsafe.Pointer(val))[:]
n++ // the pointer provided may not be word aligned, so we must treat it
} // as a byte array.
n++ randomNumber = uint32(startupRandomData[4]) | uint32(startupRandomData[5])<<8 |
auxv := (*[1 << 28]uint32)(add(unsafe.Pointer(argv), uintptr(n)*sys.PtrSize)) uint32(startupRandomData[6])<<16 | uint32(startupRandomData[7])<<24
for i := 0; auxv[i] != _AT_NULL; i += 2 { case _AT_PLATFORM: // v5l, v6l, v7l
switch auxv[i] { t := *(*uint8)(unsafe.Pointer(val + 1))
case _AT_RANDOM: // kernel provides a pointer to 16-bytes worth of random data if '5' <= t && t <= '7' {
startupRandomData = (*[16]byte)(unsafe.Pointer(uintptr(auxv[i+1])))[:] armArch = t - '0'
// 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_HWCAP: // CPU capability bit flags
hwcap = uint32(val)
} }
} }
......
...@@ -4,36 +4,22 @@ ...@@ -4,36 +4,22 @@
package runtime package runtime
import ( import "unsafe"
"runtime/internal/sys"
"unsafe"
)
const ( const (
_AT_NULL = 0
_AT_RANDOM = 25 // introduced in 2.6.29 _AT_RANDOM = 25 // introduced in 2.6.29
) )
var randomNumber uint32 var randomNumber uint32
func sysargs(argc int32, argv **byte) { func archauxv(tag, val uintptr) {
// skip over argv, envv to get to auxv switch tag {
n := argc + 1 case _AT_RANDOM: // kernel provides a pointer to 16-bytes worth of random data
for argv_index(argv, n) != nil { startupRandomData = (*[16]byte)(unsafe.Pointer(val))[:]
n++ // the pointer provided may not be word aligned, so we must treat it
} // as a byte array.
n++ randomNumber = uint32(startupRandomData[4]) | uint32(startupRandomData[5])<<8 |
auxv := (*[1 << 29]uint64)(add(unsafe.Pointer(argv), uintptr(n)*sys.PtrSize)) uint32(startupRandomData[6])<<16 | uint32(startupRandomData[7])<<24
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
}
} }
} }
......
// 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) {
}
...@@ -4,10 +4,7 @@ ...@@ -4,10 +4,7 @@
package runtime package runtime
import ( import "unsafe"
"runtime/internal/sys"
"unsafe"
)
// Look up symbols in the Linux vDSO. // Look up symbols in the Linux vDSO.
...@@ -23,7 +20,6 @@ import ( ...@@ -23,7 +20,6 @@ import (
const ( const (
_AT_RANDOM = 25 _AT_RANDOM = 25
_AT_SYSINFO_EHDR = 33 _AT_SYSINFO_EHDR = 33
_AT_NULL = 0 /* End of vector */
_PT_LOAD = 1 /* Loadable program segment */ _PT_LOAD = 1 /* Loadable program segment */
_PT_DYNAMIC = 2 /* Dynamic linking information */ _PT_DYNAMIC = 2 /* Dynamic linking information */
...@@ -294,37 +290,21 @@ func vdso_parse_symbols(info *vdso_info, version int32) { ...@@ -294,37 +290,21 @@ func vdso_parse_symbols(info *vdso_info, version int32) {
} }
} }
func sysargs(argc int32, argv **byte) { func archauxv(tag, val uintptr) {
n := argc + 1 switch tag {
case _AT_SYSINFO_EHDR:
// skip envp to get to ELF auxiliary vector. if val == 0 {
for argv_index(argv, n) != nil { // Something went wrong
n++ return
}
// 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)))[:]
} }
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))[:]
} }
} }
...@@ -2,10 +2,7 @@ ...@@ -2,10 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// +build !linux !amd64 // +build !linux
// +build !linux !386
// +build !linux !arm
// +build !linux !arm64
package runtime package runtime
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment