Index: gdb/gdbserver/server.c =================================================================== RCS file: /cvs/src/src/gdb/gdbserver/server.c,v retrieving revision 1.56 diff -u -r1.56 server.c --- gdb/gdbserver/server.c 23 Aug 2007 18:08:48 -0000 1.56 +++ gdb/gdbserver/server.c 13 Sep 2007 10:51:07 -0000 @@ -1097,21 +1097,30 @@ break; case 'Z': { - char *lenptr; - char *dataptr; - CORE_ADDR addr = strtoul (&own_buf[3], &lenptr, 16); - int len = strtol (lenptr + 1, &dataptr, 16); char type = own_buf[1]; - if (the_target->insert_watchpoint == NULL || (type < '2' || type > '4')) { /* No watchpoint support or not a watchpoint command; unrecognized either way. */ own_buf[0] = '\0'; + break; + } + + if (own_buf[2] == '\0') + { + if ((*the_target->watchpoint_support) (type)) + write_ok (own_buf); + else + /* Unsupported. */ + own_buf[0] = '\0'; } else { + char *lenptr; + char *dataptr; + CORE_ADDR addr = strtoul (&own_buf[3], &lenptr, 16); + int len = strtol (lenptr + 1, &dataptr, 16); int res; res = (*the_target->insert_watchpoint) (type, addr, len); Index: gdb/gdbserver/linux-low.c =================================================================== RCS file: /cvs/src/src/gdb/gdbserver/linux-low.c,v retrieving revision 1.61 diff -u -r1.61 linux-low.c --- gdb/gdbserver/linux-low.c 4 Sep 2007 21:30:23 -0000 1.61 +++ gdb/gdbserver/linux-low.c 13 Sep 2007 10:50:59 -0000 @@ -1635,6 +1635,16 @@ } static int +linux_watchpoint_support (char type) +{ + if (the_low_target.watchpoint_support != NULL) + return the_low_target.watchpoint_support (type); + else + /* Unsupported. */ + return 0; +} + +static int linux_stopped_by_watchpoint (void) { if (the_low_target.stopped_by_watchpoint != NULL) @@ -1721,6 +1731,7 @@ linux_read_auxv, linux_insert_watchpoint, linux_remove_watchpoint, + linux_watchpoint_support, linux_stopped_by_watchpoint, linux_stopped_data_address, #if defined(__UCLIBC__) && defined(HAS_NOMMU) Index: gdb/gdbserver/linux-low.h =================================================================== RCS file: /cvs/src/src/gdb/gdbserver/linux-low.h,v retrieving revision 1.18 diff -u -r1.18 linux-low.h --- gdb/gdbserver/linux-low.h 23 Aug 2007 18:08:48 -0000 1.18 +++ gdb/gdbserver/linux-low.h 13 Sep 2007 10:50:59 -0000 @@ -63,6 +63,7 @@ /* Watchpoint related functions. See target.h for comments. */ int (*insert_watchpoint) (char type, CORE_ADDR addr, int len); int (*remove_watchpoint) (char type, CORE_ADDR addr, int len); + int (*watchpoint_support) (char type); int (*stopped_by_watchpoint) (void); CORE_ADDR (*stopped_data_address) (void); Index: gdb/gdbserver/target.h =================================================================== RCS file: /cvs/src/src/gdb/gdbserver/target.h,v retrieving revision 1.25 diff -u -r1.25 target.h --- gdb/gdbserver/target.h 23 Aug 2007 18:08:48 -0000 1.25 +++ gdb/gdbserver/target.h 13 Sep 2007 10:51:11 -0000 @@ -155,6 +155,11 @@ int (*insert_watchpoint) (char type, CORE_ADDR addr, int len); int (*remove_watchpoint) (char type, CORE_ADDR addr, int len); + + /* Check if hardware watchpoints are supported. + Returns 0 on unsupported, else on supported. + The type is coded as mentioned above. */ + int (*watchpoint_support) (char type); /* Returns 1 if target was stopped due to a watchpoint hit, 0 otherwise. */ Index: gdb/gdbserver/win32-low.c =================================================================== RCS file: /cvs/src/src/gdb/gdbserver/win32-low.c,v retrieving revision 1.15 diff -u -r1.15 win32-low.c --- gdb/gdbserver/win32-low.c 3 Sep 2007 22:17:27 -0000 1.15 +++ gdb/gdbserver/win32-low.c 13 Sep 2007 10:51:16 -0000 @@ -1522,6 +1522,7 @@ NULL, NULL, NULL, + NULL, win32_arch_string }; Index: gdb/gdbserver/linux-x86-64-low.c =================================================================== RCS file: /cvs/src/src/gdb/gdbserver/linux-x86-64-low.c,v retrieving revision 1.16 diff -u -r1.16 linux-x86-64-low.c --- gdb/gdbserver/linux-x86-64-low.c 23 Aug 2007 18:08:48 -0000 1.16 +++ gdb/gdbserver/linux-x86-64-low.c 13 Sep 2007 10:51:00 -0000 @@ -174,6 +174,7 @@ NULL, NULL, NULL, + NULL, 0, "i386:x86-64", }; Index: gdb/gdbserver/linux-crisv32-low.c =================================================================== RCS file: /cvs/src/src/gdb/gdbserver/linux-crisv32-low.c,v retrieving revision 1.5 diff -u -r1.5 linux-crisv32-low.c --- gdb/gdbserver/linux-crisv32-low.c 23 Aug 2007 18:08:48 -0000 1.5 +++ gdb/gdbserver/linux-crisv32-low.c 13 Sep 2007 10:50:51 -0000 @@ -307,6 +307,21 @@ } static int +cris_watchpoint_support (char type) +{ + /* Breakpoint/watchpoint types is described in the comment for + cris_insert_watchpoint. */ + + if (type < '2' || type > '4') + { + /* Unsupported. */ + return 0; + } + /* Supported. */ + return 1; +} + +static int cris_stopped_by_watchpoint (void) { unsigned long exs; @@ -373,6 +388,7 @@ cris_breakpoint_at, cris_insert_watchpoint, cris_remove_watchpoint, + cris_watchpoint_support, cris_stopped_by_watchpoint, cris_stopped_data_address, }; Index: gdb/gdbserver/linux-i386-low.c =================================================================== RCS file: /cvs/src/src/gdb/gdbserver/linux-i386-low.c,v retrieving revision 1.13 diff -u -r1.13 linux-i386-low.c --- gdb/gdbserver/linux-i386-low.c 23 Aug 2007 18:08:48 -0000 1.13 +++ gdb/gdbserver/linux-i386-low.c 13 Sep 2007 10:50:51 -0000 @@ -200,6 +200,7 @@ NULL, NULL, NULL, + NULL, 0, "i386" }; Index: gdb/gdbserver/linux-ppc64-low.c =================================================================== RCS file: /cvs/src/src/gdb/gdbserver/linux-ppc64-low.c,v retrieving revision 1.8 diff -u -r1.8 linux-ppc64-low.c --- gdb/gdbserver/linux-ppc64-low.c 23 Aug 2007 18:08:48 -0000 1.8 +++ gdb/gdbserver/linux-ppc64-low.c 13 Sep 2007 10:51:00 -0000 @@ -130,5 +130,6 @@ NULL, NULL, NULL, + NULL, 1 }; Index: gdb/gdbserver/spu-low.c =================================================================== RCS file: /cvs/src/src/gdb/gdbserver/spu-low.c,v retrieving revision 1.12 diff -u -r1.12 spu-low.c --- gdb/gdbserver/spu-low.c 23 Aug 2007 18:08:48 -0000 1.12 +++ gdb/gdbserver/spu-low.c 13 Sep 2007 10:51:09 -0000 @@ -596,6 +596,7 @@ NULL, NULL, NULL, + NULL, spu_arch_string, spu_proc_xfer_spu, }; Index: gdb/gdbserver/linux-cris-low.c =================================================================== RCS file: /cvs/src/src/gdb/gdbserver/linux-cris-low.c,v retrieving revision 1.5 diff -u -r1.5 linux-cris-low.c --- gdb/gdbserver/linux-cris-low.c 23 Aug 2007 18:08:48 -0000 1.5 +++ gdb/gdbserver/linux-cris-low.c 13 Sep 2007 10:50:49 -0000 @@ -116,8 +116,4 @@ cris_reinsert_addr, 0, cris_breakpoint_at, - 0, - 0, - 0, - 0, }; Index: gdb/remote.c =================================================================== RCS file: /cvs/src/src/gdb/remote.c,v retrieving revision 1.266 diff -u -r1.266 remote.c --- gdb/remote.c 23 Aug 2007 18:08:36 -0000 1.266 +++ gdb/remote.c 13 Sep 2007 10:50:49 -0000 @@ -5374,6 +5374,53 @@ _("remote_remove_watchpoint: reached end of function")); } +static int +hardware_resouce_to_Z_packet (int type) +{ + switch (type) + { + case bp_hardware_breakpoint: + return Z_PACKET_HARDWARE_BP; + break; + case bp_hardware_watchpoint: + return Z_PACKET_WRITE_WP; + break; + case bp_read_watchpoint: + return Z_PACKET_READ_WP; + break; + case bp_access_watchpoint: + return Z_PACKET_ACCESS_WP; + break; + default: + internal_error (__FILE__, __LINE__, + _("hardware_resouce_to_Z_packet: bad watchpoint type %d"), type); + } +} + +static int +remote_check_Zpacket_support (int type) +{ + struct remote_state *rs = get_remote_state (); + enum Z_packet_type packet = hardware_resouce_to_Z_packet (type); + + if (remote_protocol_packets[PACKET_Z0 + packet].support == PACKET_DISABLE) + return 0; + + sprintf (rs->buf, "Z%x", packet); + putpkt (rs->buf); + getpkt (&rs->buf, &rs->buf_size, 0); + + switch (packet_ok (rs->buf, &remote_protocol_packets[PACKET_Z0 + packet])) + { + case PACKET_ERROR: + case PACKET_UNKNOWN: + return 0; + case PACKET_OK: + return 1; + } + internal_error (__FILE__, __LINE__, + _("remote_check_Zpacket_supported: reached end of function")); +} int remote_hw_watchpoint_limit = -1; int remote_hw_breakpoint_limit = -1; @@ -5381,6 +5428,9 @@ static int remote_check_watch_resources (int type, int cnt, int ot) { + if (! remote_check_Zpacket_support (type)) + return 0; + if (type == bp_hardware_breakpoint) { if (remote_hw_breakpoint_limit == 0)