aboutsummaryrefslogtreecommitdiff
path: root/source/Host/common/NativeBreakpointList.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/Host/common/NativeBreakpointList.cpp')
-rw-r--r--source/Host/common/NativeBreakpointList.cpp199
1 files changed, 199 insertions, 0 deletions
diff --git a/source/Host/common/NativeBreakpointList.cpp b/source/Host/common/NativeBreakpointList.cpp
new file mode 100644
index 000000000000..ecd0624bde09
--- /dev/null
+++ b/source/Host/common/NativeBreakpointList.cpp
@@ -0,0 +1,199 @@
+//===-- NativeBreakpointList.h ----------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "NativeBreakpointList.h"
+
+#include "lldb/Core/Log.h"
+
+#include "NativeBreakpoint.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+NativeBreakpointList::NativeBreakpointList () :
+ m_mutex (Mutex::eMutexTypeRecursive)
+{
+}
+
+Error
+NativeBreakpointList::AddRef (lldb::addr_t addr, size_t size_hint, bool hardware, CreateBreakpointFunc create_func)
+{
+ Log *log (GetLogIfAnyCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
+ if (log)
+ log->Printf ("NativeBreakpointList::%s addr = 0x%" PRIx64 ", size_hint = %lu, hardware = %s", __FUNCTION__, addr, size_hint, hardware ? "true" : "false");
+
+ Mutex::Locker locker (m_mutex);
+
+ // Check if the breakpoint is already set.
+ auto iter = m_breakpoints.find (addr);
+ if (iter != m_breakpoints.end ())
+ {
+ // Yes - bump up ref count.
+ if (log)
+ log->Printf ("NativeBreakpointList::%s addr = 0x%" PRIx64 " -- already enabled, upping ref count", __FUNCTION__, addr);
+
+ iter->second->AddRef ();
+ return Error ();
+ }
+
+ // Create a new breakpoint using the given create func.
+ if (log)
+ log->Printf ("NativeBreakpointList::%s creating breakpoint for addr = 0x%" PRIx64 ", size_hint = %lu, hardware = %s", __FUNCTION__, addr, size_hint, hardware ? "true" : "false");
+
+ NativeBreakpointSP breakpoint_sp;
+ Error error = create_func (addr, size_hint, hardware, breakpoint_sp);
+ if (error.Fail ())
+ {
+ if (log)
+ log->Printf ("NativeBreakpointList::%s creating breakpoint for addr = 0x%" PRIx64 ", size_hint = %lu, hardware = %s -- FAILED: %s", __FUNCTION__, addr, size_hint, hardware ? "true" : "false", error.AsCString ());
+ return error;
+ }
+
+ // Remember the breakpoint.
+ assert (breakpoint_sp && "NativeBreakpoint create function succeeded but returned NULL breakpoint");
+ m_breakpoints.insert (BreakpointMap::value_type (addr, breakpoint_sp));
+
+ return error;
+}
+
+Error
+NativeBreakpointList::DecRef (lldb::addr_t addr)
+{
+ Error error;
+
+ Log *log (GetLogIfAnyCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
+ if (log)
+ log->Printf ("NativeBreakpointList::%s addr = 0x%" PRIx64, __FUNCTION__, addr);
+
+ Mutex::Locker locker (m_mutex);
+
+ // Check if the breakpoint is already set.
+ auto iter = m_breakpoints.find (addr);
+ if (iter == m_breakpoints.end ())
+ {
+ // Not found!
+ if (log)
+ log->Printf ("NativeBreakpointList::%s addr = 0x%" PRIx64 " -- NOT FOUND", __FUNCTION__, addr);
+ error.SetErrorString ("breakpoint not found");
+ return error;
+ }
+
+ // Decrement ref count.
+ const int32_t new_ref_count = iter->second->DecRef ();
+ assert (new_ref_count >= 0 && "NativeBreakpoint ref count went negative");
+
+ if (new_ref_count > 0)
+ {
+ // Still references to this breakpoint. Leave it alone.
+ if (log)
+ log->Printf ("NativeBreakpointList::%s addr = 0x%" PRIx64 " -- new breakpoint ref count %" PRIu32, __FUNCTION__, addr, new_ref_count);
+ return error;
+ }
+
+ // Breakpoint has no more references. Disable it if it's not
+ // already disabled.
+ if (log)
+ log->Printf ("NativeBreakpointList::%s addr = 0x%" PRIx64 " -- removing due to no remaining references", __FUNCTION__, addr);
+
+ // If it's enabled, we need to disable it.
+ if (iter->second->IsEnabled ())
+ {
+ if (log)
+ log->Printf ("NativeBreakpointList::%s addr = 0x%" PRIx64 " -- currently enabled, now disabling", __FUNCTION__, addr);
+ error = iter->second->Disable ();
+ if (error.Fail ())
+ {
+ if (log)
+ log->Printf ("NativeBreakpointList::%s addr = 0x%" PRIx64 " -- removal FAILED: %s", __FUNCTION__, addr, error.AsCString ());
+ // Continue since we still want to take it out of the breakpoint list.
+ }
+ }
+ else
+ {
+ if (log)
+ log->Printf ("NativeBreakpointList::%s addr = 0x%" PRIx64 " -- already disabled, nothing to do", __FUNCTION__, addr);
+ }
+
+ // Take the breakpoint out of the list.
+ if (log)
+ log->Printf ("NativeBreakpointList::%s addr = 0x%" PRIx64 " -- removed from breakpoint map", __FUNCTION__, addr);
+
+ m_breakpoints.erase (iter);
+ return error;
+}
+
+Error
+NativeBreakpointList::EnableBreakpoint (lldb::addr_t addr)
+{
+ Log *log (GetLogIfAnyCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
+ if (log)
+ log->Printf ("NativeBreakpointList::%s addr = 0x%" PRIx64, __FUNCTION__, addr);
+
+ Mutex::Locker locker (m_mutex);
+
+ // Ensure we have said breakpoint.
+ auto iter = m_breakpoints.find (addr);
+ if (iter == m_breakpoints.end ())
+ {
+ // Not found!
+ if (log)
+ log->Printf ("NativeBreakpointList::%s addr = 0x%" PRIx64 " -- NOT FOUND", __FUNCTION__, addr);
+ return Error ("breakpoint not found");
+ }
+
+ // Enable it.
+ return iter->second->Enable ();
+}
+
+Error
+NativeBreakpointList::DisableBreakpoint (lldb::addr_t addr)
+{
+ Log *log (GetLogIfAnyCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
+ if (log)
+ log->Printf ("NativeBreakpointList::%s addr = 0x%" PRIx64, __FUNCTION__, addr);
+
+ Mutex::Locker locker (m_mutex);
+
+ // Ensure we have said breakpoint.
+ auto iter = m_breakpoints.find (addr);
+ if (iter == m_breakpoints.end ())
+ {
+ // Not found!
+ if (log)
+ log->Printf ("NativeBreakpointList::%s addr = 0x%" PRIx64 " -- NOT FOUND", __FUNCTION__, addr);
+ return Error ("breakpoint not found");
+ }
+
+ // Disable it.
+ return iter->second->Disable ();
+}
+
+Error
+NativeBreakpointList::GetBreakpoint (lldb::addr_t addr, NativeBreakpointSP &breakpoint_sp)
+{
+ Log *log (GetLogIfAnyCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
+ if (log)
+ log->Printf ("NativeBreakpointList::%s addr = 0x%" PRIx64, __FUNCTION__, addr);
+
+ Mutex::Locker locker (m_mutex);
+
+ // Ensure we have said breakpoint.
+ auto iter = m_breakpoints.find (addr);
+ if (iter == m_breakpoints.end ())
+ {
+ // Not found!
+ breakpoint_sp.reset ();
+ return Error ("breakpoint not found");
+ }
+
+ // Disable it.
+ breakpoint_sp = iter->second;
+ return Error ();
+}
+