Commit 6f287fa2 authored by Austin Clements's avatar Austin Clements

runtime: fall back to /proc/self/auxv in Android libs

Android's libc doesn't provide access to auxv, so currently the Go
runtime synthesizes a fake, minimal auxv when loaded as a library on
Android. This used to be sufficient, but now we depend on auxv to
retrieve the system physical page size and panic if we can't retrieve
it.

Fix this by falling back to reading auxv from /proc/self/auxv if the
loader-provided auxv is empty and removing the synthetic auxv vectors.

Fixes #18041.

Change-Id: Ia2ec2c764a6609331494a5d359032c56cbb83482
Reviewed-on: https://go-review.googlesource.com/33652
Run-TryBot: Austin Clements <austin@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: 's avatarDavid Crawshaw <crawshaw@golang.org>
parent d39b7b53
...@@ -187,6 +187,8 @@ const ( ...@@ -187,6 +187,8 @@ const (
_AT_HWCAP2 = 26 // hardware capability bit vector 2 _AT_HWCAP2 = 26 // hardware capability bit vector 2
) )
var procAuxv = []byte("/proc/self/auxv\x00")
func sysargs(argc int32, argv **byte) { func sysargs(argc int32, argv **byte) {
n := argc + 1 n := argc + 1
...@@ -200,11 +202,30 @@ func sysargs(argc int32, argv **byte) { ...@@ -200,11 +202,30 @@ func sysargs(argc int32, argv **byte) {
// now argv+n is auxv // now argv+n is auxv
auxv := (*[1 << 28]uintptr)(add(unsafe.Pointer(argv), uintptr(n)*sys.PtrSize)) auxv := (*[1 << 28]uintptr)(add(unsafe.Pointer(argv), uintptr(n)*sys.PtrSize))
sysauxv(auxv[:]) if sysauxv(auxv[:]) == 0 {
// In some situations we don't get a loader-provided
// auxv, such as when loaded as a library on Android.
// Fall back to /proc/self/auxv.
fd := open(&procAuxv[0], 0 /* O_RDONLY */, 0)
if fd < 0 {
return
}
var buf [128]uintptr
n := read(fd, noescape(unsafe.Pointer(&buf[0])), int32(unsafe.Sizeof(buf)))
closefd(fd)
if n < 0 {
return
}
// Make sure buf is terminated, even if we didn't read
// the whole file.
buf[len(buf)-2] = _AT_NULL
sysauxv(buf[:])
}
} }
func sysauxv(auxv []uintptr) { func sysauxv(auxv []uintptr) int {
for i := 0; auxv[i] != _AT_NULL; i += 2 { var i int
for ; auxv[i] != _AT_NULL; i += 2 {
tag, val := auxv[i], auxv[i+1] tag, val := auxv[i], auxv[i+1]
switch tag { switch tag {
case _AT_RANDOM: case _AT_RANDOM:
...@@ -218,6 +239,7 @@ func sysauxv(auxv []uintptr) { ...@@ -218,6 +239,7 @@ func sysauxv(auxv []uintptr) {
archauxv(tag, val) archauxv(tag, val)
} }
return i / 2
} }
func osinit() { func osinit() {
......
...@@ -17,17 +17,10 @@ TEXT _rt0_amd64_android_lib(SB),NOSPLIT,$0 ...@@ -17,17 +17,10 @@ TEXT _rt0_amd64_android_lib(SB),NOSPLIT,$0
JMP AX JMP AX
DATA _rt0_amd64_android_argv+0x00(SB)/8,$_rt0_amd64_android_argv0(SB) DATA _rt0_amd64_android_argv+0x00(SB)/8,$_rt0_amd64_android_argv0(SB)
DATA _rt0_amd64_android_argv+0x08(SB)/8,$0 DATA _rt0_amd64_android_argv+0x08(SB)/8,$0 // end argv
DATA _rt0_amd64_android_argv+0x10(SB)/8,$0 DATA _rt0_amd64_android_argv+0x10(SB)/8,$0 // end envv
DATA _rt0_amd64_android_argv+0x18(SB)/8,$15 // AT_PLATFORM DATA _rt0_amd64_android_argv+0x18(SB)/8,$0 // end auxv
DATA _rt0_amd64_android_argv+0x20(SB)/8,$_rt0_amd64_android_auxv0(SB) GLOBL _rt0_amd64_android_argv(SB),NOPTR,$0x20
DATA _rt0_amd64_android_argv+0x28(SB)/8,$0
GLOBL _rt0_amd64_android_argv(SB),NOPTR,$0x30
// TODO: AT_HWCAP necessary? If so, what value?
DATA _rt0_amd64_android_argv0(SB)/8, $"gojni" DATA _rt0_amd64_android_argv0(SB)/8, $"gojni"
GLOBL _rt0_amd64_android_argv0(SB),RODATA,$8 GLOBL _rt0_amd64_android_argv0(SB),RODATA,$8
DATA _rt0_amd64_android_auxv0(SB)/8, $"x86_64"
GLOBL _rt0_amd64_android_auxv0(SB),RODATA,$8
...@@ -19,17 +19,10 @@ TEXT _rt0_arm_android_lib(SB),NOSPLIT,$0 ...@@ -19,17 +19,10 @@ TEXT _rt0_arm_android_lib(SB),NOSPLIT,$0
RET RET
DATA _rt0_arm_android_argv+0x00(SB)/4,$_rt0_arm_android_argv0(SB) DATA _rt0_arm_android_argv+0x00(SB)/4,$_rt0_arm_android_argv0(SB)
DATA _rt0_arm_android_argv+0x04(SB)/4,$0 DATA _rt0_arm_android_argv+0x04(SB)/4,$0 // end argv
DATA _rt0_arm_android_argv+0x08(SB)/4,$0 DATA _rt0_arm_android_argv+0x08(SB)/4,$0 // end envv
DATA _rt0_arm_android_argv+0x0C(SB)/4,$15 // AT_PLATFORM DATA _rt0_arm_android_argv+0x0c(SB)/4,$0 // end auxv
DATA _rt0_arm_android_argv+0x10(SB)/4,$_rt0_arm_android_auxv0(SB) GLOBL _rt0_arm_android_argv(SB),NOPTR,$0x10
DATA _rt0_arm_android_argv+0x14(SB)/4,$16 // AT_HWCAP
DATA _rt0_arm_android_argv+0x18(SB)/4,$0x2040 // HWCAP_VFP | HWCAP_VFPv3
DATA _rt0_arm_android_argv+0x1C(SB)/4,$0
GLOBL _rt0_arm_android_argv(SB),NOPTR,$0x20
DATA _rt0_arm_android_argv0(SB)/8, $"gojni" DATA _rt0_arm_android_argv0(SB)/8, $"gojni"
GLOBL _rt0_arm_android_argv0(SB),RODATA,$8 GLOBL _rt0_arm_android_argv0(SB),RODATA,$8
DATA _rt0_arm_android_auxv0(SB)/4, $"v7l"
GLOBL _rt0_arm_android_auxv0(SB),RODATA,$4
...@@ -17,9 +17,10 @@ TEXT _rt0_arm64_android_lib(SB),NOSPLIT,$-8 ...@@ -17,9 +17,10 @@ TEXT _rt0_arm64_android_lib(SB),NOSPLIT,$-8
B (R4) B (R4)
DATA _rt0_arm64_android_argv+0x00(SB)/8,$_rt0_arm64_android_argv0(SB) DATA _rt0_arm64_android_argv+0x00(SB)/8,$_rt0_arm64_android_argv0(SB)
DATA _rt0_arm64_android_argv+0x08(SB)/8,$0 DATA _rt0_arm64_android_argv+0x08(SB)/8,$0 // end argv
DATA _rt0_arm64_android_argv+0x10(SB)/8,$0 DATA _rt0_arm64_android_argv+0x10(SB)/8,$0 // end envv
GLOBL _rt0_arm64_android_argv(SB),NOPTR,$0x18 DATA _rt0_arm64_android_argv+0x18(SB)/8,$0 // end auxv
GLOBL _rt0_arm64_android_argv(SB),NOPTR,$0x20
DATA _rt0_arm64_android_argv0(SB)/8, $"gojni" DATA _rt0_arm64_android_argv0(SB)/8, $"gojni"
GLOBL _rt0_arm64_android_argv0(SB),RODATA,$8 GLOBL _rt0_arm64_android_argv0(SB),RODATA,$8
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