Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 25 Jul 2016 14:16:28 +0000 (UTC)
From:      Ed Maste <emaste@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org
Subject:   svn commit: r303292 - stable/11/contrib/libcxxrt
Message-ID:  <201607251416.u6PEGSts038882@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: emaste
Date: Mon Jul 25 14:16:28 2016
New Revision: 303292
URL: https://svnweb.freebsd.org/changeset/base/303292

Log:
  MFC r303157: 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.
  
  Approved by:	re (gjb)
  Sponsored by:	The FreeBSD Foundation

Modified:
  stable/11/contrib/libcxxrt/exception.cc
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/contrib/libcxxrt/exception.cc
==============================================================================
--- stable/11/contrib/libcxxrt/exception.cc	Mon Jul 25 13:31:18 2016	(r303291)
+++ stable/11/contrib/libcxxrt/exception.cc	Mon Jul 25 14:16:28 2016	(r303292)
@@ -572,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
@@ -580,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);
 }
 
 /**
@@ -617,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)
@@ -644,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);
 }
 
 /**



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