/* * arch/arm/kernel/kprobes-test.h * * Copyright (C) 2011 Jon Medhurst . * * 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"