OSDN Git Service

2005-06-28 Paul Brook <paul@codesourcery.com>
authorpbrook <pbrook@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 28 Jun 2005 19:52:27 +0000 (19:52 +0000)
committerpbrook <pbrook@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 28 Jun 2005 19:52:27 +0000 (19:52 +0000)
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

47 files changed:
gcc/ChangeLog
gcc/Makefile.in
gcc/ada/ChangeLog
gcc/ada/misc.c
gcc/c-decl.c
gcc/config/arm/arm-protos.h
gcc/config/arm/arm.c
gcc/config/arm/arm.h
gcc/config/arm/bpabi.h
gcc/config/arm/elf.h
gcc/config/arm/lib1funcs.asm
gcc/config/arm/libgcc-bpabi.ver
gcc/config/arm/t-bpabi
gcc/config/arm/t-symbian
gcc/config/i386/t-netware
gcc/config/ia64/ia64.h
gcc/cp/ChangeLog
gcc/cp/Make-lang.in
gcc/cp/except.c
gcc/doc/tm.texi
gcc/except.c
gcc/except.h
gcc/java/ChangeLog
gcc/java/decl.c
gcc/objc/ChangeLog
gcc/objc/objc-act.c
gcc/optabs.c
gcc/opts.c
gcc/target-def.h
gcc/target.h
gcc/unwind-c.c
libstdc++-v3/ChangeLog
libstdc++-v3/Makefile.in
libstdc++-v3/acinclude.m4
libstdc++-v3/aclocal.m4
libstdc++-v3/configure
libstdc++-v3/include/Makefile.in
libstdc++-v3/libmath/Makefile.in
libstdc++-v3/libsupc++/Makefile.am
libstdc++-v3/libsupc++/Makefile.in
libstdc++-v3/libsupc++/eh_catch.cc
libstdc++-v3/libsupc++/eh_personality.cc
libstdc++-v3/libsupc++/eh_throw.cc
libstdc++-v3/libsupc++/unwind-cxx.h
libstdc++-v3/po/Makefile.in
libstdc++-v3/src/Makefile.in
libstdc++-v3/testsuite/Makefile.in

index 29c1e4f..81a3106 100644 (file)
@@ -1,3 +1,51 @@
+2005-06-28  Paul Brook  <paul@codesourcery.com>
+
+       * Makefile.in: Set and use UNWIND_H.  Install as unwind.h.
+       * c-decl.c (finish_decl): Call default_init_unwind_resume_libfunc.
+       * except.c (add_ehspec_entry): Generate arm eabi filter lists.
+       (assign_filter_values): Ditto.
+       (output_ttype): New function.
+       (output_function_exception_table): Use output_ttype.  Generate arm
+       eabi filter lists.
+       (default_init_unwind_resume_libfunc): New function.
+       * except.h (default_init_unwind_resume_libfunc): Add prototype.
+       * optabs.c (init_optabs): Don't set unwind_resume_libfunc.
+       * opts.c (decode_options): Use targetm.unwind_tables_default.
+       * target-def.h (TARGET_ASM_TTYPE): Provide and use definition.
+       (TARGET_ARM_EABI_UNWINDER, TARGET_UNWIND_TABLES_DEFAULT): Ditto.
+       * target.h (struct gcc_target): Add asm.ttype, unwind_tables_default
+       and arm_eabi_unwinder.
+       * unwind-c.c: Support Arm EABI unwinder.
+       * unwind.h: Rename ...
+       * unwind-generic.h: ... To this.
+       * doc/tm.texi (TARGET_ASM_TTYPE, TARGET_ARM_EABI_UNWINDER): Document.
+       (TARGET_UNWID_TABLES_DEFAULT): Document.
+
+       * config/arm/arm-protos.h (arm_output_fn_unwind): Add prototype.
+       * config/arm/arm.c (arm_unwind_emit, arm_output_ttype): New functions.
+       (TARGET_UNWIND_EMIT, TARGET_ASM_TTYPE, TARGET_ARM_EABI_UNWINDER):
+       Define.
+       (thumb_pushpop, thumb_output_function_prologue): Output unwinding
+       directives.
+       (arm_unwind_emit_stm, arm_unwind_emit_set): New functions.
+       * config/arm/arm.h (MUST_USE_SJLJ_EXCEPTIONS): Only define when
+       !TARGET_UNWIND_INFO.
+       (ARM_OUTPUT_FN_UNWIND, ARM_EABI_UNWIND_TABLES): Define.
+       * config/arm/bpabi.h (TARGET_UNWIND_INFO): Define.
+       * config/arm/elf.h (ASM_DECLARE_FUNCTION_NAME,
+       ASM_DECLARE_FUNCTION_SIZE): Use ARM_OUTPUT_FN_UNWIND.
+       * config/arm/lib1funcs.asm: Include libunwind.S.
+       * config/arm/libgcc-bpabi.ver: Add unwinding routines.
+       * config/arm/libunwind.S: New file.
+       * config/arm/pr-support.c: New file.
+       * config/arm/t-bpabi (LIB1ASMFUNCS): Add _unwind.
+       (UNWIND_H, LIB2ADDEH, LIB2ADDEHDEP): Set.
+       * config/arm/t-symbian (UNWIND_H, LIB2ADDEH, LIB2ADDEHDEP): Set.
+       * config/arm/unwind-arm.c: New file.
+       * config/arm/unwind-arm.h: New file.
+       * config/i386/t-netware (USER_H): Remove unwind.h.
+       * config/ia64/ia64.h (TARGET_UNWIND_TABLES_DEFAULT): Define.
+
 2005-06-28  DJ Delorie  <dj@redhat.com>
 
        * c-decl.c (pop_scope): Move warning control into warning call.
