summaryrefslogtreecommitdiffstats
path: root/arch/arm/kernel
diff options
context:
space:
mode:
authorDavid A. Long <dave.long@linaro.org>2014-03-06 18:06:43 -0500
committerDavid A. Long <dave.long@linaro.org>2014-03-18 16:39:36 -0400
commit3e6cd394bb10c2d65322e5f5d2ff0a9074d903a1 (patch)
tree0bbc61744e1a60d9a3a823a44ae5a7c279347eda /arch/arm/kernel
parent87abef63ead5ac9e2c67f0c07c461eda6be16aeb (diff)
ARM: use a function table for determining instruction interpreter action
Make the instruction interpreter call back to semantic action functions through a function pointer array provided by the invoker. The interpreter decodes the instructions into groups and uses the group number to index into the supplied array. kprobes and uprobes code will each supply their own array of functions. Signed-off-by: David A. Long <dave.long@linaro.org> Acked-by: Jon Medhurst <tixy@linaro.org>
Diffstat (limited to 'arch/arm/kernel')
-rw-r--r--arch/arm/kernel/kprobes-arm.c57
-rw-r--r--arch/arm/kernel/kprobes-common.c3
-rw-r--r--arch/arm/kernel/kprobes-thumb.c149
-rw-r--r--arch/arm/kernel/kprobes.c9
-rw-r--r--arch/arm/kernel/kprobes.h15
-rw-r--r--arch/arm/kernel/probes-arm.c114
-rw-r--r--arch/arm/kernel/probes-arm.h52
-rw-r--r--arch/arm/kernel/probes-thumb.c145
-rw-r--r--arch/arm/kernel/probes-thumb.h104
-rw-r--r--arch/arm/kernel/probes.c9
-rw-r--r--arch/arm/kernel/probes.h55
11 files changed, 441 insertions, 271 deletions
diff --git a/arch/arm/kernel/kprobes-arm.c b/arch/arm/kernel/kprobes-arm.c
index a1d0a8f00f9e..8ebd84c48867 100644
--- a/arch/arm/kernel/kprobes-arm.c
+++ b/arch/arm/kernel/kprobes-arm.c
@@ -73,7 +73,7 @@
73#endif 73#endif
74 74
75 75
76void __kprobes 76static void __kprobes
77emulate_ldrdstrd(struct kprobe *p, struct pt_regs *regs) 77emulate_ldrdstrd(struct kprobe *p, struct pt_regs *regs)
78{ 78{
79 kprobe_opcode_t insn = p->opcode; 79 kprobe_opcode_t insn = p->opcode;
@@ -102,7 +102,7 @@ emulate_ldrdstrd(struct kprobe *p, struct pt_regs *regs)
102 regs->uregs[rn] = rnv; 102 regs->uregs[rn] = rnv;
103} 103}
104 104
105void __kprobes 105static void __kprobes
106emulate_ldr(struct kprobe *p, struct pt_regs *regs) 106emulate_ldr(struct kprobe *p, struct pt_regs *regs)
107{ 107{
108 kprobe_opcode_t insn = p->opcode; 108 kprobe_opcode_t insn = p->opcode;
@@ -132,7 +132,7 @@ emulate_ldr(struct kprobe *p, struct pt_regs *regs)
132 regs->uregs[rn] = rnv; 132 regs->uregs[rn] = rnv;
133} 133}
134 134
135void __kprobes 135static void __kprobes
136emulate_str(struct kprobe *p, struct pt_regs *regs) 136emulate_str(struct kprobe *p, struct pt_regs *regs)
137{ 137{
138 kprobe_opcode_t insn = p->opcode; 138 kprobe_opcode_t insn = p->opcode;
@@ -159,7 +159,7 @@ emulate_str(struct kprobe *p, struct pt_regs *regs)
159 regs->uregs[rn] = rnv; 159 regs->uregs[rn] = rnv;
160} 160}
161 161
162void __kprobes 162static void __kprobes
163emulate_rd12rn16rm0rs8_rwflags(struct kprobe *p, struct pt_regs *regs) 163emulate_rd12rn16rm0rs8_rwflags(struct kprobe *p, struct pt_regs *regs)
164{ 164{
165 kprobe_opcode_t insn = p->opcode; 165 kprobe_opcode_t insn = p->opcode;
@@ -194,7 +194,7 @@ emulate_rd12rn16rm0rs8_rwflags(struct kprobe *p, struct pt_regs *regs)
194 regs->ARM_cpsr = (regs->ARM_cpsr & ~APSR_MASK) | (cpsr & APSR_MASK); 194 regs->ARM_cpsr = (regs->ARM_cpsr & ~APSR_MASK) | (cpsr & APSR_MASK);
195} 195}
196 196
197void __kprobes 197static void __kprobes
198emulate_rd12rn16rm0_rwflags_nopc(struct kprobe *p, struct pt_regs *regs) 198emulate_rd12rn16rm0_rwflags_nopc(struct kprobe *p, struct pt_regs *regs)
199{ 199{
200 kprobe_opcode_t insn = p->opcode; 200 kprobe_opcode_t insn = p->opcode;
@@ -221,7 +221,7 @@ emulate_rd12rn16rm0_rwflags_nopc(struct kprobe *p, struct pt_regs *regs)
221 regs->ARM_cpsr = (regs->ARM_cpsr & ~APSR_MASK) | (cpsr & APSR_MASK); 221 regs->ARM_cpsr = (regs->ARM_cpsr & ~APSR_MASK) | (cpsr & APSR_MASK);
222} 222}
223 223
224void __kprobes 224static void __kprobes
225emulate_rd16rn12rm0rs8_rwflags_nopc(struct kprobe *p, struct pt_regs *regs) 225emulate_rd16rn12rm0rs8_rwflags_nopc(struct kprobe *p, struct pt_regs *regs)
226{ 226{
227 kprobe_opcode_t insn = p->opcode; 227 kprobe_opcode_t insn = p->opcode;
@@ -250,7 +250,7 @@ emulate_rd16rn12rm0rs8_rwflags_nopc(struct kprobe *p, struct pt_regs *regs)
250 regs->ARM_cpsr = (regs->ARM_cpsr & ~APSR_MASK) | (cpsr & APSR_MASK); 250 regs->ARM_cpsr = (regs->ARM_cpsr & ~APSR_MASK) | (cpsr & APSR_MASK);
251} 251}
252 252
253void __kprobes 253static void __kprobes
254emulate_rd12rm0_noflags_nopc(struct kprobe *p, struct pt_regs *regs) 254emulate_rd12rm0_noflags_nopc(struct kprobe *p, struct pt_regs *regs)
255{ 255{
256 kprobe_opcode_t insn = p->opcode; 256 kprobe_opcode_t insn = p->opcode;
@@ -270,7 +270,7 @@ emulate_rd12rm0_noflags_nopc(struct kprobe *p, struct pt_regs *regs)
270 regs->uregs[rd] = rdv; 270 regs->uregs[rd] = rdv;
271} 271}
272 272
273void __kprobes 273static void __kprobes
274emulate_rdlo12rdhi16rn0rm8_rwflags_nopc(struct kprobe *p, struct pt_regs *regs) 274emulate_rdlo12rdhi16rn0rm8_rwflags_nopc(struct kprobe *p, struct pt_regs *regs)
275{ 275{
276 kprobe_opcode_t insn = p->opcode; 276 kprobe_opcode_t insn = p->opcode;
@@ -299,3 +299,44 @@ emulate_rdlo12rdhi16rn0rm8_rwflags_nopc(struct kprobe *p, struct pt_regs *regs)
299 regs->uregs[rdhi] = rdhiv; 299 regs->uregs[rdhi] = rdhiv;
300 regs->ARM_cpsr = (regs->ARM_cpsr & ~APSR_MASK) | (cpsr & APSR_MASK); 300 regs->ARM_cpsr = (regs->ARM_cpsr & ~APSR_MASK) | (cpsr & APSR_MASK);
301} 301}
302
303const union decode_action kprobes_arm_actions[NUM_PROBES_ARM_ACTIONS] = {
304 [PROBES_EMULATE_NONE] = {.handler = kprobe_emulate_none},
305 [PROBES_SIMULATE_NOP] = {.handler = kprobe_simulate_nop},
306 [PROBES_PRELOAD_IMM] = {.handler = kprobe_simulate_nop},
307 [PROBES_PRELOAD_REG] = {.handler = kprobe_simulate_nop},
308 [PROBES_BRANCH_IMM] = {.handler = simulate_blx1},
309 [PROBES_MRS] = {.handler = simulate_mrs},
310 [PROBES_BRANCH_REG] = {.handler = simulate_blx2bx},
311 [PROBES_CLZ] = {.handler = emulate_rd12rm0_noflags_nopc},
312 [PROBES_SATURATING_ARITHMETIC] = {
313 .handler = emulate_rd12rn16rm0_rwflags_nopc},
314 [PROBES_MUL1] = {.handler = emulate_rdlo12rdhi16rn0rm8_rwflags_nopc},
315 [PROBES_MUL2] = {.handler = emulate_rd16rn12rm0rs8_rwflags_nopc},
316 [PROBES_SWP] = {.handler = emulate_rd12rn16rm0_rwflags_nopc},
317 [PROBES_LDRSTRD] = {.handler = emulate_ldrdstrd},
318 [PROBES_LOAD_EXTRA] = {.handler = emulate_ldr},
319 [PROBES_LOAD] = {.handler = emulate_ldr},
320 [PROBES_STORE_EXTRA] = {.handler = emulate_str},
321 [PROBES_STORE] = {.handler = emulate_str},
322 [PROBES_MOV_IP_SP] = {.handler = simulate_mov_ipsp},
323 [PROBES_DATA_PROCESSING_REG] = {
324 .handler = emulate_rd12rn16rm0rs8_rwflags},
325 [PROBES_DATA_PROCESSING_IMM] = {
326 .handler = emulate_rd12rn16rm0rs8_rwflags},
327 [PROBES_MOV_HALFWORD] = {.handler = emulate_rd12rm0_noflags_nopc},
328 [PROBES_SEV] = {.handler = kprobe_emulate_none},
329 [PROBES_WFE] = {.handler = kprobe_simulate_nop},
330 [PROBES_SATURATE] = {.handler = emulate_rd12rn16rm0_rwflags_nopc},
331 [PROBES_REV] = {.handler = emulate_rd12rm0_noflags_nopc},
332 [PROBES_MMI] = {.handler = emulate_rd12rn16rm0_rwflags_nopc},
333 [PROBES_PACK] = {.handler = emulate_rd12rn16rm0_rwflags_nopc},
334 [PROBES_EXTEND] = {.handler = emulate_rd12rm0_noflags_nopc},
335 [PROBES_EXTEND_ADD] = {.handler = emulate_rd12rn16rm0_rwflags_nopc},
336 [PROBES_MUL_ADD_LONG] = {
337 .handler = emulate_rdlo12rdhi16rn0rm8_rwflags_nopc},
338 [PROBES_MUL_ADD] = {.handler = emulate_rd16rn12rm0rs8_rwflags_nopc},
339 [PROBES_BITFIELD] = {.handler = emulate_rd12rm0_noflags_nopc},
340 [PROBES_BRANCH] = {.handler = simulate_bbl},
341 [PROBES_LDMSTM] = {.decoder = kprobe_decode_ldmstm}
342};
diff --git a/arch/arm/kernel/kprobes-common.c b/arch/arm/kernel/kprobes-common.c
index f02c038059c3..029b79c6face 100644
--- a/arch/arm/kernel/kprobes-common.c
+++ b/arch/arm/kernel/kprobes-common.c
@@ -112,7 +112,8 @@ emulate_ldm_r3_15(struct kprobe *p, struct pt_regs *regs)
112} 112}
113 113
114enum kprobe_insn __kprobes 114enum kprobe_insn __kprobes
115kprobe_decode_ldmstm(kprobe_opcode_t insn, struct arch_specific_insn *asi) 115kprobe_decode_ldmstm(kprobe_opcode_t insn, struct arch_specific_insn *asi,
116 const struct decode_header *h)
116{ 117{
117 kprobe_insn_handler_t *handler = 0; 118 kprobe_insn_handler_t *handler = 0;
118 unsigned reglist = insn & 0xffff; 119 unsigned reglist = insn & 0xffff;
diff --git a/arch/arm/kernel/kprobes-thumb.c b/arch/arm/kernel/kprobes-thumb.c
index 977f21723a9c..d83f6092920a 100644
--- a/arch/arm/kernel/kprobes-thumb.c
+++ b/arch/arm/kernel/kprobes-thumb.c
@@ -16,6 +16,10 @@
16#include "kprobes.h" 16#include "kprobes.h"
17#include "probes-thumb.h" 17#include "probes-thumb.h"
18 18
19/* These emulation encodings are functionally equivalent... */
20#define t32_emulate_rd8rn16rm0ra12_noflags \
21 t32_emulate_rdlo12rdhi8rn16rm0_noflags
22
19/* 23/*
20 * Return the PC value for a probe in thumb code. 24 * Return the PC value for a probe in thumb code.
21 * This is the address of the probed instruction plus 4. 25 * This is the address of the probed instruction plus 4.
@@ -29,7 +33,7 @@ static inline unsigned long __kprobes thumb_probe_pc(struct kprobe *p)
29 33
30/* t32 thumb actions */ 34/* t32 thumb actions */
31 35
32void __kprobes 36static void __kprobes
33t32_simulate_table_branch(struct kprobe *p, struct pt_regs *regs) 37t32_simulate_table_branch(struct kprobe *p, struct pt_regs *regs)
34{ 38{
35 kprobe_opcode_t insn = p->opcode; 39 kprobe_opcode_t insn = p->opcode;
@@ -49,7 +53,7 @@ t32_simulate_table_branch(struct kprobe *p, struct pt_regs *regs)
49 regs->ARM_pc = pc + 2 * halfwords; 53 regs->ARM_pc = pc + 2 * halfwords;
50} 54}
51 55
52void __kprobes 56static void __kprobes
53t32_simulate_mrs(struct kprobe *p, struct pt_regs *regs) 57t32_simulate_mrs(struct kprobe *p, struct pt_regs *regs)
54{ 58{
55 kprobe_opcode_t insn = p->opcode; 59 kprobe_opcode_t insn = p->opcode;
@@ -58,7 +62,7 @@ t32_simulate_mrs(struct kprobe *p, struct pt_regs *regs)
58 regs->uregs[rd] = regs->ARM_cpsr & mask; 62 regs->uregs[rd] = regs->ARM_cpsr & mask;
59} 63}
60 64
61void __kprobes 65static void __kprobes
62t32_simulate_cond_branch(struct kprobe *p, struct pt_regs *regs) 66t32_simulate_cond_branch(struct kprobe *p, struct pt_regs *regs)
63{ 67{
64 kprobe_opcode_t insn = p->opcode; 68 kprobe_opcode_t insn = p->opcode;
@@ -73,8 +77,9 @@ t32_simulate_cond_branch(struct kprobe *p, struct pt_regs *regs)
73 regs->ARM_pc = pc + (offset * 2); 77 regs->ARM_pc = pc + (offset * 2);
74} 78}
75 79
76enum kprobe_insn __kprobes 80static enum kprobe_insn __kprobes
77t32_decode_cond_branch(kprobe_opcode_t insn, struct arch_specific_insn *asi) 81t32_decode_cond_branch(kprobe_opcode_t insn, struct arch_specific_insn *asi,
82 const struct decode_header *d)
78{ 83{
79 int cc = (insn >> 22) & 0xf; 84 int cc = (insn >> 22) & 0xf;
80 asi->insn_check_cc = kprobe_condition_checks[cc]; 85 asi->insn_check_cc = kprobe_condition_checks[cc];
@@ -82,7 +87,7 @@ t32_decode_cond_branch(kprobe_opcode_t insn, struct arch_specific_insn *asi)
82 return INSN_GOOD_NO_SLOT; 87 return INSN_GOOD_NO_SLOT;
83} 88}
84 89
85void __kprobes 90static void __kprobes
86t32_simulate_branch(struct kprobe *p, struct pt_regs *regs) 91t32_simulate_branch(struct kprobe *p, struct pt_regs *regs)
87{ 92{
88 kprobe_opcode_t insn = p->opcode; 93 kprobe_opcode_t insn = p->opcode;
@@ -110,7 +115,7 @@ t32_simulate_branch(struct kprobe *p, struct pt_regs *regs)
110 regs->ARM_pc = pc + (offset * 2); 115 regs->ARM_pc = pc + (offset * 2);
111} 116}
112 117
113void __kprobes 118static void __kprobes
114t32_simulate_ldr_literal(struct kprobe *p, struct pt_regs *regs) 119t32_simulate_ldr_literal(struct kprobe *p, struct pt_regs *regs)
115{ 120{
116 kprobe_opcode_t insn = p->opcode; 121 kprobe_opcode_t insn = p->opcode;
@@ -148,10 +153,11 @@ t32_simulate_ldr_literal(struct kprobe *p, struct pt_regs *regs)
148 regs->uregs[rt] = rtv; 153 regs->uregs[rt] = rtv;
149} 154}
150 155
151enum kprobe_insn __kprobes 156static enum kprobe_insn __kprobes
152t32_decode_ldmstm(kprobe_opcode_t insn, struct arch_specific_insn *asi) 157t32_decode_ldmstm(kprobe_opcode_t insn, struct arch_specific_insn *asi,
158 const struct decode_header *d)
153{ 159{
154 enum kprobe_insn ret = kprobe_decode_ldmstm(insn, asi); 160 enum kprobe_insn ret = kprobe_decode_ldmstm(insn, asi, d);
155 161
156 /* Fixup modified instruction to have halfwords in correct order...*/ 162 /* Fixup modified instruction to have halfwords in correct order...*/
157 insn = asi->insn[0]; 163 insn = asi->insn[0];
@@ -161,7 +167,7 @@ t32_decode_ldmstm(kprobe_opcode_t insn, struct arch_specific_insn *asi)
161 return ret; 167 return ret;
162} 168}
163 169
164void __kprobes 170static void __kprobes
165t32_emulate_ldrdstrd(struct kprobe *p, struct pt_regs *regs) 171t32_emulate_ldrdstrd(struct kprobe *p, struct pt_regs *regs)
166{ 172{
167 kprobe_opcode_t insn = p->opcode; 173 kprobe_opcode_t insn = p->opcode;
@@ -188,7 +194,7 @@ t32_emulate_ldrdstrd(struct kprobe *p, struct pt_regs *regs)
188 regs->uregs[rt2] = rt2v; 194 regs->uregs[rt2] = rt2v;
189} 195}
190 196
191void __kprobes 197static void __kprobes
192t32_emulate_ldrstr(struct kprobe *p, struct pt_regs *regs) 198t32_emulate_ldrstr(struct kprobe *p, struct pt_regs *regs)
193{ 199{
194 kprobe_opcode_t insn = p->opcode; 200 kprobe_opcode_t insn = p->opcode;
@@ -214,7 +220,7 @@ t32_emulate_ldrstr(struct kprobe *p, struct pt_regs *regs)
214 regs->uregs[rt] = rtv; 220 regs->uregs[rt] = rtv;
215} 221}
216 222
217void __kprobes 223static void __kprobes
218t32_emulate_rd8rn16rm0_rwflags(struct kprobe *p, struct pt_regs *regs) 224t32_emulate_rd8rn16rm0_rwflags(struct kprobe *p, struct pt_regs *regs)
219{ 225{
220 kprobe_opcode_t insn = p->opcode; 226 kprobe_opcode_t insn = p->opcode;
@@ -241,7 +247,7 @@ t32_emulate_rd8rn16rm0_rwflags(struct kprobe *p, struct pt_regs *regs)
241 regs->ARM_cpsr = (regs->ARM_cpsr & ~APSR_MASK) | (cpsr & APSR_MASK); 247 regs->ARM_cpsr = (regs->ARM_cpsr & ~APSR_MASK) | (cpsr & APSR_MASK);
242} 248}
243 249
244void __kprobes 250static void __kprobes
245t32_emulate_rd8pc16_noflags(struct kprobe *p, struct pt_regs *regs) 251t32_emulate_rd8pc16_noflags(struct kprobe *p, struct pt_regs *regs)
246{ 252{
247 kprobe_opcode_t insn = p->opcode; 253 kprobe_opcode_t insn = p->opcode;
@@ -261,7 +267,7 @@ t32_emulate_rd8pc16_noflags(struct kprobe *p, struct pt_regs *regs)
261 regs->uregs[rd] = rdv; 267 regs->uregs[rd] = rdv;
262} 268}
263 269
264void __kprobes 270static void __kprobes
265t32_emulate_rd8rn16_noflags(struct kprobe *p, struct pt_regs *regs) 271t32_emulate_rd8rn16_noflags(struct kprobe *p, struct pt_regs *regs)
266{ 272{
267 kprobe_opcode_t insn = p->opcode; 273 kprobe_opcode_t insn = p->opcode;
@@ -281,7 +287,7 @@ t32_emulate_rd8rn16_noflags(struct kprobe *p, struct pt_regs *regs)
281 regs->uregs[rd] = rdv; 287 regs->uregs[rd] = rdv;
282} 288}
283 289
284void __kprobes 290static void __kprobes
285t32_emulate_rdlo12rdhi8rn16rm0_noflags(struct kprobe *p, struct pt_regs *regs) 291t32_emulate_rdlo12rdhi8rn16rm0_noflags(struct kprobe *p, struct pt_regs *regs)
286{ 292{
287 kprobe_opcode_t insn = p->opcode; 293 kprobe_opcode_t insn = p->opcode;
@@ -308,7 +314,7 @@ t32_emulate_rdlo12rdhi8rn16rm0_noflags(struct kprobe *p, struct pt_regs *regs)
308} 314}
309/* t16 thumb actions */ 315/* t16 thumb actions */
310 316
311void __kprobes 317static void __kprobes
312t16_simulate_bxblx(struct kprobe *p, struct pt_regs *regs) 318t16_simulate_bxblx(struct kprobe *p, struct pt_regs *regs)
313{ 319{
314 kprobe_opcode_t insn = p->opcode; 320 kprobe_opcode_t insn = p->opcode;
@@ -322,7 +328,7 @@ t16_simulate_bxblx(struct kprobe *p, struct pt_regs *regs)
322 bx_write_pc(rmv, regs); 328 bx_write_pc(rmv, regs);
323} 329}
324 330
325void __kprobes 331static void __kprobes
326t16_simulate_ldr_literal(struct kprobe *p, struct pt_regs *regs) 332t16_simulate_ldr_literal(struct kprobe *p, struct pt_regs *regs)
327{ 333{
328 kprobe_opcode_t insn = p->opcode; 334 kprobe_opcode_t insn = p->opcode;
@@ -332,7 +338,7 @@ t16_simulate_ldr_literal(struct kprobe *p, struct pt_regs *regs)
332 regs->uregs[rt] = base[index]; 338 regs->uregs[rt] = base[index];
333} 339}
334 340
335void __kprobes 341static void __kprobes
336t16_simulate_ldrstr_sp_relative(struct kprobe *p, struct pt_regs *regs) 342t16_simulate_ldrstr_sp_relative(struct kprobe *p, struct pt_regs *regs)
337{ 343{
338 kprobe_opcode_t insn = p->opcode; 344 kprobe_opcode_t insn = p->opcode;
@@ -345,7 +351,7 @@ t16_simulate_ldrstr_sp_relative(struct kprobe *p, struct pt_regs *regs)
345 base[index] = regs->uregs[rt]; 351 base[index] = regs->uregs[rt];
346} 352}
347 353
348void __kprobes 354static void __kprobes
349t16_simulate_reladr(struct kprobe *p, struct pt_regs *regs) 355t16_simulate_reladr(struct kprobe *p, struct pt_regs *regs)
350{ 356{
351 kprobe_opcode_t insn = p->opcode; 357 kprobe_opcode_t insn = p->opcode;
@@ -356,7 +362,7 @@ t16_simulate_reladr(struct kprobe *p, struct pt_regs *regs)
356 regs->uregs[rt] = base + offset * 4; 362 regs->uregs[rt] = base + offset * 4;
357} 363}
358 364
359void __kprobes 365static void __kprobes
360t16_simulate_add_sp_imm(struct kprobe *p, struct pt_regs *regs) 366t16_simulate_add_sp_imm(struct kprobe *p, struct pt_regs *regs)
361{ 367{
362 kprobe_opcode_t insn = p->opcode; 368 kprobe_opcode_t insn = p->opcode;
@@ -367,7 +373,7 @@ t16_simulate_add_sp_imm(struct kprobe *p, struct pt_regs *regs)
367 regs->ARM_sp += imm * 4; 373 regs->ARM_sp += imm * 4;
368} 374}
369 375
370void __kprobes 376static void __kprobes
371t16_simulate_cbz(struct kprobe *p, struct pt_regs *regs) 377t16_simulate_cbz(struct kprobe *p, struct pt_regs *regs)
372{ 378{
373 kprobe_opcode_t insn = p->opcode; 379 kprobe_opcode_t insn = p->opcode;
@@ -381,7 +387,7 @@ t16_simulate_cbz(struct kprobe *p, struct pt_regs *regs)
381 } 387 }
382} 388}
383 389
384void __kprobes 390static void __kprobes
385t16_simulate_it(struct kprobe *p, struct pt_regs *regs) 391t16_simulate_it(struct kprobe *p, struct pt_regs *regs)
386{ 392{
387 /* 393 /*
@@ -398,21 +404,22 @@ t16_simulate_it(struct kprobe *p, struct pt_regs *regs)
398 regs->ARM_cpsr = cpsr; 404 regs->ARM_cpsr = cpsr;
399} 405}
400 406
401void __kprobes 407static void __kprobes
402t16_singlestep_it(struct kprobe *p, struct pt_regs *regs) 408t16_singlestep_it(struct kprobe *p, struct pt_regs *regs)
403{ 409{
404 regs->ARM_pc += 2; 410 regs->ARM_pc += 2;
405 t16_simulate_it(p, regs); 411 t16_simulate_it(p, regs);
406} 412}
407 413
408enum kprobe_insn __kprobes 414static enum kprobe_insn __kprobes
409t16_decode_it(kprobe_opcode_t insn, struct arch_specific_insn *asi) 415t16_decode_it(kprobe_opcode_t insn, struct arch_specific_insn *asi,
416 const struct decode_header *d)
410{ 417{
411 asi->insn_singlestep = t16_singlestep_it; 418 asi->insn_singlestep = t16_singlestep_it;
412 return INSN_GOOD_NO_SLOT; 419 return INSN_GOOD_NO_SLOT;
413} 420}
414 421
415void __kprobes 422static void __kprobes
416t16_simulate_cond_branch(struct kprobe *p, struct pt_regs *regs) 423t16_simulate_cond_branch(struct kprobe *p, struct pt_regs *regs)
417{ 424{
418 kprobe_opcode_t insn = p->opcode; 425 kprobe_opcode_t insn = p->opcode;
@@ -422,8 +429,9 @@ t16_simulate_cond_branch(struct kprobe *p, struct pt_regs *regs)
422 regs->ARM_pc = pc + (offset * 2); 429 regs->ARM_pc = pc + (offset * 2);
423} 430}
424 431
425enum kprobe_insn __kprobes 432static enum kprobe_insn __kprobes
426t16_decode_cond_branch(kprobe_opcode_t insn, struct arch_specific_insn *asi) 433t16_decode_cond_branch(kprobe_opcode_t insn, struct arch_specific_insn *asi,
434 const struct decode_header *d)
427{ 435{
428 int cc = (insn >> 8) & 0xf; 436 int cc = (insn >> 8) & 0xf;
429 asi->insn_check_cc = kprobe_condition_checks[cc]; 437 asi->insn_check_cc = kprobe_condition_checks[cc];
@@ -431,7 +439,7 @@ t16_decode_cond_branch(kprobe_opcode_t insn, struct arch_specific_insn *asi)
431 return INSN_GOOD_NO_SLOT; 439 return INSN_GOOD_NO_SLOT;
432} 440}
433 441
434void __kprobes 442static void __kprobes
435t16_simulate_branch(struct kprobe *p, struct pt_regs *regs) 443t16_simulate_branch(struct kprobe *p, struct pt_regs *regs)
436{ 444{
437 kprobe_opcode_t insn = p->opcode; 445 kprobe_opcode_t insn = p->opcode;
@@ -463,13 +471,13 @@ t16_emulate_loregs(struct kprobe *p, struct pt_regs *regs)
463 return (oldcpsr & ~APSR_MASK) | (newcpsr & APSR_MASK); 471 return (oldcpsr & ~APSR_MASK) | (newcpsr & APSR_MASK);
464} 472}
465 473
466void __kprobes 474static void __kprobes
467t16_emulate_loregs_rwflags(struct kprobe *p, struct pt_regs *regs) 475t16_emulate_loregs_rwflags(struct kprobe *p, struct pt_regs *regs)
468{ 476{
469 regs->ARM_cpsr = t16_emulate_loregs(p, regs); 477 regs->ARM_cpsr = t16_emulate_loregs(p, regs);
470} 478}
471 479
472void __kprobes 480static void __kprobes
473t16_emulate_loregs_noitrwflags(struct kprobe *p, struct pt_regs *regs) 481t16_emulate_loregs_noitrwflags(struct kprobe *p, struct pt_regs *regs)
474{ 482{
475 unsigned long cpsr = t16_emulate_loregs(p, regs); 483 unsigned long cpsr = t16_emulate_loregs(p, regs);
@@ -477,7 +485,7 @@ t16_emulate_loregs_noitrwflags(struct kprobe *p, struct pt_regs *regs)
477 regs->ARM_cpsr = cpsr; 485 regs->ARM_cpsr = cpsr;
478} 486}
479 487
480void __kprobes 488static void __kprobes
481t16_emulate_hiregs(struct kprobe *p, struct pt_regs *regs) 489t16_emulate_hiregs(struct kprobe *p, struct pt_regs *regs)
482{ 490{
483 kprobe_opcode_t insn = p->opcode; 491 kprobe_opcode_t insn = p->opcode;
@@ -508,8 +516,9 @@ t16_emulate_hiregs(struct kprobe *p, struct pt_regs *regs)
508 regs->ARM_cpsr = (regs->ARM_cpsr & ~APSR_MASK) | (cpsr & APSR_MASK); 516 regs->ARM_cpsr = (regs->ARM_cpsr & ~APSR_MASK) | (cpsr & APSR_MASK);
509} 517}
510 518
511enum kprobe_insn __kprobes 519static enum kprobe_insn __kprobes
512t16_decode_hiregs(kprobe_opcode_t insn, struct arch_specific_insn *asi) 520t16_decode_hiregs(kprobe_opcode_t insn, struct arch_specific_insn *asi,
521 const struct decode_header *d)
513{ 522{
514 insn &= ~0x00ff; 523 insn &= ~0x00ff;
515 insn |= 0x001; /* Set Rdn = R1 and Rm = R0 */ 524 insn |= 0x001; /* Set Rdn = R1 and Rm = R0 */
@@ -518,7 +527,7 @@ t16_decode_hiregs(kprobe_opcode_t insn, struct arch_specific_insn *asi)
518 return INSN_GOOD; 527 return INSN_GOOD;
519} 528}
520 529
521void __kprobes 530static void __kprobes
522t16_emulate_push(struct kprobe *p, struct pt_regs *regs) 531t16_emulate_push(struct kprobe *p, struct pt_regs *regs)
523{ 532{
524 __asm__ __volatile__ ( 533 __asm__ __volatile__ (
@@ -534,8 +543,9 @@ t16_emulate_push(struct kprobe *p, struct pt_regs *regs)
534 ); 543 );
535} 544}
536 545
537enum kprobe_insn __kprobes 546static enum kprobe_insn __kprobes
538t16_decode_push(kprobe_opcode_t insn, struct arch_specific_insn *asi) 547t16_decode_push(kprobe_opcode_t insn, struct arch_specific_insn *asi,
548 const struct decode_header *d)
539{ 549{
540 /* 550 /*
541 * To simulate a PUSH we use a Thumb-2 "STMDB R9!, {registers}" 551 * To simulate a PUSH we use a Thumb-2 "STMDB R9!, {registers}"
@@ -548,7 +558,7 @@ t16_decode_push(kprobe_opcode_t insn, struct arch_specific_insn *asi)
548 return INSN_GOOD; 558 return INSN_GOOD;
549} 559}
550 560
551void __kprobes 561static void __kprobes
552t16_emulate_pop_nopc(struct kprobe *p, struct pt_regs *regs) 562t16_emulate_pop_nopc(struct kprobe *p, struct pt_regs *regs)
553{ 563{
554 __asm__ __volatile__ ( 564 __asm__ __volatile__ (
@@ -564,7 +574,7 @@ t16_emulate_pop_nopc(struct kprobe *p, struct pt_regs *regs)
564 ); 574 );
565} 575}
566 576
567void __kprobes 577static void __kprobes
568t16_emulate_pop_pc(struct kprobe *p, struct pt_regs *regs) 578t16_emulate_pop_pc(struct kprobe *p, struct pt_regs *regs)
569{ 579{
570 register unsigned long pc asm("r8"); 580 register unsigned long pc asm("r8");
@@ -584,8 +594,9 @@ t16_emulate_pop_pc(struct kprobe *p, struct pt_regs *regs)
584 bx_write_pc(pc, regs); 594 bx_write_pc(pc, regs);
585} 595}
586 596
587enum kprobe_insn __kprobes 597static enum kprobe_insn __kprobes
588t16_decode_pop(kprobe_opcode_t insn, struct arch_specific_insn *asi) 598t16_decode_pop(kprobe_opcode_t insn, struct arch_specific_insn *asi,
599 const struct decode_header *d)
589{ 600{
590 /* 601 /*
591 * To simulate a POP we use a Thumb-2 "LDMDB R9!, {registers}" 602 * To simulate a POP we use a Thumb-2 "LDMDB R9!, {registers}"
@@ -598,3 +609,57 @@ t16_decode_pop(kprobe_opcode_t insn, struct arch_specific_insn *asi)
598 : t16_emulate_pop_nopc; 609 : t16_emulate_pop_nopc;
599 return INSN_GOOD; 610 return INSN_GOOD;
600} 611}
612
613const union decode_action kprobes_t16_actions[NUM_PROBES_T16_ACTIONS] = {
614 [PROBES_T16_ADD_SP] = {.handler = t16_simulate_add_sp_imm},
615 [PROBES_T16_CBZ] = {.handler = t16_simulate_cbz},
616 [PROBES_T16_SIGN_EXTEND] = {.handler = t16_emulate_loregs_rwflags},
617 [PROBES_T16_PUSH] = {.decoder = t16_decode_push},
618 [PROBES_T16_POP] = {.decoder = t16_decode_pop},
619 [PROBES_T16_SEV] = {.handler = kprobe_emulate_none},
620 [PROBES_T16_WFE] = {.handler = kprobe_simulate_nop},
621 [PROBES_T16_IT] = {.decoder = t16_decode_it},
622 [PROBES_T16_CMP] = {.handler = t16_emulate_loregs_rwflags},
623 [PROBES_T16_ADDSUB] = {.handler = t16_emulate_loregs_noitrwflags},
624 [PROBES_T16_LOGICAL] = {.handler = t16_emulate_loregs_noitrwflags},
625 [PROBES_T16_LDR_LIT] = {.handler = t16_simulate_ldr_literal},
626 [PROBES_T16_BLX] = {.handler = t16_simulate_bxblx},
627 [PROBES_T16_HIREGOPS] = {.decoder = t16_decode_hiregs},
628 [PROBES_T16_LDRHSTRH] = {.handler = t16_emulate_loregs_rwflags},
629 [PROBES_T16_LDRSTR] = {.handler = t16_simulate_ldrstr_sp_relative},
630 [PROBES_T16_ADR] = {.handler = t16_simulate_reladr},
631 [PROBES_T16_LDMSTM] = {.handler = t16_emulate_loregs_rwflags},
632 [PROBES_T16_BRANCH_COND] = {.decoder = t16_decode_cond_branch},
633 [PROBES_T16_BRANCH] = {.handler = t16_simulate_branch},
634};
635
636const union decode_action kprobes_t32_actions[NUM_PROBES_T32_ACTIONS] = {
637 [PROBES_T32_LDMSTM] = {.decoder = t32_decode_ldmstm},
638 [PROBES_T32_LDRDSTRD] = {.handler = t32_emulate_ldrdstrd},
639 [PROBES_T32_TABLE_BRANCH] = {.handler = t32_simulate_table_branch},
640 [PROBES_T32_TST] = {.handler = t32_emulate_rd8rn16rm0_rwflags},
641 [PROBES_T32_MOV] = {.handler = t32_emulate_rd8rn16rm0_rwflags},
642 [PROBES_T32_ADDSUB] = {.handler = t32_emulate_rd8rn16rm0_rwflags},
643 [PROBES_T32_LOGICAL] = {.handler = t32_emulate_rd8rn16rm0_rwflags},
644 [PROBES_T32_CMP] = {.handler = t32_emulate_rd8rn16rm0_rwflags},
645 [PROBES_T32_ADDWSUBW_PC] = {.handler = t32_emulate_rd8pc16_noflags,},
646 [PROBES_T32_ADDWSUBW] = {.handler = t32_emulate_rd8rn16_noflags},
647 [PROBES_T32_MOVW] = {.handler = t32_emulate_rd8rn16_noflags},
648 [PROBES_T32_SAT] = {.handler = t32_emulate_rd8rn16rm0_rwflags},
649 [PROBES_T32_BITFIELD] = {.handler = t32_emulate_rd8rn16_noflags},
650 [PROBES_T32_SEV] = {.handler = kprobe_emulate_none},
651 [PROBES_T32_WFE] = {.handler = kprobe_simulate_nop},
652 [PROBES_T32_MRS] = {.handler = t32_simulate_mrs},
653 [PROBES_T32_BRANCH_COND] = {.decoder = t32_decode_cond_branch},
654 [PROBES_T32_BRANCH] = {.handler = t32_simulate_branch},
655 [PROBES_T32_PLDI] = {.handler = kprobe_simulate_nop},
656 [PROBES_T32_LDR_LIT] = {.handler = t32_simulate_ldr_literal},
657 [PROBES_T32_LDRSTR] = {.handler = t32_emulate_ldrstr},
658 [PROBES_T32_SIGN_EXTEND] = {.handler = t32_emulate_rd8rn16rm0_rwflags},
659 [PROBES_T32_MEDIA] = {.handler = t32_emulate_rd8rn16rm0_rwflags},
660 [PROBES_T32_REVERSE] = {.handler = t32_emulate_rd8rn16_noflags},
661 [PROBES_T32_MUL_ADD] = {.handler = t32_emulate_rd8rn16rm0_rwflags},
662 [PROBES_T32_MUL_ADD2] = {.handler = t32_emulate_rd8rn16rm0ra12_noflags},
663 [PROBES_T32_MUL_ADD_LONG] = {
664 .handler = t32_emulate_rdlo12rdhi8rn16rm0_noflags},
665};
diff --git a/arch/arm/kernel/kprobes.c b/arch/arm/kernel/kprobes.c
index 54e7b46a3295..a757c3c22381 100644
--- a/arch/arm/kernel/kprobes.c
+++ b/arch/arm/kernel/kprobes.c
@@ -56,6 +56,7 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p)
56 unsigned long addr = (unsigned long)p->addr; 56 unsigned long addr = (unsigned long)p->addr;
57 bool thumb; 57 bool thumb;
58 kprobe_decode_insn_t *decode_insn; 58 kprobe_decode_insn_t *decode_insn;
59 const union decode_action *actions;
59 int is; 60 int is;
60 61
61 if (in_exception_text(addr)) 62 if (in_exception_text(addr))
@@ -69,20 +70,24 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p)
69 insn <<= 16; 70 insn <<= 16;
70 insn |= ((u16 *)addr)[1]; 71 insn |= ((u16 *)addr)[1];
71 decode_insn = thumb32_kprobe_decode_insn; 72 decode_insn = thumb32_kprobe_decode_insn;
72 } else 73 actions = kprobes_t32_actions;
74 } else {
73 decode_insn = thumb16_kprobe_decode_insn; 75 decode_insn = thumb16_kprobe_decode_insn;
76 actions = kprobes_t16_actions;
77 }
74#else /* !CONFIG_THUMB2_KERNEL */ 78#else /* !CONFIG_THUMB2_KERNEL */
75 thumb = false; 79 thumb = false;
76 if (addr & 0x3) 80 if (addr & 0x3)
77 return -EINVAL; 81 return -EINVAL;
78 insn = *p->addr; 82 insn = *p->addr;
79 decode_insn = arm_kprobe_decode_insn; 83 decode_insn = arm_kprobe_decode_insn;
84 actions = kprobes_arm_actions;
80#endif 85#endif
81 86
82 p->opcode = insn; 87 p->opcode = insn;
83 p->ainsn.insn = tmp_insn; 88 p->ainsn.insn = tmp_insn;
84 89
85 switch ((*decode_insn)(insn, &p->ainsn)) { 90 switch ((*decode_insn)(insn, &p->ainsn, actions)) {
86 case INSN_REJECTED: /* not supported */ 91 case INSN_REJECTED: /* not supported */
87 return -EINVAL; 92 return -EINVAL;
88 93
diff --git a/arch/arm/kernel/kprobes.h b/arch/arm/kernel/kprobes.h
index aa68c0ea1a0b..7798035d6003 100644
--- a/arch/arm/kernel/kprobes.h
+++ b/arch/arm/kernel/kprobes.h
@@ -27,6 +27,8 @@
27#define KPROBE_THUMB16_BREAKPOINT_INSTRUCTION 0xde18 27#define KPROBE_THUMB16_BREAKPOINT_INSTRUCTION 0xde18
28#define KPROBE_THUMB32_BREAKPOINT_INSTRUCTION 0xf7f0a018 28#define KPROBE_THUMB32_BREAKPOINT_INSTRUCTION 0xf7f0a018
29 29
30struct decode_header;
31union decode_action;
30 32
31enum kprobe_insn { 33enum kprobe_insn {
32 INSN_REJECTED, 34 INSN_REJECTED,
@@ -35,19 +37,24 @@ enum kprobe_insn {
35}; 37};
36 38
37typedef enum kprobe_insn (kprobe_decode_insn_t)(kprobe_opcode_t, 39typedef enum kprobe_insn (kprobe_decode_insn_t)(kprobe_opcode_t,
38 struct arch_specific_insn *); 40 struct arch_specific_insn *,
41 const union decode_action *);
39 42
40#ifdef CONFIG_THUMB2_KERNEL 43#ifdef CONFIG_THUMB2_KERNEL
41 44
42enum kprobe_insn thumb16_kprobe_decode_insn(kprobe_opcode_t, 45enum kprobe_insn thumb16_kprobe_decode_insn(kprobe_opcode_t,
43 struct arch_specific_insn *); 46 struct arch_specific_insn *,
47 const union decode_action *);
44enum kprobe_insn thumb32_kprobe_decode_insn(kprobe_opcode_t, 48enum kprobe_insn thumb32_kprobe_decode_insn(kprobe_opcode_t,
45 struct arch_specific_insn *); 49 struct arch_specific_insn *,
50 const union decode_action *);
46 51
47#else /* !CONFIG_THUMB2_KERNEL */ 52#else /* !CONFIG_THUMB2_KERNEL */
48 53
49enum kprobe_insn arm_kprobe_decode_insn(kprobe_opcode_t, 54enum kprobe_insn arm_kprobe_decode_insn(kprobe_opcode_t,
50 struct arch_specific_insn *); 55 struct arch_specific_insn *,
56 const union decode_action *);
57
51#endif 58#endif
52 59
53void __init arm_kprobe_decode_init(void); 60void __init arm_kprobe_decode_init(void);
diff --git a/arch/arm/kernel/probes-arm.c b/arch/arm/kernel/probes-arm.c
index 57e08b28e87f..496e0e913fa6 100644
--- a/arch/arm/kernel/probes-arm.c
+++ b/arch/arm/kernel/probes-arm.c
@@ -126,16 +126,16 @@ static const union decode_item arm_1111_table[] = {
126 /* PLDI (immediate) 1111 0100 x101 xxxx xxxx xxxx xxxx xxxx */ 126 /* PLDI (immediate) 1111 0100 x101 xxxx xxxx xxxx xxxx xxxx */
127 /* PLDW (immediate) 1111 0101 x001 xxxx xxxx xxxx xxxx xxxx */ 127 /* PLDW (immediate) 1111 0101 x001 xxxx xxxx xxxx xxxx xxxx */
128 /* PLD (immediate) 1111 0101 x101 xxxx xxxx xxxx xxxx xxxx */ 128 /* PLD (immediate) 1111 0101 x101 xxxx xxxx xxxx xxxx xxxx */
129 DECODE_SIMULATE (0xfe300000, 0xf4100000, kprobe_simulate_nop), 129 DECODE_SIMULATE (0xfe300000, 0xf4100000, PROBES_PRELOAD_IMM),
130 130
131 /* memory hint 1111 0110 x001 xxxx xxxx xxxx xxx0 xxxx */ 131 /* memory hint 1111 0110 x001 xxxx xxxx xxxx xxx0 xxxx */
132 /* PLDI (register) 1111 0110 x101 xxxx xxxx xxxx xxx0 xxxx */ 132 /* PLDI (register) 1111 0110 x101 xxxx xxxx xxxx xxx0 xxxx */
133 /* PLDW (register) 1111 0111 x001 xxxx xxxx xxxx xxx0 xxxx */ 133 /* PLDW (register) 1111 0111 x001 xxxx xxxx xxxx xxx0 xxxx */
134 /* PLD (register) 1111 0111 x101 xxxx xxxx xxxx xxx0 xxxx */ 134 /* PLD (register) 1111 0111 x101 xxxx xxxx xxxx xxx0 xxxx */
135 DECODE_SIMULATE (0xfe300010, 0xf6100000, kprobe_simulate_nop), 135 DECODE_SIMULATE (0xfe300010, 0xf6100000, PROBES_PRELOAD_REG),
136 136
137 /* BLX (immediate) 1111 101x xxxx xxxx xxxx xxxx xxxx xxxx */ 137 /* BLX (immediate) 1111 101x xxxx xxxx xxxx xxxx xxxx xxxx */
138 DECODE_SIMULATE (0xfe000000, 0xfa000000, simulate_blx1), 138 DECODE_SIMULATE (0xfe000000, 0xfa000000, PROBES_BRANCH_IMM),
139 139
140 /* CPS 1111 0001 0000 xxx0 xxxx xxxx xx0x xxxx */ 140 /* CPS 1111 0001 0000 xxx0 xxxx xxxx xx0x xxxx */
141 /* SETEND 1111 0001 0000 0001 xxxx xxxx 0000 xxxx */ 141 /* SETEND 1111 0001 0000 0001 xxxx xxxx 0000 xxxx */
@@ -159,25 +159,25 @@ static const union decode_item arm_cccc_0001_0xx0____0xxx_table[] = {
159 /* Miscellaneous instructions */ 159 /* Miscellaneous instructions */
160 160
161 /* MRS cpsr cccc 0001 0000 xxxx xxxx xxxx 0000 xxxx */ 161 /* MRS cpsr cccc 0001 0000 xxxx xxxx xxxx 0000 xxxx */
162 DECODE_SIMULATEX(0x0ff000f0, 0x01000000, simulate_mrs, 162 DECODE_SIMULATEX(0x0ff000f0, 0x01000000, PROBES_MRS,
163 REGS(0, NOPC, 0, 0, 0)), 163 REGS(0, NOPC, 0, 0, 0)),
164 164
165 /* BX cccc 0001 0010 xxxx xxxx xxxx 0001 xxxx */ 165 /* BX cccc 0001 0010 xxxx xxxx xxxx 0001 xxxx */
166 DECODE_SIMULATE (0x0ff000f0, 0x01200010, simulate_blx2bx), 166 DECODE_SIMULATE (0x0ff000f0, 0x01200010, PROBES_BRANCH_REG),
167 167
168 /* BLX (register) cccc 0001 0010 xxxx xxxx xxxx 0011 xxxx */ 168 /* BLX (register) cccc 0001 0010 xxxx xxxx xxxx 0011 xxxx */
169 DECODE_SIMULATEX(0x0ff000f0, 0x01200030, simulate_blx2bx, 169 DECODE_SIMULATEX(0x0ff000f0, 0x01200030, PROBES_BRANCH_REG,
170 REGS(0, 0, 0, 0, NOPC)), 170 REGS(0, 0, 0, 0, NOPC)),
171 171
172 /* CLZ cccc 0001 0110 xxxx xxxx xxxx 0001 xxxx */ 172 /* CLZ cccc 0001 0110 xxxx xxxx xxxx 0001 xxxx */
173 DECODE_EMULATEX (0x0ff000f0, 0x01600010, emulate_rd12rm0_noflags_nopc, 173 DECODE_EMULATEX (0x0ff000f0, 0x01600010, PROBES_CLZ,
174 REGS(0, NOPC, 0, 0, NOPC)), 174 REGS(0, NOPC, 0, 0, NOPC)),
175 175
176 /* QADD cccc 0001 0000 xxxx xxxx xxxx 0101 xxxx */ 176 /* QADD cccc 0001 0000 xxxx xxxx xxxx 0101 xxxx */
177 /* QSUB cccc 0001 0010 xxxx xxxx xxxx 0101 xxxx */ 177 /* QSUB cccc 0001 0010 xxxx xxxx xxxx 0101 xxxx */
178 /* QDADD cccc 0001 0100 xxxx xxxx xxxx 0101 xxxx */ 178 /* QDADD cccc 0001 0100 xxxx xxxx xxxx 0101 xxxx */
179 /* QDSUB cccc 0001 0110 xxxx xxxx xxxx 0101 xxxx */ 179 /* QDSUB cccc 0001 0110 xxxx xxxx xxxx 0101 xxxx */
180 DECODE_EMULATEX (0x0f9000f0, 0x01000050, emulate_rd12rn16rm0_rwflags_nopc, 180 DECODE_EMULATEX (0x0f9000f0, 0x01000050, PROBES_SATURATING_ARITHMETIC,
181 REGS(NOPC, NOPC, 0, 0, NOPC)), 181 REGS(NOPC, NOPC, 0, 0, NOPC)),
182 182
183 /* BXJ cccc 0001 0010 xxxx xxxx xxxx 0010 xxxx */ 183 /* BXJ cccc 0001 0010 xxxx xxxx xxxx 0010 xxxx */
@@ -193,19 +193,19 @@ static const union decode_item arm_cccc_0001_0xx0____1xx0_table[] = {
193 /* Halfword multiply and multiply-accumulate */ 193 /* Halfword multiply and multiply-accumulate */
194 194
195 /* SMLALxy cccc 0001 0100 xxxx xxxx xxxx 1xx0 xxxx */ 195 /* SMLALxy cccc 0001 0100 xxxx xxxx xxxx 1xx0 xxxx */
196 DECODE_EMULATEX (0x0ff00090, 0x01400080, emulate_rdlo12rdhi16rn0rm8_rwflags_nopc, 196 DECODE_EMULATEX (0x0ff00090, 0x01400080, PROBES_MUL1,
197 REGS(NOPC, NOPC, NOPC, 0, NOPC)), 197 REGS(NOPC, NOPC, NOPC, 0, NOPC)),
198 198
199 /* SMULWy cccc 0001 0010 xxxx xxxx xxxx 1x10 xxxx */ 199 /* SMULWy cccc 0001 0010 xxxx xxxx xxxx 1x10 xxxx */
200 DECODE_OR (0x0ff000b0, 0x012000a0), 200 DECODE_OR (0x0ff000b0, 0x012000a0),
201 /* SMULxy cccc 0001 0110 xxxx xxxx xxxx 1xx0 xxxx */ 201 /* SMULxy cccc 0001 0110 xxxx xxxx xxxx 1xx0 xxxx */
202 DECODE_EMULATEX (0x0ff00090, 0x01600080, emulate_rd16rn12rm0rs8_rwflags_nopc, 202 DECODE_EMULATEX (0x0ff00090, 0x01600080, PROBES_MUL2,
203 REGS(NOPC, 0, NOPC, 0, NOPC)), 203 REGS(NOPC, 0, NOPC, 0, NOPC)),
204 204
205 /* SMLAxy cccc 0001 0000 xxxx xxxx xxxx 1xx0 xxxx */ 205 /* SMLAxy cccc 0001 0000 xxxx xxxx xxxx 1xx0 xxxx */
206 DECODE_OR (0x0ff00090, 0x01000080), 206 DECODE_OR (0x0ff00090, 0x01000080),
207 /* SMLAWy cccc 0001 0010 xxxx xxxx xxxx 1x00 xxxx */ 207 /* SMLAWy cccc 0001 0010 xxxx xxxx xxxx 1x00 xxxx */
208 DECODE_EMULATEX (0x0ff000b0, 0x01200080, emulate_rd16rn12rm0rs8_rwflags_nopc, 208 DECODE_EMULATEX (0x0ff000b0, 0x01200080, PROBES_MUL2,
209 REGS(NOPC, NOPC, NOPC, 0, NOPC)), 209 REGS(NOPC, NOPC, NOPC, 0, NOPC)),
210 210
211 DECODE_END 211 DECODE_END
@@ -216,14 +216,14 @@ static const union decode_item arm_cccc_0000_____1001_table[] = {
216 216
217 /* MUL cccc 0000 0000 xxxx xxxx xxxx 1001 xxxx */ 217 /* MUL cccc 0000 0000 xxxx xxxx xxxx 1001 xxxx */
218 /* MULS cccc 0000 0001 xxxx xxxx xxxx 1001 xxxx */ 218 /* MULS cccc 0000 0001 xxxx xxxx xxxx 1001 xxxx */
219 DECODE_EMULATEX (0x0fe000f0, 0x00000090, emulate_rd16rn12rm0rs8_rwflags_nopc, 219 DECODE_EMULATEX (0x0fe000f0, 0x00000090, PROBES_MUL2,
220 REGS(NOPC, 0, NOPC, 0, NOPC)), 220 REGS(NOPC, 0, NOPC, 0, NOPC)),
221 221
222 /* MLA cccc 0000 0010 xxxx xxxx xxxx 1001 xxxx */ 222 /* MLA cccc 0000 0010 xxxx xxxx xxxx 1001 xxxx */
223 /* MLAS cccc 0000 0011 xxxx xxxx xxxx 1001 xxxx */ 223 /* MLAS cccc 0000 0011 xxxx xxxx xxxx 1001 xxxx */
224 DECODE_OR (0x0fe000f0, 0x00200090), 224 DECODE_OR (0x0fe000f0, 0x00200090),
225 /* MLS cccc 0000 0110 xxxx xxxx xxxx 1001 xxxx */ 225 /* MLS cccc 0000 0110 xxxx xxxx xxxx 1001 xxxx */
226 DECODE_EMULATEX (0x0ff000f0, 0x00600090, emulate_rd16rn12rm0rs8_rwflags_nopc, 226 DECODE_EMULATEX (0x0ff000f0, 0x00600090, PROBES_MUL2,
227 REGS(NOPC, NOPC, NOPC, 0, NOPC)), 227 REGS(NOPC, NOPC, NOPC, 0, NOPC)),
228 228
229 /* UMAAL cccc 0000 0100 xxxx xxxx xxxx 1001 xxxx */ 229 /* UMAAL cccc 0000 0100 xxxx xxxx xxxx 1001 xxxx */
@@ -236,7 +236,7 @@ static const union decode_item arm_cccc_0000_____1001_table[] = {
236 /* SMULLS cccc 0000 1101 xxxx xxxx xxxx 1001 xxxx */ 236 /* SMULLS cccc 0000 1101 xxxx xxxx xxxx 1001 xxxx */
237 /* SMLAL cccc 0000 1110 xxxx xxxx xxxx 1001 xxxx */ 237 /* SMLAL cccc 0000 1110 xxxx xxxx xxxx 1001 xxxx */
238 /* SMLALS cccc 0000 1111 xxxx xxxx xxxx 1001 xxxx */ 238 /* SMLALS cccc 0000 1111 xxxx xxxx xxxx 1001 xxxx */
239 DECODE_EMULATEX (0x0f8000f0, 0x00800090, emulate_rdlo12rdhi16rn0rm8_rwflags_nopc, 239 DECODE_EMULATEX (0x0f8000f0, 0x00800090, PROBES_MUL1,
240 REGS(NOPC, NOPC, NOPC, 0, NOPC)), 240 REGS(NOPC, NOPC, NOPC, 0, NOPC)),
241 241
242 DECODE_END 242 DECODE_END
@@ -248,7 +248,7 @@ static const union decode_item arm_cccc_0001_____1001_table[] = {
248#if __LINUX_ARM_ARCH__ < 6 248#if __LINUX_ARM_ARCH__ < 6
249 /* Deprecated on ARMv6 and may be UNDEFINED on v7 */ 249 /* Deprecated on ARMv6 and may be UNDEFINED on v7 */
250 /* SMP/SWPB cccc 0001 0x00 xxxx xxxx xxxx 1001 xxxx */ 250 /* SMP/SWPB cccc 0001 0x00 xxxx xxxx xxxx 1001 xxxx */
251 DECODE_EMULATEX (0x0fb000f0, 0x01000090, emulate_rd12rn16rm0_rwflags_nopc, 251 DECODE_EMULATEX (0x0fb000f0, 0x01000090, PROBES_SWP,
252 REGS(NOPC, NOPC, 0, 0, NOPC)), 252 REGS(NOPC, NOPC, 0, 0, NOPC)),
253#endif 253#endif
254 /* LDREX/STREX{,D,B,H} cccc 0001 1xxx xxxx xxxx xxxx 1001 xxxx */ 254 /* LDREX/STREX{,D,B,H} cccc 0001 1xxx xxxx xxxx xxxx 1001 xxxx */
@@ -271,32 +271,32 @@ static const union decode_item arm_cccc_000x_____1xx1_table[] = {
271 271
272 /* LDRD (register) cccc 000x x0x0 xxxx xxxx xxxx 1101 xxxx */ 272 /* LDRD (register) cccc 000x x0x0 xxxx xxxx xxxx 1101 xxxx */
273 /* STRD (register) cccc 000x x0x0 xxxx xxxx xxxx 1111 xxxx */ 273 /* STRD (register) cccc 000x x0x0 xxxx xxxx xxxx 1111 xxxx */
274 DECODE_EMULATEX (0x0e5000d0, 0x000000d0, emulate_ldrdstrd, 274 DECODE_EMULATEX (0x0e5000d0, 0x000000d0, PROBES_LDRSTRD,
275 REGS(NOPCWB, NOPCX, 0, 0, NOPC)), 275 REGS(NOPCWB, NOPCX, 0, 0, NOPC)),
276 276
277 /* LDRD (immediate) cccc 000x x1x0 xxxx xxxx xxxx 1101 xxxx */ 277 /* LDRD (immediate) cccc 000x x1x0 xxxx xxxx xxxx 1101 xxxx */
278 /* STRD (immediate) cccc 000x x1x0 xxxx xxxx xxxx 1111 xxxx */ 278 /* STRD (immediate) cccc 000x x1x0 xxxx xxxx xxxx 1111 xxxx */
279 DECODE_EMULATEX (0x0e5000d0, 0x004000d0, emulate_ldrdstrd, 279 DECODE_EMULATEX (0x0e5000d0, 0x004000d0, PROBES_LDRSTRD,
280 REGS(NOPCWB, NOPCX, 0, 0, 0)), 280 REGS(NOPCWB, NOPCX, 0, 0, 0)),
281 281
282 /* STRH (register) cccc 000x x0x0 xxxx xxxx xxxx 1011 xxxx */ 282 /* STRH (register) cccc 000x x0x0 xxxx xxxx xxxx 1011 xxxx */
283 DECODE_EMULATEX (0x0e5000f0, 0x000000b0, emulate_str, 283 DECODE_EMULATEX (0x0e5000f0, 0x000000b0, PROBES_STORE_EXTRA,
284 REGS(NOPCWB, NOPC, 0, 0, NOPC)), 284 REGS(NOPCWB, NOPC, 0, 0, NOPC)),
285 285
286 /* LDRH (register) cccc 000x x0x1 xxxx xxxx xxxx 1011 xxxx */ 286 /* LDRH (register) cccc 000x x0x1 xxxx xxxx xxxx 1011 xxxx */
287 /* LDRSB (register) cccc 000x x0x1 xxxx xxxx xxxx 1101 xxxx */ 287 /* LDRSB (register) cccc 000x x0x1 xxxx xxxx xxxx 1101 xxxx */
288 /* LDRSH (register) cccc 000x x0x1 xxxx xxxx xxxx 1111 xxxx */ 288 /* LDRSH (register) cccc 000x x0x1 xxxx xxxx xxxx 1111 xxxx */
289 DECODE_EMULATEX (0x0e500090, 0x00100090, emulate_ldr, 289 DECODE_EMULATEX (0x0e500090, 0x00100090, PROBES_LOAD_EXTRA,
290 REGS(NOPCWB, NOPC, 0, 0, NOPC)), 290 REGS(NOPCWB, NOPC, 0, 0, NOPC)),
291 291
292 /* STRH (immediate) cccc 000x x1x0 xxxx xxxx xxxx 1011 xxxx */ 292 /* STRH (immediate) cccc 000x x1x0 xxxx xxxx xxxx 1011 xxxx */
293 DECODE_EMULATEX (0x0e5000f0, 0x004000b0, emulate_str, 293 DECODE_EMULATEX (0x0e5000f0, 0x004000b0, PROBES_STORE_EXTRA,
294 REGS(NOPCWB, NOPC, 0, 0, 0)), 294 REGS(NOPCWB, NOPC, 0, 0, 0)),
295 295
296 /* LDRH (immediate) cccc 000x x1x1 xxxx xxxx xxxx 1011 xxxx */ 296 /* LDRH (immediate) cccc 000x x1x1 xxxx xxxx xxxx 1011 xxxx */
297 /* LDRSB (immediate) cccc 000x x1x1 xxxx xxxx xxxx 1101 xxxx */ 297 /* LDRSB (immediate) cccc 000x x1x1 xxxx xxxx xxxx 1101 xxxx */
298 /* LDRSH (immediate) cccc 000x x1x1 xxxx xxxx xxxx 1111 xxxx */ 298 /* LDRSH (immediate) cccc 000x x1x1 xxxx xxxx xxxx 1111 xxxx */
299 DECODE_EMULATEX (0x0e500090, 0x00500090, emulate_ldr, 299 DECODE_EMULATEX (0x0e500090, 0x00500090, PROBES_LOAD_EXTRA,
300 REGS(NOPCWB, NOPC, 0, 0, 0)), 300 REGS(NOPCWB, NOPC, 0, 0, 0)),
301 301
302 DECODE_END 302 DECODE_END
@@ -309,18 +309,18 @@ static const union decode_item arm_cccc_000x_table[] = {
309 DECODE_REJECT (0x0e10f000, 0x0010f000), 309 DECODE_REJECT (0x0e10f000, 0x0010f000),
310 310
311 /* MOV IP, SP 1110 0001 1010 0000 1100 0000 0000 1101 */ 311 /* MOV IP, SP 1110 0001 1010 0000 1100 0000 0000 1101 */
312 DECODE_SIMULATE (0xffffffff, 0xe1a0c00d, simulate_mov_ipsp), 312 DECODE_SIMULATE (0xffffffff, 0xe1a0c00d, PROBES_MOV_IP_SP),
313 313
314 /* TST (register) cccc 0001 0001 xxxx xxxx xxxx xxx0 xxxx */ 314 /* TST (register) cccc 0001 0001 xxxx xxxx xxxx xxx0 xxxx */
315 /* TEQ (register) cccc 0001 0011 xxxx xxxx xxxx xxx0 xxxx */ 315 /* TEQ (register) cccc 0001 0011 xxxx xxxx xxxx xxx0 xxxx */
316 /* CMP (register) cccc 0001 0101 xxxx xxxx xxxx xxx0 xxxx */ 316 /* CMP (register) cccc 0001 0101 xxxx xxxx xxxx xxx0 xxxx */
317 /* CMN (register) cccc 0001 0111 xxxx xxxx xxxx xxx0 xxxx */ 317 /* CMN (register) cccc 0001 0111 xxxx xxxx xxxx xxx0 xxxx */
318 DECODE_EMULATEX (0x0f900010, 0x01100000, emulate_rd12rn16rm0rs8_rwflags, 318 DECODE_EMULATEX (0x0f900010, 0x01100000, PROBES_DATA_PROCESSING_REG,
319 REGS(ANY, 0, 0, 0, ANY)), 319 REGS(ANY, 0, 0, 0, ANY)),
320 320
321 /* MOV (register) cccc 0001 101x xxxx xxxx xxxx xxx0 xxxx */ 321 /* MOV (register) cccc 0001 101x xxxx xxxx xxxx xxx0 xxxx */
322 /* MVN (register) cccc 0001 111x xxxx xxxx xxxx xxx0 xxxx */ 322 /* MVN (register) cccc 0001 111x xxxx xxxx xxxx xxx0 xxxx */
323 DECODE_EMULATEX (0x0fa00010, 0x01a00000, emulate_rd12rn16rm0rs8_rwflags, 323 DECODE_EMULATEX (0x0fa00010, 0x01a00000, PROBES_DATA_PROCESSING_REG,
324 REGS(0, ANY, 0, 0, ANY)), 324 REGS(0, ANY, 0, 0, ANY)),
325 325
326 /* AND (register) cccc 0000 000x xxxx xxxx xxxx xxx0 xxxx */ 326 /* AND (register) cccc 0000 000x xxxx xxxx xxxx xxx0 xxxx */
@@ -333,19 +333,19 @@ static const union decode_item arm_cccc_000x_table[] = {
333 /* RSC (register) cccc 0000 111x xxxx xxxx xxxx xxx0 xxxx */ 333 /* RSC (register) cccc 0000 111x xxxx xxxx xxxx xxx0 xxxx */
334 /* ORR (register) cccc 0001 100x xxxx xxxx xxxx xxx0 xxxx */ 334 /* ORR (register) cccc 0001 100x xxxx xxxx xxxx xxx0 xxxx */
335 /* BIC (register) cccc 0001 110x xxxx xxxx xxxx xxx0 xxxx */ 335 /* BIC (register) cccc 0001 110x xxxx xxxx xxxx xxx0 xxxx */
336 DECODE_EMULATEX (0x0e000010, 0x00000000, emulate_rd12rn16rm0rs8_rwflags, 336 DECODE_EMULATEX (0x0e000010, 0x00000000, PROBES_DATA_PROCESSING_REG,
337 REGS(ANY, ANY, 0, 0, ANY)), 337 REGS(ANY, ANY, 0, 0, ANY)),
338 338
339 /* TST (reg-shift reg) cccc 0001 0001 xxxx xxxx xxxx 0xx1 xxxx */ 339 /* TST (reg-shift reg) cccc 0001 0001 xxxx xxxx xxxx 0xx1 xxxx */
340 /* TEQ (reg-shift reg) cccc 0001 0011 xxxx xxxx xxxx 0xx1 xxxx */ 340 /* TEQ (reg-shift reg) cccc 0001 0011 xxxx xxxx xxxx 0xx1 xxxx */
341 /* CMP (reg-shift reg) cccc 0001 0101 xxxx xxxx xxxx 0xx1 xxxx */ 341 /* CMP (reg-shift reg) cccc 0001 0101 xxxx xxxx xxxx 0xx1 xxxx */
342 /* CMN (reg-shift reg) cccc 0001 0111 xxxx xxxx xxxx 0xx1 xxxx */ 342 /* CMN (reg-shift reg) cccc 0001 0111 xxxx xxxx xxxx 0xx1 xxxx */
343 DECODE_EMULATEX (0x0f900090, 0x01100010, emulate_rd12rn16rm0rs8_rwflags, 343 DECODE_EMULATEX (0x0f900090, 0x01100010, PROBES_DATA_PROCESSING_REG,
344 REGS(ANY, 0, NOPC, 0, ANY)), 344 REGS(ANY, 0, NOPC, 0, ANY)),
345 345
346 /* MOV (reg-shift reg) cccc 0001 101x xxxx xxxx xxxx 0xx1 xxxx */ 346 /* MOV (reg-shift reg) cccc 0001 101x xxxx xxxx xxxx 0xx1 xxxx */
347 /* MVN (reg-shift reg) cccc 0001 111x xxxx xxxx xxxx 0xx1 xxxx */ 347 /* MVN (reg-shift reg) cccc 0001 111x xxxx xxxx xxxx 0xx1 xxxx */
348 DECODE_EMULATEX (0x0fa00090, 0x01a00010, emulate_rd12rn16rm0rs8_rwflags, 348 DECODE_EMULATEX (0x0fa00090, 0x01a00010, PROBES_DATA_PROCESSING_REG,
349 REGS(0, ANY, NOPC, 0, ANY)), 349 REGS(0, ANY, NOPC, 0, ANY)),
350 350
351 /* AND (reg-shift reg) cccc 0000 000x xxxx xxxx xxxx 0xx1 xxxx */ 351 /* AND (reg-shift reg) cccc 0000 000x xxxx xxxx xxxx 0xx1 xxxx */
@@ -358,7 +358,7 @@ static const union decode_item arm_cccc_000x_table[] = {
358 /* RSC (reg-shift reg) cccc 0000 111x xxxx xxxx xxxx 0xx1 xxxx */ 358 /* RSC (reg-shift reg) cccc 0000 111x xxxx xxxx xxxx 0xx1 xxxx */
359 /* ORR (reg-shift reg) cccc 0001 100x xxxx xxxx xxxx 0xx1 xxxx */ 359 /* ORR (reg-shift reg) cccc 0001 100x xxxx xxxx xxxx 0xx1 xxxx */
360 /* BIC (reg-shift reg) cccc 0001 110x xxxx xxxx xxxx 0xx1 xxxx */ 360 /* BIC (reg-shift reg) cccc 0001 110x xxxx xxxx xxxx 0xx1 xxxx */
361 DECODE_EMULATEX (0x0e000090, 0x00000010, emulate_rd12rn16rm0rs8_rwflags, 361 DECODE_EMULATEX (0x0e000090, 0x00000010, PROBES_DATA_PROCESSING_REG,
362 REGS(ANY, ANY, NOPC, 0, ANY)), 362 REGS(ANY, ANY, NOPC, 0, ANY)),
363 363
364 DECODE_END 364 DECODE_END
@@ -369,17 +369,17 @@ static const union decode_item arm_cccc_001x_table[] = {
369 369
370 /* MOVW cccc 0011 0000 xxxx xxxx xxxx xxxx xxxx */ 370 /* MOVW cccc 0011 0000 xxxx xxxx xxxx xxxx xxxx */
371 /* MOVT cccc 0011 0100 xxxx xxxx xxxx xxxx xxxx */ 371 /* MOVT cccc 0011 0100 xxxx xxxx xxxx xxxx xxxx */
372 DECODE_EMULATEX (0x0fb00000, 0x03000000, emulate_rd12rm0_noflags_nopc, 372 DECODE_EMULATEX (0x0fb00000, 0x03000000, PROBES_DATA_PROCESSING_IMM,
373 REGS(0, NOPC, 0, 0, 0)), 373 REGS(0, NOPC, 0, 0, 0)),
374 374
375 /* YIELD cccc 0011 0010 0000 xxxx xxxx 0000 0001 */ 375 /* YIELD cccc 0011 0010 0000 xxxx xxxx 0000 0001 */
376 DECODE_OR (0x0fff00ff, 0x03200001), 376 DECODE_OR (0x0fff00ff, 0x03200001),
377 /* SEV cccc 0011 0010 0000 xxxx xxxx 0000 0100 */ 377 /* SEV cccc 0011 0010 0000 xxxx xxxx 0000 0100 */
378 DECODE_EMULATE (0x0fff00ff, 0x03200004, kprobe_emulate_none), 378 DECODE_EMULATE (0x0fff00ff, 0x03200004, PROBES_EMULATE_NONE),
379 /* NOP cccc 0011 0010 0000 xxxx xxxx 0000 0000 */ 379 /* NOP cccc 0011 0010 0000 xxxx xxxx 0000 0000 */
380 /* WFE cccc 0011 0010 0000 xxxx xxxx 0000 0010 */ 380 /* WFE cccc 0011 0010 0000 xxxx xxxx 0000 0010 */
381 /* WFI cccc 0011 0010 0000 xxxx xxxx 0000 0011 */ 381 /* WFI cccc 0011 0010 0000 xxxx xxxx 0000 0011 */
382 DECODE_SIMULATE (0x0fff00fc, 0x03200000, kprobe_simulate_nop), 382 DECODE_SIMULATE (0x0fff00fc, 0x03200000, PROBES_SIMULATE_NOP),
383 /* DBG cccc 0011 0010 0000 xxxx xxxx ffff xxxx */ 383 /* DBG cccc 0011 0010 0000 xxxx xxxx ffff xxxx */
384 /* unallocated hints cccc 0011 0010 0000 xxxx xxxx xxxx xxxx */ 384 /* unallocated hints cccc 0011 0010 0000 xxxx xxxx xxxx xxxx */
385 /* MSR (immediate) cccc 0011 0x10 xxxx xxxx xxxx xxxx xxxx */ 385 /* MSR (immediate) cccc 0011 0x10 xxxx xxxx xxxx xxxx xxxx */
@@ -392,12 +392,12 @@ static const union decode_item arm_cccc_001x_table[] = {
392 /* TEQ (immediate) cccc 0011 0011 xxxx xxxx xxxx xxxx xxxx */ 392 /* TEQ (immediate) cccc 0011 0011 xxxx xxxx xxxx xxxx xxxx */
393 /* CMP (immediate) cccc 0011 0101 xxxx xxxx xxxx xxxx xxxx */ 393 /* CMP (immediate) cccc 0011 0101 xxxx xxxx xxxx xxxx xxxx */
394 /* CMN (immediate) cccc 0011 0111 xxxx xxxx xxxx xxxx xxxx */ 394 /* CMN (immediate) cccc 0011 0111 xxxx xxxx xxxx xxxx xxxx */
395 DECODE_EMULATEX (0x0f900000, 0x03100000, emulate_rd12rn16rm0rs8_rwflags, 395 DECODE_EMULATEX (0x0f900000, 0x03100000, PROBES_DATA_PROCESSING_IMM,
396 REGS(ANY, 0, 0, 0, 0)), 396 REGS(ANY, 0, 0, 0, 0)),
397 397
398 /* MOV (immediate) cccc 0011 101x xxxx xxxx xxxx xxxx xxxx */ 398 /* MOV (immediate) cccc 0011 101x xxxx xxxx xxxx xxxx xxxx */
399 /* MVN (immediate) cccc 0011 111x xxxx xxxx xxxx xxxx xxxx */ 399 /* MVN (immediate) cccc 0011 111x xxxx xxxx xxxx xxxx xxxx */
400 DECODE_EMULATEX (0x0fa00000, 0x03a00000, emulate_rd12rn16rm0rs8_rwflags, 400 DECODE_EMULATEX (0x0fa00000, 0x03a00000, PROBES_DATA_PROCESSING_IMM,
401 REGS(0, ANY, 0, 0, 0)), 401 REGS(0, ANY, 0, 0, 0)),
402 402
403 /* AND (immediate) cccc 0010 000x xxxx xxxx xxxx xxxx xxxx */ 403 /* AND (immediate) cccc 0010 000x xxxx xxxx xxxx xxxx xxxx */
@@ -410,7 +410,7 @@ static const union decode_item arm_cccc_001x_table[] = {
410 /* RSC (immediate) cccc 0010 111x xxxx xxxx xxxx xxxx xxxx */ 410 /* RSC (immediate) cccc 0010 111x xxxx xxxx xxxx xxxx xxxx */
411 /* ORR (immediate) cccc 0011 100x xxxx xxxx xxxx xxxx xxxx */ 411 /* ORR (immediate) cccc 0011 100x xxxx xxxx xxxx xxxx xxxx */
412 /* BIC (immediate) cccc 0011 110x xxxx xxxx xxxx xxxx xxxx */ 412 /* BIC (immediate) cccc 0011 110x xxxx xxxx xxxx xxxx xxxx */
413 DECODE_EMULATEX (0x0e000000, 0x02000000, emulate_rd12rn16rm0rs8_rwflags, 413 DECODE_EMULATEX (0x0e000000, 0x02000000, PROBES_DATA_PROCESSING_IMM,
414 REGS(ANY, ANY, 0, 0, 0)), 414 REGS(ANY, ANY, 0, 0, 0)),
415 415
416 DECODE_END 416 DECODE_END
@@ -420,7 +420,7 @@ static const union decode_item arm_cccc_0110_____xxx1_table[] = {
420 /* Media instructions */ 420 /* Media instructions */
421 421
422 /* SEL cccc 0110 1000 xxxx xxxx xxxx 1011 xxxx */ 422 /* SEL cccc 0110 1000 xxxx xxxx xxxx 1011 xxxx */
423 DECODE_EMULATEX (0x0ff000f0, 0x068000b0, emulate_rd12rn16rm0_rwflags_nopc, 423 DECODE_EMULATEX (0x0ff000f0, 0x068000b0, PROBES_SATURATE,
424 REGS(NOPC, NOPC, 0, 0, NOPC)), 424 REGS(NOPC, NOPC, 0, 0, NOPC)),
425 425
426 /* SSAT cccc 0110 101x xxxx xxxx xxxx xx01 xxxx */ 426 /* SSAT cccc 0110 101x xxxx xxxx xxxx xx01 xxxx */
@@ -428,14 +428,14 @@ static const union decode_item arm_cccc_0110_____xxx1_table[] = {
428 DECODE_OR(0x0fa00030, 0x06a00010), 428 DECODE_OR(0x0fa00030, 0x06a00010),
429 /* SSAT16 cccc 0110 1010 xxxx xxxx xxxx 0011 xxxx */ 429 /* SSAT16 cccc 0110 1010 xxxx xxxx xxxx 0011 xxxx */
430 /* USAT16 cccc 0110 1110 xxxx xxxx xxxx 0011 xxxx */ 430 /* USAT16 cccc 0110 1110 xxxx xxxx xxxx 0011 xxxx */
431 DECODE_EMULATEX (0x0fb000f0, 0x06a00030, emulate_rd12rn16rm0_rwflags_nopc, 431 DECODE_EMULATEX (0x0fb000f0, 0x06a00030, PROBES_SATURATE,
432 REGS(0, NOPC, 0, 0, NOPC)), 432 REGS(0, NOPC, 0, 0, NOPC)),
433 433
434 /* REV cccc 0110 1011 xxxx xxxx xxxx 0011 xxxx */ 434 /* REV cccc 0110 1011 xxxx xxxx xxxx 0011 xxxx */
435 /* REV16 cccc 0110 1011 xxxx xxxx xxxx 1011 xxxx */ 435 /* REV16 cccc 0110 1011 xxxx xxxx xxxx 1011 xxxx */
436 /* RBIT cccc 0110 1111 xxxx xxxx xxxx 0011 xxxx */ 436 /* RBIT cccc 0110 1111 xxxx xxxx xxxx 0011 xxxx */
437 /* REVSH cccc 0110 1111 xxxx xxxx xxxx 1011 xxxx */ 437 /* REVSH cccc 0110 1111 xxxx xxxx xxxx 1011 xxxx */
438 DECODE_EMULATEX (0x0fb00070, 0x06b00030, emulate_rd12rm0_noflags_nopc, 438 DECODE_EMULATEX (0x0fb00070, 0x06b00030, PROBES_REV,
439 REGS(0, NOPC, 0, 0, NOPC)), 439 REGS(0, NOPC, 0, 0, NOPC)),
440 440
441 /* ??? cccc 0110 0x00 xxxx xxxx xxxx xxx1 xxxx */ 441 /* ??? cccc 0110 0x00 xxxx xxxx xxxx xxx1 xxxx */
@@ -480,12 +480,12 @@ static const union decode_item arm_cccc_0110_____xxx1_table[] = {
480 /* UHSUB16 cccc 0110 0111 xxxx xxxx xxxx 0111 xxxx */ 480 /* UHSUB16 cccc 0110 0111 xxxx xxxx xxxx 0111 xxxx */
481 /* UHADD8 cccc 0110 0111 xxxx xxxx xxxx 1001 xxxx */ 481 /* UHADD8 cccc 0110 0111 xxxx xxxx xxxx 1001 xxxx */
482 /* UHSUB8 cccc 0110 0111 xxxx xxxx xxxx 1111 xxxx */ 482 /* UHSUB8 cccc 0110 0111 xxxx xxxx xxxx 1111 xxxx */
483 DECODE_EMULATEX (0x0f800010, 0x06000010, emulate_rd12rn16rm0_rwflags_nopc, 483 DECODE_EMULATEX (0x0f800010, 0x06000010, PROBES_MMI,
484 REGS(NOPC, NOPC, 0, 0, NOPC)), 484 REGS(NOPC, NOPC, 0, 0, NOPC)),
485 485
486 /* PKHBT cccc 0110 1000 xxxx xxxx xxxx x001 xxxx */ 486 /* PKHBT cccc 0110 1000 xxxx xxxx xxxx x001 xxxx */
487 /* PKHTB cccc 0110 1000 xxxx xxxx xxxx x101 xxxx */ 487 /* PKHTB cccc 0110 1000 xxxx xxxx xxxx x101 xxxx */
488 DECODE_EMULATEX (0x0ff00030, 0x06800010, emulate_rd12rn16rm0_rwflags_nopc, 488 DECODE_EMULATEX (0x0ff00030, 0x06800010, PROBES_PACK,
489 REGS(NOPC, NOPC, 0, 0, NOPC)), 489 REGS(NOPC, NOPC, 0, 0, NOPC)),
490 490
491 /* ??? cccc 0110 1001 xxxx xxxx xxxx 0111 xxxx */ 491 /* ??? cccc 0110 1001 xxxx xxxx xxxx 0111 xxxx */
@@ -498,7 +498,7 @@ static const union decode_item arm_cccc_0110_____xxx1_table[] = {
498 /* UXTB16 cccc 0110 1100 1111 xxxx xxxx 0111 xxxx */ 498 /* UXTB16 cccc 0110 1100 1111 xxxx xxxx 0111 xxxx */
499 /* UXTB cccc 0110 1110 1111 xxxx xxxx 0111 xxxx */ 499 /* UXTB cccc 0110 1110 1111 xxxx xxxx 0111 xxxx */
500 /* UXTH cccc 0110 1111 1111 xxxx xxxx 0111 xxxx */ 500 /* UXTH cccc 0110 1111 1111 xxxx xxxx 0111 xxxx */
501 DECODE_EMULATEX (0x0f8f00f0, 0x068f0070, emulate_rd12rm0_noflags_nopc, 501 DECODE_EMULATEX (0x0f8f00f0, 0x068f0070, PROBES_EXTEND,
502 REGS(0, NOPC, 0, 0, NOPC)), 502 REGS(0, NOPC, 0, 0, NOPC)),
503 503
504 /* SXTAB16 cccc 0110 1000 xxxx xxxx xxxx 0111 xxxx */ 504 /* SXTAB16 cccc 0110 1000 xxxx xxxx xxxx 0111 xxxx */
@@ -507,7 +507,7 @@ static const union decode_item arm_cccc_0110_____xxx1_table[] = {
507 /* UXTAB16 cccc 0110 1100 xxxx xxxx xxxx 0111 xxxx */ 507 /* UXTAB16 cccc 0110 1100 xxxx xxxx xxxx 0111 xxxx */
508 /* UXTAB cccc 0110 1110 xxxx xxxx xxxx 0111 xxxx */ 508 /* UXTAB cccc 0110 1110 xxxx xxxx xxxx 0111 xxxx */
509 /* UXTAH cccc 0110 1111 xxxx xxxx xxxx 0111 xxxx */ 509 /* UXTAH cccc 0110 1111 xxxx xxxx xxxx 0111 xxxx */
510 DECODE_EMULATEX (0x0f8000f0, 0x06800070, emulate_rd12rn16rm0_rwflags_nopc, 510 DECODE_EMULATEX (0x0f8000f0, 0x06800070, PROBES_EXTEND_ADD,
511 REGS(NOPCX, NOPC, 0, 0, NOPC)), 511 REGS(NOPCX, NOPC, 0, 0, NOPC)),
512 512
513 DECODE_END 513 DECODE_END
@@ -521,7 +521,7 @@ static const union decode_item arm_cccc_0111_____xxx1_table[] = {
521 521
522 /* SMLALD cccc 0111 0100 xxxx xxxx xxxx 00x1 xxxx */ 522 /* SMLALD cccc 0111 0100 xxxx xxxx xxxx 00x1 xxxx */
523 /* SMLSLD cccc 0111 0100 xxxx xxxx xxxx 01x1 xxxx */ 523 /* SMLSLD cccc 0111 0100 xxxx xxxx xxxx 01x1 xxxx */
524 DECODE_EMULATEX (0x0ff00090, 0x07400010, emulate_rdlo12rdhi16rn0rm8_rwflags_nopc, 524 DECODE_EMULATEX (0x0ff00090, 0x07400010, PROBES_MUL_ADD_LONG,
525 REGS(NOPC, NOPC, NOPC, 0, NOPC)), 525 REGS(NOPC, NOPC, NOPC, 0, NOPC)),
526 526
527 /* SMUAD cccc 0111 0000 xxxx 1111 xxxx 00x1 xxxx */ 527 /* SMUAD cccc 0111 0000 xxxx 1111 xxxx 00x1 xxxx */
@@ -530,7 +530,7 @@ static const union decode_item arm_cccc_0111_____xxx1_table[] = {
530 /* SMMUL cccc 0111 0101 xxxx 1111 xxxx 00x1 xxxx */ 530 /* SMMUL cccc 0111 0101 xxxx 1111 xxxx 00x1 xxxx */
531 DECODE_OR (0x0ff0f0d0, 0x0750f010), 531 DECODE_OR (0x0ff0f0d0, 0x0750f010),
532 /* USAD8 cccc 0111 1000 xxxx 1111 xxxx 0001 xxxx */ 532 /* USAD8 cccc 0111 1000 xxxx 1111 xxxx 0001 xxxx */
533 DECODE_EMULATEX (0x0ff0f0f0, 0x0780f010, emulate_rd16rn12rm0rs8_rwflags_nopc, 533 DECODE_EMULATEX (0x0ff0f0f0, 0x0780f010, PROBES_MUL_ADD,
534 REGS(NOPC, 0, NOPC, 0, NOPC)), 534 REGS(NOPC, 0, NOPC, 0, NOPC)),
535 535
536 /* SMLAD cccc 0111 0000 xxxx xxxx xxxx 00x1 xxxx */ 536 /* SMLAD cccc 0111 0000 xxxx xxxx xxxx 00x1 xxxx */
@@ -539,24 +539,24 @@ static const union decode_item arm_cccc_0111_____xxx1_table[] = {
539 /* SMMLA cccc 0111 0101 xxxx xxxx xxxx 00x1 xxxx */ 539 /* SMMLA cccc 0111 0101 xxxx xxxx xxxx 00x1 xxxx */
540 DECODE_OR (0x0ff000d0, 0x07500010), 540 DECODE_OR (0x0ff000d0, 0x07500010),
541 /* USADA8 cccc 0111 1000 xxxx xxxx xxxx 0001 xxxx */ 541 /* USADA8 cccc 0111 1000 xxxx xxxx xxxx 0001 xxxx */
542 DECODE_EMULATEX (0x0ff000f0, 0x07800010, emulate_rd16rn12rm0rs8_rwflags_nopc, 542 DECODE_EMULATEX (0x0ff000f0, 0x07800010, PROBES_MUL_ADD,
543 REGS(NOPC, NOPCX, NOPC, 0, NOPC)), 543 REGS(NOPC, NOPCX, NOPC, 0, NOPC)),
544 544
545 /* SMMLS cccc 0111 0101 xxxx xxxx xxxx 11x1 xxxx */ 545 /* SMMLS cccc 0111 0101 xxxx xxxx xxxx 11x1 xxxx */
546 DECODE_EMULATEX (0x0ff000d0, 0x075000d0, emulate_rd16rn12rm0rs8_rwflags_nopc, 546 DECODE_EMULATEX (0x0ff000d0, 0x075000d0, PROBES_MUL_ADD,
547 REGS(NOPC, NOPC, NOPC, 0, NOPC)), 547 REGS(NOPC, NOPC, NOPC, 0, NOPC)),
548 548
549 /* SBFX cccc 0111 101x xxxx xxxx xxxx x101 xxxx */ 549 /* SBFX cccc 0111 101x xxxx xxxx xxxx x101 xxxx */
550 /* UBFX cccc 0111 111x xxxx xxxx xxxx x101 xxxx */ 550 /* UBFX cccc 0111 111x xxxx xxxx xxxx x101 xxxx */
551 DECODE_EMULATEX (0x0fa00070, 0x07a00050, emulate_rd12rm0_noflags_nopc, 551 DECODE_EMULATEX (0x0fa00070, 0x07a00050, PROBES_BITFIELD,
552 REGS(0, NOPC, 0, 0, NOPC)), 552 REGS(0, NOPC, 0, 0, NOPC)),
553 553
554 /* BFC cccc 0111 110x xxxx xxxx xxxx x001 1111 */ 554 /* BFC cccc 0111 110x xxxx xxxx xxxx x001 1111 */
555 DECODE_EMULATEX (0x0fe0007f, 0x07c0001f, emulate_rd12rm0_noflags_nopc, 555 DECODE_EMULATEX (0x0fe0007f, 0x07c0001f, PROBES_BITFIELD,
556 REGS(0, NOPC, 0, 0, 0)), 556 REGS(0, NOPC, 0, 0, 0)),
557 557
558 /* BFI cccc 0111 110x xxxx xxxx xxxx x001 xxxx */ 558 /* BFI cccc 0111 110x xxxx xxxx xxxx x001 xxxx */
559 DECODE_EMULATEX (0x0fe00070, 0x07c00010, emulate_rd12rm0_noflags_nopc, 559 DECODE_EMULATEX (0x0fe00070, 0x07c00010, PROBES_BITFIELD,
560 REGS(0, NOPC, 0, 0, NOPCX)), 560 REGS(0, NOPC, 0, 0, NOPCX)),
561 561
562 DECODE_END 562 DECODE_END
@@ -576,22 +576,22 @@ static const union decode_item arm_cccc_01xx_table[] = {
576 576
577 /* STR (immediate) cccc 010x x0x0 xxxx xxxx xxxx xxxx xxxx */ 577 /* STR (immediate) cccc 010x x0x0 xxxx xxxx xxxx xxxx xxxx */
578 /* STRB (immediate) cccc 010x x1x0 xxxx xxxx xxxx xxxx xxxx */ 578 /* STRB (immediate) cccc 010x x1x0 xxxx xxxx xxxx xxxx xxxx */
579 DECODE_EMULATEX (0x0e100000, 0x04000000, emulate_str, 579 DECODE_EMULATEX (0x0e100000, 0x04000000, PROBES_STORE,
580 REGS(NOPCWB, ANY, 0, 0, 0)), 580 REGS(NOPCWB, ANY, 0, 0, 0)),
581 581
582 /* LDR (immediate) cccc 010x x0x1 xxxx xxxx xxxx xxxx xxxx */ 582 /* LDR (immediate) cccc 010x x0x1 xxxx xxxx xxxx xxxx xxxx */
583 /* LDRB (immediate) cccc 010x x1x1 xxxx xxxx xxxx xxxx xxxx */ 583 /* LDRB (immediate) cccc 010x x1x1 xxxx xxxx xxxx xxxx xxxx */
584 DECODE_EMULATEX (0x0e100000, 0x04100000, emulate_ldr, 584 DECODE_EMULATEX (0x0e100000, 0x04100000, PROBES_LOAD,
585 REGS(NOPCWB, ANY, 0, 0, 0)), 585 REGS(NOPCWB, ANY, 0, 0, 0)),
586 586
587 /* STR (register) cccc 011x x0x0 xxxx xxxx xxxx xxxx xxxx */ 587 /* STR (register) cccc 011x x0x0 xxxx xxxx xxxx xxxx xxxx */
588 /* STRB (register) cccc 011x x1x0 xxxx xxxx xxxx xxxx xxxx */ 588 /* STRB (register) cccc 011x x1x0 xxxx xxxx xxxx xxxx xxxx */
589 DECODE_EMULATEX (0x0e100000, 0x06000000, emulate_str, 589 DECODE_EMULATEX (0x0e100000, 0x06000000, PROBES_STORE,
590 REGS(NOPCWB, ANY, 0, 0, NOPC)), 590 REGS(NOPCWB, ANY, 0, 0, NOPC)),
591 591
592 /* LDR (register) cccc 011x x0x1 xxxx xxxx xxxx xxxx xxxx */ 592 /* LDR (register) cccc 011x x0x1 xxxx xxxx xxxx xxxx xxxx */
593 /* LDRB (register) cccc 011x x1x1 xxxx xxxx xxxx xxxx xxxx */ 593 /* LDRB (register) cccc 011x x1x1 xxxx xxxx xxxx xxxx xxxx */
594 DECODE_EMULATEX (0x0e100000, 0x06100000, emulate_ldr, 594 DECODE_EMULATEX (0x0e100000, 0x06100000, PROBES_LOAD,
595 REGS(NOPCWB, ANY, 0, 0, NOPC)), 595 REGS(NOPCWB, ANY, 0, 0, NOPC)),
596 596
597 DECODE_END 597 DECODE_END
@@ -602,7 +602,7 @@ static const union decode_item arm_cccc_100x_table[] = {
602 602
603 /* LDM cccc 100x x0x1 xxxx xxxx xxxx xxxx xxxx */ 603 /* LDM cccc 100x x0x1 xxxx xxxx xxxx xxxx xxxx */
604 /* STM cccc 100x x0x0 xxxx xxxx xxxx xxxx xxxx */ 604 /* STM cccc 100x x0x0 xxxx xxxx xxxx xxxx xxxx */
605 DECODE_CUSTOM (0x0e400000, 0x08000000, kprobe_decode_ldmstm), 605 DECODE_CUSTOM (0x0e400000, 0x08000000, PROBES_LDMSTM),
606 606
607 /* STM (user registers) cccc 100x x1x0 xxxx xxxx xxxx xxxx xxxx */ 607 /* STM (user registers) cccc 100x x1x0 xxxx xxxx xxxx xxxx xxxx */
608 /* LDM (user registers) cccc 100x x1x1 xxxx 0xxx xxxx xxxx xxxx */ 608 /* LDM (user registers) cccc 100x x1x1 xxxx 0xxx xxxx xxxx xxxx */
@@ -682,7 +682,7 @@ const union decode_item kprobe_decode_arm_table[] = {
682 682
683 /* B cccc 1010 xxxx xxxx xxxx xxxx xxxx xxxx */ 683 /* B cccc 1010 xxxx xxxx xxxx xxxx xxxx xxxx */
684 /* BL cccc 1011 xxxx xxxx xxxx xxxx xxxx xxxx */ 684 /* BL cccc 1011 xxxx xxxx xxxx xxxx xxxx xxxx */
685 DECODE_SIMULATE (0x0e000000, 0x0a000000, simulate_bbl), 685 DECODE_SIMULATE (0x0e000000, 0x0a000000, PROBES_BRANCH),
686 686
687 /* 687 /*
688 * Supervisor Call, and coprocessor instructions 688 * Supervisor Call, and coprocessor instructions
@@ -723,9 +723,11 @@ static void __kprobes arm_singlestep(struct kprobe *p, struct pt_regs *regs)
723 * should also be very rare. 723 * should also be very rare.
724 */ 724 */
725enum kprobe_insn __kprobes 725enum kprobe_insn __kprobes
726arm_kprobe_decode_insn(kprobe_opcode_t insn, struct arch_specific_insn *asi) 726arm_kprobe_decode_insn(kprobe_opcode_t insn, struct arch_specific_insn *asi,
727 const union decode_action *actions)
727{ 728{
728 asi->insn_singlestep = arm_singlestep; 729 asi->insn_singlestep = arm_singlestep;
729 asi->insn_check_cc = kprobe_condition_checks[insn>>28]; 730 asi->insn_check_cc = kprobe_condition_checks[insn>>28];
730 return kprobe_decode_insn(insn, asi, kprobe_decode_arm_table, false); 731 return kprobe_decode_insn(insn, asi, kprobe_decode_arm_table, false,
732 actions);
731} 733}
diff --git a/arch/arm/kernel/probes-arm.h b/arch/arm/kernel/probes-arm.h
index 86084727d36d..ef3089419a0b 100644
--- a/arch/arm/kernel/probes-arm.h
+++ b/arch/arm/kernel/probes-arm.h
@@ -15,24 +15,48 @@
15#ifndef _ARM_KERNEL_PROBES_ARM_H 15#ifndef _ARM_KERNEL_PROBES_ARM_H
16#define _ARM_KERNEL_PROBES_ARM_H 16#define _ARM_KERNEL_PROBES_ARM_H
17 17
18enum probes_arm_action {
19 PROBES_EMULATE_NONE,
20 PROBES_SIMULATE_NOP,
21 PROBES_PRELOAD_IMM,
22 PROBES_PRELOAD_REG,
23 PROBES_BRANCH_IMM,
24 PROBES_BRANCH_REG,
25 PROBES_MRS,
26 PROBES_CLZ,
27 PROBES_SATURATING_ARITHMETIC,
28 PROBES_MUL1,
29 PROBES_MUL2,
30 PROBES_SWP,
31 PROBES_LDRSTRD,
32 PROBES_LOAD,
33 PROBES_STORE,
34 PROBES_LOAD_EXTRA,
35 PROBES_STORE_EXTRA,
36 PROBES_MOV_IP_SP,
37 PROBES_DATA_PROCESSING_REG,
38 PROBES_DATA_PROCESSING_IMM,
39 PROBES_MOV_HALFWORD,
40 PROBES_SEV,
41 PROBES_WFE,
42 PROBES_SATURATE,
43 PROBES_REV,
44 PROBES_MMI,
45 PROBES_PACK,
46 PROBES_EXTEND,
47 PROBES_EXTEND_ADD,
48 PROBES_MUL_ADD_LONG,
49 PROBES_MUL_ADD,
50 PROBES_BITFIELD,
51 PROBES_BRANCH,
52 PROBES_LDMSTM,
53 NUM_PROBES_ARM_ACTIONS
54};
55
18void __kprobes simulate_bbl(struct kprobe *p, struct pt_regs *regs); 56void __kprobes simulate_bbl(struct kprobe *p, struct pt_regs *regs);
19void __kprobes simulate_blx1(struct kprobe *p, struct pt_regs *regs); 57void __kprobes simulate_blx1(struct kprobe *p, struct pt_regs *regs);
20void __kprobes simulate_blx2bx(struct kprobe *p, struct pt_regs *regs); 58void __kprobes simulate_blx2bx(struct kprobe *p, struct pt_regs *regs);
21void __kprobes simulate_mrs(struct kprobe *p, struct pt_regs *regs); 59void __kprobes simulate_mrs(struct kprobe *p, struct pt_regs *regs);
22void __kprobes simulate_mov_ipsp(struct kprobe *p, struct pt_regs *regs); 60void __kprobes simulate_mov_ipsp(struct kprobe *p, struct pt_regs *regs);
23 61
24void __kprobes emulate_ldrdstrd(struct kprobe *p, struct pt_regs *regs);
25void __kprobes emulate_ldr(struct kprobe *p, struct pt_regs *regs);
26void __kprobes emulate_str(struct kprobe *p, struct pt_regs *regs);
27void __kprobes emulate_rd12rn16rm0rs8_rwflags(struct kprobe *p,
28 struct pt_regs *regs);
29void __kprobes emulate_rd12rn16rm0_rwflags_nopc(struct kprobe *p,
30 struct pt_regs *regs);
31void __kprobes emulate_rd16rn12rm0rs8_rwflags_nopc(struct kprobe *p,
32 struct pt_regs *regs);
33void __kprobes emulate_rd12rm0_noflags_nopc(struct kprobe *p,
34 struct pt_regs *regs);
35void __kprobes emulate_rdlo12rdhi16rn0rm8_rwflags_nopc(struct kprobe *p,
36 struct pt_regs *regs);
37
38#endif 62#endif
diff --git a/arch/arm/kernel/probes-thumb.c b/arch/arm/kernel/probes-thumb.c
index a1f24777a41a..2abe8ceeb670 100644
--- a/arch/arm/kernel/probes-thumb.c
+++ b/arch/arm/kernel/probes-thumb.c
@@ -16,9 +16,6 @@
16#include "kprobes.h" 16#include "kprobes.h"
17#include "probes-thumb.h" 17#include "probes-thumb.h"
18 18
19/* These emulation encodings are functionally equivalent... */
20#define t32_emulate_rd8rn16rm0ra12_noflags \
21 t32_emulate_rdlo12rdhi8rn16rm0_noflags
22 19
23static const union decode_item t32_table_1110_100x_x0xx[] = { 20static const union decode_item t32_table_1110_100x_x0xx[] = {
24 /* Load/store multiple instructions */ 21 /* Load/store multiple instructions */
@@ -44,7 +41,7 @@ static const union decode_item t32_table_1110_100x_x0xx[] = {
44 /* LDMIA 1110 1000 10x1 xxxx xxxx xxxx xxxx xxxx */ 41 /* LDMIA 1110 1000 10x1 xxxx xxxx xxxx xxxx xxxx */
45 /* STMDB 1110 1001 00x0 xxxx xxxx xxxx xxxx xxxx */ 42 /* STMDB 1110 1001 00x0 xxxx xxxx xxxx xxxx xxxx */
46 /* LDMDB 1110 1001 00x1 xxxx xxxx xxxx xxxx xxxx */ 43 /* LDMDB 1110 1001 00x1 xxxx xxxx xxxx xxxx xxxx */
47 DECODE_CUSTOM (0xfe400000, 0xe8000000, t32_decode_ldmstm), 44 DECODE_CUSTOM (0xfe400000, 0xe8000000, PROBES_T32_LDMSTM),
48 45
49 DECODE_END 46 DECODE_END
50}; 47};
@@ -57,12 +54,12 @@ static const union decode_item t32_table_1110_100x_x1xx[] = {
57 DECODE_OR (0xff600000, 0xe8600000), 54 DECODE_OR (0xff600000, 0xe8600000),
58 /* STRD (immediate) 1110 1001 x1x0 xxxx xxxx xxxx xxxx xxxx */ 55 /* STRD (immediate) 1110 1001 x1x0 xxxx xxxx xxxx xxxx xxxx */
59 /* LDRD (immediate) 1110 1001 x1x1 xxxx xxxx xxxx xxxx xxxx */ 56 /* LDRD (immediate) 1110 1001 x1x1 xxxx xxxx xxxx xxxx xxxx */
60 DECODE_EMULATEX (0xff400000, 0xe9400000, t32_emulate_ldrdstrd, 57 DECODE_EMULATEX (0xff400000, 0xe9400000, PROBES_T32_LDRDSTRD,
61 REGS(NOPCWB, NOSPPC, NOSPPC, 0, 0)), 58 REGS(NOPCWB, NOSPPC, NOSPPC, 0, 0)),
62 59
63 /* TBB 1110 1000 1101 xxxx xxxx xxxx 0000 xxxx */ 60 /* TBB 1110 1000 1101 xxxx xxxx xxxx 0000 xxxx */
64 /* TBH 1110 1000 1101 xxxx xxxx xxxx 0001 xxxx */ 61 /* TBH 1110 1000 1101 xxxx xxxx xxxx 0001 xxxx */
65 DECODE_SIMULATEX(0xfff000e0, 0xe8d00000, t32_simulate_table_branch, 62 DECODE_SIMULATEX(0xfff000e0, 0xe8d00000, PROBES_T32_TABLE_BRANCH,
66 REGS(NOSP, 0, 0, 0, NOSPPC)), 63 REGS(NOSP, 0, 0, 0, NOSPPC)),
67 64
68 /* STREX 1110 1000 0100 xxxx xxxx xxxx xxxx xxxx */ 65 /* STREX 1110 1000 0100 xxxx xxxx xxxx xxxx xxxx */
@@ -82,18 +79,18 @@ static const union decode_item t32_table_1110_101x[] = {
82 79
83 /* TST 1110 1010 0001 xxxx xxxx 1111 xxxx xxxx */ 80 /* TST 1110 1010 0001 xxxx xxxx 1111 xxxx xxxx */
84 /* TEQ 1110 1010 1001 xxxx xxxx 1111 xxxx xxxx */ 81 /* TEQ 1110 1010 1001 xxxx xxxx 1111 xxxx xxxx */
85 DECODE_EMULATEX (0xff700f00, 0xea100f00, t32_emulate_rd8rn16rm0_rwflags, 82 DECODE_EMULATEX (0xff700f00, 0xea100f00, PROBES_T32_TST,
86 REGS(NOSPPC, 0, 0, 0, NOSPPC)), 83 REGS(NOSPPC, 0, 0, 0, NOSPPC)),
87 84
88 /* CMN 1110 1011 0001 xxxx xxxx 1111 xxxx xxxx */ 85 /* CMN 1110 1011 0001 xxxx xxxx 1111 xxxx xxxx */
89 DECODE_OR (0xfff00f00, 0xeb100f00), 86 DECODE_OR (0xfff00f00, 0xeb100f00),
90 /* CMP 1110 1011 1011 xxxx xxxx 1111 xxxx xxxx */ 87 /* CMP 1110 1011 1011 xxxx xxxx 1111 xxxx xxxx */
91 DECODE_EMULATEX (0xfff00f00, 0xebb00f00, t32_emulate_rd8rn16rm0_rwflags, 88 DECODE_EMULATEX (0xfff00f00, 0xebb00f00, PROBES_T32_TST,
92 REGS(NOPC, 0, 0, 0, NOSPPC)), 89 REGS(NOPC, 0, 0, 0, NOSPPC)),
93 90
94 /* MOV 1110 1010 010x 1111 xxxx xxxx xxxx xxxx */ 91 /* MOV 1110 1010 010x 1111 xxxx xxxx xxxx xxxx */
95 /* MVN 1110 1010 011x 1111 xxxx xxxx xxxx xxxx */ 92 /* MVN 1110 1010 011x 1111 xxxx xxxx xxxx xxxx */
96 DECODE_EMULATEX (0xffcf0000, 0xea4f0000, t32_emulate_rd8rn16rm0_rwflags, 93 DECODE_EMULATEX (0xffcf0000, 0xea4f0000, PROBES_T32_MOV,
97 REGS(0, 0, NOSPPC, 0, NOSPPC)), 94 REGS(0, 0, NOSPPC, 0, NOSPPC)),
98 95
99 /* ??? 1110 1010 101x xxxx xxxx xxxx xxxx xxxx */ 96 /* ??? 1110 1010 101x xxxx xxxx xxxx xxxx xxxx */
@@ -108,7 +105,7 @@ static const union decode_item t32_table_1110_101x[] = {
108 105
109 /* ADD/SUB SP, SP, Rm, LSL #0..3 */ 106 /* ADD/SUB SP, SP, Rm, LSL #0..3 */
110 /* 1110 1011 x0xx 1101 x000 1101 xx00 xxxx */ 107 /* 1110 1011 x0xx 1101 x000 1101 xx00 xxxx */
111 DECODE_EMULATEX (0xff4f7f30, 0xeb0d0d00, t32_emulate_rd8rn16rm0_rwflags, 108 DECODE_EMULATEX (0xff4f7f30, 0xeb0d0d00, PROBES_T32_ADDSUB,
112 REGS(SP, 0, SP, 0, NOSPPC)), 109 REGS(SP, 0, SP, 0, NOSPPC)),
113 110
114 /* ADD/SUB SP, SP, Rm, shift */ 111 /* ADD/SUB SP, SP, Rm, shift */
@@ -117,7 +114,7 @@ static const union decode_item t32_table_1110_101x[] = {
117 114
118 /* ADD/SUB Rd, SP, Rm, shift */ 115 /* ADD/SUB Rd, SP, Rm, shift */
119 /* 1110 1011 x0xx 1101 xxxx xxxx xxxx xxxx */ 116 /* 1110 1011 x0xx 1101 xxxx xxxx xxxx xxxx */
120 DECODE_EMULATEX (0xff4f0000, 0xeb0d0000, t32_emulate_rd8rn16rm0_rwflags, 117 DECODE_EMULATEX (0xff4f0000, 0xeb0d0000, PROBES_T32_ADDSUB,
121 REGS(SP, 0, NOPC, 0, NOSPPC)), 118 REGS(SP, 0, NOPC, 0, NOSPPC)),
122 119
123 /* AND 1110 1010 000x xxxx xxxx xxxx xxxx xxxx */ 120 /* AND 1110 1010 000x xxxx xxxx xxxx xxxx xxxx */
@@ -131,7 +128,7 @@ static const union decode_item t32_table_1110_101x[] = {
131 /* SBC 1110 1011 011x xxxx xxxx xxxx xxxx xxxx */ 128 /* SBC 1110 1011 011x xxxx xxxx xxxx xxxx xxxx */
132 /* SUB 1110 1011 101x xxxx xxxx xxxx xxxx xxxx */ 129 /* SUB 1110 1011 101x xxxx xxxx xxxx xxxx xxxx */
133 /* RSB 1110 1011 110x xxxx xxxx xxxx xxxx xxxx */ 130 /* RSB 1110 1011 110x xxxx xxxx xxxx xxxx xxxx */
134 DECODE_EMULATEX (0xfe000000, 0xea000000, t32_emulate_rd8rn16rm0_rwflags, 131 DECODE_EMULATEX (0xfe000000, 0xea000000, PROBES_T32_LOGICAL,
135 REGS(NOSPPC, 0, NOSPPC, 0, NOSPPC)), 132 REGS(NOSPPC, 0, NOSPPC, 0, NOSPPC)),
136 133
137 DECODE_END 134 DECODE_END
@@ -142,18 +139,18 @@ static const union decode_item t32_table_1111_0x0x___0[] = {
142 139
143 /* TST 1111 0x00 0001 xxxx 0xxx 1111 xxxx xxxx */ 140 /* TST 1111 0x00 0001 xxxx 0xxx 1111 xxxx xxxx */
144 /* TEQ 1111 0x00 1001 xxxx 0xxx 1111 xxxx xxxx */ 141 /* TEQ 1111 0x00 1001 xxxx 0xxx 1111 xxxx xxxx */
145 DECODE_EMULATEX (0xfb708f00, 0xf0100f00, t32_emulate_rd8rn16rm0_rwflags, 142 DECODE_EMULATEX (0xfb708f00, 0xf0100f00, PROBES_T32_TST,
146 REGS(NOSPPC, 0, 0, 0, 0)), 143 REGS(NOSPPC, 0, 0, 0, 0)),
147 144
148 /* CMN 1111 0x01 0001 xxxx 0xxx 1111 xxxx xxxx */ 145 /* CMN 1111 0x01 0001 xxxx 0xxx 1111 xxxx xxxx */
149 DECODE_OR (0xfbf08f00, 0xf1100f00), 146 DECODE_OR (0xfbf08f00, 0xf1100f00),
150 /* CMP 1111 0x01 1011 xxxx 0xxx 1111 xxxx xxxx */ 147 /* CMP 1111 0x01 1011 xxxx 0xxx 1111 xxxx xxxx */
151 DECODE_EMULATEX (0xfbf08f00, 0xf1b00f00, t32_emulate_rd8rn16rm0_rwflags, 148 DECODE_EMULATEX (0xfbf08f00, 0xf1b00f00, PROBES_T32_CMP,
152 REGS(NOPC, 0, 0, 0, 0)), 149 REGS(NOPC, 0, 0, 0, 0)),
153 150
154 /* MOV 1111 0x00 010x 1111 0xxx xxxx xxxx xxxx */ 151 /* MOV 1111 0x00 010x 1111 0xxx xxxx xxxx xxxx */
155 /* MVN 1111 0x00 011x 1111 0xxx xxxx xxxx xxxx */ 152 /* MVN 1111 0x00 011x 1111 0xxx xxxx xxxx xxxx */
156 DECODE_EMULATEX (0xfbcf8000, 0xf04f0000, t32_emulate_rd8rn16rm0_rwflags, 153 DECODE_EMULATEX (0xfbcf8000, 0xf04f0000, PROBES_T32_MOV,
157 REGS(0, 0, NOSPPC, 0, 0)), 154 REGS(0, 0, NOSPPC, 0, 0)),
158 155
159 /* ??? 1111 0x00 101x xxxx 0xxx xxxx xxxx xxxx */ 156 /* ??? 1111 0x00 101x xxxx 0xxx xxxx xxxx xxxx */
@@ -170,7 +167,7 @@ static const union decode_item t32_table_1111_0x0x___0[] = {
170 167
171 /* ADD Rd, SP, #imm 1111 0x01 000x 1101 0xxx xxxx xxxx xxxx */ 168 /* ADD Rd, SP, #imm 1111 0x01 000x 1101 0xxx xxxx xxxx xxxx */
172 /* SUB Rd, SP, #imm 1111 0x01 101x 1101 0xxx xxxx xxxx xxxx */ 169 /* SUB Rd, SP, #imm 1111 0x01 101x 1101 0xxx xxxx xxxx xxxx */
173 DECODE_EMULATEX (0xfb4f8000, 0xf10d0000, t32_emulate_rd8rn16rm0_rwflags, 170 DECODE_EMULATEX (0xfb4f8000, 0xf10d0000, PROBES_T32_ADDSUB,
174 REGS(SP, 0, NOPC, 0, 0)), 171 REGS(SP, 0, NOPC, 0, 0)),
175 172
176 /* AND 1111 0x00 000x xxxx 0xxx xxxx xxxx xxxx */ 173 /* AND 1111 0x00 000x xxxx 0xxx xxxx xxxx xxxx */
@@ -183,7 +180,7 @@ static const union decode_item t32_table_1111_0x0x___0[] = {
183 /* SBC 1111 0x01 011x xxxx 0xxx xxxx xxxx xxxx */ 180 /* SBC 1111 0x01 011x xxxx 0xxx xxxx xxxx xxxx */
184 /* SUB 1111 0x01 101x xxxx 0xxx xxxx xxxx xxxx */ 181 /* SUB 1111 0x01 101x xxxx 0xxx xxxx xxxx xxxx */
185 /* RSB 1111 0x01 110x xxxx 0xxx xxxx xxxx xxxx */ 182 /* RSB 1111 0x01 110x xxxx 0xxx xxxx xxxx xxxx */
186 DECODE_EMULATEX (0xfa008000, 0xf0000000, t32_emulate_rd8rn16rm0_rwflags, 183 DECODE_EMULATEX (0xfa008000, 0xf0000000, PROBES_T32_LOGICAL,
187 REGS(NOSPPC, 0, NOSPPC, 0, 0)), 184 REGS(NOSPPC, 0, NOSPPC, 0, 0)),
188 185
189 DECODE_END 186 DECODE_END
@@ -195,44 +192,44 @@ static const union decode_item t32_table_1111_0x1x___0[] = {
195 /* ADDW Rd, PC, #imm 1111 0x10 0000 1111 0xxx xxxx xxxx xxxx */ 192 /* ADDW Rd, PC, #imm 1111 0x10 0000 1111 0xxx xxxx xxxx xxxx */
196 DECODE_OR (0xfbff8000, 0xf20f0000), 193 DECODE_OR (0xfbff8000, 0xf20f0000),
197 /* SUBW Rd, PC, #imm 1111 0x10 1010 1111 0xxx xxxx xxxx xxxx */ 194 /* SUBW Rd, PC, #imm 1111 0x10 1010 1111 0xxx xxxx xxxx xxxx */
198 DECODE_EMULATEX (0xfbff8000, 0xf2af0000, t32_emulate_rd8pc16_noflags, 195 DECODE_EMULATEX (0xfbff8000, 0xf2af0000, PROBES_T32_ADDWSUBW_PC,
199 REGS(PC, 0, NOSPPC, 0, 0)), 196 REGS(PC, 0, NOSPPC, 0, 0)),
200 197
201 /* ADDW SP, SP, #imm 1111 0x10 0000 1101 0xxx 1101 xxxx xxxx */ 198 /* ADDW SP, SP, #imm 1111 0x10 0000 1101 0xxx 1101 xxxx xxxx */
202 DECODE_OR (0xfbff8f00, 0xf20d0d00), 199 DECODE_OR (0xfbff8f00, 0xf20d0d00),
203 /* SUBW SP, SP, #imm 1111 0x10 1010 1101 0xxx 1101 xxxx xxxx */ 200 /* SUBW SP, SP, #imm 1111 0x10 1010 1101 0xxx 1101 xxxx xxxx */
204 DECODE_EMULATEX (0xfbff8f00, 0xf2ad0d00, t32_emulate_rd8rn16_noflags, 201 DECODE_EMULATEX (0xfbff8f00, 0xf2ad0d00, PROBES_T32_ADDWSUBW,
205 REGS(SP, 0, SP, 0, 0)), 202 REGS(SP, 0, SP, 0, 0)),
206 203
207 /* ADDW 1111 0x10 0000 xxxx 0xxx xxxx xxxx xxxx */ 204 /* ADDW 1111 0x10 0000 xxxx 0xxx xxxx xxxx xxxx */
208 DECODE_OR (0xfbf08000, 0xf2000000), 205 DECODE_OR (0xfbf08000, 0xf2000000),
209 /* SUBW 1111 0x10 1010 xxxx 0xxx xxxx xxxx xxxx */ 206 /* SUBW 1111 0x10 1010 xxxx 0xxx xxxx xxxx xxxx */
210 DECODE_EMULATEX (0xfbf08000, 0xf2a00000, t32_emulate_rd8rn16_noflags, 207 DECODE_EMULATEX (0xfbf08000, 0xf2a00000, PROBES_T32_ADDWSUBW,
211 REGS(NOPCX, 0, NOSPPC, 0, 0)), 208 REGS(NOPCX, 0, NOSPPC, 0, 0)),
212 209
213 /* MOVW 1111 0x10 0100 xxxx 0xxx xxxx xxxx xxxx */ 210 /* MOVW 1111 0x10 0100 xxxx 0xxx xxxx xxxx xxxx */
214 /* MOVT 1111 0x10 1100 xxxx 0xxx xxxx xxxx xxxx */ 211 /* MOVT 1111 0x10 1100 xxxx 0xxx xxxx xxxx xxxx */
215 DECODE_EMULATEX (0xfb708000, 0xf2400000, t32_emulate_rd8rn16_noflags, 212 DECODE_EMULATEX (0xfb708000, 0xf2400000, PROBES_T32_MOVW,
216 REGS(0, 0, NOSPPC, 0, 0)), 213 REGS(0, 0, NOSPPC, 0, 0)),
217 214
218 /* SSAT16 1111 0x11 0010 xxxx 0000 xxxx 00xx xxxx */ 215 /* SSAT16 1111 0x11 0010 xxxx 0000 xxxx 00xx xxxx */
219 /* SSAT 1111 0x11 00x0 xxxx 0xxx xxxx xxxx xxxx */ 216 /* SSAT 1111 0x11 00x0 xxxx 0xxx xxxx xxxx xxxx */
220 /* USAT16 1111 0x11 1010 xxxx 0000 xxxx 00xx xxxx */ 217 /* USAT16 1111 0x11 1010 xxxx 0000 xxxx 00xx xxxx */
221 /* USAT 1111 0x11 10x0 xxxx 0xxx xxxx xxxx xxxx */ 218 /* USAT 1111 0x11 10x0 xxxx 0xxx xxxx xxxx xxxx */
222 DECODE_EMULATEX (0xfb508000, 0xf3000000, t32_emulate_rd8rn16rm0_rwflags, 219 DECODE_EMULATEX (0xfb508000, 0xf3000000, PROBES_T32_SAT,
223 REGS(NOSPPC, 0, NOSPPC, 0, 0)), 220 REGS(NOSPPC, 0, NOSPPC, 0, 0)),
224 221
225 /* SFBX 1111 0x11 0100 xxxx 0xxx xxxx xxxx xxxx */ 222 /* SFBX 1111 0x11 0100 xxxx 0xxx xxxx xxxx xxxx */
226 /* UFBX 1111 0x11 1100 xxxx 0xxx xxxx xxxx xxxx */ 223 /* UFBX 1111 0x11 1100 xxxx 0xxx xxxx xxxx xxxx */
227 DECODE_EMULATEX (0xfb708000, 0xf3400000, t32_emulate_rd8rn16_noflags, 224 DECODE_EMULATEX (0xfb708000, 0xf3400000, PROBES_T32_BITFIELD,
228 REGS(NOSPPC, 0, NOSPPC, 0, 0)), 225 REGS(NOSPPC, 0, NOSPPC, 0, 0)),
229 226
230 /* BFC 1111 0x11 0110 1111 0xxx xxxx xxxx xxxx */ 227 /* BFC 1111 0x11 0110 1111 0xxx xxxx xxxx xxxx */
231 DECODE_EMULATEX (0xfbff8000, 0xf36f0000, t32_emulate_rd8rn16_noflags, 228 DECODE_EMULATEX (0xfbff8000, 0xf36f0000, PROBES_T32_BITFIELD,
232 REGS(0, 0, NOSPPC, 0, 0)), 229 REGS(0, 0, NOSPPC, 0, 0)),
233 230
234 /* BFI 1111 0x11 0110 xxxx 0xxx xxxx xxxx xxxx */ 231 /* BFI 1111 0x11 0110 xxxx 0xxx xxxx xxxx xxxx */
235 DECODE_EMULATEX (0xfbf08000, 0xf3600000, t32_emulate_rd8rn16_noflags, 232 DECODE_EMULATEX (0xfbf08000, 0xf3600000, PROBES_T32_BITFIELD,
236 REGS(NOSPPCX, 0, NOSPPC, 0, 0)), 233 REGS(NOSPPCX, 0, NOSPPC, 0, 0)),
237 234
238 DECODE_END 235 DECODE_END
@@ -244,14 +241,14 @@ static const union decode_item t32_table_1111_0xxx___1[] = {
244 /* YIELD 1111 0011 1010 xxxx 10x0 x000 0000 0001 */ 241 /* YIELD 1111 0011 1010 xxxx 10x0 x000 0000 0001 */
245 DECODE_OR (0xfff0d7ff, 0xf3a08001), 242 DECODE_OR (0xfff0d7ff, 0xf3a08001),
246 /* SEV 1111 0011 1010 xxxx 10x0 x000 0000 0100 */ 243 /* SEV 1111 0011 1010 xxxx 10x0 x000 0000 0100 */
247 DECODE_EMULATE (0xfff0d7ff, 0xf3a08004, kprobe_emulate_none), 244 DECODE_EMULATE (0xfff0d7ff, 0xf3a08004, PROBES_T32_SEV),
248 /* NOP 1111 0011 1010 xxxx 10x0 x000 0000 0000 */ 245 /* NOP 1111 0011 1010 xxxx 10x0 x000 0000 0000 */
249 /* WFE 1111 0011 1010 xxxx 10x0 x000 0000 0010 */ 246 /* WFE 1111 0011 1010 xxxx 10x0 x000 0000 0010 */
250 /* WFI 1111 0011 1010 xxxx 10x0 x000 0000 0011 */ 247 /* WFI 1111 0011 1010 xxxx 10x0 x000 0000 0011 */
251 DECODE_SIMULATE (0xfff0d7fc, 0xf3a08000, kprobe_simulate_nop), 248 DECODE_SIMULATE (0xfff0d7fc, 0xf3a08000, PROBES_T32_WFE),
252 249
253 /* MRS Rd, CPSR 1111 0011 1110 xxxx 10x0 xxxx xxxx xxxx */ 250 /* MRS Rd, CPSR 1111 0011 1110 xxxx 10x0 xxxx xxxx xxxx */
254 DECODE_SIMULATEX(0xfff0d000, 0xf3e08000, t32_simulate_mrs, 251 DECODE_SIMULATEX(0xfff0d000, 0xf3e08000, PROBES_T32_MRS,
255 REGS(0, 0, NOSPPC, 0, 0)), 252 REGS(0, 0, NOSPPC, 0, 0)),
256 253
257 /* 254 /*
@@ -273,13 +270,13 @@ static const union decode_item t32_table_1111_0xxx___1[] = {
273 DECODE_REJECT (0xfb80d000, 0xf3808000), 270 DECODE_REJECT (0xfb80d000, 0xf3808000),
274 271
275 /* Bcc 1111 0xxx xxxx xxxx 10x0 xxxx xxxx xxxx */ 272 /* Bcc 1111 0xxx xxxx xxxx 10x0 xxxx xxxx xxxx */
276 DECODE_CUSTOM (0xf800d000, 0xf0008000, t32_decode_cond_branch), 273 DECODE_CUSTOM (0xf800d000, 0xf0008000, PROBES_T32_BRANCH_COND),
277 274
278 /* BLX 1111 0xxx xxxx xxxx 11x0 xxxx xxxx xxx0 */ 275 /* BLX 1111 0xxx xxxx xxxx 11x0 xxxx xxxx xxx0 */
279 DECODE_OR (0xf800d001, 0xf000c000), 276 DECODE_OR (0xf800d001, 0xf000c000),
280 /* B 1111 0xxx xxxx xxxx 10x1 xxxx xxxx xxxx */ 277 /* B 1111 0xxx xxxx xxxx 10x1 xxxx xxxx xxxx */
281 /* BL 1111 0xxx xxxx xxxx 11x1 xxxx xxxx xxxx */ 278 /* BL 1111 0xxx xxxx xxxx 11x1 xxxx xxxx xxxx */
282 DECODE_SIMULATE (0xf8009000, 0xf0009000, t32_simulate_branch), 279 DECODE_SIMULATE (0xf8009000, 0xf0009000, PROBES_T32_BRANCH),
283 280
284 DECODE_END 281 DECODE_END
285}; 282};
@@ -289,7 +286,7 @@ static const union decode_item t32_table_1111_100x_x0x1__1111[] = {
289 286
290 /* PLD (literal) 1111 1000 x001 1111 1111 xxxx xxxx xxxx */ 287 /* PLD (literal) 1111 1000 x001 1111 1111 xxxx xxxx xxxx */
291 /* PLI (literal) 1111 1001 x001 1111 1111 xxxx xxxx xxxx */ 288 /* PLI (literal) 1111 1001 x001 1111 1111 xxxx xxxx xxxx */
292 DECODE_SIMULATE (0xfe7ff000, 0xf81ff000, kprobe_simulate_nop), 289 DECODE_SIMULATE (0xfe7ff000, 0xf81ff000, PROBES_T32_PLDI),
293 290
294 /* PLD{W} (immediate) 1111 1000 10x1 xxxx 1111 xxxx xxxx xxxx */ 291 /* PLD{W} (immediate) 1111 1000 10x1 xxxx 1111 xxxx xxxx xxxx */
295 DECODE_OR (0xffd0f000, 0xf890f000), 292 DECODE_OR (0xffd0f000, 0xf890f000),
@@ -298,13 +295,13 @@ static const union decode_item t32_table_1111_100x_x0x1__1111[] = {
298 /* PLI (immediate) 1111 1001 1001 xxxx 1111 xxxx xxxx xxxx */ 295 /* PLI (immediate) 1111 1001 1001 xxxx 1111 xxxx xxxx xxxx */
299 DECODE_OR (0xfff0f000, 0xf990f000), 296 DECODE_OR (0xfff0f000, 0xf990f000),
300 /* PLI (immediate) 1111 1001 0001 xxxx 1111 1100 xxxx xxxx */ 297 /* PLI (immediate) 1111 1001 0001 xxxx 1111 1100 xxxx xxxx */
301 DECODE_SIMULATEX(0xfff0ff00, 0xf910fc00, kprobe_simulate_nop, 298 DECODE_SIMULATEX(0xfff0ff00, 0xf910fc00, PROBES_T32_PLDI,
302 REGS(NOPCX, 0, 0, 0, 0)), 299 REGS(NOPCX, 0, 0, 0, 0)),
303 300
304 /* PLD{W} (register) 1111 1000 00x1 xxxx 1111 0000 00xx xxxx */ 301 /* PLD{W} (register) 1111 1000 00x1 xxxx 1111 0000 00xx xxxx */
305 DECODE_OR (0xffd0ffc0, 0xf810f000), 302 DECODE_OR (0xffd0ffc0, 0xf810f000),
306 /* PLI (register) 1111 1001 0001 xxxx 1111 0000 00xx xxxx */ 303 /* PLI (register) 1111 1001 0001 xxxx 1111 0000 00xx xxxx */
307 DECODE_SIMULATEX(0xfff0ffc0, 0xf910f000, kprobe_simulate_nop, 304 DECODE_SIMULATEX(0xfff0ffc0, 0xf910f000, PROBES_T32_PLDI,
308 REGS(NOPCX, 0, 0, 0, NOSPPC)), 305 REGS(NOPCX, 0, 0, 0, NOSPPC)),
309 306
310 /* Other unallocated instructions... */ 307 /* Other unallocated instructions... */
@@ -340,7 +337,7 @@ static const union decode_item t32_table_1111_100x[] = {
340 DECODE_REJECT (0xff10f000, 0xf800f000), 337 DECODE_REJECT (0xff10f000, 0xf800f000),
341 338
342 /* LDR (literal) 1111 1000 x101 1111 xxxx xxxx xxxx xxxx */ 339 /* LDR (literal) 1111 1000 x101 1111 xxxx xxxx xxxx xxxx */
343 DECODE_SIMULATEX(0xff7f0000, 0xf85f0000, t32_simulate_ldr_literal, 340 DECODE_SIMULATEX(0xff7f0000, 0xf85f0000, PROBES_T32_LDR_LIT,
344 REGS(PC, ANY, 0, 0, 0)), 341 REGS(PC, ANY, 0, 0, 0)),
345 342
346 /* STR (immediate) 1111 1000 0100 xxxx xxxx 1xxx xxxx xxxx */ 343 /* STR (immediate) 1111 1000 0100 xxxx xxxx 1xxx xxxx xxxx */
@@ -348,19 +345,19 @@ static const union decode_item t32_table_1111_100x[] = {
348 DECODE_OR (0xffe00800, 0xf8400800), 345 DECODE_OR (0xffe00800, 0xf8400800),
349 /* STR (immediate) 1111 1000 1100 xxxx xxxx xxxx xxxx xxxx */ 346 /* STR (immediate) 1111 1000 1100 xxxx xxxx xxxx xxxx xxxx */
350 /* LDR (immediate) 1111 1000 1101 xxxx xxxx xxxx xxxx xxxx */ 347 /* LDR (immediate) 1111 1000 1101 xxxx xxxx xxxx xxxx xxxx */
351 DECODE_EMULATEX (0xffe00000, 0xf8c00000, t32_emulate_ldrstr, 348 DECODE_EMULATEX (0xffe00000, 0xf8c00000, PROBES_T32_LDRSTR,
352 REGS(NOPCX, ANY, 0, 0, 0)), 349 REGS(NOPCX, ANY, 0, 0, 0)),
353 350
354 /* STR (register) 1111 1000 0100 xxxx xxxx 0000 00xx xxxx */ 351 /* STR (register) 1111 1000 0100 xxxx xxxx 0000 00xx xxxx */
355 /* LDR (register) 1111 1000 0101 xxxx xxxx 0000 00xx xxxx */ 352 /* LDR (register) 1111 1000 0101 xxxx xxxx 0000 00xx xxxx */
356 DECODE_EMULATEX (0xffe00fc0, 0xf8400000, t32_emulate_ldrstr, 353 DECODE_EMULATEX (0xffe00fc0, 0xf8400000, PROBES_T32_LDRSTR,
357 REGS(NOPCX, ANY, 0, 0, NOSPPC)), 354 REGS(NOPCX, ANY, 0, 0, NOSPPC)),
358 355
359 /* LDRB (literal) 1111 1000 x001 1111 xxxx xxxx xxxx xxxx */ 356 /* LDRB (literal) 1111 1000 x001 1111 xxxx xxxx xxxx xxxx */
360 /* LDRSB (literal) 1111 1001 x001 1111 xxxx xxxx xxxx xxxx */ 357 /* LDRSB (literal) 1111 1001 x001 1111 xxxx xxxx xxxx xxxx */
361 /* LDRH (literal) 1111 1000 x011 1111 xxxx xxxx xxxx xxxx */ 358 /* LDRH (literal) 1111 1000 x011 1111 xxxx xxxx xxxx xxxx */
362 /* LDRSH (literal) 1111 1001 x011 1111 xxxx xxxx xxxx xxxx */ 359 /* LDRSH (literal) 1111 1001 x011 1111 xxxx xxxx xxxx xxxx */
363 DECODE_SIMULATEX(0xfe5f0000, 0xf81f0000, t32_simulate_ldr_literal, 360 DECODE_SIMULATEX(0xfe5f0000, 0xf81f0000, PROBES_T32_LDR_LIT,
364 REGS(PC, NOSPPCX, 0, 0, 0)), 361 REGS(PC, NOSPPCX, 0, 0, 0)),
365 362
366 /* STRB (immediate) 1111 1000 0000 xxxx xxxx 1xxx xxxx xxxx */ 363 /* STRB (immediate) 1111 1000 0000 xxxx xxxx 1xxx xxxx xxxx */
@@ -376,7 +373,7 @@ static const union decode_item t32_table_1111_100x[] = {
376 /* LDRSB (immediate) 1111 1001 1001 xxxx xxxx xxxx xxxx xxxx */ 373 /* LDRSB (immediate) 1111 1001 1001 xxxx xxxx xxxx xxxx xxxx */
377 /* LDRH (immediate) 1111 1000 1011 xxxx xxxx xxxx xxxx xxxx */ 374 /* LDRH (immediate) 1111 1000 1011 xxxx xxxx xxxx xxxx xxxx */
378 /* LDRSH (immediate) 1111 1001 1011 xxxx xxxx xxxx xxxx xxxx */ 375 /* LDRSH (immediate) 1111 1001 1011 xxxx xxxx xxxx xxxx xxxx */
379 DECODE_EMULATEX (0xfec00000, 0xf8800000, t32_emulate_ldrstr, 376 DECODE_EMULATEX (0xfec00000, 0xf8800000, PROBES_T32_LDRSTR,
380 REGS(NOPCX, NOSPPCX, 0, 0, 0)), 377 REGS(NOPCX, NOSPPCX, 0, 0, 0)),
381 378
382 /* STRB (register) 1111 1000 0000 xxxx xxxx 0000 00xx xxxx */ 379 /* STRB (register) 1111 1000 0000 xxxx xxxx 0000 00xx xxxx */
@@ -385,7 +382,7 @@ static const union decode_item t32_table_1111_100x[] = {
385 /* LDRSB (register) 1111 1001 0001 xxxx xxxx 0000 00xx xxxx */ 382 /* LDRSB (register) 1111 1001 0001 xxxx xxxx 0000 00xx xxxx */
386 /* LDRH (register) 1111 1000 0011 xxxx xxxx 0000 00xx xxxx */ 383 /* LDRH (register) 1111 1000 0011 xxxx xxxx 0000 00xx xxxx */
387 /* LDRSH (register) 1111 1001 0011 xxxx xxxx 0000 00xx xxxx */ 384 /* LDRSH (register) 1111 1001 0011 xxxx xxxx 0000 00xx xxxx */
388 DECODE_EMULATEX (0xfe800fc0, 0xf8000000, t32_emulate_ldrstr, 385 DECODE_EMULATEX (0xfe800fc0, 0xf8000000, PROBES_T32_LDRSTR,
389 REGS(NOPCX, NOSPPCX, 0, 0, NOSPPC)), 386 REGS(NOPCX, NOSPPCX, 0, 0, NOSPPC)),
390 387
391 /* Other unallocated instructions... */ 388 /* Other unallocated instructions... */
@@ -404,7 +401,7 @@ static const union decode_item t32_table_1111_1010___1111[] = {
404 /* UXTB16 1111 1010 0011 1111 1111 xxxx 1xxx xxxx */ 401 /* UXTB16 1111 1010 0011 1111 1111 xxxx 1xxx xxxx */
405 /* SXTB 1111 1010 0100 1111 1111 xxxx 1xxx xxxx */ 402 /* SXTB 1111 1010 0100 1111 1111 xxxx 1xxx xxxx */
406 /* UXTB 1111 1010 0101 1111 1111 xxxx 1xxx xxxx */ 403 /* UXTB 1111 1010 0101 1111 1111 xxxx 1xxx xxxx */
407 DECODE_EMULATEX (0xff8ff080, 0xfa0ff080, t32_emulate_rd8rn16rm0_rwflags, 404 DECODE_EMULATEX (0xff8ff080, 0xfa0ff080, PROBES_T32_SIGN_EXTEND,
408 REGS(0, 0, NOSPPC, 0, NOSPPC)), 405 REGS(0, 0, NOSPPC, 0, NOSPPC)),
409 406
410 407
@@ -477,7 +474,7 @@ static const union decode_item t32_table_1111_1010___1111[] = {
477 /* LSR 1111 1010 001x xxxx 1111 xxxx 0000 xxxx */ 474 /* LSR 1111 1010 001x xxxx 1111 xxxx 0000 xxxx */
478 /* ASR 1111 1010 010x xxxx 1111 xxxx 0000 xxxx */ 475 /* ASR 1111 1010 010x xxxx 1111 xxxx 0000 xxxx */
479 /* ROR 1111 1010 011x xxxx 1111 xxxx 0000 xxxx */ 476 /* ROR 1111 1010 011x xxxx 1111 xxxx 0000 xxxx */
480 DECODE_EMULATEX (0xff80f0f0, 0xfa00f000, t32_emulate_rd8rn16rm0_rwflags, 477 DECODE_EMULATEX (0xff80f0f0, 0xfa00f000, PROBES_T32_MEDIA,
481 REGS(NOSPPC, 0, NOSPPC, 0, NOSPPC)), 478 REGS(NOSPPC, 0, NOSPPC, 0, NOSPPC)),
482 479
483 /* CLZ 1111 1010 1010 xxxx 1111 xxxx 1000 xxxx */ 480 /* CLZ 1111 1010 1010 xxxx 1111 xxxx 1000 xxxx */
@@ -487,7 +484,7 @@ static const union decode_item t32_table_1111_1010___1111[] = {
487 /* REV16 1111 1010 1001 xxxx 1111 xxxx 1001 xxxx */ 484 /* REV16 1111 1010 1001 xxxx 1111 xxxx 1001 xxxx */
488 /* RBIT 1111 1010 1001 xxxx 1111 xxxx 1010 xxxx */ 485 /* RBIT 1111 1010 1001 xxxx 1111 xxxx 1010 xxxx */
489 /* REVSH 1111 1010 1001 xxxx 1111 xxxx 1011 xxxx */ 486 /* REVSH 1111 1010 1001 xxxx 1111 xxxx 1011 xxxx */
490 DECODE_EMULATEX (0xfff0f0c0, 0xfa90f080, t32_emulate_rd8rn16_noflags, 487 DECODE_EMULATEX (0xfff0f0c0, 0xfa90f080, PROBES_T32_REVERSE,
491 REGS(NOSPPC, 0, NOSPPC, 0, SAMEAS16)), 488 REGS(NOSPPC, 0, NOSPPC, 0, SAMEAS16)),
492 489
493 /* Other unallocated instructions... */ 490 /* Other unallocated instructions... */
@@ -510,7 +507,7 @@ static const union decode_item t32_table_1111_1011_0[] = {
510 /* SMUSD{X} 1111 1011 0100 xxxx 1111 xxxx 000x xxxx */ 507 /* SMUSD{X} 1111 1011 0100 xxxx 1111 xxxx 000x xxxx */
511 /* SMMUL{R} 1111 1011 0101 xxxx 1111 xxxx 000x xxxx */ 508 /* SMMUL{R} 1111 1011 0101 xxxx 1111 xxxx 000x xxxx */
512 /* USAD8 1111 1011 0111 xxxx 1111 xxxx 0000 xxxx */ 509 /* USAD8 1111 1011 0111 xxxx 1111 xxxx 0000 xxxx */
513 DECODE_EMULATEX (0xff80f0e0, 0xfb00f000, t32_emulate_rd8rn16rm0_rwflags, 510 DECODE_EMULATEX (0xff80f0e0, 0xfb00f000, PROBES_T32_MUL_ADD,
514 REGS(NOSPPC, 0, NOSPPC, 0, NOSPPC)), 511 REGS(NOSPPC, 0, NOSPPC, 0, NOSPPC)),
515 512
516 /* ??? 1111 1011 0111 xxxx xxxx xxxx 0001 xxxx */ 513 /* ??? 1111 1011 0111 xxxx xxxx xxxx 0001 xxxx */
@@ -526,7 +523,7 @@ static const union decode_item t32_table_1111_1011_0[] = {
526 /* SMMLA{R} 1111 1011 0101 xxxx xxxx xxxx 000x xxxx */ 523 /* SMMLA{R} 1111 1011 0101 xxxx xxxx xxxx 000x xxxx */
527 /* SMMLS{R} 1111 1011 0110 xxxx xxxx xxxx 000x xxxx */ 524 /* SMMLS{R} 1111 1011 0110 xxxx xxxx xxxx 000x xxxx */
528 /* USADA8 1111 1011 0111 xxxx xxxx xxxx 0000 xxxx */ 525 /* USADA8 1111 1011 0111 xxxx xxxx xxxx 0000 xxxx */
529 DECODE_EMULATEX (0xff8000c0, 0xfb000000, t32_emulate_rd8rn16rm0ra12_noflags, 526 DECODE_EMULATEX (0xff8000c0, 0xfb000000, PROBES_T32_MUL_ADD2,
530 REGS(NOSPPC, NOSPPCX, NOSPPC, 0, NOSPPC)), 527 REGS(NOSPPC, NOSPPCX, NOSPPC, 0, NOSPPC)),
531 528
532 /* Other unallocated instructions... */ 529 /* Other unallocated instructions... */
@@ -547,7 +544,7 @@ static const union decode_item t32_table_1111_1011_1[] = {
547 /* UMULL 1111 1011 1010 xxxx xxxx xxxx 0000 xxxx */ 544 /* UMULL 1111 1011 1010 xxxx xxxx xxxx 0000 xxxx */
548 /* SMLAL 1111 1011 1100 xxxx xxxx xxxx 0000 xxxx */ 545 /* SMLAL 1111 1011 1100 xxxx xxxx xxxx 0000 xxxx */
549 /* UMLAL 1111 1011 1110 xxxx xxxx xxxx 0000 xxxx */ 546 /* UMLAL 1111 1011 1110 xxxx xxxx xxxx 0000 xxxx */
550 DECODE_EMULATEX (0xff9000f0, 0xfb800000, t32_emulate_rdlo12rdhi8rn16rm0_noflags, 547 DECODE_EMULATEX (0xff9000f0, 0xfb800000, PROBES_T32_MUL_ADD_LONG,
551 REGS(NOSPPC, NOSPPC, NOSPPC, 0, NOSPPC)), 548 REGS(NOSPPC, NOSPPC, NOSPPC, 0, NOSPPC)),
552 549
553 /* SDIV 1111 1011 1001 xxxx xxxx xxxx 1111 xxxx */ 550 /* SDIV 1111 1011 1001 xxxx xxxx xxxx 1111 xxxx */
@@ -653,11 +650,11 @@ static const union decode_item t16_table_1011[] = {
653 650
654 /* ADD (SP plus immediate) 1011 0000 0xxx xxxx */ 651 /* ADD (SP plus immediate) 1011 0000 0xxx xxxx */
655 /* SUB (SP minus immediate) 1011 0000 1xxx xxxx */ 652 /* SUB (SP minus immediate) 1011 0000 1xxx xxxx */
656 DECODE_SIMULATE (0xff00, 0xb000, t16_simulate_add_sp_imm), 653 DECODE_SIMULATE (0xff00, 0xb000, PROBES_T16_ADD_SP),
657 654
658 /* CBZ 1011 00x1 xxxx xxxx */ 655 /* CBZ 1011 00x1 xxxx xxxx */
659 /* CBNZ 1011 10x1 xxxx xxxx */ 656 /* CBNZ 1011 10x1 xxxx xxxx */
660 DECODE_SIMULATE (0xf500, 0xb100, t16_simulate_cbz), 657 DECODE_SIMULATE (0xf500, 0xb100, PROBES_T16_CBZ),
661 658
662 /* SXTH 1011 0010 00xx xxxx */ 659 /* SXTH 1011 0010 00xx xxxx */
663 /* SXTB 1011 0010 01xx xxxx */ 660 /* SXTB 1011 0010 01xx xxxx */
@@ -668,12 +665,12 @@ static const union decode_item t16_table_1011[] = {
668 /* ??? 1011 1010 10xx xxxx */ 665 /* ??? 1011 1010 10xx xxxx */
669 /* REVSH 1011 1010 11xx xxxx */ 666 /* REVSH 1011 1010 11xx xxxx */
670 DECODE_REJECT (0xffc0, 0xba80), 667 DECODE_REJECT (0xffc0, 0xba80),
671 DECODE_EMULATE (0xf500, 0xb000, t16_emulate_loregs_rwflags), 668 DECODE_EMULATE (0xf500, 0xb000, PROBES_T16_SIGN_EXTEND),
672 669
673 /* PUSH 1011 010x xxxx xxxx */ 670 /* PUSH 1011 010x xxxx xxxx */
674 DECODE_CUSTOM (0xfe00, 0xb400, t16_decode_push), 671 DECODE_CUSTOM (0xfe00, 0xb400, PROBES_T16_PUSH),
675 /* POP 1011 110x xxxx xxxx */ 672 /* POP 1011 110x xxxx xxxx */
676 DECODE_CUSTOM (0xfe00, 0xbc00, t16_decode_pop), 673 DECODE_CUSTOM (0xfe00, 0xbc00, PROBES_T16_POP),
677 674
678 /* 675 /*
679 * If-Then, and hints 676 * If-Then, and hints
@@ -683,15 +680,15 @@ static const union decode_item t16_table_1011[] = {
683 /* YIELD 1011 1111 0001 0000 */ 680 /* YIELD 1011 1111 0001 0000 */
684 DECODE_OR (0xffff, 0xbf10), 681 DECODE_OR (0xffff, 0xbf10),
685 /* SEV 1011 1111 0100 0000 */ 682 /* SEV 1011 1111 0100 0000 */
686 DECODE_EMULATE (0xffff, 0xbf40, kprobe_emulate_none), 683 DECODE_EMULATE (0xffff, 0xbf40, PROBES_T16_SEV),
687 /* NOP 1011 1111 0000 0000 */ 684 /* NOP 1011 1111 0000 0000 */
688 /* WFE 1011 1111 0010 0000 */ 685 /* WFE 1011 1111 0010 0000 */
689 /* WFI 1011 1111 0011 0000 */ 686 /* WFI 1011 1111 0011 0000 */
690 DECODE_SIMULATE (0xffcf, 0xbf00, kprobe_simulate_nop), 687 DECODE_SIMULATE (0xffcf, 0xbf00, PROBES_T16_WFE),
691 /* Unassigned hints 1011 1111 xxxx 0000 */ 688 /* Unassigned hints 1011 1111 xxxx 0000 */
692 DECODE_REJECT (0xff0f, 0xbf00), 689 DECODE_REJECT (0xff0f, 0xbf00),
693 /* IT 1011 1111 xxxx xxxx */ 690 /* IT 1011 1111 xxxx xxxx */
694 DECODE_CUSTOM (0xff00, 0xbf00, t16_decode_it), 691 DECODE_CUSTOM (0xff00, 0xbf00, PROBES_T16_IT),
695 692
696 /* SETEND 1011 0110 010x xxxx */ 693 /* SETEND 1011 0110 010x xxxx */
697 /* CPS 1011 0110 011x xxxx */ 694 /* CPS 1011 0110 011x xxxx */
@@ -708,7 +705,7 @@ const union decode_item kprobe_decode_thumb16_table[] = {
708 */ 705 */
709 706
710 /* CMP (immediate) 0010 1xxx xxxx xxxx */ 707 /* CMP (immediate) 0010 1xxx xxxx xxxx */
711 DECODE_EMULATE (0xf800, 0x2800, t16_emulate_loregs_rwflags), 708 DECODE_EMULATE (0xf800, 0x2800, PROBES_T16_CMP),
712 709
713 /* ADD (register) 0001 100x xxxx xxxx */ 710 /* ADD (register) 0001 100x xxxx xxxx */
714 /* SUB (register) 0001 101x xxxx xxxx */ 711 /* SUB (register) 0001 101x xxxx xxxx */
@@ -720,7 +717,7 @@ const union decode_item kprobe_decode_thumb16_table[] = {
720 /* MOV (immediate) 0010 0xxx xxxx xxxx */ 717 /* MOV (immediate) 0010 0xxx xxxx xxxx */
721 /* ADD (immediate, Thumb) 0011 0xxx xxxx xxxx */ 718 /* ADD (immediate, Thumb) 0011 0xxx xxxx xxxx */
722 /* SUB (immediate, Thumb) 0011 1xxx xxxx xxxx */ 719 /* SUB (immediate, Thumb) 0011 1xxx xxxx xxxx */
723 DECODE_EMULATE (0xc000, 0x0000, t16_emulate_loregs_noitrwflags), 720 DECODE_EMULATE (0xc000, 0x0000, PROBES_T16_ADDSUB),
724 721
725 /* 722 /*
726 * 16-bit Thumb data-processing instructions 723 * 16-bit Thumb data-processing instructions
@@ -728,10 +725,10 @@ const union decode_item kprobe_decode_thumb16_table[] = {
728 */ 725 */
729 726
730 /* TST (register) 0100 0010 00xx xxxx */ 727 /* TST (register) 0100 0010 00xx xxxx */
731 DECODE_EMULATE (0xffc0, 0x4200, t16_emulate_loregs_rwflags), 728 DECODE_EMULATE (0xffc0, 0x4200, PROBES_T16_CMP),
732 /* CMP (register) 0100 0010 10xx xxxx */ 729 /* CMP (register) 0100 0010 10xx xxxx */
733 /* CMN (register) 0100 0010 11xx xxxx */ 730 /* CMN (register) 0100 0010 11xx xxxx */
734 DECODE_EMULATE (0xff80, 0x4280, t16_emulate_loregs_rwflags), 731 DECODE_EMULATE (0xff80, 0x4280, PROBES_T16_CMP),
735 /* AND (register) 0100 0000 00xx xxxx */ 732 /* AND (register) 0100 0000 00xx xxxx */
736 /* EOR (register) 0100 0000 01xx xxxx */ 733 /* EOR (register) 0100 0000 01xx xxxx */
737 /* LSL (register) 0100 0000 10xx xxxx */ 734 /* LSL (register) 0100 0000 10xx xxxx */
@@ -745,7 +742,7 @@ const union decode_item kprobe_decode_thumb16_table[] = {
745 /* MUL 0100 0011 00xx xxxx */ 742 /* MUL 0100 0011 00xx xxxx */
746 /* BIC (register) 0100 0011 10xx xxxx */ 743 /* BIC (register) 0100 0011 10xx xxxx */
747 /* MVN (register) 0100 0011 10xx xxxx */ 744 /* MVN (register) 0100 0011 10xx xxxx */
748 DECODE_EMULATE (0xfc00, 0x4000, t16_emulate_loregs_noitrwflags), 745 DECODE_EMULATE (0xfc00, 0x4000, PROBES_T16_LOGICAL),
749 746
750 /* 747 /*
751 * Special data instructions and branch and exchange 748 * Special data instructions and branch and exchange
@@ -757,7 +754,7 @@ const union decode_item kprobe_decode_thumb16_table[] = {
757 754
758 /* BX (register) 0100 0111 0xxx xxxx */ 755 /* BX (register) 0100 0111 0xxx xxxx */
759 /* BLX (register) 0100 0111 1xxx xxxx */ 756 /* BLX (register) 0100 0111 1xxx xxxx */
760 DECODE_SIMULATE (0xff00, 0x4700, t16_simulate_bxblx), 757 DECODE_SIMULATE (0xff00, 0x4700, PROBES_T16_BLX),
761 758
762 /* ADD pc, pc 0100 0100 1111 1111 */ 759 /* ADD pc, pc 0100 0100 1111 1111 */
763 DECODE_REJECT (0xffff, 0x44ff), 760 DECODE_REJECT (0xffff, 0x44ff),
@@ -765,13 +762,13 @@ const union decode_item kprobe_decode_thumb16_table[] = {
765 /* ADD (register) 0100 0100 xxxx xxxx */ 762 /* ADD (register) 0100 0100 xxxx xxxx */
766 /* CMP (register) 0100 0101 xxxx xxxx */ 763 /* CMP (register) 0100 0101 xxxx xxxx */
767 /* MOV (register) 0100 0110 xxxx xxxx */ 764 /* MOV (register) 0100 0110 xxxx xxxx */
768 DECODE_CUSTOM (0xfc00, 0x4400, t16_decode_hiregs), 765 DECODE_CUSTOM (0xfc00, 0x4400, PROBES_T16_HIREGOPS),
769 766
770 /* 767 /*
771 * Load from Literal Pool 768 * Load from Literal Pool
772 * LDR (literal) 0100 1xxx xxxx xxxx 769 * LDR (literal) 0100 1xxx xxxx xxxx
773 */ 770 */
774 DECODE_SIMULATE (0xf800, 0x4800, t16_simulate_ldr_literal), 771 DECODE_SIMULATE (0xf800, 0x4800, PROBES_T16_LDR_LIT),
775 772
776 /* 773 /*
777 * 16-bit Thumb Load/store instructions 774 * 16-bit Thumb Load/store instructions
@@ -792,20 +789,20 @@ const union decode_item kprobe_decode_thumb16_table[] = {
792 /* LDR (immediate, Thumb) 0110 1xxx xxxx xxxx */ 789 /* LDR (immediate, Thumb) 0110 1xxx xxxx xxxx */
793 /* STRB (immediate, Thumb) 0111 0xxx xxxx xxxx */ 790 /* STRB (immediate, Thumb) 0111 0xxx xxxx xxxx */
794 /* LDRB (immediate, Thumb) 0111 1xxx xxxx xxxx */ 791 /* LDRB (immediate, Thumb) 0111 1xxx xxxx xxxx */
795 DECODE_EMULATE (0xc000, 0x4000, t16_emulate_loregs_rwflags), 792 DECODE_EMULATE (0xc000, 0x4000, PROBES_T16_LDRHSTRH),
796 /* STRH (immediate, Thumb) 1000 0xxx xxxx xxxx */ 793 /* STRH (immediate, Thumb) 1000 0xxx xxxx xxxx */
797 /* LDRH (immediate, Thumb) 1000 1xxx xxxx xxxx */ 794 /* LDRH (immediate, Thumb) 1000 1xxx xxxx xxxx */
798 DECODE_EMULATE (0xf000, 0x8000, t16_emulate_loregs_rwflags), 795 DECODE_EMULATE (0xf000, 0x8000, PROBES_T16_LDRHSTRH),
799 /* STR (immediate, Thumb) 1001 0xxx xxxx xxxx */ 796 /* STR (immediate, Thumb) 1001 0xxx xxxx xxxx */
800 /* LDR (immediate, Thumb) 1001 1xxx xxxx xxxx */ 797 /* LDR (immediate, Thumb) 1001 1xxx xxxx xxxx */
801 DECODE_SIMULATE (0xf000, 0x9000, t16_simulate_ldrstr_sp_relative), 798 DECODE_SIMULATE (0xf000, 0x9000, PROBES_T16_LDRSTR),
802 799
803 /* 800 /*
804 * Generate PC-/SP-relative address 801 * Generate PC-/SP-relative address
805 * ADR (literal) 1010 0xxx xxxx xxxx 802 * ADR (literal) 1010 0xxx xxxx xxxx
806 * ADD (SP plus immediate) 1010 1xxx xxxx xxxx 803 * ADD (SP plus immediate) 1010 1xxx xxxx xxxx
807 */ 804 */
808 DECODE_SIMULATE (0xf000, 0xa000, t16_simulate_reladr), 805 DECODE_SIMULATE (0xf000, 0xa000, PROBES_T16_ADR),
809 806
810 /* 807 /*
811 * Miscellaneous 16-bit instructions 808 * Miscellaneous 16-bit instructions
@@ -815,7 +812,7 @@ const union decode_item kprobe_decode_thumb16_table[] = {
815 812
816 /* STM 1100 0xxx xxxx xxxx */ 813 /* STM 1100 0xxx xxxx xxxx */
817 /* LDM 1100 1xxx xxxx xxxx */ 814 /* LDM 1100 1xxx xxxx xxxx */
818 DECODE_EMULATE (0xf000, 0xc000, t16_emulate_loregs_rwflags), 815 DECODE_EMULATE (0xf000, 0xc000, PROBES_T16_LDMSTM),
819 816
820 /* 817 /*
821 * Conditional branch, and Supervisor Call 818 * Conditional branch, and Supervisor Call
@@ -826,13 +823,13 @@ const union decode_item kprobe_decode_thumb16_table[] = {
826 DECODE_REJECT (0xfe00, 0xde00), 823 DECODE_REJECT (0xfe00, 0xde00),
827 824
828 /* Conditional branch 1101 xxxx xxxx xxxx */ 825 /* Conditional branch 1101 xxxx xxxx xxxx */
829 DECODE_CUSTOM (0xf000, 0xd000, t16_decode_cond_branch), 826 DECODE_CUSTOM (0xf000, 0xd000, PROBES_T16_BRANCH_COND),
830 827
831 /* 828 /*
832 * Unconditional branch 829 * Unconditional branch
833 * B 1110 0xxx xxxx xxxx 830 * B 1110 0xxx xxxx xxxx
834 */ 831 */
835 DECODE_SIMULATE (0xf800, 0xe000, t16_simulate_branch), 832 DECODE_SIMULATE (0xf800, 0xe000, PROBES_T16_BRANCH),
836 833
837 DECODE_END 834 DECODE_END
838}; 835};
@@ -862,17 +859,21 @@ static void __kprobes thumb32_singlestep(struct kprobe *p, struct pt_regs *regs)
862} 859}
863 860
864enum kprobe_insn __kprobes 861enum kprobe_insn __kprobes
865thumb16_kprobe_decode_insn(kprobe_opcode_t insn, struct arch_specific_insn *asi) 862thumb16_kprobe_decode_insn(kprobe_opcode_t insn, struct arch_specific_insn *asi,
863 const union decode_action *actions)
866{ 864{
867 asi->insn_singlestep = thumb16_singlestep; 865 asi->insn_singlestep = thumb16_singlestep;
868 asi->insn_check_cc = thumb_check_cc; 866 asi->insn_check_cc = thumb_check_cc;
869 return kprobe_decode_insn(insn, asi, kprobe_decode_thumb16_table, true); 867 return kprobe_decode_insn(insn, asi, kprobe_decode_thumb16_table, true,
868 actions);
870} 869}
871 870
872enum kprobe_insn __kprobes 871enum kprobe_insn __kprobes
873thumb32_kprobe_decode_insn(kprobe_opcode_t insn, struct arch_specific_insn *asi) 872thumb32_kprobe_decode_insn(kprobe_opcode_t insn, struct arch_specific_insn *asi,
873 const union decode_action *actions)
874{ 874{
875 asi->insn_singlestep = thumb32_singlestep; 875 asi->insn_singlestep = thumb32_singlestep;
876 asi->insn_check_cc = thumb_check_cc; 876 asi->insn_check_cc = thumb_check_cc;
877 return kprobe_decode_insn(insn, asi, kprobe_decode_thumb32_table, true); 877 return kprobe_decode_insn(insn, asi, kprobe_decode_thumb32_table, true,
878 actions);
878} 879}
diff --git a/arch/arm/kernel/probes-thumb.h b/arch/arm/kernel/probes-thumb.h
index 98709c40b659..8d6b4eefa706 100644
--- a/arch/arm/kernel/probes-thumb.h
+++ b/arch/arm/kernel/probes-thumb.h
@@ -27,55 +27,61 @@
27 */ 27 */
28#define current_cond(cpsr) ((cpsr >> 12) & 0xf) 28#define current_cond(cpsr) ((cpsr >> 12) & 0xf)
29 29
30void __kprobes t16_simulate_bxblx(struct kprobe *p, struct pt_regs *regs); 30enum probes_t32_action {
31void __kprobes t16_simulate_ldr_literal(struct kprobe *p, struct pt_regs *regs); 31 PROBES_T32_EMULATE_NONE,
32void __kprobes t16_simulate_ldrstr_sp_relative(struct kprobe *p, 32 PROBES_T32_SIMULATE_NOP,
33 struct pt_regs *regs); 33 PROBES_T32_LDMSTM,
34void __kprobes t16_simulate_reladr(struct kprobe *p, struct pt_regs *regs); 34 PROBES_T32_LDRDSTRD,
35void __kprobes t16_simulate_add_sp_imm(struct kprobe *p, struct pt_regs *regs); 35 PROBES_T32_TABLE_BRANCH,
36void __kprobes t16_simulate_cbz(struct kprobe *p, struct pt_regs *regs); 36 PROBES_T32_TST,
37void __kprobes t16_simulate_it(struct kprobe *p, struct pt_regs *regs); 37 PROBES_T32_CMP,
38void __kprobes t16_singlestep_it(struct kprobe *p, struct pt_regs *regs); 38 PROBES_T32_MOV,
39enum kprobe_insn __kprobes t16_decode_it(kprobe_opcode_t insn, 39 PROBES_T32_ADDSUB,
40 struct arch_specific_insn *asi); 40 PROBES_T32_LOGICAL,
41void __kprobes t16_simulate_cond_branch(struct kprobe *p, struct pt_regs *regs); 41 PROBES_T32_ADDWSUBW_PC,
42enum kprobe_insn __kprobes t16_decode_cond_branch(kprobe_opcode_t insn, 42 PROBES_T32_ADDWSUBW,
43 struct arch_specific_insn *asi); 43 PROBES_T32_MOVW,
44void __kprobes t16_simulate_branch(struct kprobe *p, struct pt_regs *regs); 44 PROBES_T32_SAT,
45void __kprobes t16_emulate_loregs_rwflags(struct kprobe *p, 45 PROBES_T32_BITFIELD,
46 struct pt_regs *regs); 46 PROBES_T32_SEV,
47void __kprobes t16_emulate_loregs_noitrwflags(struct kprobe *p, 47 PROBES_T32_WFE,
48 struct pt_regs *regs); 48 PROBES_T32_MRS,
49void __kprobes t16_emulate_hiregs(struct kprobe *p, struct pt_regs *regs); 49 PROBES_T32_BRANCH_COND,
50enum kprobe_insn __kprobes t16_decode_hiregs(kprobe_opcode_t insn, 50 PROBES_T32_BRANCH,
51 struct arch_specific_insn *asi); 51 PROBES_T32_PLDI,
52void __kprobes t16_emulate_push(struct kprobe *p, struct pt_regs *regs); 52 PROBES_T32_LDR_LIT,
53enum kprobe_insn __kprobes t16_decode_push(kprobe_opcode_t insn, 53 PROBES_T32_LDRSTR,
54 struct arch_specific_insn *asi); 54 PROBES_T32_SIGN_EXTEND,
55void __kprobes t16_emulate_pop_nopc(struct kprobe *p, struct pt_regs *regs); 55 PROBES_T32_MEDIA,
56void __kprobes t16_emulate_pop_pc(struct kprobe *p, struct pt_regs *regs); 56 PROBES_T32_REVERSE,
57enum kprobe_insn __kprobes t16_decode_pop(kprobe_opcode_t insn, 57 PROBES_T32_MUL_ADD,
58 struct arch_specific_insn *asi); 58 PROBES_T32_MUL_ADD2,
59 PROBES_T32_MUL_ADD_LONG,
60 NUM_PROBES_T32_ACTIONS
61};
59 62
60void __kprobes t32_simulate_table_branch(struct kprobe *p, 63enum probes_t16_action {
61 struct pt_regs *regs); 64 PROBES_T16_ADD_SP,
62void __kprobes t32_simulate_mrs(struct kprobe *p, struct pt_regs *regs); 65 PROBES_T16_CBZ,
63void __kprobes t32_simulate_cond_branch(struct kprobe *p, struct pt_regs *regs); 66 PROBES_T16_SIGN_EXTEND,
64enum kprobe_insn __kprobes t32_decode_cond_branch(kprobe_opcode_t insn, 67 PROBES_T16_PUSH,
65 struct arch_specific_insn *asi); 68 PROBES_T16_POP,
66void __kprobes t32_simulate_branch(struct kprobe *p, struct pt_regs *regs); 69 PROBES_T16_SEV,
67void __kprobes t32_simulate_ldr_literal(struct kprobe *p, struct pt_regs *regs); 70 PROBES_T16_WFE,
68enum kprobe_insn __kprobes t32_decode_ldmstm(kprobe_opcode_t insn, 71 PROBES_T16_IT,
69 struct arch_specific_insn *asi); 72 PROBES_T16_CMP,
70void __kprobes t32_emulate_ldrdstrd(struct kprobe *p, struct pt_regs *regs); 73 PROBES_T16_ADDSUB,
71void __kprobes t32_emulate_ldrstr(struct kprobe *p, struct pt_regs *regs); 74 PROBES_T16_LOGICAL,
72void __kprobes t32_emulate_rd8rn16rm0_rwflags(struct kprobe *p, 75 PROBES_T16_BLX,
73 struct pt_regs *regs); 76 PROBES_T16_HIREGOPS,
74void __kprobes t32_emulate_rd8pc16_noflags(struct kprobe *p, 77 PROBES_T16_LDR_LIT,
75 struct pt_regs *regs); 78 PROBES_T16_LDRHSTRH,
76void __kprobes t32_emulate_rd8rn16_noflags(struct kprobe *p, 79 PROBES_T16_LDRSTR,
77 struct pt_regs *regs); 80 PROBES_T16_ADR,
78void __kprobes t32_emulate_rdlo12rdhi8rn16rm0_noflags(struct kprobe *p, 81 PROBES_T16_LDMSTM,
79 struct pt_regs *regs); 82 PROBES_T16_BRANCH_COND,
83 PROBES_T16_BRANCH,
84 NUM_PROBES_T16_ACTIONS
85};
80 86
81#endif 87#endif
diff --git a/arch/arm/kernel/probes.c b/arch/arm/kernel/probes.c
index 3a63f8f83cf8..efd92c5b4a52 100644
--- a/arch/arm/kernel/probes.c
+++ b/arch/arm/kernel/probes.c
@@ -381,7 +381,8 @@ static const int decode_struct_sizes[NUM_DECODE_TYPES] = {
381 */ 381 */
382int __kprobes 382int __kprobes
383kprobe_decode_insn(kprobe_opcode_t insn, struct arch_specific_insn *asi, 383kprobe_decode_insn(kprobe_opcode_t insn, struct arch_specific_insn *asi,
384 const union decode_item *table, bool thumb) 384 const union decode_item *table, bool thumb,
385 const union decode_action *actions)
385{ 386{
386 const struct decode_header *h = (struct decode_header *)table; 387 const struct decode_header *h = (struct decode_header *)table;
387 const struct decode_header *next; 388 const struct decode_header *next;
@@ -415,18 +416,18 @@ kprobe_decode_insn(kprobe_opcode_t insn, struct arch_specific_insn *asi,
415 416
416 case DECODE_TYPE_CUSTOM: { 417 case DECODE_TYPE_CUSTOM: {
417 struct decode_custom *d = (struct decode_custom *)h; 418 struct decode_custom *d = (struct decode_custom *)h;
418 return (*d->decoder.decoder)(insn, asi); 419 return actions[d->decoder.action].decoder(insn, asi, h);
419 } 420 }
420 421
421 case DECODE_TYPE_SIMULATE: { 422 case DECODE_TYPE_SIMULATE: {
422 struct decode_simulate *d = (struct decode_simulate *)h; 423 struct decode_simulate *d = (struct decode_simulate *)h;
423 asi->insn_handler = d->handler.handler; 424 asi->insn_handler = actions[d->handler.action].handler;
424 return INSN_GOOD_NO_SLOT; 425 return INSN_GOOD_NO_SLOT;
425 } 426 }
426 427
427 case DECODE_TYPE_EMULATE: { 428 case DECODE_TYPE_EMULATE: {
428 struct decode_emulate *d = (struct decode_emulate *)h; 429 struct decode_emulate *d = (struct decode_emulate *)h;
429 asi->insn_handler = d->handler.handler; 430 asi->insn_handler = actions[d->handler.action].handler;
430 set_emulated_insn(insn, asi, thumb); 431 set_emulated_insn(insn, asi, thumb);
431 return INSN_GOOD; 432 return INSN_GOOD;
432 } 433 }
diff --git a/arch/arm/kernel/probes.h b/arch/arm/kernel/probes.h
index 17f656011aa3..5554f161bdac 100644
--- a/arch/arm/kernel/probes.h
+++ b/arch/arm/kernel/probes.h
@@ -133,7 +133,8 @@ void __kprobes kprobe_simulate_nop(struct kprobe *p, struct pt_regs *regs);
133void __kprobes kprobe_emulate_none(struct kprobe *p, struct pt_regs *regs); 133void __kprobes kprobe_emulate_none(struct kprobe *p, struct pt_regs *regs);
134 134
135enum kprobe_insn __kprobes 135enum kprobe_insn __kprobes
136kprobe_decode_ldmstm(kprobe_opcode_t insn, struct arch_specific_insn *asi); 136kprobe_decode_ldmstm(kprobe_opcode_t insn, struct arch_specific_insn *asi,
137 const struct decode_header *h);
137 138
138/* 139/*
139 * Test if load/store instructions writeback the address register. 140 * Test if load/store instructions writeback the address register.
@@ -160,7 +161,7 @@ kprobe_decode_ldmstm(kprobe_opcode_t insn, struct arch_specific_insn *asi);
160 * {.bits = _type}, 161 * {.bits = _type},
161 * {.bits = _mask}, 162 * {.bits = _mask},
162 * {.bits = _value}, 163 * {.bits = _value},
163 * {.handler = _handler}, 164 * {.action = _handler},
164 * 165 *
165 * Initialising a specified member of the union means that the compiler 166 * Initialising a specified member of the union means that the compiler
166 * will produce a warning if the argument is of an incorrect type. 167 * will produce a warning if the argument is of an incorrect type.
@@ -173,19 +174,23 @@ kprobe_decode_ldmstm(kprobe_opcode_t insn, struct arch_specific_insn *asi);
173 * Instruction decoding jumps to parsing the new sub-table 'table'. 174 * Instruction decoding jumps to parsing the new sub-table 'table'.
174 * 175 *
175 * DECODE_CUSTOM(mask, value, decoder) 176 * DECODE_CUSTOM(mask, value, decoder)
176 * The custom function 'decoder' is called to the complete decoding 177 * The value of 'decoder' is used as an index into the array of
177 * of an instruction. 178 * action functions, and the retrieved decoder function is invoked
179 * to complete decoding of the instruction.
178 * 180 *
179 * DECODE_SIMULATE(mask, value, handler) 181 * DECODE_SIMULATE(mask, value, handler)
180 * Set the probes instruction handler to 'handler', this will be used 182 * The probes instruction handler is set to the value found by
181 * to simulate the instruction when the probe is hit. Decoding returns 183 * indexing into the action array using the value of 'handler'. This
182 * with INSN_GOOD_NO_SLOT. 184 * will be used to simulate the instruction when the probe is hit.
185 * Decoding returns with INSN_GOOD_NO_SLOT.
183 * 186 *
184 * DECODE_EMULATE(mask, value, handler) 187 * DECODE_EMULATE(mask, value, handler)
185 * Set the probes instruction handler to 'handler', this will be used 188 * The probes instruction handler is set to the value found by
186 * to emulate the instruction when the probe is hit. The modified 189 * indexing into the action array using the value of 'handler'. This
187 * instruction (see below) is placed in the probes instruction slot so it 190 * will be used to emulate the instruction when the probe is hit. The
188 * may be called by the emulation code. Decoding returns with INSN_GOOD. 191 * modified instruction (see below) is placed in the probes instruction
192 * slot so it may be called by the emulation code. Decoding returns
193 * with INSN_GOOD.
189 * 194 *
190 * DECODE_REJECT(mask, value) 195 * DECODE_REJECT(mask, value)
191 * Instruction decoding fails with INSN_REJECTED 196 * Instruction decoding fails with INSN_REJECTED
@@ -238,7 +243,7 @@ kprobe_decode_ldmstm(kprobe_opcode_t insn, struct arch_specific_insn *asi);
238 * Here is a real example which matches ARM instructions of the form 243 * Here is a real example which matches ARM instructions of the form
239 * "AND <Rd>,<Rn>,<Rm>,<shift> <Rs>" 244 * "AND <Rd>,<Rn>,<Rm>,<shift> <Rs>"
240 * 245 *
241 * DECODE_EMULATEX (0x0e000090, 0x00000010, emulate_rd12rn16rm0rs8_rwflags, 246 * DECODE_EMULATEX (0x0e000090, 0x00000010, PROBES_DATA_PROCESSING_REG,
242 * REGS(ANY, ANY, NOPC, 0, ANY)), 247 * REGS(ANY, ANY, NOPC, 0, ANY)),
243 * ^ ^ ^ ^ 248 * ^ ^ ^ ^
244 * Rn Rd Rs Rm 249 * Rn Rd Rs Rm
@@ -249,7 +254,8 @@ kprobe_decode_ldmstm(kprobe_opcode_t insn, struct arch_specific_insn *asi);
249 * Decoding the instruction "AND R4, R5, R6, ASL R7" will be accepted and the 254 * Decoding the instruction "AND R4, R5, R6, ASL R7" will be accepted and the
250 * instruction will be modified to "AND R0, R2, R3, ASL R1" and then placed into 255 * instruction will be modified to "AND R0, R2, R3, ASL R1" and then placed into
251 * the kprobes instruction slot. This can then be called later by the handler 256 * the kprobes instruction slot. This can then be called later by the handler
252 * function emulate_rd12rn16rm0rs8_rwflags in order to simulate the instruction. 257 * function emulate_rd12rn16rm0rs8_rwflags (a pointer to which is retrieved from
258 * the indicated slot in the action array), in order to simulate the instruction.
253 */ 259 */
254 260
255enum decode_type { 261enum decode_type {
@@ -298,10 +304,17 @@ enum decode_reg_type {
298union decode_item { 304union decode_item {
299 u32 bits; 305 u32 bits;
300 const union decode_item *table; 306 const union decode_item *table;
301 kprobe_insn_handler_t *handler; 307 int action;
302 kprobe_decode_insn_t *decoder;
303}; 308};
304 309
310typedef enum kprobe_insn (probes_custom_decode_t)(kprobe_opcode_t,
311 struct arch_specific_insn *,
312 const struct decode_header *);
313
314union decode_action {
315 kprobe_insn_handler_t *handler;
316 probes_custom_decode_t *decoder;
317};
305 318
306#define DECODE_END \ 319#define DECODE_END \
307 {.bits = DECODE_TYPE_END} 320 {.bits = DECODE_TYPE_END}
@@ -336,7 +349,7 @@ struct decode_custom {
336 349
337#define DECODE_CUSTOM(_mask, _value, _decoder) \ 350#define DECODE_CUSTOM(_mask, _value, _decoder) \
338 DECODE_HEADER(DECODE_TYPE_CUSTOM, _mask, _value, 0), \ 351 DECODE_HEADER(DECODE_TYPE_CUSTOM, _mask, _value, 0), \
339 {.decoder = (_decoder)} 352 {.action = (_decoder)}
340 353
341 354
342struct decode_simulate { 355struct decode_simulate {
@@ -346,7 +359,7 @@ struct decode_simulate {
346 359
347#define DECODE_SIMULATEX(_mask, _value, _handler, _regs) \ 360#define DECODE_SIMULATEX(_mask, _value, _handler, _regs) \
348 DECODE_HEADER(DECODE_TYPE_SIMULATE, _mask, _value, _regs), \ 361 DECODE_HEADER(DECODE_TYPE_SIMULATE, _mask, _value, _regs), \
349 {.handler = (_handler)} 362 {.action = (_handler)}
350 363
351#define DECODE_SIMULATE(_mask, _value, _handler) \ 364#define DECODE_SIMULATE(_mask, _value, _handler) \
352 DECODE_SIMULATEX(_mask, _value, _handler, 0) 365 DECODE_SIMULATEX(_mask, _value, _handler, 0)
@@ -359,7 +372,7 @@ struct decode_emulate {
359 372
360#define DECODE_EMULATEX(_mask, _value, _handler, _regs) \ 373#define DECODE_EMULATEX(_mask, _value, _handler, _regs) \
361 DECODE_HEADER(DECODE_TYPE_EMULATE, _mask, _value, _regs), \ 374 DECODE_HEADER(DECODE_TYPE_EMULATE, _mask, _value, _regs), \
362 {.handler = (_handler)} 375 {.action = (_handler)}
363 376
364#define DECODE_EMULATE(_mask, _value, _handler) \ 377#define DECODE_EMULATE(_mask, _value, _handler) \
365 DECODE_EMULATEX(_mask, _value, _handler, 0) 378 DECODE_EMULATEX(_mask, _value, _handler, 0)
@@ -384,14 +397,18 @@ struct decode_reject {
384#ifdef CONFIG_THUMB2_KERNEL 397#ifdef CONFIG_THUMB2_KERNEL
385extern const union decode_item kprobe_decode_thumb16_table[]; 398extern const union decode_item kprobe_decode_thumb16_table[];
386extern const union decode_item kprobe_decode_thumb32_table[]; 399extern const union decode_item kprobe_decode_thumb32_table[];
400extern const union decode_action kprobes_t32_actions[];
401extern const union decode_action kprobes_t16_actions[];
387#else 402#else
388extern const union decode_item kprobe_decode_arm_table[]; 403extern const union decode_item kprobe_decode_arm_table[];
404extern const union decode_action kprobes_arm_actions[];
389#endif 405#endif
390 406
391extern kprobe_check_cc * const kprobe_condition_checks[16]; 407extern kprobe_check_cc * const kprobe_condition_checks[16];
392 408
393 409
394int kprobe_decode_insn(kprobe_opcode_t insn, struct arch_specific_insn *asi, 410int kprobe_decode_insn(kprobe_opcode_t insn, struct arch_specific_insn *asi,
395 const union decode_item *table, bool thumb16); 411 const union decode_item *table, bool thumb16,
412 const union decode_action *actions);
396 413
397#endif 414#endif