aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog15
-rw-r--r--gcc/common/config/i386/i386-common.c24
-rw-r--r--gcc/config/i386/cygming.h4
-rw-r--r--gcc/config/i386/i386-protos.h2
-rw-r--r--gcc/config/i386/winnt.c42
-rw-r--r--gcc/coretypes.h3
-rw-r--r--gcc/dwarf2out.c2
-rw-r--r--gcc/expr.c3
-rw-r--r--gcc/opts.c6
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);
diff --git a/gcc/expr.c b/gcc/expr.c
index 3ba5743..5aec53e 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -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 ();
}
diff --git a/gcc/opts.c b/gcc/opts.c
index 6224c6a..d928784 100644
--- a/gcc/opts.c
+++ b/gcc/opts.c
@@ -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 "