aboutsummaryrefslogtreecommitdiff
path: root/gdb/record-full.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/record-full.c')
-rw-r--r--gdb/record-full.c596
1 files changed, 306 insertions, 290 deletions
diff --git a/gdb/record-full.c b/gdb/record-full.c
index 4d8dd61..de96574 100644
--- a/gdb/record-full.c
+++ b/gdb/record-full.c
@@ -47,7 +47,7 @@
Target record has two modes: recording, and replaying.
- In record mode, we intercept the to_resume and to_wait methods.
+ In record mode, we intercept the resume and wait methods.
Whenever gdb resumes the target, we run the target in single step
mode, and we build up an execution log in which, for each executed
instruction, we record all changes in memory and register state.
@@ -63,7 +63,7 @@
#define DEFAULT_RECORD_FULL_INSN_MAX_NUM 200000
#define RECORD_FULL_IS_REPLAY \
- (record_full_list->next || execution_direction == EXEC_REVERSE)
+ (record_full_list->next || ::execution_direction == EXEC_REVERSE)
#define RECORD_FULL_FILE_MAGIC netorder32(0x20091016)
@@ -206,9 +206,144 @@ static unsigned int record_full_insn_num = 0;
than count of insns presently in execution log). */
static ULONGEST record_full_insn_count;
-/* The target_ops of process record. */
-static struct target_ops record_full_ops;
-static struct target_ops record_full_core_ops;
+/* Base class implementing functionality common to both the
+ "record-full" and "record-core" targets. */
+
+class record_full_base_target : public target_ops
+{
+public:
+ record_full_base_target ()
+ { to_stratum = record_stratum; }
+
+ const char *shortname () override = 0;
+
+ const char *longname () override
+ { return _("Process record and replay target"); }
+
+ const char *doc () override
+ { return _("Log program while executing and replay execution from log."); }
+
+ void open (const char *, int) override;
+ void close () override;
+ void async (int) override;
+ ptid_t wait (ptid_t, struct target_waitstatus *, int) override;
+ int stopped_by_watchpoint () override;
+ int stopped_data_address (CORE_ADDR *) override;
+
+ int stopped_by_sw_breakpoint () override;
+ int supports_stopped_by_sw_breakpoint () override;
+
+ int stopped_by_hw_breakpoint () override;
+ int supports_stopped_by_hw_breakpoint () override;
+
+ int can_execute_reverse () override;
+
+ /* Add bookmark target methods. */
+ gdb_byte *get_bookmark (const char *, int) override;
+ void goto_bookmark (const gdb_byte *, int) override;
+ enum exec_direction_kind execution_direction () override;
+ enum record_method record_method (ptid_t ptid) override;
+ void info_record () override;
+ void save_record (const char *filename) override;
+ bool supports_delete_record () override;
+ void delete_record () override;
+ int record_is_replaying (ptid_t ptid) override;
+ int record_will_replay (ptid_t ptid, int dir) override;
+ void record_stop_replaying () override;
+ void goto_record_begin () override;
+ void goto_record_end () override;
+ void goto_record (ULONGEST insn) override;
+};
+
+/* The "record-full" target. */
+
+class record_full_target final : public record_full_base_target
+{
+public:
+ const char *shortname () override
+ { return "record-full"; }
+
+ void commit_resume () override;
+ void resume (ptid_t, int, enum gdb_signal) override;
+ void disconnect (const char *, int) override;
+ void detach (inferior *, int) override;
+ void mourn_inferior () override;
+ void kill () override;
+ void store_registers (struct regcache *, int) override;
+ enum target_xfer_status xfer_partial (enum target_object object,
+ const char *annex,
+ gdb_byte *readbuf,
+ const gdb_byte *writebuf,
+ ULONGEST offset, ULONGEST len,
+ ULONGEST *xfered_len) override;
+ int insert_breakpoint (struct gdbarch *,
+ struct bp_target_info *) override;
+ int remove_breakpoint (struct gdbarch *,
+ struct bp_target_info *,
+ enum remove_bp_reason) override;
+};
+
+/* The "record-core" target. */
+
+class record_full_core_target final : public record_full_base_target
+{
+public:
+ const char *shortname () override
+ { return "record-core"; }
+
+ void resume (ptid_t, int, enum gdb_signal) override;
+ void disconnect (const char *, int) override;
+ void kill () override;
+ void fetch_registers (struct regcache *regcache, int regno) override;
+ void prepare_to_store (struct regcache *regcache) override;
+ void store_registers (struct regcache *, int) override;
+ enum target_xfer_status xfer_partial (enum target_object object,
+ const char *annex,
+ gdb_byte *readbuf,
+ const gdb_byte *writebuf,
+ ULONGEST offset, ULONGEST len,
+ ULONGEST *xfered_len) override;
+ int insert_breakpoint (struct gdbarch *,
+ struct bp_target_info *) override;
+ int remove_breakpoint (struct gdbarch *,
+ struct bp_target_info *,
+ enum remove_bp_reason) override;
+
+ int has_execution (ptid_t) override;
+};
+
+static record_full_target record_full_ops;
+static record_full_core_target record_full_core_ops;
+
+void
+record_full_target::detach (inferior *inf, int from_tty)
+{
+ record_detach (this, inf, from_tty);
+}
+
+void
+record_full_target::disconnect (const char *args, int from_tty)
+{
+ record_disconnect (this, args, from_tty);
+}
+
+void
+record_full_core_target::disconnect (const char *args, int from_tty)
+{
+ record_disconnect (this, args, from_tty);
+}
+
+void
+record_full_target::mourn_inferior ()
+{
+ record_mourn_inferior (this);
+}
+
+void
+record_full_target::kill ()
+{
+ record_kill (this);
+}
/* See record-full.h. */
@@ -232,8 +367,6 @@ static struct cmd_list_element *record_full_cmdlist;
static void record_full_goto_insn (struct record_full_entry *entry,
enum exec_direction_kind dir);
-static void record_full_save (struct target_ops *self,
- const char *recfilename);
/* Alloc and free functions for record_full_reg, record_full_mem, and
record_full_end entries. */
@@ -797,7 +930,7 @@ record_full_core_open_1 (const char *name, int from_tty)
record_full_restore ();
}
-/* "to_open" target method for 'live' processes. */
+/* "open" target method for 'live' processes. */
static void
record_full_open_1 (const char *name, int from_tty)
@@ -821,10 +954,10 @@ record_full_open_1 (const char *name, int from_tty)
static void record_full_init_record_breakpoints (void);
-/* "to_open" target method. Open the process record target. */
+/* "open" target method. Open the process record target. */
-static void
-record_full_open (const char *name, int from_tty)
+void
+record_full_base_target::open (const char *name, int from_tty)
{
if (record_debug)
fprintf_unfiltered (gdb_stdlog, "Process record: record_full_open\n");
@@ -852,10 +985,10 @@ record_full_open (const char *name, int from_tty)
gdb::observers::record_changed.notify (current_inferior (), 1, "full", NULL);
}
-/* "to_close" target method. Close the process record target. */
+/* "close" target method. Close the process record target. */
-static void
-record_full_close (struct target_ops *self)
+void
+record_full_base_target::close ()
{
struct record_full_core_buf_entry *entry;
@@ -887,17 +1020,17 @@ record_full_close (struct target_ops *self)
delete_async_event_handler (&record_full_async_inferior_event_token);
}
-/* "to_async" target method. */
+/* "async" target method. */
-static void
-record_full_async (struct target_ops *ops, int enable)
+void
+record_full_base_target::async (int enable)
{
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, enable);
+ beneath->async (enable);
}
static int record_full_resume_step = 0;
@@ -923,15 +1056,14 @@ static int record_full_resumed = 0;
*/
static enum exec_direction_kind record_full_execution_dir = EXEC_FORWARD;
-/* "to_resume" target method. Resume the process record target. */
+/* "resume" target method. Resume the process record target. */
-static void
-record_full_resume (struct target_ops *ops, ptid_t ptid, int step,
- enum gdb_signal signal)
+void
+record_full_target::resume (ptid_t ptid, int step, enum gdb_signal signal)
{
record_full_resume_step = step;
record_full_resumed = 1;
- record_full_execution_dir = execution_direction;
+ record_full_execution_dir = ::execution_direction;
if (!RECORD_FULL_IS_REPLAY)
{
@@ -963,7 +1095,7 @@ record_full_resume (struct target_ops *ops, ptid_t ptid, int step,
/* Make sure the target beneath reports all signals. */
target_pass_signals (0, NULL);
- ops->beneath->to_resume (ops->beneath, ptid, step, signal);
+ this->beneath->resume (ptid, step, signal);
}
/* We are about to start executing the inferior (or simulate it),
@@ -972,18 +1104,18 @@ record_full_resume (struct target_ops *ops, ptid_t ptid, int step,
target_async (1);
}
-/* "to_commit_resume" method for process record target. */
+/* "commit_resume" method for process record target. */
-static void
-record_full_commit_resume (struct target_ops *ops)
+void
+record_full_target::commit_resume ()
{
if (!RECORD_FULL_IS_REPLAY)
- ops->beneath->to_commit_resume (ops->beneath);
+ beneath->commit_resume ();
}
static int record_full_get_sig = 0;
-/* SIGINT signal handler, registered by "to_wait" method. */
+/* SIGINT signal handler, registered by "wait" method. */
static void
record_full_sig_handler (int signo)
@@ -1011,13 +1143,13 @@ record_full_wait_cleanups (void *ignore)
record_full_list = record_full_list->prev;
}
-/* "to_wait" target method for process record target.
+/* "wait" target method for process record target.
In record mode, the target is always run in singlestep mode
- (even when gdb says to continue). The to_wait method intercepts
+ (even when gdb says to continue). The wait method intercepts
the stop events and determines which ones are to be passed on to
gdb. Most stop events are just singlestep events that gdb is not
- to know about, so the to_wait method just records them and keeps
+ to know about, so the wait method just records them and keeps
singlestepping.
In replay mode, this function emulates the recorded execution log,
@@ -1060,7 +1192,7 @@ record_full_wait_1 (struct target_ops *ops,
if (record_full_resume_step)
{
/* This is a single step. */
- return ops->beneath->to_wait (ops->beneath, ptid, status, options);
+ return ops->beneath->wait (ptid, status, options);
}
else
{
@@ -1073,7 +1205,7 @@ record_full_wait_1 (struct target_ops *ops,
{
struct thread_info *tp;
- ret = ops->beneath->to_wait (ops->beneath, ptid, status, options);
+ ret = ops->beneath->wait (ptid, status, options);
if (status->kind == TARGET_WAITKIND_IGNORE)
{
if (record_debug)
@@ -1149,9 +1281,8 @@ record_full_wait_1 (struct target_ops *ops,
"Process record: record_full_wait "
"issuing one more step in the "
"target beneath\n");
- ops->beneath->to_resume (ops->beneath, ptid, step,
- GDB_SIGNAL_0);
- ops->beneath->to_commit_resume (ops->beneath);
+ ops->beneath->resume (ptid, step, GDB_SIGNAL_0);
+ ops->beneath->commit_resume ();
continue;
}
}
@@ -1315,14 +1446,13 @@ replay_out:
return inferior_ptid;
}
-static ptid_t
-record_full_wait (struct target_ops *ops,
- ptid_t ptid, struct target_waitstatus *status,
- int options)
+ptid_t
+record_full_base_target::wait (ptid_t ptid, struct target_waitstatus *status,
+ int options)
{
ptid_t return_ptid;
- return_ptid = record_full_wait_1 (ops, ptid, status, options);
+ return_ptid = record_full_wait_1 (this, ptid, status, options);
if (status->kind != TARGET_WAITKIND_IGNORE)
{
/* We're reporting a stop. Make sure any spurious
@@ -1333,54 +1463,54 @@ record_full_wait (struct target_ops *ops,
return return_ptid;
}
-static int
-record_full_stopped_by_watchpoint (struct target_ops *ops)
+int
+record_full_base_target::stopped_by_watchpoint ()
{
if (RECORD_FULL_IS_REPLAY)
return record_full_stop_reason == TARGET_STOPPED_BY_WATCHPOINT;
else
- return ops->beneath->to_stopped_by_watchpoint (ops->beneath);
+ return beneath->stopped_by_watchpoint ();
}
-static int
-record_full_stopped_data_address (struct target_ops *ops, CORE_ADDR *addr_p)
+int
+record_full_base_target::stopped_data_address (CORE_ADDR *addr_p)
{
if (RECORD_FULL_IS_REPLAY)
return 0;
else
- return ops->beneath->to_stopped_data_address (ops->beneath, addr_p);
+ return this->beneath->stopped_data_address (addr_p);
}
-/* The to_stopped_by_sw_breakpoint method of target record-full. */
+/* The stopped_by_sw_breakpoint method of target record-full. */
-static int
-record_full_stopped_by_sw_breakpoint (struct target_ops *ops)
+int
+record_full_base_target::stopped_by_sw_breakpoint ()
{
return record_full_stop_reason == TARGET_STOPPED_BY_SW_BREAKPOINT;
}
-/* The to_supports_stopped_by_sw_breakpoint method of target
+/* The supports_stopped_by_sw_breakpoint method of target
record-full. */
-static int
-record_full_supports_stopped_by_sw_breakpoint (struct target_ops *ops)
+int
+record_full_base_target::supports_stopped_by_sw_breakpoint ()
{
return 1;
}
-/* The to_stopped_by_hw_breakpoint method of target record-full. */
+/* The stopped_by_hw_breakpoint method of target record-full. */
-static int
-record_full_stopped_by_hw_breakpoint (struct target_ops *ops)
+int
+record_full_base_target::stopped_by_hw_breakpoint ()
{
return record_full_stop_reason == TARGET_STOPPED_BY_HW_BREAKPOINT;
}
-/* The to_supports_stopped_by_sw_breakpoint method of target
+/* The supports_stopped_by_sw_breakpoint method of target
record-full. */
-static int
-record_full_supports_stopped_by_hw_breakpoint (struct target_ops *ops)
+int
+record_full_base_target::supports_stopped_by_hw_breakpoint ()
{
return 1;
}
@@ -1432,12 +1562,10 @@ record_full_registers_change (struct regcache *regcache, int regnum)
record_full_insn_num++;
}
-/* "to_store_registers" method for process record target. */
+/* "store_registers" method for process record target. */
-static void
-record_full_store_registers (struct target_ops *ops,
- struct regcache *regcache,
- int regno)
+void
+record_full_target::store_registers (struct regcache *regcache, int regno)
{
if (!record_full_gdb_operation_disable)
{
@@ -1485,19 +1613,19 @@ record_full_store_registers (struct target_ops *ops,
record_full_registers_change (regcache, regno);
}
- ops->beneath->to_store_registers (ops->beneath, regcache, regno);
+ this->beneath->store_registers (regcache, regno);
}
-/* "to_xfer_partial" method. Behavior is conditional on
+/* "xfer_partial" method. Behavior is conditional on
RECORD_FULL_IS_REPLAY.
In replay mode, we cannot write memory unles we are willing to
invalidate the record/replay log from this point forward. */
-static enum target_xfer_status
-record_full_xfer_partial (struct target_ops *ops, enum target_object object,
- const char *annex, gdb_byte *readbuf,
- const gdb_byte *writebuf, ULONGEST offset,
- ULONGEST len, ULONGEST *xfered_len)
+enum target_xfer_status
+record_full_target::xfer_partial (enum target_object object,
+ const char *annex, gdb_byte *readbuf,
+ const gdb_byte *writebuf, ULONGEST offset,
+ ULONGEST len, ULONGEST *xfered_len)
{
if (!record_full_gdb_operation_disable
&& (object == TARGET_OBJECT_MEMORY
@@ -1550,9 +1678,8 @@ record_full_xfer_partial (struct target_ops *ops, enum target_object object,
record_full_insn_num++;
}
- return ops->beneath->to_xfer_partial (ops->beneath, object, annex,
- readbuf, writebuf, offset,
- len, xfered_len);
+ return this->beneath->xfer_partial (object, annex, readbuf, writebuf, offset,
+ len, xfered_len);
}
/* This structure represents a breakpoint inserted while the record
@@ -1614,10 +1741,9 @@ record_full_init_record_breakpoints (void)
insert or remove breakpoints in the real target when replaying, nor
when recording. */
-static int
-record_full_insert_breakpoint (struct target_ops *ops,
- struct gdbarch *gdbarch,
- struct bp_target_info *bp_tgt)
+int
+record_full_target::insert_breakpoint (struct gdbarch *gdbarch,
+ struct bp_target_info *bp_tgt)
{
struct record_full_breakpoint *bp;
int in_target_beneath = 0;
@@ -1630,12 +1756,11 @@ record_full_insert_breakpoint (struct target_ops *ops,
However, we do have to insert software single-step
breakpoints, in case the target can't hardware step. To keep
things simple, we always insert. */
- int ret;
scoped_restore restore_operation_disable
= record_full_gdb_operation_disable_set ();
- ret = ops->beneath->to_insert_breakpoint (ops->beneath, gdbarch, bp_tgt);
+ int ret = this->beneath->insert_breakpoint (gdbarch, bp_tgt);
if (ret != 0)
return ret;
@@ -1666,13 +1791,12 @@ record_full_insert_breakpoint (struct target_ops *ops,
return 0;
}
-/* "to_remove_breakpoint" method for process record target. */
+/* "remove_breakpoint" method for process record target. */
-static int
-record_full_remove_breakpoint (struct target_ops *ops,
- struct gdbarch *gdbarch,
- struct bp_target_info *bp_tgt,
- enum remove_bp_reason reason)
+int
+record_full_target::remove_breakpoint (struct gdbarch *gdbarch,
+ struct bp_target_info *bp_tgt,
+ enum remove_bp_reason reason)
{
struct record_full_breakpoint *bp;
int ix;
@@ -1687,12 +1811,11 @@ record_full_remove_breakpoint (struct target_ops *ops,
{
if (bp->in_target_beneath)
{
- int ret;
-
scoped_restore restore_operation_disable
= record_full_gdb_operation_disable_set ();
- ret = ops->beneath->to_remove_breakpoint (ops->beneath, gdbarch,
- bp_tgt, reason);
+
+ int ret = this->beneath->remove_breakpoint (gdbarch, bp_tgt,
+ reason);
if (ret != 0)
return ret;
}
@@ -1709,19 +1832,18 @@ record_full_remove_breakpoint (struct target_ops *ops,
gdb_assert_not_reached ("removing unknown breakpoint");
}
-/* "to_can_execute_reverse" method for process record target. */
+/* "can_execute_reverse" method for process record target. */
-static int
-record_full_can_execute_reverse (struct target_ops *self)
+int
+record_full_base_target::can_execute_reverse ()
{
return 1;
}
-/* "to_get_bookmark" method for process record and prec over core. */
+/* "get_bookmark" method for process record and prec over core. */
-static gdb_byte *
-record_full_get_bookmark (struct target_ops *self, const char *args,
- int from_tty)
+gdb_byte *
+record_full_base_target::get_bookmark (const char *args, int from_tty)
{
char *ret = NULL;
@@ -1741,11 +1863,11 @@ record_full_get_bookmark (struct target_ops *self, const char *args,
return (gdb_byte *) ret;
}
-/* "to_goto_bookmark" method for process record and prec over core. */
+/* "goto_bookmark" method for process record and prec over core. */
-static void
-record_full_goto_bookmark (struct target_ops *self,
- const gdb_byte *raw_bookmark, int from_tty)
+void
+record_full_base_target::goto_bookmark (const gdb_byte *raw_bookmark,
+ int from_tty)
{
const char *bookmark = (const char *) raw_bookmark;
@@ -1766,22 +1888,22 @@ record_full_goto_bookmark (struct target_ops *self,
record_goto (bookmark);
}
-static enum exec_direction_kind
-record_full_execution_direction (struct target_ops *self)
+enum exec_direction_kind
+record_full_base_target::execution_direction ()
{
return record_full_execution_dir;
}
-/* The to_record_method method of target record-full. */
+/* The record_method method of target record-full. */
enum record_method
-record_full_record_method (struct target_ops *self, ptid_t ptid)
+record_full_base_target::record_method (ptid_t ptid)
{
return RECORD_METHOD_FULL;
}
-static void
-record_full_info (struct target_ops *self)
+void
+record_full_base_target::info_record ()
{
struct record_full_entry *p;
@@ -1824,26 +1946,32 @@ record_full_info (struct target_ops *self)
record_full_insn_max_num);
}
-/* The "to_record_delete" target method. */
+bool
+record_full_base_target::supports_delete_record ()
+{
+ return true;
+}
-static void
-record_full_delete (struct target_ops *self)
+/* The "delete_record" target method. */
+
+void
+record_full_base_target::delete_record ()
{
record_full_list_release_following (record_full_list);
}
-/* The "to_record_is_replaying" target method. */
+/* The "record_is_replaying" target method. */
-static int
-record_full_is_replaying (struct target_ops *self, ptid_t ptid)
+int
+record_full_base_target::record_is_replaying (ptid_t ptid)
{
return RECORD_FULL_IS_REPLAY;
}
-/* The "to_record_will_replay" target method. */
+/* The "record_will_replay" target method. */
-static int
-record_full_will_replay (struct target_ops *self, ptid_t ptid, int dir)
+int
+record_full_base_target::record_will_replay (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
@@ -1880,10 +2008,10 @@ record_full_goto_entry (struct record_full_entry *p)
print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC, 1);
}
-/* The "to_goto_record_begin" target method. */
+/* The "goto_record_begin" target method. */
-static void
-record_full_goto_begin (struct target_ops *self)
+void
+record_full_base_target::goto_record_begin ()
{
struct record_full_entry *p = NULL;
@@ -1894,10 +2022,10 @@ record_full_goto_begin (struct target_ops *self)
record_full_goto_entry (p);
}
-/* The "to_goto_record_end" target method. */
+/* The "goto_record_end" target method. */
-static void
-record_full_goto_end (struct target_ops *self)
+void
+record_full_base_target::goto_record_end ()
{
struct record_full_entry *p = NULL;
@@ -1910,10 +2038,10 @@ record_full_goto_end (struct target_ops *self)
record_full_goto_entry (p);
}
-/* The "to_goto_record" target method. */
+/* The "goto_record" target method. */
-static void
-record_full_goto (struct target_ops *self, ULONGEST target_insn)
+void
+record_full_base_target::goto_record (ULONGEST target_insn)
{
struct record_full_entry *p = NULL;
@@ -1924,73 +2052,23 @@ record_full_goto (struct target_ops *self, ULONGEST target_insn)
record_full_goto_entry (p);
}
-/* The "to_record_stop_replaying" target method. */
+/* The "record_stop_replaying" target method. */
-static void
-record_full_stop_replaying (struct target_ops *self)
+void
+record_full_base_target::record_stop_replaying ()
{
- record_full_goto_end (self);
+ goto_record_end ();
}
-static void
-init_record_full_ops (void)
-{
- record_full_ops.to_shortname = "record-full";
- record_full_ops.to_longname = "Process record and replay target";
- record_full_ops.to_doc =
- "Log program while executing and replay execution from log.";
- record_full_ops.to_open = record_full_open;
- record_full_ops.to_close = record_full_close;
- record_full_ops.to_async = record_full_async;
- record_full_ops.to_resume = record_full_resume;
- record_full_ops.to_commit_resume = record_full_commit_resume;
- record_full_ops.to_wait = record_full_wait;
- record_full_ops.to_disconnect = record_disconnect;
- record_full_ops.to_detach = record_detach;
- record_full_ops.to_mourn_inferior = record_mourn_inferior;
- record_full_ops.to_kill = record_kill;
- record_full_ops.to_store_registers = record_full_store_registers;
- record_full_ops.to_xfer_partial = record_full_xfer_partial;
- record_full_ops.to_insert_breakpoint = record_full_insert_breakpoint;
- 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_get_bookmark = record_full_get_bookmark;
- record_full_ops.to_goto_bookmark = record_full_goto_bookmark;
- record_full_ops.to_execution_direction = record_full_execution_direction;
- record_full_ops.to_record_method = record_full_record_method;
- record_full_ops.to_info_record = record_full_info;
- 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;
- record_full_ops.to_magic = OPS_MAGIC;
-}
-
-/* "to_resume" method for prec over corefile. */
+/* "resume" method for prec over corefile. */
-static void
-record_full_core_resume (struct target_ops *ops, ptid_t ptid, int step,
- enum gdb_signal signal)
+void
+record_full_core_target::resume (ptid_t ptid, int step,
+ enum gdb_signal signal)
{
record_full_resume_step = step;
record_full_resumed = 1;
- record_full_execution_dir = execution_direction;
+ record_full_execution_dir = ::execution_direction;
/* We are about to start executing the inferior (or simulate it),
let's register it with the event loop. */
@@ -1998,23 +2076,22 @@ record_full_core_resume (struct target_ops *ops, ptid_t ptid, int step,
target_async (1);
}
-/* "to_kill" method for prec over corefile. */
+/* "kill" method for prec over corefile. */
-static void
-record_full_core_kill (struct target_ops *ops)
+void
+record_full_core_target::kill ()
{
if (record_debug)
fprintf_unfiltered (gdb_stdlog, "Process record: record_full_core_kill\n");
- unpush_target (&record_full_core_ops);
+ unpush_target (this);
}
-/* "to_fetch_registers" method for prec over corefile. */
+/* "fetch_registers" method for prec over corefile. */
-static void
-record_full_core_fetch_registers (struct target_ops *ops,
- struct regcache *regcache,
- int regno)
+void
+record_full_core_target::fetch_registers (struct regcache *regcache,
+ int regno)
{
if (regno < 0)
{
@@ -2028,20 +2105,18 @@ record_full_core_fetch_registers (struct target_ops *ops,
regcache->raw_supply (regno, *record_full_core_regbuf);
}
-/* "to_prepare_to_store" method for prec over corefile. */
+/* "prepare_to_store" method for prec over corefile. */
-static void
-record_full_core_prepare_to_store (struct target_ops *self,
- struct regcache *regcache)
+void
+record_full_core_target::prepare_to_store (struct regcache *regcache)
{
}
-/* "to_store_registers" method for prec over corefile. */
+/* "store_registers" method for prec over corefile. */
-static void
-record_full_core_store_registers (struct target_ops *ops,
- struct regcache *regcache,
- int regno)
+void
+record_full_core_target::store_registers (struct regcache *regcache,
+ int regno)
{
if (record_full_gdb_operation_disable)
record_full_core_regbuf->raw_supply (regno, *regcache);
@@ -2049,14 +2124,13 @@ record_full_core_store_registers (struct target_ops *ops,
error (_("You can't do that without a process to debug."));
}
-/* "to_xfer_partial" method for prec over corefile. */
+/* "xfer_partial" method for prec over corefile. */
-static enum target_xfer_status
-record_full_core_xfer_partial (struct target_ops *ops,
- enum target_object object,
- const char *annex, gdb_byte *readbuf,
- const gdb_byte *writebuf, ULONGEST offset,
- ULONGEST len, ULONGEST *xfered_len)
+enum target_xfer_status
+record_full_core_target::xfer_partial (enum target_object object,
+ const char *annex, gdb_byte *readbuf,
+ const gdb_byte *writebuf, ULONGEST offset,
+ ULONGEST len, ULONGEST *xfered_len)
{
if (object == TARGET_OBJECT_MEMORY)
{
@@ -2120,11 +2194,10 @@ record_full_core_xfer_partial (struct target_ops *ops,
else
{
if (!entry)
- return ops->beneath->to_xfer_partial (ops->beneath,
- object, annex,
- readbuf, writebuf,
- offset, len,
- xfered_len);
+ return this->beneath->xfer_partial (object, annex,
+ readbuf, writebuf,
+ offset, len,
+ xfered_len);
memcpy (readbuf, entry->buf + sec_offset,
(size_t) len);
@@ -2141,93 +2214,38 @@ record_full_core_xfer_partial (struct target_ops *ops,
error (_("You can't do that without a process to debug."));
}
- return ops->beneath->to_xfer_partial (ops->beneath, object, annex,
- readbuf, writebuf, offset, len,
- xfered_len);
+ return this->beneath->xfer_partial (object, annex,
+ readbuf, writebuf, offset, len,
+ xfered_len);
}
-/* "to_insert_breakpoint" method for prec over corefile. */
+/* "insert_breakpoint" method for prec over corefile. */
-static int
-record_full_core_insert_breakpoint (struct target_ops *ops,
- struct gdbarch *gdbarch,
- struct bp_target_info *bp_tgt)
+int
+record_full_core_target::insert_breakpoint (struct gdbarch *gdbarch,
+ struct bp_target_info *bp_tgt)
{
return 0;
}
-/* "to_remove_breakpoint" method for prec over corefile. */
+/* "remove_breakpoint" method for prec over corefile. */
-static int
-record_full_core_remove_breakpoint (struct target_ops *ops,
- struct gdbarch *gdbarch,
- struct bp_target_info *bp_tgt,
- enum remove_bp_reason reason)
+int
+record_full_core_target::remove_breakpoint (struct gdbarch *gdbarch,
+ struct bp_target_info *bp_tgt,
+ enum remove_bp_reason reason)
{
return 0;
}
-/* "to_has_execution" method for prec over corefile. */
+/* "has_execution" method for prec over corefile. */
-static int
-record_full_core_has_execution (struct target_ops *ops, ptid_t the_ptid)
+int
+record_full_core_target::has_execution (ptid_t the_ptid)
{
return 1;
}
-static void
-init_record_full_core_ops (void)
-{
- record_full_core_ops.to_shortname = "record-core";
- record_full_core_ops.to_longname = "Process record and replay target";
- record_full_core_ops.to_doc =
- "Log program while executing and replay execution from log.";
- record_full_core_ops.to_open = record_full_open;
- record_full_core_ops.to_close = record_full_close;
- record_full_core_ops.to_async = record_full_async;
- record_full_core_ops.to_resume = record_full_core_resume;
- record_full_core_ops.to_wait = record_full_wait;
- record_full_core_ops.to_kill = record_full_core_kill;
- record_full_core_ops.to_fetch_registers = record_full_core_fetch_registers;
- record_full_core_ops.to_prepare_to_store = record_full_core_prepare_to_store;
- record_full_core_ops.to_store_registers = record_full_core_store_registers;
- record_full_core_ops.to_xfer_partial = record_full_core_xfer_partial;
- record_full_core_ops.to_insert_breakpoint
- = record_full_core_insert_breakpoint;
- record_full_core_ops.to_remove_breakpoint
- = record_full_core_remove_breakpoint;
- record_full_core_ops.to_stopped_by_watchpoint
- = 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_stratum = record_stratum;
- /* Add bookmark target methods. */
- record_full_core_ops.to_get_bookmark = record_full_get_bookmark;
- record_full_core_ops.to_goto_bookmark = record_full_goto_bookmark;
- record_full_core_ops.to_execution_direction
- = record_full_execution_direction;
- record_full_core_ops.to_record_method = record_full_record_method;
- 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;
- record_full_core_ops.to_magic = OPS_MAGIC;
-}
-
/* Record log save-file format
Version 1 (never released)
@@ -2501,14 +2519,14 @@ static void
cmd_record_full_restore (const char *args, int from_tty)
{
core_file_command (args, from_tty);
- record_full_open (args, from_tty);
+ record_full_ops.open (args, from_tty);
}
/* Save the execution log to a file. We use a modified elf corefile
format, with an extra section for our data. */
-static void
-record_full_save (struct target_ops *self, const char *recfilename)
+void
+record_full_base_target::save_record (const char *recfilename)
{
struct record_full_entry *cur_record_full_list;
uint32_t magic;
@@ -2790,10 +2808,8 @@ _initialize_record_full (void)
record_full_first.next = NULL;
record_full_first.type = record_full_end;
- init_record_full_ops ();
add_target (&record_full_ops);
add_deprecated_target_alias (&record_full_ops, "record");
- init_record_full_core_ops ();
add_target (&record_full_core_ops);
add_prefix_cmd ("full", class_obscure, cmd_record_full_start,