This is the mail archive of the gdb-patches@sourceware.cygnus.com mailing list for the GDB project. See the GDB home page for more information.


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

Patch to add breakpoint extension to remote protocol


The enclosed patch adds insert and remove breakpoint commands to the
GDB remote protocol.  The protocol changes are as I described in the
messages I sent to the gdb list over the last few weeks.

Since the i386-aout config directly used the i386-sysv configuration,
I created a X86 embedded target configuration (embed.mt / tm-embed.h)
that inherits from the sysv config, but then adds the definitions for
hardware watchpoints and breakpoints.  I believe that the other X86
embeded targets (i386-coff and i386-elf) should also use the embed
config, but I have not make that change since I am unable to test it.

	--jtc

1998-12-15  J.T. Conklin  <jtc@redbacknetworks.com>

	* remote.c (stub_supports_B): New variable, set to 1 if stub
	supports the new insert and remove breakpoint commands.
	(remote_insert_breakpoint, remote_remove_breakpoint): If
	stub_supports_B is set, attempt to use use the insert and remove
	breakpoint commands.  If we receive a empty response, the stub
	does not support the new commands.  In that case, stub_supports_B
	is reset and breakpoints will be inserted and removed by writing
	breakpoint insns as before.
	(remote_insert_watchpoint, remote_remove_watchpoint,
	remote_insert_hw_watchpoint, remote_remove_hw_watchpoint): New
	functions, present if TARGET_HAS_HARDWARE_WATCHPOINTS.
	(remote_open_1): Set stub_supports_B to 1.

	* config/i386/embed.mt: New file.
	* config/i386/tm-embed.h: New file.
	* configure.tgt: Changed i[3456]86-*-aout* to use embed.mt.

Index: tools-src/gdb/gdb/configure.tgt
diff -c tools-src/gdb/gdb/configure.tgt:1.1.1.1 tools-src/gdb/gdb/configure.tgt:1.1.1.1.2.1
*** tools-src/gdb/gdb/configure.tgt:1.1.1.1	Wed Dec  2 16:05:09 1998
--- tools-src/gdb/gdb/configure.tgt	Wed Dec  9 15:09:53 1998
***************
*** 83,89 ****
  i[3456]86-sequent-sysv4*) gdb_target=ptx4 ;;
  i[3456]86-sequent-sysv*) gdb_target=ptx ;;
  i[3456]86-ncr-*)	gdb_target=ncr3000 ;;
! i[3456]86-*-aout*)	gdb_target=i386aout ;;
  i[3456]86-*-coff*)	gdb_target=i386v ;;
  i[3456]86-*-elf*)	gdb_target=i386v ;;
  i[3456]86-*-aix*)	gdb_target=i386aix ;;
--- 83,89 ----
  i[3456]86-sequent-sysv4*) gdb_target=ptx4 ;;
  i[3456]86-sequent-sysv*) gdb_target=ptx ;;
  i[3456]86-ncr-*)	gdb_target=ncr3000 ;;
! i[3456]86-*-aout*)	gdb_target=embed ;;
  i[3456]86-*-coff*)	gdb_target=i386v ;;
  i[3456]86-*-elf*)	gdb_target=i386v ;;
  i[3456]86-*-aix*)	gdb_target=i386aix ;;
Index: tools-src/gdb/gdb/remote.c
diff -c tools-src/gdb/gdb/remote.c:1.1.1.1 tools-src/gdb/gdb/remote.c:1.1.1.1.2.3
*** tools-src/gdb/gdb/remote.c:1.1.1.1	Wed Dec  2 16:05:20 1998
--- tools-src/gdb/gdb/remote.c	Tue Dec 15 15:46:37 1998
***************
*** 90,95 ****
--- 90,117 ----
  					where only part of the data was
  					written).
  
