| www.delorie.com/gnu/docs/gdb/gdbint_15.html | search |
![]() Buy the book! | |
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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:
I386_USE_GENERIC_WATCHPOINTS somewhere in the
target-dependent headers.
I386_USE_GENERIC_WATCHPOINTS.
NATDEPFILES (see section NATDEPFILES) or
TDEPFILES (see section TDEPFILES).
I386_DR_LOW_* macros described
below. Typically, each macro should call a target-specific function
which does the real work.
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)
I386_DR_LOW_SET_ADDR (idx, addr)
I386_DR_LOW_RESET_ADDR (idx)
I386_DR_LOW_GET_STATUS
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)
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)
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)
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)
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)
i386_stopped_data_address, except that it doesn't return the
address whose watchpoint triggered.
i386_cleanup_dregs (void)
Notes:
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.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
| webmaster donations bookstore | delorie software privacy |
| Copyright © 2003 by The Free Software Foundation | Updated Jun 2003 |