//===-- BreakpointLocationList.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 "lldb/Breakpoint/BreakpointLocationList.h"

#include "lldb/Breakpoint/Breakpoint.h"
#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/Section.h"
#include "lldb/Target/SectionLoadList.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/ArchSpec.h"

using namespace lldb;
using namespace lldb_private;

BreakpointLocationList::BreakpointLocationList(Breakpoint &owner)
    : m_owner(owner), m_next_id(0), m_new_location_recorder(nullptr) {}

BreakpointLocationList::~BreakpointLocationList() = default;

BreakpointLocationSP
BreakpointLocationList::Create(const Address &addr,
                               bool resolve_indirect_symbols) {
  std::lock_guard<std::recursive_mutex> guard(m_mutex);
  // The location ID is just the size of the location list + 1
  lldb::break_id_t bp_loc_id = ++m_next_id;
  BreakpointLocationSP bp_loc_sp(
      new BreakpointLocation(bp_loc_id, m_owner, addr, LLDB_INVALID_THREAD_ID,
                             m_owner.IsHardware(), resolve_indirect_symbols));
  m_locations.push_back(bp_loc_sp);
  m_address_to_location[addr] = bp_loc_sp;
  return bp_loc_sp;
}

bool BreakpointLocationList::ShouldStop(StoppointCallbackContext *context,
                                        lldb::break_id_t break_id) {
  BreakpointLocationSP bp = FindByID(break_id);
  if (bp) {
    // Let the BreakpointLocation decide if it should stop here (could not have
    // reached it's target hit count yet, or it could have a callback that
    // decided it shouldn't stop (shared library loads/unloads).
    return bp->ShouldStop(context);
  }
  // We should stop here since this BreakpointLocation isn't valid anymore or
  // it doesn't exist.
  return true;
}

lldb::break_id_t BreakpointLocationList::FindIDByAddress(const Address &addr) {
  BreakpointLocationSP bp_loc_sp = FindByAddress(addr);
  if (bp_loc_sp) {
    return bp_loc_sp->GetID();
  }
  return LLDB_INVALID_BREAK_ID;
}

static bool Compare(BreakpointLocationSP lhs, lldb::break_id_t val) {
  return lhs->GetID() < val;
}

BreakpointLocationSP
BreakpointLocationList::FindByID(lldb::break_id_t break_id) const {
  std::lock_guard<std::recursive_mutex> guard(m_mutex);
  collection::const_iterator end = m_locations.end();
  collection::const_iterator pos =
      llvm::lower_bound(m_locations, break_id, Compare);
  if (pos != end && (*pos)->GetID() == break_id)
    return *(pos);
  else
    return BreakpointLocationSP();
}

size_t BreakpointLocationList::FindInModule(
    Module *module, BreakpointLocationCollection &bp_loc_list) {
  std::lock_guard<std::recursive_mutex> guard(m_mutex);
  const size_t orig_size = bp_loc_list.GetSize();
  collection::iterator pos, end = m_locations.end();

  for (pos = m_locations.begin(); pos != end; ++pos) {
    BreakpointLocationSP break_loc = (*pos);
    SectionSP section_sp(break_loc->GetAddress().GetSection());
    if (section_sp && section_sp->GetModule().get() == module) {
      bp_loc_list.Add(break_loc);
    }
  }
  return bp_loc_list.GetSize() - orig_size;
}

const BreakpointLocationSP
BreakpointLocationList::FindByAddress(const Address &addr) const {
  std::lock_guard<std::recursive_mutex> guard(m_mutex);
  BreakpointLocationSP bp_loc_sp;
  if (!m_locations.empty()) {
    Address so_addr;

    if (addr.IsSectionOffset()) {
      so_addr = addr;
    } else {
      // Try and resolve as a load address if possible.
      m_owner.GetTarget().GetSectionLoadList().ResolveLoadAddress(
          addr.GetOffset(), so_addr);
      if (!so_addr.IsValid()) {
        // The address didn't resolve, so just set to passed in addr.
        so_addr = addr;
      }
    }

    addr_map::const_iterator pos = m_address_to_location.find(so_addr);
    if (pos != m_address_to_location.end())
      bp_loc_sp = pos->second;
  }

  return bp_loc_sp;
}

void BreakpointLocationList::Dump(Stream *s) const {
  s->Printf("%p: ", static_cast<const void *>(this));
  // s->Indent();
  std::lock_guard<std::recursive_mutex> guard(m_mutex);
  s->Printf("BreakpointLocationList with %" PRIu64 " BreakpointLocations:\n",
            (uint64_t)m_locations.size());
  s->IndentMore();
  collection::const_iterator pos, end = m_locations.end();
  for (pos = m_locations.begin(); pos != end; ++pos)
    (*pos)->Dump(s);
  s->IndentLess();
}

BreakpointLocationSP BreakpointLocationList::GetByIndex(size_t i) {
  std::lock_guard<std::recursive_mutex> guard(m_mutex);
  BreakpointLocationSP bp_loc_sp;
  if (i < m_locations.size())
    bp_loc_sp = m_locations[i];

  return bp_loc_sp;
}

const BreakpointLocationSP BreakpointLocationList::GetByIndex(size_t i) const {
  std::lock_guard<std::recursive_mutex> guard(m_mutex);
  BreakpointLocationSP bp_loc_sp;
  if (i < m_locations.size())
    bp_loc_sp = m_locations[i];

  return bp_loc_sp;
}

void BreakpointLocationList::ClearAllBreakpointSites() {
  std::lock_guard<std::recursive_mutex> guard(m_mutex);
  collection::iterator pos, end = m_locations.end();
  for (pos = m_locations.begin(); pos != end; ++pos)
    (*pos)->ClearBreakpointSite();
}

