|
1 | 1 | /* SPDX-License-Identifier: GPL-2.0-only */
|
2 | 2 | /*
|
3 | 3 | * Sigreturn trampoline for returning from a signal when the SA_RESTORER
|
4 |
| - * flag is not set. |
| 4 | + * flag is not set. It serves primarily as a hall of shame for crappy |
| 5 | + * unwinders and features an exciting but mysterious NOP instruction. |
| 6 | + * |
| 7 | + * It's also fragile as hell, so please think twice before changing anything |
| 8 | + * in here. |
5 | 9 | *
|
6 | 10 | * Copyright (C) 2012 ARM Limited
|
7 | 11 | *
|
|
14 | 18 |
|
15 | 19 | .text
|
16 | 20 |
|
17 |
| - nop |
| 21 | +/* Ensure that the mysterious NOP can be associated with a function. */ |
| 22 | + .cfi_startproc |
| 23 | + |
| 24 | +/* |
| 25 | + * .cfi_signal_frame causes the corresponding Frame Description Entry in the |
| 26 | + * .eh_frame section to be annotated as a signal frame. This allows DWARF |
| 27 | + * unwinders (e.g. libstdc++) to implement _Unwind_GetIPInfo(), which permits |
| 28 | + * unwinding out of the signal trampoline without the need for the mysterious |
| 29 | + * NOP. |
| 30 | + */ |
| 31 | + .cfi_signal_frame |
| 32 | + |
| 33 | +/* |
| 34 | + * Tell the unwinder where to locate the frame record linking back to the |
| 35 | + * interrupted context. We don't provide unwind info for registers other |
| 36 | + * than the frame pointer and the link register here; in practice, this |
| 37 | + * is sufficient for unwinding in C/C++ based runtimes and the values in |
| 38 | + * the sigcontext may have been modified by this point anyway. Debuggers |
| 39 | + * already have baked-in strategies for attempting to unwind out of signals. |
| 40 | + */ |
| 41 | + .cfi_def_cfa x29, 0 |
| 42 | + .cfi_offset x29, 0 * 8 |
| 43 | + .cfi_offset x30, 1 * 8 |
| 44 | + |
| 45 | +/* |
| 46 | + * This mysterious NOP is required for some unwinders (e.g. libc++) that |
| 47 | + * unconditionally subtract one from the result of _Unwind_GetIP() in order to |
| 48 | + * identify the calling function. |
| 49 | + * Hack borrowed from arch/powerpc/kernel/vdso64/sigtramp.S. |
| 50 | + */ |
| 51 | + nop // Mysterious NOP |
| 52 | + |
18 | 53 | /*
|
19 | 54 | * GDB relies on being able to identify the sigreturn instruction sequence to
|
20 | 55 | * unwind from signal handlers. We cannot, therefore, use SYM_FUNC_START()
|
|
23 | 58 | * is perfectly fine.
|
24 | 59 | */
|
25 | 60 | SYM_CODE_START(__kernel_rt_sigreturn)
|
26 |
| - .cfi_startproc |
27 |
| - .cfi_signal_frame |
28 |
| - .cfi_def_cfa x29, 0 |
29 |
| - .cfi_offset x29, 0 * 8 |
30 |
| - .cfi_offset x30, 1 * 8 |
31 | 61 | mov x8, #__NR_rt_sigreturn
|
32 | 62 | svc #0
|
33 | 63 | .cfi_endproc
|
|
0 commit comments