Index: remote.c =================================================================== RCS file: /cvs/src/src/gdb/remote.c,v retrieving revision 1.89 diff -u -r1.89 remote.c --- remote.c 23 Jul 2002 18:55:06 -0000 1.89 +++ remote.c 6 Aug 2002 16:13:57 -0000 @@ -250,6 +250,9 @@ long remote_packet_size; }; +static int remote_stopped_by_watchpoint_p; +static CORE_ADDR remote_watch_data_address; + /* Handle for retreving the remote protocol data from gdbarch. */ static struct gdbarch_data *remote_gdbarch_data_handle; @@ -3008,6 +3011,7 @@ struct remote_state *rs = get_remote_state (); unsigned char *buf = alloca (rs->remote_packet_size); int thread_num = -1; + int addr; status->kind = TARGET_WAITKIND_EXITED; status->value.integer = 0; @@ -3025,6 +3029,8 @@ if (target_wait_loop_hook) (*target_wait_loop_hook) (); + remote_stopped_by_watchpoint_p = 0; + switch (buf[0]) { case 'E': /* Error of some sort */ @@ -3048,10 +3054,19 @@ unsigned char *p1; char *p_temp; int fieldsize; + LONGEST pnum = 0; + + /* If this packet is an awatch packet, don't parse the 'a' + as a register number. */ - /* Read the ``P'' register number. */ - LONGEST pnum = strtol ((const char *) p, &p_temp, 16); - p1 = (unsigned char *) p_temp; + if (!strstr ((const char *) p, "awatch")) + { + /* Read the ``P'' register number. */ + pnum = strtol ((const char *) p, &p_temp, 16); + p1 = (unsigned char *) p_temp; + } + else + p1=p; if (p1 == p) /* No register number present here */ { @@ -3066,6 +3081,14 @@ record_currthread (thread_num); p = (unsigned char *) p_temp; } + else if ((strncmp ((const char *) p, "watch", p1 - p) == 0) + || (strncmp ((const char *) p, "rwatch", p1 - p) == 0) + || (strncmp ((const char *) p, "awatch", p1 - p) == 0)) + { + remote_stopped_by_watchpoint_p = 1; + p = unpack_varlen_hex (++p1, &addr); + remote_watch_data_address = (CORE_ADDR)addr; + } } else { @@ -3222,10 +3245,13 @@ struct remote_state *rs = get_remote_state (); unsigned char *buf = alloca (rs->remote_packet_size); int thread_num = -1; + int addr; status->kind = TARGET_WAITKIND_EXITED; status->value.integer = 0; + remote_stopped_by_watchpoint_p = 0; + while (1) { unsigned char *p; @@ -3268,10 +3294,19 @@ unsigned char *p1; char *p_temp; int fieldsize; + long pnum = 0; - /* Read the register number */ - long pnum = strtol ((const char *) p, &p_temp, 16); - p1 = (unsigned char *) p_temp; + /* If this packet is an awatch packet, don't parse the 'a' + as a register number. */ + + if (!strstr ((const char *) p, "awatch")) + { + /* Read the register number. */ + pnum = strtol ((const char *) p, &p_temp, 16); + p1 = (unsigned char *) p_temp; + } + else + p1=p; if (p1 == p) /* No register number present here */ { @@ -3286,7 +3321,16 @@ record_currthread (thread_num); p = (unsigned char *) p_temp; } + else if ((strncmp ((const char *) p, "watch", p1 - p) == 0) + || (strncmp ((const char *) p, "rwatch", p1 - p) == 0) + || (strncmp ((const char *) p, "awatch", p1 - p) == 0)) + { + remote_stopped_by_watchpoint_p = 1; + p = unpack_varlen_hex (++p1, &addr); + remote_watch_data_address = (CORE_ADDR)addr; + } } + else { struct packet_reg *reg = packet_reg_from_pnum (rs, pnum); @@ -4797,7 +4841,7 @@ /* FIXME: This function should be static and a member of the remote target vector. */ -int +static int remote_insert_watchpoint (CORE_ADDR addr, int len, int type) { struct remote_state *rs = get_remote_state (); @@ -4834,7 +4878,7 @@ /* FIXME: This function should be static and a member of the remote target vector. */ -int +static int remote_remove_watchpoint (CORE_ADDR addr, int len, int type) { struct remote_state *rs = get_remote_state (); @@ -4867,16 +4911,109 @@ "remote_remove_watchpoint: reached end of function"); } + +int remote_hw_watchpoint_limit = 0; +int remote_hw_breakpoint_limit = 0; + + +static void +set_hardware_watchpoint_limit (char *args, int from_tty) +{ + if (args) + { + char *arg_end; + int val = strtoul (args, &arg_end, 10); + if (*args && *arg_end == '\0') + { + remote_hw_watchpoint_limit = val; + return; + } + } + error ("Illegal argument for \"set remote hardware-watchpoint-limit\" command"); +} + +static void +show_hardware_watchpoint_limit (char *args, int from_tty) +{ + if (args) + error ("Garbage after \"show remote hardware-watchpoint-limit\" command: `%s'", args); + printf_unfiltered ("Remote target supports %d hardware watchpoints.\n", + remote_hw_watchpoint_limit); +} + +static void +set_hardware_breakpoint_limit (char *args, int from_tty) +{ + if (args) + { + char *arg_end; + int val = strtoul (args, &arg_end, 10); + if (*args && *arg_end == '\0') + { + remote_hw_breakpoint_limit = val; + return; + } + } + error ("Illegal argument for \"set remote hardware-breakpoint-limit\" command"); +} + +static void +show_hardware_breakpoint_limit (char *args, int from_tty) +{ + if (args) + error ("Garbage after \"show remote hardware-breakpoint-limit\" command: `%s'", args); + printf_unfiltered ("Remote target supports %d hardware breakpoints.\n", + remote_hw_breakpoint_limit); +} + + +int +remote_check_watch_resources (int type, int cnt, int ot) +{ + if (type == bp_hardware_breakpoint) + { + if (remote_hw_breakpoint_limit == 0) + return 0; + else if (cnt <= remote_hw_breakpoint_limit) + return 1; + } + else + { + if (remote_hw_watchpoint_limit == 0) + return 0; + else if (ot) + return -1; + else if (cnt <= remote_hw_watchpoint_limit) + return 1; + } + return -1; +} + +int +remote_stopped_by_watchpoint (void) +{ + return remote_stopped_by_watchpoint_p; +} + +CORE_ADDR +remote_stopped_data_address (void) +{ + return remote_watch_data_address; +} + /* FIXME: This function should be static and a member of the remote target vector. */ -int -remote_insert_hw_breakpoint (CORE_ADDR addr, int len) +static int +remote_insert_hw_breakpoint (CORE_ADDR addr, char *shadow) { + int len=0; struct remote_state *rs = get_remote_state (); char *buf = alloca (rs->remote_packet_size); char *p = buf; + len = strlen (shadow); + len = len ? len : 1; if (remote_protocol_Z[Z_PACKET_HARDWARE_BP].support == PACKET_DISABLE) error ("Can't set hardware breakpoint without the '%s' (%s) packet\n", remote_protocol_Z[Z_PACKET_HARDWARE_BP].name, @@ -4902,19 +5039,21 @@ return 0; } internal_error (__FILE__, __LINE__, - "remote_remove_watchpoint: reached end of function"); + "remote_insert_hw_breakpoint: reached end of function"); } /* FIXME: This function should be static and a member of the remote target vector. */ -int -remote_remove_hw_breakpoint (CORE_ADDR addr, int len) +static int +remote_remove_hw_breakpoint (CORE_ADDR addr, char * shadow) { + int len; struct remote_state *rs = get_remote_state (); char *buf = alloca (rs->remote_packet_size); char *p = buf; + len = sizeof (shadow); if (remote_protocol_Z[Z_PACKET_HARDWARE_BP].support == PACKET_DISABLE) error ("Can't clear hardware breakpoint without the '%s' (%s) packet\n", remote_protocol_Z[Z_PACKET_HARDWARE_BP].name, @@ -4940,7 +5079,7 @@ return 0; } internal_error (__FILE__, __LINE__, - "remote_remove_watchpoint: reached end of function"); + "remote_remove_hw_breakpoint: reached end of function"); } /* Some targets are only capable of doing downloads, and afterwards @@ -5417,6 +5556,13 @@ remote_ops.to_files_info = remote_files_info; remote_ops.to_insert_breakpoint = remote_insert_breakpoint; remote_ops.to_remove_breakpoint = remote_remove_breakpoint; + remote_ops.to_stopped_by_watchpoint = remote_stopped_by_watchpoint; + remote_ops.to_stopped_data_address = remote_stopped_data_address; + remote_ops.to_can_use_hw_breakpoint = remote_check_watch_resources; + remote_ops.to_insert_hw_breakpoint = remote_insert_hw_breakpoint; + remote_ops.to_remove_hw_breakpoint = remote_remove_hw_breakpoint; + remote_ops.to_insert_watchpoint = remote_insert_watchpoint; + remote_ops.to_remove_watchpoint = remote_remove_watchpoint; remote_ops.to_kill = remote_kill; remote_ops.to_load = generic_load; remote_ops.to_mourn_inferior = remote_mourn; @@ -5832,7 +5978,14 @@ remote_cisco_ops.to_xfer_memory = remote_xfer_memory; remote_cisco_ops.to_files_info = remote_files_info; remote_cisco_ops.to_insert_breakpoint = remote_insert_breakpoint; - remote_cisco_ops.to_remove_breakpoint = remote_remove_breakpoint; + remote_cisco_ops.to_remove_breakpoint = remote_remove_breakpoint; + remote_cisco_ops.to_remove_hw_breakpoint = remote_remove_hw_breakpoint; + remote_cisco_ops.to_insert_hw_breakpoint = remote_insert_hw_breakpoint; + remote_cisco_ops.to_insert_watchpoint = remote_insert_watchpoint; + remote_cisco_ops.to_remove_watchpoint = remote_remove_watchpoint; + remote_cisco_ops.to_stopped_by_watchpoint = remote_stopped_by_watchpoint; + remote_cisco_ops.to_stopped_data_address = remote_stopped_data_address; + remote_cisco_ops.to_can_use_hw_breakpoint = remote_check_watch_resources; remote_cisco_ops.to_kill = remote_kill; remote_cisco_ops.to_load = generic_load; remote_cisco_ops.to_mourn_inferior = remote_cisco_mourn; @@ -5922,6 +6075,13 @@ remote_async_ops.to_files_info = remote_files_info; remote_async_ops.to_insert_breakpoint = remote_insert_breakpoint; remote_async_ops.to_remove_breakpoint = remote_remove_breakpoint; + remote_async_ops.to_can_use_hw_breakpoint = remote_check_watch_resources; + remote_async_ops.to_insert_hw_breakpoint = remote_insert_hw_breakpoint; + remote_async_ops.to_remove_hw_breakpoint = remote_remove_hw_breakpoint; + remote_async_ops.to_insert_watchpoint = remote_insert_watchpoint; + remote_async_ops.to_remove_watchpoint = remote_remove_watchpoint; + remote_async_ops.to_stopped_by_watchpoint = remote_stopped_by_watchpoint; + remote_async_ops.to_stopped_data_address = remote_stopped_data_address; remote_async_ops.to_terminal_inferior = remote_async_terminal_inferior; remote_async_ops.to_terminal_ours = remote_async_terminal_ours; remote_async_ops.to_kill = remote_async_kill; @@ -6114,6 +6274,22 @@ add_cmd ("memory-read-packet-size", no_class, show_memory_read_packet_size, "Show the maximum number of bytes per memory-read packet.\n", + &remote_show_cmdlist); + add_cmd ("hardware-watchpoint-limit", no_class, + set_hardware_watchpoint_limit, + "Set the maximum number of target hardware watchpoints.\n", + &remote_set_cmdlist); + add_cmd ("hardware-watchpoint-limit", no_class, + show_hardware_watchpoint_limit, + "Show the maximum number of target hardware watchpoints.\n", + &remote_show_cmdlist); + add_cmd ("hardware-breakpoint-limit", no_class, + set_hardware_breakpoint_limit, + "Set the maximum number of target hardware breakpoints.\n", + &remote_set_cmdlist); + add_cmd ("hardware-breakpoint-limit", no_class, + show_hardware_breakpoint_limit, + "Show the maximum number of target hardware breakpoints.\n", &remote_show_cmdlist); add_show_from_set