+#include <sys/sdt.h>
+
+// #include <machine/thread.h> XXX include path messed up for some reason...
+
+/* XXX functions not in a Mach headers */
+extern kern_return_t thread_getstatus(register thread_t act, int flavor,
+ thread_state_t tstate, mach_msg_type_number_t *count);
+extern unsigned int get_msr_exportmask(void);
+extern kern_return_t thread_setstatus(thread_t thread, int flavor,
+ thread_state_t tstate, mach_msg_type_number_t count);
+extern void ppc_checkthreadstate(void *, int);
+extern struct savearea_vec *find_user_vec_curr(void);
+extern int thread_enable_fpe(thread_t act, int onoff);
+
+
+
+#define C_32_REDZONE_LEN 224
+#define C_32_STK_ALIGN 16
+#define C_32_PARAMSAVE_LEN 64
+#define C_32_LINKAGE_LEN 48
+
+#define C_64_REDZONE_LEN 320
+#define C_64_STK_ALIGN 32
+#define C_64_PARAMSAVE_LEN 64
+#define C_64_LINKAGE_LEN 48
+
+#define TRUNC_DOWN32(a,b,c) ((((uint32_t)a)-(b)) & ((uint32_t)(-(c))))
+#define TRUNC_DOWN64(a,b,c) ((((uint64_t)a)-(b)) & ((uint64_t)(-(c))))
+
+/*
+ * The stack layout possibilities (info style); This needs to mach with signal trampoline code
+ *
+ * Traditional: 1
+ * Traditional64: 20
+ * Traditional64with vec: 25
+ * 32bit context 30
+ * 32bit context with vector 35
+ * 64bit context 40
+ * 64bit context with vector 45
+ * Dual context 50
+ * Dual context with vector 55
+ *
+ */
+
+#define UC_TRAD 1
+#define UC_TRAD_VEC 6
+#define UC_TRAD64 20
+#define UC_TRAD64_VEC 25
+#define UC_FLAVOR 30
+#define UC_FLAVOR_VEC 35
+#define UC_FLAVOR64 40
+#define UC_FLAVOR64_VEC 45
+#define UC_DUAL 50
+#define UC_DUAL_VEC 55
+#define UC_SET_ALT_STACK 0x40000000
+#define UC_RESET_ALT_STACK 0x80000000
+
+ /* The following are valid mcontext sizes */
+#define UC_FLAVOR_SIZE ((PPC_THREAD_STATE_COUNT + PPC_EXCEPTION_STATE_COUNT + PPC_FLOAT_STATE_COUNT) * sizeof(int))
+
+#define UC_FLAVOR_VEC_SIZE ((PPC_THREAD_STATE_COUNT + PPC_EXCEPTION_STATE_COUNT + PPC_FLOAT_STATE_COUNT + PPC_VECTOR_STATE_COUNT) * sizeof(int))
+
+#define UC_FLAVOR64_SIZE ((PPC_THREAD_STATE64_COUNT + PPC_EXCEPTION_STATE64_COUNT + PPC_FLOAT_STATE_COUNT) * sizeof(int))
+
+#define UC_FLAVOR64_VEC_SIZE ((PPC_THREAD_STATE64_COUNT + PPC_EXCEPTION_STATE64_COUNT + PPC_FLOAT_STATE_COUNT + PPC_VECTOR_STATE_COUNT) * sizeof(int))
+
+
+/*
+ * NOTE: Source and target may *NOT* overlap!
+ */
+static void
+ucontext_32to64(struct ucontext64 *in, struct user_ucontext64 *out)
+{
+ out->uc_onstack = in->uc_onstack;
+ out->uc_sigmask = in->uc_sigmask;
+
+ /* internal "structure assign" */
+ out->uc_stack.ss_sp = CAST_USER_ADDR_T(in->uc_stack.ss_sp);
+ out->uc_stack.ss_size = in->uc_stack.ss_size;
+ out->uc_stack.ss_flags = in->uc_stack.ss_flags;
+
+ out->uc_link = CAST_USER_ADDR_T(in->uc_link);
+ out->uc_mcsize = in->uc_mcsize;
+ out->uc_mcontext64 = CAST_USER_ADDR_T(in->uc_mcontext64);
+}
+
+/*
+ * This conversion is safe, since if we are converting for a 32 bit process,
+ * then it's values of uc-stack.ss_size and uc_mcsize will never exceed 4G.
+ *
+ * NOTE: Source and target may *NOT* overlap!
+ */
+static void
+ucontext_64to32(struct user_ucontext64 *in, struct ucontext64 *out)
+{
+ out->uc_onstack = in->uc_onstack;
+ out->uc_sigmask = in->uc_sigmask;
+
+ /* internal "structure assign" */
+ out->uc_stack.ss_sp = CAST_DOWN(void *,in->uc_stack.ss_sp);
+ out->uc_stack.ss_size = in->uc_stack.ss_size; /* range reduction */
+ out->uc_stack.ss_flags = in->uc_stack.ss_flags;
+
+ out->uc_link = CAST_DOWN(void *,in->uc_link);
+ out->uc_mcsize = in->uc_mcsize; /* range reduction */
+ out->uc_mcontext64 = CAST_DOWN(void *,in->uc_mcontext64);
+}
+
+/*
+ * NOTE: Source and target may *NOT* overlap!
+ */
+static void
+siginfo_64to32(user_siginfo_t *in, siginfo_t *out)
+{
+ out->si_signo = in->si_signo;
+ out->si_errno = in->si_errno;
+ out->si_code = in->si_code;
+ out->si_pid = in->si_pid;
+ out->si_uid = in->si_uid;
+ out->si_status = in->si_status;
+ out->si_addr = CAST_DOWN(void *,in->si_addr);
+ /* following cast works for sival_int because of padding */
+ out->si_value.sival_ptr = CAST_DOWN(void *,in->si_value.sival_ptr);
+ out->si_band = in->si_band; /* range reduction */
+ out->__pad[0] = in->pad[0]; /* mcontext.ss.r1 */
+}
+