void BreakpointLocationList::ResolveAllBreakpointSites() {
  std::lock_guard<std::recursive_mutex> guard(m_mutex);
  collection::iterator pos, end = m_locations.end();

  for (pos = m_locations.begin(); pos != end; ++pos) {
    if ((*pos)->IsEnabled())
      (*pos)->ResolveBreakpointSite();
  }
}

uint32_t BreakpointLocationList::GetHitCount() const {
  uint32_t hit_count = 0;
  std::lock_guard<std::recursive_mutex> guard(m_mutex);
  collection::const_iterator pos, end = m_locations.end();
  for (pos = m_locations.begin(); pos != end; ++pos)
    hit_count += (*pos)->GetHitCount();
  return hit_count;
}

void BreakpointLocationList::ResetHitCount() {
  std::lock_guard<std::recursive_mutex> guard(m_mutex);
  for (auto &loc : m_locations)
    loc->ResetHitCount();
}

size_t BreakpointLocationList::GetNumResolvedLocations() const {
  std::lock_guard<std::recursive_mutex> guard(m_mutex);
  size_t resolve_count = 0;
  collection::const_iterator pos, end = m_locations.end();
  for (pos = m_locations.begin(); pos != end; ++pos) {
    if ((*pos)->IsResolved())
      ++resolve_count;
  }
  return resolve_count;
}

void BreakpointLocationList::GetDescription(Stream *s,
                                            lldb::DescriptionLevel level) {
  std::lock_guard<std::recursive_mutex> guard(m_mutex);
  collection::iterator pos, end = m_locations.end();

  for (pos = m_locations.begin(); pos != end; ++pos) {
    s->Printf(" ");
    (*pos)->GetDescription(s, level);
  }
}

BreakpointLocationSP BreakpointLocationList::AddLocation(
    const Address &addr, bool resolve_indirect_symbols, bool *new_location) {
  std::lock_guard<std::recursive_mutex> guard(m_mutex);

  if (new_location)
    *new_location = false;
  BreakpointLocationSP bp_loc_sp(FindByAddress(addr));
  if (!bp_loc_sp) {
    bp_loc_sp = Create(addr, resolve_indirect_symbols);
    if (bp_loc_sp) {
      bp_loc_sp->ResolveBreakpointSite();

      if (new_location)
        *new_location = true;
      if (m_new_location_recorder) {
        m_new_location_recorder->Add(bp_loc_sp);
      }
    }
  }
  return bp_loc_sp;
}

void BreakpointLocationList::SwapLocation(
    BreakpointLocationSP to_location_sp,
    BreakpointLocationSP from_location_sp) {
  if (!from_location_sp || !to_location_sp)
    return;

  m_address_to_location.erase(to_location_sp->GetAddress());
  to_location_sp->SwapLocation(from_location_sp);
  RemoveLocation(from_location_sp);
  m_address_to_location[to_location_sp->GetAddress()] = to_location_sp;
  to_location_sp->ResolveBreakpointSite();
}

bool BreakpointLocationList::RemoveLocation(
    const lldb::BreakpointLocationSP &bp_loc_sp) {
  if (bp_loc_sp) {
    std::lock_guard<std::recursive_mutex> guard(m_mutex);

    m_address_to_location.erase(bp_loc_sp->GetAddress());

    size_t num_locations = m_locations.size();
    for (size_t idx = 0; idx < num_locations; idx++) {
      if (m_locations[idx].get() == bp_loc_sp.get()) {
        RemoveLocationByIndex(idx);
        return true;
      }
    }
  }
  return false;
}

void BreakpointLocationList::RemoveLocationByIndex(size_t idx) {
  assert (idx < m_locations.size());
  m_address_to_location.erase(m_locations[idx]->GetAddress());
  m_locations.erase(m_locations.begin() + idx);
}

void BreakpointLocationList::RemoveInvalidLocations(const ArchSpec &arch) {
  std::lock_guard<std::recursive_mutex> guard(m_mutex);
  size_t idx = 0;
  // Don't cache m_location.size() as it will change since we might remove
  // locations from our vector...
  while (idx < m_locations.size()) {
    BreakpointLocation *bp_loc = m_locations[idx].get();
    if (bp_loc->GetAddress().SectionWasDeleted()) {
      // Section was deleted which means this breakpoint comes from a module
      // that is no longer valid, so we should remove it.
      RemoveLocationByIndex(idx);
      continue;
    }
    if (arch.IsValid()) {
      ModuleSP module_sp(bp_loc->GetAddress().GetModule());
      if (module_sp) {
        if (!arch.IsCompatibleMatch(module_sp->GetArchitecture())) {
          // The breakpoint was in a module whose architecture is no longer
          // compatible with "arch", so we need to remove it
          RemoveLocationByIndex(idx);
          continue;
        }
      }
    }
    // Only increment the index if we didn't remove the locations at index
    // "idx"
    ++idx;
  }
}

void BreakpointLocationList::StartRecordingNewLocations(
    BreakpointLocationCollection &new_locations) {
  std::lock_guard<std::recursive_mutex> guard(m_mutex);
  assert(m_new_location_recorder == nullptr);
  m_new_location_recorder = &new_locations;
}

void BreakpointLocationList::StopRecordingNewLocations() {
  std::lock_guard<std::recursive_mutex> guard(m_mutex);
  m_new_location_recorder = nullptr;
}

void BreakpointLocationList::Compact() {
  lldb::break_id_t highest_id = 0;

  for (BreakpointLocationSP loc_sp : m_locations) {
    lldb::break_id_t cur_id = loc_sp->GetID();
    if (cur_id > highest_id)
      highest_id = cur_id;
  }
  m_next_id = highest_id;
}
