1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
2 | /* |
3 | * sigreturn_codes.S - code sinpets for sigreturn syscalls |
4 | * |
5 | * Created by: Victor Kamensky, 2013-08-13 |
6 | * Copyright: (C) 2013 Linaro Limited |
7 | */ |
8 | |
9 | #include <asm/assembler.h> |
10 | #include <asm/asm-offsets.h> |
11 | #include <asm/unistd.h> |
12 | |
13 | /* |
14 | * For ARM syscalls, we encode the syscall number into the instruction. |
15 | * With EABI, the syscall number has to be loaded into r7. As result |
16 | * ARM syscall sequence snippet will have move and svc in .arm encoding |
17 | * |
18 | * For Thumb syscalls, we pass the syscall number via r7. We therefore |
19 | * need two 16-bit instructions in .thumb encoding |
20 | * |
21 | * Please note sigreturn_codes code are not executed in place. Instead |
22 | * they just copied by kernel into appropriate places. Code inside of |
23 | * arch/arm/kernel/signal.c is very sensitive to layout of these code |
24 | * snippets. |
25 | */ |
26 | |
27 | /* |
28 | * In CPU_THUMBONLY case kernel arm opcodes are not allowed. |
29 | * Note in this case codes skips those instructions but it uses .org |
30 | * directive to keep correct layout of sigreturn_codes array. |
31 | */ |
32 | #ifndef CONFIG_CPU_THUMBONLY |
33 | #define ARM_OK(code...) code |
34 | #else |
35 | #define ARM_OK(code...) |
36 | #endif |
37 | |
38 | .macro arm_slot n |
39 | .org sigreturn_codes + 12 * (\n) |
40 | ARM_OK( .arm ) |
41 | .endm |
42 | |
43 | .macro thumb_slot n |
44 | .org sigreturn_codes + 12 * (\n) + 8 |
45 | .thumb |
46 | .endm |
47 | |
48 | .macro arm_fdpic_slot n |
49 | .org sigreturn_codes + 24 + 20 * (\n) |
50 | ARM_OK( .arm ) |
51 | .endm |
52 | |
53 | .macro thumb_fdpic_slot n |
54 | .org sigreturn_codes + 24 + 20 * (\n) + 12 |
55 | .thumb |
56 | .endm |
57 | |
58 | |
59 | #if __LINUX_ARM_ARCH__ <= 4 |
60 | /* |
61 | * Note we manually set minimally required arch that supports |
62 | * required thumb opcodes for early arch versions. It is OK |
63 | * for this file to be used in combination with other |
64 | * lower arch variants, since these code snippets are only |
65 | * used as input data. |
66 | */ |
67 | .arch armv4t |
68 | #endif |
69 | |
70 | .section .rodata |
71 | .global sigreturn_codes |
72 | .type sigreturn_codes, #object |
73 | |
74 | .align |
75 | |
76 | sigreturn_codes: |
77 | |
78 | /* ARM sigreturn syscall code snippet */ |
79 | arm_slot 0 |
80 | ARM_OK( mov r7, #(__NR_sigreturn - __NR_SYSCALL_BASE) ) |
81 | ARM_OK( swi #(__NR_sigreturn)|(__NR_OABI_SYSCALL_BASE) ) |
82 | |
83 | /* Thumb sigreturn syscall code snippet */ |
84 | thumb_slot 0 |
85 | movs r7, #(__NR_sigreturn - __NR_SYSCALL_BASE) |
86 | swi #0 |
87 | |
88 | /* ARM sigreturn_rt syscall code snippet */ |
89 | arm_slot 1 |
90 | ARM_OK( mov r7, #(__NR_rt_sigreturn - __NR_SYSCALL_BASE) ) |
91 | ARM_OK( swi #(__NR_rt_sigreturn)|(__NR_OABI_SYSCALL_BASE) ) |
92 | |
93 | /* Thumb sigreturn_rt syscall code snippet */ |
94 | thumb_slot 1 |
95 | movs r7, #(__NR_rt_sigreturn - __NR_SYSCALL_BASE) |
96 | swi #0 |
97 | |
98 | /* ARM sigreturn restorer FDPIC bounce code snippet */ |
99 | arm_fdpic_slot 0 |
100 | ARM_OK( ldr r3, [sp, #SIGFRAME_RC3_OFFSET] ) |
101 | ARM_OK( ldmia r3, {r3, r9} ) |
102 | #ifdef CONFIG_ARM_THUMB |
103 | ARM_OK( bx r3 ) |
104 | #else |
105 | ARM_OK( ret r3 ) |
106 | #endif |
107 | |
108 | /* Thumb sigreturn restorer FDPIC bounce code snippet */ |
109 | thumb_fdpic_slot 0 |
110 | ldr r3, [sp, #SIGFRAME_RC3_OFFSET] |
111 | ldmia r3, {r2, r3} |
112 | mov r9, r3 |
113 | bx r2 |
114 | |
115 | /* ARM sigreturn_rt restorer FDPIC bounce code snippet */ |
116 | arm_fdpic_slot 1 |
117 | ARM_OK( ldr r3, [sp, #RT_SIGFRAME_RC3_OFFSET] ) |
118 | ARM_OK( ldmia r3, {r3, r9} ) |
119 | #ifdef CONFIG_ARM_THUMB |
120 | ARM_OK( bx r3 ) |
121 | #else |
122 | ARM_OK( ret r3 ) |
123 | #endif |
124 | |
125 | /* Thumb sigreturn_rt restorer FDPIC bounce code snippet */ |
126 | thumb_fdpic_slot 1 |
127 | ldr r3, [sp, #RT_SIGFRAME_RC3_OFFSET] |
128 | ldmia r3, {r2, r3} |
129 | mov r9, r3 |
130 | bx r2 |
131 | |
132 | /* |
133 | * Note on additional space: setup_return in signal.c |
134 | * always copies the same number of words regardless whether |
135 | * it is thumb case or not, so we need one additional padding |
136 | * word after the last entry. |
137 | */ |
138 | .space 4 |
139 | |
140 | .size sigreturn_codes, . - sigreturn_codes |
141 | |