detached 533bec3

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 Unverified4AEE18F83AFDEB23 The key is unknown
3 files · +16 -76
M .github/workflows/test.yml +2 -1
@@ -73,7 +73,8 @@ jobs:
7373
7474 - name: go test
7575 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 ./...
7778
7879 - name: go test race
7980 if: ${{ !startsWith(matrix.go, '1.18.') && !startsWith(matrix.go, '1.19.') }}
@@ -73,7 +73,8 @@ jobs:
73 73
74 - name: go test74 - 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 race79 - 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 @@
11 // SPDX-License-Identifier: Apache-2.0
22 // SPDX-FileCopyrightText: 2022 The Ebitengine Authors
33
4+//go:build darwin || linux
5+
46 /*
57 trampoline for emulating required C functions for cgo in go (see cgo.go)
68 (we convert cdecl calling convention to go and vice-versa)
@@ -81,7 +83,18 @@ TEXT ·call5(SB), NOSPLIT, $0-56
8183 MOVQ a3+24(FP), DX
8284 MOVQ a4+32(FP), CX
8385 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+
8594 CALL BX
95+
96+ MOVQ BP, SP // get SP back
97+ POPQ BP // restore BP
98+
8699 MOVQ AX, ret+48(FP)
87100 RET
@@ -1,6 +1,8 @@
1 // SPDX-License-Identifier: Apache-2.01 // SPDX-License-Identifier: Apache-2.0
2 // SPDX-FileCopyrightText: 2022 The Ebitengine Authors2 // 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), DX83 MOVQ a3+24(FP), DX
82 MOVQ a4+32(FP), CX84 MOVQ a4+32(FP), CX
83 MOVQ a5+40(FP), R885 MOVQ a5+40(FP), R8
84- XORL AX, AX86+
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 BX94 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 RET100 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

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 1

Tags 102

↑↓ moveenter openesc close