diff --git a/base/applications/network/ftp/CMakeLists.txt b/base/applications/network/ftp/CMakeLists.txt index 7609b313c35..53e608161f9 100644 --- a/base/applications/network/ftp/CMakeLists.txt +++ b/base/applications/network/ftp/CMakeLists.txt @@ -13,8 +13,8 @@ add_executable(ftp ${SOURCE} ftp.rc) target_compile_definitions(ftp PRIVATE lint) set_module_type(ftp win32cui) +target_link_libraries(ftp oldnames ${PSEH_LIB}) add_importlibs(ftp ws2_32 iphlpapi msvcrt kernel32) -target_link_libraries(ftp oldnames) add_pch(ftp precomp.h SOURCE) if(MSVC) diff --git a/dll/3rdparty/libpng/CMakeLists.txt b/dll/3rdparty/libpng/CMakeLists.txt index a5b3849377f..a746743f181 100644 --- a/dll/3rdparty/libpng/CMakeLists.txt +++ b/dll/3rdparty/libpng/CMakeLists.txt @@ -31,7 +31,7 @@ list(APPEND SOURCE add_library(libpng MODULE ${SOURCE} ${CMAKE_CURRENT_BINARY_DIR}/libpng.def) set_module_type(libpng win32dll) -target_link_libraries(libpng zlib) +target_link_libraries(libpng zlib ${PSEH_LIB}) add_importlibs(libpng msvcrt kernel32 ntdll) add_pch(libpng pngpriv.h SOURCE) add_cd_file(TARGET libpng DESTINATION reactos/system32 FOR all) diff --git a/dll/opengl/glu32/CMakeLists.txt b/dll/opengl/glu32/CMakeLists.txt index 82e36ce5508..edb9f1bf8e5 100644 --- a/dll/opengl/glu32/CMakeLists.txt +++ b/dll/opengl/glu32/CMakeLists.txt @@ -116,7 +116,7 @@ add_library(glu32 MODULE ${PCH_SKIP_SOURCE} glu32.rc ${CMAKE_CURRENT_BINARY_DIR}/glu32.def) -target_link_libraries(glu32 cpprt) +target_link_libraries(glu32 cpprt ${PSEH_LIB}) set_module_type(glu32 win32dll) diff --git a/hal/halx86/CMakeLists.txt b/hal/halx86/CMakeLists.txt index 193a4ab8ab8..830b4c52393 100644 --- a/hal/halx86/CMakeLists.txt +++ b/hal/halx86/CMakeLists.txt @@ -23,9 +23,9 @@ function(add_hal _halname) ${CMAKE_CURRENT_BINARY_DIR}/hal.def) if(${_halname} STREQUAL "hal") - target_link_libraries(${_halname} libcntpr arbiter fast486) + target_link_libraries(${_halname} libcntpr arbiter fast486 ${PSEH_LIB}) else() - target_link_libraries(${_halname} libcntpr fast486) + target_link_libraries(${_halname} libcntpr fast486 ${PSEH_LIB}) endif() add_importlibs(${_halname} ntoskrnl) diff --git a/sdk/lib/pseh/i386/pseh3.c b/sdk/lib/pseh/i386/pseh3.c index 2ad8fdfa5d1..46c55a5a01c 100644 --- a/sdk/lib/pseh/i386/pseh3.c +++ b/sdk/lib/pseh/i386/pseh3.c @@ -447,3 +447,49 @@ _SEH3$_CPP_except_handler( { return _SEH3$_common_except_handler(ExceptionRecord, EstablisherFrame, ContextRecord, DispatcherContext, _SEH3$_CPP_HANDLER); } + +void +__stdcall +_SEH3$_longjmp_unwind(_JUMP_BUFFER* _Buf) +{ + PSEH3$_REGISTRATION_FRAME RegisteredFrame = (PSEH3$_REGISTRATION_FRAME)_Buf->Registration; + PSEH3$_REGISTRATION_FRAME CurrentFrame; + + /* Native SEH registers the EH frame at the start of the function, so a call to + _setjmp(3) will always save that EH frame. PSEH only registers the frame + when entering a try block, so a call to _setjmp outside of a try block + would save a previously installed EH frame, which can be of a different + type (e.g. native EH3/EH4). We need to check whether the frame is ours + by comparing its address to the saved ebp value, which marks the boundary + of the stack frame for the caller of _setjmp. */ + if (_Buf->Registration > _Buf->Ebp) + { + /* The registration frame is not ours, we don't need to do anything */ + return; + } + + /* Loop all frames for this registration */ + for (CurrentFrame = RegisteredFrame->EndOfChain; + CurrentFrame->TryLevel != _Buf->TryLevel; + CurrentFrame = CurrentFrame->Next) + { + /* Check if this is a termination handler */ + if (CurrentFrame->ScopeTable->Target == NULL) + { + /* Call the termination handler */ + if (RegisteredFrame->Handler == _SEH3$_C_except_handler) + { +#ifdef __clang__ + _SEH3$_CallFinally(CurrentFrame, _SEH3$_CLANG_HANDLER); +#else + _SEH3$_CallFinally(CurrentFrame, _SEH3$_NESTED_HANDLER); +#endif + } + else + { + ASSERT(CurrentFrame->Handler == _SEH3$_CPP_except_handler); + _SEH3$_CallFinally(CurrentFrame, _SEH3$_CPP_HANDLER); + } + } + } +} diff --git a/sdk/lib/pseh/include/pseh/pseh3.h b/sdk/lib/pseh/include/pseh/pseh3.h index b8b5a519896..ce1ea5d0489 100644 --- a/sdk/lib/pseh/include/pseh/pseh3.h +++ b/sdk/lib/pseh/include/pseh/pseh3.h @@ -11,6 +11,7 @@ #define _PSEH3_H_ #include +#include #ifdef __cplusplus extern "C" { @@ -495,6 +496,14 @@ _Pragma("GCC diagnostic pop") \ #define _SEH3_VOLATILE volatile +int _setjmp3(jmp_buf env, int count, ...); +void __stdcall _SEH3$_longjmp_unwind(_JUMP_BUFFER* _Buf); + +#undef setjmp +#define setjmp(env) \ + _setjmp3(env, 2, (const void*)_SEH3$_longjmp_unwind, _SEH3$_TryLevel) + +#define _INC_SETJMPEX #ifdef __cplusplus }; // extern "C" diff --git a/win32ss/drivers/font/ftfd/CMakeLists.txt b/win32ss/drivers/font/ftfd/CMakeLists.txt index 442dad57d69..47ecd2c8475 100644 --- a/win32ss/drivers/font/ftfd/CMakeLists.txt +++ b/win32ss/drivers/font/ftfd/CMakeLists.txt @@ -18,7 +18,7 @@ add_library(ftfd MODULE ${CMAKE_CURRENT_BINARY_DIR}/ftfd.def) set_module_type(ftfd kerneldll ENTRYPOINT FtfdEnableDriver 12) -target_link_libraries(ftfd freetype libcntpr) +target_link_libraries(ftfd freetype libcntpr ${PSEH_LIB}) add_pch(ftfd ftfd.h "${PCH_SKIP_SOURCE}") add_importlibs(ftfd win32k) add_dependencies(ftfd psdk)