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
This commit is contained in:
Dmitry Chagin 2022-05-15 21:03:01 +03:00
parent ba279bcd6d
commit 21f2461741
13 changed files with 260 additions and 263 deletions

View File

@ -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
*/

View File

@ -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);

View File

@ -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

View File

@ -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
*/

View File

@ -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));

View File

@ -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)

View File

@ -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;

View File

@ -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_ */

View File

@ -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

View File

@ -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;
/*

View File

@ -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));

View File

@ -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;

View File

@ -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_ */