/* Process record and replay target for GDB, the GNU debugger.
- Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc.
+ Copyright (C) 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
This file is part of GDB.
return rec->u.reg.u.buf;
case record_end:
default:
- gdb_assert (0);
+ gdb_assert_not_reached ("unexpected record_entry type");
return NULL;
}
}
"record list.\n",
paddress (target_gdbarch, addr), len);
- if (!addr) /* FIXME: Why? Some arch must permit it... */
+ if (!addr) /* FIXME: Why? Some arch must permit it... */
return 0;
rec = record_mem_alloc (addr, len);
if (!tmp_to_wait)
error (_("Could not find 'to_wait' method on the target stack."));
if (!tmp_to_store_registers)
- error (_("Could not find 'to_store_registers' method on the target stack."));
+ error (_("Could not find 'to_store_registers' "
+ "method on the target stack."));
if (!tmp_to_insert_breakpoint)
- error (_("Could not find 'to_insert_breakpoint' method on the target stack."));
+ error (_("Could not find 'to_insert_breakpoint' "
+ "method on the target stack."));
if (!tmp_to_remove_breakpoint)
- error (_("Could not find 'to_remove_breakpoint' method on the target stack."));
+ error (_("Could not find 'to_remove_breakpoint' "
+ "method on the target stack."));
if (!tmp_to_stopped_by_watchpoint)
- error (_("Could not find 'to_stopped_by_watchpoint' method on the target stack."));
+ error (_("Could not find 'to_stopped_by_watchpoint' "
+ "method on the target stack."));
if (!tmp_to_stopped_data_address)
- error (_("Could not find 'to_stopped_data_address' method on the target stack."));
+ error (_("Could not find 'to_stopped_data_address' "
+ "method on the target stack."));
push_target (&record_ops);
}
record_beneath_to_stopped_by_watchpoint = tmp_to_stopped_by_watchpoint;
record_beneath_to_stopped_data_address = tmp_to_stopped_data_address;
- if (current_target.to_stratum == core_stratum)
+ if (core_bfd)
record_core_open_1 (name, from_tty);
else
record_open_1 (name, from_tty);
if (!RECORD_IS_REPLAY)
{
+ struct gdbarch *gdbarch = target_thread_architecture (ptid);
+
record_message (get_current_regcache (), signal);
- record_beneath_to_resume (record_beneath_to_resume_ops, ptid, 1,
- signal);
+
+ if (!step)
+ {
+ /* This is not hard single step. */
+ if (!gdbarch_software_single_step_p (gdbarch))
+ {
+ /* This is a normal continue. */
+ step = 1;
+ }
+ else
+ {
+ /* This arch support soft sigle step. */
+ if (single_step_breakpoints_inserted ())
+ {
+ /* This is a soft single step. */
+ record_resume_step = 1;
+ }
+ else
+ {
+ /* This is a continue.
+ Try to insert a soft single step breakpoint. */
+ if (!gdbarch_software_single_step (gdbarch,
+ get_current_frame ()))
+ {
+ /* This system don't want use soft single step.
+ Use hard sigle step. */
+ step = 1;
+ }
+ }
+ }
+ }
+
+ record_beneath_to_resume (record_beneath_to_resume_ops,
+ ptid, step, signal);
}
}
/* This is not a single step. */
ptid_t ret;
CORE_ADDR tmp_pc;
+ struct gdbarch *gdbarch = target_thread_architecture (inferior_ptid);
while (1)
{
ret = record_beneath_to_wait (record_beneath_to_wait_ops,
ptid, status, options);
+ if (single_step_breakpoints_inserted ())
+ remove_single_step_breakpoints ();
+
if (record_resume_step)
return ret;
handle it. */
if (software_breakpoint_inserted_here_p (aspace, tmp_pc))
{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ struct gdbarch *gdbarch
+ = get_regcache_arch (regcache);
CORE_ADDR decr_pc_after_break
= gdbarch_decr_pc_after_break (gdbarch);
if (decr_pc_after_break)
}
else
{
- /* This must be a single-step trap. Record the
- insn and issue another step. */
+ /* This is a single-step trap. Record the
+ insn and issue another step.
+ FIXME: this part can be a random SIGTRAP too.
+ But GDB cannot handle it. */
+ int step = 1;
+
if (!record_message_wrapper_safe (regcache,
TARGET_SIGNAL_0))
{
break;
}
+ if (gdbarch_software_single_step_p (gdbarch))
+ {
+ /* Try to insert the software single step breakpoint.
+ If insert success, set step to 0. */
+ set_executing (inferior_ptid, 0);
+ reinit_frame_cache ();
+ if (gdbarch_software_single_step (gdbarch,
+ get_current_frame ()))
+ step = 0;
+ set_executing (inferior_ptid, 1);
+ }
+
record_beneath_to_resume (record_beneath_to_resume_ops,
- ptid, 1,
+ ptid, step,
TARGET_SIGNAL_0);
continue;
}
if (record_hw_watchpoint)
{
if (record_debug)
- fprintf_unfiltered (gdb_stdlog, "\
-Process record: hit hw watchpoint.\n");
+ fprintf_unfiltered (gdb_stdlog,
+ "Process record: hit hw "
+ "watchpoint.\n");
continue_flag = 0;
}
/* Check target signal */
static void
set_record_command (char *args, int from_tty)
{
- printf_unfiltered (_("\
-\"set record\" must be followed by an apporpriate subcommand.\n"));
+ printf_unfiltered (_("\"set record\" must be followed "
+ "by an apporpriate subcommand.\n"));
help_list (set_record_cmdlist, "set record ", all_commands, gdb_stdout);
}
error (_("Version mis-match or file format error in core file %s."),
bfd_get_filename (core_bfd));
if (record_debug)
- fprintf_unfiltered (gdb_stdlog, "\
- Reading 4-byte magic cookie RECORD_FILE_MAGIC (0x%s)\n",
+ fprintf_unfiltered (gdb_stdlog,
+ " Reading 4-byte magic cookie "
+ "RECORD_FILE_MAGIC (0x%s)\n",
phex_nz (netorder32 (magic), 4));
/* Restore the entries in recfd into record_arch_list_head and
rec->u.reg.len, &bfd_offset);
if (record_debug)
- fprintf_unfiltered (gdb_stdlog, "\
- Reading register %d (1 plus %lu plus %d bytes)\n",
+ fprintf_unfiltered (gdb_stdlog,
+ " Reading register %d (1 "
+ "plus %lu plus %d bytes)\n",
rec->u.reg.num,
(unsigned long) sizeof (regnum),
rec->u.reg.len);
rec->u.mem.len, &bfd_offset);
if (record_debug)
- fprintf_unfiltered (gdb_stdlog, "\
- Reading memory %s (1 plus %lu plus %lu plus %d bytes)\n",
+ fprintf_unfiltered (gdb_stdlog,
+ " Reading memory %s (1 plus "
+ "%lu plus %lu plus %d bytes)\n",
paddress (get_current_arch (),
rec->u.mem.addr),
(unsigned long) sizeof (addr),
rec->u.end.insn_num = count;
record_insn_count = count + 1;
if (record_debug)
- fprintf_unfiltered (gdb_stdlog, "\
- Reading record_end (1 + %lu + %lu bytes), offset == %s\n",
+ fprintf_unfiltered (gdb_stdlog,
+ " Reading record_end (1 + "
+ "%lu + %lu bytes), offset == %s\n",
(unsigned long) sizeof (signal),
(unsigned long) sizeof (count),
paddress (get_current_arch (),
/* Write the magic code. */
magic = RECORD_FILE_MAGIC;
if (record_debug)
- fprintf_unfiltered (gdb_stdlog, "\
- Writing 4-byte magic cookie RECORD_FILE_MAGIC (0x%s)\n",
+ fprintf_unfiltered (gdb_stdlog,
+ " Writing 4-byte magic cookie "
+ "RECORD_FILE_MAGIC (0x%s)\n",
phex_nz (magic, 4));
bfdcore_write (obfd, osec, &magic, sizeof (magic), &bfd_offset);
{
case record_reg: /* reg */
if (record_debug)
- fprintf_unfiltered (gdb_stdlog, "\
- Writing register %d (1 plus %lu plus %d bytes)\n",
+ fprintf_unfiltered (gdb_stdlog,
+ " Writing register %d (1 "
+ "plus %lu plus %d bytes)\n",
record_list->u.reg.num,
(unsigned long) sizeof (regnum),
record_list->u.reg.len);
case record_mem: /* mem */
if (record_debug)
- fprintf_unfiltered (gdb_stdlog, "\
- Writing memory %s (1 plus %lu plus %lu plus %d bytes)\n",
+ fprintf_unfiltered (gdb_stdlog,
+ " Writing memory %s (1 plus "
+ "%lu plus %lu plus %d bytes)\n",
paddress (gdbarch,
record_list->u.mem.addr),
(unsigned long) sizeof (addr),
case record_end:
if (record_debug)
- fprintf_unfiltered (gdb_stdlog, "\
- Writing record_end (1 + %lu + %lu bytes)\n",
+ fprintf_unfiltered (gdb_stdlog,
+ " Writing record_end (1 + "
+ "%lu + %lu bytes)\n",
(unsigned long) sizeof (signal),
(unsigned long) sizeof (count));
/* Write signal value. */
add_setshow_boolean_cmd ("stop-at-limit", no_class,
&record_stop_at_limit, _("\
Set whether record/replay stops when record/replay buffer becomes full."), _("\
-Show whether record/replay stops when record/replay buffer becomes full."), _("\
-Default is ON.\n\
+Show whether record/replay stops when record/replay buffer becomes full."),
+ _("Default is ON.\n\
When ON, if the record/replay buffer becomes full, ask user what to do.\n\
When OFF, if the record/replay buffer becomes full,\n\
delete the oldest recorded instruction to make room for each new one."),
When ON, query if PREC cannot record memory change of next instruction."),
NULL, NULL,
&set_record_cmdlist, &show_record_cmdlist);
+
}