aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorqmuntal <quimmuntal@gmail.com>2023-07-18 16:55:26 +0200
committerCherry Mui <cherryyz@google.com>2023-07-20 18:24:32 +0000
commit7ee7a21ef25bd43a83c5a7248a21a42fb2e1a44d (patch)
tree24a294aecccfdd1b89c7c314eb084d1ec3523842
parent06a9034b609bf9fbfdd24ae516d2994da8ed98a9 (diff)
downloadgo-7ee7a21ef25bd43a83c5a7248a21a42fb2e1a44d.tar.gz
go-7ee7a21ef25bd43a83c5a7248a21a42fb2e1a44d.zip
[release-branch.go1.21] runtime: ensure stack is aligned in _rt0_amd64_windows_lib
The Windows DLL loader may call a DLL entry point, in our case _rt0_amd64_windows_lib, with a stack that is not 16-byte aligned. In theory, it shouldn't, but under some circumstances, it does (see below how to reproduce it). Having an unaligned stack can, and probably will, cause problems down the line, for example if a movaps instruction tries to store a value in an unaligned address it throws an Access Violation exception (code 0xc0000005). I managed to consistently reproduce this issue by loading a Go DLL into a C program that has the Page Heap Verification diagnostic enabled [1]. Updates #54187 (and potentially fixes) [1] https://learn.microsoft.com/en-us/windows-hardware/drivers/debugger/example-12---using-page-heap-verification-to-find-a-bug Change-Id: Id0fea7f407e024c9b8cdce10ce4802d7535e7542 Reviewed-on: https://go-review.googlesource.com/c/go/+/510755 TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Cherry Mui <cherryyz@google.com> Reviewed-by: Than McIntosh <thanm@google.com> Run-TryBot: Quim Muntal <quimmuntal@gmail.com> (cherry picked from commit 5fe3f0a265c90a9c0346403742c6cafeb154503b) Reviewed-on: https://go-review.googlesource.com/c/go/+/511135 Run-TryBot: Dmitri Shuralyov <dmitshur@golang.org> Reviewed-by: Quim Muntal <quimmuntal@gmail.com>
-rw-r--r--src/runtime/rt0_windows_amd64.s7
1 files changed, 6 insertions, 1 deletions
diff --git a/src/runtime/rt0_windows_amd64.s b/src/runtime/rt0_windows_amd64.s
index d5f0940540..bd18bdd311 100644
--- a/src/runtime/rt0_windows_amd64.s
+++ b/src/runtime/rt0_windows_amd64.s
@@ -16,12 +16,17 @@ TEXT _rt0_amd64_windows(SB),NOSPLIT|NOFRAME,$-8
// phase.
// Leave space for four pointers on the stack as required
// by the Windows amd64 calling convention.
-TEXT _rt0_amd64_windows_lib(SB),NOSPLIT|NOFRAME,$0x20
+TEXT _rt0_amd64_windows_lib(SB),NOSPLIT|NOFRAME,$40
// Create a new thread to do the runtime initialization and return.
+ MOVQ BX, 32(SP) // callee-saved, preserved across the CALL
+ MOVQ SP, BX
+ ANDQ $~15, SP // alignment as per Windows requirement
MOVQ _cgo_sys_thread_create(SB), AX
MOVQ $_rt0_amd64_windows_lib_go(SB), CX
MOVQ $0, DX
CALL AX
+ MOVQ BX, SP
+ MOVQ 32(SP), BX
RET
TEXT _rt0_amd64_windows_lib_go(SB),NOSPLIT|NOFRAME,$0