/* Process record and replay target for GDB, the GNU debugger.

   Copyright (C) 2013-2020 Free Software Foundation, Inc.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#include "defs.h"
#include "gdbcmd.h"
#include "regcache.h"
#include "gdbthread.h"
#include "inferior.h"
#include "event-top.h"
#include "completer.h"
#include "arch-utils.h"
#include "gdbcore.h"
#include "exec.h"
#include "record.h"
#include "record-full.h"
#include "elf-bfd.h"
#include "gcore.h"
#include "event-loop.h"
#include "inf-loop.h"
#include "gdb_bfd.h"
#include "observable.h"
#include "infrun.h"
#include "gdbsupport/gdb_unlinker.h"
#include "gdbsupport/byte-vector.h"

#include <signal.h>

/* This module implements "target record-full", also known as "process
   record and replay".  This target sits on top of a "normal" target
   (a target that "has execution"), and provides a record and replay
   functionality, including reverse debugging.

   Target record has two modes: recording, and replaying.

   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.
   This is invisible to the user, to whom it just looks like an
   ordinary debugging session (except for performance degradation).

   In replay mode, instead of actually letting the inferior run as a
   process, we simulate its execution by playing back the recorded
   execution log.  For each instruction in the log, we simulate the
   instruction's side effects by duplicating the changes that it would
   have made on memory and registers.  */

#define DEFAULT_RECORD_FULL_INSN_MAX_NUM	200000

#define RECORD_FULL_IS_REPLAY \
  (record_full_list->next || ::execution_direction == EXEC_REVERSE)

#define RECORD_FULL_FILE_MAGIC	netorder32(0x20091016)

/* These are the core structs of the process record functionality.

   A record_full_entry is a record of the value change of a register
   ("record_full_reg") or a part of memory ("record_full_mem").  And each
   instruction must have a struct record_full_entry ("record_full_end")
   that indicates that this is the last struct record_full_entry of this
   instruction.

   Each struct record_full_entry is linked to "record_full_list" by "prev"
   and "next" pointers.  */

struct record_full_mem_entry
{
  CORE_ADDR addr;
  int len;
  /* Set this flag if target memory for this entry
     can no longer be accessed.  */
  int mem_entry_not_accessible;
  union
  {
    gdb_byte *ptr;
    gdb_byte buf[sizeof (gdb_byte *)];
  } u;
};

struct record_full_reg_entry
{
  unsigned short num;
  unsigned short len;
  union 
  {
    gdb_byte *ptr;
    gdb_byte buf[2 * sizeof (gdb_byte *)];
  } u;
};

struct record_full_end_entry
{
  enum gdb_signal sigval;
  ULONGEST insn_num;
};

enum record_full_type
{
  record_full_end = 0,
  record_full_reg,
  record_full_mem
};

/* This is the data structure that makes up the execution log.

   The execution log consists of a single linked list of entries
   of type "struct record_full_entry".  It is doubly linked so that it
   can be traversed in either direction.

   The start of the list is anchored by a struct called
   "record_full_first".  The pointer "record_full_list" either points
   to the last entry that was added to the list (in record mode), or to
   the next entry in the list that will be executed (in replay mode).

   Each list element (struct record_full_entry), in addition to next
   and prev pointers, consists of a union of three entry types: mem,
   reg, and end.  A field called "type" determines which entry type is
   represented by a given list element.

   Each instruction that is added to the execution log is represented
   by a variable number of list elements ('entries').  The instruction
   will have one "reg" entry for each register that is changed by 
   executing the instruction (including the PC in every case).  It 
   will also have one "mem" entry for each memory change.  Finally,
   each instruction will have an "end" entry that separates it from
   the changes associated with the next instruction.  */

struct record_full_entry
{
  struct record_full_entry *prev;
  struct record_full_entry *next;
  enum record_full_type type;
  union
  {
    /* reg */
    struct record_full_reg_entry reg;
    /* mem */
    struct record_full_mem_entry mem;
    /* end */
    struct record_full_end_entry end;
  } u;
};

/* If true, query if PREC cannot record memory
   change of next instruction.  */
bool record_full_memory_query = false;

struct record_full_core_buf_entry
{
  struct record_full_core_buf_entry *prev;
  struct target_section *p;
  bfd_byte *buf;
};

/* Record buf with core target.  */
static detached_regcache *record_full_core_regbuf = NULL;
static struct target_section *record_full_core_start;
static struct target_section *record_full_core_end;
static struct record_full_core_buf_entry *record_full_core_buf_list = NULL;

/* The following variables are used for managing the linked list that
   represents the execution log.

   record_full_first is the anchor that holds down the beginning of
   the list.

   record_full_list serves two functions:
     1) In record mode, it anchors the end of the list.
     2) In replay mode, it traverses the list and points to
        the next instruction that must be emulated.

   record_full_arch_list_head and record_full_arch_list_tail are used
   to manage a separate list, which is used to build up the change
   elements of the currently executing instruction during record mode.
   When this instruction has been completely annotated in the "arch
   list", it will be appended to the main execution log.  */

static struct record_full_entry record_full_first;
static struct record_full_entry *record_full_list = &record_full_first;
static struct record_full_entry *record_full_arch_list_head = NULL;
static struct record_full_entry *record_full_arch_list_tail = NULL;

/* true ask user. false auto delete the last struct record_full_entry.  */
static bool record_full_stop_at_limit = true;
/* Maximum allowed number of insns in execution log.  */
static unsigned int record_full_insn_max_num
	= DEFAULT_RECORD_FULL_INSN_MAX_NUM;
/* Actual count of insns presently in execution log.  */
static unsigned int record_full_insn_num = 0;
/* Count of insns logged so far (may be larger
   than count of insns presently in execution log).  */
static ULONGEST record_full_insn_count;

static const char record_longname[]
  = N_("Process record and replay target");
static const char record_doc[]
  = N_("Log program while executing and replay execution from log.");

/* Base class implementing functionality common to both the
   "record-full" and "record-core" targets.  */

class record_full_base_target : public target_ops
{
public:
  const target_info &info () const override = 0;

  strata stratum () const override { return record_stratum; }

  void close () override;
  void async (int) override;
  ptid_t wait (ptid_t, struct target_waitstatus *, int) override;
  bool stopped_by_watchpoint () override;
  bool stopped_data_address (CORE_ADDR *) override;

  bool stopped_by_sw_breakpoint () override;
  bool supports_stopped_by_sw_breakpoint () override;

  bool stopped_by_hw_breakpoint () override;
  bool supports_stopped_by_hw_breakpoint () override;

  bool 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;
  bool record_is_replaying (ptid_t ptid) override;
  bool 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.  */

static const target_info record_full_target_info = {
  "record-full",
  record_longname,
  record_doc,
};

class record_full_target final : public record_full_base_target
{
public:
  const target_info &info () const override
  { return record_full_target_info; }

  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.  */

static const target_info record_full_core_target_info = {
  "record-core",
  record_longname,
  record_doc,
};

class record_full_core_target final : public record_full_base_target
{
public:
  const target_info &info () const override
  { return record_full_core_target_info; }

  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;

