Back to home page

OSCL-LXR

 
 

    


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