ARM: kprobes: Add Thumb breakpoint support
[pandora-kernel.git] / arch / arm / kernel / kprobes-arm.c
1 /*
2  * arch/arm/kernel/kprobes-decode.c
3  *
4  * Copyright (C) 2006, 2007 Motorola Inc.
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  * 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.
14  */
15
16 /*
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:
22  *
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.)
28  *
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.
32  *
33  * In the execution phase by an instruction's handler:
34  *
35  *   *) If the PC is written to by the instruction, the
36  *      instruction must be fully simulated in software.
37  *
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.
42  *
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.
47  *
48  *      After call completes, copy the output registers to
49  *      the original instruction's original registers.
50  *
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.
57  *
58  * TODO: ifdef out some instruction decoding based on architecture.
59  */
60
61 #include <linux/kernel.h>
62 #include <linux/kprobes.h>
63
64 #include "kprobes.h"
65
66 #define sign_extend(x, signbit) ((x) | (0 - ((x) & (1 << (signbit)))))
67
68 #define branch_displacement(insn) sign_extend(((insn) & 0xffffff) << 2, 25)
69
70 #define is_r15(insn, bitpos) (((insn) & (0xf << bitpos)) == (0xf << bitpos))
71
72 #define PSR_fs  (PSR_f|PSR_s)
73
74 #define KPROBE_RETURN_INSTRUCTION       0xe1a0f00e      /* mov pc, lr */
75
76 typedef long (insn_0arg_fn_t)(void);
77 typedef long (insn_1arg_fn_t)(long);
78 typedef long (insn_2arg_fn_t)(long, long);
79 typedef long (insn_3arg_fn_t)(long, long, long);
80 typedef long (insn_4arg_fn_t)(long, long, long, long);
81 typedef long long (insn_llret_0arg_fn_t)(void);
82 typedef long long (insn_llret_3arg_fn_t)(long, long, long);
83 typedef long long (insn_llret_4arg_fn_t)(long, long, long, long);
84
85 union reg_pair {
86         long long       dr;
87 #ifdef __LITTLE_ENDIAN
88         struct { long   r0, r1; };
89 #else
90         struct { long   r1, r0; };
91 #endif
92 };
93
94 /*
95  * The insnslot_?arg_r[w]flags() functions below are to keep the
96  * msr -> *fn -> mrs instruction sequences indivisible so that
97  * the state of the CPSR flags aren't inadvertently modified
98  * just before or just after the call.
99  */
100
101 static inline long __kprobes
102 insnslot_0arg_rflags(long cpsr, insn_0arg_fn_t *fn)
103 {
104         register long ret asm("r0");
105
106         __asm__ __volatile__ (
107                 "msr    cpsr_fs, %[cpsr]        \n\t"
108                 "mov    lr, pc                  \n\t"
109                 "mov    pc, %[fn]               \n\t"
110                 : "=r" (ret)
111                 : [cpsr] "r" (cpsr), [fn] "r" (fn)
112                 : "lr", "cc"
113         );
114         return ret;
115 }
116
117 static inline long long __kprobes
118 insnslot_llret_0arg_rflags(long cpsr, insn_llret_0arg_fn_t *fn)
119 {
120         register long ret0 asm("r0");
121         register long ret1 asm("r1");
122         union reg_pair fnr;
123
124         __asm__ __volatile__ (
125                 "msr    cpsr_fs, %[cpsr]        \n\t"
126                 "mov    lr, pc                  \n\t"
127                 "mov    pc, %[fn]               \n\t"
128                 : "=r" (ret0), "=r" (ret1)
129                 : [cpsr] "r" (cpsr), [fn] "r" (fn)
130                 : "lr", "cc"
131         );
132         fnr.r0 = ret0;
133         fnr.r1 = ret1;
134         return fnr.dr;
135 }
136
137 static inline long __kprobes
138 insnslot_1arg_rflags(long r0, long cpsr, insn_1arg_fn_t *fn)
139 {
140         register long rr0 asm("r0") = r0;
141         register long ret asm("r0");
142
143         __asm__ __volatile__ (
144                 "msr    cpsr_fs, %[cpsr]        \n\t"
145                 "mov    lr, pc                  \n\t"
146                 "mov    pc, %[fn]               \n\t"
147                 : "=r" (ret)
148                 : "0" (rr0), [cpsr] "r" (cpsr), [fn] "r" (fn)
149                 : "lr", "cc"
150         );
151         return ret;
152 }
153
154 static inline long __kprobes
155 insnslot_2arg_rflags(long r0, long r1, long cpsr, insn_2arg_fn_t *fn)
156 {
157         register long rr0 asm("r0") = r0;
158         register long rr1 asm("r1") = r1;
159         register long ret asm("r0");
160
161         __asm__ __volatile__ (
162                 "msr    cpsr_fs, %[cpsr]        \n\t"
163                 "mov    lr, pc                  \n\t"
164                 "mov    pc, %[fn]               \n\t"
165                 : "=r" (ret)
166                 : "0" (rr0), "r" (rr1),
167                   [cpsr] "r" (cpsr), [fn] "r" (fn)
168                 : "lr", "cc"
169         );
170         return ret;
171 }
172
173 static inline long __kprobes
174 insnslot_3arg_rflags(long r0, long r1, long r2, long cpsr, insn_3arg_fn_t *fn)
175 {
176         register long rr0 asm("r0") = r0;
177         register long rr1 asm("r1") = r1;
178         register long rr2 asm("r2") = r2;
179         register long ret asm("r0");
180
181         __asm__ __volatile__ (
182                 "msr    cpsr_fs, %[cpsr]        \n\t"
183                 "mov    lr, pc                  \n\t"
184                 "mov    pc, %[fn]               \n\t"
185                 : "=r" (ret)
186                 : "0" (rr0), "r" (rr1), "r" (rr2),
187                   [cpsr] "r" (cpsr), [fn] "r" (fn)
188                 : "lr", "cc"
189         );
190         return ret;
191 }
192
193 static inline long long __kprobes
194 insnslot_llret_3arg_rflags(long r0, long r1, long r2, long cpsr,
195                            insn_llret_3arg_fn_t *fn)
196 {
197         register long rr0 asm("r0") = r0;
198         register long rr1 asm("r1") = r1;
199         register long rr2 asm("r2") = r2;
200         register long ret0 asm("r0");
201         register long ret1 asm("r1");
202         union reg_pair fnr;
203
204         __asm__ __volatile__ (
205                 "msr    cpsr_fs, %[cpsr]        \n\t"
206                 "mov    lr, pc                  \n\t"
207                 "mov    pc, %[fn]               \n\t"
208                 : "=r" (ret0), "=r" (ret1)
209                 : "0" (rr0), "r" (rr1), "r" (rr2),
210                   [cpsr] "r" (cpsr), [fn] "r" (fn)
211                 : "lr", "cc"
212         );
213         fnr.r0 = ret0;
214         fnr.r1 = ret1;
215         return fnr.dr;
216 }
217
218 static inline long __kprobes
219 insnslot_4arg_rflags(long r0, long r1, long r2, long r3, long cpsr,
220                      insn_4arg_fn_t *fn)
221 {
222         register long rr0 asm("r0") = r0;
223         register long rr1 asm("r1") = r1;
224         register long rr2 asm("r2") = r2;
225         register long rr3 asm("r3") = r3;
226         register long ret asm("r0");
227
228         __asm__ __volatile__ (
229                 "msr    cpsr_fs, %[cpsr]        \n\t"
230                 "mov    lr, pc                  \n\t"
231                 "mov    pc, %[fn]               \n\t"
232                 : "=r" (ret)
233                 : "0" (rr0), "r" (rr1), "r" (rr2), "r" (rr3),
234                   [cpsr] "r" (cpsr), [fn] "r" (fn)
235                 : "lr", "cc"
236         );
237         return ret;
238 }
239
240 static inline long __kprobes
241 insnslot_1arg_rwflags(long r0, long *cpsr, insn_1arg_fn_t *fn)
242 {
243         register long rr0 asm("r0") = r0;
244         register long ret asm("r0");
245         long oldcpsr = *cpsr;
246         long newcpsr;
247
248         __asm__ __volatile__ (
249                 "msr    cpsr_fs, %[oldcpsr]     \n\t"
250                 "mov    lr, pc                  \n\t"
251                 "mov    pc, %[fn]               \n\t"
252                 "mrs    %[newcpsr], cpsr        \n\t"
253                 : "=r" (ret), [newcpsr] "=r" (newcpsr)
254                 : "0" (rr0), [oldcpsr] "r" (oldcpsr), [fn] "r" (fn)
255                 : "lr", "cc"
256         );
257         *cpsr = (oldcpsr & ~PSR_fs) | (newcpsr & PSR_fs);
258         return ret;
259 }
260
261 static inline long __kprobes
262 insnslot_2arg_rwflags(long r0, long r1, long *cpsr, insn_2arg_fn_t *fn)
263 {
264         register long rr0 asm("r0") = r0;
265         register long rr1 asm("r1") = r1;
266         register long ret asm("r0");
267         long oldcpsr = *cpsr;
268         long newcpsr;
269
270         __asm__ __volatile__ (
271                 "msr    cpsr_fs, %[oldcpsr]     \n\t"
272                 "mov    lr, pc                  \n\t"
273                 "mov    pc, %[fn]               \n\t"
274                 "mrs    %[newcpsr], cpsr        \n\t"
275                 : "=r" (ret), [newcpsr] "=r" (newcpsr)
276                 : "0" (rr0), "r" (rr1), [oldcpsr] "r" (oldcpsr), [fn] "r" (fn)
277                 : "lr", "cc"
278         );
279         *cpsr = (oldcpsr & ~PSR_fs) | (newcpsr & PSR_fs);
280         return ret;
281 }
282
283 static inline long __kprobes
284 insnslot_3arg_rwflags(long r0, long r1, long r2, long *cpsr,
285                       insn_3arg_fn_t *fn)
286 {
287         register long rr0 asm("r0") = r0;
288         register long rr1 asm("r1") = r1;
289         register long rr2 asm("r2") = r2;
290         register long ret asm("r0");
291         long oldcpsr = *cpsr;
292         long newcpsr;
293
294         __asm__ __volatile__ (
295                 "msr    cpsr_fs, %[oldcpsr]     \n\t"
296                 "mov    lr, pc                  \n\t"
297                 "mov    pc, %[fn]               \n\t"
298                 "mrs    %[newcpsr], cpsr        \n\t"
299                 : "=r" (ret), [newcpsr] "=r" (newcpsr)
300                 : "0" (rr0), "r" (rr1), "r" (rr2),
301                   [oldcpsr] "r" (oldcpsr), [fn] "r" (fn)
302                 : "lr", "cc"
303         );
304         *cpsr = (oldcpsr & ~PSR_fs) | (newcpsr & PSR_fs);
305         return ret;
306 }
307
308 static inline long __kprobes
309 insnslot_4arg_rwflags(long r0, long r1, long r2, long r3, long *cpsr,
310                       insn_4arg_fn_t *fn)
311 {
312         register long rr0 asm("r0") = r0;
313         register long rr1 asm("r1") = r1;
314         register long rr2 asm("r2") = r2;
315         register long rr3 asm("r3") = r3;
316         register long ret asm("r0");
317         long oldcpsr = *cpsr;
318         long newcpsr;
319
320         __asm__ __volatile__ (
321                 "msr    cpsr_fs, %[oldcpsr]     \n\t"
322                 "mov    lr, pc                  \n\t"
323                 "mov    pc, %[fn]               \n\t"
324                 "mrs    %[newcpsr], cpsr        \n\t"
325                 : "=r" (ret), [newcpsr] "=r" (newcpsr)
326                 : "0" (rr0), "r" (rr1), "r" (rr2), "r" (rr3),
327                   [oldcpsr] "r" (oldcpsr), [fn] "r" (fn)
328                 : "lr", "cc"
329         );
330         *cpsr = (oldcpsr & ~PSR_fs) | (newcpsr & PSR_fs);
331         return ret;
332 }
333
334 static inline long long __kprobes
335 insnslot_llret_4arg_rwflags(long r0, long r1, long r2, long r3, long *cpsr,
336                             insn_llret_4arg_fn_t *fn)
337 {
338         register long rr0 asm("r0") = r0;
339         register long rr1 asm("r1") = r1;
340         register long rr2 asm("r2") = r2;
341         register long rr3 asm("r3") = r3;
342         register long ret0 asm("r0");
343         register long ret1 asm("r1");
344         long oldcpsr = *cpsr;
345         long newcpsr;
346         union reg_pair fnr;
347
348         __asm__ __volatile__ (
349                 "msr    cpsr_fs, %[oldcpsr]     \n\t"
350                 "mov    lr, pc                  \n\t"
351                 "mov    pc, %[fn]               \n\t"
352                 "mrs    %[newcpsr], cpsr        \n\t"
353                 : "=r" (ret0), "=r" (ret1), [newcpsr] "=r" (newcpsr)
354                 : "0" (rr0), "r" (rr1), "r" (rr2), "r" (rr3),
355                   [oldcpsr] "r" (oldcpsr), [fn] "r" (fn)
356                 : "lr", "cc"
357         );
358         *cpsr = (oldcpsr & ~PSR_fs) | (newcpsr & PSR_fs);
359         fnr.r0 = ret0;
360         fnr.r1 = ret1;
361         return fnr.dr;
362 }
363
364 /*
365  * To avoid the complications of mimicing single-stepping on a
366  * processor without a Next-PC or a single-step mode, and to
367  * avoid having to deal with the side-effects of boosting, we
368  * simulate or emulate (almost) all ARM instructions.
369  *
370  * "Simulation" is where the instruction's behavior is duplicated in
371  * C code.  "Emulation" is where the original instruction is rewritten
372  * and executed, often by altering its registers.
373  *
374  * By having all behavior of the kprobe'd instruction completed before
375  * returning from the kprobe_handler(), all locks (scheduler and
376  * interrupt) can safely be released.  There is no need for secondary
377  * breakpoints, no race with MP or preemptable kernels, nor having to
378  * clean up resources counts at a later time impacting overall system
379  * performance.  By rewriting the instruction, only the minimum registers
380  * need to be loaded and saved back optimizing performance.
381  *
382  * Calling the insnslot_*_rwflags version of a function doesn't hurt
383  * anything even when the CPSR flags aren't updated by the
384  * instruction.  It's just a little slower in return for saving
385  * a little space by not having a duplicate function that doesn't
386  * update the flags.  (The same optimization can be said for
387  * instructions that do or don't perform register writeback)
388  * Also, instructions can either read the flags, only write the
389  * flags, or read and write the flags.  To save combinations
390  * rather than for sheer performance, flag functions just assume
391  * read and write of flags.
392  */
393
394 static void __kprobes simulate_bbl(struct kprobe *p, struct pt_regs *regs)
395 {
396         kprobe_opcode_t insn = p->opcode;
397         long iaddr = (long)p->addr;
398         int disp  = branch_displacement(insn);
399
400         if (insn & (1 << 24))
401                 regs->ARM_lr = iaddr + 4;
402
403         regs->ARM_pc = iaddr + 8 + disp;
404 }
405
406 static void __kprobes simulate_blx1(struct kprobe *p, struct pt_regs *regs)
407 {
408         kprobe_opcode_t insn = p->opcode;
409         long iaddr = (long)p->addr;
410         int disp = branch_displacement(insn);
411
412         regs->ARM_lr = iaddr + 4;
413         regs->ARM_pc = iaddr + 8 + disp + ((insn >> 23) & 0x2);
414         regs->ARM_cpsr |= PSR_T_BIT;
415 }
416
417 static void __kprobes simulate_blx2bx(struct kprobe *p, struct pt_regs *regs)
418 {
419         kprobe_opcode_t insn = p->opcode;
420         int rm = insn & 0xf;
421         long rmv = regs->uregs[rm];
422
423         if (insn & (1 << 5))
424                 regs->ARM_lr = (long)p->addr + 4;
425
426         regs->ARM_pc = rmv & ~0x1;
427         regs->ARM_cpsr &= ~PSR_T_BIT;
428         if (rmv & 0x1)
429                 regs->ARM_cpsr |= PSR_T_BIT;
430 }
431
432 static void __kprobes simulate_mrs(struct kprobe *p, struct pt_regs *regs)
433 {
434         kprobe_opcode_t insn = p->opcode;
435         int rd = (insn >> 12) & 0xf;
436         unsigned long mask = 0xf8ff03df; /* Mask out execution state */
437         regs->uregs[rd] = regs->ARM_cpsr & mask;
438 }
439
440 static void __kprobes simulate_ldm1stm1(struct kprobe *p, struct pt_regs *regs)
441 {
442         kprobe_opcode_t insn = p->opcode;
443         int rn = (insn >> 16) & 0xf;
444         int lbit = insn & (1 << 20);
445         int wbit = insn & (1 << 21);
446         int ubit = insn & (1 << 23);
447         int pbit = insn & (1 << 24);
448         long *addr = (long *)regs->uregs[rn];
449         int reg_bit_vector;
450         int reg_count;
451
452         reg_count = 0;
453         reg_bit_vector = insn & 0xffff;
454         while (reg_bit_vector) {
455                 reg_bit_vector &= (reg_bit_vector - 1);
456                 ++reg_count;
457         }
458
459         if (!ubit)
460                 addr -= reg_count;
461         addr += (!pbit == !ubit);
462
463         reg_bit_vector = insn & 0xffff;
464         while (reg_bit_vector) {
465                 int reg = __ffs(reg_bit_vector);
466                 reg_bit_vector &= (reg_bit_vector - 1);
467                 if (lbit)
468                         regs->uregs[reg] = *addr++;
469                 else
470                         *addr++ = regs->uregs[reg];
471         }
472
473         if (wbit) {
474                 if (!ubit)
475                         addr -= reg_count;
476                 addr -= (!pbit == !ubit);
477                 regs->uregs[rn] = (long)addr;
478         }
479 }
480
481 static void __kprobes simulate_stm1_pc(struct kprobe *p, struct pt_regs *regs)
482 {
483         regs->ARM_pc = (long)p->addr + str_pc_offset;
484         simulate_ldm1stm1(p, regs);
485         regs->ARM_pc = (long)p->addr + 4;
486 }
487
488 static void __kprobes simulate_mov_ipsp(struct kprobe *p, struct pt_regs *regs)
489 {
490         regs->uregs[12] = regs->uregs[13];
491 }
492
493 static void __kprobes emulate_ldrd(struct kprobe *p, struct pt_regs *regs)
494 {
495         insn_2arg_fn_t *i_fn = (insn_2arg_fn_t *)&p->ainsn.insn[0];
496         kprobe_opcode_t insn = p->opcode;
497         long ppc = (long)p->addr + 8;
498         int rd = (insn >> 12) & 0xf;
499         int rn = (insn >> 16) & 0xf;
500         int rm = insn & 0xf;  /* rm may be invalid, don't care. */
501         long rmv = (rm == 15) ? ppc : regs->uregs[rm];
502         long rnv = (rn == 15) ? ppc : regs->uregs[rn];
503
504         /* Not following the C calling convention here, so need asm(). */
505         __asm__ __volatile__ (
506                 "ldr    r0, %[rn]       \n\t"
507                 "ldr    r1, %[rm]       \n\t"
508                 "msr    cpsr_fs, %[cpsr]\n\t"
509                 "mov    lr, pc          \n\t"
510                 "mov    pc, %[i_fn]     \n\t"
511                 "str    r0, %[rn]       \n\t"   /* in case of writeback */
512                 "str    r2, %[rd0]      \n\t"
513                 "str    r3, %[rd1]      \n\t"
514                 : [rn]  "+m" (rnv),
515                   [rd0] "=m" (regs->uregs[rd]),
516                   [rd1] "=m" (regs->uregs[rd+1])
517                 : [rm]   "m" (rmv),
518                   [cpsr] "r" (regs->ARM_cpsr),
519                   [i_fn] "r" (i_fn)
520                 : "r0", "r1", "r2", "r3", "lr", "cc"
521         );
522         if (is_writeback(insn))
523                 regs->uregs[rn] = rnv;
524 }
525
526 static void __kprobes emulate_strd(struct kprobe *p, struct pt_regs *regs)
527 {
528         insn_4arg_fn_t *i_fn = (insn_4arg_fn_t *)&p->ainsn.insn[0];
529         kprobe_opcode_t insn = p->opcode;
530         long ppc = (long)p->addr + 8;
531         int rd = (insn >> 12) & 0xf;
532         int rn = (insn >> 16) & 0xf;
533         int rm  = insn & 0xf;
534         long rnv = (rn == 15) ? ppc : regs->uregs[rn];
535         /* rm/rmv may be invalid, don't care. */
536         long rmv = (rm == 15) ? ppc : regs->uregs[rm];
537         long rnv_wb;
538
539         rnv_wb = insnslot_4arg_rflags(rnv, rmv, regs->uregs[rd],
540                                                regs->uregs[rd+1],
541                                                regs->ARM_cpsr, i_fn);
542         if (is_writeback(insn))
543                 regs->uregs[rn] = rnv_wb;
544 }
545
546 static void __kprobes emulate_ldr(struct kprobe *p, struct pt_regs *regs)
547 {
548         insn_llret_3arg_fn_t *i_fn = (insn_llret_3arg_fn_t *)&p->ainsn.insn[0];
549         kprobe_opcode_t insn = p->opcode;
550         long ppc = (long)p->addr + 8;
551         union reg_pair fnr;
552         int rd = (insn >> 12) & 0xf;
553         int rn = (insn >> 16) & 0xf;
554         int rm = insn & 0xf;
555         long rdv;
556         long rnv = (rn == 15) ? ppc : regs->uregs[rn];
557         long rmv = (rm == 15) ? ppc : regs->uregs[rm];
558         long cpsr = regs->ARM_cpsr;
559
560         fnr.dr = insnslot_llret_3arg_rflags(rnv, 0, rmv, cpsr, i_fn);
561         if (rn != 15)
562                 regs->uregs[rn] = fnr.r0;  /* Save Rn in case of writeback. */
563         rdv = fnr.r1;
564
565         if (rd == 15) {
566 #if __LINUX_ARM_ARCH__ >= 5
567                 cpsr &= ~PSR_T_BIT;
568                 if (rdv & 0x1)
569                         cpsr |= PSR_T_BIT;
570                 regs->ARM_cpsr = cpsr;
571                 rdv &= ~0x1;
572 #else
573                 rdv &= ~0x2;
574 #endif
575         }
576         regs->uregs[rd] = rdv;
577 }
578
579 static void __kprobes emulate_str(struct kprobe *p, struct pt_regs *regs)
580 {
581         insn_3arg_fn_t *i_fn = (insn_3arg_fn_t *)&p->ainsn.insn[0];
582         kprobe_opcode_t insn = p->opcode;
583         long iaddr = (long)p->addr;
584         int rd = (insn >> 12) & 0xf;
585         int rn = (insn >> 16) & 0xf;
586         int rm = insn & 0xf;
587         long rdv = (rd == 15) ? iaddr + str_pc_offset : regs->uregs[rd];
588         long rnv = (rn == 15) ? iaddr +  8 : regs->uregs[rn];
589         long rmv = regs->uregs[rm];  /* rm/rmv may be invalid, don't care. */
590         long rnv_wb;
591
592         rnv_wb = insnslot_3arg_rflags(rnv, rdv, rmv, regs->ARM_cpsr, i_fn);
593         if (rn != 15)
594                 regs->uregs[rn] = rnv_wb;  /* Save Rn in case of writeback. */
595 }
596
597 static void __kprobes emulate_sat(struct kprobe *p, struct pt_regs *regs)
598 {
599         insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0];
600         kprobe_opcode_t insn = p->opcode;
601         int rd = (insn >> 12) & 0xf;
602         int rm = insn & 0xf;
603         long rmv = regs->uregs[rm];
604
605         /* Writes Q flag */
606         regs->uregs[rd] = insnslot_1arg_rwflags(rmv, &regs->ARM_cpsr, i_fn);
607 }
608
609 static void __kprobes emulate_sel(struct kprobe *p, struct pt_regs *regs)
610 {
611         insn_2arg_fn_t *i_fn = (insn_2arg_fn_t *)&p->ainsn.insn[0];
612         kprobe_opcode_t insn = p->opcode;
613         int rd = (insn >> 12) & 0xf;
614         int rn = (insn >> 16) & 0xf;
615         int rm = insn & 0xf;
616         long rnv = regs->uregs[rn];
617         long rmv = regs->uregs[rm];
618
619         /* Reads GE bits */
620         regs->uregs[rd] = insnslot_2arg_rflags(rnv, rmv, regs->ARM_cpsr, i_fn);
621 }
622
623 static void __kprobes emulate_none(struct kprobe *p, struct pt_regs *regs)
624 {
625         insn_0arg_fn_t *i_fn = (insn_0arg_fn_t *)&p->ainsn.insn[0];
626
627         insnslot_0arg_rflags(regs->ARM_cpsr, i_fn);
628 }
629
630 static void __kprobes emulate_nop(struct kprobe *p, struct pt_regs *regs)
631 {
632 }
633
634 static void __kprobes
635 emulate_rd12_modify(struct kprobe *p, struct pt_regs *regs)
636 {
637         insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0];
638         kprobe_opcode_t insn = p->opcode;
639         int rd = (insn >> 12) & 0xf;
640         long rdv = regs->uregs[rd];
641
642         regs->uregs[rd] = insnslot_1arg_rflags(rdv, regs->ARM_cpsr, i_fn);
643 }
644
645 static void __kprobes
646 emulate_rd12rn0_modify(struct kprobe *p, struct pt_regs *regs)
647 {
648         insn_2arg_fn_t *i_fn = (insn_2arg_fn_t *)&p->ainsn.insn[0];
649         kprobe_opcode_t insn = p->opcode;
650         int rd = (insn >> 12) & 0xf;
651         int rn = insn & 0xf;
652         long rdv = regs->uregs[rd];
653         long rnv = regs->uregs[rn];
654
655         regs->uregs[rd] = insnslot_2arg_rflags(rdv, rnv, regs->ARM_cpsr, i_fn);
656 }
657
658 static void __kprobes emulate_rd12rm0(struct kprobe *p, struct pt_regs *regs)
659 {
660         insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0];
661         kprobe_opcode_t insn = p->opcode;
662         int rd = (insn >> 12) & 0xf;
663         int rm = insn & 0xf;
664         long rmv = regs->uregs[rm];
665
666         regs->uregs[rd] = insnslot_1arg_rflags(rmv, regs->ARM_cpsr, i_fn);
667 }
668
669 static void __kprobes
670 emulate_rd12rn16rm0_rwflags(struct kprobe *p, struct pt_regs *regs)
671 {
672         insn_2arg_fn_t *i_fn = (insn_2arg_fn_t *)&p->ainsn.insn[0];
673         kprobe_opcode_t insn = p->opcode;
674         int rd = (insn >> 12) & 0xf;
675         int rn = (insn >> 16) & 0xf;
676         int rm = insn & 0xf;
677         long rnv = regs->uregs[rn];
678         long rmv = regs->uregs[rm];
679
680         regs->uregs[rd] =
681                 insnslot_2arg_rwflags(rnv, rmv, &regs->ARM_cpsr, i_fn);
682 }
683
684 static void __kprobes
685 emulate_rd16rn12rs8rm0_rwflags(struct kprobe *p, struct pt_regs *regs)
686 {
687         insn_3arg_fn_t *i_fn = (insn_3arg_fn_t *)&p->ainsn.insn[0];
688         kprobe_opcode_t insn = p->opcode;
689         int rd = (insn >> 16) & 0xf;
690         int rn = (insn >> 12) & 0xf;
691         int rs = (insn >> 8) & 0xf;
692         int rm = insn & 0xf;
693         long rnv = regs->uregs[rn];
694         long rsv = regs->uregs[rs];
695         long rmv = regs->uregs[rm];
696
697         regs->uregs[rd] =
698                 insnslot_3arg_rwflags(rnv, rsv, rmv, &regs->ARM_cpsr, i_fn);
699 }
700
701 static void __kprobes
702 emulate_rd16rs8rm0_rwflags(struct kprobe *p, struct pt_regs *regs)
703 {
704         insn_2arg_fn_t *i_fn = (insn_2arg_fn_t *)&p->ainsn.insn[0];
705         kprobe_opcode_t insn = p->opcode;
706         int rd = (insn >> 16) & 0xf;
707         int rs = (insn >> 8) & 0xf;
708         int rm = insn & 0xf;
709         long rsv = regs->uregs[rs];
710         long rmv = regs->uregs[rm];
711
712         regs->uregs[rd] =
713                 insnslot_2arg_rwflags(rsv, rmv, &regs->ARM_cpsr, i_fn);
714 }
715
716 static void __kprobes
717 emulate_rdhi16rdlo12rs8rm0_rwflags(struct kprobe *p, struct pt_regs *regs)
718 {
719         insn_llret_4arg_fn_t *i_fn = (insn_llret_4arg_fn_t *)&p->ainsn.insn[0];
720         kprobe_opcode_t insn = p->opcode;
721         union reg_pair fnr;
722         int rdhi = (insn >> 16) & 0xf;
723         int rdlo = (insn >> 12) & 0xf;
724         int rs   = (insn >> 8) & 0xf;
725         int rm   = insn & 0xf;
726         long rsv = regs->uregs[rs];
727         long rmv = regs->uregs[rm];
728
729         fnr.dr = insnslot_llret_4arg_rwflags(regs->uregs[rdhi],
730                                              regs->uregs[rdlo], rsv, rmv,
731                                              &regs->ARM_cpsr, i_fn);
732         regs->uregs[rdhi] = fnr.r0;
733         regs->uregs[rdlo] = fnr.r1;
734 }
735
736 static void __kprobes
737 emulate_alu_imm_rflags(struct kprobe *p, struct pt_regs *regs)
738 {
739         insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0];
740         kprobe_opcode_t insn = p->opcode;
741         int rd = (insn >> 12) & 0xf;
742         int rn = (insn >> 16) & 0xf;
743         long rnv = (rn == 15) ? (long)p->addr + 8 : regs->uregs[rn];
744
745         regs->uregs[rd] = insnslot_1arg_rflags(rnv, regs->ARM_cpsr, i_fn);
746 }
747
748 static void __kprobes
749 emulate_alu_imm_rwflags(struct kprobe *p, struct pt_regs *regs)
750 {
751         insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0];
752         kprobe_opcode_t insn = p->opcode;
753         int rd = (insn >> 12) & 0xf;
754         int rn = (insn >> 16) & 0xf;
755         long rnv = (rn == 15) ? (long)p->addr + 8 : regs->uregs[rn];
756
757         regs->uregs[rd] = insnslot_1arg_rwflags(rnv, &regs->ARM_cpsr, i_fn);
758 }
759
760 static void __kprobes
761 emulate_alu_tests_imm(struct kprobe *p, struct pt_regs *regs)
762 {
763         insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0];
764         kprobe_opcode_t insn = p->opcode;
765         int rn = (insn >> 16) & 0xf;
766         long rnv = (rn == 15) ? (long)p->addr + 8 : regs->uregs[rn];
767
768         insnslot_1arg_rwflags(rnv, &regs->ARM_cpsr, i_fn);
769 }
770
771 static void __kprobes
772 emulate_alu_rflags(struct kprobe *p, struct pt_regs *regs)
773 {
774         insn_3arg_fn_t *i_fn = (insn_3arg_fn_t *)&p->ainsn.insn[0];
775         kprobe_opcode_t insn = p->opcode;
776         long ppc = (long)p->addr + 8;
777         int rd = (insn >> 12) & 0xf;
778         int rn = (insn >> 16) & 0xf;    /* rn/rnv/rs/rsv may be */
779         int rs = (insn >> 8) & 0xf;     /* invalid, don't care. */
780         int rm = insn & 0xf;
781         long rnv = (rn == 15) ? ppc : regs->uregs[rn];
782         long rmv = (rm == 15) ? ppc : regs->uregs[rm];
783         long rsv = regs->uregs[rs];
784
785         regs->uregs[rd] =
786                 insnslot_3arg_rflags(rnv, rmv, rsv, regs->ARM_cpsr, i_fn);
787 }
788
789 static void __kprobes
790 emulate_alu_rwflags(struct kprobe *p, struct pt_regs *regs)
791 {
792         insn_3arg_fn_t *i_fn = (insn_3arg_fn_t *)&p->ainsn.insn[0];
793         kprobe_opcode_t insn = p->opcode;
794         long ppc = (long)p->addr + 8;
795         int rd = (insn >> 12) & 0xf;
796         int rn = (insn >> 16) & 0xf;    /* rn/rnv/rs/rsv may be */
797         int rs = (insn >> 8) & 0xf;     /* invalid, don't care. */
798         int rm = insn & 0xf;
799         long rnv = (rn == 15) ? ppc : regs->uregs[rn];
800         long rmv = (rm == 15) ? ppc : regs->uregs[rm];
801         long rsv = regs->uregs[rs];
802
803         regs->uregs[rd] =
804                 insnslot_3arg_rwflags(rnv, rmv, rsv, &regs->ARM_cpsr, i_fn);
805 }
806
807 static void __kprobes
808 emulate_alu_tests(struct kprobe *p, struct pt_regs *regs)
809 {
810         insn_3arg_fn_t *i_fn = (insn_3arg_fn_t *)&p->ainsn.insn[0];
811         kprobe_opcode_t insn = p->opcode;
812         long ppc = (long)p->addr + 8;
813         int rn = (insn >> 16) & 0xf;
814         int rs = (insn >> 8) & 0xf;     /* rs/rsv may be invalid, don't care. */
815         int rm = insn & 0xf;
816         long rnv = (rn == 15) ? ppc : regs->uregs[rn];
817         long rmv = (rm == 15) ? ppc : regs->uregs[rm];
818         long rsv = regs->uregs[rs];
819
820         insnslot_3arg_rwflags(rnv, rmv, rsv, &regs->ARM_cpsr, i_fn);
821 }
822
823 static enum kprobe_insn __kprobes
824 prep_emulate_ldr_str(kprobe_opcode_t insn, struct arch_specific_insn *asi)
825 {
826         int not_imm = (insn & (1 << 26)) ? (insn & (1 << 25))
827                                          : (~insn & (1 << 22));
828
829         if (is_writeback(insn) && is_r15(insn, 16))
830                 return INSN_REJECTED;   /* Writeback to PC */
831
832         insn &= 0xfff00fff;
833         insn |= 0x00001000;     /* Rn = r0, Rd = r1 */
834         if (not_imm) {
835                 insn &= ~0xf;
836                 insn |= 2;      /* Rm = r2 */
837         }
838         asi->insn[0] = insn;
839         asi->insn_handler = (insn & (1 << 20)) ? emulate_ldr : emulate_str;
840         return INSN_GOOD;
841 }
842
843 static enum kprobe_insn __kprobes
844 prep_emulate_rd12_modify(kprobe_opcode_t insn, struct arch_specific_insn *asi)
845 {
846         if (is_r15(insn, 12))
847                 return INSN_REJECTED;   /* Rd is PC */
848
849         insn &= 0xffff0fff;     /* Rd = r0 */
850         asi->insn[0] = insn;
851         asi->insn_handler = emulate_rd12_modify;
852         return INSN_GOOD;
853 }
854
855 static enum kprobe_insn __kprobes
856 prep_emulate_rd12rn0_modify(kprobe_opcode_t insn,
857                             struct arch_specific_insn *asi)
858 {
859         if (is_r15(insn, 12))
860                 return INSN_REJECTED;   /* Rd is PC */
861
862         insn &= 0xffff0ff0;     /* Rd = r0 */
863         insn |= 0x00000001;     /* Rn = r1 */
864         asi->insn[0] = insn;
865         asi->insn_handler = emulate_rd12rn0_modify;
866         return INSN_GOOD;
867 }
868
869 static enum kprobe_insn __kprobes
870 prep_emulate_rd12rm0(kprobe_opcode_t insn, struct arch_specific_insn *asi)
871 {
872         if (is_r15(insn, 12))
873                 return INSN_REJECTED;   /* Rd is PC */
874
875         insn &= 0xffff0ff0;     /* Rd = r0, Rm = r0 */
876         asi->insn[0] = insn;
877         asi->insn_handler = emulate_rd12rm0;
878         return INSN_GOOD;
879 }
880
881 static enum kprobe_insn __kprobes
882 prep_emulate_rd12rn16rm0_wflags(kprobe_opcode_t insn,
883                                 struct arch_specific_insn *asi)
884 {
885         if (is_r15(insn, 12))
886                 return INSN_REJECTED;   /* Rd is PC */
887
888         insn &= 0xfff00ff0;     /* Rd = r0, Rn = r0 */
889         insn |= 0x00000001;     /* Rm = r1 */
890         asi->insn[0] = insn;
891         asi->insn_handler = emulate_rd12rn16rm0_rwflags;
892         return INSN_GOOD;
893 }
894
895 static enum kprobe_insn __kprobes
896 prep_emulate_rd16rs8rm0_wflags(kprobe_opcode_t insn,
897                                struct arch_specific_insn *asi)
898 {
899         if (is_r15(insn, 16))
900                 return INSN_REJECTED;   /* Rd is PC */
901
902         insn &= 0xfff0f0f0;     /* Rd = r0, Rs = r0 */
903         insn |= 0x00000001;     /* Rm = r1          */
904         asi->insn[0] = insn;
905         asi->insn_handler = emulate_rd16rs8rm0_rwflags;
906         return INSN_GOOD;
907 }
908
909 static enum kprobe_insn __kprobes
910 prep_emulate_rd16rn12rs8rm0_wflags(kprobe_opcode_t insn,
911                                    struct arch_specific_insn *asi)
912 {
913         if (is_r15(insn, 16))
914                 return INSN_REJECTED;   /* Rd is PC */
915
916         insn &= 0xfff000f0;     /* Rd = r0, Rn = r0 */
917         insn |= 0x00000102;     /* Rs = r1, Rm = r2 */
918         asi->insn[0] = insn;
919         asi->insn_handler = emulate_rd16rn12rs8rm0_rwflags;
920         return INSN_GOOD;
921 }
922
923 static enum kprobe_insn __kprobes
924 prep_emulate_rdhi16rdlo12rs8rm0_wflags(kprobe_opcode_t insn,
925                                        struct arch_specific_insn *asi)
926 {
927         if (is_r15(insn, 16) || is_r15(insn, 12))
928                 return INSN_REJECTED;   /* RdHi or RdLo is PC */
929
930         insn &= 0xfff000f0;     /* RdHi = r0, RdLo = r1 */
931         insn |= 0x00001203;     /* Rs = r2, Rm = r3 */
932         asi->insn[0] = insn;
933         asi->insn_handler = emulate_rdhi16rdlo12rs8rm0_rwflags;
934         return INSN_GOOD;
935 }
936
937 /*
938  * For the instruction masking and comparisons in all the "space_*"
939  * functions below, Do _not_ rearrange the order of tests unless
940  * you're very, very sure of what you are doing.  For the sake of
941  * efficiency, the masks for some tests sometimes assume other test
942  * have been done prior to them so the number of patterns to test
943  * for an instruction set can be as broad as possible to reduce the
944  * number of tests needed.
945  */
946
947 static enum kprobe_insn __kprobes
948 space_1111(kprobe_opcode_t insn, struct arch_specific_insn *asi)
949 {
950         /* memory hint : 1111 0100 x001 xxxx xxxx xxxx xxxx xxxx : */
951         /* PLDI        : 1111 0100 x101 xxxx xxxx xxxx xxxx xxxx : */
952         /* PLDW        : 1111 0101 x001 xxxx xxxx xxxx xxxx xxxx : */
953         /* PLD         : 1111 0101 x101 xxxx xxxx xxxx xxxx xxxx : */
954         if ((insn & 0xfe300000) == 0xf4100000) {
955                 asi->insn_handler = emulate_nop;
956                 return INSN_GOOD_NO_SLOT;
957         }
958
959         /* BLX(1) : 1111 101x xxxx xxxx xxxx xxxx xxxx xxxx : */
960         if ((insn & 0xfe000000) == 0xfa000000) {
961                 asi->insn_handler = simulate_blx1;
962                 return INSN_GOOD_NO_SLOT;
963         }
964
965         /* CPS   : 1111 0001 0000 xxx0 xxxx xxxx xx0x xxxx */
966         /* SETEND: 1111 0001 0000 0001 xxxx xxxx 0000 xxxx */
967
968         /* SRS   : 1111 100x x1x0 xxxx xxxx xxxx xxxx xxxx */
969         /* RFE   : 1111 100x x0x1 xxxx xxxx xxxx xxxx xxxx */
970
971         /* Coprocessor instructions... */
972         /* MCRR2 : 1111 1100 0100 xxxx xxxx xxxx xxxx xxxx : (Rd != Rn) */
973         /* MRRC2 : 1111 1100 0101 xxxx xxxx xxxx xxxx xxxx : (Rd != Rn) */
974         /* LDC2  : 1111 110x xxx1 xxxx xxxx xxxx xxxx xxxx */
975         /* STC2  : 1111 110x xxx0 xxxx xxxx xxxx xxxx xxxx */
976         /* CDP2  : 1111 1110 xxxx xxxx xxxx xxxx xxx0 xxxx */
977         /* MCR2  : 1111 1110 xxx0 xxxx xxxx xxxx xxx1 xxxx */
978         /* MRC2  : 1111 1110 xxx1 xxxx xxxx xxxx xxx1 xxxx */
979
980         return INSN_REJECTED;
981 }
982
983 static enum kprobe_insn __kprobes
984 space_cccc_000x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
985 {
986         /* cccc 0001 0xx0 xxxx xxxx xxxx xxxx xxx0 xxxx */
987         if ((insn & 0x0f900010) == 0x01000000) {
988
989                 /* MRS cpsr : cccc 0001 0000 xxxx xxxx xxxx 0000 xxxx */
990                 if ((insn & 0x0ff000f0) == 0x01000000) {
991                         if (is_r15(insn, 12))
992                                 return INSN_REJECTED;   /* Rd is PC */
993                         asi->insn_handler = simulate_mrs;
994                         return INSN_GOOD_NO_SLOT;
995                 }
996
997                 /* SMLALxy : cccc 0001 0100 xxxx xxxx xxxx 1xx0 xxxx */
998                 if ((insn & 0x0ff00090) == 0x01400080)
999                         return prep_emulate_rdhi16rdlo12rs8rm0_wflags(insn,
1000                                                                         asi);
1001
1002                 /* SMULWy : cccc 0001 0010 xxxx xxxx xxxx 1x10 xxxx */
1003                 /* SMULxy : cccc 0001 0110 xxxx xxxx xxxx 1xx0 xxxx */
1004                 if ((insn & 0x0ff000b0) == 0x012000a0 ||
1005                     (insn & 0x0ff00090) == 0x01600080)
1006                         return prep_emulate_rd16rs8rm0_wflags(insn, asi);
1007
1008                 /* SMLAxy : cccc 0001 0000 xxxx xxxx xxxx 1xx0 xxxx : Q */
1009                 /* SMLAWy : cccc 0001 0010 xxxx xxxx xxxx 1x00 xxxx : Q */
1010                 if ((insn & 0x0ff00090) == 0x01000080 ||
1011                     (insn & 0x0ff000b0) == 0x01200080)
1012                         return prep_emulate_rd16rn12rs8rm0_wflags(insn, asi);
1013
1014                 /* BXJ      : cccc 0001 0010 xxxx xxxx xxxx 0010 xxxx */
1015                 /* MSR      : cccc 0001 0x10 xxxx xxxx xxxx 0000 xxxx */
1016                 /* MRS spsr : cccc 0001 0100 xxxx xxxx xxxx 0000 xxxx */
1017
1018                 /* Other instruction encodings aren't yet defined */
1019                 return INSN_REJECTED;
1020         }
1021
1022         /* cccc 0001 0xx0 xxxx xxxx xxxx xxxx 0xx1 xxxx */
1023         else if ((insn & 0x0f900090) == 0x01000010) {
1024
1025                 /* BLX(2) : cccc 0001 0010 xxxx xxxx xxxx 0011 xxxx */
1026                 /* BX     : cccc 0001 0010 xxxx xxxx xxxx 0001 xxxx */
1027                 if ((insn & 0x0ff000d0) == 0x01200010) {
1028                         if ((insn & 0x0ff000ff) == 0x0120003f)
1029                                 return INSN_REJECTED; /* BLX pc */
1030                         asi->insn_handler = simulate_blx2bx;
1031                         return INSN_GOOD_NO_SLOT;
1032                 }
1033
1034                 /* CLZ : cccc 0001 0110 xxxx xxxx xxxx 0001 xxxx */
1035                 if ((insn & 0x0ff000f0) == 0x01600010)
1036                         return prep_emulate_rd12rm0(insn, asi);
1037
1038                 /* QADD    : cccc 0001 0000 xxxx xxxx xxxx 0101 xxxx :Q */
1039                 /* QSUB    : cccc 0001 0010 xxxx xxxx xxxx 0101 xxxx :Q */
1040                 /* QDADD   : cccc 0001 0100 xxxx xxxx xxxx 0101 xxxx :Q */
1041                 /* QDSUB   : cccc 0001 0110 xxxx xxxx xxxx 0101 xxxx :Q */
1042                 if ((insn & 0x0f9000f0) == 0x01000050)
1043                         return prep_emulate_rd12rn16rm0_wflags(insn, asi);
1044
1045                 /* BKPT : 1110 0001 0010 xxxx xxxx xxxx 0111 xxxx */
1046                 /* SMC  : cccc 0001 0110 xxxx xxxx xxxx 0111 xxxx */
1047
1048                 /* Other instruction encodings aren't yet defined */
1049                 return INSN_REJECTED;
1050         }
1051
1052         /* cccc 0000 xxxx xxxx xxxx xxxx xxxx 1001 xxxx */
1053         else if ((insn & 0x0f0000f0) == 0x00000090) {
1054
1055                 /* MUL    : cccc 0000 0000 xxxx xxxx xxxx 1001 xxxx :   */
1056                 /* MULS   : cccc 0000 0001 xxxx xxxx xxxx 1001 xxxx :cc */
1057                 /* MLA    : cccc 0000 0010 xxxx xxxx xxxx 1001 xxxx :   */
1058                 /* MLAS   : cccc 0000 0011 xxxx xxxx xxxx 1001 xxxx :cc */
1059                 /* UMAAL  : cccc 0000 0100 xxxx xxxx xxxx 1001 xxxx :   */
1060                 /* undef  : cccc 0000 0101 xxxx xxxx xxxx 1001 xxxx :   */
1061                 /* MLS    : cccc 0000 0110 xxxx xxxx xxxx 1001 xxxx :   */
1062                 /* undef  : cccc 0000 0111 xxxx xxxx xxxx 1001 xxxx :   */
1063                 /* UMULL  : cccc 0000 1000 xxxx xxxx xxxx 1001 xxxx :   */
1064                 /* UMULLS : cccc 0000 1001 xxxx xxxx xxxx 1001 xxxx :cc */
1065                 /* UMLAL  : cccc 0000 1010 xxxx xxxx xxxx 1001 xxxx :   */
1066                 /* UMLALS : cccc 0000 1011 xxxx xxxx xxxx 1001 xxxx :cc */
1067                 /* SMULL  : cccc 0000 1100 xxxx xxxx xxxx 1001 xxxx :   */
1068                 /* SMULLS : cccc 0000 1101 xxxx xxxx xxxx 1001 xxxx :cc */
1069                 /* SMLAL  : cccc 0000 1110 xxxx xxxx xxxx 1001 xxxx :   */
1070                 /* SMLALS : cccc 0000 1111 xxxx xxxx xxxx 1001 xxxx :cc */
1071                 if ((insn & 0x00d00000) == 0x00500000)
1072                         return INSN_REJECTED;
1073                 else if ((insn & 0x00e00000) == 0x00000000)
1074                         return prep_emulate_rd16rs8rm0_wflags(insn, asi);
1075                 else if ((insn & 0x00a00000) == 0x00200000)
1076                         return prep_emulate_rd16rn12rs8rm0_wflags(insn, asi);
1077                 else
1078                         return prep_emulate_rdhi16rdlo12rs8rm0_wflags(insn,
1079                                                                         asi);
1080         }
1081
1082         /* cccc 000x xxxx xxxx xxxx xxxx xxxx 1xx1 xxxx */
1083         else if ((insn & 0x0e000090) == 0x00000090) {
1084
1085                 /* SWP   : cccc 0001 0000 xxxx xxxx xxxx 1001 xxxx */
1086                 /* SWPB  : cccc 0001 0100 xxxx xxxx xxxx 1001 xxxx */
1087                 /* ???   : cccc 0001 0x01 xxxx xxxx xxxx 1001 xxxx */
1088                 /* ???   : cccc 0001 0x10 xxxx xxxx xxxx 1001 xxxx */
1089                 /* ???   : cccc 0001 0x11 xxxx xxxx xxxx 1001 xxxx */
1090                 /* STREX : cccc 0001 1000 xxxx xxxx xxxx 1001 xxxx */
1091                 /* LDREX : cccc 0001 1001 xxxx xxxx xxxx 1001 xxxx */
1092                 /* STREXD: cccc 0001 1010 xxxx xxxx xxxx 1001 xxxx */
1093                 /* LDREXD: cccc 0001 1011 xxxx xxxx xxxx 1001 xxxx */
1094                 /* STREXB: cccc 0001 1100 xxxx xxxx xxxx 1001 xxxx */
1095                 /* LDREXB: cccc 0001 1101 xxxx xxxx xxxx 1001 xxxx */
1096                 /* STREXH: cccc 0001 1110 xxxx xxxx xxxx 1001 xxxx */
1097                 /* LDREXH: cccc 0001 1111 xxxx xxxx xxxx 1001 xxxx */
1098
1099                 /* LDRD  : cccc 000x xxx0 xxxx xxxx xxxx 1101 xxxx */
1100                 /* STRD  : cccc 000x xxx0 xxxx xxxx xxxx 1111 xxxx */
1101                 /* LDRH  : cccc 000x xxx1 xxxx xxxx xxxx 1011 xxxx */
1102                 /* STRH  : cccc 000x xxx0 xxxx xxxx xxxx 1011 xxxx */
1103                 /* LDRSB : cccc 000x xxx1 xxxx xxxx xxxx 1101 xxxx */
1104                 /* LDRSH : cccc 000x xxx1 xxxx xxxx xxxx 1111 xxxx */
1105                 if ((insn & 0x0f0000f0) == 0x01000090) {
1106                         if ((insn & 0x0fb000f0) == 0x01000090) {
1107                                 /* SWP/SWPB */
1108                                 return prep_emulate_rd12rn16rm0_wflags(insn,
1109                                                                         asi);
1110                         } else {
1111                                 /* STREX/LDREX variants and unallocaed space */
1112                                 return INSN_REJECTED;
1113                         }
1114
1115                 } else if ((insn & 0x0e1000d0) == 0x00000d0) {
1116                         /* STRD/LDRD */
1117                         if ((insn & 0x0000e000) == 0x0000e000)
1118                                 return INSN_REJECTED;   /* Rd is LR or PC */
1119                         if (is_writeback(insn) && is_r15(insn, 16))
1120                                 return INSN_REJECTED;   /* Writeback to PC */
1121
1122                         insn &= 0xfff00fff;
1123                         insn |= 0x00002000;     /* Rn = r0, Rd = r2 */
1124                         if (!(insn & (1 << 22))) {
1125                                 /* Register index */
1126                                 insn &= ~0xf;
1127                                 insn |= 1;      /* Rm = r1 */
1128                         }
1129                         asi->insn[0] = insn;
1130                         asi->insn_handler =
1131                                 (insn & (1 << 5)) ? emulate_strd : emulate_ldrd;
1132                         return INSN_GOOD;
1133                 }
1134
1135                 /* LDRH/STRH/LDRSB/LDRSH */
1136                 if (is_r15(insn, 12))
1137                         return INSN_REJECTED;   /* Rd is PC */
1138                 return prep_emulate_ldr_str(insn, asi);
1139         }
1140
1141         /* cccc 000x xxxx xxxx xxxx xxxx xxxx xxxx xxxx */
1142
1143         /*
1144          * ALU op with S bit and Rd == 15 :
1145          *      cccc 000x xxx1 xxxx 1111 xxxx xxxx xxxx
1146          */
1147         if ((insn & 0x0e10f000) == 0x0010f000)
1148                 return INSN_REJECTED;
1149
1150         /*
1151          * "mov ip, sp" is the most common kprobe'd instruction by far.
1152          * Check and optimize for it explicitly.
1153          */
1154         if (insn == 0xe1a0c00d) {
1155                 asi->insn_handler = simulate_mov_ipsp;
1156                 return INSN_GOOD_NO_SLOT;
1157         }
1158
1159         /*
1160          * Data processing: Immediate-shift / Register-shift
1161          * ALU op : cccc 000x xxxx xxxx xxxx xxxx xxxx xxxx
1162          * CPY    : cccc 0001 1010 xxxx xxxx 0000 0000 xxxx
1163          * MOV    : cccc 0001 101x xxxx xxxx xxxx xxxx xxxx
1164          * *S (bit 20) updates condition codes
1165          * ADC/SBC/RSC reads the C flag
1166          */
1167         insn &= 0xfff00ff0;     /* Rn = r0, Rd = r0 */
1168         insn |= 0x00000001;     /* Rm = r1 */
1169         if (insn & 0x010) {
1170                 insn &= 0xfffff0ff;     /* register shift */
1171                 insn |= 0x00000200;     /* Rs = r2 */
1172         }
1173         asi->insn[0] = insn;
1174
1175         if ((insn & 0x0f900000) == 0x01100000) {
1176                 /*
1177                  * TST : cccc 0001 0001 xxxx xxxx xxxx xxxx xxxx
1178                  * TEQ : cccc 0001 0011 xxxx xxxx xxxx xxxx xxxx
1179                  * CMP : cccc 0001 0101 xxxx xxxx xxxx xxxx xxxx
1180                  * CMN : cccc 0001 0111 xxxx xxxx xxxx xxxx xxxx
1181                  */
1182                 asi->insn_handler = emulate_alu_tests;
1183         } else {
1184                 /* ALU ops which write to Rd */
1185                 asi->insn_handler = (insn & (1 << 20)) ?  /* S-bit */
1186                                 emulate_alu_rwflags : emulate_alu_rflags;
1187         }
1188         return INSN_GOOD;
1189 }
1190
1191 static enum kprobe_insn __kprobes
1192 space_cccc_001x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1193 {
1194         /* MOVW  : cccc 0011 0000 xxxx xxxx xxxx xxxx xxxx */
1195         /* MOVT  : cccc 0011 0100 xxxx xxxx xxxx xxxx xxxx */
1196         if ((insn & 0x0fb00000) == 0x03000000)
1197                 return prep_emulate_rd12_modify(insn, asi);
1198
1199         /* hints : cccc 0011 0010 0000 xxxx xxxx xxxx xxxx */
1200         if ((insn & 0x0fff0000) == 0x03200000) {
1201                 unsigned op2 = insn & 0x000000ff;
1202                 if (op2 == 0x01 || op2 == 0x04) {
1203                         /* YIELD : cccc 0011 0010 0000 xxxx xxxx 0000 0001 */
1204                         /* SEV   : cccc 0011 0010 0000 xxxx xxxx 0000 0100 */
1205                         asi->insn[0] = insn;
1206                         asi->insn_handler = emulate_none;
1207                         return INSN_GOOD;
1208                 } else if (op2 <= 0x03) {
1209                         /* NOP   : cccc 0011 0010 0000 xxxx xxxx 0000 0000 */
1210                         /* WFE   : cccc 0011 0010 0000 xxxx xxxx 0000 0010 */
1211                         /* WFI   : cccc 0011 0010 0000 xxxx xxxx 0000 0011 */
1212                         /*
1213                          * We make WFE and WFI true NOPs to avoid stalls due
1214                          * to missing events whilst processing the probe.
1215                          */
1216                         asi->insn_handler = emulate_nop;
1217                         return INSN_GOOD_NO_SLOT;
1218                 }
1219                 /* For DBG and unallocated hints it's safest to reject them */
1220                 return INSN_REJECTED;
1221         }
1222
1223         /*
1224          * MSR   : cccc 0011 0x10 xxxx xxxx xxxx xxxx xxxx
1225          * ALU op with S bit and Rd == 15 :
1226          *         cccc 001x xxx1 xxxx 1111 xxxx xxxx xxxx
1227          */
1228         if ((insn & 0x0fb00000) == 0x03200000 ||        /* MSR */
1229             (insn & 0x0e10f000) == 0x0210f000)          /* ALU s-bit, R15  */
1230                 return INSN_REJECTED;
1231
1232         /*
1233          * Data processing: 32-bit Immediate
1234          * ALU op : cccc 001x xxxx xxxx xxxx xxxx xxxx xxxx
1235          * MOV    : cccc 0011 101x xxxx xxxx xxxx xxxx xxxx
1236          * *S (bit 20) updates condition codes
1237          * ADC/SBC/RSC reads the C flag
1238          */
1239         insn &= 0xfff00fff;     /* Rn = r0 and Rd = r0 */
1240         asi->insn[0] = insn;
1241
1242         if ((insn & 0x0f900000) == 0x03100000) {
1243                 /*
1244                  * TST : cccc 0011 0001 xxxx xxxx xxxx xxxx xxxx
1245                  * TEQ : cccc 0011 0011 xxxx xxxx xxxx xxxx xxxx
1246                  * CMP : cccc 0011 0101 xxxx xxxx xxxx xxxx xxxx
1247                  * CMN : cccc 0011 0111 xxxx xxxx xxxx xxxx xxxx
1248                  */
1249                 asi->insn_handler = emulate_alu_tests_imm;
1250         } else {
1251                 /* ALU ops which write to Rd */
1252                 asi->insn_handler = (insn & (1 << 20)) ?  /* S-bit */
1253                         emulate_alu_imm_rwflags : emulate_alu_imm_rflags;
1254         }
1255         return INSN_GOOD;
1256 }
1257
1258 static enum kprobe_insn __kprobes
1259 space_cccc_0110__1(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1260 {
1261         /* SEL : cccc 0110 1000 xxxx xxxx xxxx 1011 xxxx GE: !!! */
1262         if ((insn & 0x0ff000f0) == 0x068000b0) {
1263                 if (is_r15(insn, 12))
1264                         return INSN_REJECTED;   /* Rd is PC */
1265                 insn &= 0xfff00ff0;     /* Rd = r0, Rn = r0 */
1266                 insn |= 0x00000001;     /* Rm = r1 */
1267                 asi->insn[0] = insn;
1268                 asi->insn_handler = emulate_sel;
1269                 return INSN_GOOD;
1270         }
1271
1272         /* SSAT   : cccc 0110 101x xxxx xxxx xxxx xx01 xxxx :Q */
1273         /* USAT   : cccc 0110 111x xxxx xxxx xxxx xx01 xxxx :Q */
1274         /* SSAT16 : cccc 0110 1010 xxxx xxxx xxxx 0011 xxxx :Q */
1275         /* USAT16 : cccc 0110 1110 xxxx xxxx xxxx 0011 xxxx :Q */
1276         if ((insn & 0x0fa00030) == 0x06a00010 ||
1277             (insn & 0x0fb000f0) == 0x06a00030) {
1278                 if (is_r15(insn, 12))
1279                         return INSN_REJECTED;   /* Rd is PC */
1280                 insn &= 0xffff0ff0;     /* Rd = r0, Rm = r0 */
1281                 asi->insn[0] = insn;
1282                 asi->insn_handler = emulate_sat;
1283                 return INSN_GOOD;
1284         }
1285
1286         /* REV    : cccc 0110 1011 xxxx xxxx xxxx 0011 xxxx */
1287         /* REV16  : cccc 0110 1011 xxxx xxxx xxxx 1011 xxxx */
1288         /* RBIT   : cccc 0110 1111 xxxx xxxx xxxx 0011 xxxx */
1289         /* REVSH  : cccc 0110 1111 xxxx xxxx xxxx 1011 xxxx */
1290         if ((insn & 0x0ff00070) == 0x06b00030 ||
1291             (insn & 0x0ff00070) == 0x06f00030)
1292                 return prep_emulate_rd12rm0(insn, asi);
1293
1294         /* ???       : cccc 0110 0000 xxxx xxxx xxxx xxx1 xxxx :   */
1295         /* SADD16    : cccc 0110 0001 xxxx xxxx xxxx 0001 xxxx :GE */
1296         /* SADDSUBX  : cccc 0110 0001 xxxx xxxx xxxx 0011 xxxx :GE */
1297         /* SSUBADDX  : cccc 0110 0001 xxxx xxxx xxxx 0101 xxxx :GE */
1298         /* SSUB16    : cccc 0110 0001 xxxx xxxx xxxx 0111 xxxx :GE */
1299         /* SADD8     : cccc 0110 0001 xxxx xxxx xxxx 1001 xxxx :GE */
1300         /* ???       : cccc 0110 0001 xxxx xxxx xxxx 1011 xxxx :   */
1301         /* ???       : cccc 0110 0001 xxxx xxxx xxxx 1101 xxxx :   */
1302         /* SSUB8     : cccc 0110 0001 xxxx xxxx xxxx 1111 xxxx :GE */
1303         /* QADD16    : cccc 0110 0010 xxxx xxxx xxxx 0001 xxxx :   */
1304         /* QADDSUBX  : cccc 0110 0010 xxxx xxxx xxxx 0011 xxxx :   */
1305         /* QSUBADDX  : cccc 0110 0010 xxxx xxxx xxxx 0101 xxxx :   */
1306         /* QSUB16    : cccc 0110 0010 xxxx xxxx xxxx 0111 xxxx :   */
1307         /* QADD8     : cccc 0110 0010 xxxx xxxx xxxx 1001 xxxx :   */
1308         /* ???       : cccc 0110 0010 xxxx xxxx xxxx 1011 xxxx :   */
1309         /* ???       : cccc 0110 0010 xxxx xxxx xxxx 1101 xxxx :   */
1310         /* QSUB8     : cccc 0110 0010 xxxx xxxx xxxx 1111 xxxx :   */
1311         /* SHADD16   : cccc 0110 0011 xxxx xxxx xxxx 0001 xxxx :   */
1312         /* SHADDSUBX : cccc 0110 0011 xxxx xxxx xxxx 0011 xxxx :   */
1313         /* SHSUBADDX : cccc 0110 0011 xxxx xxxx xxxx 0101 xxxx :   */
1314         /* SHSUB16   : cccc 0110 0011 xxxx xxxx xxxx 0111 xxxx :   */
1315         /* SHADD8    : cccc 0110 0011 xxxx xxxx xxxx 1001 xxxx :   */
1316         /* ???       : cccc 0110 0011 xxxx xxxx xxxx 1011 xxxx :   */
1317         /* ???       : cccc 0110 0011 xxxx xxxx xxxx 1101 xxxx :   */
1318         /* SHSUB8    : cccc 0110 0011 xxxx xxxx xxxx 1111 xxxx :   */
1319         /* ???       : cccc 0110 0100 xxxx xxxx xxxx xxx1 xxxx :   */
1320         /* UADD16    : cccc 0110 0101 xxxx xxxx xxxx 0001 xxxx :GE */
1321         /* UADDSUBX  : cccc 0110 0101 xxxx xxxx xxxx 0011 xxxx :GE */
1322         /* USUBADDX  : cccc 0110 0101 xxxx xxxx xxxx 0101 xxxx :GE */
1323         /* USUB16    : cccc 0110 0101 xxxx xxxx xxxx 0111 xxxx :GE */
1324         /* UADD8     : cccc 0110 0101 xxxx xxxx xxxx 1001 xxxx :GE */
1325         /* ???       : cccc 0110 0101 xxxx xxxx xxxx 1011 xxxx :   */
1326         /* ???       : cccc 0110 0101 xxxx xxxx xxxx 1101 xxxx :   */
1327         /* USUB8     : cccc 0110 0101 xxxx xxxx xxxx 1111 xxxx :GE */
1328         /* UQADD16   : cccc 0110 0110 xxxx xxxx xxxx 0001 xxxx :   */
1329         /* UQADDSUBX : cccc 0110 0110 xxxx xxxx xxxx 0011 xxxx :   */
1330         /* UQSUBADDX : cccc 0110 0110 xxxx xxxx xxxx 0101 xxxx :   */
1331         /* UQSUB16   : cccc 0110 0110 xxxx xxxx xxxx 0111 xxxx :   */
1332         /* UQADD8    : cccc 0110 0110 xxxx xxxx xxxx 1001 xxxx :   */
1333         /* ???       : cccc 0110 0110 xxxx xxxx xxxx 1011 xxxx :   */
1334         /* ???       : cccc 0110 0110 xxxx xxxx xxxx 1101 xxxx :   */
1335         /* UQSUB8    : cccc 0110 0110 xxxx xxxx xxxx 1111 xxxx :   */
1336         /* UHADD16   : cccc 0110 0111 xxxx xxxx xxxx 0001 xxxx :   */
1337         /* UHADDSUBX : cccc 0110 0111 xxxx xxxx xxxx 0011 xxxx :   */
1338         /* UHSUBADDX : cccc 0110 0111 xxxx xxxx xxxx 0101 xxxx :   */
1339         /* UHSUB16   : cccc 0110 0111 xxxx xxxx xxxx 0111 xxxx :   */
1340         /* UHADD8    : cccc 0110 0111 xxxx xxxx xxxx 1001 xxxx :   */
1341         /* ???       : cccc 0110 0111 xxxx xxxx xxxx 1011 xxxx :   */
1342         /* ???       : cccc 0110 0111 xxxx xxxx xxxx 1101 xxxx :   */
1343         /* UHSUB8    : cccc 0110 0111 xxxx xxxx xxxx 1111 xxxx :   */
1344         if ((insn & 0x0f800010) == 0x06000010) {
1345                 if ((insn & 0x00300000) == 0x00000000 ||
1346                     (insn & 0x000000e0) == 0x000000a0 ||
1347                     (insn & 0x000000e0) == 0x000000c0)
1348                         return INSN_REJECTED;   /* Unallocated space */
1349                 return prep_emulate_rd12rn16rm0_wflags(insn, asi);
1350         }
1351
1352         /* PKHBT     : cccc 0110 1000 xxxx xxxx xxxx x001 xxxx :   */
1353         /* PKHTB     : cccc 0110 1000 xxxx xxxx xxxx x101 xxxx :   */
1354         if ((insn & 0x0ff00030) == 0x06800010)
1355                 return prep_emulate_rd12rn16rm0_wflags(insn, asi);
1356
1357         /* SXTAB16   : cccc 0110 1000 xxxx xxxx xxxx 0111 xxxx :   */
1358         /* SXTB16    : cccc 0110 1000 1111 xxxx xxxx 0111 xxxx :   */
1359         /* ???       : cccc 0110 1001 xxxx xxxx xxxx 0111 xxxx :   */
1360         /* SXTAB     : cccc 0110 1010 xxxx xxxx xxxx 0111 xxxx :   */
1361         /* SXTB      : cccc 0110 1010 1111 xxxx xxxx 0111 xxxx :   */
1362         /* SXTAH     : cccc 0110 1011 xxxx xxxx xxxx 0111 xxxx :   */
1363         /* SXTH      : cccc 0110 1011 1111 xxxx xxxx 0111 xxxx :   */
1364         /* UXTAB16   : cccc 0110 1100 xxxx xxxx xxxx 0111 xxxx :   */
1365         /* UXTB16    : cccc 0110 1100 1111 xxxx xxxx 0111 xxxx :   */
1366         /* ???       : cccc 0110 1101 xxxx xxxx xxxx 0111 xxxx :   */
1367         /* UXTAB     : cccc 0110 1110 xxxx xxxx xxxx 0111 xxxx :   */
1368         /* UXTB      : cccc 0110 1110 1111 xxxx xxxx 0111 xxxx :   */
1369         /* UXTAH     : cccc 0110 1111 xxxx xxxx xxxx 0111 xxxx :   */
1370         /* UXTH      : cccc 0110 1111 1111 xxxx xxxx 0111 xxxx :   */
1371         if ((insn & 0x0f8000f0) == 0x06800070) {
1372                 if ((insn & 0x00300000) == 0x00100000)
1373                         return INSN_REJECTED;   /* Unallocated space */
1374
1375                 if ((insn & 0x000f0000) == 0x000f0000)
1376                         return prep_emulate_rd12rm0(insn, asi);
1377                 else
1378                         return prep_emulate_rd12rn16rm0_wflags(insn, asi);
1379         }
1380
1381         /* Other instruction encodings aren't yet defined */
1382         return INSN_REJECTED;
1383 }
1384
1385 static enum kprobe_insn __kprobes
1386 space_cccc_0111__1(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1387 {
1388         /* Undef : cccc 0111 1111 xxxx xxxx xxxx 1111 xxxx */
1389         if ((insn & 0x0ff000f0) == 0x03f000f0)
1390                 return INSN_REJECTED;
1391
1392         /* SMLALD : cccc 0111 0100 xxxx xxxx xxxx 00x1 xxxx */
1393         /* SMLSLD : cccc 0111 0100 xxxx xxxx xxxx 01x1 xxxx */
1394         if ((insn & 0x0ff00090) == 0x07400010)
1395                 return prep_emulate_rdhi16rdlo12rs8rm0_wflags(insn, asi);
1396
1397         /* SMLAD  : cccc 0111 0000 xxxx xxxx xxxx 00x1 xxxx :Q */
1398         /* SMUAD  : cccc 0111 0000 xxxx 1111 xxxx 00x1 xxxx :Q */
1399         /* SMLSD  : cccc 0111 0000 xxxx xxxx xxxx 01x1 xxxx :Q */
1400         /* SMUSD  : cccc 0111 0000 xxxx 1111 xxxx 01x1 xxxx :  */
1401         /* SMMLA  : cccc 0111 0101 xxxx xxxx xxxx 00x1 xxxx :  */
1402         /* SMMUL  : cccc 0111 0101 xxxx 1111 xxxx 00x1 xxxx :  */
1403         /* USADA8 : cccc 0111 1000 xxxx xxxx xxxx 0001 xxxx :  */
1404         /* USAD8  : cccc 0111 1000 xxxx 1111 xxxx 0001 xxxx :  */
1405         if ((insn & 0x0ff00090) == 0x07000010 ||
1406             (insn & 0x0ff000d0) == 0x07500010 ||
1407             (insn & 0x0ff000f0) == 0x07800010) {
1408
1409                 if ((insn & 0x0000f000) == 0x0000f000)
1410                         return prep_emulate_rd16rs8rm0_wflags(insn, asi);
1411                 else
1412                         return prep_emulate_rd16rn12rs8rm0_wflags(insn, asi);
1413         }
1414
1415         /* SMMLS  : cccc 0111 0101 xxxx xxxx xxxx 11x1 xxxx :  */
1416         if ((insn & 0x0ff000d0) == 0x075000d0)
1417                 return prep_emulate_rd16rn12rs8rm0_wflags(insn, asi);
1418
1419         /* SBFX   : cccc 0111 101x xxxx xxxx xxxx x101 xxxx :  */
1420         /* UBFX   : cccc 0111 111x xxxx xxxx xxxx x101 xxxx :  */
1421         if ((insn & 0x0fa00070) == 0x07a00050)
1422                 return prep_emulate_rd12rm0(insn, asi);
1423
1424         /* BFI    : cccc 0111 110x xxxx xxxx xxxx x001 xxxx :  */
1425         /* BFC    : cccc 0111 110x xxxx xxxx xxxx x001 1111 :  */
1426         if ((insn & 0x0fe00070) == 0x07c00010) {
1427
1428                 if ((insn & 0x0000000f) == 0x0000000f)
1429                         return prep_emulate_rd12_modify(insn, asi);
1430                 else
1431                         return prep_emulate_rd12rn0_modify(insn, asi);
1432         }
1433
1434         return INSN_REJECTED;
1435 }
1436
1437 static enum kprobe_insn __kprobes
1438 space_cccc_01xx(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1439 {
1440         /* LDR   : cccc 01xx x0x1 xxxx xxxx xxxx xxxx xxxx */
1441         /* LDRB  : cccc 01xx x1x1 xxxx xxxx xxxx xxxx xxxx */
1442         /* LDRBT : cccc 01x0 x111 xxxx xxxx xxxx xxxx xxxx */
1443         /* LDRT  : cccc 01x0 x011 xxxx xxxx xxxx xxxx xxxx */
1444         /* STR   : cccc 01xx x0x0 xxxx xxxx xxxx xxxx xxxx */
1445         /* STRB  : cccc 01xx x1x0 xxxx xxxx xxxx xxxx xxxx */
1446         /* STRBT : cccc 01x0 x110 xxxx xxxx xxxx xxxx xxxx */
1447         /* STRT  : cccc 01x0 x010 xxxx xxxx xxxx xxxx xxxx */
1448
1449         if ((insn & 0x00500000) == 0x00500000 && is_r15(insn, 12))
1450                 return INSN_REJECTED;   /* LDRB into PC */
1451
1452         return prep_emulate_ldr_str(insn, asi);
1453 }
1454
1455 static enum kprobe_insn __kprobes
1456 space_cccc_100x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1457 {
1458         /* LDM(2) : cccc 100x x101 xxxx 0xxx xxxx xxxx xxxx */
1459         /* LDM(3) : cccc 100x x1x1 xxxx 1xxx xxxx xxxx xxxx */
1460         if ((insn & 0x0e708000) == 0x85000000 ||
1461             (insn & 0x0e508000) == 0x85010000)
1462                 return INSN_REJECTED;
1463
1464         /* LDM(1) : cccc 100x x0x1 xxxx xxxx xxxx xxxx xxxx */
1465         /* STM(1) : cccc 100x x0x0 xxxx xxxx xxxx xxxx xxxx */
1466         asi->insn_handler = ((insn & 0x108000) == 0x008000) ? /* STM & R15 */
1467                                 simulate_stm1_pc : simulate_ldm1stm1;
1468         return INSN_GOOD_NO_SLOT;
1469 }
1470
1471 static enum kprobe_insn __kprobes
1472 space_cccc_101x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1473 {
1474         /* B  : cccc 1010 xxxx xxxx xxxx xxxx xxxx xxxx */
1475         /* BL : cccc 1011 xxxx xxxx xxxx xxxx xxxx xxxx */
1476         asi->insn_handler = simulate_bbl;
1477         return INSN_GOOD_NO_SLOT;
1478 }
1479
1480 static enum kprobe_insn __kprobes
1481 space_cccc_11xx(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1482 {
1483         /* Coprocessor instructions... */
1484         /* MCRR : cccc 1100 0100 xxxx xxxx xxxx xxxx xxxx : (Rd!=Rn) */
1485         /* MRRC : cccc 1100 0101 xxxx xxxx xxxx xxxx xxxx : (Rd!=Rn) */
1486         /* LDC  : cccc 110x xxx1 xxxx xxxx xxxx xxxx xxxx */
1487         /* STC  : cccc 110x xxx0 xxxx xxxx xxxx xxxx xxxx */
1488         /* CDP  : cccc 1110 xxxx xxxx xxxx xxxx xxx0 xxxx */
1489         /* MCR  : cccc 1110 xxx0 xxxx xxxx xxxx xxx1 xxxx */
1490         /* MRC  : cccc 1110 xxx1 xxxx xxxx xxxx xxx1 xxxx */
1491
1492         /* SVC  : cccc 1111 xxxx xxxx xxxx xxxx xxxx xxxx */
1493
1494         return INSN_REJECTED;
1495 }
1496
1497 /* Return:
1498  *   INSN_REJECTED     If instruction is one not allowed to kprobe,
1499  *   INSN_GOOD         If instruction is supported and uses instruction slot,
1500  *   INSN_GOOD_NO_SLOT If instruction is supported but doesn't use its slot.
1501  *
1502  * For instructions we don't want to kprobe (INSN_REJECTED return result):
1503  *   These are generally ones that modify the processor state making
1504  *   them "hard" to simulate such as switches processor modes or
1505  *   make accesses in alternate modes.  Any of these could be simulated
1506  *   if the work was put into it, but low return considering they
1507  *   should also be very rare.
1508  */
1509 enum kprobe_insn __kprobes
1510 arm_kprobe_decode_insn(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1511 {
1512         asi->insn_check_cc = kprobe_condition_checks[insn>>28];
1513         asi->insn[1] = KPROBE_RETURN_INSTRUCTION;
1514
1515         if ((insn & 0xf0000000) == 0xf0000000)
1516
1517                 return space_1111(insn, asi);
1518
1519         else if ((insn & 0x0e000000) == 0x00000000)
1520
1521                 return space_cccc_000x(insn, asi);
1522
1523         else if ((insn & 0x0e000000) == 0x02000000)
1524
1525                 return space_cccc_001x(insn, asi);
1526
1527         else if ((insn & 0x0f000010) == 0x06000010)
1528
1529                 return space_cccc_0110__1(insn, asi);
1530
1531         else if ((insn & 0x0f000010) == 0x07000010)
1532
1533                 return space_cccc_0111__1(insn, asi);
1534
1535         else if ((insn & 0x0c000000) == 0x04000000)
1536
1537                 return space_cccc_01xx(insn, asi);
1538
1539         else if ((insn & 0x0e000000) == 0x08000000)
1540
1541                 return space_cccc_100x(insn, asi);
1542
1543         else if ((insn & 0x0e000000) == 0x0a000000)
1544
1545                 return space_cccc_101x(insn, asi);
1546
1547         return space_cccc_11xx(insn, asi);
1548 }