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