]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: preserve callee-saved C registers in sigtramp
authorBryan C. Mills <bcmills@google.com>
Thu, 15 Dec 2016 22:21:13 +0000 (14:21 -0800)
committerIan Lance Taylor <iant@golang.org>
Thu, 15 Dec 2016 23:41:06 +0000 (23:41 +0000)
This fixes Linux and the *BSD platforms on 386/amd64.

A few OS/arch combinations were already saving registers and/or doing
something that doesn't clearly resemble the SysV C ABI; those have
been left alone.

Fixes #18328.

Change-Id: I6398f6c71020de108fc8b26ca5946f0ba0258667
Reviewed-on: https://go-review.googlesource.com/34501
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
misc/cgo/testsanitizers/tsan9.go
src/runtime/sys_dragonfly_amd64.s
src/runtime/sys_freebsd_amd64.s
src/runtime/sys_linux_386.s
src/runtime/sys_linux_amd64.s
src/runtime/sys_netbsd_386.s
src/runtime/sys_netbsd_amd64.s
src/runtime/sys_openbsd_386.s
src/runtime/sys_openbsd_amd64.s

index 7cd0ac7dd67023be8397c481f9cd5f98d321333d..f166d8b495ac458a4a6dd236d0913cd90a68a0e9 100644 (file)
@@ -6,7 +6,8 @@ package main
 
 // This program failed when run under the C/C++ ThreadSanitizer. The
 // TSAN library was not keeping track of whether signals should be
-// delivered on the alternate signal stack.
+// delivered on the alternate signal stack, and the Go signal handler
+// was not preserving callee-saved registers from C callers.
 
 /*
 #cgo CFLAGS: -g -fsanitize=thread
@@ -19,10 +20,14 @@ void spin() {
        size_t n;
        struct timeval tvstart, tvnow;
        int diff;
+       void *prev = NULL, *cur;
 
        gettimeofday(&tvstart, NULL);
        for (n = 0; n < 1<<20; n++) {
-               free(malloc(n));
+               cur = malloc(n);
+               free(prev);
+               prev = cur;
+
                gettimeofday(&tvnow, NULL);
                diff = (tvnow.tv_sec - tvstart.tv_sec) * 1000 * 1000 + (tvnow.tv_usec - tvstart.tv_usec);
 
@@ -32,6 +37,8 @@ void spin() {
                        break;
                }
        }
+
+       free(prev);
 }
 */
 import "C"
index 88c7f9dd8ac5ce1bcdad49539bac6fb587e4059a..b950b69fe019167d8101a0afdbe1f0d0fb6a0468 100644 (file)
@@ -200,11 +200,28 @@ TEXT runtime·sigfwd(SB),NOSPLIT,$0-32
        POPQ    BP
        RET
 
-TEXT runtime·sigtramp(SB),NOSPLIT,$24
-       MOVQ    DI, 0(SP)
-       MOVQ    SI, 8(SP)
-       MOVQ    DX, 16(SP)
+TEXT runtime·sigtramp(SB),NOSPLIT,$72
+       // Save callee-saved C registers, since the caller may be a C signal handler.
+       MOVQ    BX,  bx-8(SP)
+       MOVQ    BP,  bp-16(SP)  // save in case GOEXPERIMENT=noframepointer is set
+       MOVQ    R12, r12-24(SP)
+       MOVQ    R13, r13-32(SP)
+       MOVQ    R14, r14-40(SP)
+       MOVQ    R15, r15-48(SP)
+       // We don't save mxcsr or the x87 control word because sigtrampgo doesn't
+       // modify them.
+
+       MOVQ    DX, ctx-56(SP)
+       MOVQ    SI, info-64(SP)
+       MOVQ    DI, signum-72(SP)
        CALL    runtime·sigtrampgo(SB)
