|
@@ -441,53 +441,6 @@ out:
|
|
|
exception_exit(prev_state);
|
|
|
}
|
|
|
|
|
|
-/* Jprobes support. */
|
|
|
-int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
|
|
|
-{
|
|
|
- struct jprobe *jp = container_of(p, struct jprobe, kp);
|
|
|
- struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
|
|
|
-
|
|
|
- memcpy(&(kcb->jprobe_saved_regs), regs, sizeof(*regs));
|
|
|
-
|
|
|
- regs->tpc = (unsigned long) jp->entry;
|
|
|
- regs->tnpc = ((unsigned long) jp->entry) + 0x4UL;
|
|
|
- regs->tstate |= TSTATE_PIL;
|
|
|
-
|
|
|
- return 1;
|
|
|
-}
|
|
|
-
|
|
|
-void __kprobes jprobe_return(void)
|
|
|
-{
|
|
|
- struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
|
|
|
- register unsigned long orig_fp asm("g1");
|
|
|
-
|
|
|
- orig_fp = kcb->jprobe_saved_regs.u_regs[UREG_FP];
|
|
|
- __asm__ __volatile__("\n"
|
|
|
-"1: cmp %%sp, %0\n\t"
|
|
|
- "blu,a,pt %%xcc, 1b\n\t"
|
|
|
- " restore\n\t"
|
|
|
- ".globl jprobe_return_trap_instruction\n"
|
|
|
-"jprobe_return_trap_instruction:\n\t"
|
|
|
- "ta 0x70"
|
|
|
- : /* no outputs */
|
|
|
- : "r" (orig_fp));
|
|
|
-}
|
|
|
-
|
|
|
-extern void jprobe_return_trap_instruction(void);
|
|
|
-
|
|
|
-int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
|
|
|
-{
|
|
|
- u32 *addr = (u32 *) regs->tpc;
|
|
|
- struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
|
|
|
-
|
|
|
- if (addr == (u32 *) jprobe_return_trap_instruction) {
|
|
|
- memcpy(regs, &(kcb->jprobe_saved_regs), sizeof(*regs));
|
|
|
- preempt_enable_no_resched();
|
|
|
- return 1;
|
|
|
- }
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
/* The value stored in the return address register is actually 2
|
|
|
* instructions before where the callee will return to.
|
|
|
* Sequences usually look something like this
|