diff options
author | Lin Yongting <linyongting@gmail.com> | 2014-11-26 08:38:33 -0500 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2014-11-27 11:00:25 -0500 |
commit | 279f487e0b471577e2b3c134e2ff9af939129d0f (patch) | |
tree | 6c772b214b5110c695a2774a5785489bc5c6cfc9 /arch/arm/lib | |
parent | 207a6cb06990c298d0eac982e053d370e216d93d (diff) |
ARM: 8225/1: Add unwinding support for memory copy functions
The memory copy functions(memcpy, __copy_from_user, __copy_to_user)
never had unwinding annotations added. Currently, when accessing
invalid pointer by these functions occurs the backtrace shown will
stop at these functions or some completely unrelated function.
Add unwinding annotations in hopes of getting a more useful backtrace
in following cases:
1. die on accessing invalid pointer by these functions
2. kprobe trapped at any instruction within these functions
3. interrupted at any instruction within these functions
Signed-off-by: Lin Yongting <linyongting@gmail.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/lib')
-rw-r--r-- | arch/arm/lib/copy_from_user.S | 5 | ||||
-rw-r--r-- | arch/arm/lib/copy_template.S | 30 | ||||
-rw-r--r-- | arch/arm/lib/copy_to_user.S | 5 | ||||
-rw-r--r-- | arch/arm/lib/memcpy.S | 5 |
4 files changed, 45 insertions, 0 deletions
diff --git a/arch/arm/lib/copy_from_user.S b/arch/arm/lib/copy_from_user.S index 66a477a3e3cc..7a235b9952be 100644 --- a/arch/arm/lib/copy_from_user.S +++ b/arch/arm/lib/copy_from_user.S | |||
@@ -12,6 +12,7 @@ | |||
12 | 12 | ||
13 | #include <linux/linkage.h> | 13 | #include <linux/linkage.h> |
14 | #include <asm/assembler.h> | 14 | #include <asm/assembler.h> |
15 | #include <asm/unwind.h> | ||
15 | 16 | ||
16 | /* | 17 | /* |
17 | * Prototype: | 18 | * Prototype: |
@@ -77,6 +78,10 @@ | |||
77 | stmdb sp!, {r0, r2, r3, \reg1, \reg2} | 78 | stmdb sp!, {r0, r2, r3, \reg1, \reg2} |
78 | .endm | 79 | .endm |
79 | 80 | ||
81 | .macro usave reg1 reg2 | ||
82 | UNWIND( .save {r0, r2, r3, \reg1, \reg2} ) | ||
83 | .endm | ||
84 | |||
80 | .macro exit reg1 reg2 | 85 | .macro exit reg1 reg2 |
81 | add sp, sp, #8 | 86 | add sp, sp, #8 |
82 | ldmfd sp!, {r0, \reg1, \reg2} | 87 | ldmfd sp!, {r0, \reg1, \reg2} |
diff --git a/arch/arm/lib/copy_template.S b/arch/arm/lib/copy_template.S index 3bc8eb811a73..652e4d98cd47 100644 --- a/arch/arm/lib/copy_template.S +++ b/arch/arm/lib/copy_template.S | |||
@@ -53,6 +53,12 @@ | |||
53 | * data as needed by the implementation including this code. Called | 53 | * data as needed by the implementation including this code. Called |
54 | * upon code entry. | 54 | * upon code entry. |
55 | * | 55 | * |
56 | * usave reg1 reg2 | ||
57 | * | ||
58 | * Unwind annotation macro is corresponding for 'enter' macro. | ||
59 | * It tell unwinder that preserved some provided registers on the stack | ||
60 | * and additional data by a prior 'enter' macro. | ||
61 | * | ||
56 | * exit reg1 reg2 | 62 | * exit reg1 reg2 |
57 | * | 63 | * |
58 | * Restore registers with the values previously saved with the | 64 | * Restore registers with the values previously saved with the |
@@ -67,7 +73,12 @@ | |||
67 | */ | 73 | */ |
68 | 74 | ||
69 | 75 | ||
76 | UNWIND( .fnstart ) | ||
70 | enter r4, lr | 77 | enter r4, lr |
78 | UNWIND( .fnend ) | ||
79 | |||
80 | UNWIND( .fnstart ) | ||
81 | usave r4, lr @ in first stmdb block | ||
71 | 82 | ||
72 | subs r2, r2, #4 | 83 | subs r2, r2, #4 |
73 | blt 8f | 84 | blt 8f |
@@ -79,6 +90,11 @@ | |||
79 | 90 | ||
80 | 1: subs r2, r2, #(28) | 91 | 1: subs r2, r2, #(28) |
81 | stmfd sp!, {r5 - r8} | 92 | stmfd sp!, {r5 - r8} |
93 | UNWIND( .fnend ) | ||
94 | |||
95 | UNWIND( .fnstart ) | ||
96 | usave r4, lr | ||
97 | UNWIND( .save {r5 - r8} ) @ in second stmfd block | ||
82 | blt 5f | 98 | blt 5f |
83 | 99 | ||
84 | CALGN( ands ip, r0, #31 ) | 100 | CALGN( ands ip, r0, #31 ) |
@@ -144,7 +160,10 @@ | |||
144 | CALGN( bcs 2b ) | 160 | CALGN( bcs 2b ) |
145 | 161 | ||
146 | 7: ldmfd sp!, {r5 - r8} | 162 | 7: ldmfd sp!, {r5 - r8} |
163 | UNWIND( .fnend ) @ end of second stmfd block | ||
147 | 164 | ||
165 | UNWIND( .fnstart ) | ||
166 | usave r4, lr @ still in first stmdb block | ||
148 | 8: movs r2, r2, lsl #31 | 167 | 8: movs r2, r2, lsl #31 |
149 | ldr1b r1, r3, ne, abort=21f | 168 | ldr1b r1, r3, ne, abort=21f |
150 | ldr1b r1, r4, cs, abort=21f | 169 | ldr1b r1, r4, cs, abort=21f |
@@ -173,10 +192,13 @@ | |||
173 | ldr1w r1, lr, abort=21f | 192 | ldr1w r1, lr, abort=21f |
174 | beq 17f | 193 | beq 17f |
175 | bgt 18f | 194 | bgt 18f |
195 | UNWIND( .fnend ) | ||
176 | 196 | ||
177 | 197 | ||
178 | .macro forward_copy_shift pull push | 198 | .macro forward_copy_shift pull push |
179 | 199 | ||
200 | UNWIND( .fnstart ) | ||
201 | usave r4, lr @ still in first stmdb block | ||
180 | subs r2, r2, #28 | 202 | subs r2, r2, #28 |
181 | blt 14f | 203 | blt 14f |
182 | 204 | ||
@@ -187,7 +209,11 @@ | |||
187 | CALGN( bcc 15f ) | 209 | CALGN( bcc 15f ) |
188 | 210 | ||
189 | 11: stmfd sp!, {r5 - r9} | 211 | 11: stmfd sp!, {r5 - r9} |
212 | UNWIND( .fnend ) | ||
190 | 213 | ||
214 | UNWIND( .fnstart ) | ||
215 | usave r4, lr | ||
216 | UNWIND( .save {r5 - r9} ) @ in new second stmfd block | ||
191 | PLD( pld [r1, #0] ) | 217 | PLD( pld [r1, #0] ) |
192 | PLD( subs r2, r2, #96 ) | 218 | PLD( subs r2, r2, #96 ) |
193 | PLD( pld [r1, #28] ) | 219 | PLD( pld [r1, #28] ) |
@@ -221,7 +247,10 @@ | |||
221 | PLD( bge 13b ) | 247 | PLD( bge 13b ) |
222 | 248 | ||
223 | ldmfd sp!, {r5 - r9} | 249 | ldmfd sp!, {r5 - r9} |
250 | UNWIND( .fnend ) @ end of the second stmfd block | ||
224 | 251 | ||
252 | UNWIND( .fnstart ) | ||
253 | usave r4, lr @ still in first stmdb block | ||
225 | 14: ands ip, r2, #28 | 254 | 14: ands ip, r2, #28 |
226 | beq 16f | 255 | beq 16f |
227 | 256 | ||
@@ -236,6 +265,7 @@ | |||
236 | 265 | ||
237 | 16: sub r1, r1, #(\push / 8) | 266 | 16: sub r1, r1, #(\push / 8) |
238 | b 8b | 267 | b 8b |
268 | UNWIND( .fnend ) | ||
239 | 269 | ||
240 | .endm | 270 | .endm |
241 | 271 | ||
diff --git a/arch/arm/lib/copy_to_user.S b/arch/arm/lib/copy_to_user.S index d066df686e17..a9d3db16ecb5 100644 --- a/arch/arm/lib/copy_to_user.S +++ b/arch/arm/lib/copy_to_user.S | |||
@@ -12,6 +12,7 @@ | |||
12 | 12 | ||
13 | #include <linux/linkage.h> | 13 | #include <linux/linkage.h> |
14 | #include <asm/assembler.h> | 14 | #include <asm/assembler.h> |
15 | #include <asm/unwind.h> | ||
15 | 16 | ||
16 | /* | 17 | /* |
17 | * Prototype: | 18 | * Prototype: |
@@ -80,6 +81,10 @@ | |||
80 | stmdb sp!, {r0, r2, r3, \reg1, \reg2} | 81 | stmdb sp!, {r0, r2, r3, \reg1, \reg2} |
81 | .endm | 82 | .endm |
82 | 83 | ||
84 | .macro usave reg1 reg2 | ||
85 | UNWIND( .save {r0, r2, r3, \reg1, \reg2} ) | ||
86 | .endm | ||
87 | |||
83 | .macro exit reg1 reg2 | 88 | .macro exit reg1 reg2 |
84 | add sp, sp, #8 | 89 | add sp, sp, #8 |
85 | ldmfd sp!, {r0, \reg1, \reg2} | 90 | ldmfd sp!, {r0, \reg1, \reg2} |
diff --git a/arch/arm/lib/memcpy.S b/arch/arm/lib/memcpy.S index a9b9e2287a09..7797e81e40e0 100644 --- a/arch/arm/lib/memcpy.S +++ b/arch/arm/lib/memcpy.S | |||
@@ -12,6 +12,7 @@ | |||
12 | 12 | ||
13 | #include <linux/linkage.h> | 13 | #include <linux/linkage.h> |
14 | #include <asm/assembler.h> | 14 | #include <asm/assembler.h> |
15 | #include <asm/unwind.h> | ||
15 | 16 | ||
16 | #define LDR1W_SHIFT 0 | 17 | #define LDR1W_SHIFT 0 |
17 | #define STR1W_SHIFT 0 | 18 | #define STR1W_SHIFT 0 |
@@ -48,6 +49,10 @@ | |||
48 | stmdb sp!, {r0, \reg1, \reg2} | 49 | stmdb sp!, {r0, \reg1, \reg2} |
49 | .endm | 50 | .endm |
50 | 51 | ||
52 | .macro usave reg1 reg2 | ||
53 | UNWIND( .save {r0, \reg1, \reg2} ) | ||
54 | .endm | ||
55 | |||
51 | .macro exit reg1 reg2 | 56 | .macro exit reg1 reg2 |
52 | ldmfd sp!, {r0, \reg1, \reg2} | 57 | ldmfd sp!, {r0, \reg1, \reg2} |
53 | .endm | 58 | .endm |