diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 15 | ||||
-rw-r--r-- | gcc/common/config/i386/i386-common.c | 24 | ||||
-rw-r--r-- | gcc/config/i386/cygming.h | 4 | ||||
-rw-r--r-- | gcc/config/i386/i386-protos.h | 2 | ||||
-rw-r--r-- | gcc/config/i386/winnt.c | 42 | ||||
-rw-r--r-- | gcc/coretypes.h | 3 | ||||
-rw-r--r-- | gcc/dwarf2out.c | 2 | ||||
-rw-r--r-- | gcc/expr.c | 3 | ||||
-rw-r--r-- | gcc/opts.c | 6 |
9 files changed, 96 insertions, 5 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d4bd184..174d62f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,18 @@ +2012-07-19 Tristan Gingold <gingold@adacore.com> + Richard Henderson <rth@redhat.com> + + * 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. + 2012-07-18 Maciej W. Rozycki <macro@codesourcery.com> Chao-ying Fu <fu@mips.com> 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..17ee1375 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_except_personality (rtx personality) +{ + int flags = 0; + + if (!TARGET_SEH) + return; + + fputs ("\t.seh_handler\t", asm_out_file); + output_addr_const (asm_out_file, personality); + +#if 0 + /* ??? The current implementation of _GCC_specific_handler requires + both except and unwind handling, regardless of which sorts the + user-level function requires. */ + eh_region r; + FOR_ALL_EH_REGION(r) + { + if (r->type == ERT_CLEANUP) + flags |= 1; + else + flags |= 2; + } +#else + flags = 3; +#endif + + if (flags & 1) + fputs (", @unwind", asm_out_file); + if (flags & 2) + fputs (", @except", asm_out_file); + fputc ('\n', asm_out_file); +} + +void +i386_pe_seh_init_sections (void) +{ + if (TARGET_SEH) + exception_section = get_unnamed_section (0, output_section_asm_op, + "\t.seh_handlerdata"); +} void i386_pe_start_function (FILE *f, const char *name, tree decl) diff --git a/gcc/coretypes.h b/gcc/coretypes.h index 7e5c048..02578f6 100644 --- a/gcc/coretypes.h +++ b/gcc/coretypes.h @@ -116,7 +116,8 @@ enum unwind_info_type UI_NONE, UI_SJLJ, UI_DWARF2, - UI_TARGET + UI_TARGET, + UI_SEH }; /* Callgraph node profile representation. */ diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index d4b6831..dd48d1d 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -976,7 +976,7 @@ dwarf2out_begin_prologue (unsigned int line ATTRIBUTE_UNUSED, call-site information. We must emit this label if it might be used. */ if (!do_frame && (!flag_exceptions - || targetm_common.except_unwind_info (&global_options) != UI_TARGET)) + || targetm_common.except_unwind_info (&global_options) == UI_SJLJ)) return; fnsec = function_section (current_function_decl); @@ -11011,6 +11011,9 @@ build_personality_function (const char *lang) case UI_TARGET: unwind_and_version = "_v0"; break; + case UI_SEH: + unwind_and_version = "_seh0"; + break; default: gcc_unreachable (); } @@ -717,7 +717,7 @@ finish_options (struct gcc_options *opts, struct gcc_options *opts_set, if (opts->x_flag_exceptions && opts->x_flag_reorder_blocks_and_partition - && (ui_except == UI_SJLJ || ui_except == UI_TARGET)) + && (ui_except == UI_SJLJ || ui_except >= UI_TARGET)) { inform (loc, "-freorder-blocks-and-partition does not work " @@ -732,7 +732,7 @@ finish_options (struct gcc_options *opts, struct gcc_options *opts_set, if (opts->x_flag_unwind_tables && !targetm_common.unwind_tables_default && opts->x_flag_reorder_blocks_and_partition - && (ui_except == UI_SJLJ || ui_except == UI_TARGET)) + && (ui_except == UI_SJLJ || ui_except >= UI_TARGET)) { inform (loc, "-freorder-blocks-and-partition does not support " @@ -749,7 +749,7 @@ finish_options (struct gcc_options *opts, struct gcc_options *opts_set, && (!targetm_common.have_named_sections || (opts->x_flag_unwind_tables && targetm_common.unwind_tables_default - && (ui_except == UI_SJLJ || ui_except == UI_TARGET)))) + && (ui_except == UI_SJLJ || ui_except >= UI_TARGET)))) { inform (loc, "-freorder-blocks-and-partition does not work " |