index 98ace16..3ff5c94 100644 (file)
@@ -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
index 0e6b95d..18b366b 100644 (file)
@@ -1,3 +1,7 @@
+2005-06-28  Paul Brook  <paul@codesourcery.com>
+
+       * misc.c (gnat_init_gcc_eh): Call default_init_unwind_resume_libfunc.
+
 2005-06-14  Olivier Hainque  <hainque@adacore.com>
            Eric Botcazou  <ebotcazou@adacore.com>
 
index a993bc1..544419d 100644 (file)
@@ -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;
 
index 728383f..eececb1 100644 (file)
@@ -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 ();
            }
 
index 352a289..b15fe10 100644 (file)
@@ -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);
index 5348c79..4e17d3a 100644 (file)
@@ -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;
 \f
 /* Obstack for minipool constant handling.  */
@@ -12417,6 +12433,21 @@ thumb_pushpop (FILE *f, unsigned long mask, int push, int *cfa_offset,
       return;
     }
 
+  if (ARM_EABI_UNWIND_TABLES && push)
+    {
+      fprintf (f, "\t.save\t{");
+      for (regno = 0; regno < 15; regno++)
+       {
+         if (real_regs & (1 << regno))
+           {
+             if (real_regs & ((1 << regno) -1))
+               fprintf (f, ", ");
+             asm_fprintf (f, "%r", regno);
+           }
+       }
+      fprintf (f, "}\n");
+    }
+
   fprintf (f, "\t%s\t{", push ? "push" : "pop");
 
   /* Look at the low registers first.  */
