]> Cypherpunks repositories - gostls13.git/commitdiff
runtime, syscall: switch linux/386 to use int 0x80
authorShenghou Ma <minux@golang.org>
Tue, 23 Feb 2016 06:26:50 +0000 (01:26 -0500)
committerMinux Ma <minux@golang.org>
Wed, 24 Feb 2016 02:07:17 +0000 (02:07 +0000)
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: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/runtime/os_linux_386.go
src/runtime/rt0_linux_386.s
src/runtime/runtime1.go
src/runtime/signal_386.go
src/runtime/sys_linux_386.s
src/syscall/asm_linux_386.s

index 3577a2406b9741d5224ea68bbe7bab5e5d4e161b..0f39cade3b864f348651380188ba8772bc6d7b52 100644 (file)
@@ -15,8 +15,6 @@ const (
        _AT_SYSINFO = 32
 )
 
-var _vdso uint32
-
 func sysargs(argc int32, argv **byte) {
        // skip over argv, envv to get to auxv
        n := argc + 1
@@ -28,9 +26,6 @@ func sysargs(argc int32, argv **byte) {
 
        for i := 0; auxv[i] != _AT_NULL; i += 2 {
                switch auxv[i] {
-               case _AT_SYSINFO:
-                       _vdso = auxv[i+1]
-
                case _AT_RANDOM:
                        startupRandomData = (*[16]byte)(unsafe.Pointer(uintptr(auxv[i+1])))[:]
                }
index 59a30b41e8bb9b58caf7b5e762929e866578bb42..23bfc98b100cddb5e647b8e40f09bd884f70fbaa 100644 (file)
@@ -73,11 +73,3 @@ GLOBL _rt0_386_linux_lib_argv<>(SB),NOPTR, $4
 
 TEXT main(SB),NOSPLIT,$0
        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
-
index f63e09cc6177beba5b7e07149d0c929d215d71bb..400ea296a9b3bba93b65164c29b19221726618b1 100644 (file)
@@ -52,7 +52,7 @@ var (
        argv **byte
 )
 
-// nosplit for use in linux/386 startup linux_setup_vdso
+// nosplit for use in linux startup sysargs
 //go:nosplit
 func argv_index(argv **byte, i int32) *byte {
        return *(**byte)(add(unsafe.Pointer(argv), uintptr(i)*sys.PtrSize))
index 0374f4a2d7825ef7b5f0ae17042191562057ec3e..25187dad74a36aa14d2d1f390fc06c4590133ef8 100644 (file)
@@ -142,30 +142,7 @@ func sighandler(sig uint32, info *siginfo, ctxt unsafe.Pointer, gp *g) {
        level, _, docrash := gotraceback()
        if level > 0 {
                goroutineheader(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)
+               tracebacktrap(uintptr(c.eip()), uintptr(c.esp()), 0, gp)
                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.
                        goroutineheader(_g_.m.curg)
index 1a3aaf0104714cd083b9b4b5581621b5521a1f58..4a74196032d76699d679954074451135b4adb23b 100644 (file)
 
 // 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
+// independent code and setldt in runtime does the same in the statically
+// linked case. However, systems that use alternative libc such as Android's
+// bionic and musl, do 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 syscall wrappers in bionic/musl use).
+//
+// 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
-#else
-#define INVOKE_SYSCALL CALL    0x10(GS)
-#endif
 
 TEXT runtime·exit(SB),NOSPLIT,$0
        MOVL    $252, AX        // syscall number
@@ -434,12 +435,6 @@ TEXT runtime·setldt(SB),NOSPLIT,$32
         */
        ADDL    $0x4, DX        // address
        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
 
        // set up user_desc
index c94060571b11c0205b5e22f1580f4c6cd09c1b9a..228a542cf1c8b3cf46e8270f273433b1edf8cc41 100644 (file)
 // 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
+// See ../runtime/sys_linux_386.s for the reason why we always use int 0x80
+// instead of the glibc-specific "CALL 0x10(GS)".
 #define INVOKE_SYSCALL INT     $0x80
-#else
-#define INVOKE_SYSCALL CALL    0x10(GS)
-#endif
 
 TEXT   ·Syscall(SB),NOSPLIT,$0-28
        CALL    runtime·entersyscall(SB)