[Patch/RFC] SEH exceptions for Win64
Hi, this is a rebase of RTH's patch posted a few years ago. It is almost unchanged, except that there is no SEH specific unwind.h header (there are 3 #if/#endif part in unwind-generic.h) and a minor cleanup in unwind-seh.c (indentation, unused variables). This patch allows to propagate GCC exceptions through any code (including code produced by msvc), but to my knowledge propagation of msvc exceptions through gcc code doesn't work (because we cancel the exception to run cleanups). We have tested it heavily in our infrastructure and found no issues in that part. We had to write a specific personality routine for Ada to handle stack checking and access violation in user code; but as far as I know this is not needed by c++. I did a manual build and testing for x86_64-pc-mingw32 and I will run a full bootstrap and regression run on GNU/Linux. Tristan. libstdc++-v3/ * libsupc++/eh_personality.cc (__gxx_personality_seh0): New function. Adjust for SEH. * config/abi/pre/gnu.ver: Add __gxx_personality_seh0. libobjc/ * exception.c (__gnu_objc_personality_seh0): New function. libjava/ * libgcj.ver: Add __gcj_personality_seh0. * exception.cc (__gcj_personality_seh0): New function. Adjust for SEH. libgcc/ * unwind-seh.c: New file. * unwind-generic.h: Include windows.h for SEH. (_Unwind_Exception): Use 6 private fields for SEH. (_GCC_specific_handler): Declare. * unwind-c.c (__gcc_personality_seh0): New function. Adjust for SEH. * config/i386/libgcc-cygming.ver: New file. * config/i386/t-seh-eh: New file. * config.host (x86_64-*-mingw*): Default to seh. gcc/ * opts.c (finish_options): Handle UI_SEH. * expr.c (build_personality_function): Handle UI_SEH. * dwarf2out.c (dwarf2out_begin_prologue): Handle UI_SEH. * coretypes.h (unwind_info_type): Add UI_SEH. * config/i386/winnt.c (i386_pe_seh_emit_except_personality): New function. (i386_pe_seh_init_sections): Likewise. * config/i386/cygming.h (TARGET_ASM_EMIT_EXCEPT_PERSONALITY): Define. (TARGET_ASM_INIT_SECTIONS): Define. * common/config/i386/i386-common.c (TARGET_EXCEPT_UNWIND_INFO): Define. (i386_except_unwind_info): New function. diff --git a/gcc/common/config/i386/i386-common.c b/gcc/common/config/i386/i386-common.c index 70b7eb7..1fe04a6 100644 --- a/gcc/common/config/i386/i386-common.c +++ b/gcc/common/config/i386/i386-common.c @@ -667,6 +667,30 @@ ix86_supports_split_stack (bool report ATTRIBUTE_UNUSED, return ret; } +/* Implement TARGET_EXCEPT_UNWIND_INFO. */ + +static enum unwind_info_type +i386_except_unwind_info (struct gcc_options *opts) +{ + /* Honor the --enable-sjlj-exceptions configure switch. */ +#ifdef CONFIG_SJLJ_EXCEPTIONS + if (CONFIG_SJLJ_EXCEPTIONS) +return UI_SJLJ; +#endif + + /* On windows 64, prefer SEH exceptions over anything else. */ + if (TARGET_64BIT && DEFAULT_ABI == MS_ABI && opts->x_flag_unwind_tables) +return UI_SEH; + + if (DWARF2_UNWIND_INFO) +return UI_DWARF2; + + return UI_SJLJ; +} + +#undef TARGET_EXCEPT_UNWIND_INFO +#define TARGET_EXCEPT_UNWIND_INFO i386_except_unwind_info + #undef TARGET_DEFAULT_TARGET_FLAGS #define TARGET_DEFAULT_TARGET_FLAGS\ (TARGET_DEFAULT \ diff --git a/gcc/config/i386/cygming.h b/gcc/config/i386/cygming.h index b5f89c4..8455a67 100644 --- a/gcc/config/i386/cygming.h +++ b/gcc/config/i386/cygming.h @@ -48,6 +48,10 @@ along with GCC; see the file COPYING3. If not see #define TARGET_ASM_UNWIND_EMIT_BEFORE_INSN false #undef TARGET_ASM_FUNCTION_END_PROLOGUE #define TARGET_ASM_FUNCTION_END_PROLOGUE i386_pe_seh_end_prologue +#undef TARGET_ASM_EMIT_EXCEPT_PERSONALITY +#define TARGET_ASM_EMIT_EXCEPT_PERSONALITY i386_pe_seh_emit_except_personality +#undef TARGET_ASM_INIT_SECTIONS +#define TARGET_ASM_INIT_SECTIONS i386_pe_seh_init_sections #define SUBTARGET_ASM_UNWIND_INIT i386_pe_seh_init #undef DEFAULT_ABI diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h index fe733b0..49e6bbd 100644 --- a/gcc/config/i386/i386-protos.h +++ b/gcc/config/i386/i386-protos.h @@ -258,6 +258,8 @@ extern tree i386_pe_mangle_assembler_name (const char *); extern void i386_pe_seh_init (FILE *); extern void i386_pe_seh_end_prologue (FILE *); extern void i386_pe_seh_unwind_emit (FILE *, rtx); +extern void i386_pe_seh_emit_except_personality (rtx); +extern void i386_pe_seh_init_sections (void); /* In winnt-cxx.c and winnt-stubs.c */ extern void i386_pe_adjust_class_at_definition (tree); diff --git a/gcc/config/i386/winnt.c b/gcc/config/i386/winnt.c index 5b71ccb..17ee137 100644 --- a/gcc/config/i386/winnt.c +++ b/gcc/config/i386/winnt.c @@ -1143,6 +1143,48 @@ i386_pe_seh_unwind_emit (FILE *asm_out_file, rtx insn) found: seh_frame_related_expr (asm_out_file, seh, pat); } + +void +i386_pe_seh_emit_exce
Re: [Patch/RFC] SEH exceptions for Win64
On 07/13/2012 07:13 AM, Tristan Gingold wrote: > +_Unwind_RaiseException (struct _Unwind_Exception *exc) > +{ > + memset (exc->private_, 0, sizeof (exc->private_)); > + > + RaiseException (STATUS_GCC_THROW, 0, 1, (ULONG_PTR *)&exc); We almost certainly didn't want pointer-to-pointer... r~
Re: [Patch/RFC] SEH exceptions for Win64
On Jul 16, 2012, at 6:28 PM, Richard Henderson wrote: > On 07/13/2012 07:13 AM, Tristan Gingold wrote: >> +_Unwind_RaiseException (struct _Unwind_Exception *exc) >> +{ >> + memset (exc->private_, 0, sizeof (exc->private_)); >> + >> + RaiseException (STATUS_GCC_THROW, 0, 1, (ULONG_PTR *)&exc); > > We almost certainly didn't want pointer-to-pointer... I was about to say that this is an obvious typo, but no, this code is correct AFAIK. The declaration of RaiseException is: void WINAPI RaiseException( __in DWORD dwExceptionCode, __in DWORD dwExceptionFlags, __in DWORD nNumberOfArguments, __in const ULONG_PTR *lpArguments ); That is, the last argument is an array of arguments to be copied into the exception record. In our case, the start of the array is &exc, and its length is 1. So, the first element of ExceptionInformation will be exc. Should I add a comment ? Tristan.
Re: [Patch/RFC] SEH exceptions for Win64
On 07/17/2012 12:35 AM, Tristan Gingold wrote: > So, the first element of ExceptionInformation will be exc. > > Should I add a comment ? Ah right. Definitely. Otherwise I don't see anything else in the way. Kai? r~
Re: [Patch/RFC] SEH exceptions for Win64
2012/7/17 Richard Henderson : > On 07/17/2012 12:35 AM, Tristan Gingold wrote: >> So, the first element of ExceptionInformation will be exc. >> >> Should I add a comment ? > > Ah right. Definitely. > > Otherwise I don't see anything else in the way. Kai? > > > r~ No, I don't have any objections. I just tested the patch myself with full regression-test. So patch is ok. Thanks, Kai
Re: [Patch/RFC] SEH exceptions for Win64
On Jul 17, 2012, at 2:53 PM, Kai Tietz wrote: > 2012/7/17 Richard Henderson : >> On 07/17/2012 12:35 AM, Tristan Gingold wrote: >>> So, the first element of ExceptionInformation will be exc. >>> >>> Should I add a comment ? >> >> Ah right. Definitely. >> >> Otherwise I don't see anything else in the way. Kai? >> >> >> r~ > > No, I don't have any objections. I just tested the patch myself with > full regression-test. Thank you for running the full regression-test. > So patch is ok. No regression on i386 GNU/Linux. Committed. Tristan.
Re: [Patch/RFC] SEH exceptions for Win64
On 07/19/2012 08:30 AM, Tristan Gingold wrote: > No regression on i386 GNU/Linux. > Committed. Nice. Is this NEWS / docs --or wherever release notes are written-- worthy? Something like this, borrowed from your own words: On Win64, the compiler now emits SEH unwind info. GCC exceptions now propagate through any code, including code produced by MSVC. -- Pedro Alves
Re: [Patch/RFC] SEH exceptions for Win64
On Jul 19, 2012, at 11:37 AM, Pedro Alves wrote: > On 07/19/2012 08:30 AM, Tristan Gingold wrote: > >> No regression on i386 GNU/Linux. >> Committed. > > Nice. Is this NEWS / docs --or wherever release notes are written-- worthy? > > Something like this, borrowed from your own words: > > On Win64, the compiler now emits SEH unwind info. GCC exceptions now > propagate > through any code, including code produced by MSVC. To clarify, GCC emits SEH unwind info since 4.7, so I propose slightly modified words: Index: htdocs/gcc-4.8/changes.html === RCS file: /cvs/gcc/wwwdocs/htdocs/gcc-4.8/changes.html,v retrieving revision 1.6 diff -c -r1.6 changes.html *** htdocs/gcc-4.8/changes.html 17 Jul 2012 19:47:31 - 1.6 --- htdocs/gcc-4.8/changes.html 19 Jul 2012 10:15:13 - *** *** 86,91 --- 86,97 libraries. This includes the system libraries and startup modules. + + On x86_64-mingw32, exceptions propagate through any code, + including code produced by MSVC (the GCC runtime now uses SEH on + this target) + +
Re: [Patch/RFC] SEH exceptions for Win64
On 07/19/2012 11:15 AM, Tristan Gingold wrote: > To clarify, GCC emits SEH unwind info since 4.7, so I propose slightly > modified words: Looks good to me. Thanks! -- Pedro Alves
Re: [Patch/RFC] SEH exceptions for Win64
> I did a manual build and testing for x86_64-pc-mingw32 and I will run a > full bootstrap and regression run on GNU/Linux. > > Tristan. > > libstdc++-v3/ > * libsupc++/eh_personality.cc (__gxx_personality_seh0): New function. > Adjust for SEH. > * config/abi/pre/gnu.ver: Add __gxx_personality_seh0. > > libobjc/ > * exception.c (__gnu_objc_personality_seh0): New function. > > libjava/ > * libgcj.ver: Add __gcj_personality_seh0. > * exception.cc (__gcj_personality_seh0): New function. > Adjust for SEH. > > libgcc/ > * unwind-seh.c: New file. > * unwind-generic.h: Include windows.h for SEH. > (_Unwind_Exception): Use 6 private fields for SEH. > (_GCC_specific_handler): Declare. > * unwind-c.c (__gcc_personality_seh0): New function. > Adjust for SEH. > * config/i386/libgcc-cygming.ver: New file. > * config/i386/t-seh-eh: New file. > * config.host (x86_64-*-mingw*): Default to seh. > > gcc/ > * opts.c (finish_options): Handle UI_SEH. > * expr.c (build_personality_function): Handle UI_SEH. > * dwarf2out.c (dwarf2out_begin_prologue): Handle UI_SEH. > * coretypes.h (unwind_info_type): Add UI_SEH. > * config/i386/winnt.c (i386_pe_seh_emit_except_personality): > New function. > (i386_pe_seh_init_sections): Likewise. > * config/i386/cygming.h (TARGET_ASM_EMIT_EXCEPT_PERSONALITY): Define. > (TARGET_ASM_INIT_SECTIONS): Define. > * common/config/i386/i386-common.c (TARGET_EXCEPT_UNWIND_INFO): Define. > (i386_except_unwind_info): New function. Don't we need something in ada/ as well? PR ada/54028 reports a build failure. -- Eric Botcazou
Re: [Patch/RFC] SEH exceptions for Win64
On Jul 19, 2012, at 6:54 PM, Eric Botcazou wrote: >> I did a manual build and testing for x86_64-pc-mingw32 and I will run a >> full bootstrap and regression run on GNU/Linux. >> >> Tristan. >> >> libstdc++-v3/ >> * libsupc++/eh_personality.cc (__gxx_personality_seh0): New function. >> Adjust for SEH. >> * config/abi/pre/gnu.ver: Add __gxx_personality_seh0. >> >> libobjc/ >> * exception.c (__gnu_objc_personality_seh0): New function. >> >> libjava/ >> * libgcj.ver: Add __gcj_personality_seh0. >> * exception.cc (__gcj_personality_seh0): New function. >> Adjust for SEH. >> >> libgcc/ >> * unwind-seh.c: New file. >> * unwind-generic.h: Include windows.h for SEH. >> (_Unwind_Exception): Use 6 private fields for SEH. >> (_GCC_specific_handler): Declare. >> * unwind-c.c (__gcc_personality_seh0): New function. >> Adjust for SEH. >> * config/i386/libgcc-cygming.ver: New file. >> * config/i386/t-seh-eh: New file. >> * config.host (x86_64-*-mingw*): Default to seh. >> >> gcc/ >> * opts.c (finish_options): Handle UI_SEH. >> * expr.c (build_personality_function): Handle UI_SEH. >> * dwarf2out.c (dwarf2out_begin_prologue): Handle UI_SEH. >> * coretypes.h (unwind_info_type): Add UI_SEH. >> * config/i386/winnt.c (i386_pe_seh_emit_except_personality): >> New function. >> (i386_pe_seh_init_sections): Likewise. >> * config/i386/cygming.h (TARGET_ASM_EMIT_EXCEPT_PERSONALITY): Define. >> (TARGET_ASM_INIT_SECTIONS): Define. >> * common/config/i386/i386-common.c (TARGET_EXCEPT_UNWIND_INFO): Define. >> (i386_except_unwind_info): New function. > > Don't we need something in ada/ as well? PR ada/54028 reports a build > failure. I think Arnaud already committed the ada stuff. It looks like (to me) that the build occurred before I committed the above patch. Tristan.
Re: [Patch/RFC] SEH exceptions for Win64
Gerald, it is ok ? Tristan. On Jul 19, 2012, at 12:15 PM, Tristan Gingold wrote: > > On Jul 19, 2012, at 11:37 AM, Pedro Alves wrote: > >> On 07/19/2012 08:30 AM, Tristan Gingold wrote: >> >>> No regression on i386 GNU/Linux. >>> Committed. >> >> Nice. Is this NEWS / docs --or wherever release notes are written-- worthy? >> >> Something like this, borrowed from your own words: >> >> On Win64, the compiler now emits SEH unwind info. GCC exceptions now >> propagate >> through any code, including code produced by MSVC. > > To clarify, GCC emits SEH unwind info since 4.7, so I propose slightly > modified words: > > Index: htdocs/gcc-4.8/changes.html > === > RCS file: /cvs/gcc/wwwdocs/htdocs/gcc-4.8/changes.html,v > retrieving revision 1.6 > diff -c -r1.6 changes.html > *** htdocs/gcc-4.8/changes.html 17 Jul 2012 19:47:31 - 1.6 > --- htdocs/gcc-4.8/changes.html 19 Jul 2012 10:15:13 - > *** > *** 86,91 > --- 86,97 > libraries. This includes the system libraries and startup modules. > > > + > + On x86_64-mingw32, exceptions propagate through any code, > + including code produced by MSVC (the GCC runtime now uses SEH on > + this target) > + > + > >
Re: [Patch/RFC] SEH exceptions for Win64
On Wed, 25 Jul 2012, Tristan Gingold wrote: > it is ok ? Two minor changes, fine to commit with those. 1. Full stop at the end of the sentence. 2. Avoid extra ... pair, rather add this to the existing. Thanks, Gerald