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
This commit is contained in:
parent
ba1c3b5304
commit
bcc5241c43
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=138253
@ -59,7 +59,7 @@ gdb_cpu_getreg(int regnum, size_t *regsz)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
gdb_cpu_setreg(int regnum, register_t val)
|
gdb_cpu_setreg(int regnum, void *val)
|
||||||
{
|
{
|
||||||
switch (regnum) {
|
switch (regnum) {
|
||||||
}
|
}
|
||||||
|
@ -46,7 +46,7 @@ gdb_cpu_query(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void *gdb_cpu_getreg(int, size_t *);
|
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_signal(int, int);
|
||||||
|
|
||||||
#endif /* !_MACHINE_GDB_MACHDEP_H_ */
|
#endif /* !_MACHINE_GDB_MACHDEP_H_ */
|
||||||
|
@ -81,14 +81,13 @@ gdb_cpu_getreg(int regnum, size_t *regsz)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
gdb_cpu_setreg(int regnum, register_t val)
|
gdb_cpu_setreg(int regnum, void *val)
|
||||||
{
|
{
|
||||||
|
|
||||||
val = __bswap64(val);
|
|
||||||
switch (regnum) {
|
switch (regnum) {
|
||||||
case GDB_REG_PC:
|
case GDB_REG_PC:
|
||||||
kdb_thrctx->pcb_rip = val;
|
kdb_thrctx->pcb_rip = *(register_t *)val;
|
||||||
if (kdb_thread == curthread)
|
if (kdb_thread == curthread)
|
||||||
kdb_frame->tf_rip = val;
|
kdb_frame->tf_rip = *(register_t *)val;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -52,6 +52,6 @@ gdb_cpu_query(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void *gdb_cpu_getreg(int, size_t *);
|
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_ */
|
#endif /* !_MACHINE_GDB_MACHDEP_H_ */
|
||||||
|
@ -120,16 +120,22 @@ gdb_trap(int type, int code)
|
|||||||
break;
|
break;
|
||||||
case 'c': { /* Continue. */
|
case 'c': { /* Continue. */
|
||||||
uintmax_t addr;
|
uintmax_t addr;
|
||||||
if (!gdb_rx_varhex(&addr))
|
register_t pc;
|
||||||
gdb_cpu_setreg(GDB_REG_PC, addr);
|
if (!gdb_rx_varhex(&addr)) {
|
||||||
|
pc = addr;
|
||||||
|
gdb_cpu_setreg(GDB_REG_PC, &pc);
|
||||||
|
}
|
||||||
kdb_cpu_clear_singlestep();
|
kdb_cpu_clear_singlestep();
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
case 'C': { /* Continue with signal. */
|
case 'C': { /* Continue with signal. */
|
||||||
uintmax_t addr, sig;
|
uintmax_t addr, sig;
|
||||||
|
register_t pc;
|
||||||
if (!gdb_rx_varhex(&sig) && gdb_rx_char() == ';' &&
|
if (!gdb_rx_varhex(&sig) && gdb_rx_char() == ';' &&
|
||||||
!gdb_rx_varhex(&addr))
|
!gdb_rx_varhex(&addr)) {
|
||||||
gdb_cpu_setreg(GDB_REG_PC, addr);
|
pc = addr;
|
||||||
|
gdb_cpu_setreg(GDB_REG_PC, &pc);
|
||||||
|
}
|
||||||
kdb_cpu_clear_singlestep();
|
kdb_cpu_clear_singlestep();
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
@ -191,9 +197,11 @@ gdb_trap(int type, int code)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'P': { /* Write register. */
|
case 'P': { /* Write register. */
|
||||||
uintmax_t reg, val;
|
char *val;
|
||||||
|
uintmax_t reg;
|
||||||
|
val = gdb_rxp;
|
||||||
if (gdb_rx_varhex(®) || gdb_rx_char() != '=' ||
|
if (gdb_rx_varhex(®) || gdb_rx_char() != '=' ||
|
||||||
gdb_rx_varhex(&val)) {
|
!gdb_rx_mem(val, gdb_cpu_regsz(reg))) {
|
||||||
gdb_tx_err(EINVAL);
|
gdb_tx_err(EINVAL);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -226,16 +234,22 @@ gdb_trap(int type, int code)
|
|||||||
break;
|
break;
|
||||||
case 's': { /* Step. */
|
case 's': { /* Step. */
|
||||||
uintmax_t addr;
|
uintmax_t addr;
|
||||||
if (!gdb_rx_varhex(&addr))
|
register_t pc;
|
||||||
gdb_cpu_setreg(GDB_REG_PC, addr);
|
if (!gdb_rx_varhex(&addr)) {
|
||||||
|
pc = addr;
|
||||||
|
gdb_cpu_setreg(GDB_REG_PC, &pc);
|
||||||
|
}
|
||||||
kdb_cpu_set_singlestep();
|
kdb_cpu_set_singlestep();
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
case 'S': { /* Step with signal. */
|
case 'S': { /* Step with signal. */
|
||||||
uintmax_t addr, sig;
|
uintmax_t addr, sig;
|
||||||
|
register_t pc;
|
||||||
if (!gdb_rx_varhex(&sig) && gdb_rx_char() == ';' &&
|
if (!gdb_rx_varhex(&sig) && gdb_rx_char() == ';' &&
|
||||||
!gdb_rx_varhex(&addr))
|
!gdb_rx_varhex(&addr)) {
|
||||||
gdb_cpu_setreg(GDB_REG_PC, addr);
|
pc = addr;
|
||||||
|
gdb_cpu_setreg(GDB_REG_PC, &pc);
|
||||||
|
}
|
||||||
kdb_cpu_set_singlestep();
|
kdb_cpu_set_singlestep();
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
@ -67,15 +67,14 @@ gdb_cpu_getreg(int regnum, size_t *regsz)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
gdb_cpu_setreg(int regnum, register_t val)
|
gdb_cpu_setreg(int regnum, void *val)
|
||||||
{
|
{
|
||||||
|
|
||||||
val = __bswap32(val);
|
|
||||||
switch (regnum) {
|
switch (regnum) {
|
||||||
case GDB_REG_PC:
|
case GDB_REG_PC:
|
||||||
kdb_thrctx->pcb_eip = val;
|
kdb_thrctx->pcb_eip = *(register_t *)val;
|
||||||
if (kdb_thread == curthread)
|
if (kdb_thread == curthread)
|
||||||
kdb_frame->tf_eip = val;
|
kdb_frame->tf_eip = *(register_t *)val;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ gdb_cpu_query(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void *gdb_cpu_getreg(int, size_t *);
|
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_signal(int, int);
|
||||||
|
|
||||||
#endif /* !_MACHINE_GDB_MACHDEP_H_ */
|
#endif /* !_MACHINE_GDB_MACHDEP_H_ */
|
||||||
|
@ -128,7 +128,7 @@ gdb_cpu_getreg(int regnum, size_t *regsz)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
gdb_cpu_setreg(int regnum, register_t val)
|
gdb_cpu_setreg(int regnum, void *val)
|
||||||
{
|
{
|
||||||
|
|
||||||
switch (regnum) {
|
switch (regnum) {
|
||||||
|
@ -41,7 +41,7 @@ gdb_cpu_regsz(int regnum)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void *gdb_cpu_getreg(int, size_t *);
|
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_signal(int, int);
|
||||||
int gdb_cpu_query(void);
|
int gdb_cpu_query(void);
|
||||||
|
|
||||||
|
@ -52,6 +52,6 @@ gdb_cpu_signal(int vector, int _)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void *gdb_cpu_getreg(int, size_t *);
|
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_ */
|
#endif /* !_MACHINE_GDB_MACHDEP_H_ */
|
||||||
|
@ -63,7 +63,7 @@ gdb_cpu_getreg(int regnum, size_t *regsz)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
gdb_cpu_setreg(int regnum, register_t val)
|
gdb_cpu_setreg(int regnum, void *val)
|
||||||
{
|
{
|
||||||
switch (regnum) {
|
switch (regnum) {
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user