  bool 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.  */

int
record_full_is_used (void)
{
  struct target_ops *t;

  t = find_record_target ();
  return (t == &record_full_ops
	  || t == &record_full_core_ops);
}


/* Command lists for "set/show record full".  */
static struct cmd_list_element *set_record_full_cmdlist;
static struct cmd_list_element *show_record_full_cmdlist;

/* Command list for "record full".  */
static struct cmd_list_element *record_full_cmdlist;

static void record_full_goto_insn (struct record_full_entry *entry,
				   enum exec_direction_kind dir);

/* Alloc and free functions for record_full_reg, record_full_mem, and
   record_full_end entries.  */

/* Alloc a record_full_reg record entry.  */

static inline struct record_full_entry *
record_full_reg_alloc (struct regcache *regcache, int regnum)
{
  struct record_full_entry *rec;
  struct gdbarch *gdbarch = regcache->arch ();

  rec = XCNEW (struct record_full_entry);
  rec->type = record_full_reg;
  rec->u.reg.num = regnum;
  rec->u.reg.len = register_size (gdbarch, regnum);
  if (rec->u.reg.len > sizeof (rec->u.reg.u.buf))
    rec->u.reg.u.ptr = (gdb_byte *) xmalloc (rec->u.reg.len);

  return rec;
}

/* Free a record_full_reg record entry.  */

static inline void
record_full_reg_release (struct record_full_entry *rec)
{
  gdb_assert (rec->type == record_full_reg);
  if (rec->u.reg.len > sizeof (rec->u.reg.u.buf))
    xfree (rec->u.reg.u.ptr);
  xfree (rec);
}

/* Alloc a record_full_mem record entry.  */

static inline struct record_full_entry *
record_full_mem_alloc (CORE_ADDR addr, int len)
{
  struct record_full_entry *rec;

  rec = XCNEW (struct record_full_entry);
  rec->type = record_full_mem;
  rec->u.mem.addr = addr;
  rec->u.mem.len = len;
  if (rec->u.mem.len > sizeof (rec->u.mem.u.buf))
    rec->u.mem.u.ptr = (gdb_byte *) xmalloc (len);

  return rec;
}

/* Free a record_full_mem record entry.  */

static inline void
record_full_mem_release (struct record_full_entry *rec)
{
  gdb_assert (rec->type == record_full_mem);
  if (rec->u.mem.len > sizeof (rec->u.mem.u.buf))
    xfree (rec->u.mem.u.ptr);
  xfree (rec);
}

/* Alloc a record_full_end record entry.  */

static inline struct record_full_entry *
record_full_end_alloc (void)
{
  struct record_full_entry *rec;

  rec = XCNEW (struct record_full_entry);
  rec->type = record_full_end;

  return rec;
}

/* Free a record_full_end record entry.  */

static inline void
record_full_end_release (struct record_full_entry *rec)
{
  xfree (rec);
}

/* Free one record entry, any type.
   Return entry->type, in case caller wants to know.  */

static inline enum record_full_type
record_full_entry_release (struct record_full_entry *rec)
{
  enum record_full_type type = rec->type;

  switch (type) {
  case record_full_reg:
    record_full_reg_release (rec);
    break;
  case record_full_mem:
    record_full_mem_release (rec);
    break;
  case record_full_end:
    record_full_end_release (rec);
    break;
  }
  return type;
}

/* Free all record entries in list pointed to by REC.  */

static void
record_full_list_release (struct record_full_entry *rec)
{
  if (!rec)
    return;

  while (rec->next)
    rec = rec->next;

  while (rec->prev)
    {
      rec = rec->prev;
      record_full_entry_release (rec->next);
    }

  if (rec == &record_full_first)
    {
      record_full_insn_num = 0;
      record_full_first.next = NULL;
    }
  else
    record_full_entry_release (rec);
}

/* Free all record entries forward of the given list position.  */

static void
record_full_list_release_following (struct record_full_entry *rec)
{
  struct record_full_entry *tmp = rec->next;

  rec->next = NULL;
  while (tmp)
    {
      rec = tmp->next;
      if (record_full_entry_release (tmp) == record_full_end)
	{
	  record_full_insn_num--;
	  record_full_insn_count--;
	}
      tmp = rec;
    }
}

/* Delete the first instruction from the beginning of the log, to make
   room for adding a new instruction at the end of the log.

   Note -- this function does not modify record_full_insn_num.  */

static void
record_full_list_release_first (void)
{
  struct record_full_entry *tmp;

  if (!record_full_first.next)
    return;

  /* Loop until a record_full_end.  */
  while (1)
    {
      /* Cut record_full_first.next out of the linked list.  */
      tmp = record_full_first.next;
      record_full_first.next = tmp->next;
      tmp->next->prev = &record_full_first;

      /* tmp is now isolated, and can be deleted.  */
      if (record_full_entry_release (tmp) == record_full_end)
	break;	/* End loop at first record_full_end.  */

      if (!record_full_first.next)
	{
	  gdb_assert (record_full_insn_num == 1);
	  break;	/* End loop when list is empty.  */
	}
    }
}

/* Add a struct record_full_entry to record_full_arch_list.  */

static void
record_full_arch_list_add (struct record_full_entry *rec)
{
  if (record_debug > 1)
    fprintf_unfiltered (gdb_stdlog,
			"Process record: record_full_arch_list_add %s.\n",
			host_address_to_string (rec));

  if (record_full_arch_list_tail)
    {
      record_full_arch_list_tail->next = rec;
      rec->prev = record_full_arch_list_tail;
      record_full_arch_list_tail = rec;
    }
  else
    {
      record_full_arch_list_head = rec;
      record_full_arch_list_tail = rec;
    }
}

/* Return the value storage location of a record entry.  */
static inline gdb_byte *
record_full_get_loc (struct record_full_entry *rec)
{
  switch (rec->type) {
  case record_full_mem:
    if (rec->u.mem.len > sizeof (rec->u.mem.u.buf))
      return rec->u.mem.u.ptr;
    else
      return rec->u.mem.u.buf;
  case record_full_reg:
    if (rec->u.reg.len > sizeof (rec->u.reg.u.buf))
      return rec->u.reg.u.ptr;
    else
      return rec->u.reg.u.buf;
  case record_full_end:
  default:
    gdb_assert_not_reached ("unexpected record_full_entry type");
    return NULL;
  }
}

/* Record the value of a register NUM to record_full_arch_list.  */

int
record_full_arch_list_add_reg (struct regcache *regcache, int regnum)
{
  struct record_full_entry *rec;

  if (record_debug > 1)
    fprintf_unfiltered (gdb_stdlog,
			"Process record: add register num = %d to "
			"record list.\n",
			regnum);

  rec = record_full_reg_alloc (regcache, regnum);

  regcache->raw_read (regnum, record_full_get_loc (rec));

  record_full_arch_list_add (rec);

  return 0;
}

/* Record the value of a region of memory whose address is ADDR and
   length is LEN to record_full_arch_list.  */

int
record_full_arch_list_add_mem (CORE_ADDR addr, int len)
{
  struct record_full_entry *rec;

  if (record_debug > 1)
    fprintf_unfiltered (gdb_stdlog,
			"Process record: add mem addr = %s len = %d to "
			"record list.\n",
			paddress (target_gdbarch (), addr), len);

  if (!addr)	/* FIXME: Why?  Some arch must permit it...  */
    return 0;

  rec = record_full_mem_alloc (addr, len);

  if (record_read_memory (target_gdbarch (), addr,
			  record_full_get_loc (rec), len))
    {
      record_full_mem_release (rec);
      return -1;
    }

  record_full_arch_list_add (rec);

  return 0;
}

/* Add a record_full_end type struct record_full_entry to
   record_full_arch_list.  */

int
record_full_arch_list_add_end (void)
{
  struct record_full_entry *rec;

  if (record_debug > 1)
    fprintf_unfiltered (gdb_stdlog,
			"Process record: add end to arch list.\n");

  rec = record_full_end_alloc ();
  rec->u.end.sigval = GDB_SIGNAL_0;
  rec->u.end.insn_num = ++record_full_insn_count;

  record_full_arch_list_add (rec);

  return 0;
}

static void
record_full_check_insn_num (void)
{
  if (record_full_insn_num == record_full_insn_max_num)
    {
      /* Ask user what to do.  */
      if (record_full_stop_at_limit)
	{
	  if (!yquery (_("Do you want to auto delete previous execution "
			"log entries when record/replay buffer becomes "
			"full (record full stop-at-limit)?")))
	    error (_("Process record: stopped by user."));
	  record_full_stop_at_limit = 0;
	}
    }
}

/* Before inferior step (when GDB record the running message, inferior
   only can step), GDB will call this function to record the values to
   record_full_list.  This function will call gdbarch_process_record to
   record the running message of inferior and set them to
   record_full_arch_list, and add it to record_full_list.  */

static void
record_full_message (struct regcache *regcache, enum gdb_signal signal)
{
  int ret;
  struct gdbarch *gdbarch = regcache->arch ();

  try
    {
      record_full_arch_list_head = NULL;
      record_full_arch_list_tail = NULL;

      /* Check record_full_insn_num.  */
      record_full_check_insn_num ();

      /* If gdb sends a signal value to target_resume,
	 save it in the 'end' field of the previous instruction.

	 Maybe process record should record what really happened,
	 rather than what gdb pretends has happened.

	 So if Linux delivered the signal to the child process during
	 the record mode, we will record it and deliver it again in
	 the replay mode.

	 If user says "ignore this signal" during the record mode, then
	 it will be ignored again during the replay mode (no matter if
	 the user says something different, like "deliver this signal"
	 during the replay mode).

	 User should understand that nothing he does during the replay
	 mode will change the behavior of the child.  If he tries,
	 then that is a user error.

	 But we should still deliver the signal to gdb during the replay,
	 if we delivered it during the recording.  Therefore we should
	 record the signal during record_full_wait, not
	 record_full_resume.  */
      if (record_full_list != &record_full_first)  /* FIXME better way
						      to check */
	{
	  gdb_assert (record_full_list->type == record_full_end);
	  record_full_list->u.end.sigval = signal;
	}

      if (signal == GDB_SIGNAL_0
	  || !gdbarch_process_record_signal_p (gdbarch))
	ret = gdbarch_process_record (gdbarch,
				      regcache,
				      regcache_read_pc (regcache));
      else
	ret = gdbarch_process_record_signal (gdbarch,
					     regcache,
					     signal);

      if (ret > 0)
	error (_("Process record: inferior program stopped."));
      if (ret < 0)
	error (_("Process record: failed to record execution log."));
    }
  catch (const gdb_exception &ex)
    {
      record_full_list_release (record_full_arch_list_tail);
      throw;
    }

  record_full_list->next = record_full_arch_list_head;
  record_full_arch_list_head->prev = record_full_list;
  record_full_list = record_full_arch_list_tail;

  if (record_full_insn_num == record_full_insn_max_num)
    record_full_list_release_first ();
  else
    record_full_insn_num++;
}

static bool
record_full_message_wrapper_safe (struct regcache *regcache,
				  enum gdb_signal signal)
{
  try
    {
      record_full_message (regcache, signal);
    }
  catch (const gdb_exception &ex)
    {
      exception_print (gdb_stderr, ex);
      return false;
    }

