summaryrefslogtreecommitdiffstats
path: root/lldb/source/Breakpoint/BreakpointLocationList.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Breakpoint/BreakpointLocationList.cpp')
-rw-r--r--lldb/source/Breakpoint/BreakpointLocationList.cpp305
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);
+ }
+}
+
OpenPOWER on IntegriCloud