aboutsummaryrefslogtreecommitdiff
path: root/contrib
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2013-01-10 23:36:02 +0000
committerDimitry Andric <dim@FreeBSD.org>2013-01-10 23:36:02 +0000
commitbfd6a1d202ad233ec77e35f32a525c144928d8cf (patch)
tree23512beea7ab92cc8e5a7f0aa9ccb4e1c895f54c /contrib
parent3da2132e5264c5c027b2d57181de1512417b91ae (diff)
downloadsrc-bfd6a1d202ad233ec77e35f32a525c144928d8cf.tar.gz
src-bfd6a1d202ad233ec77e35f32a525c144928d8cf.zip
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
Notes
Notes: svn path=/head/; revision=245272
Diffstat (limited to 'contrib')
-rw-r--r--contrib/gcc/unwind-dw2.c12
1 files changed, 12 insertions, 0 deletions
diff --git a/contrib/gcc/unwind-dw2.c b/contrib/gcc/unwind-dw2.c
index 62c9d0913158..3306e06b4ef8 100644
--- a/contrib/gcc/unwind-dw2.c
+++ b/contrib/gcc/unwind-dw2.c
@@ -1438,6 +1438,17 @@ uw_init_context_1 (struct _Unwind_Context *context,
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_Context *context,
{ \
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)