zoukankan      html  css  js  c++  java
  • struct arch_hw_breakpoint结构体

    struct arch_hw_breakpoint结构体

    watchpoint or breakpoint(type)、watchpoint监测的数据长度、监测的地址,这些信息都保存在arch_hw_breakpoint结构体里

    struct arch_hw_breakpoint {
        u64 address;
        u64 trigger;
        struct arch_hw_breakpoint_ctrl ctrl;
    };

    在arch_build_bp_info()里设置这个结构体:

    对于设置watchpoint时,attr->bp_type值为HW_BREAKPOINT_W(2),然后将attr->bp_addr的值赋值给arch_hw_breakpoint结构类型的address成员。

    attr->bp_len表示watchpoint监视的地址要监视多少个byte,比如值为8时,表示监视连续的8个字节,将这个len赋值给arch_hw_breakpoint里的ctrl.len成员,赋值给ctrl.len的len的含义用一个8bit的byte来表示某一个byte是否监视,比如bp_len是8时,赋值给ctrl.len的值为0xff,如果为7,则为0x7f。

    dbgwcrx_el1 register bitfield描述如下,这里的ctrl.len即是BAS field,[12:5],一共8bit:

    Figure 11.3. DBGWCRn_EL1 bit assignments

    Figure 11.3. DBGWCR

    4.19/arch/arm64/kernel/hw_breakpoint.c

    static int arch_build_bp_info(struct perf_event *bp,
                      const struct perf_event_attr *attr,
                      struct arch_hw_breakpoint *hw)
    {
        /* Type */
        switch (attr->bp_type) {
        case HW_BREAKPOINT_X:
            hw->ctrl.type = ARM_BREAKPOINT_EXECUTE;
            break;
        case HW_BREAKPOINT_R:
            hw->ctrl.type = ARM_BREAKPOINT_LOAD;
            break;
        case HW_BREAKPOINT_W:
            hw->ctrl.type = ARM_BREAKPOINT_STORE;
            break;
        case HW_BREAKPOINT_RW:
            hw->ctrl.type = ARM_BREAKPOINT_LOAD | ARM_BREAKPOINT_STORE;
            break;
        default:
            return -EINVAL;
        }
    
        /* Len */
        switch (attr->bp_len) {
        case HW_BREAKPOINT_LEN_1:
            hw->ctrl.len = ARM_BREAKPOINT_LEN_1;
            break;
        case HW_BREAKPOINT_LEN_2:
            hw->ctrl.len = ARM_BREAKPOINT_LEN_2;
            break;
        case HW_BREAKPOINT_LEN_3:
            hw->ctrl.len = ARM_BREAKPOINT_LEN_3;
            break;
        case HW_BREAKPOINT_LEN_4:
            hw->ctrl.len = ARM_BREAKPOINT_LEN_4;
            break;
        case HW_BREAKPOINT_LEN_5:
            hw->ctrl.len = ARM_BREAKPOINT_LEN_5;
            break;
        case HW_BREAKPOINT_LEN_6:
            hw->ctrl.len = ARM_BREAKPOINT_LEN_6;
            break;
        case HW_BREAKPOINT_LEN_7:
            hw->ctrl.len = ARM_BREAKPOINT_LEN_7;
            break;
        case HW_BREAKPOINT_LEN_8:
            hw->ctrl.len = ARM_BREAKPOINT_LEN_8;
            break;
        default:
            return -EINVAL;
        }
    
        /*
         * On AArch64, we only permit breakpoints of length 4, whereas
         * AArch32 also requires breakpoints of length 2 for Thumb.
         * Watchpoints can be of length 1, 2, 4 or 8 bytes.
         */
        if (hw->ctrl.type == ARM_BREAKPOINT_EXECUTE) {
            if (is_compat_bp(bp)) {
                if (hw->ctrl.len != ARM_BREAKPOINT_LEN_2 &&
                    hw->ctrl.len != ARM_BREAKPOINT_LEN_4)
                    return -EINVAL;
            } else if (hw->ctrl.len != ARM_BREAKPOINT_LEN_4) {
                /*
                 * FIXME: Some tools (I'm looking at you perf) assume
                 *      that breakpoints should be sizeof(long). This
                 *      is nonsense. For now, we fix up the parameter
                 *      but we should probably return -EINVAL instead.
                 */
                hw->ctrl.len = ARM_BREAKPOINT_LEN_4;
            }
        }
    
        /* Address */
        hw->address = attr->bp_addr;

    下面的hw_breakpoint_arch_parse()对于watchpoint,alignment_mask为0x7,如果address本身没有8对齐,则会将address向下对齐到8,同时ctrl.len也会左移对应的bit,比如address为0x5,则它会对齐到0x0,len为8(对应ctrl.len为0xff),offset为5,将0xff左移5bit得到0xe0,即只有最高3bit为1,表示只监视地址5/6/7,低位地址0-4不监视:

    setup watchpoint时,调用hw_breakpoint_control(),在这个函数里ops参数值为0,即HW_BREAKPOINT_INSTALL:

    [   21.943510] hw-breakpoint: ops: 0, reg_enable: 1.
    [   21.948240] CPU: 1 PID: 34 Comm: kworker/1:1 Tainted: P           O      4.19.116+ #19
    [   21.956172] Hardware name: test_mach(DT)
    [   21.959855] Workqueue: events watch_point_delayed_work_func
    [   21.965433] Call trace:
    [   21.967899]  dump_backtrace+0x0/0x4
    [   21.971414]  dump_stack+0xf4/0x134
    [   21.974829]  hw_breakpoint_control+0x184/0x29c
    [   21.979280]  hw_breakpoint_add+0x80/0x8c
    [   21.983210]  event_sched_in+0x44c/0x718
    [   21.987049]  group_sched_in+0x6c/0x218
    [   21.990816]  pinned_sched_in+0x158/0x264
    [   21.994749]  visit_groups_merge+0x140/0x1fc
    [   21.998947]  ctx_sched_in+0x1a4/0x1ec
    [   22.002631]  ctx_resched+0xdc/0x1e4
    [   22.006142]  __perf_event_enable+0x1d0/0x2c4
    [   22.010420]  event_function.9234+0x128/0x224
    [   22.014695]  remote_function+0x74/0xb4
    [   22.018469]  generic_exec_single+0x7c/0x1a4
    [   22.022679]  smp_call_function_single+0xc0/0x1e8
    [   22.027320]  event_function_call+0x84/0x274
    [   22.031512]  perf_event_enable+0xec/0x158
    [   22.035527]  _register_wp_bp+0x408/0x4b8
    [   22.039456]  watch_point_delayed_work_func+0x68/0xcc
    [   22.044443]  process_one_work+0x3c0/0x670
    [   22.048478]  worker_thread+0x32c/0x6d0
    [   22.052236]  kthread+0x130/0x140
    [   22.055468]  ret_from_fork+0x10/0x18
  • 相关阅读:
    常见寻找OEP脱壳的方法
    Windows内核原理系列01
    HDU 1025 Constructing Roads In JGShining's Kingdom
    HDU 1024 Max Sum Plus Plus
    HDU 1003 Max Sum
    HDU 1019 Least Common Multiple
    HDU 1018 Big Number
    HDU 1014 Uniform Generator
    HDU 1012 u Calculate e
    HDU 1005 Number Sequence
  • 原文地址:https://www.cnblogs.com/aspirs/p/15651684.html
Copyright © 2011-2022 走看看