2 * arch/arm/kernel/kprobes-decode.c
4 * Copyright (C) 2006, 2007 Motorola Inc.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
17 * We do not have hardware single-stepping on ARM, This
18 * effort is further complicated by the ARM not having a
19 * "next PC" register. Instructions that change the PC
20 * can't be safely single-stepped in a MP environment, so
21 * we have a lot of work to do:
23 * In the prepare phase:
24 * *) If it is an instruction that does anything
25 * with the CPU mode, we reject it for a kprobe.
26 * (This is out of laziness rather than need. The
27 * instructions could be simulated.)
29 * *) Otherwise, decode the instruction rewriting its
30 * registers to take fixed, ordered registers and
31 * setting a handler for it to run the instruction.
33 * In the execution phase by an instruction's handler:
35 * *) If the PC is written to by the instruction, the
36 * instruction must be fully simulated in software.
38 * *) Otherwise, a modified form of the instruction is
39 * directly executed. Its handler calls the
40 * instruction in insn[0]. In insn[1] is a
41 * "mov pc, lr" to return.
43 * Before calling, load up the reordered registers
44 * from the original instruction's registers. If one
45 * of the original input registers is the PC, compute
46 * and adjust the appropriate input register.
48 * After call completes, copy the output registers to
49 * the original instruction's original registers.
51 * We don't use a real breakpoint instruction since that
52 * would have us in the kernel go from SVC mode to SVC
53 * mode losing the link register. Instead we use an
54 * undefined instruction. To simplify processing, the
55 * undefined instruction used for kprobes must be reserved
56 * exclusively for kprobes use.
58 * TODO: ifdef out some instruction decoding based on architecture.
61 #include <linux/kernel.h>
62 #include <linux/kprobes.h>
63 #include <linux/module.h>
67 #define sign_extend(x, signbit) ((x) | (0 - ((x) & (1 << (signbit)))))
69 #define branch_displacement(insn) sign_extend(((insn) & 0xffffff) << 2, 25)
71 #if __LINUX_ARM_ARCH__ >= 6
72 #define BLX(reg) "blx "reg" \n\t"
74 #define BLX(reg) "mov lr, pc \n\t" \
79 * To avoid the complications of mimicing single-stepping on a
80 * processor without a Next-PC or a single-step mode, and to
81 * avoid having to deal with the side-effects of boosting, we
82 * simulate or emulate (almost) all ARM instructions.
84 * "Simulation" is where the instruction's behavior is duplicated in
85 * C code. "Emulation" is where the original instruction is rewritten
86 * and executed, often by altering its registers.
88 * By having all behavior of the kprobe'd instruction completed before
89 * returning from the kprobe_handler(), all locks (scheduler and
90 * interrupt) can safely be released. There is no need for secondary
91 * breakpoints, no race with MP or preemptable kernels, nor having to
92 * clean up resources counts at a later time impacting overall system
93 * performance. By rewriting the instruction, only the minimum registers
94 * need to be loaded and saved back optimizing performance.
96 * Calling the insnslot_*_rwflags version of a function doesn't hurt
97 * anything even when the CPSR flags aren't updated by the
98 * instruction. It's just a little slower in return for saving
99 * a little space by not having a duplicate function that doesn't
100 * update the flags. (The same optimization can be said for
101 * instructions that do or don't perform register writeback)
102 * Also, instructions can either read the flags, only write the
103 * flags, or read and write the flags. To save combinations
104 * rather than for sheer performance, flag functions just assume
105 * read and write of flags.
108 static void __kprobes simulate_bbl(struct kprobe *p, struct pt_regs *regs)
110 kprobe_opcode_t insn = p->opcode;
111 long iaddr = (long)p->addr;
112 int disp = branch_displacement(insn);
114 if (insn & (1 << 24))
115 regs->ARM_lr = iaddr + 4;
117 regs->ARM_pc = iaddr + 8 + disp;
120 static void __kprobes simulate_blx1(struct kprobe *p, struct pt_regs *regs)
122 kprobe_opcode_t insn = p->opcode;
123 long iaddr = (long)p->addr;
124 int disp = branch_displacement(insn);
126 regs->ARM_lr = iaddr + 4;
127 regs->ARM_pc = iaddr + 8 + disp + ((insn >> 23) & 0x2);
128 regs->ARM_cpsr |= PSR_T_BIT;
131 static void __kprobes simulate_blx2bx(struct kprobe *p, struct pt_regs *regs)
133 kprobe_opcode_t insn = p->opcode;
135 long rmv = regs->uregs[rm];
138 regs->ARM_lr = (long)p->addr + 4;
140 regs->ARM_pc = rmv & ~0x1;
141 regs->ARM_cpsr &= ~PSR_T_BIT;
143 regs->ARM_cpsr |= PSR_T_BIT;
146 static void __kprobes simulate_mrs(struct kprobe *p, struct pt_regs *regs)
148 kprobe_opcode_t insn = p->opcode;
149 int rd = (insn >> 12) & 0xf;
150 unsigned long mask = 0xf8ff03df; /* Mask out execution state */
151 regs->uregs[rd] = regs->ARM_cpsr & mask;
154 static void __kprobes simulate_mov_ipsp(struct kprobe *p, struct pt_regs *regs)
156 regs->uregs[12] = regs->uregs[13];
159 static void __kprobes
160 emulate_ldrdstrd(struct kprobe *p, struct pt_regs *regs)
162 kprobe_opcode_t insn = p->opcode;
163 unsigned long pc = (unsigned long)p->addr + 8;
164 int rt = (insn >> 12) & 0xf;
165 int rn = (insn >> 16) & 0xf;
168 register unsigned long rtv asm("r0") = regs->uregs[rt];
169 register unsigned long rt2v asm("r1") = regs->uregs[rt+1];
170 register unsigned long rnv asm("r2") = (rn == 15) ? pc
172 register unsigned long rmv asm("r3") = regs->uregs[rm];
174 __asm__ __volatile__ (
176 : "=r" (rtv), "=r" (rt2v), "=r" (rnv)
177 : "0" (rtv), "1" (rt2v), "2" (rnv), "r" (rmv),
178 [fn] "r" (p->ainsn.insn_fn)
179 : "lr", "memory", "cc"
182 regs->uregs[rt] = rtv;
183 regs->uregs[rt+1] = rt2v;
184 if (is_writeback(insn))
185 regs->uregs[rn] = rnv;
188 static void __kprobes
189 emulate_ldr(struct kprobe *p, struct pt_regs *regs)
191 kprobe_opcode_t insn = p->opcode;
192 unsigned long pc = (unsigned long)p->addr + 8;
193 int rt = (insn >> 12) & 0xf;
194 int rn = (insn >> 16) & 0xf;
197 register unsigned long rtv asm("r0");
198 register unsigned long rnv asm("r2") = (rn == 15) ? pc
200 register unsigned long rmv asm("r3") = regs->uregs[rm];
202 __asm__ __volatile__ (
204 : "=r" (rtv), "=r" (rnv)
205 : "1" (rnv), "r" (rmv), [fn] "r" (p->ainsn.insn_fn)
206 : "lr", "memory", "cc"
210 load_write_pc(rtv, regs);
212 regs->uregs[rt] = rtv;
214 if (is_writeback(insn))
215 regs->uregs[rn] = rnv;
218 static void __kprobes
219 emulate_str(struct kprobe *p, struct pt_regs *regs)
221 kprobe_opcode_t insn = p->opcode;
222 unsigned long rtpc = (unsigned long)p->addr + str_pc_offset;
223 unsigned long rnpc = (unsigned long)p->addr + 8;
224 int rt = (insn >> 12) & 0xf;
225 int rn = (insn >> 16) & 0xf;
228 register unsigned long rtv asm("r0") = (rt == 15) ? rtpc
230 register unsigned long rnv asm("r2") = (rn == 15) ? rnpc
232 register unsigned long rmv asm("r3") = regs->uregs[rm];
234 __asm__ __volatile__ (
237 : "r" (rtv), "0" (rnv), "r" (rmv), [fn] "r" (p->ainsn.insn_fn)
238 : "lr", "memory", "cc"
241 if (is_writeback(insn))
242 regs->uregs[rn] = rnv;
245 static void __kprobes
246 emulate_rd12rn16rm0rs8_rwflags(struct kprobe *p, struct pt_regs *regs)
248 kprobe_opcode_t insn = p->opcode;
249 unsigned long pc = (unsigned long)p->addr + 8;
250 int rd = (insn >> 12) & 0xf;
251 int rn = (insn >> 16) & 0xf;
253 int rs = (insn >> 8) & 0xf;
255 register unsigned long rdv asm("r0") = regs->uregs[rd];
256 register unsigned long rnv asm("r2") = (rn == 15) ? pc
258 register unsigned long rmv asm("r3") = (rm == 15) ? pc
260 register unsigned long rsv asm("r1") = regs->uregs[rs];
261 unsigned long cpsr = regs->ARM_cpsr;
263 __asm__ __volatile__ (
264 "msr cpsr_fs, %[cpsr] \n\t"
266 "mrs %[cpsr], cpsr \n\t"
267 : "=r" (rdv), [cpsr] "=r" (cpsr)
268 : "0" (rdv), "r" (rnv), "r" (rmv), "r" (rsv),
269 "1" (cpsr), [fn] "r" (p->ainsn.insn_fn)
270 : "lr", "memory", "cc"
274 alu_write_pc(rdv, regs);
276 regs->uregs[rd] = rdv;
277 regs->ARM_cpsr = (regs->ARM_cpsr & ~APSR_MASK) | (cpsr & APSR_MASK);
280 static void __kprobes
281 emulate_rd12rn16rm0_rwflags_nopc(struct kprobe *p, struct pt_regs *regs)
283 kprobe_opcode_t insn = p->opcode;
284 int rd = (insn >> 12) & 0xf;
285 int rn = (insn >> 16) & 0xf;
288 register unsigned long rdv asm("r0") = regs->uregs[rd];
289 register unsigned long rnv asm("r2") = regs->uregs[rn];
290 register unsigned long rmv asm("r3") = regs->uregs[rm];
291 unsigned long cpsr = regs->ARM_cpsr;
293 __asm__ __volatile__ (
294 "msr cpsr_fs, %[cpsr] \n\t"
296 "mrs %[cpsr], cpsr \n\t"
297 : "=r" (rdv), [cpsr] "=r" (cpsr)
298 : "0" (rdv), "r" (rnv), "r" (rmv),
299 "1" (cpsr), [fn] "r" (p->ainsn.insn_fn)
300 : "lr", "memory", "cc"
303 regs->uregs[rd] = rdv;
304 regs->ARM_cpsr = (regs->ARM_cpsr & ~APSR_MASK) | (cpsr & APSR_MASK);
307 static void __kprobes
308 emulate_rd16rn12rm0rs8_rwflags_nopc(struct kprobe *p, struct pt_regs *regs)
310 kprobe_opcode_t insn = p->opcode;
311 int rd = (insn >> 16) & 0xf;
312 int rn = (insn >> 12) & 0xf;
314 int rs = (insn >> 8) & 0xf;
316 register unsigned long rdv asm("r2") = regs->uregs[rd];
317 register unsigned long rnv asm("r0") = regs->uregs[rn];
318 register unsigned long rmv asm("r3") = regs->uregs[rm];
319 register unsigned long rsv asm("r1") = regs->uregs[rs];
320 unsigned long cpsr = regs->ARM_cpsr;
322 __asm__ __volatile__ (
323 "msr cpsr_fs, %[cpsr] \n\t"
325 "mrs %[cpsr], cpsr \n\t"
326 : "=r" (rdv), [cpsr] "=r" (cpsr)
327 : "0" (rdv), "r" (rnv), "r" (rmv), "r" (rsv),
328 "1" (cpsr), [fn] "r" (p->ainsn.insn_fn)
329 : "lr", "memory", "cc"
332 regs->uregs[rd] = rdv;
333 regs->ARM_cpsr = (regs->ARM_cpsr & ~APSR_MASK) | (cpsr & APSR_MASK);
336 static void __kprobes
337 emulate_rd12rm0_noflags_nopc(struct kprobe *p, struct pt_regs *regs)
339 kprobe_opcode_t insn = p->opcode;
340 int rd = (insn >> 12) & 0xf;
343 register unsigned long rdv asm("r0") = regs->uregs[rd];
344 register unsigned long rmv asm("r3") = regs->uregs[rm];
346 __asm__ __volatile__ (
349 : "0" (rdv), "r" (rmv), [fn] "r" (p->ainsn.insn_fn)
350 : "lr", "memory", "cc"
353 regs->uregs[rd] = rdv;
356 static void __kprobes
357 emulate_rdlo12rdhi16rn0rm8_rwflags_nopc(struct kprobe *p, struct pt_regs *regs)
359 kprobe_opcode_t insn = p->opcode;
360 int rdlo = (insn >> 12) & 0xf;
361 int rdhi = (insn >> 16) & 0xf;
363 int rm = (insn >> 8) & 0xf;
365 register unsigned long rdlov asm("r0") = regs->uregs[rdlo];
366 register unsigned long rdhiv asm("r2") = regs->uregs[rdhi];
367 register unsigned long rnv asm("r3") = regs->uregs[rn];
368 register unsigned long rmv asm("r1") = regs->uregs[rm];
369 unsigned long cpsr = regs->ARM_cpsr;
371 __asm__ __volatile__ (
372 "msr cpsr_fs, %[cpsr] \n\t"
374 "mrs %[cpsr], cpsr \n\t"
375 : "=r" (rdlov), "=r" (rdhiv), [cpsr] "=r" (cpsr)
376 : "0" (rdlov), "1" (rdhiv), "r" (rnv), "r" (rmv),
377 "2" (cpsr), [fn] "r" (p->ainsn.insn_fn)
378 : "lr", "memory", "cc"
381 regs->uregs[rdlo] = rdlov;
382 regs->uregs[rdhi] = rdhiv;
383 regs->ARM_cpsr = (regs->ARM_cpsr & ~APSR_MASK) | (cpsr & APSR_MASK);
387 * For the instruction masking and comparisons in all the "space_*"
388 * functions below, Do _not_ rearrange the order of tests unless
389 * you're very, very sure of what you are doing. For the sake of
390 * efficiency, the masks for some tests sometimes assume other test
391 * have been done prior to them so the number of patterns to test
392 * for an instruction set can be as broad as possible to reduce the
393 * number of tests needed.
396 static const union decode_item arm_1111_table[] = {
397 /* Unconditional instructions */
399 /* memory hint 1111 0100 x001 xxxx xxxx xxxx xxxx xxxx */
400 /* PLDI (immediate) 1111 0100 x101 xxxx xxxx xxxx xxxx xxxx */
401 /* PLDW (immediate) 1111 0101 x001 xxxx xxxx xxxx xxxx xxxx */
402 /* PLD (immediate) 1111 0101 x101 xxxx xxxx xxxx xxxx xxxx */
403 DECODE_SIMULATE (0xfe300000, 0xf4100000, kprobe_simulate_nop),
405 /* memory hint 1111 0110 x001 xxxx xxxx xxxx xxx0 xxxx */
406 /* PLDI (register) 1111 0110 x101 xxxx xxxx xxxx xxx0 xxxx */
407 /* PLDW (register) 1111 0111 x001 xxxx xxxx xxxx xxx0 xxxx */
408 /* PLD (register) 1111 0111 x101 xxxx xxxx xxxx xxx0 xxxx */
409 DECODE_SIMULATE (0xfe300010, 0xf6100000, kprobe_simulate_nop),
411 /* BLX (immediate) 1111 101x xxxx xxxx xxxx xxxx xxxx xxxx */
412 DECODE_SIMULATE (0xfe000000, 0xfa000000, simulate_blx1),
414 /* CPS 1111 0001 0000 xxx0 xxxx xxxx xx0x xxxx */
415 /* SETEND 1111 0001 0000 0001 xxxx xxxx 0000 xxxx */
416 /* SRS 1111 100x x1x0 xxxx xxxx xxxx xxxx xxxx */
417 /* RFE 1111 100x x0x1 xxxx xxxx xxxx xxxx xxxx */
419 /* Coprocessor instructions... */
420 /* MCRR2 1111 1100 0100 xxxx xxxx xxxx xxxx xxxx */
421 /* MRRC2 1111 1100 0101 xxxx xxxx xxxx xxxx xxxx */
422 /* LDC2 1111 110x xxx1 xxxx xxxx xxxx xxxx xxxx */
423 /* STC2 1111 110x xxx0 xxxx xxxx xxxx xxxx xxxx */
424 /* CDP2 1111 1110 xxxx xxxx xxxx xxxx xxx0 xxxx */
425 /* MCR2 1111 1110 xxx0 xxxx xxxx xxxx xxx1 xxxx */
426 /* MRC2 1111 1110 xxx1 xxxx xxxx xxxx xxx1 xxxx */
428 /* Other unallocated instructions... */
432 static const union decode_item arm_cccc_0001_0xx0____0xxx_table[] = {
433 /* Miscellaneous instructions */
435 /* MRS cpsr cccc 0001 0000 xxxx xxxx xxxx 0000 xxxx */
436 DECODE_SIMULATEX(0x0ff000f0, 0x01000000, simulate_mrs,
437 REGS(0, NOPC, 0, 0, 0)),
439 /* BX cccc 0001 0010 xxxx xxxx xxxx 0001 xxxx */
440 DECODE_SIMULATE (0x0ff000f0, 0x01200010, simulate_blx2bx),
442 /* BLX (register) cccc 0001 0010 xxxx xxxx xxxx 0011 xxxx */
443 DECODE_SIMULATEX(0x0ff000f0, 0x01200030, simulate_blx2bx,
444 REGS(0, 0, 0, 0, NOPC)),
446 /* CLZ cccc 0001 0110 xxxx xxxx xxxx 0001 xxxx */
447 DECODE_EMULATEX (0x0ff000f0, 0x01600010, emulate_rd12rm0_noflags_nopc,
448 REGS(0, NOPC, 0, 0, NOPC)),
450 /* QADD cccc 0001 0000 xxxx xxxx xxxx 0101 xxxx */
451 /* QSUB cccc 0001 0010 xxxx xxxx xxxx 0101 xxxx */
452 /* QDADD cccc 0001 0100 xxxx xxxx xxxx 0101 xxxx */
453 /* QDSUB cccc 0001 0110 xxxx xxxx xxxx 0101 xxxx */
454 DECODE_EMULATEX (0x0f9000f0, 0x01000050, emulate_rd12rn16rm0_rwflags_nopc,
455 REGS(NOPC, NOPC, 0, 0, NOPC)),
457 /* BXJ cccc 0001 0010 xxxx xxxx xxxx 0010 xxxx */
458 /* MSR cccc 0001 0x10 xxxx xxxx xxxx 0000 xxxx */
459 /* MRS spsr cccc 0001 0100 xxxx xxxx xxxx 0000 xxxx */
460 /* BKPT 1110 0001 0010 xxxx xxxx xxxx 0111 xxxx */
461 /* SMC cccc 0001 0110 xxxx xxxx xxxx 0111 xxxx */
462 /* And unallocated instructions... */
466 static const union decode_item arm_cccc_0001_0xx0____1xx0_table[] = {
467 /* Halfword multiply and multiply-accumulate */
469 /* SMLALxy cccc 0001 0100 xxxx xxxx xxxx 1xx0 xxxx */
470 DECODE_EMULATEX (0x0ff00090, 0x01400080, emulate_rdlo12rdhi16rn0rm8_rwflags_nopc,
471 REGS(NOPC, NOPC, NOPC, 0, NOPC)),
473 /* SMULWy cccc 0001 0010 xxxx xxxx xxxx 1x10 xxxx */
474 DECODE_OR (0x0ff000b0, 0x012000a0),
475 /* SMULxy cccc 0001 0110 xxxx xxxx xxxx 1xx0 xxxx */
476 DECODE_EMULATEX (0x0ff00090, 0x01600080, emulate_rd16rn12rm0rs8_rwflags_nopc,
477 REGS(NOPC, 0, NOPC, 0, NOPC)),
479 /* SMLAxy cccc 0001 0000 xxxx xxxx xxxx 1xx0 xxxx */
480 DECODE_OR (0x0ff00090, 0x01000080),
481 /* SMLAWy cccc 0001 0010 xxxx xxxx xxxx 1x00 xxxx */
482 DECODE_EMULATEX (0x0ff000b0, 0x01200080, emulate_rd16rn12rm0rs8_rwflags_nopc,
483 REGS(NOPC, NOPC, NOPC, 0, NOPC)),
488 static const union decode_item arm_cccc_0000_____1001_table[] = {
489 /* Multiply and multiply-accumulate */
491 /* MUL cccc 0000 0000 xxxx xxxx xxxx 1001 xxxx */
492 /* MULS cccc 0000 0001 xxxx xxxx xxxx 1001 xxxx */
493 DECODE_EMULATEX (0x0fe000f0, 0x00000090, emulate_rd16rn12rm0rs8_rwflags_nopc,
494 REGS(NOPC, 0, NOPC, 0, NOPC)),
496 /* MLA cccc 0000 0010 xxxx xxxx xxxx 1001 xxxx */
497 /* MLAS cccc 0000 0011 xxxx xxxx xxxx 1001 xxxx */
498 DECODE_OR (0x0fe000f0, 0x00200090),
499 /* MLS cccc 0000 0110 xxxx xxxx xxxx 1001 xxxx */
500 DECODE_EMULATEX (0x0ff000f0, 0x00600090, emulate_rd16rn12rm0rs8_rwflags_nopc,
501 REGS(NOPC, NOPC, NOPC, 0, NOPC)),
503 /* UMAAL cccc 0000 0100 xxxx xxxx xxxx 1001 xxxx */
504 DECODE_OR (0x0ff000f0, 0x00400090),
505 /* UMULL cccc 0000 1000 xxxx xxxx xxxx 1001 xxxx */
506 /* UMULLS cccc 0000 1001 xxxx xxxx xxxx 1001 xxxx */
507 /* UMLAL cccc 0000 1010 xxxx xxxx xxxx 1001 xxxx */
508 /* UMLALS cccc 0000 1011 xxxx xxxx xxxx 1001 xxxx */
509 /* SMULL cccc 0000 1100 xxxx xxxx xxxx 1001 xxxx */
510 /* SMULLS cccc 0000 1101 xxxx xxxx xxxx 1001 xxxx */
511 /* SMLAL cccc 0000 1110 xxxx xxxx xxxx 1001 xxxx */
512 /* SMLALS cccc 0000 1111 xxxx xxxx xxxx 1001 xxxx */
513 DECODE_EMULATEX (0x0f8000f0, 0x00800090, emulate_rdlo12rdhi16rn0rm8_rwflags_nopc,
514 REGS(NOPC, NOPC, NOPC, 0, NOPC)),
519 static const union decode_item arm_cccc_0001_____1001_table[] = {
520 /* Synchronization primitives */
522 /* SMP/SWPB cccc 0001 0x00 xxxx xxxx xxxx 1001 xxxx */
523 DECODE_EMULATEX (0x0fb000f0, 0x01000090, emulate_rd12rn16rm0_rwflags_nopc,
524 REGS(NOPC, NOPC, 0, 0, NOPC)),
526 /* LDREX/STREX{,D,B,H} cccc 0001 1xxx xxxx xxxx xxxx 1001 xxxx */
527 /* And unallocated instructions... */
531 static const union decode_item arm_cccc_000x_____1xx1_table[] = {
532 /* Extra load/store instructions */
534 /* STRHT cccc 0000 xx10 xxxx xxxx xxxx 1011 xxxx */
535 /* ??? cccc 0000 xx10 xxxx xxxx xxxx 11x1 xxxx */
536 /* LDRHT cccc 0000 xx11 xxxx xxxx xxxx 1011 xxxx */
537 /* LDRSBT cccc 0000 xx11 xxxx xxxx xxxx 1101 xxxx */
538 /* LDRSHT cccc 0000 xx11 xxxx xxxx xxxx 1111 xxxx */
539 DECODE_REJECT (0x0f200090, 0x00200090),
541 /* LDRD/STRD lr,pc,{... cccc 000x x0x0 xxxx 111x xxxx 1101 xxxx */
542 DECODE_REJECT (0x0e10e0d0, 0x0000e0d0),
544 /* LDRD (register) cccc 000x x0x0 xxxx xxxx xxxx 1101 xxxx */
545 /* STRD (register) cccc 000x x0x0 xxxx xxxx xxxx 1111 xxxx */
546 DECODE_EMULATEX (0x0e5000d0, 0x000000d0, emulate_ldrdstrd,
547 REGS(NOPCWB, NOPCX, 0, 0, NOPC)),
549 /* LDRD (immediate) cccc 000x x1x0 xxxx xxxx xxxx 1101 xxxx */
550 /* STRD (immediate) cccc 000x x1x0 xxxx xxxx xxxx 1111 xxxx */
551 DECODE_EMULATEX (0x0e5000d0, 0x004000d0, emulate_ldrdstrd,
552 REGS(NOPCWB, NOPCX, 0, 0, 0)),
554 /* STRH (register) cccc 000x x0x0 xxxx xxxx xxxx 1011 xxxx */
555 DECODE_EMULATEX (0x0e5000f0, 0x000000b0, emulate_str,
556 REGS(NOPCWB, NOPC, 0, 0, NOPC)),
558 /* LDRH (register) cccc 000x x0x1 xxxx xxxx xxxx 1011 xxxx */
559 /* LDRSB (register) cccc 000x x0x1 xxxx xxxx xxxx 1101 xxxx */
560 /* LDRSH (register) cccc 000x x0x1 xxxx xxxx xxxx 1111 xxxx */
561 DECODE_EMULATEX (0x0e500090, 0x00100090, emulate_ldr,
562 REGS(NOPCWB, NOPC, 0, 0, NOPC)),
564 /* STRH (immediate) cccc 000x x1x0 xxxx xxxx xxxx 1011 xxxx */
565 DECODE_EMULATEX (0x0e5000f0, 0x004000b0, emulate_str,
566 REGS(NOPCWB, NOPC, 0, 0, 0)),
568 /* LDRH (immediate) cccc 000x x1x1 xxxx xxxx xxxx 1011 xxxx */
569 /* LDRSB (immediate) cccc 000x x1x1 xxxx xxxx xxxx 1101 xxxx */
570 /* LDRSH (immediate) cccc 000x x1x1 xxxx xxxx xxxx 1111 xxxx */
571 DECODE_EMULATEX (0x0e500090, 0x00500090, emulate_ldr,
572 REGS(NOPCWB, NOPC, 0, 0, 0)),
577 static const union decode_item arm_cccc_000x_table[] = {
578 /* Data-processing (register) */
580 /* <op>S PC, ... cccc 000x xxx1 xxxx 1111 xxxx xxxx xxxx */
581 DECODE_REJECT (0x0e10f000, 0x0010f000),
583 /* MOV IP, SP 1110 0001 1010 0000 1100 0000 0000 1101 */
584 DECODE_SIMULATE (0xffffffff, 0xe1a0c00d, simulate_mov_ipsp),
586 /* TST (register) cccc 0001 0001 xxxx xxxx xxxx xxx0 xxxx */
587 /* TEQ (register) cccc 0001 0011 xxxx xxxx xxxx xxx0 xxxx */
588 /* CMP (register) cccc 0001 0101 xxxx xxxx xxxx xxx0 xxxx */
589 /* CMN (register) cccc 0001 0111 xxxx xxxx xxxx xxx0 xxxx */
590 DECODE_EMULATEX (0x0f900010, 0x01100000, emulate_rd12rn16rm0rs8_rwflags,
591 REGS(ANY, 0, 0, 0, ANY)),
593 /* MOV (register) cccc 0001 101x xxxx xxxx xxxx xxx0 xxxx */
594 /* MVN (register) cccc 0001 111x xxxx xxxx xxxx xxx0 xxxx */
595 DECODE_EMULATEX (0x0fa00010, 0x01a00000, emulate_rd12rn16rm0rs8_rwflags,
596 REGS(0, ANY, 0, 0, ANY)),
598 /* AND (register) cccc 0000 000x xxxx xxxx xxxx xxx0 xxxx */
599 /* EOR (register) cccc 0000 001x xxxx xxxx xxxx xxx0 xxxx */
600 /* SUB (register) cccc 0000 010x xxxx xxxx xxxx xxx0 xxxx */
601 /* RSB (register) cccc 0000 011x xxxx xxxx xxxx xxx0 xxxx */
602 /* ADD (register) cccc 0000 100x xxxx xxxx xxxx xxx0 xxxx */
603 /* ADC (register) cccc 0000 101x xxxx xxxx xxxx xxx0 xxxx */
604 /* SBC (register) cccc 0000 110x xxxx xxxx xxxx xxx0 xxxx */
605 /* RSC (register) cccc 0000 111x xxxx xxxx xxxx xxx0 xxxx */
606 /* ORR (register) cccc 0001 100x xxxx xxxx xxxx xxx0 xxxx */
607 /* BIC (register) cccc 0001 110x xxxx xxxx xxxx xxx0 xxxx */
608 DECODE_EMULATEX (0x0e000010, 0x00000000, emulate_rd12rn16rm0rs8_rwflags,
609 REGS(ANY, ANY, 0, 0, ANY)),
611 /* TST (reg-shift reg) cccc 0001 0001 xxxx xxxx xxxx 0xx1 xxxx */
612 /* TEQ (reg-shift reg) cccc 0001 0011 xxxx xxxx xxxx 0xx1 xxxx */
613 /* CMP (reg-shift reg) cccc 0001 0101 xxxx xxxx xxxx 0xx1 xxxx */
614 /* CMN (reg-shift reg) cccc 0001 0111 xxxx xxxx xxxx 0xx1 xxxx */
615 DECODE_EMULATEX (0x0f900090, 0x01100010, emulate_rd12rn16rm0rs8_rwflags,
616 REGS(ANY, 0, NOPC, 0, ANY)),
618 /* MOV (reg-shift reg) cccc 0001 101x xxxx xxxx xxxx 0xx1 xxxx */
619 /* MVN (reg-shift reg) cccc 0001 111x xxxx xxxx xxxx 0xx1 xxxx */
620 DECODE_EMULATEX (0x0fa00090, 0x01a00010, emulate_rd12rn16rm0rs8_rwflags,
621 REGS(0, ANY, NOPC, 0, ANY)),
623 /* AND (reg-shift reg) cccc 0000 000x xxxx xxxx xxxx 0xx1 xxxx */
624 /* EOR (reg-shift reg) cccc 0000 001x xxxx xxxx xxxx 0xx1 xxxx */
625 /* SUB (reg-shift reg) cccc 0000 010x xxxx xxxx xxxx 0xx1 xxxx */
626 /* RSB (reg-shift reg) cccc 0000 011x xxxx xxxx xxxx 0xx1 xxxx */
627 /* ADD (reg-shift reg) cccc 0000 100x xxxx xxxx xxxx 0xx1 xxxx */
628 /* ADC (reg-shift reg) cccc 0000 101x xxxx xxxx xxxx 0xx1 xxxx */
629 /* SBC (reg-shift reg) cccc 0000 110x xxxx xxxx xxxx 0xx1 xxxx */
630 /* RSC (reg-shift reg) cccc 0000 111x xxxx xxxx xxxx 0xx1 xxxx */
631 /* ORR (reg-shift reg) cccc 0001 100x xxxx xxxx xxxx 0xx1 xxxx */
632 /* BIC (reg-shift reg) cccc 0001 110x xxxx xxxx xxxx 0xx1 xxxx */
633 DECODE_EMULATEX (0x0e000090, 0x00000010, emulate_rd12rn16rm0rs8_rwflags,
634 REGS(ANY, ANY, NOPC, 0, ANY)),
639 static const union decode_item arm_cccc_001x_table[] = {
640 /* Data-processing (immediate) */
642 /* MOVW cccc 0011 0000 xxxx xxxx xxxx xxxx xxxx */
643 /* MOVT cccc 0011 0100 xxxx xxxx xxxx xxxx xxxx */
644 DECODE_EMULATEX (0x0fb00000, 0x03000000, emulate_rd12rm0_noflags_nopc,
645 REGS(0, NOPC, 0, 0, 0)),
647 /* YIELD cccc 0011 0010 0000 xxxx xxxx 0000 0001 */
648 DECODE_OR (0x0fff00ff, 0x03200001),
649 /* SEV cccc 0011 0010 0000 xxxx xxxx 0000 0100 */
650 DECODE_EMULATE (0x0fff00ff, 0x03200004, kprobe_emulate_none),
651 /* NOP cccc 0011 0010 0000 xxxx xxxx 0000 0000 */
652 /* WFE cccc 0011 0010 0000 xxxx xxxx 0000 0010 */
653 /* WFI cccc 0011 0010 0000 xxxx xxxx 0000 0011 */
654 DECODE_SIMULATE (0x0fff00fc, 0x03200000, kprobe_simulate_nop),
655 /* DBG cccc 0011 0010 0000 xxxx xxxx ffff xxxx */
656 /* unallocated hints cccc 0011 0010 0000 xxxx xxxx xxxx xxxx */
657 /* MSR (immediate) cccc 0011 0x10 xxxx xxxx xxxx xxxx xxxx */
658 DECODE_REJECT (0x0fb00000, 0x03200000),
660 /* <op>S PC, ... cccc 001x xxx1 xxxx 1111 xxxx xxxx xxxx */
661 DECODE_REJECT (0x0e10f000, 0x0210f000),
663 /* TST (immediate) cccc 0011 0001 xxxx xxxx xxxx xxxx xxxx */
664 /* TEQ (immediate) cccc 0011 0011 xxxx xxxx xxxx xxxx xxxx */
665 /* CMP (immediate) cccc 0011 0101 xxxx xxxx xxxx xxxx xxxx */
666 /* CMN (immediate) cccc 0011 0111 xxxx xxxx xxxx xxxx xxxx */
667 DECODE_EMULATEX (0x0f900000, 0x03100000, emulate_rd12rn16rm0rs8_rwflags,
668 REGS(ANY, 0, 0, 0, 0)),
670 /* MOV (immediate) cccc 0011 101x xxxx xxxx xxxx xxxx xxxx */
671 /* MVN (immediate) cccc 0011 111x xxxx xxxx xxxx xxxx xxxx */
672 DECODE_EMULATEX (0x0fa00000, 0x03a00000, emulate_rd12rn16rm0rs8_rwflags,
673 REGS(0, ANY, 0, 0, 0)),
675 /* AND (immediate) cccc 0010 000x xxxx xxxx xxxx xxxx xxxx */
676 /* EOR (immediate) cccc 0010 001x xxxx xxxx xxxx xxxx xxxx */
677 /* SUB (immediate) cccc 0010 010x xxxx xxxx xxxx xxxx xxxx */
678 /* RSB (immediate) cccc 0010 011x xxxx xxxx xxxx xxxx xxxx */
679 /* ADD (immediate) cccc 0010 100x xxxx xxxx xxxx xxxx xxxx */
680 /* ADC (immediate) cccc 0010 101x xxxx xxxx xxxx xxxx xxxx */
681 /* SBC (immediate) cccc 0010 110x xxxx xxxx xxxx xxxx xxxx */
682 /* RSC (immediate) cccc 0010 111x xxxx xxxx xxxx xxxx xxxx */
683 /* ORR (immediate) cccc 0011 100x xxxx xxxx xxxx xxxx xxxx */
684 /* BIC (immediate) cccc 0011 110x xxxx xxxx xxxx xxxx xxxx */
685 DECODE_EMULATEX (0x0e000000, 0x02000000, emulate_rd12rn16rm0rs8_rwflags,
686 REGS(ANY, ANY, 0, 0, 0)),
691 static const union decode_item arm_cccc_0110_____xxx1_table[] = {
692 /* Media instructions */
694 /* SEL cccc 0110 1000 xxxx xxxx xxxx 1011 xxxx */
695 DECODE_EMULATEX (0x0ff000f0, 0x068000b0, emulate_rd12rn16rm0_rwflags_nopc,
696 REGS(NOPC, NOPC, 0, 0, NOPC)),
698 /* SSAT cccc 0110 101x xxxx xxxx xxxx xx01 xxxx */
699 /* USAT cccc 0110 111x xxxx xxxx xxxx xx01 xxxx */
700 DECODE_OR(0x0fa00030, 0x06a00010),
701 /* SSAT16 cccc 0110 1010 xxxx xxxx xxxx 0011 xxxx */
702 /* USAT16 cccc 0110 1110 xxxx xxxx xxxx 0011 xxxx */
703 DECODE_EMULATEX (0x0fb000f0, 0x06a00030, emulate_rd12rn16rm0_rwflags_nopc,
704 REGS(0, NOPC, 0, 0, NOPC)),
706 /* REV cccc 0110 1011 xxxx xxxx xxxx 0011 xxxx */
707 /* REV16 cccc 0110 1011 xxxx xxxx xxxx 1011 xxxx */
708 /* RBIT cccc 0110 1111 xxxx xxxx xxxx 0011 xxxx */
709 /* REVSH cccc 0110 1111 xxxx xxxx xxxx 1011 xxxx */
710 DECODE_EMULATEX (0x0fb00070, 0x06b00030, emulate_rd12rm0_noflags_nopc,
711 REGS(0, NOPC, 0, 0, NOPC)),
713 /* ??? cccc 0110 0x00 xxxx xxxx xxxx xxx1 xxxx */
714 DECODE_REJECT (0x0fb00010, 0x06000010),
715 /* ??? cccc 0110 0xxx xxxx xxxx xxxx 1011 xxxx */
716 DECODE_REJECT (0x0f8000f0, 0x060000b0),
717 /* ??? cccc 0110 0xxx xxxx xxxx xxxx 1101 xxxx */
718 DECODE_REJECT (0x0f8000f0, 0x060000d0),
719 /* SADD16 cccc 0110 0001 xxxx xxxx xxxx 0001 xxxx */
720 /* SADDSUBX cccc 0110 0001 xxxx xxxx xxxx 0011 xxxx */
721 /* SSUBADDX cccc 0110 0001 xxxx xxxx xxxx 0101 xxxx */
722 /* SSUB16 cccc 0110 0001 xxxx xxxx xxxx 0111 xxxx */
723 /* SADD8 cccc 0110 0001 xxxx xxxx xxxx 1001 xxxx */
724 /* SSUB8 cccc 0110 0001 xxxx xxxx xxxx 1111 xxxx */
725 /* QADD16 cccc 0110 0010 xxxx xxxx xxxx 0001 xxxx */
726 /* QADDSUBX cccc 0110 0010 xxxx xxxx xxxx 0011 xxxx */
727 /* QSUBADDX cccc 0110 0010 xxxx xxxx xxxx 0101 xxxx */
728 /* QSUB16 cccc 0110 0010 xxxx xxxx xxxx 0111 xxxx */
729 /* QADD8 cccc 0110 0010 xxxx xxxx xxxx 1001 xxxx */
730 /* QSUB8 cccc 0110 0010 xxxx xxxx xxxx 1111 xxxx */
731 /* SHADD16 cccc 0110 0011 xxxx xxxx xxxx 0001 xxxx */
732 /* SHADDSUBX cccc 0110 0011 xxxx xxxx xxxx 0011 xxxx */
733 /* SHSUBADDX cccc 0110 0011 xxxx xxxx xxxx 0101 xxxx */
734 /* SHSUB16 cccc 0110 0011 xxxx xxxx xxxx 0111 xxxx */
735 /* SHADD8 cccc 0110 0011 xxxx xxxx xxxx 1001 xxxx */
736 /* SHSUB8 cccc 0110 0011 xxxx xxxx xxxx 1111 xxxx */
737 /* UADD16 cccc 0110 0101 xxxx xxxx xxxx 0001 xxxx */
738 /* UADDSUBX cccc 0110 0101 xxxx xxxx xxxx 0011 xxxx */
739 /* USUBADDX cccc 0110 0101 xxxx xxxx xxxx 0101 xxxx */
740 /* USUB16 cccc 0110 0101 xxxx xxxx xxxx 0111 xxxx */
741 /* UADD8 cccc 0110 0101 xxxx xxxx xxxx 1001 xxxx */
742 /* USUB8 cccc 0110 0101 xxxx xxxx xxxx 1111 xxxx */
743 /* UQADD16 cccc 0110 0110 xxxx xxxx xxxx 0001 xxxx */
744 /* UQADDSUBX cccc 0110 0110 xxxx xxxx xxxx 0011 xxxx */
745 /* UQSUBADDX cccc 0110 0110 xxxx xxxx xxxx 0101 xxxx */
746 /* UQSUB16 cccc 0110 0110 xxxx xxxx xxxx 0111 xxxx */
747 /* UQADD8 cccc 0110 0110 xxxx xxxx xxxx 1001 xxxx */
748 /* UQSUB8 cccc 0110 0110 xxxx xxxx xxxx 1111 xxxx */
749 /* UHADD16 cccc 0110 0111 xxxx xxxx xxxx 0001 xxxx */
750 /* UHADDSUBX cccc 0110 0111 xxxx xxxx xxxx 0011 xxxx */
751 /* UHSUBADDX cccc 0110 0111 xxxx xxxx xxxx 0101 xxxx */
752 /* UHSUB16 cccc 0110 0111 xxxx xxxx xxxx 0111 xxxx */
753 /* UHADD8 cccc 0110 0111 xxxx xxxx xxxx 1001 xxxx */
754 /* UHSUB8 cccc 0110 0111 xxxx xxxx xxxx 1111 xxxx */
755 DECODE_EMULATEX (0x0f800010, 0x06000010, emulate_rd12rn16rm0_rwflags_nopc,
756 REGS(NOPC, NOPC, 0, 0, NOPC)),
758 /* PKHBT cccc 0110 1000 xxxx xxxx xxxx x001 xxxx */
759 /* PKHTB cccc 0110 1000 xxxx xxxx xxxx x101 xxxx */
760 DECODE_EMULATEX (0x0ff00030, 0x06800010, emulate_rd12rn16rm0_rwflags_nopc,
761 REGS(NOPC, NOPC, 0, 0, NOPC)),
763 /* ??? cccc 0110 1001 xxxx xxxx xxxx 0111 xxxx */
764 /* ??? cccc 0110 1101 xxxx xxxx xxxx 0111 xxxx */
765 DECODE_REJECT (0x0fb000f0, 0x06900070),
767 /* SXTB16 cccc 0110 1000 1111 xxxx xxxx 0111 xxxx */
768 /* SXTB cccc 0110 1010 1111 xxxx xxxx 0111 xxxx */
769 /* SXTH cccc 0110 1011 1111 xxxx xxxx 0111 xxxx */
770 /* UXTB16 cccc 0110 1100 1111 xxxx xxxx 0111 xxxx */
771 /* UXTB cccc 0110 1110 1111 xxxx xxxx 0111 xxxx */
772 /* UXTH cccc 0110 1111 1111 xxxx xxxx 0111 xxxx */
773 DECODE_EMULATEX (0x0f8f00f0, 0x068f0070, emulate_rd12rm0_noflags_nopc,
774 REGS(0, NOPC, 0, 0, NOPC)),
776 /* SXTAB16 cccc 0110 1000 xxxx xxxx xxxx 0111 xxxx */
777 /* SXTAB cccc 0110 1010 xxxx xxxx xxxx 0111 xxxx */
778 /* SXTAH cccc 0110 1011 xxxx xxxx xxxx 0111 xxxx */
779 /* UXTAB16 cccc 0110 1100 xxxx xxxx xxxx 0111 xxxx */
780 /* UXTAB cccc 0110 1110 xxxx xxxx xxxx 0111 xxxx */
781 /* UXTAH cccc 0110 1111 xxxx xxxx xxxx 0111 xxxx */
782 DECODE_EMULATEX (0x0f8000f0, 0x06800070, emulate_rd12rn16rm0_rwflags_nopc,
783 REGS(NOPCX, NOPC, 0, 0, NOPC)),
788 static const union decode_item arm_cccc_0111_____xxx1_table[] = {
789 /* Media instructions */
791 /* UNDEFINED cccc 0111 1111 xxxx xxxx xxxx 1111 xxxx */
792 DECODE_REJECT (0x0ff000f0, 0x07f000f0),
794 /* SMLALD cccc 0111 0100 xxxx xxxx xxxx 00x1 xxxx */
795 /* SMLSLD cccc 0111 0100 xxxx xxxx xxxx 01x1 xxxx */
796 DECODE_EMULATEX (0x0ff00090, 0x07400010, emulate_rdlo12rdhi16rn0rm8_rwflags_nopc,
797 REGS(NOPC, NOPC, NOPC, 0, NOPC)),
799 /* SMUAD cccc 0111 0000 xxxx 1111 xxxx 00x1 xxxx */
800 /* SMUSD cccc 0111 0000 xxxx 1111 xxxx 01x1 xxxx */
801 DECODE_OR (0x0ff0f090, 0x0700f010),
802 /* SMMUL cccc 0111 0101 xxxx 1111 xxxx 00x1 xxxx */
803 DECODE_OR (0x0ff0f0d0, 0x0750f010),
804 /* USAD8 cccc 0111 1000 xxxx 1111 xxxx 0001 xxxx */
805 DECODE_EMULATEX (0x0ff0f0f0, 0x0780f010, emulate_rd16rn12rm0rs8_rwflags_nopc,
806 REGS(NOPC, 0, NOPC, 0, NOPC)),
808 /* SMLAD cccc 0111 0000 xxxx xxxx xxxx 00x1 xxxx */
809 /* SMLSD cccc 0111 0000 xxxx xxxx xxxx 01x1 xxxx */
810 DECODE_OR (0x0ff00090, 0x07000010),
811 /* SMMLA cccc 0111 0101 xxxx xxxx xxxx 00x1 xxxx */
812 DECODE_OR (0x0ff000d0, 0x07500010),
813 /* USADA8 cccc 0111 1000 xxxx xxxx xxxx 0001 xxxx */
814 DECODE_EMULATEX (0x0ff000f0, 0x07800010, emulate_rd16rn12rm0rs8_rwflags_nopc,
815 REGS(NOPC, NOPCX, NOPC, 0, NOPC)),
817 /* SMMLS cccc 0111 0101 xxxx xxxx xxxx 11x1 xxxx */
818 DECODE_EMULATEX (0x0ff000d0, 0x075000d0, emulate_rd16rn12rm0rs8_rwflags_nopc,
819 REGS(NOPC, NOPC, NOPC, 0, NOPC)),
821 /* SBFX cccc 0111 101x xxxx xxxx xxxx x101 xxxx */
822 /* UBFX cccc 0111 111x xxxx xxxx xxxx x101 xxxx */
823 DECODE_EMULATEX (0x0fa00070, 0x07a00050, emulate_rd12rm0_noflags_nopc,
824 REGS(0, NOPC, 0, 0, NOPC)),
826 /* BFC cccc 0111 110x xxxx xxxx xxxx x001 1111 */
827 DECODE_EMULATEX (0x0fe0007f, 0x07c0001f, emulate_rd12rm0_noflags_nopc,
828 REGS(0, NOPC, 0, 0, 0)),
830 /* BFI cccc 0111 110x xxxx xxxx xxxx x001 xxxx */
831 DECODE_EMULATEX (0x0fe00070, 0x07c00010, emulate_rd12rm0_noflags_nopc,
832 REGS(0, NOPC, 0, 0, NOPCX)),
837 static const union decode_item arm_cccc_01xx_table[] = {
838 /* Load/store word and unsigned byte */
840 /* LDRB/STRB pc,[...] cccc 01xx x0xx xxxx xxxx xxxx xxxx xxxx */
841 DECODE_REJECT (0x0c40f000, 0x0440f000),
843 /* STRT cccc 01x0 x010 xxxx xxxx xxxx xxxx xxxx */
844 /* LDRT cccc 01x0 x011 xxxx xxxx xxxx xxxx xxxx */
845 /* STRBT cccc 01x0 x110 xxxx xxxx xxxx xxxx xxxx */
846 /* LDRBT cccc 01x0 x111 xxxx xxxx xxxx xxxx xxxx */
847 DECODE_REJECT (0x0d200000, 0x04200000),
849 /* STR (immediate) cccc 010x x0x0 xxxx xxxx xxxx xxxx xxxx */
850 /* STRB (immediate) cccc 010x x1x0 xxxx xxxx xxxx xxxx xxxx */
851 DECODE_EMULATEX (0x0e100000, 0x04000000, emulate_str,
852 REGS(NOPCWB, ANY, 0, 0, 0)),
854 /* LDR (immediate) cccc 010x x0x1 xxxx xxxx xxxx xxxx xxxx */
855 /* LDRB (immediate) cccc 010x x1x1 xxxx xxxx xxxx xxxx xxxx */
856 DECODE_EMULATEX (0x0e100000, 0x04100000, emulate_ldr,
857 REGS(NOPCWB, ANY, 0, 0, 0)),
859 /* STR (register) cccc 011x x0x0 xxxx xxxx xxxx xxxx xxxx */
860 /* STRB (register) cccc 011x x1x0 xxxx xxxx xxxx xxxx xxxx */
861 DECODE_EMULATEX (0x0e100000, 0x06000000, emulate_str,
862 REGS(NOPCWB, ANY, 0, 0, NOPC)),
864 /* LDR (register) cccc 011x x0x1 xxxx xxxx xxxx xxxx xxxx */
865 /* LDRB (register) cccc 011x x1x1 xxxx xxxx xxxx xxxx xxxx */
866 DECODE_EMULATEX (0x0e100000, 0x06100000, emulate_ldr,
867 REGS(NOPCWB, ANY, 0, 0, NOPC)),
872 static const union decode_item arm_cccc_100x_table[] = {
873 /* Block data transfer instructions */
875 /* LDM cccc 100x x0x1 xxxx xxxx xxxx xxxx xxxx */
876 /* STM cccc 100x x0x0 xxxx xxxx xxxx xxxx xxxx */
877 DECODE_CUSTOM (0x0e400000, 0x08000000, kprobe_decode_ldmstm),
879 /* STM (user registers) cccc 100x x1x0 xxxx xxxx xxxx xxxx xxxx */
880 /* LDM (user registers) cccc 100x x1x1 xxxx 0xxx xxxx xxxx xxxx */
881 /* LDM (exception ret) cccc 100x x1x1 xxxx 1xxx xxxx xxxx xxxx */
885 const union decode_item kprobe_decode_arm_table[] = {
887 * Unconditional instructions
888 * 1111 xxxx xxxx xxxx xxxx xxxx xxxx xxxx
890 DECODE_TABLE (0xf0000000, 0xf0000000, arm_1111_table),
893 * Miscellaneous instructions
894 * cccc 0001 0xx0 xxxx xxxx xxxx 0xxx xxxx
896 DECODE_TABLE (0x0f900080, 0x01000000, arm_cccc_0001_0xx0____0xxx_table),
899 * Halfword multiply and multiply-accumulate
900 * cccc 0001 0xx0 xxxx xxxx xxxx 1xx0 xxxx
902 DECODE_TABLE (0x0f900090, 0x01000080, arm_cccc_0001_0xx0____1xx0_table),
905 * Multiply and multiply-accumulate
906 * cccc 0000 xxxx xxxx xxxx xxxx 1001 xxxx
908 DECODE_TABLE (0x0f0000f0, 0x00000090, arm_cccc_0000_____1001_table),
911 * Synchronization primitives
912 * cccc 0001 xxxx xxxx xxxx xxxx 1001 xxxx
914 DECODE_TABLE (0x0f0000f0, 0x01000090, arm_cccc_0001_____1001_table),
917 * Extra load/store instructions
918 * cccc 000x xxxx xxxx xxxx xxxx 1xx1 xxxx
920 DECODE_TABLE (0x0e000090, 0x00000090, arm_cccc_000x_____1xx1_table),
923 * Data-processing (register)
924 * cccc 000x xxxx xxxx xxxx xxxx xxx0 xxxx
925 * Data-processing (register-shifted register)
926 * cccc 000x xxxx xxxx xxxx xxxx 0xx1 xxxx
928 DECODE_TABLE (0x0e000000, 0x00000000, arm_cccc_000x_table),
931 * Data-processing (immediate)
932 * cccc 001x xxxx xxxx xxxx xxxx xxxx xxxx
934 DECODE_TABLE (0x0e000000, 0x02000000, arm_cccc_001x_table),
938 * cccc 011x xxxx xxxx xxxx xxxx xxx1 xxxx
940 DECODE_TABLE (0x0f000010, 0x06000010, arm_cccc_0110_____xxx1_table),
941 DECODE_TABLE (0x0f000010, 0x07000010, arm_cccc_0111_____xxx1_table),
944 * Load/store word and unsigned byte
945 * cccc 01xx xxxx xxxx xxxx xxxx xxxx xxxx
947 DECODE_TABLE (0x0c000000, 0x04000000, arm_cccc_01xx_table),
950 * Block data transfer instructions
951 * cccc 100x xxxx xxxx xxxx xxxx xxxx xxxx
953 DECODE_TABLE (0x0e000000, 0x08000000, arm_cccc_100x_table),
955 /* B cccc 1010 xxxx xxxx xxxx xxxx xxxx xxxx */
956 /* BL cccc 1011 xxxx xxxx xxxx xxxx xxxx xxxx */
957 DECODE_SIMULATE (0x0e000000, 0x0a000000, simulate_bbl),
960 * Supervisor Call, and coprocessor instructions
963 /* MCRR cccc 1100 0100 xxxx xxxx xxxx xxxx xxxx */
964 /* MRRC cccc 1100 0101 xxxx xxxx xxxx xxxx xxxx */
965 /* LDC cccc 110x xxx1 xxxx xxxx xxxx xxxx xxxx */
966 /* STC cccc 110x xxx0 xxxx xxxx xxxx xxxx xxxx */
967 /* CDP cccc 1110 xxxx xxxx xxxx xxxx xxx0 xxxx */
968 /* MCR cccc 1110 xxx0 xxxx xxxx xxxx xxx1 xxxx */
969 /* MRC cccc 1110 xxx1 xxxx xxxx xxxx xxx1 xxxx */
970 /* SVC cccc 1111 xxxx xxxx xxxx xxxx xxxx xxxx */
971 DECODE_REJECT (0x0c000000, 0x0c000000),
975 #ifdef CONFIG_ARM_KPROBES_TEST_MODULE
976 EXPORT_SYMBOL_GPL(kprobe_decode_arm_table);
979 static void __kprobes arm_singlestep(struct kprobe *p, struct pt_regs *regs)
982 p->ainsn.insn_handler(p, regs);
986 * INSN_REJECTED If instruction is one not allowed to kprobe,
987 * INSN_GOOD If instruction is supported and uses instruction slot,
988 * INSN_GOOD_NO_SLOT If instruction is supported but doesn't use its slot.
990 * For instructions we don't want to kprobe (INSN_REJECTED return result):
991 * These are generally ones that modify the processor state making
992 * them "hard" to simulate such as switches processor modes or
993 * make accesses in alternate modes. Any of these could be simulated
994 * if the work was put into it, but low return considering they
995 * should also be very rare.
997 enum kprobe_insn __kprobes
998 arm_kprobe_decode_insn(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1000 asi->insn_singlestep = arm_singlestep;
1001 asi->insn_check_cc = kprobe_condition_checks[insn>>28];
1002 return kprobe_decode_insn(insn, asi, kprobe_decode_arm_table, false);