From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 8861 invoked by alias); 1 Dec 2004 15:13:01 -0000 Mailing-List: contact gdb-patches-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sources.redhat.com Received: (qmail 8379 invoked from network); 1 Dec 2004 15:12:44 -0000 Received: from unknown (HELO krynn.se.axis.com) (212.209.10.221) by sourceware.org with SMTP; 1 Dec 2004 15:12:44 -0000 Received: from [10.84.130.1] (ironmaiden.se.axis.com [10.84.130.1]) by krynn.se.axis.com (8.12.9/8.12.9/Debian-5local0.1) with ESMTP id iB1FCgAD016673 for ; Wed, 1 Dec 2004 16:12:42 +0100 Message-ID: <41ADDF6B.2040601@axis.com> Date: Wed, 01 Dec 2004 15:13:00 -0000 From: Orjan Friberg Organization: Axis Communications User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.7.3) Gecko/20040913 MIME-Version: 1.0 To: gdb-patches@sources.redhat.com Subject: [gdbserver/patch] Z packet support Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit X-SW-Source: 2004-12/txt/msg00016.txt.bz2 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 * 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