]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Breakpoint/BreakpointLocation.cpp
MFV r328490: Update libfdt to github:f1879e1
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / source / Breakpoint / BreakpointLocation.cpp
1 //===-- BreakpointLocation.cpp ----------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 // C Includes
11 // C++ Includes
12 // Other libraries and framework includes
13 // Project includes
14 #include "lldb/Breakpoint/BreakpointLocation.h"
15 #include "lldb/Breakpoint/BreakpointID.h"
16 #include "lldb/Breakpoint/StoppointCallbackContext.h"
17 #include "lldb/Core/Debugger.h"
18 #include "lldb/Core/Module.h"
19 #include "lldb/Core/ValueObject.h"
20 #include "lldb/Expression/DiagnosticManager.h"
21 #include "lldb/Expression/ExpressionVariable.h"
22 #include "lldb/Expression/UserExpression.h"
23 #include "lldb/Symbol/CompileUnit.h"
24 #include "lldb/Symbol/Symbol.h"
25 #include "lldb/Symbol/TypeSystem.h"
26 #include "lldb/Target/Process.h"
27 #include "lldb/Target/Target.h"
28 #include "lldb/Target/Thread.h"
29 #include "lldb/Target/ThreadSpec.h"
30 #include "lldb/Utility/Log.h"
31 #include "lldb/Utility/StreamString.h"
32
33 using namespace lldb;
34 using namespace lldb_private;
35
36 BreakpointLocation::BreakpointLocation(break_id_t loc_id, Breakpoint &owner,
37                                        const Address &addr, lldb::tid_t tid,
38                                        bool hardware, bool check_for_resolver)
39     : StoppointLocation(loc_id, addr.GetOpcodeLoadAddress(&owner.GetTarget()),
40                         hardware),
41       m_being_created(true), m_should_resolve_indirect_functions(false),
42       m_is_reexported(false), m_is_indirect(false), m_address(addr),
43       m_owner(owner), m_options_ap(), m_bp_site_sp(), m_condition_mutex() {
44   if (check_for_resolver) {
45     Symbol *symbol = m_address.CalculateSymbolContextSymbol();
46     if (symbol && symbol->IsIndirect()) {
47       SetShouldResolveIndirectFunctions(true);
48     }
49   }
50
51   SetThreadID(tid);
52   m_being_created = false;
53 }
54
55 BreakpointLocation::~BreakpointLocation() { ClearBreakpointSite(); }
56
57 lldb::addr_t BreakpointLocation::GetLoadAddress() const {
58   return m_address.GetOpcodeLoadAddress(&m_owner.GetTarget());
59 }
60
61 const BreakpointOptions *
62 BreakpointLocation::GetOptionsSpecifyingKind(BreakpointOptions::OptionKind kind)
63 const {
64     if (m_options_ap && m_options_ap->IsOptionSet(kind))
65       return m_options_ap.get();
66     else
67       return m_owner.GetOptions();
68 }
69
70 Address &BreakpointLocation::GetAddress() { return m_address; }
71
72 Breakpoint &BreakpointLocation::GetBreakpoint() { return m_owner; }
73
74 Target &BreakpointLocation::GetTarget() { return m_owner.GetTarget(); }
75
76 bool BreakpointLocation::IsEnabled() const {
77   if (!m_owner.IsEnabled())
78     return false;
79   else if (m_options_ap.get() != nullptr)
80     return m_options_ap->IsEnabled();
81   else
82     return true;
83 }
84
85 void BreakpointLocation::SetEnabled(bool enabled) {
86   GetLocationOptions()->SetEnabled(enabled);
87   if (enabled) {
88     ResolveBreakpointSite();
89   } else {
90     ClearBreakpointSite();
91   }
92   SendBreakpointLocationChangedEvent(enabled ? eBreakpointEventTypeEnabled
93                                              : eBreakpointEventTypeDisabled);
94 }
95
96 bool BreakpointLocation::IsAutoContinue() const {
97   if (m_options_ap 
98       && m_options_ap->IsOptionSet(BreakpointOptions::eAutoContinue))
99     return m_options_ap->IsAutoContinue();
100   else
101     return m_owner.IsAutoContinue();
102 }
103
104 void BreakpointLocation::SetAutoContinue(bool auto_continue) {
105   GetLocationOptions()->SetAutoContinue(auto_continue);
106   SendBreakpointLocationChangedEvent(eBreakpointEventTypeAutoContinueChanged);
107 }
108
109 void BreakpointLocation::SetThreadID(lldb::tid_t thread_id) {
110   if (thread_id != LLDB_INVALID_THREAD_ID)
111     GetLocationOptions()->SetThreadID(thread_id);
112   else {
113     // If we're resetting this to an invalid thread id, then
114     // don't make an options pointer just to do that.
115     if (m_options_ap.get() != nullptr)
116       m_options_ap->SetThreadID(thread_id);
117   }
118   SendBreakpointLocationChangedEvent(eBreakpointEventTypeThreadChanged);
119 }
120
121 lldb::tid_t BreakpointLocation::GetThreadID() {
122   const ThreadSpec *thread_spec = 
123       GetOptionsSpecifyingKind(BreakpointOptions::eThreadSpec)
124           ->GetThreadSpecNoCreate();
125   if (thread_spec)
126     return thread_spec->GetTID();
127   else
128     return LLDB_INVALID_THREAD_ID;
129 }
130
131 void BreakpointLocation::SetThreadIndex(uint32_t index) {
132   if (index != 0)
133     GetLocationOptions()->GetThreadSpec()->SetIndex(index);
134   else {
135     // If we're resetting this to an invalid thread id, then
136     // don't make an options pointer just to do that.
137     if (m_options_ap.get() != nullptr)
138       m_options_ap->GetThreadSpec()->SetIndex(index);
139   }
140   SendBreakpointLocationChangedEvent(eBreakpointEventTypeThreadChanged);
141 }
142
143 uint32_t BreakpointLocation::GetThreadIndex() const {
144   const ThreadSpec *thread_spec = 
145       GetOptionsSpecifyingKind(BreakpointOptions::eThreadSpec)
146           ->GetThreadSpecNoCreate();
147   if (thread_spec)
148     return thread_spec->GetIndex();
149   else
150     return 0;
151 }
152
153 void BreakpointLocation::SetThreadName(const char *thread_name) {
154   if (thread_name != nullptr)
155     GetLocationOptions()->GetThreadSpec()->SetName(thread_name);
156   else {
157     // If we're resetting this to an invalid thread id, then
158     // don't make an options pointer just to do that.
159     if (m_options_ap.get() != nullptr)
160       m_options_ap->GetThreadSpec()->SetName(thread_name);
161   }
162   SendBreakpointLocationChangedEvent(eBreakpointEventTypeThreadChanged);
163 }
164
165 const char *BreakpointLocation::GetThreadName() const {
166   const ThreadSpec *thread_spec = 
167       GetOptionsSpecifyingKind(BreakpointOptions::eThreadSpec)
168           ->GetThreadSpecNoCreate();
169   if (thread_spec)
170     return thread_spec->GetName();
171   else
172     return nullptr;
173 }
174
175 void BreakpointLocation::SetQueueName(const char *queue_name) {
176   if (queue_name != nullptr)
177     GetLocationOptions()->GetThreadSpec()->SetQueueName(queue_name);
178   else {
179     // If we're resetting this to an invalid thread id, then
180     // don't make an options pointer just to do that.
181     if (m_options_ap.get() != nullptr)
182       m_options_ap->GetThreadSpec()->SetQueueName(queue_name);
183   }
184   SendBreakpointLocationChangedEvent(eBreakpointEventTypeThreadChanged);
185 }
186
187 const char *BreakpointLocation::GetQueueName() const {
188   const ThreadSpec *thread_spec = 
189       GetOptionsSpecifyingKind(BreakpointOptions::eThreadSpec)
190           ->GetThreadSpecNoCreate();
191   if (thread_spec)
192     return thread_spec->GetQueueName();
193   else
194     return nullptr;
195 }
196
197 bool BreakpointLocation::InvokeCallback(StoppointCallbackContext *context) {
198   if (m_options_ap.get() != nullptr && m_options_ap->HasCallback())
199     return m_options_ap->InvokeCallback(context, m_owner.GetID(), GetID());
200   else
201     return m_owner.InvokeCallback(context, GetID());
202 }
203
204 void BreakpointLocation::SetCallback(BreakpointHitCallback callback,
205                                      void *baton, bool is_synchronous) {
206   // The default "Baton" class will keep a copy of "baton" and won't free
207   // or delete it when it goes goes out of scope.
208   GetLocationOptions()->SetCallback(
209       callback, std::make_shared<UntypedBaton>(baton), is_synchronous);
210   SendBreakpointLocationChangedEvent(eBreakpointEventTypeCommandChanged);
211 }
212
213 void BreakpointLocation::SetCallback(BreakpointHitCallback callback,
214                                      const BatonSP &baton_sp,
215                                      bool is_synchronous) {
216   GetLocationOptions()->SetCallback(callback, baton_sp, is_synchronous);
217   SendBreakpointLocationChangedEvent(eBreakpointEventTypeCommandChanged);
218 }
219
220 void BreakpointLocation::ClearCallback() {
221   GetLocationOptions()->ClearCallback();
222 }
223
224 void BreakpointLocation::SetCondition(const char *condition) {
225   GetLocationOptions()->SetCondition(condition);
226   SendBreakpointLocationChangedEvent(eBreakpointEventTypeConditionChanged);
227 }
228
229 const char *BreakpointLocation::GetConditionText(size_t *hash) const {
230   return GetOptionsSpecifyingKind(BreakpointOptions::eCondition)
231       ->GetConditionText(hash);
232 }
233
234 bool BreakpointLocation::ConditionSaysStop(ExecutionContext &exe_ctx,
235                                            Status &error) {
236   Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS);
237
238   std::lock_guard<std::mutex> guard(m_condition_mutex);
239
240   size_t condition_hash;
241   const char *condition_text = GetConditionText(&condition_hash);
242
243   if (!condition_text) {
244     m_user_expression_sp.reset();
245     return false;
246   }
247
248   error.Clear();
249
250   DiagnosticManager diagnostics;
251
252   if (condition_hash != m_condition_hash || !m_user_expression_sp ||
253       !m_user_expression_sp->MatchesContext(exe_ctx)) {
254     LanguageType language = eLanguageTypeUnknown;
255     // See if we can figure out the language from the frame, otherwise use the
256     // default language:
257     CompileUnit *comp_unit = m_address.CalculateSymbolContextCompileUnit();
258     if (comp_unit)
259       language = comp_unit->GetLanguage();
260
261     m_user_expression_sp.reset(GetTarget().GetUserExpressionForLanguage(
262         condition_text, llvm::StringRef(), language, Expression::eResultTypeAny,
263         EvaluateExpressionOptions(), error));
264     if (error.Fail()) {
265       if (log)
266         log->Printf("Error getting condition expression: %s.",
267                     error.AsCString());
268       m_user_expression_sp.reset();
269       return true;
270     }
271
272     if (!m_user_expression_sp->Parse(diagnostics, exe_ctx,
273                                      eExecutionPolicyOnlyWhenNeeded, true,
274                                      false)) {
275       error.SetErrorStringWithFormat(
276           "Couldn't parse conditional expression:\n%s",
277           diagnostics.GetString().c_str());
278       m_user_expression_sp.reset();
279       return true;
280     }
281
282     m_condition_hash = condition_hash;
283   }
284
285   // We need to make sure the user sees any parse errors in their condition, so
286   // we'll hook the
287   // constructor errors up to the debugger's Async I/O.
288
289   ValueObjectSP result_value_sp;
290
291   EvaluateExpressionOptions options;
292   options.SetUnwindOnError(true);
293   options.SetIgnoreBreakpoints(true);
294   options.SetTryAllThreads(true);
295   options.SetResultIsInternal(
296       true); // Don't generate a user variable for condition expressions.
297
298   Status expr_error;
299
300   diagnostics.Clear();
301
302   ExpressionVariableSP result_variable_sp;
303
304   ExpressionResults result_code = m_user_expression_sp->Execute(
305       diagnostics, exe_ctx, options, m_user_expression_sp, result_variable_sp);
306
307   bool ret;
308
309   if (result_code == eExpressionCompleted) {
310     if (!result_variable_sp) {
311       error.SetErrorString("Expression did not return a result");
312       return false;
313     }
314
315     result_value_sp = result_variable_sp->GetValueObject();
316
317     if (result_value_sp) {
318       ret = result_value_sp->IsLogicalTrue(error);
319       if (log) {
320         if (error.Success()) {
321           log->Printf("Condition successfully evaluated, result is %s.\n",
322                       ret ? "true" : "false");
323         } else {
324           error.SetErrorString(
325               "Failed to get an integer result from the expression");
326           ret = false;
327         }
328       }
329     } else {
330       ret = false;
331       error.SetErrorString("Failed to get any result from the expression");
332     }
333   } else {
334     ret = false;
335     error.SetErrorStringWithFormat("Couldn't execute expression:\n%s",
336                                    diagnostics.GetString().c_str());
337   }
338
339   return ret;
340 }
341
342 uint32_t BreakpointLocation::GetIgnoreCount() {
343   return GetOptionsSpecifyingKind(BreakpointOptions::eIgnoreCount)
344       ->GetIgnoreCount();
345 }
346
347 void BreakpointLocation::SetIgnoreCount(uint32_t n) {
348   GetLocationOptions()->SetIgnoreCount(n);
349   SendBreakpointLocationChangedEvent(eBreakpointEventTypeIgnoreChanged);
350 }
351
352 void BreakpointLocation::DecrementIgnoreCount() {
353   if (m_options_ap.get() != nullptr) {
354     uint32_t loc_ignore = m_options_ap->GetIgnoreCount();
355     if (loc_ignore != 0)
356       m_options_ap->SetIgnoreCount(loc_ignore - 1);
357   }
358 }
359
360 bool BreakpointLocation::IgnoreCountShouldStop() {
361   if (m_options_ap.get() != nullptr) {
362     uint32_t loc_ignore = m_options_ap->GetIgnoreCount();
363     if (loc_ignore != 0) {
364       m_owner.DecrementIgnoreCount();
365       DecrementIgnoreCount(); // Have to decrement our owners' ignore count,
366                               // since it won't get a
367                               // chance to.
368       return false;
369     }
370   }
371   return true;
372 }
373
374 BreakpointOptions *BreakpointLocation::GetLocationOptions() {
375   // If we make the copy we don't copy the callbacks because that is potentially
376   // expensive and we don't want to do that for the simple case where someone is
377   // just disabling the location.
378   if (m_options_ap.get() == nullptr)
379     m_options_ap.reset(
380         new BreakpointOptions(false));
381
382   return m_options_ap.get();
383 }
384
385 bool BreakpointLocation::ValidForThisThread(Thread *thread) {
386   return thread
387       ->MatchesSpec(GetOptionsSpecifyingKind(BreakpointOptions::eThreadSpec)
388       ->GetThreadSpecNoCreate());
389 }
390
391 // RETURNS - true if we should stop at this breakpoint, false if we
392 // should continue.  Note, we don't check the thread spec for the breakpoint
393 // here, since if the breakpoint is not for this thread, then the event won't
394 // even get reported, so the check is redundant.
395
396 bool BreakpointLocation::ShouldStop(StoppointCallbackContext *context) {
397   bool should_stop = true;
398   Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS);
399
400   // Do this first, if a location is disabled, it shouldn't increment its hit
401   // count.
402   if (!IsEnabled())
403     return false;
404
405   if (!IgnoreCountShouldStop())
406     return false;
407
408   if (!m_owner.IgnoreCountShouldStop())
409     return false;
410
411   // We only run synchronous callbacks in ShouldStop:
412   context->is_synchronous = true;
413   should_stop = InvokeCallback(context);
414
415   if (log) {
416     StreamString s;
417     GetDescription(&s, lldb::eDescriptionLevelVerbose);
418     log->Printf("Hit breakpoint location: %s, %s.\n", s.GetData(),
419                 should_stop ? "stopping" : "continuing");
420   }
421
422   return should_stop;
423 }
424
425 void BreakpointLocation::BumpHitCount() {
426   if (IsEnabled()) {
427     // Step our hit count, and also step the hit count of the owner.
428     IncrementHitCount();
429     m_owner.IncrementHitCount();
430   }
431 }
432
433 void BreakpointLocation::UndoBumpHitCount() {
434   if (IsEnabled()) {
435     // Step our hit count, and also step the hit count of the owner.
436     DecrementHitCount();
437     m_owner.DecrementHitCount();
438   }
439 }
440
441 bool BreakpointLocation::IsResolved() const {
442   return m_bp_site_sp.get() != nullptr;
443 }
444
445 lldb::BreakpointSiteSP BreakpointLocation::GetBreakpointSite() const {
446   return m_bp_site_sp;
447 }
448
449 bool BreakpointLocation::ResolveBreakpointSite() {
450   if (m_bp_site_sp)
451     return true;
452
453   Process *process = m_owner.GetTarget().GetProcessSP().get();
454   if (process == nullptr)
455     return false;
456
457   lldb::break_id_t new_id =
458       process->CreateBreakpointSite(shared_from_this(), m_owner.IsHardware());
459
460   if (new_id == LLDB_INVALID_BREAK_ID) {
461     Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS);
462     if (log)
463       log->Warning("Tried to add breakpoint site at 0x%" PRIx64
464                    " but it was already present.\n",
465                    m_address.GetOpcodeLoadAddress(&m_owner.GetTarget()));
466     return false;
467   }
468
469   return true;
470 }
471
472 bool BreakpointLocation::SetBreakpointSite(BreakpointSiteSP &bp_site_sp) {
473   m_bp_site_sp = bp_site_sp;
474   SendBreakpointLocationChangedEvent(eBreakpointEventTypeLocationsResolved);
475   return true;
476 }
477
478 bool BreakpointLocation::ClearBreakpointSite() {
479   if (m_bp_site_sp.get()) {
480     ProcessSP process_sp(m_owner.GetTarget().GetProcessSP());
481     // If the process exists, get it to remove the owner, it will remove the
482     // physical implementation
483     // of the breakpoint as well if there are no more owners.  Otherwise just
484     // remove this owner.
485     if (process_sp)
486       process_sp->RemoveOwnerFromBreakpointSite(GetBreakpoint().GetID(),
487                                                 GetID(), m_bp_site_sp);
488     else
489       m_bp_site_sp->RemoveOwner(GetBreakpoint().GetID(), GetID());
490
491     m_bp_site_sp.reset();
492     return true;
493   }
494   return false;
495 }
496
497 void BreakpointLocation::GetDescription(Stream *s,
498                                         lldb::DescriptionLevel level) {
499   SymbolContext sc;
500
501   // If the description level is "initial" then the breakpoint is printing out
502   // our initial state,
503   // and we should let it decide how it wants to print our label.
504   if (level != eDescriptionLevelInitial) {
505     s->Indent();
506     BreakpointID::GetCanonicalReference(s, m_owner.GetID(), GetID());
507   }
508
509   if (level == lldb::eDescriptionLevelBrief)
510     return;
511
512   if (level != eDescriptionLevelInitial)
513     s->PutCString(": ");
514
515   if (level == lldb::eDescriptionLevelVerbose)
516     s->IndentMore();
517
518   if (m_address.IsSectionOffset()) {
519     m_address.CalculateSymbolContext(&sc);
520
521     if (level == lldb::eDescriptionLevelFull ||
522         level == eDescriptionLevelInitial) {
523       if (IsReExported())
524         s->PutCString("re-exported target = ");
525       else
526         s->PutCString("where = ");
527       sc.DumpStopContext(s, m_owner.GetTarget().GetProcessSP().get(), m_address,
528                          false, true, false, true, true);
529     } else {
530       if (sc.module_sp) {
531         s->EOL();
532         s->Indent("module = ");
533         sc.module_sp->GetFileSpec().Dump(s);
534       }
535
536       if (sc.comp_unit != nullptr) {
537         s->EOL();
538         s->Indent("compile unit = ");
539         static_cast<FileSpec *>(sc.comp_unit)->GetFilename().Dump(s);
540
541         if (sc.function != nullptr) {
542           s->EOL();
543           s->Indent("function = ");
544           s->PutCString(sc.function->GetName().AsCString("<unknown>"));
545         }
546
547         if (sc.line_entry.line > 0) {
548           s->EOL();
549           s->Indent("location = ");
550           sc.line_entry.DumpStopContext(s, true);
551         }
552
553       } else {
554         // If we don't have a comp unit, see if we have a symbol we can print.
555         if (sc.symbol) {
556           s->EOL();
557           if (IsReExported())
558             s->Indent("re-exported target = ");
559           else
560             s->Indent("symbol = ");
561           s->PutCString(sc.symbol->GetName().AsCString("<unknown>"));
562         }
563       }
564     }
565   }
566
567   if (level == lldb::eDescriptionLevelVerbose) {
568     s->EOL();
569     s->Indent();
570   }
571
572   if (m_address.IsSectionOffset() &&
573       (level == eDescriptionLevelFull || level == eDescriptionLevelInitial))
574     s->Printf(", ");
575   s->Printf("address = ");
576
577   ExecutionContextScope *exe_scope = nullptr;
578   Target *target = &m_owner.GetTarget();
579   if (target)
580     exe_scope = target->GetProcessSP().get();
581   if (exe_scope == nullptr)
582     exe_scope = target;
583
584   if (level == eDescriptionLevelInitial)
585     m_address.Dump(s, exe_scope, Address::DumpStyleLoadAddress,
586                    Address::DumpStyleFileAddress);
587   else
588     m_address.Dump(s, exe_scope, Address::DumpStyleLoadAddress,
589                    Address::DumpStyleModuleWithFileAddress);
590
591   if (IsIndirect() && m_bp_site_sp) {
592     Address resolved_address;
593     resolved_address.SetLoadAddress(m_bp_site_sp->GetLoadAddress(), target);
594     Symbol *resolved_symbol = resolved_address.CalculateSymbolContextSymbol();
595     if (resolved_symbol) {
596       if (level == eDescriptionLevelFull || level == eDescriptionLevelInitial)
597         s->Printf(", ");
598       else if (level == lldb::eDescriptionLevelVerbose) {
599         s->EOL();
600         s->Indent();
601       }
602       s->Printf("indirect target = %s",
603                 resolved_symbol->GetName().GetCString());
604     }
605   }
606
607   if (level == lldb::eDescriptionLevelVerbose) {
608     s->EOL();
609     s->Indent();
610     s->Printf("resolved = %s\n", IsResolved() ? "true" : "false");
611
612     s->Indent();
613     s->Printf("hit count = %-4u\n", GetHitCount());
614
615     if (m_options_ap.get()) {
616       s->Indent();
617       m_options_ap->GetDescription(s, level);
618       s->EOL();
619     }
620     s->IndentLess();
621   } else if (level != eDescriptionLevelInitial) {
622     s->Printf(", %sresolved, hit count = %u ", (IsResolved() ? "" : "un"),
623               GetHitCount());
624     if (m_options_ap.get()) {
625       m_options_ap->GetDescription(s, level);
626     }
627   }
628 }
629
630 void BreakpointLocation::Dump(Stream *s) const {
631   if (s == nullptr)
632     return;
633
634   lldb::tid_t tid = GetOptionsSpecifyingKind(BreakpointOptions::eThreadSpec)
635       ->GetThreadSpecNoCreate()->GetTID();
636   s->Printf(
637       "BreakpointLocation %u: tid = %4.4" PRIx64 "  load addr = 0x%8.8" PRIx64
638       "  state = %s  type = %s breakpoint  "
639       "hw_index = %i  hit_count = %-4u  ignore_count = %-4u",
640       GetID(), tid,
641       (uint64_t)m_address.GetOpcodeLoadAddress(&m_owner.GetTarget()),
642       (m_options_ap.get() ? m_options_ap->IsEnabled() : m_owner.IsEnabled())
643           ? "enabled "
644           : "disabled",
645       IsHardware() ? "hardware" : "software", GetHardwareIndex(), GetHitCount(),
646       GetOptionsSpecifyingKind(BreakpointOptions::eIgnoreCount)
647           ->GetIgnoreCount());
648 }
649
650 void BreakpointLocation::SendBreakpointLocationChangedEvent(
651     lldb::BreakpointEventType eventKind) {
652   if (!m_being_created && !m_owner.IsInternal() &&
653       m_owner.GetTarget().EventTypeHasListeners(
654           Target::eBroadcastBitBreakpointChanged)) {
655     Breakpoint::BreakpointEventData *data = new Breakpoint::BreakpointEventData(
656         eventKind, m_owner.shared_from_this());
657     data->GetBreakpointLocationCollection().Add(shared_from_this());
658     m_owner.GetTarget().BroadcastEvent(Target::eBroadcastBitBreakpointChanged,
659                                        data);
660   }
661 }
662
663 void BreakpointLocation::SwapLocation(BreakpointLocationSP swap_from) {
664   m_address = swap_from->m_address;
665   m_should_resolve_indirect_functions =
666       swap_from->m_should_resolve_indirect_functions;
667   m_is_reexported = swap_from->m_is_reexported;
668   m_is_indirect = swap_from->m_is_indirect;
669   m_user_expression_sp.reset();
670 }