svn commit: r315965 - in stable/10: contrib/libcxxrt lib/libcxxrt

Dimitry Andric dim at FreeBSD.org
Sat Mar 25 21:46:04 UTC 2017


Author: dim
Date: Sat Mar 25 21:46:02 2017
New Revision: 315965
URL: https://svnweb.freebsd.org/changeset/base/315965

Log:
  Synchronize libcxxrt in stable/10 with stable/11.
  
  MFC r284553 (by emaste):
  
  Update libcxxrt upgrade instructions
  
  The typeinfo file no longer exists upstream.
  
  MFC r297299:
  
  Compile libcxxrt as C++11, since it is only really used in combination
  with libc++, which is also C++11.  Also change one _Static_assert (which
  is really C11) back into static_assert, like upstream.
  
  This should help when compiling libcxxrt with newer versions of gcc,
  which refuse to recognize any form of static assertions, if not
  compiling for C++11 or higher.
  
  While here, add -nostdinc++ to CFLAGS, to prevent picking up any C++
  headers outside the source tree.
  
  MFC r299144:
  
  Import libcxxrt master 516a65c109eb0a01e5e95fbef455eb3215135cef.
  
  Interesting fixes:
  3adaa2e Fix _Unwind_Exception cleanup functions
  286776c Check exception cleanup function ptr before calling
  edda626 Correct exception specifications on new and delete operators
  
  MFC r303157 (by emaste):
  
  libcxxrt: add padding in __cxa_allocate_* to fix alignment
  
  The addition of the referenceCount to __cxa_allocate_exception put the
  unwindHeader at offset 0x58 in __cxa_exception, but it requires 16-byte
  alignment. In order to avoid changing the current __cxa_exception ABI
  (and thus breaking its consumers), add explicit padding in the
  allocation routines (and account for it when freeing).
  
  This is intended as a lower-risk change for FreeBSD 11. A "more correct"
  fix should be prepared for upstream and -CURRENT.
  
  Reviewed by:	dim
  Sponsored by:	The FreeBSD Foundation
  Differential Revision:	https://reviews.freebsd.org/D7271
  
  MFC r305396:
  
  Add _US_ACTION_MASK to libcxxrt's arm-specific unwind header.  This
  value is used in newer versions of compiler-rt.

Modified:
  stable/10/contrib/libcxxrt/FREEBSD-upgrade
  stable/10/contrib/libcxxrt/exception.cc
  stable/10/contrib/libcxxrt/guard.cc
  stable/10/contrib/libcxxrt/memory.cc
  stable/10/contrib/libcxxrt/unwind-arm.h
  stable/10/lib/libcxxrt/Makefile
  stable/10/lib/libcxxrt/Version.map
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/contrib/libcxxrt/FREEBSD-upgrade
==============================================================================
--- stable/10/contrib/libcxxrt/FREEBSD-upgrade	Sat Mar 25 21:33:48 2017	(r315964)
+++ stable/10/contrib/libcxxrt/FREEBSD-upgrade	Sat Mar 25 21:46:02 2017	(r315965)
@@ -3,4 +3,4 @@ $FreeBSD$
 This is the FreeBSD copy of libcxxrt.  It contains the src directory from the 
 upstream repository.
 
-When updating, copy *.{c,cc,h} and typeinfo from the upstream src/.
+When updating, copy *.{c,cc,h} from the upstream src/.