  return true;
}

/* Set to 1 if record_full_store_registers and record_full_xfer_partial
   doesn't need record.  */

static int record_full_gdb_operation_disable = 0;

scoped_restore_tmpl<int>
record_full_gdb_operation_disable_set (void)
{
  return make_scoped_restore (&record_full_gdb_operation_disable, 1);
}

/* Flag set to TRUE for target_stopped_by_watchpoint.  */
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
   entries and memory entries, followed by an 'end' entry.  */

static inline void
record_full_exec_insn (struct regcache *regcache,
		       struct gdbarch *gdbarch,
		       struct record_full_entry *entry)
{
  switch (entry->type)
    {
    case record_full_reg: /* reg */
      {
	gdb::byte_vector reg (entry->u.reg.len);

        if (record_debug > 1)
          fprintf_unfiltered (gdb_stdlog,
                              "Process record: record_full_reg %s to "
                              "inferior num = %d.\n",
                              host_address_to_string (entry),
                              entry->u.reg.num);

        regcache->cooked_read (entry->u.reg.num, reg.data ());
        regcache->cooked_write (entry->u.reg.num, record_full_get_loc (entry));
        memcpy (record_full_get_loc (entry), reg.data (), entry->u.reg.len);
      }
      break;

    case record_full_mem: /* mem */
      {
	/* Nothing to do if the entry is flagged not_accessible.  */
        if (!entry->u.mem.mem_entry_not_accessible)
          {
	    gdb::byte_vector mem (entry->u.mem.len);

            if (record_debug > 1)
              fprintf_unfiltered (gdb_stdlog,
                                  "Process record: record_full_mem %s to "
                                  "inferior addr = %s len = %d.\n",
                                  host_address_to_string (entry),
                                  paddress (gdbarch, entry->u.mem.addr),
                                  entry->u.mem.len);

            if (record_read_memory (gdbarch,
				    entry->u.mem.addr, mem.data (),
				    entry->u.mem.len))
	      entry->u.mem.mem_entry_not_accessible = 1;
            else
              {
                if (target_write_memory (entry->u.mem.addr, 
					 record_full_get_loc (entry),
					 entry->u.mem.len))
                  {
                    entry->u.mem.mem_entry_not_accessible = 1;
                    if (record_debug)
                      warning (_("Process record: error writing memory at "
				 "addr = %s len = %d."),
                               paddress (gdbarch, entry->u.mem.addr),
                               entry->u.mem.len);
                  }
                else
		  {
		    memcpy (record_full_get_loc (entry), mem.data (),
			    entry->u.mem.len);

		    /* We've changed memory --- check if a hardware
		       watchpoint should trap.  Note that this
		       presently assumes the target beneath supports
		       continuable watchpoints.  On non-continuable
		       watchpoints target, we'll want to check this
		       _before_ actually doing the memory change, and
		       not doing the change at all if the watchpoint
		       traps.  */
		    if (hardware_watchpoint_inserted_in_range
			(regcache->aspace (),
			 entry->u.mem.addr, entry->u.mem.len))
		      record_full_stop_reason = TARGET_STOPPED_BY_WATCHPOINT;
		  }
              }
          }
      }
      break;
    }
}

static void record_full_restore (void);

/* Asynchronous signal handle registered as event loop source for when
   we have pending events ready to be passed to the core.  */

static struct async_event_handler *record_full_async_inferior_event_token;

static void
record_full_async_inferior_event_handler (gdb_client_data data)
{
  inferior_event_handler (INF_REG_EVENT, NULL);
}

/* Open the process record target for 'core' files.  */

static void
record_full_core_open_1 (const char *name, int from_tty)
{
  struct regcache *regcache = get_current_regcache ();
  int regnum = gdbarch_num_regs (regcache->arch ());
  int i;

  /* Get record_full_core_regbuf.  */
  target_fetch_registers (regcache, -1);
  record_full_core_regbuf = new detached_regcache (regcache->arch (), false);

  for (i = 0; i < regnum; i ++)
    record_full_core_regbuf->raw_supply (i, *regcache);

  /* Get record_full_core_start and record_full_core_end.  */
  if (build_section_table (core_bfd, &record_full_core_start,
			   &record_full_core_end))
    {
      delete record_full_core_regbuf;
      record_full_core_regbuf = NULL;
      error (_("\"%s\": Can't find sections: %s"),
	     bfd_get_filename (core_bfd), bfd_errmsg (bfd_get_error ()));
    }

  push_target (&record_full_core_ops);
  record_full_restore ();
}

/* Open the process record target for 'live' processes.  */

static void
record_full_open_1 (const char *name, int from_tty)
{
  if (record_debug)
    fprintf_unfiltered (gdb_stdlog, "Process record: record_full_open_1\n");

  /* check exec */
  if (!target_has_execution)
    error (_("Process record: the program is not being run."));
  if (non_stop)
    error (_("Process record target can't debug inferior in non-stop mode "
	     "(non-stop)."));

  if (!gdbarch_process_record_p (target_gdbarch ()))
    error (_("Process record: the current architecture doesn't support "
	     "record function."));

  push_target (&record_full_ops);
}

static void record_full_init_record_breakpoints (void);

/* Open the process record target.  */

static void
record_full_open (const char *name, int from_tty)
{
  if (record_debug)
    fprintf_unfiltered (gdb_stdlog, "Process record: record_full_open\n");

  record_preopen ();

  /* Reset */
  record_full_insn_num = 0;
  record_full_insn_count = 0;
  record_full_list = &record_full_first;
  record_full_list->next = NULL;

  if (core_bfd)
    record_full_core_open_1 (name, from_tty);
  else
    record_full_open_1 (name, from_tty);

  /* Register extra event sources in the event loop.  */
  record_full_async_inferior_event_token
    = create_async_event_handler (record_full_async_inferior_event_handler,
				  NULL);

  record_full_init_record_breakpoints ();

  gdb::observers::record_changed.notify (current_inferior (),  1, "full", NULL);
}

/* "close" target method.  Close the process record target.  */

void
record_full_base_target::close ()
{
  struct record_full_core_buf_entry *entry;

  if (record_debug)
    fprintf_unfiltered (gdb_stdlog, "Process record: record_full_close\n");

  record_full_list_release (record_full_list);

  /* Release record_full_core_regbuf.  */
  if (record_full_core_regbuf)
    {
      delete record_full_core_regbuf;
      record_full_core_regbuf = NULL;
    }

  /* Release record_full_core_buf_list.  */
  while (record_full_core_buf_list)
    {
      entry = record_full_core_buf_list;
      record_full_core_buf_list = record_full_core_buf_list->prev;
      xfree (entry);
    }

  if (record_full_async_inferior_event_token)
    delete_async_event_handler (&record_full_async_inferior_event_token);
}

/* "async" target method.  */

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);

  beneath ()->async (enable);
}

static int record_full_resume_step = 0;

/* True if we've been resumed, and so each record_full_wait call should
   advance execution.  If this is false, record_full_wait will return a
   TARGET_WAITKIND_IGNORE.  */
static int record_full_resumed = 0;

/* The execution direction of the last resume we got.  This is
   necessary for async mode.  Vis (order is not strictly accurate):

   1. user has the global execution direction set to forward
   2. user does a reverse-step command
   3. record_full_resume is called with global execution direction
      temporarily switched to reverse
   4. GDB's execution direction is reverted back to forward
   5. target record notifies event loop there's an event to handle
   6. infrun asks the target which direction was it going, and switches
      the global execution direction accordingly (to reverse)
   7. infrun polls an event out of the record target, and handles it
   8. GDB goes back to the event loop, and goto #4.
*/
static enum exec_direction_kind record_full_execution_dir = EXEC_FORWARD;

/* "resume" target method.  Resume the process record target.  */

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;

  if (!RECORD_FULL_IS_REPLAY)
    {
      struct gdbarch *gdbarch = target_thread_architecture (ptid);

      record_full_message (get_current_regcache (), 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 supports soft single step.  */
              if (thread_has_single_step_breakpoints_set (inferior_thread ()))
                {
                  /* This is a soft single step.  */
                  record_full_resume_step = 1;
                }
              else
		step = !insert_single_step_breakpoints (gdbarch);
            }
        }

      /* Make sure the target beneath reports all signals.  */
      target_pass_signals ({});

      this->beneath ()->resume (ptid, step, signal);
    }

  /* 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 (1);
}

/* "commit_resume" method for process record target.  */

void
record_full_target::commit_resume ()
{
  if (!RECORD_FULL_IS_REPLAY)
    beneath ()->commit_resume ();
}

static int record_full_get_sig = 0;

/* SIGINT signal handler, registered by "wait" method.  */

static void
record_full_sig_handler (int signo)
{
  if (record_debug)
    fprintf_unfiltered (gdb_stdlog, "Process record: get a signal\n");

  /* It will break the running inferior in replay mode.  */
  record_full_resume_step = 1;

  /* It will let record_full_wait set inferior status to get the signal
     SIGINT.  */
  record_full_get_sig = 1;
}

/* "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 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 wait method just records them and keeps
   singlestepping.

   In replay mode, this function emulates the recorded execution log, 
   one instruction at a time (forward or backward), and determines 
   where to stop.  */

