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:
parent
26ecb42fb4
commit
c955bb2040
@ -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()
|
||||
}
|
||||
|
@ -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))[:]
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
10
src/runtime/os_linux_noauxv.go
Normal file
10
src/runtime/os_linux_noauxv.go
Normal 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) {
|
||||
}
|
@ -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))[:]
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user