From 5cecdfcb3efb1ebf12cfadcdbae524e3958a9211 Mon Sep 17 00:00:00 2001 From: Ben Gras Date: Tue, 10 Dec 2013 14:55:46 +0100 Subject: [PATCH] Change-Id: I2ad64018f3f402e7ccc5c4dc037dd0a3fe56a929 --- kernel/system/do_mcontext.c | 19 +- .../arch/arm/sys-minix/ucontextoffsets.cf | 32 ++-- .../arch/i386/sys-minix/ucontextoffsets.cf | 18 +- lib/libc/sys-minix/_ucontext.c | 40 ++-- lib/libmthread/misc.c | 8 +- sys/arch/arm/include/mcontext.h | 170 +++++++++++++++-- sys/arch/i386/include/mcontext.h | 171 ++++++++++++++++-- sys/sys/ucontext.h | 4 +- 8 files changed, 377 insertions(+), 85 deletions(-) diff --git a/kernel/system/do_mcontext.c b/kernel/system/do_mcontext.c index c72ac6fd7..e5d744901 100644 --- a/kernel/system/do_mcontext.c +++ b/kernel/system/do_mcontext.c @@ -10,6 +10,7 @@ #include "kernel/system.h" #include +#include #include #if USE_MCONTEXT @@ -35,17 +36,18 @@ int do_getmcontext(struct proc * caller, message * m_ptr) /* Get the mcontext structure into our address space. */ if ((r = data_copy(m_ptr->PR_ENDPT, (vir_bytes) m_ptr->PR_CTX_PTR, KERNEL, - (vir_bytes) &mc, (phys_bytes) sizeof(struct __mcontext))) != OK) + (vir_bytes) &mc, (phys_bytes) sizeof(mcontext_t))) != OK) return(r); + mc.mc_flags = 0; #if defined(__i386__) /* Copy FPU state */ - mc.mc_fpu_flags = 0; if (proc_used_fpu(rp)) { /* make sure that the FPU context is saved into proc structure first */ save_fpu(rp); - mc.mc_fpu_flags = rp->p_misc_flags & MF_FPU_INITIALIZED; - memcpy(&(mc.mc_fpu_state), rp->p_seg.fpu_state, FPU_XFP_SIZE); + mc.mc_flags = (rp->p_misc_flags & MF_FPU_INITIALIZED) ? _MC_FPU_SAVED : 0; + assert(sizeof(mc.__fpregs.__fp_reg_set) == FPU_XFP_SIZE); + memcpy(&(mc.__fpregs.__fp_reg_set), rp->p_seg.fpu_state, FPU_XFP_SIZE); } #endif @@ -53,7 +55,7 @@ int do_getmcontext(struct proc * caller, message * m_ptr) /* Copy the mcontext structure to the user's address space. */ if ((r = data_copy(KERNEL, (vir_bytes) &mc, m_ptr->PR_ENDPT, (vir_bytes) m_ptr->PR_CTX_PTR, - (phys_bytes) sizeof(struct __mcontext))) != OK) + (phys_bytes) sizeof(mcontext_t))) != OK) return(r); return(OK); @@ -76,14 +78,15 @@ int do_setmcontext(struct proc * caller, message * m_ptr) /* Get the mcontext structure into our address space. */ if ((r = data_copy(m_ptr->PR_ENDPT, (vir_bytes) m_ptr->PR_CTX_PTR, KERNEL, - (vir_bytes) &mc, (phys_bytes) sizeof(struct __mcontext))) != OK) + (vir_bytes) &mc, (phys_bytes) sizeof(mcontext_t))) != OK) return(r); #if defined(__i386__) /* Copy FPU state */ - if (mc.mc_fpu_flags & MF_FPU_INITIALIZED) { + if (mc.mc_flags & _MC_FPU_SAVED) { rp->p_misc_flags |= MF_FPU_INITIALIZED; - memcpy(rp->p_seg.fpu_state, &(mc.mc_fpu_state), FPU_XFP_SIZE); + assert(sizeof(mc.__fpregs.__fp_reg_set) == FPU_XFP_SIZE); + memcpy(rp->p_seg.fpu_state, &(mc.__fpregs.__fp_reg_set), FPU_XFP_SIZE); } else rp->p_misc_flags &= ~MF_FPU_INITIALIZED; /* force reloading FPU in either case */ diff --git a/lib/libc/arch/arm/sys-minix/ucontextoffsets.cf b/lib/libc/arch/arm/sys-minix/ucontextoffsets.cf index bf21f9e36..ad449aac2 100644 --- a/lib/libc/arch/arm/sys-minix/ucontextoffsets.cf +++ b/lib/libc/arch/arm/sys-minix/ucontextoffsets.cf @@ -8,22 +8,22 @@ struct __ucontext member UC_FLAGS uc_flags member UC_LINK uc_link member MAGIC uc_mcontext.mc_magic -member REG0 uc_mcontext.mc_p_reg.retreg -member REG1 uc_mcontext.mc_p_reg.r1 -member REG2 uc_mcontext.mc_p_reg.r2 -member REG3 uc_mcontext.mc_p_reg.r3 -member REG4 uc_mcontext.mc_p_reg.r4 -member REG5 uc_mcontext.mc_p_reg.r5 -member REG6 uc_mcontext.mc_p_reg.r6 -member REG7 uc_mcontext.mc_p_reg.r7 -member REG8 uc_mcontext.mc_p_reg.r8 -member REG9 uc_mcontext.mc_p_reg.r9 -member REG10 uc_mcontext.mc_p_reg.r10 -member FPREG uc_mcontext.mc_p_reg.fp -member REG12 uc_mcontext.mc_p_reg.r12 -member SPREG uc_mcontext.mc_p_reg.sp -member LRREG uc_mcontext.mc_p_reg.lr -member PCREG uc_mcontext.mc_p_reg.pc +member REG0 uc_mcontext.__gregs[_REG_R0] +member REG1 uc_mcontext.__gregs[_REG_R1] +member REG2 uc_mcontext.__gregs[_REG_R2] +member REG3 uc_mcontext.__gregs[_REG_R3] +member REG4 uc_mcontext.__gregs[_REG_R4] +member REG5 uc_mcontext.__gregs[_REG_R5] +member REG6 uc_mcontext.__gregs[_REG_R6] +member REG7 uc_mcontext.__gregs[_REG_R7] +member REG8 uc_mcontext.__gregs[_REG_R8] +member REG9 uc_mcontext.__gregs[_REG_R9] +member REG10 uc_mcontext.__gregs[_REG_R10] +member FPREG uc_mcontext.__gregs[_REG_FP] +member REG12 uc_mcontext.__gregs[_REG_R12] +member SPREG uc_mcontext.__gregs[_REG_SP] +member LRREG uc_mcontext.__gregs[_REG_LR] +member PCREG uc_mcontext.__gregs[_REG_PC] define EFAULT EFAULT define EINVAL EINVAL define MCF_MAGIC MCF_MAGIC diff --git a/lib/libc/arch/i386/sys-minix/ucontextoffsets.cf b/lib/libc/arch/i386/sys-minix/ucontextoffsets.cf index 11e1a02c7..c06f9cdef 100644 --- a/lib/libc/arch/i386/sys-minix/ucontextoffsets.cf +++ b/lib/libc/arch/i386/sys-minix/ucontextoffsets.cf @@ -8,15 +8,15 @@ struct __ucontext member UC_FLAGS uc_flags member UC_LINK uc_link member MAGIC uc_mcontext.mc_magic -member DI uc_mcontext.mc_p_reg.di -member SI uc_mcontext.mc_p_reg.si -member BP uc_mcontext.mc_p_reg.fp -member AX uc_mcontext.mc_p_reg.retreg -member BX uc_mcontext.mc_p_reg.bx -member CX uc_mcontext.mc_p_reg.cx -member DX uc_mcontext.mc_p_reg.dx -member PC uc_mcontext.mc_p_reg.pc -member SP uc_mcontext.mc_p_reg.sp +member DI uc_mcontext.__gregs[_REG_EDI] +member SI uc_mcontext.__gregs[_REG_ESI] +member BP uc_mcontext.__gregs[_REG_EBP] +member AX uc_mcontext.__gregs[_REG_EAX] +member BX uc_mcontext.__gregs[_REG_EBX] +member CX uc_mcontext.__gregs[_REG_ECX] +member DX uc_mcontext.__gregs[_REG_EDX] +member PC uc_mcontext.__gregs[_REG_EIP] +member SP uc_mcontext.__gregs[_REG_ESP] define EFAULT EFAULT define EINVAL EINVAL define MCF_MAGIC MCF_MAGIC diff --git a/lib/libc/sys-minix/_ucontext.c b/lib/libc/sys-minix/_ucontext.c index 96698c76f..bac0d6f60 100644 --- a/lib/libc/sys-minix/_ucontext.c +++ b/lib/libc/sys-minix/_ucontext.c @@ -84,7 +84,7 @@ void makecontext(ucontext_t *ucp, void (*func)(void), int argc, ...) } else if ((ucp->uc_stack.ss_sp == NULL) || (ucp->uc_stack.ss_size < MINSIGSTKSZ)) { ucp->uc_mcontext.mc_magic = 0; - ucp->uc_mcontext.mc_p_reg.sp = 0; + _UC_MACHINE_SET_STACK(ucp, 0); return; } @@ -121,9 +121,9 @@ void makecontext(ucontext_t *ucp, void (*func)(void), int argc, ...) /* Adjust the machine context to point to the top of this stack and the program counter to the context start wrapper. */ - ucp->uc_mcontext.mc_p_reg.fp = 0; /* Clear frame pointer */ - ucp->uc_mcontext.mc_p_reg.sp = (reg_t) stack_top; - ucp->uc_mcontext.mc_p_reg.pc = (reg_t) ctx_start; + _UC_MACHINE_SET_EBP(ucp, 0); /* Clear frame pointer */ + _UC_MACHINE_SET_STACK(ucp, (reg_t) stack_top); + _UC_MACHINE_SET_PC(ucp, (reg_t) ctx_start); *stack_top++ = (uintptr_t) func; @@ -140,13 +140,14 @@ void makecontext(ucontext_t *ucp, void (*func)(void), int argc, ...) /* Set ESI to point to the base of the stack where ucp is stored, so that the wrapper function knows how to clean up the stack after calling `func' (i.e., how to adjust ESP). */ - ucp->uc_mcontext.mc_p_reg.si = (reg_t) stack_top; + _UC_MACHINE_SET_ESI(ucp, (reg_t) stack_top); /* If we ran out of stack space, invalidate stack pointer. Eventually, swapcontext will choke on this and return ENOMEM. */ - if (stack_top == ucp->uc_stack.ss_sp) - ucp->uc_mcontext.mc_p_reg.sp = 0; + if (stack_top == ucp->uc_stack.ss_sp) { + _UC_MACHINE_SET_STACK(ucp, 0); + } #elif defined(__arm__) /* The caller provides a pointer to a stack that we can use to run our context on. When the context starts, control is given to the @@ -180,23 +181,23 @@ void makecontext(ucontext_t *ucp, void (*func)(void), int argc, ...) /* Adjust the machine context to point to the top of this stack and the program counter to the 'func' entry point. Set lr to ctx_start, so ctx_start runs after 'func'. Save ucp in r4 */ - ucp->uc_mcontext.mc_p_reg.fp = 0; /* Clear frame pointer */ - ucp->uc_mcontext.mc_p_reg.sp = (reg_t) stack_top; - ucp->uc_mcontext.mc_p_reg.pc = (reg_t) func; - ucp->uc_mcontext.mc_p_reg.lr = (reg_t) ctx_start; - ucp->uc_mcontext.mc_p_reg.r4 = (reg_t) ucp; + _UC_MACHINE_SET_FP(ucp, 0); /* Clear frame pointer */ + _UC_MACHINE_SET_STACK(ucp, (reg_t) stack_top); + _UC_MACHINE_SET_PC(ucp, (reg_t) func); + _UC_MACHINE_SET_LR(ucp, (reg_t) ctx_start); + _UC_MACHINE_SET_R4(ucp, (reg_t) ucp); /* Copy arguments to r0-r3 and stack. */ va_start(ap, argc); /* Pass up to four arguments in registers. */ if (argc-- > 0) - ucp->uc_mcontext.mc_p_reg.retreg = va_arg(ap, uintptr_t); + _UC_MACHINE_SET_R0(ucp, va_arg(ap, uintptr_t)); if (argc-- > 0) - ucp->uc_mcontext.mc_p_reg.r1 = va_arg(ap, uintptr_t); + _UC_MACHINE_SET_R1(ucp, va_arg(ap, uintptr_t)); if (argc-- > 0) - ucp->uc_mcontext.mc_p_reg.r2 = va_arg(ap, uintptr_t); + _UC_MACHINE_SET_R2(ucp, va_arg(ap, uintptr_t)); if (argc-- > 0) - ucp->uc_mcontext.mc_p_reg.r3 = va_arg(ap, uintptr_t); + _UC_MACHINE_SET_R3(ucp, va_arg(ap, uintptr_t)); /* Pass the rest on the stack. */ while (argc-- > 0) { *stack_top++ = va_arg(ap, uintptr_t); @@ -205,8 +206,9 @@ void makecontext(ucontext_t *ucp, void (*func)(void), int argc, ...) /* If we ran out of stack space, invalidate stack pointer. Eventually, swapcontext will choke on this and return ENOMEM. */ - if (stack_top == ucp->uc_stack.ss_sp) - ucp->uc_mcontext.mc_p_reg.sp = 0; + if (stack_top == ucp->uc_stack.ss_sp) { + _UC_MACHINE_SET_STACK(ucp, 0); + } #else # error "Unsupported platform" #endif @@ -226,7 +228,7 @@ int swapcontext(ucontext_t *oucp, const ucontext_t *ucp) return(-1); } - if (ucp->uc_mcontext.mc_p_reg.sp == 0) { + if (_UC_MACHINE_STACK(ucp) == 0) { /* No stack space. Bail out. */ errno = ENOMEM; return(-1); diff --git a/lib/libmthread/misc.c b/lib/libmthread/misc.c index 51c99c8ab..8a4ad3fba 100644 --- a/lib/libmthread/misc.c +++ b/lib/libmthread/misc.c @@ -116,11 +116,10 @@ void mthread_stats(void) *===========================================================================*/ void mthread_stacktrace(mthread_thread_t t) { +#ifdef __i386__ /* stacktrace only implemented on x86 */ unsigned long bp, hbp, pc; mthread_tcb_t *tcb; ucontext_t *ctx; - mcontext_t *mtx; - struct stackframe_s *frame; tcb = mthread_find_tcb(t); ctx = &tcb->m_context; @@ -130,9 +129,7 @@ void mthread_stacktrace(mthread_thread_t t) printf("thread %d: ", t); - mtx = &ctx->uc_mcontext; - frame = &mtx->mc_p_reg; - bp = frame->fp; + bp = _UC_MACHINE_EBP(ctx); while (bp) { pc = ((unsigned long *) bp)[1]; @@ -149,6 +146,7 @@ void mthread_stacktrace(mthread_thread_t t) } printf("\n"); +#endif } /*===========================================================================* diff --git a/sys/arch/arm/include/mcontext.h b/sys/arch/arm/include/mcontext.h index a016c0172..cdfb7c440 100644 --- a/sys/arch/arm/include/mcontext.h +++ b/sys/arch/arm/include/mcontext.h @@ -1,19 +1,165 @@ -#ifndef _MACHINE_MCONTEXT_H -#define _MACHINE_MCONTEXT_H +/* $NetBSD: mcontext.h,v 1.11 2012/08/03 07:59:23 matt Exp $ */ -#include +/*- + * Copyright (c) 2001, 2002 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Klaus Klein and by Jason R. Thorpe of Wasabi Systems, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ -#define MCF_MAGIC 0xc0ffee +#ifndef _ARM_MCONTEXT_H_ +#define _ARM_MCONTEXT_H_ + +/* + * General register state + */ +#define _NGREG 17 +typedef unsigned int __greg_t; +typedef __greg_t __gregset_t[_NGREG]; + +#define _REG_R0 0 +#define _REG_R1 1 +#define _REG_R2 2 +#define _REG_R3 3 +#define _REG_R4 4 +#define _REG_R5 5 +#define _REG_R6 6 +#define _REG_R7 7 +#define _REG_R8 8 +#define _REG_R9 9 +#define _REG_R10 10 +#define _REG_R11 11 +#define _REG_R12 12 +#define _REG_R13 13 +#define _REG_R14 14 +#define _REG_R15 15 +#define _REG_CPSR 16 +/* Convenience synonyms */ +#define _REG_FP _REG_R11 +#define _REG_SP _REG_R13 +#define _REG_LR _REG_R14 +#define _REG_PC _REG_R15 + +/* + * Floating point register state + */ +/* Note: the storage layout of this structure must be identical to ARMFPE! */ +typedef struct { + unsigned int __fp_fpsr; + struct { + unsigned int __fp_exponent; + unsigned int __fp_mantissa_hi; + unsigned int __fp_mantissa_lo; + } __fp_fr[8]; +} __fpregset_t; + +typedef struct { + unsigned int __vfp_fpscr; + unsigned int __vfp_fstmx[33]; + unsigned int __vfp_fpsid; +} __vfpregset_t; + +typedef struct { + __gregset_t __gregs; + union { + __fpregset_t __fpregs; + __vfpregset_t __vfpregs; + } __fpu; + __greg_t _mc_tlsbase; +#ifdef __minix + int mc_flags; + int mc_magic; +#endif +} mcontext_t, mcontext32_t; + +/* Machine-dependent uc_flags */ +#define _UC_ARM_VFP 0x00010000 /* FPU field is VFP */ + +/* used by signal delivery to indicate status of signal stack */ +#define _UC_SETSTACK 0x00020000 +#define _UC_CLRSTACK 0x00040000 + +#define _UC_TLSBASE 0x00080000 + +#define _UC_MACHINE_PAD 2 /* Padding appended to ucontext_t */ + +#define _UC_MACHINE_SP(uc) ((uc)->uc_mcontext.__gregs[_REG_SP]) +#define _UC_MACHINE_PC(uc) ((uc)->uc_mcontext.__gregs[_REG_PC]) +#define _UC_MACHINE_INTRV(uc) ((uc)->uc_mcontext.__gregs[_REG_R0]) -/* Context to describe processor state */ -typedef struct __mcontext { - int mc_magic; - struct stackframe_s mc_p_reg; -} mcontext_t; +#define _UC_MACHINE_SET_PC(uc, pc) _UC_MACHINE_PC(uc) = (pc) -__BEGIN_DECLS +#ifdef __minix +#define _UC_MACHINE_STACK(uc) ((uc)->uc_mcontext.__gregs[_REG_SP]) +#define _UC_MACHINE_SET_STACK(uc, sp) _UC_MACHINE_STACK(uc) = (sp) + +#define _UC_MACHINE_FP(uc) ((uc)->uc_mcontext.__gregs[_REG_FP]) +#define _UC_MACHINE_SET_FP(uc, fp) _UC_MACHINE_FP(uc) = (fp) + +#define _UC_MACHINE_LR(uc) ((uc)->uc_mcontext.__gregs[_REG_LR]) +#define _UC_MACHINE_SET_LR(uc, lr) _UC_MACHINE_LR(uc) = (lr) + +#define _UC_MACHINE_R0(uc) ((uc)->uc_mcontext.__gregs[_REG_R0]) +#define _UC_MACHINE_SET_R0(uc, setreg) _UC_MACHINE_R0(uc) = (setreg) + +#define _UC_MACHINE_R1(uc) ((uc)->uc_mcontext.__gregs[_REG_R1]) +#define _UC_MACHINE_SET_R1(uc, setreg) _UC_MACHINE_R1(uc) = (setreg) + +#define _UC_MACHINE_R2(uc) ((uc)->uc_mcontext.__gregs[_REG_R2]) +#define _UC_MACHINE_SET_R2(uc, setreg) _UC_MACHINE_R2(uc) = (setreg) + +#define _UC_MACHINE_R3(uc) ((uc)->uc_mcontext.__gregs[_REG_R3]) +#define _UC_MACHINE_SET_R3(uc, setreg) _UC_MACHINE_R3(uc) = (setreg) + +#define _UC_MACHINE_R4(uc) ((uc)->uc_mcontext.__gregs[_REG_R4]) +#define _UC_MACHINE_SET_R4(uc, setreg) _UC_MACHINE_R4(uc) = (setreg) +#endif + +#define __UCONTEXT_SIZE 256 + +static __inline void * +__lwp_getprivate_fast(void) +{ + extern void *_lwp_getprivate(void); + void *rv; + __asm("mrc p15, 0, %0, c13, c0, 3" : "=r"(rv)); + if (__predict_true(rv)) + return rv; + /* + * Some ARM cores are broken and don't raise an undefined fault when an + * unrecogized mrc instruction is encountered, but just return zero. + * To do deal with that, if we get a zero we (re-)fetch the value using + * syscall. + */ + return _lwp_getprivate(); +} + +#ifdef __minix int setmcontext(const mcontext_t *mcp); int getmcontext(mcontext_t *mcp); -__END_DECLS +#define MCF_MAGIC 0xc0ffee +#endif -#endif /* _MACHINE_MCONTEXT_H */ +#endif /* !_ARM_MCONTEXT_H_ */ diff --git a/sys/arch/i386/include/mcontext.h b/sys/arch/i386/include/mcontext.h index 3f8ab0064..c7e36723e 100644 --- a/sys/arch/i386/include/mcontext.h +++ b/sys/arch/i386/include/mcontext.h @@ -1,22 +1,165 @@ -#ifndef _MACHINE_MCONTEXT_H -#define _MACHINE_MCONTEXT_H 1 +/* $NetBSD: mcontext.h,v 1.10 2011/02/25 14:07:13 joerg Exp $ */ -#include -#include +/*- + * Copyright (c) 1999 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Klaus Klein. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ -#define MCF_MAGIC 0xc0ffee +#ifndef _I386_MCONTEXT_H_ +#define _I386_MCONTEXT_H_ + + +/* + * mcontext extensions to handle signal delivery. + */ +#define _UC_SETSTACK 0x00010000 +#define _UC_CLRSTACK 0x00020000 +#define _UC_VM 0x00040000 +#define _UC_TLSBASE 0x00080000 + +/* + * Layout of mcontext_t according to the System V Application Binary Interface, + * Intel386(tm) Architecture Processor Supplement, Fourth Edition. + */ + +/* + * General register state + */ +#define _NGREG 19 +typedef int __greg_t; +typedef __greg_t __gregset_t[_NGREG]; + +#define _REG_GS 0 +#define _REG_FS 1 +#define _REG_ES 2 +#define _REG_DS 3 +#define _REG_EDI 4 +#define _REG_ESI 5 +#define _REG_EBP 6 +#define _REG_ESP 7 +#define _REG_EBX 8 +#define _REG_EDX 9 +#define _REG_ECX 10 +#define _REG_EAX 11 +#define _REG_TRAPNO 12 +#define _REG_ERR 13 +#define _REG_EIP 14 +#define _REG_CS 15 +#define _REG_EFL 16 +#define _REG_UESP 17 +#define _REG_SS 18 -/* Context to describe processor state */ -typedef struct __mcontext { - int mc_magic; - struct stackframe_s mc_p_reg; - union fpu_state_u mc_fpu_state; - short mc_fpu_flags; +/* + * Floating point register state + */ +typedef struct { + union { + struct { + int __fp_state[27]; /* Environment and registers */ + int __fp_status; /* Software status word */ + } __fpchip_state; + struct { + char __fp_emul[246]; + char __fp_epad[2]; + } __fp_emul_space; + struct { + char __fp_xmm[512]; + } __fp_xmm_state; + int __fp_fpregs[128]; + } __fp_reg_set; + long __fp_wregs[33]; /* Weitek? */ +} __fpregset_t; + +typedef struct { + __gregset_t __gregs; + __fpregset_t __fpregs; + __greg_t _mc_tlsbase; +#ifdef __minix + int mc_magic; + int mc_flags; +#endif } mcontext_t; -__BEGIN_DECLS +#ifdef __minix +#define _MC_FPU_SAVED 0x001 +#endif + +#define _UC_FXSAVE 0x20 /* FP state is in FXSAVE format in XMM space */ + +#define _UC_MACHINE_PAD 4 /* Padding appended to ucontext_t */ + +#define _UC_UCONTEXT_ALIGN (~0xf) + +#ifdef _KERNEL_OPT +#include "opt_vm86.h" +#ifdef VM86 +/*#include */ +#define PSL_VM 0x00020000 +#define _UC_MACHINE_SP(uc) ((uc)->uc_mcontext.__gregs[_REG_UESP] + \ + ((uc)->uc_mcontext.__gregs[_REG_EFL] & PSL_VM ? \ + ((uc)->uc_mcontext.__gregs[_REG_SS] << 4) : 0)) +#endif /* VM86 */ +#endif /* _KERNEL_OPT */ + +#ifndef _UC_MACHINE_SP +#define _UC_MACHINE_SP(uc) ((uc)->uc_mcontext.__gregs[_REG_UESP]) +#endif +#define _UC_MACHINE_PC(uc) ((uc)->uc_mcontext.__gregs[_REG_EIP]) +#define _UC_MACHINE_INTRV(uc) ((uc)->uc_mcontext.__gregs[_REG_EAX]) + +#define _UC_MACHINE_SET_PC(uc, pc) _UC_MACHINE_PC(uc) = (pc) + +#ifdef __minix +#define _UC_MACHINE_STACK(uc) ((uc)->uc_mcontext.__gregs[_REG_ESP]) +#define _UC_MACHINE_SET_STACK(uc, esp) _UC_MACHINE_STACK(uc) = (esp) + +#define _UC_MACHINE_EBP(uc) ((uc)->uc_mcontext.__gregs[_REG_EBP]) +#define _UC_MACHINE_SET_EBP(uc, ebp) _UC_MACHINE_EBP(uc) = (ebp) + +#define _UC_MACHINE_ESI(uc) ((uc)->uc_mcontext.__gregs[_REG_ESI]) +#define _UC_MACHINE_SET_ESI(uc, esi) _UC_MACHINE_ESI(uc) = (esi) +#endif + +#define __UCONTEXT_SIZE 776 + +static __inline void * +__lwp_getprivate_fast(void) +{ + void *__tmp; + + __asm volatile("movl %%gs:0, %0" : "=r" (__tmp)); + + return __tmp; +} + +#ifdef __minix int setmcontext(const mcontext_t *mcp); int getmcontext(mcontext_t *mcp); -__END_DECLS +#define MCF_MAGIC 0xc0ffee +#endif -#endif /* _MACHINE_MCONTEXT_H */ +#endif /* !_I386_MCONTEXT_H_ */ diff --git a/sys/sys/ucontext.h b/sys/sys/ucontext.h index 225d1087f..b4d0d0890 100644 --- a/sys/sys/ucontext.h +++ b/sys/sys/ucontext.h @@ -109,7 +109,7 @@ struct __ucontext { #ifdef _KERNEL struct lwp; -#ifdef __UCONTEXT_SIZE +#if defined(__UCONTEXT_SIZE) && !defined(__minix) __CTASSERT(sizeof(ucontext_t) == __UCONTEXT_SIZE); #endif @@ -123,7 +123,7 @@ int cpu_mcontext_validate(struct lwp *, const mcontext_t *); #ifdef __minix __BEGIN_DECLS void resumecontext(ucontext_t *ucp); -#ifdef __UCONTEXT_SIZE +#if defined(__UCONTEXT_SIZE) && !defined(__minix) __CTASSERT(sizeof(ucontext_t) == __UCONTEXT_SIZE); #endif -- 2.44.0