www.delorie.com/gnu/docs/gdb/gdbint_15.html   search  
 
Buy the book!


GDB Internals

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.8.1 x86 Watchpoints

The 32-bit Intel x86 (a.k.a. ia32) processors feature special debug registers designed to facilitate debugging. GDB provides a generic library of functions that x86-based ports can use to implement support for watchpoints and hardware-assisted breakpoints. This subsection documents the x86 watchpoint facilities in GDB.

To use the generic x86 watchpoint support, a port should do the following:

The x86 watchpoint support works by maintaining mirror images of the debug registers. Values are copied between the mirror images and the real debug registers via a set of macros which each target needs to provide:

I386_DR_LOW_SET_CONTROL (val)
Set the Debug Control (DR7) register to the value val.

I386_DR_LOW_SET_ADDR (idx, addr)
Put the address addr into the debug register number idx.

I386_DR_LOW_RESET_ADDR (idx)
Reset (i.e. zero out) the address stored in the debug register number idx.

I386_DR_LOW_GET_STATUS
Return the value of the Debug Status (DR6) register. This value is used immediately after it is returned by I386_DR_LOW_GET_STATUS, so as to support per-thread status register values.

For each one of the 4 debug registers (whose indices are from 0 to 3) that store addresses, a reference count is maintained by GDB, to allow sharing of debug registers by several watchpoints. This allows users to define several watchpoints that watch the same expression, but with different conditions and/or commands, without wasting debug registers which are in short supply. GDB maintains the reference counts internally, targets don't have to do anything to use this feature.

The x86 debug registers can each watch a region that is 1, 2, or 4 bytes long. The ia32 architecture requires that each watched region be appropriately aligned: 2-byte region on 2-byte boundary, 4-byte region on 4-byte boundary. However, the x86 watchpoint support in GDB can watch unaligned regions and regions larger than 4 bytes (up to 16 bytes) by allocating several debug registers to watch a single region. This allocation of several registers per a watched region is also done automatically without target code intervention.

The generic x86 watchpoint support provides the following API for the GDB's application code:

i386_region_ok_for_watchpoint (addr, len)
The macro TARGET_REGION_OK_FOR_HW_WATCHPOINT is set to call this function. It counts the number of debug registers required to watch a given region, and returns a non-zero value if that number is less than 4, the number of debug registers available to x86 processors.

i386_stopped_data_address (void)
The macros STOPPED_BY_WATCHPOINT and target_stopped_data_address are set to call this function. The argument passed to STOPPED_BY_WATCHPOINT is ignored. This function examines the breakpoint condition bits in the DR6 Debug Status register, as returned by the I386_DR_LOW_GET_STATUS macro, and returns the address associated with the first bit that is set in DR6.

i386_insert_watchpoint (addr, len, type)
i386_remove_watchpoint (addr, len, type)
Insert or remove a watchpoint. The macros target_insert_watchpoint and target_remove_watchpoint are set to call these functions. i386_insert_watchpoint first looks for a debug register which is already set to watch the same region for the same access types; if found, it just increments the reference count of that debug register, thus implementing debug register sharing between watchpoints. If no such register is found, the function looks for a vacant debug register, sets its mirrored value to addr, sets the mirrored value of DR7 Debug Control register as appropriate for the len and type parameters, and then passes the new values of the debug register and DR7 to the inferior by calling I386_DR_LOW_SET_ADDR and I386_DR_LOW_SET_CONTROL. If more than one debug register is required to cover the given region, the above process is repeated for each debug register.

i386_remove_watchpoint does the opposite: it resets the address in the mirrored value of the debug register and its read/write and length bits in the mirrored value of DR7, then passes these new values to the inferior via I386_DR_LOW_RESET_ADDR and I386_DR_LOW_SET_CONTROL. If a register is shared by several watchpoints, each time a i386_remove_watchpoint is called, it decrements the reference count, and only calls I386_DR_LOW_RESET_ADDR and I386_DR_LOW_SET_CONTROL when the count goes to zero.

i386_insert_hw_breakpoint (addr, shadow
i386_remove_hw_breakpoint (addr, shadow)
These functions insert and remove hardware-assisted breakpoints. The macros target_insert_hw_breakpoint and target_remove_hw_breakpoint are set to call these functions. These functions work like i386_insert_watchpoint and i386_remove_watchpoint, respectively, except that they set up the debug registers to watch instruction execution, and each hardware-assisted breakpoint always requires exactly one debug register.

i386_stopped_by_hwbp (void)
This function returns non-zero if the inferior has some watchpoint or hardware breakpoint that triggered. It works like i386_stopped_data_address, except that it doesn't return the address whose watchpoint triggered.

i386_cleanup_dregs (void)
This function clears all the reference counts, addresses, and control bits in the mirror images of the debug registers. It doesn't affect the actual debug registers in the inferior process.

Notes:

  1. x86 processors support setting watchpoints on I/O reads or writes. However, since no target supports this (as of March 2001), and since enum target_hw_bp_type doesn't even have an enumeration for I/O watchpoints, this feature is not yet available to GDB running on x86.

  2. x86 processors can enable watchpoints locally, for the current task only, or globally, for all the tasks. For each debug register, there's a bit in the DR7 Debug Control register that determines whether the associated address is watched locally or globally. The current implementation of x86 watchpoint support in GDB always sets watchpoints to be locally enabled, since global watchpoints might interfere with the underlying OS and are probably unavailable in many platforms.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

  webmaster   donations   bookstore     delorie software   privacy  
  Copyright © 2003   by The Free Software Foundation     Updated Jun 2003