![]() |
|
|||
0001 /* SPDX-License-Identifier: GPL-2.0-only */ 0002 /* 0003 * Sigreturn trampoline for returning from a signal when the SA_RESTORER 0004 * flag is not set. It serves primarily as a hall of shame for crappy 0005 * unwinders and features an exciting but mysterious NOP instruction. 0006 * 0007 * It's also fragile as hell, so please think twice before changing anything 0008 * in here. 0009 * 0010 * Copyright (C) 2012 ARM Limited 0011 * 0012 * Author: Will Deacon <will.deacon@arm.com> 0013 */ 0014 0015 #include <linux/linkage.h> 0016 #include <asm/assembler.h> 0017 #include <asm/unistd.h> 0018 0019 .text 0020 0021 /* 0022 * NOTE!!! You may notice that all of the .cfi directives in this file have 0023 * been commented out. This is because they have been shown to trigger segfaults 0024 * in libgcc when unwinding out of a SIGCANCEL handler to invoke pthread 0025 * cleanup handlers during the thread cancellation dance. By omitting the 0026 * directives, we trigger an arm64-specific fallback path in the unwinder which 0027 * recognises the signal frame and restores many of the registers directly from 0028 * the sigcontext. Re-enabling the cfi directives here therefore needs to be 0029 * much more comprehensive to reduce the risk of further regressions. 0030 */ 0031 0032 /* Ensure that the mysterious NOP can be associated with a function. */ 0033 // .cfi_startproc 0034 0035 /* 0036 * .cfi_signal_frame causes the corresponding Frame Description Entry (FDE) in 0037 * the .eh_frame section to be annotated as a signal frame. This allows DWARF 0038 * unwinders (e.g. libstdc++) to implement _Unwind_GetIPInfo() and identify 0039 * the next frame using the unmodified return address instead of subtracting 1, 0040 * which may yield the wrong FDE. 0041 */ 0042 // .cfi_signal_frame 0043 0044 /* 0045 * Tell the unwinder where to locate the frame record linking back to the 0046 * interrupted context. We don't provide unwind info for registers other than 0047 * the frame pointer and the link register here; in practice, this is likely to 0048 * be insufficient for unwinding in C/C++ based runtimes, especially without a 0049 * means to restore the stack pointer. Thankfully, unwinders and debuggers 0050 * already have baked-in strategies for attempting to unwind out of signals. 0051 */ 0052 // .cfi_def_cfa x29, 0 0053 // .cfi_offset x29, 0 * 8 0054 // .cfi_offset x30, 1 * 8 0055 0056 /* 0057 * This mysterious NOP is required for some unwinders (e.g. libc++) that 0058 * unconditionally subtract one from the result of _Unwind_GetIP() in order to 0059 * identify the calling function. 0060 * Hack borrowed from arch/powerpc/kernel/vdso64/sigtramp.S. 0061 */ 0062 nop // Mysterious NOP 0063 0064 /* 0065 * GDB, libgcc and libunwind rely on being able to identify the sigreturn 0066 * instruction sequence to unwind from signal handlers. We cannot, therefore, 0067 * use SYM_FUNC_START() here, as it will emit a BTI C instruction and break the 0068 * unwinder. Thankfully, this function is only ever called from a RET and so 0069 * omitting the landing pad is perfectly fine. 0070 */ 0071 SYM_CODE_START(__kernel_rt_sigreturn) 0072 // PLEASE DO NOT MODIFY 0073 mov x8, #__NR_rt_sigreturn 0074 // PLEASE DO NOT MODIFY 0075 svc #0 0076 // PLEASE DO NOT MODIFY 0077 // .cfi_endproc 0078 SYM_CODE_END(__kernel_rt_sigreturn) 0079 0080 emit_aarch64_feature_1_and
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.1.0 LXR engine. The LXR team |
![]() ![]() |