Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 10 Jan 2013 23:36:03 +0000 (UTC)
From:      Dimitry Andric <dim@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r245272 - head/contrib/gcc
Message-ID:  <201301102336.r0ANa3IP073947@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: dim
Date: Thu Jan 10 23:36:02 2013
New Revision: 245272
URL: http://svnweb.freebsd.org/changeset/base/245272

Log:
  Add an ugly hack to libgcc's unwind code, to make it behave properly at
  runtime on amd64, when it is compiled by clang.  Some versions of clang
  don't save and restore all callee registers, if a __builtin_eh_return()
  intrinsic is used in a function.  This is particularly bad on amd64.
  
  Until the problem gets fixed by upstream, use an asm statement to force
  clang to assume the registers in question are clobbered, when invoking
  __builtin_eh_return(), so it will emit code to save and restore them.
  
  This should fix the crashes reported on -current with some C++ programs,
  particularly those that throw exceptions over multiple function
  boundaries.
  
  Reported by:	stefanf
  MFC after:	3 days

Modified:
  head/contrib/gcc/unwind-dw2.c

Modified: head/contrib/gcc/unwind-dw2.c
==============================================================================
--- head/contrib/gcc/unwind-dw2.c	Thu Jan 10 23:29:36 2013	(r245271)
+++ head/contrib/gcc/unwind-dw2.c	Thu Jan 10 23:36:02 2013	(r245272)
@@ -1438,6 +1438,17 @@ uw_init_context_1 (struct _Unwind_Contex
   context->ra = __builtin_extract_return_addr (outer_ra);
 }
 
+#if defined(__clang__) && defined(__amd64__)
+/* Some versions of clang don't save and restore all callee registers, if a
+   __builtin_eh_return() intrinsic is used in a function.  This is particularly
+   bad on amd64.  For now, use the following ugly hack to force it to assume
+   those registers are clobbered, when invoking __builtin_eh_return(), so it
+   will emit code to save and restore them.  */
+#define CLOBBER_REGS_HACK \
+  __asm __volatile(" " : : : "r15", "r14", "r13", "r12", "rbx", "rdx", "rax");
+#else
+#define CLOBBER_REGS_HACK
+#endif /* __clang__ */
 
 /* Install TARGET into CURRENT so that we can return to it.  This is a
    macro because __builtin_eh_return must be invoked in the context of
@@ -1448,6 +1459,7 @@ uw_init_context_1 (struct _Unwind_Contex
     {									 \
       long offset = uw_install_context_1 ((CURRENT), (TARGET));		 \
       void *handler = __builtin_frob_return_addr ((TARGET)->ra);	 \
+      CLOBBER_REGS_HACK							 \
       __builtin_eh_return (offset, handler);				 \
     }									 \
   while (0)



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