}
EXPORT_SYMBOL_GPL(trampoline_probe_handler);
-void arch_prepare_kretprobe(struct kretprobe *rp, struct pt_regs *regs)
+void arch_prepare_kretprobe(struct kretprobe_instance *ri, struct pt_regs *regs)
{
- struct kretprobe_instance *ri;
+ ri->ret_addr = (kprobe_opcode_t *)regs->ARM_lr;
+ ri->sp = (kprobe_opcode_t *)regs->ARM_sp;
- DBPRINTF ("start\n");
- //TODO: test - remove retprobe after func entry but before its exit
- if ((ri = get_free_rp_inst(rp)) != NULL) {
- ri->rp = rp;
- ri->task = current;
-
- if (rp->entry_handler) {
- rp->entry_handler(ri, regs, ri->rp->priv_arg);
- }
-
- ri->ret_addr = (kprobe_opcode_t *)regs->uregs[14];
- ri->sp = (kprobe_opcode_t *)regs->ARM_sp; //uregs[13];
-
- /* Set flag of current mode */
- ri->sp = (kprobe_opcode_t *)((long)ri->sp | !!thumb_mode(regs));
-
- /* Replace the return addr with trampoline addr */
- regs->uregs[14] = (unsigned long)&kretprobe_trampoline;
-
-// DBPRINTF ("ret addr set to %p->%lx\n", ri->ret_addr, regs->uregs[14]);
- add_rp_inst(ri);
- } else {
- DBPRINTF ("WARNING: missed retprobe %p\n", rp->kp.addr);
- rp->nmissed++;
- }
+ /* Replace the return addr with trampoline addr */
+ regs->ARM_lr = (unsigned long)&kretprobe_trampoline;
}
void swap_register_undef_hook(struct undef_hook *hook)
struct slot_manager;
struct kretprobe;
+struct kretprobe_instance;
int arch_prepare_kprobe(struct kprobe *p, struct slot_manager *sm);
-void arch_prepare_kretprobe(struct kretprobe *rp, struct pt_regs *regs);
+void arch_prepare_kretprobe(struct kretprobe_instance *ri, struct pt_regs *regs);
void arch_arm_kprobe(struct kprobe *p);
void arch_disarm_kprobe(struct kprobe *p);
* This kprobe pre_handler is registered with every kretprobe. When probe
* hits it will set up the return probe.
*/
-int pre_handler_kretprobe(struct kprobe *p, struct pt_regs *regs)
+static int pre_handler_kretprobe(struct kprobe *p, struct pt_regs *regs)
{
struct kretprobe *rp = container_of(p, struct kretprobe, kp);
+ struct kretprobe_instance *ri;
unsigned long flags = 0;
- DBPRINTF ("START\n");
- /*TODO: consider to only swap the RA after the last pre_handler fired */
+ /* TODO: consider to only swap the RA after the last pre_handler fired */
spin_lock_irqsave(&kretprobe_lock, flags);
- arch_prepare_kretprobe(rp, regs);
+ /* TODO: test - remove retprobe after func entry but before its exit */
+ if ((ri = get_free_rp_inst(rp)) != NULL) {
+ ri->rp = rp;
+ ri->task = current;
+
+ if (rp->entry_handler) {
+ rp->entry_handler(ri, regs, ri->rp->priv_arg);
+ }
+
+ arch_prepare_kretprobe(ri, regs);
+
+ add_rp_inst(ri);
+ } else {
+ ++rp->nmissed;
+ }
spin_unlock_irqrestore(&kretprobe_lock, flags);
- DBPRINTF ("END\n");
+
return 0;
}
-EXPORT_SYMBOL_GPL(pre_handler_kretprobe);
struct kretprobe *sched_rp;
void dbi_unregister_kprobe (struct kprobe *p, struct task_struct *task);
int register_aggr_kprobe (struct kprobe *old_p, struct kprobe *p);
-int pre_handler_kretprobe (struct kprobe *p, struct pt_regs *regs);
int setjmp_pre_handler (struct kprobe *, struct pt_regs *);
int longjmp_break_handler (struct kprobe *, struct pt_regs *);