* config/pa/nm-hppab.h (STOPPED_BY_WATCHPOINT): Define.
authorJeff Law <law@redhat.com>
Wed, 13 Apr 1994 22:02:52 +0000 (22:02 +0000)
committerJeff Law <law@redhat.com>
Wed, 13 Apr 1994 22:02:52 +0000 (22:02 +0000)
(HAVE_STEPPABLE_WATCHPOINT): Define.
(TARGET_CAN_USE_HARDWARE_WATCHPOINT): Define.
(target_{insert,delete}_watchpoint): Define.

gdb/config/pa/nm-hppab.h

index 8a615e8401b0d134079ae87a84f4a87cdb42e5a6..c14cb25556077e3712fcc1fec0c393cdd42198ac 100644 (file)
@@ -38,3 +38,71 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
    target process...  Which really pisses off GDB.)  */
 
 #define ATTACH_DETACH
+
+/* The PA-BSD kernel has support for using the data memory break bit
+   to implement fast watchpoints.
+
+   Watchpoints on the PA act much like traditional page protection
+   schemes, but with some notable differences.
+
+   First, a special bit in the page table entry is used to cause
+   a trap when a specific page is written to.  This avoids having
+   to overload watchpoints on the page protection bits.  This makes
+   it possible for the kernel to easily decide if a trap was caused
+   by a watchpoint or by the user writing to protected memory and can
+   signal the user program differently in each case.  
+   
+   Second, the PA has a bit in the processor status word which causes
+   data memory breakpoints (aka watchpoints) to be disabled for a single
+   instruction.  This bit can be used to avoid the overhead of unprotecting
+   and reprotecting pages when it becomes necessary to step over a watchpoint.
+
+
+   When the kernel receives a trap indicating a write to a page which
+   is being watched, the kernel performs a couple of simple actions.  First
+   is sets the magic "disable memory breakpoint" bit in the processor
+   status word, it then sends a SIGTRAP to the process which caused the
+   trap.
+
+   GDB will take control and catch the signal for the inferior.  GDB then
+   examines the PSW-X bit to determine if the SIGTRAP was caused by a 
+   watchpoint firing.  If so GDB single steps the inferior over the
+   instruction which caused the watchpoint to trigger (note because the
+   kernel disabled the data memory break bit for one instruction no trap
+   will be taken!).  GDB will then determines the appropriate action to
+   take.  (this may include restarting the inferior if the watchpoint
+   fired because of a write to an address on the same page as a watchpoint,
+   but no write to the watched address occured).  */
+
+/* The PA can watch any number of locations, there's no need for it to reject
+   anything (generic routines already check that all intermediates are
+   in memory).  */
+#define TARGET_CAN_USE_HARDWARE_WATCHPOINT(B) 1
+
+/* When a hardware watchpoint fires off the PC will be left at the
+   instruction which caused the watchpoint.  It will be necessary for
+   GDB to step over the watchpoint.
+
+   On a PA running BSD, it is trivial to identify when it will be
+   necessary to step over a hardware watchpoint as we can examine
+   the PSW-X bit.  If the bit is on, then we trapped because of a 
+   watchpoint, else we trapped for some other reason.  */
+#define STOPPED_BY_WATCHPOINT(W) \
+  ((W).kind == TARGET_WAITKIND_STOPPED \
+   && (W).value.sig == TARGET_SIGNAL_TRAP \
+   && ((int) read_register (IPSW_REGNUM) & 0x00100000))
+
+/* The PA can single step over a watchpoint if the kernel has set the
+   "X" bit in the processor status word (disable data memory breakpoint
+   for one instruction).
+
+   The kernel will always set this bit before notifying the inferior
+   that it hit a watchpoint.  Thus, the inferior can single step over
+   the instruction which caused the watchpoint to fire.  This avoids
+   the traditional need to disable the watchpoint, step the inferior,
+   then enable the watchpoint again.  */
+#define HAVE_STEPPABLE_WATCHPOINT
+
+/* Use these macros for watchpoint insertion/deletion.  */
+#define target_insert_watchpoint(addr, len) hppa_set_watchpoint (addr, len, 1)
+#define target_remove_watchpoint(addr, len) hppa_set_watchpoint (addr, len, 0)