@@ -13370,6 +13401,11 @@ thumb_output_function_prologue (FILE *f, HOST_WIDE_INT size ATTRIBUTE_UNUSED)
 
   if (current_function_pretend_args_size)
     {
+      /* Output unwind directive for the stack adjustment.  */
+      if (ARM_EABI_UNWIND_TABLES)
+       fprintf (f, "\t.pad #%d\n",
+                current_function_pretend_args_size);
+
       if (cfun->machine->uses_anonymous_args)
        {
          int num_pushes;
@@ -13435,6 +13471,9 @@ thumb_output_function_prologue (FILE *f, HOST_WIDE_INT size ATTRIBUTE_UNUSED)
 
       work_register = thumb_find_work_register (live_regs_mask);
 
+      if (ARM_EABI_UNWIND_TABLES)
+       asm_fprintf (f, "\t.pad #16\n");
+
       asm_fprintf
        (f, "\tsub\t%r, %r, #16\t%@ Create stack backtrace structure\n",
         SP_REGNUM, SP_REGNUM);
@@ -14662,3 +14701,261 @@ arm_dbx_register_number (unsigned int regno)
   gcc_unreachable ();
 }
 
+
+#ifdef TARGET_UNWIND_INFO
+/* Emit unwind directives for a store-multiple instruction.  This should
+   only ever be generated by the function prologue code, so we expect it
+   to have a particular form.  */
+
+static void
+arm_unwind_emit_stm (FILE * asm_out_file, rtx p)
+{
+  int i;
+  HOST_WIDE_INT offset;
+  HOST_WIDE_INT nregs;
+  int reg_size;
+  unsigned reg;
+  unsigned lastreg;
+  rtx e;
+
+  /* First insn will adjust the stack pointer.  */
+  e = XVECEXP (p, 0, 0);
+  if (GET_CODE (e) != SET
+      || GET_CODE (XEXP (e, 0)) != REG
+      || REGNO (XEXP (e, 0)) != SP_REGNUM
+      || GET_CODE (XEXP (e, 1)) != PLUS)
+    abort ();
+
+  offset = -INTVAL (XEXP (XEXP (e, 1), 1));
+  nregs = XVECLEN (p, 0) - 1;
+
+  reg = REGNO (XEXP (XVECEXP (p, 0, 1), 1));
+  if (reg < 16)
+    {
+      /* The function prologue may also push pc, but not annotate it as it is
+        never restored.  We turn this into an stack pointer adjustment.  */
+      if (nregs * 4 == offset - 4)
+       {
+         fprintf (asm_out_file, "\t.pad #4\n");
+         offset -= 4;
+       }
+      reg_size = 4;
+    }
+  else if (IS_VFP_REGNUM (reg))
+    {
+      /* FPA register saves use an additional word.  */
+      offset -= 4;
+      reg_size = 8;
+    }
+  else if (reg >= FIRST_FPA_REGNUM && reg <= LAST_FPA_REGNUM)
+    {
+      /* FPA registers are done differently.  */
+      asm_fprintf (asm_out_file, "\t.save %r, %d\n", reg, nregs);
+      return;
+    }
+  else
+    /* Unknown register type.  */
+    abort ();
+
+  /* If the stack increment doesn't match the size of the saved registers,
+     something has gone horribly wrong.  */
+  if (offset != nregs * reg_size)
+    abort ();
+
+  fprintf (asm_out_file, "\t.save {");
+
+  offset = 0;
+  lastreg = 0;
+  /* The remaining insns will describe the stores.  */
+  for (i = 1; i <= nregs; i++)
+    {
+      /* Expect (set (mem <addr>) (reg)).
+         Where <addr> is (reg:SP) or (plus (reg:SP) (const_int)).  */
+      e = XVECEXP (p, 0, i);
+      if (GET_CODE (e) != SET
+         || GET_CODE (XEXP (e, 0)) != MEM
+         || GET_CODE (XEXP (e, 1)) != REG)
+       abort ();
+      
+      reg = REGNO (XEXP (e, 1));
+      if (reg < lastreg)
+       abort ();
+         
+      if (i != 1)
+       fprintf (asm_out_file, ", ");
+      /* We can't use %r for vfp because we need to use the
+        double precision register names.  */
+      if (IS_VFP_REGNUM (reg))
+       asm_fprintf (asm_out_file, "d%d", (reg - FIRST_VFP_REGNUM) / 2);
+      else
+       asm_fprintf (asm_out_file, "%r", reg);
+
+#ifdef ENABLE_CHECKING
+      /* Check that the addresses are consecutive.  */
+      e = XEXP (XEXP (e, 0), 0);
+      if (GET_CODE (e) == PLUS)
+       {
+         offset += reg_size;
+         if (GET_CODE (XEXP (e, 0)) != REG
+             || REGNO (XEXP (e, 0)) != SP_REGNUM
+             || GET_CODE (XEXP (e, 1)) != CONST_INT
+             || offset != INTVAL (XEXP (e, 1)))
+           abort ();
+       }
+      else if (i != 1
+              || GET_CODE (e) != REG
+              || REGNO (e) != SP_REGNUM)
+       abort ();
+#endif
+    }
+  fprintf (asm_out_file, "}\n");
+}
+
+/*  Emit unwind directives for a SET.  */
+
+static void
+arm_unwind_emit_set (FILE * asm_out_file, rtx p)
+{
+  rtx e0;
+  rtx e1;
+
+  e0 = XEXP (p, 0);
+  e1 = XEXP (p, 1);
+  switch (GET_CODE (e0))
+    {
+    case MEM:
+      /* Pushing a single register.  */
+      if (GET_CODE (XEXP (e0, 0)) != PRE_DEC
+         || GET_CODE (XEXP (XEXP (e0, 0), 0)) != REG
+         || REGNO (XEXP (XEXP (e0, 0), 0)) != SP_REGNUM)
+       abort ();
+
+      asm_fprintf (asm_out_file, "\t.save ");
+      if (IS_VFP_REGNUM (REGNO (e1)))
+       asm_fprintf(asm_out_file, "{d%d}\n",
+                   (REGNO (e1) - FIRST_VFP_REGNUM) / 2);
+      else
+       asm_fprintf(asm_out_file, "{%r}\n", REGNO (e1));
+      break;
+
+    case REG:
+      if (REGNO (e0) == SP_REGNUM)
+       {
+         /* A stack increment.  */
+         if (GET_CODE (e1) != PLUS
+             || GET_CODE (XEXP (e1, 0)) != REG
+             || REGNO (XEXP (e1, 0)) != SP_REGNUM
+             || GET_CODE (XEXP (e1, 1)) != CONST_INT)
+           abort ();
+
+         asm_fprintf (asm_out_file, "\t.pad #%d\n",
+                      -INTVAL (XEXP (e1, 1)));
+       }
+      else if (REGNO (e0) == HARD_FRAME_POINTER_REGNUM)
+       {
+         HOST_WIDE_INT offset;
+         unsigned reg;
+         
+         if (GET_CODE (e1) == PLUS)
+           {
+             if (GET_CODE (XEXP (e1, 0)) != REG
+                 || GET_CODE (XEXP (e1, 1)) != CONST_INT)
+               abort ();
+             reg = REGNO (XEXP (e1, 0));
+             offset = INTVAL (XEXP (e1, 1));
+             asm_fprintf (asm_out_file, "\t.setfp %r, %r, #%d\n",
+                          HARD_FRAME_POINTER_REGNUM, reg,
+                          INTVAL (XEXP (e1, 1)));
+           }
+         else if (GET_CODE (e1) == REG)
+           {
+             reg = REGNO (e1);
+             asm_fprintf (asm_out_file, "\t.setfp %r, %r\n",
+                          HARD_FRAME_POINTER_REGNUM, reg);
+           }
+         else
+           abort ();
+       }
+      else if (GET_CODE (e1) == REG && REGNO (e1) == SP_REGNUM)
+       {
+         /* Move from sp to reg.  */
+         asm_fprintf (asm_out_file, "\t.movsp %r\n", REGNO (e0));
+       }
+      else
+       abort ();
+      break;
+
+    default:
+      abort ();
+    }
+}
+
+
+/* Emit unwind directives for the given insn.  */
+
+static void
+arm_unwind_emit (FILE * asm_out_file, rtx insn)
+{
+  rtx pat;
+
+  if (!ARM_EABI_UNWIND_TABLES)
+    return;
+
+  if (GET_CODE (insn) == NOTE || !RTX_FRAME_RELATED_P (insn))
+    return;
+
+  pat = find_reg_note (insn, REG_FRAME_RELATED_EXPR, NULL_RTX);
+  if (pat)
+    pat = XEXP (pat, 0);
+  else
+    pat = PATTERN (insn);
+
+  switch (GET_CODE (pat))
+    {
+    case SET:
+      arm_unwind_emit_set (asm_out_file, pat);
+      break;
+
+    case SEQUENCE:
+      /* Store multiple.  */
+      arm_unwind_emit_stm (asm_out_file, pat);
+      break;
+
+    default:
+      abort();
+    }
+}
+
+
+/* Output a reference from a function exception table to the type_info
+   object X.  The EABI specifies that the symbol should be relocated by
+   an R_ARM_TARGET2 relocation.  */
+
+static bool
+arm_output_ttype (rtx x)
+{
+  fputs ("\t.word\t", asm_out_file);
+  output_addr_const (asm_out_file, x);
+  /* Use special relocations for symbol references.  */
+  if (GET_CODE (x) != CONST_INT)
+    fputs ("(TARGET2)", asm_out_file);
+  fputc ('\n', asm_out_file);
+
+  return TRUE;
+}
+#endif /* TARGET_UNWIND_INFO */
+
+
+/* Output unwind directives for the start/end of a function.  */
+
+void
+arm_output_fn_unwind (FILE * f, bool prologue)
+{
+  if (!ARM_EABI_UNWIND_TABLES)
+    return;
+
+  if (prologue)
+    fputs ("\t.fnstart\n", f);
+  else
+    fputs ("\t.fnend\n", f);
+}
index 65b4bad..327393c 100644 (file)
@@ -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.
index 981c58c..7fb7d6a 100644 (file)
@@ -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
 
index a560021..ae3d533 100644 (file)
@@ -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);                 \
index 519b41e..ebf31eb 100644 (file)
@@ -1309,4 +1309,5 @@ LSYM(Lchange_\register):
 #include "ieee754-df.S"
 #include "ieee754-sf.S"
 #include "bpabi.S"
