internal/fakecgo: align stack on amd64 for SSE (#111)
Some SSE instructions on amd64 require that the stack be aligned. The stack was not properly aligned and would SIGSEGV inside fakecgo. This patch aligns the stack properly. It also merges the darwin and linux trampolines. This is a reverse of #104 which I believe was actually caused by this issue. It also explicitly tests the behavior with and without Cgo (CGO_ENABLED=0/1). Closes #106
- commit
- 533bec350583a749aa7bdc6c47bed182df740e79
- author
- TotallyGamerJet · · 2023-03-19 17:51 UTC
- committer
- GitHub · · 2023-03-19 17:51 UTC
- parent
- 7c07304
- signature
- GPG Unverified
4AEE18F83AFDEB23The key is unknown
3 files · +16 -76
M .github/workflows/test.yml +2 -1
| @@ -73,7 +73,8 @@ jobs: | |||
| 73 | 73 | ||
| 74 | 74 | - name: go test | |
| 75 | 75 | run: | | |
| 76 | - | go test -shuffle=on -v -count=10 ./... | |
| 76 | + | env CGO_ENABLED=0 go test -shuffle=on -v -count=10 ./... | |
| 77 | + | env CGO_ENABLED=1 go test -shuffle=on -v -count=10 ./... | |
| 77 | 78 | ||
| 78 | 79 | - name: go test race | |
| 79 | 80 | if: ${{ !startsWith(matrix.go, '1.18.') && !startsWith(matrix.go, '1.19.') }} | |
| @@ -73,7 +73,8 @@ jobs: | |||||
| 73 | 73 | ||||
| 74 | - name: go test | 74 | - name: go test | ||
| 75 | run: | | 75 | run: | | ||
| 76 | - | go test -shuffle=on -v -count=10 ./... | 76 | + | env CGO_ENABLED=0 go test -shuffle=on -v -count=10 ./... |
| 77 | + | env CGO_ENABLED=1 go test -shuffle=on -v -count=10 ./... | |||
| 77 | 78 | ||||
| 78 | - name: go test race | 79 | - name: go test race | ||
| 79 | if: ${{ !startsWith(matrix.go, '1.18.') && !startsWith(matrix.go, '1.19.') }} | 80 | if: ${{ !startsWith(matrix.go, '1.18.') && !startsWith(matrix.go, '1.19.') }} | ||
R internal/fakecgo/trampolines_darwin_amd64.s → internal/fakecgo/trampolines_amd64.s +14 -1 renamed, 86% similar
| @@ -1,6 +1,8 @@ | |||
| 1 | 1 | // SPDX-License-Identifier: Apache-2.0 | |
| 2 | 2 | // SPDX-FileCopyrightText: 2022 The Ebitengine Authors | |
| 3 | 3 | ||
| 4 | + | //go:build darwin || linux | |
| 5 | + | ||
| 4 | 6 | /* | |
| 5 | 7 | trampoline for emulating required C functions for cgo in go (see cgo.go) | |
| 6 | 8 | (we convert cdecl calling convention to go and vice-versa) | |
| @@ -81,7 +83,18 @@ TEXT ·call5(SB), NOSPLIT, $0-56 | |||
| 81 | 83 | MOVQ a3+24(FP), DX | |
| 82 | 84 | MOVQ a4+32(FP), CX | |
| 83 | 85 | MOVQ a5+40(FP), R8 | |
| 84 | - | XORL AX, AX | |
| 86 | + | ||
| 87 | + | XORL AX, AX // no floats | |
| 88 | + | ||
| 89 | + | PUSHQ BP // save BP | |
| 90 | + | MOVQ SP, BP // save SP inside BP bc BP is callee-saved | |
| 91 | + | SUBQ $16, SP // allocate space for alignment | |
| 92 | + | ANDQ $-16, SP // align on 16 bytes for SSE | |
| 93 | + | ||
| 85 | 94 | CALL BX | |
| 95 | + | ||
| 96 | + | MOVQ BP, SP // get SP back | |
| 97 | + | POPQ BP // restore BP | |
| 98 | + | ||
| 86 | 99 | MOVQ AX, ret+48(FP) | |
| 87 | 100 | RET | |
| @@ -1,6 +1,8 @@ | |||||
| 1 | // SPDX-License-Identifier: Apache-2.0 | 1 | // SPDX-License-Identifier: Apache-2.0 | ||
| 2 | // SPDX-FileCopyrightText: 2022 The Ebitengine Authors | 2 | // SPDX-FileCopyrightText: 2022 The Ebitengine Authors | ||
| 3 | 3 | ||||
| 4 | + | //go:build darwin || linux | |||
| 5 | + | ||||
| 4 | /* | 6 | /* | ||
| 5 | trampoline for emulating required C functions for cgo in go (see cgo.go) | 7 | trampoline for emulating required C functions for cgo in go (see cgo.go) | ||
| 6 | (we convert cdecl calling convention to go and vice-versa) | 8 | (we convert cdecl calling convention to go and vice-versa) | ||
| @@ -81,7 +83,18 @@ TEXT ·call5(SB), NOSPLIT, $0-56 | |||||
| 81 | MOVQ a3+24(FP), DX | 83 | MOVQ a3+24(FP), DX | ||
| 82 | MOVQ a4+32(FP), CX | 84 | MOVQ a4+32(FP), CX | ||
| 83 | MOVQ a5+40(FP), R8 | 85 | MOVQ a5+40(FP), R8 | ||
| 84 | - | XORL AX, AX | 86 | + | |
| 87 | + | XORL AX, AX // no floats | |||
| 88 | + | ||||
| 89 | + | PUSHQ BP // save BP | |||
| 90 | + | MOVQ SP, BP // save SP inside BP bc BP is callee-saved | |||
| 91 | + | SUBQ $16, SP // allocate space for alignment | |||
| 92 | + | ANDQ $-16, SP // align on 16 bytes for SSE | |||
| 93 | + | ||||
| 85 | CALL BX | 94 | CALL BX | ||
| 95 | + | ||||
| 96 | + | MOVQ BP, SP // get SP back | |||
| 97 | + | POPQ BP // restore BP | |||
| 98 | + | ||||
| 86 | MOVQ AX, ret+48(FP) | 99 | MOVQ AX, ret+48(FP) | ||
| 87 | RET | 100 | RET | ||
D internal/fakecgo/trampolines_linux_amd64.s +0 -74
| @@ -1,74 +0,0 @@ | |||
| 1 | - | // SPDX-License-Identifier: Apache-2.0 | |
| 2 | - | // SPDX-FileCopyrightText: 2022 The Ebitengine Authors | |
| 3 | - | ||
| 4 | - | /* | |
| 5 | - | trampoline for emulating required C functions for cgo in go (see cgo.go) | |
| 6 | - | (we convert cdecl calling convention to go and vice-versa) | |
| 7 | - | Since we're called from go and call into C we can cheat a bit with the calling conventions: | |
| 8 | - | - in go all the registers are caller saved | |
| 9 | - | - in C we have a couple of callee saved registers | |
| 10 | - | => we can use BX, R12, R13, R14, R15 instead of the stack | |
| 11 | - | C Calling convention cdecl used here (we only need integer args): | |
| 12 | - | 1. arg: DI | |
| 13 | - | 2. arg: SI | |
| 14 | - | 3. arg: DX | |
| 15 | - | 4. arg: CX | |
| 16 | - | 5. arg: R8 | |
| 17 | - | 6. arg: R9 | |
| 18 | - | We don't need floats with these functions -> AX=0 | |
| 19 | - | return value will be in AX | |
| 20 | - | */ | |
| 21 | - | #include "textflag.h" | |
| 22 | - | #include "go_asm.h" | |
| 23 | - | ||
| 24 | - | // these trampolines map the gcc ABI to Go ABI and then calls into the Go equivalent functions. | |
| 25 | - | ||
| 26 | - | TEXT x_cgo_init_trampoline(SB), NOSPLIT, $16 | |
| 27 | - | MOVQ DI, 0(SP) | |
| 28 | - | MOVQ SI, 8(SP) | |
| 29 | - | CALL ·x_cgo_init(SB) | |
| 30 | - | RET | |
| 31 | - | ||
| 32 | - | TEXT x_cgo_thread_start_trampoline(SB), NOSPLIT, $8 | |
| 33 | - | MOVQ DI, 0(SP) | |
| 34 | - | CALL ·x_cgo_thread_start(SB) | |
| 35 | - | RET | |
| 36 | - | ||
| 37 | - | TEXT x_cgo_setenv_trampoline(SB), NOSPLIT, $8 | |
| 38 | - | MOVQ DI, 0(SP) | |
| 39 | - | CALL ·x_cgo_setenv(SB) | |
| 40 | - | RET | |
| 41 | - | ||
| 42 | - | TEXT x_cgo_unsetenv_trampoline(SB), NOSPLIT, $8 | |
| 43 | - | MOVQ DI, 0(SP) | |
| 44 | - | CALL ·x_cgo_unsetenv(SB) | |
| 45 | - | RET | |
| 46 | - | ||
| 47 | - | TEXT x_cgo_notify_runtime_init_done_trampoline(SB), NOSPLIT, $0 | |
| 48 | - | CALL ·x_cgo_notify_runtime_init_done(SB) | |
| 49 | - | RET | |
| 50 | - | ||
| 51 | - | // func setg_trampoline(setg uintptr, g uintptr) | |
| 52 | - | TEXT ·setg_trampoline(SB), NOSPLIT, $0-16 | |
| 53 | - | MOVQ G+8(FP), DI | |
| 54 | - | MOVQ setg+0(FP), AX | |
| 55 | - | CALL AX | |
| 56 | - | RET | |
| 57 | - | ||
| 58 | - | TEXT threadentry_trampoline(SB), NOSPLIT, $16 | |
| 59 | - | MOVQ DI, 0(SP) | |
| 60 | - | CALL ·threadentry(SB) | |
| 61 | - | MOVQ 8(SP), AX | |
| 62 | - | RET | |
| 63 | - | ||
| 64 | - | TEXT ·call5(SB), NOSPLIT, $0-56 | |
| 65 | - | MOVQ fn+0(FP), BX | |
| 66 | - | MOVQ a1+8(FP), DI | |
| 67 | - | MOVQ a2+16(FP), SI | |
| 68 | - | MOVQ a3+24(FP), DX | |
| 69 | - | MOVQ a4+32(FP), CX | |
| 70 | - | MOVQ a5+40(FP), R8 | |
| 71 | - | XORL AX, AX | |
| 72 | - | CALL BX | |
| 73 | - | MOVQ AX, ret+48(FP) | |
| 74 | - | RET | |
| @@ -1,74 +0,0 @@ | |||||
| 1 | - | // SPDX-License-Identifier: Apache-2.0 | |||
| 2 | - | // SPDX-FileCopyrightText: 2022 The Ebitengine Authors | |||
| 3 | - | ||||
| 4 | - | /* | |||
| 5 | - | trampoline for emulating required C functions for cgo in go (see cgo.go) | |||
| 6 | - | (we convert cdecl calling convention to go and vice-versa) | |||
| 7 | - | Since we're called from go and call into C we can cheat a bit with the calling conventions: | |||
| 8 | - | - in go all the registers are caller saved | |||
| 9 | - | - in C we have a couple of callee saved registers | |||
| 10 | - | => we can use BX, R12, R13, R14, R15 instead of the stack | |||
| 11 | - | C Calling convention cdecl used here (we only need integer args): | |||
| 12 | - | 1. arg: DI | |||
| 13 | - | 2. arg: SI | |||
| 14 | - | 3. arg: DX | |||
| 15 | - | 4. arg: CX | |||
| 16 | - | 5. arg: R8 | |||
| 17 | - | 6. arg: R9 | |||
| 18 | - | We don't need floats with these functions -> AX=0 | |||
| 19 | - | return value will be in AX | |||
| 20 | - | */ | |||
| 21 | - | #include "textflag.h" | |||
| 22 | - | #include "go_asm.h" | |||
| 23 | - | ||||
| 24 | - | // these trampolines map the gcc ABI to Go ABI and then calls into the Go equivalent functions. | |||
| 25 | - | ||||
| 26 | - | TEXT x_cgo_init_trampoline(SB), NOSPLIT, $16 | |||
| 27 | - | MOVQ DI, 0(SP) | |||
| 28 | - | MOVQ SI, 8(SP) | |||
| 29 | - | CALL ·x_cgo_init(SB) | |||
| 30 | - | RET | |||
| 31 | - | ||||
| 32 | - | TEXT x_cgo_thread_start_trampoline(SB), NOSPLIT, $8 | |||
| 33 | - | MOVQ DI, 0(SP) | |||
| 34 | - | CALL ·x_cgo_thread_start(SB) | |||
| 35 | - | RET | |||
| 36 | - | ||||
| 37 | - | TEXT x_cgo_setenv_trampoline(SB), NOSPLIT, $8 | |||
| 38 | - | MOVQ DI, 0(SP) | |||
| 39 | - | CALL ·x_cgo_setenv(SB) | |||
| 40 | - | RET | |||
| 41 | - | ||||
| 42 | - | TEXT x_cgo_unsetenv_trampoline(SB), NOSPLIT, $8 | |||
| 43 | - | MOVQ DI, 0(SP) | |||
| 44 | - | CALL ·x_cgo_unsetenv(SB) | |||
| 45 | - | RET | |||
| 46 | - | ||||
| 47 | - | TEXT x_cgo_notify_runtime_init_done_trampoline(SB), NOSPLIT, $0 | |||
| 48 | - | CALL ·x_cgo_notify_runtime_init_done(SB) | |||
| 49 | - | RET | |||
| 50 | - | ||||
| 51 | - | // func setg_trampoline(setg uintptr, g uintptr) | |||
| 52 | - | TEXT ·setg_trampoline(SB), NOSPLIT, $0-16 | |||
| 53 | - | MOVQ G+8(FP), DI | |||
| 54 | - | MOVQ setg+0(FP), AX | |||
| 55 | - | CALL AX | |||
| 56 | - | RET | |||
| 57 | - | ||||
| 58 | - | TEXT threadentry_trampoline(SB), NOSPLIT, $16 | |||
| 59 | - | MOVQ DI, 0(SP) | |||
| 60 | - | CALL ·threadentry(SB) | |||
| 61 | - | MOVQ 8(SP), AX | |||
| 62 | - | RET | |||
| 63 | - | ||||
| 64 | - | TEXT ·call5(SB), NOSPLIT, $0-56 | |||
| 65 | - | MOVQ fn+0(FP), BX | |||
| 66 | - | MOVQ a1+8(FP), DI | |||
| 67 | - | MOVQ a2+16(FP), SI | |||
| 68 | - | MOVQ a3+24(FP), DX | |||
| 69 | - | MOVQ a4+32(FP), CX | |||
| 70 | - | MOVQ a5+40(FP), R8 | |||
| 71 | - | XORL AX, AX | |||
| 72 | - | CALL BX | |||
| 73 | - | MOVQ AX, ret+48(FP) | |||
| 74 | - | RET | |||