This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
libgo patch committed: Work around LLVM split-stack deficiency
- From: Ian Lance Taylor <iant at google dot com>
- To: gcc-patches at gcc dot gnu dot org, gofrontend-dev at googlegroups dot com
- Date: Wed, 28 May 2014 17:03:31 -0700
- Subject: libgo patch committed: Work around LLVM split-stack deficiency
- Authentication-results: sourceware.org; auth=none
This patch from Peter Collingbourne tweaks libgo to work around a
deficiency in the LLVM split-stack implementation: it doesn't support
varargs functions. This is a step toward making it possible to compile
libgo with LLVM. Bootstrapped and ran Go testsuite on
x86_64-unknown-linux-gnu. Committed to mainline.
Ian
diff -r 445501e362dd libgo/runtime/print.c
--- a/libgo/runtime/print.c Wed May 28 16:10:26 2014 -0700
+++ b/libgo/runtime/print.c Wed May 28 16:47:30 2014 -0700
@@ -11,7 +11,9 @@
//static Lock debuglock;
-static void go_vprintf(const char*, va_list);
+// Clang requires this function to not be inlined (see below).
+static void go_vprintf(const char*, va_list)
+__attribute__((noinline));
// write to goroutine-local buffer if diverting output,
// or else standard error.
@@ -61,6 +63,24 @@
gwrite(s, runtime_findnull((const byte*)s));
}
+#if defined (__clang__) && (defined (__i386__) || defined (__x86_64__))
+// LLVM's code generator does not currently support split stacks for vararg
+// functions, so we disable the feature for this function under Clang. This
+// appears to be OK as long as:
+// - this function only calls non-inlined, internal-linkage (hence no dynamic
+// loader) functions compiled with split stacks (i.e. go_vprintf), which can
+// allocate more stack space as required;
+// - this function itself does not occupy more than BACKOFF bytes of stack space
+// (see libgcc/config/i386/morestack.S).
+// These conditions are currently known to be satisfied by Clang on x86-32 and
+// x86-64. Note that signal handlers receive slightly less stack space than they
+// would normally do if they happen to be called while this function is being
+// run. If this turns out to be a problem we could consider increasing BACKOFF.
+void
+runtime_printf(const char *s, ...)
+__attribute__((no_split_stack));
+#endif
+
void
runtime_printf(const char *s, ...)
{