static ptid_t
record_full_wait_1 (struct target_ops *ops,
		    ptid_t ptid, struct target_waitstatus *status,
		    int options)
{
  scoped_restore restore_operation_disable
    = record_full_gdb_operation_disable_set ();

  if (record_debug)
    fprintf_unfiltered (gdb_stdlog,
			"Process record: record_full_wait "
			"record_full_resume_step = %d, "
			"record_full_resumed = %d, direction=%s\n",
			record_full_resume_step, record_full_resumed,
			record_full_execution_dir == EXEC_FORWARD
			? "forward" : "reverse");

  if (!record_full_resumed)
    {
      gdb_assert ((options & TARGET_WNOHANG) != 0);

      /* No interesting event.  */
      status->kind = TARGET_WAITKIND_IGNORE;
      return minus_one_ptid;
    }

  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)
	{
	  /* This is a single step.  */
	  return ops->beneath ()->wait (ptid, status, options);
	}
      else
	{
	  /* This is not a single step.  */
	  ptid_t ret;
	  CORE_ADDR tmp_pc;
	  struct gdbarch *gdbarch = target_thread_architecture (inferior_ptid);

	  while (1)
	    {
	      ret = ops->beneath ()->wait (ptid, status, options);
	      if (status->kind == TARGET_WAITKIND_IGNORE)
		{
		  if (record_debug)
		    fprintf_unfiltered (gdb_stdlog,
					"Process record: record_full_wait "
					"target beneath not done yet\n");
		  return ret;
		}

	      for (thread_info *tp : all_non_exited_threads ())
                delete_single_step_breakpoints (tp);

	      if (record_full_resume_step)
		return ret;

	      /* Is this a SIGTRAP?  */
	      if (status->kind == TARGET_WAITKIND_STOPPED
		  && status->value.sig == GDB_SIGNAL_TRAP)
		{
		  struct regcache *regcache;
		  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
		     interested in the event.  */

		  registers_changed ();
		  regcache = get_current_regcache ();
		  tmp_pc = regcache_read_pc (regcache);
		  const struct address_space *aspace = regcache->aspace ();

		  if (target_stopped_by_watchpoint ())
		    {
		      /* Always interested in watchpoints.  */
		    }
		  else if (record_check_stopped_by_breakpoint (aspace, tmp_pc,
							       stop_reason_p))
		    {
		      /* There is a breakpoint here.  Let the core
			 handle it.  */
		    }
		  else
		    {
		      /* 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_full_message_wrapper_safe (regcache,
							     GDB_SIGNAL_0))
  			{
                           status->kind = TARGET_WAITKIND_STOPPED;
                           status->value.sig = GDB_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 ();

			  step = !insert_single_step_breakpoints (gdbarch);

			  set_executing (inferior_ptid, 1);
			}

		      if (record_debug)
			fprintf_unfiltered (gdb_stdlog,
					    "Process record: record_full_wait "
					    "issuing one more step in the "
					    "target beneath\n");
		      ops->beneath ()->resume (ptid, step, GDB_SIGNAL_0);
		      ops->beneath ()->commit_resume ();
		      continue;
		    }
		}

	      /* The inferior is broken by a breakpoint or a signal.  */
	      break;
	    }

	  return ret;
	}
    }
  else
    {
      struct regcache *regcache = get_current_regcache ();
      struct gdbarch *gdbarch = regcache->arch ();
      const struct address_space *aspace = regcache->aspace ();
      int continue_flag = 1;
      int first_record_full_end = 1;

      try
	{
	  CORE_ADDR tmp_pc;

	  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 (record_check_stopped_by_breakpoint (aspace, tmp_pc,
						      &record_full_stop_reason))
		{
		  if (record_debug)
		    fprintf_unfiltered (gdb_stdlog,
					"Process record: break at %s.\n",
					paddress (gdbarch, tmp_pc));
		  goto replay_out;
		}
	    }

	  /* If GDB is in terminal_inferior mode, it will not get the
	     signal.  And in GDB replay mode, GDB doesn't need to be
	     in terminal_inferior mode, because inferior will not
	     executed.  Then set it to terminal_ours to make GDB get
	     the signal.  */
	  target_terminal::ours ();

	  /* In EXEC_FORWARD mode, record_full_list points to the tail of prev
	     instruction.  */
	  if (execution_direction == EXEC_FORWARD && record_full_list->next)
	    record_full_list = record_full_list->next;

	  /* Loop over the record_full_list, looking for the next place to
	     stop.  */
	  do
	    {
	      /* Check for beginning and end of log.  */
	      if (execution_direction == EXEC_REVERSE
		  && record_full_list == &record_full_first)
		{
		  /* Hit beginning of record log in reverse.  */
		  status->kind = TARGET_WAITKIND_NO_HISTORY;
		  break;
		}
	      if (execution_direction != EXEC_REVERSE
		  && !record_full_list->next)
		{
		  /* Hit end of record log going forward.  */
		  status->kind = TARGET_WAITKIND_NO_HISTORY;
		  break;
		}

	      record_full_exec_insn (regcache, gdbarch, record_full_list);

	      if (record_full_list->type == record_full_end)
		{
		  if (record_debug > 1)
		    fprintf_unfiltered
		      (gdb_stdlog,
		       "Process record: record_full_end %s to "
		       "inferior.\n",
		       host_address_to_string (record_full_list));

		  if (first_record_full_end
		      && execution_direction == EXEC_REVERSE)
		    {
		      /* When reverse execute, the first
			 record_full_end is the part of current
			 instruction.  */
		      first_record_full_end = 0;
		    }
		  else
		    {
		      /* In EXEC_REVERSE mode, this is the
			 record_full_end of prev instruction.  In
			 EXEC_FORWARD mode, this is the
			 record_full_end of current instruction.  */
		      /* step */
		      if (record_full_resume_step)
			{
			  if (record_debug > 1)
			    fprintf_unfiltered (gdb_stdlog,
						"Process record: step.\n");
			  continue_flag = 0;
			}

		      /* check breakpoint */
		      tmp_pc = regcache_read_pc (regcache);
		      if (record_check_stopped_by_breakpoint
			  (aspace, tmp_pc, &record_full_stop_reason))
			{
			  if (record_debug)
			    fprintf_unfiltered (gdb_stdlog,
						"Process record: break "
						"at %s.\n",
						paddress (gdbarch, tmp_pc));

			  continue_flag = 0;
			}

		      if (record_full_stop_reason
			  == TARGET_STOPPED_BY_WATCHPOINT)
			{
			  if (record_debug)
			    fprintf_unfiltered (gdb_stdlog,
						"Process record: hit hw "
						"watchpoint.\n");
			  continue_flag = 0;
			}
		      /* Check target signal */
		      if (record_full_list->u.end.sigval != GDB_SIGNAL_0)
			/* FIXME: better way to check */
			continue_flag = 0;
		    }
		}

	      if (continue_flag)
		{
		  if (execution_direction == EXEC_REVERSE)
		    {
		      if (record_full_list->prev)
			record_full_list = record_full_list->prev;
		    }
		  else
		    {
		      if (record_full_list->next)
			record_full_list = record_full_list->next;
		    }
		}
	    }
	  while (continue_flag);

	replay_out:
	  if (record_full_get_sig)
	    status->value.sig = GDB_SIGNAL_INT;
	  else if (record_full_list->u.end.sigval != GDB_SIGNAL_0)
	    /* FIXME: better way to check */
	    status->value.sig = record_full_list->u.end.sigval;
	  else
	    status->value.sig = GDB_SIGNAL_TRAP;
	}
      catch (const gdb_exception &ex)
	{
	  if (execution_direction == EXEC_REVERSE)
	    {
	      if (record_full_list->next)
		record_full_list = record_full_list->next;
	    }
	  else
	    record_full_list = record_full_list->prev;

	  throw;
	}
    }

  signal (SIGINT, handle_sigint);

  return inferior_ptid;
}

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 (this, ptid, status, options);
  if (status->kind != TARGET_WAITKIND_IGNORE)
    {
      /* We're reporting a stop.  Make sure any spurious
	 target_wait(WNOHANG) doesn't advance the target until the
	 core wants us resumed again.  */
      record_full_resumed = 0;
    }
  return return_ptid;
}

bool
record_full_base_target::stopped_by_watchpoint ()
{
  if (RECORD_FULL_IS_REPLAY)
    return record_full_stop_reason == TARGET_STOPPED_BY_WATCHPOINT;
  else
    return beneath ()->stopped_by_watchpoint ();
}

bool
record_full_base_target::stopped_data_address (CORE_ADDR *addr_p)
{
  if (RECORD_FULL_IS_REPLAY)
    return false;
  else
    return this->beneath ()->stopped_data_address (addr_p);
}

/* The stopped_by_sw_breakpoint method of target record-full.  */

bool
record_full_base_target::stopped_by_sw_breakpoint ()
{
  return record_full_stop_reason == TARGET_STOPPED_BY_SW_BREAKPOINT;
}

/* The supports_stopped_by_sw_breakpoint method of target
   record-full.  */

bool
record_full_base_target::supports_stopped_by_sw_breakpoint ()
{
  return true;
}

/* The stopped_by_hw_breakpoint method of target record-full.  */

bool
record_full_base_target::stopped_by_hw_breakpoint ()
{
  return record_full_stop_reason == TARGET_STOPPED_BY_HW_BREAKPOINT;
}

/* The supports_stopped_by_sw_breakpoint method of target
   record-full.  */

bool
record_full_base_target::supports_stopped_by_hw_breakpoint ()
{
  return true;
}

/* Record registers change (by user or by GDB) to list as an instruction.  */

static void
record_full_registers_change (struct regcache *regcache, int regnum)
{
  /* Check record_full_insn_num.  */
  record_full_check_insn_num ();

  record_full_arch_list_head = NULL;
  record_full_arch_list_tail = NULL;

  if (regnum < 0)
    {
      int i;

      for (i = 0; i < gdbarch_num_regs (regcache->arch ()); i++)
	{
	  if (record_full_arch_list_add_reg (regcache, i))
	    {
	      record_full_list_release (record_full_arch_list_tail);
	      error (_("Process record: failed to record execution log."));
	    }
	}
    }
  else
    {
      if (record_full_arch_list_add_reg (regcache, regnum))
	{
	  record_full_list_release (record_full_arch_list_tail);
	  error (_("Process record: failed to record execution log."));
	}
    }
  if (record_full_arch_list_add_end ())
    {
      record_full_list_release (record_full_arch_list_tail);
      error (_("Process record: failed to record execution log."));
    }
  record_full_list->next = record_full_arch_list_head;
  record_full_arch_list_head->prev = record_full_list;
  record_full_list = record_full_arch_list_tail;

  if (record_full_insn_num == record_full_insn_max_num)
    record_full_list_release_first ();
  else
    record_full_insn_num++;
}

