2 * arch/arm/probes/kprobes/checkers-common.c
4 * Copyright (C) 2014 Huawei Inc.
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.
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.
16 #include <linux/kernel.h>
17 #include "../decode.h"
18 #include "../decode-arm.h"
21 enum probes_insn
checker_stack_use_none(probes_opcode_t insn
,
22 struct arch_probes_insn
*asi
,
23 const struct decode_header
*h
)
26 return INSN_GOOD_NO_SLOT
;
29 enum probes_insn
checker_stack_use_unknown(probes_opcode_t insn
,
30 struct arch_probes_insn
*asi
,
31 const struct decode_header
*h
)
33 asi
->stack_space
= -1;
34 return INSN_GOOD_NO_SLOT
;
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
)
42 int imm
= insn
& 0xff;
43 asi
->stack_space
= imm
;
44 return INSN_GOOD_NO_SLOT
;
48 * Different from other insn uses imm8, the real addressing offset of
49 * STRD in T32 encoding should be imm8 * 4. See ARMARM description.
51 enum probes_insn
checker_stack_use_t32strd(probes_opcode_t insn
,
52 struct arch_probes_insn
*asi
,
53 const struct decode_header
*h
)
55 int imm
= insn
& 0xff;
56 asi
->stack_space
= imm
<< 2;
57 return INSN_GOOD_NO_SLOT
;
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
)
64 int imm
= ((insn
& 0xf00) >> 4) + (insn
& 0xf);
65 asi
->stack_space
= imm
;
66 return INSN_GOOD_NO_SLOT
;
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
)
74 int imm
= insn
& 0xfff;
75 asi
->stack_space
= imm
;
76 return INSN_GOOD_NO_SLOT
;
79 enum probes_insn
checker_stack_use_stmdx(probes_opcode_t insn
,
80 struct arch_probes_insn
*asi
,
81 const struct decode_header
*h
)
83 unsigned int reglist
= insn
& 0xffff;
84 int pbit
= insn
& (1 << 24);
85 asi
->stack_space
= (hweight32(reglist
) - (!pbit
? 1 : 0)) * 4;
87 return INSN_GOOD_NO_SLOT
;
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
},
97 [STACK_USE_FIXED_X0X
] = {.decoder
= checker_stack_use_imm_x0x
},
99 [STACK_USE_FIXED_XXX
] = {.decoder
= checker_stack_use_imm_xxx
},
100 [STACK_USE_STMDX
] = {.decoder
= checker_stack_use_stmdx
},