diff options
Diffstat (limited to 'lldb/source/Breakpoint/BreakpointLocationList.cpp')
-rw-r--r-- | lldb/source/Breakpoint/BreakpointLocationList.cpp | 305 |
1 files changed, 305 insertions, 0 deletions
diff --git a/lldb/source/Breakpoint/BreakpointLocationList.cpp b/lldb/source/Breakpoint/BreakpointLocationList.cpp new file mode 100644 index 00000000000..d86a8cf4c47 --- /dev/null +++ b/lldb/source/Breakpoint/BreakpointLocationList.cpp @@ -0,0 +1,305 @@ +//===-- BreakpointLocationList.cpp ------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/Breakpoint/BreakpointLocationList.h" +#include "lldb/Breakpoint/BreakpointLocation.h" +#include "lldb/Core/ModuleList.h" +#include "lldb/Target/Target.h" + +using namespace lldb; +using namespace lldb_private; + +BreakpointLocationList::BreakpointLocationList() : + m_locations(), + m_address_to_location (), + m_mutex (Mutex::eMutexTypeRecursive), + m_next_id (0) +{ +} + +BreakpointLocationList::~BreakpointLocationList() +{ +} + +lldb::user_id_t +BreakpointLocationList::Add (BreakpointLocationSP &bp_loc_sp) +{ + if (bp_loc_sp) + { + Mutex::Locker locker (m_mutex); + m_locations.push_back (bp_loc_sp); + m_address_to_location[bp_loc_sp->GetAddress()] = bp_loc_sp; + return bp_loc_sp->GetID(); + } + return LLDB_INVALID_BREAK_ID; +} + +bool +BreakpointLocationList::ShouldStop (StoppointCallbackContext *context, lldb::user_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::user_id_t +BreakpointLocationList::FindIDByAddress (Address &addr) +{ + BreakpointLocationSP bp_loc_sp = FindByAddress (addr); + if (bp_loc_sp) + { + return bp_loc_sp->GetID(); + } + return LLDB_INVALID_BREAK_ID; +} + +bool +BreakpointLocationList::Remove (lldb::user_id_t break_id) +{ + Mutex::Locker locker (m_mutex); + collection::iterator pos = GetIDIterator(break_id); // Predicate + if (pos != m_locations.end()) + { + m_address_to_location.erase ((*pos)->GetAddress()); + m_locations.erase(pos); + return true; + } + return false; +} + + +class BreakpointLocationIDMatches +{ +public: + BreakpointLocationIDMatches (lldb::user_id_t break_id) : + m_break_id(break_id) + { + } + + bool operator() (const BreakpointLocationSP &bp_loc_sp) const + { + return m_break_id == bp_loc_sp->GetID(); + } + +private: + const lldb::user_id_t m_break_id; +}; + +class BreakpointLocationAddressMatches +{ +public: + BreakpointLocationAddressMatches (Address& addr) : + m_addr(addr) + { + } + + bool operator() (const BreakpointLocationSP& bp_loc_sp) const + { + return Address::CompareFileAddress(m_addr, bp_loc_sp->GetAddress()) == 0; + } + +private: + const Address &m_addr; +}; + +BreakpointLocationList::collection::iterator +BreakpointLocationList::GetIDIterator (lldb::user_id_t break_id) +{ + Mutex::Locker locker (m_mutex); + return std::find_if (m_locations.begin(), + m_locations.end(), + BreakpointLocationIDMatches(break_id)); +} + +BreakpointLocationList::collection::const_iterator +BreakpointLocationList::GetIDConstIterator (lldb::user_id_t break_id) const +{ + Mutex::Locker locker (m_mutex); + return std::find_if (m_locations.begin(), + m_locations.end(), + BreakpointLocationIDMatches(break_id)); +} + +BreakpointLocationSP +BreakpointLocationList::FindByID (lldb::user_id_t break_id) +{ + Mutex::Locker locker (m_mutex); + BreakpointLocationSP stop_sp; + collection::iterator pos = GetIDIterator(break_id); + if (pos != m_locations.end()) + stop_sp = *pos; + + return stop_sp; +} + +const BreakpointLocationSP +BreakpointLocationList::FindByID (lldb::user_id_t break_id) const +{ + Mutex::Locker locker (m_mutex); + BreakpointLocationSP stop_sp; + collection::const_iterator pos = GetIDConstIterator(break_id); + if (pos != m_locations.end()) + stop_sp = *pos; + + return stop_sp; +} + +size_t +BreakpointLocationList::FindInModule (Module *module, + BreakpointLocationCollection& bp_loc_list) +{ + Mutex::Locker locker (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) + { + bool seen = false; + BreakpointLocationSP break_loc = (*pos); + const Section *section = break_loc->GetAddress().GetSection(); + if (section) + { + if (section->GetModule() == module) + { + if (!seen) + { + seen = true; + bp_loc_list.Add (break_loc); + } + + } + } + } + return bp_loc_list.GetSize() - orig_size; +} + + +static int +FindLocationByAddress (Address *addr_ptr, const BreakpointLocationSP *bp_loc_sp_ptr) +{ + return Address::CompareModulePointerAndOffset(*addr_ptr, (*bp_loc_sp_ptr)->GetAddress()); +} + +const BreakpointLocationSP +BreakpointLocationList::FindByAddress (Address &addr) const +{ + Mutex::Locker locker (m_mutex); + BreakpointLocationSP stop_sp; + if (!m_locations.empty()) + { + addr_map::const_iterator pos = m_address_to_location.find (addr); + if (pos != m_address_to_location.end()) + stop_sp = pos->second; + } + + return stop_sp; +} + +void +BreakpointLocationList::Dump (Stream *s) const +{ + s->Printf("%.*p: ", (int)sizeof(void*) * 2, this); + s->Indent(); + Mutex::Locker locker (m_mutex); + s->Printf("BreakpointLocationList with %zu BreakpointLocations:\n", m_locations.size()); + s->IndentMore(); + collection::const_iterator pos, end = m_locations.end(); + for (pos = m_locations.begin(); pos != end; ++pos) + (*pos).get()->Dump(s); + s->IndentLess(); +} + + +BreakpointLocationSP +BreakpointLocationList::GetByIndex (uint32_t i) +{ + Mutex::Locker locker (m_mutex); + BreakpointLocationSP stop_sp; + if (i >= 0 && i < m_locations.size()) + stop_sp = m_locations[i]; + + return stop_sp; +} + +const BreakpointLocationSP +BreakpointLocationList::GetByIndex (uint32_t i) const +{ + Mutex::Locker locker (m_mutex); + BreakpointLocationSP stop_sp; + if (i >= 0 && i < m_locations.size()) + stop_sp = m_locations[i]; + + return stop_sp; +} + +void +BreakpointLocationList::ClearAllBreakpointSites () +{ + Mutex::Locker locker (m_mutex); + collection::iterator pos, end = m_locations.end(); + for (pos = m_locations.begin(); pos != end; ++pos) + (*pos)->ClearBreakpointSite(); +} + +void +BreakpointLocationList::ResolveAllBreakpointSites () +{ + Mutex::Locker locker (m_mutex); + collection::iterator pos, end = m_locations.end(); + + for (pos = m_locations.begin(); pos != end; ++pos) + (*pos)->ResolveBreakpointSite(); +} + +size_t +BreakpointLocationList::GetNumResolvedLocations() const +{ + Mutex::Locker locker (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; +} + +break_id_t +BreakpointLocationList::GetNextID() +{ + return ++m_next_id; +} + +void +BreakpointLocationList::GetDescription (Stream *s, lldb::DescriptionLevel level) +{ + Mutex::Locker locker (m_mutex); + collection::iterator pos, end = m_locations.end(); + + for (pos = m_locations.begin(); pos != end; ++pos) + { + s->Printf(" "); + (*pos)->GetDescription(s, level); + } +} + |