Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F157532334
D29174.id86261.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
6 KB
Referenced Files
None
Subscribers
None
D29174.id86261.diff
View Options
Index: sys/amd64/amd64/gdb_machdep.c
===================================================================
--- sys/amd64/amd64/gdb_machdep.c
+++ sys/amd64/amd64/gdb_machdep.c
@@ -152,6 +152,43 @@
return (SIGEMT);
}
+char *
+gdb_cpu_stop_reason(int type, uintmax_t *val)
+{
+ uint64_t dr6;
+ char *reason;
+
+ *val = 0;
+ reason = NULL;
+ if (type == T_TRCTRAP) {
+ dr6 = rdr6();
+ load_dr6(dr6 & ~DBREG_DR6_BMASK);
+
+ if ((dr6 & DBREG_DR6_B(0)) != 0) {
+ *val = rdr0();
+ }
+ if ((dr6 & DBREG_DR6_B(1)) != 0) {
+ *val = rdr1();
+ }
+ if ((dr6 & DBREG_DR6_B(2)) != 0) {
+ *val = rdr2();
+ }
+ if ((dr6 & 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)
+ reason = "watch";
+ }
+
+ return (reason);
+}
+
void *
gdb_begin_write(void)
{
Index: sys/amd64/include/gdb_machdep.h
===================================================================
--- sys/amd64/include/gdb_machdep.h
+++ sys/amd64/include/gdb_machdep.h
@@ -72,5 +72,6 @@
void gdb_cpu_setreg(int, void *);
int gdb_cpu_signal(int, int);
void gdb_end_write(void *);
+char *gdb_cpu_stop_reason(int type, uintmax_t *val);
#endif /* !_MACHINE_GDB_MACHDEP_H_ */
Index: sys/arm/include/gdb_machdep.h
===================================================================
--- sys/arm/include/gdb_machdep.h
+++ sys/arm/include/gdb_machdep.h
@@ -66,6 +66,14 @@
}
+static __inline char *
+gdb_cpu_stop_reason(int type __unused, uintmax_t *val __unused)
+{
+
+ /* Not implemented. */
+ return (NULL);
+}
+
void *gdb_cpu_getreg(int, size_t *);
void gdb_cpu_setreg(int, void *);
int gdb_cpu_signal(int, int);
Index: sys/arm64/arm64/gdb_machdep.c
===================================================================
--- sys/arm64/arm64/gdb_machdep.c
+++ sys/arm64/arm64/gdb_machdep.c
@@ -110,3 +110,15 @@
}
return (SIGEMT);
}
+
+char *
+gdb_cpu_stop_reason(int type, uintmax_t *val)
+{
+
+ if (type == EXCP_WATCHPT_EL1) {
+ *val = READ_SPECIALREG(far_el1);
+ return ("watch");
+ }
+
+ return (NULL);
+}
Index: sys/arm64/include/gdb_machdep.h
===================================================================
--- sys/arm64/include/gdb_machdep.h
+++ sys/arm64/include/gdb_machdep.h
@@ -77,5 +77,6 @@
void *gdb_cpu_getreg(int, size_t *);
void gdb_cpu_setreg(int, void *);
int gdb_cpu_signal(int, int);
+char *gdb_cpu_stop_reason(int type, uintmax_t *val);
#endif /* !_MACHINE_GDB_MACHDEP_H_ */
Index: sys/gdb/gdb_main.c
===================================================================
--- sys/gdb/gdb_main.c
+++ sys/gdb/gdb_main.c
@@ -712,6 +712,31 @@
return;
}
+/*
+ * Communicate the stop reason for the trap to the gdb client.
+ *
+ * Normally, this is simply "thread:$tid". We can prepend more specific trap
+ * reasons when they are detected, such as the address that triggered a
+ * watchpoint. Doing so is never required, however.
+ *
+ * https://sourceware.org/gdb/onlinedocs/gdb/Stop-Reply-Packets.html
+ */
+static void
+gdb_stop_reason(int type)
+{
+ char *reason;
+ uintmax_t val;
+
+ reason = gdb_cpu_stop_reason(type, &val);
+ if (reason != NULL) {
+ gdb_tx_str(reason);
+ gdb_tx_char(':');
+ if (val != 0)
+ gdb_tx_varhex(val);
+ gdb_tx_char(';');
+ }
+}
+
static int
gdb_trap(int type, int code)
{
@@ -741,8 +766,9 @@
gdb_tx_char(':');
gdb_tx_reg(GDB_REG_PC);
gdb_tx_char(';');
+ gdb_stop_reason(type);
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. */
Index: sys/i386/i386/gdb_machdep.c
===================================================================
--- sys/i386/i386/gdb_machdep.c
+++ sys/i386/i386/gdb_machdep.c
@@ -36,11 +36,12 @@
#include <sys/proc.h>
#include <sys/signal.h>
+#include <machine/endian.h>
+#include <machine/frame.h>
#include <machine/gdb_machdep.h>
#include <machine/pcb.h>
+#include <machine/reg.h>
#include <machine/trap.h>
-#include <machine/frame.h>
-#include <machine/endian.h>
#include <gdb/gdb.h>
@@ -114,3 +115,40 @@
}
return (SIGEMT);
}
+
+char *
+gdb_cpu_stop_reason(int type, uintmax_t *val)
+{
+ uint64_t dr6;
+ char *reason;
+
+ *val = 0;
+ reason = NULL;
+ if (type == T_TRCTRAP) {
+ dr6 = rdr6();
+ load_dr6(dr6 & ~DBREG_DR6_BMASK);
+
+ if ((dr6 & DBREG_DR6_B(0)) != 0) {
+ *val = rdr0();
+ }
+ if ((dr6 & DBREG_DR6_B(1)) != 0) {
+ *val = rdr1();
+ }
+ if ((dr6 & DBREG_DR6_B(2)) != 0) {
+ *val = rdr2();
+ }
+ if ((dr6 & 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)
+ reason = "watch";
+ }
+
+ return (reason);
+}
Index: sys/i386/include/gdb_machdep.h
===================================================================
--- sys/i386/include/gdb_machdep.h
+++ sys/i386/include/gdb_machdep.h
@@ -63,5 +63,6 @@
void *gdb_cpu_getreg(int, size_t *);
void gdb_cpu_setreg(int, void *);
int gdb_cpu_signal(int, int);
+char *gdb_cpu_stop_reason(int type, uintmax_t *val);
#endif /* !_MACHINE_GDB_MACHDEP_H_ */
Index: sys/mips/include/gdb_machdep.h
===================================================================
--- sys/mips/include/gdb_machdep.h
+++ sys/mips/include/gdb_machdep.h
@@ -64,6 +64,14 @@
}
+static __inline char *
+gdb_cpu_stop_reason(int type __unused, uintmax_t *val __unused)
+{
+
+ /* Not implemented. */
+ return (NULL);
+}
+
void *gdb_cpu_getreg(int, size_t *);
void gdb_cpu_setreg(int, void *);
int gdb_cpu_signal(int, int);
Index: sys/powerpc/include/gdb_machdep.h
===================================================================
--- sys/powerpc/include/gdb_machdep.h
+++ sys/powerpc/include/gdb_machdep.h
@@ -128,6 +128,14 @@
}
+static __inline char *
+gdb_cpu_stop_reason(int type __unused, uintmax_t *val __unused)
+{
+
+ /* Not implemented. */
+ return (NULL);
+}
+
void *gdb_cpu_getreg(int, size_t *);
void gdb_cpu_setreg(int, void *);
int gdb_cpu_signal(int, int);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, May 23, 12:23 PM (20 h, 26 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
33446381
Default Alt Text
D29174.id86261.diff (6 KB)
Attached To
Mode
D29174: gdb: report specific stop reason for watchpoints
Attached
Detach File
Event Timeline
Log In to Comment