This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
[gdbserver/patch] Z packet support
- From: Orjan Friberg <orjan dot friberg at axis dot com>
- To: gdb-patches at sources dot redhat dot com
- Date: Wed, 01 Dec 2004 16:12:43 +0100
- Subject: [gdbserver/patch] Z packet support
- Organization: Axis Communications
A while ago there was a brief discussion concerning Z packet support in the
gdbserver (starting at
http://sources.redhat.com/ml/gdb-patches/2004-05/msg00706.html) where it was
suggested that maybe the watchpoint code should be shared with GDB.
Well, I implemented Z packet support in the most straight-forward way ever:
separate from GDB (and I have an upcoming CRISv32 port which would use it). I
don't know if the various watchpoint functions need to change to accommodate
other architectures (if memory serves me correctly there were some issues with
the s390 on the host side regarding "stopped data address").
2004-12-01 Orjan Friberg <orjanf@axis.com>
* target.h (struct target_ops): Add insert_watchpoint,
remove_watchpoint, stopped_by_watchpoint, stopped_data_address function
pointers for hardware watchpoint support.
* linux-low.h (struct linux_target_ops): Ditto.
* linux-low.c (linux_insert_watchpoint, linux_remove_watchpoint)
(linux_stopped_by_watchpoint, linux_stopped_data_address): New. Add
to linux_target_ops.
* remote-utils.c (prepare_resume_reply): Add watchpoint information to
reply packet.
* server.c (main): Recognize 'Z' and 'z' packets.
Index: target.h
===================================================================
RCS file: /cvs/src/src/gdb/gdbserver/target.h,v
retrieving revision 1.11
diff -u -p -r1.11 target.h
--- target.h 5 Mar 2004 03:43:19 -0000 1.11
+++ target.h 1 Dec 2004 14:49:02 -0000
@@ -133,6 +133,13 @@ struct target_ops
Read LEN bytes at OFFSET into a buffer at MYADDR. */
int (*read_auxv) (CORE_ADDR offset, char *myaddr, unsigned int len);
+
+ /* Watchpoint related functions. */
+ int (*insert_watchpoint)(char type, CORE_ADDR addr, int len);
+ int (*remove_watchpoint)(char type, CORE_ADDR addr, int len);
+ int (*stopped_by_watchpoint) (void);
+ CORE_ADDR (*stopped_data_address) (void);
+
};
extern struct target_ops *the_target;
Index: linux-low.h
===================================================================
RCS file: /cvs/src/src/gdb/gdbserver/linux-low.h,v
retrieving revision 1.7
diff -u -p -r1.7 linux-low.h
--- linux-low.h 31 Jan 2004 22:19:32 -0000 1.7
+++ linux-low.h 1 Dec 2004 14:49:02 -0000
@@ -57,6 +57,13 @@ struct linux_target_ops
int decr_pc_after_break;
int (*breakpoint_at) (CORE_ADDR pc);
+
+ /* Watchpoint related functions. */
+ int (*insert_watchpoint) (char type, CORE_ADDR addr, int len);
+ int (*remove_watchpoint) (char type, CORE_ADDR addr, int len);
+ int (*stopped_by_watchpoint) (void);
+ CORE_ADDR (*stopped_data_address) (void);
+
};
extern struct linux_target_ops the_low_target;
Index: linux-low.c
===================================================================
RCS file: /cvs/src/src/gdb/gdbserver/linux-low.c,v
retrieving revision 1.33
diff -u -p -r1.33 linux-low.c
--- linux-low.c 16 Oct 2004 17:42:00 -0000 1.33
+++ linux-low.c 1 Dec 2004 14:49:02 -0000
@@ -1466,7 +1466,38 @@ linux_read_auxv (CORE_ADDR offset, char
return n;
}
-
+static int linux_insert_watchpoint (char type, CORE_ADDR addr, int len)
+{
+ if (the_low_target.insert_watchpoint != NULL)
+ return the_low_target.insert_watchpoint (type, addr, len);
+ else
+ return -1;
+}
+
+static int linux_remove_watchpoint (char type, CORE_ADDR addr, int len)
+{
+ if (the_low_target.remove_watchpoint != NULL)
+ return the_low_target.remove_watchpoint (type, addr, len);
+ else
+ return -1;
+}
+
+static int linux_stopped_by_watchpoint (void)
+{
+ if (the_low_target.stopped_by_watchpoint != NULL)
+ return the_low_target.stopped_by_watchpoint ();
+ else
+ return 0;
+}
+
+static CORE_ADDR linux_stopped_data_address (void)
+{
+ if (the_low_target.stopped_data_address != NULL)
+ return the_low_target.stopped_data_address ();
+ else
+ return 0;
+}
+
static struct target_ops linux_target_ops = {
linux_create_inferior,
linux_attach,
@@ -1482,6 +1513,10 @@ static struct target_ops linux_target_op
linux_look_up_symbols,
linux_send_signal,
linux_read_auxv,
+ linux_insert_watchpoint,
+ linux_remove_watchpoint,
+ linux_stopped_by_watchpoint,
+ linux_stopped_data_address,
};
static void
Index: remote-utils.c
===================================================================
RCS file: /cvs/src/src/gdb/gdbserver/remote-utils.c,v
retrieving revision 1.22
diff -u -p -r1.22 remote-utils.c
--- remote-utils.c 16 Oct 2004 17:42:00 -0000 1.22
+++ remote-utils.c 1 Dec 2004 14:49:02 -0000
@@ -639,6 +639,30 @@ prepare_resume_reply (char *buf, char st
if (status == 'T')
{
const char **regp = gdbserver_expedite_regs;
+
+ if (*the_target->stopped_by_watchpoint != NULL
+ && (*the_target->stopped_by_watchpoint) ())
+ {
+ CORE_ADDR addr;
+
+ strncpy (buf, "watch:", 6);
+ buf += 6;
+
+ addr = (*the_target->stopped_data_address) ();
+
+ *buf++ = tohex ((addr >> 28) & 0xf);
+ *buf++ = tohex ((addr >> 24) & 0xf);
+ *buf++ = tohex ((addr >> 20) & 0xf);
+ *buf++ = tohex ((addr >> 16) & 0xf);
+
+ *buf++ = tohex ((addr >> 12) & 0xf);
+ *buf++ = tohex ((addr >> 8) & 0xf);
+ *buf++ = tohex ((addr >> 4) & 0xf);
+ *buf++ = tohex (addr & 0xf);
+
+ *buf++ = ';';
+ }
+
while (*regp)
{
buf = outreg (find_regno (*regp), buf);
Index: server.c
===================================================================
RCS file: /cvs/src/src/gdb/gdbserver/server.c,v
retrieving revision 1.22
diff -u -p -r1.22 server.c
--- server.c 5 Mar 2004 03:44:27 -0000 1.22
+++ server.c 1 Dec 2004 14:49:02 -0000
@@ -508,6 +508,41 @@ main (int argc, char *argv[])
signal = mywait (&status, 1);
prepare_resume_reply (own_buf, status, signal);
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];
+
+ set_desired_inferior (0);
+ if (the_target->insert_watchpoint != NULL
+ && ((*the_target->insert_watchpoint) (type, addr, len)
+ == 0))
+ write_ok (own_buf);
+ else
+ own_buf[0] = '\0';
+ 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];
+
+ set_desired_inferior (0);
+
+ if (the_target->remove_watchpoint != NULL
+ && ((*the_target->remove_watchpoint) (type, addr, len)
+ == 0))
+ write_ok (own_buf);
+ else
+ own_buf[0] = '\0';
+ break;
+ }
case 'k':
fprintf (stderr, "Killing inferior\n");
kill_inferior ();
--
Orjan Friberg
Axis Communications