// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef SRC_DEVELOPER_DEBUG_DEBUG_AGENT_SOFTWARE_BREAKPOINT_H_
#define SRC_DEVELOPER_DEBUG_DEBUG_AGENT_SOFTWARE_BREAKPOINT_H_

#include <zircon/status.h>

#include "src/developer/debug/debug_agent/arch.h"
#include "src/developer/debug/debug_agent/process_breakpoint.h"
#include "src/developer/debug/debug_agent/suspend_handle.h"
#include "src/developer/debug/ipc/protocol.h"

namespace debug_agent {

class ProcessMemoryAccessor;

class SoftwareBreakpoint : public ProcessBreakpoint {
 public:
  SoftwareBreakpoint(Breakpoint* breakpoint, DebuggedProcess* process, uint64_t address);
  virtual ~SoftwareBreakpoint();

  debug_ipc::BreakpointType Type() const override { return debug_ipc::BreakpointType::kSoftware; }

  // Software breakpoint is either installed for all threads or no one.
  bool Installed(zx_koid_t thread_koid) const override { return installed_; }

  // virtual picture of memory is needed, this function will replace the replacement from this
  // breakpoint if it appears in the given block. Otherwise does nothing.
  void FixupMemoryBlock(debug_ipc::MemoryBlock* block);

  // Public ProcessBreakpoint overrides. See ProcessBreakpoint for more details.
  void EndStepOver(DebuggedThread* thread) override;
  void ExecuteStepOver(DebuggedThread* thread) override;
  void StepOverCleanup(DebuggedThread* thread) override;
  debug::Status UninstallFromMemorySpace(ProcessHandle& process) override;

  const DebuggedThread* currently_stepping_over_thread() const {
    return currently_stepping_over_thread_.get();
  }

  // Returns a sorted list of the koids associated with a currently held suspend token.
  // If a thread has more than one suspend token, it wil appear twice.
  //
  // Exposed mostly for testing purposes (see process_breakpoint_unittest.cc).
  std::vector<zx_koid_t> CurrentlySuspendedThreads() const;

  // Returns true if any of the individual breakpoints are marked as is_internal_ld_so().
  bool IsInternalLdSoBreakpoint() const;

 private:
  // ProcessBreakpoint overrides.
  debug::Status Update() override;

  // A software breakpoint gets uninstalled for all the threads.
  debug::Status Uninstall(DebuggedThread* thread) override { return Uninstall(); }
  debug::Status Uninstall() override;

  debug::Status Install();

  // As stepping over are queued, only one thread should be left running at a time. This makes the
  // breakpoint get a suspend token for each other thread within the system.
  void SuspendAllOtherThreads(zx_koid_t stepping_over_koid);

  // Set to true when the instruction has been replaced.
  bool installed_ = false;

  // Previous memory contents before being replaced with the break instruction.
  arch::BreakInstructionType previous_data_ = 0;

  // Tracks the threads currently single-stepping over this breakpoint.
  // There can be only one thread stepping over, as they're serialized by the process so that only
  // one thread is stepping at a time.
  fxl::WeakPtr<DebuggedThread> currently_stepping_over_thread_;

  // A step is executed by putting back the original instruction, stepping the thread, and then
  // re-inserting the breakpoint instruction. The breakpoint instruction can't be put back until
  // there are no more threads in this map.
  //
  // It is a multimap because if two threads are queued on the same breakpoint (they both hit it at
  // the same time), the breakpoint will get suspend tokens for all the threads (except the
  // corresponding exception one) multiple times. If there is only one suspend token per koid, the
  // breakpoint will uncorrectly resume the thread that just stepped over when the other would
  // step over too, which is incorrect. We need the ability to have multiple tokens associated to
  // a thread so that the interim between executing the second step over the same breakpoint can
  // coincide with waiting for the resources of the first step over to be freed.
  //
  // See the implementation of |StepOverCleanup| for more details.
  std::multimap<zx_koid_t, std::unique_ptr<SuspendHandle>> suspend_tokens_;
};

}  // namespace debug_agent

#endif  // SRC_DEVELOPER_DEBUG_DEBUG_AGENT_SOFTWARE_BREAKPOINT_H_
