From 7ff27e9babb1564a9c0e213c4a42396aa420f8cc Mon Sep 17 00:00:00 2001 From: Markus Metzger Date: Thu, 17 Sep 2015 11:14:55 +0200 Subject: [PATCH] target: add to_record_will_replay target method Add a new target method to_record_will_replay to query if there is a record target that will replay at least one thread matching the argument PTID if it were executed in the argument execution direction. gdb/ * record-btrace.c ((record_btrace_will_replay): New. (init_record_btrace_ops): Initialize to_record_will_replay. * record-full.c ((record_full_will_replay): New. (init_record_full_ops): Initialize to_record_will_replay. * target-delegates.c: Regenerated. * target.c (target_record_will_replay): New. * target.h (struct target_ops) : New. (target_record_will_replay): New. Signed-off-by: Markus Metzger --- gdb/ChangeLog | 11 +++++++++++ gdb/record-btrace.c | 9 +++++++++ gdb/record-full.c | 14 ++++++++++++++ gdb/target-delegates.c | 35 +++++++++++++++++++++++++++++++++++ gdb/target.c | 8 ++++++++ gdb/target.h | 8 ++++++++ 6 files changed, 85 insertions(+) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 24ae06a96ff..a2bd8434049 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,14 @@ +2015-09-18 Markus Metzger + + * record-btrace.c ((record_btrace_will_replay): New. + (init_record_btrace_ops): Initialize to_record_will_replay. + * record-full.c ((record_full_will_replay): New. + (init_record_full_ops): Initialize to_record_will_replay. + * target-delegates.c: Regenerated. + * target.c (target_record_will_replay): New. + * target.h (struct target_ops) : New. + (target_record_will_replay): New. + 2015-09-18 Markus Metzger * record-btrace.c (record_btrace_resume): Call diff --git a/gdb/record-btrace.c b/gdb/record-btrace.c index e0b79a88287..df15d7770fc 100644 --- a/gdb/record-btrace.c +++ b/gdb/record-btrace.c @@ -1147,6 +1147,14 @@ record_btrace_is_replaying (struct target_ops *self, ptid_t ptid) return 0; } +/* The to_record_will_replay method of target record-btrace. */ + +static int +record_btrace_will_replay (struct target_ops *self, ptid_t ptid, int dir) +{ + return dir == EXEC_REVERSE || record_btrace_is_replaying (self, ptid); +} + /* The to_xfer_partial method of target record-btrace. */ static enum target_xfer_status @@ -2657,6 +2665,7 @@ init_record_btrace_ops (void) ops->to_call_history_from = record_btrace_call_history_from; ops->to_call_history_range = record_btrace_call_history_range; ops->to_record_is_replaying = record_btrace_is_replaying; + ops->to_record_will_replay = record_btrace_will_replay; ops->to_record_stop_replaying = record_btrace_stop_replaying_all; ops->to_xfer_partial = record_btrace_xfer_partial; ops->to_remove_breakpoint = record_btrace_remove_breakpoint; diff --git a/gdb/record-full.c b/gdb/record-full.c index 35b384115e9..cb05437784e 100644 --- a/gdb/record-full.c +++ b/gdb/record-full.c @@ -1845,6 +1845,18 @@ record_full_is_replaying (struct target_ops *self, ptid_t ptid) return RECORD_FULL_IS_REPLAY; } +/* The "to_record_will_replay" target method. */ + +static int +record_full_will_replay (struct target_ops *self, ptid_t ptid, int dir) +{ + /* We can currently only record when executing forwards. Should we be able + to record when executing backwards on targets that support reverse + execution, this needs to be changed. */ + + return RECORD_FULL_IS_REPLAY || dir == EXEC_REVERSE; +} + /* Go to a specific entry. */ static void @@ -1965,6 +1977,7 @@ init_record_full_ops (void) record_full_ops.to_save_record = record_full_save; record_full_ops.to_delete_record = record_full_delete; record_full_ops.to_record_is_replaying = record_full_is_replaying; + record_full_ops.to_record_will_replay = record_full_will_replay; record_full_ops.to_record_stop_replaying = record_full_stop_replaying; record_full_ops.to_goto_record_begin = record_full_goto_begin; record_full_ops.to_goto_record_end = record_full_goto_end; @@ -2212,6 +2225,7 @@ init_record_full_core_ops (void) record_full_core_ops.to_info_record = record_full_info; record_full_core_ops.to_delete_record = record_full_delete; record_full_core_ops.to_record_is_replaying = record_full_is_replaying; + record_full_core_ops.to_record_will_replay = record_full_will_replay; record_full_core_ops.to_goto_record_begin = record_full_goto_begin; record_full_core_ops.to_goto_record_end = record_full_goto_end; record_full_core_ops.to_goto_record = record_full_goto; diff --git a/gdb/target-delegates.c b/gdb/target-delegates.c index a07c8c9df25..a7271fa943a 100644 --- a/gdb/target-delegates.c +++ b/gdb/target-delegates.c @@ -3630,6 +3630,37 @@ debug_record_is_replaying (struct target_ops *self, ptid_t arg1) return result; } +static int +delegate_record_will_replay (struct target_ops *self, ptid_t arg1, int arg2) +{ + self = self->beneath; + return self->to_record_will_replay (self, arg1, arg2); +} + +static int +tdefault_record_will_replay (struct target_ops *self, ptid_t arg1, int arg2) +{ + return 0; +} + +static int +debug_record_will_replay (struct target_ops *self, ptid_t arg1, int arg2) +{ + int result; + fprintf_unfiltered (gdb_stdlog, "-> %s->to_record_will_replay (...)\n", debug_target.to_shortname); + result = debug_target.to_record_will_replay (&debug_target, arg1, arg2); + fprintf_unfiltered (gdb_stdlog, "<- %s->to_record_will_replay (", debug_target.to_shortname); + target_debug_print_struct_target_ops_p (&debug_target); + fputs_unfiltered (", ", gdb_stdlog); + target_debug_print_ptid_t (arg1); + fputs_unfiltered (", ", gdb_stdlog); + target_debug_print_int (arg2); + fputs_unfiltered (") = ", gdb_stdlog); + target_debug_print_int (result); + fputs_unfiltered ("\n", gdb_stdlog); + return result; +} + static void delegate_record_stop_replaying (struct target_ops *self) { @@ -4289,6 +4320,8 @@ install_delegators (struct target_ops *ops) ops->to_delete_record = delegate_delete_record; if (ops->to_record_is_replaying == NULL) ops->to_record_is_replaying = delegate_record_is_replaying; + if (ops->to_record_will_replay == NULL) + ops->to_record_will_replay = delegate_record_will_replay; if (ops->to_record_stop_replaying == NULL) ops->to_record_stop_replaying = delegate_record_stop_replaying; if (ops->to_goto_record_begin == NULL) @@ -4458,6 +4491,7 @@ install_dummy_methods (struct target_ops *ops) ops->to_save_record = tdefault_save_record; ops->to_delete_record = tdefault_delete_record; ops->to_record_is_replaying = tdefault_record_is_replaying; + ops->to_record_will_replay = tdefault_record_will_replay; ops->to_record_stop_replaying = tdefault_record_stop_replaying; ops->to_goto_record_begin = tdefault_goto_record_begin; ops->to_goto_record_end = tdefault_goto_record_end; @@ -4612,6 +4646,7 @@ init_debug_target (struct target_ops *ops) ops->to_save_record = debug_save_record; ops->to_delete_record = debug_delete_record; ops->to_record_is_replaying = debug_record_is_replaying; + ops->to_record_will_replay = debug_record_will_replay; ops->to_record_stop_replaying = debug_record_stop_replaying; ops->to_goto_record_begin = debug_goto_record_begin; ops->to_goto_record_end = debug_goto_record_end; diff --git a/gdb/target.c b/gdb/target.c index f73067c61a3..8df862ba3f8 100644 --- a/gdb/target.c +++ b/gdb/target.c @@ -3663,6 +3663,14 @@ target_record_is_replaying (ptid_t ptid) /* See target.h. */ +int +target_record_will_replay (ptid_t ptid, int dir) +{ + return current_target.to_record_will_replay (¤t_target, ptid, dir); +} + +/* See target.h. */ + void target_record_stop_replaying (void) { diff --git a/gdb/target.h b/gdb/target.h index 169785dfe26..2b2db4599ce 100644 --- a/gdb/target.h +++ b/gdb/target.h @@ -1157,6 +1157,11 @@ struct target_ops int (*to_record_is_replaying) (struct target_ops *, ptid_t ptid) TARGET_DEFAULT_RETURN (0); + /* Query if the record target will replay PTID if it were resumed in + execution direction DIR. */ + int (*to_record_will_replay) (struct target_ops *, ptid_t ptid, int dir) + TARGET_DEFAULT_RETURN (0); + /* Stop replaying. */ void (*to_record_stop_replaying) (struct target_ops *) TARGET_DEFAULT_IGNORE (); @@ -2446,6 +2451,9 @@ extern void target_delete_record (void); /* See to_record_is_replaying in struct target_ops. */ extern int target_record_is_replaying (ptid_t ptid); +/* See to_record_will_replay in struct target_ops. */ +extern int target_record_will_replay (ptid_t ptid, int dir); + /* See to_record_stop_replaying in struct target_ops. */ extern void target_record_stop_replaying (void); -- 2.30.2