Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 25 Nov 2011 15:46:25 +0000 (UTC)
From:      David Chisnall <theraven@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-vendor@freebsd.org
Subject:   svn commit: r227972 - vendor/libcxxrt/dist
Message-ID:  <201111251546.pAPFkPmF049388@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: theraven
Date: Fri Nov 25 15:46:25 2011
New Revision: 227972
URL: http://svn.freebsd.org/changeset/base/227972

Log:
  Import the new version of libcxxrt, which grew an extra ARM.
  
  Approved by:	dim (mentor)

Added:
  vendor/libcxxrt/dist/unwind-arm.h
  vendor/libcxxrt/dist/unwind-itanium.h
  vendor/libcxxrt/dist/unwind.h
Modified:
  vendor/libcxxrt/dist/cxxabi.h
  vendor/libcxxrt/dist/dwarf_eh.h
  vendor/libcxxrt/dist/exception.cc
  vendor/libcxxrt/dist/guard.cc

Modified: vendor/libcxxrt/dist/cxxabi.h
==============================================================================
--- vendor/libcxxrt/dist/cxxabi.h	Fri Nov 25 13:34:27 2011	(r227971)
+++ vendor/libcxxrt/dist/cxxabi.h	Fri Nov 25 15:46:25 2011	(r227972)
@@ -1,7 +1,7 @@
 #ifndef __CXXABI_H_
 #define __CXXABI_H_
 #include <stdint.h>
