From: Grace Sainsbury <graces@redhat.com>
To: gdb-patches@sources.redhat.com
Subject: Re: [rfa] hardware breakpoints -- remote targets
Date: Thu, 08 Aug 2002 10:06:00 -0000 [thread overview]
Message-ID: <20020808130648.A27850@tomago.toronto.redhat.com> (raw)
In-Reply-To: <20020806121916.A24815@tomago.toronto.redhat.com>; from graces@redhat.com on Tue, Aug 06, 2002 at 12:19:16PM -0400
[-- Attachment #1: Type: text/plain, Size: 1369 bytes --]
I revised the patch to include Mark Salter's earlier patch, as well as
his documentation changes.
ok to commit?
grace
Changelog:
2002-08-08 Grace Sainsbury <graces@redhat.com>
* remote.c: (remote_wait, remote_async_wait): Add check for awatch
T-packets; the 'a' is not taken as a register number.
(set_hardware_watchpoint_limit, show_hardware_watchpoint_limit)
(set_hardware_breakpoint_limit, show_hardware_breakpoint_limit):
New functions. Add commands to call them.
(remote_check_watch_resources, remote_stopped_by_watchpoint)
(remote_stopped_data_address): New functions; add to target
vector.
(remote_insert_hw_breakpoint, remote_remove_hw_breakpoint): Change
prototypes to match other implementations of this
function. replace integer argument with pointer -- the length
field in the Z-packet is the length of what is pointed to or 1 if
pointer is null. Add to target vector.
(remote_insert_watchpoint, remote_remove_watchpoint): Add to
target vector.
From Mark Salter:
* remote.c (remote_wait): Add support to extract optional
watchpoint information from T-packet. Ignore unrecognized
optional info in T-packet.
(remote_async_wait): Ditto.
doc/Changelog:
2002-08-08 Grace Sainsbury <graces@redhat.com>
From Mark Salter:
* gdb.texinfo (Protocol): Document T packet extension to
allow watchpoint address reporting.
[-- Attachment #2: watch2.patch --]
[-- Type: text/plain, Size: 13842 bytes --]
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 8 Aug 2002 17:02:27 -0000
@@ -250,6 +250,7 @@
long remote_packet_size;
};
+
/* Handle for retreving the remote protocol data from gdbarch. */
static struct gdbarch_data *remote_gdbarch_data_handle;
@@ -342,6 +343,14 @@
/* */
+/* This is set to the data address of the access causing the target
+ * to stop for a watchpoint. */
+static CORE_ADDR remote_watch_data_address;
+
+/* This is non-zero if taregt stopped for a watchpoint. */
+static int remote_stopped_by_watchpoint_p;
+
+
static struct target_ops remote_ops;
static struct target_ops extended_remote_ops;
@@ -1107,7 +1116,7 @@
#define BUF_THREAD_ID_SIZE (OPAQUETHREADBYTES*2)
-char *unpack_varlen_hex (char *buff, int *result);
+char *unpack_varlen_hex (char *buff, ULONGEST *result);
static char *unpack_nibble (char *buf, int *val);
@@ -1228,7 +1237,7 @@
char *
unpack_varlen_hex (char *buff, /* packet to parse */
- int *result)
+ ULONGEST *result)
{
int nibble;
int retval = 0;
@@ -3007,7 +3016,8 @@
{
struct remote_state *rs = get_remote_state ();
unsigned char *buf = alloca (rs->remote_packet_size);
- int thread_num = -1;
+ ULONGEST thread_num = -1;
+ ULONGEST addr;
status->kind = TARGET_WAITKIND_EXITED;
status->value.integer = 0;
@@ -3025,6 +3035,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 +3060,19 @@
unsigned char *p1;
char *p_temp;
int fieldsize;
+ LONGEST pnum = 0;
- /* Read the ``P'' register number. */
- LONGEST 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 ``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 +3087,21 @@
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
+ {
+ /* silently skip unknown optional info */
+ p_temp = (unsigned char *) strchr ((const char *) p1+1, ';');
+ if (p_temp)
+ p = p_temp;
+ }
}
else
{
@@ -3221,11 +3257,14 @@
{
struct remote_state *rs = get_remote_state ();
unsigned char *buf = alloca (rs->remote_packet_size);
- int thread_num = -1;
+ ULONGEST thread_num = -1;
+ ULONGEST addr;
status->kind = TARGET_WAITKIND_EXITED;
status->value.integer = 0;
+ remote_stopped_by_watchpoint_p = 0;
+
while (1)
{
unsigned char *p;
@@ -3268,10 +3307,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 +3334,23 @@
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
+ {
+ /* silently skip unknown optional info */
+ p_temp = (unsigned char *) strchr ((const char *) p1+1, ';');
+ if (p_temp)
+ p = p_temp;
+ }
}
+
else
{
struct packet_reg *reg = packet_reg_from_pnum (rs, pnum);
@@ -4797,7 +4861,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 +4898,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 +4931,109 @@
"remote_remove_watchpoint: reached end of function");
}
-/* FIXME: This function should be static and a member of the remote
- target vector. */
+
+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_insert_hw_breakpoint (CORE_ADDR addr, int len)
+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)
+{
+ if (remote_stopped_by_watchpoint ())
+ return remote_watch_data_address;
+ return (CORE_ADDR)0;
+}
+
+
+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 +5059,19 @@
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 +5097,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 +5574,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 +5996,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 +6093,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 +6292,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
Index: doc/gdb.texinfo
===================================================================
RCS file: /cvs/src/src/gdb/doc/gdb.texinfo,v
retrieving revision 1.107
diff -u -r1.107 gdb.texinfo
--- doc/gdb.texinfo 3 Aug 2002 23:37:07 -0000 1.107
+++ doc/gdb.texinfo 8 Aug 2002 17:02:33 -0000
@@ -14751,10 +14751,11 @@
@var{AA} = two hex digit signal number; @var{n...} = register number
(hex), @var{r...} = target byte ordered register contents, size defined
by @code{REGISTER_RAW_SIZE}; @var{n...} = @samp{thread}, @var{r...} =
-thread process ID, this is a hex integer; @var{n...} = other string not
-starting with valid hex digit. @value{GDBN} should ignore this
-@var{n...}, @var{r...} pair and go on to the next. This way we can
-extend the protocol.
+thread process ID, this is a hex integer; @var{n...} = (@samp{watch} |
+@samp{rwatch} | @samp{awatch}, @var{r...} = data address, this is a hex
+integer; @var{n...} = other string not starting with valid hex digit.
+@value{GDBN} should ignore this @var{n...}, @var{r...} pair and go on
+to the next. This way we can extend the protocol.
@item @code{W}@var{AA}
@tab
next prev parent reply other threads:[~2002-08-08 17:06 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2002-08-06 9:19 Grace Sainsbury
2002-08-08 10:06 ` Grace Sainsbury [this message]
2002-08-08 11:30 ` Andrew Cagney
2002-08-08 12:44 ` [patch] remote.c: unpack_varlen_hex Grace Sainsbury
2002-08-09 8:41 ` [rfa] hardware breakpoints -- remote targets Grace Sainsbury
2002-08-09 9:26 ` Andrew Cagney
2002-08-11 6:48 ` Eli Zaretskii
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20020808130648.A27850@tomago.toronto.redhat.com \
--to=graces@redhat.com \
--cc=gdb-patches@sources.redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox