struct record_full_entry *rec;
struct gdbarch *gdbarch = get_regcache_arch (regcache);
- rec = xcalloc (1, sizeof (struct record_full_entry));
+ rec = XCNEW (struct record_full_entry);
rec->type = record_full_reg;
rec->u.reg.num = regnum;
rec->u.reg.len = register_size (gdbarch, regnum);
{
struct record_full_entry *rec;
- rec = xcalloc (1, sizeof (struct record_full_entry));
+ rec = XCNEW (struct record_full_entry);
rec->type = record_full_mem;
rec->u.mem.addr = addr;
rec->u.mem.len = len;
{
struct record_full_entry *rec;
- rec = xcalloc (1, sizeof (struct record_full_entry));
+ rec = XCNEW (struct record_full_entry);
rec->type = record_full_end;
return rec;
}
/* 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;
}
}
}
/* "to_async" target method. */
static void
-record_full_async (struct target_ops *ops,
- void (*callback) (enum inferior_event_type event_type,
- void *context),
- void *context)
+record_full_async (struct target_ops *ops, int enable)
{
- if (callback != NULL)
+ if (enable)
mark_async_event_handler (record_full_async_inferior_event_token);
else
clear_async_event_handler (record_full_async_inferior_event_token);
- ops->beneath->to_async (ops->beneath, callback, context);
+ ops->beneath->to_async (ops->beneath, enable);
}
static int record_full_resume_step = 0;
/* We are about to start executing the inferior (or simulate it),
let's register it with the event loop. */
if (target_can_async_p ())
- target_async (inferior_event_handler, 0);
+ target_async (1);
}
static int record_full_get_sig = 0;
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
/* The "to_record_is_replaying" target method. */
static int
-record_full_is_replaying (struct target_ops *self)
+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
registers_changed ();
reinit_frame_cache ();
+ stop_pc = regcache_read_pc (get_current_regcache ());
print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC, 1);
}
record_full_goto_entry (p);
}
+/* The "to_record_stop_replaying" target method. */
+
+static void
+record_full_stop_replaying (struct target_ops *self)
+{
+ record_full_goto_end (self);
+}
+
static void
init_record_full_ops (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_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;
record_full_ops.to_goto_record = record_full_goto;
/* We are about to start executing the inferior (or simulate it),
let's register it with the event loop. */
if (target_can_async_p ())
- target_async (inferior_event_handler, 0);
+ target_async (1);
}
/* "to_kill" method for prec over corefile. */
if (!entry)
{
/* Add a new entry. */
- entry = (struct record_full_core_buf_entry *)
- xmalloc
- (sizeof (struct record_full_core_buf_entry));
+ entry = XNEW (struct record_full_core_buf_entry);
entry->p = p;
if (!bfd_malloc_and_get_section
(p->the_bfd_section->owner,
= 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;
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;
bfdcore_read (core_bfd, osec, &signal,
sizeof (signal), &bfd_offset);
signal = netorder32 (signal);
- rec->u.end.sigval = signal;
+ rec->u.end.sigval = (enum gdb_signal) signal;
/* Get insn count. */
bfdcore_read (core_bfd, osec, &count,