diff options
| -rw-r--r-- | arch/arm/kernel/kprobes-test-thumb.c | 16 | ||||
| -rw-r--r-- | arch/arm/kernel/kprobes-test.h | 100 | 
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 5e726c31c45..5d8b8579222 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)  DONT_TEST_IN_ITBLOCK(  	TEST_BF_R(  "cbnz	r",0,0, ", 2f")  	TEST_BF_R(  "cbz	r",2,-1,", 2f") -	TEST_BF_RX( "cbnz	r",4,1, ", 2f",0x20) -	TEST_BF_RX( "cbz	r",7,0, ", 2f",0x40) +	TEST_BF_RX( "cbnz	r",4,1, ", 2f", SPACE_0x20) +	TEST_BF_RX( "cbz	r",7,0, ", 2f", SPACE_0x40)  )  	TEST_R("sxth	r0, r",7, HH1,"")  	TEST_R("sxth	r7, r",0, HH2,"") @@ -246,7 +246,7 @@ DONT_TEST_IN_ITBLOCK(  	TESTCASE_START(code)		\  	TEST_ARG_PTR(13, offset)	\  	TEST_ARG_END("")		\ -	TEST_BRANCH_F(code,0)		\ +	TEST_BRANCH_F(code)		\  	TESTCASE_END  	TEST("push	{r0}") @@ -319,8 +319,8 @@ CONDITION_INSTRUCTIONS(8,  	TEST_BF(  "b	2f")  	TEST_BB(  "b	2b") -	TEST_BF_X("b	2f", 0x400) -	TEST_BB_X("b	2b", 0x400) +	TEST_BF_X("b	2f", SPACE_0x400) +	TEST_BB_X("b	2b", SPACE_0x400)  	TEST_GROUP("Testing instructions in IT blocks") @@ -746,7 +746,7 @@ CONDITION_INSTRUCTIONS(22,  	TEST_BB("bne.w	2b")  	TEST_BF("bgt.w	2f")  	TEST_BB("blt.w	2b") -	TEST_BF_X("bpl.w	2f",0x1000) +	TEST_BF_X("bpl.w	2f", SPACE_0x1000)  )  	TEST_UNSUPPORTED("msr	cpsr, r0") @@ -786,11 +786,11 @@ CONDITION_INSTRUCTIONS(22,  	TEST_BF(  "b.w	2f")  	TEST_BB(  "b.w	2b") -	TEST_BF_X("b.w	2f", 0x1000) +	TEST_BF_X("b.w	2f", SPACE_0x1000)  	TEST_BF(  "bl.w	2f")  	TEST_BB(  "bl.w	2b") -	TEST_BB_X("bl.w	2b", 0x1000) +	TEST_BB_X("bl.w	2b", SPACE_0x1000)  	TEST_X(	"blx	__dummy_arm_subroutine",  		".arm				\n\t" diff --git a/arch/arm/kernel/kprobes-test.h b/arch/arm/kernel/kprobes-test.h index 0dc5d77b935..e28a869b1ae 100644 --- a/arch/arm/kernel/kprobes-test.h +++ b/arch/arm/kernel/kprobes-test.h @@ -149,23 +149,31 @@ struct test_arg_end {  	"1:	"instruction"				\n\t"	\  	"	nop					\n\t" -#define TEST_BRANCH_F(instruction, xtra_dist)			\ +#define TEST_BRANCH_F(instruction)				\  	TEST_INSTRUCTION(instruction)				\ -	".if "#xtra_dist"				\n\t"	\  	"	b	99f				\n\t"	\ -	".space "#xtra_dist"				\n\t"	\ -	".endif						\n\t"	\ +	"2:	nop					\n\t" + +#define TEST_BRANCH_B(instruction)				\ +	"	b	50f				\n\t"	\ +	"	b	99f				\n\t"	\ +	"2:	nop					\n\t"	\ +	"	b	99f				\n\t"	\ +	TEST_INSTRUCTION(instruction) + +#define TEST_BRANCH_FX(instruction, codex)			\ +	TEST_INSTRUCTION(instruction)				\ +	"	b	99f				\n\t"	\ +	codex"						\n\t"	\  	"	b	99f				\n\t"	\  	"2:	nop					\n\t" -#define TEST_BRANCH_B(instruction, xtra_dist)			\ +#define TEST_BRANCH_BX(instruction, codex)			\  	"	b	50f				\n\t"	\  	"	b	99f				\n\t"	\  	"2:	nop					\n\t"	\  	"	b	99f				\n\t"	\ -	".if "#xtra_dist"				\n\t"	\ -	".space "#xtra_dist"				\n\t"	\ -	".endif						\n\t"	\ +	codex"						\n\t"	\  	TEST_INSTRUCTION(instruction)  #define TESTCASE_END						\ @@ -301,47 +309,60 @@ struct test_arg_end {  	TESTCASE_START(code1 #reg1 code2)	\  	TEST_ARG_PTR(reg1, val1)		\  	TEST_ARG_END("")			\ -	TEST_BRANCH_F(code1 #reg1 code2, 0)	\ +	TEST_BRANCH_F(code1 #reg1 code2)	\  	TESTCASE_END -#define TEST_BF_X(code, xtra_dist)		\ +#define TEST_BF(code)				\  	TESTCASE_START(code)			\  	TEST_ARG_END("")			\ -	TEST_BRANCH_F(code, xtra_dist)		\ +	TEST_BRANCH_F(code)			\  	TESTCASE_END -#define TEST_BB_X(code, xtra_dist)		\ +#define TEST_BB(code)				\  	TESTCASE_START(code)			\  	TEST_ARG_END("")			\ -	TEST_BRANCH_B(code, xtra_dist)		\ +	TEST_BRANCH_B(code)			\  	TESTCASE_END -#define TEST_BF_RX(code1, reg, val, code2, xtra_dist)	\ -	TESTCASE_START(code1 #reg code2)		\ -	TEST_ARG_REG(reg, val)				\ -	TEST_ARG_END("")				\ -	TEST_BRANCH_F(code1 #reg code2, xtra_dist)	\ +#define TEST_BF_R(code1, reg, val, code2)	\ +	TESTCASE_START(code1 #reg code2)	\ +	TEST_ARG_REG(reg, val)			\ +	TEST_ARG_END("")			\ +	TEST_BRANCH_F(code1 #reg code2)		\  	TESTCASE_END -#define TEST_BB_RX(code1, reg, val, code2, xtra_dist)	\ -	TESTCASE_START(code1 #reg code2)		\ -	TEST_ARG_REG(reg, val)				\ -	TEST_ARG_END("")				\ -	TEST_BRANCH_B(code1 #reg code2, xtra_dist)	\ +#define TEST_BB_R(code1, reg, val, code2)	\ +	TESTCASE_START(code1 #reg code2)	\ +	TEST_ARG_REG(reg, val)			\ +	TEST_ARG_END("")			\ +	TEST_BRANCH_B(code1 #reg code2)		\  	TESTCASE_END -#define TEST_BF(code)	TEST_BF_X(code, 0) -#define TEST_BB(code)	TEST_BB_X(code, 0) - -#define TEST_BF_R(code1, reg, val, code2) TEST_BF_RX(code1, reg, val, code2, 0) -#define TEST_BB_R(code1, reg, val, code2) TEST_BB_RX(code1, reg, val, code2, 0) -  #define TEST_BF_RR(code1, reg1, val1, code2, reg2, val2, code3)	\  	TESTCASE_START(code1 #reg1 code2 #reg2 code3)		\  	TEST_ARG_REG(reg1, val1)				\  	TEST_ARG_REG(reg2, val2)				\  	TEST_ARG_END("")					\ -	TEST_BRANCH_F(code1 #reg1 code2 #reg2 code3, 0)		\ +	TEST_BRANCH_F(code1 #reg1 code2 #reg2 code3)		\ +	TESTCASE_END + +#define TEST_BF_X(code, codex)			\ +	TESTCASE_START(code)			\ +	TEST_ARG_END("")			\ +	TEST_BRANCH_FX(code, codex)		\ +	TESTCASE_END + +#define TEST_BB_X(code, codex)			\ +	TESTCASE_START(code)			\ +	TEST_ARG_END("")			\ +	TEST_BRANCH_BX(code, codex)		\ +	TESTCASE_END + +#define TEST_BF_RX(code1, reg, val, code2, codex)	\ +	TESTCASE_START(code1 #reg code2)		\ +	TEST_ARG_REG(reg, val)				\ +	TEST_ARG_END("")				\ +	TEST_BRANCH_FX(code1 #reg code2, codex)		\  	TESTCASE_END  #define TEST_X(code, codex)			\ @@ -372,6 +393,25 @@ struct test_arg_end {  	TESTCASE_END +/* + * Macros for defining space directives spread over multiple lines. + * These are required so the compiler guesses better the length of inline asm + * code and will spill the literal pool early enough to avoid generating PC + * relative loads with out of range offsets. + */ +#define TWICE(x)	x x +#define SPACE_0x8	TWICE(".space 4\n\t") +#define SPACE_0x10	TWICE(SPACE_0x8) +#define SPACE_0x20	TWICE(SPACE_0x10) +#define SPACE_0x40	TWICE(SPACE_0x20) +#define SPACE_0x80	TWICE(SPACE_0x40) +#define SPACE_0x100	TWICE(SPACE_0x80) +#define SPACE_0x200	TWICE(SPACE_0x100) +#define SPACE_0x400	TWICE(SPACE_0x200) +#define SPACE_0x800	TWICE(SPACE_0x400) +#define SPACE_0x1000	TWICE(SPACE_0x800) + +  /* Various values used in test cases... */  #define N(val)	(val ^ 0xffffffff)  #define VAL1	0x12345678  |