]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: fall back to /proc/self/auxv in Android libs
authorAustin Clements <austin@google.com>
Mon, 28 Nov 2016 23:03:16 +0000 (18:03 -0500)
committerAustin Clements <austin@google.com>
Tue, 29 Nov 2016 15:27:53 +0000 (15:27 +0000)
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: David Crawshaw <crawshaw@golang.org>
src/runtime/os_linux.go
src/runtime/rt0_android_amd64.s
src/runtime/rt0_android_arm.s
src/runtime/rt0_android_arm64.s

index 67c62bc18e6e9eea9b80172979ce24fcc235c5aa..320c1281c28c24be771d6cb3e5c7efc2fbaaae57 100644 (file)
@@ -187,6 +187,8 @@ const (
        _AT_HWCAP2 = 26 // hardware capability bit vector 2
 )
 
+var procAuxv = []byte("/proc/self/auxv\x00")
+
 func sysargs(argc int32, argv **byte) {
        n := argc + 1
 
@@ -200,11 +202,30 @@ func sysargs(argc int32, argv **byte) {
 
        // now argv+n is auxv
        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) {
-       for i := 0; auxv[i] != _AT_NULL; i += 2 {
+func sysauxv(auxv []uintptr) int {
+       var i int
+       for ; auxv[i] != _AT_NULL; i += 2 {
                tag, val := auxv[i], auxv[i+1]
                switch tag {
                case _AT_RANDOM:
@@ -218,6 +239,7 @@ func sysauxv(auxv []uintptr) {
 
                archauxv(tag, val)
        }
+       return i / 2
 }
 
 func osinit() {
index 9af6cab16f62174deaf1f1b4a7416338d40be0b2..6420c9f35d547e6c343a08e23975bdd5a294ffc1 100644 (file)
@@ -17,17 +17,10 @@ TEXT _rt0_amd64_android_lib(SB),NOSPLIT,$0
        JMP     AX
 
 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+0x10(SB)/8,$0
-DATA _rt0_amd64_android_argv+0x18(SB)/8,$15  // AT_PLATFORM
-DATA _rt0_amd64_android_argv+0x20(SB)/8,$_rt0_amd64_android_auxv0(SB)
-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_argv+0x08(SB)/8,$0 // end argv
+DATA _rt0_amd64_android_argv+0x10(SB)/8,$0 // end envv
+DATA _rt0_amd64_android_argv+0x18(SB)/8,$0 // end auxv
+GLOBL _rt0_amd64_android_argv(SB),NOPTR,$0x20
 
 DATA _rt0_amd64_android_argv0(SB)/8, $"gojni"
 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
index 85712531d2138b8082a9d60834e68904be9abb6e..189e290e354fa3943eb1eb9618ab1e31c1f2e077 100644 (file)
@@ -19,17 +19,10 @@ TEXT _rt0_arm_android_lib(SB),NOSPLIT,$0
        RET
 
 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+0x08(SB)/4,$0
-DATA _rt0_arm_android_argv+0x0C(SB)/4,$15      // AT_PLATFORM
-DATA _rt0_arm_android_argv+0x10(SB)/4,$_rt0_arm_android_auxv0(SB)
-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_argv+0x04(SB)/4,$0 // end argv
+DATA _rt0_arm_android_argv+0x08(SB)/4,$0 // end envv
+DATA _rt0_arm_android_argv+0x0c(SB)/4,$0 // end auxv
+GLOBL _rt0_arm_android_argv(SB),NOPTR,$0x10
 
 DATA _rt0_arm_android_argv0(SB)/8, $"gojni"
 GLOBL _rt0_arm_android_argv0(SB),RODATA,$8
-
-DATA _rt0_arm_android_auxv0(SB)/4, $"v7l"
-GLOBL _rt0_arm_android_auxv0(SB),RODATA,$4
index 582fc5a28c4725e9dc8b13414f188a021da7ca98..9378213daca4b7a412bd3e247d305b57aabdde34 100644 (file)
@@ -17,9 +17,10 @@ TEXT _rt0_arm64_android_lib(SB),NOSPLIT,$-8
        B       (R4)
 
 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+0x10(SB)/8,$0
-GLOBL _rt0_arm64_android_argv(SB),NOPTR,$0x18
+DATA _rt0_arm64_android_argv+0x08(SB)/8,$0 // end argv
+DATA _rt0_arm64_android_argv+0x10(SB)/8,$0 // end envv
+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"
 GLOBL _rt0_arm64_android_argv0(SB),RODATA,$8