/* "store_registers" method for process record target.  */

void
record_full_target::store_registers (struct regcache *regcache, int regno)
{
  if (!record_full_gdb_operation_disable)
    {
      if (RECORD_FULL_IS_REPLAY)
	{
	  int n;

	  /* Let user choose if he wants to write register or not.  */
	  if (regno < 0)
	    n =
	      query (_("Because GDB is in replay mode, changing the "
		       "value of a register will make the execution "
		       "log unusable from this point onward.  "
		       "Change all registers?"));
	  else
	    n =
	      query (_("Because GDB is in replay mode, changing the value "
		       "of a register will make the execution log unusable "
		       "from this point onward.  Change register %s?"),
		      gdbarch_register_name (regcache->arch (),
					       regno));

	  if (!n)
	    {
	      /* Invalidate the value of regcache that was set in function
	         "regcache_raw_write".  */
	      if (regno < 0)
		{
		  int i;

		  for (i = 0;
		       i < gdbarch_num_regs (regcache->arch ());
		       i++)
		    regcache->invalidate (i);
		}
	      else
		regcache->invalidate (regno);

	      error (_("Process record canceled the operation."));
	    }

	  /* Destroy the record from here forward.  */
	  record_full_list_release_following (record_full_list);
	}

      record_full_registers_change (regcache, regno);
    }
  this->beneath ()->store_registers (regcache, regno);
}

/* "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.  */

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
	  || object == TARGET_OBJECT_RAW_MEMORY) && writebuf)
    {
      if (RECORD_FULL_IS_REPLAY)
	{
	  /* Let user choose if he wants to write memory or not.  */
	  if (!query (_("Because GDB is in replay mode, writing to memory "
		        "will make the execution log unusable from this "
		        "point onward.  Write memory at address %s?"),
		       paddress (target_gdbarch (), offset)))
	    error (_("Process record canceled the operation."));

	  /* Destroy the record from here forward.  */
	  record_full_list_release_following (record_full_list);
	}

      /* Check record_full_insn_num */
      record_full_check_insn_num ();

      /* Record registers change to list as an instruction.  */
      record_full_arch_list_head = NULL;
      record_full_arch_list_tail = NULL;
      if (record_full_arch_list_add_mem (offset, len))
	{
	  record_full_list_release (record_full_arch_list_tail);
	  if (record_debug)
	    fprintf_unfiltered (gdb_stdlog,
				"Process record: failed to record "
				"execution log.");
	  return TARGET_XFER_E_IO;
	}
      if (record_full_arch_list_add_end ())
	{
	  record_full_list_release (record_full_arch_list_tail);
	  if (record_debug)
	    fprintf_unfiltered (gdb_stdlog,
				"Process record: failed to record "
				"execution log.");
	  return TARGET_XFER_E_IO;
	}
      record_full_list->next = record_full_arch_list_head;
      record_full_arch_list_head->prev = record_full_list;
      record_full_list = record_full_arch_list_tail;

      if (record_full_insn_num == record_full_insn_max_num)
	record_full_list_release_first ();
      else
	record_full_insn_num++;
    }

  return this->beneath ()->xfer_partial (object, annex, readbuf, writebuf,
					 offset, len, xfered_len);
}

/* This structure represents a breakpoint inserted while the record
   target is active.  We use this to know when to install/remove
   breakpoints in/from the target beneath.  For example, a breakpoint
   may be inserted while recording, but removed when not replaying nor
   recording.  In that case, the breakpoint had not been inserted on
   the target beneath, so we should not try to remove it there.  */

struct record_full_breakpoint
{
  record_full_breakpoint (struct address_space *address_space_,
			  CORE_ADDR addr_,
			  bool in_target_beneath_)
    : address_space (address_space_),
      addr (addr_),
      in_target_beneath (in_target_beneath_)
  {
  }

  /* The address and address space the breakpoint was set at.  */
  struct address_space *address_space;
  CORE_ADDR addr;

  /* True when the breakpoint has been also installed in the target
     beneath.  This will be false for breakpoints set during replay or
     when recording.  */
  bool in_target_beneath;
};

/* The list of breakpoints inserted while the record target is
   active.  */
static std::vector<record_full_breakpoint> record_full_breakpoints;

static void
record_full_sync_record_breakpoints (struct bp_location *loc, void *data)
{
  if (loc->loc_type != bp_loc_software_breakpoint)
      return;

  if (loc->inserted)
    {
      record_full_breakpoints.emplace_back
	(loc->target_info.placed_address_space,
	 loc->target_info.placed_address,
	 1);
    }
}

/* Sync existing breakpoints to record_full_breakpoints.  */

static void
record_full_init_record_breakpoints (void)
{
  record_full_breakpoints.clear ();

  iterate_over_bp_locations (record_full_sync_record_breakpoints);
}

/* Behavior is conditional on RECORD_FULL_IS_REPLAY.  We will not actually
   insert or remove breakpoints in the real target when replaying, nor
   when recording.  */

int
record_full_target::insert_breakpoint (struct gdbarch *gdbarch,
				       struct bp_target_info *bp_tgt)
{
  bool in_target_beneath = false;

  if (!RECORD_FULL_IS_REPLAY)
    {
      /* When recording, we currently always single-step, so we don't
	 really need to install regular breakpoints in the inferior.
	 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.  */

      scoped_restore restore_operation_disable
	= record_full_gdb_operation_disable_set ();

      int ret = this->beneath ()->insert_breakpoint (gdbarch, bp_tgt);
      if (ret != 0)
	return ret;

      in_target_beneath = true;
    }

  /* Use the existing entries if found in order to avoid duplication
     in record_full_breakpoints.  */

  for (const record_full_breakpoint &bp : record_full_breakpoints)
    {
      if (bp.addr == bp_tgt->placed_address
	  && bp.address_space == bp_tgt->placed_address_space)
	{
	  gdb_assert (bp.in_target_beneath == in_target_beneath);
	  return 0;
	}
    }

  record_full_breakpoints.emplace_back (bp_tgt->placed_address_space,
					bp_tgt->placed_address,
					in_target_beneath);
  return 0;
}

/* "remove_breakpoint" method for process record target.  */

int
record_full_target::remove_breakpoint (struct gdbarch *gdbarch,
				       struct bp_target_info *bp_tgt,
				       enum remove_bp_reason reason)
{
  for (auto iter = record_full_breakpoints.begin ();
       iter != record_full_breakpoints.end ();
       ++iter)
    {
      struct record_full_breakpoint &bp = *iter;

      if (bp.addr == bp_tgt->placed_address
	  && bp.address_space == bp_tgt->placed_address_space)
	{
	  if (bp.in_target_beneath)
	    {
	      scoped_restore restore_operation_disable
		= record_full_gdb_operation_disable_set ();

	      int ret = this->beneath ()->remove_breakpoint (gdbarch, bp_tgt,
							     reason);
	      if (ret != 0)
		return ret;
	    }

	  if (reason == REMOVE_BREAKPOINT)
	    unordered_remove (record_full_breakpoints, iter);
	  return 0;
	}
    }

  gdb_assert_not_reached ("removing unknown breakpoint");
}

/* "can_execute_reverse" method for process record target.  */

bool
record_full_base_target::can_execute_reverse ()
{
  return true;
}

/* "get_bookmark" method for process record and prec over core.  */

gdb_byte *
record_full_base_target::get_bookmark (const char *args, int from_tty)
{
  char *ret = NULL;

  /* Return stringified form of instruction count.  */
  if (record_full_list && record_full_list->type == record_full_end)
    ret = xstrdup (pulongest (record_full_list->u.end.insn_num));

  if (record_debug)
    {
      if (ret)
	fprintf_unfiltered (gdb_stdlog,
			    "record_full_get_bookmark returns %s\n", ret);
      else
	fprintf_unfiltered (gdb_stdlog,
			    "record_full_get_bookmark returns NULL\n");
    }
  return (gdb_byte *) ret;
}

/* "goto_bookmark" method for process record and prec over core.  */

void
record_full_base_target::goto_bookmark (const gdb_byte *raw_bookmark,
					int from_tty)
{
  const char *bookmark = (const char *) raw_bookmark;

  if (record_debug)
    fprintf_unfiltered (gdb_stdlog,
			"record_full_goto_bookmark receives %s\n", bookmark);

  std::string name_holder;
  if (bookmark[0] == '\'' || bookmark[0] == '\"')
    {
      if (bookmark[strlen (bookmark) - 1] != bookmark[0])
	error (_("Unbalanced quotes: %s"), bookmark);

      name_holder = std::string (bookmark + 1, strlen (bookmark) - 2);
      bookmark = name_holder.c_str ();
    }

  record_goto (bookmark);
}

enum exec_direction_kind
record_full_base_target::execution_direction ()
{
  return record_full_execution_dir;
}

/* The record_method method of target record-full.  */

