From owner-dev-commits-src-all@freebsd.org Tue Mar 30 14:37:12 2021 Return-Path: Delivered-To: dev-commits-src-all@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 2A0A15788C3; Tue, 30 Mar 2021 14:37:12 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4F8sTz3w6hz4p7d; Tue, 30 Mar 2021 14:37:11 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id E2E6320A; Tue, 30 Mar 2021 14:37:10 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 12UEbAbJ039975; Tue, 30 Mar 2021 14:37:10 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 12UEbA5e039974; Tue, 30 Mar 2021 14:37:10 GMT (envelope-from git) Date: Tue, 30 Mar 2021 14:37:10 GMT Message-Id: <202103301437.12UEbA5e039974@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Mitchell Horne Subject: git: 7446b0888d92 - main - gdb: report specific stop reason for watchpoints MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: mhorne X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 7446b0888d920124516284eaa32714d63353e2c9 Auto-Submitted: auto-generated X-BeenThere: dev-commits-src-all@freebsd.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Commit messages for all branches of the src repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 30 Mar 2021 14:37:12 -0000 The branch main has been updated by mhorne: URL: https://cgit.FreeBSD.org/src/commit/?id=7446b0888d920124516284eaa32714d63353e2c9 commit 7446b0888d920124516284eaa32714d63353e2c9 Author: Mitchell Horne AuthorDate: 2021-03-08 19:04:51 +0000 Commit: Mitchell Horne CommitDate: 2021-03-30 14:36:41 +0000 gdb: report specific stop reason for watchpoints The remote protocol allows for implementations to report more specific reasons for the break in execution back to the client [1]. This is entirely optional, so it is only implemented for amd64, arm64, and i386 at the moment. [1] https://sourceware.org/gdb/current/onlinedocs/gdb/Stop-Reply-Packets.html Reviewed by: jhb MFC after: 3 weeks Sponsored by: NetApp, Inc. Sponsored by: Klara, Inc. NetApp PR: 51 Differential Revision: https://reviews.freebsd.org/D29174 --- sys/amd64/amd64/gdb_machdep.c | 35 ++++++++++++++++++++++++++++++++++ sys/amd64/include/gdb_machdep.h | 1 + sys/arm/include/gdb_machdep.h | 6 ++++++ sys/arm64/arm64/gdb_machdep.c | 12 ++++++++++++ sys/arm64/include/gdb_machdep.h | 1 + sys/gdb/gdb_main.c | 3 ++- sys/i386/i386/gdb_machdep.c | 40 +++++++++++++++++++++++++++++++++++++-- sys/i386/include/gdb_machdep.h | 1 + sys/mips/include/gdb_machdep.h | 6 ++++++ sys/powerpc/include/gdb_machdep.h | 6 ++++++ 10 files changed, 108 insertions(+), 3 deletions(-) diff --git a/sys/amd64/amd64/gdb_machdep.c b/sys/amd64/amd64/gdb_machdep.c index 610096e1355d..176c770a3731 100644 --- a/sys/amd64/amd64/gdb_machdep.c +++ b/sys/amd64/amd64/gdb_machdep.c @@ -49,6 +49,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include void * gdb_cpu_getreg(int regnum, size_t *regsz) @@ -152,6 +153,40 @@ gdb_cpu_signal(int type, int code) return (SIGEMT); } +void +gdb_cpu_stop_reason(int type, int code) +{ + uintmax_t val; + + val = 0; + if (type == T_TRCTRAP) { + /* NB: 'code' contains the value of dr6 at the trap. */ + if ((code & DBREG_DR6_B(0)) != 0) { + val = rdr0(); + } + if ((code & DBREG_DR6_B(1)) != 0) { + val = rdr1(); + } + if ((code & DBREG_DR6_B(2)) != 0) { + val = rdr2(); + } + if ((code & DBREG_DR6_B(3)) != 0) { + val = rdr3(); + } + + /* + * TODO: validate the bits in DR7 to differentiate between a + * watchpoint trap and a hardware breakpoint trap (currently + * unsupported). + */ + if (val != 0) { + gdb_tx_str("watch:"); + gdb_tx_varhex(val); + gdb_tx_char(';'); + } + } +} + void * gdb_begin_write(void) { diff --git a/sys/amd64/include/gdb_machdep.h b/sys/amd64/include/gdb_machdep.h index 459d4f17e9d1..4379b8a74709 100644 --- a/sys/amd64/include/gdb_machdep.h +++ b/sys/amd64/include/gdb_machdep.h @@ -72,5 +72,6 @@ void *gdb_cpu_getreg(int, size_t *); void gdb_cpu_setreg(int, void *); int gdb_cpu_signal(int, int); void gdb_end_write(void *); +void gdb_cpu_stop_reason(int, int); #endif /* !_MACHINE_GDB_MACHDEP_H_ */ diff --git a/sys/arm/include/gdb_machdep.h b/sys/arm/include/gdb_machdep.h index 017025253bd5..5190c2a4097e 100644 --- a/sys/arm/include/gdb_machdep.h +++ b/sys/arm/include/gdb_machdep.h @@ -66,6 +66,12 @@ gdb_end_write(void *arg __unused) } +static __inline void +gdb_cpu_stop_reason(int type __unused, int code __unused) +{ + +} + void *gdb_cpu_getreg(int, size_t *); void gdb_cpu_setreg(int, void *); int gdb_cpu_signal(int, int); diff --git a/sys/arm64/arm64/gdb_machdep.c b/sys/arm64/arm64/gdb_machdep.c index dc0a7eeba692..b27e1edb3d7f 100644 --- a/sys/arm64/arm64/gdb_machdep.c +++ b/sys/arm64/arm64/gdb_machdep.c @@ -41,6 +41,7 @@ #include #include +#include void * gdb_cpu_getreg(int regnum, size_t *regsz) @@ -110,3 +111,14 @@ gdb_cpu_signal(int type, int code __unused) } return (SIGEMT); } + +void +gdb_cpu_stop_reason(int type, int code __unused) +{ + + if (type == EXCP_WATCHPT_EL1) { + gdb_tx_str("watch:"); + gdb_tx_varhex((uintmax_t)READ_SPECIALREG(far_el1)); + gdb_tx_char(';'); + } +} diff --git a/sys/arm64/include/gdb_machdep.h b/sys/arm64/include/gdb_machdep.h index 755c5d1657c0..17b46edd1a27 100644 --- a/sys/arm64/include/gdb_machdep.h +++ b/sys/arm64/include/gdb_machdep.h @@ -77,5 +77,6 @@ gdb_end_write(void *arg __unused) void *gdb_cpu_getreg(int, size_t *); void gdb_cpu_setreg(int, void *); int gdb_cpu_signal(int, int); +void gdb_cpu_stop_reason(int, int); #endif /* !_MACHINE_GDB_MACHDEP_H_ */ diff --git a/sys/gdb/gdb_main.c b/sys/gdb/gdb_main.c index a4469fdf4997..c5e4ba608f29 100644 --- a/sys/gdb/gdb_main.c +++ b/sys/gdb/gdb_main.c @@ -741,8 +741,9 @@ gdb_trap(int type, int code) gdb_tx_char(':'); gdb_tx_reg(GDB_REG_PC); gdb_tx_char(';'); + gdb_cpu_stop_reason(type, code); gdb_tx_str("thread:"); - gdb_tx_varhex((long)kdb_thread->td_tid); + gdb_tx_varhex((uintmax_t)kdb_thread->td_tid); gdb_tx_char(';'); gdb_tx_end(); /* XXX check error condition. */ diff --git a/sys/i386/i386/gdb_machdep.c b/sys/i386/i386/gdb_machdep.c index fd522309dbb2..549c6de7ba1b 100644 --- a/sys/i386/i386/gdb_machdep.c +++ b/sys/i386/i386/gdb_machdep.c @@ -36,13 +36,15 @@ __FBSDID("$FreeBSD$"); #include #include +#include +#include #include #include +#include #include -#include -#include #include +#include void * gdb_cpu_getreg(int regnum, size_t *regsz) @@ -114,3 +116,37 @@ gdb_cpu_signal(int type, int code) } return (SIGEMT); } + +void +gdb_cpu_stop_reason(int type, int code) +{ + uintmax_t val; + + val = 0; + if (type == T_TRCTRAP) { + /* NB: 'code' contains the value of dr6 at the trap. */ + if ((code & DBREG_DR6_B(0)) != 0) { + val = rdr0(); + } + if ((code & DBREG_DR6_B(1)) != 0) { + val = rdr1(); + } + if ((code & DBREG_DR6_B(2)) != 0) { + val = rdr2(); + } + if ((code & DBREG_DR6_B(3)) != 0) { + val = rdr3(); + } + + /* + * TODO: validate the bits in DR7 to differentiate between a + * watchpoint trap and a hardware breakpoint trap (currently + * unsupported). + */ + if (val != 0) { + gdb_tx_str("watch:"); + gdb_tx_varhex(val); + gdb_tx_char(';'); + } + } +} diff --git a/sys/i386/include/gdb_machdep.h b/sys/i386/include/gdb_machdep.h index ef9500160be1..77eb70e2fb28 100644 --- a/sys/i386/include/gdb_machdep.h +++ b/sys/i386/include/gdb_machdep.h @@ -63,5 +63,6 @@ gdb_end_write(void *arg __unused) void *gdb_cpu_getreg(int, size_t *); void gdb_cpu_setreg(int, void *); int gdb_cpu_signal(int, int); +void gdb_cpu_stop_reason(int, int); #endif /* !_MACHINE_GDB_MACHDEP_H_ */ diff --git a/sys/mips/include/gdb_machdep.h b/sys/mips/include/gdb_machdep.h index 03378b760024..e8ff620edc88 100644 --- a/sys/mips/include/gdb_machdep.h +++ b/sys/mips/include/gdb_machdep.h @@ -64,6 +64,12 @@ gdb_end_write(void *arg __unused) } +static __inline void +gdb_cpu_stop_reason(int type __unused, int code __unused) +{ + +} + void *gdb_cpu_getreg(int, size_t *); void gdb_cpu_setreg(int, void *); int gdb_cpu_signal(int, int); diff --git a/sys/powerpc/include/gdb_machdep.h b/sys/powerpc/include/gdb_machdep.h index 41a9ab1f4fa7..5edf4d96cb7c 100644 --- a/sys/powerpc/include/gdb_machdep.h +++ b/sys/powerpc/include/gdb_machdep.h @@ -128,6 +128,12 @@ gdb_end_write(void *arg __unused) } +static __inline void +gdb_cpu_stop_reason(int type __unused, int code __unused) +{ + +} + void *gdb_cpu_getreg(int, size_t *); void gdb_cpu_setreg(int, void *); int gdb_cpu_signal(int, int);