Changeset View
Standalone View
sys/amd64/amd64/sigtramp.S
/*- | /*- | |||||||||
* Copyright (c) 2003 Peter Wemm <peter@freeBSD.org> | * Copyright (c) 2003 Peter Wemm <peter@freeBSD.org> | |||||||||
* 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 9 Lines | ||||||||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | * 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 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||||||||
* SUCH DAMAGE. | * SUCH DAMAGE. | |||||||||
* | * | |||||||||
* $FreeBSD$ | * $FreeBSD$ | |||||||||
*/ | */ | |||||||||
#include <sys/syscall.h> | #include <sys/syscall.h> | |||||||||
#include <machine/asmacros.h> | #include <machine/asmacros.h> | |||||||||
#include "assym.inc" | #include "assym.inc" | |||||||||
.text | .text | |||||||||
/********************************************************************** | /* | |||||||||
* | * Signal trampoline, mapped as vdso into shared page. | |||||||||
* Signal trampoline, copied to top of user stack | ||||||||||
* | ||||||||||
*/ | */ | |||||||||
ENTRY(sigcode) | ENTRY(__vdso_sigcode) | |||||||||
.cfi_startproc | ||||||||||
.cfi_signal_frame | ||||||||||
.cfi_def_cfa %rsp, 0 | ||||||||||
.cfi_offset %rdi, SIGF_UC + UC_RDI | ||||||||||
emaste: I did not verify these | ||||||||||
Done Inline ActionsYou mean, you did not checked the layout of the frame, or you did not verified that unwinding around signal frame work? First fact is more or less about matching register name and corresponding UC_XXX offset name. Second is tough, indeed. For instance, gdb, lldb, non-gnu libunwind match signal handler by comparing code sequence with the known one, so this change seems to be nop for them. On the other hand, in-tree unwinder from libgcc_s was able to catch an exception thrown from a signal handler context. kib: You mean, you did not checked the layout of the frame, or you did not verified that unwinding… | ||||||||||
.cfi_offset %rsi, SIGF_UC + UC_RSI | ||||||||||
.cfi_offset %rdx, SIGF_UC + UC_RDX | ||||||||||
.cfi_offset %rcx, SIGF_UC + UC_RCX | ||||||||||
.cfi_offset %r8, SIGF_UC + UC_R8 | ||||||||||
.cfi_offset %r9, SIGF_UC + UC_R9 | ||||||||||
.cfi_offset %rax, SIGF_UC + UC_RAX | ||||||||||
.cfi_offset %rbx, SIGF_UC + UC_RBX | ||||||||||
.cfi_offset %rbp, SIGF_UC + UC_RBP | ||||||||||
.cfi_offset %r10, SIGF_UC + UC_R10 | ||||||||||
.cfi_offset %r11, SIGF_UC + UC_R11 | ||||||||||
.cfi_offset %r12, SIGF_UC + UC_R12 | ||||||||||
.cfi_offset %r13, SIGF_UC + UC_R13 | ||||||||||
.cfi_offset %r14, SIGF_UC + UC_R14 | ||||||||||
.cfi_offset %r15, SIGF_UC + UC_R15 | ||||||||||
#if 0 | ||||||||||
.cfi_offset %fs, SIGF_UC + UC_FS | ||||||||||
Done Inline ActionsAre there CFI annotations for segment registers, fsbase, gsbase, and eflags? (Those are all present in ucontext_t as well and a recent change I have for GDB pulls all of those out of signal frames.) jhb: Are there CFI annotations for segment registers, fsbase, gsbase, and eflags? (Those are all… | ||||||||||
Done Inline ActionsAll listed registers have DWARF register mapping number assigned to them in psABI, so there is a way to specify that in final object. But trying to actually do that resulted in the mess. For instance, i386 psABI specifies 93 as %fs.base, but binutils interpret it as %k0. Clang IAS does know about all segment names, but objdump from binutils report all encoded registers as invalid then. And so on. The only semi-consistent pseudo-registers seems to be fs/gs.base on x86_64, but even there clang managed to fail, it does not recognize the registers name, and I have to use numeric value. On the other hand, I am sure that %eflags are not useful for unwinders, and doubt that segment registers or fs/gsbase are useful. I think really doing that would require some iterations with toolchain maintainers, for now I commented out cfi instructions for segments/flags everywhere, and bases on 32bit. kib: All listed registers have DWARF register mapping number assigned to them in psABI, so there is… | ||||||||||
Not Done Inline ActionsThis is mostly for debuggers and when inspecting in core dumps. That said, GDB will keep using its own unwinder that will unwind all those registers ok even with out CFI (so long as we don't change the sigcode so the sigframe unwinder keeps matching). %eflags is possibly useful when debugging a core dump where a thread had caught a signal and you want to see the register state at the time of the faulting instruction, but that is definitely an obscure case. GDB uses fsbase/gsbase for TLS on amd64/i386, but those likely don't change between the signal handler and the signal frame so missing those is less important. My other interest is around using CFI for kernel exception frames as that removes the need for custom unwinders in kernel debuggers, but when I last tried that I found I couldn't annotate all of the registers (for some reason I couldn't annotate %eflags at the time. and probably it is what you ran into which is that there is a DWARF register number but IAS doesn't support it). jhb: This is mostly for debuggers and when inspecting in core dumps. That said, GDB will keep using… | ||||||||||
.cfi_offset %gs, SIGF_UC + UC_GS | ||||||||||
.cfi_offset %es, SIGF_UC + UC_ES | ||||||||||
.cfi_offset %ds, SIGF_UC + UC_DS | ||||||||||
#endif | ||||||||||
.cfi_offset %rip, SIGF_UC + UC_RIP | ||||||||||
#if 0 | ||||||||||
Done Inline Actions
Fixed locally. kib: Fixed locally. | ||||||||||
.cfi_offset %cs, SIGF_UC + UC_CS | ||||||||||
.cfi_offset %flags, SIGF_UC + UC_RFLAGS | ||||||||||
#endif | ||||||||||
.cfi_offset %rsp, SIGF_UC + UC_RSP | ||||||||||
#if 0 | ||||||||||
.cfi_offset %ss, SIGF_UC + UC_SS | ||||||||||
#endif | ||||||||||
.cfi_offset 58 /* %fs.base */, SIGF_UC + UC_FSBASE | ||||||||||
.cfi_offset 59 /* %gs.base */, SIGF_UC + UC_GSBASE | ||||||||||
call *SIGF_HANDLER(%rsp) /* call signal handler */ | call *SIGF_HANDLER(%rsp) /* call signal handler */ | |||||||||
lea SIGF_UC(%rsp),%rdi /* get ucontext_t */ | lea SIGF_UC(%rsp),%rdi /* get ucontext_t */ | |||||||||
pushq $0 /* junk to fake return addr. */ | pushq $0 /* junk to fake return addr. */ | |||||||||
.cfi_def_cfa %rsp, 8 | ||||||||||
movq $SYS_sigreturn,%rax | movq $SYS_sigreturn,%rax | |||||||||
syscall /* enter kernel with args */ | syscall /* enter kernel with args */ | |||||||||
0: hlt /* trap priviliged instruction */ | 0: hlt /* trap priviliged instruction */ | |||||||||
jmp 0b | jmp 0b | |||||||||
.cfi_endproc | ||||||||||
END(__vdso_sigcode) | ||||||||||
ALIGN_TEXT | .section .note.GNU-stack,"",%progbits | |||||||||
esigcode: | ||||||||||
.data | ||||||||||
.globl szsigcode | ||||||||||
szsigcode: | ||||||||||
.long esigcode-sigcode |
I did not verify these