Modified: stable/10/contrib/libcxxrt/exception.cc
==============================================================================
--- stable/10/contrib/libcxxrt/exception.cc	Sat Mar 25 21:33:48 2017	(r315964)
+++ stable/10/contrib/libcxxrt/exception.cc	Sat Mar 25 21:46:02 2017	(r315965)
@@ -304,13 +304,17 @@ static pthread_key_t eh_key;
 static void exception_cleanup(_Unwind_Reason_Code reason, 
                               struct _Unwind_Exception *ex)
 {
-	__cxa_free_exception(static_cast<void*>(ex));
+	// Exception layout:
+	// [__cxa_exception [_Unwind_Exception]] [exception object]
+	//
+	// __cxa_free_exception expects a pointer to the exception object
+	__cxa_free_exception(static_cast<void*>(ex + 1));
 }
 static void dependent_exception_cleanup(_Unwind_Reason_Code reason, 
                               struct _Unwind_Exception *ex)
 {
 
-	__cxa_free_dependent_exception(static_cast<void*>(ex));
+	__cxa_free_dependent_exception(static_cast<void*>(ex + 1));
 }
 
 /**
@@ -340,7 +344,8 @@ static void thread_cleanup(void* thread_
 		if (info->foreign_exception_state != __cxa_thread_info::none)
 		{
 			_Unwind_Exception *e = reinterpret_cast<_Unwind_Exception*>(info->globals.caughtExceptions);
-			e->exception_cleanup(_URC_FOREIGN_EXCEPTION_CAUGHT, e);
+			if (e->exception_cleanup)
+				e->exception_cleanup(_URC_FOREIGN_EXCEPTION_CAUGHT, e);
 		}
 		else
 		{
@@ -567,6 +572,19 @@ static void free_exception(char *e)
 	}
 }
 
+#ifdef __LP64__
+/**
+ * There's an ABI bug in __cxa_exception: unwindHeader requires 16-byte
+ * alignment but it was broken by the addition of the referenceCount.
+ * The unwindHeader is at offset 0x58 in __cxa_exception.  In order to keep
+ * compatibility with consumers of the broken __cxa_exception, explicitly add
+ * padding on allocation (and account for it on free).
+ */
+static const int exception_alignment_padding = 8;
+#else
+static const int exception_alignment_padding = 0;
+#endif
+
 /**
  * Allocates an exception structure.  Returns a pointer to the space that can
  * be used to store an object of thrown_size bytes.  This function will use an
@@ -575,16 +593,19 @@ static void free_exception(char *e)
  */
 extern "C" void *__cxa_allocate_exception(size_t thrown_size)
 {
-	size_t size = thrown_size + sizeof(__cxa_exception);
+	size_t size = exception_alignment_padding + sizeof(__cxa_exception) +
+	    thrown_size;
 	char *buffer = alloc_or_die(size);
-	return buffer+sizeof(__cxa_exception);
+	return buffer + exception_alignment_padding + sizeof(__cxa_exception);
 }
 
 extern "C" void *__cxa_allocate_dependent_exception(void)
 {
-	size_t size = sizeof(__cxa_dependent_exception);
+	size_t size = exception_alignment_padding +
+	    sizeof(__cxa_dependent_exception);
 	char *buffer = alloc_or_die(size);
-	return buffer+sizeof(__cxa_dependent_exception);
+	return buffer + exception_alignment_padding +
+	    sizeof(__cxa_dependent_exception);
 }
 
 /**
@@ -612,7 +633,8 @@ extern "C" void __cxa_free_exception(voi
 		}
 	}
 
-	free_exception(reinterpret_cast<char*>(ex));
+	free_exception(reinterpret_cast<char*>(ex) -
+	    exception_alignment_padding);
 }
 
 static void releaseException(__cxa_exception *exception)
@@ -639,7 +661,8 @@ void __cxa_free_dependent_exception(void
 	{
 		releaseException(realExceptionFromException(reinterpret_cast<__cxa_exception*>(ex)));
 	}
-	free_exception(reinterpret_cast<char*>(ex));
+	free_exception(reinterpret_cast<char*>(ex) -
+	    exception_alignment_padding);
 }
 
 /**
@@ -1282,12 +1305,13 @@ extern "C" void __cxa_end_catch()
 	
 	if (ti->foreign_exception_state != __cxa_thread_info::none)
 	{
-		globals->caughtExceptions = 0;
 		if (ti->foreign_exception_state != __cxa_thread_info::rethrown)
 		{
 			_Unwind_Exception *e = reinterpret_cast<_Unwind_Exception*>(ti->globals.caughtExceptions);
-			e->exception_cleanup(_URC_FOREIGN_EXCEPTION_CAUGHT, e);
+			if (e->exception_cleanup)
+				e->exception_cleanup(_URC_FOREIGN_EXCEPTION_CAUGHT, e);
 		}
+		globals->caughtExceptions = 0;
 		ti->foreign_exception_state = __cxa_thread_info::none;
 		return;
 	}
@@ -1474,6 +1498,15 @@ namespace std
 		return info->globals.uncaughtExceptions != 0;
 	}
 	/**
+	 * Returns the number of exceptions currently being thrown that have not
+	 * been caught.  This can occur inside a nested catch statement.
+	 */
+	int uncaught_exceptions() throw()
+	{
+		__cxa_thread_info *info = thread_info();
+		return info->globals.uncaughtExceptions;
+	}
+	/**
 	 * Returns the current unexpected handler.
 	 */
 	unexpected_handler get_unexpected() throw()

Modified: stable/10/contrib/libcxxrt/guard.cc
==============================================================================
--- stable/10/contrib/libcxxrt/guard.cc	Sat Mar 25 21:33:48 2017	(r315964)
+++ stable/10/contrib/libcxxrt/guard.cc	Sat Mar 25 21:46:02 2017	(r315965)
@@ -101,7 +101,7 @@ typedef struct {
 	uint32_t init_half;
 	uint32_t lock_half;
 } guard_t;
-_Static_assert(sizeof(guard_t) == sizeof(uint64_t), "");
+static_assert(sizeof(guard_t) == sizeof(uint64_t), "");
 static const uint32_t LOCKED = 1;
 static const uint32_t INITIALISED = static_cast<guard_lock_t>(1) << 24;
 #	endif

