This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[gdbserver/patch] Z packet support


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]