22 #include <linux/kernel.h>
24 #include <linux/module.h>
25 #include <linux/slab.h>
28 #include <asm/traps.h>
29 #include <asm/cacheflush.h>
34 #define MIN_STACK_SIZE(addr) \
35 min((unsigned long)MAX_STACK_SIZE, \
36 (unsigned long)current_thread_info() + THREAD_START_SP - (addr))
38 #define flush_insns(addr, size) \
39 flush_icache_range((unsigned long)(addr), \
40 (unsigned long)(addr) + \
44 #define JPROBE_MAGIC_ADDR 0xffffffff
59 if (in_exception_text(addr))
62 #ifdef CONFIG_THUMB2_KERNEL
65 insn = ((
u16 *)addr)[0];
68 insn |= ((
u16 *)addr)[1];
81 p->
ainsn.insn = tmp_insn;
83 switch ((*decode_insn)(
insn, &p->
ainsn)) {
88 p->
ainsn.insn = get_insn_slot();
94 sizeof(p->
ainsn.insn[0]) * MAX_INSN_SIZE);
126 if (insn >= 0xe0000000)
129 brkp |= insn & 0xf0000000;
161 free_insn_slot(p->
ainsn.insn, 0);
186 #ifdef CONFIG_THUMB2_KERNEL
187 regs->ARM_cpsr = it_advance(regs->ARM_cpsr);
200 p->
ainsn.insn_singlestep(p, regs);
215 kcb = get_kprobe_ctlblk();
216 cur = kprobe_running();
218 #ifdef CONFIG_THUMB2_KERNEL
237 case KPROBE_HIT_SSDONE:
240 save_previous_kprobe(kcb);
241 set_current_kprobe(p);
243 singlestep(p, regs, kcb);
244 restore_previous_kprobe(kcb);
250 }
else if (p->
ainsn.insn_check_cc(regs->ARM_cpsr)) {
252 set_current_kprobe(p);
264 singlestep(p, regs, kcb);
269 reset_current_kprobe();
277 singlestep_skip(p, regs);
283 singlestep(cur, regs, kcb);
289 reset_current_kprobe();
326 restore_previous_kprobe(kcb);
328 reset_current_kprobe();
333 case KPROBE_HIT_SSDONE:
380 "stmdb sp!, {r0 - r11} \n\t"
382 "bl trampoline_handler \n\t"
384 "ldmia sp!, {r0 - r11} \n\t"
385 #ifdef CONFIG_THUMB2_KERNEL
399 unsigned long flags, orig_ret_address = 0;
423 if (ri->
rp && ri->
rp->handler) {
426 ri->
rp->handler(ri, regs);
433 if (orig_ret_address != trampoline_address)
442 kretprobe_assert(ri, orig_ret_address, trampoline_address);
446 hlist_del(&ri->
hlist);
450 return (
void *)orig_ret_address;
466 long sp_addr = regs->ARM_sp;
474 #ifdef CONFIG_THUMB2_KERNEL
476 if (regs->ARM_pc & 1)
481 regs->ARM_cpsr = cpsr;
504 #ifdef CONFIG_THUMB2_KERNEL
505 "sub r0, %0, %1 \n\t"
508 "sub sp, %0, %1 \n\t"
511 "str %0, [sp, %2] \n\t"
512 "str r0, [sp, %3] \n\t"
514 "bl kprobe_handler \n\t"
520 #ifdef CONFIG_THUMB2_KERNEL
521 "ldr lr, [sp, %2] \n\t"
522 "ldrd r0, r1, [sp, %5] \n\t"
523 "ldr r2, [sp, %4] \n\t"
524 "stmdb lr!, {r0, r1, r2} \n\t"
526 "ldmia sp, {r0 - r12} \n\t"
528 "ldr lr, [sp], #4 \n\t"
531 "ldr r0, [sp, %4] \n\t"
532 "msr cpsr_cxsf, r0 \n\t"
533 "ldmia sp, {r0 - pc} \n\t"
537 "I" (
sizeof(
struct pt_regs) * 2),
549 long orig_sp = regs->ARM_sp;
553 if (orig_sp != stack_addr) {
556 printk(
"current sp %lx does not match saved sp %lx\n",
557 orig_sp, stack_addr);
558 printk(
"Saved registers for jprobe %p\n", jp);
560 printk(
"Current registers\n");
578 #ifdef CONFIG_THUMB2_KERNEL
580 static struct undef_hook kprobes_thumb16_break_hook = {
585 .fn = kprobe_trap_handler,
588 static struct undef_hook kprobes_thumb32_break_hook = {
593 .fn = kprobe_trap_handler,
598 static struct undef_hook kprobes_arm_break_hook = {
599 .instr_mask = 0x0fffffff,
603 .fn = kprobe_trap_handler,
611 #ifdef CONFIG_THUMB2_KERNEL