This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

ia64 eh, part 20c [libstdc++]


This is the libstdc++ change.  Differences since the last time
that Ben saw this are bug fixes to the personality routine and
the --enable-sjlj-exceptions configury (based on a change he
suggested).


r~


	IA-64 ABI Exception Handling:
	* acinclude.m4 (GLIBCPP_ENABLE_SJLJ_EXCEPTIONS): New.
	* configure.in: Use it.
	* Makefile.in, aclocal.m4, config.h.in, configure: Regenerate.
        * libsupc++/Makefile.am (sources): Update files list.
        * libsupc++/Makefile.in: Regenerate.
        * libsupc++/eh_alloc.cc, libsupc++/eh_aux_runtime.cc: New files.
        * libsupc++/eh_catch.cc, libsupc++/eh_exception.cc: New files.
	* libsupc++/eh_globals.cc, libsupc++/eh_personality.cc: New files.
        * libsupc++/eh_terminate.cc, libsupc++/eh_throw.cc: New files.
        * libsupc++/exception_support.cc: Remove.
        * libsupc++/exception_support.h: Remove.
        * libsupc++/pure.cc: Use std::terminate.
        * libsupc++/tinfo2.cc (__throw_type_match_rtti_2): Remove.
        (__is_pointer): Remove.
        * libsupc++/unwind-cxx.h: New file.
        * libsupc++/vec.cc (uncatch_exception): Update for new abi.

