|
@@ -149,3 +149,189 @@ struct test_arg_end {
|
|
|
"1: "instruction" \n\t" \
|
|
|
" nop \n\t"
|
|
|
|
|
|
+#define TEST_BRANCH_F(instruction) \
|
|
|
+ TEST_INSTRUCTION(instruction) \
|
|
|
+ " b 99f \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_BX(instruction, codex) \
|
|
|
+ " b 50f \n\t" \
|
|
|
+ " b 99f \n\t" \
|
|
|
+ "2: nop \n\t" \
|
|
|
+ " b 99f \n\t" \
|
|
|
+ codex" \n\t" \
|
|
|
+ TEST_INSTRUCTION(instruction)
|
|
|
+
|
|
|
+#define TESTCASE_END \
|
|
|
+ "2: \n\t" \
|
|
|
+ "99: \n\t" \
|
|
|
+ " bl __kprobes_test_case_end_"TEST_ISA" \n\t" \
|
|
|
+ ".code "NORMAL_ISA" \n\t" \
|
|
|
+ : : \
|
|
|
+ : "r0", "r1", "r2", "r3", "ip", "lr", "memory", "cc" \
|
|
|
+ );
|
|
|
+
|
|
|
+
|
|
|
+/*
|
|
|
+ * Macros to define test cases.
|
|
|
+ *
|
|
|
+ * Those of the form TEST_{R,P,M}* can be used to define test cases
|
|
|
+ * which take combinations of the three basic types of arguments. E.g.
|
|
|
+ *
|
|
|
+ * TEST_R One register argument
|
|
|
+ * TEST_RR Two register arguments
|
|
|
+ * TEST_RPR A register, a pointer, then a register argument
|
|
|
+ *
|
|
|
+ * For testing instructions which may branch, there are macros TEST_BF_*
|
|
|
+ * and TEST_BB_* for branching forwards and backwards.
|
|
|
+ *
|
|
|
+ * TEST_SUPPORTED and TEST_UNSUPPORTED don't cause the code to be executed,
|
|
|
+ * the just verify that a kprobe is or is not allowed on the given instruction.
|
|
|
+ */
|
|
|
+
|
|
|
+#define TEST(code) \
|
|
|
+ TESTCASE_START(code) \
|
|
|
+ TEST_ARG_END("") \
|
|
|
+ TEST_INSTRUCTION(code) \
|
|
|
+ TESTCASE_END
|
|
|
+
|
|
|
+#define TEST_UNSUPPORTED(code) \
|
|
|
+ TESTCASE_START(code) \
|
|
|
+ TEST_ARG_END("|"__stringify(ARG_FLAG_UNSUPPORTED)) \
|
|
|
+ TEST_INSTRUCTION(code) \
|
|
|
+ TESTCASE_END
|
|
|
+
|
|
|
+#define TEST_SUPPORTED(code) \
|
|
|
+ TESTCASE_START(code) \
|
|
|
+ TEST_ARG_END("|"__stringify(ARG_FLAG_SUPPORTED)) \
|
|
|
+ TEST_INSTRUCTION(code) \
|
|
|
+ TESTCASE_END
|
|
|
+
|
|
|
+#define TEST_R(code1, reg, val, code2) \
|
|
|
+ TESTCASE_START(code1 #reg code2) \
|
|
|
+ TEST_ARG_REG(reg, val) \
|
|
|
+ TEST_ARG_END("") \
|
|
|
+ TEST_INSTRUCTION(code1 #reg code2) \
|
|
|
+ TESTCASE_END
|
|
|
+
|
|
|
+#define TEST_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_INSTRUCTION(code1 #reg1 code2 #reg2 code3) \
|
|
|
+ TESTCASE_END
|
|
|
+
|
|
|
+#define TEST_RRR(code1, reg1, val1, code2, reg2, val2, code3, reg3, val3, code4)\
|
|
|
+ TESTCASE_START(code1 #reg1 code2 #reg2 code3 #reg3 code4) \
|
|
|
+ TEST_ARG_REG(reg1, val1) \
|
|
|
+ TEST_ARG_REG(reg2, val2) \
|
|
|
+ TEST_ARG_REG(reg3, val3) \
|
|
|
+ TEST_ARG_END("") \
|
|
|
+ TEST_INSTRUCTION(code1 #reg1 code2 #reg2 code3 #reg3 code4) \
|
|
|
+ TESTCASE_END
|
|
|
+
|
|
|
+#define TEST_RRRR(code1, reg1, val1, code2, reg2, val2, code3, reg3, val3, code4, reg4, val4) \
|
|
|
+ TESTCASE_START(code1 #reg1 code2 #reg2 code3 #reg3 code4 #reg4) \
|
|
|
+ TEST_ARG_REG(reg1, val1) \
|
|
|
+ TEST_ARG_REG(reg2, val2) \
|
|
|
+ TEST_ARG_REG(reg3, val3) \
|
|
|
+ TEST_ARG_REG(reg4, val4) \
|
|
|
+ TEST_ARG_END("") \
|
|
|
+ TEST_INSTRUCTION(code1 #reg1 code2 #reg2 code3 #reg3 code4 #reg4) \
|
|
|
+ TESTCASE_END
|
|
|
+
|
|
|
+#define TEST_P(code1, reg1, val1, code2) \
|
|
|
+ TESTCASE_START(code1 #reg1 code2) \
|
|
|
+ TEST_ARG_PTR(reg1, val1) \
|
|
|
+ TEST_ARG_END("") \
|
|
|
+ TEST_INSTRUCTION(code1 #reg1 code2) \
|
|
|
+ TESTCASE_END
|
|
|
+
|
|
|
+#define TEST_PR(code1, reg1, val1, code2, reg2, val2, code3) \
|
|
|
+ TESTCASE_START(code1 #reg1 code2 #reg2 code3) \
|
|
|
+ TEST_ARG_PTR(reg1, val1) \
|
|
|
+ TEST_ARG_REG(reg2, val2) \
|
|
|
+ TEST_ARG_END("") \
|
|
|
+ TEST_INSTRUCTION(code1 #reg1 code2 #reg2 code3) \
|
|
|
+ TESTCASE_END
|
|
|
+
|
|
|
+#define TEST_RP(code1, reg1, val1, code2, reg2, val2, code3) \
|
|
|
+ TESTCASE_START(code1 #reg1 code2 #reg2 code3) \
|
|
|
+ TEST_ARG_REG(reg1, val1) \
|
|
|
+ TEST_ARG_PTR(reg2, val2) \
|
|
|
+ TEST_ARG_END("") \
|
|
|
+ TEST_INSTRUCTION(code1 #reg1 code2 #reg2 code3) \
|
|
|
+ TESTCASE_END
|
|
|
+
|
|
|
+#define TEST_PRR(code1, reg1, val1, code2, reg2, val2, code3, reg3, val3, code4)\
|
|
|
+ TESTCASE_START(code1 #reg1 code2 #reg2 code3 #reg3 code4) \
|
|
|
+ TEST_ARG_PTR(reg1, val1) \
|
|
|
+ TEST_ARG_REG(reg2, val2) \
|
|
|
+ TEST_ARG_REG(reg3, val3) \
|
|
|
+ TEST_ARG_END("") \
|
|
|
+ TEST_INSTRUCTION(code1 #reg1 code2 #reg2 code3 #reg3 code4) \
|
|
|
+ TESTCASE_END
|
|
|
+
|
|
|
+#define TEST_RPR(code1, reg1, val1, code2, reg2, val2, code3, reg3, val3, code4)\
|
|
|
+ TESTCASE_START(code1 #reg1 code2 #reg2 code3 #reg3 code4) \
|
|
|
+ TEST_ARG_REG(reg1, val1) \
|
|
|
+ TEST_ARG_PTR(reg2, val2) \
|
|
|
+ TEST_ARG_REG(reg3, val3) \
|
|
|
+ TEST_ARG_END("") \
|
|
|
+ TEST_INSTRUCTION(code1 #reg1 code2 #reg2 code3 #reg3 code4) \
|
|
|
+ TESTCASE_END
|
|
|
+
|
|
|
+#define TEST_RRP(code1, reg1, val1, code2, reg2, val2, code3, reg3, val3, code4)\
|
|
|
+ TESTCASE_START(code1 #reg1 code2 #reg2 code3 #reg3 code4) \
|
|
|
+ TEST_ARG_REG(reg1, val1) \
|
|
|
+ TEST_ARG_REG(reg2, val2) \
|
|
|
+ TEST_ARG_PTR(reg3, val3) \
|
|
|
+ TEST_ARG_END("") \
|
|
|
+ TEST_INSTRUCTION(code1 #reg1 code2 #reg2 code3 #reg3 code4) \
|
|
|
+ TESTCASE_END
|
|
|
+
|
|
|
+#define TEST_BF_P(code1, reg1, val1, code2) \
|
|
|
+ TESTCASE_START(code1 #reg1 code2) \
|
|
|
+ TEST_ARG_PTR(reg1, val1) \
|
|
|
+ TEST_ARG_END("") \
|
|
|
+ TEST_BRANCH_F(code1 #reg1 code2) \
|
|
|
+ TESTCASE_END
|
|
|
+
|
|
|
+#define TEST_BF(code) \
|
|
|
+ TESTCASE_START(code) \
|
|
|
+ TEST_ARG_END("") \
|
|
|
+ TEST_BRANCH_F(code) \
|
|
|
+ TESTCASE_END
|
|
|
+
|
|
|
+#define TEST_BB(code) \
|
|
|
+ TESTCASE_START(code) \
|
|
|
+ TEST_ARG_END("") \
|
|
|
+ TEST_BRANCH_B(code) \
|
|
|
+ TESTCASE_END
|
|
|
+
|
|
|
+#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_R(code1, reg, val, code2) \
|
|
|
+ TESTCASE_START(code1 #reg code2) \
|
|
|
+ TEST_ARG_REG(reg, val) \
|
|
|
+ TEST_ARG_END("") \
|