diff options
author | Wang Nan <wangnan0@huawei.com> | 2015-01-05 06:29:21 -0500 |
---|---|---|
committer | Jon Medhurst <tixy@linaro.org> | 2015-01-13 11:10:06 -0500 |
commit | 6624cf651f1a14363d0385f36dc255d304ac7ebb (patch) | |
tree | 38cb38d33f5faa96e36814caa3fa63bfe322c193 /arch/arm/probes/kprobes | |
parent | 83803d97dae1eaf6850a45ef8ee179cc66e147dc (diff) |
ARM: kprobes: collects stack consumption for store instructions
This patch uses the previously introduced checker functionality on
store instructions to record their stack consumption information to
arch_probes_insn.
Signed-off-by: Wang Nan <wangnan0@huawei.com>
Reviewed-by: Jon Medhurst <tixy@linaro.org>
Signed-off-by: Jon Medhurst <tixy@linaro.org>
Diffstat (limited to 'arch/arm/probes/kprobes')
-rw-r--r-- | arch/arm/probes/kprobes/Makefile | 6 | ||||
-rw-r--r-- | arch/arm/probes/kprobes/actions-arm.c | 3 | ||||
-rw-r--r-- | arch/arm/probes/kprobes/actions-thumb.c | 5 | ||||
-rw-r--r-- | arch/arm/probes/kprobes/checkers-arm.c | 99 | ||||
-rw-r--r-- | arch/arm/probes/kprobes/checkers-common.c | 101 | ||||
-rw-r--r-- | arch/arm/probes/kprobes/checkers-thumb.c | 110 | ||||
-rw-r--r-- | arch/arm/probes/kprobes/checkers.h | 54 |
7 files changed, 372 insertions, 6 deletions
diff --git a/arch/arm/probes/kprobes/Makefile b/arch/arm/probes/kprobes/Makefile index eb38a428ecd6..bc8d504c3d78 100644 --- a/arch/arm/probes/kprobes/Makefile +++ b/arch/arm/probes/kprobes/Makefile | |||
@@ -1,11 +1,11 @@ | |||
1 | obj-$(CONFIG_KPROBES) += core.o actions-common.o | 1 | obj-$(CONFIG_KPROBES) += core.o actions-common.o checkers-common.o |
2 | obj-$(CONFIG_ARM_KPROBES_TEST) += test-kprobes.o | 2 | obj-$(CONFIG_ARM_KPROBES_TEST) += test-kprobes.o |
3 | test-kprobes-objs := test-core.o | 3 | test-kprobes-objs := test-core.o |
4 | 4 | ||
5 | ifdef CONFIG_THUMB2_KERNEL | 5 | ifdef CONFIG_THUMB2_KERNEL |
6 | obj-$(CONFIG_KPROBES) += actions-thumb.o | 6 | obj-$(CONFIG_KPROBES) += actions-thumb.o checkers-thumb.o |
7 | test-kprobes-objs += test-thumb.o | 7 | test-kprobes-objs += test-thumb.o |
8 | else | 8 | else |
9 | obj-$(CONFIG_KPROBES) += actions-arm.o | 9 | obj-$(CONFIG_KPROBES) += actions-arm.o checkers-arm.o |
10 | test-kprobes-objs += test-arm.o | 10 | test-kprobes-objs += test-arm.o |
11 | endif | 11 | endif |
diff --git a/arch/arm/probes/kprobes/actions-arm.c b/arch/arm/probes/kprobes/actions-arm.c index fbd93a9ada75..06988ef7eeb7 100644 --- a/arch/arm/probes/kprobes/actions-arm.c +++ b/arch/arm/probes/kprobes/actions-arm.c | |||
@@ -64,6 +64,7 @@ | |||
64 | 64 | ||
65 | #include "../decode-arm.h" | 65 | #include "../decode-arm.h" |
66 | #include "core.h" | 66 | #include "core.h" |
67 | #include "checkers.h" | ||
67 | 68 | ||
68 | #if __LINUX_ARM_ARCH__ >= 6 | 69 | #if __LINUX_ARM_ARCH__ >= 6 |
69 | #define BLX(reg) "blx "reg" \n\t" | 70 | #define BLX(reg) "blx "reg" \n\t" |
@@ -340,4 +341,4 @@ const union decode_action kprobes_arm_actions[NUM_PROBES_ARM_ACTIONS] = { | |||
340 | [PROBES_LDMSTM] = {.decoder = kprobe_decode_ldmstm} | 341 | [PROBES_LDMSTM] = {.decoder = kprobe_decode_ldmstm} |
341 | }; | 342 | }; |
342 | 343 | ||
343 | const struct decode_checker *kprobes_arm_checkers[] = {NULL}; | 344 | const struct decode_checker *kprobes_arm_checkers[] = {arm_stack_checker, NULL}; |
diff --git a/arch/arm/probes/kprobes/actions-thumb.c b/arch/arm/probes/kprobes/actions-thumb.c index 2796121fe90e..07cfd9bef340 100644 --- a/arch/arm/probes/kprobes/actions-thumb.c +++ b/arch/arm/probes/kprobes/actions-thumb.c | |||
@@ -15,6 +15,7 @@ | |||
15 | 15 | ||
16 | #include "../decode-thumb.h" | 16 | #include "../decode-thumb.h" |
17 | #include "core.h" | 17 | #include "core.h" |
18 | #include "checkers.h" | ||
18 | 19 | ||
19 | /* These emulation encodings are functionally equivalent... */ | 20 | /* These emulation encodings are functionally equivalent... */ |
20 | #define t32_emulate_rd8rn16rm0ra12_noflags \ | 21 | #define t32_emulate_rd8rn16rm0ra12_noflags \ |
@@ -665,5 +666,5 @@ const union decode_action kprobes_t32_actions[NUM_PROBES_T32_ACTIONS] = { | |||
665 | .handler = t32_emulate_rdlo12rdhi8rn16rm0_noflags}, | 666 | .handler = t32_emulate_rdlo12rdhi8rn16rm0_noflags}, |
666 | }; | 667 | }; |
667 | 668 | ||
668 | const struct decode_checker *kprobes_t32_checkers[] = {NULL}; | 669 | const struct decode_checker *kprobes_t32_checkers[] = {t32_stack_checker, NULL}; |
669 | const struct decode_checker *kprobes_t16_checkers[] = {NULL}; | 670 | const struct decode_checker *kprobes_t16_checkers[] = {t16_stack_checker, NULL}; |
diff --git a/arch/arm/probes/kprobes/checkers-arm.c b/arch/arm/probes/kprobes/checkers-arm.c new file mode 100644 index 000000000000..f8176631d2a5 --- /dev/null +++ b/arch/arm/probes/kprobes/checkers-arm.c | |||
@@ -0,0 +1,99 @@ | |||
1 | /* | ||
2 | * arch/arm/probes/kprobes/checkers-arm.c | ||
3 | * | ||
4 | * Copyright (C) 2014 Huawei Inc. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | * General Public License for more details. | ||
14 | */ | ||
15 | |||
16 | #include <linux/kernel.h> | ||
17 | #include "../decode.h" | ||
18 | #include "../decode-arm.h" | ||
19 | #include "checkers.h" | ||
20 | |||
21 | static enum probes_insn __kprobes arm_check_stack(probes_opcode_t insn, | ||
22 | struct arch_probes_insn *asi, | ||
23 | const struct decode_header *h) | ||
24 | { | ||
25 | /* | ||
26 | * PROBES_LDRSTRD, PROBES_LDMSTM, PROBES_STORE, | ||
27 | * PROBES_STORE_EXTRA may get here. Simply mark all normal | ||
28 | * insns as STACK_USE_NONE. | ||
29 | */ | ||
30 | static const union decode_item table[] = { | ||
31 | /* | ||
32 | * 'STR{,D,B,H}, Rt, [Rn, Rm]' should be marked as UNKNOWN | ||
33 | * if Rn or Rm is SP. | ||
34 | * x | ||
35 | * STR (register) cccc 011x x0x0 xxxx xxxx xxxx xxxx xxxx | ||
36 | * STRB (register) cccc 011x x1x0 xxxx xxxx xxxx xxxx xxxx | ||
37 | */ | ||
38 | DECODE_OR (0x0e10000f, 0x0600000d), | ||
39 | DECODE_OR (0x0e1f0000, 0x060d0000), | ||
40 | |||
41 | /* | ||
42 | * x | ||
43 | * STRD (register) cccc 000x x0x0 xxxx xxxx xxxx 1111 xxxx | ||
44 | * STRH (register) cccc 000x x0x0 xxxx xxxx xxxx 1011 xxxx | ||
45 | */ | ||
46 | DECODE_OR (0x0e5000bf, 0x000000bd), | ||
47 | DECODE_CUSTOM (0x0e5f00b0, 0x000d00b0, STACK_USE_UNKNOWN), | ||
48 | |||
49 | /* | ||
50 | * For PROBES_LDMSTM, only stmdx sp, [...] need to examine | ||
51 | * | ||
52 | * Bit B/A (bit 24) encodes arithmetic operation order. 1 means | ||
53 | * before, 0 means after. | ||
54 | * Bit I/D (bit 23) encodes arithmetic operation. 1 means | ||
55 | * increment, 0 means decrement. | ||
56 | * | ||
57 | * So: | ||
58 | * B I | ||
59 | * / / | ||
60 | * A D | Rn | | ||
61 | * STMDX SP, [...] cccc 100x 00x0 xxxx xxxx xxxx xxxx xxxx | ||
62 | */ | ||
63 | DECODE_CUSTOM (0x0edf0000, 0x080d0000, STACK_USE_STMDX), | ||
64 | |||
65 | /* P U W | Rn | Rt | imm12 |*/ | ||
66 | /* STR (immediate) cccc 010x x0x0 1101 xxxx xxxx xxxx xxxx */ | ||
67 | /* STRB (immediate) cccc 010x x1x0 1101 xxxx xxxx xxxx xxxx */ | ||
68 | /* P U W | Rn | Rt |imm4| |imm4|*/ | ||
69 | /* STRD (immediate) cccc 000x x1x0 1101 xxxx xxxx 1111 xxxx */ | ||
70 | /* STRH (immediate) cccc 000x x1x0 1101 xxxx xxxx 1011 xxxx */ | ||
71 | /* | ||
72 | * index = (P == '1'); add = (U == '1'). | ||
73 | * Above insns with: | ||
74 | * index == 0 (str{,d,h} rx, [sp], #+/-imm) or | ||
75 | * add == 1 (str{,d,h} rx, [sp, #+<imm>]) | ||
76 | * should be STACK_USE_NONE. | ||
77 | * Only str{,b,d,h} rx,[sp,#-n] (P == 1 and U == 0) are | ||
78 | * required to be examined. | ||
79 | */ | ||
80 | /* STR{,B} Rt,[SP,#-n] cccc 0101 0xx0 1101 xxxx xxxx xxxx xxxx */ | ||
81 | DECODE_CUSTOM (0x0f9f0000, 0x050d0000, STACK_USE_FIXED_XXX), | ||
82 | |||
83 | /* STR{D,H} Rt,[SP,#-n] cccc 0001 01x0 1101 xxxx xxxx 1x11 xxxx */ | ||
84 | DECODE_CUSTOM (0x0fdf00b0, 0x014d00b0, STACK_USE_FIXED_X0X), | ||
85 | |||
86 | /* fall through */ | ||
87 | DECODE_CUSTOM (0, 0, STACK_USE_NONE), | ||
88 | DECODE_END | ||
89 | }; | ||
90 | |||
91 | return probes_decode_insn(insn, asi, table, false, false, stack_check_actions, NULL); | ||
92 | } | ||
93 | |||
94 | const struct decode_checker arm_stack_checker[NUM_PROBES_ARM_ACTIONS] = { | ||
95 | [PROBES_LDRSTRD] = {.checker = arm_check_stack}, | ||
96 | [PROBES_STORE_EXTRA] = {.checker = arm_check_stack}, | ||
97 | [PROBES_STORE] = {.checker = arm_check_stack}, | ||
98 | [PROBES_LDMSTM] = {.checker = arm_check_stack}, | ||
99 | }; | ||
diff --git a/arch/arm/probes/kprobes/checkers-common.c b/arch/arm/probes/kprobes/checkers-common.c new file mode 100644 index 000000000000..971119c29474 --- /dev/null +++ b/arch/arm/probes/kprobes/checkers-common.c | |||
@@ -0,0 +1,101 @@ | |||
1 | /* | ||
2 | * arch/arm/probes/kprobes/checkers-common.c | ||
3 | * | ||
4 | * Copyright (C) 2014 Huawei Inc. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | * General Public License for more details. | ||
14 | */ | ||
15 | |||
16 | #include <linux/kernel.h> | ||
17 | #include "../decode.h" | ||
18 | #include "../decode-arm.h" | ||
19 | #include "checkers.h" | ||
20 | |||
21 | enum probes_insn checker_stack_use_none(probes_opcode_t insn, | ||
22 | struct arch_probes_insn *asi, | ||
23 | const struct decode_header *h) | ||
24 | { | ||
25 | asi->stack_space = 0; | ||
26 | return INSN_GOOD_NO_SLOT; | ||
27 | } | ||
28 | |||
29 | enum probes_insn checker_stack_use_unknown(probes_opcode_t insn, | ||
30 | struct arch_probes_insn *asi, | ||
31 | const struct decode_header *h) | ||
32 | { | ||
33 | asi->stack_space = -1; | ||
34 | return INSN_GOOD_NO_SLOT; | ||
35 | } | ||
36 | |||
37 | #ifdef CONFIG_THUMB2_KERNEL | ||
38 | enum probes_insn checker_stack_use_imm_0xx(probes_opcode_t insn, | ||
39 | struct arch_probes_insn *asi, | ||
40 | const struct decode_header *h) | ||
41 | { | ||
42 | int imm = insn & 0xff; | ||
43 | asi->stack_space = imm; | ||
44 | return INSN_GOOD_NO_SLOT; | ||
45 | } | ||
46 | |||
47 | /* | ||
48 | * Different from other insn uses imm8, the real addressing offset of | ||
49 | * STRD in T32 encoding should be imm8 * 4. See ARMARM description. | ||
50 | */ | ||
51 | enum probes_insn checker_stack_use_t32strd(probes_opcode_t insn, | ||
52 | struct arch_probes_insn *asi, | ||
53 | const struct decode_header *h) | ||
54 | { | ||
55 | int imm = insn & 0xff; | ||
56 | asi->stack_space = imm << 2; | ||
57 | return INSN_GOOD_NO_SLOT; | ||
58 | } | ||
59 | #else | ||
60 | enum probes_insn checker_stack_use_imm_x0x(probes_opcode_t insn, | ||
61 | struct arch_probes_insn *asi, | ||
62 | const struct decode_header *h) | ||
63 | { | ||
64 | int imm = ((insn & 0xf00) >> 4) + (insn & 0xf); | ||
65 | asi->stack_space = imm; | ||
66 | return INSN_GOOD_NO_SLOT; | ||
67 | } | ||
68 | #endif | ||
69 | |||
70 | enum probes_insn checker_stack_use_imm_xxx(probes_opcode_t insn, | ||
71 | struct arch_probes_insn *asi, | ||
72 | const struct decode_header *h) | ||
73 | { | ||
74 | int imm = insn & 0xfff; | ||
75 | asi->stack_space = imm; | ||
76 | return INSN_GOOD_NO_SLOT; | ||
77 | } | ||
78 | |||
79 | enum probes_insn checker_stack_use_stmdx(probes_opcode_t insn, | ||
80 | struct arch_probes_insn *asi, | ||
81 | const struct decode_header *h) | ||
82 | { | ||
83 | unsigned int reglist = insn & 0xffff; | ||
84 | int pbit = insn & (1 << 24); | ||
85 | asi->stack_space = (hweight32(reglist) - (!pbit ? 1 : 0)) * 4; | ||
86 | |||
87 | return INSN_GOOD_NO_SLOT; | ||
88 | } | ||
89 | |||
90 | const union decode_action stack_check_actions[] = { | ||
91 | [STACK_USE_NONE] = {.decoder = checker_stack_use_none}, | ||
92 | [STACK_USE_UNKNOWN] = {.decoder = checker_stack_use_unknown}, | ||
93 | #ifdef CONFIG_THUMB2_KERNEL | ||
94 | [STACK_USE_FIXED_0XX] = {.decoder = checker_stack_use_imm_0xx}, | ||
95 | [STACK_USE_T32STRD] = {.decoder = checker_stack_use_t32strd}, | ||
96 | #else | ||
97 | [STACK_USE_FIXED_X0X] = {.decoder = checker_stack_use_imm_x0x}, | ||
98 | #endif | ||
99 | [STACK_USE_FIXED_XXX] = {.decoder = checker_stack_use_imm_xxx}, | ||
100 | [STACK_USE_STMDX] = {.decoder = checker_stack_use_stmdx}, | ||
101 | }; | ||
diff --git a/arch/arm/probes/kprobes/checkers-thumb.c b/arch/arm/probes/kprobes/checkers-thumb.c new file mode 100644 index 000000000000..d608e3b9017a --- /dev/null +++ b/arch/arm/probes/kprobes/checkers-thumb.c | |||
@@ -0,0 +1,110 @@ | |||
1 | /* | ||
2 | * arch/arm/probes/kprobes/checkers-thumb.c | ||
3 | * | ||
4 | * Copyright (C) 2014 Huawei Inc. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | * General Public License for more details. | ||
14 | */ | ||
15 | |||
16 | #include <linux/kernel.h> | ||
17 | #include "../decode.h" | ||
18 | #include "../decode-thumb.h" | ||
19 | #include "checkers.h" | ||
20 | |||
21 | static enum probes_insn __kprobes t32_check_stack(probes_opcode_t insn, | ||
22 | struct arch_probes_insn *asi, | ||
23 | const struct decode_header *h) | ||
24 | { | ||
25 | /* | ||
26 | * PROBES_T32_LDMSTM, PROBES_T32_LDRDSTRD and PROBES_T32_LDRSTR | ||
27 | * may get here. Simply mark all normal insns as STACK_USE_NONE. | ||
28 | */ | ||
29 | static const union decode_item table[] = { | ||
30 | |||
31 | /* | ||
32 | * First, filter out all ldr insns to make our life easier. | ||
33 | * Following load insns may come here: | ||
34 | * LDM, LDRD, LDR. | ||
35 | * In T32 encoding, bit 20 is enough for distinguishing | ||
36 | * load and store. All load insns have this bit set, when | ||
37 | * all store insns have this bit clear. | ||
38 | */ | ||
39 | DECODE_CUSTOM (0x00100000, 0x00100000, STACK_USE_NONE), | ||
40 | |||
41 | /* | ||
42 | * Mark all 'STR{,B,H}, Rt, [Rn, Rm]' as STACK_USE_UNKNOWN | ||
43 | * if Rn or Rm is SP. T32 doesn't encode STRD. | ||
44 | */ | ||
45 | /* xx | Rn | Rt | | Rm |*/ | ||
46 | /* STR (register) 1111 1000 0100 xxxx xxxx 0000 00xx xxxx */ | ||
47 | /* STRB (register) 1111 1000 0000 xxxx xxxx 0000 00xx xxxx */ | ||
48 | /* STRH (register) 1111 1000 0010 xxxx xxxx 0000 00xx xxxx */ | ||
49 | /* INVALID INSN 1111 1000 0110 xxxx xxxx 0000 00xx xxxx */ | ||
50 | /* By Introducing INVALID INSN, bit 21 and 22 can be ignored. */ | ||
51 | DECODE_OR (0xff9f0fc0, 0xf80d0000), | ||
52 | DECODE_CUSTOM (0xff900fcf, 0xf800000d, STACK_USE_UNKNOWN), | ||
53 | |||
54 | |||
55 | /* xx | Rn | Rt | PUW| imm8 |*/ | ||
56 | /* STR (imm 8) 1111 1000 0100 1101 xxxx 110x xxxx xxxx */ | ||
57 | /* STRB (imm 8) 1111 1000 0000 1101 xxxx 110x xxxx xxxx */ | ||
58 | /* STRH (imm 8) 1111 1000 0010 1101 xxxx 110x xxxx xxxx */ | ||
59 | /* INVALID INSN 1111 1000 0110 1101 xxxx 110x xxxx xxxx */ | ||
60 | /* Only consider U == 0 and P == 1: strx rx, [sp, #-<imm>] */ | ||
61 | DECODE_CUSTOM (0xff9f0e00, 0xf80d0c00, STACK_USE_FIXED_0XX), | ||
62 | |||
63 | /* For STR{,B,H} (imm 12), offset is always positive, so ignore them. */ | ||
64 | |||
65 | /* P U W | Rn | Rt | Rt2| imm8 |*/ | ||
66 | /* STRD (immediate) 1110 1001 01x0 1101 xxxx xxxx xxxx xxxx */ | ||
67 | /* | ||
68 | * Only consider U == 0 and P == 1. | ||
69 | * Also note that STRD in T32 encoding is special: | ||
70 | * imm = ZeroExtend(imm8:'00', 32) | ||
71 | */ | ||
72 | DECODE_CUSTOM (0xffdf0000, 0xe94d0000, STACK_USE_T32STRD), | ||
73 | |||
74 | /* | Rn | */ | ||
75 | /* STMDB 1110 1001 00x0 1101 xxxx xxxx xxxx xxxx */ | ||
76 | DECODE_CUSTOM (0xffdf0000, 0xe90d0000, STACK_USE_STMDX), | ||
77 | |||
78 | /* fall through */ | ||
79 | DECODE_CUSTOM (0, 0, STACK_USE_NONE), | ||
80 | DECODE_END | ||
81 | }; | ||
82 | |||
83 | return probes_decode_insn(insn, asi, table, false, false, stack_check_actions, NULL); | ||
84 | } | ||
85 | |||
86 | const struct decode_checker t32_stack_checker[NUM_PROBES_T32_ACTIONS] = { | ||
87 | [PROBES_T32_LDMSTM] = {.checker = t32_check_stack}, | ||
88 | [PROBES_T32_LDRDSTRD] = {.checker = t32_check_stack}, | ||
89 | [PROBES_T32_LDRSTR] = {.checker = t32_check_stack}, | ||
90 | }; | ||
91 | |||
92 | /* | ||
93 | * See following comments. This insn must be 'push'. | ||
94 | */ | ||
95 | static enum probes_insn __kprobes t16_check_stack(probes_opcode_t insn, | ||
96 | struct arch_probes_insn *asi, | ||
97 | const struct decode_header *h) | ||
98 | { | ||
99 | unsigned int reglist = insn & 0x1ff; | ||
100 | asi->stack_space = hweight32(reglist) * 4; | ||
101 | return INSN_GOOD; | ||
102 | } | ||
103 | |||
104 | /* | ||
105 | * T16 encoding is simple: only the 'push' insn can need extra stack space. | ||
106 | * Other insns, like str, can only use r0-r7 as Rn. | ||
107 | */ | ||
108 | const struct decode_checker t16_stack_checker[NUM_PROBES_T16_ACTIONS] = { | ||
109 | [PROBES_T16_PUSH] = {.checker = t16_check_stack}, | ||
110 | }; | ||
diff --git a/arch/arm/probes/kprobes/checkers.h b/arch/arm/probes/kprobes/checkers.h new file mode 100644 index 000000000000..bddfa0e82389 --- /dev/null +++ b/arch/arm/probes/kprobes/checkers.h | |||
@@ -0,0 +1,54 @@ | |||
1 | /* | ||
2 | * arch/arm/probes/kprobes/checkers.h | ||
3 | * | ||
4 | * Copyright (C) 2014 Huawei Inc. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | * General Public License for more details. | ||
14 | */ | ||
15 | #ifndef _ARM_KERNEL_PROBES_CHECKERS_H | ||
16 | #define _ARM_KERNEL_PROBES_CHECKERS_H | ||
17 | |||
18 | #include <linux/kernel.h> | ||
19 | #include <linux/types.h> | ||
20 | #include "../decode.h" | ||
21 | |||
22 | extern probes_check_t checker_stack_use_none; | ||
23 | extern probes_check_t checker_stack_use_unknown; | ||
24 | #ifdef CONFIG_THUMB2_KERNEL | ||
25 | extern probes_check_t checker_stack_use_imm_0xx; | ||
26 | #else | ||
27 | extern probes_check_t checker_stack_use_imm_x0x; | ||
28 | #endif | ||
29 | extern probes_check_t checker_stack_use_imm_xxx; | ||
30 | extern probes_check_t checker_stack_use_stmdx; | ||
31 | |||
32 | enum { | ||
33 | STACK_USE_NONE, | ||
34 | STACK_USE_UNKNOWN, | ||
35 | #ifdef CONFIG_THUMB2_KERNEL | ||
36 | STACK_USE_FIXED_0XX, | ||
37 | STACK_USE_T32STRD, | ||
38 | #else | ||
39 | STACK_USE_FIXED_X0X, | ||
40 | #endif | ||
41 | STACK_USE_FIXED_XXX, | ||
42 | STACK_USE_STMDX, | ||
43 | NUM_STACK_USE_TYPES | ||
44 | }; | ||
45 | |||
46 | extern const union decode_action stack_check_actions[]; | ||
47 | |||
48 | #ifndef CONFIG_THUMB2_KERNEL | ||
49 | extern const struct decode_checker arm_stack_checker[]; | ||
50 | #else | ||
51 | #endif | ||
52 | extern const struct decode_checker t32_stack_checker[]; | ||
53 | extern const struct decode_checker t16_stack_checker[]; | ||
54 | #endif | ||