//===-- DNBBreakpoint.h -----------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  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
