#include <setjmp.h>
#include <signal.h>
+#include <stdarg.h>
#include <stddef.h>
#include <stdio.h>
+#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
static jmp_buf jmp;
static char* nullPointer;
+// An arbitrary function which requires proper stack alignment; see
+// http://golang.org/issue/17641.
+static void callWithVarargs(void* dummy, ...) {
+ va_list args;
+ va_start(args, dummy);
+ va_end(args);
+}
+
// Signal handler for SIGSEGV on a C thread.
static void segvHandler(int signo, siginfo_t* info, void* ctxt) {
sigset_t mask;
int i;
+ // Call an arbitrary function that requires the stack to be properly aligned.
+ callWithVarargs("dummy arg", 3.1415);
+
if (sigemptyset(&mask) < 0) {
die("sigemptyset");
}
MOVL info+8(FP), CX
MOVL ctx+12(FP), DX
MOVL SP, SI
- SUBL $32, SP // align stack; handler might be C code
- ANDL $~15, SP
+ SUBL $32, SP
+ ANDL $~15, SP // align stack: handler might be a C function
MOVL BX, 0(SP)
MOVL CX, 4(SP)
MOVL DX, 8(SP)
- MOVL SI, 12(SP)
+ MOVL SI, 12(SP) // save SI: handler might be a Go function
CALL AX
MOVL 12(SP), AX
MOVL AX, SP
RET
TEXT runtime·sigfwd(SB),NOSPLIT,$0-32
- MOVQ fn+0(FP), AX
- MOVL sig+8(FP), DI
- MOVQ info+16(FP), SI
- MOVQ ctx+24(FP), DX
- MOVQ SP, BP
- SUBQ $64, SP
- ANDQ $~15, SP // alignment for x86_64 ABI
- CALL AX
- MOVQ BP, SP
+ MOVQ fn+0(FP), AX
+ MOVL sig+8(FP), DI
+ MOVQ info+16(FP), SI
+ MOVQ ctx+24(FP), DX
+ PUSHQ BP
+ MOVQ SP, BP
+ ANDQ $~15, SP // alignment for x86_64 ABI
+ CALL AX
+ MOVQ BP, SP
+ POPQ BP
RET
TEXT runtime·sigtramp(SB),NOSPLIT,$32
RET
TEXT runtime·sigfwd(SB),NOSPLIT,$0-32
- MOVL sig+8(FP), DI
+ MOVQ fn+0(FP), AX
+ MOVL sig+8(FP), DI
MOVQ info+16(FP), SI
- MOVQ ctx+24(FP), DX
- MOVQ fn+0(FP), AX
+ MOVQ ctx+24(FP), DX
+ PUSHQ BP
+ MOVQ SP, BP
+ ANDQ $~15, SP // alignment for x86_64 ABI
CALL AX
+ MOVQ BP, SP
+ POPQ BP
RET
TEXT runtime·sigtramp(SB),NOSPLIT,$24
RET
TEXT runtime·sigfwd(SB),NOSPLIT,$12-16
- MOVL sig+4(FP), AX
- MOVL AX, 0(SP)
- MOVL info+8(FP), AX
- MOVL AX, 4(SP)
- MOVL ctx+12(FP), AX
- MOVL AX, 8(SP)
MOVL fn+0(FP), AX
+ MOVL sig+4(FP), BX
+ MOVL info+8(FP), CX
+ MOVL ctx+12(FP), DX
+ MOVL SP, SI
+ SUBL $32, SP
+ ANDL $~15, SP // align stack: handler might be a C function
+ MOVL BX, 0(SP)
+ MOVL CX, 4(SP)
+ MOVL DX, 8(SP)
+ MOVL SI, 12(SP) // save SI: handler might be a Go function
CALL AX
+ MOVL 12(SP), AX
+ MOVL AX, SP
RET
TEXT runtime·sigtramp(SB),NOSPLIT,$12
RET
TEXT runtime·sigfwd(SB),NOSPLIT,$0-32
- MOVL sig+8(FP), DI
+ MOVQ fn+0(FP), AX
+ MOVL sig+8(FP), DI
MOVQ info+16(FP), SI
- MOVQ ctx+24(FP), DX
- MOVQ fn+0(FP), AX
+ MOVQ ctx+24(FP), DX
+ PUSHQ BP
+ MOVQ SP, BP
+ ANDQ $~15, SP // alignment for x86_64 ABI
CALL AX
+ MOVQ BP, SP
+ POPQ BP
RET
TEXT runtime·sigtramp(SB),NOSPLIT,$24
RET
TEXT runtime·sigfwd(SB),NOSPLIT,$12-16
- MOVL sig+4(FP), AX
- MOVL AX, 0(SP)
- MOVL info+8(FP), AX
- MOVL AX, 4(SP)
- MOVL ctx+12(FP), AX
- MOVL AX, 8(SP)
MOVL fn+0(FP), AX
+ MOVL sig+4(FP), BX
+ MOVL info+8(FP), CX
+ MOVL ctx+12(FP), DX
+ MOVL SP, SI
+ SUBL $32, SP
+ ANDL $-15, SP // align stack: handler might be a C function
+ MOVL BX, 0(SP)
+ MOVL CX, 4(SP)
+ MOVL DX, 8(SP)
+ MOVL SI, 12(SP) // save SI: handler might be a Go function
CALL AX
+ MOVL 12(SP), AX
+ MOVL AX, SP
RET
TEXT runtime·sigtramp(SB),NOSPLIT,$12
RET
TEXT runtime·sigfwd(SB),NOSPLIT,$0-32
- MOVL sig+8(FP), DI
+ MOVQ fn+0(FP), AX
+ MOVL sig+8(FP), DI
MOVQ info+16(FP), SI
- MOVQ ctx+24(FP), DX
- MOVQ fn+0(FP), AX
+ MOVQ ctx+24(FP), DX
+ PUSHQ BP
+ MOVQ SP, BP
+ ANDQ $~15, SP // alignment for x86_64 ABI
CALL AX
+ MOVQ BP, SP
+ POPQ BP
RET
TEXT runtime·sigtramp(SB),NOSPLIT,$24
RET
TEXT runtime·sigfwd(SB),NOSPLIT,$12-16
- MOVL sig+4(FP), AX
- MOVL AX, 0(SP)
- MOVL info+8(FP), AX
- MOVL AX, 4(SP)
- MOVL ctx+12(FP), AX
- MOVL AX, 8(SP)
MOVL fn+0(FP), AX
+ MOVL sig+4(FP), BX
+ MOVL info+8(FP), CX
+ MOVL ctx+12(FP), DX
+ MOVL SP, SI
+ SUBL $32, SP
+ ANDL $-15, SP // align stack: handler might be a C function
+ MOVL BX, 0(SP)
+ MOVL CX, 4(SP)
+ MOVL DX, 8(SP)
+ MOVL SI, 12(SP) // save SI: handler might be a Go function
CALL AX
+ MOVL 12(SP), AX
+ MOVL AX, SP
RET
TEXT runtime·sigtramp(SB),NOSPLIT,$12
RET
TEXT runtime·sigfwd(SB),NOSPLIT,$0-32
- MOVL sig+8(FP), DI
+ MOVQ fn+0(FP), AX
+ MOVL sig+8(FP), DI
MOVQ info+16(FP), SI
- MOVQ ctx+24(FP), DX
- MOVQ fn+0(FP), AX
+ MOVQ ctx+24(FP), DX
+ PUSHQ BP
+ MOVQ SP, BP
+ ANDQ $~15, SP // alignment for x86_64 ABI
CALL AX
+ MOVQ BP, SP
+ POPQ BP
RET
TEXT runtime·sigtramp(SB),NOSPLIT,$32
RET
TEXT runtime·sigfwd(SB),NOSPLIT,$12-16
- MOVL sig+4(FP), AX
- MOVL AX, 0(SP)
- MOVL info+8(FP), AX
- MOVL AX, 4(SP)
- MOVL ctx+12(FP), AX
- MOVL AX, 8(SP)
MOVL fn+0(FP), AX
+ MOVL sig+4(FP), BX
+ MOVL info+8(FP), CX
+ MOVL ctx+12(FP), DX
+ MOVL SP, SI
+ SUBL $32, SP
+ ANDL $~15, SP // align stack: handler might be a C function
+ MOVL BX, 0(SP)
+ MOVL CX, 4(SP)
+ MOVL DX, 8(SP)
+ MOVL SI, 12(SP) // save SI: handler might be a Go function
CALL AX
+ MOVL 12(SP), AX
+ MOVL AX, SP
RET
TEXT runtime·sigtramp(SB),NOSPLIT,$12
RET
TEXT runtime·sigfwd(SB),NOSPLIT,$0-32
- MOVL sig+8(FP), DI
+ MOVQ fn+0(FP), AX
+ MOVL sig+8(FP), DI
MOVQ info+16(FP), SI
- MOVQ ctx+24(FP), DX
- MOVQ fn+0(FP), AX
+ MOVQ ctx+24(FP), DX
+ PUSHQ BP
+ MOVQ SP, BP
+ ANDQ $~15, SP // alignment for x86_64 ABI
CALL AX
+ MOVQ BP, SP
+ POPQ BP
RET
TEXT runtime·sigtramp(SB),NOSPLIT,$24
RET
TEXT runtime·sigfwd(SB),NOSPLIT,$0-32
- MOVL sig+8(FP), DI
+ MOVQ fn+0(FP), AX
+ MOVL sig+8(FP), DI
MOVQ info+16(FP), SI
- MOVQ ctx+24(FP), DX
- MOVQ fn+0(FP), AX
+ MOVQ ctx+24(FP), DX
+ PUSHQ BP
+ MOVQ SP, BP
+ ANDQ $~15, SP // alignment for x86_64 ABI
CALL AX
+ MOVQ BP, SP
+ POPQ BP
RET
// Called from runtime·usleep (Go). Can be called on Go stack, on OS stack,