//===-- 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)
    : StoppointSite(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) {
  m_hit_counter.Increment();
  // 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();
  }
}

bool BreakpointSite::IntersectsRange(lldb::addr_t addr, size_t size,
                                     lldb::addr_t *intersect_addr,
                                     size_t *intersect_size,
                                     size_t *opcode_offset) const {
  // The function should be called only for software breakpoints.
  lldbassert(GetType() == Type::eSoftware);

  if (m_byte_size == 0)
    return false;

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

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();
}
