aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/kernel/kprobes-thumb.c
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2014-03-19 16:15:46 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2014-03-19 16:15:46 -0400
commit566b60c04ab230b8cc3845f964306f99504b18df (patch)
tree1897a526488c3496f4ffe5eebb39a1dd41ab731d /arch/arm/kernel/kprobes-thumb.c
parent3ba4cea21901d90d703b52e4a806fbafa86037a6 (diff)
parentc7edc9e326d53ca5ef9bed82de0740c6b107d55b (diff)
Merge branch 'uprobes-v7' of git://git.linaro.org/people/dave.long/linux into devel-stable
This patch series adds basic uprobes support to ARM. It is based on patches developed earlier by Rabin Vincent. That approach of adding hooks into the kprobes instruction parsing code was not well received. This approach separates the ARM instruction parsing code in kprobes out into a separate set of functions which can be used by both kprobes and uprobes. Both kprobes and uprobes then provide their own semantic action tables to process the results of the parsing.
Diffstat (limited to 'arch/arm/kernel/kprobes-thumb.c')
-rw-r--r--arch/arm/kernel/kprobes-thumb.c1145
1 files changed, 169 insertions, 976 deletions
diff --git a/arch/arm/kernel/kprobes-thumb.c b/arch/arm/kernel/kprobes-thumb.c
index 6123daf397a7..6619188619ae 100644
--- a/arch/arm/kernel/kprobes-thumb.c
+++ b/arch/arm/kernel/kprobes-thumb.c
@@ -8,41 +8,25 @@
8 * published by the Free Software Foundation. 8 * published by the Free Software Foundation.
9 */ 9 */
10 10
11#include <linux/types.h>
11#include <linux/kernel.h> 12#include <linux/kernel.h>
13#include <linux/ptrace.h>
12#include <linux/kprobes.h> 14#include <linux/kprobes.h>
13#include <linux/module.h>
14 15
15#include "kprobes.h" 16#include "kprobes.h"
17#include "probes-thumb.h"
16 18
19/* These emulation encodings are functionally equivalent... */
20#define t32_emulate_rd8rn16rm0ra12_noflags \
21 t32_emulate_rdlo12rdhi8rn16rm0_noflags
17 22
18/* 23/* t32 thumb actions */
19 * True if current instruction is in an IT block.
20 */
21#define in_it_block(cpsr) ((cpsr & 0x06000c00) != 0x00000000)
22
23/*
24 * Return the condition code to check for the currently executing instruction.
25 * This is in ITSTATE<7:4> which is in CPSR<15:12> but is only valid if
26 * in_it_block returns true.
27 */
28#define current_cond(cpsr) ((cpsr >> 12) & 0xf)
29
30/*
31 * Return the PC value for a probe in thumb code.
32 * This is the address of the probed instruction plus 4.
33 * We subtract one because the address will have bit zero set to indicate
34 * a pointer to thumb code.
35 */
36static inline unsigned long __kprobes thumb_probe_pc(struct kprobe *p)
37{
38 return (unsigned long)p->addr - 1 + 4;
39}
40 24
41static void __kprobes 25static void __kprobes
42t32_simulate_table_branch(struct kprobe *p, struct pt_regs *regs) 26t32_simulate_table_branch(probes_opcode_t insn,
27 struct arch_probes_insn *asi, struct pt_regs *regs)
43{ 28{
44 kprobe_opcode_t insn = p->opcode; 29 unsigned long pc = regs->ARM_pc;
45 unsigned long pc = thumb_probe_pc(p);
46 int rn = (insn >> 16) & 0xf; 30 int rn = (insn >> 16) & 0xf;
47 int rm = insn & 0xf; 31 int rm = insn & 0xf;
48 32
@@ -59,19 +43,19 @@ t32_simulate_table_branch(struct kprobe *p, struct pt_regs *regs)
59} 43}
60 44
61static void __kprobes 45static void __kprobes
62t32_simulate_mrs(struct kprobe *p, struct pt_regs *regs) 46t32_simulate_mrs(probes_opcode_t insn,
47 struct arch_probes_insn *asi, struct pt_regs *regs)
63{ 48{
64 kprobe_opcode_t insn = p->opcode;
65 int rd = (insn >> 8) & 0xf; 49 int rd = (insn >> 8) & 0xf;
66 unsigned long mask = 0xf8ff03df; /* Mask out execution state */ 50 unsigned long mask = 0xf8ff03df; /* Mask out execution state */
67 regs->uregs[rd] = regs->ARM_cpsr & mask; 51 regs->uregs[rd] = regs->ARM_cpsr & mask;
68} 52}
69 53
70static void __kprobes 54static void __kprobes
71t32_simulate_cond_branch(struct kprobe *p, struct pt_regs *regs) 55t32_simulate_cond_branch(probes_opcode_t insn,
56 struct arch_probes_insn *asi, struct pt_regs *regs)
72{ 57{
73 kprobe_opcode_t insn = p->opcode; 58 unsigned long pc = regs->ARM_pc;
74 unsigned long pc = thumb_probe_pc(p);
75 59
76 long offset = insn & 0x7ff; /* imm11 */ 60 long offset = insn & 0x7ff; /* imm11 */
77 offset += (insn & 0x003f0000) >> 5; /* imm6 */ 61 offset += (insn & 0x003f0000) >> 5; /* imm6 */
@@ -82,20 +66,21 @@ t32_simulate_cond_branch(struct kprobe *p, struct pt_regs *regs)
82 regs->ARM_pc = pc + (offset * 2); 66 regs->ARM_pc = pc + (offset * 2);
83} 67}
84 68
85static enum kprobe_insn __kprobes 69static enum probes_insn __kprobes
86t32_decode_cond_branch(kprobe_opcode_t insn, struct arch_specific_insn *asi) 70t32_decode_cond_branch(probes_opcode_t insn, struct arch_probes_insn *asi,
71 const struct decode_header *d)
87{ 72{
88 int cc = (insn >> 22) & 0xf; 73 int cc = (insn >> 22) & 0xf;
89 asi->insn_check_cc = kprobe_condition_checks[cc]; 74 asi->insn_check_cc = probes_condition_checks[cc];
90 asi->insn_handler = t32_simulate_cond_branch; 75 asi->insn_handler = t32_simulate_cond_branch;
91 return INSN_GOOD_NO_SLOT; 76 return INSN_GOOD_NO_SLOT;
92} 77}
93 78
94static void __kprobes 79static void __kprobes
95t32_simulate_branch(struct kprobe *p, struct pt_regs *regs) 80t32_simulate_branch(probes_opcode_t insn,
81 struct arch_probes_insn *asi, struct pt_regs *regs)
96{ 82{
97 kprobe_opcode_t insn = p->opcode; 83 unsigned long pc = regs->ARM_pc;
98 unsigned long pc = thumb_probe_pc(p);
99 84
100 long offset = insn & 0x7ff; /* imm11 */ 85 long offset = insn & 0x7ff; /* imm11 */
101 offset += (insn & 0x03ff0000) >> 5; /* imm10 */ 86 offset += (insn & 0x03ff0000) >> 5; /* imm10 */
@@ -108,7 +93,7 @@ t32_simulate_branch(struct kprobe *p, struct pt_regs *regs)
108 93
109 if (insn & (1 << 14)) { 94 if (insn & (1 << 14)) {
110 /* BL or BLX */ 95 /* BL or BLX */
111 regs->ARM_lr = (unsigned long)p->addr + 4; 96 regs->ARM_lr = regs->ARM_pc | 1;
112 if (!(insn & (1 << 12))) { 97 if (!(insn & (1 << 12))) {
113 /* BLX so switch to ARM mode */ 98 /* BLX so switch to ARM mode */
114 regs->ARM_cpsr &= ~PSR_T_BIT; 99 regs->ARM_cpsr &= ~PSR_T_BIT;
@@ -120,10 +105,10 @@ t32_simulate_branch(struct kprobe *p, struct pt_regs *regs)
120} 105}
121 106
122static void __kprobes 107static void __kprobes
123t32_simulate_ldr_literal(struct kprobe *p, struct pt_regs *regs) 108t32_simulate_ldr_literal(probes_opcode_t insn,
109 struct arch_probes_insn *asi, struct pt_regs *regs)
124{ 110{
125 kprobe_opcode_t insn = p->opcode; 111 unsigned long addr = regs->ARM_pc & ~3;
126 unsigned long addr = thumb_probe_pc(p) & ~3;
127 int rt = (insn >> 12) & 0xf; 112 int rt = (insn >> 12) & 0xf;
128 unsigned long rtv; 113 unsigned long rtv;
129 114
@@ -157,10 +142,11 @@ t32_simulate_ldr_literal(struct kprobe *p, struct pt_regs *regs)
157 regs->uregs[rt] = rtv; 142 regs->uregs[rt] = rtv;
158} 143}
159 144
160static enum kprobe_insn __kprobes 145static enum probes_insn __kprobes
161t32_decode_ldmstm(kprobe_opcode_t insn, struct arch_specific_insn *asi) 146t32_decode_ldmstm(probes_opcode_t insn, struct arch_probes_insn *asi,
147 const struct decode_header *d)
162{ 148{
163 enum kprobe_insn ret = kprobe_decode_ldmstm(insn, asi); 149 enum probes_insn ret = kprobe_decode_ldmstm(insn, asi, d);
164 150
165 /* Fixup modified instruction to have halfwords in correct order...*/ 151 /* Fixup modified instruction to have halfwords in correct order...*/
166 insn = asi->insn[0]; 152 insn = asi->insn[0];
@@ -171,10 +157,10 @@ t32_decode_ldmstm(kprobe_opcode_t insn, struct arch_specific_insn *asi)
171} 157}
172 158
173static void __kprobes 159static void __kprobes
174t32_emulate_ldrdstrd(struct kprobe *p, struct pt_regs *regs) 160t32_emulate_ldrdstrd(probes_opcode_t insn,
161 struct arch_probes_insn *asi, struct pt_regs *regs)
175{ 162{
176 kprobe_opcode_t insn = p->opcode; 163 unsigned long pc = regs->ARM_pc & ~3;
177 unsigned long pc = thumb_probe_pc(p) & ~3;
178 int rt1 = (insn >> 12) & 0xf; 164 int rt1 = (insn >> 12) & 0xf;
179 int rt2 = (insn >> 8) & 0xf; 165 int rt2 = (insn >> 8) & 0xf;
180 int rn = (insn >> 16) & 0xf; 166 int rn = (insn >> 16) & 0xf;
@@ -187,7 +173,7 @@ t32_emulate_ldrdstrd(struct kprobe *p, struct pt_regs *regs)
187 __asm__ __volatile__ ( 173 __asm__ __volatile__ (
188 "blx %[fn]" 174 "blx %[fn]"
189 : "=r" (rt1v), "=r" (rt2v), "=r" (rnv) 175 : "=r" (rt1v), "=r" (rt2v), "=r" (rnv)
190 : "0" (rt1v), "1" (rt2v), "2" (rnv), [fn] "r" (p->ainsn.insn_fn) 176 : "0" (rt1v), "1" (rt2v), "2" (rnv), [fn] "r" (asi->insn_fn)
191 : "lr", "memory", "cc" 177 : "lr", "memory", "cc"
192 ); 178 );
193 179
@@ -198,9 +184,9 @@ t32_emulate_ldrdstrd(struct kprobe *p, struct pt_regs *regs)
198} 184}
199 185
200static void __kprobes 186static void __kprobes
201t32_emulate_ldrstr(struct kprobe *p, struct pt_regs *regs) 187t32_emulate_ldrstr(probes_opcode_t insn,
188 struct arch_probes_insn *asi, struct pt_regs *regs)
202{ 189{
203 kprobe_opcode_t insn = p->opcode;
204 int rt = (insn >> 12) & 0xf; 190 int rt = (insn >> 12) & 0xf;
205 int rn = (insn >> 16) & 0xf; 191 int rn = (insn >> 16) & 0xf;
206 int rm = insn & 0xf; 192 int rm = insn & 0xf;
@@ -212,7 +198,7 @@ t32_emulate_ldrstr(struct kprobe *p, struct pt_regs *regs)
212 __asm__ __volatile__ ( 198 __asm__ __volatile__ (
213 "blx %[fn]" 199 "blx %[fn]"
214 : "=r" (rtv), "=r" (rnv) 200 : "=r" (rtv), "=r" (rnv)
215 : "0" (rtv), "1" (rnv), "r" (rmv), [fn] "r" (p->ainsn.insn_fn) 201 : "0" (rtv), "1" (rnv), "r" (rmv), [fn] "r" (asi->insn_fn)
216 : "lr", "memory", "cc" 202 : "lr", "memory", "cc"
217 ); 203 );
218 204
@@ -224,9 +210,9 @@ t32_emulate_ldrstr(struct kprobe *p, struct pt_regs *regs)
224} 210}
225 211
226static void __kprobes 212static void __kprobes
227t32_emulate_rd8rn16rm0_rwflags(struct kprobe *p, struct pt_regs *regs) 213t32_emulate_rd8rn16rm0_rwflags(probes_opcode_t insn,
214 struct arch_probes_insn *asi, struct pt_regs *regs)
228{ 215{
229 kprobe_opcode_t insn = p->opcode;
230 int rd = (insn >> 8) & 0xf; 216 int rd = (insn >> 8) & 0xf;
231 int rn = (insn >> 16) & 0xf; 217 int rn = (insn >> 16) & 0xf;
232 int rm = insn & 0xf; 218 int rm = insn & 0xf;
@@ -242,7 +228,7 @@ t32_emulate_rd8rn16rm0_rwflags(struct kprobe *p, struct pt_regs *regs)
242 "mrs %[cpsr], cpsr \n\t" 228 "mrs %[cpsr], cpsr \n\t"
243 : "=r" (rdv), [cpsr] "=r" (cpsr) 229 : "=r" (rdv), [cpsr] "=r" (cpsr)
244 : "0" (rdv), "r" (rnv), "r" (rmv), 230 : "0" (rdv), "r" (rnv), "r" (rmv),
245 "1" (cpsr), [fn] "r" (p->ainsn.insn_fn) 231 "1" (cpsr), [fn] "r" (asi->insn_fn)
246 : "lr", "memory", "cc" 232 : "lr", "memory", "cc"
247 ); 233 );
248 234
@@ -251,10 +237,10 @@ t32_emulate_rd8rn16rm0_rwflags(struct kprobe *p, struct pt_regs *regs)
251} 237}
252 238
253static void __kprobes 239static void __kprobes
254t32_emulate_rd8pc16_noflags(struct kprobe *p, struct pt_regs *regs) 240t32_emulate_rd8pc16_noflags(probes_opcode_t insn,
241 struct arch_probes_insn *asi, struct pt_regs *regs)
255{ 242{
256 kprobe_opcode_t insn = p->opcode; 243 unsigned long pc = regs->ARM_pc;
257 unsigned long pc = thumb_probe_pc(p);
258 int rd = (insn >> 8) & 0xf; 244 int rd = (insn >> 8) & 0xf;
259 245
260 register unsigned long rdv asm("r1") = regs->uregs[rd]; 246 register unsigned long rdv asm("r1") = regs->uregs[rd];
@@ -263,7 +249,7 @@ t32_emulate_rd8pc16_noflags(struct kprobe *p, struct pt_regs *regs)
263 __asm__ __volatile__ ( 249 __asm__ __volatile__ (
264 "blx %[fn]" 250 "blx %[fn]"
265 : "=r" (rdv) 251 : "=r" (rdv)
266 : "0" (rdv), "r" (rnv), [fn] "r" (p->ainsn.insn_fn) 252 : "0" (rdv), "r" (rnv), [fn] "r" (asi->insn_fn)
267 : "lr", "memory", "cc" 253 : "lr", "memory", "cc"
268 ); 254 );
269 255
@@ -271,9 +257,9 @@ t32_emulate_rd8pc16_noflags(struct kprobe *p, struct pt_regs *regs)
271} 257}
272 258
273static void __kprobes 259static void __kprobes
274t32_emulate_rd8rn16_noflags(struct kprobe *p, struct pt_regs *regs) 260t32_emulate_rd8rn16_noflags(probes_opcode_t insn,
261 struct arch_probes_insn *asi, struct pt_regs *regs)
275{ 262{
276 kprobe_opcode_t insn = p->opcode;
277 int rd = (insn >> 8) & 0xf; 263 int rd = (insn >> 8) & 0xf;
278 int rn = (insn >> 16) & 0xf; 264 int rn = (insn >> 16) & 0xf;
279 265
@@ -283,7 +269,7 @@ t32_emulate_rd8rn16_noflags(struct kprobe *p, struct pt_regs *regs)
283 __asm__ __volatile__ ( 269 __asm__ __volatile__ (
284 "blx %[fn]" 270 "blx %[fn]"
285 : "=r" (rdv) 271 : "=r" (rdv)
286 : "0" (rdv), "r" (rnv), [fn] "r" (p->ainsn.insn_fn) 272 : "0" (rdv), "r" (rnv), [fn] "r" (asi->insn_fn)
287 : "lr", "memory", "cc" 273 : "lr", "memory", "cc"
288 ); 274 );
289 275
@@ -291,9 +277,10 @@ t32_emulate_rd8rn16_noflags(struct kprobe *p, struct pt_regs *regs)
291} 277}
292 278
293static void __kprobes 279static void __kprobes
294t32_emulate_rdlo12rdhi8rn16rm0_noflags(struct kprobe *p, struct pt_regs *regs) 280t32_emulate_rdlo12rdhi8rn16rm0_noflags(probes_opcode_t insn,
281 struct arch_probes_insn *asi,
282 struct pt_regs *regs)
295{ 283{
296 kprobe_opcode_t insn = p->opcode;
297 int rdlo = (insn >> 12) & 0xf; 284 int rdlo = (insn >> 12) & 0xf;
298 int rdhi = (insn >> 8) & 0xf; 285 int rdhi = (insn >> 8) & 0xf;
299 int rn = (insn >> 16) & 0xf; 286 int rn = (insn >> 16) & 0xf;
@@ -308,674 +295,43 @@ t32_emulate_rdlo12rdhi8rn16rm0_noflags(struct kprobe *p, struct pt_regs *regs)
308 "blx %[fn]" 295 "blx %[fn]"
309 : "=r" (rdlov), "=r" (rdhiv) 296 : "=r" (rdlov), "=r" (rdhiv)
310 : "0" (rdlov), "1" (rdhiv), "r" (rnv), "r" (rmv), 297 : "0" (rdlov), "1" (rdhiv), "r" (rnv), "r" (rmv),
311 [fn] "r" (p->ainsn.insn_fn) 298 [fn] "r" (asi->insn_fn)
312 : "lr", "memory", "cc" 299 : "lr", "memory", "cc"
313 ); 300 );
314 301
315 regs->uregs[rdlo] = rdlov; 302 regs->uregs[rdlo] = rdlov;
316 regs->uregs[rdhi] = rdhiv; 303 regs->uregs[rdhi] = rdhiv;
317} 304}
318 305/* t16 thumb actions */
319/* These emulation encodings are functionally equivalent... */
320#define t32_emulate_rd8rn16rm0ra12_noflags \
321 t32_emulate_rdlo12rdhi8rn16rm0_noflags
322
323static const union decode_item t32_table_1110_100x_x0xx[] = {
324 /* Load/store multiple instructions */
325
326 /* Rn is PC 1110 100x x0xx 1111 xxxx xxxx xxxx xxxx */
327 DECODE_REJECT (0xfe4f0000, 0xe80f0000),
328
329 /* SRS 1110 1000 00x0 xxxx xxxx xxxx xxxx xxxx */
330 /* RFE 1110 1000 00x1 xxxx xxxx xxxx xxxx xxxx */
331 DECODE_REJECT (0xffc00000, 0xe8000000),
332 /* SRS 1110 1001 10x0 xxxx xxxx xxxx xxxx xxxx */
333 /* RFE 1110 1001 10x1 xxxx xxxx xxxx xxxx xxxx */
334 DECODE_REJECT (0xffc00000, 0xe9800000),
335
336 /* STM Rn, {...pc} 1110 100x x0x0 xxxx 1xxx xxxx xxxx xxxx */
337 DECODE_REJECT (0xfe508000, 0xe8008000),
338 /* LDM Rn, {...lr,pc} 1110 100x x0x1 xxxx 11xx xxxx xxxx xxxx */
339 DECODE_REJECT (0xfe50c000, 0xe810c000),
340 /* LDM/STM Rn, {...sp} 1110 100x x0xx xxxx xx1x xxxx xxxx xxxx */
341 DECODE_REJECT (0xfe402000, 0xe8002000),
342
343 /* STMIA 1110 1000 10x0 xxxx xxxx xxxx xxxx xxxx */
344 /* LDMIA 1110 1000 10x1 xxxx xxxx xxxx xxxx xxxx */
345 /* STMDB 1110 1001 00x0 xxxx xxxx xxxx xxxx xxxx */
346 /* LDMDB 1110 1001 00x1 xxxx xxxx xxxx xxxx xxxx */
347 DECODE_CUSTOM (0xfe400000, 0xe8000000, t32_decode_ldmstm),
348
349 DECODE_END
350};
351
352static const union decode_item t32_table_1110_100x_x1xx[] = {
353 /* Load/store dual, load/store exclusive, table branch */
354
355 /* STRD (immediate) 1110 1000 x110 xxxx xxxx xxxx xxxx xxxx */
356 /* LDRD (immediate) 1110 1000 x111 xxxx xxxx xxxx xxxx xxxx */
357 DECODE_OR (0xff600000, 0xe8600000),
358 /* STRD (immediate) 1110 1001 x1x0 xxxx xxxx xxxx xxxx xxxx */
359 /* LDRD (immediate) 1110 1001 x1x1 xxxx xxxx xxxx xxxx xxxx */
360 DECODE_EMULATEX (0xff400000, 0xe9400000, t32_emulate_ldrdstrd,
361 REGS(NOPCWB, NOSPPC, NOSPPC, 0, 0)),
362
363 /* TBB 1110 1000 1101 xxxx xxxx xxxx 0000 xxxx */
364 /* TBH 1110 1000 1101 xxxx xxxx xxxx 0001 xxxx */
365 DECODE_SIMULATEX(0xfff000e0, 0xe8d00000, t32_simulate_table_branch,
366 REGS(NOSP, 0, 0, 0, NOSPPC)),
367
368 /* STREX 1110 1000 0100 xxxx xxxx xxxx xxxx xxxx */
369 /* LDREX 1110 1000 0101 xxxx xxxx xxxx xxxx xxxx */
370 /* STREXB 1110 1000 1100 xxxx xxxx xxxx 0100 xxxx */
371 /* STREXH 1110 1000 1100 xxxx xxxx xxxx 0101 xxxx */
372 /* STREXD 1110 1000 1100 xxxx xxxx xxxx 0111 xxxx */
373 /* LDREXB 1110 1000 1101 xxxx xxxx xxxx 0100 xxxx */
374 /* LDREXH 1110 1000 1101 xxxx xxxx xxxx 0101 xxxx */
375 /* LDREXD 1110 1000 1101 xxxx xxxx xxxx 0111 xxxx */
376 /* And unallocated instructions... */
377 DECODE_END
378};
379
380static const union decode_item t32_table_1110_101x[] = {
381 /* Data-processing (shifted register) */
382
383 /* TST 1110 1010 0001 xxxx xxxx 1111 xxxx xxxx */
384 /* TEQ 1110 1010 1001 xxxx xxxx 1111 xxxx xxxx */
385 DECODE_EMULATEX (0xff700f00, 0xea100f00, t32_emulate_rd8rn16rm0_rwflags,
386 REGS(NOSPPC, 0, 0, 0, NOSPPC)),
387
388 /* CMN 1110 1011 0001 xxxx xxxx 1111 xxxx xxxx */
389 DECODE_OR (0xfff00f00, 0xeb100f00),
390 /* CMP 1110 1011 1011 xxxx xxxx 1111 xxxx xxxx */
391 DECODE_EMULATEX (0xfff00f00, 0xebb00f00, t32_emulate_rd8rn16rm0_rwflags,
392 REGS(NOPC, 0, 0, 0, NOSPPC)),
393
394 /* MOV 1110 1010 010x 1111 xxxx xxxx xxxx xxxx */
395 /* MVN 1110 1010 011x 1111 xxxx xxxx xxxx xxxx */
396 DECODE_EMULATEX (0xffcf0000, 0xea4f0000, t32_emulate_rd8rn16rm0_rwflags,
397 REGS(0, 0, NOSPPC, 0, NOSPPC)),
398
399 /* ??? 1110 1010 101x xxxx xxxx xxxx xxxx xxxx */
400 /* ??? 1110 1010 111x xxxx xxxx xxxx xxxx xxxx */
401 DECODE_REJECT (0xffa00000, 0xeaa00000),
402 /* ??? 1110 1011 001x xxxx xxxx xxxx xxxx xxxx */
403 DECODE_REJECT (0xffe00000, 0xeb200000),
404 /* ??? 1110 1011 100x xxxx xxxx xxxx xxxx xxxx */
405 DECODE_REJECT (0xffe00000, 0xeb800000),
406 /* ??? 1110 1011 111x xxxx xxxx xxxx xxxx xxxx */
407 DECODE_REJECT (0xffe00000, 0xebe00000),
408
409 /* ADD/SUB SP, SP, Rm, LSL #0..3 */
410 /* 1110 1011 x0xx 1101 x000 1101 xx00 xxxx */
411 DECODE_EMULATEX (0xff4f7f30, 0xeb0d0d00, t32_emulate_rd8rn16rm0_rwflags,
412 REGS(SP, 0, SP, 0, NOSPPC)),
413
414 /* ADD/SUB SP, SP, Rm, shift */
415 /* 1110 1011 x0xx 1101 xxxx 1101 xxxx xxxx */
416 DECODE_REJECT (0xff4f0f00, 0xeb0d0d00),
417
418 /* ADD/SUB Rd, SP, Rm, shift */
419 /* 1110 1011 x0xx 1101 xxxx xxxx xxxx xxxx */
420 DECODE_EMULATEX (0xff4f0000, 0xeb0d0000, t32_emulate_rd8rn16rm0_rwflags,
421 REGS(SP, 0, NOPC, 0, NOSPPC)),
422
423 /* AND 1110 1010 000x xxxx xxxx xxxx xxxx xxxx */
424 /* BIC 1110 1010 001x xxxx xxxx xxxx xxxx xxxx */
425 /* ORR 1110 1010 010x xxxx xxxx xxxx xxxx xxxx */
426 /* ORN 1110 1010 011x xxxx xxxx xxxx xxxx xxxx */
427 /* EOR 1110 1010 100x xxxx xxxx xxxx xxxx xxxx */
428 /* PKH 1110 1010 110x xxxx xxxx xxxx xxxx xxxx */
429 /* ADD 1110 1011 000x xxxx xxxx xxxx xxxx xxxx */
430 /* ADC 1110 1011 010x xxxx xxxx xxxx xxxx xxxx */
431 /* SBC 1110 1011 011x xxxx xxxx xxxx xxxx xxxx */
432 /* SUB 1110 1011 101x xxxx xxxx xxxx xxxx xxxx */
433 /* RSB 1110 1011 110x xxxx xxxx xxxx xxxx xxxx */
434 DECODE_EMULATEX (0xfe000000, 0xea000000, t32_emulate_rd8rn16rm0_rwflags,
435 REGS(NOSPPC, 0, NOSPPC, 0, NOSPPC)),
436
437 DECODE_END
438};
439
440static const union decode_item t32_table_1111_0x0x___0[] = {
441 /* Data-processing (modified immediate) */
442
443 /* TST 1111 0x00 0001 xxxx 0xxx 1111 xxxx xxxx */
444 /* TEQ 1111 0x00 1001 xxxx 0xxx 1111 xxxx xxxx */
445 DECODE_EMULATEX (0xfb708f00, 0xf0100f00, t32_emulate_rd8rn16rm0_rwflags,
446 REGS(NOSPPC, 0, 0, 0, 0)),
447
448 /* CMN 1111 0x01 0001 xxxx 0xxx 1111 xxxx xxxx */
449 DECODE_OR (0xfbf08f00, 0xf1100f00),
450 /* CMP 1111 0x01 1011 xxxx 0xxx 1111 xxxx xxxx */
451 DECODE_EMULATEX (0xfbf08f00, 0xf1b00f00, t32_emulate_rd8rn16rm0_rwflags,
452 REGS(NOPC, 0, 0, 0, 0)),
453
454 /* MOV 1111 0x00 010x 1111 0xxx xxxx xxxx xxxx */
455 /* MVN 1111 0x00 011x 1111 0xxx xxxx xxxx xxxx */
456 DECODE_EMULATEX (0xfbcf8000, 0xf04f0000, t32_emulate_rd8rn16rm0_rwflags,
457 REGS(0, 0, NOSPPC, 0, 0)),
458
459 /* ??? 1111 0x00 101x xxxx 0xxx xxxx xxxx xxxx */
460 DECODE_REJECT (0xfbe08000, 0xf0a00000),
461 /* ??? 1111 0x00 110x xxxx 0xxx xxxx xxxx xxxx */
462 /* ??? 1111 0x00 111x xxxx 0xxx xxxx xxxx xxxx */
463 DECODE_REJECT (0xfbc08000, 0xf0c00000),
464 /* ??? 1111 0x01 001x xxxx 0xxx xxxx xxxx xxxx */
465 DECODE_REJECT (0xfbe08000, 0xf1200000),
466 /* ??? 1111 0x01 100x xxxx 0xxx xxxx xxxx xxxx */
467 DECODE_REJECT (0xfbe08000, 0xf1800000),
468 /* ??? 1111 0x01 111x xxxx 0xxx xxxx xxxx xxxx */
469 DECODE_REJECT (0xfbe08000, 0xf1e00000),
470
471 /* ADD Rd, SP, #imm 1111 0x01 000x 1101 0xxx xxxx xxxx xxxx */
472 /* SUB Rd, SP, #imm 1111 0x01 101x 1101 0xxx xxxx xxxx xxxx */
473 DECODE_EMULATEX (0xfb4f8000, 0xf10d0000, t32_emulate_rd8rn16rm0_rwflags,
474 REGS(SP, 0, NOPC, 0, 0)),
475
476 /* AND 1111 0x00 000x xxxx 0xxx xxxx xxxx xxxx */
477 /* BIC 1111 0x00 001x xxxx 0xxx xxxx xxxx xxxx */
478 /* ORR 1111 0x00 010x xxxx 0xxx xxxx xxxx xxxx */
479 /* ORN 1111 0x00 011x xxxx 0xxx xxxx xxxx xxxx */
480 /* EOR 1111 0x00 100x xxxx 0xxx xxxx xxxx xxxx */
481 /* ADD 1111 0x01 000x xxxx 0xxx xxxx xxxx xxxx */
482 /* ADC 1111 0x01 010x xxxx 0xxx xxxx xxxx xxxx */
483 /* SBC 1111 0x01 011x xxxx 0xxx xxxx xxxx xxxx */
484 /* SUB 1111 0x01 101x xxxx 0xxx xxxx xxxx xxxx */
485 /* RSB 1111 0x01 110x xxxx 0xxx xxxx xxxx xxxx */
486 DECODE_EMULATEX (0xfa008000, 0xf0000000, t32_emulate_rd8rn16rm0_rwflags,
487 REGS(NOSPPC, 0, NOSPPC, 0, 0)),
488
489 DECODE_END
490};
491
492static const union decode_item t32_table_1111_0x1x___0[] = {
493 /* Data-processing (plain binary immediate) */
494
495 /* ADDW Rd, PC, #imm 1111 0x10 0000 1111 0xxx xxxx xxxx xxxx */
496 DECODE_OR (0xfbff8000, 0xf20f0000),
497 /* SUBW Rd, PC, #imm 1111 0x10 1010 1111 0xxx xxxx xxxx xxxx */
498 DECODE_EMULATEX (0xfbff8000, 0xf2af0000, t32_emulate_rd8pc16_noflags,
499 REGS(PC, 0, NOSPPC, 0, 0)),
500
501 /* ADDW SP, SP, #imm 1111 0x10 0000 1101 0xxx 1101 xxxx xxxx */
502 DECODE_OR (0xfbff8f00, 0xf20d0d00),
503 /* SUBW SP, SP, #imm 1111 0x10 1010 1101 0xxx 1101 xxxx xxxx */
504 DECODE_EMULATEX (0xfbff8f00, 0xf2ad0d00, t32_emulate_rd8rn16_noflags,
505 REGS(SP, 0, SP, 0, 0)),
506
507 /* ADDW 1111 0x10 0000 xxxx 0xxx xxxx xxxx xxxx */
508 DECODE_OR (0xfbf08000, 0xf2000000),
509 /* SUBW 1111 0x10 1010 xxxx 0xxx xxxx xxxx xxxx */
510 DECODE_EMULATEX (0xfbf08000, 0xf2a00000, t32_emulate_rd8rn16_noflags,
511 REGS(NOPCX, 0, NOSPPC, 0, 0)),
512
513 /* MOVW 1111 0x10 0100 xxxx 0xxx xxxx xxxx xxxx */
514 /* MOVT 1111 0x10 1100 xxxx 0xxx xxxx xxxx xxxx */
515 DECODE_EMULATEX (0xfb708000, 0xf2400000, t32_emulate_rd8rn16_noflags,
516 REGS(0, 0, NOSPPC, 0, 0)),
517
518 /* SSAT16 1111 0x11 0010 xxxx 0000 xxxx 00xx xxxx */
519 /* SSAT 1111 0x11 00x0 xxxx 0xxx xxxx xxxx xxxx */
520 /* USAT16 1111 0x11 1010 xxxx 0000 xxxx 00xx xxxx */
521 /* USAT 1111 0x11 10x0 xxxx 0xxx xxxx xxxx xxxx */
522 DECODE_EMULATEX (0xfb508000, 0xf3000000, t32_emulate_rd8rn16rm0_rwflags,
523 REGS(NOSPPC, 0, NOSPPC, 0, 0)),
524
525 /* SFBX 1111 0x11 0100 xxxx 0xxx xxxx xxxx xxxx */
526 /* UFBX 1111 0x11 1100 xxxx 0xxx xxxx xxxx xxxx */
527 DECODE_EMULATEX (0xfb708000, 0xf3400000, t32_emulate_rd8rn16_noflags,
528 REGS(NOSPPC, 0, NOSPPC, 0, 0)),
529
530 /* BFC 1111 0x11 0110 1111 0xxx xxxx xxxx xxxx */
531 DECODE_EMULATEX (0xfbff8000, 0xf36f0000, t32_emulate_rd8rn16_noflags,
532 REGS(0, 0, NOSPPC, 0, 0)),
533
534 /* BFI 1111 0x11 0110 xxxx 0xxx xxxx xxxx xxxx */
535 DECODE_EMULATEX (0xfbf08000, 0xf3600000, t32_emulate_rd8rn16_noflags,
536 REGS(NOSPPCX, 0, NOSPPC, 0, 0)),
537
538 DECODE_END
539};
540
541static const union decode_item t32_table_1111_0xxx___1[] = {
542 /* Branches and miscellaneous control */
543
544 /* YIELD 1111 0011 1010 xxxx 10x0 x000 0000 0001 */
545 DECODE_OR (0xfff0d7ff, 0xf3a08001),
546 /* SEV 1111 0011 1010 xxxx 10x0 x000 0000 0100 */
547 DECODE_EMULATE (0xfff0d7ff, 0xf3a08004, kprobe_emulate_none),
548 /* NOP 1111 0011 1010 xxxx 10x0 x000 0000 0000 */
549 /* WFE 1111 0011 1010 xxxx 10x0 x000 0000 0010 */
550 /* WFI 1111 0011 1010 xxxx 10x0 x000 0000 0011 */
551 DECODE_SIMULATE (0xfff0d7fc, 0xf3a08000, kprobe_simulate_nop),
552
553 /* MRS Rd, CPSR 1111 0011 1110 xxxx 10x0 xxxx xxxx xxxx */
554 DECODE_SIMULATEX(0xfff0d000, 0xf3e08000, t32_simulate_mrs,
555 REGS(0, 0, NOSPPC, 0, 0)),
556
557 /*
558 * Unsupported instructions
559 * 1111 0x11 1xxx xxxx 10x0 xxxx xxxx xxxx
560 *
561 * MSR 1111 0011 100x xxxx 10x0 xxxx xxxx xxxx
562 * DBG hint 1111 0011 1010 xxxx 10x0 x000 1111 xxxx
563 * Unallocated hints 1111 0011 1010 xxxx 10x0 x000 xxxx xxxx
564 * CPS 1111 0011 1010 xxxx 10x0 xxxx xxxx xxxx
565 * CLREX/DSB/DMB/ISB 1111 0011 1011 xxxx 10x0 xxxx xxxx xxxx
566 * BXJ 1111 0011 1100 xxxx 10x0 xxxx xxxx xxxx
567 * SUBS PC,LR,#<imm8> 1111 0011 1101 xxxx 10x0 xxxx xxxx xxxx
568 * MRS Rd, SPSR 1111 0011 1111 xxxx 10x0 xxxx xxxx xxxx
569 * SMC 1111 0111 1111 xxxx 1000 xxxx xxxx xxxx
570 * UNDEFINED 1111 0111 1111 xxxx 1010 xxxx xxxx xxxx
571 * ??? 1111 0111 1xxx xxxx 1010 xxxx xxxx xxxx
572 */
573 DECODE_REJECT (0xfb80d000, 0xf3808000),
574
575 /* Bcc 1111 0xxx xxxx xxxx 10x0 xxxx xxxx xxxx */
576 DECODE_CUSTOM (0xf800d000, 0xf0008000, t32_decode_cond_branch),
577
578 /* BLX 1111 0xxx xxxx xxxx 11x0 xxxx xxxx xxx0 */
579 DECODE_OR (0xf800d001, 0xf000c000),
580 /* B 1111 0xxx xxxx xxxx 10x1 xxxx xxxx xxxx */
581 /* BL 1111 0xxx xxxx xxxx 11x1 xxxx xxxx xxxx */
582 DECODE_SIMULATE (0xf8009000, 0xf0009000, t32_simulate_branch),
583
584 DECODE_END
585};
586
587static const union decode_item t32_table_1111_100x_x0x1__1111[] = {
588 /* Memory hints */
589
590 /* PLD (literal) 1111 1000 x001 1111 1111 xxxx xxxx xxxx */
591 /* PLI (literal) 1111 1001 x001 1111 1111 xxxx xxxx xxxx */
592 DECODE_SIMULATE (0xfe7ff000, 0xf81ff000, kprobe_simulate_nop),
593
594 /* PLD{W} (immediate) 1111 1000 10x1 xxxx 1111 xxxx xxxx xxxx */
595 DECODE_OR (0xffd0f000, 0xf890f000),
596 /* PLD{W} (immediate) 1111 1000 00x1 xxxx 1111 1100 xxxx xxxx */
597 DECODE_OR (0xffd0ff00, 0xf810fc00),
598 /* PLI (immediate) 1111 1001 1001 xxxx 1111 xxxx xxxx xxxx */
599 DECODE_OR (0xfff0f000, 0xf990f000),
600 /* PLI (immediate) 1111 1001 0001 xxxx 1111 1100 xxxx xxxx */
601 DECODE_SIMULATEX(0xfff0ff00, 0xf910fc00, kprobe_simulate_nop,
602 REGS(NOPCX, 0, 0, 0, 0)),
603
604 /* PLD{W} (register) 1111 1000 00x1 xxxx 1111 0000 00xx xxxx */
605 DECODE_OR (0xffd0ffc0, 0xf810f000),
606 /* PLI (register) 1111 1001 0001 xxxx 1111 0000 00xx xxxx */
607 DECODE_SIMULATEX(0xfff0ffc0, 0xf910f000, kprobe_simulate_nop,
608 REGS(NOPCX, 0, 0, 0, NOSPPC)),
609
610 /* Other unallocated instructions... */
611 DECODE_END
612};
613
614static const union decode_item t32_table_1111_100x[] = {
615 /* Store/Load single data item */
616
617 /* ??? 1111 100x x11x xxxx xxxx xxxx xxxx xxxx */
618 DECODE_REJECT (0xfe600000, 0xf8600000),
619
620 /* ??? 1111 1001 0101 xxxx xxxx xxxx xxxx xxxx */
621 DECODE_REJECT (0xfff00000, 0xf9500000),
622
623 /* ??? 1111 100x 0xxx xxxx xxxx 10x0 xxxx xxxx */
624 DECODE_REJECT (0xfe800d00, 0xf8000800),
625
626 /* STRBT 1111 1000 0000 xxxx xxxx 1110 xxxx xxxx */
627 /* STRHT 1111 1000 0010 xxxx xxxx 1110 xxxx xxxx */
628 /* STRT 1111 1000 0100 xxxx xxxx 1110 xxxx xxxx */
629 /* LDRBT 1111 1000 0001 xxxx xxxx 1110 xxxx xxxx */
630 /* LDRSBT 1111 1001 0001 xxxx xxxx 1110 xxxx xxxx */
631 /* LDRHT 1111 1000 0011 xxxx xxxx 1110 xxxx xxxx */
632 /* LDRSHT 1111 1001 0011 xxxx xxxx 1110 xxxx xxxx */
633 /* LDRT 1111 1000 0101 xxxx xxxx 1110 xxxx xxxx */
634 DECODE_REJECT (0xfe800f00, 0xf8000e00),
635
636 /* STR{,B,H} Rn,[PC...] 1111 1000 xxx0 1111 xxxx xxxx xxxx xxxx */
637 DECODE_REJECT (0xff1f0000, 0xf80f0000),
638
639 /* STR{,B,H} PC,[Rn...] 1111 1000 xxx0 xxxx 1111 xxxx xxxx xxxx */
640 DECODE_REJECT (0xff10f000, 0xf800f000),
641
642 /* LDR (literal) 1111 1000 x101 1111 xxxx xxxx xxxx xxxx */
643 DECODE_SIMULATEX(0xff7f0000, 0xf85f0000, t32_simulate_ldr_literal,
644 REGS(PC, ANY, 0, 0, 0)),
645
646 /* STR (immediate) 1111 1000 0100 xxxx xxxx 1xxx xxxx xxxx */
647 /* LDR (immediate) 1111 1000 0101 xxxx xxxx 1xxx xxxx xxxx */
648 DECODE_OR (0xffe00800, 0xf8400800),
649 /* STR (immediate) 1111 1000 1100 xxxx xxxx xxxx xxxx xxxx */
650 /* LDR (immediate) 1111 1000 1101 xxxx xxxx xxxx xxxx xxxx */
651 DECODE_EMULATEX (0xffe00000, 0xf8c00000, t32_emulate_ldrstr,
652 REGS(NOPCX, ANY, 0, 0, 0)),
653
654 /* STR (register) 1111 1000 0100 xxxx xxxx 0000 00xx xxxx */
655 /* LDR (register) 1111 1000 0101 xxxx xxxx 0000 00xx xxxx */
656 DECODE_EMULATEX (0xffe00fc0, 0xf8400000, t32_emulate_ldrstr,
657 REGS(NOPCX, ANY, 0, 0, NOSPPC)),
658
659 /* LDRB (literal) 1111 1000 x001 1111 xxxx xxxx xxxx xxxx */
660 /* LDRSB (literal) 1111 1001 x001 1111 xxxx xxxx xxxx xxxx */
661 /* LDRH (literal) 1111 1000 x011 1111 xxxx xxxx xxxx xxxx */
662 /* LDRSH (literal) 1111 1001 x011 1111 xxxx xxxx xxxx xxxx */
663 DECODE_SIMULATEX(0xfe5f0000, 0xf81f0000, t32_simulate_ldr_literal,
664 REGS(PC, NOSPPCX, 0, 0, 0)),
665
666 /* STRB (immediate) 1111 1000 0000 xxxx xxxx 1xxx xxxx xxxx */
667 /* STRH (immediate) 1111 1000 0010 xxxx xxxx 1xxx xxxx xxxx */
668 /* LDRB (immediate) 1111 1000 0001 xxxx xxxx 1xxx xxxx xxxx */
669 /* LDRSB (immediate) 1111 1001 0001 xxxx xxxx 1xxx xxxx xxxx */
670 /* LDRH (immediate) 1111 1000 0011 xxxx xxxx 1xxx xxxx xxxx */
671 /* LDRSH (immediate) 1111 1001 0011 xxxx xxxx 1xxx xxxx xxxx */
672 DECODE_OR (0xfec00800, 0xf8000800),
673 /* STRB (immediate) 1111 1000 1000 xxxx xxxx xxxx xxxx xxxx */
674 /* STRH (immediate) 1111 1000 1010 xxxx xxxx xxxx xxxx xxxx */
675 /* LDRB (immediate) 1111 1000 1001 xxxx xxxx xxxx xxxx xxxx */
676 /* LDRSB (immediate) 1111 1001 1001 xxxx xxxx xxxx xxxx xxxx */
677 /* LDRH (immediate) 1111 1000 1011 xxxx xxxx xxxx xxxx xxxx */
678 /* LDRSH (immediate) 1111 1001 1011 xxxx xxxx xxxx xxxx xxxx */
679 DECODE_EMULATEX (0xfec00000, 0xf8800000, t32_emulate_ldrstr,
680 REGS(NOPCX, NOSPPCX, 0, 0, 0)),
681
682 /* STRB (register) 1111 1000 0000 xxxx xxxx 0000 00xx xxxx */
683 /* STRH (register) 1111 1000 0010 xxxx xxxx 0000 00xx xxxx */
684 /* LDRB (register) 1111 1000 0001 xxxx xxxx 0000 00xx xxxx */
685 /* LDRSB (register) 1111 1001 0001 xxxx xxxx 0000 00xx xxxx */
686 /* LDRH (register) 1111 1000 0011 xxxx xxxx 0000 00xx xxxx */
687 /* LDRSH (register) 1111 1001 0011 xxxx xxxx 0000 00xx xxxx */
688 DECODE_EMULATEX (0xfe800fc0, 0xf8000000, t32_emulate_ldrstr,
689 REGS(NOPCX, NOSPPCX, 0, 0, NOSPPC)),
690
691 /* Other unallocated instructions... */
692 DECODE_END
693};
694
695static const union decode_item t32_table_1111_1010___1111[] = {
696 /* Data-processing (register) */
697
698 /* ??? 1111 1010 011x xxxx 1111 xxxx 1xxx xxxx */
699 DECODE_REJECT (0xffe0f080, 0xfa60f080),
700
701 /* SXTH 1111 1010 0000 1111 1111 xxxx 1xxx xxxx */
702 /* UXTH 1111 1010 0001 1111 1111 xxxx 1xxx xxxx */
703 /* SXTB16 1111 1010 0010 1111 1111 xxxx 1xxx xxxx */
704 /* UXTB16 1111 1010 0011 1111 1111 xxxx 1xxx xxxx */
705 /* SXTB 1111 1010 0100 1111 1111 xxxx 1xxx xxxx */
706 /* UXTB 1111 1010 0101 1111 1111 xxxx 1xxx xxxx */
707 DECODE_EMULATEX (0xff8ff080, 0xfa0ff080, t32_emulate_rd8rn16rm0_rwflags,
708 REGS(0, 0, NOSPPC, 0, NOSPPC)),
709
710
711 /* ??? 1111 1010 1xxx xxxx 1111 xxxx 0x11 xxxx */
712 DECODE_REJECT (0xff80f0b0, 0xfa80f030),
713 /* ??? 1111 1010 1x11 xxxx 1111 xxxx 0xxx xxxx */
714 DECODE_REJECT (0xffb0f080, 0xfab0f000),
715
716 /* SADD16 1111 1010 1001 xxxx 1111 xxxx 0000 xxxx */
717 /* SASX 1111 1010 1010 xxxx 1111 xxxx 0000 xxxx */
718 /* SSAX 1111 1010 1110 xxxx 1111 xxxx 0000 xxxx */
719 /* SSUB16 1111 1010 1101 xxxx 1111 xxxx 0000 xxxx */
720 /* SADD8 1111 1010 1000 xxxx 1111 xxxx 0000 xxxx */
721 /* SSUB8 1111 1010 1100 xxxx 1111 xxxx 0000 xxxx */
722
723 /* QADD16 1111 1010 1001 xxxx 1111 xxxx 0001 xxxx */
724 /* QASX 1111 1010 1010 xxxx 1111 xxxx 0001 xxxx */
725 /* QSAX 1111 1010 1110 xxxx 1111 xxxx 0001 xxxx */
726 /* QSUB16 1111 1010 1101 xxxx 1111 xxxx 0001 xxxx */
727 /* QADD8 1111 1010 1000 xxxx 1111 xxxx 0001 xxxx */
728 /* QSUB8 1111 1010 1100 xxxx 1111 xxxx 0001 xxxx */
729
730 /* SHADD16 1111 1010 1001 xxxx 1111 xxxx 0010 xxxx */
731 /* SHASX 1111 1010 1010 xxxx 1111 xxxx 0010 xxxx */
732 /* SHSAX 1111 1010 1110 xxxx 1111 xxxx 0010 xxxx */
733 /* SHSUB16 1111 1010 1101 xxxx 1111 xxxx 0010 xxxx */
734 /* SHADD8 1111 1010 1000 xxxx 1111 xxxx 0010 xxxx */
735 /* SHSUB8 1111 1010 1100 xxxx 1111 xxxx 0010 xxxx */
736
737 /* UADD16 1111 1010 1001 xxxx 1111 xxxx 0100 xxxx */
738 /* UASX 1111 1010 1010 xxxx 1111 xxxx 0100 xxxx */
739 /* USAX 1111 1010 1110 xxxx 1111 xxxx 0100 xxxx */
740 /* USUB16 1111 1010 1101 xxxx 1111 xxxx 0100 xxxx */
741 /* UADD8 1111 1010 1000 xxxx 1111 xxxx 0100 xxxx */
742 /* USUB8 1111 1010 1100 xxxx 1111 xxxx 0100 xxxx */
743
744 /* UQADD16 1111 1010 1001 xxxx 1111 xxxx 0101 xxxx */
745 /* UQASX 1111 1010 1010 xxxx 1111 xxxx 0101 xxxx */
746 /* UQSAX 1111 1010 1110 xxxx 1111 xxxx 0101 xxxx */
747 /* UQSUB16 1111 1010 1101 xxxx 1111 xxxx 0101 xxxx */
748 /* UQADD8 1111 1010 1000 xxxx 1111 xxxx 0101 xxxx */
749 /* UQSUB8 1111 1010 1100 xxxx 1111 xxxx 0101 xxxx */
750
751 /* UHADD16 1111 1010 1001 xxxx 1111 xxxx 0110 xxxx */
752 /* UHASX 1111 1010 1010 xxxx 1111 xxxx 0110 xxxx */
753 /* UHSAX 1111 1010 1110 xxxx 1111 xxxx 0110 xxxx */
754 /* UHSUB16 1111 1010 1101 xxxx 1111 xxxx 0110 xxxx */
755 /* UHADD8 1111 1010 1000 xxxx 1111 xxxx 0110 xxxx */
756 /* UHSUB8 1111 1010 1100 xxxx 1111 xxxx 0110 xxxx */
757 DECODE_OR (0xff80f080, 0xfa80f000),
758
759 /* SXTAH 1111 1010 0000 xxxx 1111 xxxx 1xxx xxxx */
760 /* UXTAH 1111 1010 0001 xxxx 1111 xxxx 1xxx xxxx */
761 /* SXTAB16 1111 1010 0010 xxxx 1111 xxxx 1xxx xxxx */
762 /* UXTAB16 1111 1010 0011 xxxx 1111 xxxx 1xxx xxxx */
763 /* SXTAB 1111 1010 0100 xxxx 1111 xxxx 1xxx xxxx */
764 /* UXTAB 1111 1010 0101 xxxx 1111 xxxx 1xxx xxxx */
765 DECODE_OR (0xff80f080, 0xfa00f080),
766
767 /* QADD 1111 1010 1000 xxxx 1111 xxxx 1000 xxxx */
768 /* QDADD 1111 1010 1000 xxxx 1111 xxxx 1001 xxxx */
769 /* QSUB 1111 1010 1000 xxxx 1111 xxxx 1010 xxxx */
770 /* QDSUB 1111 1010 1000 xxxx 1111 xxxx 1011 xxxx */
771 DECODE_OR (0xfff0f0c0, 0xfa80f080),
772
773 /* SEL 1111 1010 1010 xxxx 1111 xxxx 1000 xxxx */
774 DECODE_OR (0xfff0f0f0, 0xfaa0f080),
775
776 /* LSL 1111 1010 000x xxxx 1111 xxxx 0000 xxxx */
777 /* LSR 1111 1010 001x xxxx 1111 xxxx 0000 xxxx */
778 /* ASR 1111 1010 010x xxxx 1111 xxxx 0000 xxxx */
779 /* ROR 1111 1010 011x xxxx 1111 xxxx 0000 xxxx */
780 DECODE_EMULATEX (0xff80f0f0, 0xfa00f000, t32_emulate_rd8rn16rm0_rwflags,
781 REGS(NOSPPC, 0, NOSPPC, 0, NOSPPC)),
782
783 /* CLZ 1111 1010 1010 xxxx 1111 xxxx 1000 xxxx */
784 DECODE_OR (0xfff0f0f0, 0xfab0f080),
785
786 /* REV 1111 1010 1001 xxxx 1111 xxxx 1000 xxxx */
787 /* REV16 1111 1010 1001 xxxx 1111 xxxx 1001 xxxx */
788 /* RBIT 1111 1010 1001 xxxx 1111 xxxx 1010 xxxx */
789 /* REVSH 1111 1010 1001 xxxx 1111 xxxx 1011 xxxx */
790 DECODE_EMULATEX (0xfff0f0c0, 0xfa90f080, t32_emulate_rd8rn16_noflags,
791 REGS(NOSPPC, 0, NOSPPC, 0, SAMEAS16)),
792
793 /* Other unallocated instructions... */
794 DECODE_END
795};
796
797static const union decode_item t32_table_1111_1011_0[] = {
798 /* Multiply, multiply accumulate, and absolute difference */
799
800 /* ??? 1111 1011 0000 xxxx 1111 xxxx 0001 xxxx */
801 DECODE_REJECT (0xfff0f0f0, 0xfb00f010),
802 /* ??? 1111 1011 0111 xxxx 1111 xxxx 0001 xxxx */
803 DECODE_REJECT (0xfff0f0f0, 0xfb70f010),
804
805 /* SMULxy 1111 1011 0001 xxxx 1111 xxxx 00xx xxxx */
806 DECODE_OR (0xfff0f0c0, 0xfb10f000),
807 /* MUL 1111 1011 0000 xxxx 1111 xxxx 0000 xxxx */
808 /* SMUAD{X} 1111 1011 0010 xxxx 1111 xxxx 000x xxxx */
809 /* SMULWy 1111 1011 0011 xxxx 1111 xxxx 000x xxxx */
810 /* SMUSD{X} 1111 1011 0100 xxxx 1111 xxxx 000x xxxx */
811 /* SMMUL{R} 1111 1011 0101 xxxx 1111 xxxx 000x xxxx */
812 /* USAD8 1111 1011 0111 xxxx 1111 xxxx 0000 xxxx */
813 DECODE_EMULATEX (0xff80f0e0, 0xfb00f000, t32_emulate_rd8rn16rm0_rwflags,
814 REGS(NOSPPC, 0, NOSPPC, 0, NOSPPC)),
815
816 /* ??? 1111 1011 0111 xxxx xxxx xxxx 0001 xxxx */
817 DECODE_REJECT (0xfff000f0, 0xfb700010),
818
819 /* SMLAxy 1111 1011 0001 xxxx xxxx xxxx 00xx xxxx */
820 DECODE_OR (0xfff000c0, 0xfb100000),
821 /* MLA 1111 1011 0000 xxxx xxxx xxxx 0000 xxxx */
822 /* MLS 1111 1011 0000 xxxx xxxx xxxx 0001 xxxx */
823 /* SMLAD{X} 1111 1011 0010 xxxx xxxx xxxx 000x xxxx */
824 /* SMLAWy 1111 1011 0011 xxxx xxxx xxxx 000x xxxx */
825 /* SMLSD{X} 1111 1011 0100 xxxx xxxx xxxx 000x xxxx */
826 /* SMMLA{R} 1111 1011 0101 xxxx xxxx xxxx 000x xxxx */
827 /* SMMLS{R} 1111 1011 0110 xxxx xxxx xxxx 000x xxxx */
828 /* USADA8 1111 1011 0111 xxxx xxxx xxxx 0000 xxxx */
829 DECODE_EMULATEX (0xff8000c0, 0xfb000000, t32_emulate_rd8rn16rm0ra12_noflags,
830 REGS(NOSPPC, NOSPPCX, NOSPPC, 0, NOSPPC)),
831
832 /* Other unallocated instructions... */
833 DECODE_END
834};
835
836static const union decode_item t32_table_1111_1011_1[] = {
837 /* Long multiply, long multiply accumulate, and divide */
838
839 /* UMAAL 1111 1011 1110 xxxx xxxx xxxx 0110 xxxx */
840 DECODE_OR (0xfff000f0, 0xfbe00060),
841 /* SMLALxy 1111 1011 1100 xxxx xxxx xxxx 10xx xxxx */
842 DECODE_OR (0xfff000c0, 0xfbc00080),
843 /* SMLALD{X} 1111 1011 1100 xxxx xxxx xxxx 110x xxxx */
844 /* SMLSLD{X} 1111 1011 1101 xxxx xxxx xxxx 110x xxxx */
845 DECODE_OR (0xffe000e0, 0xfbc000c0),
846 /* SMULL 1111 1011 1000 xxxx xxxx xxxx 0000 xxxx */
847 /* UMULL 1111 1011 1010 xxxx xxxx xxxx 0000 xxxx */
848 /* SMLAL 1111 1011 1100 xxxx xxxx xxxx 0000 xxxx */
849 /* UMLAL 1111 1011 1110 xxxx xxxx xxxx 0000 xxxx */
850 DECODE_EMULATEX (0xff9000f0, 0xfb800000, t32_emulate_rdlo12rdhi8rn16rm0_noflags,
851 REGS(NOSPPC, NOSPPC, NOSPPC, 0, NOSPPC)),
852
853 /* SDIV 1111 1011 1001 xxxx xxxx xxxx 1111 xxxx */
854 /* UDIV 1111 1011 1011 xxxx xxxx xxxx 1111 xxxx */
855 /* Other unallocated instructions... */
856 DECODE_END
857};
858
859const union decode_item kprobe_decode_thumb32_table[] = {
860
861 /*
862 * Load/store multiple instructions
863 * 1110 100x x0xx xxxx xxxx xxxx xxxx xxxx
864 */
865 DECODE_TABLE (0xfe400000, 0xe8000000, t32_table_1110_100x_x0xx),
866
867 /*
868 * Load/store dual, load/store exclusive, table branch
869 * 1110 100x x1xx xxxx xxxx xxxx xxxx xxxx
870 */
871 DECODE_TABLE (0xfe400000, 0xe8400000, t32_table_1110_100x_x1xx),
872
873 /*
874 * Data-processing (shifted register)
875 * 1110 101x xxxx xxxx xxxx xxxx xxxx xxxx
876 */
877 DECODE_TABLE (0xfe000000, 0xea000000, t32_table_1110_101x),
878
879 /*
880 * Coprocessor instructions
881 * 1110 11xx xxxx xxxx xxxx xxxx xxxx xxxx
882 */
883 DECODE_REJECT (0xfc000000, 0xec000000),
884
885 /*
886 * Data-processing (modified immediate)
887 * 1111 0x0x xxxx xxxx 0xxx xxxx xxxx xxxx
888 */
889 DECODE_TABLE (0xfa008000, 0xf0000000, t32_table_1111_0x0x___0),
890
891 /*
892 * Data-processing (plain binary immediate)
893 * 1111 0x1x xxxx xxxx 0xxx xxxx xxxx xxxx
894 */
895 DECODE_TABLE (0xfa008000, 0xf2000000, t32_table_1111_0x1x___0),
896
897 /*
898 * Branches and miscellaneous control
899 * 1111 0xxx xxxx xxxx 1xxx xxxx xxxx xxxx
900 */
901 DECODE_TABLE (0xf8008000, 0xf0008000, t32_table_1111_0xxx___1),
902
903 /*
904 * Advanced SIMD element or structure load/store instructions
905 * 1111 1001 xxx0 xxxx xxxx xxxx xxxx xxxx
906 */
907 DECODE_REJECT (0xff100000, 0xf9000000),
908
909 /*
910 * Memory hints
911 * 1111 100x x0x1 xxxx 1111 xxxx xxxx xxxx
912 */
913 DECODE_TABLE (0xfe50f000, 0xf810f000, t32_table_1111_100x_x0x1__1111),
914
915 /*
916 * Store single data item
917 * 1111 1000 xxx0 xxxx xxxx xxxx xxxx xxxx
918 * Load single data items
919 * 1111 100x xxx1 xxxx xxxx xxxx xxxx xxxx
920 */
921 DECODE_TABLE (0xfe000000, 0xf8000000, t32_table_1111_100x),
922
923 /*
924 * Data-processing (register)
925 * 1111 1010 xxxx xxxx 1111 xxxx xxxx xxxx
926 */
927 DECODE_TABLE (0xff00f000, 0xfa00f000, t32_table_1111_1010___1111),
928
929 /*
930 * Multiply, multiply accumulate, and absolute difference
931 * 1111 1011 0xxx xxxx xxxx xxxx xxxx xxxx
932 */
933 DECODE_TABLE (0xff800000, 0xfb000000, t32_table_1111_1011_0),
934
935 /*
936 * Long multiply, long multiply accumulate, and divide
937 * 1111 1011 1xxx xxxx xxxx xxxx xxxx xxxx
938 */
939 DECODE_TABLE (0xff800000, 0xfb800000, t32_table_1111_1011_1),
940
941 /*
942 * Coprocessor instructions
943 * 1111 11xx xxxx xxxx xxxx xxxx xxxx xxxx
944 */
945 DECODE_END
946};
947#ifdef CONFIG_ARM_KPROBES_TEST_MODULE
948EXPORT_SYMBOL_GPL(kprobe_decode_thumb32_table);
949#endif
950 306
951static void __kprobes 307static void __kprobes
952t16_simulate_bxblx(struct kprobe *p, struct pt_regs *regs) 308t16_simulate_bxblx(probes_opcode_t insn,
309 struct arch_probes_insn *asi, struct pt_regs *regs)
953{ 310{
954 kprobe_opcode_t insn = p->opcode; 311 unsigned long pc = regs->ARM_pc + 2;
955 unsigned long pc = thumb_probe_pc(p);
956 int rm = (insn >> 3) & 0xf; 312 int rm = (insn >> 3) & 0xf;
957 unsigned long rmv = (rm == 15) ? pc : regs->uregs[rm]; 313 unsigned long rmv = (rm == 15) ? pc : regs->uregs[rm];
958 314
959 if (insn & (1 << 7)) /* BLX ? */ 315 if (insn & (1 << 7)) /* BLX ? */
960 regs->ARM_lr = (unsigned long)p->addr + 2; 316 regs->ARM_lr = regs->ARM_pc | 1;
961 317
962 bx_write_pc(rmv, regs); 318 bx_write_pc(rmv, regs);
963} 319}
964 320
965static void __kprobes 321static void __kprobes
966t16_simulate_ldr_literal(struct kprobe *p, struct pt_regs *regs) 322t16_simulate_ldr_literal(probes_opcode_t insn,
323 struct arch_probes_insn *asi, struct pt_regs *regs)
967{ 324{
968 kprobe_opcode_t insn = p->opcode; 325 unsigned long *base = (unsigned long *)((regs->ARM_pc + 2) & ~3);
969 unsigned long* base = (unsigned long *)(thumb_probe_pc(p) & ~3);
970 long index = insn & 0xff; 326 long index = insn & 0xff;
971 int rt = (insn >> 8) & 0x7; 327 int rt = (insn >> 8) & 0x7;
972 regs->uregs[rt] = base[index]; 328 regs->uregs[rt] = base[index];
973} 329}
974 330
975static void __kprobes 331static void __kprobes
976t16_simulate_ldrstr_sp_relative(struct kprobe *p, struct pt_regs *regs) 332t16_simulate_ldrstr_sp_relative(probes_opcode_t insn,
333 struct arch_probes_insn *asi, struct pt_regs *regs)
977{ 334{
978 kprobe_opcode_t insn = p->opcode;
979 unsigned long* base = (unsigned long *)regs->ARM_sp; 335 unsigned long* base = (unsigned long *)regs->ARM_sp;
980 long index = insn & 0xff; 336 long index = insn & 0xff;
981 int rt = (insn >> 8) & 0x7; 337 int rt = (insn >> 8) & 0x7;
@@ -986,20 +342,20 @@ t16_simulate_ldrstr_sp_relative(struct kprobe *p, struct pt_regs *regs)
986} 342}
987 343
988static void __kprobes 344static void __kprobes
989t16_simulate_reladr(struct kprobe *p, struct pt_regs *regs) 345t16_simulate_reladr(probes_opcode_t insn,
346 struct arch_probes_insn *asi, struct pt_regs *regs)
990{ 347{
991 kprobe_opcode_t insn = p->opcode;
992 unsigned long base = (insn & 0x800) ? regs->ARM_sp 348 unsigned long base = (insn & 0x800) ? regs->ARM_sp
993 : (thumb_probe_pc(p) & ~3); 349 : ((regs->ARM_pc + 2) & ~3);
994 long offset = insn & 0xff; 350 long offset = insn & 0xff;
995 int rt = (insn >> 8) & 0x7; 351 int rt = (insn >> 8) & 0x7;
996 regs->uregs[rt] = base + offset * 4; 352 regs->uregs[rt] = base + offset * 4;
997} 353}
998 354
999static void __kprobes 355static void __kprobes
1000t16_simulate_add_sp_imm(struct kprobe *p, struct pt_regs *regs) 356t16_simulate_add_sp_imm(probes_opcode_t insn,
357 struct arch_probes_insn *asi, struct pt_regs *regs)
1001{ 358{
1002 kprobe_opcode_t insn = p->opcode;
1003 long imm = insn & 0x7f; 359 long imm = insn & 0x7f;
1004 if (insn & 0x80) /* SUB */ 360 if (insn & 0x80) /* SUB */
1005 regs->ARM_sp -= imm * 4; 361 regs->ARM_sp -= imm * 4;
@@ -1008,21 +364,22 @@ t16_simulate_add_sp_imm(struct kprobe *p, struct pt_regs *regs)
1008} 364}
1009 365
1010static void __kprobes 366static void __kprobes
1011t16_simulate_cbz(struct kprobe *p, struct pt_regs *regs) 367t16_simulate_cbz(probes_opcode_t insn,
368 struct arch_probes_insn *asi, struct pt_regs *regs)
1012{ 369{
1013 kprobe_opcode_t insn = p->opcode;
1014 int rn = insn & 0x7; 370 int rn = insn & 0x7;
1015 kprobe_opcode_t nonzero = regs->uregs[rn] ? insn : ~insn; 371 probes_opcode_t nonzero = regs->uregs[rn] ? insn : ~insn;
1016 if (nonzero & 0x800) { 372 if (nonzero & 0x800) {
1017 long i = insn & 0x200; 373 long i = insn & 0x200;
1018 long imm5 = insn & 0xf8; 374 long imm5 = insn & 0xf8;
1019 unsigned long pc = thumb_probe_pc(p); 375 unsigned long pc = regs->ARM_pc + 2;
1020 regs->ARM_pc = pc + (i >> 3) + (imm5 >> 2); 376 regs->ARM_pc = pc + (i >> 3) + (imm5 >> 2);
1021 } 377 }
1022} 378}
1023 379
1024static void __kprobes 380static void __kprobes
1025t16_simulate_it(struct kprobe *p, struct pt_regs *regs) 381t16_simulate_it(probes_opcode_t insn,
382 struct arch_probes_insn *asi, struct pt_regs *regs)
1026{ 383{
1027 /* 384 /*
1028 * The 8 IT state bits are split into two parts in CPSR: 385 * The 8 IT state bits are split into two parts in CPSR:
@@ -1030,7 +387,6 @@ t16_simulate_it(struct kprobe *p, struct pt_regs *regs)
1030 * ITSTATE<7:2> are in CPSR<15:10> 387 * ITSTATE<7:2> are in CPSR<15:10>
1031 * The new IT state is in the lower byte of insn. 388 * The new IT state is in the lower byte of insn.
1032 */ 389 */
1033 kprobe_opcode_t insn = p->opcode;
1034 unsigned long cpsr = regs->ARM_cpsr; 390 unsigned long cpsr = regs->ARM_cpsr;
1035 cpsr &= ~PSR_IT_MASK; 391 cpsr &= ~PSR_IT_MASK;
1036 cpsr |= (insn & 0xfc) << 8; 392 cpsr |= (insn & 0xfc) << 8;
@@ -1039,50 +395,54 @@ t16_simulate_it(struct kprobe *p, struct pt_regs *regs)
1039} 395}
1040 396
1041static void __kprobes 397static void __kprobes
1042t16_singlestep_it(struct kprobe *p, struct pt_regs *regs) 398t16_singlestep_it(probes_opcode_t insn,
399 struct arch_probes_insn *asi, struct pt_regs *regs)
1043{ 400{
1044 regs->ARM_pc += 2; 401 regs->ARM_pc += 2;
1045 t16_simulate_it(p, regs); 402 t16_simulate_it(insn, asi, regs);
1046} 403}
1047 404
1048static enum kprobe_insn __kprobes 405static enum probes_insn __kprobes
1049t16_decode_it(kprobe_opcode_t insn, struct arch_specific_insn *asi) 406t16_decode_it(probes_opcode_t insn, struct arch_probes_insn *asi,
407 const struct decode_header *d)
1050{ 408{
1051 asi->insn_singlestep = t16_singlestep_it; 409 asi->insn_singlestep = t16_singlestep_it;
1052 return INSN_GOOD_NO_SLOT; 410 return INSN_GOOD_NO_SLOT;
1053} 411}
1054 412
1055static void __kprobes 413static void __kprobes
1056t16_simulate_cond_branch(struct kprobe *p, struct pt_regs *regs) 414t16_simulate_cond_branch(probes_opcode_t insn,
415 struct arch_probes_insn *asi, struct pt_regs *regs)
1057{ 416{
1058 kprobe_opcode_t insn = p->opcode; 417 unsigned long pc = regs->ARM_pc + 2;
1059 unsigned long pc = thumb_probe_pc(p);
1060 long offset = insn & 0x7f; 418 long offset = insn & 0x7f;
1061 offset -= insn & 0x80; /* Apply sign bit */ 419 offset -= insn & 0x80; /* Apply sign bit */
1062 regs->ARM_pc = pc + (offset * 2); 420 regs->ARM_pc = pc + (offset * 2);
1063} 421}
1064 422
1065static enum kprobe_insn __kprobes 423static enum probes_insn __kprobes
1066t16_decode_cond_branch(kprobe_opcode_t insn, struct arch_specific_insn *asi) 424t16_decode_cond_branch(probes_opcode_t insn, struct arch_probes_insn *asi,
425 const struct decode_header *d)
1067{ 426{
1068 int cc = (insn >> 8) & 0xf; 427 int cc = (insn >> 8) & 0xf;
1069 asi->insn_check_cc = kprobe_condition_checks[cc]; 428 asi->insn_check_cc = probes_condition_checks[cc];
1070 asi->insn_handler = t16_simulate_cond_branch; 429 asi->insn_handler = t16_simulate_cond_branch;
1071 return INSN_GOOD_NO_SLOT; 430 return INSN_GOOD_NO_SLOT;
1072} 431}
1073 432
1074static void __kprobes 433static void __kprobes
1075t16_simulate_branch(struct kprobe *p, struct pt_regs *regs) 434t16_simulate_branch(probes_opcode_t insn,
435 struct arch_probes_insn *asi, struct pt_regs *regs)
1076{ 436{
1077 kprobe_opcode_t insn = p->opcode; 437 unsigned long pc = regs->ARM_pc + 2;
1078 unsigned long pc = thumb_probe_pc(p);
1079 long offset = insn & 0x3ff; 438 long offset = insn & 0x3ff;
1080 offset -= insn & 0x400; /* Apply sign bit */ 439 offset -= insn & 0x400; /* Apply sign bit */
1081 regs->ARM_pc = pc + (offset * 2); 440 regs->ARM_pc = pc + (offset * 2);
1082} 441}
1083 442
1084static unsigned long __kprobes 443static unsigned long __kprobes
1085t16_emulate_loregs(struct kprobe *p, struct pt_regs *regs) 444t16_emulate_loregs(probes_opcode_t insn,
445 struct arch_probes_insn *asi, struct pt_regs *regs)
1086{ 446{
1087 unsigned long oldcpsr = regs->ARM_cpsr; 447 unsigned long oldcpsr = regs->ARM_cpsr;
1088 unsigned long newcpsr; 448 unsigned long newcpsr;
@@ -1095,7 +455,7 @@ t16_emulate_loregs(struct kprobe *p, struct pt_regs *regs)
1095 "mrs %[newcpsr], cpsr \n\t" 455 "mrs %[newcpsr], cpsr \n\t"
1096 : [newcpsr] "=r" (newcpsr) 456 : [newcpsr] "=r" (newcpsr)
1097 : [oldcpsr] "r" (oldcpsr), [regs] "r" (regs), 457 : [oldcpsr] "r" (oldcpsr), [regs] "r" (regs),
1098 [fn] "r" (p->ainsn.insn_fn) 458 [fn] "r" (asi->insn_fn)
1099 : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", 459 : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
1100 "lr", "memory", "cc" 460 "lr", "memory", "cc"
1101 ); 461 );
@@ -1104,24 +464,26 @@ t16_emulate_loregs(struct kprobe *p, struct pt_regs *regs)
1104} 464}
1105 465
1106static void __kprobes 466static void __kprobes
1107t16_emulate_loregs_rwflags(struct kprobe *p, struct pt_regs *regs) 467t16_emulate_loregs_rwflags(probes_opcode_t insn,
468 struct arch_probes_insn *asi, struct pt_regs *regs)
1108{ 469{
1109 regs->ARM_cpsr = t16_emulate_loregs(p, regs); 470 regs->ARM_cpsr = t16_emulate_loregs(insn, asi, regs);
1110} 471}
1111 472
1112static void __kprobes 473static void __kprobes
1113t16_emulate_loregs_noitrwflags(struct kprobe *p, struct pt_regs *regs) 474t16_emulate_loregs_noitrwflags(probes_opcode_t insn,
475 struct arch_probes_insn *asi, struct pt_regs *regs)
1114{ 476{
1115 unsigned long cpsr = t16_emulate_loregs(p, regs); 477 unsigned long cpsr = t16_emulate_loregs(insn, asi, regs);
1116 if (!in_it_block(cpsr)) 478 if (!in_it_block(cpsr))
1117 regs->ARM_cpsr = cpsr; 479 regs->ARM_cpsr = cpsr;
1118} 480}
1119 481
1120static void __kprobes 482static void __kprobes
1121t16_emulate_hiregs(struct kprobe *p, struct pt_regs *regs) 483t16_emulate_hiregs(probes_opcode_t insn,
484 struct arch_probes_insn *asi, struct pt_regs *regs)
1122{ 485{
1123 kprobe_opcode_t insn = p->opcode; 486 unsigned long pc = regs->ARM_pc + 2;
1124 unsigned long pc = thumb_probe_pc(p);
1125 int rdn = (insn & 0x7) | ((insn & 0x80) >> 4); 487 int rdn = (insn & 0x7) | ((insn & 0x80) >> 4);
1126 int rm = (insn >> 3) & 0xf; 488 int rm = (insn >> 3) & 0xf;
1127 489
@@ -1137,7 +499,7 @@ t16_emulate_hiregs(struct kprobe *p, struct pt_regs *regs)
1137 "blx %[fn] \n\t" 499 "blx %[fn] \n\t"
1138 "mrs %[cpsr], cpsr \n\t" 500 "mrs %[cpsr], cpsr \n\t"
1139 : "=r" (rdnv), [cpsr] "=r" (cpsr) 501 : "=r" (rdnv), [cpsr] "=r" (cpsr)
1140 : "0" (rdnv), "r" (rmv), "1" (cpsr), [fn] "r" (p->ainsn.insn_fn) 502 : "0" (rdnv), "r" (rmv), "1" (cpsr), [fn] "r" (asi->insn_fn)
1141 : "lr", "memory", "cc" 503 : "lr", "memory", "cc"
1142 ); 504 );
1143 505
@@ -1148,8 +510,9 @@ t16_emulate_hiregs(struct kprobe *p, struct pt_regs *regs)
1148 regs->ARM_cpsr = (regs->ARM_cpsr & ~APSR_MASK) | (cpsr & APSR_MASK); 510 regs->ARM_cpsr = (regs->ARM_cpsr & ~APSR_MASK) | (cpsr & APSR_MASK);
1149} 511}
1150 512
1151static enum kprobe_insn __kprobes 513static enum probes_insn __kprobes
1152t16_decode_hiregs(kprobe_opcode_t insn, struct arch_specific_insn *asi) 514t16_decode_hiregs(probes_opcode_t insn, struct arch_probes_insn *asi,
515 const struct decode_header *d)
1153{ 516{
1154 insn &= ~0x00ff; 517 insn &= ~0x00ff;
1155 insn |= 0x001; /* Set Rdn = R1 and Rm = R0 */ 518 insn |= 0x001; /* Set Rdn = R1 and Rm = R0 */
@@ -1159,7 +522,8 @@ t16_decode_hiregs(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1159} 522}
1160 523
1161static void __kprobes 524static void __kprobes
1162t16_emulate_push(struct kprobe *p, struct pt_regs *regs) 525t16_emulate_push(probes_opcode_t insn,
526 struct arch_probes_insn *asi, struct pt_regs *regs)
1163{ 527{
1164 __asm__ __volatile__ ( 528 __asm__ __volatile__ (
1165 "ldr r9, [%[regs], #13*4] \n\t" 529 "ldr r9, [%[regs], #13*4] \n\t"
@@ -1168,14 +532,15 @@ t16_emulate_push(struct kprobe *p, struct pt_regs *regs)
1168 "blx %[fn] \n\t" 532 "blx %[fn] \n\t"
1169 "str r9, [%[regs], #13*4] \n\t" 533 "str r9, [%[regs], #13*4] \n\t"
1170 : 534 :
1171 : [regs] "r" (regs), [fn] "r" (p->ainsn.insn_fn) 535 : [regs] "r" (regs), [fn] "r" (asi->insn_fn)
1172 : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", 536 : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9",
1173 "lr", "memory", "cc" 537 "lr", "memory", "cc"
1174 ); 538 );
1175} 539}
1176 540
1177static enum kprobe_insn __kprobes 541static enum probes_insn __kprobes
1178t16_decode_push(kprobe_opcode_t insn, struct arch_specific_insn *asi) 542t16_decode_push(probes_opcode_t insn, struct arch_probes_insn *asi,
543 const struct decode_header *d)
1179{ 544{
1180 /* 545 /*
1181 * To simulate a PUSH we use a Thumb-2 "STMDB R9!, {registers}" 546 * To simulate a PUSH we use a Thumb-2 "STMDB R9!, {registers}"
@@ -1189,7 +554,8 @@ t16_decode_push(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1189} 554}
1190 555
1191static void __kprobes 556static void __kprobes
1192t16_emulate_pop_nopc(struct kprobe *p, struct pt_regs *regs) 557t16_emulate_pop_nopc(probes_opcode_t insn,
558 struct arch_probes_insn *asi, struct pt_regs *regs)
1193{ 559{
1194 __asm__ __volatile__ ( 560 __asm__ __volatile__ (
1195 "ldr r9, [%[regs], #13*4] \n\t" 561 "ldr r9, [%[regs], #13*4] \n\t"
@@ -1198,14 +564,15 @@ t16_emulate_pop_nopc(struct kprobe *p, struct pt_regs *regs)
1198 "stmia %[regs], {r0-r7} \n\t" 564 "stmia %[regs], {r0-r7} \n\t"
1199 "str r9, [%[regs], #13*4] \n\t" 565 "str r9, [%[regs], #13*4] \n\t"
1200 : 566 :
1201 : [regs] "r" (regs), [fn] "r" (p->ainsn.insn_fn) 567 : [regs] "r" (regs), [fn] "r" (asi->insn_fn)
1202 : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r9", 568 : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r9",
1203 "lr", "memory", "cc" 569 "lr", "memory", "cc"
1204 ); 570 );
1205} 571}
1206 572
1207static void __kprobes 573static void __kprobes
1208t16_emulate_pop_pc(struct kprobe *p, struct pt_regs *regs) 574t16_emulate_pop_pc(probes_opcode_t insn,
575 struct arch_probes_insn *asi, struct pt_regs *regs)
1209{ 576{
1210 register unsigned long pc asm("r8"); 577 register unsigned long pc asm("r8");
1211 578
@@ -1216,7 +583,7 @@ t16_emulate_pop_pc(struct kprobe *p, struct pt_regs *regs)
1216 "stmia %[regs], {r0-r7} \n\t" 583 "stmia %[regs], {r0-r7} \n\t"
1217 "str r9, [%[regs], #13*4] \n\t" 584 "str r9, [%[regs], #13*4] \n\t"
1218 : "=r" (pc) 585 : "=r" (pc)
1219 : [regs] "r" (regs), [fn] "r" (p->ainsn.insn_fn) 586 : [regs] "r" (regs), [fn] "r" (asi->insn_fn)
1220 : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r9", 587 : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r9",
1221 "lr", "memory", "cc" 588 "lr", "memory", "cc"
1222 ); 589 );
@@ -1224,8 +591,9 @@ t16_emulate_pop_pc(struct kprobe *p, struct pt_regs *regs)
1224 bx_write_pc(pc, regs); 591 bx_write_pc(pc, regs);
1225} 592}
1226 593
1227static enum kprobe_insn __kprobes 594static enum probes_insn __kprobes
1228t16_decode_pop(kprobe_opcode_t insn, struct arch_specific_insn *asi) 595t16_decode_pop(probes_opcode_t insn, struct arch_probes_insn *asi,
596 const struct decode_header *d)
1229{ 597{
1230 /* 598 /*
1231 * To simulate a POP we use a Thumb-2 "LDMDB R9!, {registers}" 599 * To simulate a POP we use a Thumb-2 "LDMDB R9!, {registers}"
@@ -1239,231 +607,56 @@ t16_decode_pop(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1239 return INSN_GOOD; 607 return INSN_GOOD;
1240} 608}
1241 609
1242static const union decode_item t16_table_1011[] = { 610const union decode_action kprobes_t16_actions[NUM_PROBES_T16_ACTIONS] = {
1243 /* Miscellaneous 16-bit instructions */ 611 [PROBES_T16_ADD_SP] = {.handler = t16_simulate_add_sp_imm},
1244 612 [PROBES_T16_CBZ] = {.handler = t16_simulate_cbz},
1245 /* ADD (SP plus immediate) 1011 0000 0xxx xxxx */ 613 [PROBES_T16_SIGN_EXTEND] = {.handler = t16_emulate_loregs_rwflags},
1246 /* SUB (SP minus immediate) 1011 0000 1xxx xxxx */ 614 [PROBES_T16_PUSH] = {.decoder = t16_decode_push},
1247 DECODE_SIMULATE (0xff00, 0xb000, t16_simulate_add_sp_imm), 615 [PROBES_T16_POP] = {.decoder = t16_decode_pop},
1248 616 [PROBES_T16_SEV] = {.handler = probes_emulate_none},
1249 /* CBZ 1011 00x1 xxxx xxxx */ 617 [PROBES_T16_WFE] = {.handler = probes_simulate_nop},
1250 /* CBNZ 1011 10x1 xxxx xxxx */ 618 [PROBES_T16_IT] = {.decoder = t16_decode_it},
1251 DECODE_SIMULATE (0xf500, 0xb100, t16_simulate_cbz), 619 [PROBES_T16_CMP] = {.handler = t16_emulate_loregs_rwflags},
1252 620 [PROBES_T16_ADDSUB] = {.handler = t16_emulate_loregs_noitrwflags},
1253 /* SXTH 1011 0010 00xx xxxx */ 621 [PROBES_T16_LOGICAL] = {.handler = t16_emulate_loregs_noitrwflags},
1254 /* SXTB 1011 0010 01xx xxxx */ 622 [PROBES_T16_LDR_LIT] = {.handler = t16_simulate_ldr_literal},
1255 /* UXTH 1011 0010 10xx xxxx */ 623 [PROBES_T16_BLX] = {.handler = t16_simulate_bxblx},
1256 /* UXTB 1011 0010 11xx xxxx */ 624 [PROBES_T16_HIREGOPS] = {.decoder = t16_decode_hiregs},
1257 /* REV 1011 1010 00xx xxxx */ 625 [PROBES_T16_LDRHSTRH] = {.handler = t16_emulate_loregs_rwflags},
1258 /* REV16 1011 1010 01xx xxxx */ 626 [PROBES_T16_LDRSTR] = {.handler = t16_simulate_ldrstr_sp_relative},
1259 /* ??? 1011 1010 10xx xxxx */ 627 [PROBES_T16_ADR] = {.handler = t16_simulate_reladr},
1260 /* REVSH 1011 1010 11xx xxxx */ 628 [PROBES_T16_LDMSTM] = {.handler = t16_emulate_loregs_rwflags},
1261 DECODE_REJECT (0xffc0, 0xba80), 629 [PROBES_T16_BRANCH_COND] = {.decoder = t16_decode_cond_branch},
1262 DECODE_EMULATE (0xf500, 0xb000, t16_emulate_loregs_rwflags), 630 [PROBES_T16_BRANCH] = {.handler = t16_simulate_branch},
1263
1264 /* PUSH 1011 010x xxxx xxxx */
1265 DECODE_CUSTOM (0xfe00, 0xb400, t16_decode_push),
1266 /* POP 1011 110x xxxx xxxx */
1267 DECODE_CUSTOM (0xfe00, 0xbc00, t16_decode_pop),
1268
1269 /*
1270 * If-Then, and hints
1271 * 1011 1111 xxxx xxxx
1272 */
1273
1274 /* YIELD 1011 1111 0001 0000 */
1275 DECODE_OR (0xffff, 0xbf10),
1276 /* SEV 1011 1111 0100 0000 */
1277 DECODE_EMULATE (0xffff, 0xbf40, kprobe_emulate_none),
1278 /* NOP 1011 1111 0000 0000 */
1279 /* WFE 1011 1111 0010 0000 */
1280 /* WFI 1011 1111 0011 0000 */
1281 DECODE_SIMULATE (0xffcf, 0xbf00, kprobe_simulate_nop),
1282 /* Unassigned hints 1011 1111 xxxx 0000 */
1283 DECODE_REJECT (0xff0f, 0xbf00),
1284 /* IT 1011 1111 xxxx xxxx */
1285 DECODE_CUSTOM (0xff00, 0xbf00, t16_decode_it),
1286
1287 /* SETEND 1011 0110 010x xxxx */
1288 /* CPS 1011 0110 011x xxxx */
1289 /* BKPT 1011 1110 xxxx xxxx */
1290 /* And unallocated instructions... */
1291 DECODE_END
1292}; 631};
1293 632
1294const union decode_item kprobe_decode_thumb16_table[] = { 633const union decode_action kprobes_t32_actions[NUM_PROBES_T32_ACTIONS] = {
1295 634 [PROBES_T32_LDMSTM] = {.decoder = t32_decode_ldmstm},
1296 /* 635 [PROBES_T32_LDRDSTRD] = {.handler = t32_emulate_ldrdstrd},
1297 * Shift (immediate), add, subtract, move, and compare 636 [PROBES_T32_TABLE_BRANCH] = {.handler = t32_simulate_table_branch},
1298 * 00xx xxxx xxxx xxxx 637 [PROBES_T32_TST] = {.handler = t32_emulate_rd8rn16rm0_rwflags},
1299 */ 638 [PROBES_T32_MOV] = {.handler = t32_emulate_rd8rn16rm0_rwflags},
1300 639 [PROBES_T32_ADDSUB] = {.handler = t32_emulate_rd8rn16rm0_rwflags},
1301 /* CMP (immediate) 0010 1xxx xxxx xxxx */ 640 [PROBES_T32_LOGICAL] = {.handler = t32_emulate_rd8rn16rm0_rwflags},
1302 DECODE_EMULATE (0xf800, 0x2800, t16_emulate_loregs_rwflags), 641 [PROBES_T32_CMP] = {.handler = t32_emulate_rd8rn16rm0_rwflags},
1303 642 [PROBES_T32_ADDWSUBW_PC] = {.handler = t32_emulate_rd8pc16_noflags,},
1304 /* ADD (register) 0001 100x xxxx xxxx */ 643 [PROBES_T32_ADDWSUBW] = {.handler = t32_emulate_rd8rn16_noflags},
1305 /* SUB (register) 0001 101x xxxx xxxx */ 644 [PROBES_T32_MOVW] = {.handler = t32_emulate_rd8rn16_noflags},
1306 /* LSL (immediate) 0000 0xxx xxxx xxxx */ 645 [PROBES_T32_SAT] = {.handler = t32_emulate_rd8rn16rm0_rwflags},
1307 /* LSR (immediate) 0000 1xxx xxxx xxxx */ 646 [PROBES_T32_BITFIELD] = {.handler = t32_emulate_rd8rn16_noflags},
1308 /* ASR (immediate) 0001 0xxx xxxx xxxx */ 647 [PROBES_T32_SEV] = {.handler = probes_emulate_none},
1309 /* ADD (immediate, Thumb) 0001 110x xxxx xxxx */ 648 [PROBES_T32_WFE] = {.handler = probes_simulate_nop},
1310 /* SUB (immediate, Thumb) 0001 111x xxxx xxxx */ 649 [PROBES_T32_MRS] = {.handler = t32_simulate_mrs},
1311 /* MOV (immediate) 0010 0xxx xxxx xxxx */ 650 [PROBES_T32_BRANCH_COND] = {.decoder = t32_decode_cond_branch},
1312 /* ADD (immediate, Thumb) 0011 0xxx xxxx xxxx */ 651 [PROBES_T32_BRANCH] = {.handler = t32_simulate_branch},
1313 /* SUB (immediate, Thumb) 0011 1xxx xxxx xxxx */ 652 [PROBES_T32_PLDI] = {.handler = probes_simulate_nop},
1314 DECODE_EMULATE (0xc000, 0x0000, t16_emulate_loregs_noitrwflags), 653 [PROBES_T32_LDR_LIT] = {.handler = t32_simulate_ldr_literal},
1315 654 [PROBES_T32_LDRSTR] = {.handler = t32_emulate_ldrstr},
1316 /* 655 [PROBES_T32_SIGN_EXTEND] = {.handler = t32_emulate_rd8rn16rm0_rwflags},
1317 * 16-bit Thumb data-processing instructions 656 [PROBES_T32_MEDIA] = {.handler = t32_emulate_rd8rn16rm0_rwflags},
1318 * 0100 00xx xxxx xxxx 657 [PROBES_T32_REVERSE] = {.handler = t32_emulate_rd8rn16_noflags},
1319 */ 658 [PROBES_T32_MUL_ADD] = {.handler = t32_emulate_rd8rn16rm0_rwflags},
1320 659 [PROBES_T32_MUL_ADD2] = {.handler = t32_emulate_rd8rn16rm0ra12_noflags},
1321 /* TST (register) 0100 0010 00xx xxxx */ 660 [PROBES_T32_MUL_ADD_LONG] = {
1322 DECODE_EMULATE (0xffc0, 0x4200, t16_emulate_loregs_rwflags), 661 .handler = t32_emulate_rdlo12rdhi8rn16rm0_noflags},
1323 /* CMP (register) 0100 0010 10xx xxxx */
1324 /* CMN (register) 0100 0010 11xx xxxx */
1325 DECODE_EMULATE (0xff80, 0x4280, t16_emulate_loregs_rwflags),
1326 /* AND (register) 0100 0000 00xx xxxx */
1327 /* EOR (register) 0100 0000 01xx xxxx */
1328 /* LSL (register) 0100 0000 10xx xxxx */
1329 /* LSR (register) 0100 0000 11xx xxxx */
1330 /* ASR (register) 0100 0001 00xx xxxx */
1331 /* ADC (register) 0100 0001 01xx xxxx */
1332 /* SBC (register) 0100 0001 10xx xxxx */
1333 /* ROR (register) 0100 0001 11xx xxxx */
1334 /* RSB (immediate) 0100 0010 01xx xxxx */
1335 /* ORR (register) 0100 0011 00xx xxxx */
1336 /* MUL 0100 0011 00xx xxxx */
1337 /* BIC (register) 0100 0011 10xx xxxx */
1338 /* MVN (register) 0100 0011 10xx xxxx */
1339 DECODE_EMULATE (0xfc00, 0x4000, t16_emulate_loregs_noitrwflags),
1340
1341 /*
1342 * Special data instructions and branch and exchange
1343 * 0100 01xx xxxx xxxx
1344 */
1345
1346 /* BLX pc 0100 0111 1111 1xxx */
1347 DECODE_REJECT (0xfff8, 0x47f8),
1348
1349 /* BX (register) 0100 0111 0xxx xxxx */
1350 /* BLX (register) 0100 0111 1xxx xxxx */
1351 DECODE_SIMULATE (0xff00, 0x4700, t16_simulate_bxblx),
1352
1353 /* ADD pc, pc 0100 0100 1111 1111 */
1354 DECODE_REJECT (0xffff, 0x44ff),
1355
1356 /* ADD (register) 0100 0100 xxxx xxxx */
1357 /* CMP (register) 0100 0101 xxxx xxxx */
1358 /* MOV (register) 0100 0110 xxxx xxxx */
1359 DECODE_CUSTOM (0xfc00, 0x4400, t16_decode_hiregs),
1360
1361 /*
1362 * Load from Literal Pool
1363 * LDR (literal) 0100 1xxx xxxx xxxx
1364 */
1365 DECODE_SIMULATE (0xf800, 0x4800, t16_simulate_ldr_literal),
1366
1367 /*
1368 * 16-bit Thumb Load/store instructions
1369 * 0101 xxxx xxxx xxxx
1370 * 011x xxxx xxxx xxxx
1371 * 100x xxxx xxxx xxxx
1372 */
1373
1374 /* STR (register) 0101 000x xxxx xxxx */
1375 /* STRH (register) 0101 001x xxxx xxxx */
1376 /* STRB (register) 0101 010x xxxx xxxx */
1377 /* LDRSB (register) 0101 011x xxxx xxxx */
1378 /* LDR (register) 0101 100x xxxx xxxx */
1379 /* LDRH (register) 0101 101x xxxx xxxx */
1380 /* LDRB (register) 0101 110x xxxx xxxx */
1381 /* LDRSH (register) 0101 111x xxxx xxxx */
1382 /* STR (immediate, Thumb) 0110 0xxx xxxx xxxx */
1383 /* LDR (immediate, Thumb) 0110 1xxx xxxx xxxx */
1384 /* STRB (immediate, Thumb) 0111 0xxx xxxx xxxx */
1385 /* LDRB (immediate, Thumb) 0111 1xxx xxxx xxxx */
1386 DECODE_EMULATE (0xc000, 0x4000, t16_emulate_loregs_rwflags),
1387 /* STRH (immediate, Thumb) 1000 0xxx xxxx xxxx */
1388 /* LDRH (immediate, Thumb) 1000 1xxx xxxx xxxx */
1389 DECODE_EMULATE (0xf000, 0x8000, t16_emulate_loregs_rwflags),
1390 /* STR (immediate, Thumb) 1001 0xxx xxxx xxxx */
1391 /* LDR (immediate, Thumb) 1001 1xxx xxxx xxxx */
1392 DECODE_SIMULATE (0xf000, 0x9000, t16_simulate_ldrstr_sp_relative),
1393
1394 /*
1395 * Generate PC-/SP-relative address
1396 * ADR (literal) 1010 0xxx xxxx xxxx
1397 * ADD (SP plus immediate) 1010 1xxx xxxx xxxx
1398 */
1399 DECODE_SIMULATE (0xf000, 0xa000, t16_simulate_reladr),
1400
1401 /*
1402 * Miscellaneous 16-bit instructions
1403 * 1011 xxxx xxxx xxxx
1404 */
1405 DECODE_TABLE (0xf000, 0xb000, t16_table_1011),
1406
1407 /* STM 1100 0xxx xxxx xxxx */
1408 /* LDM 1100 1xxx xxxx xxxx */
1409 DECODE_EMULATE (0xf000, 0xc000, t16_emulate_loregs_rwflags),
1410
1411 /*
1412 * Conditional branch, and Supervisor Call
1413 */
1414
1415 /* Permanently UNDEFINED 1101 1110 xxxx xxxx */
1416 /* SVC 1101 1111 xxxx xxxx */
1417 DECODE_REJECT (0xfe00, 0xde00),
1418
1419 /* Conditional branch 1101 xxxx xxxx xxxx */
1420 DECODE_CUSTOM (0xf000, 0xd000, t16_decode_cond_branch),
1421
1422 /*
1423 * Unconditional branch
1424 * B 1110 0xxx xxxx xxxx
1425 */
1426 DECODE_SIMULATE (0xf800, 0xe000, t16_simulate_branch),
1427
1428 DECODE_END
1429}; 662};
1430#ifdef CONFIG_ARM_KPROBES_TEST_MODULE
1431EXPORT_SYMBOL_GPL(kprobe_decode_thumb16_table);
1432#endif
1433
1434static unsigned long __kprobes thumb_check_cc(unsigned long cpsr)
1435{
1436 if (unlikely(in_it_block(cpsr)))
1437 return kprobe_condition_checks[current_cond(cpsr)](cpsr);
1438 return true;
1439}
1440
1441static void __kprobes thumb16_singlestep(struct kprobe *p, struct pt_regs *regs)
1442{
1443 regs->ARM_pc += 2;
1444 p->ainsn.insn_handler(p, regs);
1445 regs->ARM_cpsr = it_advance(regs->ARM_cpsr);
1446}
1447
1448static void __kprobes thumb32_singlestep(struct kprobe *p, struct pt_regs *regs)
1449{
1450 regs->ARM_pc += 4;
1451 p->ainsn.insn_handler(p, regs);
1452 regs->ARM_cpsr = it_advance(regs->ARM_cpsr);
1453}
1454
1455enum kprobe_insn __kprobes
1456thumb16_kprobe_decode_insn(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1457{
1458 asi->insn_singlestep = thumb16_singlestep;
1459 asi->insn_check_cc = thumb_check_cc;
1460 return kprobe_decode_insn(insn, asi, kprobe_decode_thumb16_table, true);
1461}
1462
1463enum kprobe_insn __kprobes
1464thumb32_kprobe_decode_insn(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1465{
1466 asi->insn_singlestep = thumb32_singlestep;
1467 asi->insn_check_cc = thumb_check_cc;
1468 return kprobe_decode_insn(insn, asi, kprobe_decode_thumb32_table, true);
1469}