Ptrace

GDB計劃支援BookE處理器的以下硬體除錯功能

4個硬體斷點 (IAC) 2個硬體觀察點(讀、寫和讀寫)(DAC) 硬體觀察點的2個值條件 (DVC)

為此,我們需要擴充套件ptrace,以便GDB可以查詢和設定這些資源。 由於我們正在擴充套件,我們嘗試建立一個可擴充套件的介面,該介面涵蓋BookE和伺服器處理器,以便GDB不需要特殊處理它們中的每一個。 我們添加了以下3個新的ptrace請求。

1. PPC_PTRACE_GETHWDBGINFO

查詢,供GDB發現硬體除錯功能。 這裡要返回的主要資訊是硬體觀察點的最小對齊。 BookE處理器沒有限制,但伺服器處理器對硬體觀察點有8位元組對齊限制。 我們希望避免根據GDB在AUXV中看到的內容向GDB新增特殊情況。

既然我們正在做,我們添加了核心可以返回給GDB的其他有用資訊:此查詢將返回硬體斷點,硬體觀察點的數量,以及它是否支援地址範圍和條件。 該查詢將填充請求程序提供的以下結構

struct ppc_debug_info {
     unit32_t version;
     unit32_t num_instruction_bps;
     unit32_t num_data_bps;
     unit32_t num_condition_regs;
     unit32_t data_bp_alignment;
     unit32_t sizeof_condition; /* size of the DVC register */
     uint64_t features; /* bitmask of the individual flags */
};

features將具有指示是否支援的位

#define PPC_DEBUG_FEATURE_INSN_BP_RANGE               0x1
#define PPC_DEBUG_FEATURE_INSN_BP_MASK                0x2
#define PPC_DEBUG_FEATURE_DATA_BP_RANGE               0x4
#define PPC_DEBUG_FEATURE_DATA_BP_MASK                0x8
#define PPC_DEBUG_FEATURE_DATA_BP_DAWR                0x10
#define PPC_DEBUG_FEATURE_DATA_BP_ARCH_31             0x20
  1. PPC_PTRACE_SETHWDEBUG

根據提供的結構設定硬體斷點或觀察點

 struct ppc_hw_breakpoint {
       uint32_t version;
 #define PPC_BREAKPOINT_TRIGGER_EXECUTE  0x1
 #define PPC_BREAKPOINT_TRIGGER_READ     0x2
#define PPC_BREAKPOINT_TRIGGER_WRITE    0x4
       uint32_t trigger_type;       /* only some combinations allowed */
 #define PPC_BREAKPOINT_MODE_EXACT               0x0
 #define PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE     0x1
 #define PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE     0x2
 #define PPC_BREAKPOINT_MODE_MASK                0x3
       uint32_t addr_mode;          /* address match mode */

 #define PPC_BREAKPOINT_CONDITION_MODE   0x3
 #define PPC_BREAKPOINT_CONDITION_NONE   0x0
 #define PPC_BREAKPOINT_CONDITION_AND    0x1
 #define PPC_BREAKPOINT_CONDITION_EXACT  0x1   /* different name for the same thing as above */
 #define PPC_BREAKPOINT_CONDITION_OR     0x2
 #define PPC_BREAKPOINT_CONDITION_AND_OR 0x3
 #define PPC_BREAKPOINT_CONDITION_BE_ALL 0x00ff0000    /* byte enable bits */
 #define PPC_BREAKPOINT_CONDITION_BE(n)  (1<<((n)+16))
       uint32_t condition_mode;     /* break/watchpoint condition flags */

       uint64_t addr;
       uint64_t addr2;
       uint64_t condition_value;
 };

一個請求指定一個事件,不一定只設置一個暫存器。 例如,如果請求是具有條件的觀察點,則DAC和DVC暫存器將在同一請求中設定。

有了這個,GDB可以要求BookE支援的各種硬體斷點和觀察點。 沒有考慮伺服器處理器中可用的COMEFROM斷點,但這不在此工作範圍內。

ptrace將返回一個整數(控制代碼),唯一地標識剛建立的斷點或觀察點。 該整數將用於PPC_PTRACE_DELHWDEBUG請求中,以請求將其刪除。 如果無法在暫存器上分配請求的斷點,則返回 -ENOSPC。

使用該結構的一些示例

  • 在第一個斷點暫存器中設定斷點

    p.version         = PPC_DEBUG_CURRENT_VERSION;
    p.trigger_type    = PPC_BREAKPOINT_TRIGGER_EXECUTE;
    p.addr_mode       = PPC_BREAKPOINT_MODE_EXACT;
    p.condition_mode  = PPC_BREAKPOINT_CONDITION_NONE;
    p.addr            = (uint64_t) address;
    p.addr2           = 0;
    p.condition_value = 0;
    
  • 設定一個在第二個觀察點暫存器中觸發讀取的觀察點

    p.version         = PPC_DEBUG_CURRENT_VERSION;
    p.trigger_type    = PPC_BREAKPOINT_TRIGGER_READ;
    p.addr_mode       = PPC_BREAKPOINT_MODE_EXACT;
    p.condition_mode  = PPC_BREAKPOINT_CONDITION_NONE;
    p.addr            = (uint64_t) address;
    p.addr2           = 0;
    p.condition_value = 0;
    
  • 設定一個僅用特定值觸發的觀察點

    p.version         = PPC_DEBUG_CURRENT_VERSION;
    p.trigger_type    = PPC_BREAKPOINT_TRIGGER_READ;
    p.addr_mode       = PPC_BREAKPOINT_MODE_EXACT;
    p.condition_mode  = PPC_BREAKPOINT_CONDITION_AND | PPC_BREAKPOINT_CONDITION_BE_ALL;
    p.addr            = (uint64_t) address;
    p.addr2           = 0;
    p.condition_value = (uint64_t) condition;
    
  • 設定一個範圍硬體斷點

    p.version         = PPC_DEBUG_CURRENT_VERSION;
    p.trigger_type    = PPC_BREAKPOINT_TRIGGER_EXECUTE;
    p.addr_mode       = PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE;
    p.condition_mode  = PPC_BREAKPOINT_CONDITION_NONE;
    p.addr            = (uint64_t) begin_range;
    p.addr2           = (uint64_t) end_range;
    p.condition_value = 0;
    
  • 在伺服器處理器 (BookS) 中設定一個觀察點

    p.version         = 1;
    p.trigger_type    = PPC_BREAKPOINT_TRIGGER_RW;
    p.addr_mode       = PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE;
    or
    p.addr_mode       = PPC_BREAKPOINT_MODE_EXACT;
    
    p.condition_mode  = PPC_BREAKPOINT_CONDITION_NONE;
    p.addr            = (uint64_t) begin_range;
    /* For PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE addr2 needs to be specified, where
     * addr2 - addr <= 8 Bytes.
     */
    p.addr2           = (uint64_t) end_range;
    p.condition_value = 0;
    
  1. PPC_PTRACE_DELHWDEBUG

接受一個整數,該整數標識現有斷點或觀察點(即,從PTRACE_SETHWDEBUG返回的值),並刪除相應的斷點或觀察點。