This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[csl-arm] Revise __cxa_type_match
- From: Paul Brook <paul at codesourcery dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Wed, 17 Nov 2004 00:11:04 +0000
- Subject: [csl-arm] Revise __cxa_type_match
- Organization: CodeSourcery
The attached patch revises __cxa_type_match. The existing implementation was
based on an outdated version of the EABI.
The additional parameter is necessary to get some bit of c++ EH semantics
correct. After talking to people who understand g++ better than me, I believe
the new code is no more broken than the old version of the ABI, or g++ on
other targets. Fixing it would require more information that is currently
available in the g++ unwind tables. I'd file a PR, but I can't find the email
with the example.
Tested with cross to arm-none-eabi.
Applied to csl-arm-branch.
Paul
2004-11-16 Paul Brook <paul@codesourcery.com>
* libsupc++/eh_arm.cc: Include cxxabi.h.
(__cxa_type_match): Update prototype. Change return values.
* libsupc++/eh_call.cc (__cxa_call_unexpected): Pass extra argument
to __cxa_type_match.
* libsupc++/eh_personality.cc (get_adjusted_ptr): Ditto.
* libsupc++/unwind-cxx.h (__cxa_type_match_result): Declare.
(__cxa_type_match): Update prototype.
Index: libsupc++/eh_arm.cc
===================================================================
RCS file: /var/cvsroot/gcc-cvs/gcc/libstdc++-v3/libsupc++/Attic/eh_arm.cc,v
retrieving revision 1.1.2.2
diff -u -p -r1.1.2.2 eh_arm.cc
--- libsupc++/eh_arm.cc 29 Sep 2004 16:11:56 -0000 1.1.2.2
+++ libsupc++/eh_arm.cc 16 Nov 2004 20:14:44 -0000
@@ -27,6 +27,7 @@
// invalidate any other reasons why the executable file might be covered by
// the GNU General Public License.
+#include <cxxabi.h>
#include "unwind-cxx.h"
#ifdef __ARM_EABI_UNWINDER__
@@ -39,13 +40,14 @@ using namespace __cxxabiv1;
// compare against, return whether or not there is a match and if so,
// update *THROWN_PTR_P.
-extern "C" bool
+extern "C" __cxa_type_match_result
__cxa_type_match(_Unwind_Exception* ue_header,
const std::type_info* catch_type,
+ bool is_reference __attribute__((unused)),
void** thrown_ptr_p)
{
if (!__is_gxx_exception_class(ue_header->exception_class))
- return false;
+ return ctm_failed;
__cxa_exception* xh = __get_exception_header_from_ue(ue_header);
const std::type_info* throw_type = xh->exceptionType;
@@ -61,10 +63,24 @@ __cxa_type_match(_Unwind_Exception* ue_h
if (catch_type->__do_catch(throw_type, &thrown_ptr, 1))
{
*thrown_ptr_p = thrown_ptr;
- return true;
+
+ if (typeid(*catch_type) == typeid (typeid(void*)))
+ {
+ const __pointer_type_info *catch_pointer_type =
+ static_cast<const __pointer_type_info *> (catch_type);
+ const __pointer_type_info *throw_pointer_type =
+ static_cast<const __pointer_type_info *> (throw_type);
+
+ if (typeid (*catch_pointer_type->__pointee) != typeid (void)
+ && (*catch_pointer_type->__pointee !=
+ *throw_pointer_type->__pointee))
+ return ctm_succeeded_with_ptr_to_base;
+ }
+
+ return ctm_succeeded;
}
- return false;
+ return ctm_failed;
}
extern "C" void
Index: libsupc++/eh_call.cc
===================================================================
RCS file: /var/cvsroot/gcc-cvs/gcc/libstdc++-v3/libsupc++/Attic/eh_call.cc,v
retrieving revision 1.1.2.1
diff -u -p -r1.1.2.1 eh_call.cc
--- libsupc++/eh_call.cc 22 Sep 2004 15:40:33 -0000 1.1.2.1
+++ libsupc++/eh_call.cc 16 Nov 2004 20:25:23 -0000
@@ -136,7 +136,8 @@ __cxa_call_unexpected(void* exc_obj_in)
offset = _Unwind_decode_target2(offset);
catch_type = (const std::type_info*) (offset);
- if (__cxa_type_match(&new_xh->unwindHeader, catch_type, &new_ptr))
+ if (__cxa_type_match(&new_xh->unwindHeader, catch_type, false,
+ &new_ptr) != ctm_failed)
__throw_exception_again;
if (catch_type->__do_catch(&bad_exc, 0, 1))
Index: libsupc++/eh_personality.cc
===================================================================
RCS file: /var/cvsroot/gcc-cvs/gcc/libstdc++-v3/libsupc++/eh_personality.cc,v
retrieving revision 1.13.8.2
diff -u -p -r1.13.8.2 eh_personality.cc
--- libsupc++/eh_personality.cc 22 Sep 2004 15:40:33 -0000 1.13.8.2
+++ libsupc++/eh_personality.cc 16 Nov 2004 20:25:54 -0000
@@ -103,7 +103,8 @@ get_ttype_entry(lsda_header_info* info,
/* The ABI provides a routine for matching exception object types. */
typedef _Unwind_Control_Block _throw_typet;
#define get_adjusted_ptr(catch_type, throw_type, thrown_ptr_p) \
- __cxa_type_match (throw_type, catch_type, thrown_ptr_p)
+ (__cxa_type_match (throw_type, catch_type, false, thrown_ptr_p) \
+ != ctm_failed)
// Return true if THROW_TYPE matches one if the filter types.
Index: libsupc++/unwind-cxx.h
===================================================================
RCS file: /var/cvsroot/gcc-cvs/gcc/libstdc++-v3/libsupc++/unwind-cxx.h,v
retrieving revision 1.6.8.2
diff -u -p -r1.6.8.2 unwind-cxx.h
--- libsupc++/unwind-cxx.h 22 Sep 2004 15:40:33 -0000 1.6.8.2
+++ libsupc++/unwind-cxx.h 16 Nov 2004 17:16:22 -0000
@@ -124,9 +124,14 @@ extern "C" void __cxa_call_unexpected (v
extern "C" void __cxa_call_terminate (void*) __attribute__((noreturn));
#ifdef __ARM_EABI_UNWINDER__
-/* Arm EABI specified routines. */
-extern "C" bool __cxa_type_match (_Unwind_Exception*, const std::type_info*,
- void**);
+// Arm EABI specified routines.
+typedef enum {
+ ctm_failed = 0,
+ ctm_succeeded = 1,
+ ctm_succeeded_with_ptr_to_base = 2
+} __cxa_type_match_result;
+extern "C" bool __cxa_type_match(_Unwind_Exception*, const std::type_info*,
+ bool, void**);
extern "C" void __cxa_begin_cleanup (_Unwind_Exception*);
extern "C" void __cxa_end_cleanup (_Unwind_Exception*);
#endif