The branch stable/13 has been updated by mhorne:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=123578f890ee067662670832099fc9616ae3c1fc

commit 123578f890ee067662670832099fc9616ae3c1fc
Author:     Mitchell Horne <[email protected]>
AuthorDate: 2021-03-08 19:03:45 +0000
Commit:     Mitchell Horne <[email protected]>
CommitDate: 2021-04-21 13:20:33 +0000

    gdb: allow setting/removing hardware watchpoints
    
    Handle the 'z' and 'Z' remote packets for manipulating hardware
    watchpoints.
    
    This could be expanded quite easily to support hardware or software
    breakpoints as well.
    
    https://sourceware.org/gdb/onlinedocs/gdb/Packets.html
    
    Reviewed by:    cem, markj
    Sponsored by:   NetApp, Inc.
    Sponsored by:   Klara, Inc.
    NetApp PR:      51
    
    (cherry picked from commit 4beb385813c8b1014f8250a31b07fdc09a059713)
---
 sys/arm64/arm64/debug_monitor.c |   5 +-
 sys/conf/files.arm              |   3 +-
 sys/conf/files.x86              |   2 +-
 sys/gdb/gdb_main.c              | 102 ++++++++++++++++++++++++++++++++++++++++
 sys/x86/x86/mp_x86.c            |   3 +-
 5 files changed, 110 insertions(+), 5 deletions(-)

diff --git a/sys/arm64/arm64/debug_monitor.c b/sys/arm64/arm64/debug_monitor.c
index 3a5a40925c92..91594d5c3a78 100644
--- a/sys/arm64/arm64/debug_monitor.c
+++ b/sys/arm64/arm64/debug_monitor.c
@@ -28,6 +28,7 @@
  */
 
 #include "opt_ddb.h"
+#include "opt_gdb.h"
 
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
@@ -181,7 +182,7 @@ dbg_wb_write_reg(int reg, int n, uint64_t val)
        isb();
 }
 
-#ifdef DDB
+#if defined(DDB) || defined(GDB)
 void
 kdb_cpu_set_singlestep(void)
 {
@@ -254,7 +255,9 @@ kdb_cpu_clr_watchpoint(vm_offset_t addr, vm_size_t size)
 
        return (dbg_remove_watchpoint(NULL, addr, size));
 }
+#endif /* DDB || GDB */
 
+#ifdef DDB
 static const char *
 dbg_watchtype_str(uint32_t type)
 {
diff --git a/sys/conf/files.arm b/sys/conf/files.arm
index 69986585bdf6..a3b0d166f020 100644
--- a/sys/conf/files.arm
+++ b/sys/conf/files.arm
@@ -19,8 +19,7 @@ arm/arm/cpu_asm-v6.S          standard
 arm/arm/db_disasm.c            optional        ddb
 arm/arm/db_interface.c         optional        ddb
 arm/arm/db_trace.c             optional        ddb
-arm/arm/debug_monitor.c                optional        ddb armv6
-arm/arm/debug_monitor.c                optional        ddb armv7
+arm/arm/debug_monitor.c                optional        ddb | gdb
 arm/arm/disassem.c             optional        ddb
 arm/arm/dump_machdep.c         standard
 arm/arm/elf_machdep.c          standard
diff --git a/sys/conf/files.x86 b/sys/conf/files.x86
index 292389ac312f..7df289375cd3 100644
--- a/sys/conf/files.x86
+++ b/sys/conf/files.x86
@@ -331,7 +331,7 @@ x86/x86/bus_machdep.c               standard
 x86/x86/busdma_bounce.c                standard
 x86/x86/busdma_machdep.c       standard
 x86/x86/cpu_machdep.c          standard
-x86/x86/dbreg.c                        optional        ddb
+x86/x86/dbreg.c                        optional        ddb | gdb
 x86/x86/dump_machdep.c         standard
 x86/x86/fdt_machdep.c          optional        fdt
 x86/x86/identcpu.c             standard
diff --git a/sys/gdb/gdb_main.c b/sys/gdb/gdb_main.c
index 6e0c9f21f947..d0dbdfa63cb7 100644
--- a/sys/gdb/gdb_main.c
+++ b/sys/gdb/gdb_main.c
@@ -618,6 +618,100 @@ gdb_handle_detach(void)
 #endif
 }
 