enum record_method
record_full_base_target::record_method (ptid_t ptid)
{
  return RECORD_METHOD_FULL;
}

void
record_full_base_target::info_record ()
{
  struct record_full_entry *p;

  if (RECORD_FULL_IS_REPLAY)
    printf_filtered (_("Replay mode:\n"));
  else
    printf_filtered (_("Record mode:\n"));

  /* Find entry for first actual instruction in the log.  */
  for (p = record_full_first.next;
       p != NULL && p->type != record_full_end;
       p = p->next)
    ;

  /* Do we have a log at all?  */
  if (p != NULL && p->type == record_full_end)
    {
      /* Display instruction number for first instruction in the log.  */
      printf_filtered (_("Lowest recorded instruction number is %s.\n"),
		       pulongest (p->u.end.insn_num));

      /* If in replay mode, display where we are in the log.  */
      if (RECORD_FULL_IS_REPLAY)
	printf_filtered (_("Current instruction number is %s.\n"),
			 pulongest (record_full_list->u.end.insn_num));

      /* Display instruction number for last instruction in the log.  */
      printf_filtered (_("Highest recorded instruction number is %s.\n"),
		       pulongest (record_full_insn_count));

      /* Display log count.  */
      printf_filtered (_("Log contains %u instructions.\n"),
		       record_full_insn_num);
    }
  else
    printf_filtered (_("No instructions have been logged.\n"));

  /* Display max log size.  */
  printf_filtered (_("Max logged instructions is %u.\n"),
		   record_full_insn_max_num);
}

bool
record_full_base_target::supports_delete_record ()
{
  return true;
}

/* The "delete_record" target method.  */

void
record_full_base_target::delete_record ()
{
  record_full_list_release_following (record_full_list);
}

/* The "record_is_replaying" target method.  */

bool
record_full_base_target::record_is_replaying (ptid_t ptid)
{
  return RECORD_FULL_IS_REPLAY;
}

/* The "record_will_replay" target method.  */

bool
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
     execution, this needs to be changed.  */

  return RECORD_FULL_IS_REPLAY || dir == EXEC_REVERSE;
}

/* Go to a specific entry.  */

static void
record_full_goto_entry (struct record_full_entry *p)
{
  if (p == NULL)
    error (_("Target insn not found."));
  else if (p == record_full_list)
    error (_("Already at target insn."));
  else if (p->u.end.insn_num > record_full_list->u.end.insn_num)
    {
      printf_filtered (_("Go forward to insn number %s\n"),
		       pulongest (p->u.end.insn_num));
      record_full_goto_insn (p, EXEC_FORWARD);
    }
  else
    {
      printf_filtered (_("Go backward to insn number %s\n"),
		       pulongest (p->u.end.insn_num));
      record_full_goto_insn (p, EXEC_REVERSE);
    }

  registers_changed ();
  reinit_frame_cache ();
  inferior_thread ()->suspend.stop_pc
    = regcache_read_pc (get_current_regcache ());
  print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC, 1);
}

/* The "goto_record_begin" target method.  */

void
record_full_base_target::goto_record_begin ()
{
  struct record_full_entry *p = NULL;

  for (p = &record_full_first; p != NULL; p = p->next)
    if (p->type == record_full_end)
      break;

  record_full_goto_entry (p);
}

/* The "goto_record_end" target method.  */

void
record_full_base_target::goto_record_end ()
{
  struct record_full_entry *p = NULL;

  for (p = record_full_list; p->next != NULL; p = p->next)
    ;
  for (; p!= NULL; p = p->prev)
    if (p->type == record_full_end)
      break;

  record_full_goto_entry (p);
}

/* The "goto_record" target method.  */

void
record_full_base_target::goto_record (ULONGEST target_insn)
{
  struct record_full_entry *p = NULL;

  for (p = &record_full_first; p != NULL; p = p->next)
    if (p->type == record_full_end && p->u.end.insn_num == target_insn)
      break;

  record_full_goto_entry (p);
}

/* The "record_stop_replaying" target method.  */

void
record_full_base_target::record_stop_replaying ()
{
  goto_record_end ();
}

/* "resume" method for prec over corefile.  */

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;

  /* 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 (1);
}

/* "kill" method for prec over corefile.  */

void
record_full_core_target::kill ()
{
  if (record_debug)
    fprintf_unfiltered (gdb_stdlog, "Process record: record_full_core_kill\n");

  unpush_target (this);
}

/* "fetch_registers" method for prec over corefile.  */

void
record_full_core_target::fetch_registers (struct regcache *regcache,
					  int regno)
{
  if (regno < 0)
    {
      int num = gdbarch_num_regs (regcache->arch ());
      int i;

      for (i = 0; i < num; i ++)
	regcache->raw_supply (i, *record_full_core_regbuf);
    }
  else
    regcache->raw_supply (regno, *record_full_core_regbuf);
}

/* "prepare_to_store" method for prec over corefile.  */

void
record_full_core_target::prepare_to_store (struct regcache *regcache)
{
}

/* "store_registers" method for prec over corefile.  */

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);
  else
    error (_("You can't do that without a process to debug."));
}

/* "xfer_partial" method for prec over corefile.  */

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)
    {
      if (record_full_gdb_operation_disable || !writebuf)
	{
	  struct target_section *p;

	  for (p = record_full_core_start; p < record_full_core_end; p++)
	    {
	      if (offset >= p->addr)
		{
		  struct record_full_core_buf_entry *entry;
		  ULONGEST sec_offset;

		  if (offset >= p->endaddr)
		    continue;

		  if (offset + len > p->endaddr)
		    len = p->endaddr - offset;

		  sec_offset = offset - p->addr;

		  /* Read readbuf or write writebuf p, offset, len.  */
		  /* Check flags.  */
		  if (p->the_bfd_section->flags & SEC_CONSTRUCTOR
		      || (p->the_bfd_section->flags & SEC_HAS_CONTENTS) == 0)
		    {
		      if (readbuf)
			memset (readbuf, 0, len);

		      *xfered_len = len;
		      return TARGET_XFER_OK;
		    }
		  /* Get record_full_core_buf_entry.  */
		  for (entry = record_full_core_buf_list; entry;
		       entry = entry->prev)
		    if (entry->p == p)
		      break;
		  if (writebuf)
		    {
		      if (!entry)
			{
			  /* Add a new entry.  */
			  entry = XNEW (struct record_full_core_buf_entry);
			  entry->p = p;
			  if (!bfd_malloc_and_get_section
			        (p->the_bfd_section->owner,
				 p->the_bfd_section,
				 &entry->buf))
			    {
			      xfree (entry);
			      return TARGET_XFER_EOF;
			    }
			  entry->prev = record_full_core_buf_list;
			  record_full_core_buf_list = entry;
			}

		      memcpy (entry->buf + sec_offset, writebuf,
			      (size_t) len);
		    }
		  else
		    {
		      if (!entry)
			return this->beneath ()->xfer_partial (object, annex,
							       readbuf, writebuf,
							       offset, len,
							       xfered_len);

		      memcpy (readbuf, entry->buf + sec_offset,
			      (size_t) len);
		    }

		  *xfered_len = len;
		  return TARGET_XFER_OK;
		}
	    }

	  return TARGET_XFER_E_IO;
	}
      else
	error (_("You can't do that without a process to debug."));
    }

  return this->beneath ()->xfer_partial (object, annex,
					 readbuf, writebuf, offset, len,
					 xfered_len);
}

/* "insert_breakpoint" method for prec over corefile.  */

int
record_full_core_target::insert_breakpoint (struct gdbarch *gdbarch,
					    struct bp_target_info *bp_tgt)
{
  return 0;
}

/* "remove_breakpoint" method for prec over corefile.  */

int
record_full_core_target::remove_breakpoint (struct gdbarch *gdbarch,
					    struct bp_target_info *bp_tgt,
					    enum remove_bp_reason reason)
{
  return 0;
}

/* "has_execution" method for prec over corefile.  */

bool
record_full_core_target::has_execution (ptid_t the_ptid)
{
  return true;
}

/* Record log save-file format
   Version 1 (never released)

   Header:
     4 bytes: magic number htonl(0x20090829).
       NOTE: be sure to change whenever this file format changes!

   Records:
     record_full_end:
       1 byte:  record type (record_full_end, see enum record_full_type).
     record_full_reg:
       1 byte:  record type (record_full_reg, see enum record_full_type).
       8 bytes: register id (network byte order).
       MAX_REGISTER_SIZE bytes: register value.
     record_full_mem:
       1 byte:  record type (record_full_mem, see enum record_full_type).
       8 bytes: memory length (network byte order).
       8 bytes: memory address (network byte order).
       n bytes: memory value (n == memory length).

   Version 2
     4 bytes: magic number netorder32(0x20091016).
       NOTE: be sure to change whenever this file format changes!

   Records:
     record_full_end:
       1 byte:  record type (record_full_end, see enum record_full_type).
       4 bytes: signal
       4 bytes: instruction count
     record_full_reg:
       1 byte:  record type (record_full_reg, see enum record_full_type).
       4 bytes: register id (network byte order).
       n bytes: register value (n == actual register size).
                (eg. 4 bytes for x86 general registers).
     record_full_mem:
       1 byte:  record type (record_full_mem, see enum record_full_type).
       4 bytes: memory length (network byte order).
       8 bytes: memory address (network byte order).
       n bytes: memory value (n == memory length).

*/

/* bfdcore_read -- read bytes from a core file section.  */

