From bcc5241c43307d18ef4cb61b4f98eb624d31367d Mon Sep 17 00:00:00 2001 From: Marcel Moolenaar Date: Wed, 1 Dec 2004 06:40:35 +0000 Subject: [PATCH] Change gdb_cpu_setreg() to not take the value to which to set the specified register, but a pointer to the in-memory representation of that value. The reason for this is twofold: 1. Not all registers can be represented by a register_t. In particular FP registers fall in that category. Passing the new register value by reference instead of by value makes this point moot. 2. When we receive a G or P packet, both are for writing a register, the packet will have the register value in target-byte order and in the memory representation (modulo the fact that bytes are sent as 2 printable hexadecimal numbers of course). We only need to decode the packet to have a pointer to the register value. This change fixes the bug of extracting the register value of the P packet as a hexadecimal number instead of as a bit array. The quick (and dirty) fix to bswap the register value in gdb_cpu_setreg() as it has been added on i386 and amd64 can therefore be removed and has in fact been that. Tested on: alpha, amd64, i386, ia64, sparc64 --- sys/alpha/alpha/gdb_machdep.c | 2 +- sys/alpha/include/gdb_machdep.h | 2 +- sys/amd64/amd64/gdb_machdep.c | 7 +++---- sys/amd64/include/gdb_machdep.h | 2 +- sys/gdb/gdb_main.c | 34 ++++++++++++++++++++++--------- sys/i386/i386/gdb_machdep.c | 7 +++---- sys/i386/include/gdb_machdep.h | 2 +- sys/ia64/ia64/gdb_machdep.c | 2 +- sys/ia64/include/gdb_machdep.h | 2 +- sys/sparc64/include/gdb_machdep.h | 2 +- sys/sparc64/sparc64/gdb_machdep.c | 2 +- 11 files changed, 38 insertions(+), 26 deletions(-) diff --git a/sys/alpha/alpha/gdb_machdep.c b/sys/alpha/alpha/gdb_machdep.c index cbc38a8a9caf..a701c6f0749e 100644 --- a/sys/alpha/alpha/gdb_machdep.c +++ b/sys/alpha/alpha/gdb_machdep.c @@ -59,7 +59,7 @@ gdb_cpu_getreg(int regnum, size_t *regsz) } void -gdb_cpu_setreg(int regnum, register_t val) +gdb_cpu_setreg(int regnum, void *val) { switch (regnum) { } diff --git a/sys/alpha/include/gdb_machdep.h b/sys/alpha/include/gdb_machdep.h index 5ca5d69f5890..c404c739efb1 100644 --- a/sys/alpha/include/gdb_machdep.h +++ b/sys/alpha/include/gdb_machdep.h @@ -46,7 +46,7 @@ gdb_cpu_query(void) } void *gdb_cpu_getreg(int, size_t *); -void gdb_cpu_setreg(int, register_t); +void gdb_cpu_setreg(int, void *); int gdb_cpu_signal(int, int); #endif /* !_MACHINE_GDB_MACHDEP_H_ */ diff --git a/sys/amd64/amd64/gdb_machdep.c b/sys/amd64/amd64/gdb_machdep.c index 770e9038e4e9..ea1c3eff10d1 100644 --- a/sys/amd64/amd64/gdb_machdep.c +++ b/sys/amd64/amd64/gdb_machdep.c @@ -81,14 +81,13 @@ gdb_cpu_getreg(int regnum, size_t *regsz) } void -gdb_cpu_setreg(int regnum, register_t val) +gdb_cpu_setreg(int regnum, void *val) { - val = __bswap64(val); switch (regnum) { case GDB_REG_PC: - kdb_thrctx->pcb_rip = val; + kdb_thrctx->pcb_rip = *(register_t *)val; if (kdb_thread == curthread) - kdb_frame->tf_rip = val; + kdb_frame->tf_rip = *(register_t *)val; } } diff --git a/sys/amd64/include/gdb_machdep.h b/sys/amd64/include/gdb_machdep.h index 458f2f6eb9b5..c2fd8bf198d1 100644 --- a/sys/amd64/include/gdb_machdep.h +++ b/sys/amd64/include/gdb_machdep.h @@ -52,6 +52,6 @@ gdb_cpu_query(void) } void *gdb_cpu_getreg(int, size_t *); -void gdb_cpu_setreg(int, register_t); +void gdb_cpu_setreg(int, void *); #endif /* !_MACHINE_GDB_MACHDEP_H_ */ diff --git a/sys/gdb/gdb_main.c b/sys/gdb/gdb_main.c index 0eed036aa9ce..bed693af3082 100644 --- a/sys/gdb/gdb_main.c +++ b/sys/gdb/gdb_main.c @@ -120,16 +120,22 @@ gdb_trap(int type, int code) break; case 'c': { /* Continue. */ uintmax_t addr; - if (!gdb_rx_varhex(&addr)) - gdb_cpu_setreg(GDB_REG_PC, addr); + register_t pc; + if (!gdb_rx_varhex(&addr)) { + pc = addr; + gdb_cpu_setreg(GDB_REG_PC, &pc); + } kdb_cpu_clear_singlestep(); return (1); } case 'C': { /* Continue with signal. */ uintmax_t addr, sig; + register_t pc; if (!gdb_rx_varhex(&sig) && gdb_rx_char() == ';' && - !gdb_rx_varhex(&addr)) - gdb_cpu_setreg(GDB_REG_PC, addr); + !gdb_rx_varhex(&addr)) { + pc = addr; + gdb_cpu_setreg(GDB_REG_PC, &pc); + } kdb_cpu_clear_singlestep(); return (1); } @@ -191,9 +197,11 @@ gdb_trap(int type, int code) break; } case 'P': { /* Write register. */ - uintmax_t reg, val; + char *val; + uintmax_t reg; + val = gdb_rxp; if (gdb_rx_varhex(®) || gdb_rx_char() != '=' || - gdb_rx_varhex(&val)) { + !gdb_rx_mem(val, gdb_cpu_regsz(reg))) { gdb_tx_err(EINVAL); break; } @@ -226,16 +234,22 @@ gdb_trap(int type, int code) break; case 's': { /* Step. */ uintmax_t addr; - if (!gdb_rx_varhex(&addr)) - gdb_cpu_setreg(GDB_REG_PC, addr); + register_t pc; + if (!gdb_rx_varhex(&addr)) { + pc = addr; + gdb_cpu_setreg(GDB_REG_PC, &pc); + } kdb_cpu_set_singlestep(); return (1); } case 'S': { /* Step with signal. */ uintmax_t addr, sig; + register_t pc; if (!gdb_rx_varhex(&sig) && gdb_rx_char() == ';' && - !gdb_rx_varhex(&addr)) - gdb_cpu_setreg(GDB_REG_PC, addr); + !gdb_rx_varhex(&addr)) { + pc = addr; + gdb_cpu_setreg(GDB_REG_PC, &pc); + } kdb_cpu_set_singlestep(); return (1); } diff --git a/sys/i386/i386/gdb_machdep.c b/sys/i386/i386/gdb_machdep.c index 836b13e73b89..042b1041c811 100644 --- a/sys/i386/i386/gdb_machdep.c +++ b/sys/i386/i386/gdb_machdep.c @@ -67,15 +67,14 @@ gdb_cpu_getreg(int regnum, size_t *regsz) } void -gdb_cpu_setreg(int regnum, register_t val) +gdb_cpu_setreg(int regnum, void *val) { - val = __bswap32(val); switch (regnum) { case GDB_REG_PC: - kdb_thrctx->pcb_eip = val; + kdb_thrctx->pcb_eip = *(register_t *)val; if (kdb_thread == curthread) - kdb_frame->tf_eip = val; + kdb_frame->tf_eip = *(register_t *)val; } } diff --git a/sys/i386/include/gdb_machdep.h b/sys/i386/include/gdb_machdep.h index c67412a292ff..3b426a1e69cc 100644 --- a/sys/i386/include/gdb_machdep.h +++ b/sys/i386/include/gdb_machdep.h @@ -46,7 +46,7 @@ gdb_cpu_query(void) } void *gdb_cpu_getreg(int, size_t *); -void gdb_cpu_setreg(int, register_t); +void gdb_cpu_setreg(int, void *); int gdb_cpu_signal(int, int); #endif /* !_MACHINE_GDB_MACHDEP_H_ */ diff --git a/sys/ia64/ia64/gdb_machdep.c b/sys/ia64/ia64/gdb_machdep.c index 62b475577832..7729d71fbae4 100644 --- a/sys/ia64/ia64/gdb_machdep.c +++ b/sys/ia64/ia64/gdb_machdep.c @@ -128,7 +128,7 @@ gdb_cpu_getreg(int regnum, size_t *regsz) } void -gdb_cpu_setreg(int regnum, register_t val) +gdb_cpu_setreg(int regnum, void *val) { switch (regnum) { diff --git a/sys/ia64/include/gdb_machdep.h b/sys/ia64/include/gdb_machdep.h index 1b957fb8560d..b6294d7ab00e 100644 --- a/sys/ia64/include/gdb_machdep.h +++ b/sys/ia64/include/gdb_machdep.h @@ -41,7 +41,7 @@ gdb_cpu_regsz(int regnum) } void *gdb_cpu_getreg(int, size_t *); -void gdb_cpu_setreg(int, register_t); +void gdb_cpu_setreg(int, void *); int gdb_cpu_signal(int, int); int gdb_cpu_query(void); diff --git a/sys/sparc64/include/gdb_machdep.h b/sys/sparc64/include/gdb_machdep.h index b30ad04b634a..27fbe46c7e1a 100644 --- a/sys/sparc64/include/gdb_machdep.h +++ b/sys/sparc64/include/gdb_machdep.h @@ -52,6 +52,6 @@ gdb_cpu_signal(int vector, int _) } void *gdb_cpu_getreg(int, size_t *); -void gdb_cpu_setreg(int, register_t); +void gdb_cpu_setreg(int, void *); #endif /* !_MACHINE_GDB_MACHDEP_H_ */ diff --git a/sys/sparc64/sparc64/gdb_machdep.c b/sys/sparc64/sparc64/gdb_machdep.c index 219ac13ffdb2..4a3d2e67fe02 100644 --- a/sys/sparc64/sparc64/gdb_machdep.c +++ b/sys/sparc64/sparc64/gdb_machdep.c @@ -63,7 +63,7 @@ gdb_cpu_getreg(int regnum, size_t *regsz) } void -gdb_cpu_setreg(int regnum, register_t val) +gdb_cpu_setreg(int regnum, void *val) { switch (regnum) { }