+/*
+ * Handle a 'Z' packet: set a breakpoint or watchpoint.
+ *
+ * Currently, only watchpoints are supported.
+ */
+static void
+gdb_z_insert(void)
+{
+       intmax_t addr, length;
+       char ztype;
+       int error;
+
+       ztype = gdb_rx_char();
+       if (gdb_rx_char() != ',' || gdb_rx_varhex(&addr) ||
+           gdb_rx_char() != ',' || gdb_rx_varhex(&length)) {
+               error = EINVAL;
+               goto fail;
+       }
+
+       switch (ztype) {
+       case '2': /* write watchpoint */
+               error = kdb_cpu_set_watchpoint((vm_offset_t)addr,
+                   (vm_size_t)length, KDB_DBG_ACCESS_W);
+               break;
+       case '3': /* read watchpoint */
+               error = kdb_cpu_set_watchpoint((vm_offset_t)addr,
+                   (vm_size_t)length, KDB_DBG_ACCESS_R);
+               break;
+       case '4': /* access (RW) watchpoint */
+               error = kdb_cpu_set_watchpoint((vm_offset_t)addr,
+                   (vm_size_t)length, KDB_DBG_ACCESS_RW);
+               break;
+       case '1': /* hardware breakpoint */
+       case '0': /* software breakpoint */
+               /* Not implemented. */
+               gdb_tx_empty();
+               return;
+       default:
+               error = EINVAL;
+               break;
+       }
+       if (error != 0)
+               goto fail;
+       gdb_tx_ok();
+       return;
+fail:
+       gdb_tx_err(error);
+       return;
+}
+
+/*
+ * Handle a 'z' packet; clear a breakpoint or watchpoint.
+ *
+ * Currently, only watchpoints are supported.
+ */
+static void
+gdb_z_remove(void)
+{
+       intmax_t addr, length;
+       char ztype;
+       int error;
+
+       ztype = gdb_rx_char();
+       if (gdb_rx_char() != ',' || gdb_rx_varhex(&addr) ||
+           gdb_rx_char() != ',' || gdb_rx_varhex(&length)) {
+               error = EINVAL;
+               goto fail;
+       }
+
+       switch (ztype) {
+       case '2': /* write watchpoint */
+       case '3': /* read watchpoint */
+       case '4': /* access (RW) watchpoint */
+               error = kdb_cpu_clr_watchpoint((vm_offset_t)addr,
+                   (vm_size_t)length);
+               break;
+       case '1': /* hardware breakpoint */
+       case '0': /* software breakpoint */
+               /* Not implemented. */
+               gdb_tx_empty();
+               return;
+       default:
+               error = EINVAL;
+               break;
+       }
+       if (error != 0)
+               goto fail;
+       gdb_tx_ok();
+       return;
+fail:
+       gdb_tx_err(error);
+       return;
+}
+
 static int
 gdb_trap(int type, int code)
 {
@@ -868,6 +962,14 @@ gdb_trap(int type, int code)
                                gdb_tx_err(ENOENT);
                        break;
                }
+               case 'z': {     /* Remove watchpoint. */
+                       gdb_z_remove();
+                       break;
+               }
+               case 'Z': {     /* Set watchpoint. */
+                       gdb_z_insert();
+                       break;
+               }
                case EOF:
                        /* Empty command. Treat as unknown command. */
                        /* FALLTHROUGH */
diff --git a/sys/x86/x86/mp_x86.c b/sys/x86/x86/mp_x86.c
index 0f528f6567ee..2dcdf923c467 100644
--- a/sys/x86/x86/mp_x86.c
+++ b/sys/x86/x86/mp_x86.c
@@ -32,6 +32,7 @@ __FBSDID("$FreeBSD$");
 #endif
 #include "opt_cpu.h"
 #include "opt_ddb.h"
+#include "opt_gdb.h"
 #include "opt_kstack_pages.h"
 #include "opt_pmap.h"
 #include "opt_sched.h"
@@ -1520,7 +1521,7 @@ cpustop_handler_post(u_int cpu)
         */
        invltlb_glob();
 
-#if defined(__amd64__) && defined(DDB)
+#if defined(__amd64__) && (defined(DDB) || defined(GDB))
        amd64_db_resume_dbreg();
 #endif
 
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/dev-commits-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to