git: 21f246174184 - main - linux(4): Move sigframe definitions to separate headers
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sun, 15 May 2022 18:12:24 UTC
The branch main has been updated by dchagin: URL: https://cgit.FreeBSD.org/src/commit/?id=21f246174184742ba8952aeb1dadbf58d48d54b4 commit 21f246174184742ba8952aeb1dadbf58d48d54b4 Author: Dmitry Chagin <dchagin@FreeBSD.org> AuthorDate: 2022-05-15 18:03:01 +0000 Commit: Dmitry Chagin <dchagin@FreeBSD.org> CommitDate: 2022-05-15 18:03:01 +0000 linux(4): Move sigframe definitions to separate headers The signal trampoine-related definitions are used only in the MD part of code, wherefore moved from everywhere used linux.h to separate MD headers. MFC after: 2 weeks --- sys/amd64/linux/linux.h | 65 ------------ sys/amd64/linux/linux_genassym.c | 2 + sys/amd64/linux/linux_sysvec.c | 2 + sys/amd64/linux32/linux.h | 90 ---------------- sys/amd64/linux32/linux32_genassym.c | 2 + sys/amd64/linux32/linux32_sysvec.c | 2 + sys/arm64/linux/linux.h | 10 -- sys/arm64/linux/linux_sigframe.h | 44 ++++++++ sys/arm64/linux/linux_sysvec.c | 2 + sys/i386/linux/linux.h | 92 ---------------- sys/i386/linux/linux_genassym.c | 2 + sys/i386/linux/linux_sysvec.c | 14 +-- sys/x86/linux/linux_x86_sigframe.h | 196 +++++++++++++++++++++++++++++++++++ 13 files changed, 260 insertions(+), 263 deletions(-) diff --git a/sys/amd64/linux/linux.h b/sys/amd64/linux/linux.h index 08cf3d4b6bbd..51a2906f45cf 100644 --- a/sys/amd64/linux/linux.h +++ b/sys/amd64/linux/linux.h @@ -182,59 +182,6 @@ typedef struct { l_size_t ss_size; } l_stack_t; -struct l_fpstate { - u_int16_t cwd; - u_int16_t swd; - u_int16_t twd; - u_int16_t fop; - u_int64_t rip; - u_int64_t rdp; - u_int32_t mxcsr; - u_int32_t mxcsr_mask; - u_int32_t st_space[32]; - u_int32_t xmm_space[64]; - u_int32_t reserved2[24]; -}; - -struct l_sigcontext { - l_ulong sc_r8; - l_ulong sc_r9; - l_ulong sc_r10; - l_ulong sc_r11; - l_ulong sc_r12; - l_ulong sc_r13; - l_ulong sc_r14; - l_ulong sc_r15; - l_ulong sc_rdi; - l_ulong sc_rsi; - l_ulong sc_rbp; - l_ulong sc_rbx; - l_ulong sc_rdx; - l_ulong sc_rax; - l_ulong sc_rcx; - l_ulong sc_rsp; - l_ulong sc_rip; - l_ulong sc_rflags; - l_ushort sc_cs; - l_ushort sc_gs; - l_ushort sc_fs; - l_ushort sc___pad0; - l_ulong sc_err; - l_ulong sc_trapno; - l_sigset_t sc_mask; - l_ulong sc_cr2; - struct l_fpstate *sc_fpstate; - l_ulong sc_reserved1[8]; -}; - -struct l_ucontext { - l_ulong uc_flags; - l_uintptr_t uc_link; - l_stack_t uc_stack; - struct l_sigcontext uc_mcontext; - l_sigset_t uc_sigmask; -}; - #define LINUX_SI_PREAMBLE_SIZE (4 * sizeof(int)) #define LINUX_SI_MAX_SIZE 128 #define LINUX_SI_PAD_SIZE ((LINUX_SI_MAX_SIZE - \ @@ -304,18 +251,6 @@ typedef struct l_siginfo { #define lsi_band _sifields._sigpoll._band #define lsi_fd _sifields._sigpoll._fd -/* - * We make the stack look like Linux expects it when calling a signal - * handler, but use the BSD way of calling the handler and sigreturn(). - * This means that we need to pass the pointer to the handler too. - * It is appended to the frame to not interfere with the rest of it. - */ - -struct l_rt_sigframe { - struct l_ucontext sf_sc; - struct l_siginfo sf_si; -}; - /* * mount flags */ diff --git a/sys/amd64/linux/linux_genassym.c b/sys/amd64/linux/linux_genassym.c index 73febbe6ef40..a468520431dc 100644 --- a/sys/amd64/linux/linux_genassym.c +++ b/sys/amd64/linux/linux_genassym.c @@ -8,6 +8,8 @@ __FBSDID("$FreeBSD$"); #include <amd64/linux/linux.h> #include <compat/linux/linux_mib.h> +#include <x86/linux/linux_x86_sigframe.h> + ASSYM(LINUX_RT_SIGF_UC, offsetof(struct l_rt_sigframe, sf_sc)); ASSYM(LINUX_RT_SIGF_SC, offsetof(struct l_ucontext, uc_mcontext)); ASSYM(LINUX_VERSION_CODE, LINUX_VERSION_CODE); diff --git a/sys/amd64/linux/linux_sysvec.c b/sys/amd64/linux/linux_sysvec.c index ea91dcae5d49..58ab443cd8b1 100644 --- a/sys/amd64/linux/linux_sysvec.c +++ b/sys/amd64/linux/linux_sysvec.c @@ -86,6 +86,8 @@ __FBSDID("$FreeBSD$"); #include <compat/linux/linux_util.h> #include <compat/linux/linux_vdso.h> +#include <x86/linux/linux_x86_sigframe.h> + MODULE_VERSION(linux64, 1); #define LINUX_VDSOPAGE_SIZE PAGE_SIZE * 2 diff --git a/sys/amd64/linux32/linux.h b/sys/amd64/linux32/linux.h index ba7aeac517e1..1987ff515275 100644 --- a/sys/amd64/linux32/linux.h +++ b/sys/amd64/linux32/linux.h @@ -287,40 +287,6 @@ typedef struct { l_size_t ss_size; } l_stack_t; -/* The Linux sigcontext, pretty much a standard 386 trapframe. */ -struct l_sigcontext { - l_uint sc_gs; - l_uint sc_fs; - l_uint sc_es; - l_uint sc_ds; - l_uint sc_edi; - l_uint sc_esi; - l_uint sc_ebp; - l_uint sc_esp; - l_uint sc_ebx; - l_uint sc_edx; - l_uint sc_ecx; - l_uint sc_eax; - l_uint sc_trapno; - l_uint sc_err; - l_uint sc_eip; - l_uint sc_cs; - l_uint sc_eflags; - l_uint sc_esp_at_signal; - l_uint sc_ss; - l_uint sc_387; - l_uint sc_mask; - l_uint sc_cr2; -}; - -struct l_ucontext { - l_ulong uc_flags; - l_uintptr_t uc_link; - l_stack_t uc_stack; - struct l_sigcontext uc_mcontext; - l_sigset_t uc_sigmask; -} __packed; - #define LINUX_SI_MAX_SIZE 128 #define LINUX_SI_PAD_SIZE ((LINUX_SI_MAX_SIZE/sizeof(l_int)) - 3) @@ -389,62 +355,6 @@ typedef struct l_siginfo { #define lsi_band _sifields._sigpoll._band #define lsi_fd _sifields._sigpoll._fd -struct l_fpreg { - u_int16_t significand[4]; - u_int16_t exponent; -}; - -struct l_fpxreg { - u_int16_t significand[4]; - u_int16_t exponent; - u_int16_t padding[3]; -}; - -struct l_xmmreg { - u_int32_t element[4]; -}; - -struct l_fpstate { - /* Regular FPU environment */ - u_int32_t cw; - u_int32_t sw; - u_int32_t tag; - u_int32_t ipoff; - u_int32_t cssel; - u_int32_t dataoff; - u_int32_t datasel; - struct l_fpreg _st[8]; - u_int16_t status; - u_int16_t magic; /* 0xffff = regular FPU data */ - - /* FXSR FPU environment */ - u_int32_t _fxsr_env[6]; /* env is ignored. */ - u_int32_t mxcsr; - u_int32_t reserved; - struct l_fpxreg _fxsr_st[8]; /* reg data is ignored. */ - struct l_xmmreg _xmm[8]; - u_int32_t padding[56]; -}; - -/* - * We make the stack look like Linux expects it when calling a signal - * handler, but use the BSD way of calling the handler and sigreturn(). - */ -struct l_sigframe { - l_int sf_sig; - struct l_sigcontext sf_sc; - struct l_fpstate sf_fpstate; - l_uint sf_extramask[1]; -}; - -struct l_rt_sigframe { - l_int sf_sig; - l_uintptr_t sf_siginfo; - l_uintptr_t sf_ucontext; - l_siginfo_t sf_si; - struct l_ucontext sf_sc; -} __packed; - /* * arch specific open/fcntl flags */ diff --git a/sys/amd64/linux32/linux32_genassym.c b/sys/amd64/linux32/linux32_genassym.c index ca618c01ffab..2bc2586ebe4a 100644 --- a/sys/amd64/linux32/linux32_genassym.c +++ b/sys/amd64/linux32/linux32_genassym.c @@ -9,6 +9,8 @@ __FBSDID("$FreeBSD$"); #include <amd64/linux32/linux.h> #include <compat/linux/linux_mib.h> +#include <x86/linux/linux_x86_sigframe.h> + ASSYM(LINUX_SIGF_SC, offsetof(struct l_sigframe, sf_sc)); ASSYM(LINUX_RT_SIGF_UC, offsetof(struct l_rt_sigframe, sf_sc)); ASSYM(LINUX_RT_SIGF_SC, offsetof(struct l_ucontext, uc_mcontext)); diff --git a/sys/amd64/linux32/linux32_sysvec.c b/sys/amd64/linux32/linux32_sysvec.c index b2d0f2401bf9..c40cc6a2d269 100644 --- a/sys/amd64/linux32/linux32_sysvec.c +++ b/sys/amd64/linux32/linux32_sysvec.c @@ -91,6 +91,8 @@ __FBSDID("$FreeBSD$"); #include <compat/linux/linux_util.h> #include <compat/linux/linux_vdso.h> +#include <x86/linux/linux_x86_sigframe.h> + MODULE_VERSION(linux, 1); #define LINUX32_MAXUSER ((1ul << 32) - PAGE_SIZE) diff --git a/sys/arm64/linux/linux.h b/sys/arm64/linux/linux.h index d43795a71a83..b6e2af506ad2 100644 --- a/sys/arm64/linux/linux.h +++ b/sys/arm64/linux/linux.h @@ -248,16 +248,6 @@ typedef struct l_siginfo { #define lsi_band _sifields._sigpoll._band #define lsi_fd _sifields._sigpoll._fd -/* - * This structure is different from the one used by Linux, - * but it doesn't matter - it's not user-accessible. We need - * it instead of the native one because of l_siginfo. - */ -struct l_sigframe { - struct l_siginfo sf_si; - ucontext_t sf_uc; -}; - union l_semun { l_int val; l_uintptr_t buf; diff --git a/sys/arm64/linux/linux_sigframe.h b/sys/arm64/linux/linux_sigframe.h new file mode 100644 index 000000000000..060b89c920ac --- /dev/null +++ b/sys/arm64/linux/linux_sigframe.h @@ -0,0 +1,44 @@ +/*- + * Copyright (c) 1994-1996 Søren Schmidt + * Copyright (c) 2013 Dmitry Chagin <dchagin@FreeBSD.org> + * Copyright (c) 2018 Turing Robotic Industries 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 AUTHOR 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 AUTHOR 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. + */ + +/* + * $FreeBSD$ + */ +#ifndef _ARM64_LINUX_SIGFRAME_H_ +#define _ARM64_LINUX_SIGFRAME_H_ + +/* + * This structure is different from the one used by Linux, + * but it doesn't matter - it's not user-accessible. We need + * it instead of the native one because of l_siginfo. + */ +struct l_sigframe { + struct l_siginfo sf_si; + ucontext_t sf_uc; +}; + +#endif /* _ARM64_LINUX_SIGFRAME_H_ */ diff --git a/sys/arm64/linux/linux_sysvec.c b/sys/arm64/linux/linux_sysvec.c index 0ac2d759b0d4..3d3e64f15c6c 100644 --- a/sys/arm64/linux/linux_sysvec.c +++ b/sys/arm64/linux/linux_sysvec.c @@ -68,6 +68,8 @@ __FBSDID("$FreeBSD$"); #include <compat/linux/linux_util.h> #include <compat/linux/linux_vdso.h> +#include <arm64/linux/linux_sigframe.h> + #include <machine/md_var.h> #ifdef VFP diff --git a/sys/i386/linux/linux.h b/sys/i386/linux/linux.h index c26294ddc178..75995587373b 100644 --- a/sys/i386/linux/linux.h +++ b/sys/i386/linux/linux.h @@ -218,8 +218,6 @@ struct l_statfs64 { l_int f_spare[4]; }; -#define LINUX_NSIG_WORDS 2 - /* sigaction flags */ #define LINUX_SA_NOCLDSTOP 0x00000001 #define LINUX_SA_NOCLDWAIT 0x00000002 @@ -262,40 +260,6 @@ typedef struct { l_size_t ss_size; } l_stack_t; -/* The Linux sigcontext, pretty much a standard 386 trapframe. */ -struct l_sigcontext { - l_int sc_gs; - l_int sc_fs; - l_int sc_es; - l_int sc_ds; - l_int sc_edi; - l_int sc_esi; - l_int sc_ebp; - l_int sc_esp; - l_int sc_ebx; - l_int sc_edx; - l_int sc_ecx; - l_int sc_eax; - l_int sc_trapno; - l_int sc_err; - l_int sc_eip; - l_int sc_cs; - l_int sc_eflags; - l_int sc_esp_at_signal; - l_int sc_ss; - l_int sc_387; - l_int sc_mask; - l_int sc_cr2; -}; - -struct l_ucontext { - l_ulong uc_flags; - void *uc_link; - l_stack_t uc_stack; - struct l_sigcontext uc_mcontext; - l_sigset_t uc_sigmask; -}; - #define LINUX_SI_MAX_SIZE 128 #define LINUX_SI_PAD_SIZE ((LINUX_SI_MAX_SIZE/sizeof(l_int)) - 3) @@ -364,62 +328,6 @@ typedef struct l_siginfo { #define lsi_band _sifields._sigpoll._band #define lsi_fd _sifields._sigpoll._fd -struct l_fpreg { - u_int16_t significand[4]; - u_int16_t exponent; -}; - -struct l_fpxreg { - u_int16_t significand[4]; - u_int16_t exponent; - u_int16_t padding[3]; -}; - -struct l_xmmreg { - u_int32_t element[4]; -}; - -struct l_fpstate { - /* Regular FPU environment */ - u_int32_t cw; - u_int32_t sw; - u_int32_t tag; - u_int32_t ipoff; - u_int32_t cssel; - u_int32_t dataoff; - u_int32_t datasel; - struct l_fpreg _st[8]; - u_int16_t status; - u_int16_t magic; /* 0xffff = regular FPU data */ - - /* FXSR FPU environment */ - u_int32_t _fxsr_env[6]; /* env is ignored. */ - u_int32_t mxcsr; - u_int32_t reserved; - struct l_fpxreg _fxsr_st[8]; /* reg data is ignored. */ - struct l_xmmreg _xmm[8]; - u_int32_t padding[56]; -}; - -/* - * We make the stack look like Linux expects it when calling a signal - * handler, but use the BSD way of calling the handler and sigreturn(). - */ -struct l_sigframe { - l_int sf_sig; - struct l_sigcontext sf_sc; - struct l_fpstate sf_fpstate; - l_uint sf_extramask[LINUX_NSIG_WORDS-1]; -}; - -struct l_rt_sigframe { - l_int sf_sig; - l_siginfo_t *sf_siginfo; - struct l_ucontext *sf_ucontext; - l_siginfo_t sf_si; - struct l_ucontext sf_sc; -}; - extern struct sysentvec linux_sysvec; /* diff --git a/sys/i386/linux/linux_genassym.c b/sys/i386/linux/linux_genassym.c index 08aa0979d793..1491ce586b09 100644 --- a/sys/i386/linux/linux_genassym.c +++ b/sys/i386/linux/linux_genassym.c @@ -8,6 +8,8 @@ __FBSDID("$FreeBSD$"); #include <i386/linux/linux.h> #include <compat/linux/linux_mib.h> +#include <x86/linux/linux_x86_sigframe.h> + ASSYM(LINUX_SIGF_SC, offsetof(struct l_sigframe, sf_sc)); ASSYM(LINUX_SC_GS, offsetof(struct l_sigcontext, sc_gs)); ASSYM(LINUX_SC_EFLAGS, offsetof(struct l_sigcontext, sc_eflags)); diff --git a/sys/i386/linux/linux_sysvec.c b/sys/i386/linux/linux_sysvec.c index d37250d7552f..c71fd6b94649 100644 --- a/sys/i386/linux/linux_sysvec.c +++ b/sys/i386/linux/linux_sysvec.c @@ -74,6 +74,8 @@ __FBSDID("$FreeBSD$"); #include <compat/linux/linux_util.h> #include <compat/linux/linux_vdso.h> +#include <x86/linux/linux_x86_sigframe.h> + MODULE_VERSION(linux, 1); #define LINUX_VDSOPAGE_SIZE PAGE_SIZE * 2 @@ -423,8 +425,8 @@ linux_rt_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) bzero(&frame, sizeof(frame)); frame.sf_sig = sig; - frame.sf_siginfo = &fp->sf_si; - frame.sf_ucontext = &fp->sf_sc; + frame.sf_siginfo = PTROUT(&fp->sf_si); + frame.sf_ucontext = PTROUT(&fp->sf_sc); /* Fill in POSIX parts. */ siginfo_to_lsiginfo(&ksi->ksi_info, &frame.sf_si, sig); @@ -470,9 +472,9 @@ linux_rt_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) } /* Build context to run handler in. */ - regs->tf_esp = (int)fp; + regs->tf_esp = PTROUT(fp); regs->tf_eip = __kernel_rt_sigreturn; - regs->tf_edi = catcher; + regs->tf_edi = PTROUT(catcher); regs->tf_eflags &= ~(PSL_T | PSL_VM | PSL_D); regs->tf_cs = _ucodesel; regs->tf_ds = _udatasel; @@ -571,9 +573,9 @@ linux_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) } /* Build context to run handler in. */ - regs->tf_esp = (int)fp; + regs->tf_esp = PTROUT(fp); regs->tf_eip = __kernel_sigreturn; - regs->tf_edi = catcher; + regs->tf_edi = PTROUT(catcher); regs->tf_eflags &= ~(PSL_T | PSL_VM | PSL_D); regs->tf_cs = _ucodesel; regs->tf_ds = _udatasel; diff --git a/sys/x86/linux/linux_x86_sigframe.h b/sys/x86/linux/linux_x86_sigframe.h new file mode 100644 index 000000000000..13294740eb39 --- /dev/null +++ b/sys/x86/linux/linux_x86_sigframe.h @@ -0,0 +1,196 @@ +/*- + * SPDX-License-Identifier: BSD-3-Clause + * + * Copyright (c) 2004 Tim J. Robbins + * Copyright (c) 2001 Doug Rabson + * Copyright (c) 1994-1996 Søren Schmidt + * All rights reserved. + * + * 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 + * in this position and unchanged. + * 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. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * $FreeBSD$ + */ + +#ifndef _X86_LINUX_SIGFRAME_H_ +#define _X86_LINUX_SIGFRAME_H_ + +#if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32)) + +/* The Linux sigcontext, pretty much a standard 386 trapframe. */ +struct l_sigcontext { + l_uint sc_gs; + l_uint sc_fs; + l_uint sc_es; + l_uint sc_ds; + l_uint sc_edi; + l_uint sc_esi; + l_uint sc_ebp; + l_uint sc_esp; + l_uint sc_ebx; + l_uint sc_edx; + l_uint sc_ecx; + l_uint sc_eax; + l_uint sc_trapno; + l_uint sc_err; + l_uint sc_eip; + l_uint sc_cs; + l_uint sc_eflags; + l_uint sc_esp_at_signal; + l_uint sc_ss; + l_uint sc_387; + l_uint sc_mask; + l_uint sc_cr2; +}; + +struct l_ucontext { + l_ulong uc_flags; + l_uintptr_t uc_link; + l_stack_t uc_stack; + struct l_sigcontext uc_mcontext; + l_sigset_t uc_sigmask; +} __packed; + +struct l_fpreg { + u_int16_t significand[4]; + u_int16_t exponent; +}; + +struct l_fpxreg { + u_int16_t significand[4]; + u_int16_t exponent; + u_int16_t padding[3]; +}; + +struct l_xmmreg { + u_int32_t element[4]; +}; + +struct l_fpstate { + /* Regular FPU environment */ + u_int32_t cw; + u_int32_t sw; + u_int32_t tag; + u_int32_t ipoff; + u_int32_t cssel; + u_int32_t dataoff; + u_int32_t datasel; + struct l_fpreg _st[8]; + u_int16_t status; + u_int16_t magic; /* 0xffff = regular FPU data */ + + /* FXSR FPU environment */ + u_int32_t _fxsr_env[6]; /* env is ignored. */ + u_int32_t mxcsr; + u_int32_t reserved; + struct l_fpxreg _fxsr_st[8]; /* reg data is ignored. */ + struct l_xmmreg _xmm[8]; + u_int32_t padding[56]; +}; + +/* + * We make the stack look like Linux expects it when calling a signal + * handler, but use the BSD way of calling the handler and sigreturn(). + */ +struct l_sigframe { + l_int sf_sig; + struct l_sigcontext sf_sc; + struct l_fpstate sf_fpstate; + l_uint sf_extramask[1]; +}; + +struct l_rt_sigframe { + l_int sf_sig; + l_uintptr_t sf_siginfo; + l_uintptr_t sf_ucontext; + l_siginfo_t sf_si; + struct l_ucontext sf_sc; +}; + +#else + +struct l_fpstate { + u_int16_t cwd; + u_int16_t swd; + u_int16_t twd; + u_int16_t fop; + u_int64_t rip; + u_int64_t rdp; + u_int32_t mxcsr; + u_int32_t mxcsr_mask; + u_int32_t st_space[32]; + u_int32_t xmm_space[64]; + u_int32_t reserved2[24]; +}; + +struct l_sigcontext { + l_ulong sc_r8; + l_ulong sc_r9; + l_ulong sc_r10; + l_ulong sc_r11; + l_ulong sc_r12; + l_ulong sc_r13; + l_ulong sc_r14; + l_ulong sc_r15; + l_ulong sc_rdi; + l_ulong sc_rsi; + l_ulong sc_rbp; + l_ulong sc_rbx; + l_ulong sc_rdx; + l_ulong sc_rax; + l_ulong sc_rcx; + l_ulong sc_rsp; + l_ulong sc_rip; + l_ulong sc_rflags; + l_ushort sc_cs; + l_ushort sc_gs; + l_ushort sc_fs; + l_ushort sc___pad0; + l_ulong sc_err; + l_ulong sc_trapno; + l_sigset_t sc_mask; + l_ulong sc_cr2; + struct l_fpstate *sc_fpstate; + l_ulong sc_reserved1[8]; +}; + +struct l_ucontext { + l_ulong uc_flags; + l_uintptr_t uc_link; + l_stack_t uc_stack; + struct l_sigcontext uc_mcontext; + l_sigset_t uc_sigmask; +}; + +/* + * We make the stack look like Linux expects it when calling a signal + * handler, but use the BSD way of calling the handler and sigreturn(). + */ +struct l_rt_sigframe { + struct l_ucontext sf_sc; + struct l_siginfo sf_si; +}; + +#endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */ + +#endif /* !_X86_LINUX_SIGFRAME_H_ */