aboutsummaryrefslogtreecommitdiff
path: root/arch/arm
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm')
-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 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