mirror of https://github.com/golang/go.git
runtime, syscall: use int $0x80 to invoke syscalls on android/386
golang.org/cl/16796 broke android/386 by assuming behaviour specific to glibc's dynamic linker. Copy bionic by using int $0x80 to invoke syscalls on android/386 as the old alternative (CALL *runtime_vdso(SB)) cannot be compiled without text relocations, which we want to get rid of on android. Also remove "CALL *runtime_vdso(SB)" variant from the syscall package. Change-Id: I6c01849f8dcbd073d000ddc8f13948a836b8b261 Reviewed-on: https://go-review.googlesource.com/16996 TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: David Crawshaw <crawshaw@golang.org> Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
This commit is contained in:
parent
f4a9bd87ba
commit
90e26f52c6
|
|
@ -10,17 +10,30 @@
|
|||
#include "go_tls.h"
|
||||
#include "textflag.h"
|
||||
|
||||
// Most linux systems use glibc's dynamic linker, which puts the
|
||||
// __kernel_vsyscall vdso helper at 0x10(GS) for easy access from position
|
||||
// independent code and setldt in this file does the same in the statically
|
||||
// linked case. Android, however, uses bionic's dynamic linker, which does not
|
||||
// save the helper anywhere, and so the only way to invoke a syscall from
|
||||
// position independent code is boring old int $0x80 (which is also what
|
||||
// bionic's syscall wrappers use).
|
||||
#ifdef GOOS_android
|
||||
#define INVOKE_SYSCALL INT $0x80
|
||||
#else
|
||||
#define INVOKE_SYSCALL CALL 0x10(GS)
|
||||
#endif
|
||||
|
||||
TEXT runtime·exit(SB),NOSPLIT,$0
|
||||
MOVL $252, AX // syscall number
|
||||
MOVL code+0(FP), BX
|
||||
CALL 0x10(GS)
|
||||
INVOKE_SYSCALL
|
||||
INT $3 // not reached
|
||||
RET
|
||||
|
||||
TEXT runtime·exit1(SB),NOSPLIT,$0
|
||||
MOVL $1, AX // exit - exit the current os thread
|
||||
MOVL code+0(FP), BX
|
||||
CALL 0x10(GS)
|
||||
INVOKE_SYSCALL
|
||||
INT $3 // not reached
|
||||
RET
|
||||
|
||||
|
|
@ -29,7 +42,7 @@ TEXT runtime·open(SB),NOSPLIT,$0
|
|||
MOVL name+0(FP), BX
|
||||
MOVL mode+4(FP), CX
|
||||
MOVL perm+8(FP), DX
|
||||
CALL 0x10(GS)
|
||||
INVOKE_SYSCALL
|
||||
CMPL AX, $0xfffff001
|
||||
JLS 2(PC)
|
||||
MOVL $-1, AX
|
||||
|
|
@ -39,7 +52,7 @@ TEXT runtime·open(SB),NOSPLIT,$0
|
|||
TEXT runtime·closefd(SB),NOSPLIT,$0
|
||||
MOVL $6, AX // syscall - close
|
||||
MOVL fd+0(FP), BX
|
||||
CALL 0x10(GS)
|
||||
INVOKE_SYSCALL
|
||||
CMPL AX, $0xfffff001
|
||||
JLS 2(PC)
|
||||
MOVL $-1, AX
|
||||
|
|
@ -51,7 +64,7 @@ TEXT runtime·write(SB),NOSPLIT,$0
|
|||
MOVL fd+0(FP), BX
|
||||
MOVL p+4(FP), CX
|
||||
MOVL n+8(FP), DX
|
||||
CALL 0x10(GS)
|
||||
INVOKE_SYSCALL
|
||||
CMPL AX, $0xfffff001
|
||||
JLS 2(PC)
|
||||
MOVL $-1, AX
|
||||
|
|
@ -63,7 +76,7 @@ TEXT runtime·read(SB),NOSPLIT,$0
|
|||
MOVL fd+0(FP), BX
|
||||
MOVL p+4(FP), CX
|
||||
MOVL n+8(FP), DX
|
||||
CALL 0x10(GS)
|
||||
INVOKE_SYSCALL
|
||||
CMPL AX, $0xfffff001
|
||||
JLS 2(PC)
|
||||
MOVL $-1, AX
|
||||
|
|
@ -74,7 +87,7 @@ TEXT runtime·getrlimit(SB),NOSPLIT,$0
|
|||
MOVL $191, AX // syscall - ugetrlimit
|
||||
MOVL kind+0(FP), BX
|
||||
MOVL limit+4(FP), CX
|
||||
CALL 0x10(GS)
|
||||
INVOKE_SYSCALL
|
||||
MOVL AX, ret+8(FP)
|
||||
RET
|
||||
|
||||
|
|
@ -93,31 +106,31 @@ TEXT runtime·usleep(SB),NOSPLIT,$8
|
|||
MOVL $0, DX
|
||||
MOVL $0, SI
|
||||
LEAL 0(SP), DI
|
||||
CALL 0x10(GS)
|
||||
INVOKE_SYSCALL
|
||||
RET
|
||||
|
||||
TEXT runtime·gettid(SB),NOSPLIT,$0-4
|
||||
MOVL $224, AX // syscall - gettid
|
||||
CALL 0x10(GS)
|
||||
INVOKE_SYSCALL
|
||||
MOVL AX, ret+0(FP)
|
||||
RET
|
||||
|
||||
TEXT runtime·raise(SB),NOSPLIT,$12
|
||||
MOVL $224, AX // syscall - gettid
|
||||
CALL 0x10(GS)
|
||||
INVOKE_SYSCALL
|
||||
MOVL AX, BX // arg 1 tid
|
||||
MOVL sig+0(FP), CX // arg 2 signal
|
||||
MOVL $238, AX // syscall - tkill
|
||||
CALL 0x10(GS)
|
||||
INVOKE_SYSCALL
|
||||
RET
|
||||
|
||||
TEXT runtime·raiseproc(SB),NOSPLIT,$12
|
||||
MOVL $20, AX // syscall - getpid
|
||||
CALL 0x10(GS)
|
||||
INVOKE_SYSCALL
|
||||
MOVL AX, BX // arg 1 pid
|
||||
MOVL sig+0(FP), CX // arg 2 signal
|
||||
MOVL $37, AX // syscall - kill
|
||||
CALL 0x10(GS)
|
||||
INVOKE_SYSCALL
|
||||
RET
|
||||
|
||||
TEXT runtime·setitimer(SB),NOSPLIT,$0-12
|
||||
|
|
@ -125,7 +138,7 @@ TEXT runtime·setitimer(SB),NOSPLIT,$0-12
|
|||
MOVL mode+0(FP), BX
|
||||
MOVL new+4(FP), CX
|
||||
MOVL old+8(FP), DX
|
||||
CALL 0x10(GS)
|
||||
INVOKE_SYSCALL
|
||||
RET
|
||||
|
||||
TEXT runtime·mincore(SB),NOSPLIT,$0-16
|
||||
|
|
@ -133,7 +146,7 @@ TEXT runtime·mincore(SB),NOSPLIT,$0-16
|
|||
MOVL addr+0(FP), BX
|
||||
MOVL n+4(FP), CX
|
||||
MOVL dst+8(FP), DX
|
||||
CALL 0x10(GS)
|
||||
INVOKE_SYSCALL
|
||||
MOVL AX, ret+12(FP)
|
||||
RET
|
||||
|
||||
|
|
@ -143,7 +156,7 @@ TEXT time·now(SB), NOSPLIT, $32
|
|||
MOVL $0, BX // CLOCK_REALTIME
|
||||
LEAL 8(SP), CX
|
||||
MOVL $0, DX
|
||||
CALL 0x10(GS)
|
||||
INVOKE_SYSCALL
|
||||
MOVL 8(SP), AX // sec
|
||||
MOVL 12(SP), BX // nsec
|
||||
|
||||
|
|
@ -160,7 +173,7 @@ TEXT runtime·nanotime(SB), NOSPLIT, $32
|
|||
MOVL $1, BX // CLOCK_MONOTONIC
|
||||
LEAL 8(SP), CX
|
||||
MOVL $0, DX
|
||||
CALL 0x10(GS)
|
||||
INVOKE_SYSCALL
|
||||
MOVL 8(SP), AX // sec
|
||||
MOVL 12(SP), BX // nsec
|
||||
|
||||
|
|
@ -181,7 +194,7 @@ TEXT runtime·rtsigprocmask(SB),NOSPLIT,$0
|
|||
MOVL new+4(FP), CX
|
||||
MOVL old+8(FP), DX
|
||||
MOVL size+12(FP), SI
|
||||
CALL 0x10(GS)
|
||||
INVOKE_SYSCALL
|
||||
CMPL AX, $0xfffff001
|
||||
JLS 2(PC)
|
||||
INT $3
|
||||
|
|
@ -193,7 +206,7 @@ TEXT runtime·rt_sigaction(SB),NOSPLIT,$0
|
|||
MOVL new+4(FP), CX
|
||||
MOVL old+8(FP), DX
|
||||
MOVL size+12(FP), SI
|
||||
CALL 0x10(GS)
|
||||
INVOKE_SYSCALL
|
||||
MOVL AX, ret+16(FP)
|
||||
RET
|
||||
|
||||
|
|
@ -235,7 +248,7 @@ TEXT runtime·mmap(SB),NOSPLIT,$0
|
|||
MOVL fd+16(FP), DI
|
||||
MOVL off+20(FP), BP
|
||||
SHRL $12, BP
|
||||
CALL 0x10(GS)
|
||||
INVOKE_SYSCALL
|
||||
CMPL AX, $0xfffff001
|
||||
JLS 3(PC)
|
||||
NOTL AX
|
||||
|
|
@ -247,7 +260,7 @@ TEXT runtime·munmap(SB),NOSPLIT,$0
|
|||
MOVL $91, AX // munmap
|
||||
MOVL addr+0(FP), BX
|
||||
MOVL n+4(FP), CX
|
||||
CALL 0x10(GS)
|
||||
INVOKE_SYSCALL
|
||||
CMPL AX, $0xfffff001
|
||||
JLS 2(PC)
|
||||
INT $3
|
||||
|
|
@ -258,7 +271,7 @@ TEXT runtime·madvise(SB),NOSPLIT,$0
|
|||
MOVL addr+0(FP), BX
|
||||
MOVL n+4(FP), CX
|
||||
MOVL flags+8(FP), DX
|
||||
CALL 0x10(GS)
|
||||
INVOKE_SYSCALL
|
||||
// ignore failure - maybe pages are locked
|
||||
RET
|
||||
|
||||
|
|
@ -272,7 +285,7 @@ TEXT runtime·futex(SB),NOSPLIT,$0
|
|||
MOVL ts+12(FP), SI
|
||||
MOVL addr2+16(FP), DI
|
||||
MOVL val3+20(FP), BP
|
||||
CALL 0x10(GS)
|
||||
INVOKE_SYSCALL
|
||||
MOVL AX, ret+24(FP)
|
||||
RET
|
||||
|
||||
|
|
@ -313,7 +326,7 @@ TEXT runtime·clone(SB),NOSPLIT,$0
|
|||
|
||||
// Initialize AX to Linux tid
|
||||
MOVL $224, AX
|
||||
CALL 0x10(GS)
|
||||
INVOKE_SYSCALL
|
||||
|
||||
MOVL 0(SP), BX // m
|
||||
MOVL 4(SP), DX // g
|
||||
|
|
@ -364,7 +377,7 @@ TEXT runtime·sigaltstack(SB),NOSPLIT,$-8
|
|||
MOVL $186, AX // sigaltstack
|
||||
MOVL new+4(SP), BX
|
||||
MOVL old+8(SP), CX
|
||||
CALL 0x10(GS)
|
||||
INVOKE_SYSCALL
|
||||
CMPL AX, $0xfffff001
|
||||
JLS 2(PC)
|
||||
INT $3
|
||||
|
|
@ -421,13 +434,13 @@ TEXT runtime·setldt(SB),NOSPLIT,$32
|
|||
*/
|
||||
ADDL $0x4, CX // address
|
||||
MOVL CX, 0(CX)
|
||||
#endif
|
||||
// We copy the dynamic linker behaviour of storing the vsyscall entry point
|
||||
// at 0x10(GS) so that it can be invoked by "CALL 0x10(GS)" in all
|
||||
// situations, not only those where the binary is actually dynamically
|
||||
// linked.
|
||||
// We copy the glibc dynamic linker behaviour of storing the
|
||||
// __kernel_vsyscall entry point at 0x10(GS) so that it can be invoked
|
||||
// by "CALL 0x10(GS)" in all situations, not only those where the
|
||||
// binary is actually dynamically linked.
|
||||
MOVL runtime·_vdso(SB), AX
|
||||
MOVL AX, 0x10(CX)
|
||||
#endif
|
||||
|
||||
// set up user_desc
|
||||
LEAL 16(SP), AX // struct user_desc
|
||||
|
|
@ -459,7 +472,7 @@ TEXT runtime·setldt(SB),NOSPLIT,$32
|
|||
|
||||
TEXT runtime·osyield(SB),NOSPLIT,$0
|
||||
MOVL $158, AX
|
||||
CALL 0x10(GS)
|
||||
INVOKE_SYSCALL
|
||||
RET
|
||||
|
||||
TEXT runtime·sched_getaffinity(SB),NOSPLIT,$0
|
||||
|
|
@ -467,7 +480,7 @@ TEXT runtime·sched_getaffinity(SB),NOSPLIT,$0
|
|||
MOVL pid+0(FP), BX
|
||||
MOVL len+4(FP), CX
|
||||
MOVL buf+8(FP), DX
|
||||
CALL 0x10(GS)
|
||||
INVOKE_SYSCALL
|
||||
MOVL AX, ret+12(FP)
|
||||
RET
|
||||
|
||||
|
|
@ -475,7 +488,7 @@ TEXT runtime·sched_getaffinity(SB),NOSPLIT,$0
|
|||
TEXT runtime·epollcreate(SB),NOSPLIT,$0
|
||||
MOVL $254, AX
|
||||
MOVL size+0(FP), BX
|
||||
CALL 0x10(GS)
|
||||
INVOKE_SYSCALL
|
||||
MOVL AX, ret+4(FP)
|
||||
RET
|
||||
|
||||
|
|
@ -483,7 +496,7 @@ TEXT runtime·epollcreate(SB),NOSPLIT,$0
|
|||
TEXT runtime·epollcreate1(SB),NOSPLIT,$0
|
||||
MOVL $329, AX
|
||||
MOVL flags+0(FP), BX
|
||||
CALL 0x10(GS)
|
||||
INVOKE_SYSCALL
|
||||
MOVL AX, ret+4(FP)
|
||||
RET
|
||||
|
||||
|
|
@ -494,7 +507,7 @@ TEXT runtime·epollctl(SB),NOSPLIT,$0
|
|||
MOVL op+4(FP), CX
|
||||
MOVL fd+8(FP), DX
|
||||
MOVL ev+12(FP), SI
|
||||
CALL 0x10(GS)
|
||||
INVOKE_SYSCALL
|
||||
MOVL AX, ret+16(FP)
|
||||
RET
|
||||
|
||||
|
|
@ -505,7 +518,7 @@ TEXT runtime·epollwait(SB),NOSPLIT,$0
|
|||
MOVL ev+4(FP), CX
|
||||
MOVL nev+8(FP), DX
|
||||
MOVL timeout+12(FP), SI
|
||||
CALL 0x10(GS)
|
||||
INVOKE_SYSCALL
|
||||
MOVL AX, ret+16(FP)
|
||||
RET
|
||||
|
||||
|
|
@ -515,7 +528,7 @@ TEXT runtime·closeonexec(SB),NOSPLIT,$0
|
|||
MOVL fd+0(FP), BX // fd
|
||||
MOVL $2, CX // F_SETFD
|
||||
MOVL $1, DX // FD_CLOEXEC
|
||||
CALL 0x10(GS)
|
||||
INVOKE_SYSCALL
|
||||
RET
|
||||
|
||||
// int access(const char *name, int mode)
|
||||
|
|
@ -523,7 +536,7 @@ TEXT runtime·access(SB),NOSPLIT,$0
|
|||
MOVL $33, AX // syscall - access
|
||||
MOVL name+0(FP), BX
|
||||
MOVL mode+4(FP), CX
|
||||
CALL 0x10(GS)
|
||||
INVOKE_SYSCALL
|
||||
MOVL AX, ret+8(FP)
|
||||
RET
|
||||
|
||||
|
|
@ -534,7 +547,7 @@ TEXT runtime·connect(SB),NOSPLIT,$0-16
|
|||
MOVL $102, AX // syscall - socketcall
|
||||
MOVL $3, BX // connect
|
||||
LEAL fd+0(FP), CX
|
||||
CALL 0x10(GS)
|
||||
INVOKE_SYSCALL
|
||||
MOVL AX, ret+12(FP)
|
||||
RET
|
||||
|
||||
|
|
@ -545,6 +558,6 @@ TEXT runtime·socket(SB),NOSPLIT,$0-16
|
|||
MOVL $102, AX // syscall - socketcall
|
||||
MOVL $1, BX // socket
|
||||
LEAL domain+0(FP), CX
|
||||
CALL 0x10(GS)
|
||||
INVOKE_SYSCALL
|
||||
MOVL AX, ret+12(FP)
|
||||
RET
|
||||
|
|
|
|||
|
|
@ -12,6 +12,19 @@
|
|||
// func Syscall(trap uintptr, a1, a2, a3 uintptr) (r1, r2, err uintptr);
|
||||
// Trap # in AX, args in BX CX DX SI DI, return in AX
|
||||
|
||||
// Most linux systems use glibc's dynamic linker, which puts the
|
||||
// __kernel_vsyscall vdso helper at 0x10(GS) for easy access from position
|
||||
// independent code and setldt in runtime does the same in the statically
|
||||
// linked case. Android, however, uses bionic's dynamic linker, which does not
|
||||
// save the helper anywhere, and so the only way to invoke a syscall from
|
||||
// position independent code is boring old int $0x80 (which is also what
|
||||
// bionic's syscall wrappers use).
|
||||
#ifdef GOOS_android
|
||||
#define INVOKE_SYSCALL INT $0x80
|
||||
#else
|
||||
#define INVOKE_SYSCALL CALL 0x10(GS)
|
||||
#endif
|
||||
|
||||
TEXT ·Syscall(SB),NOSPLIT,$0-28
|
||||
CALL runtime·entersyscall(SB)
|
||||
MOVL trap+0(FP), AX // syscall entry
|
||||
|
|
@ -20,7 +33,7 @@ TEXT ·Syscall(SB),NOSPLIT,$0-28
|
|||
MOVL a3+12(FP), DX
|
||||
MOVL $0, SI
|
||||
MOVL $0, DI
|
||||
CALL *runtime·_vdso(SB)
|
||||
INVOKE_SYSCALL
|
||||
CMPL AX, $0xfffff001
|
||||
JLS ok
|
||||
MOVL $-1, r1+16(FP)
|
||||
|
|
@ -46,7 +59,7 @@ TEXT ·Syscall6(SB),NOSPLIT,$0-40
|
|||
MOVL a4+16(FP), SI
|
||||
MOVL a5+20(FP), DI
|
||||
MOVL a6+24(FP), BP
|
||||
CALL *runtime·_vdso(SB)
|
||||
INVOKE_SYSCALL
|
||||
CMPL AX, $0xfffff001
|
||||
JLS ok6
|
||||
MOVL $-1, r1+28(FP)
|
||||
|
|
@ -70,7 +83,7 @@ TEXT ·RawSyscall(SB),NOSPLIT,$0-28
|
|||
MOVL a3+12(FP), DX
|
||||
MOVL $0, SI
|
||||
MOVL $0, DI
|
||||
CALL *runtime·_vdso(SB)
|
||||
INVOKE_SYSCALL
|
||||
CMPL AX, $0xfffff001
|
||||
JLS ok1
|
||||
MOVL $-1, r1+16(FP)
|
||||
|
|
@ -93,7 +106,7 @@ TEXT ·RawSyscall6(SB),NOSPLIT,$0-40
|
|||
MOVL a4+16(FP), SI
|
||||
MOVL a5+20(FP), DI
|
||||
MOVL a6+24(FP), BP
|
||||
CALL *runtime·_vdso(SB)
|
||||
INVOKE_SYSCALL
|
||||
CMPL AX, $0xfffff001
|
||||
JLS ok2
|
||||
MOVL $-1, r1+28(FP)
|
||||
|
|
@ -119,7 +132,7 @@ TEXT ·socketcall(SB),NOSPLIT,$0-36
|
|||
MOVL $0, DX
|
||||
MOVL $0, SI
|
||||
MOVL $0, DI
|
||||
CALL *runtime·_vdso(SB)
|
||||
INVOKE_SYSCALL
|
||||
CMPL AX, $0xfffff001
|
||||
JLS oksock
|
||||
MOVL $-1, n+28(FP)
|
||||
|
|
@ -142,7 +155,7 @@ TEXT ·rawsocketcall(SB),NOSPLIT,$0-36
|
|||
MOVL $0, DX
|
||||
MOVL $0, SI
|
||||
MOVL $0, DI
|
||||
CALL *runtime·_vdso(SB)
|
||||
INVOKE_SYSCALL
|
||||
CMPL AX, $0xfffff001
|
||||
JLS oksock1
|
||||
MOVL $-1, n+28(FP)
|
||||
|
|
@ -168,7 +181,7 @@ TEXT ·seek(SB),NOSPLIT,$0-28
|
|||
MOVL offset_lo+4(FP), DX
|
||||
LEAL newoffset_lo+16(FP), SI // result pointer
|
||||
MOVL whence+12(FP), DI
|
||||
CALL *runtime·_vdso(SB)
|
||||
INVOKE_SYSCALL
|
||||
CMPL AX, $0xfffff001
|
||||
JLS okseek
|
||||
MOVL $-1, newoffset_lo+16(FP)
|
||||
|
|
|
|||
Loading…
Reference in New Issue