+
+       MOVQ    r15-48(SP), R15
+       MOVQ    r14-40(SP), R14
+       MOVQ    r13-32(SP), R13
+       MOVQ    r12-24(SP), R12
+       MOVQ    bp-16(SP),  BP
+       MOVQ    bx-8(SP),   BX
        RET
 
 TEXT runtime·mmap(SB),NOSPLIT,$0
index 19007dc401156db4be4d383306b358560244c78f..158a60dec2e2a2125b5ae0985ad94d6de5bbee92 100644 (file)
@@ -196,11 +196,28 @@ TEXT runtime·sigfwd(SB),NOSPLIT,$0-32
        POPQ    BP
        RET
 
-TEXT runtime·sigtramp(SB),NOSPLIT,$24
-       MOVQ    DI, 0(SP)
-       MOVQ    SI, 8(SP)
-       MOVQ    DX, 16(SP)
+TEXT runtime·sigtramp(SB),NOSPLIT,$72
+       // Save callee-saved C registers, since the caller may be a C signal handler.
+       MOVQ    BX, bx-8(SP)
+       MOVQ    BP, bp-16(SP)  // save in case GOEXPERIMENT=noframepointer is set
+       MOVQ    R12, r12-24(SP)
+       MOVQ    R13, r13-32(SP)
+       MOVQ    R14, r14-40(SP)
+       MOVQ    R15, r15-48(SP)
+       // We don't save mxcsr or the x87 control word because sigtrampgo doesn't
+       // modify them.
+
+       MOVQ    DX, ctx-56(SP)
+       MOVQ    SI, info-64(SP)
+       MOVQ    DI, signum-72(SP)
        CALL    runtime·sigtrampgo(SB)
+
+       MOVQ    r15-48(SP), R15
+       MOVQ    r14-40(SP), R14
+       MOVQ    r13-32(SP), R13
+       MOVQ    r12-24(SP), R12
+       MOVQ    bp-16(SP),  BP
+       MOVQ    bx-8(SP),   BX
        RET
 
 TEXT runtime·mmap(SB),NOSPLIT,$0
index 1d798c741ed634ba7bbacbd7030507ac51001e95..45320c068a0d7647236d1cf54ddc9cc37a8cf6aa 100644 (file)
@@ -228,7 +228,15 @@ TEXT runtime·sigfwd(SB),NOSPLIT,$12-16
        MOVL    AX, SP
        RET
 
-TEXT runtime·sigtramp(SB),NOSPLIT,$12
+TEXT runtime·sigtramp(SB),NOSPLIT,$28
+       // Save callee-saved C registers, since the caller may be a C signal handler.
+       MOVL    BX, bx-4(SP)
+       MOVL    BP, bp-8(SP)
+       MOVL    SI, si-12(SP)
+       MOVL    DI, di-16(SP)
+       // We don't save mxcsr or the x87 control word because sigtrampgo doesn't
+       // modify them.
+
        MOVL    sig+0(FP), BX
        MOVL    BX, 0(SP)
        MOVL    info+4(FP), BX
@@ -236,6 +244,11 @@ TEXT runtime·sigtramp(SB),NOSPLIT,$12
        MOVL    ctx+8(FP), BX
        MOVL    BX, 8(SP)
        CALL    runtime·sigtrampgo(SB)
+
+       MOVL    di-16(SP), DI
+       MOVL    si-12(SP), SI
+       MOVL    bp-8(SP),  BP
+       MOVL    bx-4(SP),  BX
        RET
 
 TEXT runtime·cgoSigtramp(SB),NOSPLIT,$0
index 832b98b6740b50fa282ace31def2d839929b5c07..839df164068f0c302cf4329ea956ce53c343893c 100644 (file)
@@ -244,12 +244,29 @@ TEXT runtime·sigfwd(SB),NOSPLIT,$0-32
        POPQ    BP
        RET
 
