* remote.c: (remote_wait, remote_async_wait): Add check for awatch
T-packets; the 'a' is not taken as a register number. (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: From Mark Salter: * gdb.texinfo (Protocol): Document T packet extension to allow watchpoint address reporting.
This commit is contained in:
parent
5d1d95de0e
commit
3c3bea1c7e
|
@ -1,3 +1,24 @@
|
|||
2002-08-09 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.
|
||||
(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.
|
||||
|
||||
2002-08-09 Corinna Vinschen <vinschen@redhat.com>
|
||||
|
||||
* cli/cli-dump.c: Change fopen modes to use binary open modes
|
||||
|
@ -22,9 +43,10 @@
|
|||
|
||||
2002-08-08 Grace Sainsbury <graces@redhat.com>
|
||||
|
||||
* remote.c (remote_wait, remote_async_wait): Change thread_num
|
||||
ULONGEST.
|
||||
* (unpack_varlen_hex): Change result prameter to ULONGEST *.
|
||||
* remote.c (remote_wait, remote_async_wait): Change
|
||||
thread_num from int to ULONGEST.
|
||||
(unpack_varlen_hex): Change result parameter from
|
||||
int * to ULONGEST *.
|
||||
|
||||
2002-08-08 Andrew Cagney <ac131313@redhat.com>
|
||||
|
||||
|
|
|
@ -1,3 +1,10 @@
|
|||
2002-08-08 Grace Sainsbury <graces@redhat.com>
|
||||
|
||||
From Mark Salter:
|
||||
* gdb.texinfo (Protocol): Document T packet extension to
|
||||
allow watchpoint address reporting.
|
||||
|
||||
|
||||
2002-08-03 Andrew Cagney <ac131313@redhat.com>
|
||||
|
||||
* gdb.texinfo (Dump/Restore Files): Move `[]' to outside of @var.
|
||||
|
|
|
@ -14751,10 +14751,11 @@ conventions is used.
|
|||
@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
|
||||
|
|
190
gdb/remote.c
190
gdb/remote.c
|
@ -250,6 +250,7 @@ struct remote_state
|
|||
long remote_packet_size;
|
||||
};
|
||||
|
||||
|
||||
/* Handle for retreving the remote protocol data from gdbarch. */
|
||||
static struct gdbarch_data *remote_gdbarch_data_handle;
|
||||
|
||||
|
@ -340,7 +341,17 @@ packet_reg_from_pnum (struct remote_state *rs, LONGEST pnum)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* */
|
||||
/* FIXME: graces/2002-08-08: These variables should eventually be
|
||||
bound to an instance of the target object (as in gdbarch-tdep()),
|
||||
when such a thing exists. */
|
||||
|
||||
/* 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;
|
||||
|
||||
|
@ -3008,6 +3019,7 @@ remote_wait (ptid_t ptid, struct target_waitstatus *status)
|
|||
struct remote_state *rs = get_remote_state ();
|
||||
unsigned char *buf = alloca (rs->remote_packet_size);
|
||||
ULONGEST thread_num = -1;
|
||||
ULONGEST addr;
|
||||
|
||||
status->kind = TARGET_WAITKIND_EXITED;
|
||||
status->value.integer = 0;
|
||||
|
@ -3025,6 +3037,8 @@ remote_wait (ptid_t ptid, struct target_waitstatus *status)
|
|||
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,24 +3062,52 @@ remote_wait (ptid_t ptid, struct target_waitstatus *status)
|
|||
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 the packet contains a register number save it in pnum
|
||||
and set p1 to point to the character following it.
|
||||
Otherwise p1 points to p. */
|
||||
|
||||
/* If this packet is an awatch packet, don't parse the 'a'
|
||||
as a register number. */
|
||||
|
||||
if (strncmp (p, "awatch", strlen("awatch")) != 0)
|
||||
{
|
||||
/* Read the ``P'' register number. */
|
||||
pnum = strtol (p, &p_temp, 16);
|
||||
p1 = (unsigned char *) p_temp;
|
||||
}
|
||||
else
|
||||
p1 = p;
|
||||
|
||||
if (p1 == p) /* No register number present here */
|
||||
{
|
||||
p1 = (unsigned char *) strchr ((const char *) p, ':');
|
||||
p1 = (unsigned char *) strchr (p, ':');
|
||||
if (p1 == NULL)
|
||||
warning ("Malformed packet(a) (missing colon): %s\n\
|
||||
Packet: '%s'\n",
|
||||
p, buf);
|
||||
if (strncmp ((const char *) p, "thread", p1 - p) == 0)
|
||||
if (strncmp (p, "thread", p1 - p) == 0)
|
||||
{
|
||||
p_temp = unpack_varlen_hex (++p1, &thread_num);
|
||||
record_currthread (thread_num);
|
||||
p = (unsigned char *) p_temp;
|
||||
}
|
||||
else if ((strncmp (p, "watch", p1 - p) == 0)
|
||||
|| (strncmp (p, "rwatch", p1 - p) == 0)
|
||||
|| (strncmp (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 = strchr (p1 + 1, ';');
|
||||
if (p_temp)
|
||||
p = (unsigned char *) p_temp;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -3222,10 +3264,13 @@ remote_async_wait (ptid_t ptid, struct target_waitstatus *status)
|
|||
struct remote_state *rs = get_remote_state ();
|
||||
unsigned char *buf = alloca (rs->remote_packet_size);
|
||||
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,25 +3313,54 @@ remote_async_wait (ptid_t ptid, struct target_waitstatus *status)
|
|||
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 the packet contains a register number, save it in pnum
|
||||
and set p1 to point to the character following it.
|
||||
Otherwise p1 points to p. */
|
||||
|
||||
/* If this packet is an awatch packet, don't parse the 'a'
|
||||
as a register number. */
|
||||
|
||||
if (!strncmp (p, "awatch", strlen ("awatch")) != 0)
|
||||
{
|
||||
/* Read the register number. */
|
||||
pnum = strtol (p, &p_temp, 16);
|
||||
p1 = (unsigned char *) p_temp;
|
||||
}
|
||||
else
|
||||
p1 = p;
|
||||
|
||||
if (p1 == p) /* No register number present here */
|
||||
{
|
||||
p1 = (unsigned char *) strchr ((const char *) p, ':');
|
||||
p1 = (unsigned char *) strchr (p, ':');
|
||||
if (p1 == NULL)
|
||||
warning ("Malformed packet(a) (missing colon): %s\n\
|
||||
Packet: '%s'\n",
|
||||
p, buf);
|
||||
if (strncmp ((const char *) p, "thread", p1 - p) == 0)
|
||||
if (strncmp (p, "thread", p1 - p) == 0)
|
||||
{
|
||||
p_temp = unpack_varlen_hex (++p1, &thread_num);
|
||||
record_currthread (thread_num);
|
||||
p = (unsigned char *) p_temp;
|
||||
}
|
||||
else if ((strncmp (p, "watch", p1 - p) == 0)
|
||||
|| (strncmp (p, "rwatch", p1 - p) == 0)
|
||||
|| (strncmp (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 (p1 + 1, ';');
|
||||
if (p_temp)
|
||||
p = p_temp;
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
struct packet_reg *reg = packet_reg_from_pnum (rs, pnum);
|
||||
|
@ -4794,10 +4868,7 @@ watchpoint_to_Z_packet (int type)
|
|||
}
|
||||
}
|
||||
|
||||
/* 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 ();
|
||||
|
@ -4831,10 +4902,8 @@ remote_insert_watchpoint (CORE_ADDR addr, int len, int type)
|
|||
"remote_insert_watchpoint: reached end of function");
|
||||
}
|
||||
|
||||
/* 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 +4936,60 @@ remote_remove_watchpoint (CORE_ADDR addr, int len, int type)
|
|||
"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;
|
||||
|
||||
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;
|
||||
|
||||
/* The length field should be set to soething so that the packet is
|
||||
well formed. */
|
||||
|
||||
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 +5015,19 @@ remote_insert_hw_breakpoint (CORE_ADDR addr, int len)
|
|||
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 +5053,7 @@ remote_remove_hw_breakpoint (CORE_ADDR addr, int len)
|
|||
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 +5530,13 @@ Specify the serial device it is connected to\n\
|
|||
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 +5952,14 @@ Specify the serial device it is connected to (e.g. host:2020).";
|
|||
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 +6049,13 @@ Specify the serial device it is connected to (e.g. /dev/ttya).";
|
|||
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;
|
||||
|
|
Loading…
Reference in New Issue