gdb server: new feature, add stop reason in stop reply packet for gdb

In GDB remote serial protocol, the stop reply packet could contain more
detail stop reason. The currently defined stop reasons are listed below.

* watch
* rwatch
* awatch
* library
* replaylog

This commit adds stop reason, watch/rwatch/awatch, in stop reply packet for
just hit watchpoint. As manual indicates, at most one stop reason should be present.

The function needs target to implement new hook, hit_watchpoint. The hook will fill
the hit watchpoint in second parameter. The information will assist gdb to locate
the watchpoint. If no such information, gdb needs to scan all watchpoints by itself.

Refer to GDB Manual, D.3 Stop Reply Packets

Change-Id: I1f70a1a9cc772e88e641b6171f1a009629a43bd1
Signed-off-by: Hsiangkai Wang <hsiangkai@gmail.com>
Reviewed-on: http://openocd.zylin.com/1092
Tested-by: jenkins
Reviewed-by: Spencer Oliver <spen@spen-soft.co.uk>
This commit is contained in:
Hsiangkai Wang
2012-12-26 19:11:03 +08:00
committed by Spencer Oliver
parent d979d78e97
commit 80d412bafc
10 changed files with 163 additions and 3 deletions

View File

@@ -705,7 +705,9 @@ static void gdb_frontend_halted(struct target *target, struct connection *connec
* that are to be ignored.
*/
if (gdb_connection->frontend_state == TARGET_RUNNING) {
char sig_reply[4];
char sig_reply[20];
char stop_reason[20];
int sig_reply_len;
int signal_var;
/* stop forwarding log packets! */
@@ -717,8 +719,36 @@ static void gdb_frontend_halted(struct target *target, struct connection *connec
} else
signal_var = gdb_last_signal(target);
snprintf(sig_reply, 4, "T%2.2x", signal_var);
gdb_put_packet(connection, sig_reply, 3);
stop_reason[0] = '\0';
if (target->debug_reason == DBG_REASON_WATCHPOINT) {
enum watchpoint_rw hit_wp_type;
uint32_t hit_wp_address;
if (watchpoint_hit(target, &hit_wp_type, &hit_wp_address) == ERROR_OK) {
switch (hit_wp_type) {
case WPT_WRITE:
snprintf(stop_reason, sizeof(stop_reason),
"watch:%08x;", hit_wp_address);
break;
case WPT_READ:
snprintf(stop_reason, sizeof(stop_reason),
"rwatch:%08x;", hit_wp_address);
break;
case WPT_ACCESS:
snprintf(stop_reason, sizeof(stop_reason),
"awatch:%08x;", hit_wp_address);
break;
default:
break;
}
}
}
sig_reply_len = snprintf(sig_reply, sizeof(sig_reply), "T%2.2x%s",
signal_var, stop_reason);
gdb_put_packet(connection, sig_reply, sig_reply_len);
gdb_connection->frontend_state = TARGET_HALTED;
rtos_update_threads(target);
}