Skip to content

Commit 46589e2

Browse files
Jon MedhurstRussell King
authored andcommitted
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 <[email protected]> Signed-off-by: Jon Medhurst <[email protected]> Signed-off-by: Russell King <[email protected]>
1 parent ea2e705 commit 46589e2

File tree

2 files changed

+78
-38
lines changed

2 files changed

+78
-38
lines changed

arch/arm/kernel/kprobes-test-thumb.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -222,8 +222,8 @@ void kprobe_thumb16_test_cases(void)
222222
DONT_TEST_IN_ITBLOCK(
223223
TEST_BF_R( "cbnz r",0,0, ", 2f")
224224
TEST_BF_R( "cbz r",2,-1,", 2f")
225-
TEST_BF_RX( "cbnz r",4,1, ", 2f",0x20)
226-
TEST_BF_RX( "cbz r",7,0, ", 2f",0x40)
225+
TEST_BF_RX( "cbnz r",4,1, ", 2f", SPACE_0x20)
226+
TEST_BF_RX( "cbz r",7,0, ", 2f", SPACE_0x40)
227227
)
228228
TEST_R("sxth r0, r",7, HH1,"")
229229
TEST_R("sxth r7, r",0, HH2,"")
@@ -246,7 +246,7 @@ DONT_TEST_IN_ITBLOCK(
246246
TESTCASE_START(code) \
247247
TEST_ARG_PTR(13, offset) \
248248
TEST_ARG_END("") \
249-
TEST_BRANCH_F(code,0) \
249+
TEST_BRANCH_F(code) \
250250
TESTCASE_END
251251

252252
TEST("push {r0}")
@@ -319,8 +319,8 @@ CONDITION_INSTRUCTIONS(8,
319319

320320
TEST_BF( "b 2f")
321321
TEST_BB( "b 2b")
322-
TEST_BF_X("b 2f", 0x400)
323-
TEST_BB_X("b 2b", 0x400)
322+
TEST_BF_X("b 2f", SPACE_0x400)
323+
TEST_BB_X("b 2b", SPACE_0x400)
324324

325325
TEST_GROUP("Testing instructions in IT blocks")
326326

@@ -746,7 +746,7 @@ CONDITION_INSTRUCTIONS(22,
746746
TEST_BB("bne.w 2b")
747747
TEST_BF("bgt.w 2f")
748748
TEST_BB("blt.w 2b")
749-
TEST_BF_X("bpl.w 2f",0x1000)
749+
TEST_BF_X("bpl.w 2f", SPACE_0x1000)
750750
)
751751

752752
TEST_UNSUPPORTED("msr cpsr, r0")
@@ -786,11 +786,11 @@ CONDITION_INSTRUCTIONS(22,
786786

787787
TEST_BF( "b.w 2f")
788788
TEST_BB( "b.w 2b")
789-
TEST_BF_X("b.w 2f", 0x1000)
789+
TEST_BF_X("b.w 2f", SPACE_0x1000)
790790

791791
TEST_BF( "bl.w 2f")
792792
TEST_BB( "bl.w 2b")
793-
TEST_BB_X("bl.w 2b", 0x1000)
793+
TEST_BB_X("bl.w 2b", SPACE_0x1000)
794794

795795
TEST_X( "blx __dummy_arm_subroutine",
796796
".arm \n\t"

arch/arm/kernel/kprobes-test.h

Lines changed: 70 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -149,23 +149,31 @@ struct test_arg_end {
149149
"1: "instruction" \n\t" \
150150
" nop \n\t"
151151

152-
#define TEST_BRANCH_F(instruction, xtra_dist) \
152+
#define TEST_BRANCH_F(instruction) \
153153
TEST_INSTRUCTION(instruction) \
154-
".if "#xtra_dist" \n\t" \
155154
" b 99f \n\t" \
156-
".space "#xtra_dist" \n\t" \
157-
".endif \n\t" \
155+
"2: nop \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" \
158168
" b 99f \n\t" \
159169
"2: nop \n\t"
160170

161-
#define TEST_BRANCH_B(instruction, xtra_dist) \
171+
#define TEST_BRANCH_BX(instruction, codex) \
162172
" b 50f \n\t" \
163173
" b 99f \n\t" \
164174
"2: nop \n\t" \
165175
" b 99f \n\t" \
166-
".if "#xtra_dist" \n\t" \
167-
".space "#xtra_dist" \n\t" \
168-
".endif \n\t" \
176+
codex" \n\t" \
169177
TEST_INSTRUCTION(instruction)
170178

171179
#define TESTCASE_END \
@@ -301,47 +309,60 @@ struct test_arg_end {
301309
TESTCASE_START(code1 #reg1 code2) \
302310
TEST_ARG_PTR(reg1, val1) \
303311
TEST_ARG_END("") \
304-
TEST_BRANCH_F(code1 #reg1 code2, 0) \
312+
TEST_BRANCH_F(code1 #reg1 code2) \
305313
TESTCASE_END
306314

307-
#define TEST_BF_X(code, xtra_dist) \
315+
#define TEST_BF(code) \
308316
TESTCASE_START(code) \
309317
TEST_ARG_END("") \
310-
TEST_BRANCH_F(code, xtra_dist) \
318+
TEST_BRANCH_F(code) \
311319
TESTCASE_END
312320

313-
#define TEST_BB_X(code, xtra_dist) \
321+
#define TEST_BB(code) \
314322
TESTCASE_START(code) \
315323
TEST_ARG_END("") \
316-
TEST_BRANCH_B(code, xtra_dist) \
324+
TEST_BRANCH_B(code) \
317325
TESTCASE_END
318326

319-
#define TEST_BF_RX(code1, reg, val, code2, xtra_dist) \
320-
TESTCASE_START(code1 #reg code2) \
321-
TEST_ARG_REG(reg, val) \
322-
TEST_ARG_END("") \
323-
TEST_BRANCH_F(code1 #reg code2, xtra_dist) \
327+
#define TEST_BF_R(code1, reg, val, code2) \
328+
TESTCASE_START(code1 #reg code2) \
329+
TEST_ARG_REG(reg, val) \
330+
TEST_ARG_END("") \
331+
TEST_BRANCH_F(code1 #reg code2) \
324332
TESTCASE_END
325333

326-
#define TEST_BB_RX(code1, reg, val, code2, xtra_dist) \
327-
TESTCASE_START(code1 #reg code2) \
328-
TEST_ARG_REG(reg, val) \
329-
TEST_ARG_END("") \
330-
TEST_BRANCH_B(code1 #reg code2, xtra_dist) \
334+
#define TEST_BB_R(code1, reg, val, code2) \
335+
TESTCASE_START(code1 #reg code2) \
336+
TEST_ARG_REG(reg, val) \
337+
TEST_ARG_END("") \
338+
TEST_BRANCH_B(code1 #reg code2) \
331339
TESTCASE_END
332340

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-
339341
#define TEST_BF_RR(code1, reg1, val1, code2, reg2, val2, code3) \
340342
TESTCASE_START(code1 #reg1 code2 #reg2 code3) \
341343
TEST_ARG_REG(reg1, val1) \
342344
TEST_ARG_REG(reg2, val2) \
343345
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) \
345366
TESTCASE_END
346367

347368
#define TEST_X(code, codex) \
@@ -372,6 +393,25 @@ struct test_arg_end {
372393
TESTCASE_END
373394

374395

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+
375415
/* Various values used in test cases... */
376416
#define N(val) (val ^ 0xffffffff)
377417
#define VAL1 0x12345678

0 commit comments

Comments
 (0)