Module Name: src Committed By: maxv Date: Tue Aug 1 14:43:54 UTC 2017
Modified Files: src/sys/arch/i386/conf: files.i386 src/sys/arch/xen/conf: files.xen src/sys/compat/freebsd: files.freebsd src/sys/modules/compat_freebsd: Makefile Added Files: src/sys/compat/freebsd: freebsd_machdep.c freebsd_sigcode.S freebsd_syscall.c Removed Files: src/sys/arch/i386/i386: freebsd_machdep.c freebsd_sigcode.S freebsd_syscall.c Log Message: Move arch/i386/i386/freebsd_* into compat/freebsd/. COMPAT_FREEBSD is i386-specific. To generate a diff of this commit: cvs rdiff -u -r1.382 -r1.383 src/sys/arch/i386/conf/files.i386 cvs rdiff -u -r1.60 -r0 src/sys/arch/i386/i386/freebsd_machdep.c cvs rdiff -u -r1.5 -r0 src/sys/arch/i386/i386/freebsd_sigcode.S cvs rdiff -u -r1.40 -r0 src/sys/arch/i386/i386/freebsd_syscall.c cvs rdiff -u -r1.151 -r1.152 src/sys/arch/xen/conf/files.xen cvs rdiff -u -r1.14 -r1.15 src/sys/compat/freebsd/files.freebsd cvs rdiff -u -r0 -r1.1 src/sys/compat/freebsd/freebsd_machdep.c \ src/sys/compat/freebsd/freebsd_sigcode.S \ src/sys/compat/freebsd/freebsd_syscall.c cvs rdiff -u -r1.4 -r1.5 src/sys/modules/compat_freebsd/Makefile Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/i386/conf/files.i386 diff -u src/sys/arch/i386/conf/files.i386:1.382 src/sys/arch/i386/conf/files.i386:1.383 --- src/sys/arch/i386/conf/files.i386:1.382 Tue Aug 1 13:47:49 2017 +++ src/sys/arch/i386/conf/files.i386 Tue Aug 1 14:43:54 2017 @@ -1,4 +1,4 @@ -# $NetBSD: files.i386,v 1.382 2017/08/01 13:47:49 maxv Exp $ +# $NetBSD: files.i386,v 1.383 2017/08/01 14:43:54 maxv Exp $ # # new style config file for i386 architecture # @@ -340,9 +340,6 @@ file arch/x86/x86/linux_trap.c compat_l # FreeBSD binary compatibility (COMPAT_FREEBSD) include "compat/freebsd/files.freebsd" -file arch/i386/i386/freebsd_machdep.c compat_freebsd -file arch/i386/i386/freebsd_sigcode.S compat_freebsd -file arch/i386/i386/freebsd_syscall.c compat_freebsd # NDIS compatibilty (COMPAT_NDIS) include "compat/ndis/files.ndis" Index: src/sys/arch/xen/conf/files.xen diff -u src/sys/arch/xen/conf/files.xen:1.151 src/sys/arch/xen/conf/files.xen:1.152 --- src/sys/arch/xen/conf/files.xen:1.151 Tue Aug 1 13:47:49 2017 +++ src/sys/arch/xen/conf/files.xen Tue Aug 1 14:43:54 2017 @@ -1,4 +1,4 @@ -# $NetBSD: files.xen,v 1.151 2017/08/01 13:47:49 maxv Exp $ +# $NetBSD: files.xen,v 1.152 2017/08/01 14:43:54 maxv Exp $ # NetBSD: files.x86,v 1.10 2003/10/08 17:30:00 bouyer Exp # NetBSD: files.i386,v 1.254 2004/03/25 23:32:10 jmc Exp @@ -334,9 +334,6 @@ file arch/x86/x86/linux_trap.c compat_l # FreeBSD binary compatibility (COMPAT_FREEBSD) include "compat/freebsd/files.freebsd" -file arch/i386/i386/freebsd_machdep.c compat_freebsd -file arch/i386/i386/freebsd_sigcode.S compat_freebsd -file arch/i386/i386/freebsd_syscall.c compat_freebsd elifdef amd64 Index: src/sys/compat/freebsd/files.freebsd diff -u src/sys/compat/freebsd/files.freebsd:1.14 src/sys/compat/freebsd/files.freebsd:1.15 --- src/sys/compat/freebsd/files.freebsd:1.14 Sat Jul 29 10:39:48 2017 +++ src/sys/compat/freebsd/files.freebsd Tue Aug 1 14:43:54 2017 @@ -1,10 +1,7 @@ -# $NetBSD: files.freebsd,v 1.14 2017/07/29 10:39:48 maxv Exp $ +# $NetBSD: files.freebsd,v 1.15 2017/08/01 14:43:54 maxv Exp $ # # Config file description for machine-independent FreeBSD compat code. -# Included by ports that need it. - -# ports should define any machine-specific files they need in their -# own file lists. +# Included by ports that need it. Only i386 is supported. define compat_freebsd file compat/freebsd/freebsd_exec.c compat_freebsd @@ -13,10 +10,14 @@ file compat/freebsd/freebsd_file.c comp file compat/freebsd/freebsd_fork.c compat_freebsd file compat/freebsd/freebsd_ioctl.c compat_freebsd file compat/freebsd/freebsd_ipc.c compat_freebsd +file compat/freebsd/freebsd_machdep.c compat_freebsd file compat/freebsd/freebsd_misc.c compat_freebsd file compat/freebsd/freebsd_mod.c compat_freebsd file compat/freebsd/freebsd_ptrace.c compat_freebsd & ptrace file compat/freebsd/freebsd_sched.c compat_freebsd +file compat/freebsd/freebsd_sigcode.S compat_freebsd file compat/freebsd/freebsd_sysctl.c compat_freebsd file compat/freebsd/freebsd_sysent.c compat_freebsd file compat/freebsd/freebsd_syscalls.c compat_freebsd +file compat/freebsd/freebsd_syscall.c compat_freebsd + Index: src/sys/modules/compat_freebsd/Makefile diff -u src/sys/modules/compat_freebsd/Makefile:1.4 src/sys/modules/compat_freebsd/Makefile:1.5 --- src/sys/modules/compat_freebsd/Makefile:1.4 Sat Jul 29 10:39:48 2017 +++ src/sys/modules/compat_freebsd/Makefile Tue Aug 1 14:43:54 2017 @@ -1,4 +1,4 @@ -# $NetBSD: Makefile,v 1.4 2017/07/29 10:39:48 maxv Exp $ +# $NetBSD: Makefile,v 1.5 2017/08/01 14:43:54 maxv Exp $ .include "../Makefile.inc" .include "../Makefile.assym" @@ -17,7 +17,6 @@ SRCS+= freebsd_sysctl.c freebsd_sysent.c .if ${MACHINE_ARCH} == "i386" CPPFLAGS+= -DEXEC_ELF32 -.PATH: ${S}/arch/i386/i386 SRCS+= freebsd_machdep.c freebsd_syscall.c freebsd_sigcode.S .endif Added files: Index: src/sys/compat/freebsd/freebsd_machdep.c diff -u /dev/null src/sys/compat/freebsd/freebsd_machdep.c:1.1 --- /dev/null Tue Aug 1 14:43:55 2017 +++ src/sys/compat/freebsd/freebsd_machdep.c Tue Aug 1 14:43:54 2017 @@ -0,0 +1,252 @@ +/* $NetBSD: freebsd_machdep.c,v 1.1 2017/08/01 14:43:54 maxv Exp $ */ + +/*- + * Copyright (c) 1998, 2000 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Charles M. Hannum. + * + * 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. + */ + +#include <sys/cdefs.h> +__KERNEL_RCSID(0, "$NetBSD: freebsd_machdep.c,v 1.1 2017/08/01 14:43:54 maxv Exp $"); + +#if defined(_KERNEL_OPT) +#include "opt_vm86.h" +#endif + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/signalvar.h> +#include <sys/proc.h> +#include <sys/exec.h> +#include <sys/mount.h> + +#include <compat/sys/signal.h> + +#include <machine/cpufunc.h> +#include <x86/fpu.h> +#include <machine/reg.h> +#include <machine/vm86.h> +#include <machine/vmparam.h> +#include <machine/freebsd_machdep.h> + + +#include <compat/freebsd/freebsd_syscallargs.h> +#include <compat/freebsd/freebsd_exec.h> +#include <compat/freebsd/freebsd_signal.h> + +void +freebsd_setregs(struct lwp *l, struct exec_package *epp, vaddr_t stack) +{ + + setregs(l, epp, stack); + fpu_set_default_cw(l, __FreeBSD_NPXCW__); +} + +/* + * signal support + */ + +/* + * Send an interrupt to process. + * + * Stack is set up to allow sigcode stored + * in u. to call routine, followed by kcall + * to sigreturn routine below. After sigreturn + * resets the signal mask, the stack, and the + * frame pointer, it returns to the user + * specified pc, psl. + */ +void +freebsd_sendsig(const ksiginfo_t *ksi, const sigset_t *mask) +{ + int sig = ksi->ksi_signo; + u_long code = KSI_TRAPCODE(ksi); + struct lwp *l = curlwp; + struct proc *p = l->l_proc; + int onstack, error; + struct freebsd_sigframe *fp = getframe(l, sig, &onstack), frame; + sig_t catcher = SIGACTION(p, sig).sa_handler; + struct trapframe *tf = l->l_md.md_regs; + + fp--; + + /* Build stack frame for signal trampoline. */ + frame.sf_signum = sig; + frame.sf_code = code; + frame.sf_scp = &fp->sf_sc; + frame.sf_addr = (char *)rcr2(); + frame.sf_handler = catcher; + + /* Save context. */ +#ifdef VM86 + if (tf->tf_eflags & PSL_VM) { + frame.sf_sc.sc_gs = tf->tf_vm86_gs; + frame.sf_sc.sc_fs = tf->tf_vm86_fs; + frame.sf_sc.sc_es = tf->tf_vm86_es; + frame.sf_sc.sc_ds = tf->tf_vm86_ds; + frame.sf_sc.sc_efl = get_vflags(l); + (*p->p_emul->e_syscall_intern)(p); + } else +#endif + { + frame.sf_sc.sc_gs = tf->tf_gs; + frame.sf_sc.sc_fs = tf->tf_fs; + frame.sf_sc.sc_es = tf->tf_es; + frame.sf_sc.sc_ds = tf->tf_ds; + frame.sf_sc.sc_efl = tf->tf_eflags; + } + frame.sf_sc.sc_edi = tf->tf_edi; + frame.sf_sc.sc_esi = tf->tf_esi; + frame.sf_sc.sc_ebp = tf->tf_ebp; + frame.sf_sc.sc_isp = 0; /* don't have to pass kernel sp to user. */ + frame.sf_sc.sc_ebx = tf->tf_ebx; + frame.sf_sc.sc_edx = tf->tf_edx; + frame.sf_sc.sc_ecx = tf->tf_ecx; + frame.sf_sc.sc_eax = tf->tf_eax; + frame.sf_sc.sc_eip = tf->tf_eip; + frame.sf_sc.sc_cs = tf->tf_cs; + frame.sf_sc.sc_esp = tf->tf_esp; + frame.sf_sc.sc_ss = tf->tf_ss; + + /* Save signal stack. */ + frame.sf_sc.sc_onstack = l->l_sigstk.ss_flags & SS_ONSTACK; + + /* Save signal mask. */ + /* XXX freebsd_osigcontext compat? */ + frame.sf_sc.sc_mask = *mask; + + sendsig_reset(l, sig); + + mutex_exit(p->p_lock); + error = copyout(&frame, fp, sizeof(frame)); + mutex_enter(p->p_lock); + + if (error != 0) { + /* + * Process has trashed its stack; give it an illegal + * instruction to halt it in its tracks. + */ + sigexit(l, SIGILL); + /* NOTREACHED */ + } + + buildcontext(l, GUCODEBIG_SEL, p->p_sigctx.ps_sigcode, fp); + + /* Remember that we're now on the signal stack. */ + if (onstack) + l->l_sigstk.ss_flags |= SS_ONSTACK; +} + +/* + * System call to cleanup state after a signal + * has been taken. Reset signal mask and + * stack state from context left by sendsig (above). + * Return to previous pc and psl as specified by + * context left by sendsig. Check carefully to + * make sure that the user has not modified the + * psl to gain improper privileges or to cause + * a machine fault. + */ +int +freebsd_sys_sigreturn(struct lwp *l, const struct freebsd_sys_sigreturn_args *uap, register_t *retval) +{ + /* { + syscallarg(struct freebsd_sigcontext *) scp; + } */ + struct proc *p = l->l_proc; + struct freebsd_sigcontext *scp, context; + struct trapframe *tf; + sigset_t mask; + + /* + * The trampoline code hands us the context. + * It is unsafe to keep track of it ourselves, in the event that a + * program jumps out of a signal handler. + */ + scp = SCARG(uap, scp); + if (copyin((void *)scp, &context, sizeof(*scp)) != 0) + return (EFAULT); + + /* Restore register context. */ + tf = l->l_md.md_regs; +#ifdef VM86 + if (context.sc_efl & PSL_VM) { + void syscall_vm86(struct trapframe *); + + tf->tf_vm86_gs = context.sc_gs; + tf->tf_vm86_fs = context.sc_fs; + tf->tf_vm86_es = context.sc_es; + tf->tf_vm86_ds = context.sc_ds; + set_vflags(l, context.sc_efl); + p->p_md.md_syscall = syscall_vm86; + } else +#endif + { + /* + * Check for security violations. If we're returning to + * protected mode, the CPU will validate the segment registers + * automatically and generate a trap on violations. We handle + * the trap, rather than doing all of the checking here. + */ + if (((context.sc_efl ^ tf->tf_eflags) & PSL_USERSTATIC) != 0 || + !USERMODE(context.sc_cs, context.sc_efl)) + return (EINVAL); + + tf->tf_gs = context.sc_gs; + tf->tf_fs = context.sc_fs; + tf->tf_es = context.sc_es; + tf->tf_ds = context.sc_ds; + tf->tf_eflags &= ~PSL_USER; + tf->tf_eflags |= context.sc_efl & PSL_USER; + } + tf->tf_edi = context.sc_edi; + tf->tf_esi = context.sc_esi; + tf->tf_ebp = context.sc_ebp; + /* FreeBSD's context.sc_isp is useless. (`popal' ignores it.) */ + tf->tf_ebx = context.sc_ebx; + tf->tf_edx = context.sc_edx; + tf->tf_ecx = context.sc_ecx; + tf->tf_eax = context.sc_eax; + tf->tf_eip = context.sc_eip; + tf->tf_cs = context.sc_cs; + tf->tf_esp = context.sc_esp; + tf->tf_ss = context.sc_ss; + + mutex_enter(p->p_lock); + /* Restore signal stack. */ + if (context.sc_onstack & SS_ONSTACK) + l->l_sigstk.ss_flags |= SS_ONSTACK; + else + l->l_sigstk.ss_flags &= ~SS_ONSTACK; + /* Restore signal mask. */ + /* XXX freebsd_osigcontext compat? */ + mask = context.sc_mask; + (void) sigprocmask1(l, SIG_SETMASK, &mask, 0); + mutex_exit(p->p_lock); + + return (EJUSTRETURN); +} + Index: src/sys/compat/freebsd/freebsd_sigcode.S diff -u /dev/null src/sys/compat/freebsd/freebsd_sigcode.S:1.1 --- /dev/null Tue Aug 1 14:43:55 2017 +++ src/sys/compat/freebsd/freebsd_sigcode.S Tue Aug 1 14:43:54 2017 @@ -0,0 +1,91 @@ +/* $NetBSD: freebsd_sigcode.S,v 1.1 2017/08/01 14:43:54 maxv Exp $ */ + +/*- + * Copyright (c) 1998 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Charles M. Hannum. + * + * 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. + */ + +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * William Jolitz. + * + * 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. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. + * + * @(#)locore.s 7.3 (Berkeley) 5/13/91 + */ + +#include <machine/asm.h> +__KERNEL_RCSID(0, "$NetBSD: freebsd_sigcode.S,v 1.1 2017/08/01 14:43:54 maxv Exp $"); + +#include "assym.h" + +#include <sys/errno.h> +#include <sys/syscall.h> + +#include <compat/freebsd/freebsd_syscall.h> + +/* + * Signal trampoline; copied to top of user stack. + */ +/* LINTSTUB: Var: char freebsd_sigcode[1], freebsd_esigcode[1]; */ +NENTRY(freebsd_sigcode) + call *FREEBSD_SIGF_HANDLER(%esp) + leal FREEBSD_SIGF_SC(%esp),%eax # scp (the call may have clobbered + # the copy at SIGF_SCP(%esp)) + pushl %eax + pushl %eax # junk to fake return address + movl $FREEBSD_SYS_sigreturn,%eax + int $0x80 # enter kernel with args on stack + movl $FREEBSD_SYS_exit,%eax + int $0x80 # exit if sigreturn fails + .globl _C_LABEL(freebsd_esigcode) +_C_LABEL(freebsd_esigcode): Index: src/sys/compat/freebsd/freebsd_syscall.c diff -u /dev/null src/sys/compat/freebsd/freebsd_syscall.c:1.1 --- /dev/null Tue Aug 1 14:43:55 2017 +++ src/sys/compat/freebsd/freebsd_syscall.c Tue Aug 1 14:43:54 2017 @@ -0,0 +1,150 @@ +/* $NetBSD: freebsd_syscall.c,v 1.1 2017/08/01 14:43:54 maxv Exp $ */ + +/*- + * Copyright (c) 1998, 2000 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Charles M. Hannum. + * + * 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. + */ + +#include <sys/cdefs.h> +__KERNEL_RCSID(0, "$NetBSD: freebsd_syscall.c,v 1.1 2017/08/01 14:43:54 maxv Exp $"); + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/proc.h> +#include <sys/signal.h> +#include <sys/syscall.h> +#include <sys/syscallvar.h> + +#include <uvm/uvm_extern.h> + +#include <machine/cpu.h> +#include <machine/psl.h> +#include <machine/userret.h> + +#include <compat/sys/signal.h> + +#include <machine/freebsd_machdep.h> +#include <compat/freebsd/freebsd_syscall.h> + +void freebsd_syscall(struct trapframe *); + +void +freebsd_syscall_intern(struct proc *p) +{ + + p->p_md.md_syscall = freebsd_syscall; +} + +/* + * syscall(frame): + * System call request from POSIX system call gate interface to kernel. + * Like trap(), argument is call by reference. + */ +void +freebsd_syscall(struct trapframe *frame) +{ + char *params; + const struct sysent *callp; + struct lwp *l; + struct proc *p; + int error; + size_t argsize; + register_t code, args[8], rval[2]; + + l = curlwp; + p = l->l_proc; + LWP_CACHE_CREDS(l, p); + + code = frame->tf_eax; + callp = p->p_emul->e_sysent; + params = (char *)frame->tf_esp + sizeof(int); + + switch (code) { + case SYS_syscall: + /* + * Code is first argument, followed by actual args. + */ + code = fuword(params); + params += sizeof(int); + break; + case SYS___syscall: + /* + * Like syscall, but code is a quad, so as to maintain + * quad alignment for the rest of the arguments. + */ + code = fuword(params + _QUAD_LOWWORD * sizeof(int)); + params += sizeof(quad_t); + break; + default: + break; + } + + code &= (SYS_NSYSENT - 1); + callp += code; + argsize = callp->sy_argsize; + if (argsize) { + error = copyin(params, (void *)args, argsize); + if (error) + goto bad; + } + + if (!__predict_false(p->p_trace_enabled || KDTRACE_ENTRY(callp->sy_entry)) + || (error = trace_enter(code, callp, args)) == 0) { + rval[0] = 0; + rval[1] = frame->tf_edx; /* need to keep edx for shared FreeBSD bins */ + error = sy_call(callp, l, args, rval); + } + + switch (error) { + case 0: + frame->tf_eax = rval[0]; + frame->tf_edx = rval[1]; + frame->tf_eflags &= ~PSL_C; /* carry bit */ + break; + case ERESTART: + /* + * The offset to adjust the PC by depends on whether we entered + * the kernel through the trap or call gate. We pushed the + * size of the instruction into tf_err on entry. + */ + frame->tf_eip -= frame->tf_err; + break; + case EJUSTRETURN: + /* nothing to do */ + break; + default: + bad: + frame->tf_eax = error; + frame->tf_eflags |= PSL_C; /* carry bit */ + break; + } + + if (__predict_false(p->p_trace_enabled || KDTRACE_ENTRY(callp->sy_return))) + trace_exit(code, callp, args, rval, error); + + userret(l); +}