mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-28 03:58:02 +07:00
arm64: vdso: Fix CFI directives in sigreturn trampoline
Daniel reports that the .cfi_startproc is misplaced for the sigreturn trampoline, which causes LLVM's unwinder to misbehave: | I run into this with LLVM’s unwinder. | This combination was always broken. This prompted Dave to question our use of CFI directives more generally, and I ended up going down a rabbit hole trying to figure out how this very poorly documented stuff gets used. Move the CFI directives so that the "mysterious NOP" is included in the .cfi_{start,end}proc block and add a bunch of comments so that I can save myself another headache in future. Cc: Tamas Zsoldos <tamas.zsoldos@arm.com> Reported-by: Dave Martin <dave.martin@arm.com> Reported-by: Daniel Kiss <daniel.kiss@arm.com> Tested-by: Daniel Kiss <daniel.kiss@arm.com> Signed-off-by: Will Deacon <will@kernel.org>
This commit is contained in:
parent
9a96428557
commit
a4eb355a3f
@ -1,7 +1,11 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Sigreturn trampoline for returning from a signal when the SA_RESTORER
|
||||
* flag is not set.
|
||||
* flag is not set. It serves primarily as a hall of shame for crappy
|
||||
* unwinders and features an exciting but mysterious NOP instruction.
|
||||
*
|
||||
* It's also fragile as hell, so please think twice before changing anything
|
||||
* in here.
|
||||
*
|
||||
* Copyright (C) 2012 ARM Limited
|
||||
*
|
||||
@ -14,7 +18,38 @@
|
||||
|
||||
.text
|
||||
|
||||
nop
|
||||
/* Ensure that the mysterious NOP can be associated with a function. */
|
||||
.cfi_startproc
|
||||
|
||||
/*
|
||||
* .cfi_signal_frame causes the corresponding Frame Description Entry in the
|
||||
* .eh_frame section to be annotated as a signal frame. This allows DWARF
|
||||
* unwinders (e.g. libstdc++) to implement _Unwind_GetIPInfo(), which permits
|
||||
* unwinding out of the signal trampoline without the need for the mysterious
|
||||
* NOP.
|
||||
*/
|
||||
.cfi_signal_frame
|
||||
|
||||
/*
|
||||
* Tell the unwinder where to locate the frame record linking back to the
|
||||
* interrupted context. We don't provide unwind info for registers other
|
||||
* than the frame pointer and the link register here; in practice, this
|
||||
* is sufficient for unwinding in C/C++ based runtimes and the values in
|
||||
* the sigcontext may have been modified by this point anyway. Debuggers
|
||||
* already have baked-in strategies for attempting to unwind out of signals.
|
||||
*/
|
||||
.cfi_def_cfa x29, 0
|
||||
.cfi_offset x29, 0 * 8
|
||||
.cfi_offset x30, 1 * 8
|
||||
|
||||
/*
|
||||
* This mysterious NOP is required for some unwinders (e.g. libc++) that
|
||||
* unconditionally subtract one from the result of _Unwind_GetIP() in order to
|
||||
* identify the calling function.
|
||||
* Hack borrowed from arch/powerpc/kernel/vdso64/sigtramp.S.
|
||||
*/
|
||||
nop // Mysterious NOP
|
||||
|
||||
/*
|
||||
* GDB relies on being able to identify the sigreturn instruction sequence to
|
||||
* unwind from signal handlers. We cannot, therefore, use SYM_FUNC_START()
|
||||
@ -23,11 +58,6 @@
|
||||
* is perfectly fine.
|
||||
*/
|
||||
SYM_CODE_START(__kernel_rt_sigreturn)
|
||||
.cfi_startproc
|
||||
.cfi_signal_frame
|
||||
.cfi_def_cfa x29, 0
|
||||
.cfi_offset x29, 0 * 8
|
||||
.cfi_offset x30, 1 * 8
|
||||
mov x8, #__NR_rt_sigreturn
|
||||
svc #0
|
||||
.cfi_endproc
|
||||
|
@ -3,6 +3,9 @@
|
||||
* This file provides both A32 and T32 versions, in accordance with the
|
||||
* arm sigreturn code.
|
||||
*
|
||||
* Please read the comments in arch/arm64/kernel/vdso/sigreturn.S to
|
||||
* understand some of the craziness in here.
|
||||
*
|
||||
* Copyright (C) 2018 ARM Limited
|
||||
*/
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user