Fix setjmp/longjmp on native Windows (#1331)
* Add setjmp wrapper * Add to projects * Use wrapper on x64 * Always build on x64 and exclude on win32 * Fix signature * Add comments * Add comments for os-win32.h * Add extern decleration * Support cmake Windows build * Fix for MinGW
This commit is contained in:
parent
225f6f2889
commit
644da9babc
@ -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}
|
||||
|
@ -53,6 +53,7 @@
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
@ -357,7 +358,16 @@ copy "$(SolutionDir)..\include\unicorn\*.h" "$(SolutionDir)distro\include\unicor
|
||||
<ClInclude Include="..\qapi-types.h" />
|
||||
<ClInclude Include="..\qapi-visit.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<MASM Include="..\..\..\qemu\util\setjmp-wrapper-win32.asm">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild>
|
||||
</MASM>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" />
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
</Project>
|
@ -499,4 +499,7 @@
|
||||
<ClInclude Include="..\..\..\include\unicorn\unicorn.h" />
|
||||
<ClInclude Include="..\..\..\include\unicorn\x86.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<MASM Include="..\..\..\qemu\util\setjmp-wrapper-win32.asm" />
|
||||
</ItemGroup>
|
||||
</Project>
|
@ -169,6 +169,14 @@
|
||||
<ClInclude Include="..\qapi-types.h" />
|
||||
<ClInclude Include="..\qapi-visit.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<MASM Include="..\..\..\qemu\util\setjmp-wrapper-win32.asm">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild>
|
||||
</MASM>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{B6EFD6D7-C2D4-4FBB-B363-2E08CE09CC96}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
@ -204,6 +212,7 @@
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
@ -363,5 +372,6 @@ copy "$(SolutionDir)..\include\unicorn\*.h" "$(SolutionDir)distro\include\unicor
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" />
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
</Project>
|
@ -498,4 +498,7 @@
|
||||
<Filter>qemu</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<MASM Include="..\..\..\qemu\util\setjmp-wrapper-win32.asm" />
|
||||
</ItemGroup>
|
||||
</Project>
|
@ -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
|
||||
|
26
qemu/util/setjmp-wrapper-win32.asm
Normal file
26
qemu/util/setjmp-wrapper-win32.asm
Normal file
@ -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
|
Loading…
x
Reference in New Issue
Block a user