aboutsummaryrefslogtreecommitdiff
path: root/libstdc++-v3/libsupc++
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2001-03-28 03:04:51 -0800
committerRichard Henderson <rth@gcc.gnu.org>2001-03-28 03:04:51 -0800
commit52a11cbfcf0cfb32628b6953588b6af4037ac0b6 (patch)
treea923c8785a06871784c5177530130063c4925f5a /libstdc++-v3/libsupc++
parentce1c98ea459813570b4588427030daa03958fda6 (diff)
downloadgcc-52a11cbfcf0cfb32628b6953588b6af4037ac0b6.zip
gcc-52a11cbfcf0cfb32628b6953588b6af4037ac0b6.tar.gz
gcc-52a11cbfcf0cfb32628b6953588b6af4037ac0b6.tar.bz2
IA-64 ABI Exception Handling.
From-SVN: r40924
Diffstat (limited to 'libstdc++-v3/libsupc++')
-rw-r--r--libstdc++-v3/libsupc++/Makefile.am9
-rw-r--r--libstdc++-v3/libsupc++/Makefile.in57
-rw-r--r--libstdc++-v3/libsupc++/eh_alloc.cc157
-rw-r--r--libstdc++-v3/libsupc++/eh_aux_runtime.cc56
-rw-r--r--libstdc++-v3/libsupc++/eh_catch.cc103
-rw-r--r--libstdc++-v3/libsupc++/eh_exception.cc44
-rw-r--r--libstdc++-v3/libsupc++/eh_globals.cc120
-rw-r--r--libstdc++-v3/libsupc++/eh_personality.cc599
-rw-r--r--libstdc++-v3/libsupc++/eh_terminate.cc87
-rw-r--r--libstdc++-v3/libsupc++/eh_throw.cc102
-rw-r--r--libstdc++-v3/libsupc++/exception_support.cc388
-rw-r--r--libstdc++-v3/libsupc++/exception_support.h65
-rw-r--r--libstdc++-v3/libsupc++/pure.cc11
-rw-r--r--libstdc++-v3/libsupc++/tinfo2.cc28
-rw-r--r--libstdc++-v3/libsupc++/unwind-cxx.h163
-rw-r--r--libstdc++-v3/libsupc++/vec.cc18
16 files changed, 1472 insertions, 535 deletions
diff --git a/libstdc++-v3/libsupc++/Makefile.am b/libstdc++-v3/libsupc++/Makefile.am
index 4694032..ad08c0e 100644
--- a/libstdc++-v3/libsupc++/Makefile.am
+++ b/libstdc++-v3/libsupc++/Makefile.am
@@ -75,7 +75,14 @@ sources = \
del_opnt.cc \
del_opv.cc \
del_opvnt.cc \
- exception_support.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 \
diff --git a/libstdc++-v3/libsupc++/Makefile.in b/libstdc++-v3/libsupc++/Makefile.in
index 79fe2e9..bdc1316 100644
--- a/libstdc++-v3/libsupc++/Makefile.in
+++ b/libstdc++-v3/libsupc++/Makefile.in
@@ -127,13 +127,11 @@ OPTIMIZE_CXXFLAGS = @OPTIMIZE_CXXFLAGS@
# These bits are all figured out from configure. Look in acinclude.m4
# or configure.in to see how they are set. See GLIBCPP_EXPORT_FLAGS
# NB: DEBUGFLAGS have to be at the end so that -O2 can be overridden.
-CONFIG_CXXFLAGS = \
- @EXTRA_CXX_FLAGS@ @SECTION_FLAGS@ @CSHADOW_FLAGS@ @DEBUG_FLAGS@
+CONFIG_CXXFLAGS = @EXTRA_CXX_FLAGS@ @SECTION_FLAGS@ @CSHADOW_FLAGS@ @DEBUG_FLAGS@
# Warning flags to use.
-WARN_CXXFLAGS = \
- @WARN_FLAGS@ $(WERROR) -fdiagnostics-show-location=once
+WARN_CXXFLAGS = @WARN_FLAGS@ $(WERROR) -fdiagnostics-show-location=once
# Use common includes from acinclude.m4/GLIBCPP_EXPORT_INCLUDES
@@ -145,31 +143,13 @@ LIBSUPCXX_INCLUDES = @LIBSUPCXX_INCLUDES@
LIBIO_INCLUDES = @LIBIO_INCLUDES@
TOPLEVEL_INCLUDES = @TOPLEVEL_INCLUDES@
-INCLUDES = \
- -I$(toplevel_srcdir)/gcc -I$(toplevel_srcdir)/include \
- -I$(GLIBCPP_INCLUDE_DIR) $(CSTD_INCLUDES) -I$(top_builddir)/include \
- $(LIBSUPCXX_INCLUDES)
+INCLUDES = -I$(toplevel_srcdir)/gcc -I$(toplevel_srcdir)/include -I$(GLIBCPP_INCLUDE_DIR) $(CSTD_INCLUDES) -I$(top_builddir)/include $(LIBSUPCXX_INCLUDES)
-headers = \
- exception new typeinfo cxxabi.h exception_defines.h
+headers = exception new typeinfo cxxabi.h exception_defines.h
-sources = \
- del_op.cc \
- del_opnt.cc \
- del_opv.cc \
- del_opvnt.cc \
- exception_support.cc \
- new_handler.cc \
- new_op.cc \
- new_opnt.cc \
- new_opv.cc \
- new_opvnt.cc \
- pure.cc \
- tinfo.cc \
- tinfo2.cc \
- vec.cc
+sources = 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_terminate.cc eh_throw.cc new_handler.cc new_op.cc new_opnt.cc new_opv.cc new_opvnt.cc pure.cc tinfo.cc tinfo2.cc vec.cc
libsupc___la_SOURCES = $(sources)
@@ -187,12 +167,7 @@ LIBSUPCXX_CXXFLAGS = -prefer-pic
# set this option because CONFIG_CXXFLAGS has to be after
# OPTIMIZE_CXXFLAGS on the compile line so that -O2 can be overridden
# as the occasion call for it. (ie, --enable-debug)
-AM_CXXFLAGS = \
- -fno-implicit-templates \
- $(LIBSUPCXX_CXXFLAGS) \
- $(WARN_CXXFLAGS) \
- $(OPTIMIZE_CXXFLAGS) \
- $(CONFIG_CXXFLAGS)
+AM_CXXFLAGS = -fno-implicit-templates $(LIBSUPCXX_CXXFLAGS) $(WARN_CXXFLAGS) $(OPTIMIZE_CXXFLAGS) $(CONFIG_CXXFLAGS)
# libstdc++ libtool notes
@@ -216,9 +191,7 @@ AM_CXXFLAGS = \
#
# We have to put --tag disable-shared after --tag CXX lest things
# CXX undo the affect of disable-shared.
-LTCXXCOMPILE = $(LIBTOOL) --tag CXX --tag disable-shared \
- --mode=compile $(CXX) $(INCLUDES) \
- $(AM_CPPFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(AM_CXXFLAGS)
+LTCXXCOMPILE = $(LIBTOOL) --tag CXX --tag disable-shared --mode=compile $(CXX) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(AM_CXXFLAGS)
# 3) We'd have a problem when building the shared libstdc++ object if
@@ -227,8 +200,7 @@ LTCXXCOMPILE = $(LIBTOOL) --tag CXX --tag disable-shared \
# course is problematic at this point. So, we get the top-level
# directory to configure libstdc++-v3 to use gcc as the C++
# compilation driver.
-CXXLINK = $(LIBTOOL) --tag CXX --mode=link $(CXX) \
- @OPT_LDFLAGS@ @SECTION_LDFLAGS@ $(AM_CXXFLAGS) $(LDFLAGS) -o $@
+CXXLINK = $(LIBTOOL) --tag CXX --mode=link $(CXX) @OPT_LDFLAGS@ @SECTION_LDFLAGS@ $(AM_CXXFLAGS) $(LDFLAGS) -o $@
CONFIG_HEADER = ../config.h
CONFIG_CLEAN_FILES =
@@ -242,13 +214,16 @@ LIBS = @LIBS@
libsupc__convenience_la_LDFLAGS =
libsupc__convenience_la_LIBADD =
libsupc__convenience_la_OBJECTS = del_op.lo del_opnt.lo del_opv.lo \
-del_opvnt.lo exception_support.lo new_handler.lo new_op.lo new_opnt.lo \
-new_opv.lo new_opvnt.lo pure.lo tinfo.lo tinfo2.lo vec.lo
+del_opvnt.lo eh_alloc.lo eh_aux_runtime.lo eh_catch.lo eh_exception.lo \
+eh_globals.lo eh_personality.lo eh_terminate.lo eh_throw.lo \
+new_handler.lo new_op.lo new_opnt.lo new_opv.lo new_opvnt.lo pure.lo \
+tinfo.lo tinfo2.lo vec.lo
libsupc___la_LDFLAGS =
libsupc___la_LIBADD =
libsupc___la_OBJECTS = del_op.lo del_opnt.lo del_opv.lo del_opvnt.lo \
-exception_support.lo new_handler.lo new_op.lo new_opnt.lo new_opv.lo \
-new_opvnt.lo pure.lo tinfo.lo tinfo2.lo vec.lo
+eh_alloc.lo eh_aux_runtime.lo eh_catch.lo eh_exception.lo eh_globals.lo \
+eh_personality.lo eh_terminate.lo eh_throw.lo new_handler.lo new_op.lo \
+new_opnt.lo new_opv.lo new_opvnt.lo pure.lo tinfo.lo tinfo2.lo vec.lo
CXXFLAGS = @CXXFLAGS@
CXXCOMPILE = $(CXX) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
CXXLD = $(CXX)
@@ -417,7 +392,7 @@ distdir: $(DISTFILES)
@for file in $(DISTFILES); do \
if test -f $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
- cp -pr $$d/$$file $(distdir)/$$file; \
+ cp -pr $$/$$file $(distdir)/$$file; \
else \
test -f $(distdir)/$$file \
|| ln $$d/$$file $(distdir)/$$file 2> /dev/null \
diff --git a/libstdc++-v3/libsupc++/eh_alloc.cc b/libstdc++-v3/libsupc++/eh_alloc.cc
new file mode 100644
index 0000000..61dc75d
--- /dev/null
+++ b/libstdc++-v3/libsupc++/eh_alloc.cc
@@ -0,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));
+}
diff --git a/libstdc++-v3/libsupc++/eh_aux_runtime.cc b/libstdc++-v3/libsupc++/eh_aux_runtime.cc
new file mode 100644
index 0000000..b10a219
--- /dev/null
+++ b/libstdc++-v3/libsupc++/eh_aux_runtime.cc
@@ -0,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
+}
diff --git a/libstdc++-v3/libsupc++/eh_catch.cc b/libstdc++-v3/libsupc++/eh_catch.cc
new file mode 100644
index 0000000..4f55d68
--- /dev/null
+++ b/libstdc++-v3/libsupc++/eh_catch.cc
@@ -0,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;
+}
diff --git a/libstdc++-v3/libsupc++/eh_exception.cc b/libstdc++-v3/libsupc++/eh_exception.cc
new file mode 100644
index 0000000..3c1a7a4
--- /dev/null
+++ b/libstdc++-v3/libsupc++/eh_exception.cc
@@ -0,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 ();
+}
diff --git a/libstdc++-v3/libsupc++/eh_globals.cc b/libstdc++-v3/libsupc++/eh_globals.cc
new file mode 100644
index 0000000..a247b84
--- /dev/null
+++ b/libstdc++-v3/libsupc++/eh_globals.cc
@@ -0,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
+}
diff --git a/libstdc++-v3/libsupc++/eh_personality.cc b/libstdc++-v3/libsupc++/eh_personality.cc
new file mode 100644
index 0000000..5dfadc9
--- /dev/null
+++ b/libstdc++-v3/libsupc++/eh_personality.cc
@@ -0,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);
+ }
+}
diff --git a/libstdc++-v3/libsupc++/eh_terminate.cc b/libstdc++-v3/libsupc++/eh_terminate.cc
new file mode 100644
index 0000000..11d5829
--- /dev/null
+++ b/libstdc++-v3/libsupc++/eh_terminate.cc
@@ -0,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;
+}
diff --git a/libstdc++-v3/libsupc++/eh_throw.cc b/libstdc++-v3/libsupc++/eh_throw.cc
new file mode 100644
index 0000000..a8e9ba3
--- /dev/null
+++ b/libstdc++-v3/libsupc++/eh_throw.cc
@@ -0,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 ();
+}
diff --git a/libstdc++-v3/libsupc++/exception_support.cc b/libstdc++-v3/libsupc++/exception_support.cc
deleted file mode 100644
index 48adafa..0000000
--- a/libstdc++-v3/libsupc++/exception_support.cc
+++ /dev/null
@@ -1,388 +0,0 @@
-// Functions for Exception Support for -*- C++ -*-
-
-// 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 "exception_support.h"
-#include "exception_defines.h"
-
-/* Define terminate, unexpected, set_terminate, set_unexpected as
- well as the default terminate func and default unexpected func. */
-
-/* __terminate and __terminate_set_func, defined in libgcc2. */
-typedef void (*__terminate_func_ptr)(void) __attribute__ ((__noreturn__));
-extern "C" void __terminate (void) __attribute__ ((__noreturn__));
-extern "C" __terminate_func_ptr __terminate_set_func (__terminate_func_ptr);
-
-using std::terminate;
-
-void
-std::terminate ()
-{
- __terminate ();
-}
-
-void
-__default_unexpected ()
-{
- terminate ();
-}
-
-static std::unexpected_handler __unexpected_func __attribute__((__noreturn__))
- = __default_unexpected;
-
-std::terminate_handler
-std::set_terminate (std::terminate_handler func) throw()
-{
- return __terminate_set_func (func);
-}
-
-std::unexpected_handler
-std::set_unexpected (std::unexpected_handler func) throw()
-{
- std::unexpected_handler old = __unexpected_func;
-
- __unexpected_func = func;
- return old;
-}
-
-void
-std::unexpected ()
-{
- __unexpected_func ();
-}
-
-/* Language-specific EH info pointer, defined in libgcc2. */
-extern "C" cp_eh_info **__get_eh_info (); // actually void **
-#define CP_EH_INFO ((cp_eh_info *) *__get_eh_info ())
-
-/* Exception allocate and free, defined in libgcc2. */
-extern "C" void *__eh_alloc(std::size_t);
-extern "C" void __eh_free(void *);
-
-/* Is P the type_info node for a pointer of some kind? */
-extern bool __is_pointer (void *);
-
-
-#ifdef __EXCEPTIONS
-/* OLD Compiler hook to return a pointer to the info for the current exception.
- Used by get_eh_info (). This fudges the actualy returned value to
- point to the beginning of what USE to be the cp_eh_info structure.
- THis is so that old code that dereferences this pointer will find
- things where it expects it to be.*/
-extern "C" void *
-__cp_exception_info (void)
-{
- return &((*__get_eh_info ())->value);
-}
-
-/* Old Compiler hook to return a pointer to the info for the current exception.
- Used by get_eh_info (). */
-
-extern "C" cp_eh_info *
-__cp_eh_info (void)
-{
- cp_eh_info *p = CP_EH_INFO;
- return p;
-}
-
-/* Compiler hook to return a pointer to the info for the current exception,
- Set the caught bit, and increment the number of handlers that are
- looking at this exception. This makes handlers smaller. */
-
-extern "C" cp_eh_info *
-__start_cp_handler (void)
-{
- cp_eh_info *p = CP_EH_INFO;
- p->caught = 1;
- p->handlers++;
- return p;
-}
-
-extern "C" int __throw_type_match_rtti_2 (const void *, const void *,
- void *, void **);
-
-extern "C" void *
-__cplus_type_matcher (__eh_info *info_, void *match_info,
- exception_descriptor *exception_table)
-{
- cp_eh_info *info = (cp_eh_info *)info_;
-
- /* No exception table implies the old style mechanism, so don't check. */
- if (exception_table != NULL
- && exception_table->lang.language != EH_LANG_C_plus_plus)
- return NULL;
-
- if (match_info == CATCH_ALL_TYPE)
- return (void *)1;
-
- /* we don't worry about version info yet, there is only one version! */
-
- void *match_type = match_info;
-
- if (__throw_type_match_rtti_2 (match_type, info->type,
- info->original_value, &info->value))
- // Arbitrary non-null pointer.
- return (void *)1;
- else
- return NULL;
-}
-
-/* Compiler hook to push a new exception onto the stack.
- Used by expand_throw(). */
-
-extern "C" void
-__cp_push_exception (void *value, void *type, cleanup_fn cleanup)
-{
- cp_eh_info *p = (cp_eh_info *) __eh_alloc (sizeof (cp_eh_info));
-
- p->value = value;
- p->type = type;
- p->cleanup = cleanup;
- p->handlers = 0;
- p->caught = false;
- p->original_value = value;
-
- p->eh_info.match_function = __cplus_type_matcher;
- p->eh_info.language = EH_LANG_C_plus_plus;
- p->eh_info.version = 1;
-
- cp_eh_info **q = __get_eh_info ();
-
- p->next = *q;
- *q = p;
-}
-
-/* Compiler hook to pop an exception that has been finalized. Used by
- push_eh_cleanup(). P is the info for the exception caught by the
- current catch block. */
-
-extern "C" void
-__cp_pop_exception (void* p_)
-{
- cp_eh_info *p = static_cast <cp_eh_info *> (p_);
- cp_eh_info **stack = __get_eh_info ();
- cp_eh_info **q = stack;
-
- --p->handlers;
-
- /* Do nothing if our exception is being rethrown (i.e. if the active
- exception is our exception and it is uncaught). */
- if (p == *q && !p->caught)
- return;
-
- /* Don't really pop if there are still active handlers for our exception;
- rather, push it down past any uncaught exceptions. */
- if (p->handlers != 0)
- {
- if (p == *q && p->next && !p->next->caught)
- {
- q = &(p->next);
- while (1)
- {
- if (*q == 0 || (*q)->caught)
- break;
-
- q = &((*q)->next);
- }
- *stack = p->next;
- p->next = *q;
- *q = p;
- }
- return;
- }
-
- for (; *q; q = &((*q)->next))
- if (*q == p)
- break;
-
- if (! *q)
- terminate ();
-
- *q = p->next;
-
- if (p->cleanup)
- // value may have been adjusted.
- CALL_CLEANUP (p->cleanup, p->original_value);
-
- if (! __is_pointer (p->type))
- __eh_free (p->original_value); // value may have been adjusted.
-
- __eh_free (p);
-}
-
-/* We're doing a rethrow. Find the currently handled exception, mark it
- uncaught, and move it to the top of the EH stack. */
-
-extern "C" cp_eh_info *
-__uncatch_exception (void)
-{
- cp_eh_info **stack = __get_eh_info ();
- cp_eh_info **q = stack;
- cp_eh_info *p;
-
- while (1)
- {
- p = *q;
-
- if (p == 0)
- terminate ();
- if (p->caught)
- break;
-
- q = &(p->next);
- }
-
- if (q != stack)
- {
- *q = p->next;
- p->next = *stack;
- *stack = p;
- }
-
- p->caught = false;
-
- return p;
-}
-
-/* Mark P as caught after we previously marked it as uncaught. */
-
-extern "C" void
-__recatch_exception (cp_eh_info *p)
-{
- p->caught = true;
-}
-
-/* As per [except.unexpected]:
- If an exception is thrown, we check it against the spec. If it doesn't
- match, we call unexpected (). If unexpected () throws, we check that
- exception against the spec. If it doesn't match, if the spec allows
- bad_exception we throw that; otherwise we call terminate ().
-
- The compiler treats an exception spec as a try block with a generic
- handler that just calls this function with a list of the allowed
- exception types, so we have an active exception that can be rethrown.
-
- This function does not return. */
-
-extern "C" void
-__check_eh_spec (int n, const void **spec)
-{
- cp_eh_info *p = CP_EH_INFO;
- void *d;
-
- for (int i = 0; i < n; ++i)
- {
- if (__throw_type_match_rtti_2 (spec[i], p->type, p->value, &d))
- throw;
- }
-
- try
- {
- std::unexpected ();
- }
- catch (...)
- {
- // __exception_info is an artificial var pushed into each catch block.
- if (p != __exception_info)
- {
- p = __exception_info;
- for (int i = 0; i < n; ++i)
- {
- if (__throw_type_match_rtti_2 (spec[i], p->type, p->value, &d))
- throw;
- }
- }
-
- const std::type_info &bad_exc = typeid (std::bad_exception);
- for (int i = 0; i < n; ++i)
- {
- if (__throw_type_match_rtti_2 (spec[i], &bad_exc, p->value, &d))
- throw std::bad_exception ();
- }
-
- terminate ();
- }
-}
-
-/* Special case of the above for throw() specs. */
-
-extern "C" void
-__check_null_eh_spec (void)
-{
- __check_eh_spec (0, 0);
-}
-#endif //__EXCEPTIONS
-
-// Helpers for rtti. Although these don't return, we give them return types so
-// that the type system is not broken.
-extern "C" void *
-__cxa_bad_cast ()
-{
-#ifdef __EXCEPTIONS
- throw std::bad_cast();
-#else
- std::abort();
-#endif
- return 0;
-}
-
-extern "C" std::type_info const &
-__cxa_bad_typeid ()
-{
-#ifdef __EXCEPTIONS
- throw std::bad_typeid();
-#else
- std::abort();
-#endif
- return typeid (void);
-}
-
-/* Has the current exception been caught? */
-bool
-std::uncaught_exception() throw()
-{
- cp_eh_info *p = CP_EH_INFO;
- return p && ! p->caught;
-}
-
-std::exception::~exception() throw() { }
-
-std::bad_exception::~bad_exception() throw() { }
-
-const char*
-std::exception::what() const throw()
-{ return typeid (*this).name (); }
-
-
-
-
diff --git a/libstdc++-v3/libsupc++/exception_support.h b/libstdc++-v3/libsupc++/exception_support.h
deleted file mode 100644
index cc78119..0000000
--- a/libstdc++-v3/libsupc++/exception_support.h
+++ /dev/null
@@ -1,65 +0,0 @@
-// Copyright (C) 2000 Free Software Foundation, Inc.
-//
-// 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 "gansidecl.h" /* Needed to support macros used in eh-common.h. */
-#include "eh-common.h"
-
-/* The type of a function called to clean up an exception object.
- (These will be destructors.) Under the old ABI, these take a
- second argument (the `in-charge' argument), that indicates whether
- or not do delete the object, and whether or not to destroy virtual
- bases. Under the new ABI, there is no second argument. */
-#if !defined (__GXX_ABI_VERSION) || __GXX_ABI_VERSION < 100
-typedef void (*cleanup_fn)(void *, int);
-/* The `2' is the value for the in-charge parameter that indicates
- that virtual bases should be destroyed. */
-#define CALL_CLEANUP(FN, THIS) FN (THIS, 2)
-#else
-typedef void (*cleanup_fn)(void *);
-#define CALL_CLEANUP(FN, THIS) FN (THIS)
-#endif
-
-/* C++-specific state about the current exception. This must match
- init_exception_processing().
-
- Note that handlers and caught are not redundant; when rethrown, an
- exception can have multiple active handlers and still be considered
- uncaught. */
-
-struct cp_eh_info
-{
- __eh_info eh_info;
- void *value;
- void *type;
- cleanup_fn cleanup;
- bool caught;
- cp_eh_info *next;
- long handlers;
- void *original_value;
-};
-
-extern "C" cp_eh_info *__uncatch_exception (void);
-extern "C" void __recatch_exception (cp_eh_info *);
diff --git a/libstdc++-v3/libsupc++/pure.cc b/libstdc++-v3/libsupc++/pure.cc
index 7373cd1..5f9b3c8 100644
--- a/libstdc++-v3/libsupc++/pure.cc
+++ b/libstdc++-v3/libsupc++/pure.cc
@@ -28,6 +28,7 @@
// the GNU General Public License.
#include <bits/c++config.h>
+#include "unwind-cxx.h"
#ifdef _GLIBCPP_HAVE_UNISTD_H
# include <unistd.h>
@@ -42,15 +43,9 @@
# define writestr(str) fputs(str, stderr)
#endif
-extern "C" {
-
-extern void __terminate(void) __attribute__ ((__noreturn__));
-
-void
+extern "C" void
__cxa_pure_virtual (void)
{
writestr ("pure virtual method called\n");
- __terminate ();
-}
-
+ std::terminate ();
}
diff --git a/libstdc++-v3/libsupc++/tinfo2.cc b/libstdc++-v3/libsupc++/tinfo2.cc
index a29d1d3..8f3d631 100644
--- a/libstdc++-v3/libsupc++/tinfo2.cc
+++ b/libstdc++-v3/libsupc++/tinfo2.cc
@@ -165,31 +165,3 @@ __pointer_catch (const __pbase_type_info *thr_type,
}
} // 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 ();
-}
-
diff --git a/libstdc++-v3/libsupc++/unwind-cxx.h b/libstdc++-v3/libsupc++/unwind-cxx.h
new file mode 100644
index 0000000..ce897b9
--- /dev/null
+++ b/libstdc++-v3/libsupc++/unwind-cxx.h
@@ -0,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
diff --git a/libstdc++-v3/libsupc++/vec.cc b/libstdc++-v3/libsupc++/vec.cc
index 037d052..5bd8ec8 100644
--- a/libstdc++-v3/libsupc++/vec.cc
+++ b/libstdc++-v3/libsupc++/vec.cc
@@ -35,7 +35,7 @@
#include <exception>
#include <exception_defines.h>
-#include "exception_support.h"
+#include "unwind-cxx.h"
namespace __cxxabiv1
{
@@ -43,11 +43,21 @@ namespace __cxxabiv1
{
struct uncatch_exception
{
- uncatch_exception () { p = __uncatch_exception (); }
- ~uncatch_exception () { __recatch_exception (p); }
+ uncatch_exception ();
+ ~uncatch_exception () { __cxa_begin_catch (&p->unwindHeader); }
- cp_eh_info *p;
+ __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.