aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorJon Medhurst <jon.medhurst@linaro.org>2011-11-24 07:01:08 -0500
committerRussell King <rmk+kernel@arm.linux.org.uk>2011-11-26 16:58:53 -0500
commit46589e2922509f9134ce79fa75180886c9765c58 (patch)
treeb702b16e613ce805a89dd57184f2f6b3dcc8c87f /arch
parentea2e7057c0234cfb8b09467d8f137760d371fc72 (diff)
ARM: 7174/1: Fix build error in kprobes test code on Thumb2 kernels
When compiling kprobes-test-thumb.c an error like below may occur: /tmp/ccKcuJcG.s:19179: Error: offset out of range This is caused by the compiler underestimating the size of the inline assembler instructions containing ".space 0x1000" and failing to spill the literal pool in time to prevent the generation of PC relative load instruction with invalid offsets. The fix implemented by this patch is to replace a single large .space directive by a number of 4 byte .space's. This requires splitting the macros which generate test cases for branch instructions into two forms: one with, and one without support for inserting extra code between branch and target. Acked-by: Nicolas Pitre <nicolas.pitre@linaro.org> Signed-off-by: Jon Medhurst <jon.medhurst@linaro.org> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/kernel/kprobes-test-thumb.c16
-rw-r--r--arch/arm/kernel/kprobes-test.h100
2 files changed, 78 insertions, 38 deletions
diff --git a/arch/arm/kernel/kprobes-test-thumb.c b/arch/arm/kernel/kprobes-test-thumb.c
index 5e726c31c45a..5d8b85792222 100644
--- a/arch/arm/kernel/kprobes-test-thumb.c
+++ b/arch/arm/kernel/kprobes-test-thumb.c
@@ -222,8 +222,8 @@ void kprobe_thumb16_test_cases(void)
222DONT_TEST_IN_ITBLOCK( 222DONT_TEST_IN_ITBLOCK(
223 TEST_BF_R( "cbnz r",0,0, ", 2f") 223 TEST_BF_R( "cbnz r",0,0, ", 2f")
224 TEST_BF_R( "cbz r",2,-1,", 2f") 224 TEST_BF_R( "cbz r",2,-1,", 2f")
225 TEST_BF_RX( "cbnz r",4,1, ", 2f",0x20) 225 TEST_BF_RX( "cbnz r",4,1, ", 2f", SPACE_0x20)
226 TEST_BF_RX( "cbz r",7,0, ", 2f",0x40) 226 TEST_BF_RX( "cbz r",7,0, ", 2f", SPACE_0x40)
227) 227)
228 TEST_R("sxth r0, r",7, HH1,"") 228 TEST_R("sxth r0, r",7, HH1,"")
229 TEST_R("sxth r7, r",0, HH2,"") 229 TEST_R("sxth r7, r",0, HH2,"")
@@ -246,7 +246,7 @@ DONT_TEST_IN_ITBLOCK(
246 TESTCASE_START(code) \ 246 TESTCASE_START(code) \
247 TEST_ARG_PTR(13, offset) \ 247 TEST_ARG_PTR(13, offset) \
248 TEST_ARG_END("") \ 248 TEST_ARG_END("") \
249 TEST_BRANCH_F(code,0) \ 249 TEST_BRANCH_F(code) \
250 TESTCASE_END 250 TESTCASE_END
251 251
252 TEST("push {r0}") 252 TEST("push {r0}")
@@ -319,8 +319,8 @@ CONDITION_INSTRUCTIONS(8,
319 319
320 TEST_BF( "b 2f") 320 TEST_BF( "b 2f")
321 TEST_BB( "b 2b") 321 TEST_BB( "b 2b")
322 TEST_BF_X("b 2f", 0x400) 322 TEST_BF_X("b 2f", SPACE_0x400)
323 TEST_BB_X("b 2b", 0x400) 323 TEST_BB_X("b 2b", SPACE_0x400)
324 324
325 TEST_GROUP("Testing instructions in IT blocks") 325 TEST_GROUP("Testing instructions in IT blocks")
326 326
@@ -746,7 +746,7 @@ CONDITION_INSTRUCTIONS(22,
746 TEST_BB("bne.w 2b") 746 TEST_BB("bne.w 2b")
747 TEST_BF("bgt.w 2f") 747 TEST_BF("bgt.w 2f")
748 TEST_BB("blt.w 2b") 748 TEST_BB("blt.w 2b")
749 TEST_BF_X("bpl.w 2f",0x1000) 749 TEST_BF_X("bpl.w 2f", SPACE_0x1000)
750) 750)
751 751
752 TEST_UNSUPPORTED("msr cpsr, r0") 752 TEST_UNSUPPORTED("msr cpsr, r0")
@@ -786,11 +786,11 @@ CONDITION_INSTRUCTIONS(22,
786 786
787 TEST_BF( "b.w 2f") 787 TEST_BF( "b.w 2f")
788 TEST_BB( "b.w 2b") 788 TEST_BB( "b.w 2b")
789 TEST_BF_X("b.w 2f", 0x1000) 789 TEST_BF_X("b.w 2f", SPACE_0x1000)
790 790
791 TEST_BF( "bl.w 2f") 791 TEST_BF( "bl.w 2f")
792 TEST_BB( "bl.w 2b") 792 TEST_BB( "bl.w 2b")
793 TEST_BB_X("bl.w 2b", 0x1000) 793 TEST_BB_X("bl.w 2b", SPACE_0x1000)
794 794
795 TEST_X( "blx __dummy_arm_subroutine", 795 TEST_X( "blx __dummy_arm_subroutine",
796 ".arm \n\t" 796 ".arm \n\t"
diff --git a/arch/arm/kernel/kprobes-test.h b/arch/arm/kernel/kprobes-test.h
index 0dc5d77b9356..e28a869b1ae4 100644
--- a/arch/arm/kernel/kprobes-test.h
+++ b/arch/arm/kernel/kprobes-test.h
@@ -149,23 +149,31 @@ struct test_arg_end {
149 "1: "instruction" \n\t" \ 149 "1: "instruction" \n\t" \
150 " nop \n\t" 150 " nop \n\t"
151 151
152#define TEST_BRANCH_F(instruction, xtra_dist) \ 152#define TEST_BRANCH_F(instruction) \
153 TEST_INSTRUCTION(instruction) \ 153 TEST_INSTRUCTION(instruction) \
154 ".if "#xtra_dist" \n\t" \
155 " b 99f \n\t" \ 154 " b 99f \n\t" \
156 ".space "#xtra_dist" \n\t" \ 155 "2: nop \n\t"
157 ".endif \n\t" \ 156
157#define TEST_BRANCH_B(instruction) \
158 " b 50f \n\t" \
159 " b 99f \n\t" \
160 "2: nop \n\t" \
161 " b 99f \n\t" \
162 TEST_INSTRUCTION(instruction)
163
164#define TEST_BRANCH_FX(instruction, codex) \
165 TEST_INSTRUCTION(instruction) \
166 " b 99f \n\t" \
167 codex" \n\t" \
158 " b 99f \n\t" \ 168 " b 99f \n\t" \
159 "2: nop \n\t" 169 "2: nop \n\t"
160 170
161#define TEST_BRANCH_B(instruction, xtra_dist) \ 171#define TEST_BRANCH_BX(instruction, codex) \
162 " b 50f \n\t" \ 172 " b 50f \n\t" \
163 " b 99f \n\t" \ 173 " b 99f \n\t" \
164 "2: nop \n\t" \ 174 "2: nop \n\t" \
165 " b 99f \n\t" \ 175 " b 99f \n\t" \
166 ".if "#xtra_dist" \n\t" \ 176 codex" \n\t" \
167 ".space "#xtra_dist" \n\t" \
168 ".endif \n\t" \
169 TEST_INSTRUCTION(instruction) 177 TEST_INSTRUCTION(instruction)
170 178
171#define TESTCASE_END \ 179#define TESTCASE_END \
@@ -301,47 +309,60 @@ struct test_arg_end {
301 TESTCASE_START(code1 #reg1 code2) \ 309 TESTCASE_START(code1 #reg1 code2) \
302 TEST_ARG_PTR(reg1, val1) \ 310 TEST_ARG_PTR(reg1, val1) \
303 TEST_ARG_END("") \ 311 TEST_ARG_END("") \
304 TEST_BRANCH_F(code1 #reg1 code2, 0) \ 312 TEST_BRANCH_F(code1 #reg1 code2) \
305 TESTCASE_END 313 TESTCASE_END
306 314
307#define TEST_BF_X(code, xtra_dist) \ 315#define TEST_BF(code) \
308 TESTCASE_START(code) \ 316 TESTCASE_START(code) \
309 TEST_ARG_END("") \ 317 TEST_ARG_END("") \
310 TEST_BRANCH_F(code, xtra_dist) \ 318 TEST_BRANCH_F(code) \
311 TESTCASE_END 319 TESTCASE_END
312 320
313#define TEST_BB_X(code, xtra_dist) \ 321#define TEST_BB(code) \
314 TESTCASE_START(code) \ 322 TESTCASE_START(code) \
315 TEST_ARG_END("") \ 323 TEST_ARG_END("") \
316 TEST_BRANCH_B(code, xtra_dist) \ 324 TEST_BRANCH_B(code) \
317 TESTCASE_END 325 TESTCASE_END
318 326
319#define TEST_BF_RX(code1, reg, val, code2, xtra_dist) \ 327#define TEST_BF_R(code1, reg, val, code2) \
320 TESTCASE_START(code1 #reg code2) \ 328 TESTCASE_START(code1 #reg code2) \
321 TEST_ARG_REG(reg, val) \ 329 TEST_ARG_REG(reg, val) \
322 TEST_ARG_END("") \ 330 TEST_ARG_END("") \
323 TEST_BRANCH_F(code1 #reg code2, xtra_dist) \ 331 TEST_BRANCH_F(code1 #reg code2) \
324 TESTCASE_END 332 TESTCASE_END
325 333
326#define TEST_BB_RX(code1, reg, val, code2, xtra_dist) \ 334#define TEST_BB_R(code1, reg, val, code2) \
327 TESTCASE_START(code1 #reg code2) \ 335 TESTCASE_START(code1 #reg code2) \
328 TEST_ARG_REG(reg, val) \ 336 TEST_ARG_REG(reg, val) \
329 TEST_ARG_END("") \ 337 TEST_ARG_END("") \
330 TEST_BRANCH_B(code1 #reg code2, xtra_dist) \ 338 TEST_BRANCH_B(code1 #reg code2) \
331 TESTCASE_END 339 TESTCASE_END
332 340
333#define TEST_BF(code) TEST_BF_X(code, 0)
334#define TEST_BB(code) TEST_BB_X(code, 0)
335
336#define TEST_BF_R(code1, reg, val, code2) TEST_BF_RX(code1, reg, val, code2, 0)
337#define TEST_BB_R(code1, reg, val, code2) TEST_BB_RX(code1, reg, val, code2, 0)
338
339#define TEST_BF_RR(code1, reg1, val1, code2, reg2, val2, code3) \ 341#define TEST_BF_RR(code1, reg1, val1, code2, reg2, val2, code3) \
340 TESTCASE_START(code1 #reg1 code2 #reg2 code3) \ 342 TESTCASE_START(code1 #reg1 code2 #reg2 code3) \
341 TEST_ARG_REG(reg1, val1) \ 343 TEST_ARG_REG(reg1, val1) \
342 TEST_ARG_REG(reg2, val2) \ 344 TEST_ARG_REG(reg2, val2) \
343 TEST_ARG_END("") \ 345 TEST_ARG_END("") \
344 TEST_BRANCH_F(code1 #reg1 code2 #reg2 code3, 0) \ 346 TEST_BRANCH_F(code1 #reg1 code2 #reg2 code3) \
347 TESTCASE_END
348
349#define TEST_BF_X(code, codex) \
350 TESTCASE_START(code) \
351 TEST_ARG_END("") \
352 TEST_BRANCH_FX(code, codex) \
353 TESTCASE_END
354
355#define TEST_BB_X(code, codex) \
356 TESTCASE_START(code) \
357 TEST_ARG_END("") \
358 TEST_BRANCH_BX(code, codex) \
359 TESTCASE_END
360
361#define TEST_BF_RX(code1, reg, val, code2, codex) \
362 TESTCASE_START(code1 #reg code2) \
363 TEST_ARG_REG(reg, val) \
364 TEST_ARG_END("") \
365 TEST_BRANCH_FX(code1 #reg code2, codex) \
345 TESTCASE_END 366 TESTCASE_END
346 367
347#define TEST_X(code, codex) \ 368#define TEST_X(code, codex) \
@@ -372,6 +393,25 @@ struct test_arg_end {
372 TESTCASE_END 393 TESTCASE_END
373 394
374 395
396/*
397 * Macros for defining space directives spread over multiple lines.
398 * These are required so the compiler guesses better the length of inline asm
399 * code and will spill the literal pool early enough to avoid generating PC
400 * relative loads with out of range offsets.
401 */
402#define TWICE(x) x x
403#define SPACE_0x8 TWICE(".space 4\n\t")
404#define SPACE_0x10 TWICE(SPACE_0x8)
405#define SPACE_0x20 TWICE(SPACE_0x10)
406#define SPACE_0x40 TWICE(SPACE_0x20)
407#define SPACE_0x80 TWICE(SPACE_0x40)
408#define SPACE_0x100 TWICE(SPACE_0x80)
409#define SPACE_0x200 TWICE(SPACE_0x100)
410#define SPACE_0x400 TWICE(SPACE_0x200)
411#define SPACE_0x800 TWICE(SPACE_0x400)
412#define SPACE_0x1000 TWICE(SPACE_0x800)
413
414
375/* Various values used in test cases... */ 415/* Various values used in test cases... */
376#define N(val) (val ^ 0xffffffff) 416#define N(val) (val ^ 0xffffffff)
377#define VAL1 0x12345678 417#define VAL1 0x12345678