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

#include <inttypes.h>

#include "lldb/Breakpoint/BreakpointSite.h"

#include "lldb/Breakpoint/Breakpoint.h"
#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Breakpoint/BreakpointSiteList.h"
#include "lldb/Utility/Stream.h"

using namespace lldb;
using namespace lldb_private;

BreakpointSite::BreakpointSite(BreakpointSiteList *list,
                               const BreakpointLocationSP &owner,
                               lldb::addr_t addr, bool use_hardware)
    : StoppointLocation(GetNextID(), addr, 0, use_hardware),
      m_type(eSoftware), // Process subclasses need to set this correctly using
                         // SetType()
      m_saved_opcode(), m_trap_opcode(),
      m_enabled(false), // Need to create it disabled, so the first enable turns
                        // it on.
      m_owners(), m_owners_mutex() {
  m_owners.Add(owner);
}

BreakpointSite::~BreakpointSite() {
  BreakpointLocationSP bp_loc_sp;
  const size_t owner_count = m_owners.GetSize();
  for (size_t i = 0; i < owner_count; i++) {
    m_owners.GetByIndex(i)->ClearBreakpointSite();
  }
}

break_id_t BreakpointSite::GetNextID() {
  static break_id_t g_next_id = 0;
  return ++g_next_id;
}

// RETURNS - true if we should stop at this breakpoint, false if we
// should continue.

bool BreakpointSite::ShouldStop(StoppointCallbackContext *context) {
  IncrementHitCount();
  // ShouldStop can do a lot of work, and might even come come back and hit
  // this breakpoint site again.  So don't hold the m_owners_mutex the whole
  // while.  Instead make a local copy of the collection and call ShouldStop on
  // the copy.
  BreakpointLocationCollection owners_copy;
  {
    std::lock_guard<std::recursive_mutex> guard(m_owners_mutex);
    owners_copy = m_owners;
  }
  return owners_copy.ShouldStop(context);
}

bool BreakpointSite::IsBreakpointAtThisSite(lldb::break_id_t bp_id) {
  std::lock_guard<std::recursive_mutex> guard(m_owners_mutex);
  const size_t owner_count = m_owners.GetSize();
  for (size_t i = 0; i < owner_count; i++) {
    if (m_owners.GetByIndex(i)->GetBreakpoint().GetID() == bp_id)
      return true;
  }
  return false;
}

void BreakpointSite::Dump(Stream *s) const {
  if (s == nullptr)
    return;

  s->Printf("BreakpointSite %u: addr = 0x%8.8" PRIx64
            "  type = %s breakpoint  hw_index = %i  hit_count = %-4u",
            GetID(), (uint64_t)m_addr, IsHardware() ? "hardware" : "software",
            GetHardwareIndex(), GetHitCount());
}

void BreakpointSite::GetDescription(Stream *s, lldb::DescriptionLevel level) {
  std::lock_guard<std::recursive_mutex> guard(m_owners_mutex);
  if (level != lldb::eDescriptionLevelBrief)
    s->Printf("breakpoint site: %d at 0x%8.8" PRIx64, GetID(),
              GetLoadAddress());
  m_owners.GetDescription(s, level);
}

bool BreakpointSite::IsInternal() const { return m_owners.IsInternal(); }

uint8_t *BreakpointSite::GetTrapOpcodeBytes() { return &m_trap_opcode[0]; }

const uint8_t *BreakpointSite::GetTrapOpcodeBytes() const {
  return &m_trap_opcode[0];
}

size_t BreakpointSite::GetTrapOpcodeMaxByteSize() const {
  return sizeof(m_trap_opcode);
}

bool BreakpointSite::SetTrapOpcode(const uint8_t *trap_opcode,
                                   uint32_t trap_opcode_size) {
  if (trap_opcode_size > 0 && trap_opcode_size <= sizeof(m_trap_opcode)) {
    m_byte_size = trap_opcode_size;
    ::memcpy(m_trap_opcode, trap_opcode, trap_opcode_size);
    return true;
  }
  m_byte_size = 0;
  return false;
}

uint8_t *BreakpointSite::GetSavedOpcodeBytes() { return &m_saved_opcode[0]; }

const uint8_t *BreakpointSite::GetSavedOpcodeBytes() const {
  return &m_saved_opcode[0];
}

bool BreakpointSite::IsEnabled() const { return m_enabled; }

void BreakpointSite::SetEnabled(bool enabled) { m_enabled = enabled; }

void BreakpointSite::AddOwner(const BreakpointLocationSP &owner) {
  std::lock_guard<std::recursive_mutex> guard(m_owners_mutex);
  m_owners.Add(owner);
}

size_t BreakpointSite::RemoveOwner(lldb::break_id_t break_id,
                                   lldb::break_id_t break_loc_id) {
  std::lock_guard<std::recursive_mutex> guard(m_owners_mutex);
  m_owners.Remove(break_id, break_loc_id);
  return m_owners.GetSize();
}

size_t BreakpointSite::GetNumberOfOwners() {
  std::lock_guard<std::recursive_mutex> guard(m_owners_mutex);
  return m_owners.GetSize();
}

BreakpointLocationSP BreakpointSite::GetOwnerAtIndex(size_t index) {
  std::lock_guard<std::recursive_mutex> guard(m_owners_mutex);
  return m_owners.GetByIndex(index);
}

bool BreakpointSite::ValidForThisThread(Thread *thread) {
  std::lock_guard<std::recursive_mutex> guard(m_owners_mutex);
  return m_owners.ValidForThisThread(thread);
}

void BreakpointSite::BumpHitCounts() {
  std::lock_guard<std::recursive_mutex> guard(m_owners_mutex);
  for (BreakpointLocationSP loc_sp : m_owners.BreakpointLocations()) {
    loc_sp->BumpHitCount();
  }
}

void BreakpointSite::SetHardwareIndex(uint32_t index) {
  std::lock_guard<std::recursive_mutex> guard(m_owners_mutex);
  for (BreakpointLocationSP loc_sp : m_owners.BreakpointLocations()) {
    loc_sp->SetHardwareIndex(index);
  }
}

bool BreakpointSite::IntersectsRange(lldb::addr_t addr, size_t size,
                                     lldb::addr_t *intersect_addr,
                                     size_t *intersect_size,
                                     size_t *opcode_offset) const {
  // We only use software traps for software breakpoints
  if (!IsHardware()) {
    if (m_byte_size > 0) {
      const lldb::addr_t bp_end_addr = m_addr + m_byte_size;
      const lldb::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<lldb::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<lldb::addr_t>(bp_end_addr, end_addr) - m_addr;
          if (opcode_offset)
            *opcode_offset = 0;
        }
      }
      return true;
    }
  }
  return false;
}

size_t
BreakpointSite::CopyOwnersList(BreakpointLocationCollection &out_collection) {
  std::lock_guard<std::recursive_mutex> guard(m_owners_mutex);
  for (BreakpointLocationSP loc_sp : m_owners.BreakpointLocations()) {
    out_collection.Add(loc_sp);
  }
  return out_collection.GetSize();
}
