/* Displaced stepping related things.

   Copyright (C) 2020-2021 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/>.  */

#ifndef DISPLACED_STEPPING_H
#define DISPLACED_STEPPING_H

#include "gdbsupport/array-view.h"
#include "gdbsupport/byte-vector.h"

struct gdbarch;
struct thread_info;

/* True if we are debugging displaced stepping.  */

extern bool debug_displaced;

/* Print a "displaced" debug statement.  */

#define displaced_debug_printf(fmt, ...) \
  debug_prefixed_printf_cond (debug_displaced, "displaced",fmt, ##__VA_ARGS__)

enum displaced_step_prepare_status
{
  /* A displaced stepping buffer was successfully allocated and prepared.  */
  DISPLACED_STEP_PREPARE_STATUS_OK,

  /* This particular instruction can't be displaced stepped, GDB should fall
     back on in-line stepping.  */
  DISPLACED_STEP_PREPARE_STATUS_CANT,

  /* Not enough resources are available at this time, try again later.  */
  DISPLACED_STEP_PREPARE_STATUS_UNAVAILABLE,
};

enum displaced_step_finish_status
{
  /* Either the instruction was stepped and fixed up, or the specified thread
     wasn't executing a displaced step (in which case there's nothing to
     finish). */
  DISPLACED_STEP_FINISH_STATUS_OK,

  /* The thread started a displaced step, but didn't complete it.  */
  DISPLACED_STEP_FINISH_STATUS_NOT_EXECUTED,
};

/* Data returned by a gdbarch displaced_step_copy_insn method, to be passed to
   the matching displaced_step_fixup method.  */

struct displaced_step_copy_insn_closure
{
  virtual ~displaced_step_copy_insn_closure () = 0;
};

using displaced_step_copy_insn_closure_up
  = std::unique_ptr<displaced_step_copy_insn_closure>;

/* A simple displaced step closure that contains only a byte buffer.  */

struct buf_displaced_step_copy_insn_closure : displaced_step_copy_insn_closure
{
  buf_displaced_step_copy_insn_closure (int buf_size)
  : buf (buf_size)
  {}

  /* The content of this buffer is up to the user of the class, but typically
     original instruction bytes, used during fixup to determine what needs to
     be fixed up.  */
  gdb::byte_vector buf;
};

/* Per-inferior displaced stepping state.  */

struct displaced_step_inferior_state
{
  displaced_step_inferior_state ()
  {
    reset ();
  }

  /* Put this object back in its original state.  */
  void reset ()
  {
    failed_before = false;
    in_progress_count = 0;
    unavailable = false;
  }

  /* True if preparing a displaced step ever failed.  If so, we won't
     try displaced stepping for this inferior again.  */
  bool failed_before;

  /* Number of displaced steps in progress for this inferior.  */
  unsigned int in_progress_count;

  /* If true, this tells GDB that it's not worth asking the gdbarch displaced
     stepping implementation to prepare a displaced step, because it would
     return UNAVAILABLE.  This is set and reset by the gdbarch in the
     displaced_step_prepare and displaced_step_finish methods.  */
  bool unavailable;
};

/* Per-thread displaced stepping state.  */

struct displaced_step_thread_state
{
  /* Return true if this thread is currently executing a displaced step.  */
  bool in_progress () const
  {
    return m_original_gdbarch != nullptr;
  }

  /* Return the gdbarch of the thread prior to the step.  */
  gdbarch *get_original_gdbarch () const
  {
    return m_original_gdbarch;
  }

  /* Mark this thread as currently executing a displaced step.

     ORIGINAL_GDBARCH is the current gdbarch of the thread (before the step
     is executed).  */
  void set (gdbarch *original_gdbarch)
  {
    m_original_gdbarch = original_gdbarch;
  }

  /* Mark this thread as no longer executing a displaced step.  */
  void reset ()
  {
    m_original_gdbarch = nullptr;
  }

private:
  gdbarch *m_original_gdbarch = nullptr;
};

/* Control access to multiple displaced stepping buffers at fixed addresses.  */

struct displaced_step_buffers
{
  explicit displaced_step_buffers (gdb::array_view<CORE_ADDR> buffer_addrs)
  {
    gdb_assert (buffer_addrs.size () > 0);

    m_buffers.reserve (buffer_addrs.size ());

    for (CORE_ADDR buffer_addr : buffer_addrs)
      m_buffers.emplace_back (buffer_addr);
  }

  displaced_step_prepare_status prepare (thread_info *thread,
					 CORE_ADDR &displaced_pc);

  displaced_step_finish_status finish (gdbarch *arch, thread_info *thread,
				       gdb_signal sig);

  const displaced_step_copy_insn_closure *
    copy_insn_closure_by_addr (CORE_ADDR addr);

  void restore_in_ptid (ptid_t ptid);

private:

  /* State of a single buffer.  */

  struct displaced_step_buffer
  {
    explicit displaced_step_buffer (CORE_ADDR addr)
      : addr (addr)
    {}

    /* Address of the buffer.  */
    const CORE_ADDR addr;

    /* The original PC of the instruction currently being stepped.  */
    CORE_ADDR original_pc = 0;

    /* If set, the thread currently using the buffer.  If unset, the buffer is not
       used.  */
    thread_info *current_thread = nullptr;

    /* Saved copy of the bytes in the displaced buffer, to be restored once the
       buffer is no longer used.  */
    gdb::byte_vector saved_copy;

    /* Closure obtained from gdbarch_displaced_step_copy_insn, to be passed to
       gdbarch_displaced_step_fixup_insn.  */
    displaced_step_copy_insn_closure_up copy_insn_closure;
  };

  std::vector<displaced_step_buffer> m_buffers;
};

#endif /* DISPLACED_STEPPING_H */