static inline void
bfdcore_read (bfd *obfd, asection *osec, void *buf, int len, int *offset)
{
  int ret = bfd_get_section_contents (obfd, osec, buf, *offset, len);

  if (ret)
    *offset += len;
  else
    error (_("Failed to read %d bytes from core file %s ('%s')."),
	   len, bfd_get_filename (obfd),
	   bfd_errmsg (bfd_get_error ()));
}

static inline uint64_t
netorder64 (uint64_t input)
{
  uint64_t ret;

  store_unsigned_integer ((gdb_byte *) &ret, sizeof (ret), 
			  BFD_ENDIAN_BIG, input);
  return ret;
}

static inline uint32_t
netorder32 (uint32_t input)
{
  uint32_t ret;

  store_unsigned_integer ((gdb_byte *) &ret, sizeof (ret), 
			  BFD_ENDIAN_BIG, input);
  return ret;
}

/* Restore the execution log from a core_bfd file.  */
static void
record_full_restore (void)
{
  uint32_t magic;
  struct record_full_entry *rec;
  asection *osec;
  uint32_t osec_size;
  int bfd_offset = 0;
  struct regcache *regcache;

  /* We restore the execution log from the open core bfd,
     if there is one.  */
  if (core_bfd == NULL)
    return;

  /* "record_full_restore" can only be called when record list is empty.  */
  gdb_assert (record_full_first.next == NULL);
 
  if (record_debug)
    fprintf_unfiltered (gdb_stdlog, "Restoring recording from core file.\n");

  /* Now need to find our special note section.  */
  osec = bfd_get_section_by_name (core_bfd, "null0");
  if (record_debug)
    fprintf_unfiltered (gdb_stdlog, "Find precord section %s.\n",
			osec ? "succeeded" : "failed");
  if (osec == NULL)
    return;
  osec_size = bfd_section_size (osec);
  if (record_debug)
    fprintf_unfiltered (gdb_stdlog, "%s", bfd_section_name (osec));

  /* Check the magic code.  */
  bfdcore_read (core_bfd, osec, &magic, sizeof (magic), &bfd_offset);
  if (magic != RECORD_FULL_FILE_MAGIC)
    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_FULL_FILE_MAGIC (0x%s)\n",
			phex_nz (netorder32 (magic), 4));

  /* Restore the entries in recfd into record_full_arch_list_head and
     record_full_arch_list_tail.  */
  record_full_arch_list_head = NULL;
  record_full_arch_list_tail = NULL;
  record_full_insn_num = 0;

  try
    {
      regcache = get_current_regcache ();

      while (1)
	{
	  uint8_t rectype;
	  uint32_t regnum, len, signal, count;
	  uint64_t addr;

	  /* We are finished when offset reaches osec_size.  */
	  if (bfd_offset >= osec_size)
	    break;
	  bfdcore_read (core_bfd, osec, &rectype, sizeof (rectype), &bfd_offset);

	  switch (rectype)
	    {
	    case record_full_reg: /* reg */
	      /* Get register number to regnum.  */
	      bfdcore_read (core_bfd, osec, &regnum,
			    sizeof (regnum), &bfd_offset);
	      regnum = netorder32 (regnum);

	      rec = record_full_reg_alloc (regcache, regnum);

	      /* Get val.  */
	      bfdcore_read (core_bfd, osec, record_full_get_loc (rec),
			    rec->u.reg.len, &bfd_offset);

	      if (record_debug)
		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);
	      break;

	    case record_full_mem: /* mem */
	      /* Get len.  */
	      bfdcore_read (core_bfd, osec, &len,
			    sizeof (len), &bfd_offset);
	      len = netorder32 (len);

	      /* Get addr.  */
	      bfdcore_read (core_bfd, osec, &addr,
			    sizeof (addr), &bfd_offset);
	      addr = netorder64 (addr);

	      rec = record_full_mem_alloc (addr, len);

	      /* Get val.  */
	      bfdcore_read (core_bfd, osec, record_full_get_loc (rec),
			    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",
				    paddress (get_current_arch (),
					      rec->u.mem.addr),
				    (unsigned long) sizeof (addr),
				    (unsigned long) sizeof (len),
				    rec->u.mem.len);
	      break;

	    case record_full_end: /* end */
	      rec = record_full_end_alloc ();
	      record_full_insn_num ++;

	      /* Get signal value.  */
	      bfdcore_read (core_bfd, osec, &signal,
			    sizeof (signal), &bfd_offset);
	      signal = netorder32 (signal);
	      rec->u.end.sigval = (enum gdb_signal) signal;

	      /* Get insn count.  */
	      bfdcore_read (core_bfd, osec, &count,
			    sizeof (count), &bfd_offset);
	      count = netorder32 (count);
	      rec->u.end.insn_num = count;
	      record_full_insn_count = count + 1;
	      if (record_debug)
		fprintf_unfiltered (gdb_stdlog,
				    "  Reading record_full_end (1 + "
				    "%lu + %lu bytes), offset == %s\n",
				    (unsigned long) sizeof (signal),
				    (unsigned long) sizeof (count),
				    paddress (get_current_arch (),
					      bfd_offset));
	      break;

	    default:
	      error (_("Bad entry type in core file %s."),
		     bfd_get_filename (core_bfd));
	      break;
	    }

	  /* Add rec to record arch list.  */
	  record_full_arch_list_add (rec);
	}
    }
  catch (const gdb_exception &ex)
    {
      record_full_list_release (record_full_arch_list_tail);
      throw;
    }

  /* Add record_full_arch_list_head to the end of record list.  */
  record_full_first.next = record_full_arch_list_head;
  record_full_arch_list_head->prev = &record_full_first;
  record_full_arch_list_tail->next = NULL;
  record_full_list = &record_full_first;

  /* Update record_full_insn_max_num.  */
  if (record_full_insn_num > record_full_insn_max_num)
    {
      record_full_insn_max_num = record_full_insn_num;
      warning (_("Auto increase record/replay buffer limit to %u."),
               record_full_insn_max_num);
    }

  /* Succeeded.  */
  printf_filtered (_("Restored records from core file %s.\n"),
		   bfd_get_filename (core_bfd));

  print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC, 1);
}

/* bfdcore_write -- write bytes into a core file section.  */

static inline void
bfdcore_write (bfd *obfd, asection *osec, void *buf, int len, int *offset)
{
  int ret = bfd_set_section_contents (obfd, osec, buf, *offset, len);

  if (ret)
    *offset += len;
  else
    error (_("Failed to write %d bytes to core file %s ('%s')."),
	   len, bfd_get_filename (obfd),
	   bfd_errmsg (bfd_get_error ()));
}

/* Restore the execution log from a file.  We use a modified elf
   corefile format, with an extra section for our data.  */

