cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

sigreturn.S (3040B)


      1/* SPDX-License-Identifier: GPL-2.0-only */
      2/*
      3 * Sigreturn trampoline for returning from a signal when the SA_RESTORER
      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.
      9 *
     10 * Copyright (C) 2012 ARM Limited
     11 *
     12 * Author: Will Deacon <will.deacon@arm.com>
     13 */
     14
     15#include <linux/linkage.h>
     16#include <asm/assembler.h>
     17#include <asm/unistd.h>
     18
     19	.text
     20
     21/*
     22 * NOTE!!!  You may notice that all of the .cfi directives in this file have
     23 * been commented out. This is because they have been shown to trigger segfaults
     24 * in libgcc when unwinding out of a SIGCANCEL handler to invoke pthread
     25 * cleanup handlers during the thread cancellation dance. By omitting the
     26 * directives, we trigger an arm64-specific fallback path in the unwinder which
     27 * recognises the signal frame and restores many of the registers directly from
     28 * the sigcontext. Re-enabling the cfi directives here therefore needs to be
     29 * much more comprehensive to reduce the risk of further regressions.
     30 */
     31
     32/* Ensure that the mysterious NOP can be associated with a function. */
     33//	.cfi_startproc
     34
     35/*
     36 * .cfi_signal_frame causes the corresponding Frame Description Entry (FDE) in
     37 * the .eh_frame section to be annotated as a signal frame. This allows DWARF
     38 * unwinders (e.g. libstdc++) to implement _Unwind_GetIPInfo() and identify
     39 * the next frame using the unmodified return address instead of subtracting 1,
     40 * which may yield the wrong FDE.
     41 */
     42//	.cfi_signal_frame
     43
     44/*
     45 * Tell the unwinder where to locate the frame record linking back to the
     46 * interrupted context. We don't provide unwind info for registers other than
     47 * the frame pointer and the link register here; in practice, this is likely to
     48 * be insufficient for unwinding in C/C++ based runtimes, especially without a
     49 * means to restore the stack pointer. Thankfully, unwinders and debuggers
     50 * already have baked-in strategies for attempting to unwind out of signals.
     51 */
     52//	.cfi_def_cfa    x29, 0
     53//	.cfi_offset     x29, 0 * 8
     54//	.cfi_offset     x30, 1 * 8
     55
     56/*
     57 * This mysterious NOP is required for some unwinders (e.g. libc++) that
     58 * unconditionally subtract one from the result of _Unwind_GetIP() in order to
     59 * identify the calling function.
     60 * Hack borrowed from arch/powerpc/kernel/vdso64/sigtramp.S.
     61 */
     62	nop	// Mysterious NOP
     63
     64/*
     65 * GDB, libgcc and libunwind rely on being able to identify the sigreturn
     66 * instruction sequence to unwind from signal handlers. We cannot, therefore,
     67 * use SYM_FUNC_START() here, as it will emit a BTI C instruction and break the
     68 * unwinder. Thankfully, this function is only ever called from a RET and so
     69 * omitting the landing pad is perfectly fine.
     70 */
     71SYM_CODE_START(__kernel_rt_sigreturn)
     72//	PLEASE DO NOT MODIFY
     73	mov	x8, #__NR_rt_sigreturn
     74//	PLEASE DO NOT MODIFY
     75	svc	#0
     76//	PLEASE DO NOT MODIFY
     77//	.cfi_endproc
     78SYM_CODE_END(__kernel_rt_sigreturn)
     79
     80emit_aarch64_feature_1_and