+ 	insert break	Bt,AA..AA[,LLLL]
+ 	or watchpoint			t is type: 0 - software breakpoint, 
+ 					1 - hardware breakpoint, 2 - write
+ 					watchpoint, 3 - read watchpoint, 4 -
+ 					access watchpoint;
+ 					AA..AA is address;
+ 					LLLL is number of bytes
+ 	reply		OK		for success
+ 			ENN		for an error
+ 	(not supported by all stubs).
+ 					
+ 	remove break	bt,AA..AA[,LLLL]
+ 	or watchpoint			t is type: 0 - software breakpoint, 
+ 					1 - hardware breakpoint, 2 - write
+ 					watchpoint, 3 - read watchpoint, 4 -
+ 					access watchpoint;
+ 					AA..AA is address;
+ 					LLLL is number of bytes
+ 	reply		OK		for success
+ 			ENN		for an error
+ 	(not supported by all stubs).
+ 
  	continue	cAA..AA		AA..AA is address to resume
  					If AA..AA is omitted,
  					resume at same address.
***************
*** 387,392 ****
--- 409,419 ----
  
  static int remote_register_buf_size = 0;
  
+ /* Should we try the 'b'/'B' requests?  If this is set to one when the
+    stub doesn't support 'b'/'B', the only consequence is some
+    unecessary traffic. */
+ static int stub_supports_B = 1;
+ 
  /* Should we try the 'P' request?  If this is set to one when the stub
     doesn't support 'P', the only consequence is some unnecessary traffic.  */
  static int stub_supports_P = 1;
***************
*** 1678,1686 ****
       so we use this function to call back into the thread module and
       register the thread vector and its contained functions. */
    bind_target_thread_vector(&remote_thread_vec);
!   /* Start out by trying the 'P' request to set registers.  We set this each
!      time that we open a new target so that if the user switches from one
!      stub to another, we can (if the target is closed and reopened) cope.  */
    stub_supports_P = 1;
  
    general_thread = -2;
--- 1705,1717 ----
       so we use this function to call back into the thread module and
       register the thread vector and its contained functions. */
    bind_target_thread_vector(&remote_thread_vec);
! 
!   /* Start out by trying the 'B' request for stub-managed breakpoints
!      and the 'P' request to set registers.  We set these each time
!      that we open a new target so that if the user switches from one
!      stub to another, we can (if the target is closed and reopened)
!      cope.  */
!   stub_supports_B = 1;
    stub_supports_P = 1;
  
    general_thread = -2;
