+
+uint32_t
+get_eflags_exportmask(void)
+{
+ return EFL_USER_SET;
+}
+
+/*
+ * x86_SAVED_STATE32 - internal save/restore general register state on 32/64 bit processors
+ * for 32bit tasks only
+ * x86_SAVED_STATE64 - internal save/restore general register state on 64 bit processors
+ * for 64bit tasks only
+ * x86_THREAD_STATE32 - external set/get general register state on 32/64 bit processors
+ * for 32bit tasks only
+ * x86_THREAD_STATE64 - external set/get general register state on 64 bit processors
+ * for 64bit tasks only
+ * x86_SAVED_STATE - external set/get general register state on 32/64 bit processors
+ * for either 32bit or 64bit tasks
+ * x86_FLOAT_STATE32 - internal/external save/restore float and xmm state on 32/64 bit processors
+ * for 32bit tasks only
+ * x86_FLOAT_STATE64 - internal/external save/restore float and xmm state on 64 bit processors
+ * for 64bit tasks only
+ * x86_FLOAT_STATE - external save/restore float and xmm state on 32/64 bit processors
+ * for either 32bit or 64bit tasks
+ * x86_EXCEPTION_STATE32 - external get exception state on 32/64 bit processors
+ * for 32bit tasks only
+ * x86_EXCEPTION_STATE64 - external get exception state on 64 bit processors
+ * for 64bit tasks only
+ * x86_EXCEPTION_STATE - external get exception state on 323/64 bit processors
+ * for either 32bit or 64bit tasks
+ */
+
+
+static void
+get_exception_state64(thread_t thread, x86_exception_state64_t *es)
+{
+ x86_saved_state64_t *saved_state;
+
+ saved_state = USER_REGS64(thread);
+
+ es->trapno = saved_state->isf.trapno;
+ es->err = saved_state->isf.err;
+ es->faultvaddr = saved_state->cr2;
+}
+
+static void
+get_exception_state32(thread_t thread, x86_exception_state32_t *es)
+{
+ x86_saved_state32_t *saved_state;
+
+ saved_state = USER_REGS32(thread);
+
+ es->trapno = saved_state->trapno;
+ es->err = saved_state->err;
+ es->faultvaddr = saved_state->cr2;
+}
+
+
+static int
+set_thread_state32(thread_t thread, x86_thread_state32_t *ts)
+{
+ x86_saved_state32_t *saved_state;
+
+ saved_state = USER_REGS32(thread);
+
+ saved_state->eax = ts->eax;
+ saved_state->ebx = ts->ebx;
+ saved_state->ecx = ts->ecx;
+ saved_state->edx = ts->edx;
+ saved_state->edi = ts->edi;
+ saved_state->esi = ts->esi;
+ saved_state->ebp = ts->ebp;
+ saved_state->uesp = ts->esp;
+ saved_state->efl = (ts->eflags & ~EFL_USER_CLEAR) | EFL_USER_SET;
+ saved_state->eip = ts->eip;
+ saved_state->cs = ts->cs ? ts->cs : USER_CS;
+ saved_state->ss = ts->ss ? ts->ss : USER_DS;
+ saved_state->ds = ts->ds ? ts->ds : USER_DS;
+ saved_state->es = ts->es ? ts->es : USER_DS;
+ saved_state->fs = ts->fs;
+ saved_state->gs = ts->gs;
+
+ /*
+ * If the trace trap bit is being set,
+ * ensure that the user returns via iret
+ * - which is signaled thusly:
+ */
+ if ((saved_state->efl & EFL_TF) && saved_state->cs == SYSENTER_CS)
+ saved_state->cs = SYSENTER_TF_CS;
+
+ return(KERN_SUCCESS);
+}
+
+static int
+set_thread_state64(thread_t thread, x86_thread_state64_t *ts)
+{
+ x86_saved_state64_t *saved_state;
+
+ saved_state = USER_REGS64(thread);
+
+ if (!IS_USERADDR64_CANONICAL(ts->rsp) ||
+ !IS_USERADDR64_CANONICAL(ts->rip))
+ return(KERN_INVALID_ARGUMENT);
+
+ saved_state->r8 = ts->r8;
+ saved_state->r9 = ts->r9;
+ saved_state->r10 = ts->r10;
+ saved_state->r11 = ts->r11;
+ saved_state->r12 = ts->r12;
+ saved_state->r13 = ts->r13;
+ saved_state->r14 = ts->r14;
+ saved_state->r15 = ts->r15;
+ saved_state->rax = ts->rax;
+ saved_state->rax = ts->rax;
+ saved_state->rbx = ts->rbx;
+ saved_state->rcx = ts->rcx;
+ saved_state->rdx = ts->rdx;
+ saved_state->rdi = ts->rdi;
+ saved_state->rsi = ts->rsi;
+ saved_state->rbp = ts->rbp;
+ saved_state->isf.rsp = ts->rsp;
+ saved_state->isf.rflags = (ts->rflags & ~EFL_USER_CLEAR) | EFL_USER_SET;
+ saved_state->isf.rip = ts->rip;
+ saved_state->isf.cs = USER64_CS;
+ saved_state->fs = ts->fs;
+ saved_state->gs = ts->gs;
+
+ return(KERN_SUCCESS);
+}
+
+
+
+static void
+get_thread_state32(thread_t thread, x86_thread_state32_t *ts)
+{
+ x86_saved_state32_t *saved_state;
+
+ saved_state = USER_REGS32(thread);
+
+ ts->eax = saved_state->eax;
+ ts->ebx = saved_state->ebx;
+ ts->ecx = saved_state->ecx;
+ ts->edx = saved_state->edx;
+ ts->edi = saved_state->edi;
+ ts->esi = saved_state->esi;
+ ts->ebp = saved_state->ebp;
+ ts->esp = saved_state->uesp;
+ ts->eflags = saved_state->efl;
+ ts->eip = saved_state->eip;
+ ts->cs = saved_state->cs;
+ ts->ss = saved_state->ss;
+ ts->ds = saved_state->ds;
+ ts->es = saved_state->es;
+ ts->fs = saved_state->fs;
+ ts->gs = saved_state->gs;
+}
+
+
+static void
+get_thread_state64(thread_t thread, x86_thread_state64_t *ts)
+{
+ x86_saved_state64_t *saved_state;
+
+ saved_state = USER_REGS64(thread);
+
+ ts->r8 = saved_state->r8;
+ ts->r9 = saved_state->r9;
+ ts->r10 = saved_state->r10;
+ ts->r11 = saved_state->r11;
+ ts->r12 = saved_state->r12;
+ ts->r13 = saved_state->r13;
+ ts->r14 = saved_state->r14;
+ ts->r15 = saved_state->r15;
+ ts->rax = saved_state->rax;
+ ts->rbx = saved_state->rbx;
+ ts->rcx = saved_state->rcx;
+ ts->rdx = saved_state->rdx;
+ ts->rdi = saved_state->rdi;
+ ts->rsi = saved_state->rsi;
+ ts->rbp = saved_state->rbp;
+ ts->rsp = saved_state->isf.rsp;
+ ts->rflags = saved_state->isf.rflags;
+ ts->rip = saved_state->isf.rip;
+ ts->cs = saved_state->isf.cs;
+ ts->fs = saved_state->fs;
+ ts->gs = saved_state->gs;
+}
+
+
+