}
EXPORT_SYMBOL_GPL(arch_check_insn_arm);
-int arch_prepare_kprobe(struct kprobe *p)
+int arch_prepare_kprobe(struct kprobe *p, struct slot_manager *sm)
{
kprobe_opcode_t insns[KPROBES_TRAMP_LEN];
int uregs, pc_dep, ret = 0;
struct arch_specific_insn ainsn;
/* insn: must be on special executable page on i386. */
- p->ainsn.insn = get_insn_slot(NULL, &kprobe_insn_pages, 0);
+ p->ainsn.insn = alloc_insn_slot(sm);
if (!p->ainsn.insn)
return -ENOMEM;
// check instructions that can write result to SP andu uses PC
if (pc_dep && (ARM_INSN_REG_RD(ainsn.insn[0]) == 13)) {
- free_insn_slot(&kprobe_insn_pages, NULL, p->ainsn.insn);
+ free_insn_slot(sm, p->ainsn.insn);
ret = -EFAULT;
} else {
if (uregs && pc_dep) {
memcpy(insns, pc_dep_insn_execbuf, sizeof(insns));
if (prep_pc_dep_insn_execbuf(insns, insn[0], uregs) != 0) {
DBPRINTF ("failed to prepare exec buffer for insn %lx!", insn[0]);
- free_insn_slot(&kprobe_insn_pages, NULL, p->ainsn.insn);
+ free_insn_slot(sm, p->ainsn.insn);
return -EINVAL;
}
insns[6] = (kprobe_opcode_t)(p->addr + 2);
#endif
}
} else {
- free_insn_slot(&kprobe_insn_pages, NULL, p->ainsn.insn);
+ free_insn_slot(sm, p->ainsn.insn);
printk("arch_prepare_kprobe: instruction 0x%lx not instrumentation, addr=0x%p\n", insn[0], p->addr);
}
struct kretprobe *crp = NULL;
struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
- DBPRINTF ("start");
-
spin_lock_irqsave(&kretprobe_lock, flags);
/*
}
kretprobe_assert(ri, orig_ret_address, trampoline_address);
- regs->uregs[14] = orig_ret_address;
- DBPRINTF ("regs->uregs[14] = 0x%lx\n", regs->uregs[14]);
- DBPRINTF ("regs->uregs[15] = 0x%lx\n", regs->uregs[15]);
+ regs->ARM_lr = orig_ret_address;
+ regs->ARM_pc = orig_ret_address;
- if (trampoline_address != (unsigned long) &kretprobe_trampoline) {
- regs->uregs[15] = orig_ret_address;
+ if (kcb->kprobe_status == KPROBE_REENTER) {
+ restore_previous_kprobe(kcb);
} else {
- if (!thumb_mode( regs )) {
- regs->uregs[15] += 4;
- } else {
- regs->uregs[15] += 2;
- }
- }
-
- DBPRINTF ("regs->uregs[15] = 0x%lx\n", regs->uregs[15]);
-
- if(p) { // ARM, MIPS, X86 user space
- if (thumb_mode(regs) && !(regs->uregs[14] & 0x01)) {
- regs->ARM_cpsr &= 0xFFFFFFDF;
- } else {
- if (user_mode(regs) && (regs->uregs[14] & 0x01)) {
- regs->ARM_cpsr |= 0x20;
- }
- }
-
- if (kcb->kprobe_status == KPROBE_REENTER) {
- restore_previous_kprobe(kcb);
- } else {
- reset_current_kprobe();
- }
+ reset_current_kprobe();
}
spin_unlock_irqrestore(&kretprobe_lock, flags);
void arch_exit_kprobes(void)
{
+ dbi_unregister_kprobe(&trampoline_p, NULL);
swap_unregister_undef_hook(&undef_ho_k);
}