aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog48
-rw-r--r--gcc/Makefile.in9
-rw-r--r--gcc/ada/ChangeLog4
-rw-r--r--gcc/ada/misc.c1
-rw-r--r--gcc/c-decl.c1
-rw-r--r--gcc/config/arm/arm-protos.h2
-rw-r--r--gcc/config/arm/arm.c297
-rw-r--r--gcc/config/arm/arm.h12
-rw-r--r--gcc/config/arm/bpabi.h3
-rw-r--r--gcc/config/arm/elf.h2
-rw-r--r--gcc/config/arm/lib1funcs.asm1
-rw-r--r--gcc/config/arm/libgcc-bpabi.ver14
-rw-r--r--gcc/config/arm/t-bpabi8
-rw-r--r--gcc/config/arm/t-symbian5
-rw-r--r--gcc/config/i386/t-netware1
-rw-r--r--gcc/config/ia64/ia64.h2
-rw-r--r--gcc/cp/ChangeLog7
-rw-r--r--gcc/cp/Make-lang.in2
-rw-r--r--gcc/cp/except.c5
-rw-r--r--gcc/doc/tm.texi19
-rw-r--r--gcc/except.c134
-rw-r--r--gcc/except.h1
-rw-r--r--gcc/java/ChangeLog5
-rw-r--r--gcc/java/decl.c1
-rw-r--r--gcc/objc/ChangeLog5
-rw-r--r--gcc/objc/objc-act.c1
-rw-r--r--gcc/optabs.c3
-rw-r--r--gcc/opts.c7
-rw-r--r--gcc/target-def.h14
-rw-r--r--gcc/target.h11
-rw-r--r--gcc/unwind-c.c46
31 files changed, 609 insertions, 62 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 29c1e4f..81a3106 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,51 @@
+2005-06-28 Paul Brook <paul@codesourcery.com>
+
+ * Makefile.in: Set and use UNWIND_H. Install as unwind.h.
+ * c-decl.c (finish_decl): Call default_init_unwind_resume_libfunc.
+ * except.c (add_ehspec_entry): Generate arm eabi filter lists.
+ (assign_filter_values): Ditto.
+ (output_ttype): New function.
+ (output_function_exception_table): Use output_ttype. Generate arm
+ eabi filter lists.
+ (default_init_unwind_resume_libfunc): New function.
+ * except.h (default_init_unwind_resume_libfunc): Add prototype.
+ * optabs.c (init_optabs): Don't set unwind_resume_libfunc.
+ * opts.c (decode_options): Use targetm.unwind_tables_default.
+ * target-def.h (TARGET_ASM_TTYPE): Provide and use definition.
+ (TARGET_ARM_EABI_UNWINDER, TARGET_UNWIND_TABLES_DEFAULT): Ditto.
+ * target.h (struct gcc_target): Add asm.ttype, unwind_tables_default
+ and arm_eabi_unwinder.
+ * unwind-c.c: Support Arm EABI unwinder.
+ * unwind.h: Rename ...
+ * unwind-generic.h: ... To this.
+ * doc/tm.texi (TARGET_ASM_TTYPE, TARGET_ARM_EABI_UNWINDER): Document.
+ (TARGET_UNWID_TABLES_DEFAULT): Document.
+
+ * config/arm/arm-protos.h (arm_output_fn_unwind): Add prototype.
+ * config/arm/arm.c (arm_unwind_emit, arm_output_ttype): New functions.
+ (TARGET_UNWIND_EMIT, TARGET_ASM_TTYPE, TARGET_ARM_EABI_UNWINDER):
+ Define.
+ (thumb_pushpop, thumb_output_function_prologue): Output unwinding
+ directives.
+ (arm_unwind_emit_stm, arm_unwind_emit_set): New functions.
+ * config/arm/arm.h (MUST_USE_SJLJ_EXCEPTIONS): Only define when
+ !TARGET_UNWIND_INFO.
+ (ARM_OUTPUT_FN_UNWIND, ARM_EABI_UNWIND_TABLES): Define.
+ * config/arm/bpabi.h (TARGET_UNWIND_INFO): Define.
+ * config/arm/elf.h (ASM_DECLARE_FUNCTION_NAME,
+ ASM_DECLARE_FUNCTION_SIZE): Use ARM_OUTPUT_FN_UNWIND.
+ * config/arm/lib1funcs.asm: Include libunwind.S.
+ * config/arm/libgcc-bpabi.ver: Add unwinding routines.
+ * config/arm/libunwind.S: New file.
+ * config/arm/pr-support.c: New file.
+ * config/arm/t-bpabi (LIB1ASMFUNCS): Add _unwind.
+ (UNWIND_H, LIB2ADDEH, LIB2ADDEHDEP): Set.
+ * config/arm/t-symbian (UNWIND_H, LIB2ADDEH, LIB2ADDEHDEP): Set.
+ * config/arm/unwind-arm.c: New file.
+ * config/arm/unwind-arm.h: New file.
+ * config/i386/t-netware (USER_H): Remove unwind.h.
+ * config/ia64/ia64.h (TARGET_UNWIND_TABLES_DEFAULT): Define.
+
2005-06-28 DJ Delorie <dj@redhat.com>
* c-decl.c (pop_scope): Move warning control into warning call.
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 98ace16..3ff5c94 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -313,9 +313,10 @@ USER_H = $(srcdir)/ginclude/float.h \
$(srcdir)/ginclude/stdbool.h \
$(srcdir)/ginclude/stddef.h \
$(srcdir)/ginclude/varargs.h \
- $(srcdir)/unwind.h \
$(EXTRA_HEADERS)
+UNWIND_H = $(srcdir)/unwind-generic.h
+
# The GCC to use for compiling libgcc.a and crt*.o.
# Usually the one we just built.
# Don't use this as a dependency--use $(GCC_PASSES) or $(GCC_PARTS).
@@ -534,7 +535,7 @@ LIB2ADDEH = $(srcdir)/unwind-dw2.c $(srcdir)/unwind-dw2-fde.c \
$(srcdir)/unwind-sjlj.c $(srcdir)/gthr-gnat.c $(srcdir)/unwind-c.c
LIB2ADDEHSTATIC = $(LIB2ADDEH)
LIB2ADDEHSHARED = $(LIB2ADDEH)
-LIB2ADDEHDEP = unwind.h unwind-pe.h unwind.inc unwind-dw2-fde.h unwind-dw2.h
+LIB2ADDEHDEP = $(UNWIND_H) unwind-pe.h unwind.inc unwind-dw2-fde.h unwind-dw2.h
# Don't build libunwind by default.
LIBUNWIND =
@@ -3034,7 +3035,7 @@ gcov-dump$(exeext): $(GCOV_DUMP_OBJS) $(LIBDEPS)
# be rebuilt.
# Build the include directory
-stmp-int-hdrs: $(STMP_FIXINC) $(USER_H) xlimits.h
+stmp-int-hdrs: $(STMP_FIXINC) $(USER_H) xlimits.h $(UNWIND_H)
# Copy in the headers provided with gcc.
# The sed command gets just the last file name component;
# this is necessary because VPATH could add a dirname.
@@ -3052,6 +3053,7 @@ stmp-int-hdrs: $(STMP_FIXINC) $(USER_H) xlimits.h
done
rm -f include/limits.h
cp xlimits.h include/limits.h
+ cp $(UNWIND_H) include/unwind.h
chmod a+r include/limits.h
# Install the README
rm -f include/README
@@ -3684,6 +3686,7 @@ install-mkheaders: stmp-int-hdrs $(STMP_FIXPROTO) install-itoolsdirs \
$(DESTDIR)$(itoolsdatadir)/include/$$realfile ; \
done
$(INSTALL_DATA) xlimits.h $(DESTDIR)$(itoolsdatadir)/include/limits.h
+ $(INSTALL_DATA) $(UNWIND_H) $(DESTDIR)$(itoolsdatadir)/include/unwind.h
$(INSTALL_DATA) $(srcdir)/gsyslimits.h \
$(DESTDIR)$(itoolsdatadir)/gsyslimits.h
$(INSTALL_DATA) macro_list $(DESTDIR)$(itoolsdatadir)/macro_list
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index 0e6b95d..18b366b 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,3 +1,7 @@
+2005-06-28 Paul Brook <paul@codesourcery.com>
+
+ * misc.c (gnat_init_gcc_eh): Call default_init_unwind_resume_libfunc.
+
2005-06-14 Olivier Hainque <hainque@adacore.com>
Eric Botcazou <ebotcazou@adacore.com>
diff --git a/gcc/ada/misc.c b/gcc/ada/misc.c
index a993bc1..544419d 100644
--- a/gcc/ada/misc.c
+++ b/gcc/ada/misc.c
@@ -462,6 +462,7 @@ gnat_init_gcc_eh (void)
using_eh_for_cleanups ();
eh_personality_libfunc = init_one_libfunc ("__gnat_eh_personality");
+ default_init_unwind_resume_libfunc ();
lang_eh_type_covers = gnat_eh_type_covers;
lang_eh_runtime_type = gnat_eh_runtime_type;
diff --git a/gcc/c-decl.c b/gcc/c-decl.c
index 728383f..eececb1 100644
--- a/gcc/c-decl.c
+++ b/gcc/c-decl.c
@@ -3537,6 +3537,7 @@ finish_decl (tree decl, tree init, tree asmspec_tree)
= init_one_libfunc (USING_SJLJ_EXCEPTIONS
? "__gcc_personality_sj0"
: "__gcc_personality_v0");
+ default_init_unwind_resume_libfunc ();
using_eh_for_cleanups ();
}
diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h
index 352a289..b15fe10 100644
--- a/gcc/config/arm/arm-protos.h
+++ b/gcc/config/arm/arm-protos.h
@@ -39,6 +39,8 @@ extern HOST_WIDE_INT arm_compute_initial_elimination_offset (unsigned int,
extern HOST_WIDE_INT thumb_compute_initial_elimination_offset (unsigned int,
unsigned int);
extern unsigned int arm_dbx_register_number (unsigned int);
+extern void arm_output_fn_unwind (FILE *, bool);
+
#ifdef TREE_CODE
extern int arm_return_in_memory (tree);
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 5348c79..4e17d3a 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -171,6 +171,10 @@ static bool arm_default_short_enums (void);
static bool arm_align_anon_bitfield (void);
static bool arm_return_in_msb (tree);
static bool arm_must_pass_in_stack (enum machine_mode, tree);
+#ifdef TARGET_UNWIND_INFO
+static void arm_unwind_emit (FILE *, rtx);
+static bool arm_output_ttype (rtx);
+#endif
static tree arm_cxx_guard_type (void);
static bool arm_cxx_guard_mask_bit (void);
@@ -337,6 +341,18 @@ static unsigned HOST_WIDE_INT arm_shift_truncation_mask (enum machine_mode);
#undef TARGET_MUST_PASS_IN_STACK
#define TARGET_MUST_PASS_IN_STACK arm_must_pass_in_stack
+#ifdef TARGET_UNWIND_INFO
+#undef TARGET_UNWIND_EMIT
+#define TARGET_UNWIND_EMIT arm_unwind_emit
+
+/* EABI unwinding tables use a different format for the typeinfo tables. */
+#undef TARGET_ASM_TTYPE
+#define TARGET_ASM_TTYPE arm_output_ttype
+
+#undef TARGET_ARM_EABI_UNWINDER
+#define TARGET_ARM_EABI_UNWINDER true
+#endif /* TARGET_UNWIND_INFO */
+
struct gcc_target targetm = TARGET_INITIALIZER;
/* Obstack for minipool constant handling. */
@@ -12417,6 +12433,21 @@ thumb_pushpop (FILE *f, unsigned long mask, int push, int *cfa_offset,
return;
}
+ if (ARM_EABI_UNWIND_TABLES && push)
+ {
+ fprintf (f, "\t.save\t{");
+ for (regno = 0; regno < 15; regno++)
+ {
+ if (real_regs & (1 << regno))
+ {
+ if (real_regs & ((1 << regno) -1))
+ fprintf (f, ", ");
+ asm_fprintf (f, "%r", regno);
+ }
+ }
+ fprintf (f, "}\n");
+ }
+
fprintf (f, "\t%s\t{", push ? "push" : "pop");
/* Look at the low registers first. */
@@ -13370,6 +13401,11 @@ thumb_output_function_prologue (FILE *f, HOST_WIDE_INT size ATTRIBUTE_UNUSED)
if (current_function_pretend_args_size)
{
+ /* Output unwind directive for the stack adjustment. */
+ if (ARM_EABI_UNWIND_TABLES)
+ fprintf (f, "\t.pad #%d\n",
+ current_function_pretend_args_size);
+
if (cfun->machine->uses_anonymous_args)
{
int num_pushes;
@@ -13435,6 +13471,9 @@ thumb_output_function_prologue (FILE *f, HOST_WIDE_INT size ATTRIBUTE_UNUSED)
work_register = thumb_find_work_register (live_regs_mask);
+ if (ARM_EABI_UNWIND_TABLES)
+ asm_fprintf (f, "\t.pad #16\n");
+
asm_fprintf
(f, "\tsub\t%r, %r, #16\t%@ Create stack backtrace structure\n",
SP_REGNUM, SP_REGNUM);
@@ -14662,3 +14701,261 @@ arm_dbx_register_number (unsigned int regno)
gcc_unreachable ();
}
+
+#ifdef TARGET_UNWIND_INFO
+/* Emit unwind directives for a store-multiple instruction. This should
+ only ever be generated by the function prologue code, so we expect it
+ to have a particular form. */
+
+static void
+arm_unwind_emit_stm (FILE * asm_out_file, rtx p)
+{
+ int i;
+ HOST_WIDE_INT offset;
+ HOST_WIDE_INT nregs;
+ int reg_size;
+ unsigned reg;
+ unsigned lastreg;
+ rtx e;
+
+ /* First insn will adjust the stack pointer. */
+ e = XVECEXP (p, 0, 0);
+ if (GET_CODE (e) != SET
+ || GET_CODE (XEXP (e, 0)) != REG
+ || REGNO (XEXP (e, 0)) != SP_REGNUM
+ || GET_CODE (XEXP (e, 1)) != PLUS)
+ abort ();
+
+ offset = -INTVAL (XEXP (XEXP (e, 1), 1));
+ nregs = XVECLEN (p, 0) - 1;
+
+ reg = REGNO (XEXP (XVECEXP (p, 0, 1), 1));
+ if (reg < 16)
+ {
+ /* The function prologue may also push pc, but not annotate it as it is
+ never restored. We turn this into an stack pointer adjustment. */
+ if (nregs * 4 == offset - 4)
+ {
+ fprintf (asm_out_file, "\t.pad #4\n");
+ offset -= 4;
+ }
+ reg_size = 4;
+ }
+ else if (IS_VFP_REGNUM (reg))
+ {
+ /* FPA register saves use an additional word. */
+ offset -= 4;
+ reg_size = 8;
+ }
+ else if (reg >= FIRST_FPA_REGNUM && reg <= LAST_FPA_REGNUM)
+ {
+ /* FPA registers are done differently. */
+ asm_fprintf (asm_out_file, "\t.save %r, %d\n", reg, nregs);
+ return;
+ }
+ else
+ /* Unknown register type. */
+ abort ();
+
+ /* If the stack increment doesn't match the size of the saved registers,
+ something has gone horribly wrong. */
+ if (offset != nregs * reg_size)
+ abort ();
+
+ fprintf (asm_out_file, "\t.save {");
+
+ offset = 0;
+ lastreg = 0;
+ /* The remaining insns will describe the stores. */
+ for (i = 1; i <= nregs; i++)
+ {
+ /* Expect (set (mem <addr>) (reg)).
+ Where <addr> is (reg:SP) or (plus (reg:SP) (const_int)). */
+ e = XVECEXP (p, 0, i);
+ if (GET_CODE (e) != SET
+ || GET_CODE (XEXP (e, 0)) != MEM
+ || GET_CODE (XEXP (e, 1)) != REG)
+ abort ();
+
+ reg = REGNO (XEXP (e, 1));
+ if (reg < lastreg)
+ abort ();
+
+ if (i != 1)
+ fprintf (asm_out_file, ", ");
+ /* We can't use %r for vfp because we need to use the
+ double precision register names. */
+ if (IS_VFP_REGNUM (reg))
+ asm_fprintf (asm_out_file, "d%d", (reg - FIRST_VFP_REGNUM) / 2);
+ else
+ asm_fprintf (asm_out_file, "%r", reg);
+
+#ifdef ENABLE_CHECKING
+ /* Check that the addresses are consecutive. */
+ e = XEXP (XEXP (e, 0), 0);
+ if (GET_CODE (e) == PLUS)
+ {
+ offset += reg_size;
+ if (GET_CODE (XEXP (e, 0)) != REG
+ || REGNO (XEXP (e, 0)) != SP_REGNUM
+ || GET_CODE (XEXP (e, 1)) != CONST_INT
+ || offset != INTVAL (XEXP (e, 1)))
+ abort ();
+ }
+ else if (i != 1
+ || GET_CODE (e) != REG
+ || REGNO (e) != SP_REGNUM)
+ abort ();
+#endif
+ }
+ fprintf (asm_out_file, "}\n");
+}
+
+/* Emit unwind directives for a SET. */
+
+static void
+arm_unwind_emit_set (FILE * asm_out_file, rtx p)
+{
+ rtx e0;
+ rtx e1;
+
+ e0 = XEXP (p, 0);
+ e1 = XEXP (p, 1);
+ switch (GET_CODE (e0))
+ {
+ case MEM:
+ /* Pushing a single register. */
+ if (GET_CODE (XEXP (e0, 0)) != PRE_DEC
+ || GET_CODE (XEXP (XEXP (e0, 0), 0)) != REG
+ || REGNO (XEXP (XEXP (e0, 0), 0)) != SP_REGNUM)
+ abort ();
+
+ asm_fprintf (asm_out_file, "\t.save ");
+ if (IS_VFP_REGNUM (REGNO (e1)))
+ asm_fprintf(asm_out_file, "{d%d}\n",
+ (REGNO (e1) - FIRST_VFP_REGNUM) / 2);
+ else
+ asm_fprintf(asm_out_file, "{%r}\n", REGNO (e1));
+ break;
+
+ case REG:
+ if (REGNO (e0) == SP_REGNUM)
+ {
+ /* A stack increment. */
+ if (GET_CODE (e1) != PLUS
+ || GET_CODE (XEXP (e1, 0)) != REG
+ || REGNO (XEXP (e1, 0)) != SP_REGNUM
+ || GET_CODE (XEXP (e1, 1)) != CONST_INT)
+ abort ();
+
+ asm_fprintf (asm_out_file, "\t.pad #%d\n",
+ -INTVAL (XEXP (e1, 1)));
+ }
+ else if (REGNO (e0) == HARD_FRAME_POINTER_REGNUM)
+ {
+ HOST_WIDE_INT offset;
+ unsigned reg;
+
+ if (GET_CODE (e1) == PLUS)
+ {
+ if (GET_CODE (XEXP (e1, 0)) != REG
+ || GET_CODE (XEXP (e1, 1)) != CONST_INT)
+ abort ();
+ reg = REGNO (XEXP (e1, 0));
+ offset = INTVAL (XEXP (e1, 1));
+ asm_fprintf (asm_out_file, "\t.setfp %r, %r, #%d\n",
+ HARD_FRAME_POINTER_REGNUM, reg,
+ INTVAL (XEXP (e1, 1)));
+ }
+ else if (GET_CODE (e1) == REG)
+ {
+ reg = REGNO (e1);
+ asm_fprintf (asm_out_file, "\t.setfp %r, %r\n",
+ HARD_FRAME_POINTER_REGNUM, reg);
+ }
+ else
+ abort ();
+ }
+ else if (GET_CODE (e1) == REG && REGNO (e1) == SP_REGNUM)
+ {
+ /* Move from sp to reg. */
+ asm_fprintf (asm_out_file, "\t.movsp %r\n", REGNO (e0));
+ }
+ else
+ abort ();
+ break;
+
+ default:
+ abort ();
+ }
+}
+
+
+/* Emit unwind directives for the given insn. */
+
+static void
+arm_unwind_emit (FILE * asm_out_file, rtx insn)
+{
+ rtx pat;
+
+ if (!ARM_EABI_UNWIND_TABLES)
+ return;
+
+ if (GET_CODE (insn) == NOTE || !RTX_FRAME_RELATED_P (insn))
+ return;
+
+ pat = find_reg_note (insn, REG_FRAME_RELATED_EXPR, NULL_RTX);
+ if (pat)
+ pat = XEXP (pat, 0);
+ else
+ pat = PATTERN (insn);
+
+ switch (GET_CODE (pat))
+ {
+ case SET:
+ arm_unwind_emit_set (asm_out_file, pat);
+ break;
+
+ case SEQUENCE:
+ /* Store multiple. */
+ arm_unwind_emit_stm (asm_out_file, pat);
+ break;
+
+ default:
+ abort();
+ }
+}
+
+
+/* Output a reference from a function exception table to the type_info
+ object X. The EABI specifies that the symbol should be relocated by
+ an R_ARM_TARGET2 relocation. */
+
+static bool
+arm_output_ttype (rtx x)
+{
+ fputs ("\t.word\t", asm_out_file);
+ output_addr_const (asm_out_file, x);
+ /* Use special relocations for symbol references. */
+ if (GET_CODE (x) != CONST_INT)
+ fputs ("(TARGET2)", asm_out_file);
+ fputc ('\n', asm_out_file);
+
+ return TRUE;
+}
+#endif /* TARGET_UNWIND_INFO */
+
+
+/* Output unwind directives for the start/end of a function. */
+
+void
+arm_output_fn_unwind (FILE * f, bool prologue)
+{
+ if (!ARM_EABI_UNWIND_TABLES)
+ return;
+
+ if (prologue)
+ fputs ("\t.fnstart\n", f);
+ else
+ fputs ("\t.fnend\n", f);
+}
diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h
index 65b4bad..327393c 100644
--- a/gcc/config/arm/arm.h
+++ b/gcc/config/arm/arm.h
@@ -770,8 +770,11 @@ extern int arm_structure_size_boundary;
#define FIRST_HI_REGNUM 8
#define LAST_HI_REGNUM 11
+#ifndef TARGET_UNWIND_INFO
/* We use sjlj exceptions for backwards compatibility. */
#define MUST_USE_SJLJ_EXCEPTIONS 1
+#endif
+
/* We can generate DWARF2 Unwind info, even though we don't use it. */
#define DWARF2_UNWIND_INFO 1
@@ -1977,6 +1980,15 @@ typedef struct
if (!TARGET_LONG_CALLS || ! DECL_SECTION_NAME (DECL)) \
arm_encode_call_attribute (DECL, SHORT_CALL_FLAG_CHAR)
+#define ARM_OUTPUT_FN_UNWIND(F, PROLOGUE) arm_output_fn_unwind (F, PROLOGUE)
+
+#ifdef TARGET_UNWIND_INFO
+#define ARM_EABI_UNWIND_TABLES \
+ ((!USING_SJLJ_EXCEPTIONS && flag_exceptions) || flag_unwind_tables)
+#else
+#define ARM_EABI_UNWIND_TABLES 0
+#endif
+
/* The macros REG_OK_FOR..._P assume that the arg is a REG rtx
and check its validity for a certain class.
We have two alternate definitions for each of them.
diff --git a/gcc/config/arm/bpabi.h b/gcc/config/arm/bpabi.h
index 981c58c..7fb7d6a 100644
--- a/gcc/config/arm/bpabi.h
+++ b/gcc/config/arm/bpabi.h
@@ -26,6 +26,9 @@
/* Assume that AAPCS ABIs should adhere to the full BPABI. */
#define TARGET_BPABI (TARGET_AAPCS_BASED)
+/* BPABI targets use EABI frame unwinding tables. */
+#define TARGET_UNWIND_INFO 1
+
/* Section 4.1 of the AAPCS requires the use of VFP format. */
#define FPUTYPE_DEFAULT FPUTYPE_VFP
diff --git a/gcc/config/arm/elf.h b/gcc/config/arm/elf.h
index a560021..ae3d533 100644
--- a/gcc/config/arm/elf.h
+++ b/gcc/config/arm/elf.h
@@ -77,6 +77,7 @@
ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "function"); \
ASM_DECLARE_RESULT (FILE, DECL_RESULT (DECL)); \
ASM_OUTPUT_LABEL(FILE, NAME); \
+ ARM_OUTPUT_FN_UNWIND (FILE, TRUE); \
} \
while (0)
@@ -85,6 +86,7 @@
#define ASM_DECLARE_FUNCTION_SIZE(FILE, FNAME, DECL) \
do \
{ \
+ ARM_OUTPUT_FN_UNWIND (FILE, FALSE); \
ARM_DECLARE_FUNCTION_SIZE (FILE, FNAME, DECL); \
if (!flag_inhibit_size_directive) \
ASM_OUTPUT_MEASURED_SIZE (FILE, FNAME); \
diff --git a/gcc/config/arm/lib1funcs.asm b/gcc/config/arm/lib1funcs.asm
index 519b41e..ebf31eb 100644
--- a/gcc/config/arm/lib1funcs.asm
+++ b/gcc/config/arm/lib1funcs.asm
@@ -1309,4 +1309,5 @@ LSYM(Lchange_\register):
#include "ieee754-df.S"
#include "ieee754-sf.S"
#include "bpabi.S"
+#include "libunwind.S"
#endif /* __symbian__ */
diff --git a/gcc/config/arm/libgcc-bpabi.ver b/gcc/config/arm/libgcc-bpabi.ver
index 788e3ad..35966bb 100644
--- a/gcc/config/arm/libgcc-bpabi.ver
+++ b/gcc/config/arm/libgcc-bpabi.ver
@@ -60,4 +60,18 @@ GCC_3.5 {
__aeabi_ulcmp
__aeabi_ul2d
__aeabi_ul2f
+
+ # Exception-Handling
+ # \S 7.5
+ _Unwind_Complete
+ _Unwind_VRS_Get
+ _Unwind_VRS_Set
+ _Unwind_VRS_Pop
+ # \S 9.2
+ __aeabi_unwind_cpp_pr0
+ __aeabi_unwind_cpp_pr1
+ __aeabi_unwind_cpp_pr2
+ # The libstdc++ exception-handling personality routine uses this
+ # GNU-specific entry point.
+ __gnu_unwind_frame
}
diff --git a/gcc/config/arm/t-bpabi b/gcc/config/arm/t-bpabi
index 74445dd..74c0ae1 100644
--- a/gcc/config/arm/t-bpabi
+++ b/gcc/config/arm/t-bpabi
@@ -1,9 +1,15 @@
# Add the bpabi.S functions.
-LIB1ASMFUNCS += _aeabi_lcmp _aeabi_ulcmp _aeabi_ldivmod _aeabi_uldivmod
+LIB1ASMFUNCS += _aeabi_lcmp _aeabi_ulcmp _aeabi_ldivmod _aeabi_uldivmod \
+ _unwind
# Add the BPABI C functions.
LIB2FUNCS_EXTRA = $(srcdir)/config/arm/bpabi.c
+UNWIND_H = $(srcdir)/config/arm/unwind-arm.h
+LIB2ADDEH = $(srcdir)/config/arm/unwind-arm.c \
+ $(srcdir)/config/arm/pr-support.c $(srcdir)/unwind-c.c
+LIB2ADDEHDEP = $(UNWIND_H)
+
# Add the BPABI names.
SHLIB_MAPFILES += $(srcdir)/config/arm/libgcc-bpabi.ver
diff --git a/gcc/config/arm/t-symbian b/gcc/config/arm/t-symbian
index 34a58ce..8f72b3e 100644
--- a/gcc/config/arm/t-symbian
+++ b/gcc/config/arm/t-symbian
@@ -12,6 +12,11 @@ LIB1ASMFUNCS += \
_truncdfsf2 _negsf2 _addsubsf3 _muldivsf3 _cmpsf2 _unordsf2 \
_fixsfsi _fixunssfsi
+# Include the gcc personality routine
+UNWIND_H = $(srcdir)/config/arm/unwind-arm.h
+LIB2ADDEH = $(srcdir)/unwind-c.c
+LIB2ADDEHDEP = $(UNWIND_H)
+
# Create a multilib for processors with VFP floating-point, and a
# multilib for those without -- using the soft-float ABI in both
# cases. Symbian OS object should be compiled with interworking
diff --git a/gcc/config/i386/t-netware b/gcc/config/i386/t-netware
index cc229b8..2d3a828 100644
--- a/gcc/config/i386/t-netware
+++ b/gcc/config/i386/t-netware
@@ -6,5 +6,4 @@ netware.o: $(srcdir)/config/i386/netware.c $(RTL_H) $(TREE_H) $(CONFIG_H) $(TM_P
# We don't need some of GCC's own include files.
USER_H = $(srcdir)/ginclude/stdarg.h \
$(srcdir)/ginclude/varargs.h \
- $(srcdir)/unwind.h \
$(EXTRA_HEADERS) $(LANG_EXTRA_HEADERS)
diff --git a/gcc/config/ia64/ia64.h b/gcc/config/ia64/ia64.h
index e97bf07..9e52773 100644
--- a/gcc/config/ia64/ia64.h
+++ b/gcc/config/ia64/ia64.h
@@ -1985,6 +1985,8 @@ extern int ia64_final_schedule;
#define TARGET_UNWIND_INFO 1
+#define TARGET_UNWIND_TABLES_DEFAULT true
+
#define EH_RETURN_DATA_REGNO(N) ((N) < 4 ? (N) + 15 : INVALID_REGNUM)
/* This function contains machine specific function data. */
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index d22990e..128ea64 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,10 @@
+2005-06-28 Paul Brook <paul@codesourcery.com>
+
+ * Make-lang.in (cp/except.o): Depend on $(TARGET_H)
+ * except.c: Include target.h.
+ (init_exception_processing): Initialize unwind_resume_libfunc.
+ * doc/tm.texi: Document TARGET_ASM_TTYPE
+
2005-06-26 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* call.c (build_over_call): Pass in named argument list to
diff --git a/gcc/cp/Make-lang.in b/gcc/cp/Make-lang.in
index 6adedec..f555f31 100644
--- a/gcc/cp/Make-lang.in
+++ b/gcc/cp/Make-lang.in
@@ -272,7 +272,7 @@ cp/ptree.o: cp/ptree.c $(CXX_TREE_H) $(TM_H)
cp/rtti.o: cp/rtti.c $(CXX_TREE_H) $(TM_H) flags.h toplev.h convert.h \
gt-cp-rtti.h
cp/except.o: cp/except.c $(CXX_TREE_H) $(TM_H) flags.h $(RTL_H) except.h \
- toplev.h cp/cfns.h $(EXPR_H) libfuncs.h tree-inline.h
+ toplev.h cp/cfns.h $(EXPR_H) libfuncs.h tree-inline.h $(TARGET_H)
cp/expr.o: cp/expr.c $(CXX_TREE_H) $(TM_H) $(RTL_H) flags.h $(EXPR_H) \
toplev.h except.h $(TM_P_H)
cp/pt.o: cp/pt.c $(CXX_TREE_H) $(TM_H) cp/decl.h cp/cp-objcp-common.h \
diff --git a/gcc/cp/except.c b/gcc/cp/except.c
index de83bba..be7208e 100644
--- a/gcc/cp/except.c
+++ b/gcc/cp/except.c
@@ -38,6 +38,7 @@ Boston, MA 02110-1301, USA. */
#include "toplev.h"
#include "tree-inline.h"
#include "tree-iterator.h"
+#include "target.h"
static void push_eh_cleanup (tree);
static tree prepare_eh_type (tree);
@@ -79,6 +80,10 @@ init_exception_processing (void)
eh_personality_libfunc = init_one_libfunc (USING_SJLJ_EXCEPTIONS
? "__gxx_personality_sj0"
: "__gxx_personality_v0");
+ if (targetm.arm_eabi_unwinder)
+ unwind_resume_libfunc = init_one_libfunc ("__cxa_end_cleanup");
+ else
+ default_init_unwind_resume_libfunc ();
lang_eh_runtime_type = build_eh_type_type;
lang_protect_cleanup_actions = &cp_protect_cleanup_actions;
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index cd2bf87..bbca6b9 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -7648,6 +7648,11 @@ Define this macro if your target has ABI specified unwind tables. Usually
these will be output by @code{TARGET_UNWIND_EMIT}.
@end defmac
+@deftypevar {Target Hook} bool TARGET_UNWID_TABLES_DEFAULT
+This variable should be set to @code{true} if the target ABI requires unwinding
+tables even when exceptions are not used.
+@end deftypevar
+
@defmac MUST_USE_SJLJ_EXCEPTIONS
This macro need only be defined if @code{DWARF2_UNWIND_INFO} is
runtime-variable. In that case, @file{except.h} cannot correctly
@@ -7698,6 +7703,20 @@ register in Dwarf. Otherwise, this hook should return @code{NULL_RTX}.
If not defined, the default is to return @code{NULL_RTX}.
@end deftypefn
+@deftypefn {Target Hook} bool TARGET_ASM_TTYPE (rtx @var{sym})
+This hook is used to output a reference from a frame unwinding table to
+the type_info object identified by @var{sym}. It should return @code{true}
+if the reference was output. Returning @code{false} will cause the
+reference to be output using the normal Dwarf2 routines.
+@end deftypefn
+
+@deftypefn {Target Hook} bool TARGET_ARM_EABI_UNWINDER
+This hook should be set to @code{true} on targets that use an ARM EABI
+based unwinding library, and @code{false} on other targets. This effects
+the format of unwinding tables, and how the unwinder in entered after
+running a cleanup. The default is @code{false}.
+@end deftypefn
+
@node Alignment Output
@subsection Assembler Commands for Alignment
diff --git a/gcc/except.c b/gcc/except.c
index 3c42910..1bcdc28 100644
--- a/gcc/except.c
+++ b/gcc/except.c
@@ -1134,12 +1134,23 @@ add_ehspec_entry (htab_t ehspec_hash, htab_t ttypes_hash, tree list)
n->filter = -(VARRAY_ACTIVE_SIZE (cfun->eh->ehspec_data) + 1);
*slot = n;
- /* Look up each type in the list and encode its filter
- value as a uleb128. Terminate the list with 0. */
+ /* Generate a 0 terminated list of filter values. */
for (; list ; list = TREE_CHAIN (list))
- push_uleb128 (&cfun->eh->ehspec_data,
- add_ttypes_entry (ttypes_hash, TREE_VALUE (list)));
- VARRAY_PUSH_UCHAR (cfun->eh->ehspec_data, 0);
+ {
+ if (targetm.arm_eabi_unwinder)
+ VARRAY_PUSH_TREE (cfun->eh->ehspec_data, TREE_VALUE (list));
+ else
+ {
+ /* Look up each type in the list and encode its filter
+ value as a uleb128. */
+ push_uleb128 (&cfun->eh->ehspec_data,
+ add_ttypes_entry (ttypes_hash, TREE_VALUE (list)));
+ }
+ }
+ if (targetm.arm_eabi_unwinder)
+ VARRAY_PUSH_TREE (cfun->eh->ehspec_data, NULL_TREE);
+ else
+ VARRAY_PUSH_UCHAR (cfun->eh->ehspec_data, 0);
}
return n->filter;
@@ -1157,7 +1168,10 @@ assign_filter_values (void)
htab_t ttypes, ehspec;
cfun->eh->ttype_data = VEC_alloc (tree, gc, 16);
- VARRAY_UCHAR_INIT (cfun->eh->ehspec_data, 64, "ehspec_data");
+ if (targetm.arm_eabi_unwinder)
+ VARRAY_TREE_INIT (cfun->eh->ehspec_data, 64, "ehspec_data");
+ else
+ VARRAY_UCHAR_INIT (cfun->eh->ehspec_data, 64, "ehspec_data");
ttypes = htab_create (31, ttypes_filter_hash, ttypes_filter_eq, free);
ehspec = htab_create (31, ehspec_filter_hash, ehspec_filter_eq, free);
@@ -3377,6 +3391,54 @@ default_exception_section (void)
readonly_data_section ();
}
+
+/* Output a reference from an exception table to the type_info object TYPE.
+ TT_FORMAT and TT_FORMAT_SIZE descibe the DWARF encoding method used for
+ the value. */
+
+static void
+output_ttype (tree type, int tt_format, int tt_format_size)
+{
+ rtx value;
+
+ if (type == NULL_TREE)
+ value = const0_rtx;
+ else
+ {
+ struct cgraph_varpool_node *node;
+
+ type = lookup_type_for_runtime (type);
+ value = expand_expr (type, NULL_RTX, VOIDmode, EXPAND_INITIALIZER);
+
+ /* Let cgraph know that the rtti decl is used. Not all of the
+ paths below go through assemble_integer, which would take
+ care of this for us. */
+ STRIP_NOPS (type);
+ if (TREE_CODE (type) == ADDR_EXPR)
+ {
+ type = TREE_OPERAND (type, 0);
+ if (TREE_CODE (type) == VAR_DECL)
+ {
+ node = cgraph_varpool_node (type);
+ if (node)
+ cgraph_varpool_mark_needed_node (node);
+ }
+ }
+ else if (TREE_CODE (type) != INTEGER_CST)
+ abort ();
+ }
+
+ /* Allow the target to override the type table entry format. */
+ if (targetm.asm_out.ttype (value))
+ return;
+
+ if (tt_format == DW_EH_PE_absptr || tt_format == DW_EH_PE_aligned)
+ assemble_integer (value, tt_format_size,
+ tt_format_size * BITS_PER_UNIT, 1);
+ else
+ dw2_asm_output_encoded_addr_rtx (tt_format, value, NULL);
+}
+
void
output_function_exception_table (void)
{
@@ -3536,40 +3598,7 @@ output_function_exception_table (void)
while (i-- > 0)
{
tree type = VEC_index (tree, cfun->eh->ttype_data, i);
- rtx value;
-
- if (type == NULL_TREE)
- value = const0_rtx;
- else
- {
- struct cgraph_varpool_node *node;
-
- type = lookup_type_for_runtime (type);
- value = expand_expr (type, NULL_RTX, VOIDmode, EXPAND_INITIALIZER);
-
- /* Let cgraph know that the rtti decl is used. Not all of the
- paths below go through assemble_integer, which would take
- care of this for us. */
- STRIP_NOPS (type);
- if (TREE_CODE (type) == ADDR_EXPR)
- {
- type = TREE_OPERAND (type, 0);
- if (TREE_CODE (type) == VAR_DECL)
- {
- node = cgraph_varpool_node (type);
- if (node)
- cgraph_varpool_mark_needed_node (node);
- }
- }
- else
- gcc_assert (TREE_CODE (type) == INTEGER_CST);
- }
-
- if (tt_format == DW_EH_PE_absptr || tt_format == DW_EH_PE_aligned)
- assemble_integer (value, tt_format_size,
- tt_format_size * BITS_PER_UNIT, 1);
- else
- dw2_asm_output_encoded_addr_rtx (tt_format, value, NULL);
+ output_ttype (type, tt_format, tt_format_size);
}
#ifdef HAVE_AS_LEB128
@@ -3580,8 +3609,16 @@ output_function_exception_table (void)
/* ??? Decode and interpret the data for flag_debug_asm. */
n = VARRAY_ACTIVE_SIZE (cfun->eh->ehspec_data);
for (i = 0; i < n; ++i)
- dw2_asm_output_data (1, VARRAY_UCHAR (cfun->eh->ehspec_data, i),
- (i ? NULL : "Exception specification table"));
+ {
+ if (targetm.arm_eabi_unwinder)
+ {
+ tree type = VARRAY_TREE (cfun->eh->ehspec_data, i);
+ output_ttype (type, tt_format, tt_format_size);
+ }
+ else
+ dw2_asm_output_data (1, VARRAY_UCHAR (cfun->eh->ehspec_data, i),
+ (i ? NULL : "Exception specification table"));
+ }
current_function_section (current_function_decl);
}
@@ -3730,4 +3767,17 @@ verify_eh_tree (struct function *fun)
}
}
}
+
+
+/* Initialize unwind_resume_libfunc. */
+
+void
+default_init_unwind_resume_libfunc (void)
+{
+ /* The default c++ routines aren't actually c++ specific, so use those. */
+ unwind_resume_libfunc =
+ init_one_libfunc ( USING_SJLJ_EXCEPTIONS ? "_Unwind_SjLj_Resume"
+ : "_Unwind_Resume");
+}
+
#include "gt-except.h"
diff --git a/gcc/except.h b/gcc/except.h
index 72073c0..d5e391d 100644
--- a/gcc/except.h
+++ b/gcc/except.h
@@ -85,6 +85,7 @@ typedef tree (*duplicate_eh_regions_map) (tree, void *);
extern int duplicate_eh_regions (struct function *, duplicate_eh_regions_map, void *, int);
extern void sjlj_emit_function_exit_after (rtx);
+extern void default_init_unwind_resume_libfunc (void);
extern struct eh_region *gen_eh_region_cleanup (struct eh_region *,
struct eh_region *);
diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog
index 239e2b7..68699ff 100644
--- a/gcc/java/ChangeLog
+++ b/gcc/java/ChangeLog
@@ -1,3 +1,8 @@
+2005-06-28 Paul Brook <paul@codesourcery.com>
+
+ * decl.c (java_init_decl_processing): Call
+ default_init_unwind_resume_libfunc.
+
2005-06-27 Tom Tromey <tromey@redhat.com>
PR java/21540, PR java/13788:
diff --git a/gcc/java/decl.c b/gcc/java/decl.c
index b869016..e63ef84 100644
--- a/gcc/java/decl.c
+++ b/gcc/java/decl.c
@@ -1197,6 +1197,7 @@ java_init_decl_processing (void)
eh_personality_libfunc = init_one_libfunc (USING_SJLJ_EXCEPTIONS
? "__gcj_personality_sj0"
: "__gcj_personality_v0");
+ default_init_unwind_resume_libfunc ();
lang_eh_runtime_type = do_nothing;
diff --git a/gcc/objc/ChangeLog b/gcc/objc/ChangeLog
index 57a326a..52325f4 100644
--- a/gcc/objc/ChangeLog
+++ b/gcc/objc/ChangeLog
@@ -1,3 +1,8 @@
+2005-06-28 Paul Brook <paul@codesourcery.com>
+
+ * objc-act.c (objc_init_exceptions): Call
+ default_init_unwind_resume_libfunc.
+
2005-06-27 Ziemowit Laski <zlaski@apple.com>
* objc-act.c (objc_build_struct): Save the TYPE_OBJC_INFO
diff --git a/gcc/objc/objc-act.c b/gcc/objc/objc-act.c
index 35951fe..d4c20a8 100644
--- a/gcc/objc/objc-act.c
+++ b/gcc/objc/objc-act.c
@@ -3407,6 +3407,7 @@ objc_init_exceptions (void)
= init_one_libfunc (USING_SJLJ_EXCEPTIONS
? "__gnu_objc_personality_sj0"
: "__gnu_objc_personality_v0");
+ default_init_unwind_resume_libfunc ();
using_eh_for_cleanups ();
lang_eh_runtime_type = objc_eh_runtime_type;
}
diff --git a/gcc/optabs.c b/gcc/optabs.c
index 1fb1136..6f5716e 100644
--- a/gcc/optabs.c
+++ b/gcc/optabs.c
@@ -5288,9 +5288,6 @@ init_optabs (void)
memset_libfunc = init_one_libfunc ("memset");
setbits_libfunc = init_one_libfunc ("__setbits");
- unwind_resume_libfunc = init_one_libfunc (USING_SJLJ_EXCEPTIONS
- ? "_Unwind_SjLj_Resume"
- : "_Unwind_Resume");
#ifndef DONT_USE_BUILTIN_SETJMP
setjmp_libfunc = init_one_libfunc ("__builtin_setjmp");
longjmp_libfunc = init_one_libfunc ("__builtin_longjmp");
diff --git a/gcc/opts.c b/gcc/opts.c
index ec41688..e96d6d5 100644
--- a/gcc/opts.c
+++ b/gcc/opts.c
@@ -627,11 +627,8 @@ decode_options (unsigned int argc, const char **argv)
modify it. */
target_flags = targetm.default_target_flags;
- /* Unwind tables are always present when a target has ABI-specified unwind
- tables, so the default should be ON. */
-#ifdef TARGET_UNWIND_INFO
- flag_unwind_tables = TARGET_UNWIND_INFO;
-#endif
+ /* Some tagets have ABI-specified unwind tables. */
+ flag_unwind_tables = targetm.unwind_tables_default;
#ifdef OPTIMIZATION_OPTIONS
/* Allow default optimizations to be specified on a per-machine basis. */
diff --git a/gcc/target-def.h b/gcc/target-def.h
index cdaf3d3..9998a19 100644
--- a/gcc/target-def.h
+++ b/gcc/target-def.h
@@ -70,6 +70,10 @@ Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#define TARGET_ASM_INTERNAL_LABEL default_internal_label
#endif
+#ifndef TARGET_ARM_TTYPE
+#define TARGET_ASM_TTYPE hook_bool_rtx_false
+#endif
+
#ifndef TARGET_ASM_ASSEMBLE_VISIBILITY
#define TARGET_ASM_ASSEMBLE_VISIBILITY default_assemble_visibility
#endif
@@ -217,6 +221,7 @@ Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
TARGET_ASM_EMIT_UNWIND_LABEL, \
TARGET_UNWIND_EMIT, \
TARGET_ASM_INTERNAL_LABEL, \
+ TARGET_ASM_TTYPE, \
TARGET_ASM_ASSEMBLE_VISIBILITY, \
TARGET_ASM_FUNCTION_PROLOGUE, \
TARGET_ASM_FUNCTION_END_PROLOGUE, \
@@ -401,6 +406,8 @@ Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#define TARGET_STACK_PROTECT_GUARD default_stack_protect_guard
#define TARGET_STACK_PROTECT_FAIL default_external_stack_protect_fail
+#define TARGET_ARM_EABI_UNWINDER false
+
#define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_tree_false
#define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_tree_false
#define TARGET_PROMOTE_PROTOTYPES hook_bool_tree_false
@@ -444,6 +451,9 @@ Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN \
}
+#ifndef TARGET_UNWIND_TABLES_DEFAULT
+#define TARGET_UNWIND_TABLES_DEFAULT false
+#endif
#ifndef TARGET_HANDLE_PRAGMA_REDEFINE_EXTNAME
#define TARGET_HANDLE_PRAGMA_REDEFINE_EXTNAME 0
@@ -506,7 +516,7 @@ Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
TARGET_CXX_KEY_METHOD_MAY_BE_INLINE, \
TARGET_CXX_DETERMINE_CLASS_DATA_VISIBILITY, \
TARGET_CXX_CLASS_DATA_ALWAYS_COMDAT, \
- TARGET_CXX_USE_AEABI_ATEXIT \
+ TARGET_CXX_USE_AEABI_ATEXIT, \
}
/* The whole shebang. */
@@ -572,6 +582,7 @@ Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
TARGET_INVALID_WITHIN_DOLOOP, \
TARGET_CALLS, \
TARGET_CXX, \
+ TARGET_UNWIND_TABLES_DEFAULT, \
TARGET_HAVE_NAMED_SECTIONS, \
TARGET_HAVE_CTORS_DTORS, \
TARGET_HAVE_TLS, \
@@ -582,6 +593,7 @@ Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
TARGET_HANDLE_PRAGMA_REDEFINE_EXTNAME, \
TARGET_HANDLE_PRAGMA_EXTERN_PREFIX, \
TARGET_RELAXED_ORDERING, \
+ TARGET_ARM_EABI_UNWINDER \
}
#include "hooks.h"
diff --git a/gcc/target.h b/gcc/target.h
index 87e644b..364e95a 100644
--- a/gcc/target.h
+++ b/gcc/target.h
@@ -93,6 +93,9 @@ struct gcc_target
/* Output an internal label. */
void (* internal_label) (FILE *, const char *, unsigned long);
+ /* Emit a ttype table reference to a typeinfo object. */
+ bool (* ttype) (rtx);
+
/* Emit an assembler directive to set visibility for the symbol
associated with the tree decl. */
void (* visibility) (tree, int);
@@ -635,6 +638,9 @@ struct gcc_target
bool (*use_aeabi_atexit) (void);
} cxx;
+ /* True if unwinding tables should be generated by default. */
+ bool unwind_tables_default;
+
/* Leave the boolean fields at the end. */
/* True if arbitrary sections are supported. */
@@ -671,6 +677,11 @@ struct gcc_target
synchronization is explicitly requested. */
bool relaxed_ordering;
+ /* Returns true if we should generate exception tables for use with the
+ ARM EABI. The effects the encoding of function exception specifications.
+ */
+ bool arm_eabi_unwinder;
+
/* Leave the boolean fields at the end. */
};
diff --git a/gcc/unwind-c.c b/gcc/unwind-c.c
index fc76edb..6fb66e0 100644
--- a/gcc/unwind-c.c
+++ b/gcc/unwind-c.c
@@ -81,6 +81,20 @@ parse_lsda_header (struct _Unwind_Context *context, const unsigned char *p,
return p;
}
+#ifdef __ARM_EABI_UNWINDER__
+/* ARM EABI personality routines must also unwind the stack. */
+#define CONTINUE_UNWINDING \
+ do \
+ { \
+ if (__gnu_unwind_frame (ue_header, context) != _URC_OK) \
+ return _URC_FAILURE; \
+ return _URC_CONTINUE_UNWIND; \
+ } \
+ while (0)
+#else
+#define CONTINUE_UNWINDING return _URC_CONTINUE_UNWIND
+#endif
+
#ifdef __USING_SJLJ_EXCEPTIONS__
#define PERSONALITY_FUNCTION __gcc_personality_sj0
#define __builtin_eh_return_data_regno(x) x
@@ -88,6 +102,16 @@ parse_lsda_header (struct _Unwind_Context *context, const unsigned char *p,
#define PERSONALITY_FUNCTION __gcc_personality_v0
#endif
+#ifdef __ARM_EABI_UNWINDER__
+_Unwind_Reason_Code
+PERSONALITY_FUNCTION (_Unwind_State, struct _Unwind_Exception *,
+ struct _Unwind_Context *);
+
+_Unwind_Reason_Code
+PERSONALITY_FUNCTION (_Unwind_State state,
+ struct _Unwind_Exception * ue_header,
+ struct _Unwind_Context * context)
+#else
_Unwind_Reason_Code
PERSONALITY_FUNCTION (int, _Unwind_Action, _Unwind_Exception_Class,
struct _Unwind_Exception *, struct _Unwind_Context *);
@@ -98,24 +122,37 @@ PERSONALITY_FUNCTION (int version,
_Unwind_Exception_Class exception_class ATTRIBUTE_UNUSED,
struct _Unwind_Exception *ue_header,
struct _Unwind_Context *context)
+#endif
{
lsda_header_info info;
const unsigned char *language_specific_data, *p, *action_record;
_Unwind_Ptr landing_pad, ip;
+#ifdef __ARM_EABI_UNWINDER__
+ if (state != _US_UNWIND_FRAME_STARTING)
+ CONTINUE_UNWINDING;
+
+ /* The dwarf unwinder assumes the context structure holds things like the
+ function and LSDA pointers. The ARM implementation caches these in
+ the exception header (UCB). To avoid rewriting everything we make the
+ virtual IP register point at the UCB. */
+ ip = (_Unwind_Ptr) ue_header;
+ _Unwind_SetGR (context, 12, ip);
+#else
if (version != 1)
return _URC_FATAL_PHASE1_ERROR;
/* Currently we only support cleanups for C. */
if ((actions & _UA_CLEANUP_PHASE) == 0)
- return _URC_CONTINUE_UNWIND;
+ CONTINUE_UNWINDING;
+#endif
language_specific_data = (const unsigned char *)
_Unwind_GetLanguageSpecificData (context);
/* If no LSDA, then there are no handlers or cleanups. */
if (! language_specific_data)
- return _URC_CONTINUE_UNWIND;
+ CONTINUE_UNWINDING;
/* Parse the LSDA header. */
p = parse_lsda_header (context, language_specific_data, &info);
@@ -171,20 +208,19 @@ PERSONALITY_FUNCTION (int version,
goto found_something;
}
}
-
#endif
/* IP is not in table. No associated cleanups. */
/* ??? This is where C++ calls std::terminate to catch throw
from a destructor. */
- return _URC_CONTINUE_UNWIND;
+ CONTINUE_UNWINDING;
found_something:
if (landing_pad == 0)
{
/* IP is present, but has a null landing pad.
No handler to be run. */
- return _URC_CONTINUE_UNWIND;
+ CONTINUE_UNWINDING;
}
_Unwind_SetGR (context, __builtin_eh_return_data_regno (0),