-TEXT runtime·sigtramp(SB),NOSPLIT,$24
-       MOVQ    DI, 0(SP)   // signum
-       MOVQ    SI, 8(SP)   // info
-       MOVQ    DX, 16(SP)  // ctx
+TEXT runtime·sigtramp(SB),NOSPLIT,$72
+       // Save callee-saved C registers, since the caller may be a C signal handler.
+       MOVQ    BX,  bx-8(SP)
+       MOVQ    BP,  bp-16(SP)  // save in case GOEXPERIMENT=noframepointer is set
+       MOVQ    R12, r12-24(SP)
+       MOVQ    R13, r13-32(SP)
+       MOVQ    R14, r14-40(SP)
+       MOVQ    R15, r15-48(SP)
+       // We don't save mxcsr or the x87 control word because sigtrampgo doesn't
+       // modify them.
+
+       MOVQ    DX, ctx-56(SP)
+       MOVQ    SI, info-64(SP)
+       MOVQ    DI, signum-72(SP)
        MOVQ    $runtime·sigtrampgo(SB), AX
        CALL AX
+
+       MOVQ    r15-48(SP), R15
+       MOVQ    r14-40(SP), R14
+       MOVQ    r13-32(SP), R13
+       MOVQ    r12-24(SP), R12
+       MOVQ    bp-16(SP),  BP
+       MOVQ    bx-8(SP),   BX
        RET
 
 // Used instead of sigtramp in programs that use cgo.
index 50d35e5b5ca15df15e43deccb5afcfffa6ddb571..8c4f004a4b1398b17b33c3baa6dad0a1086cf9a8 100644 (file)
@@ -232,7 +232,15 @@ TEXT runtime·sigfwd(SB),NOSPLIT,$12-16
        MOVL    AX, SP
        RET
 
-TEXT runtime·sigtramp(SB),NOSPLIT,$12
+TEXT runtime·sigtramp(SB),NOSPLIT,$28
+       // Save callee-saved C registers, since the caller may be a C signal handler.
+       MOVL    BX, bx-4(SP)
+       MOVL    BP, bp-8(SP)
+       MOVL    SI, si-12(SP)
+       MOVL    DI, di-16(SP)
+       // We don't save mxcsr or the x87 control word because sigtrampgo doesn't
+       // modify them.
+
        MOVL    signo+0(FP), BX
        MOVL    BX, 0(SP)
        MOVL    info+4(FP), BX
@@ -240,6 +248,11 @@ TEXT runtime·sigtramp(SB),NOSPLIT,$12
        MOVL    context+8(FP), BX
        MOVL    BX, 8(SP)
        CALL    runtime·sigtrampgo(SB)
+
+       MOVL    di-16(SP), DI
+       MOVL    si-12(SP), SI
+       MOVL    bp-8(SP),  BP
+       MOVL    bx-4(SP),  BX
        RET
 
 // int32 lwp_create(void *context, uintptr flags, void *lwpid);
index 2c50adb123d0a5127610f65a7264d76d49ec93b7..7c7771bcba634a9d7310d2c278aa5792b6515dcd 100644 (file)
@@ -250,13 +250,28 @@ TEXT runtime·sigfwd(SB),NOSPLIT,$0-32
        POPQ    BP
        RET
 
-TEXT runtime·sigtramp(SB),NOSPLIT,$32
-       MOVQ    DI, 0(SP)   // signum
-       MOVQ    SI, 8(SP)   // info
-       MOVQ    DX, 16(SP)  // ctx
-       MOVQ    R15, 24(SP) // for sigreturn
+TEXT runtime·sigtramp(SB),NOSPLIT,$72
+       // Save callee-saved C registers, since the caller may be a C signal handler.
+       MOVQ    BX,  bx-8(SP)
+       MOVQ    BP,  bp-16(SP)  // save in case GOEXPERIMENT=noframepointer is set
+       MOVQ    R12, r12-24(SP)
+       MOVQ    R13, r13-32(SP)
+       MOVQ    R14, r14-40(SP)
+       MOVQ    R15, r15-48(SP)
+       // We don't save mxcsr or the x87 control word because sigtrampgo doesn't
+       // modify them.
+
+       MOVQ    DX, ctx-56(SP)
+       MOVQ    SI, info-64(SP)
+       MOVQ    DI, signum-72(SP)
        CALL    runtime·sigtrampgo(SB)
