167 lines
3.8 KiB
ArmAsm
167 lines
3.8 KiB
ArmAsm
|
/* 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:
|