From 7af0839e11378b153feaa9570aeb2cdcdc06b75f Mon Sep 17 00:00:00 2001 From: Michael Hudson-Doyle Date: Thu, 12 Nov 2015 12:55:57 +1300 Subject: [PATCH] cmd/go, runtime: always use position-independent code to invoke vsyscall helper on linux/386 golang.org/cl/16346 changed the runtime on linux/386 to invoke the vsyscall helper via a PIC sequence (CALL 0x10(GS)) when dynamically linking. But it's actually quite easy to make that code sequence work all the time, so do that, and remove the ugly machinery that passed the buildmode from the go tool to the assembly. This means enlarging m.tls so that we can safely access 0x10(GS) (GS is set to &m.tls + 4, so 0x10(GS) accesses m_tls[5]). Change-Id: I1345c34029b149cb5f25320bf19a3cdd73a056fa Reviewed-on: https://go-review.googlesource.com/16796 Reviewed-by: Ian Lance Taylor --- src/cmd/go/build.go | 3 -- src/runtime/runtime2.go | 2 +- src/runtime/sys_linux_386.s | 96 ++++++++++++++++++------------------- 3 files changed, 49 insertions(+), 52 deletions(-) diff --git a/src/cmd/go/build.go b/src/cmd/go/build.go index c29f6a78a0..5cd92c23fa 100644 --- a/src/cmd/go/build.go +++ b/src/cmd/go/build.go @@ -332,9 +332,6 @@ func buildModeInit() { _, gccgo := buildToolchain.(gccgoToolchain) var codegenArg string platform := goos + "/" + goarch - if buildBuildmode != "default" { - buildAsmflags = append(buildAsmflags, "-D=GOBUILDMODE_"+strings.Replace(buildBuildmode, "-", "_", -1)+"=1") - } switch buildBuildmode { case "archive": pkgsFilter = pkgsNotMain diff --git a/src/runtime/runtime2.go b/src/runtime/runtime2.go index 1dbd3d2094..eb7b30a344 100644 --- a/src/runtime/runtime2.go +++ b/src/runtime/runtime2.go @@ -274,7 +274,7 @@ type m struct { procid uint64 // for debuggers, but offset not hard-coded gsignal *g // signal-handling g sigmask [4]uintptr // storage for saved signal mask - tls [4]uintptr // thread-local storage (for x86 extern register) + tls [6]uintptr // thread-local storage (for x86 extern register) mstartfn func() curg *g // current running goroutine caughtsig guintptr // goroutine running during fatal signal diff --git a/src/runtime/sys_linux_386.s b/src/runtime/sys_linux_386.s index d26b25e987..98626d14c8 100644 --- a/src/runtime/sys_linux_386.s +++ b/src/runtime/sys_linux_386.s @@ -10,23 +10,17 @@ #include "go_tls.h" #include "textflag.h" -#ifdef GOBUILDMODE_shared -#define INVOKE_SYSINFO CALL 0x10(GS) -#else -#define INVOKE_SYSINFO CALL *runtime·_vdso(SB) -#endif - TEXT runtime·exit(SB),NOSPLIT,$0 MOVL $252, AX // syscall number MOVL code+0(FP), BX - INVOKE_SYSINFO + CALL 0x10(GS) 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 - INVOKE_SYSINFO + CALL 0x10(GS) INT $3 // not reached RET @@ -35,7 +29,7 @@ TEXT runtime·open(SB),NOSPLIT,$0 MOVL name+0(FP), BX MOVL mode+4(FP), CX MOVL perm+8(FP), DX - INVOKE_SYSINFO + CALL 0x10(GS) CMPL AX, $0xfffff001 JLS 2(PC) MOVL $-1, AX @@ -45,7 +39,7 @@ TEXT runtime·open(SB),NOSPLIT,$0 TEXT runtime·closefd(SB),NOSPLIT,$0 MOVL $6, AX // syscall - close MOVL fd+0(FP), BX - INVOKE_SYSINFO + CALL 0x10(GS) CMPL AX, $0xfffff001 JLS 2(PC) MOVL $-1, AX @@ -57,7 +51,7 @@ TEXT runtime·write(SB),NOSPLIT,$0 MOVL fd+0(FP), BX MOVL p+4(FP), CX MOVL n+8(FP), DX - INVOKE_SYSINFO + CALL 0x10(GS) CMPL AX, $0xfffff001 JLS 2(PC) MOVL $-1, AX @@ -69,7 +63,7 @@ TEXT runtime·read(SB),NOSPLIT,$0 MOVL fd+0(FP), BX MOVL p+4(FP), CX MOVL n+8(FP), DX - INVOKE_SYSINFO + CALL 0x10(GS) CMPL AX, $0xfffff001 JLS 2(PC) MOVL $-1, AX @@ -80,7 +74,7 @@ TEXT runtime·getrlimit(SB),NOSPLIT,$0 MOVL $191, AX // syscall - ugetrlimit MOVL kind+0(FP), BX MOVL limit+4(FP), CX - INVOKE_SYSINFO + CALL 0x10(GS) MOVL AX, ret+8(FP) RET @@ -99,31 +93,31 @@ TEXT runtime·usleep(SB),NOSPLIT,$8 MOVL $0, DX MOVL $0, SI LEAL 0(SP), DI - INVOKE_SYSINFO + CALL 0x10(GS) RET TEXT runtime·gettid(SB),NOSPLIT,$0-4 MOVL $224, AX // syscall - gettid - INVOKE_SYSINFO + CALL 0x10(GS) MOVL AX, ret+0(FP) RET TEXT runtime·raise(SB),NOSPLIT,$12 MOVL $224, AX // syscall - gettid - INVOKE_SYSINFO + CALL 0x10(GS) MOVL AX, BX // arg 1 tid MOVL sig+0(FP), CX // arg 2 signal MOVL $238, AX // syscall - tkill - INVOKE_SYSINFO + CALL 0x10(GS) RET TEXT runtime·raiseproc(SB),NOSPLIT,$12 MOVL $20, AX // syscall - getpid - INVOKE_SYSINFO + CALL 0x10(GS) MOVL AX, BX // arg 1 pid MOVL sig+0(FP), CX // arg 2 signal MOVL $37, AX // syscall - kill - INVOKE_SYSINFO + CALL 0x10(GS) RET TEXT runtime·setitimer(SB),NOSPLIT,$0-12 @@ -131,7 +125,7 @@ TEXT runtime·setitimer(SB),NOSPLIT,$0-12 MOVL mode+0(FP), BX MOVL new+4(FP), CX MOVL old+8(FP), DX - INVOKE_SYSINFO + CALL 0x10(GS) RET TEXT runtime·mincore(SB),NOSPLIT,$0-16 @@ -139,7 +133,7 @@ TEXT runtime·mincore(SB),NOSPLIT,$0-16 MOVL addr+0(FP), BX MOVL n+4(FP), CX MOVL dst+8(FP), DX - INVOKE_SYSINFO + CALL 0x10(GS) MOVL AX, ret+12(FP) RET @@ -149,7 +143,7 @@ TEXT time·now(SB), NOSPLIT, $32 MOVL $0, BX // CLOCK_REALTIME LEAL 8(SP), CX MOVL $0, DX - INVOKE_SYSINFO + CALL 0x10(GS) MOVL 8(SP), AX // sec MOVL 12(SP), BX // nsec @@ -166,7 +160,7 @@ TEXT runtime·nanotime(SB), NOSPLIT, $32 MOVL $1, BX // CLOCK_MONOTONIC LEAL 8(SP), CX MOVL $0, DX - INVOKE_SYSINFO + CALL 0x10(GS) MOVL 8(SP), AX // sec MOVL 12(SP), BX // nsec @@ -187,7 +181,7 @@ TEXT runtime·rtsigprocmask(SB),NOSPLIT,$0 MOVL new+4(FP), CX MOVL old+8(FP), DX MOVL size+12(FP), SI - INVOKE_SYSINFO + CALL 0x10(GS) CMPL AX, $0xfffff001 JLS 2(PC) INT $3 @@ -199,7 +193,7 @@ TEXT runtime·rt_sigaction(SB),NOSPLIT,$0 MOVL new+4(FP), CX MOVL old+8(FP), DX MOVL size+12(FP), SI - INVOKE_SYSINFO + CALL 0x10(GS) MOVL AX, ret+16(FP) RET @@ -227,9 +221,9 @@ TEXT runtime·sigtramp(SB),NOSPLIT,$12 TEXT runtime·sigreturn(SB),NOSPLIT,$0 MOVL $173, AX // rt_sigreturn // Sigreturn expects same SP as signal handler, - // so cannot CALL *runtime._vsdo(SB) here. + // so cannot CALL 0x10(GS) here. INT $0x80 - INT $3 // not reached + INT $3 // not reached RET TEXT runtime·mmap(SB),NOSPLIT,$0 @@ -241,7 +235,7 @@ TEXT runtime·mmap(SB),NOSPLIT,$0 MOVL fd+16(FP), DI MOVL off+20(FP), BP SHRL $12, BP - INVOKE_SYSINFO + CALL 0x10(GS) CMPL AX, $0xfffff001 JLS 3(PC) NOTL AX @@ -253,7 +247,7 @@ TEXT runtime·munmap(SB),NOSPLIT,$0 MOVL $91, AX // munmap MOVL addr+0(FP), BX MOVL n+4(FP), CX - INVOKE_SYSINFO + CALL 0x10(GS) CMPL AX, $0xfffff001 JLS 2(PC) INT $3 @@ -264,7 +258,7 @@ TEXT runtime·madvise(SB),NOSPLIT,$0 MOVL addr+0(FP), BX MOVL n+4(FP), CX MOVL flags+8(FP), DX - INVOKE_SYSINFO + CALL 0x10(GS) // ignore failure - maybe pages are locked RET @@ -278,7 +272,7 @@ TEXT runtime·futex(SB),NOSPLIT,$0 MOVL ts+12(FP), SI MOVL addr2+16(FP), DI MOVL val3+20(FP), BP - INVOKE_SYSINFO + CALL 0x10(GS) MOVL AX, ret+24(FP) RET @@ -300,10 +294,9 @@ TEXT runtime·clone(SB),NOSPLIT,$0 MOVL SI, 8(CX) MOVL $1234, 12(CX) - // cannot use CALL *runtime·_vdso(SB) here, because - // the stack changes during the system call (after - // CALL *runtime·_vdso(SB), the child is still using - // the parent's stack when executing its RET instruction). + // cannot use CALL 0x10(GS) here, because the stack changes during the + // system call (after CALL 0x10(GS), the child is still using the + // parent's stack when executing its RET instruction). INT $0x80 // In parent, return. @@ -320,7 +313,7 @@ TEXT runtime·clone(SB),NOSPLIT,$0 // Initialize AX to Linux tid MOVL $224, AX - INVOKE_SYSINFO + CALL 0x10(GS) MOVL 0(SP), BX // m MOVL 4(SP), DX // g @@ -371,7 +364,7 @@ TEXT runtime·sigaltstack(SB),NOSPLIT,$-8 MOVL $186, AX // sigaltstack MOVL new+4(SP), BX MOVL old+8(SP), CX - INVOKE_SYSINFO + CALL 0x10(GS) CMPL AX, $0xfffff001 JLS 2(PC) INT $3 @@ -429,6 +422,12 @@ 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. + MOVL runtime·_vdso(SB), AX + MOVL AX, 0x10(CX) // set up user_desc LEAL 16(SP), AX // struct user_desc @@ -442,7 +441,8 @@ TEXT runtime·setldt(SB),NOSPLIT,$32 MOVL AX, CX // user_desc MOVL $16, DX // sizeof(user_desc) MOVL $123, AX // syscall - modify_ldt - INVOKE_SYSINFO + // We can't call this via 0x10(GS) because this is called from setldt0 to set that up. + INT $0x80 // breakpoint on error CMPL AX, $0xfffff001 @@ -459,7 +459,7 @@ TEXT runtime·setldt(SB),NOSPLIT,$32 TEXT runtime·osyield(SB),NOSPLIT,$0 MOVL $158, AX - INVOKE_SYSINFO + CALL 0x10(GS) RET TEXT runtime·sched_getaffinity(SB),NOSPLIT,$0 @@ -467,7 +467,7 @@ TEXT runtime·sched_getaffinity(SB),NOSPLIT,$0 MOVL pid+0(FP), BX MOVL len+4(FP), CX MOVL buf+8(FP), DX - INVOKE_SYSINFO + CALL 0x10(GS) MOVL AX, ret+12(FP) RET @@ -475,7 +475,7 @@ TEXT runtime·sched_getaffinity(SB),NOSPLIT,$0 TEXT runtime·epollcreate(SB),NOSPLIT,$0 MOVL $254, AX MOVL size+0(FP), BX - INVOKE_SYSINFO + CALL 0x10(GS) MOVL AX, ret+4(FP) RET @@ -483,7 +483,7 @@ TEXT runtime·epollcreate(SB),NOSPLIT,$0 TEXT runtime·epollcreate1(SB),NOSPLIT,$0 MOVL $329, AX MOVL flags+0(FP), BX - INVOKE_SYSINFO + CALL 0x10(GS) MOVL AX, ret+4(FP) RET @@ -494,7 +494,7 @@ TEXT runtime·epollctl(SB),NOSPLIT,$0 MOVL op+4(FP), CX MOVL fd+8(FP), DX MOVL ev+12(FP), SI - INVOKE_SYSINFO + CALL 0x10(GS) MOVL AX, ret+16(FP) RET @@ -505,7 +505,7 @@ TEXT runtime·epollwait(SB),NOSPLIT,$0 MOVL ev+4(FP), CX MOVL nev+8(FP), DX MOVL timeout+12(FP), SI - INVOKE_SYSINFO + CALL 0x10(GS) MOVL AX, ret+16(FP) RET @@ -515,7 +515,7 @@ TEXT runtime·closeonexec(SB),NOSPLIT,$0 MOVL fd+0(FP), BX // fd MOVL $2, CX // F_SETFD MOVL $1, DX // FD_CLOEXEC - INVOKE_SYSINFO + CALL 0x10(GS) RET // int access(const char *name, int mode) @@ -523,7 +523,7 @@ TEXT runtime·access(SB),NOSPLIT,$0 MOVL $33, AX // syscall - access MOVL name+0(FP), BX MOVL mode+4(FP), CX - INVOKE_SYSINFO + CALL 0x10(GS) MOVL AX, ret+8(FP) RET @@ -534,7 +534,7 @@ TEXT runtime·connect(SB),NOSPLIT,$0-16 MOVL $102, AX // syscall - socketcall MOVL $3, BX // connect LEAL fd+0(FP), CX - INVOKE_SYSINFO + CALL 0x10(GS) MOVL AX, ret+12(FP) RET @@ -545,6 +545,6 @@ TEXT runtime·socket(SB),NOSPLIT,$0-16 MOVL $102, AX // syscall - socketcall MOVL $1, BX // socket LEAL domain+0(FP), CX - INVOKE_SYSINFO + CALL 0x10(GS) MOVL AX, ret+12(FP) RET