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>
// 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
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);
break;
}
}
+
+ free(prev);
}
*/
import "C"
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
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
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
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
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.
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
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);
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
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
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));
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