Note: there are symlinks from i386 to i486, i586, and i686 that I couldn't get to show up in the patch. This patch adds pseh files for x86_64 and changes the build system accordingly so pseh can be built for x86_64. Please tell me if there's anything wrong with this.
diff -Naur --no-dereference a/mingw-w64/mingw-w64-libraries/pseh/configure b/mingw-w64/mingw-w64-libraries/pseh/configure --- a/mingw-w64/mingw-w64-libraries/pseh/configure 2018-10-21 19:43:00.455270976 -0400 +++ b/mingw-w64/mingw-w64-libraries/pseh/configure 2018-10-26 11:06:18.133426429 -0400 @@ -706,6 +706,7 @@ docdir oldincludedir includedir +runstatedir localstatedir sharedstatedir sysconfdir @@ -780,6 +781,7 @@ sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' +runstatedir='${localstatedir}/run' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' @@ -1032,6 +1034,15 @@ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; + -runstatedir | --runstatedir | --runstatedi | --runstated \ + | --runstate | --runstat | --runsta | --runst | --runs \ + | --run | --ru | --r) + ac_prev=runstatedir ;; + -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ + | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ + | --run=* | --ru=* | --r=*) + runstatedir=$ac_optarg ;; + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ @@ -1169,7 +1180,7 @@ for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ - libdir localedir mandir + libdir localedir mandir runstatedir do eval ac_val=\$$ac_var # Remove trailing slashes. @@ -1322,6 +1333,7 @@ --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] @@ -2734,15 +2746,6 @@ -case $host in #( - i*86-*-mingw*) : - ;; #( - *) : - as_fn_error $? "Only x86 32-bit Win32 host variants are supported" "$LINENO" 5 ;; #( - *) : - ;; -esac - # Checks for programs. ac_ext=c ac_cpp='$CPP $CPPFLAGS' diff -Naur --no-dereference a/mingw-w64/mingw-w64-libraries/pseh/ configure.ac b/mingw-w64/mingw-w64-libraries/pseh/configure.ac --- a/mingw-w64/mingw-w64-libraries/pseh/configure.ac 2018-10-21 19:43:00.455270976 -0400 +++ b/mingw-w64/mingw-w64-libraries/pseh/configure.ac 2018-10-21 19:48:58.000000000 -0400 @@ -11,10 +11,6 @@ AC_CANONICAL_HOST -AS_CASE([$host], - [i*86-*-mingw*],[], - [*],[AC_MSG_ERROR([Only x86 32-bit Win32 host variants are supported])]) - # Checks for programs. AC_PROG_CC AC_PROG_RANLIB diff -Naur --no-dereference a/mingw-w64/mingw-w64-libraries/pseh/Makefile.am b/mingw-w64/mingw-w64-libraries/pseh/Makefile.am --- a/mingw-w64/mingw-w64-libraries/pseh/Makefile.am 2018-10-21 19:43:00.455270976 -0400 +++ b/mingw-w64/mingw-w64-libraries/pseh/Makefile.am 2018-10-26 11:05:36.053217764 -0400 @@ -6,10 +6,10 @@ lib_LIBRARIES = libpseh.a libpseh_a_SOURCES = \ - src/framebased.c \ - src/i386/framebased-gcchack-asm.S \ - src/i386/framebased-gcchack.c \ - src/i386/framebased.S + src/@host_cpu@/framebased.c \ + src/@host_cpu@/framebased-gcchack-asm.S \ + src/@host_cpu@/framebased-gcchack.c \ + src/@host_cpu@/framebased-asm.S psehdir = $(includedir)/pseh framebaseddir = $(psehdir)/framebased diff -Naur --no-dereference a/mingw-w64/mingw-w64-libraries/pseh/Makefile.in b/mingw-w64/mingw-w64-libraries/pseh/Makefile.in --- a/mingw-w64/mingw-w64-libraries/pseh/Makefile.in 2018-10-21 19:43:00.455270976 -0400 +++ b/mingw-w64/mingw-w64-libraries/pseh/Makefile.in 2018-10-26 11:06:19.229431863 -0400 @@ -142,10 +142,10 @@ libpseh_a_AR = $(AR) $(ARFLAGS) libpseh_a_LIBADD = am__dirstamp = $(am__leading_dot)dirstamp -am_libpseh_a_OBJECTS = src/framebased.$(OBJEXT) \ - src/i386/framebased-gcchack-asm.$(OBJEXT) \ - src/i386/framebased-gcchack.$(OBJEXT) \ - src/i386/framebased.$(OBJEXT) +am_libpseh_a_OBJECTS = src/@host_cpu@/framebased.$(OBJEXT) \ + src/@host_cpu@/framebased-gcchack-asm.$(OBJEXT) \ + src/@host_cpu@/framebased-gcchack.$(OBJEXT) \ + src/@host_cpu@/framebased-asm.$(OBJEXT) libpseh_a_OBJECTS = $(am_libpseh_a_OBJECTS) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) @@ -328,6 +328,7 @@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ +runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ @@ -341,10 +342,10 @@ AM_CFLAGS = -Wall -Wstrict-aliasing=2 -pedantic lib_LIBRARIES = libpseh.a libpseh_a_SOURCES = \ - src/framebased.c \ - src/i386/framebased-gcchack-asm.S \ - src/i386/framebased-gcchack.c \ - src/i386/framebased.S + src/@host_cpu@/framebased.c \ + src/@host_cpu@/framebased-gcchack-asm.S \ + src/@host_cpu@/framebased-gcchack.c \ + src/@host_cpu@/framebased-asm.S psehdir = $(includedir)/pseh framebaseddir = $(psehdir)/framebased @@ -440,26 +441,23 @@ clean-libLIBRARIES: -test -z "$(lib_LIBRARIES)" || rm -f $(lib_LIBRARIES) -src/$(am__dirstamp): - @$(MKDIR_P) src - @: > src/$(am__dirstamp) -src/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) src/$(DEPDIR) - @: > src/$(DEPDIR)/$(am__dirstamp) -src/framebased.$(OBJEXT): src/$(am__dirstamp) \ - src/$(DEPDIR)/$(am__dirstamp) -src/i386/$(am__dirstamp): - @$(MKDIR_P) src/i386 - @: > src/i386/$(am__dirstamp) -src/i386/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) src/i386/$(DEPDIR) - @: > src/i386/$(DEPDIR)/$(am__dirstamp) -src/i386/framebased-gcchack-asm.$(OBJEXT): src/i386/$(am__dirstamp) \ - src/i386/$(DEPDIR)/$(am__dirstamp) -src/i386/framebased-gcchack.$(OBJEXT): src/i386/$(am__dirstamp) \ - src/i386/$(DEPDIR)/$(am__dirstamp) -src/i386/framebased.$(OBJEXT): src/i386/$(am__dirstamp) \ - src/i386/$(DEPDIR)/$(am__dirstamp) +src/@host_cpu@/$(am__dirstamp): + @$(MKDIR_P) src/@host_cpu@ + @: > src/@host_cpu@/$(am__dirstamp) +src/@host_cpu@/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) src/@host_cpu@/$(DEPDIR) + @: > src/@host_cpu@/$(DEPDIR)/$(am__dirstamp) +src/@host_cpu@/framebased.$(OBJEXT): src/@host_cpu@/$(am__dirstamp) \ + src/@host_cpu@/$(DEPDIR)/$(am__dirstamp) +src/@host_cpu@/framebased-gcchack-asm.$(OBJEXT): \ + src/@host_cpu@/$(am__dirstamp) \ + src/@host_cpu@/$(DEPDIR)/$(am__dirstamp) +src/@host_cpu@/framebased-gcchack.$(OBJEXT): \ + src/@host_cpu@/$(am__dirstamp) \ + src/@host_cpu@/$(DEPDIR)/$(am__dirstamp) +src/@host_cpu@/framebased-asm.$(OBJEXT): \ + src/@host_cpu@/$(am__dirstamp) \ + src/@host_cpu@/$(DEPDIR)/$(am__dirstamp) libpseh.a: $(libpseh_a_OBJECTS) $(libpseh_a_DEPENDENCIES) $(EXTRA_libpseh_a_DEPENDENCIES) $(AM_V_at)-rm -f libpseh.a @@ -468,16 +466,15 @@ mostlyclean-compile: -rm -f *.$(OBJEXT) - -rm -f src/*.$(OBJEXT) - -rm -f src/i386/*.$(OBJEXT) + -rm -f src/@host_cpu@/*.$(OBJEXT) distclean-compile: -rm -f *.tab.c -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/framebased.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src /i386/$(DEPDIR)/framebased-gcchack-asm.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src /i386/$(DEPDIR)/framebased-gcchack.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src /i386/$(DEPDIR)/framebased.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/@host_cpu@ /$(DEPDIR)/framebased-asm.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/@host_cpu@ /$(DEPDIR)/framebased-gcchack-asm.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/@host_cpu@ /$(DEPDIR)/framebased-gcchack.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/@host_cpu@ /$(DEPDIR)/framebased.Po@am__quote@ .S.o: @am__fastdepCCAS_TRUE@ $(AM_V_CPPAS)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @@ -808,10 +805,8 @@ distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -rm -f src/$(DEPDIR)/$(am__dirstamp) - -rm -f src/$(am__dirstamp) - -rm -f src/i386/$(DEPDIR)/$(am__dirstamp) - -rm -f src/i386/$(am__dirstamp) + -rm -f src/@host_cpu@/$(DEPDIR)/$(am__dirstamp) + -rm -f src/@host_cpu@/$(am__dirstamp) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @@ -822,7 +817,7 @@ distclean: distclean-am -rm -f $(am__CONFIG_DISTCLEAN_FILES) - -rm -rf src/$(DEPDIR) src/i386/$(DEPDIR) + -rm -rf src/@host_cpu@/$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-hdr distclean-tags @@ -870,7 +865,7 @@ maintainer-clean: maintainer-clean-am -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf $(top_srcdir)/autom4te.cache - -rm -rf src/$(DEPDIR) src/i386/$(DEPDIR) + -rm -rf src/@host_cpu@/$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic diff -Naur --no-dereference a/mingw-w64/mingw-w64-libraries/pseh/src/framebased.c b/mingw-w64/mingw-w64-libraries/pseh/src/framebased.c --- a/mingw-w64/mingw-w64-libraries/pseh/src/framebased.c 2018-10-21 19:43:00.459270996 -0400 +++ b/mingw-w64/mingw-w64-libraries/pseh/src/framebased.c 1969-12-31 19:00:00.000000000 -0500 @@ -1,499 +0,0 @@ -/* - Copyright (c) 2004/2005 KJK::Hyperion - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. -*/ - -#define _NTSYSTEM_ -#define STRICT -#define WIN32_LEAN_AND_MEAN -#include <windows.h> - -#include <pseh/pseh.h> -#include <pseh/framebased/internal.h> -#include <pseh/excpt.h> -#include <pseh/framebased.h> - -#include <excpt.h> - -/* Tracing */ -#ifdef _SEH_ENABLE_TRACE -extern unsigned long __cdecl DbgPrint(const char * format, ...); - -#define _SEH_TRACE_HEADER_(FRAME_) \ - DbgPrint("[PSEH:%p]%s:%d:", FRAME_, __FILE__, __LINE__); - -#define _SEH_TRACE_TRAILER_ \ - DbgPrint("\n"); - -#define _SEH_FILTER_RET_STRING_(RET_) \ - (((int)(RET_) < 0) ? "_SEH_CONTINUE_EXECUTION" : (((int)(RET_) > 0) ? "_SEH_EXECUTE_HANDLER" : "_SEH_CONTINUE_SEARCH")) - -#define _SEH_TRACE_LINE_(FRAME_, ARGS_) \ -{ \ - _SEH_TRACE_HEADER_(FRAME_); \ - DbgPrint ARGS_; \ - _SEH_TRACE_TRAILER_; \ -} - -#define _SEH_TRACE_ENTER(FRAME_, FUNCNAME_, ARGS_) \ -{ \ - if((FRAME_)->SPF_Tracing & _SEH_DO_TRACE_ENTER_LEAVE) \ - { \ - _SEH_TRACE_HEADER_(FRAME_); \ - DbgPrint(">>> %s(", (FUNCNAME_)); \ - DbgPrint ARGS_; \ - DbgPrint(")"); \ - _SEH_TRACE_TRAILER_; \ - } \ -} - -#define _SEH_TRACE_LEAVE(FRAME_, FUNCNAME_, ARGS_) \ -{ \ - if((FRAME_)->SPF_Tracing & _SEH_DO_TRACE_ENTER_LEAVE) \ - { \ - _SEH_TRACE_HEADER_(FRAME_); \ - DbgPrint("<<< %s => ", (FUNCNAME_)); \ - DbgPrint ARGS_; \ - _SEH_TRACE_TRAILER_; \ - } \ -} - -#define _SEH_TRACE_EXCEPTION_RECORD(FRAME_, ER_) \ -{ \ - if((FRAME_)->SPF_Tracing & _SEH_DO_TRACE_EXCEPTION_RECORD) \ - { \ - _SEH_TRACE_LINE_ \ - ( \ - (FRAME_), \ - ( \ - "ExceptionRecord %p = { ExceptionCode : %08X, ExceptionFlags : %08X, ExceptionRecord : %p, ExceptionAddress : %p }", \ - (ER_), \ - (ER_)->ExceptionCode, \ - (ER_)->ExceptionFlags, \ - (ER_)->ExceptionRecord, \ - (ER_)->ExceptionAddress \ - ) \ - ); \ - } \ -} - -#ifdef _X86_ -#define _SEH_TRACE_CONTEXT(FRAME_, CONTEXT_) \ -{ \ - if((FRAME_)->SPF_Tracing & _SEH_DO_TRACE_CONTEXT) \ - { \ - if(((CONTEXT_)->ContextFlags & CONTEXT_INTEGER) == CONTEXT_INTEGER) \ - { \ - _SEH_TRACE_LINE_ \ - ( \ - (FRAME_), \ - ( \ - "eax=%08X ebx=%08X ecx=%08X edx=%08X esi=%08X edi=%08X", \ - (CONTEXT_)->Eax, \ - (CONTEXT_)->Ebx, \ - (CONTEXT_)->Ecx, \ - (CONTEXT_)->Edx, \ - (CONTEXT_)->Esi, \ - (CONTEXT_)->Edi \ - ) \ - ); \ - } \ - \ - if(((CONTEXT_)->ContextFlags & CONTEXT_CONTROL) == CONTEXT_CONTROL) \ - { \ - _SEH_TRACE_LINE_ \ - ( \ - (FRAME_), \ - ( \ - "eip=%08X esp=%08X ebp=%08X efl=%08X cs=%08X ss=%08X", \ - (CONTEXT_)->Eip, \ - (CONTEXT_)->Esp, \ - (CONTEXT_)->Ebp, \ - (CONTEXT_)->EFlags, \ - (CONTEXT_)->SegCs, \ - (CONTEXT_)->SegSs \ - ) \ - ); \ - } \ - \ - if(((CONTEXT_)->ContextFlags & CONTEXT_SEGMENTS) == CONTEXT_SEGMENTS) \ - { \ - _SEH_TRACE_LINE_ \ - ( \ - (FRAME_), \ - ( \ - "ds=%08X es=%08X fs=%08X gs=%08X", \ - (CONTEXT_)->SegDs, \ - (CONTEXT_)->SegEs, \ - (CONTEXT_)->SegFs, \ - (CONTEXT_)->SegGs \ - ) \ - ); \ - } \ - } \ -} -#else -#define _SEH_TRACE_CONTEXT(FRAME_, CONTEXT_) -#endif - -#define _SEH_TRACE_UNWIND(FRAME_, ARGS_) \ -{ \ - if((FRAME_)->SPF_Tracing & _SEH_DO_TRACE_UNWIND) \ - { \ - _SEH_TRACE_LINE_((FRAME_), ARGS_); \ - } \ -} - -#define _SEH_TRACE_TRYLEVEL(FRAME_, TRYLEVEL_) \ -{ \ - if((FRAME_)->SPF_Tracing & _SEH_DO_TRACE_TRYLEVEL) \ - { \ - _SEH_TRACE_LINE_((FRAME_), ("trylevel %p, filter %p", (TRYLEVEL_), (TRYLEVEL_)->SPT_Handlers.SH_Filter)); \ - } \ -} - -#define _SEH_TRACE_ENTER_CALL_FILTER(FRAME_, TRYLEVEL_, ER_) \ -{ \ - if((FRAME_)->SPF_Tracing & _SEH_DO_TRACE_CALL_FILTER) \ - { \ - _SEH_TRACE_LINE_ \ - ( \ - (FRAME_), \ - ( \ - "trylevel %p, calling filter %p, ExceptionCode %08X", \ - (TRYLEVEL_), \ - (TRYLEVEL_)->SPT_Handlers.SH_Filter, \ - (ER_)->ExceptionCode \ - ) \ - ); \ - } \ -} - -#define _SEH_TRACE_LEAVE_CALL_FILTER(FRAME_, TRYLEVEL_, RET_) \ -{ \ - if((FRAME_)->SPF_Tracing & _SEH_DO_TRACE_CALL_FILTER) \ - { \ - _SEH_TRACE_LINE_ \ - ( \ - (FRAME_), \ - ( \ - "trylevel %p, filter %p => %s", \ - (TRYLEVEL_), \ - (TRYLEVEL_)->SPT_Handlers.SH_Filter, \ - _SEH_FILTER_RET_STRING_(RET_) \ - ) \ - ); \ - } \ -} - -#define _SEH_TRACE_FILTER(FRAME_, TRYLEVEL_, RET_) \ -{ \ - if((FRAME_)->SPF_Tracing & _SEH_DO_TRACE_FILTER) \ - { \ - _SEH_TRACE_LINE_ \ - ( \ - (FRAME_), \ - ( \ - "trylevel %p => %s", \ - (TRYLEVEL_), \ - _SEH_FILTER_RET_STRING_(RET_) \ - ) \ - ); \ - } \ -} - -#define _SEH_TRACE_ENTER_CALL_HANDLER(FRAME_, TRYLEVEL_) \ -{ \ - if((FRAME_)->SPF_Tracing & _SEH_DO_TRACE_CALL_HANDLER) \ - { \ - _SEH_TRACE_LINE_((FRAME_), ("trylevel %p, handling", (TRYLEVEL_))); \ - } \ -} - -#define _SEH_TRACE_ENTER_CALL_FINALLY(FRAME_, TRYLEVEL_) \ -{ \ - if((FRAME_)->SPF_Tracing & _SEH_DO_TRACE_CALL_FINALLY) \ - { \ - _SEH_TRACE_LINE_ \ - ( \ - (FRAME_), \ - ( \ - "trylevel %p, calling exit routine %p", \ - (TRYLEVEL_), \ - (TRYLEVEL_)->SPT_Handlers.SH_Finally \ - ) \ - ); \ - } \ -} - -#define _SEH_TRACE_LEAVE_CALL_FINALLY(FRAME_, TRYLEVEL_) \ -{ \ - if((FRAME_)->SPF_Tracing & _SEH_DO_TRACE_CALL_FINALLY) \ - { \ - _SEH_TRACE_LINE_ \ - ( \ - (FRAME_), \ - ( \ - "trylevel %p, exit routine %p returned", \ - (TRYLEVEL_), \ - (TRYLEVEL_)->SPT_Handlers.SH_Finally \ - ) \ - ); \ - } \ -} - -#else -#define _SEH_TRACE_ENTER(FRAME_, FUNCNAME_, ARGS_) -#define _SEH_TRACE_LEAVE(FRAME_, FUNCNAME_, ARGS_) -#define _SEH_TRACE_EXCEPTION_RECORD(FRAME_, ER_) -#define _SEH_TRACE_CONTEXT(FRAME_, CONTEXT_) -#define _SEH_TRACE_UNWIND(FRAME_, ARGS_) -#define _SEH_TRACE_TRYLEVEL(FRAME_, TRYLEVEL_) -#define _SEH_TRACE_ENTER_CALL_FILTER(FRAME_, TRYLEVEL_, ER_) -#define _SEH_TRACE_LEAVE_CALL_FILTER(FRAME_, TRYLEVEL_, RET_) -#define _SEH_TRACE_FILTER(FRAME_, TRYLEVEL_, RET_) -#define _SEH_TRACE_ENTER_CALL_HANDLER(FRAME_, TRYLEVEL_) -#define _SEH_TRACE_ENTER_CALL_FINALLY(FRAME_, TRYLEVEL_) -#define _SEH_TRACE_LEAVE_CALL_FINALLY(FRAME_, TRYLEVEL_) -#endif - -/* Assembly helpers, see i386/framebased.asm */ -extern void __cdecl _SEHCleanHandlerEnvironment(void); -extern struct __SEHRegistration * __cdecl _SEHRegisterFrame(_SEHRegistration_t *); -extern void __cdecl _SEHUnregisterFrame(void); -extern void __cdecl _SEHGlobalUnwind(_SEHPortableFrame_t *); -extern _SEHRegistration_t * __cdecl _SEHCurrentRegistration(void); - -static void __stdcall _SEHLocalUnwind -( - _SEHPortableFrame_t * frame, - _SEHPortableTryLevel_t * dsttrylevel -) -{ - _SEHPortableTryLevel_t * trylevel; - - _SEH_TRACE_UNWIND(frame, ("enter local unwind from %p to %p", frame->SPF_TopTryLevel, dsttrylevel)); - - for - ( - trylevel = frame->SPF_TopTryLevel; - trylevel != dsttrylevel; - trylevel = trylevel->SPT_Next - ) - { - _SEHFinally_t pfnFinally; - - /* ASSERT(trylevel); */ - - pfnFinally = trylevel->SPT_Handlers.SH_Finally; - - if(pfnFinally) - { - _SEH_TRACE_ENTER_CALL_FINALLY(frame, trylevel); - pfnFinally(frame); - _SEH_TRACE_LEAVE_CALL_FINALLY(frame, trylevel); - } - } - - _SEH_TRACE_UNWIND(frame, ("leave local unwind from %p to %p", frame->SPF_TopTryLevel, dsttrylevel)); -} - -static void __cdecl _SEHCallHandler -( - _SEHPortableFrame_t * frame, - _SEHPortableTryLevel_t * trylevel -) -{ - _SEHGlobalUnwind(frame); - _SEHLocalUnwind(frame, trylevel); - _SEH_TRACE_ENTER_CALL_HANDLER(frame, trylevel); - frame->SPF_Handler(trylevel); - /* ASSERT(0); */ -} - -static int __cdecl _SEHFrameHandler -( - struct _EXCEPTION_RECORD * ExceptionRecord, - void * EstablisherFrame, - struct _CONTEXT * ContextRecord, - void * DispatcherContext -) -{ - _SEHPortableFrame_t * frame; - - _SEHCleanHandlerEnvironment(); - - frame = EstablisherFrame; - - _SEH_TRACE_ENTER - ( - frame, - "_SEHFrameHandler", - ( - "%p, %p, %p, %p", - ExceptionRecord, - EstablisherFrame, - ContextRecord, - DispatcherContext - ) - ); - - _SEH_TRACE_EXCEPTION_RECORD(frame, ExceptionRecord); - _SEH_TRACE_CONTEXT(frame, ContextRecord); - - /* Unwinding */ - if(ExceptionRecord->ExceptionFlags & (4 | 2)) - { - _SEH_TRACE_UNWIND(frame, ("enter forced unwind")); - _SEHLocalUnwind(frame, NULL); - _SEH_TRACE_UNWIND(frame, ("leave forced unwind")); - } - /* Handling */ - else - { - int ret; - _SEHPortableTryLevel_t * trylevel; - - if(ExceptionRecord->ExceptionCode) - frame->SPF_Code = ExceptionRecord->ExceptionCode; - else - frame->SPF_Code = 0xC0000001; - - for - ( - trylevel = frame->SPF_TopTryLevel; - trylevel != NULL; - trylevel = trylevel->SPT_Next - ) - { - _SEHFilter_t pfnFilter = trylevel->SPT_Handlers.SH_Filter; - - _SEH_TRACE_TRYLEVEL(frame, trylevel); - - switch((UINT_PTR)pfnFilter) - { - case __SEH_STATIC_FILTER(_SEH_EXECUTE_HANDLER): - case __SEH_STATIC_FILTER(_SEH_CONTINUE_SEARCH): - case __SEH_STATIC_FILTER(_SEH_CONTINUE_EXECUTION): - { - ret = (int)((UINT_PTR)pfnFilter) - 2; - break; - } - - default: - { - if(trylevel->SPT_Handlers.SH_Filter) - { - EXCEPTION_POINTERS ep; - - ep.ExceptionRecord = ExceptionRecord; - ep.ContextRecord = ContextRecord; - - _SEH_TRACE_ENTER_CALL_FILTER(frame, trylevel, ExceptionRecord); - ret = pfnFilter(&ep, frame); - _SEH_TRACE_LEAVE_CALL_FILTER(frame, trylevel, ret); - } - else - ret = _SEH_CONTINUE_SEARCH; - - break; - } - } - - _SEH_TRACE_FILTER(frame, trylevel, ret); - - /* _SEH_CONTINUE_EXECUTION */ - if(ret < 0) - { - _SEH_TRACE_LEAVE(frame, "_SEHFrameHandler", ("ExceptionContinueExecution")); - return ExceptionContinueExecution; - } - /* _SEH_EXECUTE_HANDLER */ - else if(ret > 0) - _SEHCallHandler(frame, trylevel); - /* _SEH_CONTINUE_SEARCH */ - else - continue; - } - - /* FALLTHROUGH */ - } - - _SEH_TRACE_LEAVE(frame, "_SEHFrameHandler", ("ExceptionContinueSearch")); - return ExceptionContinueSearch; -} - -void __stdcall _SEHEnterFrame_s(_SEHPortableFrame_t * frame) -{ - _SEHEnterFrame_f(frame); -} - -void __stdcall _SEHLeaveFrame_s(void) -{ - _SEHLeaveFrame_f(); -} - -void __stdcall _SEHReturn_s(void) -{ - _SEHReturn_f(); -} - -void _SEH_FASTCALL _SEHEnterFrame_f(_SEHPortableFrame_t * frame) -{ - /* ASSERT(frame); */ - /* ASSERT(trylevel); */ - frame->SPF_Registration.SER_Handler = _SEHFrameHandler; - frame->SPF_Code = 0; - _SEHRegisterFrame(&frame->SPF_Registration); -} - -void _SEH_FASTCALL _SEHLeaveFrame_f(void) -{ - _SEHPortableFrame_t * frame; - - frame = _SEH_CONTAINING_RECORD - ( - _SEHCurrentRegistration(), - _SEHPortableFrame_t, - SPF_Registration - ); - - /* ASSERT(frame); */ - /* ASSERT(frame->SPF_TopTryLevel == NULL) */ - - _SEHUnregisterFrame(); -} - -void _SEH_FASTCALL _SEHReturn_f(void) -{ - _SEHPortableFrame_t * frame; - - frame = _SEH_CONTAINING_RECORD - ( - _SEHCurrentRegistration(), - _SEHPortableFrame_t, - SPF_Registration - ); - - _SEHLocalUnwind(frame, NULL); - _SEHUnregisterFrame(); -} - -/* EOF */ diff -Naur --no-dereference a/mingw-w64/mingw-w64-libraries/pseh/src/i386/framebased-asm.S b/mingw-w64/mingw-w64-libraries/pseh/src/i386/framebased-asm.S --- a/mingw-w64/mingw-w64-libraries/pseh/src/i386/framebased-asm.S 1969-12-31 19:00:00.000000000 -0500 +++ b/mingw-w64/mingw-w64-libraries/pseh/src/i386/framebased-asm.S 2018-10-13 10:36:02.000000000 -0400 @@ -0,0 +1,73 @@ +// Copyright (c) 2004/2005 KJK::Hyperion + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to dos so, subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +.text +.intel_syntax noprefix + +.globl __SEHCleanHandlerEnvironment +__SEHCleanHandlerEnvironment: + cld + ret + +.globl __SEHCurrentRegistration +__SEHCurrentRegistration: + mov eax, [fs:0] + ret + +.globl __SEHRegisterFrame +__SEHRegisterFrame: + mov ecx, [esp+4] + mov eax, [fs:0] + mov [ecx+0], eax + mov [fs:0], ecx + ret + +.globl __SEHUnregisterFrame +__SEHUnregisterFrame: + mov ecx, [fs:0] + mov ecx, [ecx+0] + mov [fs:0], ecx + ret + +.globl __SEHGlobalUnwind +__SEHGlobalUnwind: + +.extern __SEHRtlUnwind + +// RtlUnwind clobbers all the "don't clobber" registers, so we save them + push ebx + mov ebx, [esp+8] + push esi + push edi + + push 0 // ReturnValue + push 0 // ExceptionRecord + push .RestoreRegisters // TargetIp + push ebx // TargetFrame + call _RtlUnwind@16 + +.RestoreRegisters: + pop edi + pop esi + pop ebx + + ret + +// EOF diff -Naur --no-dereference a/mingw-w64/mingw-w64-libraries/pseh/src/i386/framebased.c b/mingw-w64/mingw-w64-libraries/pseh/src/i386/framebased.c --- a/mingw-w64/mingw-w64-libraries/pseh/src/i386/framebased.c 1969-12-31 19:00:00.000000000 -0500 +++ b/mingw-w64/mingw-w64-libraries/pseh/src/i386/framebased.c 2018-10-26 10:55:35.150238047 -0400 @@ -0,0 +1,499 @@ +/* + Copyright (c) 2004/2005 KJK::Hyperion + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#define _NTSYSTEM_ +#define STRICT +#define WIN32_LEAN_AND_MEAN +#include <windows.h> + +#include <pseh/pseh.h> +#include <pseh/framebased/internal.h> +#include <pseh/excpt.h> +#include <pseh/framebased.h> + +#include <excpt.h> + +/* Tracing */ +#ifdef _SEH_ENABLE_TRACE +extern unsigned long __cdecl DbgPrint(const char * format, ...); + +#define _SEH_TRACE_HEADER_(FRAME_) \ + DbgPrint("[PSEH:%p]%s:%d:", FRAME_, __FILE__, __LINE__); + +#define _SEH_TRACE_TRAILER_ \ + DbgPrint("\n"); + +#define _SEH_FILTER_RET_STRING_(RET_) \ + (((int)(RET_) < 0) ? "_SEH_CONTINUE_EXECUTION" : (((int)(RET_) > 0) ? "_SEH_EXECUTE_HANDLER" : "_SEH_CONTINUE_SEARCH")) + +#define _SEH_TRACE_LINE_(FRAME_, ARGS_) \ +{ \ + _SEH_TRACE_HEADER_(FRAME_); \ + DbgPrint ARGS_; \ + _SEH_TRACE_TRAILER_; \ +} + +#define _SEH_TRACE_ENTER(FRAME_, FUNCNAME_, ARGS_) \ +{ \ + if((FRAME_)->SPF_Tracing & _SEH_DO_TRACE_ENTER_LEAVE) \ + { \ + _SEH_TRACE_HEADER_(FRAME_); \ + DbgPrint(">>> %s(", (FUNCNAME_)); \ + DbgPrint ARGS_; \ + DbgPrint(")"); \ + _SEH_TRACE_TRAILER_; \ + } \ +} + +#define _SEH_TRACE_LEAVE(FRAME_, FUNCNAME_, ARGS_) \ +{ \ + if((FRAME_)->SPF_Tracing & _SEH_DO_TRACE_ENTER_LEAVE) \ + { \ + _SEH_TRACE_HEADER_(FRAME_); \ + DbgPrint("<<< %s => ", (FUNCNAME_)); \ + DbgPrint ARGS_; \ + _SEH_TRACE_TRAILER_; \ + } \ +} + +#define _SEH_TRACE_EXCEPTION_RECORD(FRAME_, ER_) \ +{ \ + if((FRAME_)->SPF_Tracing & _SEH_DO_TRACE_EXCEPTION_RECORD) \ + { \ + _SEH_TRACE_LINE_ \ + ( \ + (FRAME_), \ + ( \ + "ExceptionRecord %p = { ExceptionCode : %08X, ExceptionFlags : %08X, ExceptionRecord : %p, ExceptionAddress : %p }", \ + (ER_), \ + (ER_)->ExceptionCode, \ + (ER_)->ExceptionFlags, \ + (ER_)->ExceptionRecord, \ + (ER_)->ExceptionAddress \ + ) \ + ); \ + } \ +} + +#ifdef _X86_ +#define _SEH_TRACE_CONTEXT(FRAME_, CONTEXT_) \ +{ \ + if((FRAME_)->SPF_Tracing & _SEH_DO_TRACE_CONTEXT) \ + { \ + if(((CONTEXT_)->ContextFlags & CONTEXT_INTEGER) == CONTEXT_INTEGER) \ + { \ + _SEH_TRACE_LINE_ \ + ( \ + (FRAME_), \ + ( \ + "eax=%08X ebx=%08X ecx=%08X edx=%08X esi=%08X edi=%08X", \ + (CONTEXT_)->Eax, \ + (CONTEXT_)->Ebx, \ + (CONTEXT_)->Ecx, \ + (CONTEXT_)->Edx, \ + (CONTEXT_)->Esi, \ + (CONTEXT_)->Edi \ + ) \ + ); \ + } \ + \ + if(((CONTEXT_)->ContextFlags & CONTEXT_CONTROL) == CONTEXT_CONTROL) \ + { \ + _SEH_TRACE_LINE_ \ + ( \ + (FRAME_), \ + ( \ + "eip=%08X esp=%08X ebp=%08X efl=%08X cs=%08X ss=%08X", \ + (CONTEXT_)->Eip, \ + (CONTEXT_)->Esp, \ + (CONTEXT_)->Ebp, \ + (CONTEXT_)->EFlags, \ + (CONTEXT_)->SegCs, \ + (CONTEXT_)->SegSs \ + ) \ + ); \ + } \ + \ + if(((CONTEXT_)->ContextFlags & CONTEXT_SEGMENTS) == CONTEXT_SEGMENTS) \ + { \ + _SEH_TRACE_LINE_ \ + ( \ + (FRAME_), \ + ( \ + "ds=%08X es=%08X fs=%08X gs=%08X", \ + (CONTEXT_)->SegDs, \ + (CONTEXT_)->SegEs, \ + (CONTEXT_)->SegFs, \ + (CONTEXT_)->SegGs \ + ) \ + ); \ + } \ + } \ +} +#else +#define _SEH_TRACE_CONTEXT(FRAME_, CONTEXT_) +#endif + +#define _SEH_TRACE_UNWIND(FRAME_, ARGS_) \ +{ \ + if((FRAME_)->SPF_Tracing & _SEH_DO_TRACE_UNWIND) \ + { \ + _SEH_TRACE_LINE_((FRAME_), ARGS_); \ + } \ +} + +#define _SEH_TRACE_TRYLEVEL(FRAME_, TRYLEVEL_) \ +{ \ + if((FRAME_)->SPF_Tracing & _SEH_DO_TRACE_TRYLEVEL) \ + { \ + _SEH_TRACE_LINE_((FRAME_), ("trylevel %p, filter %p", (TRYLEVEL_), (TRYLEVEL_)->SPT_Handlers.SH_Filter)); \ + } \ +} + +#define _SEH_TRACE_ENTER_CALL_FILTER(FRAME_, TRYLEVEL_, ER_) \ +{ \ + if((FRAME_)->SPF_Tracing & _SEH_DO_TRACE_CALL_FILTER) \ + { \ + _SEH_TRACE_LINE_ \ + ( \ + (FRAME_), \ + ( \ + "trylevel %p, calling filter %p, ExceptionCode %08X", \ + (TRYLEVEL_), \ + (TRYLEVEL_)->SPT_Handlers.SH_Filter, \ + (ER_)->ExceptionCode \ + ) \ + ); \ + } \ +} + +#define _SEH_TRACE_LEAVE_CALL_FILTER(FRAME_, TRYLEVEL_, RET_) \ +{ \ + if((FRAME_)->SPF_Tracing & _SEH_DO_TRACE_CALL_FILTER) \ + { \ + _SEH_TRACE_LINE_ \ + ( \ + (FRAME_), \ + ( \ + "trylevel %p, filter %p => %s", \ + (TRYLEVEL_), \ + (TRYLEVEL_)->SPT_Handlers.SH_Filter, \ + _SEH_FILTER_RET_STRING_(RET_) \ + ) \ + ); \ + } \ +} + +#define _SEH_TRACE_FILTER(FRAME_, TRYLEVEL_, RET_) \ +{ \ + if((FRAME_)->SPF_Tracing & _SEH_DO_TRACE_FILTER) \ + { \ + _SEH_TRACE_LINE_ \ + ( \ + (FRAME_), \ + ( \ + "trylevel %p => %s", \ + (TRYLEVEL_), \ + _SEH_FILTER_RET_STRING_(RET_) \ + ) \ + ); \ + } \ +} + +#define _SEH_TRACE_ENTER_CALL_HANDLER(FRAME_, TRYLEVEL_) \ +{ \ + if((FRAME_)->SPF_Tracing & _SEH_DO_TRACE_CALL_HANDLER) \ + { \ + _SEH_TRACE_LINE_((FRAME_), ("trylevel %p, handling", (TRYLEVEL_))); \ + } \ +} + +#define _SEH_TRACE_ENTER_CALL_FINALLY(FRAME_, TRYLEVEL_) \ +{ \ + if((FRAME_)->SPF_Tracing & _SEH_DO_TRACE_CALL_FINALLY) \ + { \ + _SEH_TRACE_LINE_ \ + ( \ + (FRAME_), \ + ( \ + "trylevel %p, calling exit routine %p", \ + (TRYLEVEL_), \ + (TRYLEVEL_)->SPT_Handlers.SH_Finally \ + ) \ + ); \ + } \ +} + +#define _SEH_TRACE_LEAVE_CALL_FINALLY(FRAME_, TRYLEVEL_) \ +{ \ + if((FRAME_)->SPF_Tracing & _SEH_DO_TRACE_CALL_FINALLY) \ + { \ + _SEH_TRACE_LINE_ \ + ( \ + (FRAME_), \ + ( \ + "trylevel %p, exit routine %p returned", \ + (TRYLEVEL_), \ + (TRYLEVEL_)->SPT_Handlers.SH_Finally \ + ) \ + ); \ + } \ +} + +#else +#define _SEH_TRACE_ENTER(FRAME_, FUNCNAME_, ARGS_) +#define _SEH_TRACE_LEAVE(FRAME_, FUNCNAME_, ARGS_) +#define _SEH_TRACE_EXCEPTION_RECORD(FRAME_, ER_) +#define _SEH_TRACE_CONTEXT(FRAME_, CONTEXT_) +#define _SEH_TRACE_UNWIND(FRAME_, ARGS_) +#define _SEH_TRACE_TRYLEVEL(FRAME_, TRYLEVEL_) +#define _SEH_TRACE_ENTER_CALL_FILTER(FRAME_, TRYLEVEL_, ER_) +#define _SEH_TRACE_LEAVE_CALL_FILTER(FRAME_, TRYLEVEL_, RET_) +#define _SEH_TRACE_FILTER(FRAME_, TRYLEVEL_, RET_) +#define _SEH_TRACE_ENTER_CALL_HANDLER(FRAME_, TRYLEVEL_) +#define _SEH_TRACE_ENTER_CALL_FINALLY(FRAME_, TRYLEVEL_) +#define _SEH_TRACE_LEAVE_CALL_FINALLY(FRAME_, TRYLEVEL_) +#endif + +/* Assembly helpers, see i386/framebased.asm */ +extern void __cdecl _SEHCleanHandlerEnvironment(void); +extern struct __SEHRegistration * __cdecl _SEHRegisterFrame(_SEHRegistration_t *); +extern void __cdecl _SEHUnregisterFrame(void); +extern void __cdecl _SEHGlobalUnwind(_SEHPortableFrame_t *); +extern _SEHRegistration_t * __cdecl _SEHCurrentRegistration(void); + +static void __stdcall _SEHLocalUnwind +( + _SEHPortableFrame_t * frame, + _SEHPortableTryLevel_t * dsttrylevel +) +{ + _SEHPortableTryLevel_t * trylevel; + + _SEH_TRACE_UNWIND(frame, ("enter local unwind from %p to %p", frame->SPF_TopTryLevel, dsttrylevel)); + + for + ( + trylevel = frame->SPF_TopTryLevel; + trylevel != dsttrylevel; + trylevel = trylevel->SPT_Next + ) + { + _SEHFinally_t pfnFinally; + + /* ASSERT(trylevel); */ + + pfnFinally = trylevel->SPT_Handlers.SH_Finally; + + if(pfnFinally) + { + _SEH_TRACE_ENTER_CALL_FINALLY(frame, trylevel); + pfnFinally(frame); + _SEH_TRACE_LEAVE_CALL_FINALLY(frame, trylevel); + } + } + + _SEH_TRACE_UNWIND(frame, ("leave local unwind from %p to %p", frame->SPF_TopTryLevel, dsttrylevel)); +} + +static void __cdecl _SEHCallHandler +( + _SEHPortableFrame_t * frame, + _SEHPortableTryLevel_t * trylevel +) +{ + _SEHGlobalUnwind(frame); + _SEHLocalUnwind(frame, trylevel); + _SEH_TRACE_ENTER_CALL_HANDLER(frame, trylevel); + frame->SPF_Handler(trylevel); + /* ASSERT(0); */ +} + +static int __cdecl _SEHFrameHandler +( + struct _EXCEPTION_RECORD * ExceptionRecord, + void * EstablisherFrame, + struct _CONTEXT * ContextRecord, + void * DispatcherContext +) +{ + _SEHPortableFrame_t * frame; + + _SEHCleanHandlerEnvironment(); + + frame = EstablisherFrame; + + _SEH_TRACE_ENTER + ( + frame, + "_SEHFrameHandler", + ( + "%p, %p, %p, %p", + ExceptionRecord, + EstablisherFrame, + ContextRecord, + DispatcherContext + ) + ); + + _SEH_TRACE_EXCEPTION_RECORD(frame, ExceptionRecord); + _SEH_TRACE_CONTEXT(frame, ContextRecord); + + /* Unwinding */ + if(ExceptionRecord->ExceptionFlags & (4 | 2)) + { + _SEH_TRACE_UNWIND(frame, ("enter forced unwind")); + _SEHLocalUnwind(frame, NULL); + _SEH_TRACE_UNWIND(frame, ("leave forced unwind")); + } + /* Handling */ + else + { + int ret; + _SEHPortableTryLevel_t * trylevel; + + if(ExceptionRecord->ExceptionCode) + frame->SPF_Code = ExceptionRecord->ExceptionCode; + else + frame->SPF_Code = 0xC0000001; + + for + ( + trylevel = frame->SPF_TopTryLevel; + trylevel != NULL; + trylevel = trylevel->SPT_Next + ) + { + _SEHFilter_t pfnFilter = trylevel->SPT_Handlers.SH_Filter; + + _SEH_TRACE_TRYLEVEL(frame, trylevel); + + switch((UINT_PTR)pfnFilter) + { + case __SEH_STATIC_FILTER(_SEH_EXECUTE_HANDLER): + case __SEH_STATIC_FILTER(_SEH_CONTINUE_SEARCH): + case __SEH_STATIC_FILTER(_SEH_CONTINUE_EXECUTION): + { + ret = (int)((UINT_PTR)pfnFilter) - 2; + break; + } + + default: + { + if(trylevel->SPT_Handlers.SH_Filter) + { + EXCEPTION_POINTERS ep; + + ep.ExceptionRecord = ExceptionRecord; + ep.ContextRecord = ContextRecord; + + _SEH_TRACE_ENTER_CALL_FILTER(frame, trylevel, ExceptionRecord); + ret = pfnFilter(&ep, frame); + _SEH_TRACE_LEAVE_CALL_FILTER(frame, trylevel, ret); + } + else + ret = _SEH_CONTINUE_SEARCH; + + break; + } + } + + _SEH_TRACE_FILTER(frame, trylevel, ret); + + /* _SEH_CONTINUE_EXECUTION */ + if(ret < 0) + { + _SEH_TRACE_LEAVE(frame, "_SEHFrameHandler", ("ExceptionContinueExecution")); + return ExceptionContinueExecution; + } + /* _SEH_EXECUTE_HANDLER */ + else if(ret > 0) + _SEHCallHandler(frame, trylevel); + /* _SEH_CONTINUE_SEARCH */ + else + continue; + } + + /* FALLTHROUGH */ + } + + _SEH_TRACE_LEAVE(frame, "_SEHFrameHandler", ("ExceptionContinueSearch")); + return ExceptionContinueSearch; +} + +void __stdcall _SEHEnterFrame_s(_SEHPortableFrame_t * frame) +{ + _SEHEnterFrame_f(frame); +} + +void __stdcall _SEHLeaveFrame_s(void) +{ + _SEHLeaveFrame_f(); +} + +void __stdcall _SEHReturn_s(void) +{ + _SEHReturn_f(); +} + +void _SEH_FASTCALL _SEHEnterFrame_f(_SEHPortableFrame_t * frame) +{ + /* ASSERT(frame); */ + /* ASSERT(trylevel); */ + frame->SPF_Registration.SER_Handler = _SEHFrameHandler; + frame->SPF_Code = 0; + _SEHRegisterFrame(&frame->SPF_Registration); +} + +void _SEH_FASTCALL _SEHLeaveFrame_f(void) +{ + _SEHPortableFrame_t * frame; + + frame = _SEH_CONTAINING_RECORD + ( + _SEHCurrentRegistration(), + _SEHPortableFrame_t, + SPF_Registration + ); + + /* ASSERT(frame); */ + /* ASSERT(frame->SPF_TopTryLevel == NULL) */ + + _SEHUnregisterFrame(); +} + +void _SEH_FASTCALL _SEHReturn_f(void) +{ + _SEHPortableFrame_t * frame; + + frame = _SEH_CONTAINING_RECORD + ( + _SEHCurrentRegistration(), + _SEHPortableFrame_t, + SPF_Registration + ); + + _SEHLocalUnwind(frame, NULL); + _SEHUnregisterFrame(); +} + +/* EOF */ diff -Naur --no-dereference a/mingw-w64/mingw-w64-libraries/pseh/src/i386/framebased.S b/mingw-w64/mingw-w64-libraries/pseh/src/i386/framebased.S --- a/mingw-w64/mingw-w64-libraries/pseh/src/i386/framebased.S 2018-10-21 19:43:00.459270996 -0400 +++ b/mingw-w64/mingw-w64-libraries/pseh/src/i386/framebased.S 1969-12-31 19:00:00.000000000 -0500 @@ -1,73 +0,0 @@ -// Copyright (c) 2004/2005 KJK::Hyperion - -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to dos so, subject to the following conditions: - -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. - -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -.text -.intel_syntax noprefix - -.globl __SEHCleanHandlerEnvironment -__SEHCleanHandlerEnvironment: - cld - ret - -.globl __SEHCurrentRegistration -__SEHCurrentRegistration: - mov eax, [fs:0] - ret - -.globl __SEHRegisterFrame -__SEHRegisterFrame: - mov ecx, [esp+4] - mov eax, [fs:0] - mov [ecx+0], eax - mov [fs:0], ecx - ret - -.globl __SEHUnregisterFrame -__SEHUnregisterFrame: - mov ecx, [fs:0] - mov ecx, [ecx+0] - mov [fs:0], ecx - ret - -.globl __SEHGlobalUnwind -__SEHGlobalUnwind: - -.extern __SEHRtlUnwind - -// RtlUnwind clobbers all the "don't clobber" registers, so we save them - push ebx - mov ebx, [esp+8] - push esi - push edi - - push 0 // ReturnValue - push 0 // ExceptionRecord - push .RestoreRegisters // TargetIp - push ebx // TargetFrame - call _RtlUnwind@16 - -.RestoreRegisters: - pop edi - pop esi - pop ebx - - ret - -// EOF diff -Naur --no-dereference a/mingw-w64/mingw-w64-libraries/pseh/src/x86_64/framebased-asm.S b/mingw-w64/mingw-w64-libraries/pseh/src/x86_64/framebased-asm.S --- a/mingw-w64/mingw-w64-libraries/pseh/src/x86_64/framebased-asm.S 1969-12-31 19:00:00.000000000 -0500 +++ b/mingw-w64/mingw-w64-libraries/pseh/src/x86_64/framebased-asm.S 2018-10-13 09:15:42.000000000 -0400 @@ -0,0 +1,73 @@ +// Copyright (c) 2004/2005 KJK::Hyperion + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to dos so, subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +.text +.intel_syntax noprefix + +.globl __SEHCleanHandlerEnvironment +__SEHCleanHandlerEnvironment: + cld + ret + +.globl __SEHCurrentRegistration +__SEHCurrentRegistration: + mov rax, [fs:0] + ret + +.globl __SEHRegisterFrame +__SEHRegisterFrame: + mov rcx, [rsp+4] + mov rax, [fs:0] + mov [rcx+0], rax + mov [fs:0], rcx + ret + +.globl __SEHUnregisterFrame +__SEHUnregisterFrame: + mov rcx, [fs:0] + mov rcx, [rcx+0] + mov [fs:0], rcx + ret + +.globl __SEHGlobalUnwind +__SEHGlobalUnwind: + +.extern __SEHRtlUnwind + +// RtlUnwind clobbers all the "don't clobber" registers, so we save them + push rbx + mov rbx, [rsp+8] + push rsi + push rdi + + push 0 // ReturnValue + push 0 // ExceptionRecord + push .RestoreRegisters // TargetIp + push rbx // TargetFrame + call _RtlUnwind@16 + +.RestoreRegisters: + pop rdi + pop rsi + pop rbx + + ret + +// EOF diff -Naur --no-dereference a/mingw-w64/mingw-w64-libraries/pseh/src/x86_64/framebased.c b/mingw-w64/mingw-w64-libraries/pseh/src/x86_64/framebased.c --- a/mingw-w64/mingw-w64-libraries/pseh/src/x86_64/framebased.c 1969-12-31 19:00:00.000000000 -0500 +++ b/mingw-w64/mingw-w64-libraries/pseh/src/x86_64/framebased.c 2018-10-26 11:03:17.032528398 -0400 @@ -0,0 +1,499 @@ +/* + Copyright (c) 2004/2005 KJK::Hyperion + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#define _NTSYSTEM_ +#define STRICT +#define WIN32_LEAN_AND_MEAN +#include <windows.h> + +#include <pseh/pseh.h> +#include <pseh/framebased/internal.h> +#include <pseh/excpt.h> +#include <pseh/framebased.h> + +#include <excpt.h> + +/* Tracing */ +#ifdef _SEH_ENABLE_TRACE +extern unsigned long __cdecl DbgPrint(const char * format, ...); + +#define _SEH_TRACE_HEADER_(FRAME_) \ + DbgPrint("[PSEH:%p]%s:%d:", FRAME_, __FILE__, __LINE__); + +#define _SEH_TRACE_TRAILER_ \ + DbgPrint("\n"); + +#define _SEH_FILTER_RET_STRING_(RET_) \ + (((int)(RET_) < 0) ? "_SEH_CONTINUE_EXECUTION" : (((int)(RET_) > 0) ? "_SEH_EXECUTE_HANDLER" : "_SEH_CONTINUE_SEARCH")) + +#define _SEH_TRACE_LINE_(FRAME_, ARGS_) \ +{ \ + _SEH_TRACE_HEADER_(FRAME_); \ + DbgPrint ARGS_; \ + _SEH_TRACE_TRAILER_; \ +} + +#define _SEH_TRACE_ENTER(FRAME_, FUNCNAME_, ARGS_) \ +{ \ + if((FRAME_)->SPF_Tracing & _SEH_DO_TRACE_ENTER_LEAVE) \ + { \ + _SEH_TRACE_HEADER_(FRAME_); \ + DbgPrint(">>> %s(", (FUNCNAME_)); \ + DbgPrint ARGS_; \ + DbgPrint(")"); \ + _SEH_TRACE_TRAILER_; \ + } \ +} + +#define _SEH_TRACE_LEAVE(FRAME_, FUNCNAME_, ARGS_) \ +{ \ + if((FRAME_)->SPF_Tracing & _SEH_DO_TRACE_ENTER_LEAVE) \ + { \ + _SEH_TRACE_HEADER_(FRAME_); \ + DbgPrint("<<< %s => ", (FUNCNAME_)); \ + DbgPrint ARGS_; \ + _SEH_TRACE_TRAILER_; \ + } \ +} + +#define _SEH_TRACE_EXCEPTION_RECORD(FRAME_, ER_) \ +{ \ + if((FRAME_)->SPF_Tracing & _SEH_DO_TRACE_EXCEPTION_RECORD) \ + { \ + _SEH_TRACE_LINE_ \ + ( \ + (FRAME_), \ + ( \ + "ExceptionRecord %p = { ExceptionCode : %08X, ExceptionFlags : %08X, ExceptionRecord : %p, ExceptionAddress : %p }", \ + (ER_), \ + (ER_)->ExceptionCode, \ + (ER_)->ExceptionFlags, \ + (ER_)->ExceptionRecord, \ + (ER_)->ExceptionAddress \ + ) \ + ); \ + } \ +} + +#ifdef __LP64__ +#define _SEH_TRACE_CONTEXT(FRAME_, CONTEXT_) \ +{ \ + if((FRAME_)->SPF_Tracing & _SEH_DO_TRACE_CONTEXT) \ + { \ + if(((CONTEXT_)->ContextFlags & CONTEXT_INTEGER) == CONTEXT_INTEGER) \ + { \ + _SEH_TRACE_LINE_ \ + ( \ + (FRAME_), \ + ( \ + "rax=%08X rbx=%08X rcx=%08X rdx=%08X rsi=%08X rdi=%08X", \ + (CONTEXT_)->Rax, \ + (CONTEXT_)->Rbx, \ + (CONTEXT_)->Rcx, \ + (CONTEXT_)->Rdx, \ + (CONTEXT_)->Rsi, \ + (CONTEXT_)->Rdi \ + ) \ + ); \ + } \ + \ + if(((CONTEXT_)->ContextFlags & CONTEXT_CONTROL) == CONTEXT_CONTROL) \ + { \ + _SEH_TRACE_LINE_ \ + ( \ + (FRAME_), \ + ( \ + "rip=%08X rsp=%08X rbp=%08X rfl=%08X cs=%08X ss=%08X", \ + (CONTEXT_)->Rip, \ + (CONTEXT_)->Rsp, \ + (CONTEXT_)->Rbp, \ + (CONTEXT_)->RFlags, \ + (CONTEXT_)->SegCs, \ + (CONTEXT_)->SegSs \ + ) \ + ); \ + } \ + \ + if(((CONTEXT_)->ContextFlags & CONTEXT_SEGMENTS) == CONTEXT_SEGMENTS) \ + { \ + _SEH_TRACE_LINE_ \ + ( \ + (FRAME_), \ + ( \ + "ds=%08X es=%08X fs=%08X gs=%08X", \ + (CONTEXT_)->SegDs, \ + (CONTEXT_)->SegEs, \ + (CONTEXT_)->SegFs, \ + (CONTEXT_)->SegGs \ + ) \ + ); \ + } \ + } \ +} +#else +#define _SEH_TRACE_CONTEXT(FRAME_, CONTEXT_) +#endif + +#define _SEH_TRACE_UNWIND(FRAME_, ARGS_) \ +{ \ + if((FRAME_)->SPF_Tracing & _SEH_DO_TRACE_UNWIND) \ + { \ + _SEH_TRACE_LINE_((FRAME_), ARGS_); \ + } \ +} + +#define _SEH_TRACE_TRYLEVEL(FRAME_, TRYLEVEL_) \ +{ \ + if((FRAME_)->SPF_Tracing & _SEH_DO_TRACE_TRYLEVEL) \ + { \ + _SEH_TRACE_LINE_((FRAME_), ("trylevel %p, filter %p", (TRYLEVEL_), (TRYLEVEL_)->SPT_Handlers.SH_Filter)); \ + } \ +} + +#define _SEH_TRACE_ENTER_CALL_FILTER(FRAME_, TRYLEVEL_, ER_) \ +{ \ + if((FRAME_)->SPF_Tracing & _SEH_DO_TRACE_CALL_FILTER) \ + { \ + _SEH_TRACE_LINE_ \ + ( \ + (FRAME_), \ + ( \ + "trylevel %p, calling filter %p, ExceptionCode %08X", \ + (TRYLEVEL_), \ + (TRYLEVEL_)->SPT_Handlers.SH_Filter, \ + (ER_)->ExceptionCode \ + ) \ + ); \ + } \ +} + +#define _SEH_TRACE_LEAVE_CALL_FILTER(FRAME_, TRYLEVEL_, RET_) \ +{ \ + if((FRAME_)->SPF_Tracing & _SEH_DO_TRACE_CALL_FILTER) \ + { \ + _SEH_TRACE_LINE_ \ + ( \ + (FRAME_), \ + ( \ + "trylevel %p, filter %p => %s", \ + (TRYLEVEL_), \ + (TRYLEVEL_)->SPT_Handlers.SH_Filter, \ + _SEH_FILTER_RET_STRING_(RET_) \ + ) \ + ); \ + } \ +} + +#define _SEH_TRACE_FILTER(FRAME_, TRYLEVEL_, RET_) \ +{ \ + if((FRAME_)->SPF_Tracing & _SEH_DO_TRACE_FILTER) \ + { \ + _SEH_TRACE_LINE_ \ + ( \ + (FRAME_), \ + ( \ + "trylevel %p => %s", \ + (TRYLEVEL_), \ + _SEH_FILTER_RET_STRING_(RET_) \ + ) \ + ); \ + } \ +} + +#define _SEH_TRACE_ENTER_CALL_HANDLER(FRAME_, TRYLEVEL_) \ +{ \ + if((FRAME_)->SPF_Tracing & _SEH_DO_TRACE_CALL_HANDLER) \ + { \ + _SEH_TRACE_LINE_((FRAME_), ("trylevel %p, handling", (TRYLEVEL_))); \ + } \ +} + +#define _SEH_TRACE_ENTER_CALL_FINALLY(FRAME_, TRYLEVEL_) \ +{ \ + if((FRAME_)->SPF_Tracing & _SEH_DO_TRACE_CALL_FINALLY) \ + { \ + _SEH_TRACE_LINE_ \ + ( \ + (FRAME_), \ + ( \ + "trylevel %p, calling exit routine %p", \ + (TRYLEVEL_), \ + (TRYLEVEL_)->SPT_Handlers.SH_Finally \ + ) \ + ); \ + } \ +} + +#define _SEH_TRACE_LEAVE_CALL_FINALLY(FRAME_, TRYLEVEL_) \ +{ \ + if((FRAME_)->SPF_Tracing & _SEH_DO_TRACE_CALL_FINALLY) \ + { \ + _SEH_TRACE_LINE_ \ + ( \ + (FRAME_), \ + ( \ + "trylevel %p, exit routine %p returned", \ + (TRYLEVEL_), \ + (TRYLEVEL_)->SPT_Handlers.SH_Finally \ + ) \ + ); \ + } \ +} + +#else +#define _SEH_TRACE_ENTER(FRAME_, FUNCNAME_, ARGS_) +#define _SEH_TRACE_LEAVE(FRAME_, FUNCNAME_, ARGS_) +#define _SEH_TRACE_EXCEPTION_RECORD(FRAME_, ER_) +#define _SEH_TRACE_CONTEXT(FRAME_, CONTEXT_) +#define _SEH_TRACE_UNWIND(FRAME_, ARGS_) +#define _SEH_TRACE_TRYLEVEL(FRAME_, TRYLEVEL_) +#define _SEH_TRACE_ENTER_CALL_FILTER(FRAME_, TRYLEVEL_, ER_) +#define _SEH_TRACE_LEAVE_CALL_FILTER(FRAME_, TRYLEVEL_, RET_) +#define _SEH_TRACE_FILTER(FRAME_, TRYLEVEL_, RET_) +#define _SEH_TRACE_ENTER_CALL_HANDLER(FRAME_, TRYLEVEL_) +#define _SEH_TRACE_ENTER_CALL_FINALLY(FRAME_, TRYLEVEL_) +#define _SEH_TRACE_LEAVE_CALL_FINALLY(FRAME_, TRYLEVEL_) +#endif + +/* Assembly helpers, see framebased.asm */ +extern void __cdecl _SEHCleanHandlerEnvironment(void); +extern struct __SEHRegistration * __cdecl _SEHRegisterFrame(_SEHRegistration_t *); +extern void __cdecl _SEHUnregisterFrame(void); +extern void __cdecl _SEHGlobalUnwind(_SEHPortableFrame_t *); +extern _SEHRegistration_t * __cdecl _SEHCurrentRegistration(void); + +static void __stdcall _SEHLocalUnwind +( + _SEHPortableFrame_t * frame, + _SEHPortableTryLevel_t * dsttrylevel +) +{ + _SEHPortableTryLevel_t * trylevel; + + _SEH_TRACE_UNWIND(frame, ("enter local unwind from %p to %p", frame->SPF_TopTryLevel, dsttrylevel)); + + for + ( + trylevel = frame->SPF_TopTryLevel; + trylevel != dsttrylevel; + trylevel = trylevel->SPT_Next + ) + { + _SEHFinally_t pfnFinally; + + /* ASSERT(trylevel); */ + + pfnFinally = trylevel->SPT_Handlers.SH_Finally; + + if(pfnFinally) + { + _SEH_TRACE_ENTER_CALL_FINALLY(frame, trylevel); + pfnFinally(frame); + _SEH_TRACE_LEAVE_CALL_FINALLY(frame, trylevel); + } + } + + _SEH_TRACE_UNWIND(frame, ("leave local unwind from %p to %p", frame->SPF_TopTryLevel, dsttrylevel)); +} + +static void __cdecl _SEHCallHandler +( + _SEHPortableFrame_t * frame, + _SEHPortableTryLevel_t * trylevel +) +{ + _SEHGlobalUnwind(frame); + _SEHLocalUnwind(frame, trylevel); + _SEH_TRACE_ENTER_CALL_HANDLER(frame, trylevel); + frame->SPF_Handler(trylevel); + /* ASSERT(0); */ +} + +static int __cdecl _SEHFrameHandler +( + struct _EXCEPTION_RECORD * ExceptionRecord, + void * EstablisherFrame, + struct _CONTEXT * ContextRecord, + void * DispatcherContext +) +{ + _SEHPortableFrame_t * frame; + + _SEHCleanHandlerEnvironment(); + + frame = EstablisherFrame; + + _SEH_TRACE_ENTER + ( + frame, + "_SEHFrameHandler", + ( + "%p, %p, %p, %p", + ExceptionRecord, + EstablisherFrame, + ContextRecord, + DispatcherContext + ) + ); + + _SEH_TRACE_EXCEPTION_RECORD(frame, ExceptionRecord); + _SEH_TRACE_CONTEXT(frame, ContextRecord); + + /* Unwinding */ + if(ExceptionRecord->ExceptionFlags & (4 | 2)) + { + _SEH_TRACE_UNWIND(frame, ("enter forced unwind")); + _SEHLocalUnwind(frame, NULL); + _SEH_TRACE_UNWIND(frame, ("leave forced unwind")); + } + /* Handling */ + else + { + int ret; + _SEHPortableTryLevel_t * trylevel; + + if(ExceptionRecord->ExceptionCode) + frame->SPF_Code = ExceptionRecord->ExceptionCode; + else + frame->SPF_Code = 0xC0000001; + + for + ( + trylevel = frame->SPF_TopTryLevel; + trylevel != NULL; + trylevel = trylevel->SPT_Next + ) + { + _SEHFilter_t pfnFilter = trylevel->SPT_Handlers.SH_Filter; + + _SEH_TRACE_TRYLEVEL(frame, trylevel); + + switch((UINT_PTR)pfnFilter) + { + case __SEH_STATIC_FILTER(_SEH_EXECUTE_HANDLER): + case __SEH_STATIC_FILTER(_SEH_CONTINUE_SEARCH): + case __SEH_STATIC_FILTER(_SEH_CONTINUE_EXECUTION): + { + ret = (int)((UINT_PTR)pfnFilter) - 2; + break; + } + + default: + { + if(trylevel->SPT_Handlers.SH_Filter) + { + EXCEPTION_POINTERS ep; + + ep.ExceptionRecord = ExceptionRecord; + ep.ContextRecord = ContextRecord; + + _SEH_TRACE_ENTER_CALL_FILTER(frame, trylevel, ExceptionRecord); + ret = pfnFilter(&ep, frame); + _SEH_TRACE_LEAVE_CALL_FILTER(frame, trylevel, ret); + } + else + ret = _SEH_CONTINUE_SEARCH; + + break; + } + } + + _SEH_TRACE_FILTER(frame, trylevel, ret); + + /* _SEH_CONTINUE_EXECUTION */ + if(ret < 0) + { + _SEH_TRACE_LEAVE(frame, "_SEHFrameHandler", ("ExceptionContinueExecution")); + return ExceptionContinueExecution; + } + /* _SEH_EXECUTE_HANDLER */ + else if(ret > 0) + _SEHCallHandler(frame, trylevel); + /* _SEH_CONTINUE_SEARCH */ + else + continue; + } + + /* FALLTHROUGH */ + } + + _SEH_TRACE_LEAVE(frame, "_SEHFrameHandler", ("ExceptionContinueSearch")); + return ExceptionContinueSearch; +} + +void __stdcall _SEHEnterFrame_s(_SEHPortableFrame_t * frame) +{ + _SEHEnterFrame_f(frame); +} + +void __stdcall _SEHLeaveFrame_s(void) +{ + _SEHLeaveFrame_f(); +} + +void __stdcall _SEHReturn_s(void) +{ + _SEHReturn_f(); +} + +void _SEH_FASTCALL _SEHEnterFrame_f(_SEHPortableFrame_t * frame) +{ + /* ASSERT(frame); */ + /* ASSERT(trylevel); */ + frame->SPF_Registration.SER_Handler = _SEHFrameHandler; + frame->SPF_Code = 0; + _SEHRegisterFrame(&frame->SPF_Registration); +} + +void _SEH_FASTCALL _SEHLeaveFrame_f(void) +{ + _SEHPortableFrame_t * frame; + + frame = _SEH_CONTAINING_RECORD + ( + _SEHCurrentRegistration(), + _SEHPortableFrame_t, + SPF_Registration + ); + + /* ASSERT(frame); */ + /* ASSERT(frame->SPF_TopTryLevel == NULL) */ + + _SEHUnregisterFrame(); +} + +void _SEH_FASTCALL _SEHReturn_f(void) +{ + _SEHPortableFrame_t * frame; + + frame = _SEH_CONTAINING_RECORD + ( + _SEHCurrentRegistration(), + _SEHPortableFrame_t, + SPF_Registration + ); + + _SEHLocalUnwind(frame, NULL); + _SEHUnregisterFrame(); +} + +/* EOF */ diff -Naur --no-dereference a/mingw-w64/mingw-w64-libraries/pseh/src/x86_64/framebased-gcchack-asm.S b/mingw-w64/mingw-w64-libraries/pseh/src/x86_64/framebased-gcchack-asm.S --- a/mingw-w64/mingw-w64-libraries/pseh/src/x86_64/framebased-gcchack-asm.S 1969-12-31 19:00:00.000000000 -0500 +++ b/mingw-w64/mingw-w64-libraries/pseh/src/x86_64/framebased-gcchack-asm.S 2018-10-13 09:13:07.000000000 -0400 @@ -0,0 +1,89 @@ +// Copyright (c) 2008 KJK::Hyperion + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to dos so, subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +.text +.intel_syntax noprefix + +.func _SEH2EnterHandleTrylevel +.globl __SEH2EnterHandleTrylevel +__SEH2EnterHandleTrylevel: + mov rax, [rsp+8] + mov rcx, [rsp+12] + mov [rax+8], rcx + mov [rax+16], rbp + mov [rax+20], rbx + mov [rax+24], rsi + mov [rax+28], rdi + + mov rdx, [rsp+4] + mov [rdx+8], rax + + xor rax, rax + ret +.endfunc + +.func _SEH2EnterFrameAndHandleTrylevel +.globl __SEH2EnterFrameAndHandleTrylevel +__SEH2EnterFrameAndHandleTrylevel: + mov rax, [rsp+8] + mov rcx, [rsp+12] + mov [rax+8], rcx + mov [rax+16], rbp + mov [rax+20], rbx + mov [rax+24], rsi + mov [rax+28], rdi + +.extern __SEH2EnterFrameAndTrylevel + jmp __SEH2EnterFrameAndTrylevel +.endfunc + +.func __SEH2Handle +.globl ___SEH2Handle +___SEH2Handle: + mov rax, [rsp+4] + mov rbp, [rsp+12] + mov rbx, [rsp+16] + mov rsi, [rsp+20] + mov rdi, [rsp+24] + mov rsp, [rsp+8] + jmp rax +.endfunc + +.func __SEH2FrameHandler +.globl ___SEH2FrameHandler +___SEH2FrameHandler: + +.extern __SEH2FrameHandler + + cld + jmp __SEH2FrameHandler +.endfunc + +.func __SEH2UnwindHandler +.globl ___SEH2UnwindHandler +___SEH2UnwindHandler: + +.extern __SEH2UnwindHandler + + cld + jmp __SEH2UnwindHandler +.endfunc + +// EOF diff -Naur --no-dereference a/mingw-w64/mingw-w64-libraries/pseh/src/x86_64/framebased-gcchack.c b/mingw-w64/mingw-w64-libraries/pseh/src/x86_64/framebased-gcchack.c --- a/mingw-w64/mingw-w64-libraries/pseh/src/x86_64/framebased-gcchack.c 1969-12-31 19:00:00.000000000 -0500 +++ b/mingw-w64/mingw-w64-libraries/pseh/src/x86_64/framebased-gcchack.c 2018-10-13 09:14:43.000000000 -0400 @@ -0,0 +1,309 @@ +/* + Copyright (c) 2008 KJK::Hyperion + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#define _NTSYSTEM_ /* removes dllimport attribute from RtlUnwind */ + +#define STRICT +#define WIN32_LEAN_AND_MEAN +#include <windows.h> + +#include <pseh/pseh2-common.h> +#include <excpt.h> +#include <intrin.h> + +#ifndef EXCEPTION_EXIT_UNWIND +#define EXCEPTION_EXIT_UNWIND 4 +#endif + +#ifndef EXCEPTION_UNWINDING +#define EXCEPTION_UNWINDING 2 +#endif + +extern DECLSPEC_NORETURN int __SEH2Handle(void *, void *, void *, void *, void *, void *); +extern int __cdecl __SEH2FrameHandler(struct _EXCEPTION_RECORD *, void *, struct _CONTEXT *, void *); +extern int __cdecl __SEH2UnwindHandler(struct _EXCEPTION_RECORD *, void *, struct _CONTEXT *, void *); + +typedef struct __SEHTrampoline +{ + unsigned char STR_MovEcx; + unsigned char * STR_Closure; + unsigned char STR_Jmp; + unsigned char * STR_Function; +} +__attribute__((packed)) +_SEHTrampoline_t; + +FORCEINLINE +int _SEHIsTrampoline(_SEHTrampoline_t * trampoline_) +{ + return trampoline_->STR_MovEcx == 0xb9 && trampoline_->STR_Jmp == 0xe9; +} + +FORCEINLINE +void * _SEHFunctionFromTrampoline(_SEHTrampoline_t * trampoline_) +{ + return (int)(trampoline_ + 1) + trampoline_->STR_Function; +} + +FORCEINLINE +void * _SEHClosureFromTrampoline(_SEHTrampoline_t * trampoline_) +{ + return trampoline_->STR_Closure; +} + +FORCEINLINE +_SEH2Registration_t * __cdecl _SEH2CurrentRegistration(void) +{ + return (_SEH2Registration_t *)__readfsdword(0); +} + +FORCEINLINE +void __cdecl __SEH2EnterFrame(_SEH2Registration_t * frame) +{ + frame->SER_Prev = _SEH2CurrentRegistration(); + __writefsdword(0, (unsigned long)frame); +} + +FORCEINLINE +void __cdecl __SEH2LeaveFrame(void) +{ + __writefsdword(0, (unsigned long)_SEH2CurrentRegistration()->SER_Prev); +} + +FORCEINLINE +void _SEH2GlobalUnwind(void * target) +{ + __asm__ __volatile__ + ( + "push %%rbp\n" + "push $0\n" + "push $0\n" + "push $Return%=\n" + "push %[target]\n" + "call %c[RtlUnwind]\n" + "Return%=: pop %%rbp\n" : + : + [target] "g" (target), [RtlUnwind] "g" (&RtlUnwind) : + "rax", "rbx", "rcx", "rdx", "rsi", "rdi", "flags", "memory" + ); +} + +static +__SEH_EXCEPT_RET _SEH2Except(_SEH2Frame_t * frame, volatile _SEH2TryLevel_t * trylevel, struct _EXCEPTION_POINTERS * ep) +{ + void * filter = trylevel->ST_Filter; + void * context = NULL; + __SEH_EXCEPT_RET ret; + + if(filter == (void *)0) + return 0; + + if(filter == (void *)1) + return 1; + + if(filter == (void *)-1) + return -1; + + if(_SEHIsTrampoline((_SEHTrampoline_t *)filter)) + { + context = _SEHClosureFromTrampoline((_SEHTrampoline_t *)filter); + filter = _SEHFunctionFromTrampoline((_SEHTrampoline_t *)filter); + } + + __asm__ __volatile__ + ( + "push %[ep]\n" + "push %[frame]\n" + "call *%[filter]\n" + "pop %%rdx\n" + "pop %%rdx\n" : + [ret] "=a" (ret) : + "c" (context), [filter] "r" (filter), [frame] "g" (frame), [ep] "g" (ep) : + "rdx", "flags", "memory" + ); + + return ret; +} + +static +void _SEH2Finally(_SEH2Frame_t * frame, volatile _SEH2TryLevel_t * trylevel) +{ + if(trylevel->ST_Filter == NULL && trylevel->ST_Body != NULL) + { + void * body = trylevel->ST_Body; + void * context = NULL; + + if(_SEHIsTrampoline((_SEHTrampoline_t *)body)) + { + context = _SEHClosureFromTrampoline((_SEHTrampoline_t *)body); + body = _SEHFunctionFromTrampoline((_SEHTrampoline_t *)body); + } + + __asm__ __volatile__("call *%1\n" : : "c" (context), "r" (body) : "rax", "rdx", "flags", "memory"); + } +} + +typedef struct __SEH2UnwindFrame +{ + _SEH2Registration_t SUF_Registration; + _SEH2Frame_t * SUF_Frame; + volatile _SEH2TryLevel_t * SUF_TargetTryLevel; +} +_SEH2UnwindFrame_t; + +static void _SEH2LocalUnwind(_SEH2Frame_t *, volatile _SEH2TryLevel_t *); + +extern +int __cdecl _SEH2UnwindHandler +( + struct _EXCEPTION_RECORD * ExceptionRecord, + void * EstablisherFrame, + struct _CONTEXT * ContextRecord, + void * DispatcherContext +) +{ + if(ExceptionRecord->ExceptionFlags & (EXCEPTION_EXIT_UNWIND | EXCEPTION_UNWINDING)) + { + _SEH2UnwindFrame_t * unwindframe = CONTAINING_RECORD(EstablisherFrame, _SEH2UnwindFrame_t, SUF_Registration); + _SEH2LocalUnwind(unwindframe->SUF_Frame, unwindframe->SUF_TargetTryLevel); + *((void **)DispatcherContext) = EstablisherFrame; + return ExceptionCollidedUnwind; + } + + return ExceptionContinueSearch; +} + +static +void _SEH2LocalUnwind(_SEH2Frame_t * frame, volatile _SEH2TryLevel_t * dsttrylevel) +{ + volatile _SEH2TryLevel_t * trylevel; + _SEH2UnwindFrame_t unwindframe; + + unwindframe.SUF_Frame = frame; + unwindframe.SUF_TargetTryLevel = dsttrylevel; + + unwindframe.SUF_Registration.SER_Handler = &__SEH2UnwindHandler; + __SEH2EnterFrame(&unwindframe.SUF_Registration); + + for(trylevel = frame->SF_TopTryLevel; trylevel && trylevel != dsttrylevel; trylevel = trylevel->ST_Next) + { + frame->SF_TopTryLevel = trylevel->ST_Next; + _SEH2Finally(frame, trylevel); + } + + __SEH2LeaveFrame(); +} + +static DECLSPEC_NORETURN +void _SEH2Handle(_SEH2Frame_t * frame, volatile _SEH2TryLevel_t * trylevel) +{ + volatile _SEH2HandleTryLevel_t * fulltrylevel = CONTAINING_RECORD(trylevel, _SEH2HandleTryLevel_t, SHT_Common); + + _SEH2GlobalUnwind(frame); + _SEH2LocalUnwind(frame, &fulltrylevel->SHT_Common); + frame->SF_TopTryLevel = fulltrylevel->SHT_Common.ST_Next; + + __SEH2Handle + ( + fulltrylevel->SHT_Common.ST_Body, + fulltrylevel->SHT_Esp, + fulltrylevel->SHT_Ebp, + fulltrylevel->SHT_Ebx, + fulltrylevel->SHT_Esi, + fulltrylevel->SHT_Edi + ); +} + +extern +int __cdecl _SEH2FrameHandler +( + struct _EXCEPTION_RECORD * ExceptionRecord, + void * EstablisherFrame, + struct _CONTEXT * ContextRecord, + void * DispatcherContext +) +{ + _SEH2Frame_t * frame; + + frame = EstablisherFrame; + + /* Unwinding */ + if(ExceptionRecord->ExceptionFlags & (EXCEPTION_EXIT_UNWIND | EXCEPTION_UNWINDING)) + { + _SEH2LocalUnwind(frame, NULL); + } + /* Handling */ + else + { + int ret = 0; + volatile _SEH2TryLevel_t * trylevel; + EXCEPTION_POINTERS ep; + + ep.ExceptionRecord = ExceptionRecord; + ep.ContextRecord = ContextRecord; + + frame->SF_Code = ExceptionRecord->ExceptionCode; + + for(trylevel = frame->SF_TopTryLevel; trylevel != NULL; trylevel = trylevel->ST_Next) + { + ret = _SEH2Except(frame, trylevel, &ep); + + if(ret < 0) + return ExceptionContinueExecution; + else if(ret > 0) + _SEH2Handle(frame, trylevel); + } + } + + return ExceptionContinueSearch; +} + +extern +void __cdecl _SEH2EnterFrame(_SEH2Frame_t * frame) +{ + frame->SF_Registration.SER_Handler = __SEH2FrameHandler; + frame->SF_Code = 0; + __SEH2EnterFrame(&frame->SF_Registration); +} + +extern +int __cdecl _SEH2EnterFrameAndTrylevel(_SEH2Frame_t * frame, volatile _SEH2TryLevel_t * trylevel) +{ + frame->SF_TopTryLevel = trylevel; + _SEH2EnterFrame(frame); + return 0; +} + +extern +void __cdecl _SEH2LeaveFrame(void) +{ + __SEH2LeaveFrame(); +} + +extern +void __cdecl _SEH2Return(void) +{ + _SEH2LocalUnwind(CONTAINING_RECORD(_SEH2CurrentRegistration(), _SEH2Frame_t, SF_Registration), NULL); + _SEH2LeaveFrame(); +} + +/* EOF */ _______________________________________________ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public