//===-- 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 LLDB_TOOLS_DEBUGSERVER_SOURCE_DNBBREAKPOINT_H
#define LLDB_TOOLS_DEBUGSERVER_SOURCE_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