-#include <unwind.h>
+#include "unwind.h"
 namespace std 
 {
 	class type_info;
@@ -87,6 +87,18 @@ struct __cxa_exception
 	 * handler count reaches 0 (which it doesn't with the top bit set).
 	 */
 	int handlerCount;
+#ifdef __arm__
+	/**
+	 * The ARM EH ABI requires the unwind library to keep track of exceptions
+	 * during cleanups.  These support nesting, so we need to keep a list of
+	 * them.
+	 */
+	_Unwind_Exception *nextCleanup;
+	/**
+	 * The number of cleanups that are currently being run on this exception. 
+	 */
+	int cleanupCount;
+#endif
 	/**
 	 * The selector value to be returned when installing the catch handler.
 	 * Used at the call site to determine which catch() block should execute.

Modified: vendor/libcxxrt/dist/dwarf_eh.h
==============================================================================
--- vendor/libcxxrt/dist/dwarf_eh.h	Fri Nov 25 13:34:27 2011	(r227971)
+++ vendor/libcxxrt/dist/dwarf_eh.h	Fri Nov 25 15:46:25 2011	(r227972)
@@ -16,10 +16,10 @@
 // that it doesn't impact the rest of the program.
 #ifndef _GNU_SOURCE
 #	define _GNU_SOURCE 1
-#	include <unwind.h>
+#	include "unwind.h"
 #	undef _GNU_SOURCE
 #else
-#	include <unwind.h>
+#	include "unwind.h"
 #endif
 
 #include <stdint.h>
@@ -340,6 +340,9 @@ static inline struct dwarf_eh_lsda parse
 		lsda.type_table = type_table;
 		//lsda.type_table = (uintptr_t*)(data + v);
 	}
+#if __arm__
+	lsda.type_table_encoding = (DW_EH_PE_pcrel | DW_EH_PE_indirect);
+#endif
 
 	lsda.callsite_encoding = (enum dwarf_data_encoding)(*(data++));
 

Modified: vendor/libcxxrt/dist/exception.cc
==============================================================================
--- vendor/libcxxrt/dist/exception.cc	Fri Nov 25 13:34:27 2011	(r227971)
+++ vendor/libcxxrt/dist/exception.cc	Fri Nov 25 15:46:25 2011	(r227972)
@@ -2,6 +2,7 @@
 #include <dlfcn.h>
 #include <stdio.h>
 #include <string.h>
+#include <stdint.h>
 #include <pthread.h>
 #include "typeinfo.h"
 #include "dwarf_eh.h"
@@ -9,6 +10,66 @@
 
 using namespace ABI_NAMESPACE;
 
+/**
+ * Saves the result of the landing pad that we have found.  For ARM, this is
+ * stored in the generic unwind structure, while on other platforms it is
+ * stored in the C++ exception.
+ */
+static void saveLandingPad(struct _Unwind_Context *context,
+                           struct _Unwind_Exception *ucb,
+                           struct __cxa_exception *ex,
+                           int selector,
+                           dw_eh_ptr_t landingPad)
+{
+#ifdef __arm__
+	// On ARM, we store the saved exception in the generic part of the structure
+	ucb->barrier_cache.sp = _Unwind_GetGR(context, 13);
+	ucb->barrier_cache.bitpattern[1] = (uint32_t)selector;
+	ucb->barrier_cache.bitpattern[3] = (uint32_t)landingPad;
+#endif
+	// Cache the results for the phase 2 unwind, if we found a handler
+	// and this is not a foreign exception.  
+	if (ex)
+	{
+		ex->handlerSwitchValue = selector;
+		ex->catchTemp = landingPad;
+	}
+}
+
+/**
+ * Loads the saved landing pad.  Returns 1 on success, 0 on failure.
+ */
+static int loadLandingPad(struct _Unwind_Context *context,
+                          struct _Unwind_Exception *ucb,
+                          struct __cxa_exception *ex,
+                          unsigned long *selector,
+                          dw_eh_ptr_t *landingPad)
+{
+#ifdef __arm__
+	*selector = ucb->barrier_cache.bitpattern[1];
+	*landingPad = (dw_eh_ptr_t)ucb->barrier_cache.bitpattern[3];
+	return 1;
+#else
+	if (ex)
+	{
+		*selector = ex->handlerSwitchValue;
+		*landingPad = (dw_eh_ptr_t)ex->catchTemp;
+		return 0;
+	}
+	return 0;
+#endif
+}
+
+static inline _Unwind_Reason_Code continueUnwinding(struct _Unwind_Exception *ex,
+                                                    struct _Unwind_Context *context)
+{
+#ifdef __arm__
+	if (__gnu_unwind_frame(ex, context) != _URC_OK) { return _URC_FAILURE; }
+#endif
+	return _URC_CONTINUE_UNWIND;
+}
+
+
 extern "C" void __cxa_free_exception(void *thrown_exception);
 extern "C" void __cxa_free_dependent_exception(void *thrown_exception);
 extern "C" void* __dynamic_cast(const void *sub,
@@ -59,6 +120,10 @@ struct __cxa_thread_info
 	 */
 	int emergencyBuffersHeld;
 	/**
+	 * The exception currently running in a cleanup.
+	 */
+	_Unwind_Exception *currentCleanup;
+	/**
 	 * The public part of this structure, accessible from outside of this
 	 * module.
 	 */
@@ -78,6 +143,10 @@ struct __cxa_dependent_exception
 	terminate_handler terminateHandler;
 	__cxa_exception *nextException;
 	int handlerCount;
+#ifdef __arm__
+	_Unwind_Exception *nextCleanup;
+	int cleanupCount;
+#endif
 	int handlerSwitchValue;
 	const char *actionRecord;
 	const char *languageSpecificData;
@@ -519,9 +588,11 @@ static void report_failure(_Unwind_Reaso
 		case _URC_FATAL_PHASE1_ERROR:
 			fprintf(stderr, "Fatal error during phase 1 unwinding\n");
 			break;
+#ifndef __arm__
 		case _URC_FATAL_PHASE2_ERROR:
 			fprintf(stderr, "Fatal error during phase 2 unwinding\n");
 			break;
+#endif
 		case _URC_END_OF_STACK:
 			fprintf(stderr, "Terminating due to uncaught exception %p", 
 					(void*)thrown_exception);
@@ -696,6 +767,7 @@ static std::type_info *get_type_info_ent
 	// Get the address of the record in the table.
 	dw_eh_ptr_t record = lsda->type_table - 
 		dwarf_size_of_fixed_size_field(lsda->type_table_encoding)*filter;
+	//record -= 4;
 	dw_eh_ptr_t start = record;
 	// Read the value, but it's probably an indirect reference...
 	int64_t offset = read_value(lsda->type_table_encoding, &record);
@@ -709,6 +781,7 @@ static std::type_info *get_type_info_ent
 }
 
 
+
 /**
  * Checks the type signature found in a handler against the type of the thrown
  * object.  If ex is 0 then it is assumed to be a foreign exception and only
@@ -829,9 +902,22 @@ static handler_type check_action_record(
 		}
 		else if (filter < 0 && 0 != ex)
 		{
-			unsigned char *type_index = ((unsigned char*)lsda->type_table - filter - 1);
 			bool matched = false;
 			*selector = filter;
+#ifdef __arm__
+			filter++;
+			std::type_info *handler_type = get_type_info_entry(context, lsda, filter--);
+			while (handler_type)
+			{
+				if (check_type_signature(ex, handler_type, adjustedPtr))
+				{
+					matched = true;
+					break;
+				}
+				handler_type = get_type_info_entry(context, lsda, filter--);
+			}
+#else
+			unsigned char *type_index = ((unsigned char*)lsda->type_table - filter - 1);
 			while (*type_index)
 			{
 				std::type_info *handler_type = get_type_info_entry(context, lsda, *(type_index++));
@@ -844,6 +930,7 @@ static handler_type check_action_record(
 					break;
 				}
 			}
+#endif
 			if (matched) { continue; }
 			// If we don't find an allowed exception spec, we need to install
 			// the context for this action.  The landing pad will then call the
@@ -859,17 +946,32 @@ static handler_type check_action_record(
 	return found;
 }
 
+static void pushCleanupException(_Unwind_Exception *exceptionObject,
+                                 __cxa_exception *ex)
+{
+#ifdef __arm__
+	__cxa_thread_info *info = thread_info_fast();
+	if (ex)
+	{
+		ex->cleanupCount++;
+		if (ex->cleanupCount > 1)
+		{
+			assert(exceptionObject == info->currentCleanup);
+			return;
+		}
+		ex->nextCleanup = info->currentCleanup;
+	}
+	info->currentCleanup = exceptionObject;
+#endif
+}
+
 /**
  * The exception personality function.  This is referenced in the unwinding
  * DWARF metadata and is called by the unwind library for each C++ stack frame
  * containing catch or cleanup code.
  */
-extern "C" _Unwind_Reason_Code  __gxx_personality_v0(int version,
-                                                     _Unwind_Action actions,
-                                                     uint64_t exceptionClass,
-                                                     struct _Unwind_Exception *exceptionObject,
-                                                     struct _Unwind_Context *context)
-{
+extern "C"
+BEGIN_PERSONALITY_FUNCTION(__gxx_personality_v0)
 	// This personality function is for version 1 of the ABI.  If you use it
 	// with a future version of the ABI, it won't know what to do, so it
 	// reports a fatal error and give up before it breaks anything.
@@ -896,7 +998,7 @@ extern "C" _Unwind_Reason_Code  __gxx_pe
 		(unsigned char*)_Unwind_GetLanguageSpecificData(context);
 
 	// No LSDA implies no landing pads - try the next frame
-	if (0 == lsda_addr) { return _URC_CONTINUE_UNWIND; }
+	if (0 == lsda_addr) { return continueUnwinding(exceptionObject, context); }
 
 	// These two variables define how the exception will be handled.
 	dwarf_eh_action action = {0};
@@ -941,15 +1043,14 @@ extern "C" _Unwind_Reason_Code  __gxx_pe
 			// and this is not a foreign exception.
 			if (ex)
 			{
-				ex->handlerSwitchValue = selector;
-				ex->actionRecord = (const char*)action.action_record;
+				saveLandingPad(context, exceptionObject, ex, selector, action.landing_pad);
 				ex->languageSpecificData = (const char*)lsda_addr;
-				ex->catchTemp = action.landing_pad;
+				ex->actionRecord = (const char*)action.action_record;
 				// ex->adjustedPtr is set when finding the action record.
 			}
 			return _URC_HANDLER_FOUND;
 		}
-		return _URC_CONTINUE_UNWIND;
+		return continueUnwinding(exceptionObject, context);
 	}
 
 
@@ -962,11 +1063,12 @@ extern "C" _Unwind_Reason_Code  __gxx_pe
 		// cleanup
 		struct dwarf_eh_lsda lsda = parse_lsda(context, lsda_addr);
 		dwarf_eh_find_callsite(context, &lsda, &action);
-		if (0 == action.landing_pad) { return _URC_CONTINUE_UNWIND; }
+		if (0 == action.landing_pad) { return continueUnwinding(exceptionObject, context); }
 		handler_type found_handler = check_action_record(context, &lsda,
 				action.action_record, realEx, &selector, ex->adjustedPtr);
 		// Ignore handlers this time.
-		if (found_handler != handler_cleanup) { return _URC_CONTINUE_UNWIND; }
+		if (found_handler != handler_cleanup) { return continueUnwinding(exceptionObject, context); }
+		pushCleanupException(exceptionObject, ex);
 	}
 	else if (foreignException)
 	{
@@ -983,9 +1085,8 @@ extern "C" _Unwind_Reason_Code  __gxx_pe
 	else
 	{
 		// Restore the saved info if we saved some last time.
-		action.landing_pad = (dw_eh_ptr_t)ex->catchTemp;
+		loadLandingPad(context, exceptionObject, ex, &selector, &action.landing_pad);
 		ex->catchTemp = 0;
-		selector = (unsigned long)ex->handlerSwitchValue;
 		ex->handlerSwitchValue = 0;
 	}
 
@@ -1063,6 +1164,8 @@ extern "C" void *__cxa_begin_catch(void 
 	return ((char*)exceptionObject + sizeof(_Unwind_Exception));
 }
 
+
+
 /**
  * ABI function called when exiting a catch block.  This will free the current
  * exception if it is no longer referenced in other catch blocks.
@@ -1281,3 +1384,38 @@ namespace std
 		return terminateHandler;
 	}
 }
+#ifdef __arm__
+extern "C" _Unwind_Exception *__cxa_get_cleanup(void)
+{
+	__cxa_thread_info *info = thread_info_fast();
+	_Unwind_Exception *exceptionObject = info->currentCleanup;
+	if (isCXXException(exceptionObject->exception_class))
+	{
+		__cxa_exception *ex =  exceptionFromPointer(exceptionObject);
+		ex->cleanupCount--;
+		if (ex->cleanupCount == 0)
+		{
+			info->currentCleanup = ex->nextCleanup;
+			ex->nextCleanup = 0;
+		}
+	}
+	else
+	{
+		info->currentCleanup = 0;
+	}
+	return exceptionObject;
+}
+
+asm (
+".pushsection .text.__cxa_end_cleanup    \n"
+".global __cxa_end_cleanup               \n"
+".type __cxa_end_cleanup, \"function\"   \n"
+"__cxa_end_cleanup:                      \n"
+"	push {r1, r2, r3, r4}                \n"
+"	bl __cxa_get_cleanup                 \n"
+"	push {r1, r2, r3, r4}                \n"
+"	b _Unwind_Resume                     \n"
+"	bl abort                             \n"
+".popsection                             \n"
+);
+#endif

Modified: vendor/libcxxrt/dist/guard.cc
==============================================================================
--- vendor/libcxxrt/dist/guard.cc	Fri Nov 25 13:34:27 2011	(r227971)
+++ vendor/libcxxrt/dist/guard.cc	Fri Nov 25 15:46:25 2011	(r227972)
@@ -16,6 +16,59 @@
  */
 #include <stdint.h>
 #include <pthread.h>
+#include <assert.h>
+
+#ifdef __arm__
+// ARM ABI - 32-bit guards.
+
+/**
+ * Acquires a lock on a guard, returning 0 if the object has already been
+ * initialised, and 1 if it has not.  If the object is already constructed then
+ * this function just needs to read a byte from memory and return.
+ */
+extern "C" int __cxa_guard_acquire(volatile int32_t *guard_object)
+{
+	if ((1<<31) == *guard_object) { return 0; }
+	// If we can atomically move the value from 0 -> 1, then this is
+	// uninitialised.
+	if (__sync_bool_compare_and_swap(guard_object, 0, 1))
+	{
+		return 1;
+	}
+	// If the value is not 0, some other thread was initialising this.  Spin
+	// until it's finished.
+	while (__sync_bool_compare_and_swap(guard_object, (1<<31), (1<<31)))
+	{
+		// If the other thread aborted, then we grab the lock
+		if (__sync_bool_compare_and_swap(guard_object, 0, 1))
+		{
+			return 1;
+		}
+		sched_yield();
+	}
+	return 0;
+}
+
+/**
+ * Releases the lock without marking the object as initialised.  This function
+ * is called if initialising a static causes an exception to be thrown.
+ */
+extern "C" void __cxa_guard_abort(int32_t *guard_object)
+{
+	assert(__sync_bool_compare_and_swap(guard_object, 1, 0));
+}
+/**
+ * Releases the guard and marks the object as initialised.  This function is
+ * called after successful initialisation of a static.
+ */
+extern "C" void __cxa_guard_release(int32_t *guard_object)
+{
+	assert(__sync_bool_compare_and_swap(guard_object, 1, (1<<31)));
+}
+
+
+#else
+// Itanium ABI: 64-bit guards
 
 /**
  * Returns a pointer to the low 32 bits in a 64-bit value, respecting the
@@ -78,3 +131,4 @@ extern "C" void __cxa_guard_release(int6
 	__cxa_guard_abort(guard_object);
 }
 
+#endif

Added: vendor/libcxxrt/dist/unwind-arm.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ vendor/libcxxrt/dist/unwind-arm.h	Fri Nov 25 15:46:25 2011	(r227972)
@@ -0,0 +1,201 @@
+/**
+ * ARM-specific unwind definitions.  These are taken from the ARM EHABI
+ * specification.
+ */
+ typedef enum
+{
+	_URC_OK = 0,                /* operation completed successfully */
+	_URC_FOREIGN_EXCEPTION_CAUGHT = 1,
+    _URC_END_OF_STACK = 5,
+	_URC_HANDLER_FOUND = 6,
+	_URC_INSTALL_CONTEXT = 7,
+	_URC_CONTINUE_UNWIND = 8,
+	_URC_FAILURE = 9,            /* unspecified failure of some kind */
+	_URC_FATAL_PHASE1_ERROR = _URC_FAILURE
+} _Unwind_Reason_Code;
+
+typedef uint32_t _Unwind_State;
+#ifdef __clang__
+static const _Unwind_State _US_VIRTUAL_UNWIND_FRAME  = 0;
+static const _Unwind_State _US_UNWIND_FRAME_STARTING = 1;
+static const _Unwind_State _US_UNWIND_FRAME_RESUME   = 2;
+#else // GCC fails at knowing what a constant expression is
+#	define _US_VIRTUAL_UNWIND_FRAME  0
+#	define _US_UNWIND_FRAME_STARTING 1
+#	define _US_UNWIND_FRAME_RESUME 2
+#endif
+
+typedef struct _Unwind_Context _Unwind_Context;
+
+typedef uint32_t _Unwind_EHT_Header;
+
+struct _Unwind_Exception
+{
+	uint64_t exception_class;
+	void (*exception_cleanup)(_Unwind_Reason_Code, struct _Unwind_Exception *);
+	/* Unwinder cache, private fields for the unwinder's use */
+	struct
+	{
+		uint32_t reserved1;
+		uint32_t reserved2;
+		uint32_t reserved3;
+		uint32_t reserved4;
+		uint32_t reserved5;
+	/* init reserved1 to 0, then don't touch */
+	} unwinder_cache;
+	/* Propagation barrier cache (valid after phase 1): */
+	struct
+	{
+		uint32_t sp;
+		uint32_t bitpattern[5];
+	} barrier_cache;
+	/* Cleanup cache (preserved over cleanup): */
+	struct
+	{
+		uint32_t bitpattern[4];
+	} cleanup_cache;
+	/* Pr cache (for pr's benefit): */
+	struct
+	{
+		/** function start address */
+		uint32_t fnstart;
+		/** pointer to EHT entry header word */
+		_Unwind_EHT_Header *ehtp;
+		/** additional data */
+		uint32_t additional;
+		uint32_t reserved1;
+	} pr_cache;
+	/** Force alignment of next item to 8-byte boundary */
+	long long int :0;
+};
+
+/* Unwinding functions */
+_Unwind_Reason_Code _Unwind_RaiseException(struct _Unwind_Exception *ucbp);
+void _Unwind_Resume(struct _Unwind_Exception *ucbp);
+void _Unwind_Complete(struct _Unwind_Exception *ucbp);
+void _Unwind_DeleteException(struct _Unwind_Exception *ucbp);
+void *_Unwind_GetLanguageSpecificData(struct _Unwind_Context*);
+
+typedef enum
+{
+	_UVRSR_OK = 0,
+	_UVRSR_NOT_IMPLEMENTED = 1,
+	_UVRSR_FAILED = 2
+} _Unwind_VRS_Result;
+typedef enum
+{
+	_UVRSC_CORE = 0,
+	_UVRSC_VFP = 1,
+	_UVRSC_WMMXD = 3,
+	_UVRSC_WMMXC = 4
+} _Unwind_VRS_RegClass;
+typedef enum
+{
+	_UVRSD_UINT32 = 0,
+	_UVRSD_VFPX = 1,
+	_UVRSD_UINT64 = 3,
+	_UVRSD_FLOAT = 4,
+	_UVRSD_DOUBLE = 5
+} _Unwind_VRS_DataRepresentation;
+
+_Unwind_VRS_Result _Unwind_VRS_Get(_Unwind_Context *context,
+                                   _Unwind_VRS_RegClass regclass,
+                                   uint32_t regno,
+                                   _Unwind_VRS_DataRepresentation representation,
+                                   void *valuep);
+_Unwind_VRS_Result _Unwind_VRS_Set(_Unwind_Context *context,
+                                   _Unwind_VRS_RegClass regclass,
+                                   uint32_t regno,
+                                   _Unwind_VRS_DataRepresentation representation,
+                                   void *valuep);
+
+/* Return the base-address for data references.  */
+extern unsigned long _Unwind_GetDataRelBase(struct _Unwind_Context *);
+
+/* Return the base-address for text references.  */
+extern unsigned long _Unwind_GetTextRelBase(struct _Unwind_Context *);
+extern unsigned long _Unwind_GetRegionStart(struct _Unwind_Context *);
+
+typedef _Unwind_Reason_Code (*_Unwind_Trace_Fn) (struct _Unwind_Context *,
+						 void *);
+extern _Unwind_Reason_Code _Unwind_Backtrace (_Unwind_Trace_Fn, void *);
+extern _Unwind_Reason_Code
+	  _Unwind_Resume_or_Rethrow (struct _Unwind_Exception *);
+
+/**
+ * The next set of functions are compatibility extensions, implementing Itanium
+ * ABI functions on top of ARM ones.
+ */
+
+#define _UA_SEARCH_PHASE	1
+#define _UA_CLEANUP_PHASE	2
+#define _UA_HANDLER_FRAME	4
+#define _UA_FORCE_UNWIND	8
+
+static inline unsigned long _Unwind_GetGR(struct _Unwind_Context *context, int reg)
+{
+	unsigned long val;
+	_Unwind_VRS_Get(context, _UVRSC_CORE, reg, _UVRSD_UINT32, &val);
+	return val;
+}
+static inline  void _Unwind_SetGR(struct _Unwind_Context *context, int reg, unsigned long val)
+{
+	_Unwind_VRS_Set(context, _UVRSC_CORE, reg, _UVRSD_UINT32, &val);
+}
+static inline unsigned long _Unwind_GetIP(_Unwind_Context *context)
+{
+	// Low bit store the thumb state - discard it
+	return _Unwind_GetGR(context, 15) & ~1;
+}
+static inline void _Unwind_SetIP(_Unwind_Context *context, unsigned long val)
+{
+	// The lowest bit of the instruction pointer indicates whether we're in
+	// thumb or ARM mode.  This is assumed to be fixed throughout a function,
+	// so must be propagated when setting the program counter.
+	unsigned long thumbState = _Unwind_GetGR(context, 15) & 1;
+   _Unwind_SetGR(context, 15, (val | thumbState));
+}
+
+/** GNU API function that unwinds the frame */
+_Unwind_Reason_Code __gnu_unwind_frame(struct _Unwind_Exception*, struct _Unwind_Context*);
+
+
+#define DECLARE_PERSONALITY_FUNCTION(name) \
+_Unwind_Reason_Code name(_Unwind_State state,\
+                         struct _Unwind_Exception *exceptionObject,\
+                         struct _Unwind_Context *context);
+
+#define BEGIN_PERSONALITY_FUNCTION(name) \
+_Unwind_Reason_Code name(_Unwind_State state,\
+                         struct _Unwind_Exception *exceptionObject,\
+                         struct _Unwind_Context *context)\
+{\
+	int version = 1;\
+	uint64_t exceptionClass = exceptionObject->exception_class;\
+	int actions;\
+	switch (state)\
+	{\
+		default: return _URC_FAILURE;\
+		case _US_VIRTUAL_UNWIND_FRAME:\
+		{\
+			actions = _UA_SEARCH_PHASE;\
+			break;\
+		}\
+		case _US_UNWIND_FRAME_STARTING:\
+		{\
+			actions = _UA_CLEANUP_PHASE;\
+			if (exceptionObject->barrier_cache.sp == _Unwind_GetGR(context, 13))\
+			{\
+				actions |= _UA_HANDLER_FRAME;\
+			}\
+			break;\
+		}\
+		case _US_UNWIND_FRAME_RESUME:\
+		{\
+			return continueUnwinding(exceptionObject, context);\
+			break;\
+		}\
+	}\
+	_Unwind_SetGR (context, 12, (unsigned long)exceptionObject);\
+
+#define CALL_PERSONALITY_FUNCTION(name) name(state,exceptionObject,context)

Added: vendor/libcxxrt/dist/unwind-itanium.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ vendor/libcxxrt/dist/unwind-itanium.h	Fri Nov 25 15:46:25 2011	(r227972)
@@ -0,0 +1,170 @@
+/* libunwind - a platform-independent unwind library
+   Copyright (C) 2003 Hewlett-Packard Co
+	Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
+
+This file is part of libunwind.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
+
+#ifndef _UNWIND_H
+#define _UNWIND_H
+
+/* For uint64_t */
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Minimal interface as per C++ ABI draft standard:
+
+	http://www.codesourcery.com/cxx-abi/abi-eh.html */
+
+typedef enum
+  {
+    _URC_NO_REASON = 0,
+    _URC_FOREIGN_EXCEPTION_CAUGHT = 1,
+    _URC_FATAL_PHASE2_ERROR = 2,
+    _URC_FATAL_PHASE1_ERROR = 3,
+    _URC_NORMAL_STOP = 4,
+    _URC_END_OF_STACK = 5,
+    _URC_HANDLER_FOUND = 6,
+    _URC_INSTALL_CONTEXT = 7,
+    _URC_CONTINUE_UNWIND = 8
+  }
+_Unwind_Reason_Code;
+
+typedef int _Unwind_Action;
+
+#define _UA_SEARCH_PHASE	1
+#define _UA_CLEANUP_PHASE	2
+#define _UA_HANDLER_FRAME	4
+#define _UA_FORCE_UNWIND	8
+
+struct _Unwind_Context;		/* opaque data-structure */
+struct _Unwind_Exception;	/* forward-declaration */
+
+typedef void (*_Unwind_Exception_Cleanup_Fn) (_Unwind_Reason_Code,
+					      struct _Unwind_Exception *);
+
+typedef _Unwind_Reason_Code (*_Unwind_Stop_Fn) (int, _Unwind_Action,
+						uint64_t,
+						struct _Unwind_Exception *,
+						struct _Unwind_Context *,
+						void *);
+
+/* The C++ ABI requires exception_class, private_1, and private_2 to
+   be of type uint64 and the entire structure to be
+   double-word-aligned. Please note that exception_class stays 64-bit 
+   even on 32-bit machines for gcc compatibility.  */
+struct _Unwind_Exception
+  {
+    uint64_t exception_class;
+    _Unwind_Exception_Cleanup_Fn exception_cleanup;
+    unsigned long private_1;
+    unsigned long private_2;
+  } __attribute__((__aligned__));
+
+extern _Unwind_Reason_Code _Unwind_RaiseException (struct _Unwind_Exception *);
+extern _Unwind_Reason_Code _Unwind_ForcedUnwind (struct _Unwind_Exception *,
+						 _Unwind_Stop_Fn, void *);
+extern void _Unwind_Resume (struct _Unwind_Exception *);
+extern void _Unwind_DeleteException (struct _Unwind_Exception *);
+extern unsigned long _Unwind_GetGR (struct _Unwind_Context *, int);
+extern void _Unwind_SetGR (struct _Unwind_Context *, int, unsigned long);
+extern unsigned long _Unwind_GetIP (struct _Unwind_Context *);
+extern unsigned long _Unwind_GetIPInfo (struct _Unwind_Context *, int *);
+extern void _Unwind_SetIP (struct _Unwind_Context *, unsigned long);
+extern unsigned long _Unwind_GetLanguageSpecificData (struct _Unwind_Context*);
+extern unsigned long _Unwind_GetRegionStart (struct _Unwind_Context *);
+
+#ifdef _GNU_SOURCE
+
+/* Callback for _Unwind_Backtrace().  The backtrace stops immediately
+   if the callback returns any value other than _URC_NO_REASON. */
+typedef _Unwind_Reason_Code (*_Unwind_Trace_Fn) (struct _Unwind_Context *,
+						 void *);
+
+/* See http://gcc.gnu.org/ml/gcc-patches/2001-09/msg00082.html for why
+   _UA_END_OF_STACK exists.  */
+# define _UA_END_OF_STACK	16
+
+/* If the unwind was initiated due to a forced unwind, resume that
+   operation, else re-raise the exception.  This is used by
+   __cxa_rethrow().  */
+extern _Unwind_Reason_Code
+	  _Unwind_Resume_or_Rethrow (struct _Unwind_Exception *);
+
+/* See http://gcc.gnu.org/ml/gcc-patches/2003-09/msg00154.html for why
+   _Unwind_GetBSP() exists.  */
+extern unsigned long _Unwind_GetBSP (struct _Unwind_Context *);
+
+/* Return the "canonical frame address" for the given context.
+   This is used by NPTL... */
+extern unsigned long _Unwind_GetCFA (struct _Unwind_Context *);
+
+/* Return the base-address for data references.  */
+extern unsigned long _Unwind_GetDataRelBase (struct _Unwind_Context *);
+
+/* Return the base-address for text references.  */
+extern unsigned long _Unwind_GetTextRelBase (struct _Unwind_Context *);
+
+/* Call _Unwind_Trace_Fn once for each stack-frame, without doing any
+   cleanup.  The first frame for which the callback is invoked is the
+   one for the caller of _Unwind_Backtrace().  _Unwind_Backtrace()
+   returns _URC_END_OF_STACK when the backtrace stopped due to
+   reaching the end of the call-chain or _URC_FATAL_PHASE1_ERROR if it
+   stops for any other reason.  */
+extern _Unwind_Reason_Code _Unwind_Backtrace (_Unwind_Trace_Fn, void *);
+
+/* Find the start-address of the procedure containing the specified IP
+   or NULL if it cannot be found (e.g., because the function has no
+   unwind info).  Note: there is not necessarily a one-to-one
+   correspondence between source-level functions and procedures: some
+   functions don't have unwind-info and others are split into multiple
+   procedures.  */
+extern void *_Unwind_FindEnclosingFunction (void *);
+
+/* See also Linux Standard Base Spec:
+    http://www.linuxbase.org/spec/refspecs/LSB_1.3.0/gLSB/gLSB/libgcc-s.html */
+
+#endif /* _GNU_SOURCE */
+
+#define DECLARE_PERSONALITY_FUNCTION(name) \
+_Unwind_Reason_Code name(int version,\
+                         _Unwind_Action actions,\
+                         uint64_t exceptionClass,\
+                         struct _Unwind_Exception *exceptionObject,\
+                         struct _Unwind_Context *context);
+#define BEGIN_PERSONALITY_FUNCTION(name) \
+_Unwind_Reason_Code name(int version,\
+                         _Unwind_Action actions,\
+                         uint64_t exceptionClass,\
+                         struct _Unwind_Exception *exceptionObject,\
+                         struct _Unwind_Context *context)\
+{
+
+#define CALL_PERSONALITY_FUNCTION(name) name(version, actions, exceptionClass, exceptionObject, context)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _UNWIND_H */

Added: vendor/libcxxrt/dist/unwind.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ vendor/libcxxrt/dist/unwind.h	Fri Nov 25 15:46:25 2011	(r227972)
@@ -0,0 +1,18 @@
+#ifndef UNWIND_H_INCLUDED
+#define UNWIND_H_INCLUDED
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __arm__
+#include "unwind-arm.h"
+#else
+#include "unwind-itanium.h"
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201111251546.pAPFkPmF049388>