-       MOVQ    24(SP), R15
+
+       MOVQ    r15-48(SP), R15
+       MOVQ    r14-40(SP), R14
+       MOVQ    r13-32(SP), R13
+       MOVQ    r12-24(SP), R12
+       MOVQ    bp-16(SP),  BP
+       MOVQ    bx-8(SP),   BX
        RET
 
 TEXT runtime·mmap(SB),NOSPLIT,$0
index 997c07fe17c893acc0037d6669088fd283db2867..76d22b01311d1f381c53ebfeb7dacf44f0e68bba 100644 (file)
@@ -213,7 +213,15 @@ TEXT runtime·sigfwd(SB),NOSPLIT,$12-16
        MOVL    AX, SP
        RET
 
-TEXT runtime·sigtramp(SB),NOSPLIT,$12
+TEXT runtime·sigtramp(SB),NOSPLIT,$28
+       // Save callee-saved C registers, since the caller may be a C signal handler.
+       MOVL    BX, bx-4(SP)
+       MOVL    BP, bp-8(SP)
+       MOVL    SI, si-12(SP)
+       MOVL    DI, di-16(SP)
+       // We don't save mxcsr or the x87 control word because sigtrampgo doesn't
+       // modify them.
+
        MOVL    signo+0(FP), BX
        MOVL    BX, 0(SP)
        MOVL    info+4(FP), BX
@@ -221,6 +229,11 @@ TEXT runtime·sigtramp(SB),NOSPLIT,$12
        MOVL    context+8(FP), BX
        MOVL    BX, 8(SP)
        CALL    runtime·sigtrampgo(SB)
+
+       MOVL    di-16(SP), DI
+       MOVL    si-12(SP), SI
+       MOVL    bp-8(SP),  BP
+       MOVL    bx-4(SP),  BX
        RET
 
 // int32 tfork(void *param, uintptr psize, M *mp, G *gp, void (*fn)(void));
index 6ca5a81d2a2f74e134e088636ef3dd1a8cb81939..cf7a3fb7a9b952424b03013b97aba908a180ad0d 100644 (file)
@@ -242,11 +242,28 @@ TEXT runtime·sigfwd(SB),NOSPLIT,$0-32
        POPQ    BP
        RET
 
-TEXT runtime·sigtramp(SB),NOSPLIT,$24
-       MOVQ    DI, 0(SP)
-       MOVQ    SI, 8(SP)
-       MOVQ    DX, 16(SP)
+TEXT runtime·sigtramp(SB),NOSPLIT,$72
+       // Save callee-saved C registers, since the caller may be a C signal handler.
+       MOVQ    BX,  bx-8(SP)
+       MOVQ    BP,  bp-16(SP)  // save in case GOEXPERIMENT=noframepointer is set
+       MOVQ    R12, r12-24(SP)
+       MOVQ    R13, r13-32(SP)
+       MOVQ    R14, r14-40(SP)
+       MOVQ    R15, r15-48(SP)
+       // We don't save mxcsr or the x87 control word because sigtrampgo doesn't
+       // modify them.
+
+       MOVQ    DX, ctx-56(SP)
+       MOVQ    SI, info-64(SP)
+       MOVQ    DI, signum-72(SP)
        CALL    runtime·sigtrampgo(SB)
+
+       MOVQ    r15-48(SP), R15
+       MOVQ    r14-40(SP), R14
+       MOVQ    r13-32(SP), R13
+       MOVQ    r12-24(SP), R12
+       MOVQ    bp-16(SP),  BP
+       MOVQ    bx-8(SP),   BX
        RET
 
 TEXT runtime·mmap(SB),NOSPLIT,$0