1ac7ddfbfSEd Maste //===-- SBBreakpoint.cpp ----------------------------------------*- C++ -*-===//
2ac7ddfbfSEd Maste //
3ac7ddfbfSEd Maste //                     The LLVM Compiler Infrastructure
4ac7ddfbfSEd Maste //
5ac7ddfbfSEd Maste // This file is distributed under the University of Illinois Open Source
6ac7ddfbfSEd Maste // License. See LICENSE.TXT for details.
7ac7ddfbfSEd Maste //
8ac7ddfbfSEd Maste //===----------------------------------------------------------------------===//
9ac7ddfbfSEd Maste 
10ac7ddfbfSEd Maste #include "lldb/API/SBBreakpoint.h"
11ac7ddfbfSEd Maste #include "lldb/API/SBBreakpointLocation.h"
12ac7ddfbfSEd Maste #include "lldb/API/SBDebugger.h"
13ac7ddfbfSEd Maste #include "lldb/API/SBEvent.h"
14ac7ddfbfSEd Maste #include "lldb/API/SBProcess.h"
15ac7ddfbfSEd Maste #include "lldb/API/SBStream.h"
167aa51b79SEd Maste #include "lldb/API/SBStringList.h"
17ac7ddfbfSEd Maste #include "lldb/API/SBThread.h"
18ac7ddfbfSEd Maste 
19ac7ddfbfSEd Maste #include "lldb/Breakpoint/Breakpoint.h"
20435933ddSDimitry Andric #include "lldb/Breakpoint/BreakpointIDList.h"
21ac7ddfbfSEd Maste #include "lldb/Breakpoint/BreakpointLocation.h"
22*b5893f02SDimitry Andric #include "lldb/Breakpoint/BreakpointResolver.h"
23*b5893f02SDimitry Andric #include "lldb/Breakpoint/BreakpointResolverScripted.h"
24ac7ddfbfSEd Maste #include "lldb/Breakpoint/StoppointCallbackContext.h"
25ac7ddfbfSEd Maste #include "lldb/Core/Address.h"
260127ef0fSEd Maste #include "lldb/Core/Debugger.h"
27ac7ddfbfSEd Maste #include "lldb/Core/StreamFile.h"
280127ef0fSEd Maste #include "lldb/Interpreter/CommandInterpreter.h"
290127ef0fSEd Maste #include "lldb/Interpreter/ScriptInterpreter.h"
30ac7ddfbfSEd Maste #include "lldb/Target/Process.h"
3112b93ac6SEd Maste #include "lldb/Target/SectionLoadList.h"
32ac7ddfbfSEd Maste #include "lldb/Target/Target.h"
33ac7ddfbfSEd Maste #include "lldb/Target/Thread.h"
34ac7ddfbfSEd Maste #include "lldb/Target/ThreadSpec.h"
35f678e45dSDimitry Andric #include "lldb/Utility/Log.h"
36f678e45dSDimitry Andric #include "lldb/Utility/Stream.h"
37ac7ddfbfSEd Maste 
38acac075bSDimitry Andric #include "SBBreakpointOptionCommon.h"
39acac075bSDimitry Andric 
40ac7ddfbfSEd Maste #include "lldb/lldb-enumerations.h"
41ac7ddfbfSEd Maste 
42435933ddSDimitry Andric #include "llvm/ADT/STLExtras.h"
43435933ddSDimitry Andric 
44ac7ddfbfSEd Maste using namespace lldb;
45ac7ddfbfSEd Maste using namespace lldb_private;
46ac7ddfbfSEd Maste 
SBBreakpoint()47f678e45dSDimitry Andric SBBreakpoint::SBBreakpoint() {}
48ac7ddfbfSEd Maste 
SBBreakpoint(const SBBreakpoint & rhs)49435933ddSDimitry Andric SBBreakpoint::SBBreakpoint(const SBBreakpoint &rhs)
50f678e45dSDimitry Andric     : m_opaque_wp(rhs.m_opaque_wp) {}
51ac7ddfbfSEd Maste 
SBBreakpoint(const lldb::BreakpointSP & bp_sp)52435933ddSDimitry Andric SBBreakpoint::SBBreakpoint(const lldb::BreakpointSP &bp_sp)
53f678e45dSDimitry Andric     : m_opaque_wp(bp_sp) {}
54ac7ddfbfSEd Maste 
559f2f44ceSEd Maste SBBreakpoint::~SBBreakpoint() = default;
56ac7ddfbfSEd Maste 
operator =(const SBBreakpoint & rhs)57435933ddSDimitry Andric const SBBreakpoint &SBBreakpoint::operator=(const SBBreakpoint &rhs) {
58f678e45dSDimitry Andric   m_opaque_wp = rhs.m_opaque_wp;
59ac7ddfbfSEd Maste   return *this;
60ac7ddfbfSEd Maste }
61ac7ddfbfSEd Maste 
operator ==(const lldb::SBBreakpoint & rhs)62435933ddSDimitry Andric bool SBBreakpoint::operator==(const lldb::SBBreakpoint &rhs) {
63f678e45dSDimitry Andric   return m_opaque_wp.lock() == rhs.m_opaque_wp.lock();
64ac7ddfbfSEd Maste }
65ac7ddfbfSEd Maste 
operator !=(const lldb::SBBreakpoint & rhs)66435933ddSDimitry Andric bool SBBreakpoint::operator!=(const lldb::SBBreakpoint &rhs) {
67f678e45dSDimitry Andric   return m_opaque_wp.lock() != rhs.m_opaque_wp.lock();
68ac7ddfbfSEd Maste }
69ac7ddfbfSEd Maste 
GetID() const70435933ddSDimitry Andric break_id_t SBBreakpoint::GetID() const {
71ac7ddfbfSEd Maste   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
72ac7ddfbfSEd Maste 
73ac7ddfbfSEd Maste   break_id_t break_id = LLDB_INVALID_BREAK_ID;
74f678e45dSDimitry Andric   BreakpointSP bkpt_sp = GetSP();
75f678e45dSDimitry Andric   if (bkpt_sp)
76f678e45dSDimitry Andric     break_id = bkpt_sp->GetID();
77ac7ddfbfSEd Maste 
78f678e45dSDimitry Andric   LLDB_LOG(log, "breakpoint = {0}, id = {1}", bkpt_sp.get(), break_id);
79ac7ddfbfSEd Maste   return break_id;
80ac7ddfbfSEd Maste }
81ac7ddfbfSEd Maste 
IsValid() const82435933ddSDimitry Andric bool SBBreakpoint::IsValid() const {
83f678e45dSDimitry Andric   BreakpointSP bkpt_sp = GetSP();
84f678e45dSDimitry Andric   if (!bkpt_sp)
850127ef0fSEd Maste     return false;
86f678e45dSDimitry Andric   else if (bkpt_sp->GetTarget().GetBreakpointByID(bkpt_sp->GetID()))
870127ef0fSEd Maste     return true;
880127ef0fSEd Maste   else
890127ef0fSEd Maste     return false;
90ac7ddfbfSEd Maste }
91ac7ddfbfSEd Maste 
ClearAllBreakpointSites()92435933ddSDimitry Andric void SBBreakpoint::ClearAllBreakpointSites() {
93f678e45dSDimitry Andric   BreakpointSP bkpt_sp = GetSP();
94f678e45dSDimitry Andric   if (bkpt_sp) {
95435933ddSDimitry Andric     std::lock_guard<std::recursive_mutex> guard(
96f678e45dSDimitry Andric         bkpt_sp->GetTarget().GetAPIMutex());
97f678e45dSDimitry Andric     bkpt_sp->ClearAllBreakpointSites();
98ac7ddfbfSEd Maste   }
99ac7ddfbfSEd Maste }
100ac7ddfbfSEd Maste 
FindLocationByAddress(addr_t vm_addr)101435933ddSDimitry Andric SBBreakpointLocation SBBreakpoint::FindLocationByAddress(addr_t vm_addr) {
102ac7ddfbfSEd Maste   SBBreakpointLocation sb_bp_location;
103ac7ddfbfSEd Maste 
104f678e45dSDimitry Andric   BreakpointSP bkpt_sp = GetSP();
105f678e45dSDimitry Andric   if (bkpt_sp) {
106435933ddSDimitry Andric     if (vm_addr != LLDB_INVALID_ADDRESS) {
107435933ddSDimitry Andric       std::lock_guard<std::recursive_mutex> guard(
108f678e45dSDimitry Andric           bkpt_sp->GetTarget().GetAPIMutex());
109ac7ddfbfSEd Maste       Address address;
110f678e45dSDimitry Andric       Target &target = bkpt_sp->GetTarget();
111435933ddSDimitry Andric       if (!target.GetSectionLoadList().ResolveLoadAddress(vm_addr, address)) {
112ac7ddfbfSEd Maste         address.SetRawAddress(vm_addr);
113ac7ddfbfSEd Maste       }
114f678e45dSDimitry Andric       sb_bp_location.SetLocation(bkpt_sp->FindLocationByAddress(address));
115ac7ddfbfSEd Maste     }
116ac7ddfbfSEd Maste   }
117ac7ddfbfSEd Maste   return sb_bp_location;
118ac7ddfbfSEd Maste }
119ac7ddfbfSEd Maste 
FindLocationIDByAddress(addr_t vm_addr)120435933ddSDimitry Andric break_id_t SBBreakpoint::FindLocationIDByAddress(addr_t vm_addr) {
121ac7ddfbfSEd Maste   break_id_t break_id = LLDB_INVALID_BREAK_ID;
122f678e45dSDimitry Andric   BreakpointSP bkpt_sp = GetSP();
123ac7ddfbfSEd Maste 
124f678e45dSDimitry Andric   if (bkpt_sp && vm_addr != LLDB_INVALID_ADDRESS) {
125435933ddSDimitry Andric     std::lock_guard<std::recursive_mutex> guard(
126f678e45dSDimitry Andric         bkpt_sp->GetTarget().GetAPIMutex());
127ac7ddfbfSEd Maste     Address address;
128f678e45dSDimitry Andric     Target &target = bkpt_sp->GetTarget();
129435933ddSDimitry Andric     if (!target.GetSectionLoadList().ResolveLoadAddress(vm_addr, address)) {
130ac7ddfbfSEd Maste       address.SetRawAddress(vm_addr);
131ac7ddfbfSEd Maste     }
132f678e45dSDimitry Andric     break_id = bkpt_sp->FindLocationIDByAddress(address);
133ac7ddfbfSEd Maste   }
134ac7ddfbfSEd Maste 
135ac7ddfbfSEd Maste   return break_id;
136ac7ddfbfSEd Maste }
137ac7ddfbfSEd Maste 
FindLocationByID(break_id_t bp_loc_id)138435933ddSDimitry Andric SBBreakpointLocation SBBreakpoint::FindLocationByID(break_id_t bp_loc_id) {
139ac7ddfbfSEd Maste   SBBreakpointLocation sb_bp_location;
140f678e45dSDimitry Andric   BreakpointSP bkpt_sp = GetSP();
141ac7ddfbfSEd Maste 
142f678e45dSDimitry Andric   if (bkpt_sp) {
143435933ddSDimitry Andric     std::lock_guard<std::recursive_mutex> guard(
144f678e45dSDimitry Andric         bkpt_sp->GetTarget().GetAPIMutex());
145f678e45dSDimitry Andric     sb_bp_location.SetLocation(bkpt_sp->FindLocationByID(bp_loc_id));
146ac7ddfbfSEd Maste   }
147ac7ddfbfSEd Maste 
148ac7ddfbfSEd Maste   return sb_bp_location;
149ac7ddfbfSEd Maste }
150ac7ddfbfSEd Maste 
GetLocationAtIndex(uint32_t index)151435933ddSDimitry Andric SBBreakpointLocation SBBreakpoint::GetLocationAtIndex(uint32_t index) {
152ac7ddfbfSEd Maste   SBBreakpointLocation sb_bp_location;
153f678e45dSDimitry Andric   BreakpointSP bkpt_sp = GetSP();
154ac7ddfbfSEd Maste 
155f678e45dSDimitry Andric   if (bkpt_sp) {
156435933ddSDimitry Andric     std::lock_guard<std::recursive_mutex> guard(
157f678e45dSDimitry Andric         bkpt_sp->GetTarget().GetAPIMutex());
158f678e45dSDimitry Andric     sb_bp_location.SetLocation(bkpt_sp->GetLocationAtIndex(index));
159ac7ddfbfSEd Maste   }
160ac7ddfbfSEd Maste 
161ac7ddfbfSEd Maste   return sb_bp_location;
162ac7ddfbfSEd Maste }
163ac7ddfbfSEd Maste 
SetEnabled(bool enable)164435933ddSDimitry Andric void SBBreakpoint::SetEnabled(bool enable) {
165ac7ddfbfSEd Maste   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
166f678e45dSDimitry Andric   BreakpointSP bkpt_sp = GetSP();
167ac7ddfbfSEd Maste 
168f678e45dSDimitry Andric   LLDB_LOG(log, "breakpoint = {0}, enable = {1}", bkpt_sp.get(), enable);
169ac7ddfbfSEd Maste 
170f678e45dSDimitry Andric   if (bkpt_sp) {
171435933ddSDimitry Andric     std::lock_guard<std::recursive_mutex> guard(
172f678e45dSDimitry Andric         bkpt_sp->GetTarget().GetAPIMutex());
173f678e45dSDimitry Andric     bkpt_sp->SetEnabled(enable);
174ac7ddfbfSEd Maste   }
175ac7ddfbfSEd Maste }
176ac7ddfbfSEd Maste 
IsEnabled()177435933ddSDimitry Andric bool SBBreakpoint::IsEnabled() {
178f678e45dSDimitry Andric   BreakpointSP bkpt_sp = GetSP();
179f678e45dSDimitry Andric   if (bkpt_sp) {
180435933ddSDimitry Andric     std::lock_guard<std::recursive_mutex> guard(
181f678e45dSDimitry Andric         bkpt_sp->GetTarget().GetAPIMutex());
182f678e45dSDimitry Andric     return bkpt_sp->IsEnabled();
183435933ddSDimitry Andric   } else
184ac7ddfbfSEd Maste     return false;
185ac7ddfbfSEd Maste }
186ac7ddfbfSEd Maste 
SetOneShot(bool one_shot)187435933ddSDimitry Andric void SBBreakpoint::SetOneShot(bool one_shot) {
188ac7ddfbfSEd Maste   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
189f678e45dSDimitry Andric   BreakpointSP bkpt_sp = GetSP();
190ac7ddfbfSEd Maste 
191f678e45dSDimitry Andric   LLDB_LOG(log, "breakpoint = {0}, one_shot = {1}", bkpt_sp.get(), one_shot);
192ac7ddfbfSEd Maste 
193f678e45dSDimitry Andric   if (bkpt_sp) {
194435933ddSDimitry Andric     std::lock_guard<std::recursive_mutex> guard(
195f678e45dSDimitry Andric         bkpt_sp->GetTarget().GetAPIMutex());
196f678e45dSDimitry Andric     bkpt_sp->SetOneShot(one_shot);
197ac7ddfbfSEd Maste   }
198ac7ddfbfSEd Maste }
199ac7ddfbfSEd Maste 
IsOneShot() const200435933ddSDimitry Andric bool SBBreakpoint::IsOneShot() const {
201f678e45dSDimitry Andric   BreakpointSP bkpt_sp = GetSP();
202f678e45dSDimitry Andric   if (bkpt_sp) {
203435933ddSDimitry Andric     std::lock_guard<std::recursive_mutex> guard(
204f678e45dSDimitry Andric         bkpt_sp->GetTarget().GetAPIMutex());
205f678e45dSDimitry Andric     return bkpt_sp->IsOneShot();
206435933ddSDimitry Andric   } else
207ac7ddfbfSEd Maste     return false;
208ac7ddfbfSEd Maste }
209ac7ddfbfSEd Maste 
IsInternal()210435933ddSDimitry Andric bool SBBreakpoint::IsInternal() {
211f678e45dSDimitry Andric   BreakpointSP bkpt_sp = GetSP();
212f678e45dSDimitry Andric   if (bkpt_sp) {
213435933ddSDimitry Andric     std::lock_guard<std::recursive_mutex> guard(
214f678e45dSDimitry Andric         bkpt_sp->GetTarget().GetAPIMutex());
215f678e45dSDimitry Andric     return bkpt_sp->IsInternal();
216435933ddSDimitry Andric   } else
217ac7ddfbfSEd Maste     return false;
218ac7ddfbfSEd Maste }
219ac7ddfbfSEd Maste 
SetIgnoreCount(uint32_t count)220435933ddSDimitry Andric void SBBreakpoint::SetIgnoreCount(uint32_t count) {
221ac7ddfbfSEd Maste   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
222f678e45dSDimitry Andric   BreakpointSP bkpt_sp = GetSP();
223ac7ddfbfSEd Maste 
224f678e45dSDimitry Andric   LLDB_LOG(log, "breakpoint = {0}, count = {1}", bkpt_sp.get(), count);
225ac7ddfbfSEd Maste 
226f678e45dSDimitry Andric   if (bkpt_sp) {
227435933ddSDimitry Andric     std::lock_guard<std::recursive_mutex> guard(
228f678e45dSDimitry Andric         bkpt_sp->GetTarget().GetAPIMutex());
229f678e45dSDimitry Andric     bkpt_sp->SetIgnoreCount(count);
230ac7ddfbfSEd Maste   }
231ac7ddfbfSEd Maste }
232ac7ddfbfSEd Maste 
SetCondition(const char * condition)233435933ddSDimitry Andric void SBBreakpoint::SetCondition(const char *condition) {
234f678e45dSDimitry Andric   BreakpointSP bkpt_sp = GetSP();
235f678e45dSDimitry Andric   if (bkpt_sp) {
236435933ddSDimitry Andric     std::lock_guard<std::recursive_mutex> guard(
237f678e45dSDimitry Andric         bkpt_sp->GetTarget().GetAPIMutex());
238f678e45dSDimitry Andric     bkpt_sp->SetCondition(condition);
239ac7ddfbfSEd Maste   }
240ac7ddfbfSEd Maste }
241ac7ddfbfSEd Maste 
GetCondition()242435933ddSDimitry Andric const char *SBBreakpoint::GetCondition() {
243f678e45dSDimitry Andric   BreakpointSP bkpt_sp = GetSP();
244f678e45dSDimitry Andric   if (bkpt_sp) {
245435933ddSDimitry Andric     std::lock_guard<std::recursive_mutex> guard(
246f678e45dSDimitry Andric         bkpt_sp->GetTarget().GetAPIMutex());
247f678e45dSDimitry Andric     return bkpt_sp->GetConditionText();
248ac7ddfbfSEd Maste   }
2499f2f44ceSEd Maste   return nullptr;
250ac7ddfbfSEd Maste }
251ac7ddfbfSEd Maste 
SetAutoContinue(bool auto_continue)252acac075bSDimitry Andric void SBBreakpoint::SetAutoContinue(bool auto_continue) {
253acac075bSDimitry Andric   BreakpointSP bkpt_sp = GetSP();
254acac075bSDimitry Andric   if (bkpt_sp) {
255acac075bSDimitry Andric     std::lock_guard<std::recursive_mutex> guard(
256acac075bSDimitry Andric         bkpt_sp->GetTarget().GetAPIMutex());
257acac075bSDimitry Andric     bkpt_sp->SetAutoContinue(auto_continue);
258acac075bSDimitry Andric   }
259acac075bSDimitry Andric }
260acac075bSDimitry Andric 
GetAutoContinue()261acac075bSDimitry Andric bool SBBreakpoint::GetAutoContinue() {
262acac075bSDimitry Andric   BreakpointSP bkpt_sp = GetSP();
263acac075bSDimitry Andric   if (bkpt_sp) {
264acac075bSDimitry Andric     std::lock_guard<std::recursive_mutex> guard(
265acac075bSDimitry Andric         bkpt_sp->GetTarget().GetAPIMutex());
266acac075bSDimitry Andric     return bkpt_sp->IsAutoContinue();
267acac075bSDimitry Andric   }
268acac075bSDimitry Andric   return false;
269acac075bSDimitry Andric }
270acac075bSDimitry Andric 
GetHitCount() const271435933ddSDimitry Andric uint32_t SBBreakpoint::GetHitCount() const {
272ac7ddfbfSEd Maste   uint32_t count = 0;
273f678e45dSDimitry Andric   BreakpointSP bkpt_sp = GetSP();
274f678e45dSDimitry Andric   if (bkpt_sp) {
275435933ddSDimitry Andric     std::lock_guard<std::recursive_mutex> guard(
276f678e45dSDimitry Andric         bkpt_sp->GetTarget().GetAPIMutex());
277f678e45dSDimitry Andric     count = bkpt_sp->GetHitCount();
278ac7ddfbfSEd Maste   }
279ac7ddfbfSEd Maste 
280ac7ddfbfSEd Maste   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
281f678e45dSDimitry Andric   LLDB_LOG(log, "breakpoint = {0}, count = {1}", bkpt_sp.get(), count);
282ac7ddfbfSEd Maste 
283ac7ddfbfSEd Maste   return count;
284ac7ddfbfSEd Maste }
285ac7ddfbfSEd Maste 
GetIgnoreCount() const286435933ddSDimitry Andric uint32_t SBBreakpoint::GetIgnoreCount() const {
287ac7ddfbfSEd Maste   uint32_t count = 0;
288f678e45dSDimitry Andric   BreakpointSP bkpt_sp = GetSP();
289f678e45dSDimitry Andric   if (bkpt_sp) {
290435933ddSDimitry Andric     std::lock_guard<std::recursive_mutex> guard(
291f678e45dSDimitry Andric         bkpt_sp->GetTarget().GetAPIMutex());
292f678e45dSDimitry Andric     count = bkpt_sp->GetIgnoreCount();
293ac7ddfbfSEd Maste   }
294ac7ddfbfSEd Maste 
295ac7ddfbfSEd Maste   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
296f678e45dSDimitry Andric   LLDB_LOG(log, "breakpoint = {0}, count = {1}", bkpt_sp.get(), count);
297ac7ddfbfSEd Maste 
298ac7ddfbfSEd Maste   return count;
299ac7ddfbfSEd Maste }
300ac7ddfbfSEd Maste 
SetThreadID(tid_t tid)301435933ddSDimitry Andric void SBBreakpoint::SetThreadID(tid_t tid) {
302f678e45dSDimitry Andric   BreakpointSP bkpt_sp = GetSP();
303f678e45dSDimitry Andric   if (bkpt_sp) {
304435933ddSDimitry Andric     std::lock_guard<std::recursive_mutex> guard(
305f678e45dSDimitry Andric         bkpt_sp->GetTarget().GetAPIMutex());
306f678e45dSDimitry Andric     bkpt_sp->SetThreadID(tid);
307ac7ddfbfSEd Maste   }
308ac7ddfbfSEd Maste   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
309f678e45dSDimitry Andric   LLDB_LOG(log, "breakpoint = {0}, tid = {1:x}", bkpt_sp.get(), tid);
310ac7ddfbfSEd Maste }
311ac7ddfbfSEd Maste 
GetThreadID()312435933ddSDimitry Andric tid_t SBBreakpoint::GetThreadID() {
313ac7ddfbfSEd Maste   tid_t tid = LLDB_INVALID_THREAD_ID;
314f678e45dSDimitry Andric   BreakpointSP bkpt_sp = GetSP();
315f678e45dSDimitry Andric   if (bkpt_sp) {
316435933ddSDimitry Andric     std::lock_guard<std::recursive_mutex> guard(
317f678e45dSDimitry Andric         bkpt_sp->GetTarget().GetAPIMutex());
318f678e45dSDimitry Andric     tid = bkpt_sp->GetThreadID();
319ac7ddfbfSEd Maste   }
320ac7ddfbfSEd Maste 
321ac7ddfbfSEd Maste   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
322f678e45dSDimitry Andric   LLDB_LOG(log, "breakpoint = {0}, tid = {1:x}", bkpt_sp.get(), tid);
323ac7ddfbfSEd Maste   return tid;
324ac7ddfbfSEd Maste }
325ac7ddfbfSEd Maste 
SetThreadIndex(uint32_t index)326435933ddSDimitry Andric void SBBreakpoint::SetThreadIndex(uint32_t index) {
327ac7ddfbfSEd Maste   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
328f678e45dSDimitry Andric   BreakpointSP bkpt_sp = GetSP();
329f678e45dSDimitry Andric   LLDB_LOG(log, "breakpoint = {0}, index = {1}", bkpt_sp.get(), index);
330f678e45dSDimitry Andric   if (bkpt_sp) {
331435933ddSDimitry Andric     std::lock_guard<std::recursive_mutex> guard(
332f678e45dSDimitry Andric         bkpt_sp->GetTarget().GetAPIMutex());
333f678e45dSDimitry Andric     bkpt_sp->GetOptions()->GetThreadSpec()->SetIndex(index);
334ac7ddfbfSEd Maste   }
335ac7ddfbfSEd Maste }
336ac7ddfbfSEd Maste 
GetThreadIndex() const337435933ddSDimitry Andric uint32_t SBBreakpoint::GetThreadIndex() const {
338ac7ddfbfSEd Maste   uint32_t thread_idx = UINT32_MAX;
339f678e45dSDimitry Andric   BreakpointSP bkpt_sp = GetSP();
340f678e45dSDimitry Andric   if (bkpt_sp) {
341435933ddSDimitry Andric     std::lock_guard<std::recursive_mutex> guard(
342f678e45dSDimitry Andric         bkpt_sp->GetTarget().GetAPIMutex());
343435933ddSDimitry Andric     const ThreadSpec *thread_spec =
344f678e45dSDimitry Andric         bkpt_sp->GetOptions()->GetThreadSpecNoCreate();
3459f2f44ceSEd Maste     if (thread_spec != nullptr)
346ac7ddfbfSEd Maste       thread_idx = thread_spec->GetIndex();
347ac7ddfbfSEd Maste   }
348ac7ddfbfSEd Maste   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
349f678e45dSDimitry Andric   LLDB_LOG(log, "breakpoint = {0}, index = {1}", bkpt_sp.get(), thread_idx);
350ac7ddfbfSEd Maste 
351ac7ddfbfSEd Maste   return thread_idx;
352ac7ddfbfSEd Maste }
353ac7ddfbfSEd Maste 
SetThreadName(const char * thread_name)354435933ddSDimitry Andric void SBBreakpoint::SetThreadName(const char *thread_name) {
355ac7ddfbfSEd Maste   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
356f678e45dSDimitry Andric   BreakpointSP bkpt_sp = GetSP();
357f678e45dSDimitry Andric   LLDB_LOG(log, "breakpoint = {0}, name = {1}", bkpt_sp.get(), thread_name);
358ac7ddfbfSEd Maste 
359f678e45dSDimitry Andric   if (bkpt_sp) {
360435933ddSDimitry Andric     std::lock_guard<std::recursive_mutex> guard(
361f678e45dSDimitry Andric         bkpt_sp->GetTarget().GetAPIMutex());
362f678e45dSDimitry Andric     bkpt_sp->GetOptions()->GetThreadSpec()->SetName(thread_name);
363ac7ddfbfSEd Maste   }
364ac7ddfbfSEd Maste }
365ac7ddfbfSEd Maste 
GetThreadName() const366435933ddSDimitry Andric const char *SBBreakpoint::GetThreadName() const {
3679f2f44ceSEd Maste   const char *name = nullptr;
368f678e45dSDimitry Andric   BreakpointSP bkpt_sp = GetSP();
369f678e45dSDimitry Andric   if (bkpt_sp) {
370435933ddSDimitry Andric     std::lock_guard<std::recursive_mutex> guard(
371f678e45dSDimitry Andric         bkpt_sp->GetTarget().GetAPIMutex());
372435933ddSDimitry Andric     const ThreadSpec *thread_spec =
373f678e45dSDimitry Andric         bkpt_sp->GetOptions()->GetThreadSpecNoCreate();
3749f2f44ceSEd Maste     if (thread_spec != nullptr)
375ac7ddfbfSEd Maste       name = thread_spec->GetName();
376ac7ddfbfSEd Maste   }
377ac7ddfbfSEd Maste   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
378f678e45dSDimitry Andric   LLDB_LOG(log, "breakpoint = {0}, name = {1}", bkpt_sp.get(), name);
379ac7ddfbfSEd Maste 
380ac7ddfbfSEd Maste   return name;
381ac7ddfbfSEd Maste }
382ac7ddfbfSEd Maste 
SetQueueName(const char * queue_name)383435933ddSDimitry Andric void SBBreakpoint::SetQueueName(const char *queue_name) {
384ac7ddfbfSEd Maste   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
385f678e45dSDimitry Andric   BreakpointSP bkpt_sp = GetSP();
386f678e45dSDimitry Andric   LLDB_LOG(log, "breakpoint = {0}, queue_name = {1}", bkpt_sp.get(),
387f678e45dSDimitry Andric            queue_name);
388f678e45dSDimitry Andric   if (bkpt_sp) {
389435933ddSDimitry Andric     std::lock_guard<std::recursive_mutex> guard(
390f678e45dSDimitry Andric         bkpt_sp->GetTarget().GetAPIMutex());
391f678e45dSDimitry Andric     bkpt_sp->GetOptions()->GetThreadSpec()->SetQueueName(queue_name);
392ac7ddfbfSEd Maste   }
393ac7ddfbfSEd Maste }
394ac7ddfbfSEd Maste 
GetQueueName() const395435933ddSDimitry Andric const char *SBBreakpoint::GetQueueName() const {
3969f2f44ceSEd Maste   const char *name = nullptr;
397f678e45dSDimitry Andric   BreakpointSP bkpt_sp = GetSP();
398f678e45dSDimitry Andric   if (bkpt_sp) {
399435933ddSDimitry Andric     std::lock_guard<std::recursive_mutex> guard(
400f678e45dSDimitry Andric         bkpt_sp->GetTarget().GetAPIMutex());
401435933ddSDimitry Andric     const ThreadSpec *thread_spec =
402f678e45dSDimitry Andric         bkpt_sp->GetOptions()->GetThreadSpecNoCreate();
403ac7ddfbfSEd Maste     if (thread_spec)
404ac7ddfbfSEd Maste       name = thread_spec->GetQueueName();
405ac7ddfbfSEd Maste   }
406ac7ddfbfSEd Maste   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
407f678e45dSDimitry Andric   LLDB_LOG(log, "breakpoint = {0}, name = {1}", bkpt_sp.get(), name);
408ac7ddfbfSEd Maste 
409ac7ddfbfSEd Maste   return name;
410ac7ddfbfSEd Maste }
411ac7ddfbfSEd Maste 
GetNumResolvedLocations() const412435933ddSDimitry Andric size_t SBBreakpoint::GetNumResolvedLocations() const {
413ac7ddfbfSEd Maste   size_t num_resolved = 0;
414f678e45dSDimitry Andric   BreakpointSP bkpt_sp = GetSP();
415f678e45dSDimitry Andric   if (bkpt_sp) {
416435933ddSDimitry Andric     std::lock_guard<std::recursive_mutex> guard(
417f678e45dSDimitry Andric         bkpt_sp->GetTarget().GetAPIMutex());
418f678e45dSDimitry Andric     num_resolved = bkpt_sp->GetNumResolvedLocations();
419ac7ddfbfSEd Maste   }
420ac7ddfbfSEd Maste   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
421f678e45dSDimitry Andric   LLDB_LOG(log, "breakpoint = {0}, num_resolved = {1}", bkpt_sp.get(),
422f678e45dSDimitry Andric            num_resolved);
423ac7ddfbfSEd Maste   return num_resolved;
424ac7ddfbfSEd Maste }
425ac7ddfbfSEd Maste 
GetNumLocations() const426435933ddSDimitry Andric size_t SBBreakpoint::GetNumLocations() const {
427f678e45dSDimitry Andric   BreakpointSP bkpt_sp = GetSP();
428ac7ddfbfSEd Maste   size_t num_locs = 0;
429f678e45dSDimitry Andric   if (bkpt_sp) {
430435933ddSDimitry Andric     std::lock_guard<std::recursive_mutex> guard(
431f678e45dSDimitry Andric         bkpt_sp->GetTarget().GetAPIMutex());
432f678e45dSDimitry Andric     num_locs = bkpt_sp->GetNumLocations();
433ac7ddfbfSEd Maste   }
434ac7ddfbfSEd Maste   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
435f678e45dSDimitry Andric   LLDB_LOG(log, "breakpoint = {0}, num_locs = {1}", bkpt_sp.get(), num_locs);
436ac7ddfbfSEd Maste   return num_locs;
437ac7ddfbfSEd Maste }
438ac7ddfbfSEd Maste 
SetCommandLineCommands(SBStringList & commands)439435933ddSDimitry Andric void SBBreakpoint::SetCommandLineCommands(SBStringList &commands) {
440f678e45dSDimitry Andric   BreakpointSP bkpt_sp = GetSP();
441f678e45dSDimitry Andric   if (!bkpt_sp)
442435933ddSDimitry Andric     return;
443435933ddSDimitry Andric   if (commands.GetSize() == 0)
444435933ddSDimitry Andric     return;
445435933ddSDimitry Andric 
446435933ddSDimitry Andric   std::lock_guard<std::recursive_mutex> guard(
447f678e45dSDimitry Andric       bkpt_sp->GetTarget().GetAPIMutex());
448435933ddSDimitry Andric   std::unique_ptr<BreakpointOptions::CommandData> cmd_data_up(
449435933ddSDimitry Andric       new BreakpointOptions::CommandData(*commands, eScriptLanguageNone));
450435933ddSDimitry Andric 
451f678e45dSDimitry Andric   bkpt_sp->GetOptions()->SetCommandDataCallback(cmd_data_up);
452435933ddSDimitry Andric }
453435933ddSDimitry Andric 
GetCommandLineCommands(SBStringList & commands)454435933ddSDimitry Andric bool SBBreakpoint::GetCommandLineCommands(SBStringList &commands) {
455f678e45dSDimitry Andric   BreakpointSP bkpt_sp = GetSP();
456f678e45dSDimitry Andric   if (!bkpt_sp)
457435933ddSDimitry Andric     return false;
458435933ddSDimitry Andric   StringList command_list;
459435933ddSDimitry Andric   bool has_commands =
460f678e45dSDimitry Andric       bkpt_sp->GetOptions()->GetCommandLineCallbacks(command_list);
461435933ddSDimitry Andric   if (has_commands)
462435933ddSDimitry Andric     commands.AppendList(command_list);
463435933ddSDimitry Andric   return has_commands;
464435933ddSDimitry Andric }
465435933ddSDimitry Andric 
GetDescription(SBStream & s)466435933ddSDimitry Andric bool SBBreakpoint::GetDescription(SBStream &s) {
467435933ddSDimitry Andric   return GetDescription(s, true);
468435933ddSDimitry Andric }
469435933ddSDimitry Andric 
GetDescription(SBStream & s,bool include_locations)470435933ddSDimitry Andric bool SBBreakpoint::GetDescription(SBStream &s, bool include_locations) {
471f678e45dSDimitry Andric   BreakpointSP bkpt_sp = GetSP();
472f678e45dSDimitry Andric   if (bkpt_sp) {
473435933ddSDimitry Andric     std::lock_guard<std::recursive_mutex> guard(
474f678e45dSDimitry Andric         bkpt_sp->GetTarget().GetAPIMutex());
475f678e45dSDimitry Andric     s.Printf("SBBreakpoint: id = %i, ", bkpt_sp->GetID());
476f678e45dSDimitry Andric     bkpt_sp->GetResolverDescription(s.get());
477f678e45dSDimitry Andric     bkpt_sp->GetFilterDescription(s.get());
478435933ddSDimitry Andric     if (include_locations) {
479f678e45dSDimitry Andric       const size_t num_locations = bkpt_sp->GetNumLocations();
480ac7ddfbfSEd Maste       s.Printf(", locations = %" PRIu64, (uint64_t)num_locations);
481435933ddSDimitry Andric     }
482ac7ddfbfSEd Maste     return true;
483ac7ddfbfSEd Maste   }
484ac7ddfbfSEd Maste   s.Printf("No value");
485ac7ddfbfSEd Maste   return false;
486ac7ddfbfSEd Maste }
487ac7ddfbfSEd Maste 
488*b5893f02SDimitry Andric SBError
AddLocation(SBAddress & address)489*b5893f02SDimitry Andric SBBreakpoint::AddLocation(SBAddress &address) {
490*b5893f02SDimitry Andric     BreakpointSP bkpt_sp = GetSP();
491*b5893f02SDimitry Andric     SBError error;
492*b5893f02SDimitry Andric 
493*b5893f02SDimitry Andric     if (!address.IsValid()) {
494*b5893f02SDimitry Andric       error.SetErrorString("Can't add an invalid address.");
495*b5893f02SDimitry Andric       return error;
496*b5893f02SDimitry Andric     }
497*b5893f02SDimitry Andric 
498*b5893f02SDimitry Andric     if (!bkpt_sp) {
499*b5893f02SDimitry Andric       error.SetErrorString("No breakpoint to add a location to.");
500*b5893f02SDimitry Andric       return error;
501*b5893f02SDimitry Andric     }
502*b5893f02SDimitry Andric 
503*b5893f02SDimitry Andric     if (!llvm::isa<BreakpointResolverScripted>(bkpt_sp->GetResolver().get())) {
504*b5893f02SDimitry Andric       error.SetErrorString("Only a scripted resolver can add locations.");
505*b5893f02SDimitry Andric       return error;
506*b5893f02SDimitry Andric     }
507*b5893f02SDimitry Andric 
508*b5893f02SDimitry Andric     if (bkpt_sp->GetSearchFilter()->AddressPasses(address.ref()))
509*b5893f02SDimitry Andric       bkpt_sp->AddLocation(address.ref());
510*b5893f02SDimitry Andric     else
511*b5893f02SDimitry Andric     {
512*b5893f02SDimitry Andric       StreamString s;
513*b5893f02SDimitry Andric       address.get()->Dump(&s, &bkpt_sp->GetTarget(),
514*b5893f02SDimitry Andric                           Address::DumpStyleModuleWithFileAddress);
515*b5893f02SDimitry Andric       error.SetErrorStringWithFormat("Address: %s didn't pass the filter.",
516*b5893f02SDimitry Andric                                      s.GetData());
517*b5893f02SDimitry Andric     }
518*b5893f02SDimitry Andric     return error;
519*b5893f02SDimitry Andric }
520*b5893f02SDimitry Andric 
521*b5893f02SDimitry Andric 
522acac075bSDimitry Andric void SBBreakpoint
SetCallback(SBBreakpointHitCallback callback,void * baton)523acac075bSDimitry Andric   ::SetCallback(SBBreakpointHitCallback callback,
524acac075bSDimitry Andric   void *baton) {
525ac7ddfbfSEd Maste   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
526f678e45dSDimitry Andric   BreakpointSP bkpt_sp = GetSP();
527f678e45dSDimitry Andric   LLDB_LOG(log, "breakpoint = {0}, callback = {1}, baton = {2}", bkpt_sp.get(),
528f678e45dSDimitry Andric            callback, baton);
529ac7ddfbfSEd Maste 
530f678e45dSDimitry Andric   if (bkpt_sp) {
531435933ddSDimitry Andric     std::lock_guard<std::recursive_mutex> guard(
532f678e45dSDimitry Andric         bkpt_sp->GetTarget().GetAPIMutex());
533ac7ddfbfSEd Maste     BatonSP baton_sp(new SBBreakpointCallbackBaton(callback, baton));
534acac075bSDimitry Andric     bkpt_sp->SetCallback(SBBreakpointCallbackBaton
535acac075bSDimitry Andric       ::PrivateBreakpointHitCallback, baton_sp,
536f678e45dSDimitry Andric                          false);
537ac7ddfbfSEd Maste   }
538ac7ddfbfSEd Maste }
539ac7ddfbfSEd Maste 
SetScriptCallbackFunction(const char * callback_function_name)540435933ddSDimitry Andric void SBBreakpoint::SetScriptCallbackFunction(
541435933ddSDimitry Andric     const char *callback_function_name) {
5420127ef0fSEd Maste   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
543f678e45dSDimitry Andric   BreakpointSP bkpt_sp = GetSP();
544f678e45dSDimitry Andric   LLDB_LOG(log, "breakpoint = {0}, callback = {1}", bkpt_sp.get(),
545f678e45dSDimitry Andric            callback_function_name);
5460127ef0fSEd Maste 
547f678e45dSDimitry Andric   if (bkpt_sp) {
548435933ddSDimitry Andric     std::lock_guard<std::recursive_mutex> guard(
549f678e45dSDimitry Andric         bkpt_sp->GetTarget().GetAPIMutex());
550f678e45dSDimitry Andric     BreakpointOptions *bp_options = bkpt_sp->GetOptions();
551f678e45dSDimitry Andric     bkpt_sp->GetTarget()
552435933ddSDimitry Andric         .GetDebugger()
553435933ddSDimitry Andric         .GetCommandInterpreter()
554435933ddSDimitry Andric         .GetScriptInterpreter()
555435933ddSDimitry Andric         ->SetBreakpointCommandCallbackFunction(bp_options,
5560127ef0fSEd Maste                                                callback_function_name);
5570127ef0fSEd Maste   }
5580127ef0fSEd Maste }
5590127ef0fSEd Maste 
SetScriptCallbackBody(const char * callback_body_text)560435933ddSDimitry Andric SBError SBBreakpoint::SetScriptCallbackBody(const char *callback_body_text) {
5610127ef0fSEd Maste   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
562f678e45dSDimitry Andric   BreakpointSP bkpt_sp = GetSP();
563f678e45dSDimitry Andric   LLDB_LOG(log, "breakpoint = {0}, callback body:\n{1}", bkpt_sp.get(),
564f678e45dSDimitry Andric            callback_body_text);
5650127ef0fSEd Maste 
5660127ef0fSEd Maste   SBError sb_error;
567f678e45dSDimitry Andric   if (bkpt_sp) {
568435933ddSDimitry Andric     std::lock_guard<std::recursive_mutex> guard(
569f678e45dSDimitry Andric         bkpt_sp->GetTarget().GetAPIMutex());
570f678e45dSDimitry Andric     BreakpointOptions *bp_options = bkpt_sp->GetOptions();
5715517e702SDimitry Andric     Status error =
572f678e45dSDimitry Andric         bkpt_sp->GetTarget()
573435933ddSDimitry Andric             .GetDebugger()
574435933ddSDimitry Andric             .GetCommandInterpreter()
575435933ddSDimitry Andric             .GetScriptInterpreter()
576435933ddSDimitry Andric             ->SetBreakpointCommandCallback(bp_options, callback_body_text);
5770127ef0fSEd Maste     sb_error.SetError(error);
578435933ddSDimitry Andric   } else
5790127ef0fSEd Maste     sb_error.SetErrorString("invalid breakpoint");
5800127ef0fSEd Maste 
5810127ef0fSEd Maste   return sb_error;
5820127ef0fSEd Maste }
583ac7ddfbfSEd Maste 
AddName(const char * new_name)584435933ddSDimitry Andric bool SBBreakpoint::AddName(const char *new_name) {
5857aa51b79SEd Maste   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
586f678e45dSDimitry Andric   BreakpointSP bkpt_sp = GetSP();
587f678e45dSDimitry Andric   LLDB_LOG(log, "breakpoint = {0}, name = {1}", bkpt_sp.get(), new_name);
5887aa51b79SEd Maste 
589f678e45dSDimitry Andric   if (bkpt_sp) {
590435933ddSDimitry Andric     std::lock_guard<std::recursive_mutex> guard(
591f678e45dSDimitry Andric         bkpt_sp->GetTarget().GetAPIMutex());
5925517e702SDimitry Andric     Status error; // Think I'm just going to swallow the error here, it's
593435933ddSDimitry Andric                   // probably more annoying to have to provide it.
594acac075bSDimitry Andric     bkpt_sp->GetTarget().AddNameToBreakpoint(bkpt_sp, new_name, error);
595acac075bSDimitry Andric     if (error.Fail())
596acac075bSDimitry Andric     {
597acac075bSDimitry Andric       if (log)
598acac075bSDimitry Andric         log->Printf("Failed to add name: '%s' to breakpoint: %s",
599acac075bSDimitry Andric             new_name, error.AsCString());
600acac075bSDimitry Andric       return false;
601acac075bSDimitry Andric     }
6027aa51b79SEd Maste   }
6037aa51b79SEd Maste 
604acac075bSDimitry Andric   return true;
6057aa51b79SEd Maste }
6067aa51b79SEd Maste 
RemoveName(const char * name_to_remove)607435933ddSDimitry Andric void SBBreakpoint::RemoveName(const char *name_to_remove) {
6087aa51b79SEd Maste   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
609f678e45dSDimitry Andric   BreakpointSP bkpt_sp = GetSP();
610f678e45dSDimitry Andric   LLDB_LOG(log, "breakpoint = {0}, name = {1}", bkpt_sp.get(), name_to_remove);
6117aa51b79SEd Maste 
612f678e45dSDimitry Andric   if (bkpt_sp) {
613435933ddSDimitry Andric     std::lock_guard<std::recursive_mutex> guard(
614f678e45dSDimitry Andric         bkpt_sp->GetTarget().GetAPIMutex());
615acac075bSDimitry Andric     bkpt_sp->GetTarget().RemoveNameFromBreakpoint(bkpt_sp,
616acac075bSDimitry Andric                                                  ConstString(name_to_remove));
6177aa51b79SEd Maste   }
6187aa51b79SEd Maste }
6197aa51b79SEd Maste 
MatchesName(const char * name)620435933ddSDimitry Andric bool SBBreakpoint::MatchesName(const char *name) {
6217aa51b79SEd Maste   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
622f678e45dSDimitry Andric   BreakpointSP bkpt_sp = GetSP();
623f678e45dSDimitry Andric   LLDB_LOG(log, "breakpoint = {0}, name = {1}", bkpt_sp.get(), name);
6247aa51b79SEd Maste 
625f678e45dSDimitry Andric   if (bkpt_sp) {
626435933ddSDimitry Andric     std::lock_guard<std::recursive_mutex> guard(
627f678e45dSDimitry Andric         bkpt_sp->GetTarget().GetAPIMutex());
628f678e45dSDimitry Andric     return bkpt_sp->MatchesName(name);
6297aa51b79SEd Maste   }
6307aa51b79SEd Maste 
6317aa51b79SEd Maste   return false;
6327aa51b79SEd Maste }
6337aa51b79SEd Maste 
GetNames(SBStringList & names)634435933ddSDimitry Andric void SBBreakpoint::GetNames(SBStringList &names) {
6357aa51b79SEd Maste   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
636f678e45dSDimitry Andric   BreakpointSP bkpt_sp = GetSP();
637f678e45dSDimitry Andric   LLDB_LOG(log, "breakpoint = {0}", bkpt_sp.get());
6387aa51b79SEd Maste 
639f678e45dSDimitry Andric   if (bkpt_sp) {
640435933ddSDimitry Andric     std::lock_guard<std::recursive_mutex> guard(
641f678e45dSDimitry Andric         bkpt_sp->GetTarget().GetAPIMutex());
6427aa51b79SEd Maste     std::vector<std::string> names_vec;
643f678e45dSDimitry Andric     bkpt_sp->GetNames(names_vec);
644435933ddSDimitry Andric     for (std::string name : names_vec) {
6457aa51b79SEd Maste       names.AppendString(name.c_str());
6467aa51b79SEd Maste     }
6477aa51b79SEd Maste   }
6487aa51b79SEd Maste }
6497aa51b79SEd Maste 
EventIsBreakpointEvent(const lldb::SBEvent & event)650435933ddSDimitry Andric bool SBBreakpoint::EventIsBreakpointEvent(const lldb::SBEvent &event) {
651435933ddSDimitry Andric   return Breakpoint::BreakpointEventData::GetEventDataFromEvent(event.get()) !=
652435933ddSDimitry Andric          nullptr;
653ac7ddfbfSEd Maste }
654ac7ddfbfSEd Maste 
655ac7ddfbfSEd Maste BreakpointEventType
GetBreakpointEventTypeFromEvent(const SBEvent & event)656435933ddSDimitry Andric SBBreakpoint::GetBreakpointEventTypeFromEvent(const SBEvent &event) {
657ac7ddfbfSEd Maste   if (event.IsValid())
658435933ddSDimitry Andric     return Breakpoint::BreakpointEventData::GetBreakpointEventTypeFromEvent(
659435933ddSDimitry Andric         event.GetSP());
660ac7ddfbfSEd Maste   return eBreakpointEventTypeInvalidType;
661ac7ddfbfSEd Maste }
662ac7ddfbfSEd Maste 
GetBreakpointFromEvent(const lldb::SBEvent & event)663435933ddSDimitry Andric SBBreakpoint SBBreakpoint::GetBreakpointFromEvent(const lldb::SBEvent &event) {
664ac7ddfbfSEd Maste   if (event.IsValid())
665f678e45dSDimitry Andric     return SBBreakpoint(
666f678e45dSDimitry Andric         Breakpoint::BreakpointEventData::GetBreakpointFromEvent(event.GetSP()));
667f678e45dSDimitry Andric   return SBBreakpoint();
668ac7ddfbfSEd Maste }
669ac7ddfbfSEd Maste 
670ac7ddfbfSEd Maste SBBreakpointLocation
GetBreakpointLocationAtIndexFromEvent(const lldb::SBEvent & event,uint32_t loc_idx)671435933ddSDimitry Andric SBBreakpoint::GetBreakpointLocationAtIndexFromEvent(const lldb::SBEvent &event,
672435933ddSDimitry Andric                                                     uint32_t loc_idx) {
673ac7ddfbfSEd Maste   SBBreakpointLocation sb_breakpoint_loc;
674ac7ddfbfSEd Maste   if (event.IsValid())
675435933ddSDimitry Andric     sb_breakpoint_loc.SetLocation(
676435933ddSDimitry Andric         Breakpoint::BreakpointEventData::GetBreakpointLocationAtIndexFromEvent(
677435933ddSDimitry Andric             event.GetSP(), loc_idx));
678ac7ddfbfSEd Maste   return sb_breakpoint_loc;
679ac7ddfbfSEd Maste }
680ac7ddfbfSEd Maste 
681ac7ddfbfSEd Maste uint32_t
GetNumBreakpointLocationsFromEvent(const lldb::SBEvent & event)682435933ddSDimitry Andric SBBreakpoint::GetNumBreakpointLocationsFromEvent(const lldb::SBEvent &event) {
683ac7ddfbfSEd Maste   uint32_t num_locations = 0;
684ac7ddfbfSEd Maste   if (event.IsValid())
685435933ddSDimitry Andric     num_locations =
686435933ddSDimitry Andric         (Breakpoint::BreakpointEventData::GetNumBreakpointLocationsFromEvent(
687435933ddSDimitry Andric             event.GetSP()));
688ac7ddfbfSEd Maste   return num_locations;
689ac7ddfbfSEd Maste }
690435933ddSDimitry Andric 
IsHardware() const691*b5893f02SDimitry Andric bool SBBreakpoint::IsHardware() const {
692*b5893f02SDimitry Andric   BreakpointSP bkpt_sp = GetSP();
693*b5893f02SDimitry Andric   if (bkpt_sp)
694*b5893f02SDimitry Andric     return bkpt_sp->IsHardware();
695*b5893f02SDimitry Andric   return false;
696*b5893f02SDimitry Andric }
697*b5893f02SDimitry Andric 
GetSP() const698f678e45dSDimitry Andric BreakpointSP SBBreakpoint::GetSP() const { return m_opaque_wp.lock(); }
699f678e45dSDimitry Andric 
700435933ddSDimitry Andric // This is simple collection of breakpoint id's and their target.
701435933ddSDimitry Andric class SBBreakpointListImpl {
702435933ddSDimitry Andric public:
SBBreakpointListImpl(lldb::TargetSP target_sp)703435933ddSDimitry Andric   SBBreakpointListImpl(lldb::TargetSP target_sp) : m_target_wp() {
704435933ddSDimitry Andric     if (target_sp && target_sp->IsValid())
705435933ddSDimitry Andric       m_target_wp = target_sp;
706435933ddSDimitry Andric   }
707435933ddSDimitry Andric 
708435933ddSDimitry Andric   ~SBBreakpointListImpl() = default;
709435933ddSDimitry Andric 
GetSize()710435933ddSDimitry Andric   size_t GetSize() { return m_break_ids.size(); }
711435933ddSDimitry Andric 
GetBreakpointAtIndex(size_t idx)712435933ddSDimitry Andric   BreakpointSP GetBreakpointAtIndex(size_t idx) {
713435933ddSDimitry Andric     if (idx >= m_break_ids.size())
714435933ddSDimitry Andric       return BreakpointSP();
715435933ddSDimitry Andric     TargetSP target_sp = m_target_wp.lock();
716435933ddSDimitry Andric     if (!target_sp)
717435933ddSDimitry Andric       return BreakpointSP();
718435933ddSDimitry Andric     lldb::break_id_t bp_id = m_break_ids[idx];
719435933ddSDimitry Andric     return target_sp->GetBreakpointList().FindBreakpointByID(bp_id);
720435933ddSDimitry Andric   }
721435933ddSDimitry Andric 
FindBreakpointByID(lldb::break_id_t desired_id)722435933ddSDimitry Andric   BreakpointSP FindBreakpointByID(lldb::break_id_t desired_id) {
723435933ddSDimitry Andric     TargetSP target_sp = m_target_wp.lock();
724435933ddSDimitry Andric     if (!target_sp)
725435933ddSDimitry Andric       return BreakpointSP();
726435933ddSDimitry Andric 
727435933ddSDimitry Andric     for (lldb::break_id_t &break_id : m_break_ids) {
728435933ddSDimitry Andric       if (break_id == desired_id)
729435933ddSDimitry Andric         return target_sp->GetBreakpointList().FindBreakpointByID(break_id);
730435933ddSDimitry Andric     }
731435933ddSDimitry Andric     return BreakpointSP();
732435933ddSDimitry Andric   }
733435933ddSDimitry Andric 
Append(BreakpointSP bkpt)734f678e45dSDimitry Andric   bool Append(BreakpointSP bkpt) {
735435933ddSDimitry Andric     TargetSP target_sp = m_target_wp.lock();
736f678e45dSDimitry Andric     if (!target_sp || !bkpt)
737435933ddSDimitry Andric       return false;
738f678e45dSDimitry Andric     if (bkpt->GetTargetSP() != target_sp)
739435933ddSDimitry Andric       return false;
740f678e45dSDimitry Andric     m_break_ids.push_back(bkpt->GetID());
741435933ddSDimitry Andric     return true;
742435933ddSDimitry Andric   }
743435933ddSDimitry Andric 
AppendIfUnique(BreakpointSP bkpt)744f678e45dSDimitry Andric   bool AppendIfUnique(BreakpointSP bkpt) {
745435933ddSDimitry Andric     TargetSP target_sp = m_target_wp.lock();
746f678e45dSDimitry Andric     if (!target_sp || !bkpt)
747435933ddSDimitry Andric       return false;
748f678e45dSDimitry Andric     if (bkpt->GetTargetSP() != target_sp)
749435933ddSDimitry Andric       return false;
750f678e45dSDimitry Andric     lldb::break_id_t bp_id = bkpt->GetID();
751435933ddSDimitry Andric     if (find(m_break_ids.begin(), m_break_ids.end(), bp_id) ==
752435933ddSDimitry Andric         m_break_ids.end())
753435933ddSDimitry Andric       return false;
754435933ddSDimitry Andric 
755f678e45dSDimitry Andric     m_break_ids.push_back(bkpt->GetID());
756435933ddSDimitry Andric     return true;
757435933ddSDimitry Andric   }
758435933ddSDimitry Andric 
AppendByID(lldb::break_id_t id)759435933ddSDimitry Andric   bool AppendByID(lldb::break_id_t id) {
760435933ddSDimitry Andric     TargetSP target_sp = m_target_wp.lock();
761435933ddSDimitry Andric     if (!target_sp)
762435933ddSDimitry Andric       return false;
763435933ddSDimitry Andric     if (id == LLDB_INVALID_BREAK_ID)
764435933ddSDimitry Andric       return false;
765435933ddSDimitry Andric     m_break_ids.push_back(id);
766435933ddSDimitry Andric     return true;
767435933ddSDimitry Andric   }
768435933ddSDimitry Andric 
Clear()769435933ddSDimitry Andric   void Clear() { m_break_ids.clear(); }
770435933ddSDimitry Andric 
CopyToBreakpointIDList(lldb_private::BreakpointIDList & bp_list)771435933ddSDimitry Andric   void CopyToBreakpointIDList(lldb_private::BreakpointIDList &bp_list) {
772435933ddSDimitry Andric     for (lldb::break_id_t id : m_break_ids) {
773435933ddSDimitry Andric       bp_list.AddBreakpointID(BreakpointID(id));
774435933ddSDimitry Andric     }
775435933ddSDimitry Andric   }
776435933ddSDimitry Andric 
GetTarget()777435933ddSDimitry Andric   TargetSP GetTarget() { return m_target_wp.lock(); }
778435933ddSDimitry Andric 
779435933ddSDimitry Andric private:
780435933ddSDimitry Andric   std::vector<lldb::break_id_t> m_break_ids;
781435933ddSDimitry Andric   TargetWP m_target_wp;
782435933ddSDimitry Andric };
783435933ddSDimitry Andric 
SBBreakpointList(SBTarget & target)784435933ddSDimitry Andric SBBreakpointList::SBBreakpointList(SBTarget &target)
785435933ddSDimitry Andric     : m_opaque_sp(new SBBreakpointListImpl(target.GetSP())) {}
786435933ddSDimitry Andric 
~SBBreakpointList()787435933ddSDimitry Andric SBBreakpointList::~SBBreakpointList() {}
788435933ddSDimitry Andric 
GetSize() const789435933ddSDimitry Andric size_t SBBreakpointList::GetSize() const {
790435933ddSDimitry Andric   if (!m_opaque_sp)
791435933ddSDimitry Andric     return 0;
792435933ddSDimitry Andric   else
793435933ddSDimitry Andric     return m_opaque_sp->GetSize();
794435933ddSDimitry Andric }
795435933ddSDimitry Andric 
GetBreakpointAtIndex(size_t idx)796435933ddSDimitry Andric SBBreakpoint SBBreakpointList::GetBreakpointAtIndex(size_t idx) {
797435933ddSDimitry Andric   if (!m_opaque_sp)
798435933ddSDimitry Andric     return SBBreakpoint();
799435933ddSDimitry Andric 
800435933ddSDimitry Andric   BreakpointSP bkpt_sp = m_opaque_sp->GetBreakpointAtIndex(idx);
801435933ddSDimitry Andric   return SBBreakpoint(bkpt_sp);
802435933ddSDimitry Andric }
803435933ddSDimitry Andric 
FindBreakpointByID(lldb::break_id_t id)804435933ddSDimitry Andric SBBreakpoint SBBreakpointList::FindBreakpointByID(lldb::break_id_t id) {
805435933ddSDimitry Andric   if (!m_opaque_sp)
806435933ddSDimitry Andric     return SBBreakpoint();
807435933ddSDimitry Andric   BreakpointSP bkpt_sp = m_opaque_sp->FindBreakpointByID(id);
808435933ddSDimitry Andric   return SBBreakpoint(bkpt_sp);
809435933ddSDimitry Andric }
810435933ddSDimitry Andric 
Append(const SBBreakpoint & sb_bkpt)811435933ddSDimitry Andric void SBBreakpointList::Append(const SBBreakpoint &sb_bkpt) {
812435933ddSDimitry Andric   if (!sb_bkpt.IsValid())
813435933ddSDimitry Andric     return;
814435933ddSDimitry Andric   if (!m_opaque_sp)
815435933ddSDimitry Andric     return;
816f678e45dSDimitry Andric   m_opaque_sp->Append(sb_bkpt.m_opaque_wp.lock());
817435933ddSDimitry Andric }
818435933ddSDimitry Andric 
AppendByID(lldb::break_id_t id)819435933ddSDimitry Andric void SBBreakpointList::AppendByID(lldb::break_id_t id) {
820435933ddSDimitry Andric   if (!m_opaque_sp)
821435933ddSDimitry Andric     return;
822435933ddSDimitry Andric   m_opaque_sp->AppendByID(id);
823435933ddSDimitry Andric }
824435933ddSDimitry Andric 
AppendIfUnique(const SBBreakpoint & sb_bkpt)825435933ddSDimitry Andric bool SBBreakpointList::AppendIfUnique(const SBBreakpoint &sb_bkpt) {
826435933ddSDimitry Andric   if (!sb_bkpt.IsValid())
827435933ddSDimitry Andric     return false;
828435933ddSDimitry Andric   if (!m_opaque_sp)
829435933ddSDimitry Andric     return false;
830f678e45dSDimitry Andric   return m_opaque_sp->AppendIfUnique(sb_bkpt.GetSP());
831435933ddSDimitry Andric }
832435933ddSDimitry Andric 
Clear()833435933ddSDimitry Andric void SBBreakpointList::Clear() {
834435933ddSDimitry Andric   if (m_opaque_sp)
835435933ddSDimitry Andric     m_opaque_sp->Clear();
836435933ddSDimitry Andric }
837435933ddSDimitry Andric 
CopyToBreakpointIDList(lldb_private::BreakpointIDList & bp_id_list)838435933ddSDimitry Andric void SBBreakpointList::CopyToBreakpointIDList(
839435933ddSDimitry Andric     lldb_private::BreakpointIDList &bp_id_list) {
840435933ddSDimitry Andric   if (m_opaque_sp)
841435933ddSDimitry Andric     m_opaque_sp->CopyToBreakpointIDList(bp_id_list);
842435933ddSDimitry Andric }
843