1
0
mirror of https://github.com/golang/go synced 2024-11-19 14:54:43 -07:00

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>
This commit is contained in:
Austin Clements 2016-04-14 12:12:45 -04:00
parent 26ecb42fb4
commit c955bb2040
7 changed files with 80 additions and 112 deletions

View File

@ -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()
}

View File

@ -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))[:]
}
}

View File

@ -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))
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
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
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)
}
}

View File

@ -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
}
}

View File

@ -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) {
}

View File

@ -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))[:]
}
}

View File

@ -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