+#include "libunwind.S"
 #endif /* __symbian__ */
index 788e3ad..35966bb 100644 (file)
@@ -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
 }
index 74445dd..74c0ae1 100644 (file)
@@ -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
 
index 34a58ce..8f72b3e 100644 (file)
@@ -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
index cc229b8..2d3a828 100644 (file)
@@ -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)
index e97bf07..9e52773 100644 (file)
@@ -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.  */
index d22990e..128ea64 100644 (file)
@@ -1,3 +1,10 @@
+2005-06-28  Paul Brook  <paul@codesourcery.com>
+
+       * Make-lang.in (cp/except.o): Depend on $(TARGET_H)
+       * except.c: Include target.h.
+       (init_exception_processing): Initialize unwind_resume_libfunc.
+       * doc/tm.texi: Document TARGET_ASM_TTYPE
+
 2005-06-26  Kaveh R. Ghazi  <ghazi@caip.rutgers.edu>
 
        * call.c (build_over_call): Pass in named argument list to
index 6adedec..f555f31 100644 (file)
@@ -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 \
index de83bba..be7208e 100644 (file)
@@ -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;
index cd2bf87..bbca6b9 100644 (file)
@@ -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
 
index 3c42910..1bcdc28 100644 (file)
@@ -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"
index 72073c0..d5e391d 100644 (file)
@@ -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 *);
index 239e2b7..68699ff 100644 (file)
@@ -1,3 +1,8 @@
+2005-06-28  Paul Brook  <paul@codesourcery.com>
+
+       * decl.c (java_init_decl_processing): Call
+       default_init_unwind_resume_libfunc.
+
 2005-06-27  Tom Tromey  <tromey@redhat.com>
 
        PR java/21540, PR java/13788:
index b869016..e63ef84 100644 (file)
@@ -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;
 
index 57a326a..52325f4 100644 (file)
@@ -1,3 +1,8 @@
+2005-06-28  Paul Brook  <paul@codesourcery.com>
+
+       * objc-act.c (objc_init_exceptions): Call
+       default_init_unwind_resume_libfunc.
+
 2005-06-27  Ziemowit Laski  <zlaski@apple.com>
 
        * objc-act.c (objc_build_struct): Save the TYPE_OBJC_INFO
index 35951fe..d4c20a8 100644 (file)
@@ -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;
     }
index 1fb1136..6f5716e 100644 (file)
@@ -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");
index ec41688..e96d6d5 100644 (file)
@@ -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.  */
index cdaf3d3..9998a19 100644 (file)
@@ -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"
index 87e644b..364e95a 100644 (file)
@@ -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.  */
 };
 
index fc76edb..6fb66e0 100644 (file)
@@ -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),
index 45b0fc5..c46431f 100644 (file)
@@ -1,3 +1,47 @@
+2005-06-28  Paul Brook  <paul@codesourcery.com>
+
+       * 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  <pcarlini@suse.de>
 
        PR libstdc++/22102
index 5350407..f2da8e9 100644 (file)
@@ -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 \
index ee1b9f3..d3156f2 100644 (file)
@@ -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"
index 9c72982..79d81cc 100644 (file)
@@ -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.
 # 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)
 # --------------------
index fd37799..b679737 100755 (executable)
@@ -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"
index cbda94c..f075d3e 100644 (file)
@@ -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.
index f3aaf3e..3f0cf27 100644 (file)
@@ -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.
index a55ef66..c67c294 100644 (file)
@@ -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 \
index 9e11edd..4c0650e 100644 (file)
@@ -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 \
index ba4b7d7..47b4596 100644 (file)
@@ -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);
index 4d5ae57..ecade83 100644 (file)
 
 using namespace __cxxabiv1;
 
+#ifdef __ARM_EABI_UNWINDER__
+#define NO_SIZE_OF_ENCODED_VALUE
+#endif
+
 #include "unwind-pe.h"
 
 \f
@@ -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<const std::type_info *>(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<const std::type_info*>(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,
+                     voidthrown_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
index 0807c5e..eebd56c 100644 (file)
@@ -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);
index e79dd83..a2c2f48 100644 (file)
@@ -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 */
 
index 9f4baca..804a9cd 100644 (file)
@@ -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.
index 076115b..3a0670c 100644 (file)
@@ -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.
index 91e1874..242dc2e 100644 (file)
@@ -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.