***************
*** 3012,3022 ****
       CORE_ADDR addr;
       char *contents_cache;
  {
  #ifdef REMOTE_BREAKPOINT
    int val;
  
!   val = target_read_memory (addr, contents_cache, sizeof big_break_insn);
  
    if (val == 0)
      {
        if (TARGET_BYTE_ORDER == BIG_ENDIAN)
--- 3043,3068 ----
       CORE_ADDR addr;
       char *contents_cache;
  {
+   char buf[PBUFSIZ];
  #ifdef REMOTE_BREAKPOINT
    int val;
+ #endif
  
!   if (stub_supports_B) 
!     {
!       sprintf (buf, "B0,%lx", (long) addr);
!       putpkt (buf);
!       getpkt (buf, 0);
! 
!       if (buf[0] != '\0') 
! 	return (buf[0] == 'E');
  
+       /* The stub does not support the 'B' request. */
+       stub_supports_B = 0;
+     }
+ 
+ #ifdef REMOTE_BREAKPOINT
+   val = target_read_memory (addr, contents_cache, sizeof big_break_insn);
    if (val == 0)
      {
        if (TARGET_BYTE_ORDER == BIG_ENDIAN)
***************
*** 3038,3049 ****
--- 3084,3179 ----
       CORE_ADDR addr;
       char *contents_cache;
  {
+   char buf[PBUFSIZ];
+ 
+   if (stub_supports_B)
+     {
+       sprintf (buf, "b0,%lx", (long) addr);
+       putpkt (buf);
+       getpkt (buf, 0);
+ 
+       return (buf[0] == 'E');
+     }
+ 
  #ifdef REMOTE_BREAKPOINT
    return target_write_memory (addr, contents_cache, sizeof big_break_insn);
  #else
    return memory_remove_breakpoint (addr, contents_cache);
  #endif /* REMOTE_BREAKPOINT */
  }
+ 
+ #ifdef TARGET_HAS_HARDWARE_WATCHPOINTS
+ int
+ remote_insert_watchpoint (addr, len, type)
+      CORE_ADDR addr;
+      int len;
+      int type;
+ {
+   char buf[PBUFSIZ];
+   
+   sprintf (buf, "B%x,%lx,%lx", type + 2, (long) addr, len);
+   putpkt (buf);
+   getpkt (buf, 0);
+ 
+   if (buf[0] == '\0' || buf [0] == 'E')
+     return -1;
+ 
+   return 0;
+ }
+ 
+ int
+ remote_remove_watchpoint (addr, len, type)
+      CORE_ADDR addr;
+      int len;
+      int type;
+ {
+   char buf[PBUFSIZ];
+   
+   sprintf (buf, "b%x,%lx,%lx", type + 2, (long) addr, len);
+   putpkt (buf);
+   getpkt (buf, 0);
+ 
+   if (buf[0] == '\0' || buf [0] == 'E')
+     return -1;
+ 
+   return 0;
+ }
+ 
+ int
+ remote_insert_hw_breakpoint (addr, len)
+      CORE_ADDR addr;
+      int len;
+ {
+   char buf[PBUFSIZ];
+ 
+   sprintf (buf, "B1,%lx", (long) addr);
+   putpkt (buf);
+   getpkt (buf, 0);
+ 
+   if (buf[0] == '\0' || buf [0] == 'E')
+     return -1;
+ 
+   return 0;
+ }
+ 
+ int 
+ remote_remove_hw_breakpoint (addr, len)
+      CORE_ADDR addr;
+      int len;
+ {
+   char buf[PBUFSIZ];
+ 
+   sprintf (buf, "b1,%lx", (long) addr);
+   putpkt(buf);
+   getpkt (buf, 0);
+   
+   if (buf[0] == '\0' || buf [0] == 'E')
+     return -1;
+ 
+   return 0;
+ }
+ #endif
+ 
  
  /* Some targets are only capable of doing downloads, and afterwards they switch
     to the remote serial protocol.  This function provides a clean way to get
Index: tools-src/gdb/gdb/config/i386/embed.mt
diff -c /dev/null tools-src/gdb/gdb/config/i386/embed.mt:1.1.2.1
*** /dev/null	Tue Dec 15 16:15:14 1998
--- tools-src/gdb/gdb/config/i386/embed.mt	Wed Dec  9 15:10:00 1998
***************
*** 0 ****
--- 1,3 ----
+ # Target: Intel 386 embedded target
+ TDEPFILES= i386-tdep.o
+ TM_FILE= tm-embed.h
Index: tools-src/gdb/gdb/config/i386/tm-embed.h
diff -c /dev/null tools-src/gdb/gdb/config/i386/tm-embed.h:1.1.2.1
*** /dev/null	Tue Dec 15 16:15:15 1998
--- tools-src/gdb/gdb/config/i386/tm-embed.h	Wed Dec  9 15:10:01 1998
***************
*** 0 ****
--- 1,47 ----
+ /* Macro definitions for i386, embedded targets.
+    Copyright 1998 Free Software Foundation, Inc.
+ 
+ This file is part of GDB.
+ 
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+ 
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU General Public License for more details.
+ 
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+ 
+ #ifndef TM_EMBED_H
+ #define TM_EMBED_H 1
+ 
+ #include "i386/tm-i386v.h"
+ 
+ /* Remote protocol can use hardware debugging registers */
+ #define TARGET_HAS_HARDWARE_WATCHPOINTS
+ 
+ #define TARGET_CAN_USE_HARDWARE_WATCHPOINT(type, cnt, ot) 1
+ 
+ /* After a watchpoint trap, the PC points to the instruction after the
+    one that caused the trap.  Therefore we don't need to step over it.
+    But we do need to reset the status register to avoid another trap. */
+ #define HAVE_CONTINUABLE_WATCHPOINT
+ 
+ #define target_insert_watchpoint(addr, len, type) \
+ 	remote_insert_watchpoint(addr, len, type)
+ 
+ #define target_remove_watchpoint(addr, len, type) \
+ 	remote_remove_watchpoint(addr, len, type)
+ 
+ #define target_insert_hw_breakpoint(addr, len) \
+ 	remote_insert_hw_breakpoint(addr, len)
+ 
+ #define target_remove_hw_breakpoint(addr, len) \
+ 	remote_remove_hw_breakpoint(addr, len)
+ 
+ #endif /* ifndef TM_EMBED_H */