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