Index: acinclude.m4
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/acinclude.m4,v
retrieving revision 1.138
diff -c -p -d -r1.138 acinclude.m4
*** acinclude.m4	2001/03/25 00:16:54	1.138
--- acinclude.m4	2001/03/28 09:55:14
*************** AC_DEFUN(GLIBCPP_ENABLE_THREADS, [
*** 1258,1263 ****
--- 1258,1323 ----
  
  
  dnl
+ dnl Check for exception handling support.  If an explicit enable/disable
+ dnl sjlj exceptions is given, we don't have to detect.  Otherwise the
+ dnl target may or may not support call frame exceptions.
+ dnl
+ dnl GLIBCPP_ENABLE_SJLJ_EXCEPTIONS
+ dnl --enable-sjlj-exceptions forces the use of builtin setjmp.
+ dnl --disable-sjlj-exceptions forces the use of call frame unwinding.
+ dnl
+ dnl Define _GLIBCPP_SJLJ_EXCEPTIONS if the compiler is configured for it.
+ dnl
+ AC_DEFUN(GLIBCPP_ENABLE_SJLJ_EXCEPTIONS, [
+   AC_MSG_CHECKING([for exception model to use])
+   AC_LANG_SAVE
+   AC_LANG_CPLUSPLUS
+   AC_ARG_ENABLE(sjlj-exceptions,
+   [  --enable-sjlj-exceptions  force use of builtin_setjmp for exceptions],
+   [:],
+   [dnl Botheration.  Now we've got to detect the exception model.
+    dnl Link tests against libgcc.a are problematic since -- at least
+    dnl as of this writing -- we've not been given proper -L bits for
+    dnl single-tree newlib and libgloss.
+    dnl
+    dnl This is what AC_TRY_COMPILE would do if it didn't delete the
+    dnl conftest files before we got a change to grep them first.
+    cat > conftest.$ac_ext << EOF
+ [#]line __oline__ "configure"
+ struct S { ~S(); };
+ void bar();
+ void foo()
+ {
+   S s;
+   bar();
+ }
+ EOF
+    old_CXXFLAGS="$CXXFLAGS"  
+    CXXFLAGS=-S
+    if AC_TRY_EVAL(ac_compile); then
+      if grep _Unwind_Sjlj_Resume conftest.s >/dev/null 2>&1 ; then
+        enable_sjlj_exceptions=yes
+      elif grep _Unwind_Resume conftest.s >/dev/null 2>&1 ; then
+        enable_sjlj_exceptions=no
+      fi
+    fi
+    CXXFLAGS="$old_CXXFLAGS"
+    rm -f conftest*])
+    if test x$enable_sjlj_exceptions = xyes; then
+      AC_DEFINE(_GLIBCPP_SJLJ_EXCEPTIONS, 1,
+ 	[Define if the compiler is configured for setjmp/longjmp exceptions.])
+      ac_exception_model_name=sjlj
+    elif test x$enable_sjlj_exceptions = xno; then
+      ac_exception_model_name="call frame"
+    else
+      AC_MSG_ERROR([unable to detect exception model])
+    fi
+    AC_LANG_RESTORE
+    AC_MSG_RESULT($ac_exception_model_name)
+ ])
+ 
+ 
+ dnl
  dnl Check for template specializations for the 'long long' type extension.
  dnl
  dnl GLIBCPP_ENABLE_LONG_LONG
Index: configure.in
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/configure.in,v
retrieving revision 1.55
diff -c -p -d -r1.55 configure.in
*** configure.in	2001/02/26 21:47:59	1.55
--- configure.in	2001/03/28 09:55:15
*************** GLIBCPP_ENABLE_LONG_LONG([no])
*** 68,73 ****
--- 68,74 ----
  GLIBCPP_ENABLE_CHEADERS([c_std])
  GLIBCPP_ENABLE_THREADS
  GLIBCPP_ENABLE_CXX_FLAGS([none])
+ GLIBCPP_ENABLE_SJLJ_EXCEPTIONS
  
  if test -n "$with_cross_host"; then
  
Index: libsupc++/Makefile.am
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/libsupc++/Makefile.am,v
retrieving revision 1.22
diff -c -p -d -r1.22 Makefile.am
*** Makefile.am	2001/03/28 01:19:41	1.22
--- Makefile.am	2001/03/28 09:55:15
*************** sources = \
*** 75,81 ****
  	del_opnt.cc \
  	del_opv.cc \
  	del_opvnt.cc \
! 	exception_support.cc \
  	new_handler.cc \
  	new_op.cc \
  	new_opnt.cc \
--- 75,88 ----
  	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_terminate.cc \
! 	eh_throw.cc \
  	new_handler.cc \
  	new_op.cc \
  	new_opnt.cc \
Index: libsupc++/eh_alloc.cc
===================================================================
RCS file: eh_alloc.cc
diff -N eh_alloc.cc
*** /dev/null	Tue May  5 13:32:27 1998
--- eh_alloc.cc	Wed Mar 28 01:55:15 2001
***************
*** 0 ****
--- 1,157 ----
+ // -*- C++ -*- Allocate exception objects.
+ // Copyright (C) 2001 Free Software Foundation, Inc.
+ //
+ // This file is part of GNU CC.
+ //
+ // GNU CC 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.
+ //
+ // GNU CC 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 GNU CC; see the file COPYING.  If not, write to
+ // the Free Software Foundation, 59 Temple Place - Suite 330,
+ // Boston, MA 02111-1307, USA.
+ 
+ // As a special exception, you may use this file as part of a free software
+ // library without restriction.  Specifically, if other files instantiate
+ // templates or use macros or inline functions from this file, or you compile
+ // this file and link it with other files to produce an executable, this
+ // file does not by itself cause the resulting executable to be covered by
+ // the GNU General Public License.  This exception does not however
+ // invalidate any other reasons why the executable file might be covered by
+ // the GNU General Public License.
+ 
+ // This is derived from the C++ ABI for IA-64.  Where we diverge
+ // for cross-architecture compatibility are noted with "@@@".
+ 
+ #include <exception>
+ #include <cstdlib>
+ #include <cstring>
+ #include <limits.h>
+ #include "unwind-cxx.h"
+ #include "gthr.h"
+ 
+ using namespace __cxxabiv1;
+ 
+ 
+ // ??? How to control these parameters.
+ 
+ // Guess from the size of basic types how large a buffer is reasonable.
+ // Note that the basic c++ exception header has 13 pointers and 2 ints,
+ // so on a system with PSImode pointers we're talking about 56 bytes
+ // just for overhead.
+ 
+ #if INT_MAX == 32767
+ # define EMERGENCY_OBJ_SIZE	128
+ # define EMERGENCY_OBJ_COUNT	16
+ #elif LONG_MAX == 2147483647
+ # define EMERGENCY_OBJ_SIZE	512
+ # define EMERGENCY_OBJ_COUNT	32
+ #else
+ # define EMERGENCY_OBJ_SIZE	1024
+ # define EMERGENCY_OBJ_COUNT	64
+ #endif
+ 
+ #ifndef __GTHREADS
+ # undef EMERGENCY_OBJ_COUNT
+ # define EMERGENCY_OBJ_COUNT	4
+ #endif
+ 
+ #if INT_MAX == 32767 || EMERGENCY_OBJ_COUNT <= 32
+ typedef unsigned int bitmask_type;
+ #else
+ typedef unsigned long bitmask_type;
+ #endif
+ 
+ 
+ typedef char one_buffer[EMERGENCY_OBJ_SIZE] __attribute__((aligned));
+ static one_buffer emergency_buffer[EMERGENCY_OBJ_COUNT];
+ static bitmask_type emergency_used;
+ 
+ 
+ #ifdef __GTHREADS
+ #ifdef __GTHREAD_MUTEX_INIT
+ static __gthread_mutex_t emergency_mutex =__GTHREAD_MUTEX_INIT;
+ #else 
+ static __gthread_mutex_t emergency_mutex;
+ #endif
+ 
+ #ifdef __GTHREAD_MUTEX_INIT_FUNCTION
+ static void
+ emergency_mutex_init ()
+ {
+   __GTHREAD_MUTEX_INIT_FUNCTION (&emergency_mutex);
+ }
+ #endif
+ #endif
+ 
+ 
+ extern "C" void *
+ __cxa_allocate_exception(std::size_t thrown_size)
+ {
+   void *ret;
+ 
+   thrown_size += sizeof (__cxa_exception);
+   ret = malloc (thrown_size);
+ 
+   if (! ret)
+     {
+ #ifdef __GTHREADS
+ #ifdef __GTHREAD_MUTEX_INIT_FUNCTION
+       static __gthread_once_t once = __GTHREAD_ONCE_INIT;
+       __gthread_once (&once, emergency_mutex_init);
+ #endif
+       __gthread_mutex_lock (&emergency_mutex);
+ #endif
+ 
+       bitmask_type used = emergency_used;
+       unsigned int which = 0;
+ 
+       while (used & 1)
+ 	{
+ 	  used >>= 1;
+ 	  if (++which >= EMERGENCY_OBJ_COUNT)
+ 	    std::terminate ();
+ 	}
+ 
+       emergency_used |= (bitmask_type)1 << which;
+       ret = &emergency_buffer[which][0];
+ 
+ #ifdef __GTHREADS
+       __gthread_mutex_unlock (&emergency_mutex);
+ #endif
+     }
+ 
+   memset (ret, 0, sizeof (__cxa_exception));
+ 
+   return (void *)((char *)ret + sizeof (__cxa_exception));
+ }
+ 
+ 
+ extern "C" void
+ __cxa_free_exception(void *vptr)
+ {
+   char *ptr = (char *) vptr;
+   if (ptr >= &emergency_buffer[0][0]
+       && ptr < &emergency_buffer[0][0] + sizeof (emergency_buffer))
+     {
+       unsigned int which
+ 	= (unsigned)(ptr - &emergency_buffer[0][0]) / EMERGENCY_OBJ_SIZE;
+ 
+ #ifdef __GTHREADS
+       __gthread_mutex_lock (&emergency_mutex);
+       emergency_used &= ~((bitmask_type)1 << which);
+       __gthread_mutex_unlock (&emergency_mutex);
+ #else
+       emergency_used &= ~((bitmask_type)1 << which);
+ #endif
+     }
+   else
+     free (ptr - sizeof (__cxa_exception));
+ }
Index: libsupc++/eh_aux_runtime.cc
===================================================================
RCS file: eh_aux_runtime.cc
diff -N eh_aux_runtime.cc
*** /dev/null	Tue May  5 13:32:27 1998
--- eh_aux_runtime.cc	Wed Mar 28 01:55:15 2001
***************
*** 0 ****
--- 1,56 ----
+ // -*- C++ -*- Common throw conditions.
+ // Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 
+ // Free Software Foundation
+ //
+ // This file is part of GNU CC.
+ //
+ // GNU CC 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.
+ //
+ // GNU CC 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 GNU CC; see the file COPYING.  If not, write to
+ // the Free Software Foundation, 59 Temple Place - Suite 330,
+ // Boston, MA 02111-1307, USA. 
+ 
+ // As a special exception, you may use this file as part of a free software
+ // library without restriction.  Specifically, if other files instantiate
+ // templates or use macros or inline functions from this file, or you compile
+ // this file and link it with other files to produce an executable, this
+ // file does not by itself cause the resulting executable to be covered by
+ // the GNU General Public License.  This exception does not however
+ // invalidate any other reasons why the executable file might be covered by
+ // the GNU General Public License.
+ 
+ #include "typeinfo"
+ #include "exception"
+ #include <cstddef>
+ #include "unwind-cxx.h"
+ #include "exception_defines.h"
+ 
+ 
+ extern "C" void
+ __cxa_bad_cast ()
+ {
+ #ifdef __EXCEPTIONS  
+   throw std::bad_cast();
+ #else
+   std::abort();
+ #endif
+ }
+ 
+ extern "C" void
+ __cxa_bad_typeid ()
+ {
+ #ifdef __EXCEPTIONS  
+   throw std::bad_typeid();
+ #else
+   std::abort();
+ #endif
+ }
Index: libsupc++/eh_catch.cc
===================================================================
RCS file: eh_catch.cc
diff -N eh_catch.cc
*** /dev/null	Tue May  5 13:32:27 1998
--- eh_catch.cc	Wed Mar 28 01:55:15 2001
***************
*** 0 ****
--- 1,103 ----
+ // -*- C++ -*- Exception handling routines for catching.
+ // Copyright (C) 2001 Free Software Foundation, Inc.
+ //
+ // This file is part of GNU CC.
+ //
+ // GNU CC 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.
+ //
+ // GNU CC 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 GNU CC; see the file COPYING.  If not, write to
+ // the Free Software Foundation, 59 Temple Place - Suite 330,
+ // Boston, MA 02111-1307, USA.
+ 
+ // As a special exception, you may use this file as part of a free software
+ // library without restriction.  Specifically, if other files instantiate
+ // templates or use macros or inline functions from this file, or you compile
+ // this file and link it with other files to produce an executable, this
+ // file does not by itself cause the resulting executable to be covered by
+ // the GNU General Public License.  This exception does not however
+ // invalidate any other reasons why the executable file might be covered by
+ // the GNU General Public License.
+ 
+ 
+ #include <cstdlib>
+ #include "unwind-cxx.h"
+ 
+ using namespace __cxxabiv1;
+ 
+ 
+ extern "C" void *
+ __cxa_begin_catch (_Unwind_Exception *exceptionObject)
+ {
+   // ??? Foreign exceptions can't be stacked here, and there doesn't
+   // appear to be any place to store for __cxa_end_catch to destroy.
+ 
+   __cxa_exception *header = __get_exception_header_from_ue (exceptionObject);
+   __cxa_eh_globals *globals = __cxa_get_globals ();
+   __cxa_exception *prev = globals->caughtExceptions;
+   int count = header->handlerCount;
+ 
+   if (count < 0)
+     // This exception was rethrown from an immediately enclosing region.
+     count = -count + 1;
+   else
+     count += 1;
+   header->handlerCount = count;
+ 
+   globals->uncaughtExceptions -= 1;
+   if (header != prev)
+     {
+       header->nextException = prev;
+       globals->caughtExceptions = header;
+     }
+ 
+   return header->adjustedPtr;
+ }
+ 
+ 
+ extern "C" void
+ __cxa_end_catch ()
+ {
+   __cxa_eh_globals *globals = __cxa_get_globals_fast ();
+   __cxa_exception *header = globals->caughtExceptions;
+   int count = header->handlerCount;
+ 
+   if (count < 0)
+     {
+       // This exception was rethrown.  Decrement the (inverted) catch
+       // count and remove it from the chain when it reaches zero.
+       if (++count == 0)
+ 	{
+ 	  globals->uncaughtExceptions += 1;
+ 	  globals->caughtExceptions = header->nextException;
+ 	}
+     }
+   else if (--count == 0)
+     {
+       // Handling for this exception is complete.  Destroy the object.
+       globals->caughtExceptions = header->nextException;
+       _Unwind_DeleteException (&header->unwindHeader);
+       return;
+     }
+   else if (count < 0)
+     // A bug in the exception handling library or compiler.
+     abort ();
+ 
+   header->handlerCount = count;
+ }
+ 
+ 
+ bool
+ std::uncaught_exception() throw()
+ {
+   __cxa_eh_globals *globals = __cxa_get_globals ();
+   return globals->uncaughtExceptions != 0;
+ }
Index: libsupc++/eh_exception.cc
===================================================================
RCS file: eh_exception.cc
diff -N eh_exception.cc
*** /dev/null	Tue May  5 13:32:27 1998
--- eh_exception.cc	Wed Mar 28 01:55:15 2001
***************
*** 0 ****
--- 1,44 ----
+ // -*- C++ -*- std::exception implementation.
+ // Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 
+ // Free Software Foundation
+ //
+ // This file is part of GNU CC.
+ //
+ // GNU CC 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.
+ //
+ // GNU CC 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 GNU CC; see the file COPYING.  If not, write to
+ // the Free Software Foundation, 59 Temple Place - Suite 330,
+ // Boston, MA 02111-1307, USA. 
+ 
+ // As a special exception, you may use this file as part of a free software
+ // library without restriction.  Specifically, if other files instantiate
+ // templates or use macros or inline functions from this file, or you compile
+ // this file and link it with other files to produce an executable, this
+ // file does not by itself cause the resulting executable to be covered by
+ // the GNU General Public License.  This exception does not however
+ // invalidate any other reasons why the executable file might be covered by
+ // the GNU General Public License.
+ 
+ 
+ #include "typeinfo"
+ #include "exception"
+ #include "unwind-cxx.h"
+ 
+ std::exception::~exception() throw() { }
+ 
+ std::bad_exception::~bad_exception() throw() { }
+ 
+ const char* 
+ std::exception::what() const throw()
+ {
+   return typeid (*this).name ();
+ }
Index: libsupc++/eh_globals.cc
===================================================================
RCS file: eh_globals.cc
diff -N eh_globals.cc
*** /dev/null	Tue May  5 13:32:27 1998
--- eh_globals.cc	Wed Mar 28 01:55:15 2001
***************
*** 0 ****
--- 1,120 ----
+ // -*- C++ -*- Manage the thread-local exception globals.
+ // Copyright (C) 2001 Free Software Foundation, Inc.
+ //
+ // This file is part of GNU CC.
+ //
+ // GNU CC 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.
+ //
+ // GNU CC 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 GNU CC; see the file COPYING.  If not, write to
+ // the Free Software Foundation, 59 Temple Place - Suite 330,
+ // Boston, MA 02111-1307, USA.
+ 
+ // As a special exception, you may use this file as part of a free software
+ // library without restriction.  Specifically, if other files instantiate
+ // templates or use macros or inline functions from this file, or you compile
+ // this file and link it with other files to produce an executable, this
+ // file does not by itself cause the resulting executable to be covered by
+ // the GNU General Public License.  This exception does not however
+ // invalidate any other reasons why the executable file might be covered by
+ // the GNU General Public License.
+ 
+ 
+ #include <exception>
+ #include "unwind-cxx.h"
+ #include "gthr.h"
+ 
+ using namespace __cxxabiv1;
+ 
+ 
+ // Single-threaded fallback buffer.
+ static __cxa_eh_globals globals_static;
+ 
+ #if __GTHREADS
+ static __gthread_key_t globals_key;
+ static int use_thread_key = -1;
+ 
+ static void
+ get_globals_dtor (void *ptr)
+ {
+   __gthread_key_dtor (globals_key, ptr);
+   if (ptr)
+     free (ptr);
+ }
+ 
+ static void
+ get_globals_init ()
+ {
+   use_thread_key =
+     (__gthread_key_create (&globals_key, get_globals_dtor) == 0);
+ }
+ 
+ static void
+ get_globals_init_once ()
+ {
+   static __gthread_once_t once = __GTHREAD_ONCE_INIT;
+   if (__gthread_once (&once, get_globals_init) != 0
+       || use_thread_key < 0)
+     use_thread_key = 0;
+ }
+ #endif
+ 
+ extern "C" __cxa_eh_globals *
+ __cxa_get_globals_fast ()
+ {
+ #if __GTHREADS
+   if (use_thread_key)
+     return (__cxa_eh_globals *) __gthread_getspecific (globals_key);
+   else
+     return &globals_static;
+ #else
+   return &globals_static;
+ #endif
+ }
+ 
+ extern "C" __cxa_eh_globals *
+ __cxa_get_globals ()
+ {
+ #if __GTHREADS
+   __cxa_eh_globals *g;
+ 
+   if (use_thread_key == 0)
+     return &globals_static;
+ 
+   if (use_thread_key < 0)
+     get_globals_init_once ();
+ 
+   g = (__cxa_eh_globals *) __gthread_getspecific (globals_key);
+   if (! g)
+     {
+       static __gthread_once_t once = __GTHREAD_ONCE_INIT;
+ 
+       // Make sure use_thread_key got initialized.  Some systems have
+       // dummy thread routines in their libc that return a success.
+       if (__gthread_once (&once, eh_threads_initialize) != 0
+ 	  || use_thread_key < 0)
+ 	{
+ 	  use_thread_key = 0;
+ 	  return &globals_static;
+ 	}
+       
+       if ((g = malloc (sizeof (__cxa_eh_globals))) == 0
+ 	  || __gthread_setspecific (eh_context_key, (void *) g) != 0)
+         std::terminate ();
+       g->caughtExceptions = 0;
+       g->uncaughtExceptions = 0;
+     }
+ 
+   return g;
+ #else
+   return &globals_static;
+ #endif
+ }
Index: libsupc++/eh_personality.cc
===================================================================
RCS file: eh_personality.cc
diff -N eh_personality.cc
*** /dev/null	Tue May  5 13:32:27 1998
--- eh_personality.cc	Wed Mar 28 01:55:15 2001
***************
*** 0 ****
--- 1,599 ----
+ // -*- C++ -*- The GNU C++ exception personality routine.
+ // Copyright (C) 2001 Free Software Foundation, Inc.
+ //
+ // This file is part of GNU CC.
+ //
+ // GNU CC 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.
+ //
+ // GNU CC 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 GNU CC; see the file COPYING.  If not, write to
+ // the Free Software Foundation, 59 Temple Place - Suite 330,
+ // Boston, MA 02111-1307, USA.
+ 
+ // As a special exception, you may use this file as part of a free software
+ // library without restriction.  Specifically, if other files instantiate
+ // templates or use macros or inline functions from this file, or you compile
+ // this file and link it with other files to produce an executable, this
+ // file does not by itself cause the resulting executable to be covered by
+ // the GNU General Public License.  This exception does not however
+ // invalidate any other reasons why the executable file might be covered by
+ // the GNU General Public License.
+ 
+ 
+ #include <bits/c++config.h>
+ #include <cstdlib>
+ #include "unwind-cxx.h"
+ 
+ using namespace __cxxabiv1;
+ 
+ 
+ 
+ // ??? These ought to go somewhere else dwarf2 or dwarf2eh related.
+ 
+ // Pointer encodings.
+ #define DW_EH_PE_absptr         0x00
+ #define DW_EH_PE_omit           0xff
+ 
+ #define DW_EH_PE_uleb128        0x01
+ #define DW_EH_PE_udata2         0x02
+ #define DW_EH_PE_udata4         0x03
+ #define DW_EH_PE_udata8         0x04
+ #define DW_EH_PE_sleb128        0x09
+ #define DW_EH_PE_sdata2         0x0A
+ #define DW_EH_PE_sdata4         0x0B
+ #define DW_EH_PE_sdata8         0x0C
+ #define DW_EH_PE_signed         0x08
+ 
+ #define DW_EH_PE_pcrel          0x10
+ #define DW_EH_PE_textrel        0x20
+ #define DW_EH_PE_datarel        0x30
+ #define DW_EH_PE_funcrel        0x40
+ 
+ static unsigned int
+ size_of_encoded_value (unsigned char encoding)
+ {
+   switch (encoding & 0x07)
+     {
+     case DW_EH_PE_absptr:
+       return sizeof (void *);
+     case DW_EH_PE_udata2:
+       return 2;
+     case DW_EH_PE_udata4:
+       return 4;
+     case DW_EH_PE_udata8:
+       return 8;
+     }
+   abort ();
+ }
+ 
+ static const unsigned char *
+ read_encoded_value (_Unwind_Context *context, unsigned char encoding,
+ 		    const unsigned char *p, _Unwind_Ptr *val)
+ {
+   union unaligned
+     {
+       void *ptr;
+       unsigned u2 __attribute__ ((mode (HI)));
+       unsigned u4 __attribute__ ((mode (SI)));
+       unsigned u8 __attribute__ ((mode (DI)));
+       signed s2 __attribute__ ((mode (HI)));
+       signed s4 __attribute__ ((mode (SI)));
+       signed s8 __attribute__ ((mode (DI)));
+     } __attribute__((__packed__));
+ 
+   union unaligned *u = (union unaligned *) p;
+   _Unwind_Ptr result;
+ 
+   switch (encoding & 0x0f)
+     {
+     case DW_EH_PE_absptr:
+       result = (_Unwind_Ptr) u->ptr;
+       p += sizeof (void *);
+       break;
+ 
+     case DW_EH_PE_uleb128:
+       {
+ 	unsigned int shift = 0;
+ 	unsigned char byte;
+ 
+ 	result = 0;
+ 	do
+ 	  {
+ 	    byte = *p++;
+ 	    result |= (_Unwind_Ptr)(byte & 0x7f) << shift;
+ 	    shift += 7;
+ 	  }
+ 	while (byte & 0x80);
+       }
+       break;
+ 
+     case DW_EH_PE_sleb128:
+       {
+ 	unsigned int shift = 0;
+ 	unsigned char byte;
+ 
+ 	result = 0;
+ 	do
+ 	  {
+ 	    byte = *p++;
+ 	    result |= (_Unwind_Ptr)(byte & 0x7f) << shift;
+ 	    shift += 7;
+ 	  }
+ 	while (byte & 0x80);
+ 
+ 	if (shift < 8 * sizeof(result) && (byte & 0x40) != 0)
+ 	  result |= -(1L << shift);
+       }
+       break;
+ 
+     case DW_EH_PE_udata2:
+       result = u->u2;
+       p += 2;
+       break;
+     case DW_EH_PE_udata4:
+       result = u->u4;
+       p += 4;
+       break;
+     case DW_EH_PE_udata8:
+       result = u->u8;
+       p += 8;
+       break;
+ 
+     case DW_EH_PE_sdata2:
+       result = u->s2;
+       p += 2;
+       break;
+     case DW_EH_PE_sdata4:
+       result = u->s4;
+       p += 4;
+       break;
+     case DW_EH_PE_sdata8:
+       result = u->s8;
+       p += 8;
+       break;
+ 
+     default:
+       abort ();
+     }
+ 
+   if (result != 0)
+     switch (encoding & 0xf0)
+       {
+       case DW_EH_PE_absptr:
+ 	break;
+ 
+       case DW_EH_PE_pcrel:
+ 	// Define as relative to the beginning of the pointer.
+ 	result += (_Unwind_Ptr) u;
+ 	break;
+ 
+       case DW_EH_PE_textrel:
+       case DW_EH_PE_datarel:
+ 	// FIXME.
+ 	abort ();
+ 
+       case DW_EH_PE_funcrel:
+ 	result += _Unwind_GetRegionStart (context);
+ 	break;
+ 
+       default:
+ 	abort ();
+       }
+ 
+   *val = result;
+   return p;
+ }
+ 
+ static inline const unsigned char *
+ read_uleb128 (const unsigned char *p, _Unwind_Ptr *val)
+ {
+   return read_encoded_value (0, DW_EH_PE_uleb128, p, val);
+ }
+ 
+ static inline const unsigned char *
+ read_sleb128 (const unsigned char *p, _Unwind_Ptr *val)
+ {
+   return read_encoded_value (0, DW_EH_PE_sleb128, p, val);
+ }
+ 
+ 
+ struct lsda_header_info
+ {
+   _Unwind_Ptr Start;
+   _Unwind_Ptr LPStart;
+   const unsigned char *TType;
+   const unsigned char *action_table;
+   unsigned char ttype_encoding;
+   unsigned char call_site_encoding;
+ };
+ 
+ static const unsigned char *
+ parse_lsda_header (_Unwind_Context *context, const unsigned char *p,
+ 		   lsda_header_info *info)
+ {
+   _Unwind_Ptr tmp;
+   unsigned char lpstart_encoding;
+ 
+   info->Start = (context ? _Unwind_GetRegionStart (context) : 0);
+ 
+   // Find @LPStart, the base to which landing pad offsets are relative.
+   lpstart_encoding = *p++;
+   if (lpstart_encoding != DW_EH_PE_omit)
+     p = read_encoded_value (context, lpstart_encoding, p, &info->LPStart);
+   else
+     info->LPStart = info->Start;
+ 
+   // Find @TType, the base of the handler and exception spec type data.
+   info->ttype_encoding = *p++;
+   if (info->ttype_encoding != DW_EH_PE_omit)
+     {
+       p = read_uleb128 (p, &tmp);
+       info->TType = p + tmp;
+     }
+   else
+     info->TType = 0;
+ 
+   // The encoding and length of the call-site table; the action table
+   // immediately follows.
+   info->call_site_encoding = *p++;
+   p = read_uleb128 (p, &tmp);
+   info->action_table = p + tmp;
+ 
+   return p;
+ }
+ 
+ static const std::type_info *
+ get_ttype_entry (_Unwind_Context *context, lsda_header_info *info, long i)
+ {
+   _Unwind_Ptr ptr;
+ 
+   i *= size_of_encoded_value (info->ttype_encoding);
+   read_encoded_value (context, info->ttype_encoding, info->TType - i, &ptr);
+ 
+   return reinterpret_cast<const std::type_info *>(ptr);
+ }
+ 
+ static bool
+ check_exception_spec (_Unwind_Context *context, lsda_header_info *info,
+ 		      const std::type_info *throw_type, long filter_value)
+ {
+   const unsigned char *e = info->TType - filter_value - 1;
+ 
+   while (1)
+     {
+       const std::type_info *catch_type;
+       _Unwind_Ptr tmp;
+       void *dummy;
+ 
+       e = read_uleb128 (e, &tmp);
+ 
+       // 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;
+ 
+       // Match a ttype entry.
+       catch_type = get_ttype_entry (context, info, tmp);
+       if (catch_type->__do_catch (throw_type, &dummy, 1))
+ 	return true;
+     }
+ }
+ 
+ // Using a different personality function name causes link failures
+ // when trying to mix code using different exception handling models.
+ #ifdef _GLIBCPP_SJLJ_EXCEPTIONS
+ #define PERSONALITY_FUNCTION	__gxx_personality_sj0
+ #define __builtin_eh_return_data_regno(x) x
+ #else
+ #define PERSONALITY_FUNCTION	__gxx_personality_v0
+ #endif
+ 
+ extern "C" _Unwind_Reason_Code
+ PERSONALITY_FUNCTION (int version,
+ 		      _Unwind_Action actions,
+ 		      _Unwind_Exception_Class exception_class,
+ 		      struct _Unwind_Exception *ue_header,
+ 		      struct _Unwind_Context *context)
+ {
+   __cxa_exception *xh = __get_exception_header_from_ue (ue_header);
+ 
+   enum found_handler_type
+   {
+     found_nothing,
+     found_terminate,
+     found_cleanup,
+     found_handler
+   } found_type;
+ 
+   lsda_header_info info;
+   const unsigned char *language_specific_data;
+   const unsigned char *action_record;
+   const unsigned char *p;
+   _Unwind_Ptr landing_pad, ip;
+   int handler_switch_value;
+   void *adjusted_ptr = xh + 1;
+ 
+   // Interface version check.
+   if (version != 1)
+     return _URC_FATAL_PHASE1_ERROR;
+ 
+   // Shortcut for phase 2 found handler for domestic exception.
+   if (actions == (_UA_CLEANUP_PHASE | _UA_HANDLER_FRAME)
+       && exception_class == __gxx_exception_class)
+     {
+       handler_switch_value = xh->handlerSwitchValue;
+       landing_pad = (_Unwind_Ptr) xh->catchTemp;
+       found_type = (landing_pad == 0 ? found_terminate : found_handler);
+       goto install_context;
+     }
+ 
+   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;
+ 
+   // Parse the LSDA header.
+   p = parse_lsda_header (context, language_specific_data, &info);
+   ip = _Unwind_GetIP (context) - 1;
+   landing_pad = 0;
+   action_record = 0;
+   handler_switch_value = 0;
+ 
+ #ifdef _GLIBCPP_SJLJ_EXCEPTIONS
+   // The given "IP" is an index into the call-site table, with two
+   // exceptions -- -1 means no-action, and 0 means terminate.  But
+   // since we're using uleb128 values, we've not got random access
+   // to the array.
+   if ((int) ip < 0)
+     return _URC_CONTINUE_UNWIND;
+   else if (ip == 0)
+     {
+       // Fall through to set found_terminate.
+     }
+   else
+     {
+       _Unwind_Ptr cs_lp, cs_action;
+       do
+ 	{
+ 	  p = read_uleb128 (p, &cs_lp);
+ 	  p = read_uleb128 (p, &cs_action);
+ 	}
+       while (--ip);
+ 
+       // Can never have null landing pad for sjlj -- that would have
+       // been indicated by a -1 call site index.
+       landing_pad = cs_lp + 1;
+       if (cs_action)
+ 	action_record = info.action_table + cs_action - 1;
+       goto found_something;
+     }
+ #else
+   // Search the call-site table for the action associated with this IP.
+   while (p < info.action_table)
+     {
+       _Unwind_Ptr cs_start, cs_len, cs_lp, cs_action;
+ 
+       // Note that all call-site encodings are "absolute" displacements.
+       p = read_encoded_value (0, info.call_site_encoding, p, &cs_start);
+       p = read_encoded_value (0, info.call_site_encoding, p, &cs_len);
+       p = read_encoded_value (0, info.call_site_encoding, p, &cs_lp);
+       p = read_uleb128 (p, &cs_action);
+ 
+       // The table is sorted, so if we've passed the ip, stop.
+       if (ip < info.Start + cs_start)
+ 	p = info.action_table;
+       else if (ip < info.Start + cs_start + cs_len)
+ 	{
+ 	  if (cs_lp)
+ 	    landing_pad = info.LPStart + cs_lp;
+ 	  if (cs_action)
+ 	    action_record = info.action_table + cs_action - 1;
+ 	  goto found_something;
+ 	}
+     }
+ #endif // _GLIBCPP_SJLJ_EXCEPTIONS
+ 
+   // If ip is not present in the table, call terminate.  This is for
+   // a destructor inside a cleanup, or a library routine the compiler
+   // was not expecting to throw.
+   found_type = (actions & _UA_FORCE_UNWIND ? found_nothing : found_terminate);
+   goto do_something;
+ 
+  found_something:
+   if (landing_pad == 0)
+     {
+       // If ip is present, and has a null landing pad, there are
+       // no cleanups or handlers to be run.
+       found_type = found_nothing;
+     }
+   else if (action_record == 0)
+     {
+       // If ip is present, has a non-null landing pad, and a null
+       // action table offset, then there are only cleanups present.
+       // Cleanups use a zero switch value, as set above.
+       found_type = found_cleanup;
+     }
+   else
+     {
+       // Otherwise we have a catch handler or exception specification.
+ 
+       signed long ar_filter, ar_disp;
+       const std::type_info *throw_type, *catch_type;
+       bool saw_cleanup = false;
+       bool saw_handler = false;
+ 
+       // During forced unwinding, we only run cleanups.  With a foreign
+       // exception class, there's no exception type.
+       // ??? What to do about GNU Java and GNU Ada exceptions.
+ 
+       if ((actions & _UA_FORCE_UNWIND)
+ 	  || exception_class != __gxx_exception_class)
+ 	throw_type = 0;
+       else
+ 	throw_type = xh->exceptionType;
+ 
+       while (1)
+ 	{
+ 	  _Unwind_Ptr tmp;
+ 
+ 	  p = action_record;
+ 	  p = read_sleb128 (p, &tmp); ar_filter = tmp;
+ 	  read_sleb128 (p, &tmp); ar_disp = tmp;
+ 
+ 	  if (ar_filter == 0)
+ 	    {
+ 	      // Zero filter values are cleanups.
+ 	      saw_cleanup = true;
+ 	    }
+ 	  else if (ar_filter > 0)
+ 	    {
+ 	      // Positive filter values are handlers.
+ 	      catch_type = get_ttype_entry (context, &info, ar_filter);
+ 	      adjusted_ptr = xh + 1;
+ 
+ 	      // Null catch type is a catch-all handler.  We can catch
+ 	      // foreign exceptions with this.
+ 	      if (! catch_type)
+ 		{
+ 		  if (!(actions & _UA_FORCE_UNWIND))
+ 		    {
+ 		      saw_handler = true;
+ 		      break;
+ 		    }
+ 		}
+ 	      else if (throw_type)
+ 		{
+ 		  // Pointer types need to adjust the actual pointer, not
+ 		  // the pointer to pointer that is the exception object.
+ 		  // This also has the effect of passing pointer types
+ 		  // "by value" through the __cxa_begin_catch return value.
+ 		  if (throw_type->__is_pointer_p ())
+ 		    adjusted_ptr = *(void **) adjusted_ptr;
+ 
+ 		  if (catch_type->__do_catch (throw_type, &adjusted_ptr, 1))
+ 		    {
+ 		      saw_handler = true;
+ 		      break;
+ 		    }
+ 		}
+ 	    }
+ 	  else
+ 	    {
+ 	      // Negative filter values are exception specifications.
+ 	      // ??? How do foreign exceptions fit in?  As far as I can
+ 	      // see we can't match because there's no __cxa_exception
+ 	      // object to stuff bits in for __cxa_call_unexpected to use.
+ 	      if (throw_type
+ 		  && ! check_exception_spec (context, &info, throw_type,
+ 					     ar_filter))
+ 		{
+ 		  saw_handler = true;
+ 		  break;
+ 		}
+ 	    }
+ 
+ 	  if (ar_disp == 0)
+ 	    break;
+ 	  action_record = p + ar_disp;
+ 	}
+ 
+       if (saw_handler)
+ 	{
+ 	  handler_switch_value = ar_filter;
+ 	  found_type = found_handler;
+ 	}
+       else
+ 	found_type = (saw_cleanup ? found_cleanup : found_nothing);
+     }
+ 
+  do_something:
+    if (found_type == found_nothing)
+      return _URC_CONTINUE_UNWIND;
+ 
+   if (actions & _UA_SEARCH_PHASE)
+     {
+       if (found_type == found_cleanup)
+ 	return _URC_CONTINUE_UNWIND;
+ 
+       // For domestic exceptions, we cache data from phase 1 for phase 2.
+       if (exception_class == __gxx_exception_class)
+         {
+           xh->handlerSwitchValue = handler_switch_value;
+           xh->actionRecord = action_record;
+           xh->languageSpecificData = language_specific_data;
+           xh->adjustedPtr = adjusted_ptr;
+ 
+           // ??? Completely unknown what this field is supposed to be for.
+           // ??? Need to cache TType encoding base for call_unexpected.
+           xh->catchTemp = (void *) (_Unwind_Ptr) landing_pad;
+ 	}
+       return _URC_HANDLER_FOUND;
+     }
+ 
+  install_context:
+   if (found_type == found_terminate)
+     {
+       __cxa_begin_catch (&xh->unwindHeader);
+       __terminate (xh->terminateHandler);
+     }
+ 
+   _Unwind_SetGR (context, __builtin_eh_return_data_regno (0),
+ 		 (_Unwind_Ptr) &xh->unwindHeader);
+   _Unwind_SetGR (context, __builtin_eh_return_data_regno (1),
+ 		 handler_switch_value);
+   _Unwind_SetIP (context, landing_pad);
+   return _URC_INSTALL_CONTEXT;
+ }
+ 
+ extern "C" void
+ __cxa_call_unexpected (_Unwind_Exception *exc_obj)
+ {
+   __cxa_begin_catch (exc_obj);
+ 
+   // This function is a handler for our exception argument.  If we exit
+   // by throwing a different exception, we'll need the original cleaned up.
+   struct end_catch_protect
+   {
+     end_catch_protect() { }
+     ~end_catch_protect() { __cxa_end_catch(); }
+   } end_catch_protect_obj;
+ 
+   __cxa_exception *xh = __get_exception_header_from_ue (exc_obj);
+ 
+   try {
+     __unexpected (xh->unexpectedHandler);
+   } catch (...) {
+     // Get the exception thrown from unexpected.
+     // ??? Foreign exceptions can't be stacked this way.
+ 
+     __cxa_eh_globals *globals = __cxa_get_globals_fast ();
+     __cxa_exception *new_xh = globals->caughtExceptions;
+ 
+     // We don't quite have enough stuff cached; re-parse the LSDA.
+     lsda_header_info info;
+     parse_lsda_header (0, xh->languageSpecificData, &info);
+ 
+     // If this new exception meets the exception spec, allow it.
+     if (check_exception_spec (0, &info, new_xh->exceptionType,
+ 			      xh->handlerSwitchValue))
+       throw;
+ 
+     // If the exception spec allows std::bad_exception, throw that.
+     const std::type_info &bad_exc = typeid (std::bad_exception);
+     if (check_exception_spec (0, &info, &bad_exc, xh->handlerSwitchValue))
+       throw std::bad_exception ();
+ 
+     // Otherwise, die.
+     __terminate(xh->terminateHandler);
+   }
+ }
Index: libsupc++/eh_terminate.cc
===================================================================
RCS file: eh_terminate.cc
diff -N eh_terminate.cc
*** /dev/null	Tue May  5 13:32:27 1998
--- eh_terminate.cc	Wed Mar 28 01:55:15 2001
***************
*** 0 ****
--- 1,87 ----
+ // -*- C++ -*- std::terminate, std::unexpected and friends.
+ // Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 
+ // Free Software Foundation
+ //
+ // This file is part of GNU CC.
+ //
+ // GNU CC 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.
+ //
+ // GNU CC 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 GNU CC; see the file COPYING.  If not, write to
+ // the Free Software Foundation, 59 Temple Place - Suite 330,
+ // Boston, MA 02111-1307, USA. 
+ 
+ // As a special exception, you may use this file as part of a free software
+ // library without restriction.  Specifically, if other files instantiate
+ // templates or use macros or inline functions from this file, or you compile
+ // this file and link it with other files to produce an executable, this
+ // file does not by itself cause the resulting executable to be covered by
+ // the GNU General Public License.  This exception does not however
+ // invalidate any other reasons why the executable file might be covered by
+ // the GNU General Public License.
+ 
+ #include "typeinfo"
+ #include "exception"
+ #include <cstdlib>
+ #include "unwind-cxx.h"
+ #include "exception_defines.h"
+ 
+ using namespace __cxxabiv1;
+ 
+ /* The current installed user handlers.  */
+ std::terminate_handler __cxxabiv1::__terminate_handler = abort;
+ std::unexpected_handler __cxxabiv1::__unexpected_handler = std::terminate;
+ 
+ void
+ __cxxabiv1::__terminate (std::terminate_handler handler)
+ {
+   try {
+     handler ();
+     abort ();
+   } catch (...) {
+     abort ();
+   }
+ }
+ 
+ void
+ std::terminate ()
+ {
+   __terminate (__terminate_handler);
+ }
+ 
+ void
+ __cxxabiv1::__unexpected (std::unexpected_handler handler)
+ {
+   handler();
+   std::terminate ();
+ }
+ 
+ void
+ std::unexpected ()
+ {
+   __unexpected (__unexpected_handler);
+ }
+ 
+ std::terminate_handler
+ std::set_terminate (std::terminate_handler func) throw()
+ {
+   std::terminate_handler old = __terminate_handler;
+   __terminate_handler = func;
+   return old;
+ }
+ 
+ std::unexpected_handler
+ std::set_unexpected (std::unexpected_handler func) throw()
+ {
+   std::unexpected_handler old = __unexpected_handler;
+   __unexpected_handler = func;
+   return old;
+ }
Index: libsupc++/eh_throw.cc
===================================================================
RCS file: eh_throw.cc
diff -N eh_throw.cc
*** /dev/null	Tue May  5 13:32:27 1998
--- eh_throw.cc	Wed Mar 28 01:55:15 2001
***************
*** 0 ****
--- 1,102 ----
+ // -*- C++ -*- Exception handling routines for throwing.
+ // Copyright (C) 2001 Free Software Foundation, Inc.
+ //
+ // This file is part of GNU CC.
+ //
+ // GNU CC 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.
+ //
+ // GNU CC 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 GNU CC; see the file COPYING.  If not, write to
+ // the Free Software Foundation, 59 Temple Place - Suite 330,
+ // Boston, MA 02111-1307, USA.
+ 
+ // As a special exception, you may use this file as part of a free software
+ // library without restriction.  Specifically, if other files instantiate
+ // templates or use macros or inline functions from this file, or you compile
+ // this file and link it with other files to produce an executable, this
+ // file does not by itself cause the resulting executable to be covered by
+ // the GNU General Public License.  This exception does not however
+ // invalidate any other reasons why the executable file might be covered by
+ // the GNU General Public License.
+ 
+ 
+ #include <bits/c++config.h>
+ #include "unwind-cxx.h"
+ 
+ 
+ using namespace __cxxabiv1;
+ 
+ 
+ static void
+ __gxx_exception_cleanup (_Unwind_Reason_Code code, _Unwind_Exception *exc)
+ {
+   __cxa_exception *header = __get_exception_header_from_ue (exc);
+ 
+   // If we havn't been caught by a foreign handler, then this is
+   // some sort of unwind error.  In that case just die immediately.
+   if (code != _URC_FOREIGN_EXCEPTION_CAUGHT)
+     __terminate (header->terminateHandler);
+ 
+   if (header->exceptionDestructor)
+     header->exceptionDestructor (header + 1);
+ 
+   __cxa_free_exception (header + 1);
+ }
+ 
+ 
+ extern "C" void
+ __cxa_throw (void *obj, std::type_info *tinfo, void (*dest) (void *))
+ {
+   __cxa_exception *header = __get_exception_header_from_obj (obj);
+   header->exceptionType = tinfo;
+   header->exceptionDestructor = dest;
+   header->unexpectedHandler = __unexpected_handler;
+   header->terminateHandler = __terminate_handler;
+   header->unwindHeader.exception_class = __gxx_exception_class;
+   header->unwindHeader.exception_cleanup = __gxx_exception_cleanup;
+ 
+   __cxa_eh_globals *globals = __cxa_get_globals ();
+   globals->uncaughtExceptions += 1;
+ 
+ #ifdef _GLIBCPP_SJLJ_EXCEPTIONS
+   _Unwind_SjLj_RaiseException (&header->unwindHeader);
+ #else
+   _Unwind_RaiseException (&header->unwindHeader);
+ #endif
+ 
+   // Some sort of unwinding error.  Note that terminate is a handler.
+   __cxa_begin_catch (&header->unwindHeader);
+   std::terminate ();
+ }
+ 
+ extern "C" void
+ __cxa_rethrow ()
+ {
+   __cxa_eh_globals *globals = __cxa_get_globals ();
+   __cxa_exception *header = globals->caughtExceptions;
+ 
+   // Watch for luser rethrowing with no active exception.
+   if (header)
+     {
+       // Tell __cxa_end_catch this is a rethrow.
+       header->handlerCount = -header->handlerCount;
+ 
+ #ifdef _GLIBCPP_SJLJ_EXCEPTIONS
+       _Unwind_SjLj_RaiseException (&header->unwindHeader);
+ #else
+       _Unwind_RaiseException (&header->unwindHeader);
+ #endif
+   
+       // Some sort of unwinding error.  Note that terminate is a handler.
+       __cxa_begin_catch (&header->unwindHeader);
+     }
+   std::terminate ();
+ }
Index: libsupc++/pure.cc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/libsupc++/pure.cc,v
retrieving revision 1.7
diff -c -p -d -r1.7 pure.cc
*** pure.cc	2001/02/16 01:26:14	1.7
--- pure.cc	2001/03/28 09:55:15
***************
*** 28,33 ****
--- 28,34 ----
  // the GNU General Public License.
  
  #include <bits/c++config.h>
+ #include "unwind-cxx.h"
  
  #ifdef _GLIBCPP_HAVE_UNISTD_H
  # include <unistd.h>
***************
*** 41,56 ****
  # include <stdio.h>
  # define writestr(str)	fputs(str, stderr)
  #endif
- 
- extern "C" {
  
! extern void __terminate(void) __attribute__ ((__noreturn__));
! 
! void
  __cxa_pure_virtual (void)
  {
    writestr ("pure virtual method called\n");
!   __terminate ();
! }
! 
  }
--- 42,51 ----
  # include <stdio.h>
  # define writestr(str)	fputs(str, stderr)
  #endif
  
! extern "C" void
  __cxa_pure_virtual (void)
  {
    writestr ("pure virtual method called\n");
!   std::terminate ();
  }
Index: libsupc++/tinfo2.cc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/libsupc++/tinfo2.cc,v
retrieving revision 1.5
diff -c -p -d -r1.5 tinfo2.cc
*** tinfo2.cc	2001/02/16 01:26:14	1.5
--- tinfo2.cc	2001/03/28 09:55:15
*************** __pointer_catch (const __pbase_type_info
*** 165,195 ****
  }
  
  } // namespace std
- 
- // Entry points for the compiler.
- 
- /* Low level match routine used by compiler to match types of catch
-    variables and thrown objects.  */
- 
- extern "C" int
- __throw_type_match_rtti_2 (const void *catch_type_r, const void *throw_type_r,
- 			 void *objptr, void **valp)
- {
-   const type_info &catch_type = *(const type_info *)catch_type_r;
-   const type_info &throw_type = *(const type_info *)throw_type_r;
- 
-   *valp = objptr;
- 
-   return catch_type.__do_catch (&throw_type, valp, 1);
- }
- 
- /* Called from __cp_pop_exception.  Is P the type_info node for a pointer
-    of some kind?  */
- 
- bool
- __is_pointer (void *p)
- {
-   const type_info *t = reinterpret_cast <const type_info *>(p);
-   return t->__is_pointer_p ();
- }
- 
--- 165,167 ----
Index: libsupc++/unwind-cxx.h
===================================================================
RCS file: unwind-cxx.h
diff -N unwind-cxx.h
*** /dev/null	Tue May  5 13:32:27 1998
--- unwind-cxx.h	Wed Mar 28 01:55:15 2001
***************
*** 0 ****
--- 1,163 ----
+ // -*- C++ -*- Exception handling and frame unwind runtime interface routines.
+ // Copyright (C) 2001 Free Software Foundation, Inc.
+ //
+ // This file is part of GNU CC.
+ //
+ // GNU CC 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.
+ //
+ // GNU CC 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 GNU CC; see the file COPYING.  If not, write to
+ // the Free Software Foundation, 59 Temple Place - Suite 330,
+ // Boston, MA 02111-1307, USA.
+ 
+ // This is derived from the C++ ABI for IA-64.  Where we diverge
+ // for cross-architecture compatibility are noted with "@@@".
+ 
+ #ifndef __UNWIND_CXX_H
+ #define __UNWIND_CXX_H 1
+ 
+ // Level 2: C++ ABI
+ 
+ #include <typeinfo>
+ #include <exception>
+ #include <cstddef>
+ #include "unwind.h"
+ 
+ namespace __cxxabiv1
+ {
+ 
+ // A C++ exception object consists of a header, which is a wrapper around
+ // an unwind object header with additional C++ specific information,
+ // followed by the exception object itself.
+ 
+ struct __cxa_exception
+ { 
+   // Manage the exception object itself.
+   std::type_info *exceptionType;
+   void (*exceptionDestructor)(void *); 
+ 
+   // The C++ standard has entertaining rules wrt calling set_terminate
+   // and set_unexpected in the middle of the exception cleanup process.
+   std::unexpected_handler unexpectedHandler;
+   std::terminate_handler terminateHandler;
+ 
+   // The caught exception stack threads through here.
+   __cxa_exception *nextException;
+ 
+   // How many nested handlers have caught this exception.  A negated
+   // value is a signal that this object has been rethrown.
+   int handlerCount;
+ 
+   // Cache parsed handler data from the personality routine Phase 1
+   // for Phase 2 and __cxa_call_unexpected.
+   int handlerSwitchValue;
+   const unsigned char *actionRecord;
+   const unsigned char *languageSpecificData;
+   void *catchTemp;
+   void *adjustedPtr;
+ 
+   // The generic exception header.  Must be last.
+   _Unwind_Exception unwindHeader;
+ };
+ 
+ // Each thread in a C++ program has access to a __cxa_eh_globals object.
+ struct __cxa_eh_globals
+ {
+   __cxa_exception *caughtExceptions;
+   unsigned int uncaughtExceptions;
+ };
+ 
+ 
+ // The __cxa_eh_globals for the current thread can be obtained by using
+ // either of the following functions.  The "fast" version assumes at least
+ // one prior call of __cxa_get_globals has been made from the current
+ // thread, so no initialization is necessary.
+ extern "C" __cxa_eh_globals *__cxa_get_globals () throw();
+ extern "C" __cxa_eh_globals *__cxa_get_globals_fast () throw();
+ 
+ // Allocate memory for the exception plus the thown object.
+ extern "C" void *__cxa_allocate_exception(std::size_t thrown_size) throw();
+ 
+ // Free the space allocated for the exception.
+ extern "C" void __cxa_free_exception(void *thrown_exception) throw();
+ 
+ // Throw the exception.
+ extern "C" void __cxa_throw (void *thrown_exception,
+ 			     std::type_info *tinfo,
+ 			     void (*dest) (void *))
+      __attribute__((noreturn));
+ 
+ // Used to implement exception handlers.
+ extern "C" void *__cxa_begin_catch (_Unwind_Exception *) throw();
+ extern "C" void __cxa_end_catch ();
+ extern "C" void __cxa_rethrow () __attribute__((noreturn));
+ 
+ // These facilitate code generation for recurring situations.
+ extern "C" void __cxa_bad_cast ();
+ extern "C" void __cxa_bad_typeid ();
+ 
+ // @@@ These are not directly specified by the IA-64 C++ ABI.
+ 
+ // Handles re-checking the exception specification if unexpectedHandler
+ // throws, and if bad_exception needs to be thrown.  Called from the
+ // compiler.
+ extern "C" void __cxa_call_unexpected (_Unwind_Exception *)
+      __attribute__((noreturn));
+ 
+ // Invokes given handler, dying appropriately if the user handler was
+ // so inconsiderate as to return.
+ extern void __terminate(std::terminate_handler) __attribute__((noreturn));
+ extern void __unexpected(std::unexpected_handler) __attribute__((noreturn));
+ 
+ // The current installed user handlers.
+ extern std::terminate_handler __terminate_handler;
+ extern std::unexpected_handler __unexpected_handler;
+ 
+ // These are explicitly GNU C++ specific.
+ 
+ // This is the exception class we report -- "GNUCC++\0".
+ const _Unwind_Exception_Class __gxx_exception_class
+ = ((((((((_Unwind_Exception_Class) 'G' 
+ 	 << 8 | (_Unwind_Exception_Class) 'N')
+ 	<< 8 | (_Unwind_Exception_Class) 'U')
+        << 8 | (_Unwind_Exception_Class) 'C')
+       << 8 | (_Unwind_Exception_Class) 'C')
+      << 8 | (_Unwind_Exception_Class) '+')
+     << 8 | (_Unwind_Exception_Class) '+')
+    << 8 | (_Unwind_Exception_Class) '\0');
+ 
+ // GNU C++ personality routine, Version 0.
+ extern "C" _Unwind_Reason_Code __gxx_personality_v0
+      (int, _Unwind_Action, _Unwind_Exception_Class,
+       struct _Unwind_Exception *, struct _Unwind_Context *);
+ 
+ // GNU C++ sjlj personality routine, Version 0.
+ 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)
+ {
+   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;
+ }
+ 
+ } /* namespace __cxxabiv1 */
+ 
+ #endif // __UNWIND_CXX_H
Index: libsupc++/vec.cc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/libsupc++/vec.cc,v
retrieving revision 1.7
diff -c -p -d -r1.7 vec.cc
*** vec.cc	2001/03/20 16:59:44	1.7
--- vec.cc	2001/03/28 09:55:15
***************
*** 35,41 ****
  #include <exception>
  #include <exception_defines.h>
  
! #include "exception_support.h"
  
  namespace __cxxabiv1
  {
--- 35,41 ----
  #include <exception>
  #include <exception_defines.h>
  
! #include "unwind-cxx.h"
  
  namespace __cxxabiv1
  {
*************** namespace __cxxabiv1
*** 43,53 ****
    {
      struct uncatch_exception 
      {
!       uncatch_exception () { p = __uncatch_exception (); }
!       ~uncatch_exception () { __recatch_exception (p); }
        
!       cp_eh_info *p;
      };
    }
  
    // Allocate and construct array.
--- 43,63 ----
    {
      struct uncatch_exception 
      {
!       uncatch_exception ();
!       ~uncatch_exception () { __cxa_begin_catch (&p->unwindHeader); }
        
!       __cxa_exception *p;
      };
+ 
+     uncatch_exception::uncatch_exception ()
+     {
+       __cxa_eh_globals *globals = __cxa_get_globals_fast ();
+ 
+       p = globals->caughtExceptions;
+       p->handlerCount -= 1;
+       globals->caughtExceptions = p->nextException;
+       globals->uncaughtExceptions += 1;
+     }
    }
  
    // Allocate and construct array.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]