函数源码

Linux Kernel

v5.5.9

Brick Technologies Co., Ltd

Source File:arch\x86\kernel\kprobes\core.c Create Date:2022-07-27 09:37:57
首页 Copyright©Brick

652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
NOKPROBE_SYMBOL(reenter_kprobe);
 
/*
 * Interrupts are disabled on entry as trap3 is an interrupt gate and they
 * remain disabled throughout this function.
 */
int kprobe_int3_handler(struct pt_regs *regs)
{
    kprobe_opcode_t *addr;
    struct kprobe *p;
    struct kprobe_ctlblk *kcb;
 
    if (user_mode(regs))
        return 0;
 
    addr = (kprobe_opcode_t *)(regs->ip - sizeof(kprobe_opcode_t));
    /*
     * We don't want to be preempted for the entire duration of kprobe
     * processing. Since int3 and debug trap disables irqs and we clear
     * IF while singlestepping, it must be no preemptible.
     */
 
    kcb = get_kprobe_ctlblk();
    p = get_kprobe(addr);
 
    if (p) {
        if (kprobe_running()) {
            if (reenter_kprobe(p, regs, kcb))
                return 1;
        } else {
            set_current_kprobe(p, regs, kcb);
            kcb->kprobe_status = KPROBE_HIT_ACTIVE;
 
            /*
             * If we have no pre-handler or it returned 0, we
             * continue with normal processing.  If we have a
             * pre-handler and it returned non-zero, that means
             * user handler setup registers to exit to another
             * instruction, we must skip the single stepping.
             */
            if (!p->pre_handler || !p->pre_handler(p, regs))
                setup_singlestep(p, regs, kcb, 0);
            else
                reset_current_kprobe();
            return 1;
        }
    } else if (*addr != BREAKPOINT_INSTRUCTION) {
        /*
         * The breakpoint instruction was removed right
         * after we hit it.  Another cpu has removed
         * either a probepoint or a debugger breakpoint
         * at this address.  In either case, no further
         * handling of this interrupt is appropriate.
         * Back up over the (now missing) int3 and run
         * the original instruction.
         */
        regs->ip = (unsigned long)addr;
        return 1;
    } /* else: not a kprobe fault; let the kernel handle it */
 
    return 0;
}