aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShenghou Ma <minux@golang.org>2016-02-23 01:26:50 -0500
committerAndrew Gerrand <adg@golang.org>2016-04-14 05:21:00 +0000
commit002cf2820d49009e6e5590d53b8ee640bfd6eb5c (patch)
tree97c8efcd4e4ee5d7fff6460c038ff83885fd88cd
parent8624a53c50d6c955501a14b480c799cf71c21718 (diff)
downloadgo-002cf2820d49009e6e5590d53b8ee640bfd6eb5c.tar.gz
go-002cf2820d49009e6e5590d53b8ee640bfd6eb5c.zip
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: Ian Lance Taylor <iant@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-on: https://go-review.googlesource.com/22038 Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
-rw-r--r--src/runtime/os_linux_386.go5
-rw-r--r--src/runtime/rt0_linux_386.s8
-rw-r--r--src/runtime/runtime1.go2
-rw-r--r--src/runtime/signal_386.go25
-rw-r--r--src/runtime/sys_linux_386.s25
-rw-r--r--src/syscall/asm_linux_386.s13
6 files changed, 14 insertions, 64 deletions
diff --git a/src/runtime/os_linux_386.go b/src/runtime/os_linux_386.go
index 3577a2406b..0f39cade3b 100644
--- a/src/runtime/os_linux_386.go
+++ b/src/runtime/os_linux_386.go
@@ -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])))[:]
}
diff --git a/src/runtime/rt0_linux_386.s b/src/runtime/rt0_linux_386.s
index 59a30b41e8..23bfc98b10 100644
--- a/src/runtime/rt0_linux_386.s
+++ b/src/runtime/rt0_linux_386.s
@@ -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
-
diff --git a/src/runtime/runtime1.go b/src/runtime/runtime1.go
index f63e09cc61..400ea296a9 100644
--- a/src/runtime/runtime1.go
+++ b/src/runtime/runtime1.go
@@ -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))
diff --git a/src/runtime/signal_386.go b/src/runtime/signal_386.go
index 0374f4a2d7..25187dad74 100644
--- a/src/runtime/signal_386.go
+++ b/src/runtime/signal_386.go
@@ -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)
diff --git a/src/runtime/sys_linux_386.s b/src/runtime/sys_linux_386.s
index 1a3aaf0104..4a74196032 100644
--- a/src/runtime/sys_linux_386.s
+++ b/src/runtime/sys_linux_386.s
@@ -12,16 +12,17 @@
// 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
diff --git a/src/syscall/asm_linux_386.s b/src/syscall/asm_linux_386.s
index c94060571b..228a542cf1 100644
--- a/src/syscall/asm_linux_386.s
+++ b/src/syscall/asm_linux_386.s
@@ -12,18 +12,9 @@
// 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)