130fdc8d8SChris Lattner //===-- BreakpointSiteList.cpp ----------------------------------*- C++ -*-===// 230fdc8d8SChris Lattner // 330fdc8d8SChris Lattner // The LLVM Compiler Infrastructure 430fdc8d8SChris Lattner // 530fdc8d8SChris Lattner // This file is distributed under the University of Illinois Open Source 630fdc8d8SChris Lattner // License. See LICENSE.TXT for details. 730fdc8d8SChris Lattner // 830fdc8d8SChris Lattner //===----------------------------------------------------------------------===// 930fdc8d8SChris Lattner 1030fdc8d8SChris Lattner #include "lldb/Breakpoint/BreakpointSiteList.h" 1130fdc8d8SChris Lattner 1230fdc8d8SChris Lattner // C Includes 1330fdc8d8SChris Lattner // C++ Includes 1430fdc8d8SChris Lattner // Other libraries and framework includes 1530fdc8d8SChris Lattner // Project includes 1630fdc8d8SChris Lattner #include "lldb/Core/Stream.h" 17*ebb81bebSEli Friedman #include <algorithm> 1830fdc8d8SChris Lattner 1930fdc8d8SChris Lattner using namespace lldb; 2030fdc8d8SChris Lattner using namespace lldb_private; 2130fdc8d8SChris Lattner 2230fdc8d8SChris Lattner BreakpointSiteList::BreakpointSiteList() : 2330fdc8d8SChris Lattner m_bp_site_list() 2430fdc8d8SChris Lattner { 2530fdc8d8SChris Lattner } 2630fdc8d8SChris Lattner 2730fdc8d8SChris Lattner BreakpointSiteList::~BreakpointSiteList() 2830fdc8d8SChris Lattner { 2930fdc8d8SChris Lattner } 3030fdc8d8SChris Lattner 3130fdc8d8SChris Lattner // Add breakpoint site to the list. However, if the element already exists in the 3230fdc8d8SChris Lattner // list, then we don't add it, and return LLDB_INVALID_BREAK_ID. 3330fdc8d8SChris Lattner 3430fdc8d8SChris Lattner lldb::user_id_t 3530fdc8d8SChris Lattner BreakpointSiteList::Add(const BreakpointSiteSP &bp) 3630fdc8d8SChris Lattner { 3730fdc8d8SChris Lattner lldb::addr_t bp_site_load_addr = bp->GetLoadAddress(); 3830fdc8d8SChris Lattner collection::iterator iter = m_bp_site_list.find (bp_site_load_addr); 3930fdc8d8SChris Lattner 4030fdc8d8SChris Lattner if (iter == m_bp_site_list.end()) 4130fdc8d8SChris Lattner { 4230fdc8d8SChris Lattner m_bp_site_list.insert (iter, collection::value_type (bp_site_load_addr, bp)); 4330fdc8d8SChris Lattner return bp->GetID(); 4430fdc8d8SChris Lattner } 4530fdc8d8SChris Lattner else 4630fdc8d8SChris Lattner { 4730fdc8d8SChris Lattner return LLDB_INVALID_BREAK_ID; 4830fdc8d8SChris Lattner } 4930fdc8d8SChris Lattner } 5030fdc8d8SChris Lattner 5130fdc8d8SChris Lattner bool 5230fdc8d8SChris Lattner BreakpointSiteList::ShouldStop (StoppointCallbackContext *context, lldb::user_id_t break_id) 5330fdc8d8SChris Lattner { 5430fdc8d8SChris Lattner BreakpointSiteSP bp = FindByID (break_id); 5530fdc8d8SChris Lattner if (bp) 5630fdc8d8SChris Lattner { 5730fdc8d8SChris Lattner // Let the BreakpointSite decide if it should stop here (could not have 5830fdc8d8SChris Lattner // reached it's target hit count yet, or it could have a callback 5930fdc8d8SChris Lattner // that decided it shouldn't stop (shared library loads/unloads). 6030fdc8d8SChris Lattner return bp->ShouldStop (context); 6130fdc8d8SChris Lattner } 6230fdc8d8SChris Lattner // We should stop here since this BreakpointSite isn't valid anymore or it 6330fdc8d8SChris Lattner // doesn't exist. 6430fdc8d8SChris Lattner return true; 6530fdc8d8SChris Lattner } 6630fdc8d8SChris Lattner lldb::user_id_t 6730fdc8d8SChris Lattner BreakpointSiteList::FindIDByAddress (lldb::addr_t addr) 6830fdc8d8SChris Lattner { 6930fdc8d8SChris Lattner BreakpointSiteSP bp = FindByAddress (addr); 7030fdc8d8SChris Lattner if (bp) 7130fdc8d8SChris Lattner { 7230fdc8d8SChris Lattner //DBLogIf(PD_LOG_BREAKPOINTS, "BreakpointSiteList::%s ( addr = 0x%8.8llx ) => %u", __FUNCTION__, (uint64_t)addr, bp->GetID()); 7330fdc8d8SChris Lattner return bp.get()->GetID(); 7430fdc8d8SChris Lattner } 7530fdc8d8SChris Lattner //DBLogIf(PD_LOG_BREAKPOINTS, "BreakpointSiteList::%s ( addr = 0x%8.8llx ) => NONE", __FUNCTION__, (uint64_t)addr); 7630fdc8d8SChris Lattner return LLDB_INVALID_BREAK_ID; 7730fdc8d8SChris Lattner } 7830fdc8d8SChris Lattner 7930fdc8d8SChris Lattner bool 8030fdc8d8SChris Lattner BreakpointSiteList::Remove (lldb::user_id_t break_id) 8130fdc8d8SChris Lattner { 8230fdc8d8SChris Lattner collection::iterator pos = GetIDIterator(break_id); // Predicate 8330fdc8d8SChris Lattner if (pos != m_bp_site_list.end()) 8430fdc8d8SChris Lattner { 8530fdc8d8SChris Lattner m_bp_site_list.erase(pos); 8630fdc8d8SChris Lattner return true; 8730fdc8d8SChris Lattner } 8830fdc8d8SChris Lattner return false; 8930fdc8d8SChris Lattner } 9030fdc8d8SChris Lattner 9130fdc8d8SChris Lattner bool 9230fdc8d8SChris Lattner BreakpointSiteList::RemoveByAddress (lldb::addr_t address) 9330fdc8d8SChris Lattner { 9430fdc8d8SChris Lattner collection::iterator pos = m_bp_site_list.find(address); 9530fdc8d8SChris Lattner if (pos != m_bp_site_list.end()) 9630fdc8d8SChris Lattner { 9730fdc8d8SChris Lattner m_bp_site_list.erase(pos); 9830fdc8d8SChris Lattner return true; 9930fdc8d8SChris Lattner } 10030fdc8d8SChris Lattner return false; 10130fdc8d8SChris Lattner } 10230fdc8d8SChris Lattner 10330fdc8d8SChris Lattner class BreakpointSiteIDMatches 10430fdc8d8SChris Lattner { 10530fdc8d8SChris Lattner public: 10630fdc8d8SChris Lattner BreakpointSiteIDMatches (lldb::user_id_t break_id) : 10730fdc8d8SChris Lattner m_break_id(break_id) 10830fdc8d8SChris Lattner { 10930fdc8d8SChris Lattner } 11030fdc8d8SChris Lattner 11130fdc8d8SChris Lattner bool operator() (std::pair <lldb::addr_t, BreakpointSiteSP> val_pair) const 11230fdc8d8SChris Lattner { 11330fdc8d8SChris Lattner return m_break_id == val_pair.second.get()->GetID(); 11430fdc8d8SChris Lattner } 11530fdc8d8SChris Lattner 11630fdc8d8SChris Lattner private: 11730fdc8d8SChris Lattner const lldb::user_id_t m_break_id; 11830fdc8d8SChris Lattner }; 11930fdc8d8SChris Lattner 12030fdc8d8SChris Lattner BreakpointSiteList::collection::iterator 12130fdc8d8SChris Lattner BreakpointSiteList::GetIDIterator (lldb::user_id_t break_id) 12230fdc8d8SChris Lattner { 12330fdc8d8SChris Lattner return std::find_if(m_bp_site_list.begin(), m_bp_site_list.end(), // Search full range 12430fdc8d8SChris Lattner BreakpointSiteIDMatches(break_id)); // Predicate 12530fdc8d8SChris Lattner } 12630fdc8d8SChris Lattner 12730fdc8d8SChris Lattner BreakpointSiteList::collection::const_iterator 12830fdc8d8SChris Lattner BreakpointSiteList::GetIDConstIterator (lldb::user_id_t break_id) const 12930fdc8d8SChris Lattner { 13030fdc8d8SChris Lattner return std::find_if(m_bp_site_list.begin(), m_bp_site_list.end(), // Search full range 13130fdc8d8SChris Lattner BreakpointSiteIDMatches(break_id)); // Predicate 13230fdc8d8SChris Lattner } 13330fdc8d8SChris Lattner 13430fdc8d8SChris Lattner BreakpointSiteSP 13530fdc8d8SChris Lattner BreakpointSiteList::FindByID (lldb::user_id_t break_id) 13630fdc8d8SChris Lattner { 13730fdc8d8SChris Lattner BreakpointSiteSP stop_sp; 13830fdc8d8SChris Lattner collection::iterator pos = GetIDIterator(break_id); 13930fdc8d8SChris Lattner if (pos != m_bp_site_list.end()) 14030fdc8d8SChris Lattner stop_sp = pos->second; 14130fdc8d8SChris Lattner 14230fdc8d8SChris Lattner return stop_sp; 14330fdc8d8SChris Lattner } 14430fdc8d8SChris Lattner 14530fdc8d8SChris Lattner const BreakpointSiteSP 14630fdc8d8SChris Lattner BreakpointSiteList::FindByID (lldb::user_id_t break_id) const 14730fdc8d8SChris Lattner { 14830fdc8d8SChris Lattner BreakpointSiteSP stop_sp; 14930fdc8d8SChris Lattner collection::const_iterator pos = GetIDConstIterator(break_id); 15030fdc8d8SChris Lattner if (pos != m_bp_site_list.end()) 15130fdc8d8SChris Lattner stop_sp = pos->second; 15230fdc8d8SChris Lattner 15330fdc8d8SChris Lattner return stop_sp; 15430fdc8d8SChris Lattner } 15530fdc8d8SChris Lattner 15630fdc8d8SChris Lattner BreakpointSiteSP 15730fdc8d8SChris Lattner BreakpointSiteList::FindByAddress (lldb::addr_t addr) 15830fdc8d8SChris Lattner { 15930fdc8d8SChris Lattner BreakpointSiteSP found_sp; 16030fdc8d8SChris Lattner 16130fdc8d8SChris Lattner collection::iterator iter = m_bp_site_list.find(addr); 16230fdc8d8SChris Lattner if (iter != m_bp_site_list.end()) 16330fdc8d8SChris Lattner found_sp = iter->second; 16430fdc8d8SChris Lattner return found_sp; 16530fdc8d8SChris Lattner } 16630fdc8d8SChris Lattner 16730fdc8d8SChris Lattner void 16830fdc8d8SChris Lattner BreakpointSiteList::Dump (Stream *s) const 16930fdc8d8SChris Lattner { 17030fdc8d8SChris Lattner s->Printf("%.*p: ", (int)sizeof(void*) * 2, this); 17130fdc8d8SChris Lattner s->Indent(); 17230fdc8d8SChris Lattner s->Printf("BreakpointSiteList with %u BreakpointSites:\n", (uint32_t)m_bp_site_list.size()); 17330fdc8d8SChris Lattner s->IndentMore(); 17430fdc8d8SChris Lattner collection::const_iterator pos; 17530fdc8d8SChris Lattner collection::const_iterator end = m_bp_site_list.end(); 17630fdc8d8SChris Lattner for (pos = m_bp_site_list.begin(); pos != end; ++pos) 17730fdc8d8SChris Lattner pos->second.get()->Dump(s); 17830fdc8d8SChris Lattner s->IndentLess(); 17930fdc8d8SChris Lattner } 18030fdc8d8SChris Lattner 18130fdc8d8SChris Lattner 18230fdc8d8SChris Lattner BreakpointSiteSP 18330fdc8d8SChris Lattner BreakpointSiteList::GetByIndex (uint32_t i) 18430fdc8d8SChris Lattner { 18530fdc8d8SChris Lattner BreakpointSiteSP stop_sp; 18630fdc8d8SChris Lattner collection::iterator end = m_bp_site_list.end(); 18730fdc8d8SChris Lattner collection::iterator pos; 18830fdc8d8SChris Lattner uint32_t curr_i = 0; 18930fdc8d8SChris Lattner for (pos = m_bp_site_list.begin(), curr_i = 0; pos != end; ++pos, ++curr_i) 19030fdc8d8SChris Lattner { 19130fdc8d8SChris Lattner if (curr_i == i) 19230fdc8d8SChris Lattner stop_sp = pos->second; 19330fdc8d8SChris Lattner } 19430fdc8d8SChris Lattner return stop_sp; 19530fdc8d8SChris Lattner } 19630fdc8d8SChris Lattner 19730fdc8d8SChris Lattner const BreakpointSiteSP 19830fdc8d8SChris Lattner BreakpointSiteList::GetByIndex (uint32_t i) const 19930fdc8d8SChris Lattner { 20030fdc8d8SChris Lattner BreakpointSiteSP stop_sp; 20130fdc8d8SChris Lattner collection::const_iterator end = m_bp_site_list.end(); 20230fdc8d8SChris Lattner collection::const_iterator pos; 20330fdc8d8SChris Lattner uint32_t curr_i = 0; 20430fdc8d8SChris Lattner for (pos = m_bp_site_list.begin(), curr_i = 0; pos != end; ++pos, ++curr_i) 20530fdc8d8SChris Lattner { 20630fdc8d8SChris Lattner if (curr_i == i) 20730fdc8d8SChris Lattner stop_sp = pos->second; 20830fdc8d8SChris Lattner } 20930fdc8d8SChris Lattner return stop_sp; 21030fdc8d8SChris Lattner } 21130fdc8d8SChris Lattner 21230fdc8d8SChris Lattner void 21330fdc8d8SChris Lattner BreakpointSiteList::SetEnabledForAll (const bool enabled, const lldb::user_id_t except_id) 21430fdc8d8SChris Lattner { 21530fdc8d8SChris Lattner collection::iterator end = m_bp_site_list.end(); 21630fdc8d8SChris Lattner collection::iterator pos; 21730fdc8d8SChris Lattner for (pos = m_bp_site_list.begin(); pos != end; ++pos) 21830fdc8d8SChris Lattner { 21930fdc8d8SChris Lattner if (except_id != LLDB_INVALID_BREAK_ID && except_id != pos->second->GetID()) 22030fdc8d8SChris Lattner pos->second->SetEnabled (enabled); 22130fdc8d8SChris Lattner else 22230fdc8d8SChris Lattner pos->second->SetEnabled (!enabled); 22330fdc8d8SChris Lattner } 22430fdc8d8SChris Lattner } 22530fdc8d8SChris Lattner 22630fdc8d8SChris Lattner const BreakpointSiteList::collection * 22730fdc8d8SChris Lattner BreakpointSiteList::GetMap () 22830fdc8d8SChris Lattner { 22930fdc8d8SChris Lattner return &m_bp_site_list; 23030fdc8d8SChris Lattner } 231