Modified: stable/10/contrib/libcxxrt/memory.cc
==============================================================================
--- stable/10/contrib/libcxxrt/memory.cc	Sat Mar 25 21:33:48 2017	(r315964)
+++ stable/10/contrib/libcxxrt/memory.cc	Sat Mar 25 21:46:02 2017	(r315965)
@@ -71,8 +71,17 @@ namespace std
 }
 
 
+#if __cplusplus < 201103L
+#define NOEXCEPT throw()
+#define BADALLOC throw(std::bad_alloc)
+#else
+#define NOEXCEPT noexcept
+#define BADALLOC
+#endif
+
+
 __attribute__((weak))
-void* operator new(size_t size)
+void* operator new(size_t size) BADALLOC
 {
 	if (0 == size)
 	{
@@ -97,7 +106,7 @@ void* operator new(size_t size)
 }
 
 __attribute__((weak))
-void* operator new(size_t size, const std::nothrow_t &) throw()
+void* operator new(size_t size, const std::nothrow_t &) NOEXCEPT
 {
 	try {
 		return :: operator new(size);
@@ -110,27 +119,21 @@ void* operator new(size_t size, const st
 
 
 __attribute__((weak))
-void operator delete(void * ptr)
-#if __cplusplus < 201000L
-throw()
-#endif
+void operator delete(void * ptr) NOEXCEPT
 {
 	free(ptr);
 }
 
 
 __attribute__((weak))
-void * operator new[](size_t size)
-#if __cplusplus < 201000L
-throw(std::bad_alloc)
-#endif
+void * operator new[](size_t size) BADALLOC
 {
 	return ::operator new(size);
 }
 
 
 __attribute__((weak))
-void * operator new[](size_t size, const std::nothrow_t &) throw()
+void * operator new[](size_t size, const std::nothrow_t &) NOEXCEPT
 {
 	try {
 		return ::operator new[](size);
@@ -143,10 +146,7 @@ void * operator new[](size_t size, const
 
 
 __attribute__((weak))
-void operator delete[](void * ptr)
-#if __cplusplus < 201000L
-throw()
-#endif
+void operator delete[](void * ptr) NOEXCEPT
 {
 	::operator delete(ptr);
 }

Modified: stable/10/contrib/libcxxrt/unwind-arm.h
==============================================================================
--- stable/10/contrib/libcxxrt/unwind-arm.h	Sat Mar 25 21:33:48 2017	(r315964)
+++ stable/10/contrib/libcxxrt/unwind-arm.h	Sat Mar 25 21:46:02 2017	(r315965)
@@ -28,7 +28,7 @@
 {
 	_URC_OK = 0,                /* operation completed successfully */
 	_URC_FOREIGN_EXCEPTION_CAUGHT = 1,
-    _URC_END_OF_STACK = 5,
+	_URC_END_OF_STACK = 5,
 	_URC_HANDLER_FOUND = 6,
 	_URC_INSTALL_CONTEXT = 7,
 	_URC_CONTINUE_UNWIND = 8,
@@ -43,10 +43,12 @@ typedef uint32_t _Unwind_State;
 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;
+static const _Unwind_State _US_ACTION_MASK           = 3;
 #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
+#	define _US_UNWIND_FRAME_RESUME   2
+#	define _US_ACTION_MASK           3
 #endif
 
 typedef struct _Unwind_Context _Unwind_Context;

Modified: stable/10/lib/libcxxrt/Makefile
==============================================================================
--- stable/10/lib/libcxxrt/Makefile	Sat Mar 25 21:33:48 2017	(r315964)
+++ stable/10/lib/libcxxrt/Makefile	Sat Mar 25 21:46:02 2017	(r315965)
@@ -20,7 +20,10 @@ SRCS+=		libelftc_dem_gnu3.c\
 		guard.cc
 
 WARNS=		0
-CFLAGS+=	-I${SRCDIR}
+CFLAGS+=	-I${SRCDIR} -nostdinc++
+.if empty(CXXFLAGS:M-std=*)
+CXXFLAGS+=	-std=c++11
+.endif
 VERSION_MAP=	${.CURDIR}/Version.map
 
 .include <bsd.lib.mk>

Modified: stable/10/lib/libcxxrt/Version.map
==============================================================================
--- stable/10/lib/libcxxrt/Version.map	Sat Mar 25 21:33:48 2017	(r315964)
+++ stable/10/lib/libcxxrt/Version.map	Sat Mar 25 21:46:02 2017	(r315965)
@@ -377,3 +377,9 @@ GLIBCXX_3.4.9 {
     };
 } GLIBCXX_3.4;
 
+GLIBCXX_3.4.22 {
+    extern "C++" {
+        "std::uncaught_exceptions()";
+    };
+} GLIBCXX_3.4.9;
+


More information about the svn-src-stable-10 mailing list