Patch to add breakpoint extension to remote protocol
J.T. Conklin
jtc@redbacknetworks.com
Tue Dec 15 16:31:00 GMT 1998
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 */
More information about the Gdb-patches
mailing list