//===-- DNBBreakpoint.cpp ---------------------------------------*- 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.
//
//===----------------------------------------------------------------------===//

#include "DNBBreakpoint.h"
#include "DNBLog.h"
#include "MachProcess.h"
#include <algorithm>
#include <assert.h>
#include <inttypes.h>

#pragma mark-- DNBBreakpoint
DNBBreakpoint::DNBBreakpoint(nub_addr_t addr, nub_size_t byte_size,
                             bool hardware)
    : m_retain_count(1), m_byte_size(static_cast<uint32_t>(byte_size)),
      m_opcode(), m_addr(addr), m_enabled(0), m_hw_preferred(hardware),
      m_is_watchpoint(0), m_watch_read(0), m_watch_write(0),
      m_hw_index(INVALID_NUB_HW_INDEX) {}

DNBBreakpoint::~DNBBreakpoint() {}

void DNBBreakpoint::Dump() const {
  if (IsBreakpoint()) {
    DNBLog("DNBBreakpoint addr = 0x%llx  state = %s  type = %s breakpoint  "
           "hw_index = %i",
           (uint64_t)m_addr, m_enabled ? "enabled " : "disabled",
           IsHardware() ? "hardware" : "software", GetHardwareIndex());
  } else {
    DNBLog("DNBBreakpoint addr = 0x%llx  size = %llu  state = %s  type = %s "
           "watchpoint (%s%s)  hw_index = %i",
           (uint64_t)m_addr, (uint64_t)m_byte_size,
           m_enabled ? "enabled " : "disabled",
           IsHardware() ? "hardware" : "software", m_watch_read ? "r" : "",
           m_watch_write ? "w" : "", GetHardwareIndex());
  }
}

#pragma mark-- DNBBreakpointList

DNBBreakpointList::DNBBreakpointList() {}

DNBBreakpointList::~DNBBreakpointList() {}

DNBBreakpoint *DNBBreakpointList::Add(nub_addr_t addr, nub_size_t length,
                                      bool hardware) {
  m_breakpoints.insert(
      std::make_pair(addr, DNBBreakpoint(addr, length, hardware)));
  iterator pos = m_breakpoints.find(addr);
  return &pos->second;
}

bool DNBBreakpointList::Remove(nub_addr_t addr) {
  iterator pos = m_breakpoints.find(addr);
  if (pos != m_breakpoints.end()) {
    m_breakpoints.erase(pos);
    return true;
  }
  return false;
}

DNBBreakpoint *DNBBreakpointList::FindByAddress(nub_addr_t addr) {
  iterator pos = m_breakpoints.find(addr);
  if (pos != m_breakpoints.end())
    return &pos->second;

  return NULL;
}

const DNBBreakpoint *DNBBreakpointList::FindByAddress(nub_addr_t addr) const {
  const_iterator pos = m_breakpoints.find(addr);
  if (pos != m_breakpoints.end())
    return &pos->second;

  return NULL;
}

// Finds the next breakpoint at an address greater than or equal to "addr"
size_t DNBBreakpointList::FindBreakpointsThatOverlapRange(
    nub_addr_t addr, nub_addr_t size, std::vector<DNBBreakpoint *> &bps) {
  bps.clear();
  iterator end = m_breakpoints.end();
  // Find the first breakpoint with an address >= to "addr"
  iterator pos = m_breakpoints.lower_bound(addr);
  if (pos != end) {
    if (pos != m_breakpoints.begin()) {
      // Watch out for a breakpoint at an address less than "addr" that might
      // still overlap
      iterator prev_pos = pos;
      --prev_pos;
      if (prev_pos->second.IntersectsRange(addr, size, NULL, NULL, NULL))
        bps.push_back(&pos->second);
    }

    while (pos != end) {
      // When we hit a breakpoint whose start address is greater than "addr +
      // size" we are done.
      // Do the math in a way that doesn't risk unsigned overflow with bad
      // input.
      if ((pos->second.Address() - addr) >= size)
        break;

      // Check if this breakpoint overlaps, and if it does, add it to the list
      if (pos->second.IntersectsRange(addr, size, NULL, NULL, NULL)) {
        bps.push_back(&pos->second);
        ++pos;
      }
    }
  }
  return bps.size();
}

void DNBBreakpointList::Dump() const {
  const_iterator pos;
  const_iterator end = m_breakpoints.end();
  for (pos = m_breakpoints.begin(); pos != end; ++pos)
    pos->second.Dump();
}

void DNBBreakpointList::DisableAll() {
  iterator pos, end = m_breakpoints.end();
  for (pos = m_breakpoints.begin(); pos != end; ++pos)
    pos->second.SetEnabled(false);
}

void DNBBreakpointList::RemoveTrapsFromBuffer(nub_addr_t addr, nub_size_t size,
                                              void *p) const {
  uint8_t *buf = (uint8_t *)p;
  const_iterator end = m_breakpoints.end();
  const_iterator pos = m_breakpoints.lower_bound(addr);
  while (pos != end && (pos->first < (addr + size))) {
    nub_addr_t intersect_addr;
    nub_size_t intersect_size;
    nub_size_t opcode_offset;
    const DNBBreakpoint &bp = pos->second;
    if (bp.IntersectsRange(addr, size, &intersect_addr, &intersect_size,
                           &opcode_offset)) {
      assert(addr <= intersect_addr && intersect_addr < addr + size);
      assert(addr < intersect_addr + intersect_size &&
             intersect_addr + intersect_size <= addr + size);
      assert(opcode_offset + intersect_size <= bp.ByteSize());
      nub_size_t buf_offset = intersect_addr - addr;
      ::memcpy(buf + buf_offset, bp.SavedOpcodeBytes() + opcode_offset,
               intersect_size);
    }
    ++pos;
  }
}

void DNBBreakpointList::DisableAllBreakpoints(MachProcess *process) {
  iterator pos, end = m_breakpoints.end();
  for (pos = m_breakpoints.begin(); pos != end; ++pos)
    process->DisableBreakpoint(pos->second.Address(), false);
}

void DNBBreakpointList::DisableAllWatchpoints(MachProcess *process) {
  iterator pos, end = m_breakpoints.end();
  for (pos = m_breakpoints.begin(); pos != end; ++pos)
    process->DisableWatchpoint(pos->second.Address(), false);
}

void DNBBreakpointList::RemoveDisabled() {
  iterator pos = m_breakpoints.begin();
  while (pos != m_breakpoints.end()) {
    if (!pos->second.IsEnabled())
      pos = m_breakpoints.erase(pos);
    else
      ++pos;
  }
}