static void
cmd_record_full_restore (const char *args, int from_tty)
{
  core_file_command (args, from_tty);
  record_full_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.  */

void
record_full_base_target::save_record (const char *recfilename)
{
  struct record_full_entry *cur_record_full_list;
  uint32_t magic;
  struct regcache *regcache;
  struct gdbarch *gdbarch;
  int save_size = 0;
  asection *osec = NULL;
  int bfd_offset = 0;

  /* Open the save file.  */
  if (record_debug)
    fprintf_unfiltered (gdb_stdlog, "Saving execution log to core file '%s'\n",
			recfilename);

  /* Open the output file.  */
  gdb_bfd_ref_ptr obfd (create_gcore_bfd (recfilename));

  /* Arrange to remove the output file on failure.  */
  gdb::unlinker unlink_file (recfilename);

  /* Save the current record entry to "cur_record_full_list".  */
  cur_record_full_list = record_full_list;

  /* Get the values of regcache and gdbarch.  */
  regcache = get_current_regcache ();
  gdbarch = regcache->arch ();

  /* Disable the GDB operation record.  */
  scoped_restore restore_operation_disable
    = record_full_gdb_operation_disable_set ();

  /* Reverse execute to the begin of record list.  */
  while (1)
    {
      /* Check for beginning and end of log.  */
      if (record_full_list == &record_full_first)
        break;

      record_full_exec_insn (regcache, gdbarch, record_full_list);

      if (record_full_list->prev)
        record_full_list = record_full_list->prev;
    }

  /* Compute the size needed for the extra bfd section.  */
  save_size = 4;	/* magic cookie */
  for (record_full_list = record_full_first.next; record_full_list;
       record_full_list = record_full_list->next)
    switch (record_full_list->type)
      {
      case record_full_end:
	save_size += 1 + 4 + 4;
	break;
      case record_full_reg:
	save_size += 1 + 4 + record_full_list->u.reg.len;
	break;
      case record_full_mem:
	save_size += 1 + 4 + 8 + record_full_list->u.mem.len;
	break;
      }

  /* Make the new bfd section.  */
  osec = bfd_make_section_anyway_with_flags (obfd.get (), "precord",
                                             SEC_HAS_CONTENTS
                                             | SEC_READONLY);
  if (osec == NULL)
    error (_("Failed to create 'precord' section for corefile %s: %s"),
	   recfilename,
           bfd_errmsg (bfd_get_error ()));
  bfd_set_section_size (osec, save_size);
  bfd_set_section_vma (osec, 0);
  bfd_set_section_alignment (osec, 0);

  /* Save corefile state.  */
  write_gcore_file (obfd.get ());

  /* Write out the record log.  */
  /* Write the magic code.  */
  magic = RECORD_FULL_FILE_MAGIC;
  if (record_debug)
    fprintf_unfiltered (gdb_stdlog,
			"  Writing 4-byte magic cookie "
			"RECORD_FULL_FILE_MAGIC (0x%s)\n",
		      phex_nz (magic, 4));
  bfdcore_write (obfd.get (), osec, &magic, sizeof (magic), &bfd_offset);

  /* Save the entries to recfd and forward execute to the end of
     record list.  */
  record_full_list = &record_full_first;
  while (1)
    {
      /* Save entry.  */
      if (record_full_list != &record_full_first)
        {
	  uint8_t type;
	  uint32_t regnum, len, signal, count;
          uint64_t addr;

	  type = record_full_list->type;
          bfdcore_write (obfd.get (), osec, &type, sizeof (type), &bfd_offset);

          switch (record_full_list->type)
            {
            case record_full_reg: /* reg */
	      if (record_debug)
		fprintf_unfiltered (gdb_stdlog,
				    "  Writing register %d (1 "
				    "plus %lu plus %d bytes)\n",
				    record_full_list->u.reg.num,
				    (unsigned long) sizeof (regnum),
				    record_full_list->u.reg.len);

              /* Write regnum.  */
              regnum = netorder32 (record_full_list->u.reg.num);
              bfdcore_write (obfd.get (), osec, &regnum,
			     sizeof (regnum), &bfd_offset);

              /* Write regval.  */
              bfdcore_write (obfd.get (), osec,
			     record_full_get_loc (record_full_list),
			     record_full_list->u.reg.len, &bfd_offset);
              break;

            case record_full_mem: /* mem */
	      if (record_debug)
		fprintf_unfiltered (gdb_stdlog,
				    "  Writing memory %s (1 plus "
				    "%lu plus %lu plus %d bytes)\n",
				    paddress (gdbarch,
					      record_full_list->u.mem.addr),
				    (unsigned long) sizeof (addr),
				    (unsigned long) sizeof (len),
				    record_full_list->u.mem.len);

	      /* Write memlen.  */
	      len = netorder32 (record_full_list->u.mem.len);
	      bfdcore_write (obfd.get (), osec, &len, sizeof (len),
			     &bfd_offset);

	      /* Write memaddr.  */
	      addr = netorder64 (record_full_list->u.mem.addr);
	      bfdcore_write (obfd.get (), osec, &addr, 
			     sizeof (addr), &bfd_offset);

	      /* Write memval.  */
	      bfdcore_write (obfd.get (), osec,
			     record_full_get_loc (record_full_list),
			     record_full_list->u.mem.len, &bfd_offset);
              break;

              case record_full_end:
		if (record_debug)
		  fprintf_unfiltered (gdb_stdlog,
				      "  Writing record_full_end (1 + "
				      "%lu + %lu bytes)\n", 
				      (unsigned long) sizeof (signal),
				      (unsigned long) sizeof (count));
		/* Write signal value.  */
		signal = netorder32 (record_full_list->u.end.sigval);
		bfdcore_write (obfd.get (), osec, &signal,
			       sizeof (signal), &bfd_offset);

		/* Write insn count.  */
		count = netorder32 (record_full_list->u.end.insn_num);
		bfdcore_write (obfd.get (), osec, &count,
			       sizeof (count), &bfd_offset);
                break;
            }
        }

      /* Execute entry.  */
      record_full_exec_insn (regcache, gdbarch, record_full_list);

      if (record_full_list->next)
        record_full_list = record_full_list->next;
      else
        break;
    }

  /* Reverse execute to cur_record_full_list.  */
  while (1)
    {
      /* Check for beginning and end of log.  */
      if (record_full_list == cur_record_full_list)
        break;

      record_full_exec_insn (regcache, gdbarch, record_full_list);

      if (record_full_list->prev)
        record_full_list = record_full_list->prev;
    }

  unlink_file.keep ();

  /* Succeeded.  */
  printf_filtered (_("Saved core file %s with execution log.\n"),
		   recfilename);
}

/* record_full_goto_insn -- rewind the record log (forward or backward,
   depending on DIR) to the given entry, changing the program state
   correspondingly.  */

static void
record_full_goto_insn (struct record_full_entry *entry,
		       enum exec_direction_kind dir)
{
  scoped_restore restore_operation_disable
    = record_full_gdb_operation_disable_set ();
  struct regcache *regcache = get_current_regcache ();
  struct gdbarch *gdbarch = regcache->arch ();

  /* Assume everything is valid: we will hit the entry,
     and we will not hit the end of the recording.  */

  if (dir == EXEC_FORWARD)
    record_full_list = record_full_list->next;

  do
    {
      record_full_exec_insn (regcache, gdbarch, record_full_list);
      if (dir == EXEC_REVERSE)
	record_full_list = record_full_list->prev;
      else
	record_full_list = record_full_list->next;
    } while (record_full_list != entry);
}

/* Alias for "target record-full".  */

static void
cmd_record_full_start (const char *args, int from_tty)
{
  execute_command ("target record-full", from_tty);
}

static void
set_record_full_insn_max_num (const char *args, int from_tty,
			      struct cmd_list_element *c)
{
  if (record_full_insn_num > record_full_insn_max_num)
    {
      /* Count down record_full_insn_num while releasing records from list.  */
      while (record_full_insn_num > record_full_insn_max_num)
       {
         record_full_list_release_first ();
         record_full_insn_num--;
       }
    }
}

/* The "set record full" command.  */

static void
set_record_full_command (const char *args, int from_tty)
{
  printf_unfiltered (_("\"set record full\" must be followed "
		       "by an appropriate subcommand.\n"));
  help_list (set_record_full_cmdlist, "set record full ", all_commands,
	     gdb_stdout);
}

/* The "show record full" command.  */

static void
show_record_full_command (const char *args, int from_tty)
{
  cmd_show_list (show_record_full_cmdlist, from_tty, "");
}

void
_initialize_record_full (void)
{
  struct cmd_list_element *c;

  /* Init record_full_first.  */
  record_full_first.prev = NULL;
  record_full_first.next = NULL;
  record_full_first.type = record_full_end;

  add_target (record_full_target_info, record_full_open);
  add_deprecated_target_alias (record_full_target_info, "record");
  add_target (record_full_core_target_info, record_full_open);

  add_prefix_cmd ("full", class_obscure, cmd_record_full_start,
		  _("Start full execution recording."), &record_full_cmdlist,
		  "record full ", 0, &record_cmdlist);

  c = add_cmd ("restore", class_obscure, cmd_record_full_restore,
	       _("Restore the execution log from a file.\n\
Argument is filename.  File must be created with 'record save'."),
	       &record_full_cmdlist);
  set_cmd_completer (c, filename_completer);

  /* Deprecate the old version without "full" prefix.  */
  c = add_alias_cmd ("restore", "full restore", class_obscure, 1,
		     &record_cmdlist);
  set_cmd_completer (c, filename_completer);
  deprecate_cmd (c, "record full restore");

  add_prefix_cmd ("full", class_support, set_record_full_command,
		  _("Set record options."), &set_record_full_cmdlist,
		  "set record full ", 0, &set_record_cmdlist);

  add_prefix_cmd ("full", class_support, show_record_full_command,
		  _("Show record options."), &show_record_full_cmdlist,
		  "show record full ", 0, &show_record_cmdlist);

  /* Record instructions number limit command.  */
  add_setshow_boolean_cmd ("stop-at-limit", no_class,
			   &record_full_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\
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."),
			   NULL, NULL,
			   &set_record_full_cmdlist, &show_record_full_cmdlist);

  c = add_alias_cmd ("stop-at-limit", "full stop-at-limit", no_class, 1,
		     &set_record_cmdlist);
  deprecate_cmd (c, "set record full stop-at-limit");

  c = add_alias_cmd ("stop-at-limit", "full stop-at-limit", no_class, 1,
		     &show_record_cmdlist);
  deprecate_cmd (c, "show record full stop-at-limit");

  add_setshow_uinteger_cmd ("insn-number-max", no_class,
			    &record_full_insn_max_num,
			    _("Set record/replay buffer limit."),
			    _("Show record/replay buffer limit."), _("\
Set the maximum number of instructions to be stored in the\n\
record/replay buffer.  A value of either \"unlimited\" or zero means no\n\
limit.  Default is 200000."),
			    set_record_full_insn_max_num,
			    NULL, &set_record_full_cmdlist,
			    &show_record_full_cmdlist);

  c = add_alias_cmd ("insn-number-max", "full insn-number-max", no_class, 1,
		     &set_record_cmdlist);
  deprecate_cmd (c, "set record full insn-number-max");

  c = add_alias_cmd ("insn-number-max", "full insn-number-max", no_class, 1,
		     &show_record_cmdlist);
  deprecate_cmd (c, "show record full insn-number-max");

  add_setshow_boolean_cmd ("memory-query", no_class,
			   &record_full_memory_query, _("\
Set whether query if PREC cannot record memory change of next instruction."),
                           _("\
Show whether query if PREC cannot record memory change of next instruction."),
                           _("\
Default is OFF.\n\
When ON, query if PREC cannot record memory change of next instruction."),
			   NULL, NULL,
			   &set_record_full_cmdlist,
			   &show_record_full_cmdlist);

  c = add_alias_cmd ("memory-query", "full memory-query", no_class, 1,
		     &set_record_cmdlist);
  deprecate_cmd (c, "set record full memory-query");

  c = add_alias_cmd ("memory-query", "full memory-query", no_class, 1,
		     &show_record_cmdlist);
  deprecate_cmd (c, "show record full memory-query");
}
