1*30fdc8d8SChris Lattner //===-- BreakpointSiteList.cpp ----------------------------------*- C++ -*-===// 2*30fdc8d8SChris Lattner // 3*30fdc8d8SChris Lattner // The LLVM Compiler Infrastructure 4*30fdc8d8SChris Lattner // 5*30fdc8d8SChris Lattner // This file is distributed under the University of Illinois Open Source 6*30fdc8d8SChris Lattner // License. See LICENSE.TXT for details. 7*30fdc8d8SChris Lattner // 8*30fdc8d8SChris Lattner //===----------------------------------------------------------------------===// 9*30fdc8d8SChris Lattner 10*30fdc8d8SChris Lattner #include "lldb/Breakpoint/BreakpointSiteList.h" 11*30fdc8d8SChris Lattner 12*30fdc8d8SChris Lattner // C Includes 13*30fdc8d8SChris Lattner // C++ Includes 14*30fdc8d8SChris Lattner // Other libraries and framework includes 15*30fdc8d8SChris Lattner // Project includes 16*30fdc8d8SChris Lattner #include "lldb/Core/Stream.h" 17*30fdc8d8SChris Lattner 18*30fdc8d8SChris Lattner using namespace lldb; 19*30fdc8d8SChris Lattner using namespace lldb_private; 20*30fdc8d8SChris Lattner 21*30fdc8d8SChris Lattner BreakpointSiteList::BreakpointSiteList() : 22*30fdc8d8SChris Lattner m_bp_site_list() 23*30fdc8d8SChris Lattner { 24*30fdc8d8SChris Lattner } 25*30fdc8d8SChris Lattner 26*30fdc8d8SChris Lattner BreakpointSiteList::~BreakpointSiteList() 27*30fdc8d8SChris Lattner { 28*30fdc8d8SChris Lattner } 29*30fdc8d8SChris Lattner 30*30fdc8d8SChris Lattner // Add breakpoint site to the list. However, if the element already exists in the 31*30fdc8d8SChris Lattner // list, then we don't add it, and return LLDB_INVALID_BREAK_ID. 32*30fdc8d8SChris Lattner 33*30fdc8d8SChris Lattner lldb::user_id_t 34*30fdc8d8SChris Lattner BreakpointSiteList::Add(const BreakpointSiteSP &bp) 35*30fdc8d8SChris Lattner { 36*30fdc8d8SChris Lattner lldb::addr_t bp_site_load_addr = bp->GetLoadAddress(); 37*30fdc8d8SChris Lattner collection::iterator iter = m_bp_site_list.find (bp_site_load_addr); 38*30fdc8d8SChris Lattner 39*30fdc8d8SChris Lattner if (iter == m_bp_site_list.end()) 40*30fdc8d8SChris Lattner { 41*30fdc8d8SChris Lattner m_bp_site_list.insert (iter, collection::value_type (bp_site_load_addr, bp)); 42*30fdc8d8SChris Lattner return bp->GetID(); 43*30fdc8d8SChris Lattner } 44*30fdc8d8SChris Lattner else 45*30fdc8d8SChris Lattner { 46*30fdc8d8SChris Lattner return LLDB_INVALID_BREAK_ID; 47*30fdc8d8SChris Lattner } 48*30fdc8d8SChris Lattner } 49*30fdc8d8SChris Lattner 50*30fdc8d8SChris Lattner bool 51*30fdc8d8SChris Lattner BreakpointSiteList::ShouldStop (StoppointCallbackContext *context, lldb::user_id_t break_id) 52*30fdc8d8SChris Lattner { 53*30fdc8d8SChris Lattner BreakpointSiteSP bp = FindByID (break_id); 54*30fdc8d8SChris Lattner if (bp) 55*30fdc8d8SChris Lattner { 56*30fdc8d8SChris Lattner // Let the BreakpointSite decide if it should stop here (could not have 57*30fdc8d8SChris Lattner // reached it's target hit count yet, or it could have a callback 58*30fdc8d8SChris Lattner // that decided it shouldn't stop (shared library loads/unloads). 59*30fdc8d8SChris Lattner return bp->ShouldStop (context); 60*30fdc8d8SChris Lattner } 61*30fdc8d8SChris Lattner // We should stop here since this BreakpointSite isn't valid anymore or it 62*30fdc8d8SChris Lattner // doesn't exist. 63*30fdc8d8SChris Lattner return true; 64*30fdc8d8SChris Lattner } 65*30fdc8d8SChris Lattner lldb::user_id_t 66*30fdc8d8SChris Lattner BreakpointSiteList::FindIDByAddress (lldb::addr_t addr) 67*30fdc8d8SChris Lattner { 68*30fdc8d8SChris Lattner BreakpointSiteSP bp = FindByAddress (addr); 69*30fdc8d8SChris Lattner if (bp) 70*30fdc8d8SChris Lattner { 71*30fdc8d8SChris Lattner //DBLogIf(PD_LOG_BREAKPOINTS, "BreakpointSiteList::%s ( addr = 0x%8.8llx ) => %u", __FUNCTION__, (uint64_t)addr, bp->GetID()); 72*30fdc8d8SChris Lattner return bp.get()->GetID(); 73*30fdc8d8SChris Lattner } 74*30fdc8d8SChris Lattner //DBLogIf(PD_LOG_BREAKPOINTS, "BreakpointSiteList::%s ( addr = 0x%8.8llx ) => NONE", __FUNCTION__, (uint64_t)addr); 75*30fdc8d8SChris Lattner return LLDB_INVALID_BREAK_ID; 76*30fdc8d8SChris Lattner } 77*30fdc8d8SChris Lattner 78*30fdc8d8SChris Lattner bool 79*30fdc8d8SChris Lattner BreakpointSiteList::Remove (lldb::user_id_t break_id) 80*30fdc8d8SChris Lattner { 81*30fdc8d8SChris Lattner collection::iterator pos = GetIDIterator(break_id); // Predicate 82*30fdc8d8SChris Lattner if (pos != m_bp_site_list.end()) 83*30fdc8d8SChris Lattner { 84*30fdc8d8SChris Lattner m_bp_site_list.erase(pos); 85*30fdc8d8SChris Lattner return true; 86*30fdc8d8SChris Lattner } 87*30fdc8d8SChris Lattner return false; 88*30fdc8d8SChris Lattner } 89*30fdc8d8SChris Lattner 90*30fdc8d8SChris Lattner bool 91*30fdc8d8SChris Lattner BreakpointSiteList::RemoveByAddress (lldb::addr_t address) 92*30fdc8d8SChris Lattner { 93*30fdc8d8SChris Lattner collection::iterator pos = m_bp_site_list.find(address); 94*30fdc8d8SChris Lattner if (pos != m_bp_site_list.end()) 95*30fdc8d8SChris Lattner { 96*30fdc8d8SChris Lattner m_bp_site_list.erase(pos); 97*30fdc8d8SChris Lattner return true; 98*30fdc8d8SChris Lattner } 99*30fdc8d8SChris Lattner return false; 100*30fdc8d8SChris Lattner } 101*30fdc8d8SChris Lattner 102*30fdc8d8SChris Lattner class BreakpointSiteIDMatches 103*30fdc8d8SChris Lattner { 104*30fdc8d8SChris Lattner public: 105*30fdc8d8SChris Lattner BreakpointSiteIDMatches (lldb::user_id_t break_id) : 106*30fdc8d8SChris Lattner m_break_id(break_id) 107*30fdc8d8SChris Lattner { 108*30fdc8d8SChris Lattner } 109*30fdc8d8SChris Lattner 110*30fdc8d8SChris Lattner bool operator() (std::pair <lldb::addr_t, BreakpointSiteSP> val_pair) const 111*30fdc8d8SChris Lattner { 112*30fdc8d8SChris Lattner return m_break_id == val_pair.second.get()->GetID(); 113*30fdc8d8SChris Lattner } 114*30fdc8d8SChris Lattner 115*30fdc8d8SChris Lattner private: 116*30fdc8d8SChris Lattner const lldb::user_id_t m_break_id; 117*30fdc8d8SChris Lattner }; 118*30fdc8d8SChris Lattner 119*30fdc8d8SChris Lattner BreakpointSiteList::collection::iterator 120*30fdc8d8SChris Lattner BreakpointSiteList::GetIDIterator (lldb::user_id_t break_id) 121*30fdc8d8SChris Lattner { 122*30fdc8d8SChris Lattner return std::find_if(m_bp_site_list.begin(), m_bp_site_list.end(), // Search full range 123*30fdc8d8SChris Lattner BreakpointSiteIDMatches(break_id)); // Predicate 124*30fdc8d8SChris Lattner } 125*30fdc8d8SChris Lattner 126*30fdc8d8SChris Lattner BreakpointSiteList::collection::const_iterator 127*30fdc8d8SChris Lattner BreakpointSiteList::GetIDConstIterator (lldb::user_id_t break_id) const 128*30fdc8d8SChris Lattner { 129*30fdc8d8SChris Lattner return std::find_if(m_bp_site_list.begin(), m_bp_site_list.end(), // Search full range 130*30fdc8d8SChris Lattner BreakpointSiteIDMatches(break_id)); // Predicate 131*30fdc8d8SChris Lattner } 132*30fdc8d8SChris Lattner 133*30fdc8d8SChris Lattner BreakpointSiteSP 134*30fdc8d8SChris Lattner BreakpointSiteList::FindByID (lldb::user_id_t break_id) 135*30fdc8d8SChris Lattner { 136*30fdc8d8SChris Lattner BreakpointSiteSP stop_sp; 137*30fdc8d8SChris Lattner collection::iterator pos = GetIDIterator(break_id); 138*30fdc8d8SChris Lattner if (pos != m_bp_site_list.end()) 139*30fdc8d8SChris Lattner stop_sp = pos->second; 140*30fdc8d8SChris Lattner 141*30fdc8d8SChris Lattner return stop_sp; 142*30fdc8d8SChris Lattner } 143*30fdc8d8SChris Lattner 144*30fdc8d8SChris Lattner const BreakpointSiteSP 145*30fdc8d8SChris Lattner BreakpointSiteList::FindByID (lldb::user_id_t break_id) const 146*30fdc8d8SChris Lattner { 147*30fdc8d8SChris Lattner BreakpointSiteSP stop_sp; 148*30fdc8d8SChris Lattner collection::const_iterator pos = GetIDConstIterator(break_id); 149*30fdc8d8SChris Lattner if (pos != m_bp_site_list.end()) 150*30fdc8d8SChris Lattner stop_sp = pos->second; 151*30fdc8d8SChris Lattner 152*30fdc8d8SChris Lattner return stop_sp; 153*30fdc8d8SChris Lattner } 154*30fdc8d8SChris Lattner 155*30fdc8d8SChris Lattner BreakpointSiteSP 156*30fdc8d8SChris Lattner BreakpointSiteList::FindByAddress (lldb::addr_t addr) 157*30fdc8d8SChris Lattner { 158*30fdc8d8SChris Lattner BreakpointSiteSP found_sp; 159*30fdc8d8SChris Lattner 160*30fdc8d8SChris Lattner collection::iterator iter = m_bp_site_list.find(addr); 161*30fdc8d8SChris Lattner if (iter != m_bp_site_list.end()) 162*30fdc8d8SChris Lattner found_sp = iter->second; 163*30fdc8d8SChris Lattner return found_sp; 164*30fdc8d8SChris Lattner } 165*30fdc8d8SChris Lattner 166*30fdc8d8SChris Lattner void 167*30fdc8d8SChris Lattner BreakpointSiteList::Dump (Stream *s) const 168*30fdc8d8SChris Lattner { 169*30fdc8d8SChris Lattner s->Printf("%.*p: ", (int)sizeof(void*) * 2, this); 170*30fdc8d8SChris Lattner s->Indent(); 171*30fdc8d8SChris Lattner s->Printf("BreakpointSiteList with %u BreakpointSites:\n", (uint32_t)m_bp_site_list.size()); 172*30fdc8d8SChris Lattner s->IndentMore(); 173*30fdc8d8SChris Lattner collection::const_iterator pos; 174*30fdc8d8SChris Lattner collection::const_iterator end = m_bp_site_list.end(); 175*30fdc8d8SChris Lattner for (pos = m_bp_site_list.begin(); pos != end; ++pos) 176*30fdc8d8SChris Lattner pos->second.get()->Dump(s); 177*30fdc8d8SChris Lattner s->IndentLess(); 178*30fdc8d8SChris Lattner } 179*30fdc8d8SChris Lattner 180*30fdc8d8SChris Lattner 181*30fdc8d8SChris Lattner BreakpointSiteSP 182*30fdc8d8SChris Lattner BreakpointSiteList::GetByIndex (uint32_t i) 183*30fdc8d8SChris Lattner { 184*30fdc8d8SChris Lattner BreakpointSiteSP stop_sp; 185*30fdc8d8SChris Lattner collection::iterator end = m_bp_site_list.end(); 186*30fdc8d8SChris Lattner collection::iterator pos; 187*30fdc8d8SChris Lattner uint32_t curr_i = 0; 188*30fdc8d8SChris Lattner for (pos = m_bp_site_list.begin(), curr_i = 0; pos != end; ++pos, ++curr_i) 189*30fdc8d8SChris Lattner { 190*30fdc8d8SChris Lattner if (curr_i == i) 191*30fdc8d8SChris Lattner stop_sp = pos->second; 192*30fdc8d8SChris Lattner } 193*30fdc8d8SChris Lattner return stop_sp; 194*30fdc8d8SChris Lattner } 195*30fdc8d8SChris Lattner 196*30fdc8d8SChris Lattner const BreakpointSiteSP 197*30fdc8d8SChris Lattner BreakpointSiteList::GetByIndex (uint32_t i) const 198*30fdc8d8SChris Lattner { 199*30fdc8d8SChris Lattner BreakpointSiteSP stop_sp; 200*30fdc8d8SChris Lattner collection::const_iterator end = m_bp_site_list.end(); 201*30fdc8d8SChris Lattner collection::const_iterator pos; 202*30fdc8d8SChris Lattner uint32_t curr_i = 0; 203*30fdc8d8SChris Lattner for (pos = m_bp_site_list.begin(), curr_i = 0; pos != end; ++pos, ++curr_i) 204*30fdc8d8SChris Lattner { 205*30fdc8d8SChris Lattner if (curr_i == i) 206*30fdc8d8SChris Lattner stop_sp = pos->second; 207*30fdc8d8SChris Lattner } 208*30fdc8d8SChris Lattner return stop_sp; 209*30fdc8d8SChris Lattner } 210*30fdc8d8SChris Lattner 211*30fdc8d8SChris Lattner void 212*30fdc8d8SChris Lattner BreakpointSiteList::SetEnabledForAll (const bool enabled, const lldb::user_id_t except_id) 213*30fdc8d8SChris Lattner { 214*30fdc8d8SChris Lattner collection::iterator end = m_bp_site_list.end(); 215*30fdc8d8SChris Lattner collection::iterator pos; 216*30fdc8d8SChris Lattner for (pos = m_bp_site_list.begin(); pos != end; ++pos) 217*30fdc8d8SChris Lattner { 218*30fdc8d8SChris Lattner if (except_id != LLDB_INVALID_BREAK_ID && except_id != pos->second->GetID()) 219*30fdc8d8SChris Lattner pos->second->SetEnabled (enabled); 220*30fdc8d8SChris Lattner else 221*30fdc8d8SChris Lattner pos->second->SetEnabled (!enabled); 222*30fdc8d8SChris Lattner } 223*30fdc8d8SChris Lattner } 224*30fdc8d8SChris Lattner 225*30fdc8d8SChris Lattner const BreakpointSiteList::collection * 226*30fdc8d8SChris Lattner BreakpointSiteList::GetMap () 227*30fdc8d8SChris Lattner { 228*30fdc8d8SChris Lattner return &m_bp_site_list; 229*30fdc8d8SChris Lattner } 230