diff --git a/CMakeLists.txt b/CMakeLists.txt
index 59a1e695..696d070f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -859,6 +859,10 @@ if (MSVC)
${CMAKE_CURRENT_SOURCE_DIR}/msvc/unicorn/qapi-types.c
${CMAKE_CURRENT_SOURCE_DIR}/msvc/unicorn/qapi-visit.c
)
+ if(CMAKE_SIZEOF_VOID_P EQUAL 8)
+ enable_language(ASM_MASM)
+ set(UNICORN_SRCS ${UNICORN_SRCS} qemu/util/setjmp-wrapper-win32.asm)
+ endif()
else()
set(UNICORN_SRCS
${UNICORN_SRCS_COMMON}
diff --git a/msvc/unicorn/unicorn/unicorn.vcxproj b/msvc/unicorn/unicorn/unicorn.vcxproj
index 27f7762b..4b896c9e 100644
--- a/msvc/unicorn/unicorn/unicorn.vcxproj
+++ b/msvc/unicorn/unicorn/unicorn.vcxproj
@@ -53,6 +53,7 @@
+
@@ -357,7 +358,16 @@ copy "$(SolutionDir)..\include\unicorn\*.h" "$(SolutionDir)distro\include\unicor
+
+
+ true
+ true
+ false
+ false
+
+
+
-
+
\ No newline at end of file
diff --git a/msvc/unicorn/unicorn/unicorn.vcxproj.filters b/msvc/unicorn/unicorn/unicorn.vcxproj.filters
index 149590fc..da3121fc 100644
--- a/msvc/unicorn/unicorn/unicorn.vcxproj.filters
+++ b/msvc/unicorn/unicorn/unicorn.vcxproj.filters
@@ -499,4 +499,7 @@
+
+
+
\ No newline at end of file
diff --git a/msvc/unicorn/unicorn_static/unicorn_static.vcxproj b/msvc/unicorn/unicorn_static/unicorn_static.vcxproj
index 08d8cd02..57551e52 100644
--- a/msvc/unicorn/unicorn_static/unicorn_static.vcxproj
+++ b/msvc/unicorn/unicorn_static/unicorn_static.vcxproj
@@ -169,6 +169,14 @@
+
+
+ true
+ true
+ false
+ false
+
+
{B6EFD6D7-C2D4-4FBB-B363-2E08CE09CC96}
Win32Proj
@@ -204,6 +212,7 @@
+
@@ -363,5 +372,6 @@ copy "$(SolutionDir)..\include\unicorn\*.h" "$(SolutionDir)distro\include\unicor
+
-
+
\ No newline at end of file
diff --git a/msvc/unicorn/unicorn_static/unicorn_static.vcxproj.filters b/msvc/unicorn/unicorn_static/unicorn_static.vcxproj.filters
index 8dd77e0a..121c3eee 100644
--- a/msvc/unicorn/unicorn_static/unicorn_static.vcxproj.filters
+++ b/msvc/unicorn/unicorn_static/unicorn_static.vcxproj.filters
@@ -498,4 +498,7 @@
qemu
+
+
+
\ No newline at end of file
diff --git a/qemu/include/sysemu/os-win32.h b/qemu/include/sysemu/os-win32.h
index 5d7b1d83..7825c310 100644
--- a/qemu/include/sysemu/os-win32.h
+++ b/qemu/include/sysemu/os-win32.h
@@ -56,13 +56,27 @@
# define EWOULDBLOCK WSAEWOULDBLOCK
#endif
-#if defined(_WIN64) && !defined(_MSC_VER)
+#if defined(_WIN64)
/* On w64, setjmp is implemented by _setjmp which needs a second parameter.
* If this parameter is NULL, longjump does no stack unwinding.
* That is what we need for QEMU. Passing the value of register rsp (default)
* lets longjmp try a stack unwinding which will crash with generated code. */
+
+#if defined(_MSC_VER) // MSVC
+
+// See qemu/include/utils/setjmp-wrapper-win32.asm for details.
+extern int _setjmp_wrapper(jmp_buf);
+
+# undef setjmp
+# define setjmp(env) _setjmp_wrapper(env)
+
+#else // MinGW
+
+// Original QEMU patch.
# undef setjmp
# define setjmp(env) _setjmp(env, NULL)
+#endif
+
#endif
/* QEMU uses sigsetjmp()/siglongjmp() as the portable way to specify
* "longjmp and don't touch the signal masks". Since we know that the
diff --git a/qemu/util/setjmp-wrapper-win32.asm b/qemu/util/setjmp-wrapper-win32.asm
new file mode 100644
index 00000000..6e6b6ab9
--- /dev/null
+++ b/qemu/util/setjmp-wrapper-win32.asm
@@ -0,0 +1,26 @@
+EXTERN _setjmp: proc
+PUBLIC _setjmp_wrapper
+
+_TEXT SEGMENT
+
+_setjmp_wrapper PROC
+
+; Why do we need this wrapper?
+; Short answer: Windows default implementation of setjmp/longjmp is incompatible with generated code.
+; A longer answer: https://blog.lazym.io/2020/09/21/Unicorn-Devblog-setjmp-longjmp-on-Windows/.
+
+; From qemu os-win32 comments:
+; > On w64, setjmp is implemented by _setjmp which needs a second parameter.
+; > If this parameter is NULL, longjump does no stack unwinding.
+; > That is what we need for QEMU. Passing the value of register rsp (default)
+; > lets longjmp try a stack unwinding which will crash with generated code.
+; It's true indeed, but MSVC doesn't has a setjmp signature which receives two arguements.
+; Therefore, we add a wrapper to keep the second argument zero.
+xor rdx, rdx
+jmp _setjmp
+
+_setjmp_wrapper ENDP
+
+_TEXT ENDS
+
+END
\ No newline at end of file