return ret;
}
-void arch_prepare_uretprobe_hl(struct kretprobe *rp, struct pt_regs *regs)
+void arch_prepare_uretprobe_hl(struct kretprobe_instance *ri,
+ struct pt_regs *regs)
{
- struct kretprobe_instance *ri;
+ /* Set flag of current mode */
+ ri->sp = (kprobe_opcode_t *)((long)ri->sp | !!thumb_mode(regs));
- /* TODO: test - remove retprobe after func entry but before its exit */
- if ((ri = get_free_rp_inst(rp)) != NULL) {
- ri->rp = rp;
- ri->rp2 = NULL;
- ri->task = current;
- ri->ret_addr = (kprobe_opcode_t *)regs->ARM_lr;
- ri->sp = (kprobe_opcode_t *)regs->ARM_sp;
-
- /* Set flag of current mode */
- ri->sp = (kprobe_opcode_t *)((long)ri->sp | !!thumb_mode(regs));
-
- if (thumb_mode(regs)) {
- regs->ARM_lr = (unsigned long)(rp->kp.ainsn.insn) + 0x1b;
- } else {
- regs->ARM_lr = (unsigned long)(rp->kp.ainsn.insn + UPROBES_TRAMP_RET_BREAK_IDX);
- }
-
- add_rp_inst(ri);
+ if (thumb_mode(regs)) {
+ regs->ARM_lr = (unsigned long)(ri->rp->kp.ainsn.insn) + 0x1b;
} else {
- ++rp->nmissed;
+ regs->ARM_lr = (unsigned long)(ri->rp->kp.ainsn.insn + UPROBES_TRAMP_RET_BREAK_IDX);
}
}
return 0;
}
-void arch_prepare_uretprobe_hl(struct kretprobe *rp, struct pt_regs *regs);
+void arch_prepare_uretprobe_hl(struct kretprobe_instance *ri, struct pt_regs *regs);
int swap_arch_init_uprobes(void);
void swap_arch_exit_uprobes(void);
static int pre_handler_uretprobe(struct kprobe *p, struct pt_regs *regs)
{
struct kretprobe *rp = container_of(p, struct kretprobe, kp);
+ struct kretprobe_instance *ri;
unsigned long flags;
/* TODO: consider to only swap the RA after the last pre_handler fired */
spin_lock_irqsave(&kretprobe_lock, flags);
- if (!rp->disarm) {
- arch_prepare_uretprobe_hl(rp, regs);
+ if (rp->disarm) {
+ goto unlock;
}
+
+ /* TODO: test - remove retprobe after func entry but before its exit */
+ if ((ri = get_free_rp_inst(rp)) != NULL) {
+ ri->rp = rp;
+ ri->rp2 = NULL;
+ ri->task = current;
+ ri->ret_addr = (kprobe_opcode_t *)regs->ARM_lr;
+ ri->sp = (kprobe_opcode_t *)regs->ARM_sp;
+
+ arch_prepare_uretprobe_hl(ri, regs);
+
+ add_rp_inst(ri);
+ } else {
+ ++rp->nmissed;
+ }
+
+unlock:
spin_unlock_irqrestore(&kretprobe_lock, flags);
return 0;