| /* SPDX-License-Identifier: GPL-2.0 */ | |
| /* | |
| * Signal trampolines for 64 bit processes. | |
| * | |
| * Copyright (C) 2006 Randolph Chung <tausq@debian.org> | |
| * Copyright (C) 2018-2022 Helge Deller <deller@gmx.de> | |
| * Copyright (C) 2022 John David Anglin <dave.anglin@bell.net> | |
| */ | |
| #include <asm/unistd.h> | |
| #include <linux/linkage.h> | |
| #include <generated/asm-offsets.h> | |
| .text | |
| /* Gdb expects the trampoline is on the stack and the pc is offset from | |
| a 64-byte boundary by 0, 4 or 5 instructions. Since the vdso trampoline | |
| is not on the stack, we need a new variant with different offsets and | |
| data to tell gdb where to find the signal context on the stack. | |
| Here we put the offset to the context data at the start of the trampoline | |
| region and offset the first trampoline by 2 instructions. Please do | |
| not change the trampoline as the code in gdb depends on the following | |
| instruction sequence exactly. | |
| */ | |
| .align 64 | |
| .word SIGFRAME_CONTEXT_REGS | |
| /* The nop here is a hack. The dwarf2 unwind routines subtract 1 from | |
| the return address to get an address in the middle of the presumed | |
| call instruction. Since we don't have a call here, we artifically | |
| extend the range covered by the unwind info by adding a nop before | |
| the real start. | |
| */ | |
| nop | |
| .globl __kernel_sigtramp_rt | |
| .type __kernel_sigtramp_rt, @function | |
| __kernel_sigtramp_rt: | |
| .proc | |
| .callinfo FRAME=ASM_SIGFRAME_SIZE,CALLS,SAVE_RP | |
| .entry | |
| .Lsigrt_start = . - 4 | |
| 0: ldi 0, %r25 /* (in_syscall=0) */ | |
| ldi __NR_rt_sigreturn, %r20 | |
| ble 0x100(%sr2, %r0) | |
| nop | |
| 1: ldi 1, %r25 /* (in_syscall=1) */ | |
| ldi __NR_rt_sigreturn, %r20 | |
| ble 0x100(%sr2, %r0) | |
| nop | |
| .Lsigrt_end: | |
| .exit | |
| .procend | |
| .size __kernel_sigtramp_rt,.-__kernel_sigtramp_rt | |
| .section .eh_frame,"a",@progbits | |
| /* This is where the mcontext_t struct can be found on the stack. */ | |
| #define PTREGS SIGFRAME_CONTEXT_REGS /* 64-bit process offset is -720 */ | |
| /* Register REGNO can be found at offset OFS of the mcontext_t structure. */ | |
| .macro rsave regno,ofs | |
| .byte 0x05 /* DW_CFA_offset_extended */ | |
| .uleb128 \regno; /* regno */ | |
| .uleb128 \ofs /* factored offset */ | |
| .endm | |
| .Lcie: | |
| .long .Lcie_end - .Lcie_start | |
| .Lcie_start: | |
| .long 0 /* CIE ID */ | |
| .byte 1 /* Version number */ | |
| .stringz "zRS" /* NUL-terminated augmentation string */ | |
| .uleb128 4 /* Code alignment factor */ | |
| .sleb128 8 /* Data alignment factor */ | |
| .byte 61 /* Return address register column, iaoq[0] */ | |
| .uleb128 1 /* Augmentation value length */ | |
| .byte 0x1b /* DW_EH_PE_pcrel | DW_EH_PE_sdata4. */ | |
| .byte 0x0f /* DW_CFA_def_cfa_expresion */ | |
| .uleb128 9f - 1f /* length */ | |
| 1: | |
| .byte 0x8e /* DW_OP_breg30 */ | |
| .sleb128 PTREGS | |
| 9: | |
| .balign 8 | |
| .Lcie_end: | |
| .long .Lfde0_end - .Lfde0_start | |
| .Lfde0_start: | |
| .long .Lfde0_start - .Lcie /* CIE pointer. */ | |
| .long .Lsigrt_start - . /* PC start, length */ | |
| .long .Lsigrt_end - .Lsigrt_start | |
| .uleb128 0 /* Augmentation */ | |
| /* General registers */ | |
| rsave 1, 2 | |
| rsave 2, 3 | |
| rsave 3, 4 | |
| rsave 4, 5 | |
| rsave 5, 6 | |
| rsave 6, 7 | |
| rsave 7, 8 | |
| rsave 8, 9 | |
| rsave 9, 10 | |
| rsave 10, 11 | |
| rsave 11, 12 | |
| rsave 12, 13 | |
| rsave 13, 14 | |
| rsave 14, 15 | |
| rsave 15, 16 | |
| rsave 16, 17 | |
| rsave 17, 18 | |
| rsave 18, 19 | |
| rsave 19, 20 | |
| rsave 20, 21 | |
| rsave 21, 22 | |
| rsave 22, 23 | |
| rsave 23, 24 | |
| rsave 24, 25 | |
| rsave 25, 26 | |
| rsave 26, 27 | |
| rsave 27, 28 | |
| rsave 28, 29 | |
| rsave 29, 30 | |
| rsave 30, 31 | |
| rsave 31, 32 | |
| /* Floating-point registers */ | |
| rsave 32, 36 | |
| rsave 33, 37 | |
| rsave 34, 38 | |
| rsave 35, 39 | |
| rsave 36, 40 | |
| rsave 37, 41 | |
| rsave 38, 42 | |
| rsave 39, 43 | |
| rsave 40, 44 | |
| rsave 41, 45 | |
| rsave 42, 46 | |
| rsave 43, 47 | |
| rsave 44, 48 | |
| rsave 45, 49 | |
| rsave 46, 50 | |
| rsave 47, 51 | |
| rsave 48, 52 | |
| rsave 49, 53 | |
| rsave 50, 54 | |
| rsave 51, 55 | |
| rsave 52, 56 | |
| rsave 53, 57 | |
| rsave 54, 58 | |
| rsave 55, 59 | |
| rsave 56, 60 | |
| rsave 57, 61 | |
| rsave 58, 62 | |
| rsave 59, 63 | |
| /* SAR register */ | |
| rsave 60, 67 | |
| /* iaoq[0] return address register */ | |
| rsave 61, 65 | |
| .balign 8 | |
| .Lfde0_end: |