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