Skip to content

Commit 1439158

Browse files
committed
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 <[email protected]> Reviewed-by: Ian Lance Taylor <[email protected]> TryBot-Result: Gobot Gobot <[email protected]>
1 parent 5c096cc commit 1439158

File tree

6 files changed

+14
-64
lines changed

6 files changed

+14
-64
lines changed

src/runtime/os_linux_386.go

-5
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@ const (
1515
_AT_SYSINFO = 32
1616
)
1717

18-
var _vdso uint32
19-
2018
func sysargs(argc int32, argv **byte) {
2119
// skip over argv, envv to get to auxv
2220
n := argc + 1
@@ -28,9 +26,6 @@ func sysargs(argc int32, argv **byte) {
2826

2927
for i := 0; auxv[i] != _AT_NULL; i += 2 {
3028
switch auxv[i] {
31-
case _AT_SYSINFO:
32-
_vdso = auxv[i+1]
33-
3429
case _AT_RANDOM:
3530
startupRandomData = (*[16]byte)(unsafe.Pointer(uintptr(auxv[i+1])))[:]
3631
}

src/runtime/rt0_linux_386.s

-8
Original file line numberDiff line numberDiff line change
@@ -73,11 +73,3 @@ GLOBL _rt0_386_linux_lib_argv<>(SB),NOPTR, $4
7373

7474
TEXT main(SB),NOSPLIT,$0
7575
JMP runtime·rt0_go(SB)
76-
77-
TEXT _fallback_vdso(SB),NOSPLIT,$0
78-
INT $0x80
79-
RET
80-
81-
DATA runtime·_vdso(SB)/4, $_fallback_vdso(SB)
82-
GLOBL runtime·_vdso(SB), NOPTR, $4
83-

src/runtime/runtime1.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ var (
5252
argv **byte
5353
)
5454

55-
// nosplit for use in linux/386 startup linux_setup_vdso
55+
// nosplit for use in linux startup sysargs
5656
//go:nosplit
5757
func argv_index(argv **byte, i int32) *byte {
5858
return *(**byte)(add(unsafe.Pointer(argv), uintptr(i)*sys.PtrSize))

src/runtime/signal_386.go

+1-24
Original file line numberDiff line numberDiff line change
@@ -142,30 +142,7 @@ func sighandler(sig uint32, info *siginfo, ctxt unsafe.Pointer, gp *g) {
142142
level, _, docrash := gotraceback()
143143
if level > 0 {
144144
goroutineheader(gp)
145-
146-
// On Linux/386, all system calls go through the vdso kernel_vsyscall routine.
147-
// Normally we don't see those PCs, but during signals we can.
148-
// If we see a PC in the vsyscall area (it moves around, but near the top of memory),
149-
// assume we're blocked in the vsyscall routine, which has saved
150-
// three words on the stack after the initial call saved the caller PC.
151-
// Pop all four words off SP and use the saved PC.
152-
// The check of the stack bounds here should suffice to avoid a fault
153-
// during the actual PC pop.
154-
// If we do load a bogus PC, not much harm done: we weren't going
155-
// to get a decent traceback anyway.
156-
// TODO(rsc): Make this more precise: we should do more checks on the PC,
157-
// and we should find out whether different versions of the vdso page
158-
// use different prologues that store different amounts on the stack.
159-
pc := uintptr(c.eip())
160-
sp := uintptr(c.esp())
161-
if GOOS == "linux" && pc >= 0xf4000000 && gp.stack.lo <= sp && sp+16 <= gp.stack.hi {
162-
// Assume in vsyscall page.
163-
sp += 16
164-
pc = *(*uintptr)(unsafe.Pointer(sp - 4))
165-
print("runtime: unwind vdso kernel_vsyscall: pc=", hex(pc), " sp=", hex(sp), "\n")
166-
}
167-
168-
tracebacktrap(pc, sp, 0, gp)
145+
tracebacktrap(uintptr(c.eip()), uintptr(c.esp()), 0, gp)
169146
if crashing > 0 && gp != _g_.m.curg && _g_.m.curg != nil && readgstatus(_g_.m.curg)&^_Gscan == _Grunning {
170147
// tracebackothers on original m skipped this one; trace it now.
171148
goroutineheader(_g_.m.curg)

src/runtime/sys_linux_386.s

+10-15
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,17 @@
1212

1313
// Most linux systems use glibc's dynamic linker, which puts the
1414
// __kernel_vsyscall vdso helper at 0x10(GS) for easy access from position
15-
// independent code and setldt in this file does the same in the statically
16-
// linked case. Android, however, uses bionic's dynamic linker, which does not
17-
// save the helper anywhere, and so the only way to invoke a syscall from
18-
// position independent code is boring old int $0x80 (which is also what
19-
// bionic's syscall wrappers use).
20-
#ifdef GOOS_android
15+
// independent code and setldt in runtime does the same in the statically
16+
// linked case. However, systems that use alternative libc such as Android's
17+
// bionic and musl, do not save the helper anywhere, and so the only way to
18+
// invoke a syscall from position independent code is boring old int $0x80
19+
// (which is also what syscall wrappers in bionic/musl use).
20+
//
21+
// The benchmarks also showed that using int $0x80 is as fast as calling
22+
// *%gs:0x10 except on AMD Opteron. See https://golang.org/cl/19833
23+
// for the benchmark program and raw data.
24+
//#define INVOKE_SYSCALL CALL 0x10(GS) // non-portable
2125
#define INVOKE_SYSCALL INT $0x80
22-
#else
23-
#define INVOKE_SYSCALL CALL 0x10(GS)
24-
#endif
2526

2627
TEXT runtime·exit(SB),NOSPLIT,$0
2728
MOVL $252, AX // syscall number
@@ -434,12 +435,6 @@ TEXT runtime·setldt(SB),NOSPLIT,$32
434435
*/
435436
ADDL $0x4, DX // address
436437
MOVL DX, 0(DX)
437-
// We copy the glibc dynamic linker behaviour of storing the
438-
// __kernel_vsyscall entry point at 0x10(GS) so that it can be invoked
439-
// by "CALL 0x10(GS)" in all situations, not only those where the
440-
// binary is actually dynamically linked.
441-
MOVL runtime·_vdso(SB), AX
442-
MOVL AX, 0x10(DX)
443438
#endif
444439

445440
// set up user_desc

src/syscall/asm_linux_386.s

+2-11
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,9 @@
1212
// func Syscall(trap uintptr, a1, a2, a3 uintptr) (r1, r2, err uintptr);
1313
// Trap # in AX, args in BX CX DX SI DI, return in AX
1414

15-
// Most linux systems use glibc's dynamic linker, which puts the
16-
// __kernel_vsyscall vdso helper at 0x10(GS) for easy access from position
17-
// independent code and setldt in runtime does the same in the statically
18-
// linked case. Android, however, uses bionic's dynamic linker, which does not
19-
// save the helper anywhere, and so the only way to invoke a syscall from
20-
// position independent code is boring old int $0x80 (which is also what
21-
// bionic's syscall wrappers use).
22-
#ifdef GOOS_android
15+
// See ../runtime/sys_linux_386.s for the reason why we always use int 0x80
16+
// instead of the glibc-specific "CALL 0x10(GS)".
2317
#define INVOKE_SYSCALL INT $0x80
24-
#else
25-
#define INVOKE_SYSCALL CALL 0x10(GS)
26-
#endif
2718

2819
TEXT ·Syscall(SB),NOSPLIT,$0-28
2920
CALL runtime·entersyscall(SB)

0 commit comments

Comments
 (0)