Changeset View
Changeset View
Standalone View
Standalone View
sys/amd64/ia32/ia32_sigtramp.S
/*- | /*- | ||||
* Copyright (c) 2003 Peter Wemm | * Copyright (c) 2003 Peter Wemm | ||||
* All rights reserved. | * All rights reserved. | ||||
* | * | ||||
* Copyright (c) 2021 The FreeBSD Foundation | |||||
* | |||||
* Portions of this software were developed by Konstantin Belousov | |||||
* under sponsorship from the FreeBSD Foundation. | |||||
* | |||||
* Redistribution and use in source and binary forms, with or without | * Redistribution and use in source and binary forms, with or without | ||||
* modification, are permitted provided that the following conditions | * modification, are permitted provided that the following conditions | ||||
* are met: | * are met: | ||||
* 1. Redistributions of source code must retain the above copyright | * 1. Redistributions of source code must retain the above copyright | ||||
* notice, this list of conditions and the following disclaimer. | * notice, this list of conditions and the following disclaimer. | ||||
* 2. Redistributions in binary form must reproduce the above copyright | * 2. Redistributions in binary form must reproduce the above copyright | ||||
* notice, this list of conditions and the following disclaimer in the | * notice, this list of conditions and the following disclaimer in the | ||||
* documentation and/or other materials provided with the distribution. | * documentation and/or other materials provided with the distribution. | ||||
Show All 14 Lines | |||||
*/ | */ | ||||
#include <machine/asmacros.h> | #include <machine/asmacros.h> | ||||
#include <sys/syscall.h> | #include <sys/syscall.h> | ||||
#include "ia32_assym.h" | #include "ia32_assym.h" | ||||
.text | .text | ||||
.code32 | |||||
/* | /* | ||||
* Signal trampoline, copied to top of user stack | * Signal trampoline, mapped as vdso into shared page, or copied to | ||||
* XXX may need to be MD to match backend sendsig handoff protocol | * top of user stack for old binaries. | ||||
*/ | */ | ||||
ALIGN_TEXT | ALIGN_TEXT | ||||
.globl ia32_sigcode | .globl __vdso_ia32_sigcode | ||||
ia32_sigcode: | __vdso_ia32_sigcode: | ||||
.cfi_startproc | |||||
.cfi_signal_frame | |||||
.cfi_def_cfa %esp, 0 | |||||
#if 0 | |||||
.cfi_offset %gs, IA32_SIGF_UC + IA32_UC_GS | |||||
emaste: did not verify these | |||||
.cfi_offset %fs, IA32_SIGF_UC + IA32_UC_FS | |||||
.cfi_offset %es, IA32_SIGF_UC + IA32_UC_ES | |||||
.cfi_offset %ds, IA32_SIGF_UC + IA32_UC_DS | |||||
#endif | |||||
.cfi_offset %edi, IA32_SIGF_UC + IA32_UC_EDI | |||||
.cfi_offset %esi, IA32_SIGF_UC + IA32_UC_ESI | |||||
.cfi_offset %ebp, IA32_SIGF_UC + IA32_UC_EBP | |||||
Done Inline ActionsSimilar question about segment registers, fsbase/gsbase (GDB uses those for TLS), and flags. jhb: Similar question about segment registers, fsbase/gsbase (GDB uses those for TLS), and flags. | |||||
.cfi_offset %ebx, IA32_SIGF_UC + IA32_UC_EBX | |||||
.cfi_offset %edx, IA32_SIGF_UC + IA32_UC_EDX | |||||
.cfi_offset %ecx, IA32_SIGF_UC + IA32_UC_ECX | |||||
.cfi_offset %eax, IA32_SIGF_UC + IA32_UC_EAX | |||||
.cfi_offset %eip, IA32_SIGF_UC + IA32_UC_EIP | |||||
#if 0 | |||||
.cfi_offset %cs, IA32_SIGF_UC + IA32_UC_CS | |||||
.cfi_offset %flags, IA32_SIGF_UC + IA32_UC_EFLAGS | |||||
#endif | |||||
.cfi_offset %esp, IA32_SIGF_UC + IA32_UC_ESP | |||||
#if 0 | |||||
.cfi_offset %ss, IA32_SIGF_UC + IA32_UC_SS | |||||
.cfi_offset 93 /* %fs.base */, IA32_SIGF_UC + IA32_UC_FSBASE | |||||
.cfi_offset 94 /* %gs.base */, IA32_SIGF_UC + IA32_UC_GSBASE | |||||
#endif | |||||
calll *IA32_SIGF_HANDLER(%esp) | calll *IA32_SIGF_HANDLER(%esp) | ||||
leal IA32_SIGF_UC(%esp),%eax /* get ucontext */ | leal IA32_SIGF_UC(%esp),%eax /* get ucontext */ | ||||
pushl %eax | pushl %eax | ||||
.cfi_def_cfa %esp, 4 | |||||
movl $SYS_sigreturn,%eax | movl $SYS_sigreturn,%eax | ||||
pushl %eax /* junk to fake return addr. */ | pushl %eax /* junk to fake return addr. */ | ||||
.cfi_def_cfa %esp, 8 | |||||
int $0x80 /* enter kernel with args */ | int $0x80 /* enter kernel with args */ | ||||
/* on stack */ | /* on stack */ | ||||
1: | 1: | ||||
jmp 1b | jmp 1b | ||||
.cfi_endproc | |||||
#ifdef COMPAT_FREEBSD4 | #ifdef COMPAT_FREEBSD4 | ||||
ALIGN_TEXT | ALIGN_TEXT | ||||
freebsd4_ia32_sigcode: | .globl __vdso_freebsd4_ia32_sigcode | ||||
__vdso_freebsd4_ia32_sigcode: | |||||
calll *IA32_SIGF_HANDLER(%esp) | calll *IA32_SIGF_HANDLER(%esp) | ||||
leal IA32_SIGF_UC4(%esp),%eax/* get ucontext */ | leal IA32_SIGF_UC4(%esp),%eax/* get ucontext */ | ||||
pushl %eax | pushl %eax | ||||
movl $344,%eax /* 4.x SYS_sigreturn */ | movl $344,%eax /* 4.x SYS_sigreturn */ | ||||
pushl %eax /* junk to fake return addr. */ | pushl %eax /* junk to fake return addr. */ | ||||
int $0x80 /* enter kernel with args */ | int $0x80 /* enter kernel with args */ | ||||
/* on stack */ | /* on stack */ | ||||
1: | 1: | ||||
jmp 1b | jmp 1b | ||||
#endif | #endif | ||||
#ifdef COMPAT_43 | #ifdef COMPAT_43 | ||||
ALIGN_TEXT | ALIGN_TEXT | ||||
ia32_osigcode: | .globl __vdso_ia32_osigcode | ||||
__vdso_ia32_osigcode: | |||||
calll *IA32_SIGF_HANDLER(%esp)/* call signal handler */ | calll *IA32_SIGF_HANDLER(%esp)/* call signal handler */ | ||||
leal IA32_SIGF_SC(%esp),%eax /* get sigcontext */ | leal IA32_SIGF_SC(%esp),%eax /* get sigcontext */ | ||||
pushl %eax | pushl %eax | ||||
movl $103,%eax /* 3.x SYS_sigreturn */ | movl $103,%eax /* 3.x SYS_sigreturn */ | ||||
pushl %eax /* junk to fake return addr. */ | pushl %eax /* junk to fake return addr. */ | ||||
int $0x80 /* enter kernel with args */ | int $0x80 /* enter kernel with args */ | ||||
1: | 1: | ||||
jmp 1b | jmp 1b | ||||
/* | /* | ||||
* Our lcall $7,$0 handler remains in user mode (ring 3), since lcalls | * Our lcall $7,$0 handler remains in user mode (ring 3), since lcalls | ||||
* don't change the interrupt mask, so if this one went directly to the | * don't change the interrupt mask, so if this one went directly to the | ||||
* kernel then there would be a window with interrupts enabled in kernel | * kernel then there would be a window with interrupts enabled in kernel | ||||
* mode, and all interrupt handlers would have to be almost as complicated | * mode, and all interrupt handlers would have to be almost as complicated | ||||
* as the NMI handler to support this. | * as the NMI handler to support this. | ||||
* | * | ||||
* Instead, convert the lcall to an int0x80 call. The kernel does most | * Instead, convert the lcall to an int0x80 call. The kernel does most | ||||
* of the conversion by popping the lcall return values off the user | * of the conversion by popping the lcall return values off the user | ||||
* stack and returning to them instead of to here, except when the | * stack and returning to them instead of to here, except when the | ||||
* conversion itself fails. Adjusting the stack here is impossible for | * conversion itself fails. Adjusting the stack here is impossible for | ||||
* vfork() and harder for other syscalls. | * vfork() and harder for other syscalls. | ||||
*/ | */ | ||||
ALIGN_TEXT | ALIGN_TEXT | ||||
lcall_tramp: | .globl __vdso_lcall_tramp | ||||
__vdso_lcall_tramp: | |||||
int $0x80 | int $0x80 | ||||
1: jmp 1b | 1: jmp 1b | ||||
#endif | #endif | ||||
.p2align 1 | |||||
ALIGN_TEXT | |||||
esigcode: | |||||
.data | |||||
.globl sz_ia32_sigcode | |||||
sz_ia32_sigcode: | |||||
.long esigcode-ia32_sigcode | |||||
#ifdef COMPAT_FREEBSD4 | |||||
.globl sz_freebsd4_ia32_sigcode | |||||
sz_freebsd4_ia32_sigcode: | |||||
.long esigcode-freebsd4_ia32_sigcode | |||||
#endif | |||||
#ifdef COMPAT_43 | |||||
.globl sz_ia32_osigcode | |||||
sz_ia32_osigcode: | |||||
.long esigcode-ia32_osigcode | |||||
.globl sz_lcall_tramp | |||||
sz_lcall_tramp: | |||||
.long esigcode-lcall_tramp | |||||
#endif |
did not verify these