+/*
+ * 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 */
+}
+
+