//===-- DNBBreakpoint.h -----------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
//  Created by Greg Clayton on 6/29/07.
//
//===----------------------------------------------------------------------===//

#ifndef __DNBBreakpoint_h__
#define __DNBBreakpoint_h__

#include <mach/mach.h>

#include <map>
#include <vector>

#include "DNBDefs.h"

class MachProcess;

class DNBBreakpoint {
public:
  DNBBreakpoint(nub_addr_t m_addr, nub_size_t byte_size, bool hardware);
  ~DNBBreakpoint();

  nub_size_t ByteSize() const { return m_byte_size; }
  uint8_t *SavedOpcodeBytes() { return &m_opcode[0]; }
  const uint8_t *SavedOpcodeBytes() const { return &m_opcode[0]; }
  nub_addr_t Address() const { return m_addr; }
  //    nub_thread_t ThreadID() const { return m_tid; }
  bool IsEnabled() const { return m_enabled; }
  bool IntersectsRange(nub_addr_t addr, nub_size_t size,
                       nub_addr_t *intersect_addr, nub_size_t *intersect_size,
                       nub_size_t *opcode_offset) const {
    // We only use software traps for software breakpoints
    if (IsBreakpoint() && IsEnabled() && !IsHardware()) {
      if (m_byte_size > 0) {
        const nub_addr_t bp_end_addr = m_addr + m_byte_size;
        const nub_addr_t end_addr = addr + size;
        // Is the breakpoint end address before the passed in start address?
        if (bp_end_addr <= addr)
          return false;
        // Is the breakpoint start address after passed in end address?
        if (end_addr <= m_addr)
          return false;
        if (intersect_addr || intersect_size || opcode_offset) {
          if (m_addr < addr) {
            if (intersect_addr)
              *intersect_addr = addr;
            if (intersect_size)
              *intersect_size =
                  std::min<nub_addr_t>(bp_end_addr, end_addr) - addr;
            if (opcode_offset)
              *opcode_offset = addr - m_addr;
          } else {
            if (intersect_addr)
              *intersect_addr = m_addr;
            if (intersect_size)
              *intersect_size =
                  std::min<nub_addr_t>(bp_end_addr, end_addr) - m_addr;
            if (opcode_offset)
              *opcode_offset = 0;
          }
        }
        return true;
      }
    }
    return false;
  }
  void SetEnabled(bool enabled) {
    if (!enabled)
      SetHardwareIndex(INVALID_NUB_HW_INDEX);
    m_enabled = enabled;
  }
  void SetIsWatchpoint(uint32_t type) {
    m_is_watchpoint = 1;
    m_watch_read = (type & WATCH_TYPE_READ) != 0;
    m_watch_write = (type & WATCH_TYPE_WRITE) != 0;
  }
  bool IsBreakpoint() const { return m_is_watchpoint == 0; }
  bool IsWatchpoint() const { return m_is_watchpoint == 1; }
  bool WatchpointRead() const { return m_watch_read != 0; }
  bool WatchpointWrite() const { return m_watch_write != 0; }
  bool HardwarePreferred() const { return m_hw_preferred; }
  bool IsHardware() const { return m_hw_index != INVALID_NUB_HW_INDEX; }
  uint32_t GetHardwareIndex() const { return m_hw_index; }
  void SetHardwareIndex(uint32_t hw_index) { m_hw_index = hw_index; }
  void Dump() const;
  uint32_t Retain() { return ++m_retain_count; }
  uint32_t Release() {
    if (m_retain_count == 0)
      return 0;
    return --m_retain_count;
  }

private:
  uint32_t m_retain_count; // Each breakpoint is maintained by address and is
                           // ref counted in case multiple people set a
                           // breakpoint at the same address
  uint32_t m_byte_size;    // Length in bytes of the breakpoint if set in memory
  uint8_t m_opcode[8];     // Saved opcode bytes
  nub_addr_t m_addr;       // Address of this breakpoint
  uint32_t m_enabled : 1,  // Flags for this breakpoint
      m_hw_preferred : 1,  // 1 if this point has been requested to be set using
                           // hardware (which may fail due to lack of resources)
      m_is_watchpoint : 1, // 1 if this is a watchpoint
      m_watch_read : 1,    // 1 if we stop when the watched data is read from
      m_watch_write : 1;   // 1 if we stop when the watched data is written to
  uint32_t
      m_hw_index; // The hardware resource index for this breakpoint/watchpoint
};

class DNBBreakpointList {
public:
  DNBBreakpointList();
  ~DNBBreakpointList();

  DNBBreakpoint *Add(nub_addr_t addr, nub_size_t length, bool hardware);
  bool Remove(nub_addr_t addr);
  DNBBreakpoint *FindByAddress(nub_addr_t addr);
  const DNBBreakpoint *FindByAddress(nub_addr_t addr) const;

  size_t FindBreakpointsThatOverlapRange(nub_addr_t addr, nub_addr_t size,
                                         std::vector<DNBBreakpoint *> &bps);

  void Dump() const;

  size_t Size() const { return m_breakpoints.size(); }
  void DisableAll();

  void RemoveTrapsFromBuffer(nub_addr_t addr, nub_size_t size, void *buf) const;

  void DisableAllBreakpoints(MachProcess *process);
  void DisableAllWatchpoints(MachProcess *process);
  void RemoveDisabled();

protected:
  typedef std::map<nub_addr_t, DNBBreakpoint> collection;
  typedef collection::iterator iterator;
  typedef collection::const_iterator const_iterator;
  collection m_breakpoints;
};

#endif
