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

#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;
  }
}
