aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid A. Long <dave.long@linaro.org>2014-03-05 21:06:29 -0500
committerDavid A. Long <dave.long@linaro.org>2014-03-18 16:39:36 -0400
commit87abef63ead5ac9e2c67f0c07c461eda6be16aeb (patch)
tree6f420f180379f63231dc91ab27696841dcb02528
parentc18377c303787ded44b7decd7dee694db0f205e9 (diff)
ARM: move generic thumb instruction parsing code to new files for use by other feature
Move the thumb version of the kprobes instruction parsing code into more generic files from where it can be used by uprobes and possibly other subsystems. The symbol names will be made more generic in a subsequent part of this patchset. Signed-off-by: David A. Long <dave.long@linaro.org> Acked-by: Jon Medhurst <tixy@linaro.org>
-rw-r--r--arch/arm/kernel/Makefile2
-rw-r--r--arch/arm/kernel/kprobes-thumb.c949
-rw-r--r--arch/arm/kernel/probes-thumb.c878
-rw-r--r--arch/arm/kernel/probes-thumb.h81
4 files changed, 1000 insertions, 910 deletions
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index 4c8b13e64280..bb739f28dd80 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -52,7 +52,7 @@ obj-$(CONFIG_JUMP_LABEL) += jump_label.o insn.o patch.o
52obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o 52obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o
53obj-$(CONFIG_KPROBES) += probes.o kprobes.o kprobes-common.o patch.o 53obj-$(CONFIG_KPROBES) += probes.o kprobes.o kprobes-common.o patch.o
54ifdef CONFIG_THUMB2_KERNEL 54ifdef CONFIG_THUMB2_KERNEL
55obj-$(CONFIG_KPROBES) += kprobes-thumb.o 55obj-$(CONFIG_KPROBES) += kprobes-thumb.o probes-thumb.o
56else 56else
57obj-$(CONFIG_KPROBES) += kprobes-arm.o probes-arm.o 57obj-$(CONFIG_KPROBES) += kprobes-arm.o probes-arm.o
58endif 58endif
diff --git a/arch/arm/kernel/kprobes-thumb.c b/arch/arm/kernel/kprobes-thumb.c
index 6123daf397a7..977f21723a9c 100644
--- a/arch/arm/kernel/kprobes-thumb.c
+++ b/arch/arm/kernel/kprobes-thumb.c
@@ -8,24 +8,13 @@
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"
16 17#include "probes-thumb.h"
17
18/*
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 18
30/* 19/*
31 * Return the PC value for a probe in thumb code. 20 * Return the PC value for a probe in thumb code.
@@ -38,7 +27,9 @@ static inline unsigned long __kprobes thumb_probe_pc(struct kprobe *p)
38 return (unsigned long)p->addr - 1 + 4; 27 return (unsigned long)p->addr - 1 + 4;
39} 28}
40 29
41static void __kprobes 30/* t32 thumb actions */
31
32void __kprobes
42t32_simulate_table_branch(struct kprobe *p, struct pt_regs *regs) 33t32_simulate_table_branch(struct kprobe *p, struct pt_regs *regs)
43{ 34{
44 kprobe_opcode_t insn = p->opcode; 35 kprobe_opcode_t insn = p->opcode;
@@ -58,7 +49,7 @@ t32_simulate_table_branch(struct kprobe *p, struct pt_regs *regs)
58 regs->ARM_pc = pc + 2 * halfwords; 49 regs->ARM_pc = pc + 2 * halfwords;
59} 50}
60 51
61static void __kprobes 52void __kprobes
62t32_simulate_mrs(struct kprobe *p, struct pt_regs *regs) 53t32_simulate_mrs(struct kprobe *p, struct pt_regs *regs)
63{ 54{
64 kprobe_opcode_t insn = p->opcode; 55 kprobe_opcode_t insn = p->opcode;
@@ -67,7 +58,7 @@ t32_simulate_mrs(struct kprobe *p, struct pt_regs *regs)
67 regs->uregs[rd] = regs->ARM_cpsr & mask; 58 regs->uregs[rd] = regs->ARM_cpsr & mask;
68} 59}
69 60
70static void __kprobes 61void __kprobes
71t32_simulate_cond_branch(struct kprobe *p, struct pt_regs *regs) 62t32_simulate_cond_branch(struct kprobe *p, struct pt_regs *regs)
72{ 63{
73 kprobe_opcode_t insn = p->opcode; 64 kprobe_opcode_t insn = p->opcode;
@@ -82,7 +73,7 @@ t32_simulate_cond_branch(struct kprobe *p, struct pt_regs *regs)
82 regs->ARM_pc = pc + (offset * 2); 73 regs->ARM_pc = pc + (offset * 2);
83} 74}
84 75
85static enum kprobe_insn __kprobes 76enum kprobe_insn __kprobes
86t32_decode_cond_branch(kprobe_opcode_t insn, struct arch_specific_insn *asi) 77t32_decode_cond_branch(kprobe_opcode_t insn, struct arch_specific_insn *asi)
87{ 78{
88 int cc = (insn >> 22) & 0xf; 79 int cc = (insn >> 22) & 0xf;
@@ -91,7 +82,7 @@ t32_decode_cond_branch(kprobe_opcode_t insn, struct arch_specific_insn *asi)
91 return INSN_GOOD_NO_SLOT; 82 return INSN_GOOD_NO_SLOT;
92} 83}
93 84
94static void __kprobes 85void __kprobes
95t32_simulate_branch(struct kprobe *p, struct pt_regs *regs) 86t32_simulate_branch(struct kprobe *p, struct pt_regs *regs)
96{ 87{
97 kprobe_opcode_t insn = p->opcode; 88 kprobe_opcode_t insn = p->opcode;
@@ -119,7 +110,7 @@ t32_simulate_branch(struct kprobe *p, struct pt_regs *regs)
119 regs->ARM_pc = pc + (offset * 2); 110 regs->ARM_pc = pc + (offset * 2);
120} 111}
121 112
122static void __kprobes 113void __kprobes
123t32_simulate_ldr_literal(struct kprobe *p, struct pt_regs *regs) 114t32_simulate_ldr_literal(struct kprobe *p, struct pt_regs *regs)
124{ 115{
125 kprobe_opcode_t insn = p->opcode; 116 kprobe_opcode_t insn = p->opcode;
@@ -157,7 +148,7 @@ t32_simulate_ldr_literal(struct kprobe *p, struct pt_regs *regs)
157 regs->uregs[rt] = rtv; 148 regs->uregs[rt] = rtv;
158} 149}
159 150
160static enum kprobe_insn __kprobes 151enum kprobe_insn __kprobes
161t32_decode_ldmstm(kprobe_opcode_t insn, struct arch_specific_insn *asi) 152t32_decode_ldmstm(kprobe_opcode_t insn, struct arch_specific_insn *asi)
162{ 153{
163 enum kprobe_insn ret = kprobe_decode_ldmstm(insn, asi); 154 enum kprobe_insn ret = kprobe_decode_ldmstm(insn, asi);
@@ -170,7 +161,7 @@ t32_decode_ldmstm(kprobe_opcode_t insn, struct arch_specific_insn *asi)
170 return ret; 161 return ret;
171} 162}
172 163
173static void __kprobes 164void __kprobes
174t32_emulate_ldrdstrd(struct kprobe *p, struct pt_regs *regs) 165t32_emulate_ldrdstrd(struct kprobe *p, struct pt_regs *regs)
175{ 166{
176 kprobe_opcode_t insn = p->opcode; 167 kprobe_opcode_t insn = p->opcode;
@@ -197,7 +188,7 @@ t32_emulate_ldrdstrd(struct kprobe *p, struct pt_regs *regs)
197 regs->uregs[rt2] = rt2v; 188 regs->uregs[rt2] = rt2v;
198} 189}
199 190
200static void __kprobes 191void __kprobes
201t32_emulate_ldrstr(struct kprobe *p, struct pt_regs *regs) 192t32_emulate_ldrstr(struct kprobe *p, struct pt_regs *regs)
202{ 193{
203 kprobe_opcode_t insn = p->opcode; 194 kprobe_opcode_t insn = p->opcode;
@@ -223,7 +214,7 @@ t32_emulate_ldrstr(struct kprobe *p, struct pt_regs *regs)
223 regs->uregs[rt] = rtv; 214 regs->uregs[rt] = rtv;
224} 215}
225 216
226static void __kprobes 217void __kprobes
227t32_emulate_rd8rn16rm0_rwflags(struct kprobe *p, struct pt_regs *regs) 218t32_emulate_rd8rn16rm0_rwflags(struct kprobe *p, struct pt_regs *regs)
228{ 219{
229 kprobe_opcode_t insn = p->opcode; 220 kprobe_opcode_t insn = p->opcode;
@@ -250,7 +241,7 @@ t32_emulate_rd8rn16rm0_rwflags(struct kprobe *p, struct pt_regs *regs)
250 regs->ARM_cpsr = (regs->ARM_cpsr & ~APSR_MASK) | (cpsr & APSR_MASK); 241 regs->ARM_cpsr = (regs->ARM_cpsr & ~APSR_MASK) | (cpsr & APSR_MASK);
251} 242}
252 243
253static void __kprobes 244void __kprobes
254t32_emulate_rd8pc16_noflags(struct kprobe *p, struct pt_regs *regs) 245t32_emulate_rd8pc16_noflags(struct kprobe *p, struct pt_regs *regs)
255{ 246{
256 kprobe_opcode_t insn = p->opcode; 247 kprobe_opcode_t insn = p->opcode;
@@ -270,7 +261,7 @@ t32_emulate_rd8pc16_noflags(struct kprobe *p, struct pt_regs *regs)
270 regs->uregs[rd] = rdv; 261 regs->uregs[rd] = rdv;
271} 262}
272 263
273static void __kprobes 264void __kprobes
274t32_emulate_rd8rn16_noflags(struct kprobe *p, struct pt_regs *regs) 265t32_emulate_rd8rn16_noflags(struct kprobe *p, struct pt_regs *regs)
275{ 266{
276 kprobe_opcode_t insn = p->opcode; 267 kprobe_opcode_t insn = p->opcode;
@@ -290,7 +281,7 @@ t32_emulate_rd8rn16_noflags(struct kprobe *p, struct pt_regs *regs)
290 regs->uregs[rd] = rdv; 281 regs->uregs[rd] = rdv;
291} 282}
292 283
293static void __kprobes 284void __kprobes
294t32_emulate_rdlo12rdhi8rn16rm0_noflags(struct kprobe *p, struct pt_regs *regs) 285t32_emulate_rdlo12rdhi8rn16rm0_noflags(struct kprobe *p, struct pt_regs *regs)
295{ 286{
296 kprobe_opcode_t insn = p->opcode; 287 kprobe_opcode_t insn = p->opcode;
@@ -315,640 +306,9 @@ t32_emulate_rdlo12rdhi8rn16rm0_noflags(struct kprobe *p, struct pt_regs *regs)
315 regs->uregs[rdlo] = rdlov; 306 regs->uregs[rdlo] = rdlov;
316 regs->uregs[rdhi] = rdhiv; 307 regs->uregs[rdhi] = rdhiv;
317} 308}
309/* t16 thumb actions */
318 310
319/* These emulation encodings are functionally equivalent... */ 311void __kprobes
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
951static void __kprobes
952t16_simulate_bxblx(struct kprobe *p, struct pt_regs *regs) 312t16_simulate_bxblx(struct kprobe *p, struct pt_regs *regs)
953{ 313{
954 kprobe_opcode_t insn = p->opcode; 314 kprobe_opcode_t insn = p->opcode;
@@ -962,7 +322,7 @@ t16_simulate_bxblx(struct kprobe *p, struct pt_regs *regs)
962 bx_write_pc(rmv, regs); 322 bx_write_pc(rmv, regs);
963} 323}
964 324
965static void __kprobes 325void __kprobes
966t16_simulate_ldr_literal(struct kprobe *p, struct pt_regs *regs) 326t16_simulate_ldr_literal(struct kprobe *p, struct pt_regs *regs)
967{ 327{
968 kprobe_opcode_t insn = p->opcode; 328 kprobe_opcode_t insn = p->opcode;
@@ -972,7 +332,7 @@ t16_simulate_ldr_literal(struct kprobe *p, struct pt_regs *regs)
972 regs->uregs[rt] = base[index]; 332 regs->uregs[rt] = base[index];
973} 333}
974 334
975static void __kprobes 335void __kprobes
976t16_simulate_ldrstr_sp_relative(struct kprobe *p, struct pt_regs *regs) 336t16_simulate_ldrstr_sp_relative(struct kprobe *p, struct pt_regs *regs)
977{ 337{
978 kprobe_opcode_t insn = p->opcode; 338 kprobe_opcode_t insn = p->opcode;
@@ -985,7 +345,7 @@ t16_simulate_ldrstr_sp_relative(struct kprobe *p, struct pt_regs *regs)
985 base[index] = regs->uregs[rt]; 345 base[index] = regs->uregs[rt];
986} 346}
987 347
988static void __kprobes 348void __kprobes
989t16_simulate_reladr(struct kprobe *p, struct pt_regs *regs) 349t16_simulate_reladr(struct kprobe *p, struct pt_regs *regs)
990{ 350{
991 kprobe_opcode_t insn = p->opcode; 351 kprobe_opcode_t insn = p->opcode;
@@ -996,7 +356,7 @@ t16_simulate_reladr(struct kprobe *p, struct pt_regs *regs)
996 regs->uregs[rt] = base + offset * 4; 356 regs->uregs[rt] = base + offset * 4;
997} 357}
998 358
999static void __kprobes 359void __kprobes
1000t16_simulate_add_sp_imm(struct kprobe *p, struct pt_regs *regs) 360t16_simulate_add_sp_imm(struct kprobe *p, struct pt_regs *regs)
1001{ 361{
1002 kprobe_opcode_t insn = p->opcode; 362 kprobe_opcode_t insn = p->opcode;
@@ -1007,7 +367,7 @@ t16_simulate_add_sp_imm(struct kprobe *p, struct pt_regs *regs)
1007 regs->ARM_sp += imm * 4; 367 regs->ARM_sp += imm * 4;
1008} 368}
1009 369
1010static void __kprobes 370void __kprobes
1011t16_simulate_cbz(struct kprobe *p, struct pt_regs *regs) 371t16_simulate_cbz(struct kprobe *p, struct pt_regs *regs)
1012{ 372{
1013 kprobe_opcode_t insn = p->opcode; 373 kprobe_opcode_t insn = p->opcode;
@@ -1021,7 +381,7 @@ t16_simulate_cbz(struct kprobe *p, struct pt_regs *regs)
1021 } 381 }
1022} 382}
1023 383
1024static void __kprobes 384void __kprobes
1025t16_simulate_it(struct kprobe *p, struct pt_regs *regs) 385t16_simulate_it(struct kprobe *p, struct pt_regs *regs)
1026{ 386{
1027 /* 387 /*
@@ -1038,21 +398,21 @@ t16_simulate_it(struct kprobe *p, struct pt_regs *regs)
1038 regs->ARM_cpsr = cpsr; 398 regs->ARM_cpsr = cpsr;
1039} 399}
1040 400
1041static void __kprobes 401void __kprobes
1042t16_singlestep_it(struct kprobe *p, struct pt_regs *regs) 402t16_singlestep_it(struct kprobe *p, struct pt_regs *regs)
1043{ 403{
1044 regs->ARM_pc += 2; 404 regs->ARM_pc += 2;
1045 t16_simulate_it(p, regs); 405 t16_simulate_it(p, regs);
1046} 406}
1047 407
1048static enum kprobe_insn __kprobes 408enum kprobe_insn __kprobes
1049t16_decode_it(kprobe_opcode_t insn, struct arch_specific_insn *asi) 409t16_decode_it(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1050{ 410{
1051 asi->insn_singlestep = t16_singlestep_it; 411 asi->insn_singlestep = t16_singlestep_it;
1052 return INSN_GOOD_NO_SLOT; 412 return INSN_GOOD_NO_SLOT;
1053} 413}
1054 414
1055static void __kprobes 415void __kprobes
1056t16_simulate_cond_branch(struct kprobe *p, struct pt_regs *regs) 416t16_simulate_cond_branch(struct kprobe *p, struct pt_regs *regs)
1057{ 417{
1058 kprobe_opcode_t insn = p->opcode; 418 kprobe_opcode_t insn = p->opcode;
@@ -1062,7 +422,7 @@ t16_simulate_cond_branch(struct kprobe *p, struct pt_regs *regs)
1062 regs->ARM_pc = pc + (offset * 2); 422 regs->ARM_pc = pc + (offset * 2);
1063} 423}
1064 424
1065static enum kprobe_insn __kprobes 425enum kprobe_insn __kprobes
1066t16_decode_cond_branch(kprobe_opcode_t insn, struct arch_specific_insn *asi) 426t16_decode_cond_branch(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1067{ 427{
1068 int cc = (insn >> 8) & 0xf; 428 int cc = (insn >> 8) & 0xf;
@@ -1071,7 +431,7 @@ t16_decode_cond_branch(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1071 return INSN_GOOD_NO_SLOT; 431 return INSN_GOOD_NO_SLOT;
1072} 432}
1073 433
1074static void __kprobes 434void __kprobes
1075t16_simulate_branch(struct kprobe *p, struct pt_regs *regs) 435t16_simulate_branch(struct kprobe *p, struct pt_regs *regs)
1076{ 436{
1077 kprobe_opcode_t insn = p->opcode; 437 kprobe_opcode_t insn = p->opcode;
@@ -1103,13 +463,13 @@ t16_emulate_loregs(struct kprobe *p, struct pt_regs *regs)
1103 return (oldcpsr & ~APSR_MASK) | (newcpsr & APSR_MASK); 463 return (oldcpsr & ~APSR_MASK) | (newcpsr & APSR_MASK);
1104} 464}
1105 465
1106static void __kprobes 466void __kprobes
1107t16_emulate_loregs_rwflags(struct kprobe *p, struct pt_regs *regs) 467t16_emulate_loregs_rwflags(struct kprobe *p, struct pt_regs *regs)
1108{ 468{
1109 regs->ARM_cpsr = t16_emulate_loregs(p, regs); 469 regs->ARM_cpsr = t16_emulate_loregs(p, regs);
1110} 470}
1111 471
1112static void __kprobes 472void __kprobes
1113t16_emulate_loregs_noitrwflags(struct kprobe *p, struct pt_regs *regs) 473t16_emulate_loregs_noitrwflags(struct kprobe *p, struct pt_regs *regs)
1114{ 474{
1115 unsigned long cpsr = t16_emulate_loregs(p, regs); 475 unsigned long cpsr = t16_emulate_loregs(p, regs);
@@ -1117,7 +477,7 @@ t16_emulate_loregs_noitrwflags(struct kprobe *p, struct pt_regs *regs)
1117 regs->ARM_cpsr = cpsr; 477 regs->ARM_cpsr = cpsr;
1118} 478}
1119 479
1120static void __kprobes 480void __kprobes
1121t16_emulate_hiregs(struct kprobe *p, struct pt_regs *regs) 481t16_emulate_hiregs(struct kprobe *p, struct pt_regs *regs)
1122{ 482{
1123 kprobe_opcode_t insn = p->opcode; 483 kprobe_opcode_t insn = p->opcode;
@@ -1148,7 +508,7 @@ t16_emulate_hiregs(struct kprobe *p, struct pt_regs *regs)
1148 regs->ARM_cpsr = (regs->ARM_cpsr & ~APSR_MASK) | (cpsr & APSR_MASK); 508 regs->ARM_cpsr = (regs->ARM_cpsr & ~APSR_MASK) | (cpsr & APSR_MASK);
1149} 509}
1150 510
1151static enum kprobe_insn __kprobes 511enum kprobe_insn __kprobes
1152t16_decode_hiregs(kprobe_opcode_t insn, struct arch_specific_insn *asi) 512t16_decode_hiregs(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1153{ 513{
1154 insn &= ~0x00ff; 514 insn &= ~0x00ff;
@@ -1158,7 +518,7 @@ t16_decode_hiregs(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1158 return INSN_GOOD; 518 return INSN_GOOD;
1159} 519}
1160 520
1161static void __kprobes 521void __kprobes
1162t16_emulate_push(struct kprobe *p, struct pt_regs *regs) 522t16_emulate_push(struct kprobe *p, struct pt_regs *regs)
1163{ 523{
1164 __asm__ __volatile__ ( 524 __asm__ __volatile__ (
@@ -1174,7 +534,7 @@ t16_emulate_push(struct kprobe *p, struct pt_regs *regs)
1174 ); 534 );
1175} 535}
1176 536
1177static enum kprobe_insn __kprobes 537enum kprobe_insn __kprobes
1178t16_decode_push(kprobe_opcode_t insn, struct arch_specific_insn *asi) 538t16_decode_push(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1179{ 539{
1180 /* 540 /*
@@ -1188,7 +548,7 @@ t16_decode_push(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1188 return INSN_GOOD; 548 return INSN_GOOD;
1189} 549}
1190 550
1191static void __kprobes 551void __kprobes
1192t16_emulate_pop_nopc(struct kprobe *p, struct pt_regs *regs) 552t16_emulate_pop_nopc(struct kprobe *p, struct pt_regs *regs)
1193{ 553{
1194 __asm__ __volatile__ ( 554 __asm__ __volatile__ (
@@ -1204,7 +564,7 @@ t16_emulate_pop_nopc(struct kprobe *p, struct pt_regs *regs)
1204 ); 564 );
1205} 565}
1206 566
1207static void __kprobes 567void __kprobes
1208t16_emulate_pop_pc(struct kprobe *p, struct pt_regs *regs) 568t16_emulate_pop_pc(struct kprobe *p, struct pt_regs *regs)
1209{ 569{
1210 register unsigned long pc asm("r8"); 570 register unsigned long pc asm("r8");
@@ -1224,7 +584,7 @@ t16_emulate_pop_pc(struct kprobe *p, struct pt_regs *regs)
1224 bx_write_pc(pc, regs); 584 bx_write_pc(pc, regs);
1225} 585}
1226 586
1227static enum kprobe_insn __kprobes 587enum kprobe_insn __kprobes
1228t16_decode_pop(kprobe_opcode_t insn, struct arch_specific_insn *asi) 588t16_decode_pop(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1229{ 589{
1230 /* 590 /*
@@ -1238,232 +598,3 @@ t16_decode_pop(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1238 : t16_emulate_pop_nopc; 598 : t16_emulate_pop_nopc;
1239 return INSN_GOOD; 599 return INSN_GOOD;
1240} 600}
1241
1242static const union decode_item t16_table_1011[] = {
1243 /* Miscellaneous 16-bit instructions */
1244
1245 /* ADD (SP plus immediate) 1011 0000 0xxx xxxx */
1246 /* SUB (SP minus immediate) 1011 0000 1xxx xxxx */
1247 DECODE_SIMULATE (0xff00, 0xb000, t16_simulate_add_sp_imm),
1248
1249 /* CBZ 1011 00x1 xxxx xxxx */
1250 /* CBNZ 1011 10x1 xxxx xxxx */
1251 DECODE_SIMULATE (0xf500, 0xb100, t16_simulate_cbz),
1252
1253 /* SXTH 1011 0010 00xx xxxx */
1254 /* SXTB 1011 0010 01xx xxxx */
1255 /* UXTH 1011 0010 10xx xxxx */
1256 /* UXTB 1011 0010 11xx xxxx */
1257 /* REV 1011 1010 00xx xxxx */
1258 /* REV16 1011 1010 01xx xxxx */
1259 /* ??? 1011 1010 10xx xxxx */
1260 /* REVSH 1011 1010 11xx xxxx */
1261 DECODE_REJECT (0xffc0, 0xba80),
1262 DECODE_EMULATE (0xf500, 0xb000, t16_emulate_loregs_rwflags),
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};
1293
1294const union decode_item kprobe_decode_thumb16_table[] = {
1295
1296 /*
1297 * Shift (immediate), add, subtract, move, and compare
1298 * 00xx xxxx xxxx xxxx
1299 */
1300
1301 /* CMP (immediate) 0010 1xxx xxxx xxxx */
1302 DECODE_EMULATE (0xf800, 0x2800, t16_emulate_loregs_rwflags),
1303
1304 /* ADD (register) 0001 100x xxxx xxxx */
1305 /* SUB (register) 0001 101x xxxx xxxx */
1306 /* LSL (immediate) 0000 0xxx xxxx xxxx */
1307 /* LSR (immediate) 0000 1xxx xxxx xxxx */
1308 /* ASR (immediate) 0001 0xxx xxxx xxxx */
1309 /* ADD (immediate, Thumb) 0001 110x xxxx xxxx */
1310 /* SUB (immediate, Thumb) 0001 111x xxxx xxxx */
1311 /* MOV (immediate) 0010 0xxx xxxx xxxx */
1312 /* ADD (immediate, Thumb) 0011 0xxx xxxx xxxx */
1313 /* SUB (immediate, Thumb) 0011 1xxx xxxx xxxx */
1314 DECODE_EMULATE (0xc000, 0x0000, t16_emulate_loregs_noitrwflags),
1315
1316 /*
1317 * 16-bit Thumb data-processing instructions
1318 * 0100 00xx xxxx xxxx
1319 */
1320
1321 /* TST (register) 0100 0010 00xx xxxx */
1322 DECODE_EMULATE (0xffc0, 0x4200, t16_emulate_loregs_rwflags),
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};
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}
diff --git a/arch/arm/kernel/probes-thumb.c b/arch/arm/kernel/probes-thumb.c
new file mode 100644
index 000000000000..a1f24777a41a
--- /dev/null
+++ b/arch/arm/kernel/probes-thumb.c
@@ -0,0 +1,878 @@
1/*
2 * arch/arm/kernel/kprobes-thumb.c
3 *
4 * Copyright (C) 2011 Jon Medhurst <tixy@yxit.co.uk>.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#include <linux/stddef.h>
12#include <linux/kernel.h>
13#include <linux/kprobes.h>
14#include <linux/module.h>
15
16#include "kprobes.h"
17#include "probes-thumb.h"
18
19/* These emulation encodings are functionally equivalent... */
20#define t32_emulate_rd8rn16rm0ra12_noflags \
21 t32_emulate_rdlo12rdhi8rn16rm0_noflags
22
23static const union decode_item t32_table_1110_100x_x0xx[] = {
24 /* Load/store multiple instructions */
25
26 /* Rn is PC 1110 100x x0xx 1111 xxxx xxxx xxxx xxxx */
27 DECODE_REJECT (0xfe4f0000, 0xe80f0000),
28
29 /* SRS 1110 1000 00x0 xxxx xxxx xxxx xxxx xxxx */
30 /* RFE 1110 1000 00x1 xxxx xxxx xxxx xxxx xxxx */
31 DECODE_REJECT (0xffc00000, 0xe8000000),
32 /* SRS 1110 1001 10x0 xxxx xxxx xxxx xxxx xxxx */
33 /* RFE 1110 1001 10x1 xxxx xxxx xxxx xxxx xxxx */
34 DECODE_REJECT (0xffc00000, 0xe9800000),
35
36 /* STM Rn, {...pc} 1110 100x x0x0 xxxx 1xxx xxxx xxxx xxxx */
37 DECODE_REJECT (0xfe508000, 0xe8008000),
38 /* LDM Rn, {...lr,pc} 1110 100x x0x1 xxxx 11xx xxxx xxxx xxxx */
39 DECODE_REJECT (0xfe50c000, 0xe810c000),
40 /* LDM/STM Rn, {...sp} 1110 100x x0xx xxxx xx1x xxxx xxxx xxxx */
41 DECODE_REJECT (0xfe402000, 0xe8002000),
42
43 /* STMIA 1110 1000 10x0 xxxx xxxx xxxx xxxx xxxx */
44 /* LDMIA 1110 1000 10x1 xxxx xxxx xxxx xxxx xxxx */
45 /* STMDB 1110 1001 00x0 xxxx xxxx xxxx xxxx xxxx */
46 /* LDMDB 1110 1001 00x1 xxxx xxxx xxxx xxxx xxxx */
47 DECODE_CUSTOM (0xfe400000, 0xe8000000, t32_decode_ldmstm),
48
49 DECODE_END
50};
51
52static const union decode_item t32_table_1110_100x_x1xx[] = {
53 /* Load/store dual, load/store exclusive, table branch */
54
55 /* STRD (immediate) 1110 1000 x110 xxxx xxxx xxxx xxxx xxxx */
56 /* LDRD (immediate) 1110 1000 x111 xxxx xxxx xxxx xxxx xxxx */
57 DECODE_OR (0xff600000, 0xe8600000),
58 /* STRD (immediate) 1110 1001 x1x0 xxxx xxxx xxxx xxxx xxxx */
59 /* LDRD (immediate) 1110 1001 x1x1 xxxx xxxx xxxx xxxx xxxx */
60 DECODE_EMULATEX (0xff400000, 0xe9400000, t32_emulate_ldrdstrd,
61 REGS(NOPCWB, NOSPPC, NOSPPC, 0, 0)),
62
63 /* TBB 1110 1000 1101 xxxx xxxx xxxx 0000 xxxx */
64 /* TBH 1110 1000 1101 xxxx xxxx xxxx 0001 xxxx */
65 DECODE_SIMULATEX(0xfff000e0, 0xe8d00000, t32_simulate_table_branch,
66 REGS(NOSP, 0, 0, 0, NOSPPC)),
67
68 /* STREX 1110 1000 0100 xxxx xxxx xxxx xxxx xxxx */
69 /* LDREX 1110 1000 0101 xxxx xxxx xxxx xxxx xxxx */
70 /* STREXB 1110 1000 1100 xxxx xxxx xxxx 0100 xxxx */
71 /* STREXH 1110 1000 1100 xxxx xxxx xxxx 0101 xxxx */
72 /* STREXD 1110 1000 1100 xxxx xxxx xxxx 0111 xxxx */
73 /* LDREXB 1110 1000 1101 xxxx xxxx xxxx 0100 xxxx */
74 /* LDREXH 1110 1000 1101 xxxx xxxx xxxx 0101 xxxx */
75 /* LDREXD 1110 1000 1101 xxxx xxxx xxxx 0111 xxxx */
76 /* And unallocated instructions... */
77 DECODE_END
78};
79
80static const union decode_item t32_table_1110_101x[] = {
81 /* Data-processing (shifted register) */
82
83 /* TST 1110 1010 0001 xxxx xxxx 1111 xxxx xxxx */
84 /* TEQ 1110 1010 1001 xxxx xxxx 1111 xxxx xxxx */
85 DECODE_EMULATEX (0xff700f00, 0xea100f00, t32_emulate_rd8rn16rm0_rwflags,
86 REGS(NOSPPC, 0, 0, 0, NOSPPC)),
87
88 /* CMN 1110 1011 0001 xxxx xxxx 1111 xxxx xxxx */
89 DECODE_OR (0xfff00f00, 0xeb100f00),
90 /* CMP 1110 1011 1011 xxxx xxxx 1111 xxxx xxxx */
91 DECODE_EMULATEX (0xfff00f00, 0xebb00f00, t32_emulate_rd8rn16rm0_rwflags,
92 REGS(NOPC, 0, 0, 0, NOSPPC)),
93
94 /* MOV 1110 1010 010x 1111 xxxx xxxx xxxx xxxx */
95 /* MVN 1110 1010 011x 1111 xxxx xxxx xxxx xxxx */
96 DECODE_EMULATEX (0xffcf0000, 0xea4f0000, t32_emulate_rd8rn16rm0_rwflags,
97 REGS(0, 0, NOSPPC, 0, NOSPPC)),
98
99 /* ??? 1110 1010 101x xxxx xxxx xxxx xxxx xxxx */
100 /* ??? 1110 1010 111x xxxx xxxx xxxx xxxx xxxx */
101 DECODE_REJECT (0xffa00000, 0xeaa00000),
102 /* ??? 1110 1011 001x xxxx xxxx xxxx xxxx xxxx */
103 DECODE_REJECT (0xffe00000, 0xeb200000),
104 /* ??? 1110 1011 100x xxxx xxxx xxxx xxxx xxxx */
105 DECODE_REJECT (0xffe00000, 0xeb800000),
106 /* ??? 1110 1011 111x xxxx xxxx xxxx xxxx xxxx */
107 DECODE_REJECT (0xffe00000, 0xebe00000),
108
109 /* ADD/SUB SP, SP, Rm, LSL #0..3 */
110 /* 1110 1011 x0xx 1101 x000 1101 xx00 xxxx */
111 DECODE_EMULATEX (0xff4f7f30, 0xeb0d0d00, t32_emulate_rd8rn16rm0_rwflags,
112 REGS(SP, 0, SP, 0, NOSPPC)),
113
114 /* ADD/SUB SP, SP, Rm, shift */
115 /* 1110 1011 x0xx 1101 xxxx 1101 xxxx xxxx */
116 DECODE_REJECT (0xff4f0f00, 0xeb0d0d00),
117
118 /* ADD/SUB Rd, SP, Rm, shift */
119 /* 1110 1011 x0xx 1101 xxxx xxxx xxxx xxxx */
120 DECODE_EMULATEX (0xff4f0000, 0xeb0d0000, t32_emulate_rd8rn16rm0_rwflags,
121 REGS(SP, 0, NOPC, 0, NOSPPC)),
122
123 /* AND 1110 1010 000x xxxx xxxx xxxx xxxx xxxx */
124 /* BIC 1110 1010 001x xxxx xxxx xxxx xxxx xxxx */
125 /* ORR 1110 1010 010x xxxx xxxx xxxx xxxx xxxx */
126 /* ORN 1110 1010 011x xxxx xxxx xxxx xxxx xxxx */
127 /* EOR 1110 1010 100x xxxx xxxx xxxx xxxx xxxx */
128 /* PKH 1110 1010 110x xxxx xxxx xxxx xxxx xxxx */
129 /* ADD 1110 1011 000x xxxx xxxx xxxx xxxx xxxx */
130 /* ADC 1110 1011 010x xxxx xxxx xxxx xxxx xxxx */
131 /* SBC 1110 1011 011x xxxx xxxx xxxx xxxx xxxx */
132 /* SUB 1110 1011 101x xxxx xxxx xxxx xxxx xxxx */
133 /* RSB 1110 1011 110x xxxx xxxx xxxx xxxx xxxx */
134 DECODE_EMULATEX (0xfe000000, 0xea000000, t32_emulate_rd8rn16rm0_rwflags,
135 REGS(NOSPPC, 0, NOSPPC, 0, NOSPPC)),
136
137 DECODE_END
138};
139
140static const union decode_item t32_table_1111_0x0x___0[] = {
141 /* Data-processing (modified immediate) */
142
143 /* TST 1111 0x00 0001 xxxx 0xxx 1111 xxxx xxxx */
144 /* TEQ 1111 0x00 1001 xxxx 0xxx 1111 xxxx xxxx */
145 DECODE_EMULATEX (0xfb708f00, 0xf0100f00, t32_emulate_rd8rn16rm0_rwflags,
146 REGS(NOSPPC, 0, 0, 0, 0)),
147
148 /* CMN 1111 0x01 0001 xxxx 0xxx 1111 xxxx xxxx */
149 DECODE_OR (0xfbf08f00, 0xf1100f00),
150 /* CMP 1111 0x01 1011 xxxx 0xxx 1111 xxxx xxxx */
151 DECODE_EMULATEX (0xfbf08f00, 0xf1b00f00, t32_emulate_rd8rn16rm0_rwflags,
152 REGS(NOPC, 0, 0, 0, 0)),
153
154 /* MOV 1111 0x00 010x 1111 0xxx xxxx xxxx xxxx */
155 /* MVN 1111 0x00 011x 1111 0xxx xxxx xxxx xxxx */
156 DECODE_EMULATEX (0xfbcf8000, 0xf04f0000, t32_emulate_rd8rn16rm0_rwflags,
157 REGS(0, 0, NOSPPC, 0, 0)),
158
159 /* ??? 1111 0x00 101x xxxx 0xxx xxxx xxxx xxxx */
160 DECODE_REJECT (0xfbe08000, 0xf0a00000),
161 /* ??? 1111 0x00 110x xxxx 0xxx xxxx xxxx xxxx */
162 /* ??? 1111 0x00 111x xxxx 0xxx xxxx xxxx xxxx */
163 DECODE_REJECT (0xfbc08000, 0xf0c00000),
164 /* ??? 1111 0x01 001x xxxx 0xxx xxxx xxxx xxxx */
165 DECODE_REJECT (0xfbe08000, 0xf1200000),
166 /* ??? 1111 0x01 100x xxxx 0xxx xxxx xxxx xxxx */
167 DECODE_REJECT (0xfbe08000, 0xf1800000),
168 /* ??? 1111 0x01 111x xxxx 0xxx xxxx xxxx xxxx */
169 DECODE_REJECT (0xfbe08000, 0xf1e00000),
170
171 /* 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 */
173 DECODE_EMULATEX (0xfb4f8000, 0xf10d0000, t32_emulate_rd8rn16rm0_rwflags,
174 REGS(SP, 0, NOPC, 0, 0)),
175
176 /* AND 1111 0x00 000x xxxx 0xxx xxxx xxxx xxxx */
177 /* BIC 1111 0x00 001x xxxx 0xxx xxxx xxxx xxxx */
178 /* ORR 1111 0x00 010x xxxx 0xxx xxxx xxxx xxxx */
179 /* ORN 1111 0x00 011x xxxx 0xxx xxxx xxxx xxxx */
180 /* EOR 1111 0x00 100x xxxx 0xxx xxxx xxxx xxxx */
181 /* ADD 1111 0x01 000x xxxx 0xxx xxxx xxxx xxxx */
182 /* ADC 1111 0x01 010x xxxx 0xxx xxxx xxxx xxxx */
183 /* SBC 1111 0x01 011x xxxx 0xxx xxxx xxxx xxxx */
184 /* SUB 1111 0x01 101x xxxx 0xxx xxxx xxxx xxxx */
185 /* RSB 1111 0x01 110x xxxx 0xxx xxxx xxxx xxxx */
186 DECODE_EMULATEX (0xfa008000, 0xf0000000, t32_emulate_rd8rn16rm0_rwflags,
187 REGS(NOSPPC, 0, NOSPPC, 0, 0)),
188
189 DECODE_END
190};
191
192static const union decode_item t32_table_1111_0x1x___0[] = {
193 /* Data-processing (plain binary immediate) */
194
195 /* ADDW Rd, PC, #imm 1111 0x10 0000 1111 0xxx xxxx xxxx xxxx */
196 DECODE_OR (0xfbff8000, 0xf20f0000),
197 /* SUBW Rd, PC, #imm 1111 0x10 1010 1111 0xxx xxxx xxxx xxxx */
198 DECODE_EMULATEX (0xfbff8000, 0xf2af0000, t32_emulate_rd8pc16_noflags,
199 REGS(PC, 0, NOSPPC, 0, 0)),
200
201 /* ADDW SP, SP, #imm 1111 0x10 0000 1101 0xxx 1101 xxxx xxxx */
202 DECODE_OR (0xfbff8f00, 0xf20d0d00),
203 /* SUBW SP, SP, #imm 1111 0x10 1010 1101 0xxx 1101 xxxx xxxx */
204 DECODE_EMULATEX (0xfbff8f00, 0xf2ad0d00, t32_emulate_rd8rn16_noflags,
205 REGS(SP, 0, SP, 0, 0)),
206
207 /* ADDW 1111 0x10 0000 xxxx 0xxx xxxx xxxx xxxx */
208 DECODE_OR (0xfbf08000, 0xf2000000),
209 /* SUBW 1111 0x10 1010 xxxx 0xxx xxxx xxxx xxxx */
210 DECODE_EMULATEX (0xfbf08000, 0xf2a00000, t32_emulate_rd8rn16_noflags,
211 REGS(NOPCX, 0, NOSPPC, 0, 0)),
212
213 /* MOVW 1111 0x10 0100 xxxx 0xxx xxxx xxxx xxxx */
214 /* MOVT 1111 0x10 1100 xxxx 0xxx xxxx xxxx xxxx */
215 DECODE_EMULATEX (0xfb708000, 0xf2400000, t32_emulate_rd8rn16_noflags,
216 REGS(0, 0, NOSPPC, 0, 0)),
217
218 /* SSAT16 1111 0x11 0010 xxxx 0000 xxxx 00xx xxxx */
219 /* SSAT 1111 0x11 00x0 xxxx 0xxx xxxx xxxx xxxx */
220 /* USAT16 1111 0x11 1010 xxxx 0000 xxxx 00xx xxxx */
221 /* USAT 1111 0x11 10x0 xxxx 0xxx xxxx xxxx xxxx */
222 DECODE_EMULATEX (0xfb508000, 0xf3000000, t32_emulate_rd8rn16rm0_rwflags,
223 REGS(NOSPPC, 0, NOSPPC, 0, 0)),
224
225 /* SFBX 1111 0x11 0100 xxxx 0xxx xxxx xxxx xxxx */
226 /* UFBX 1111 0x11 1100 xxxx 0xxx xxxx xxxx xxxx */
227 DECODE_EMULATEX (0xfb708000, 0xf3400000, t32_emulate_rd8rn16_noflags,
228 REGS(NOSPPC, 0, NOSPPC, 0, 0)),
229
230 /* BFC 1111 0x11 0110 1111 0xxx xxxx xxxx xxxx */
231 DECODE_EMULATEX (0xfbff8000, 0xf36f0000, t32_emulate_rd8rn16_noflags,
232 REGS(0, 0, NOSPPC, 0, 0)),
233
234 /* BFI 1111 0x11 0110 xxxx 0xxx xxxx xxxx xxxx */
235 DECODE_EMULATEX (0xfbf08000, 0xf3600000, t32_emulate_rd8rn16_noflags,
236 REGS(NOSPPCX, 0, NOSPPC, 0, 0)),
237
238 DECODE_END
239};
240
241static const union decode_item t32_table_1111_0xxx___1[] = {
242 /* Branches and miscellaneous control */
243
244 /* YIELD 1111 0011 1010 xxxx 10x0 x000 0000 0001 */
245 DECODE_OR (0xfff0d7ff, 0xf3a08001),
246 /* SEV 1111 0011 1010 xxxx 10x0 x000 0000 0100 */
247 DECODE_EMULATE (0xfff0d7ff, 0xf3a08004, kprobe_emulate_none),
248 /* NOP 1111 0011 1010 xxxx 10x0 x000 0000 0000 */
249 /* WFE 1111 0011 1010 xxxx 10x0 x000 0000 0010 */
250 /* WFI 1111 0011 1010 xxxx 10x0 x000 0000 0011 */
251 DECODE_SIMULATE (0xfff0d7fc, 0xf3a08000, kprobe_simulate_nop),
252
253 /* MRS Rd, CPSR 1111 0011 1110 xxxx 10x0 xxxx xxxx xxxx */
254 DECODE_SIMULATEX(0xfff0d000, 0xf3e08000, t32_simulate_mrs,
255 REGS(0, 0, NOSPPC, 0, 0)),
256
257 /*
258 * Unsupported instructions
259 * 1111 0x11 1xxx xxxx 10x0 xxxx xxxx xxxx
260 *
261 * MSR 1111 0011 100x xxxx 10x0 xxxx xxxx xxxx
262 * DBG hint 1111 0011 1010 xxxx 10x0 x000 1111 xxxx
263 * Unallocated hints 1111 0011 1010 xxxx 10x0 x000 xxxx xxxx
264 * CPS 1111 0011 1010 xxxx 10x0 xxxx xxxx xxxx
265 * CLREX/DSB/DMB/ISB 1111 0011 1011 xxxx 10x0 xxxx xxxx xxxx
266 * BXJ 1111 0011 1100 xxxx 10x0 xxxx xxxx xxxx
267 * SUBS PC,LR,#<imm8> 1111 0011 1101 xxxx 10x0 xxxx xxxx xxxx
268 * MRS Rd, SPSR 1111 0011 1111 xxxx 10x0 xxxx xxxx xxxx
269 * SMC 1111 0111 1111 xxxx 1000 xxxx xxxx xxxx
270 * UNDEFINED 1111 0111 1111 xxxx 1010 xxxx xxxx xxxx
271 * ??? 1111 0111 1xxx xxxx 1010 xxxx xxxx xxxx
272 */
273 DECODE_REJECT (0xfb80d000, 0xf3808000),
274
275 /* Bcc 1111 0xxx xxxx xxxx 10x0 xxxx xxxx xxxx */
276 DECODE_CUSTOM (0xf800d000, 0xf0008000, t32_decode_cond_branch),
277
278 /* BLX 1111 0xxx xxxx xxxx 11x0 xxxx xxxx xxx0 */
279 DECODE_OR (0xf800d001, 0xf000c000),
280 /* B 1111 0xxx xxxx xxxx 10x1 xxxx xxxx xxxx */
281 /* BL 1111 0xxx xxxx xxxx 11x1 xxxx xxxx xxxx */
282 DECODE_SIMULATE (0xf8009000, 0xf0009000, t32_simulate_branch),
283
284 DECODE_END
285};
286
287static const union decode_item t32_table_1111_100x_x0x1__1111[] = {
288 /* Memory hints */
289
290 /* PLD (literal) 1111 1000 x001 1111 1111 xxxx xxxx xxxx */
291 /* PLI (literal) 1111 1001 x001 1111 1111 xxxx xxxx xxxx */
292 DECODE_SIMULATE (0xfe7ff000, 0xf81ff000, kprobe_simulate_nop),
293
294 /* PLD{W} (immediate) 1111 1000 10x1 xxxx 1111 xxxx xxxx xxxx */
295 DECODE_OR (0xffd0f000, 0xf890f000),
296 /* PLD{W} (immediate) 1111 1000 00x1 xxxx 1111 1100 xxxx xxxx */
297 DECODE_OR (0xffd0ff00, 0xf810fc00),
298 /* PLI (immediate) 1111 1001 1001 xxxx 1111 xxxx xxxx xxxx */
299 DECODE_OR (0xfff0f000, 0xf990f000),
300 /* PLI (immediate) 1111 1001 0001 xxxx 1111 1100 xxxx xxxx */
301 DECODE_SIMULATEX(0xfff0ff00, 0xf910fc00, kprobe_simulate_nop,
302 REGS(NOPCX, 0, 0, 0, 0)),
303
304 /* PLD{W} (register) 1111 1000 00x1 xxxx 1111 0000 00xx xxxx */
305 DECODE_OR (0xffd0ffc0, 0xf810f000),
306 /* PLI (register) 1111 1001 0001 xxxx 1111 0000 00xx xxxx */
307 DECODE_SIMULATEX(0xfff0ffc0, 0xf910f000, kprobe_simulate_nop,
308 REGS(NOPCX, 0, 0, 0, NOSPPC)),
309
310 /* Other unallocated instructions... */
311 DECODE_END
312};
313
314static const union decode_item t32_table_1111_100x[] = {
315 /* Store/Load single data item */
316
317 /* ??? 1111 100x x11x xxxx xxxx xxxx xxxx xxxx */
318 DECODE_REJECT (0xfe600000, 0xf8600000),
319
320 /* ??? 1111 1001 0101 xxxx xxxx xxxx xxxx xxxx */
321 DECODE_REJECT (0xfff00000, 0xf9500000),
322
323 /* ??? 1111 100x 0xxx xxxx xxxx 10x0 xxxx xxxx */
324 DECODE_REJECT (0xfe800d00, 0xf8000800),
325
326 /* STRBT 1111 1000 0000 xxxx xxxx 1110 xxxx xxxx */
327 /* STRHT 1111 1000 0010 xxxx xxxx 1110 xxxx xxxx */
328 /* STRT 1111 1000 0100 xxxx xxxx 1110 xxxx xxxx */
329 /* LDRBT 1111 1000 0001 xxxx xxxx 1110 xxxx xxxx */
330 /* LDRSBT 1111 1001 0001 xxxx xxxx 1110 xxxx xxxx */
331 /* LDRHT 1111 1000 0011 xxxx xxxx 1110 xxxx xxxx */
332 /* LDRSHT 1111 1001 0011 xxxx xxxx 1110 xxxx xxxx */
333 /* LDRT 1111 1000 0101 xxxx xxxx 1110 xxxx xxxx */
334 DECODE_REJECT (0xfe800f00, 0xf8000e00),
335
336 /* STR{,B,H} Rn,[PC...] 1111 1000 xxx0 1111 xxxx xxxx xxxx xxxx */
337 DECODE_REJECT (0xff1f0000, 0xf80f0000),
338
339 /* STR{,B,H} PC,[Rn...] 1111 1000 xxx0 xxxx 1111 xxxx xxxx xxxx */
340 DECODE_REJECT (0xff10f000, 0xf800f000),
341
342 /* LDR (literal) 1111 1000 x101 1111 xxxx xxxx xxxx xxxx */
343 DECODE_SIMULATEX(0xff7f0000, 0xf85f0000, t32_simulate_ldr_literal,
344 REGS(PC, ANY, 0, 0, 0)),
345
346 /* STR (immediate) 1111 1000 0100 xxxx xxxx 1xxx xxxx xxxx */
347 /* LDR (immediate) 1111 1000 0101 xxxx xxxx 1xxx xxxx xxxx */
348 DECODE_OR (0xffe00800, 0xf8400800),
349 /* STR (immediate) 1111 1000 1100 xxxx xxxx xxxx xxxx xxxx */
350 /* LDR (immediate) 1111 1000 1101 xxxx xxxx xxxx xxxx xxxx */
351 DECODE_EMULATEX (0xffe00000, 0xf8c00000, t32_emulate_ldrstr,
352 REGS(NOPCX, ANY, 0, 0, 0)),
353
354 /* STR (register) 1111 1000 0100 xxxx xxxx 0000 00xx xxxx */
355 /* LDR (register) 1111 1000 0101 xxxx xxxx 0000 00xx xxxx */
356 DECODE_EMULATEX (0xffe00fc0, 0xf8400000, t32_emulate_ldrstr,
357 REGS(NOPCX, ANY, 0, 0, NOSPPC)),
358
359 /* LDRB (literal) 1111 1000 x001 1111 xxxx xxxx xxxx xxxx */
360 /* LDRSB (literal) 1111 1001 x001 1111 xxxx xxxx xxxx xxxx */
361 /* LDRH (literal) 1111 1000 x011 1111 xxxx xxxx xxxx xxxx */
362 /* LDRSH (literal) 1111 1001 x011 1111 xxxx xxxx xxxx xxxx */
363 DECODE_SIMULATEX(0xfe5f0000, 0xf81f0000, t32_simulate_ldr_literal,
364 REGS(PC, NOSPPCX, 0, 0, 0)),
365
366 /* STRB (immediate) 1111 1000 0000 xxxx xxxx 1xxx xxxx xxxx */
367 /* STRH (immediate) 1111 1000 0010 xxxx xxxx 1xxx xxxx xxxx */
368 /* LDRB (immediate) 1111 1000 0001 xxxx xxxx 1xxx xxxx xxxx */
369 /* LDRSB (immediate) 1111 1001 0001 xxxx xxxx 1xxx xxxx xxxx */
370 /* LDRH (immediate) 1111 1000 0011 xxxx xxxx 1xxx xxxx xxxx */
371 /* LDRSH (immediate) 1111 1001 0011 xxxx xxxx 1xxx xxxx xxxx */
372 DECODE_OR (0xfec00800, 0xf8000800),
373 /* STRB (immediate) 1111 1000 1000 xxxx xxxx xxxx xxxx xxxx */
374 /* STRH (immediate) 1111 1000 1010 xxxx xxxx xxxx xxxx xxxx */
375 /* LDRB (immediate) 1111 1000 1001 xxxx xxxx xxxx xxxx xxxx */
376 /* LDRSB (immediate) 1111 1001 1001 xxxx xxxx xxxx xxxx xxxx */
377 /* LDRH (immediate) 1111 1000 1011 xxxx xxxx xxxx xxxx xxxx */
378 /* LDRSH (immediate) 1111 1001 1011 xxxx xxxx xxxx xxxx xxxx */
379 DECODE_EMULATEX (0xfec00000, 0xf8800000, t32_emulate_ldrstr,
380 REGS(NOPCX, NOSPPCX, 0, 0, 0)),
381
382 /* STRB (register) 1111 1000 0000 xxxx xxxx 0000 00xx xxxx */
383 /* STRH (register) 1111 1000 0010 xxxx xxxx 0000 00xx xxxx */
384 /* LDRB (register) 1111 1000 0001 xxxx xxxx 0000 00xx xxxx */
385 /* LDRSB (register) 1111 1001 0001 xxxx xxxx 0000 00xx xxxx */
386 /* LDRH (register) 1111 1000 0011 xxxx xxxx 0000 00xx xxxx */
387 /* LDRSH (register) 1111 1001 0011 xxxx xxxx 0000 00xx xxxx */
388 DECODE_EMULATEX (0xfe800fc0, 0xf8000000, t32_emulate_ldrstr,
389 REGS(NOPCX, NOSPPCX, 0, 0, NOSPPC)),
390
391 /* Other unallocated instructions... */
392 DECODE_END
393};
394
395static const union decode_item t32_table_1111_1010___1111[] = {
396 /* Data-processing (register) */
397
398 /* ??? 1111 1010 011x xxxx 1111 xxxx 1xxx xxxx */
399 DECODE_REJECT (0xffe0f080, 0xfa60f080),
400
401 /* SXTH 1111 1010 0000 1111 1111 xxxx 1xxx xxxx */
402 /* UXTH 1111 1010 0001 1111 1111 xxxx 1xxx xxxx */
403 /* SXTB16 1111 1010 0010 1111 1111 xxxx 1xxx xxxx */
404 /* UXTB16 1111 1010 0011 1111 1111 xxxx 1xxx xxxx */
405 /* SXTB 1111 1010 0100 1111 1111 xxxx 1xxx xxxx */
406 /* UXTB 1111 1010 0101 1111 1111 xxxx 1xxx xxxx */
407 DECODE_EMULATEX (0xff8ff080, 0xfa0ff080, t32_emulate_rd8rn16rm0_rwflags,
408 REGS(0, 0, NOSPPC, 0, NOSPPC)),
409
410
411 /* ??? 1111 1010 1xxx xxxx 1111 xxxx 0x11 xxxx */
412 DECODE_REJECT (0xff80f0b0, 0xfa80f030),
413 /* ??? 1111 1010 1x11 xxxx 1111 xxxx 0xxx xxxx */
414 DECODE_REJECT (0xffb0f080, 0xfab0f000),
415
416 /* SADD16 1111 1010 1001 xxxx 1111 xxxx 0000 xxxx */
417 /* SASX 1111 1010 1010 xxxx 1111 xxxx 0000 xxxx */
418 /* SSAX 1111 1010 1110 xxxx 1111 xxxx 0000 xxxx */
419 /* SSUB16 1111 1010 1101 xxxx 1111 xxxx 0000 xxxx */
420 /* SADD8 1111 1010 1000 xxxx 1111 xxxx 0000 xxxx */
421 /* SSUB8 1111 1010 1100 xxxx 1111 xxxx 0000 xxxx */
422
423 /* QADD16 1111 1010 1001 xxxx 1111 xxxx 0001 xxxx */
424 /* QASX 1111 1010 1010 xxxx 1111 xxxx 0001 xxxx */
425 /* QSAX 1111 1010 1110 xxxx 1111 xxxx 0001 xxxx */
426 /* QSUB16 1111 1010 1101 xxxx 1111 xxxx 0001 xxxx */
427 /* QADD8 1111 1010 1000 xxxx 1111 xxxx 0001 xxxx */
428 /* QSUB8 1111 1010 1100 xxxx 1111 xxxx 0001 xxxx */
429
430 /* SHADD16 1111 1010 1001 xxxx 1111 xxxx 0010 xxxx */
431 /* SHASX 1111 1010 1010 xxxx 1111 xxxx 0010 xxxx */
432 /* SHSAX 1111 1010 1110 xxxx 1111 xxxx 0010 xxxx */
433 /* SHSUB16 1111 1010 1101 xxxx 1111 xxxx 0010 xxxx */
434 /* SHADD8 1111 1010 1000 xxxx 1111 xxxx 0010 xxxx */
435 /* SHSUB8 1111 1010 1100 xxxx 1111 xxxx 0010 xxxx */
436
437 /* UADD16 1111 1010 1001 xxxx 1111 xxxx 0100 xxxx */
438 /* UASX 1111 1010 1010 xxxx 1111 xxxx 0100 xxxx */
439 /* USAX 1111 1010 1110 xxxx 1111 xxxx 0100 xxxx */
440 /* USUB16 1111 1010 1101 xxxx 1111 xxxx 0100 xxxx */
441 /* UADD8 1111 1010 1000 xxxx 1111 xxxx 0100 xxxx */
442 /* USUB8 1111 1010 1100 xxxx 1111 xxxx 0100 xxxx */
443
444 /* UQADD16 1111 1010 1001 xxxx 1111 xxxx 0101 xxxx */
445 /* UQASX 1111 1010 1010 xxxx 1111 xxxx 0101 xxxx */
446 /* UQSAX 1111 1010 1110 xxxx 1111 xxxx 0101 xxxx */
447 /* UQSUB16 1111 1010 1101 xxxx 1111 xxxx 0101 xxxx */
448 /* UQADD8 1111 1010 1000 xxxx 1111 xxxx 0101 xxxx */
449 /* UQSUB8 1111 1010 1100 xxxx 1111 xxxx 0101 xxxx */
450
451 /* UHADD16 1111 1010 1001 xxxx 1111 xxxx 0110 xxxx */
452 /* UHASX 1111 1010 1010 xxxx 1111 xxxx 0110 xxxx */
453 /* UHSAX 1111 1010 1110 xxxx 1111 xxxx 0110 xxxx */
454 /* UHSUB16 1111 1010 1101 xxxx 1111 xxxx 0110 xxxx */
455 /* UHADD8 1111 1010 1000 xxxx 1111 xxxx 0110 xxxx */
456 /* UHSUB8 1111 1010 1100 xxxx 1111 xxxx 0110 xxxx */
457 DECODE_OR (0xff80f080, 0xfa80f000),
458
459 /* SXTAH 1111 1010 0000 xxxx 1111 xxxx 1xxx xxxx */
460 /* UXTAH 1111 1010 0001 xxxx 1111 xxxx 1xxx xxxx */
461 /* SXTAB16 1111 1010 0010 xxxx 1111 xxxx 1xxx xxxx */
462 /* UXTAB16 1111 1010 0011 xxxx 1111 xxxx 1xxx xxxx */
463 /* SXTAB 1111 1010 0100 xxxx 1111 xxxx 1xxx xxxx */
464 /* UXTAB 1111 1010 0101 xxxx 1111 xxxx 1xxx xxxx */
465 DECODE_OR (0xff80f080, 0xfa00f080),
466
467 /* QADD 1111 1010 1000 xxxx 1111 xxxx 1000 xxxx */
468 /* QDADD 1111 1010 1000 xxxx 1111 xxxx 1001 xxxx */
469 /* QSUB 1111 1010 1000 xxxx 1111 xxxx 1010 xxxx */
470 /* QDSUB 1111 1010 1000 xxxx 1111 xxxx 1011 xxxx */
471 DECODE_OR (0xfff0f0c0, 0xfa80f080),
472
473 /* SEL 1111 1010 1010 xxxx 1111 xxxx 1000 xxxx */
474 DECODE_OR (0xfff0f0f0, 0xfaa0f080),
475
476 /* LSL 1111 1010 000x xxxx 1111 xxxx 0000 xxxx */
477 /* LSR 1111 1010 001x xxxx 1111 xxxx 0000 xxxx */
478 /* ASR 1111 1010 010x xxxx 1111 xxxx 0000 xxxx */
479 /* ROR 1111 1010 011x xxxx 1111 xxxx 0000 xxxx */
480 DECODE_EMULATEX (0xff80f0f0, 0xfa00f000, t32_emulate_rd8rn16rm0_rwflags,
481 REGS(NOSPPC, 0, NOSPPC, 0, NOSPPC)),
482
483 /* CLZ 1111 1010 1010 xxxx 1111 xxxx 1000 xxxx */
484 DECODE_OR (0xfff0f0f0, 0xfab0f080),
485
486 /* REV 1111 1010 1001 xxxx 1111 xxxx 1000 xxxx */
487 /* REV16 1111 1010 1001 xxxx 1111 xxxx 1001 xxxx */
488 /* RBIT 1111 1010 1001 xxxx 1111 xxxx 1010 xxxx */
489 /* REVSH 1111 1010 1001 xxxx 1111 xxxx 1011 xxxx */
490 DECODE_EMULATEX (0xfff0f0c0, 0xfa90f080, t32_emulate_rd8rn16_noflags,
491 REGS(NOSPPC, 0, NOSPPC, 0, SAMEAS16)),
492
493 /* Other unallocated instructions... */
494 DECODE_END
495};
496
497static const union decode_item t32_table_1111_1011_0[] = {
498 /* Multiply, multiply accumulate, and absolute difference */
499
500 /* ??? 1111 1011 0000 xxxx 1111 xxxx 0001 xxxx */
501 DECODE_REJECT (0xfff0f0f0, 0xfb00f010),
502 /* ??? 1111 1011 0111 xxxx 1111 xxxx 0001 xxxx */
503 DECODE_REJECT (0xfff0f0f0, 0xfb70f010),
504
505 /* SMULxy 1111 1011 0001 xxxx 1111 xxxx 00xx xxxx */
506 DECODE_OR (0xfff0f0c0, 0xfb10f000),
507 /* MUL 1111 1011 0000 xxxx 1111 xxxx 0000 xxxx */
508 /* SMUAD{X} 1111 1011 0010 xxxx 1111 xxxx 000x xxxx */
509 /* SMULWy 1111 1011 0011 xxxx 1111 xxxx 000x xxxx */
510 /* SMUSD{X} 1111 1011 0100 xxxx 1111 xxxx 000x xxxx */
511 /* SMMUL{R} 1111 1011 0101 xxxx 1111 xxxx 000x xxxx */
512 /* USAD8 1111 1011 0111 xxxx 1111 xxxx 0000 xxxx */
513 DECODE_EMULATEX (0xff80f0e0, 0xfb00f000, t32_emulate_rd8rn16rm0_rwflags,
514 REGS(NOSPPC, 0, NOSPPC, 0, NOSPPC)),
515
516 /* ??? 1111 1011 0111 xxxx xxxx xxxx 0001 xxxx */
517 DECODE_REJECT (0xfff000f0, 0xfb700010),
518
519 /* SMLAxy 1111 1011 0001 xxxx xxxx xxxx 00xx xxxx */
520 DECODE_OR (0xfff000c0, 0xfb100000),
521 /* MLA 1111 1011 0000 xxxx xxxx xxxx 0000 xxxx */
522 /* MLS 1111 1011 0000 xxxx xxxx xxxx 0001 xxxx */
523 /* SMLAD{X} 1111 1011 0010 xxxx xxxx xxxx 000x xxxx */
524 /* SMLAWy 1111 1011 0011 xxxx xxxx xxxx 000x xxxx */
525 /* SMLSD{X} 1111 1011 0100 xxxx xxxx xxxx 000x xxxx */
526 /* SMMLA{R} 1111 1011 0101 xxxx xxxx xxxx 000x xxxx */
527 /* SMMLS{R} 1111 1011 0110 xxxx xxxx xxxx 000x xxxx */
528 /* USADA8 1111 1011 0111 xxxx xxxx xxxx 0000 xxxx */
529 DECODE_EMULATEX (0xff8000c0, 0xfb000000, t32_emulate_rd8rn16rm0ra12_noflags,
530 REGS(NOSPPC, NOSPPCX, NOSPPC, 0, NOSPPC)),
531
532 /* Other unallocated instructions... */
533 DECODE_END
534};
535
536static const union decode_item t32_table_1111_1011_1[] = {
537 /* Long multiply, long multiply accumulate, and divide */
538
539 /* UMAAL 1111 1011 1110 xxxx xxxx xxxx 0110 xxxx */
540 DECODE_OR (0xfff000f0, 0xfbe00060),
541 /* SMLALxy 1111 1011 1100 xxxx xxxx xxxx 10xx xxxx */
542 DECODE_OR (0xfff000c0, 0xfbc00080),
543 /* SMLALD{X} 1111 1011 1100 xxxx xxxx xxxx 110x xxxx */
544 /* SMLSLD{X} 1111 1011 1101 xxxx xxxx xxxx 110x xxxx */
545 DECODE_OR (0xffe000e0, 0xfbc000c0),
546 /* SMULL 1111 1011 1000 xxxx xxxx xxxx 0000 xxxx */
547 /* UMULL 1111 1011 1010 xxxx xxxx xxxx 0000 xxxx */
548 /* SMLAL 1111 1011 1100 xxxx xxxx xxxx 0000 xxxx */
549 /* UMLAL 1111 1011 1110 xxxx xxxx xxxx 0000 xxxx */
550 DECODE_EMULATEX (0xff9000f0, 0xfb800000, t32_emulate_rdlo12rdhi8rn16rm0_noflags,
551 REGS(NOSPPC, NOSPPC, NOSPPC, 0, NOSPPC)),
552
553 /* SDIV 1111 1011 1001 xxxx xxxx xxxx 1111 xxxx */
554 /* UDIV 1111 1011 1011 xxxx xxxx xxxx 1111 xxxx */
555 /* Other unallocated instructions... */
556 DECODE_END
557};
558
559const union decode_item kprobe_decode_thumb32_table[] = {
560
561 /*
562 * Load/store multiple instructions
563 * 1110 100x x0xx xxxx xxxx xxxx xxxx xxxx
564 */
565 DECODE_TABLE (0xfe400000, 0xe8000000, t32_table_1110_100x_x0xx),
566
567 /*
568 * Load/store dual, load/store exclusive, table branch
569 * 1110 100x x1xx xxxx xxxx xxxx xxxx xxxx
570 */
571 DECODE_TABLE (0xfe400000, 0xe8400000, t32_table_1110_100x_x1xx),
572
573 /*
574 * Data-processing (shifted register)
575 * 1110 101x xxxx xxxx xxxx xxxx xxxx xxxx
576 */
577 DECODE_TABLE (0xfe000000, 0xea000000, t32_table_1110_101x),
578
579 /*
580 * Coprocessor instructions
581 * 1110 11xx xxxx xxxx xxxx xxxx xxxx xxxx
582 */
583 DECODE_REJECT (0xfc000000, 0xec000000),
584
585 /*
586 * Data-processing (modified immediate)
587 * 1111 0x0x xxxx xxxx 0xxx xxxx xxxx xxxx
588 */
589 DECODE_TABLE (0xfa008000, 0xf0000000, t32_table_1111_0x0x___0),
590
591 /*
592 * Data-processing (plain binary immediate)
593 * 1111 0x1x xxxx xxxx 0xxx xxxx xxxx xxxx
594 */
595 DECODE_TABLE (0xfa008000, 0xf2000000, t32_table_1111_0x1x___0),
596
597 /*
598 * Branches and miscellaneous control
599 * 1111 0xxx xxxx xxxx 1xxx xxxx xxxx xxxx
600 */
601 DECODE_TABLE (0xf8008000, 0xf0008000, t32_table_1111_0xxx___1),
602
603 /*
604 * Advanced SIMD element or structure load/store instructions
605 * 1111 1001 xxx0 xxxx xxxx xxxx xxxx xxxx
606 */
607 DECODE_REJECT (0xff100000, 0xf9000000),
608
609 /*
610 * Memory hints
611 * 1111 100x x0x1 xxxx 1111 xxxx xxxx xxxx
612 */
613 DECODE_TABLE (0xfe50f000, 0xf810f000, t32_table_1111_100x_x0x1__1111),
614
615 /*
616 * Store single data item
617 * 1111 1000 xxx0 xxxx xxxx xxxx xxxx xxxx
618 * Load single data items
619 * 1111 100x xxx1 xxxx xxxx xxxx xxxx xxxx
620 */
621 DECODE_TABLE (0xfe000000, 0xf8000000, t32_table_1111_100x),
622
623 /*
624 * Data-processing (register)
625 * 1111 1010 xxxx xxxx 1111 xxxx xxxx xxxx
626 */
627 DECODE_TABLE (0xff00f000, 0xfa00f000, t32_table_1111_1010___1111),
628
629 /*
630 * Multiply, multiply accumulate, and absolute difference
631 * 1111 1011 0xxx xxxx xxxx xxxx xxxx xxxx
632 */
633 DECODE_TABLE (0xff800000, 0xfb000000, t32_table_1111_1011_0),
634
635 /*
636 * Long multiply, long multiply accumulate, and divide
637 * 1111 1011 1xxx xxxx xxxx xxxx xxxx xxxx
638 */
639 DECODE_TABLE (0xff800000, 0xfb800000, t32_table_1111_1011_1),
640
641 /*
642 * Coprocessor instructions
643 * 1111 11xx xxxx xxxx xxxx xxxx xxxx xxxx
644 */
645 DECODE_END
646};
647#ifdef CONFIG_ARM_KPROBES_TEST_MODULE
648EXPORT_SYMBOL_GPL(kprobe_decode_thumb32_table);
649#endif
650
651static const union decode_item t16_table_1011[] = {
652 /* Miscellaneous 16-bit instructions */
653
654 /* ADD (SP plus immediate) 1011 0000 0xxx xxxx */
655 /* SUB (SP minus immediate) 1011 0000 1xxx xxxx */
656 DECODE_SIMULATE (0xff00, 0xb000, t16_simulate_add_sp_imm),
657
658 /* CBZ 1011 00x1 xxxx xxxx */
659 /* CBNZ 1011 10x1 xxxx xxxx */
660 DECODE_SIMULATE (0xf500, 0xb100, t16_simulate_cbz),
661
662 /* SXTH 1011 0010 00xx xxxx */
663 /* SXTB 1011 0010 01xx xxxx */
664 /* UXTH 1011 0010 10xx xxxx */
665 /* UXTB 1011 0010 11xx xxxx */
666 /* REV 1011 1010 00xx xxxx */
667 /* REV16 1011 1010 01xx xxxx */
668 /* ??? 1011 1010 10xx xxxx */
669 /* REVSH 1011 1010 11xx xxxx */
670 DECODE_REJECT (0xffc0, 0xba80),
671 DECODE_EMULATE (0xf500, 0xb000, t16_emulate_loregs_rwflags),
672
673 /* PUSH 1011 010x xxxx xxxx */
674 DECODE_CUSTOM (0xfe00, 0xb400, t16_decode_push),
675 /* POP 1011 110x xxxx xxxx */
676 DECODE_CUSTOM (0xfe00, 0xbc00, t16_decode_pop),
677
678 /*
679 * If-Then, and hints
680 * 1011 1111 xxxx xxxx
681 */
682
683 /* YIELD 1011 1111 0001 0000 */
684 DECODE_OR (0xffff, 0xbf10),
685 /* SEV 1011 1111 0100 0000 */
686 DECODE_EMULATE (0xffff, 0xbf40, kprobe_emulate_none),
687 /* NOP 1011 1111 0000 0000 */
688 /* WFE 1011 1111 0010 0000 */
689 /* WFI 1011 1111 0011 0000 */
690 DECODE_SIMULATE (0xffcf, 0xbf00, kprobe_simulate_nop),
691 /* Unassigned hints 1011 1111 xxxx 0000 */
692 DECODE_REJECT (0xff0f, 0xbf00),
693 /* IT 1011 1111 xxxx xxxx */
694 DECODE_CUSTOM (0xff00, 0xbf00, t16_decode_it),
695
696 /* SETEND 1011 0110 010x xxxx */
697 /* CPS 1011 0110 011x xxxx */
698 /* BKPT 1011 1110 xxxx xxxx */
699 /* And unallocated instructions... */
700 DECODE_END
701};
702
703const union decode_item kprobe_decode_thumb16_table[] = {
704
705 /*
706 * Shift (immediate), add, subtract, move, and compare
707 * 00xx xxxx xxxx xxxx
708 */
709
710 /* CMP (immediate) 0010 1xxx xxxx xxxx */
711 DECODE_EMULATE (0xf800, 0x2800, t16_emulate_loregs_rwflags),
712
713 /* ADD (register) 0001 100x xxxx xxxx */
714 /* SUB (register) 0001 101x xxxx xxxx */
715 /* LSL (immediate) 0000 0xxx xxxx xxxx */
716 /* LSR (immediate) 0000 1xxx xxxx xxxx */
717 /* ASR (immediate) 0001 0xxx xxxx xxxx */
718 /* ADD (immediate, Thumb) 0001 110x xxxx xxxx */
719 /* SUB (immediate, Thumb) 0001 111x xxxx xxxx */
720 /* MOV (immediate) 0010 0xxx xxxx xxxx */
721 /* ADD (immediate, Thumb) 0011 0xxx xxxx xxxx */
722 /* SUB (immediate, Thumb) 0011 1xxx xxxx xxxx */
723 DECODE_EMULATE (0xc000, 0x0000, t16_emulate_loregs_noitrwflags),
724
725 /*
726 * 16-bit Thumb data-processing instructions
727 * 0100 00xx xxxx xxxx
728 */
729
730 /* TST (register) 0100 0010 00xx xxxx */
731 DECODE_EMULATE (0xffc0, 0x4200, t16_emulate_loregs_rwflags),
732 /* CMP (register) 0100 0010 10xx xxxx */
733 /* CMN (register) 0100 0010 11xx xxxx */
734 DECODE_EMULATE (0xff80, 0x4280, t16_emulate_loregs_rwflags),
735 /* AND (register) 0100 0000 00xx xxxx */
736 /* EOR (register) 0100 0000 01xx xxxx */
737 /* LSL (register) 0100 0000 10xx xxxx */
738 /* LSR (register) 0100 0000 11xx xxxx */
739 /* ASR (register) 0100 0001 00xx xxxx */
740 /* ADC (register) 0100 0001 01xx xxxx */
741 /* SBC (register) 0100 0001 10xx xxxx */
742 /* ROR (register) 0100 0001 11xx xxxx */
743 /* RSB (immediate) 0100 0010 01xx xxxx */
744 /* ORR (register) 0100 0011 00xx xxxx */
745 /* MUL 0100 0011 00xx xxxx */
746 /* BIC (register) 0100 0011 10xx xxxx */
747 /* MVN (register) 0100 0011 10xx xxxx */
748 DECODE_EMULATE (0xfc00, 0x4000, t16_emulate_loregs_noitrwflags),
749
750 /*
751 * Special data instructions and branch and exchange
752 * 0100 01xx xxxx xxxx
753 */
754
755 /* BLX pc 0100 0111 1111 1xxx */
756 DECODE_REJECT (0xfff8, 0x47f8),
757
758 /* BX (register) 0100 0111 0xxx xxxx */
759 /* BLX (register) 0100 0111 1xxx xxxx */
760 DECODE_SIMULATE (0xff00, 0x4700, t16_simulate_bxblx),
761
762 /* ADD pc, pc 0100 0100 1111 1111 */
763 DECODE_REJECT (0xffff, 0x44ff),
764
765 /* ADD (register) 0100 0100 xxxx xxxx */
766 /* CMP (register) 0100 0101 xxxx xxxx */
767 /* MOV (register) 0100 0110 xxxx xxxx */
768 DECODE_CUSTOM (0xfc00, 0x4400, t16_decode_hiregs),
769
770 /*
771 * Load from Literal Pool
772 * LDR (literal) 0100 1xxx xxxx xxxx
773 */
774 DECODE_SIMULATE (0xf800, 0x4800, t16_simulate_ldr_literal),
775
776 /*
777 * 16-bit Thumb Load/store instructions
778 * 0101 xxxx xxxx xxxx
779 * 011x xxxx xxxx xxxx
780 * 100x xxxx xxxx xxxx
781 */
782
783 /* STR (register) 0101 000x xxxx xxxx */
784 /* STRH (register) 0101 001x xxxx xxxx */
785 /* STRB (register) 0101 010x xxxx xxxx */
786 /* LDRSB (register) 0101 011x xxxx xxxx */
787 /* LDR (register) 0101 100x xxxx xxxx */
788 /* LDRH (register) 0101 101x xxxx xxxx */
789 /* LDRB (register) 0101 110x xxxx xxxx */
790 /* LDRSH (register) 0101 111x xxxx xxxx */
791 /* STR (immediate, Thumb) 0110 0xxx xxxx xxxx */
792 /* LDR (immediate, Thumb) 0110 1xxx xxxx xxxx */
793 /* STRB (immediate, Thumb) 0111 0xxx xxxx xxxx */
794 /* LDRB (immediate, Thumb) 0111 1xxx xxxx xxxx */
795 DECODE_EMULATE (0xc000, 0x4000, t16_emulate_loregs_rwflags),
796 /* STRH (immediate, Thumb) 1000 0xxx xxxx xxxx */
797 /* LDRH (immediate, Thumb) 1000 1xxx xxxx xxxx */
798 DECODE_EMULATE (0xf000, 0x8000, t16_emulate_loregs_rwflags),
799 /* STR (immediate, Thumb) 1001 0xxx xxxx xxxx */
800 /* LDR (immediate, Thumb) 1001 1xxx xxxx xxxx */
801 DECODE_SIMULATE (0xf000, 0x9000, t16_simulate_ldrstr_sp_relative),
802
803 /*
804 * Generate PC-/SP-relative address
805 * ADR (literal) 1010 0xxx xxxx xxxx
806 * ADD (SP plus immediate) 1010 1xxx xxxx xxxx
807 */
808 DECODE_SIMULATE (0xf000, 0xa000, t16_simulate_reladr),
809
810 /*
811 * Miscellaneous 16-bit instructions
812 * 1011 xxxx xxxx xxxx
813 */
814 DECODE_TABLE (0xf000, 0xb000, t16_table_1011),
815
816 /* STM 1100 0xxx xxxx xxxx */
817 /* LDM 1100 1xxx xxxx xxxx */
818 DECODE_EMULATE (0xf000, 0xc000, t16_emulate_loregs_rwflags),
819
820 /*
821 * Conditional branch, and Supervisor Call
822 */
823
824 /* Permanently UNDEFINED 1101 1110 xxxx xxxx */
825 /* SVC 1101 1111 xxxx xxxx */
826 DECODE_REJECT (0xfe00, 0xde00),
827
828 /* Conditional branch 1101 xxxx xxxx xxxx */
829 DECODE_CUSTOM (0xf000, 0xd000, t16_decode_cond_branch),
830
831 /*
832 * Unconditional branch
833 * B 1110 0xxx xxxx xxxx
834 */
835 DECODE_SIMULATE (0xf800, 0xe000, t16_simulate_branch),
836
837 DECODE_END
838};
839#ifdef CONFIG_ARM_KPROBES_TEST_MODULE
840EXPORT_SYMBOL_GPL(kprobe_decode_thumb16_table);
841#endif
842
843static unsigned long __kprobes thumb_check_cc(unsigned long cpsr)
844{
845 if (unlikely(in_it_block(cpsr)))
846 return kprobe_condition_checks[current_cond(cpsr)](cpsr);
847 return true;
848}
849
850static void __kprobes thumb16_singlestep(struct kprobe *p, struct pt_regs *regs)
851{
852 regs->ARM_pc += 2;
853 p->ainsn.insn_handler(p, regs);
854 regs->ARM_cpsr = it_advance(regs->ARM_cpsr);
855}
856
857static void __kprobes thumb32_singlestep(struct kprobe *p, struct pt_regs *regs)
858{
859 regs->ARM_pc += 4;
860 p->ainsn.insn_handler(p, regs);
861 regs->ARM_cpsr = it_advance(regs->ARM_cpsr);
862}
863
864enum kprobe_insn __kprobes
865thumb16_kprobe_decode_insn(kprobe_opcode_t insn, struct arch_specific_insn *asi)
866{
867 asi->insn_singlestep = thumb16_singlestep;
868 asi->insn_check_cc = thumb_check_cc;
869 return kprobe_decode_insn(insn, asi, kprobe_decode_thumb16_table, true);
870}
871
872enum kprobe_insn __kprobes
873thumb32_kprobe_decode_insn(kprobe_opcode_t insn, struct arch_specific_insn *asi)
874{
875 asi->insn_singlestep = thumb32_singlestep;
876 asi->insn_check_cc = thumb_check_cc;
877 return kprobe_decode_insn(insn, asi, kprobe_decode_thumb32_table, true);
878}
diff --git a/arch/arm/kernel/probes-thumb.h b/arch/arm/kernel/probes-thumb.h
new file mode 100644
index 000000000000..98709c40b659
--- /dev/null
+++ b/arch/arm/kernel/probes-thumb.h
@@ -0,0 +1,81 @@
1/*
2 * arch/arm/kernel/probes-thumb.h
3 *
4 * Copyright 2013 Linaro Ltd.
5 * Written by: David A. Long
6 *
7 * The code contained herein is licensed under the GNU General Public
8 * License. You may obtain a copy of the GNU General Public License
9 * Version 2 or later at the following locations:
10 *
11 * http://www.opensource.org/licenses/gpl-license.html
12 * http://www.gnu.org/copyleft/gpl.html
13 */
14
15#ifndef _ARM_KERNEL_PROBES_THUMB_H
16#define _ARM_KERNEL_PROBES_THUMB_H
17
18/*
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
30void __kprobes t16_simulate_bxblx(struct kprobe *p, struct pt_regs *regs);
31void __kprobes t16_simulate_ldr_literal(struct kprobe *p, struct pt_regs *regs);
32void __kprobes t16_simulate_ldrstr_sp_relative(struct kprobe *p,
33 struct pt_regs *regs);
34void __kprobes t16_simulate_reladr(struct kprobe *p, struct pt_regs *regs);
35void __kprobes t16_simulate_add_sp_imm(struct kprobe *p, struct pt_regs *regs);
36void __kprobes t16_simulate_cbz(struct kprobe *p, struct pt_regs *regs);
37void __kprobes t16_simulate_it(struct kprobe *p, struct pt_regs *regs);
38void __kprobes t16_singlestep_it(struct kprobe *p, struct pt_regs *regs);
39enum kprobe_insn __kprobes t16_decode_it(kprobe_opcode_t insn,
40 struct arch_specific_insn *asi);
41void __kprobes t16_simulate_cond_branch(struct kprobe *p, struct pt_regs *regs);
42enum kprobe_insn __kprobes t16_decode_cond_branch(kprobe_opcode_t insn,
43 struct arch_specific_insn *asi);
44void __kprobes t16_simulate_branch(struct kprobe *p, struct pt_regs *regs);
45void __kprobes t16_emulate_loregs_rwflags(struct kprobe *p,
46 struct pt_regs *regs);
47void __kprobes t16_emulate_loregs_noitrwflags(struct kprobe *p,
48 struct pt_regs *regs);
49void __kprobes t16_emulate_hiregs(struct kprobe *p, struct pt_regs *regs);
50enum kprobe_insn __kprobes t16_decode_hiregs(kprobe_opcode_t insn,
51 struct arch_specific_insn *asi);
52void __kprobes t16_emulate_push(struct kprobe *p, struct pt_regs *regs);
53enum kprobe_insn __kprobes t16_decode_push(kprobe_opcode_t insn,
54 struct arch_specific_insn *asi);
55void __kprobes t16_emulate_pop_nopc(struct kprobe *p, struct pt_regs *regs);
56void __kprobes t16_emulate_pop_pc(struct kprobe *p, struct pt_regs *regs);
57enum kprobe_insn __kprobes t16_decode_pop(kprobe_opcode_t insn,
58 struct arch_specific_insn *asi);
59
60void __kprobes t32_simulate_table_branch(struct kprobe *p,
61 struct pt_regs *regs);
62void __kprobes t32_simulate_mrs(struct kprobe *p, struct pt_regs *regs);
63void __kprobes t32_simulate_cond_branch(struct kprobe *p, struct pt_regs *regs);
64enum kprobe_insn __kprobes t32_decode_cond_branch(kprobe_opcode_t insn,
65 struct arch_specific_insn *asi);
66void __kprobes t32_simulate_branch(struct kprobe *p, struct pt_regs *regs);
67void __kprobes t32_simulate_ldr_literal(struct kprobe *p, struct pt_regs *regs);
68enum kprobe_insn __kprobes t32_decode_ldmstm(kprobe_opcode_t insn,
69 struct arch_specific_insn *asi);
70void __kprobes t32_emulate_ldrdstrd(struct kprobe *p, struct pt_regs *regs);
71void __kprobes t32_emulate_ldrstr(struct kprobe *p, struct pt_regs *regs);
72void __kprobes t32_emulate_rd8rn16rm0_rwflags(struct kprobe *p,
73 struct pt_regs *regs);
74void __kprobes t32_emulate_rd8pc16_noflags(struct kprobe *p,
75 struct pt_regs *regs);
76void __kprobes t32_emulate_rd8rn16_noflags(struct kprobe *p,
77 struct pt_regs *regs);
78void __kprobes t32_emulate_rdlo12rdhi8rn16rm0_noflags(struct kprobe *p,
79 struct pt_regs *regs);
80
81#endif