From c106bd9120d0e0d75dc9a28f87686d6b6d18ae8c Mon Sep 17 00:00:00 2001 From: marcel Date: Wed, 1 Dec 2004 06:40:35 +0000 Subject: 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/gdb/gdb_main.c | 34 ++++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) (limited to 'sys/gdb') diff --git a/sys/gdb/gdb_main.c b/sys/gdb/gdb_main.c index 0eed036..bed693a 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); } -- cgit v1.1