| 
					
				 | 
			
			
				@@ -0,0 +1,151 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * arch/arm/kernel/kprobes-test.h 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * Copyright (C) 2011 Jon Medhurst <tixy@yxit.co.uk>. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * This program is free software; you can redistribute it and/or modify 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * it under the terms of the GNU General Public License version 2 as 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * published by the Free Software Foundation. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#define VERBOSE 0 /* Set to '1' for more logging of test cases */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#ifdef CONFIG_THUMB2_KERNEL 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#define NORMAL_ISA "16" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#define NORMAL_ISA "32" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* Flags used in kprobe_test_flags */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#define TEST_FLAG_NO_ITBLOCK	(1<<0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#define TEST_FLAG_FULL_ITBLOCK	(1<<1) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#define TEST_FLAG_NARROW_INSTR	(1<<2) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+extern int kprobe_test_flags; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+extern int kprobe_test_cc_position; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#define TEST_MEMORY_SIZE 256 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * Test case structures. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * The arguments given to test cases can be one of three types. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ *   ARG_TYPE_REG 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ *	Load a register with the given value. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ *   ARG_TYPE_PTR 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ *	Load a register with a pointer into the stack buffer (SP + given value). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ *   ARG_TYPE_MEM 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ *	Store the given value into the stack buffer at [SP+index]. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#define	ARG_TYPE_END	0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#define	ARG_TYPE_REG	1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#define	ARG_TYPE_PTR	2 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#define	ARG_TYPE_MEM	3 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#define ARG_FLAG_UNSUPPORTED	0x01 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#define ARG_FLAG_SUPPORTED	0x02 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#define ARG_FLAG_THUMB		0x10	/* Must be 16 so TEST_ISA can be used */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#define ARG_FLAG_ARM		0x20	/* Must be 32 so TEST_ISA can be used */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+struct test_arg { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	u8	type;		/* ARG_TYPE_x */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	u8	_padding[7]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+struct test_arg_regptr { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	u8	type;		/* ARG_TYPE_REG or ARG_TYPE_PTR */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	u8	reg; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	u8	_padding[2]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	u32	val; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+struct test_arg_mem { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	u8	type;		/* ARG_TYPE_MEM */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	u8	index; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	u8	_padding[2]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	u32	val; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+struct test_arg_end { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	u8	type;		/* ARG_TYPE_END */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	u8	flags;		/* ARG_FLAG_x */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	u16	code_offset; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	u16	branch_offset; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	u16	end_offset; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * Building blocks for test cases. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * Each test case is wrapped between TESTCASE_START and TESTCASE_END. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * To specify arguments for a test case the TEST_ARG_{REG,PTR,MEM} macros are 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * used followed by a terminating TEST_ARG_END. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * After this, the instruction to be tested is defined with TEST_INSTRUCTION. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * Or for branches, TEST_BRANCH_B and TEST_BRANCH_F (branch forwards/backwards). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * Some specific test cases may make use of other custom constructs. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#if VERBOSE 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#define verbose(fmt, ...) pr_info(fmt, ##__VA_ARGS__) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#define verbose(fmt, ...) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#define TEST_GROUP(title)					\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	verbose("\n");						\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	verbose(title"\n");					\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	verbose("---------------------------------------------------------\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#define TESTCASE_START(title)					\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	__asm__ __volatile__ (					\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	"bl	__kprobes_test_case_start		\n\t"	\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	/* don't use .asciz here as 'title' may be */		\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	/* multiple strings to be concatenated.  */		\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	".ascii "#title"				\n\t"	\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	".byte	0					\n\t"	\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	".align	2					\n\t" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#define	TEST_ARG_REG(reg, val)					\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	".byte	"__stringify(ARG_TYPE_REG)"		\n\t"	\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	".byte	"#reg"					\n\t"	\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	".short	0					\n\t"	\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	".word	"#val"					\n\t" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#define	TEST_ARG_PTR(reg, val)					\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	".byte	"__stringify(ARG_TYPE_PTR)"		\n\t"	\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	".byte	"#reg"					\n\t"	\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	".short	0					\n\t"	\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	".word	"#val"					\n\t" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#define	TEST_ARG_MEM(index, val)				\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	".byte	"__stringify(ARG_TYPE_MEM)"		\n\t"	\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	".byte	"#index"				\n\t"	\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	".short	0					\n\t"	\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	".word	"#val"					\n\t" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#define	TEST_ARG_END(flags)					\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	".byte	"__stringify(ARG_TYPE_END)"		\n\t"	\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	".byte	"TEST_ISA flags"			\n\t"	\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	".short	50f-0f					\n\t"	\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	".short	2f-0f					\n\t"	\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	".short	99f-0f					\n\t"	\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	".code "TEST_ISA"				\n\t"	\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	"0:						\n\t" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#define TEST_INSTRUCTION(instruction)				\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	"50:	nop					\n\t"	\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	"1:	"instruction"				\n\t"	\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	"	nop					\n\t" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 |