From 1774763d780a39d0233820f41aa03e244d0b4033 Mon Sep 17 00:00:00 2001 From: pbrook Date: Tue, 28 Jun 2005 19:52:27 +0000 Subject: [PATCH] 2005-06-28 Paul Brook gcc/ * 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. gcc/cp/ * 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 gcc/ada/ * misc.c (gnat_init_gcc_eh): Call default_init_unwind_resume_libfunc. gcc/java/ * decl.c (java_init_decl_processing): Call default_init_unwind_resume_libfunc. gcc/objc/ * objc-act.c (objc_init_exceptions): Call default_init_unwind_resume_libfunc. libstdc++/ * acinclude.m4 (GLIBCXX_ENABLE_SJLJ_EXCEPTIONS): Check for __cxa_end_cleanup. * libsupc++/Makefile.am (sources): Add eh_call.c and eh_arm.c. * libsupc++/eh_arm.cc: New file. * libsupc++/eh_call.cc: New file. * libsupc++/eh_catch.cc (__cxa_get_exception_ptr): Use __gxx_caught_object. (__cxa_begin_catch): Ditto. Use __is_gxx_exception_class. Call _Unwind_Complete when using the ARM EABI. (__cxa_end_catch): Use __is_gxx_exception_class. * libsupc++/eh_personality.cc: Define NO_SIZE_OF_ENCODED_VALUE when using the ARM EABI. (save_caught_exception, restore_caught_exception): New functions. (_throw_typet): New typedef. (get_ttype_entry, get_adjusted_ptr, check_exception_spec): Add ARM EABI implementations. (PERSONALITY_FUNCTION): Use new functions. Addd support for ARM EABI unwinding libary. (__cxa_unexpected): Disable when using the ARM EABI. * libsupc++/eh_throw.cc (__cxa_throw): Use __GXX_INIT_EXCEPTION_CLASS. (__cxa_rethrow): Use __is_gxx_exception_class. Call _Unwind_RaiseException when using the ARM EABI. * libsupc++/unwind-cxx.h (struct __cxa_exception): Add fields for ARM EABI semantics. (struct __cxa_eh_globals): Ditto. (__cxa_call_terminate): Add prototype. (__cxa_type_match, __cxa_begin_cleanup, __cxa_end_cleanup): Add prototypes. (__get_exception_header_from_obj, __get_exception_header_from_ue): Move earlier in file. (__is_gxx_exception_class, __GXX_INIT_EXCEPTION_CLASS, __gxx_caught_object): New functions. * aclocal.m4: Regenerate. * configure: Regenerate. * Makefile.in: Regenerate. * include/Makefile.in: Regenerate. * libmath/Makefile.in: Regenerate. * libsupc++/Makefile.in: Regenerate. * po/Makefile.in: Regenerate. * src/Makefie.in: Regenerate. * testsuite/makefile.in: Regenerate. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@101385 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 48 +++++ gcc/Makefile.in | 9 +- gcc/ada/ChangeLog | 4 + gcc/ada/misc.c | 1 + gcc/c-decl.c | 1 + gcc/config/arm/arm-protos.h | 2 + gcc/config/arm/arm.c | 297 +++++++++++++++++++++++++++++ gcc/config/arm/arm.h | 12 ++ gcc/config/arm/bpabi.h | 3 + gcc/config/arm/elf.h | 2 + gcc/config/arm/lib1funcs.asm | 1 + gcc/config/arm/libgcc-bpabi.ver | 14 ++ gcc/config/arm/t-bpabi | 8 +- gcc/config/arm/t-symbian | 5 + gcc/config/i386/t-netware | 1 - gcc/config/ia64/ia64.h | 2 + gcc/cp/ChangeLog | 7 + gcc/cp/Make-lang.in | 2 +- gcc/cp/except.c | 5 + gcc/doc/tm.texi | 19 ++ gcc/except.c | 134 ++++++++----- gcc/except.h | 1 + gcc/java/ChangeLog | 5 + gcc/java/decl.c | 1 + gcc/objc/ChangeLog | 5 + gcc/objc/objc-act.c | 1 + gcc/optabs.c | 3 - gcc/opts.c | 7 +- gcc/target-def.h | 14 +- gcc/target.h | 11 ++ gcc/unwind-c.c | 46 ++++- libstdc++-v3/ChangeLog | 44 +++++ libstdc++-v3/Makefile.in | 24 ++- libstdc++-v3/acinclude.m4 | 2 + libstdc++-v3/aclocal.m4 | 310 +++++++++---------------------- libstdc++-v3/configure | 2 + libstdc++-v3/include/Makefile.in | 4 +- libstdc++-v3/libmath/Makefile.in | 4 +- libstdc++-v3/libsupc++/Makefile.am | 2 + libstdc++-v3/libsupc++/Makefile.in | 42 +++-- libstdc++-v3/libsupc++/eh_catch.cc | 14 +- libstdc++-v3/libsupc++/eh_personality.cc | 293 ++++++++++++++++++++++++++--- libstdc++-v3/libsupc++/eh_throw.cc | 6 +- libstdc++-v3/libsupc++/unwind-cxx.h | 97 ++++++++-- libstdc++-v3/po/Makefile.in | 4 +- libstdc++-v3/src/Makefile.in | 4 +- libstdc++-v3/testsuite/Makefile.in | 4 +- 47 files changed, 1159 insertions(+), 368 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 29c1e4f478e..81a31064f84 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,51 @@ +2005-06-28 Paul Brook + + * 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 * c-decl.c (pop_scope): Move warning control into warning call. diff --git a/gcc/Makefile.in b/gcc/Makefile.in index 98ace16f4a7..3ff5c94820a 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 0e6b95d2af9..18b366bce89 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,7 @@ +2005-06-28 Paul Brook + + * misc.c (gnat_init_gcc_eh): Call default_init_unwind_resume_libfunc. + 2005-06-14 Olivier Hainque Eric Botcazou diff --git a/gcc/ada/misc.c b/gcc/ada/misc.c index a993bc1f094..544419dedc5 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 728383fb2b3..eececb18d39 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 352a289bd75..b15fe10ce43 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 5348c79ba49..4e17d3a7fe3 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 ) (reg)). + Where 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 65b4bad144b..327393c7e3d 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 981c58c4902..7fb7d6a265b 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 a5600210092..ae3d5338d8f 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 519b41e0515..ebf31eb8cc5 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 788e3ad2b1f..35966bbfc72 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 74445ddc92e..74c0ae138a3 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 34a58ce9f11..8f72b3ea89d 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 cc229b8c1a1..2d3a828a5e5 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 e97bf077bfc..9e52773fdcb 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 d22990e69a5..128ea648dfe 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2005-06-28 Paul Brook + + * 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 * 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 6adedec5d87..f555f31ede9 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 de83bbaa841..be7208e2f0f 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 cd2bf87a032..bbca6b9a699 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 3c4291019e0..1bcdc28f8b1 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 72073c01954..d5e391d9c77 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 239e2b7182b..68699ffe3cf 100644 --- a/gcc/java/ChangeLog +++ b/gcc/java/ChangeLog @@ -1,3 +1,8 @@ +2005-06-28 Paul Brook + + * decl.c (java_init_decl_processing): Call + default_init_unwind_resume_libfunc. + 2005-06-27 Tom Tromey PR java/21540, PR java/13788: diff --git a/gcc/java/decl.c b/gcc/java/decl.c index b8690160756..e63ef840af9 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 57a326ade94..52325f4b70a 100644 --- a/gcc/objc/ChangeLog +++ b/gcc/objc/ChangeLog @@ -1,3 +1,8 @@ +2005-06-28 Paul Brook + + * objc-act.c (objc_init_exceptions): Call + default_init_unwind_resume_libfunc. + 2005-06-27 Ziemowit Laski * 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 35951fea145..d4c20a87ec9 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 1fb11368538..6f5716ebcda 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 ec416887a41..e96d6d56a55 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 cdaf3d368ae..9998a19b5aa 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 87e644b02ac..364e95afbbd 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 fc76edbc350..6fb66e0b738 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), diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 45b0fc5a5c7..c46431fbdd3 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,47 @@ +2005-06-28 Paul Brook + + * acinclude.m4 (GLIBCXX_ENABLE_SJLJ_EXCEPTIONS): Check for + __cxa_end_cleanup. + * libsupc++/Makefile.am (sources): Add eh_call.c and eh_arm.c. + * libsupc++/eh_arm.cc: New file. + * libsupc++/eh_call.cc: New file. + * libsupc++/eh_catch.cc (__cxa_get_exception_ptr): Use + __gxx_caught_object. + (__cxa_begin_catch): Ditto. Use __is_gxx_exception_class. Call + _Unwind_Complete when using the ARM EABI. + (__cxa_end_catch): Use __is_gxx_exception_class. + * libsupc++/eh_personality.cc: Define NO_SIZE_OF_ENCODED_VALUE when + using the ARM EABI. + (save_caught_exception, restore_caught_exception): New functions. + (_throw_typet): New typedef. + (get_ttype_entry, get_adjusted_ptr, check_exception_spec): Add ARM + EABI implementations. + (PERSONALITY_FUNCTION): Use new functions. Addd support for ARM EABI + unwinding libary. + (__cxa_unexpected): Disable when using the ARM EABI. + * libsupc++/eh_throw.cc (__cxa_throw): Use __GXX_INIT_EXCEPTION_CLASS. + (__cxa_rethrow): Use __is_gxx_exception_class. Call + _Unwind_RaiseException when using the ARM EABI. + * libsupc++/unwind-cxx.h (struct __cxa_exception): Add fields for ARM + EABI semantics. + (struct __cxa_eh_globals): Ditto. + (__cxa_call_terminate): Add prototype. + (__cxa_type_match, __cxa_begin_cleanup, __cxa_end_cleanup): Add + prototypes. + (__get_exception_header_from_obj, __get_exception_header_from_ue): + Move earlier in file. + (__is_gxx_exception_class, __GXX_INIT_EXCEPTION_CLASS, + __gxx_caught_object): New functions. + * aclocal.m4: Regenerate. + * configure: Regenerate. + * Makefile.in: Regenerate. + * include/Makefile.in: Regenerate. + * libmath/Makefile.in: Regenerate. + * libsupc++/Makefile.in: Regenerate. + * po/Makefile.in: Regenerate. + * src/Makefie.in: Regenerate. + * testsuite/makefile.in: Regenerate. + 2005-06-27 Paolo Carlini PR libstdc++/22102 diff --git a/libstdc++-v3/Makefile.in b/libstdc++-v3/Makefile.in index 5350407138b..f2da8e9acf7 100644 --- a/libstdc++-v3/Makefile.in +++ b/libstdc++-v3/Makefile.in @@ -1,8 +1,8 @@ -# Makefile.in generated by automake 1.9.3 from Makefile.am. +# Makefile.in generated by automake 1.9.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004 Free Software Foundation, Inc. +# 2003, 2004, 2005 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -408,7 +408,13 @@ uninstall-info-am: # (which will cause the Makefiles to be regenerated when you run `make'); # (2) otherwise, pass the desired values on the `make' command line. $(RECURSIVE_TARGETS): - @set fnord $$MAKEFLAGS; amf=$$2; \ + @failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ list='$(SUBDIRS)'; for subdir in $$list; do \ @@ -420,7 +426,7 @@ $(RECURSIVE_TARGETS): local_target="$$target"; \ fi; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ - || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ + || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ @@ -428,7 +434,13 @@ $(RECURSIVE_TARGETS): mostlyclean-recursive clean-recursive distclean-recursive \ maintainer-clean-recursive: - @set fnord $$MAKEFLAGS; amf=$$2; \ + @failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ dot_seen=no; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ @@ -449,7 +461,7 @@ maintainer-clean-recursive: local_target="$$target"; \ fi; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ - || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ + || eval $$failcom; \ done && test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ diff --git a/libstdc++-v3/acinclude.m4 b/libstdc++-v3/acinclude.m4 index ee1b9f3e89a..d3156f2b2c4 100644 --- a/libstdc++-v3/acinclude.m4 +++ b/libstdc++-v3/acinclude.m4 @@ -1626,6 +1626,8 @@ EOF enable_sjlj_exceptions=yes elif grep _Unwind_Resume conftest.s >/dev/null 2>&1 ; then enable_sjlj_exceptions=no + elif grep __cxa_end_cleanup conftest.s >/dev/null 2>&1 ; then + enable_sjlj_exceptions=no fi fi CXXFLAGS="$old_CXXFLAGS" diff --git a/libstdc++-v3/aclocal.m4 b/libstdc++-v3/aclocal.m4 index 9c72982dce1..79d81ccfab2 100644 --- a/libstdc++-v3/aclocal.m4 +++ b/libstdc++-v3/aclocal.m4 @@ -1,7 +1,7 @@ -# generated automatically by aclocal 1.9.3 -*- Autoconf -*- +# generated automatically by aclocal 1.9.5 -*- Autoconf -*- -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 -# Free Software Foundation, Inc. +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, +# 2005 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -11,23 +11,11 @@ # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. -# -*- Autoconf -*- -# Copyright (C) 2002, 2003 Free Software Foundation, Inc. -# Generated from amversion.in; do not edit by hand. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. # AM_AUTOMAKE_VERSION(VERSION) # ---------------------------- @@ -40,26 +28,15 @@ AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version="1.9"]) # Call AM_AUTOMAKE_VERSION so it can be traced. # This function is AC_REQUIREd by AC_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], - [AM_AUTOMAKE_VERSION([1.9.3])]) - -# AM_AUX_DIR_EXPAND - -# Copyright (C) 2001, 2003 Free Software Foundation, Inc. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. + [AM_AUTOMAKE_VERSION([1.9.5])]) -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. +# AM_AUX_DIR_EXPAND -*- Autoconf -*- -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -# 02111-1307, USA. +# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. # For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets # $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to @@ -106,26 +83,16 @@ AC_PREREQ([2.50])dnl am_aux_dir=`cd $ac_aux_dir && pwd` ]) -# AM_CONDITIONAL -*- Autoconf -*- - -# Copyright (C) 1997, 2000, 2001, 2003, 2004 Free Software Foundation, Inc. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. +# AM_CONDITIONAL -*- Autoconf -*- -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -# 02111-1307, USA. +# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. -# serial 6 +# serial 7 # AM_CONDITIONAL(NAME, SHELL-CONDITION) # ------------------------------------- @@ -149,30 +116,19 @@ AC_CONFIG_COMMANDS_PRE( Usually this means the macro was only invoked conditionally.]]) fi])]) -# Do all the work for Automake. -*- Autoconf -*- - -# This macro actually does too much some checks are only needed if -# your package does certain things. But this isn't really a big deal. +# Do all the work for Automake. -*- Autoconf -*- -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 # Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -# 02111-1307, USA. +# serial 12 -# serial 11 +# This macro actually does too much. Some checks are only needed if +# your package does certain things. But this isn't really a big deal. # AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) # AM_INIT_AUTOMAKE([OPTIONS]) @@ -300,28 +256,17 @@ AC_DEFUN([AM_PROG_INSTALL_SH], install_sh=${install_sh-"$am_aux_dir/install-sh"} AC_SUBST(install_sh)]) -# Add --enable-maintainer-mode option to configure. +# Add --enable-maintainer-mode option to configure. -*- Autoconf -*- # From Jim Meyering -# Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004 +# Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004, 2005 # Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -# 02111-1307, USA. - -# serial 3 +# serial 4 AC_DEFUN([AM_MAINTAINER_MODE], [AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles]) @@ -340,27 +285,16 @@ AC_DEFUN([AM_MAINTAINER_MODE], AU_DEFUN([jm_MAINTAINER_MODE], [AM_MAINTAINER_MODE]) -# -*- Autoconf -*- - - -# Copyright (C) 1997, 1999, 2000, 2001, 2003 Free Software Foundation, Inc. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. +# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -# 02111-1307, USA. +# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2005 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. -# serial 3 +# serial 4 # AM_MISSING_PROG(NAME, PROGRAM) # ------------------------------ @@ -386,27 +320,16 @@ else fi ]) +# Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + # AM_PROG_MKDIR_P # --------------- # Check whether `mkdir -p' is supported, fallback to mkinstalldirs otherwise. - -# Copyright (C) 2003, 2004 Free Software Foundation, Inc. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -# 02111-1307, USA. - +# # Automake 1.8 used `mkdir -m 0755 -p --' to ensure that directories # created by `make install' are always world readable, even if the # installer happens to have an overly restrictive umask (e.g. 077). @@ -460,25 +383,14 @@ else fi AC_SUBST([mkdir_p])]) -# Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004 +# Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004, 2005 # Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -# 02111-1307, USA. - -# serial 4 +# serial 5 # AM_ENABLE_MULTILIB([MAKEFILE], [REL-TO-TOP-SRCDIR]) # --------------------------------------------------- @@ -529,26 +441,15 @@ multi_basedir="$multi_basedir" CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} CC="$CC"])])dnl -# Helper functions for option handling. -*- Autoconf -*- - -# Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. +# Helper functions for option handling. -*- Autoconf -*- -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -# 02111-1307, USA. +# Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. -# serial 2 +# serial 3 # _AM_MANGLE_OPTION(NAME) # ----------------------- @@ -573,28 +474,16 @@ AC_DEFUN([_AM_SET_OPTIONS], AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) -# -# Check to make sure that the build environment is sane. -# - -# Copyright (C) 1996, 1997, 2000, 2001, 2003 Free Software Foundation, Inc. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. +# Check to make sure that the build environment is sane. -*- Autoconf -*- -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -# 02111-1307, USA. +# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. -# serial 3 +# serial 4 # AM_SANITY_CHECK # --------------- @@ -637,25 +526,14 @@ Check your system clock]) fi AC_MSG_RESULT(yes)]) -# AM_PROG_INSTALL_STRIP - -# Copyright (C) 2001, 2003 Free Software Foundation, Inc. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -# 02111-1307, USA. +# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. +# AM_PROG_INSTALL_STRIP +# --------------------- # One issue with vendor `install' (even GNU) is that you can't # specify the program used to strip binaries. This is especially # annoying in cross-compiling environments, where the build's strip @@ -678,25 +556,13 @@ AC_SUBST([INSTALL_STRIP_PROGRAM])]) # Check how to create a tarball. -*- Autoconf -*- -# Copyright (C) 2004 Free Software Foundation, Inc. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -# 02111-1307, USA. - -# serial 1 +# Copyright (C) 2004, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. +# serial 2 # _AM_PROG_TAR(FORMAT) # -------------------- diff --git a/libstdc++-v3/configure b/libstdc++-v3/configure index fd377997956..b679737757c 100755 --- a/libstdc++-v3/configure +++ b/libstdc++-v3/configure @@ -5079,6 +5079,8 @@ EOF enable_sjlj_exceptions=yes elif grep _Unwind_Resume conftest.s >/dev/null 2>&1 ; then enable_sjlj_exceptions=no + elif grep __cxa_end_cleanup conftest.s >/dev/null 2>&1 ; then + enable_sjlj_exceptions=no fi fi CXXFLAGS="$old_CXXFLAGS" diff --git a/libstdc++-v3/include/Makefile.in b/libstdc++-v3/include/Makefile.in index cbda94c713f..f075d3e16c0 100644 --- a/libstdc++-v3/include/Makefile.in +++ b/libstdc++-v3/include/Makefile.in @@ -1,8 +1,8 @@ -# Makefile.in generated by automake 1.9.3 from Makefile.am. +# Makefile.in generated by automake 1.9.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004 Free Software Foundation, Inc. +# 2003, 2004, 2005 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. diff --git a/libstdc++-v3/libmath/Makefile.in b/libstdc++-v3/libmath/Makefile.in index f3aaf3eae7f..3f0cf27e997 100644 --- a/libstdc++-v3/libmath/Makefile.in +++ b/libstdc++-v3/libmath/Makefile.in @@ -1,8 +1,8 @@ -# Makefile.in generated by automake 1.9.3 from Makefile.am. +# Makefile.in generated by automake 1.9.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004 Free Software Foundation, Inc. +# 2003, 2004, 2005 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. diff --git a/libstdc++-v3/libsupc++/Makefile.am b/libstdc++-v3/libsupc++/Makefile.am index a55ef6626a2..c67c294fca0 100644 --- a/libstdc++-v3/libsupc++/Makefile.am +++ b/libstdc++-v3/libsupc++/Makefile.am @@ -45,7 +45,9 @@ sources = \ del_opv.cc \ del_opvnt.cc \ eh_alloc.cc \ + eh_arm.cc \ eh_aux_runtime.cc \ + eh_call.cc \ eh_catch.cc \ eh_exception.cc \ eh_globals.cc \ diff --git a/libstdc++-v3/libsupc++/Makefile.in b/libstdc++-v3/libsupc++/Makefile.in index 9e11edd2229..4c0650ec91d 100644 --- a/libstdc++-v3/libsupc++/Makefile.in +++ b/libstdc++-v3/libsupc++/Makefile.in @@ -1,8 +1,8 @@ -# Makefile.in generated by automake 1.9.3 from Makefile.am. +# Makefile.in generated by automake 1.9.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004 Free Software Foundation, Inc. +# 2003, 2004, 2005 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -65,29 +65,31 @@ toolexeclibLTLIBRARIES_INSTALL = $(INSTALL) LTLIBRARIES = $(noinst_LTLIBRARIES) $(toolexeclib_LTLIBRARIES) libsupc___la_LIBADD = am__libsupc___la_SOURCES_DIST = del_op.cc del_opnt.cc del_opv.cc \ - del_opvnt.cc eh_alloc.cc eh_aux_runtime.cc eh_catch.cc \ - eh_exception.cc eh_globals.cc eh_personality.cc \ - eh_term_handler.cc eh_terminate.cc eh_throw.cc eh_type.cc \ - eh_unex_handler.cc guard.cc new_handler.cc new_op.cc \ - new_opnt.cc new_opv.cc new_opvnt.cc pure.cc tinfo.cc tinfo2.cc \ - vec.cc vterminate.cc cp-demangle.c + del_opvnt.cc eh_alloc.cc eh_arm.cc eh_aux_runtime.cc \ + eh_call.cc eh_catch.cc eh_exception.cc eh_globals.cc \ + eh_personality.cc eh_term_handler.cc eh_terminate.cc \ + eh_throw.cc eh_type.cc eh_unex_handler.cc guard.cc \ + new_handler.cc new_op.cc new_opnt.cc new_opv.cc new_opvnt.cc \ + pure.cc tinfo.cc tinfo2.cc vec.cc vterminate.cc cp-demangle.c am__objects_1 = del_op.lo del_opnt.lo del_opv.lo del_opvnt.lo \ - eh_alloc.lo eh_aux_runtime.lo eh_catch.lo eh_exception.lo \ - eh_globals.lo eh_personality.lo eh_term_handler.lo \ - eh_terminate.lo eh_throw.lo eh_type.lo eh_unex_handler.lo \ - guard.lo new_handler.lo new_op.lo new_opnt.lo new_opv.lo \ - new_opvnt.lo pure.lo tinfo.lo tinfo2.lo vec.lo vterminate.lo + eh_alloc.lo eh_arm.lo eh_aux_runtime.lo eh_call.lo eh_catch.lo \ + eh_exception.lo eh_globals.lo eh_personality.lo \ + eh_term_handler.lo eh_terminate.lo eh_throw.lo eh_type.lo \ + eh_unex_handler.lo guard.lo new_handler.lo new_op.lo \ + new_opnt.lo new_opv.lo new_opvnt.lo pure.lo tinfo.lo tinfo2.lo \ + vec.lo vterminate.lo @GLIBCXX_HOSTED_TRUE@am__objects_2 = cp-demangle.lo am_libsupc___la_OBJECTS = $(am__objects_1) $(am__objects_2) libsupc___la_OBJECTS = $(am_libsupc___la_OBJECTS) libsupc__convenience_la_LIBADD = am__libsupc__convenience_la_SOURCES_DIST = del_op.cc del_opnt.cc \ - del_opv.cc del_opvnt.cc eh_alloc.cc eh_aux_runtime.cc \ - eh_catch.cc eh_exception.cc eh_globals.cc eh_personality.cc \ - eh_term_handler.cc eh_terminate.cc eh_throw.cc eh_type.cc \ - eh_unex_handler.cc guard.cc new_handler.cc new_op.cc \ - new_opnt.cc new_opv.cc new_opvnt.cc pure.cc tinfo.cc tinfo2.cc \ - vec.cc vterminate.cc cp-demangle.c + del_opv.cc del_opvnt.cc eh_alloc.cc eh_arm.cc \ + eh_aux_runtime.cc eh_call.cc eh_catch.cc eh_exception.cc \ + eh_globals.cc eh_personality.cc eh_term_handler.cc \ + eh_terminate.cc eh_throw.cc eh_type.cc eh_unex_handler.cc \ + guard.cc new_handler.cc new_op.cc new_opnt.cc new_opv.cc \ + new_opvnt.cc pure.cc tinfo.cc tinfo2.cc vec.cc vterminate.cc \ + cp-demangle.c am_libsupc__convenience_la_OBJECTS = $(am__objects_1) $(am__objects_2) libsupc__convenience_la_OBJECTS = \ $(am_libsupc__convenience_la_OBJECTS) @@ -309,7 +311,9 @@ sources = \ del_opv.cc \ del_opvnt.cc \ eh_alloc.cc \ + eh_arm.cc \ eh_aux_runtime.cc \ + eh_call.cc \ eh_catch.cc \ eh_exception.cc \ eh_globals.cc \ diff --git a/libstdc++-v3/libsupc++/eh_catch.cc b/libstdc++-v3/libsupc++/eh_catch.cc index ba4b7d75f48..47b45963805 100644 --- a/libstdc++-v3/libsupc++/eh_catch.cc +++ b/libstdc++-v3/libsupc++/eh_catch.cc @@ -38,9 +38,8 @@ __cxxabiv1::__cxa_get_exception_ptr(void *exc_obj_in) throw() { _Unwind_Exception *exceptionObject = reinterpret_cast <_Unwind_Exception *>(exc_obj_in); - __cxa_exception *header = __get_exception_header_from_ue (exceptionObject); - return header->adjustedPtr; + return __gxx_caught_object(exceptionObject); } extern "C" void * @@ -51,12 +50,13 @@ __cxxabiv1::__cxa_begin_catch (void *exc_obj_in) throw() __cxa_eh_globals *globals = __cxa_get_globals (); __cxa_exception *prev = globals->caughtExceptions; __cxa_exception *header = __get_exception_header_from_ue (exceptionObject); + void* objectp; // Foreign exceptions can't be stacked here. If the exception stack is // empty, then fine. Otherwise we really have no choice but to terminate. // Note that this use of "header" is a lie. It's fine so long as we only // examine header->unwindHeader though. - if (header->unwindHeader.exception_class != __gxx_exception_class) + if (!__is_gxx_exception_class(header->unwindHeader.exception_class)) { if (prev != 0) std::terminate (); @@ -85,7 +85,11 @@ __cxxabiv1::__cxa_begin_catch (void *exc_obj_in) throw() globals->caughtExceptions = header; } - return header->adjustedPtr; + objectp = __gxx_caught_object(exceptionObject); +#ifdef __ARM_EABI_UNWINDER__ + _Unwind_Complete(exceptionObject); +#endif + return objectp; } @@ -102,7 +106,7 @@ __cxxabiv1::__cxa_end_catch () // A foreign exception couldn't have been stacked (see above), // so by definition processing must be complete. - if (header->unwindHeader.exception_class != __gxx_exception_class) + if (!__is_gxx_exception_class(header->unwindHeader.exception_class)) { globals->caughtExceptions = 0; _Unwind_DeleteException (&header->unwindHeader); diff --git a/libstdc++-v3/libsupc++/eh_personality.cc b/libstdc++-v3/libsupc++/eh_personality.cc index 4d5ae57b8d2..ecade83399f 100644 --- a/libstdc++-v3/libsupc++/eh_personality.cc +++ b/libstdc++-v3/libsupc++/eh_personality.cc @@ -35,6 +35,10 @@ using namespace __cxxabiv1; +#ifdef __ARM_EABI_UNWINDER__ +#define NO_SIZE_OF_ENCODED_VALUE +#endif + #include "unwind-pe.h" @@ -84,6 +88,117 @@ parse_lsda_header (_Unwind_Context *context, const unsigned char *p, return p; } +#ifdef __ARM_EABI_UNWINDER__ + +// Return an element from a type table. + +static const std::type_info* +get_ttype_entry(lsda_header_info* info, _Unwind_Word i) +{ + _Unwind_Ptr ptr; + + ptr = (_Unwind_Ptr) (info->TType - (i * 4)); + ptr = _Unwind_decode_target2(ptr); + + return reinterpret_cast(ptr); +} + +// The ABI provides a routine for matching exception object types. +typedef _Unwind_Control_Block _throw_typet; +#define get_adjusted_ptr(catch_type, throw_type, thrown_ptr_p) \ + (__cxa_type_match (throw_type, catch_type, false, thrown_ptr_p) \ + != ctm_failed) + +// Return true if THROW_TYPE matches one if the filter types. + +static bool +check_exception_spec(lsda_header_info* info, _throw_typet* throw_type, + void* thrown_ptr, _Unwind_Sword filter_value) +{ + const _Unwind_Word* e = ((const _Unwind_Word*) info->TType) + - filter_value - 1; + + while (1) + { + const std::type_info* catch_type; + _Unwind_Word tmp; + + tmp = *e; + + // Zero signals the end of the list. If we've not found + // a match by now, then we've failed the specification. + if (tmp == 0) + return false; + + tmp = _Unwind_decode_target2((_Unwind_Word) e); + + // Match a ttype entry. + catch_type = reinterpret_cast(tmp); + + // ??? There is currently no way to ask the RTTI code about the + // relationship between two types without reference to a specific + // object. There should be; then we wouldn't need to mess with + // thrown_ptr here. + if (get_adjusted_ptr(catch_type, throw_type, &thrown_ptr)) + return true; + + // Advance to the next entry. + e++; + } +} + + +// Save stage1 handler information in the exception object + +static inline void +save_caught_exception(struct _Unwind_Exception* ue_header, + struct _Unwind_Context* context, + void* thrown_ptr, + int handler_switch_value, + const unsigned char* language_specific_data, + _Unwind_Ptr landing_pad, + const unsigned char* action_record + __attribute__((__unused__))) +{ + ue_header->barrier_cache.sp = _Unwind_GetGR(context, 13); + ue_header->barrier_cache.bitpattern[0] = (_uw) thrown_ptr; + ue_header->barrier_cache.bitpattern[1] + = (_uw) handler_switch_value; + ue_header->barrier_cache.bitpattern[2] + = (_uw) language_specific_data; + ue_header->barrier_cache.bitpattern[3] = (_uw) landing_pad; +} + + +// Restore the catch handler data saved during phase1. + +static inline void +restore_caught_exception(struct _Unwind_Exception* ue_header, + int& handler_switch_value, + const unsigned char*& language_specific_data, + _Unwind_Ptr& landing_pad) +{ + handler_switch_value = (int) ue_header->barrier_cache.bitpattern[1]; + language_specific_data = + (const unsigned char*) ue_header->barrier_cache.bitpattern[2]; + landing_pad = (_Unwind_Ptr) ue_header->barrier_cache.bitpattern[3]; +} + +#define CONTINUE_UNWINDING \ + do \ + { \ + if (__gnu_unwind_frame(ue_header, context) != _URC_OK) \ + return _URC_FAILURE; \ + return _URC_CONTINUE_UNWIND; \ + } \ + while (0) + +#else +typedef const std::type_info _throw_typet; + + +// Return an element from a type table. + static const std::type_info * get_ttype_entry (lsda_header_info *info, _Unwind_Word i) { @@ -127,8 +242,8 @@ get_adjusted_ptr (const std::type_info *catch_type, // Return true if THROW_TYPE matches one if the filter types. static bool -check_exception_spec (lsda_header_info *info, const std::type_info *throw_type, - void *thrown_ptr, _Unwind_Sword filter_value) +check_exception_spec(lsda_header_info* info, _throw_typet* throw_type, + void* thrown_ptr, _Unwind_Sword filter_value) { const unsigned char *e = info->TType - filter_value - 1; @@ -156,6 +271,50 @@ check_exception_spec (lsda_header_info *info, const std::type_info *throw_type, } } + +// Save stage1 handler information in the exception object + +static inline void +save_caught_exception(struct _Unwind_Exception* ue_header, + struct _Unwind_Context* context + __attribute__((__unused__)), + void* thrown_ptr, + int handler_switch_value, + const unsigned char* language_specific_data, + _Unwind_Ptr landing_pad __attribute__((__unused__)), + const unsigned char* action_record) +{ + __cxa_exception* xh = __get_exception_header_from_ue(ue_header); + + xh->handlerSwitchValue = handler_switch_value; + xh->actionRecord = action_record; + xh->languageSpecificData = language_specific_data; + xh->adjustedPtr = thrown_ptr; + + // ??? Completely unknown what this field is supposed to be for. + // ??? Need to cache TType encoding base for call_unexpected. + xh->catchTemp = landing_pad; +} + + +// Restore the catch handler information saved during phase1. + +static inline void +restore_caught_exception(struct _Unwind_Exception* ue_header, + int& handler_switch_value, + const unsigned char*& language_specific_data, + _Unwind_Ptr& landing_pad) +{ + __cxa_exception* xh = __get_exception_header_from_ue(ue_header); + handler_switch_value = xh->handlerSwitchValue; + language_specific_data = xh->languageSpecificData; + landing_pad = (_Unwind_Ptr) xh->catchTemp; +} + +#define CONTINUE_UNWINDING return _URC_CONTINUE_UNWIND + +#endif // !__ARM_EABI_UNWINDER__ + // Return true if the filter spec is empty, ie throw(). static bool @@ -178,14 +337,18 @@ empty_exception_spec (lsda_header_info *info, _Unwind_Sword filter_value) #endif extern "C" _Unwind_Reason_Code +#ifdef __ARM_EABI_UNWINDER__ +PERSONALITY_FUNCTION (_Unwind_State state, + struct _Unwind_Exception* ue_header, + struct _Unwind_Context* context) +#else PERSONALITY_FUNCTION (int version, _Unwind_Action actions, _Unwind_Exception_Class exception_class, struct _Unwind_Exception *ue_header, struct _Unwind_Context *context) +#endif { - __cxa_exception *xh = __get_exception_header_from_ue (ue_header); - enum found_handler_type { found_nothing, @@ -200,19 +363,58 @@ PERSONALITY_FUNCTION (int version, const unsigned char *p; _Unwind_Ptr landing_pad, ip; int handler_switch_value; - void *thrown_ptr = xh + 1; + void* thrown_ptr = ue_header + 1; + bool foreign_exception; + +#ifdef __ARM_EABI_UNWINDER__ + _Unwind_Action actions; + + switch (state) + { + case _US_VIRTUAL_UNWIND_FRAME: + actions = _UA_SEARCH_PHASE; + break; + + case _US_UNWIND_FRAME_STARTING: + actions = _UA_CLEANUP_PHASE; + if (ue_header->barrier_cache.sp == _Unwind_GetGR(context, 13)) + actions |= _UA_HANDLER_FRAME; + break; + + case _US_UNWIND_FRAME_RESUME: + CONTINUE_UNWINDING; + break; + + default: + abort(); + } + + // We don't know which runtime we're working with, so can't check this. + // However the ABI routines hide this from us, and we don't actually need + // to know. + foreign_exception = false; + + // 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 + __cxa_exception* xh = __get_exception_header_from_ue(ue_header); // Interface version check. if (version != 1) return _URC_FATAL_PHASE1_ERROR; + foreign_exception = !__is_gxx_exception_class(exception_class); +#endif // Shortcut for phase 2 found handler for domestic exception. if (actions == (_UA_CLEANUP_PHASE | _UA_HANDLER_FRAME) - && exception_class == __gxx_exception_class) + && !foreign_exception) { - handler_switch_value = xh->handlerSwitchValue; - language_specific_data = xh->languageSpecificData; - landing_pad = (_Unwind_Ptr) xh->catchTemp; + restore_caught_exception(ue_header, handler_switch_value, + language_specific_data, landing_pad); found_type = (landing_pad == 0 ? found_terminate : found_handler); goto install_context; } @@ -222,11 +424,11 @@ PERSONALITY_FUNCTION (int version, // 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); - info.ttype_base = base_of_encoded_value (info.ttype_encoding, context); + info.ttype_base = 0; ip = _Unwind_GetIP (context) - 1; landing_pad = 0; action_record = 0; @@ -312,7 +514,8 @@ PERSONALITY_FUNCTION (int version, // Otherwise we have a catch handler or exception specification. _Unwind_Sword ar_filter, ar_disp; - const std::type_info *throw_type, *catch_type; + const std::type_info* catch_type; + _throw_typet* throw_type; bool saw_cleanup = false; bool saw_handler = false; @@ -320,11 +523,15 @@ PERSONALITY_FUNCTION (int version, // exception class, there's no exception type. // ??? What to do about GNU Java and GNU Ada exceptions. +#ifdef __ARM_EABI_UNWINDER__ + throw_type = ue_header; +#else if ((actions & _UA_FORCE_UNWIND) - || exception_class != __gxx_exception_class) + || foreign_exception) throw_type = 0; else throw_type = xh->exceptionType; +#endif while (1) { @@ -387,34 +594,31 @@ PERSONALITY_FUNCTION (int version, do_something: if (found_type == found_nothing) - return _URC_CONTINUE_UNWIND; + CONTINUE_UNWINDING; if (actions & _UA_SEARCH_PHASE) { if (found_type == found_cleanup) - return _URC_CONTINUE_UNWIND; + CONTINUE_UNWINDING; // For domestic exceptions, we cache data from phase 1 for phase 2. - if (exception_class == __gxx_exception_class) + if (!foreign_exception) { - xh->handlerSwitchValue = handler_switch_value; - xh->actionRecord = action_record; - xh->languageSpecificData = language_specific_data; - xh->adjustedPtr = thrown_ptr; - - // ??? Completely unknown what this field is supposed to be for. - // ??? Need to cache TType encoding base for call_unexpected. - xh->catchTemp = landing_pad; + save_caught_exception(ue_header, context, thrown_ptr, + handler_switch_value, language_specific_data, + landing_pad, action_record); } return _URC_HANDLER_FOUND; } install_context: + +#ifndef __ARM_EABI_UNWINDER__ // We can't use any of the cxa routines with foreign exceptions, // because they all expect ue_header to be a struct __cxa_exception. // So in that case, call terminate or unexpected directly. if ((actions & _UA_FORCE_UNWIND) - || exception_class != __gxx_exception_class) + || foreign_exception) { if (found_type == found_terminate) std::terminate (); @@ -427,32 +631,60 @@ PERSONALITY_FUNCTION (int version, } } else +#endif { if (found_type == found_terminate) - { - __cxa_begin_catch (&xh->unwindHeader); - __terminate (xh->terminateHandler); - } + __cxa_call_terminate(ue_header); // Cache the TType base value for __cxa_call_unexpected, as we won't // have an _Unwind_Context then. if (handler_switch_value < 0) { parse_lsda_header (context, language_specific_data, &info); + +#ifdef __ARM_EABI_UNWINDER__ + const _Unwind_Word* e; + _Unwind_Word n; + + e = ((const _Unwind_Word*) info.TType) - handler_switch_value - 1; + // Count the number of rtti objects. + n = 0; + while (e[n] != 0) + n++; + + // Count. + ue_header->barrier_cache.bitpattern[1] = n; + // Base (obsolete) + ue_header->barrier_cache.bitpattern[2] = 0; + // Stride. + ue_header->barrier_cache.bitpattern[3] = 4; + // List head. + ue_header->barrier_cache.bitpattern[4] = (_Unwind_Word) e; +#else xh->catchTemp = base_of_encoded_value (info.ttype_encoding, context); +#endif } } /* For targets with pointers smaller than the word size, we must extend the pointer, and this extension is target dependent. */ _Unwind_SetGR (context, __builtin_eh_return_data_regno (0), - __builtin_extend_pointer (&xh->unwindHeader)); + __builtin_extend_pointer (ue_header)); _Unwind_SetGR (context, __builtin_eh_return_data_regno (1), handler_switch_value); _Unwind_SetIP (context, landing_pad); +#ifdef __ARM_EABI_UNWINDER__ + if (found_type == found_cleanup) + __cxa_begin_cleanup(ue_header); +#endif return _URC_INSTALL_CONTEXT; } +/* The ARM EABI implementation of __cxa_call_unexpected is in a different + file so that the personality routine san be used standalone. The generic + routine sahred datastructures with the PR so it is most convenient to + implement it here. */ +#ifndef __ARM_EABI_UNWINDER__ extern "C" void __cxa_call_unexpected (void *exc_obj_in) { @@ -513,3 +745,4 @@ __cxa_call_unexpected (void *exc_obj_in) __terminate (xh_terminate_handler); } } +#endif diff --git a/libstdc++-v3/libsupc++/eh_throw.cc b/libstdc++-v3/libsupc++/eh_throw.cc index 0807c5e1df7..eebd56c2316 100644 --- a/libstdc++-v3/libsupc++/eh_throw.cc +++ b/libstdc++-v3/libsupc++/eh_throw.cc @@ -63,7 +63,7 @@ __cxxabiv1::__cxa_throw (void *obj, std::type_info *tinfo, header->exceptionDestructor = dest; header->unexpectedHandler = __unexpected_handler; header->terminateHandler = __terminate_handler; - header->unwindHeader.exception_class = __gxx_exception_class; + __GXX_INIT_EXCEPTION_CLASS(header->unwindHeader.exception_class); header->unwindHeader.exception_cleanup = __gxx_exception_cleanup; #ifdef _GLIBCXX_SJLJ_EXCEPTIONS @@ -89,7 +89,7 @@ __cxxabiv1::__cxa_rethrow () if (header) { // Tell __cxa_end_catch this is a rethrow. - if (header->unwindHeader.exception_class != __gxx_exception_class) + if (!__is_gxx_exception_class(header->unwindHeader.exception_class)) globals->caughtExceptions = 0; else header->handlerCount = -header->handlerCount; @@ -97,7 +97,7 @@ __cxxabiv1::__cxa_rethrow () #ifdef _GLIBCXX_SJLJ_EXCEPTIONS _Unwind_SjLj_Resume_or_Rethrow (&header->unwindHeader); #else -#ifdef _LIBUNWIND_STD_ABI +#if defined(_LIBUNWIND_STD_ABI) || defined (__ARM_EABI_UNWINDER__) _Unwind_RaiseException (&header->unwindHeader); #else _Unwind_Resume_or_Rethrow (&header->unwindHeader); diff --git a/libstdc++-v3/libsupc++/unwind-cxx.h b/libstdc++-v3/libsupc++/unwind-cxx.h index e79dd83628e..a2c2f4886cc 100644 --- a/libstdc++-v3/libsupc++/unwind-cxx.h +++ b/libstdc++-v3/libsupc++/unwind-cxx.h @@ -67,6 +67,13 @@ struct __cxa_exception // value is a signal that this object has been rethrown. int handlerCount; +#ifdef __ARM_EABI_UNWINDER__ + // Stack of exceptions in cleanups. + __cxa_exception* nextPropagatingException; + + // The nuber of active cleanup handlers for this exception. + int propagationCount; +#else // Cache parsed handler data from the personality routine Phase 1 // for Phase 2 and __cxa_call_unexpected. int handlerSwitchValue; @@ -74,6 +81,7 @@ struct __cxa_exception const unsigned char *languageSpecificData; _Unwind_Ptr catchTemp; void *adjustedPtr; +#endif // The generic exception header. Must be last. _Unwind_Exception unwindHeader; @@ -84,6 +92,9 @@ struct __cxa_eh_globals { __cxa_exception *caughtExceptions; unsigned int uncaughtExceptions; +#ifdef __ARM_EABI_UNWINDER__ + __cxa_exception* propagatingExceptions; +#endif }; @@ -122,6 +133,20 @@ extern "C" void __cxa_bad_typeid (); // throws, and if bad_exception needs to be thrown. Called from the // compiler. extern "C" void __cxa_call_unexpected (void *) __attribute__((noreturn)); +extern "C" void __cxa_call_terminate (void*) __attribute__((noreturn)); + +#ifdef __ARM_EABI_UNWINDER__ +// Arm EABI specified routines. +typedef enum { + ctm_failed = 0, + ctm_succeeded = 1, + ctm_succeeded_with_ptr_to_base = 2 +} __cxa_type_match_result; +extern "C" bool __cxa_type_match(_Unwind_Exception*, const std::type_info*, + bool, void**); +extern "C" void __cxa_begin_cleanup (_Unwind_Exception*); +extern "C" void __cxa_end_cleanup (void); +#endif // Invokes given handler, dying appropriately if the user handler was // so inconsiderate as to return. @@ -134,6 +159,54 @@ extern std::unexpected_handler __unexpected_handler; // These are explicitly GNU C++ specific. +// Acquire the C++ exception header from the C++ object. +static inline __cxa_exception * +__get_exception_header_from_obj (void *ptr) +{ + return reinterpret_cast<__cxa_exception *>(ptr) - 1; +} + +// Acquire the C++ exception header from the generic exception header. +static inline __cxa_exception * +__get_exception_header_from_ue (_Unwind_Exception *exc) +{ + return reinterpret_cast<__cxa_exception *>(exc + 1) - 1; +} + +#ifdef __ARM_EABI_UNWINDER__ +static inline bool +__is_gxx_exception_class(_Unwind_Exception_Class c) +{ + // TODO: Take advantage of the fact that c will always be word aligned. + return c[0] == 'G' + && c[1] == 'N' + && c[2] == 'U' + && c[3] == 'C' + && c[4] == 'C' + && c[5] == '+' + && c[6] == '+' + && c[7] == '\0'; +} + +static inline void +__GXX_INIT_EXCEPTION_CLASS(_Unwind_Exception_Class c) +{ + c[0] = 'G'; + c[1] = 'N'; + c[2] = 'U'; + c[3] = 'C'; + c[4] = 'C'; + c[5] = '+'; + c[6] = '+'; + c[7] = '\0'; +} + +static inline void* +__gxx_caught_object(_Unwind_Exception* eo) +{ + return (void*)eo->barrier_cache.bitpattern[0]; +} +#else // !__ARM_EABI_UNWINDER__ // This is the exception class we report -- "GNUCC++\0". const _Unwind_Exception_Class __gxx_exception_class = ((((((((_Unwind_Exception_Class) 'G' @@ -145,6 +218,14 @@ const _Unwind_Exception_Class __gxx_exception_class << 8 | (_Unwind_Exception_Class) '+') << 8 | (_Unwind_Exception_Class) '\0'); +static inline bool +__is_gxx_exception_class(_Unwind_Exception_Class c) +{ + return c == __gxx_exception_class; +} + +#define __GXX_INIT_EXCEPTION_CLASS(c) c = __gxx_exception_class + // GNU C++ personality routine, Version 0. extern "C" _Unwind_Reason_Code __gxx_personality_v0 (int, _Unwind_Action, _Unwind_Exception_Class, @@ -155,19 +236,13 @@ extern "C" _Unwind_Reason_Code __gxx_personality_sj0 (int, _Unwind_Action, _Unwind_Exception_Class, struct _Unwind_Exception *, struct _Unwind_Context *); -// Acquire the C++ exception header from the C++ object. -static inline __cxa_exception * -__get_exception_header_from_obj (void *ptr) +static inline void* +__gxx_caught_object(_Unwind_Exception* eo) { - return reinterpret_cast<__cxa_exception *>(ptr) - 1; -} - -// Acquire the C++ exception header from the generic exception header. -static inline __cxa_exception * -__get_exception_header_from_ue (_Unwind_Exception *exc) -{ - return reinterpret_cast<__cxa_exception *>(exc + 1) - 1; + __cxa_exception* header = __get_exception_header_from_ue (eo); + return header->adjustedPtr; } +#endif // !__ARM_EABI_UNWINDER__ } /* namespace __cxxabiv1 */ diff --git a/libstdc++-v3/po/Makefile.in b/libstdc++-v3/po/Makefile.in index 9f4bacab3e7..804a9cd8c81 100644 --- a/libstdc++-v3/po/Makefile.in +++ b/libstdc++-v3/po/Makefile.in @@ -1,8 +1,8 @@ -# Makefile.in generated by automake 1.9.3 from Makefile.am. +# Makefile.in generated by automake 1.9.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004 Free Software Foundation, Inc. +# 2003, 2004, 2005 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. diff --git a/libstdc++-v3/src/Makefile.in b/libstdc++-v3/src/Makefile.in index 076115b2e4c..3a0670c8015 100644 --- a/libstdc++-v3/src/Makefile.in +++ b/libstdc++-v3/src/Makefile.in @@ -1,8 +1,8 @@ -# Makefile.in generated by automake 1.9.3 from Makefile.am. +# Makefile.in generated by automake 1.9.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004 Free Software Foundation, Inc. +# 2003, 2004, 2005 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. diff --git a/libstdc++-v3/testsuite/Makefile.in b/libstdc++-v3/testsuite/Makefile.in index 91e1874ebab..242dc2e30a0 100644 --- a/libstdc++-v3/testsuite/Makefile.in +++ b/libstdc++-v3/testsuite/Makefile.in @@ -1,8 +1,8 @@ -# Makefile.in generated by automake 1.9.3 from Makefile.am. +# Makefile.in generated by automake 1.9.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004 Free Software Foundation, Inc. +# 2003, 2004, 2005 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -- 2.11.4.GIT