summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJiri Gaisler <jiri@gaisler.se>2019-11-04 22:57:29 +0100
committerJiri Gaisler <jiri@gaisler.se>2019-11-08 22:33:05 +0100
commit88b545002e553f1e21fab1aff854a3e325976ad3 (patch)
tree45aaddcb10ccc2d17706e2fee31d367042bbd2f0
parentRelease version 2.18 (diff)
downloadsis-88b545002e553f1e21fab1aff854a3e325976ad3.tar.bz2
Improve gdb watchpoint handling
* show old/new values * stop at correct instruction
-rw-r--r--func.c2
-rw-r--r--remote.c12
-rw-r--r--riscv.c20
-rw-r--r--sis.h1
-rw-r--r--sparc.c13
5 files changed, 40 insertions, 8 deletions
diff --git a/func.c b/func.c
index d63c511..8fd004f 100644
--- a/func.c
+++ b/func.c
@@ -1092,6 +1092,7 @@ check_wpr (struct pstate *sregs, int32 address, unsigned char mask)
ebase.wpaddress = address;
if (ebase.wphit)
return (0);
+ ebase.wptype = 3;
return (WPT_HIT);
}
}
@@ -1111,6 +1112,7 @@ check_wpw (struct pstate *sregs, int32 address, unsigned char mask)
ebase.wpaddress = ebase.wpws[i];
if (ebase.wphit)
return (0);
+ ebase.wptype = 2;
return (WPT_HIT);
}
}
diff --git a/remote.c b/remote.c
index 95e1a32..2587750 100644
--- a/remote.c
+++ b/remote.c
@@ -288,12 +288,14 @@ gdb_remote_exec (char *buf)
case 'c':
sim_resume (0);
i = sim_stat ();
- /* The T watch response does not seem to work with sparc/gdb, disable ...
- if ((i == SIGTRAP) && ebase.wphit)
- sprintf (txbuf, "T%02xwatch:%x;", i, ebase.wpaddress);
- else
- */
sprintf (txbuf, "S%02x", i);
+ if ((i == SIGTRAP) && ebase.wphit)
+ {
+ if (ebase.wptype == 2)
+ sprintf (txbuf, "T%02xwatch:%x;", i, ebase.wpaddress);
+ else if (ebase.wptype == 3)
+ sprintf (txbuf, "T%02xrwatch:%x;", i, ebase.wpaddress);
+ }
break;
case 'k': /* kill */
case 'R': /* restart */
diff --git a/riscv.c b/riscv.c
index 450283d..7498fce 100644
--- a/riscv.c
+++ b/riscv.c
@@ -870,6 +870,13 @@ riscv_dispatch_instruction (sregs)
break;
case OP_STORE: /* store instructions */
+ /* skip store if we resume after a write watchpoint */
+ if (sis_gdb_break && ebase.wphit)
+ {
+ ebase.wphit = 0;
+ break;
+ }
+
#if defined(STAT) || defined(ENABLE_L1CACHE)
sregs->nstore++;
#endif
@@ -882,7 +889,10 @@ riscv_dispatch_instruction (sregs)
if ((ebase.wphit = check_wpw (sregs, address, funct3 & 3)))
{
sregs->trap = WPT_TRAP;
- break;
+ /* gdb seems to expect that the write goes trough when the
+ * watchpoint is hit, but PC stays on the store instruction */
+ if (!sis_gdb_break)
+ break;
}
}
@@ -940,6 +950,11 @@ riscv_dispatch_instruction (sregs)
break;
case OP_FSW: /* F store instructions */
+ if (sis_gdb_break && ebase.wphit)
+ {
+ ebase.wphit = 0;
+ break;
+ }
#if defined(STAT) || defined(ENABLE_L1CACHE)
sregs->nstore++;
#endif
@@ -952,7 +967,8 @@ riscv_dispatch_instruction (sregs)
if ((ebase.wphit = check_wpw (sregs, address, funct3 & 3)))
{
sregs->trap = WPT_TRAP;
- break;
+ if (!sis_gdb_break)
+ break;
}
}
diff --git a/sis.h b/sis.h
index 493afbb..4e12686 100644
--- a/sis.h
+++ b/sis.h
@@ -207,6 +207,7 @@ struct estate
uint32 bpsave[BPT_MAX]; /* Saved opcode */
uint32 wprnum;
uint32 wphit;
+ uint32 wptype;
uint32 wprs[WPR_MAX]; /* Read Watchpoints */
unsigned char wprm[WPR_MAX]; /* Read Watchpoint masks */
uint32 wpwnum;
diff --git a/sparc.c b/sparc.c
index db40e8d..a06aa6b 100644
--- a/sparc.c
+++ b/sparc.c
@@ -961,12 +961,23 @@ sparc_dispatch_instruction (sregs)
if (op3 & 4)
{
sregs->icnt = T_ST; /* Set store instruction count */
+
+ /* skip store if we resume after a write watchpoint */
+ if (sis_gdb_break && ebase.wphit)
+ {
+ ebase.wphit = 0;
+ break;
+ }
+
if (ebase.wpwnum)
{
if ((ebase.wphit = check_wpw (sregs, address, wpmask (op3))))
{
sregs->trap = WPT_TRAP;
- break;
+ /* gdb seems to expect that the write goes trough when the
+ * watchpoint is hit, but PC stays on the store instruction */
+ if (!sis_gdb_break)
+ break;
}
}
#if defined(STAT) || defined(ENABLE_L1CACHE)