Commit 002cf282 authored by Shenghou Ma's avatar Shenghou Ma Committed by Andrew Gerrand

runtime, syscall: switch linux/386 to use int 0x80

Like bionic, musl also doesn't provide vsyscall helper in %gs:0x10,
and as int $0x80 is as fast as calling %gs:0x10, just use int $0x80
always.

Because we're no longer using vsyscall in VDSO, get rid of VDSO code
for linux/386 too.

Fixes #14476.

Change-Id: I00ec8652060700e0a3c9b524bfe3c16a810263f6
Reviewed-on: https://go-review.googlesource.com/19833
Run-TryBot: Minux Ma <minux@golang.org>
Reviewed-by: default avatarIan Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-on: https://go-review.googlesource.com/22038Reviewed-by: default avatarBrad Fitzpatrick <bradfitz@golang.org>
parent 8624a53c
...@@ -15,8 +15,6 @@ const ( ...@@ -15,8 +15,6 @@ const (
_AT_SYSINFO = 32 _AT_SYSINFO = 32
) )
var _vdso uint32
func sysargs(argc int32, argv **byte) { func sysargs(argc int32, argv **byte) {
// skip over argv, envv to get to auxv // skip over argv, envv to get to auxv
n := argc + 1 n := argc + 1
...@@ -28,9 +26,6 @@ func sysargs(argc int32, argv **byte) { ...@@ -28,9 +26,6 @@ func sysargs(argc int32, argv **byte) {
for i := 0; auxv[i] != _AT_NULL; i += 2 { for i := 0; auxv[i] != _AT_NULL; i += 2 {
switch auxv[i] { switch auxv[i] {
case _AT_SYSINFO:
_vdso = auxv[i+1]
case _AT_RANDOM: case _AT_RANDOM:
startupRandomData = (*[16]byte)(unsafe.Pointer(uintptr(auxv[i+1])))[:] startupRandomData = (*[16]byte)(unsafe.Pointer(uintptr(auxv[i+1])))[:]
} }
......
...@@ -73,11 +73,3 @@ GLOBL _rt0_386_linux_lib_argv<>(SB),NOPTR, $4 ...@@ -73,11 +73,3 @@ GLOBL _rt0_386_linux_lib_argv<>(SB),NOPTR, $4
TEXT main(SB),NOSPLIT,$0 TEXT main(SB),NOSPLIT,$0
JMP runtime·rt0_go(SB) JMP runtime·rt0_go(SB)
TEXT _fallback_vdso(SB),NOSPLIT,$0
INT $0x80
RET
DATA runtime·_vdso(SB)/4, $_fallback_vdso(SB)
GLOBL runtime·_vdso(SB), NOPTR, $4
...@@ -52,7 +52,7 @@ var ( ...@@ -52,7 +52,7 @@ var (
argv **byte argv **byte
) )
// nosplit for use in linux/386 startup linux_setup_vdso // nosplit for use in linux startup sysargs
//go:nosplit //go:nosplit
func argv_index(argv **byte, i int32) *byte { func argv_index(argv **byte, i int32) *byte {
return *(**byte)(add(unsafe.Pointer(argv), uintptr(i)*sys.PtrSize)) return *(**byte)(add(unsafe.Pointer(argv), uintptr(i)*sys.PtrSize))
......
...@@ -142,30 +142,7 @@ func sighandler(sig uint32, info *siginfo, ctxt unsafe.Pointer, gp *g) { ...@@ -142,30 +142,7 @@ func sighandler(sig uint32, info *siginfo, ctxt unsafe.Pointer, gp *g) {
level, _, docrash := gotraceback() level, _, docrash := gotraceback()
if level > 0 { if level > 0 {
goroutineheader(gp) goroutineheader(gp)
tracebacktrap(uintptr(c.eip()), uintptr(c.esp()), 0, gp)
// On Linux/386, all system calls go through the vdso kernel_vsyscall routine.
// Normally we don't see those PCs, but during signals we can.
// If we see a PC in the vsyscall area (it moves around, but near the top of memory),
// assume we're blocked in the vsyscall routine, which has saved
// three words on the stack after the initial call saved the caller PC.
// Pop all four words off SP and use the saved PC.
// The check of the stack bounds here should suffice to avoid a fault
// during the actual PC pop.
// If we do load a bogus PC, not much harm done: we weren't going
// to get a decent traceback anyway.
// TODO(rsc): Make this more precise: we should do more checks on the PC,
// and we should find out whether different versions of the vdso page
// use different prologues that store different amounts on the stack.
pc := uintptr(c.eip())
sp := uintptr(c.esp())
if GOOS == "linux" && pc >= 0xf4000000 && gp.stack.lo <= sp && sp+16 <= gp.stack.hi {
// Assume in vsyscall page.
sp += 16
pc = *(*uintptr)(unsafe.Pointer(sp - 4))
print("runtime: unwind vdso kernel_vsyscall: pc=", hex(pc), " sp=", hex(sp), "\n")
}
tracebacktrap(pc, sp, 0, gp)
if crashing > 0 && gp != _g_.m.curg && _g_.m.curg != nil && readgstatus(_g_.m.curg)&^_Gscan == _Grunning { if crashing > 0 && gp != _g_.m.curg && _g_.m.curg != nil && readgstatus(_g_.m.curg)&^_Gscan == _Grunning {
// tracebackothers on original m skipped this one; trace it now. // tracebackothers on original m skipped this one; trace it now.
goroutineheader(_g_.m.curg) goroutineheader(_g_.m.curg)
......
...@@ -12,16 +12,17 @@ ...@@ -12,16 +12,17 @@
// Most linux systems use glibc's dynamic linker, which puts the // Most linux systems use glibc's dynamic linker, which puts the
// __kernel_vsyscall vdso helper at 0x10(GS) for easy access from position // __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 // independent code and setldt in runtime does the same in the statically
// linked case. Android, however, uses bionic's dynamic linker, which does not // linked case. However, systems that use alternative libc such as Android's
// save the helper anywhere, and so the only way to invoke a syscall from // bionic and musl, do not save the helper anywhere, and so the only way to
// position independent code is boring old int $0x80 (which is also what // invoke a syscall from position independent code is boring old int $0x80
// bionic's syscall wrappers use). // (which is also what syscall wrappers in bionic/musl use).
#ifdef GOOS_android //
// The benchmarks also showed that using int $0x80 is as fast as calling
// *%gs:0x10 except on AMD Opteron. See https://golang.org/cl/19833
// for the benchmark program and raw data.
//#define INVOKE_SYSCALL CALL 0x10(GS) // non-portable
#define INVOKE_SYSCALL INT $0x80 #define INVOKE_SYSCALL INT $0x80
#else
#define INVOKE_SYSCALL CALL 0x10(GS)
#endif
TEXT runtime·exit(SB),NOSPLIT,$0 TEXT runtime·exit(SB),NOSPLIT,$0
MOVL $252, AX // syscall number MOVL $252, AX // syscall number
...@@ -434,12 +435,6 @@ TEXT runtime·setldt(SB),NOSPLIT,$32 ...@@ -434,12 +435,6 @@ TEXT runtime·setldt(SB),NOSPLIT,$32
*/ */
ADDL $0x4, DX // address ADDL $0x4, DX // address
MOVL DX, 0(DX) MOVL DX, 0(DX)
// 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(DX)
#endif #endif
// set up user_desc // set up user_desc
......
...@@ -12,18 +12,9 @@ ...@@ -12,18 +12,9 @@
// func Syscall(trap uintptr, a1, a2, a3 uintptr) (r1, r2, err uintptr); // 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 // Trap # in AX, args in BX CX DX SI DI, return in AX
// Most linux systems use glibc's dynamic linker, which puts the // See ../runtime/sys_linux_386.s for the reason why we always use int 0x80
// __kernel_vsyscall vdso helper at 0x10(GS) for easy access from position // instead of the glibc-specific "CALL 0x10(GS)".
// 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 #define INVOKE_SYSCALL INT $0x80
#else
#define INVOKE_SYSCALL CALL 0x10(GS)
#endif
TEXT ·Syscall(SB),NOSPLIT,$0-28 TEXT ·Syscall(SB),NOSPLIT,$0-28
CALL runtime·entersyscall(SB) CALL runtime·entersyscall(SB)
......
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