# sdl2-compat: fixing MSVC link failures about \_\_chkstk with stuff taken from SDL3

**URL:** <https://discourse.libsdl.org/t/sdl2-compat-fixing-msvc-link-failures-about-chkstk-with-stuff-taken-from-sdl3/48907>\
**Category:** SDL Commits\
**Created:** [January 31, 2024, 7:22pm UTC](https://discourse.libsdl.org/t/sdl2-compat-fixing-msvc-link-failures-about-chkstk-with-stuff-taken-from-sdl3/48907 "2024-01-31T19:22:01Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![SDLPushPostBot](https://discourse.libsdl.org/user_avatar/discourse.libsdl.org/sdlpushpostbot/32/4370_2.png) [@SDLPushPostBot](https://discourse.libsdl.org/u/SDLPushPostBot)\
**Post date:** [January 31, 2024, 7:22pm UTC](https://discourse.libsdl.org/t/sdl2-compat-fixing-msvc-link-failures-about-chkstk-with-stuff-taken-from-sdl3/48907/1 "2024-01-31T19:22:02Z")

</div>

> <https://github.com/libsdl-org/sdl2-compat/commit/35a65dee79ca145acd8c0657fd4fe3163bdec63d>

```diff
From 35a65dee79ca145acd8c0657fd4fe3163bdec63d Mon Sep 17 00:00:00 2001
From: Ozkan Sezer <[EMAIL REDACTED]>
Date: Wed, 31 Jan 2024 22:20:50 +0300
Subject: [PATCH] fixing MSVC link failures about __chkstk with stuff taken
 from SDL3

---
 CMakeLists.txt | 20 +++-
 src/Makefile.vc | 15 ++-
 src/sdl2_compat.c | 3 -
 src/{x86_msvc.h => sdl2_mslibc.c} | 161 ++++++++++++++++++++++--------
 src/sdl2_mslibc_x64.masm | 29 ++++++
 5 files changed, 181 insertions(+), 47 deletions(-)
 rename src/{x86_msvc.h => sdl2_mslibc.c} (85%)
 create mode 100644 src/sdl2_mslibc_x64.masm

diff --git a/CMakeLists.txt b/CMakeLists.txt
index a030cb6..f0b6a7b 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -184,9 +184,22 @@ endif()
 
 if(WIN32)
   list(APPEND SDL2COMPAT_SRCS
+ "src/sdl2_mslibc.c"
     "src/version.rc"
   )
 endif()
+if(MSVC)
+ if(SDL_CPU_X64)
+ list(APPEND SDL2COMPAT_SRCS
+ "src/sdl2_mslibc_x64.masm"
+ )
+ enable_language(ASM_MASM)
+ set_property(SOURCE "src/sdl2_mslibc_x64.masm" PROPERTY LANGUAGE "ASM_MASM")
+ elseif(SDL_CPU_ARM32 OR SDL_CPU_ARM64)
+ # FIXME: ARM assembler (armasm.exe/armasm64.exe) is NOT ASM_MASM, and does currently not work with CMake
+ # (https://gitlab.kitware.com/cmake/cmake/-/issues/18912)
+ endif()
+endif()
 
 if(APPLE)
   foreach(SOURCE_FILE ${SDL2COMPAT_SRCS})
@@ -215,6 +228,9 @@ if(TARGET SDL3::SDL3-shared)
   set_property(TARGET SDL2 PROPERTY BUILD_RPATH $<TARGET_FILE_DIR:SDL3::SDL3-shared>)
 endif()
 
+if(MSVC AND SDL_CPU_X64)
+ target_compile_options(SDL2 PRIVATE "$<$<COMPILE_LANGUAGE:ASM_MASM>:/nologo>")
+endif()
 set(EXTRA_CFLAGS )
 if(CMAKE_C_COMPILER_ID MATCHES "Clang|GNU")
   set(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Wall")
@@ -309,9 +325,9 @@ if(WINDOWS_STORE)
   target_compile_options(SDL2 PRIVATE "-ZW")
 elseif(MSVC)
   # Don't try to link with the default set of libraries.
- target_compile_options(SDL2 PRIVATE /GS-)
+ target_compile_options(SDL2 PRIVATE "$<$<COMPILE_LANGUAGE:C>:/GS->")
   if(SDL_CPU_X86) # don't emit SSE2 in x86 builds
- target_compile_options(SDL2 PRIVATE /arch:SSE)
+ target_compile_options(SDL2 PRIVATE "$<$<COMPILE_LANGUAGE:C>:/arch:SSE>")
   endif()
   if(NOT MSVC_CLANG AND NOT SDL_CPU_ARM32)
     set_property(TARGET SDL2 APPEND_STRING PROPERTY LINK_FLAGS " /NODEFAULTLIB")
diff --git a/src/Makefile.vc b/src/Makefile.vc
index 47e12ef..72a93e5 100644
--- a/src/Makefile.vc
+++ b/src/Makefile.vc
@@ -3,6 +3,9 @@
 #
 # If you specifically want to build for x86:
 #	nmake /f Makefile.vc CPU=x86
+#
+# If you specifically want to build for x64:
+#	nmake /f Makefile.vc CPU=x64
 
 # change INCLUDES so it points to SDL3 headers directory:
 INCLUDES = -Iinclude
@@ -12,19 +15,27 @@ CPPFLAGS = -DNDEBUG -DDLL_EXPORT
 CC = cl
 LD = link
 RC = rc
+AS64 = ml64
 
 CFLAGS = /nologo /O2 /MD /W3 /GS-
 LDFLAGS = /nologo /DLL /NODEFAULTLIB /RELEASE
 LDLIBS = kernel32.lib user32.lib
+AS64FLAGS = /nologo /W3 /Ta
 
 !if "$(CPU)" == "x86"
 CFLAGS = $(CFLAGS) /arch:SSE
 !endif
+!if "$(CPU)" == "x64"
+X64_OBJ = sdl2_mslibc_x64.obj
+!endif
 
 DLLNAME = SDL2.dll
 IMPNAME = SDL2.lib
 
-OBJ = sdl2_compat.obj dynapi\SDL_dynapi.obj version.res
+OBJ = sdl2_compat.obj dynapi\SDL_dynapi.obj sdl2_mslibc.obj $(X64_OBJ) version.res
+
+.SUFFIXES:
+.SUFFIXES: .dll .obj .res .c .cpp .asm .masm .rc
 
 all: $(DLLNAME)
 
@@ -33,6 +44,8 @@ $(DLLNAME): $(OBJ)
 
 .c.obj:
 	$(CC) $(CFLAGS) $(CPPFLAGS) $(INCLUDES) /Fo$@ -c $<
+.masm.obj:
+	$(AS64) $(AS64FLAGS) $< /Fo$@ /c
 .rc.res:
 	$(RC) /r /Fo$@ $<
 
diff --git a/src/sdl2_compat.c b/src/sdl2_compat.c
index 485dad2..25fafb2 100644
--- a/src/sdl2_compat.c
+++ b/src/sdl2_compat.c
@@ -609,9 +609,6 @@ LoadSDL3(void)
 }
 
 #if defined(_MSC_VER) && !defined(SDL_BUILDING_WINRT)
-#ifdef _M_IX86
-#include "x86_msvc.h"
-#endif
 
 /* NOLINTNEXTLINE(readability-redundant-declaration) */
 extern void *memcpy(void *dst, const void *src, size_t len);
diff --git a/src/x86_msvc.h b/src/sdl2_mslibc.c
similarity index 85%
rename from src/x86_msvc.h
rename to src/sdl2_mslibc.c
index 4e88e4f..bfd4b21 100644
--- a/src/x86_msvc.h
+++ b/src/sdl2_mslibc.c
@@ -19,15 +19,21 @@
   3. This notice may not be removed or altered from any source distribution.
 */
 
-/* taken from SDL_stdlib.c of SDL2 */
+/* taken from SDL_mslibc.c of SDL3 */
 
-/* *INDENT-OFF* */
+#if defined(_MSC_VER) && !defined(SDL_BUILDING_WINRT)
+
+#ifndef __FLTUSED__
+#define __FLTUSED__
+__declspec(selectany) int _fltused = 1;
+#endif
+
+#ifdef _M_IX86
 
 /* Float to long */
-void
-__declspec(naked)
-_ftol()
+void __declspec(naked) _ftol()
 {
+ /* *INDENT-OFF* */
     __asm {
         push ebp
         mov ebp,esp
@@ -71,25 +77,23 @@ _ftol()
         leave
         ret
     }
+ /* *INDENT-ON* */
 }
 
-void
-_ftol2()
+void _ftol2_sse()
 {
     _ftol();
 }
 
-void
-_ftol2_sse()
+void _ftol2()
 {
     _ftol();
 }
 
 /* 64-bit math operators for 32-bit systems */
-void
-__declspec(naked)
-_allmul()
+void __declspec(naked) _allmul()
 {
+ /* *INDENT-OFF* */
     __asm {
         mov eax, dword ptr[esp+8]
         mov ecx, dword ptr[esp+10h]
@@ -112,12 +116,12 @@ _allmul()
         pop ebx
         ret 10h
     }
+ /* *INDENT-ON* */
 }
 
-void
-__declspec(naked)
-_alldiv()
+void __declspec(naked) _alldiv()
 {
+ /* *INDENT-OFF* */
     __asm {
         push edi
         push esi
@@ -198,12 +202,12 @@ _alldiv()
         pop edi
         ret 10h
     }
+ /* *INDENT-ON* */
 }
 
-void
-__declspec(naked)
-_aulldiv()
+void __declspec(naked) _aulldiv()
 {
+ /* *INDENT-OFF* */
     __asm {
         push ebx
         push esi
@@ -254,12 +258,12 @@ _aulldiv()
         pop ebx
         ret 10h
     }
+ /* *INDENT-ON* */
 }
 
-void
-__declspec(naked)
-_allrem()
+void __declspec(naked) _allrem()
 {
+ /* *INDENT-OFF* */
     __asm {
         push ebx
         push edi
@@ -339,12 +343,12 @@ _allrem()
         pop ebx
         ret 10h
     }
+ /* *INDENT-ON* */
 }
 
-void
-__declspec(naked)
-_aullrem()
+void __declspec(naked) _aullrem()
 {
+ /* *INDENT-OFF* */
     __asm {
         push ebx
         mov eax,dword ptr [esp+14h]
@@ -396,12 +400,12 @@ _aullrem()
         pop ebx
         ret 10h
     }
+ /* *INDENT-ON* */
 }
 
-void
-__declspec(naked)
-_alldvrm()
+void __declspec(naked) _alldvrm()
 {
+ /* *INDENT-OFF* */
     __asm {
         push edi
         push esi
@@ -504,12 +508,12 @@ _alldvrm()
         pop edi
         ret 10h
     }
+ /* *INDENT-ON* */
 }
 
-void
-__declspec(naked)
-_aulldvrm()
+void __declspec(naked) _aulldvrm()
 {
+ /* *INDENT-OFF* */
     __asm {
         push esi
         mov eax,dword ptr [esp+14h]
@@ -575,12 +579,12 @@ _aulldvrm()
         pop esi
         ret 10h
     }
+ /* *INDENT-ON* */
 }
 
-void
-__declspec(naked)
-_allshl()
+void __declspec(naked) _allshl()
 {
+ /* *INDENT-OFF* */
     __asm {
         cmp cl,40h
         jae RETZERO
@@ -600,12 +604,12 @@ _allshl()
         xor edx,edx
         ret
     }
+ /* *INDENT-ON* */
 }
 
-void
-__declspec(naked)
-_allshr()
+void __declspec(naked) _allshr()
 {
+ /* *INDENT-OFF* */
     __asm {
         cmp cl,3Fh
         jae RETSIGN
@@ -625,12 +629,12 @@ _allshr()
         mov eax,edx
         ret
     }
+ /* *INDENT-ON* */
 }
 
-void
-__declspec(naked)
-_aullshr()
+void __declspec(naked) _aullshr()
 {
+ /* *INDENT-OFF* */
     __asm {
         cmp cl,40h
         jae RETZERO
@@ -650,7 +654,82 @@ _aullshr()
         xor edx,edx
         ret
     }
+ /* *INDENT-ON* */
 }
-/* *INDENT-ON* */
 
-/* vi: set ts=4 sw=4 expandtab: */
+void __declspec(naked) _chkstk(void)
+{
+ __asm {
+ push ecx
+ mov ecx,esp ; lea ecx,dword ptr [esp]+4
+ add ecx,4
+ sub ecx,eax
+ sbb eax,eax
+ not eax
+ and ecx,eax
+ mov eax,esp
+ and eax,0xfffff000
+L1:
+ cmp ecx,eax
+ jb short L2
+ mov eax,ecx
+ pop ecx
+ xchg esp,eax
+ mov eax,dword ptr [eax]
+ mov dword ptr [esp],eax
+ ret
+L2:
+ sub eax,0x1000
+ test dword ptr [eax],eax
+ jmp short L1
+ }
+}
+
+void __declspec(naked) _alloca_probe_8(void)
+{
+ /* *INDENT-OFF* */
+ __asm {
+ push ecx
+ mov ecx,esp ; lea ecx,dword ptr [esp]+8
+ add ecx,8
+ sub ecx,eax
+ and ecx,0x7
+ add eax,ecx
+ sbb ecx,ecx
+ or eax,ecx
+ pop ecx
+ jmp _chkstk
+ }
+ /* *INDENT-ON* */
+}
+
+void __declspec(naked) _alloca_probe_16(void)
+{
+ /* *INDENT-OFF* */
+ __asm {
+ push ecx
+ mov ecx,esp ; lea ecx,dword ptr [esp]+8
+ add ecx,8
+ sub ecx,eax
+ and ecx,0xf
+ add eax,ecx
+ sbb ecx,ecx
+ or eax,ecx
+ pop ecx
+ jmp _chkstk
+ }
+ /* *INDENT-ON* */
+}
+
+#endif /* _M_IX86 */
+
+#ifdef _M_ARM64
+
+/* !!! FIXME !!! */
+void __chkstk(void);
+void __chkstk() {
+}
+
+#endif
+
+#endif /* MSC_VER */
diff --git a/src/sdl2_mslibc_x64.masm b/src/sdl2_mslibc_x64.masm
new file mode 100644
index 0000000..1590d88
--- /dev/null
+++ b/src/sdl2_mslibc_x64.masm
@@ -0,0 +1,29 @@
+include ksamd64.inc
+
+text SEGMENT EXECUTE
+
+public __chkstk
+
+__chkstk:
+ sub rsp,010h
+ mov QWORD PTR [rsp],r10
+ mov QWORD PTR [rsp+08h],r11
+ xor r11,r11
+ lea r10,[rsp+018h]
+ sub r10,rax
+ cmovb r10,r11
+ mov r11,QWORD PTR gs:[TeStackLimit]
+ cmp r10,r11
+ jae chkstk_finish
+ and r10w,0f000h
+chkstk_loop:
+ lea r11,[r11-PAGE_SIZE]
+ mov BYTE PTR [r11],0h
+ cmp r10,r11
+ jne chkstk_loop
+chkstk_finish:
+ mov r10,QWORD PTR [rsp]
+ mov r11,QWORD PTR [rsp+08h]
+ add rsp,010h
+ ret
+end

```
