1114987Speter/*-
2114987Speter * Copyright (c) 2003 Peter Wemm
3114987Speter * All rights reserved.
4114987Speter *
5114987Speter * Redistribution and use in source and binary forms, with or without
6114987Speter * modification, are permitted provided that the following conditions
7114987Speter * are met:
8114987Speter * 1. Redistributions of source code must retain the above copyright
9114987Speter *    notice, this list of conditions and the following disclaimer.
10114987Speter * 2. Redistributions in binary form must reproduce the above copyright
11114987Speter *    notice, this list of conditions and the following disclaimer in the
12114987Speter *    documentation and/or other materials provided with the distribution.
13114987Speter *
14114987Speter * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15114987Speter * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16114987Speter * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17114987Speter * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18114987Speter * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19114987Speter * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20114987Speter * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21114987Speter * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22114987Speter * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23114987Speter * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24114987Speter * SUCH DAMAGE.
25114987Speter *
26114987Speter * $FreeBSD: releng/10.2/sys/amd64/ia32/ia32_sigtramp.S 276601 2015-01-03 01:41:10Z kib $
27114987Speter */
28114987Speter
29114987Speter#include "opt_compat.h"
30114987Speter
31114987Speter#include <machine/asmacros.h>
32114987Speter#include <sys/syscall.h>
33114987Speter
34114987Speter#include "ia32_assym.h"
35114987Speter
36114987Speter	.text
37114987Speter	.code32
38114987Speter/*
39114987Speter * Signal trampoline, copied to top of user stack
40119334Speter * XXX may need to be MD to match backend sendsig handoff protocol
41114987Speter */
42114987Speter	ALIGN_TEXT
43114987Speter	.globl	ia32_sigcode
44114987Speteria32_sigcode:
45114987Speter	calll	*IA32_SIGF_HANDLER(%esp)
46114987Speter	leal	IA32_SIGF_UC(%esp),%eax	/* get ucontext */
47114987Speter	pushl	%eax
48114987Speter	movl	$SYS_sigreturn,%eax
49114987Speter	pushl	%eax			/* junk to fake return addr. */
50114987Speter	int	$0x80			/* enter kernel with args */
51114987Speter					/* on stack */
52114987Speter1:
53114987Speter	jmp	1b
54114987Speter
55114987Speter#ifdef COMPAT_FREEBSD4
56114987Speter	ALIGN_TEXT
57114987Speterfreebsd4_ia32_sigcode:
58114987Speter	calll	*IA32_SIGF_HANDLER(%esp)
59114987Speter	leal	IA32_SIGF_UC4(%esp),%eax/* get ucontext */
60114987Speter	pushl	%eax
61114987Speter	movl	$344,%eax		/* 4.x SYS_sigreturn */
62114987Speter	pushl	%eax			/* junk to fake return addr. */
63114987Speter	int	$0x80			/* enter kernel with args */
64114987Speter					/* on stack */
65114987Speter1:
66114987Speter	jmp	1b
67114987Speter#endif
68114987Speter
69220238Skib#ifdef COMPAT_43
70114987Speter	ALIGN_TEXT
71220238Skibia32_osigcode:
72220238Skib	calll	*IA32_SIGF_HANDLER(%esp)/* call signal handler */
73220238Skib	leal	IA32_SIGF_SC(%esp),%eax	/* get sigcontext */
74220238Skib	pushl	%eax
75220238Skib	movl	$103,%eax		/* 3.x SYS_sigreturn */
76220238Skib	pushl	%eax			/* junk to fake return addr. */
77220238Skib	int	$0x80			/* enter kernel with args */
78220238Skib1:
79220238Skib	jmp	1b
80220238Skib
81220238Skib
82223254Skib/*
83223254Skib * The lcall $7,$0 emulator cannot use the call gate that does an
84223254Skib * inter-privilege transition. The reason is that the call gate
85223254Skib * does not disable interrupts, and, before the swapgs is
86223254Skib * executed, we would have a window where the ring 0 code is
87223254Skib * executed with the wrong gsbase.
88223254Skib *
89276601Skib * Instead, set LDT descriptor 0 as code segment, which reflects
90276601Skib * the lcall $7,$0 back to ring 3 trampoline.  The trampoline sets up
91276601Skib * the frame for int $0x80.
92223254Skib */
93220238Skib	ALIGN_TEXT
94220238Skiblcall_tramp:
95223254Skib	cmpl	$SYS_vfork,%eax
96276601Skib	je	1f
97220238Skib	pushl	%ebp
98220238Skib	movl	%esp,%ebp
99220238Skib	pushl	0x24(%ebp) /* arg 6 */
100220238Skib	pushl	0x20(%ebp)
101220238Skib	pushl	0x1c(%ebp)
102220238Skib	pushl	0x18(%ebp)
103220238Skib	pushl	0x14(%ebp)
104220238Skib	pushl	0x10(%ebp) /* arg 1 */
105276601Skib	subl	$4,%esp   /* gap */
106220238Skib	int	$0x80
107223254Skib	leavel
108220238Skib	lretl
109276601Skib1:
110223254Skib	/*
111223254Skib	 * vfork handling is special and relies on the libc stub saving
112276601Skib	 * the return ip in %ecx.  Also, we assume that the call was done
113276601Skib	 * with ucode32 selector in %cs.
114223254Skib	 */
115223254Skib	int	$0x80
116276601Skib	movl	$0x33,4(%esp)	/* GUCODE32_SEL | SEL_UPL */
117276601Skib	movl	%ecx,(%esp)
118276601Skib	lretl
119220238Skib#endif
120220238Skib
121220238Skib	ALIGN_TEXT
122114987Speteresigcode:
123114987Speter
124114987Speter	.data
125114987Speter	.globl	sz_ia32_sigcode
126114987Spetersz_ia32_sigcode:
127114987Speter	.long	esigcode-ia32_sigcode
128114987Speter#ifdef COMPAT_FREEBSD4
129114987Speter	.globl	sz_freebsd4_ia32_sigcode
130114987Spetersz_freebsd4_ia32_sigcode:
131114987Speter	.long	esigcode-freebsd4_ia32_sigcode
132114987Speter#endif
133220238Skib#ifdef COMPAT_43
134220238Skib	.globl	sz_ia32_osigcode
135220238Skibsz_ia32_osigcode:
136220238Skib	.long	esigcode-ia32_osigcode
137220238Skib	.globl	sz_lcall_tramp
138220238Skibsz_lcall_tramp:
139220238Skib	.long	esigcode-lcall_tramp
140220238Skib#endif
141