+2015-03-04 Pedro Alves <palves@redhat.com>
+
+ * btrace.h: Include target/waitstatus.h.
+ (struct btrace_thread_info) <stop_reason>: New field.
+ * record-btrace.c (record_btrace_step_thread): Use
+ record_check_stopped_by_breakpoint instead of breakpoint_here_p.
+ (record_btrace_decr_pc_after_break): Delete.
+ (record_btrace_stopped_by_sw_breakpoint)
+ (record_btrace_supports_stopped_by_sw_breakpoint)
+ (record_btrace_stopped_by_hw_breakpoint)
+ (record_btrace_supports_stopped_by_hw_breakpoint): New functions.
+ (init_record_btrace_ops): Install them.
+ * record-full.c (record_full_hw_watchpoint): Delete and replace
+ with ...
+ (record_full_stop_reason): ... this throughout.
+ (record_full_exec_insn): Adjust.
+ (record_full_wait_1): Adjust. No longer re-increment the PC.
+ (record_full_wait_1): Adjust. Use
+ record_check_stopped_by_breakpoint instead of breakpoint_here_p.
+ (record_full_stopped_by_watchpoint): Adjust.
+ (record_full_stopped_by_sw_breakpoint)
+ (record_full_supports_stopped_by_sw_breakpoint)
+ (record_full_supports_stopped_by_sw_breakpoint)
+ (record_full_stopped_by_hw_breakpoint)
+ (record_full_supports_stopped_by_hw_breakpoint): New functions.
+ (init_record_full_ops, init_record_full_core_ops): Install them.
+ * record.c (record_check_stopped_by_breakpoint): New function.
+ * record.h: Include target/waitstatus.h.
+ (record_check_stopped_by_breakpoint): New declaration.
+
2015-03-04 Pedro Alves <palves@redhat.com>
enum lwp_stop_reason -> enum target_stop_reason
target_pid_to_str (tp->ptid),
core_addr_to_string_nz (insn->pc));
- if (breakpoint_here_p (aspace, insn->pc))
+ if (record_check_stopped_by_breakpoint (aspace, insn->pc,
+ &btinfo->stop_reason))
return btrace_step_stopped ();
}
target_pid_to_str (tp->ptid),
core_addr_to_string_nz (insn->pc));
- if (breakpoint_here_p (aspace, insn->pc))
+ if (record_check_stopped_by_breakpoint (aspace, insn->pc,
+ &btinfo->stop_reason))
return btrace_step_stopped ();
}
}
return 1;
}
-/* The to_decr_pc_after_break method of target record-btrace. */
+/* The to_stopped_by_sw_breakpoint method of target record-btrace. */
-static CORE_ADDR
-record_btrace_decr_pc_after_break (struct target_ops *ops,
- struct gdbarch *gdbarch)
+static int
+record_btrace_stopped_by_sw_breakpoint (struct target_ops *ops)
{
- /* When replaying, we do not actually execute the breakpoint instruction
- so there is no need to adjust the PC after hitting a breakpoint. */
if (record_btrace_is_replaying (ops))
- return 0;
+ {
+ struct thread_info *tp = inferior_thread ();
+
+ return tp->btrace.stop_reason == TARGET_STOPPED_BY_SW_BREAKPOINT;
+ }
+
+ return ops->beneath->to_stopped_by_sw_breakpoint (ops->beneath);
+}
+
+/* The to_supports_stopped_by_sw_breakpoint method of target
+ record-btrace. */
+
+static int
+record_btrace_supports_stopped_by_sw_breakpoint (struct target_ops *ops)
+{
+ if (record_btrace_is_replaying (ops))
+ return 1;
+
+ return ops->beneath->to_supports_stopped_by_sw_breakpoint (ops->beneath);
+}
+
+/* The to_stopped_by_sw_breakpoint method of target record-btrace. */
+
+static int
+record_btrace_stopped_by_hw_breakpoint (struct target_ops *ops)
+{
+ if (record_btrace_is_replaying (ops))
+ {
+ struct thread_info *tp = inferior_thread ();
+
+ return tp->btrace.stop_reason == TARGET_STOPPED_BY_HW_BREAKPOINT;
+ }
+
+ return ops->beneath->to_stopped_by_hw_breakpoint (ops->beneath);
+}
+
+/* The to_supports_stopped_by_hw_breakpoint method of target
+ record-btrace. */
+
+static int
+record_btrace_supports_stopped_by_hw_breakpoint (struct target_ops *ops)
+{
+ if (record_btrace_is_replaying (ops))
+ return 1;
- return ops->beneath->to_decr_pc_after_break (ops->beneath, gdbarch);
+ return ops->beneath->to_supports_stopped_by_hw_breakpoint (ops->beneath);
}
/* The to_update_thread_list method of target record-btrace. */
ops->to_goto_record_end = record_btrace_goto_end;
ops->to_goto_record = record_btrace_goto;
ops->to_can_execute_reverse = record_btrace_can_execute_reverse;
- ops->to_decr_pc_after_break = record_btrace_decr_pc_after_break;
+ ops->to_stopped_by_sw_breakpoint = record_btrace_stopped_by_sw_breakpoint;
+ ops->to_supports_stopped_by_sw_breakpoint
+ = record_btrace_supports_stopped_by_sw_breakpoint;
+ ops->to_stopped_by_hw_breakpoint = record_btrace_stopped_by_hw_breakpoint;
+ ops->to_supports_stopped_by_hw_breakpoint
+ = record_btrace_supports_stopped_by_hw_breakpoint;
ops->to_execution_direction = record_btrace_execution_direction;
ops->to_prepare_to_generate_core = record_btrace_prepare_to_generate_core;
ops->to_done_generating_core = record_btrace_done_generating_core;
}
/* Flag set to TRUE for target_stopped_by_watchpoint. */
-static int record_full_hw_watchpoint = 0;
+static enum target_stop_reason record_full_stop_reason
+ = TARGET_STOPPED_BY_NO_REASON;
/* Execute one instruction from the record log. Each instruction in
the log will be represented by an arbitrary sequence of register
if (hardware_watchpoint_inserted_in_range
(get_regcache_aspace (regcache),
entry->u.mem.addr, entry->u.mem.len))
- record_full_hw_watchpoint = 1;
+ record_full_stop_reason = TARGET_STOPPED_BY_WATCHPOINT;
}
}
}
record_full_get_sig = 0;
signal (SIGINT, record_full_sig_handler);
+ record_full_stop_reason = TARGET_STOPPED_BY_NO_REASON;
+
if (!RECORD_FULL_IS_REPLAY && ops != &record_full_core_ops)
{
if (record_full_resume_step)
{
struct regcache *regcache;
struct address_space *aspace;
+ enum target_stop_reason *stop_reason_p
+ = &record_full_stop_reason;
/* Yes -- this is likely our single-step finishing,
but check if there's any reason the core would be
{
/* Always interested in watchpoints. */
}
- else if (breakpoint_inserted_here_p (aspace, tmp_pc))
+ else if (record_check_stopped_by_breakpoint (aspace, tmp_pc,
+ stop_reason_p))
{
/* There is a breakpoint here. Let the core
handle it. */
- if (software_breakpoint_inserted_here_p (aspace, tmp_pc))
- {
- struct gdbarch *gdbarch
- = get_regcache_arch (regcache);
- CORE_ADDR decr_pc_after_break
- = target_decr_pc_after_break (gdbarch);
- if (decr_pc_after_break)
- regcache_write_pc (regcache,
- tmp_pc + decr_pc_after_break);
- }
}
else
{
= make_cleanup (record_full_wait_cleanups, 0);
CORE_ADDR tmp_pc;
- record_full_hw_watchpoint = 0;
+ record_full_stop_reason = TARGET_STOPPED_BY_NO_REASON;
status->kind = TARGET_WAITKIND_STOPPED;
/* Check breakpoint when forward execute. */
if (execution_direction == EXEC_FORWARD)
{
tmp_pc = regcache_read_pc (regcache);
- if (breakpoint_inserted_here_p (aspace, tmp_pc))
+ if (record_check_stopped_by_breakpoint (aspace, tmp_pc,
+ &record_full_stop_reason))
{
- int decr_pc_after_break = target_decr_pc_after_break (gdbarch);
-
if (record_debug)
fprintf_unfiltered (gdb_stdlog,
"Process record: break at %s.\n",
paddress (gdbarch, tmp_pc));
-
- if (decr_pc_after_break
- && !record_full_resume_step
- && software_breakpoint_inserted_here_p (aspace, tmp_pc))
- regcache_write_pc (regcache,
- tmp_pc + decr_pc_after_break);
goto replay_out;
}
}
/* check breakpoint */
tmp_pc = regcache_read_pc (regcache);
- if (breakpoint_inserted_here_p (aspace, tmp_pc))
+ if (record_check_stopped_by_breakpoint (aspace, tmp_pc,
+ &record_full_stop_reason))
{
- int decr_pc_after_break
- = target_decr_pc_after_break (gdbarch);
-
if (record_debug)
fprintf_unfiltered (gdb_stdlog,
"Process record: break "
"at %s.\n",
paddress (gdbarch, tmp_pc));
- if (decr_pc_after_break
- && execution_direction == EXEC_FORWARD
- && !record_full_resume_step
- && software_breakpoint_inserted_here_p (aspace,
- tmp_pc))
- regcache_write_pc (regcache,
- tmp_pc + decr_pc_after_break);
+
continue_flag = 0;
}
- if (record_full_hw_watchpoint)
+ if (record_full_stop_reason == TARGET_STOPPED_BY_WATCHPOINT)
{
if (record_debug)
fprintf_unfiltered (gdb_stdlog,
record_full_stopped_by_watchpoint (struct target_ops *ops)
{
if (RECORD_FULL_IS_REPLAY)
- return record_full_hw_watchpoint;
+ return record_full_stop_reason == TARGET_STOPPED_BY_WATCHPOINT;
else
return ops->beneath->to_stopped_by_watchpoint (ops->beneath);
}
return ops->beneath->to_stopped_data_address (ops->beneath, addr_p);
}
+/* The to_stopped_by_sw_breakpoint method of target record-full. */
+
+static int
+record_full_stopped_by_sw_breakpoint (struct target_ops *ops)
+{
+ return record_full_stop_reason == TARGET_STOPPED_BY_SW_BREAKPOINT;
+}
+
+/* The to_supports_stopped_by_sw_breakpoint method of target
+ record-full. */
+
+static int
+record_full_supports_stopped_by_sw_breakpoint (struct target_ops *ops)
+{
+ return 1;
+}
+
+/* The to_stopped_by_hw_breakpoint method of target record-full. */
+
+static int
+record_full_stopped_by_hw_breakpoint (struct target_ops *ops)
+{
+ return record_full_stop_reason == TARGET_STOPPED_BY_HW_BREAKPOINT;
+}
+
+/* The to_supports_stopped_by_sw_breakpoint method of target
+ record-full. */
+
+static int
+record_full_supports_stopped_by_hw_breakpoint (struct target_ops *ops)
+{
+ return 1;
+}
+
/* Record registers change (by user or by GDB) to list as an instruction. */
static void
record_full_ops.to_remove_breakpoint = record_full_remove_breakpoint;
record_full_ops.to_stopped_by_watchpoint = record_full_stopped_by_watchpoint;
record_full_ops.to_stopped_data_address = record_full_stopped_data_address;
+ record_full_ops.to_stopped_by_sw_breakpoint
+ = record_full_stopped_by_sw_breakpoint;
+ record_full_ops.to_supports_stopped_by_sw_breakpoint
+ = record_full_supports_stopped_by_sw_breakpoint;
+ record_full_ops.to_stopped_by_hw_breakpoint
+ = record_full_stopped_by_hw_breakpoint;
+ record_full_ops.to_supports_stopped_by_hw_breakpoint
+ = record_full_supports_stopped_by_hw_breakpoint;
record_full_ops.to_can_execute_reverse = record_full_can_execute_reverse;
record_full_ops.to_stratum = record_stratum;
/* Add bookmark target methods. */
= record_full_stopped_by_watchpoint;
record_full_core_ops.to_stopped_data_address
= record_full_stopped_data_address;
+ record_full_core_ops.to_stopped_by_sw_breakpoint
+ = record_full_stopped_by_sw_breakpoint;
+ record_full_core_ops.to_supports_stopped_by_sw_breakpoint
+ = record_full_supports_stopped_by_sw_breakpoint;
+ record_full_core_ops.to_stopped_by_hw_breakpoint
+ = record_full_stopped_by_hw_breakpoint;
+ record_full_core_ops.to_supports_stopped_by_hw_breakpoint
+ = record_full_supports_stopped_by_hw_breakpoint;
record_full_core_ops.to_can_execute_reverse
= record_full_can_execute_reverse;
record_full_core_ops.to_has_execution = record_full_core_has_execution;