if (!p->tgid || (p->tgid == current->tgid)) {
/* handle __switch_to probe */
if(!p->tgid && (p->addr == sched_addr) && sched_rp) {
- struct thread_info *tinfo = NULL; //TODO implement for x86
- patch_suspended_task(sched_rp, tinfo->task);
+ /* FIXME: Acutally 2nd parameter is not used for x86 */
+ patch_suspended_task(sched_rp, (struct task_struct *)regs->dx, regs);
}
}
#define KPROBES_TRAMP_LEN MAX_INSN_SIZE
#define KPROBES_TRAMP_INSN_IDX 0
+static inline unsigned long *arch_get_patch_addr(struct task_struct *p,
+ struct pt_regs *regs)
+{
+ return (unsigned long *)kernel_stack_pointer(regs);
+}
+
static inline unsigned long arch_get_task_pc(struct task_struct *p)
{
- return p->thread.ip;
+ /* FIXME: Not implemented yet */
+ return 0;
}
static inline void arch_set_task_pc(struct task_struct *p, unsigned long val)
{
- p->thread.ip = val;
+ /* FIXME: Not implemented yet */
}
static inline struct pt_regs *dbi_get_syscall_uregs(unsigned long sp)
extern void arch_disarm_uretprobe (struct kretprobe *p, struct task_struct *tsk);
extern int arch_init_kprobes (void);
extern void dbi_arch_exit_kprobes (void);
-extern int patch_suspended_task(struct kretprobe *rp, struct task_struct *tsk);
+extern int patch_suspended_task(struct kretprobe *rp, struct task_struct *tsk, struct pt_regs *);
void dbi_arch_uprobe_return (void);
return clone;
}
-static void inline set_task_trampoline(struct task_struct *p, struct kretprobe_instance *ri, unsigned long tramp_addr)
+static void inline set_task_trampoline(unsigned long *patch_addr,
+ struct kretprobe_instance *ri,
+ unsigned long tramp_addr)
{
- unsigned long pc = arch_get_task_pc(p);
+ unsigned long pc = *patch_addr;
if (pc == tramp_addr)
panic("[%d] %s (%d/%d): pc = %08lx --- [%d] %s (%d/%d)\n",
- task_cpu(p), p->comm, p->tgid, p->pid, pc,
- task_cpu(current), current->comm, current->tgid, current->pid);
+ task_cpu(ri->task), ri->task->comm, ri->task->tgid,
+ ri->task->pid, pc, task_cpu(current), current->comm,
+ current->tgid, current->pid);
ri->ret_addr = (kprobe_opcode_t *)pc;
- arch_set_task_pc(p, tramp_addr);
+ *patch_addr = tramp_addr;
}
static void inline rm_task_trampoline(struct task_struct *p, struct kretprobe_instance *ri)
return retval;
}
-int patch_suspended_task(struct kretprobe *rp, struct task_struct *task)
+int patch_suspended_task(struct kretprobe *rp,
+ struct task_struct *task,
+ struct pt_regs *regs)
{
struct kretprobe_instance *ri;
unsigned long flags;
kprobe_opcode_t *tramp = (kprobe_opcode_t *)&kretprobe_trampoline;
+ unsigned long *patch_addr;
spin_lock_irqsave(&kretprobe_lock, flags);
ri->rp2 = NULL;
ri->task = task;
ri->sp = NULL;
- set_task_trampoline(task, ri, (unsigned long)tramp);
+ patch_addr = arch_get_patch_addr(task, regs);
+ set_task_trampoline(patch_addr, ri, (unsigned long)tramp);
add_rp_inst(ri);
spin_unlock_irqrestore(&kretprobe_lock, flags);