1254721Semaste//===-- BreakpointLocation.cpp ----------------------------------*- C++ -*-===//
2254721Semaste//
3254721Semaste//                     The LLVM Compiler Infrastructure
4254721Semaste//
5254721Semaste// This file is distributed under the University of Illinois Open Source
6254721Semaste// License. See LICENSE.TXT for details.
7254721Semaste//
8254721Semaste//===----------------------------------------------------------------------===//
9254721Semaste
10254721Semaste#include "lldb/lldb-python.h"
11254721Semaste
12254721Semaste// C Includes
13254721Semaste// C++ Includes
14254721Semaste#include <string>
15254721Semaste
16254721Semaste// Other libraries and framework includes
17254721Semaste// Project includes
18254721Semaste#include "lldb/lldb-private-log.h"
19254721Semaste#include "lldb/Breakpoint/BreakpointLocation.h"
20254721Semaste#include "lldb/Breakpoint/BreakpointID.h"
21254721Semaste#include "lldb/Breakpoint/StoppointCallbackContext.h"
22254721Semaste#include "lldb/Core/Debugger.h"
23254721Semaste#include "lldb/Core/Log.h"
24254721Semaste#include "lldb/Core/Module.h"
25254721Semaste#include "lldb/Core/StreamString.h"
26254721Semaste#include "lldb/Symbol/CompileUnit.h"
27254721Semaste#include "lldb/Symbol/Symbol.h"
28254721Semaste#include "lldb/Target/Target.h"
29254721Semaste#include "lldb/Target/Process.h"
30254721Semaste#include "lldb/Target/Thread.h"
31254721Semaste#include "lldb/Target/ThreadSpec.h"
32254721Semaste
33254721Semasteusing namespace lldb;
34254721Semasteusing namespace lldb_private;
35254721Semaste
36254721SemasteBreakpointLocation::BreakpointLocation
37254721Semaste(
38254721Semaste    break_id_t loc_id,
39254721Semaste    Breakpoint &owner,
40254721Semaste    const Address &addr,
41254721Semaste    lldb::tid_t tid,
42269024Semaste    bool hardware,
43269024Semaste    bool check_for_resolver
44254721Semaste) :
45254721Semaste    StoppointLocation (loc_id, addr.GetOpcodeLoadAddress(&owner.GetTarget()), hardware),
46254721Semaste    m_being_created(true),
47269024Semaste    m_should_resolve_indirect_functions (false),
48269024Semaste    m_is_reexported (false),
49269024Semaste    m_is_indirect (false),
50254721Semaste    m_address (addr),
51254721Semaste    m_owner (owner),
52254721Semaste    m_options_ap (),
53254721Semaste    m_bp_site_sp (),
54254721Semaste    m_condition_mutex ()
55254721Semaste{
56269024Semaste    if (check_for_resolver)
57269024Semaste    {
58269024Semaste        Symbol *symbol = m_address.CalculateSymbolContextSymbol();
59269024Semaste        if (symbol && symbol->IsIndirect())
60269024Semaste        {
61269024Semaste            SetShouldResolveIndirectFunctions (true);
62269024Semaste        }
63269024Semaste    }
64269024Semaste
65254721Semaste    SetThreadID (tid);
66254721Semaste    m_being_created = false;
67254721Semaste}
68254721Semaste
69254721SemasteBreakpointLocation::~BreakpointLocation()
70254721Semaste{
71254721Semaste    ClearBreakpointSite();
72254721Semaste}
73254721Semaste
74254721Semastelldb::addr_t
75254721SemasteBreakpointLocation::GetLoadAddress () const
76254721Semaste{
77254721Semaste    return m_address.GetOpcodeLoadAddress (&m_owner.GetTarget());
78254721Semaste}
79254721Semaste
80254721SemasteAddress &
81254721SemasteBreakpointLocation::GetAddress ()
82254721Semaste{
83254721Semaste    return m_address;
84254721Semaste}
85254721Semaste
86254721SemasteBreakpoint &
87254721SemasteBreakpointLocation::GetBreakpoint ()
88254721Semaste{
89254721Semaste    return m_owner;
90254721Semaste}
91254721Semaste
92254721Semastebool
93254721SemasteBreakpointLocation::IsEnabled () const
94254721Semaste{
95254721Semaste    if (!m_owner.IsEnabled())
96254721Semaste        return false;
97254721Semaste    else if (m_options_ap.get() != NULL)
98254721Semaste        return m_options_ap->IsEnabled();
99254721Semaste    else
100254721Semaste        return true;
101254721Semaste}
102254721Semaste
103254721Semastevoid
104254721SemasteBreakpointLocation::SetEnabled (bool enabled)
105254721Semaste{
106254721Semaste    GetLocationOptions()->SetEnabled(enabled);
107254721Semaste    if (enabled)
108254721Semaste    {
109254721Semaste        ResolveBreakpointSite();
110254721Semaste    }
111254721Semaste    else
112254721Semaste    {
113254721Semaste        ClearBreakpointSite();
114254721Semaste    }
115254721Semaste    SendBreakpointLocationChangedEvent (enabled ? eBreakpointEventTypeEnabled : eBreakpointEventTypeDisabled);
116254721Semaste}
117254721Semaste
118254721Semastevoid
119254721SemasteBreakpointLocation::SetThreadID (lldb::tid_t thread_id)
120254721Semaste{
121254721Semaste    if (thread_id != LLDB_INVALID_THREAD_ID)
122254721Semaste        GetLocationOptions()->SetThreadID(thread_id);
123254721Semaste    else
124254721Semaste    {
125254721Semaste        // If we're resetting this to an invalid thread id, then
126254721Semaste        // don't make an options pointer just to do that.
127254721Semaste        if (m_options_ap.get() != NULL)
128254721Semaste            m_options_ap->SetThreadID (thread_id);
129254721Semaste    }
130254721Semaste    SendBreakpointLocationChangedEvent (eBreakpointEventTypeThreadChanged);
131254721Semaste}
132254721Semaste
133254721Semastelldb::tid_t
134254721SemasteBreakpointLocation::GetThreadID ()
135254721Semaste{
136254721Semaste    if (GetOptionsNoCreate()->GetThreadSpecNoCreate())
137254721Semaste        return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetTID();
138254721Semaste    else
139254721Semaste        return LLDB_INVALID_THREAD_ID;
140254721Semaste}
141254721Semaste
142254721Semastevoid
143254721SemasteBreakpointLocation::SetThreadIndex (uint32_t index)
144254721Semaste{
145254721Semaste    if (index != 0)
146254721Semaste        GetLocationOptions()->GetThreadSpec()->SetIndex(index);
147254721Semaste    else
148254721Semaste    {
149254721Semaste        // If we're resetting this to an invalid thread id, then
150254721Semaste        // don't make an options pointer just to do that.
151254721Semaste        if (m_options_ap.get() != NULL)
152254721Semaste            m_options_ap->GetThreadSpec()->SetIndex(index);
153254721Semaste    }
154254721Semaste    SendBreakpointLocationChangedEvent (eBreakpointEventTypeThreadChanged);
155254721Semaste
156254721Semaste}
157254721Semaste
158254721Semasteuint32_t
159254721SemasteBreakpointLocation::GetThreadIndex() const
160254721Semaste{
161254721Semaste    if (GetOptionsNoCreate()->GetThreadSpecNoCreate())
162254721Semaste        return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetIndex();
163254721Semaste    else
164254721Semaste        return 0;
165254721Semaste}
166254721Semaste
167254721Semastevoid
168254721SemasteBreakpointLocation::SetThreadName (const char *thread_name)
169254721Semaste{
170254721Semaste    if (thread_name != NULL)
171254721Semaste        GetLocationOptions()->GetThreadSpec()->SetName(thread_name);
172254721Semaste    else
173254721Semaste    {
174254721Semaste        // If we're resetting this to an invalid thread id, then
175254721Semaste        // don't make an options pointer just to do that.
176254721Semaste        if (m_options_ap.get() != NULL)
177254721Semaste            m_options_ap->GetThreadSpec()->SetName(thread_name);
178254721Semaste    }
179254721Semaste    SendBreakpointLocationChangedEvent (eBreakpointEventTypeThreadChanged);
180254721Semaste}
181254721Semaste
182254721Semasteconst char *
183254721SemasteBreakpointLocation::GetThreadName () const
184254721Semaste{
185254721Semaste    if (GetOptionsNoCreate()->GetThreadSpecNoCreate())
186254721Semaste        return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetName();
187254721Semaste    else
188254721Semaste        return NULL;
189254721Semaste}
190254721Semaste
191254721Semastevoid
192254721SemasteBreakpointLocation::SetQueueName (const char *queue_name)
193254721Semaste{
194254721Semaste    if (queue_name != NULL)
195254721Semaste        GetLocationOptions()->GetThreadSpec()->SetQueueName(queue_name);
196254721Semaste    else
197254721Semaste    {
198254721Semaste        // If we're resetting this to an invalid thread id, then
199254721Semaste        // don't make an options pointer just to do that.
200254721Semaste        if (m_options_ap.get() != NULL)
201254721Semaste            m_options_ap->GetThreadSpec()->SetQueueName(queue_name);
202254721Semaste    }
203254721Semaste    SendBreakpointLocationChangedEvent (eBreakpointEventTypeThreadChanged);
204254721Semaste}
205254721Semaste
206254721Semasteconst char *
207254721SemasteBreakpointLocation::GetQueueName () const
208254721Semaste{
209254721Semaste    if (GetOptionsNoCreate()->GetThreadSpecNoCreate())
210254721Semaste        return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetQueueName();
211254721Semaste    else
212254721Semaste        return NULL;
213254721Semaste}
214254721Semaste
215254721Semastebool
216254721SemasteBreakpointLocation::InvokeCallback (StoppointCallbackContext *context)
217254721Semaste{
218254721Semaste    if (m_options_ap.get() != NULL && m_options_ap->HasCallback())
219254721Semaste        return m_options_ap->InvokeCallback (context, m_owner.GetID(), GetID());
220254721Semaste    else
221254721Semaste        return m_owner.InvokeCallback (context, GetID());
222254721Semaste}
223254721Semaste
224254721Semastevoid
225254721SemasteBreakpointLocation::SetCallback (BreakpointHitCallback callback, void *baton,
226254721Semaste                 bool is_synchronous)
227254721Semaste{
228254721Semaste    // The default "Baton" class will keep a copy of "baton" and won't free
229254721Semaste    // or delete it when it goes goes out of scope.
230254721Semaste    GetLocationOptions()->SetCallback(callback, BatonSP (new Baton(baton)), is_synchronous);
231254721Semaste    SendBreakpointLocationChangedEvent (eBreakpointEventTypeCommandChanged);
232254721Semaste}
233254721Semaste
234254721Semastevoid
235254721SemasteBreakpointLocation::SetCallback (BreakpointHitCallback callback, const BatonSP &baton_sp,
236254721Semaste                 bool is_synchronous)
237254721Semaste{
238254721Semaste    GetLocationOptions()->SetCallback (callback, baton_sp, is_synchronous);
239254721Semaste    SendBreakpointLocationChangedEvent (eBreakpointEventTypeCommandChanged);
240254721Semaste}
241254721Semaste
242254721Semaste
243254721Semastevoid
244254721SemasteBreakpointLocation::ClearCallback ()
245254721Semaste{
246254721Semaste    GetLocationOptions()->ClearCallback();
247254721Semaste}
248254721Semaste
249254721Semastevoid
250254721SemasteBreakpointLocation::SetCondition (const char *condition)
251254721Semaste{
252254721Semaste    GetLocationOptions()->SetCondition (condition);
253254721Semaste    SendBreakpointLocationChangedEvent (eBreakpointEventTypeConditionChanged);
254254721Semaste}
255254721Semaste
256254721Semasteconst char *
257254721SemasteBreakpointLocation::GetConditionText (size_t *hash) const
258254721Semaste{
259254721Semaste    return GetOptionsNoCreate()->GetConditionText(hash);
260254721Semaste}
261254721Semaste
262254721Semastebool
263254721SemasteBreakpointLocation::ConditionSaysStop (ExecutionContext &exe_ctx, Error &error)
264254721Semaste{
265254721Semaste    Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS);
266254721Semaste
267254721Semaste    Mutex::Locker evaluation_locker(m_condition_mutex);
268254721Semaste
269254721Semaste    size_t condition_hash;
270254721Semaste    const char *condition_text = GetConditionText(&condition_hash);
271254721Semaste
272254721Semaste    if (!condition_text)
273254721Semaste    {
274254721Semaste        m_user_expression_sp.reset();
275254721Semaste        return false;
276254721Semaste    }
277254721Semaste
278254721Semaste    if (condition_hash != m_condition_hash ||
279254721Semaste        !m_user_expression_sp ||
280254721Semaste        !m_user_expression_sp->MatchesContext(exe_ctx))
281254721Semaste    {
282254721Semaste        m_user_expression_sp.reset(new ClangUserExpression(condition_text,
283254721Semaste                                                           NULL,
284254721Semaste                                                           lldb::eLanguageTypeUnknown,
285254721Semaste                                                           ClangUserExpression::eResultTypeAny));
286254721Semaste
287254721Semaste        StreamString errors;
288254721Semaste
289254721Semaste        if (!m_user_expression_sp->Parse(errors,
290254721Semaste                                         exe_ctx,
291254721Semaste                                         eExecutionPolicyOnlyWhenNeeded,
292254721Semaste                                         true))
293254721Semaste        {
294254721Semaste            error.SetErrorStringWithFormat("Couldn't parse conditional expression:\n%s",
295254721Semaste                                           errors.GetData());
296254721Semaste            m_user_expression_sp.reset();
297254721Semaste            return false;
298254721Semaste        }
299254721Semaste
300254721Semaste        m_condition_hash = condition_hash;
301254721Semaste    }
302254721Semaste
303254721Semaste    // We need to make sure the user sees any parse errors in their condition, so we'll hook the
304254721Semaste    // constructor errors up to the debugger's Async I/O.
305254721Semaste
306254721Semaste    ValueObjectSP result_value_sp;
307254721Semaste
308263363Semaste    EvaluateExpressionOptions options;
309263363Semaste    options.SetUnwindOnError(true);
310263363Semaste    options.SetIgnoreBreakpoints(true);
311263367Semaste    options.SetTryAllThreads(true);
312263363Semaste
313254721Semaste    Error expr_error;
314254721Semaste
315254721Semaste    StreamString execution_errors;
316254721Semaste
317254721Semaste    ClangExpressionVariableSP result_variable_sp;
318254721Semaste
319254721Semaste    ExecutionResults result_code =
320254721Semaste    m_user_expression_sp->Execute(execution_errors,
321254721Semaste                                  exe_ctx,
322263363Semaste                                  options,
323254721Semaste                                  m_user_expression_sp,
324263363Semaste                                  result_variable_sp);
325254721Semaste
326254721Semaste    bool ret;
327254721Semaste
328254721Semaste    if (result_code == eExecutionCompleted)
329254721Semaste    {
330254721Semaste        if (!result_variable_sp)
331254721Semaste        {
332254721Semaste            ret = false;
333254721Semaste            error.SetErrorString("Expression did not return a result");
334254721Semaste            return false;
335254721Semaste        }
336254721Semaste
337254721Semaste        result_value_sp = result_variable_sp->GetValueObject();
338254721Semaste
339254721Semaste        if (result_value_sp)
340254721Semaste        {
341254721Semaste            Scalar scalar_value;
342254721Semaste            if (result_value_sp->ResolveValue (scalar_value))
343254721Semaste            {
344254721Semaste                if (scalar_value.ULongLong(1) == 0)
345254721Semaste                    ret = false;
346254721Semaste                else
347254721Semaste                    ret = true;
348254721Semaste                if (log)
349254721Semaste                    log->Printf("Condition successfully evaluated, result is %s.\n",
350254721Semaste                                ret ? "true" : "false");
351254721Semaste            }
352254721Semaste            else
353254721Semaste            {
354254721Semaste                ret = false;
355254721Semaste                error.SetErrorString("Failed to get an integer result from the expression");
356254721Semaste            }
357254721Semaste        }
358254721Semaste        else
359254721Semaste        {
360254721Semaste            ret = false;
361254721Semaste            error.SetErrorString("Failed to get any result from the expression");
362254721Semaste        }
363254721Semaste    }
364254721Semaste    else
365254721Semaste    {
366254721Semaste        ret = false;
367254721Semaste        error.SetErrorStringWithFormat("Couldn't execute expression:\n%s", execution_errors.GetData());
368254721Semaste    }
369254721Semaste
370254721Semaste    return ret;
371254721Semaste}
372254721Semaste
373254721Semasteuint32_t
374254721SemasteBreakpointLocation::GetIgnoreCount ()
375254721Semaste{
376254721Semaste    return GetOptionsNoCreate()->GetIgnoreCount();
377254721Semaste}
378254721Semaste
379254721Semastevoid
380254721SemasteBreakpointLocation::SetIgnoreCount (uint32_t n)
381254721Semaste{
382254721Semaste    GetLocationOptions()->SetIgnoreCount(n);
383254721Semaste    SendBreakpointLocationChangedEvent (eBreakpointEventTypeIgnoreChanged);
384254721Semaste}
385254721Semaste
386254721Semastevoid
387254721SemasteBreakpointLocation::DecrementIgnoreCount()
388254721Semaste{
389254721Semaste    if (m_options_ap.get() != NULL)
390254721Semaste    {
391254721Semaste        uint32_t loc_ignore = m_options_ap->GetIgnoreCount();
392254721Semaste        if (loc_ignore != 0)
393254721Semaste            m_options_ap->SetIgnoreCount(loc_ignore - 1);
394254721Semaste    }
395254721Semaste}
396254721Semaste
397254721Semastebool
398254721SemasteBreakpointLocation::IgnoreCountShouldStop()
399254721Semaste{
400254721Semaste    if (m_options_ap.get() != NULL)
401254721Semaste    {
402254721Semaste        uint32_t loc_ignore = m_options_ap->GetIgnoreCount();
403254721Semaste        if (loc_ignore != 0)
404254721Semaste        {
405254721Semaste            m_owner.DecrementIgnoreCount();
406254721Semaste            DecrementIgnoreCount();          // Have to decrement our owners' ignore count, since it won't get a
407254721Semaste                                             // chance to.
408254721Semaste            return false;
409254721Semaste        }
410254721Semaste    }
411254721Semaste    return true;
412254721Semaste}
413254721Semaste
414254721Semasteconst BreakpointOptions *
415254721SemasteBreakpointLocation::GetOptionsNoCreate () const
416254721Semaste{
417254721Semaste    if (m_options_ap.get() != NULL)
418254721Semaste        return m_options_ap.get();
419254721Semaste    else
420254721Semaste        return m_owner.GetOptions ();
421254721Semaste}
422254721Semaste
423254721SemasteBreakpointOptions *
424254721SemasteBreakpointLocation::GetLocationOptions ()
425254721Semaste{
426254721Semaste    // If we make the copy we don't copy the callbacks because that is potentially
427254721Semaste    // expensive and we don't want to do that for the simple case where someone is
428254721Semaste    // just disabling the location.
429254721Semaste    if (m_options_ap.get() == NULL)
430254721Semaste        m_options_ap.reset(BreakpointOptions::CopyOptionsNoCallback(*m_owner.GetOptions ()));
431254721Semaste
432254721Semaste    return m_options_ap.get();
433254721Semaste}
434254721Semaste
435254721Semastebool
436254721SemasteBreakpointLocation::ValidForThisThread (Thread *thread)
437254721Semaste{
438254721Semaste    return thread->MatchesSpec(GetOptionsNoCreate()->GetThreadSpecNoCreate());
439254721Semaste}
440254721Semaste
441254721Semaste// RETURNS - true if we should stop at this breakpoint, false if we
442254721Semaste// should continue.  Note, we don't check the thread spec for the breakpoint
443254721Semaste// here, since if the breakpoint is not for this thread, then the event won't
444254721Semaste// even get reported, so the check is redundant.
445254721Semaste
446254721Semastebool
447254721SemasteBreakpointLocation::ShouldStop (StoppointCallbackContext *context)
448254721Semaste{
449254721Semaste    bool should_stop = true;
450254721Semaste    Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS);
451254721Semaste
452254721Semaste    IncrementHitCount();
453254721Semaste
454254721Semaste    if (!IsEnabled())
455254721Semaste        return false;
456254721Semaste
457254721Semaste    if (!IgnoreCountShouldStop())
458254721Semaste        return false;
459254721Semaste
460254721Semaste    if (!m_owner.IgnoreCountShouldStop())
461254721Semaste        return false;
462254721Semaste
463254721Semaste    // We only run synchronous callbacks in ShouldStop:
464254721Semaste    context->is_synchronous = true;
465254721Semaste    should_stop = InvokeCallback (context);
466254721Semaste
467254721Semaste    if (log)
468254721Semaste    {
469254721Semaste        StreamString s;
470254721Semaste        GetDescription (&s, lldb::eDescriptionLevelVerbose);
471254721Semaste        log->Printf ("Hit breakpoint location: %s, %s.\n", s.GetData(), should_stop ? "stopping" : "continuing");
472254721Semaste    }
473254721Semaste
474254721Semaste    return should_stop;
475254721Semaste}
476254721Semaste
477254721Semastebool
478254721SemasteBreakpointLocation::IsResolved () const
479254721Semaste{
480254721Semaste    return m_bp_site_sp.get() != NULL;
481254721Semaste}
482254721Semaste
483254721Semastelldb::BreakpointSiteSP
484254721SemasteBreakpointLocation::GetBreakpointSite() const
485254721Semaste{
486254721Semaste    return m_bp_site_sp;
487254721Semaste}
488254721Semaste
489254721Semastebool
490254721SemasteBreakpointLocation::ResolveBreakpointSite ()
491254721Semaste{
492254721Semaste    if (m_bp_site_sp)
493254721Semaste        return true;
494254721Semaste
495254721Semaste    Process *process = m_owner.GetTarget().GetProcessSP().get();
496254721Semaste    if (process == NULL)
497254721Semaste        return false;
498254721Semaste
499263363Semaste    lldb::break_id_t new_id = process->CreateBreakpointSite (shared_from_this(), m_owner.IsHardware());
500254721Semaste
501254721Semaste    if (new_id == LLDB_INVALID_BREAK_ID)
502254721Semaste    {
503254721Semaste        Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS);
504254721Semaste        if (log)
505254721Semaste            log->Warning ("Tried to add breakpoint site at 0x%" PRIx64 " but it was already present.\n",
506254721Semaste                          m_address.GetOpcodeLoadAddress (&m_owner.GetTarget()));
507254721Semaste        return false;
508254721Semaste    }
509254721Semaste
510254721Semaste    return true;
511254721Semaste}
512254721Semaste
513254721Semastebool
514254721SemasteBreakpointLocation::SetBreakpointSite (BreakpointSiteSP& bp_site_sp)
515254721Semaste{
516254721Semaste    m_bp_site_sp = bp_site_sp;
517254721Semaste    return true;
518254721Semaste}
519254721Semaste
520254721Semastebool
521254721SemasteBreakpointLocation::ClearBreakpointSite ()
522254721Semaste{
523254721Semaste    if (m_bp_site_sp.get())
524254721Semaste    {
525254721Semaste        m_owner.GetTarget().GetProcessSP()->RemoveOwnerFromBreakpointSite (GetBreakpoint().GetID(),
526254721Semaste                                                                           GetID(), m_bp_site_sp);
527254721Semaste        m_bp_site_sp.reset();
528254721Semaste        return true;
529254721Semaste    }
530254721Semaste    return false;
531254721Semaste}
532254721Semaste
533254721Semastevoid
534254721SemasteBreakpointLocation::GetDescription (Stream *s, lldb::DescriptionLevel level)
535254721Semaste{
536254721Semaste    SymbolContext sc;
537254721Semaste
538254721Semaste    // If the description level is "initial" then the breakpoint is printing out our initial state,
539254721Semaste    // and we should let it decide how it wants to print our label.
540254721Semaste    if (level != eDescriptionLevelInitial)
541254721Semaste    {
542254721Semaste        s->Indent();
543254721Semaste        BreakpointID::GetCanonicalReference(s, m_owner.GetID(), GetID());
544254721Semaste    }
545254721Semaste
546254721Semaste    if (level == lldb::eDescriptionLevelBrief)
547254721Semaste        return;
548254721Semaste
549254721Semaste    if (level != eDescriptionLevelInitial)
550254721Semaste        s->PutCString(": ");
551254721Semaste
552254721Semaste    if (level == lldb::eDescriptionLevelVerbose)
553254721Semaste        s->IndentMore();
554254721Semaste
555254721Semaste    if (m_address.IsSectionOffset())
556254721Semaste    {
557254721Semaste        m_address.CalculateSymbolContext(&sc);
558254721Semaste
559254721Semaste        if (level == lldb::eDescriptionLevelFull || level == eDescriptionLevelInitial)
560254721Semaste        {
561269024Semaste            if (IsReExported())
562269024Semaste                s->PutCString ("re-exported target = ");
563269024Semaste            else
564269024Semaste                s->PutCString("where = ");
565254721Semaste            sc.DumpStopContext (s, m_owner.GetTarget().GetProcessSP().get(), m_address, false, true, false);
566254721Semaste        }
567254721Semaste        else
568254721Semaste        {
569254721Semaste            if (sc.module_sp)
570254721Semaste            {
571254721Semaste                s->EOL();
572254721Semaste                s->Indent("module = ");
573254721Semaste                sc.module_sp->GetFileSpec().Dump (s);
574254721Semaste            }
575254721Semaste
576254721Semaste            if (sc.comp_unit != NULL)
577254721Semaste            {
578254721Semaste                s->EOL();
579254721Semaste                s->Indent("compile unit = ");
580254721Semaste                static_cast<FileSpec*>(sc.comp_unit)->GetFilename().Dump (s);
581254721Semaste
582254721Semaste                if (sc.function != NULL)
583254721Semaste                {
584254721Semaste                    s->EOL();
585254721Semaste                    s->Indent("function = ");
586254721Semaste                    s->PutCString (sc.function->GetMangled().GetName().AsCString("<unknown>"));
587254721Semaste                }
588254721Semaste
589254721Semaste                if (sc.line_entry.line > 0)
590254721Semaste                {
591254721Semaste                    s->EOL();
592254721Semaste                    s->Indent("location = ");
593254721Semaste                    sc.line_entry.DumpStopContext (s, true);
594254721Semaste                }
595254721Semaste
596254721Semaste            }
597254721Semaste            else
598254721Semaste            {
599254721Semaste                // If we don't have a comp unit, see if we have a symbol we can print.
600254721Semaste                if (sc.symbol)
601254721Semaste                {
602254721Semaste                    s->EOL();
603269024Semaste                    if (IsReExported())
604269024Semaste                        s->Indent ("re-exported target = ");
605269024Semaste                    else
606269024Semaste                        s->Indent("symbol = ");
607254721Semaste                    s->PutCString(sc.symbol->GetMangled().GetName().AsCString("<unknown>"));
608254721Semaste                }
609254721Semaste            }
610254721Semaste        }
611254721Semaste    }
612254721Semaste
613254721Semaste    if (level == lldb::eDescriptionLevelVerbose)
614254721Semaste    {
615254721Semaste        s->EOL();
616254721Semaste        s->Indent();
617254721Semaste    }
618254721Semaste
619254721Semaste    if (m_address.IsSectionOffset() && (level == eDescriptionLevelFull || level == eDescriptionLevelInitial))
620254721Semaste        s->Printf (", ");
621254721Semaste    s->Printf ("address = ");
622254721Semaste
623254721Semaste    ExecutionContextScope *exe_scope = NULL;
624254721Semaste    Target *target = &m_owner.GetTarget();
625254721Semaste    if (target)
626254721Semaste        exe_scope = target->GetProcessSP().get();
627254721Semaste    if (exe_scope == NULL)
628254721Semaste        exe_scope = target;
629254721Semaste
630254721Semaste    if (eDescriptionLevelInitial)
631254721Semaste        m_address.Dump(s, exe_scope, Address::DumpStyleLoadAddress, Address::DumpStyleFileAddress);
632254721Semaste    else
633254721Semaste        m_address.Dump(s, exe_scope, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress);
634269024Semaste
635269024Semaste    if (IsIndirect() && m_bp_site_sp)
636269024Semaste    {
637269024Semaste        Address resolved_address;
638269024Semaste        resolved_address.SetLoadAddress(m_bp_site_sp->GetLoadAddress(), target);
639269024Semaste        Symbol *resolved_symbol = resolved_address.CalculateSymbolContextSymbol();
640269024Semaste        if (resolved_symbol)
641269024Semaste        {
642269024Semaste            if (level == eDescriptionLevelFull || level == eDescriptionLevelInitial)
643269024Semaste                s->Printf (", ");
644269024Semaste            else if (level == lldb::eDescriptionLevelVerbose)
645269024Semaste            {
646269024Semaste                s->EOL();
647269024Semaste                s->Indent();
648269024Semaste            }
649269024Semaste            s->Printf ("indirect target = %s", resolved_symbol->GetName().GetCString());
650269024Semaste        }
651269024Semaste    }
652254721Semaste
653254721Semaste    if (level == lldb::eDescriptionLevelVerbose)
654254721Semaste    {
655254721Semaste        s->EOL();
656254721Semaste        s->Indent();
657254721Semaste        s->Printf("resolved = %s\n", IsResolved() ? "true" : "false");
658254721Semaste
659254721Semaste        s->Indent();
660254721Semaste        s->Printf ("hit count = %-4u\n", GetHitCount());
661254721Semaste
662254721Semaste        if (m_options_ap.get())
663254721Semaste        {
664254721Semaste            s->Indent();
665254721Semaste            m_options_ap->GetDescription (s, level);
666254721Semaste            s->EOL();
667254721Semaste        }
668254721Semaste        s->IndentLess();
669254721Semaste    }
670254721Semaste    else if (level != eDescriptionLevelInitial)
671254721Semaste    {
672254721Semaste        s->Printf(", %sresolved, hit count = %u ",
673254721Semaste                  (IsResolved() ? "" : "un"),
674254721Semaste                  GetHitCount());
675254721Semaste        if (m_options_ap.get())
676254721Semaste        {
677254721Semaste            m_options_ap->GetDescription (s, level);
678254721Semaste        }
679254721Semaste    }
680254721Semaste}
681254721Semaste
682254721Semastevoid
683254721SemasteBreakpointLocation::Dump(Stream *s) const
684254721Semaste{
685254721Semaste    if (s == NULL)
686254721Semaste        return;
687254721Semaste
688254721Semaste    s->Printf("BreakpointLocation %u: tid = %4.4" PRIx64 "  load addr = 0x%8.8" PRIx64 "  state = %s  type = %s breakpoint  "
689254721Semaste              "hw_index = %i  hit_count = %-4u  ignore_count = %-4u",
690254721Semaste              GetID(),
691254721Semaste              GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetTID(),
692254721Semaste              (uint64_t) m_address.GetOpcodeLoadAddress (&m_owner.GetTarget()),
693254721Semaste              (m_options_ap.get() ? m_options_ap->IsEnabled() : m_owner.IsEnabled()) ? "enabled " : "disabled",
694254721Semaste              IsHardware() ? "hardware" : "software",
695254721Semaste              GetHardwareIndex(),
696254721Semaste              GetHitCount(),
697254721Semaste              GetOptionsNoCreate()->GetIgnoreCount());
698254721Semaste}
699254721Semaste
700254721Semastevoid
701254721SemasteBreakpointLocation::SendBreakpointLocationChangedEvent (lldb::BreakpointEventType eventKind)
702254721Semaste{
703254721Semaste    if (!m_being_created
704254721Semaste        && !m_owner.IsInternal()
705254721Semaste        && m_owner.GetTarget().EventTypeHasListeners(Target::eBroadcastBitBreakpointChanged))
706254721Semaste    {
707254721Semaste        Breakpoint::BreakpointEventData *data = new Breakpoint::BreakpointEventData (eventKind,
708254721Semaste                                                                                     m_owner.shared_from_this());
709254721Semaste        data->GetBreakpointLocationCollection().Add (shared_from_this());
710254721Semaste        m_owner.GetTarget().BroadcastEvent (Target::eBroadcastBitBreakpointChanged, data);
711254721Semaste    }
712254721Semaste}
713254721Semaste
714