14 #include <linux/kernel.h>
21 #ifndef find_str_pc_offset
37 "sub %[ret], pc, #4 \n\t"
38 "str pc, %[addr] \n\t"
39 "ldr %[scr], %[addr] \n\t"
40 "sub %[ret], %[scr], %[ret] \n\t"
41 : [ret]
"=r" (ret), [
scr]
"=r" (scratch), [addr]
"+m" (addr));
49 #ifndef test_load_write_pc_interworking
63 #ifndef test_alu_write_pc_interworking
85 static unsigned long __kprobes __check_eq(
unsigned long cpsr)
90 static unsigned long __kprobes __check_ne(
unsigned long cpsr)
95 static unsigned long __kprobes __check_cs(
unsigned long cpsr)
100 static unsigned long __kprobes __check_cc(
unsigned long cpsr)
105 static unsigned long __kprobes __check_mi(
unsigned long cpsr)
110 static unsigned long __kprobes __check_pl(
unsigned long cpsr)
115 static unsigned long __kprobes __check_vs(
unsigned long cpsr)
120 static unsigned long __kprobes __check_vc(
unsigned long cpsr)
125 static unsigned long __kprobes __check_hi(
unsigned long cpsr)
127 cpsr &= ~(cpsr >> 1);
131 static unsigned long __kprobes __check_ls(
unsigned long cpsr)
133 cpsr &= ~(cpsr >> 1);
137 static unsigned long __kprobes __check_ge(
unsigned long cpsr)
143 static unsigned long __kprobes __check_lt(
unsigned long cpsr)
149 static unsigned long __kprobes __check_gt(
unsigned long cpsr)
151 unsigned long temp = cpsr ^ (cpsr << 3);
156 static unsigned long __kprobes __check_le(
unsigned long cpsr)
158 unsigned long temp = cpsr ^ (cpsr << 3);
163 static unsigned long __kprobes __check_al(
unsigned long cpsr)
169 &__check_eq, &__check_ne, &__check_cs, &__check_cc,
170 &__check_mi, &__check_pl, &__check_vs, &__check_vc,
171 &__check_hi, &__check_ls, &__check_ge, &__check_lt,
172 &__check_gt, &__check_le, &__check_al, &__check_al
188 int rn = (insn >> 16) & 0xf;
189 int lbit = insn & (1 << 20);
190 int wbit = insn & (1 << 21);
191 int ubit = insn & (1 << 23);
192 int pbit = insn & (1 << 24);
198 reg_bit_vector = insn & 0xffff;
199 while (reg_bit_vector) {
200 reg_bit_vector &= (reg_bit_vector - 1);
206 addr += (!pbit == !ubit);
208 reg_bit_vector = insn & 0xffff;
209 while (reg_bit_vector) {
211 reg_bit_vector &= (reg_bit_vector - 1);
221 addr -= (!pbit == !ubit);
229 simulate_ldm1stm1(p, regs);
235 simulate_ldm1stm1(p, regs);
236 load_write_pc(regs->ARM_pc, regs);
240 emulate_generic_r0_12_noflags(
struct kprobe *p,
struct pt_regs *regs)
242 register void *rregs
asm(
"r1") = regs;
243 register void *rfn
asm(
"lr") = p->
ainsn.insn_fn;
246 "stmdb sp!, {%[regs], r11} \n\t"
247 "ldmia %[regs], {r0-r12} \n\t"
248 #
if __LINUX_ARM_ARCH__ >= 6
251 "str %[fn], [sp, #-4]! \n\t"
253 "ldr pc, [sp], #4 \n\t"
256 "ldr lr, [sp], #4 \n\t"
257 "stmia lr, {r0-r12} \n\t"
258 "ldr r11, [sp], #4 \n\t"
259 : [regs]
"=r" (rregs), [
fn]
"=r" (rfn)
260 :
"0" (rregs),
"1" (rfn)
261 :
"r0",
"r2",
"r3",
"r4",
"r5",
"r6",
"r7",
262 "r8",
"r9",
"r10",
"r12",
"memory",
"cc"
267 emulate_generic_r2_14_noflags(
struct kprobe *p,
struct pt_regs *regs)
269 emulate_generic_r0_12_noflags(p, (
struct pt_regs *)(regs->
uregs+2));
275 emulate_generic_r0_12_noflags(p, (
struct pt_regs *)(regs->
uregs+3));
276 load_write_pc(regs->ARM_pc, regs);
283 unsigned reglist = insn & 0xffff;
284 int is_ldm = insn & 0x100000;
285 int rn = (insn >> 16) & 0xf;
287 if (rn <= 12 && (reglist & 0xe000) == 0) {
289 handler = emulate_generic_r0_12_noflags;
291 }
else if (rn >= 2 && (reglist & 0x8003) == 0) {
295 handler = emulate_generic_r2_14_noflags;
297 }
else if (rn >= 3 && (reglist & 0x0007) == 0) {
299 if (is_ldm && (reglist & 0x8000)) {
302 handler = emulate_ldm_r3_15;
308 asi->
insn[0] = (insn & 0xfff00000) | (rn << 16) | reglist;
314 if (reglist & 0x8000)
315 handler = is_ldm ? simulate_ldm1_pc : simulate_stm1_pc;
317 handler = simulate_ldm1stm1;
334 #ifdef CONFIG_THUMB2_KERNEL
337 thumb_insn[1] = 0x4770;
338 thumb_insn[2] = 0x4770;
341 asi->
insn[1] = 0xe12fff1e;
343 asi->
insn[1] = 0xe1a0f00e;
346 if (insn < 0xe0000000)
347 insn = (insn | 0xe0000000) & ~0x10000000;
359 #ifdef CONFIG_THUMB2_KERNEL
380 #define INSN_NEW_BITS 0x00020103
383 #define INSN_SAMEAS16_BITS 0x22222222
397 for (; regs != 0; regs >>= 4, mask <<= 4) {
401 switch (regs & 0xf) {
418 if ((insn ^ 0xdddddddd) & mask)
424 if ((insn ^ 0xffffffff) & mask)
430 if (((insn ^ 0xdddddddd) & mask) == 0)
437 if (((insn ^ 0xdddddddd) & 0xdddddddd & mask) == 0)
448 if (((insn ^ 0xffffffff) & mask) == 0)
455 insn |= new_bits &
mask;
523 bool matched =
false;
525 insn = prepare_emulated_insn(insn, asi, thumb);
540 if (!decode_regs(&insn, regs))
565 set_emulated_insn(insn, asi, thumb);