forked from OSchip/llvm-project
200 lines
6.4 KiB
C++
200 lines
6.4 KiB
C++
//===-- 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 ();
|
|
}
|
|
|