summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormhorne <mhorne@ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f>2020-12-18 16:09:24 +0000
committermhorne <mhorne@ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f>2020-12-18 16:09:24 +0000
commit8e1731aad9acd8d9ab4d962da12668c9ec8343f8 (patch)
treebf5a8af3fd06ced65ab7372b5cc79c50a482e5ae
parent08d3bb4081071529219daf3f1d2485c5c229212e (diff)
downloadfreebsd-8e1731aad9acd8d9ab4d962da12668c9ec8343f8.tar.gz
freebsd-8e1731aad9acd8d9ab4d962da12668c9ec8343f8.tar.bz2
amd64: allow gdb(4) to write to most registers
Similar to the recent patch to arm's gdb stub in r368414, allow GDB to update the contents of most general purpose registers. Reviewed by: cem, jhb, markj MFC after: 2 weeks Sponsored by: NetApp, Inc. Sponsored by: Klara, Inc. NetApp PR: 44 Differential Revision: https://reviews.freebsd.org/D27642 git-svn-id: http://svn.freebsd.org/base/head@368764 ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f
-rw-r--r--sys/amd64/amd64/gdb_machdep.c38
-rw-r--r--sys/amd64/include/gdb_machdep.h16
2 files changed, 50 insertions, 4 deletions
diff --git a/sys/amd64/amd64/gdb_machdep.c b/sys/amd64/amd64/gdb_machdep.c
index 89da4519683..efcf545362c 100644
--- a/sys/amd64/amd64/gdb_machdep.c
+++ b/sys/amd64/amd64/gdb_machdep.c
@@ -92,12 +92,42 @@ gdb_cpu_getreg(int regnum, size_t *regsz)
void
gdb_cpu_setreg(int regnum, void *val)
{
+ register_t regval = *(register_t *)val;
+ /*
+ * Write registers to the trapframe and pcb, if applicable.
+ * Some scratch registers are not tracked by the pcb.
+ */
+ if (kdb_thread == curthread) {
+ switch (regnum) {
+ case GDB_REG_RAX: kdb_frame->tf_rax = regval; break;
+ case GDB_REG_RBX: kdb_frame->tf_rbx = regval; break;
+ case GDB_REG_RCX: kdb_frame->tf_rcx = regval; break;
+ case GDB_REG_RDX: kdb_frame->tf_rdx = regval; break;
+ case GDB_REG_RSI: kdb_frame->tf_rsi = regval; break;
+ case GDB_REG_RDI: kdb_frame->tf_rdi = regval; break;
+ case GDB_REG_RBP: kdb_frame->tf_rbp = regval; break;
+ case GDB_REG_RSP: kdb_frame->tf_rsp = regval; break;
+ case GDB_REG_R8: kdb_frame->tf_r8 = regval; break;
+ case GDB_REG_R9: kdb_frame->tf_r9 = regval; break;
+ case GDB_REG_R10: kdb_frame->tf_r10 = regval; break;
+ case GDB_REG_R11: kdb_frame->tf_r11 = regval; break;
+ case GDB_REG_R12: kdb_frame->tf_r12 = regval; break;
+ case GDB_REG_R13: kdb_frame->tf_r13 = regval; break;
+ case GDB_REG_R14: kdb_frame->tf_r14 = regval; break;
+ case GDB_REG_R15: kdb_frame->tf_r15 = regval; break;
+ case GDB_REG_PC: kdb_frame->tf_rip = regval; break;
+ }
+ }
switch (regnum) {
- case GDB_REG_PC:
- kdb_thrctx->pcb_rip = *(register_t *)val;
- if (kdb_thread == curthread)
- kdb_frame->tf_rip = *(register_t *)val;
+ case GDB_REG_RBX: kdb_thrctx->pcb_rbx = regval; break;
+ case GDB_REG_RBP: kdb_thrctx->pcb_rbp = regval; break;
+ case GDB_REG_RSP: kdb_thrctx->pcb_rsp = regval; break;
+ case GDB_REG_R12: kdb_thrctx->pcb_r12 = regval; break;
+ case GDB_REG_R13: kdb_thrctx->pcb_r13 = regval; break;
+ case GDB_REG_R14: kdb_thrctx->pcb_r14 = regval; break;
+ case GDB_REG_R15: kdb_thrctx->pcb_r15 = regval; break;
+ case GDB_REG_PC: kdb_thrctx->pcb_rip = regval; break;
}
}
diff --git a/sys/amd64/include/gdb_machdep.h b/sys/amd64/include/gdb_machdep.h
index c462ae91809..6a78cb70230 100644
--- a/sys/amd64/include/gdb_machdep.h
+++ b/sys/amd64/include/gdb_machdep.h
@@ -33,6 +33,22 @@
#define GDB_BUFSZ 4096
#define GDB_NREGS 56
+#define GDB_REG_RAX 0
+#define GDB_REG_RBX 1
+#define GDB_REG_RCX 2
+#define GDB_REG_RDX 3
+#define GDB_REG_RSI 4
+#define GDB_REG_RDI 5
+#define GDB_REG_RBP 6
+#define GDB_REG_RSP 7
+#define GDB_REG_R8 8
+#define GDB_REG_R9 9
+#define GDB_REG_R10 10
+#define GDB_REG_R11 11
+#define GDB_REG_R12 12
+#define GDB_REG_R13 13
+#define GDB_REG_R14 14
+#define GDB_REG_R15 15
#define GDB_REG_PC 16
_Static_assert(GDB_BUFSZ >= (GDB_NREGS * 16), "buffer fits 'g' regs");