+#include <string.h>
+
+/*
+ * This is a workaround for some slightly silly Linux/GNU Libc
+ * behaviour: glibc defines sigset_t to support 1024 signals, which is
+ * more than the kernel. This is usually not a problem, but becomes
+ * one when we want to save a signal mask from a ucontext, and restore
+ * it later into another ucontext: the ucontext is allocated on the
+ * stack by the kernel, so copying a libc-sized sigset_t into it will
+ * overflow and cause other data on the stack to be corrupted */
+/* FIXME: do not rely on NSIG being a multiple of 8 */
+#define REAL_SIGSET_SIZE_BYTES ((NSIG/8))
+
+extern void check_blockables_blocked_or_lose(void);
+extern void check_gc_signals_unblocked_or_lose(void);
+extern void unblock_gc_signals(void);
+
+static inline void
+sigcopyset(sigset_t *new, sigset_t *old)
+{
+ memcpy(new, old, REAL_SIGSET_SIZE_BYTES);
+}