svn commit: r246314 - in head/contrib: gcc/config/arm libstdc++/libsupc++

Andrew Turner andrew at FreeBSD.org
Mon Feb 4 09:28:37 UTC 2013


Author: andrew
Date: Mon Feb  4 09:28:36 2013
New Revision: 246314
URL: http://svnweb.freebsd.org/changeset/base/246314

Log:
  Allow the unwind functions int libgcc_s to interact correctly with libthr.
  
  _Unwind_ForcedUnwind in libgcc_s takes as one of it's parameters a stop
  function to tell it when to stop unwinding. One of the stop function's
  parameters is a _Unwind_Exception_Class. On most architectures this is an
  int64_t, however on ARM EABI the gcc developers have made this a char array
  with 8 items. While both of these take the same space they are passed into
  the stop function differently, an int64_t is passed in in registers r2 and
  r3, while the char[8] is passed in as a pointer to the first item in
  register r2.
  
  Because libthr expects the value to be an int64_t we would get incorrect
  results when it passes a function that take an int64_t but libgcc passes in
  a pointer to a char array including crashing.
  
  The fix is to update libgcc_s to make it pass an int64_t to the stop
  function and to libstdc++ as it expects _Unwind_Exception_Class to be an
  array.

Modified:
  head/contrib/gcc/config/arm/unwind-arm.h
  head/contrib/libstdc++/libsupc++/unwind-cxx.h

Modified: head/contrib/gcc/config/arm/unwind-arm.h
==============================================================================
--- head/contrib/gcc/config/arm/unwind-arm.h	Mon Feb  4 08:53:51 2013	(r246313)
+++ head/contrib/gcc/config/arm/unwind-arm.h	Mon Feb  4 09:28:36 2013	(r246314)
@@ -87,7 +87,7 @@ extern "C" {
 
   struct _Unwind_Control_Block
     {
-      char exception_class[8];
+      unsigned  exception_class __attribute__((__mode__(__DI__)));
       void (*exception_cleanup)(_Unwind_Reason_Code, _Unwind_Control_Block *);
       /* Unwinder cache, private fields for the unwinder's use */
       struct
@@ -186,7 +186,7 @@ extern "C" {
 
   /* Support functions for the PR.  */
 #define _Unwind_Exception _Unwind_Control_Block
-  typedef char _Unwind_Exception_Class[8];
+  typedef unsigned _Unwind_Exception_Class __attribute__((__mode__(__DI__)));
 
   void * _Unwind_GetLanguageSpecificData (_Unwind_Context *);
   _Unwind_Ptr _Unwind_GetRegionStart (_Unwind_Context *);

Modified: head/contrib/libstdc++/libsupc++/unwind-cxx.h
==============================================================================
--- head/contrib/libstdc++/libsupc++/unwind-cxx.h	Mon Feb  4 08:53:51 2013	(r246313)
+++ head/contrib/libstdc++/libsupc++/unwind-cxx.h	Mon Feb  4 09:28:36 2013	(r246314)
@@ -173,7 +173,7 @@ __get_exception_header_from_ue (_Unwind_
   return reinterpret_cast<__cxa_exception *>(exc + 1) - 1;
 }
 
-#ifdef __ARM_EABI_UNWINDER__
+#if defined(__ARM_EABI_UNWINDER__) && !defined(__FreeBSD__)
 static inline bool
 __is_gxx_exception_class(_Unwind_Exception_Class c)
 {
@@ -200,13 +200,7 @@ __GXX_INIT_EXCEPTION_CLASS(_Unwind_Excep
   c[6] = '+';
   c[7] = '\0';
 }
-
-static inline void*
-__gxx_caught_object(_Unwind_Exception* eo)
-{
-  return (void*)eo->barrier_cache.bitpattern[0];
-}
-#else // !__ARM_EABI_UNWINDER__
+#else // !__ARM_EABI_UNWINDER__ || __FreeBSD__
 // This is the exception class we report -- "GNUCC++\0".
 const _Unwind_Exception_Class __gxx_exception_class
 = ((((((((_Unwind_Exception_Class) 'G' 
@@ -223,8 +217,16 @@ __is_gxx_exception_class(_Unwind_Excepti
 {
   return c == __gxx_exception_class;
 }
-
 #define __GXX_INIT_EXCEPTION_CLASS(c) c = __gxx_exception_class
+#endif
+
+#ifdef __ARM_EABI_UNWINDER__
+static inline void*
+__gxx_caught_object(_Unwind_Exception* eo)
+{
+  return (void*)eo->barrier_cache.bitpattern[0];
+}
+#else // !__ARM_EABI_UNWINDER__
 
 // GNU C++ personality routine, Version 0.
 extern "C" _Unwind_Reason_Code __gxx_personality_v0


More information about the svn-src-head mailing list