diff options
Diffstat (limited to 'source/Host/common/NativeBreakpointList.cpp')
-rw-r--r-- | source/Host/common/NativeBreakpointList.cpp | 349 |
1 files changed, 179 insertions, 170 deletions
diff --git a/source/Host/common/NativeBreakpointList.cpp b/source/Host/common/NativeBreakpointList.cpp index 67873a06dd27..df5bce8079e0 100644 --- a/source/Host/common/NativeBreakpointList.cpp +++ b/source/Host/common/NativeBreakpointList.cpp @@ -17,204 +17,213 @@ using namespace lldb; using namespace lldb_private; -NativeBreakpointList::NativeBreakpointList() : m_mutex() -{ -} +NativeBreakpointList::NativeBreakpointList() : m_mutex() {} + +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 = %zu, hardware = %s", + __FUNCTION__, addr, size_hint, hardware ? "true" : "false"); + + std::lock_guard<std::recursive_mutex> guard(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); -Error -NativeBreakpointList::AddRef (lldb::addr_t addr, size_t size_hint, bool hardware, CreateBreakpointFunc create_func) -{ - Log *log (GetLogIfAnyCategoriesSet (LIBLLDB_LOG_BREAKPOINTS)); + 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 = %zu, 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 addr = 0x%" PRIx64 ", size_hint = %lu, hardware = %s", __FUNCTION__, addr, size_hint, hardware ? "true" : "false"); + log->Printf( + "NativeBreakpointList::%s creating breakpoint for addr = 0x%" PRIx64 + ", size_hint = %zu, hardware = %s -- FAILED: %s", + __FUNCTION__, addr, size_hint, hardware ? "true" : "false", + error.AsCString()); + return error; + } - std::lock_guard<std::recursive_mutex> guard(m_mutex); + // Remember the breakpoint. + assert(breakpoint_sp && "NativeBreakpoint create function succeeded but " + "returned NULL breakpoint"); + m_breakpoints.insert(BreakpointMap::value_type(addr, breakpoint_sp)); - // 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); + return error; +} - iter->second->AddRef (); - return Error (); - } +Error NativeBreakpointList::DecRef(lldb::addr_t addr) { + Error 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; - } + Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); + if (log) + log->Printf("NativeBreakpointList::%s addr = 0x%" PRIx64, __FUNCTION__, + addr); - // Remember the breakpoint. - assert (breakpoint_sp && "NativeBreakpoint create function succeeded but returned NULL breakpoint"); - m_breakpoints.insert (BreakpointMap::value_type (addr, breakpoint_sp)); + std::lock_guard<std::recursive_mutex> guard(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; -} + } -Error -NativeBreakpointList::DecRef (lldb::addr_t addr) -{ - Error error; + // Decrement ref count. + const int32_t new_ref_count = iter->second->DecRef(); + assert(new_ref_count >= 0 && "NativeBreakpoint ref count went negative"); - Log *log (GetLogIfAnyCategoriesSet (LIBLLDB_LOG_BREAKPOINTS)); + if (new_ref_count > 0) { + // Still references to this breakpoint. Leave it alone. if (log) - log->Printf ("NativeBreakpointList::%s addr = 0x%" PRIx64, __FUNCTION__, addr); - - std::lock_guard<std::recursive_mutex> guard(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"); + log->Printf("NativeBreakpointList::%s addr = 0x%" PRIx64 + " -- new breakpoint ref count %" PRIu32, + __FUNCTION__, addr, new_ref_count); + return error; + } - 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); - // Breakpoint has no more references. Disable it if it's not - // already disabled. + // If it's enabled, we need to disable it. + if (iter->second->IsEnabled()) { 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); + 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. } - - // Take the breakpoint out of the list. + } else { if (log) - log->Printf ("NativeBreakpointList::%s addr = 0x%" PRIx64 " -- removed from breakpoint map", __FUNCTION__, addr); - - m_breakpoints.erase (iter); - return error; + 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); - - std::lock_guard<std::recursive_mutex> guard(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"); - } +Error NativeBreakpointList::EnableBreakpoint(lldb::addr_t addr) { + Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); + if (log) + log->Printf("NativeBreakpointList::%s addr = 0x%" PRIx64, __FUNCTION__, + addr); - // Enable it. - return iter->second->Enable (); -} + std::lock_guard<std::recursive_mutex> guard(m_mutex); -Error -NativeBreakpointList::DisableBreakpoint (lldb::addr_t addr) -{ - Log *log (GetLogIfAnyCategoriesSet (LIBLLDB_LOG_BREAKPOINTS)); + // 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, __FUNCTION__, addr); - - std::lock_guard<std::recursive_mutex> guard(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"); - } + log->Printf("NativeBreakpointList::%s addr = 0x%" PRIx64 " -- NOT FOUND", + __FUNCTION__, addr); + return Error("breakpoint not found"); + } - // Disable it. - return iter->second->Disable (); + // Enable it. + return iter->second->Enable(); } -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); +Error NativeBreakpointList::DisableBreakpoint(lldb::addr_t addr) { + Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); + if (log) + log->Printf("NativeBreakpointList::%s addr = 0x%" PRIx64, __FUNCTION__, + addr); - std::lock_guard<std::recursive_mutex> guard(m_mutex); + std::lock_guard<std::recursive_mutex> guard(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"); - } + // 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. - breakpoint_sp = iter->second; - return Error (); + // Disable it. + return iter->second->Disable(); } -Error -NativeBreakpointList::RemoveTrapsFromBuffer(lldb::addr_t addr, void *buf, size_t size) const -{ - for (const auto &map : m_breakpoints) - { - lldb::addr_t bp_addr = map.first; - // Breapoint not in range, ignore - if (bp_addr < addr || addr + size <= bp_addr) - continue; - const auto &bp_sp = map.second; - // Not software breakpoint, ignore - if (!bp_sp->IsSoftwareBreakpoint()) - continue; - auto software_bp_sp = std::static_pointer_cast<SoftwareBreakpoint>(bp_sp); - auto opcode_addr = static_cast<char *>(buf) + bp_addr - addr; - auto saved_opcodes = software_bp_sp->m_saved_opcodes; - auto opcode_size = software_bp_sp->m_opcode_size; - ::memcpy(opcode_addr, saved_opcodes, opcode_size); - } - return Error(); +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); + + std::lock_guard<std::recursive_mutex> guard(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(); +} + +Error NativeBreakpointList::RemoveTrapsFromBuffer(lldb::addr_t addr, void *buf, + size_t size) const { + for (const auto &map : m_breakpoints) { + lldb::addr_t bp_addr = map.first; + // Breapoint not in range, ignore + if (bp_addr < addr || addr + size <= bp_addr) + continue; + const auto &bp_sp = map.second; + // Not software breakpoint, ignore + if (!bp_sp->IsSoftwareBreakpoint()) + continue; + auto software_bp_sp = std::static_pointer_cast<SoftwareBreakpoint>(bp_sp); + auto opcode_addr = static_cast<char *>(buf) + bp_addr - addr; + auto saved_opcodes = software_bp_sp->m_saved_opcodes; + auto opcode_size = software_bp_sp->m_opcode_size; + ::memcpy(opcode_addr, saved_opcodes, opcode_size); + } + return Error(); } |