SBTarget.cpp revision 49ce682dfa7993d31206cea19ce7006cd3f3077e
1//===-- SBTarget.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#include "lldb/API/SBTarget.h"
11
12#include "lldb/lldb-include.h"
13
14#include "lldb/API/SBFileSpec.h"
15#include "lldb/API/SBModule.h"
16#include "lldb/API/SBStream.h"
17#include "lldb/Breakpoint/BreakpointID.h"
18#include "lldb/Breakpoint/BreakpointIDList.h"
19#include "lldb/Breakpoint/BreakpointList.h"
20#include "lldb/Breakpoint/BreakpointLocation.h"
21#include "lldb/Core/Address.h"
22#include "lldb/Core/AddressResolver.h"
23#include "lldb/Core/AddressResolverName.h"
24#include "lldb/Interpreter/Args.h"
25#include "lldb/Core/ArchSpec.h"
26#include "lldb/Core/Debugger.h"
27#include "lldb/Core/Disassembler.h"
28#include "lldb/Core/FileSpec.h"
29#include "lldb/Core/Log.h"
30#include "lldb/Core/RegularExpression.h"
31#include "lldb/Core/SearchFilter.h"
32#include "lldb/Core/STLUtils.h"
33#include "lldb/Target/Process.h"
34#include "lldb/Target/Target.h"
35#include "lldb/Target/TargetList.h"
36
37#include "lldb/Interpreter/CommandReturnObject.h"
38#include "../source/Commands/CommandObjectBreakpoint.h"
39
40#include "lldb/API/SBDebugger.h"
41#include "lldb/API/SBProcess.h"
42#include "lldb/API/SBListener.h"
43#include "lldb/API/SBBreakpoint.h"
44
45using namespace lldb;
46using namespace lldb_private;
47
48#define DEFAULT_DISASM_BYTE_SIZE 32
49
50//----------------------------------------------------------------------
51// SBTarget constructor
52//----------------------------------------------------------------------
53SBTarget::SBTarget ()
54{
55}
56
57SBTarget::SBTarget (const SBTarget& rhs) :
58    m_opaque_sp (rhs.m_opaque_sp)
59{
60}
61
62SBTarget::SBTarget(const TargetSP& target_sp) :
63    m_opaque_sp (target_sp)
64{
65}
66
67//----------------------------------------------------------------------
68// Destructor
69//----------------------------------------------------------------------
70SBTarget::~SBTarget()
71{
72}
73
74bool
75SBTarget::IsValid () const
76{
77    return m_opaque_sp.get() != NULL;
78}
79
80SBProcess
81SBTarget::GetProcess ()
82{
83
84    SBProcess sb_process;
85    if (m_opaque_sp)
86        sb_process.SetProcess (m_opaque_sp->GetProcessSP());
87
88    Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API);
89    if (log)
90    {
91        log->Printf ("SBTarget(%p)::GetProcess () => SBProcess(%p)",
92                     m_opaque_sp.get(), sb_process.get());
93    }
94
95    return sb_process;
96}
97
98SBDebugger
99SBTarget::GetDebugger () const
100{
101    SBDebugger debugger;
102    if (m_opaque_sp)
103        debugger.reset (m_opaque_sp->GetDebugger().GetSP());
104    return debugger;
105}
106
107
108// DEPRECATED
109SBProcess
110SBTarget::CreateProcess ()
111{
112
113    SBProcess sb_process;
114
115    if (m_opaque_sp)
116        sb_process.SetProcess (m_opaque_sp->CreateProcess (m_opaque_sp->GetDebugger().GetListener()));
117
118    Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API);
119    if (log)
120    {
121        log->Printf ("SBTarget(%p)::CreateProcess () => SBProcess(%p)",
122                     m_opaque_sp.get(), sb_process.get());
123    }
124
125    return sb_process;
126}
127
128
129SBProcess
130SBTarget::LaunchProcess
131(
132    char const **argv,
133    char const **envp,
134    const char *tty,
135    uint32_t launch_flags,
136    bool stop_at_entry
137)
138{
139    Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API);
140
141    if (log)
142        log->Printf ("SBTarget(%p)::LaunchProcess (argv=%p, envp=%p, tty=\"%s\", launch_flags=%d, stop_at_entry=%i)",
143                     m_opaque_sp.get(), argv, envp, tty, launch_flags, stop_at_entry);
144
145    SBError sb_error;
146    SBProcess sb_process = Launch (argv, envp, tty, launch_flags, stop_at_entry, sb_error);
147
148    log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API);
149    if (log)
150    {
151        log->Printf ("SBTarget(%p)::LaunchProcess (...) => SBProcess(%p)",
152                     m_opaque_sp.get(), sb_process.get());
153    }
154
155    return sb_process;
156}
157
158SBProcess
159SBTarget::Launch
160(
161    char const **argv,
162    char const **envp,
163    const char *tty,
164    uint32_t launch_flags,
165    bool stop_at_entry,
166    SBError &error
167)
168{
169    Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API);
170
171    if (log)
172    {
173        log->Printf ("SBTarget(%p)::Launch (argv=%p, envp=%p, tty=\"%s\", launch_flags=%d, stop_at_entry=%i, &error (%p))...",
174                     m_opaque_sp.get(), argv, envp, tty, launch_flags, stop_at_entry, error.get());
175    }
176    SBProcess sb_process;
177    if (m_opaque_sp)
178    {
179        // DEPRECATED, this will change when CreateProcess is removed...
180        if (m_opaque_sp->GetProcessSP())
181        {
182            sb_process.SetProcess(m_opaque_sp->GetProcessSP());
183        }
184        else
185        {
186            // When launching, we always want to create a new process When
187            // SBTarget::CreateProcess is removed, this will always happen.
188            sb_process.SetProcess (m_opaque_sp->CreateProcess (m_opaque_sp->GetDebugger().GetListener()));
189        }
190
191        if (sb_process.IsValid())
192        {
193            error.SetError (sb_process->Launch (argv, envp, launch_flags, tty, tty, tty));
194            if (error.Success())
195            {
196                // We we are stopping at the entry point, we can return now!
197                if (stop_at_entry)
198                    return sb_process;
199
200                // Make sure we are stopped at the entry
201                StateType state = sb_process->WaitForProcessToStop (NULL);
202                if (state == eStateStopped)
203                {
204                    // resume the process to skip the entry point
205                    error.SetError (sb_process->Resume());
206                    if (error.Success())
207                    {
208                        // If we are doing synchronous mode, then wait for the
209                        // process to stop yet again!
210                        if (m_opaque_sp->GetDebugger().GetAsyncExecution () == false)
211                            sb_process->WaitForProcessToStop (NULL);
212                    }
213                }
214            }
215        }
216        else
217        {
218            error.SetErrorString ("unable to create lldb_private::Process");
219        }
220    }
221    else
222    {
223        error.SetErrorString ("SBTarget is invalid");
224    }
225
226    log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API);
227    if (log)
228    {
229        log->Printf ("SBTarget(%p)::Launch (...) => SBProceess(%p)",
230                     m_opaque_sp.get(), sb_process.get());
231    }
232
233    return sb_process;
234}
235
236
237lldb::SBProcess
238SBTarget::AttachToProcessWithID
239(
240    lldb::pid_t pid,// The process ID to attach to
241    SBError& error  // An error explaining what went wrong if attach fails
242)
243{
244    SBProcess sb_process;
245    if (m_opaque_sp)
246    {
247        // DEPRECATED, this will change when CreateProcess is removed...
248        if (m_opaque_sp->GetProcessSP())
249        {
250            sb_process.SetProcess(m_opaque_sp->GetProcessSP());
251        }
252        else
253        {
254            // When launching, we always want to create a new process When
255            // SBTarget::CreateProcess is removed, this will always happen.
256            sb_process.SetProcess (m_opaque_sp->CreateProcess (m_opaque_sp->GetDebugger().GetListener()));
257        }
258
259        if (sb_process.IsValid())
260        {
261            error.SetError (sb_process->Attach (pid));
262        }
263        else
264        {
265            error.SetErrorString ("unable to create lldb_private::Process");
266        }
267    }
268    else
269    {
270        error.SetErrorString ("SBTarget is invalid");
271    }
272    return sb_process;
273
274}
275
276lldb::SBProcess
277SBTarget::AttachToProcessWithName
278(
279    const char *name,   // basename of process to attach to
280    bool wait_for,      // if true wait for a new instance of "name" to be launched
281    SBError& error      // An error explaining what went wrong if attach fails
282)
283{
284    SBProcess sb_process;
285    if (m_opaque_sp)
286    {
287        // DEPRECATED, this will change when CreateProcess is removed...
288        if (m_opaque_sp->GetProcessSP())
289        {
290            sb_process.SetProcess(m_opaque_sp->GetProcessSP());
291        }
292        else
293        {
294            // When launching, we always want to create a new process When
295            // SBTarget::CreateProcess is removed, this will always happen.
296            sb_process.SetProcess (m_opaque_sp->CreateProcess (m_opaque_sp->GetDebugger().GetListener()));
297        }
298
299        if (sb_process.IsValid())
300        {
301            error.SetError (sb_process->Attach (name, wait_for));
302        }
303        else
304        {
305            error.SetErrorString ("unable to create lldb_private::Process");
306        }
307    }
308    else
309    {
310        error.SetErrorString ("SBTarget is invalid");
311    }
312    return sb_process;
313
314}
315
316SBFileSpec
317SBTarget::GetExecutable ()
318{
319
320    SBFileSpec exe_file_spec;
321    if (m_opaque_sp)
322    {
323        ModuleSP exe_module_sp (m_opaque_sp->GetExecutableModule ());
324        if (exe_module_sp)
325            exe_file_spec.SetFileSpec (exe_module_sp->GetFileSpec());
326    }
327
328    Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API);
329    if (log)
330    {
331        log->Printf ("SBTarget(%p)::GetExecutable () => SBFileSpec(%p)",
332                     m_opaque_sp.get(), exe_file_spec.get());
333    }
334
335    return exe_file_spec;
336}
337
338
339bool
340SBTarget::DeleteTargetFromList (TargetList *list)
341{
342    if (m_opaque_sp)
343        return list->DeleteTarget (m_opaque_sp);
344    else
345        return false;
346}
347
348bool
349SBTarget::operator == (const SBTarget &rhs) const
350{
351    return m_opaque_sp.get() == rhs.m_opaque_sp.get();
352}
353
354bool
355SBTarget::operator != (const SBTarget &rhs) const
356{
357    return m_opaque_sp.get() != rhs.m_opaque_sp.get();
358}
359
360lldb_private::Target *
361SBTarget::operator ->() const
362{
363    return m_opaque_sp.get();
364}
365
366lldb_private::Target *
367SBTarget::get() const
368{
369    return m_opaque_sp.get();
370}
371
372void
373SBTarget::reset (const lldb::TargetSP& target_sp)
374{
375    m_opaque_sp = target_sp;
376}
377
378SBBreakpoint
379SBTarget::BreakpointCreateByLocation (const char *file, uint32_t line)
380{
381    return SBBreakpoint(BreakpointCreateByLocation (SBFileSpec (file), line));
382}
383
384SBBreakpoint
385SBTarget::BreakpointCreateByLocation (const SBFileSpec &sb_file_spec, uint32_t line)
386{
387    Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API);
388
389    SBBreakpoint sb_bp;
390    if (m_opaque_sp.get() && line != 0)
391        *sb_bp = m_opaque_sp->CreateBreakpoint (NULL, *sb_file_spec, line, true, false);
392
393    if (log)
394    {
395        SBStream sstr;
396        sb_bp.GetDescription (sstr);
397        char path[PATH_MAX];
398        sb_file_spec->GetPath (path, sizeof(path));
399        log->Printf ("SBTarget(%p)::BreakpointCreateByLocation ( %s:%u ) => SBBreakpoint(%p): %s",
400                     m_opaque_sp.get(),
401                     path,
402                     line,
403                     sb_bp.get(),
404                     sstr.GetData());
405    }
406
407    return sb_bp;
408}
409
410SBBreakpoint
411SBTarget::BreakpointCreateByName (const char *symbol_name, const char *module_name)
412{
413    Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API);
414
415    SBBreakpoint sb_bp;
416    if (m_opaque_sp.get() && symbol_name && symbol_name[0])
417    {
418        if (module_name && module_name[0])
419        {
420            FileSpec module_file_spec(module_name, false);
421            *sb_bp = m_opaque_sp->CreateBreakpoint (&module_file_spec, symbol_name, eFunctionNameTypeFull | eFunctionNameTypeBase, false);
422        }
423        else
424        {
425            *sb_bp = m_opaque_sp->CreateBreakpoint (NULL, symbol_name, eFunctionNameTypeFull | eFunctionNameTypeBase, false);
426        }
427    }
428
429    if (log)
430    {
431        log->Printf ("SBTarget(%p)::BreakpointCreateByName (symbol=\"%s\", module=\"%s\") => SBBreakpoint(%p)",
432                     m_opaque_sp.get(), symbol_name, module_name, sb_bp.get());
433    }
434
435    return sb_bp;
436}
437
438SBBreakpoint
439SBTarget::BreakpointCreateByRegex (const char *symbol_name_regex, const char *module_name)
440{
441    Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API);
442
443    SBBreakpoint sb_bp;
444    if (m_opaque_sp.get() && symbol_name_regex && symbol_name_regex[0])
445    {
446        RegularExpression regexp(symbol_name_regex);
447
448        if (module_name && module_name[0])
449        {
450            FileSpec module_file_spec(module_name, false);
451
452            *sb_bp = m_opaque_sp->CreateBreakpoint (&module_file_spec, regexp, false);
453        }
454        else
455        {
456            *sb_bp = m_opaque_sp->CreateBreakpoint (NULL, regexp, false);
457        }
458    }
459
460    if (log)
461    {
462        log->Printf ("SBTarget(%p)::BreakpointCreateByRegex (symbol_regex=\"%s\", module_name=\"%s\") => SBBreakpoint(%p)",
463                     m_opaque_sp.get(), symbol_name_regex, module_name, sb_bp.get());
464    }
465
466    return sb_bp;
467}
468
469
470
471SBBreakpoint
472SBTarget::BreakpointCreateByAddress (addr_t address)
473{
474    Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API);
475
476    SBBreakpoint sb_bp;
477    if (m_opaque_sp.get())
478        *sb_bp = m_opaque_sp->CreateBreakpoint (address, false);
479
480    if (log)
481    {
482        log->Printf ("SBTarget(%p)::BreakpointCreateByAddress (%p, address=%p) => SBBreakpoint(%p)", m_opaque_sp.get(), address, sb_bp.get());
483    }
484
485    return sb_bp;
486}
487
488SBBreakpoint
489SBTarget::FindBreakpointByID (break_id_t bp_id)
490{
491    Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API);
492
493    SBBreakpoint sb_breakpoint;
494    if (m_opaque_sp && bp_id != LLDB_INVALID_BREAK_ID)
495        *sb_breakpoint = m_opaque_sp->GetBreakpointByID (bp_id);
496
497    if (log)
498    {
499        log->Printf ("SBTarget(%p)::FindBreakpointByID (bp_id=%d) => SBBreakpoint(%p)",
500                     m_opaque_sp.get(), (uint32_t) bp_id, sb_breakpoint.get());
501    }
502
503    return sb_breakpoint;
504}
505
506uint32_t
507SBTarget::GetNumBreakpoints () const
508{
509    if (m_opaque_sp)
510        return m_opaque_sp->GetBreakpointList().GetSize();
511    return 0;
512}
513
514SBBreakpoint
515SBTarget::GetBreakpointAtIndex (uint32_t idx) const
516{
517    SBBreakpoint sb_breakpoint;
518    if (m_opaque_sp)
519        *sb_breakpoint = m_opaque_sp->GetBreakpointList().GetBreakpointAtIndex(idx);
520    return sb_breakpoint;
521}
522
523bool
524SBTarget::BreakpointDelete (break_id_t bp_id)
525{
526    Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API);
527
528    bool result = false;
529    if (m_opaque_sp)
530        result = m_opaque_sp->RemoveBreakpointByID (bp_id);
531
532    if (log)
533    {
534        log->Printf ("SBTarget(%p)::BreakpointDelete (bp_id=%d) => %i", m_opaque_sp.get(), (uint32_t) bp_id, result);
535    }
536
537    return result;
538}
539
540bool
541SBTarget::EnableAllBreakpoints ()
542{
543    if (m_opaque_sp)
544    {
545        m_opaque_sp->EnableAllBreakpoints ();
546        return true;
547    }
548    return false;
549}
550
551bool
552SBTarget::DisableAllBreakpoints ()
553{
554    if (m_opaque_sp)
555    {
556        m_opaque_sp->DisableAllBreakpoints ();
557        return true;
558    }
559    return false;
560}
561
562bool
563SBTarget::DeleteAllBreakpoints ()
564{
565    if (m_opaque_sp)
566    {
567        m_opaque_sp->RemoveAllBreakpoints ();
568        return true;
569    }
570    return false;
571}
572
573
574uint32_t
575SBTarget::GetNumModules () const
576{
577    Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API);
578
579    uint32_t num = 0;
580    if (m_opaque_sp)
581        num =  m_opaque_sp->GetImages().GetSize();
582
583    if (log)
584        log->Printf ("SBTarget(%p)::GetNumModules () => %d", m_opaque_sp.get(), num);
585
586    return num;
587}
588
589void
590SBTarget::Clear ()
591{
592    Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API);
593
594    if (log)
595        log->Printf ("SBTarget(%p)::Clear ()", m_opaque_sp.get());
596
597    m_opaque_sp.reset();
598}
599
600
601SBModule
602SBTarget::FindModule (const SBFileSpec &sb_file_spec)
603{
604    SBModule sb_module;
605    if (m_opaque_sp && sb_file_spec.IsValid())
606        sb_module.SetModule (m_opaque_sp->GetImages().FindFirstModuleForFileSpec (*sb_file_spec, NULL));
607    return sb_module;
608}
609
610SBModule
611SBTarget::GetModuleAtIndex (uint32_t idx)
612{
613    Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API);
614
615    SBModule sb_module;
616    if (m_opaque_sp)
617        sb_module.SetModule(m_opaque_sp->GetImages().GetModuleAtIndex(idx));
618
619    if (log)
620    {
621        log->Printf ("SBTarget(%p)::GetModuleAtIndex (idx=%d) => SBModule(%p)",
622                     m_opaque_sp.get(), idx, sb_module.get());
623    }
624
625    return sb_module;
626}
627
628
629SBBroadcaster
630SBTarget::GetBroadcaster () const
631{
632    Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API);
633
634    SBBroadcaster broadcaster(m_opaque_sp.get(), false);
635
636    if (log)
637        log->Printf ("SBTarget(%p)::GetBroadcaster () => SBBroadcaster(%p)",
638                     m_opaque_sp.get(), broadcaster.get());
639
640    return broadcaster;
641}
642
643void
644SBTarget::Disassemble (lldb::addr_t start_addr, lldb::addr_t end_addr, const char *module_name)
645{
646    if (start_addr == LLDB_INVALID_ADDRESS)
647        return;
648
649    FILE *out = m_opaque_sp->GetDebugger().GetOutputFileHandle();
650    if (out == NULL)
651        return;
652
653    if (m_opaque_sp)
654    {
655        ModuleSP module_sp;
656        if (module_name != NULL)
657        {
658            FileSpec module_file_spec (module_name, false);
659            module_sp = m_opaque_sp->GetImages().FindFirstModuleForFileSpec (module_file_spec, NULL);
660        }
661
662        AddressRange range;
663
664        // Make sure the process object is alive if we have one (it might be
665        // created but we might not be launched yet).
666
667        Process *sb_process = m_opaque_sp->GetProcessSP().get();
668        if (sb_process && !sb_process->IsAlive())
669            sb_process = NULL;
670
671        // If we are given a module, then "start_addr" is a file address in
672        // that module.
673        if (module_sp)
674        {
675            if (!module_sp->ResolveFileAddress (start_addr, range.GetBaseAddress()))
676                range.GetBaseAddress().SetOffset(start_addr);
677        }
678        else if (m_opaque_sp->GetSectionLoadList().IsEmpty() == false)
679        {
680            // We don't have a module, se we need to figure out if "start_addr"
681            // resolves to anything in a running process.
682            if (!m_opaque_sp->GetSectionLoadList().ResolveLoadAddress (start_addr, range.GetBaseAddress()))
683                range.GetBaseAddress().SetOffset(start_addr);
684        }
685        else
686        {
687            if (m_opaque_sp->GetImages().ResolveFileAddress (start_addr, range.GetBaseAddress()))
688                range.GetBaseAddress().SetOffset(start_addr);
689        }
690
691        // For now, we need a process;  the disassembly functions insist.  If we don't have one already,
692        // make one.
693
694        ExecutionContext exe_ctx;
695
696        if (sb_process)
697            sb_process->CalculateExecutionContext(exe_ctx);
698        else
699            m_opaque_sp->CalculateExecutionContext(exe_ctx);
700
701        if (end_addr == LLDB_INVALID_ADDRESS || end_addr < start_addr)
702            range.SetByteSize( DEFAULT_DISASM_BYTE_SIZE);
703        else
704            range.SetByteSize(end_addr - start_addr);
705
706        StreamFile out_stream (out);
707
708        Disassembler::Disassemble (m_opaque_sp->GetDebugger(),
709                                   m_opaque_sp->GetArchitecture(),
710                                   exe_ctx,
711                                   range,
712                                   3,
713                                   false,
714                                   out_stream);
715    }
716}
717
718void
719SBTarget::Disassemble (const char *function_name, const char *module_name)
720{
721    if (function_name == NULL)
722        return;
723
724    FILE *out = m_opaque_sp->GetDebugger().GetOutputFileHandle();
725    if (out == NULL)
726        return;
727
728    if (m_opaque_sp)
729    {
730        Disassembler *disassembler = Disassembler::FindPlugin (m_opaque_sp->GetArchitecture());
731        if (disassembler == NULL)
732          return;
733
734        ModuleSP module_sp;
735        if (module_name != NULL)
736        {
737            FileSpec module_file_spec (module_name, false);
738            module_sp = m_opaque_sp->GetImages().FindFirstModuleForFileSpec (module_file_spec, NULL);
739        }
740
741        ExecutionContext exe_ctx;
742
743        // Make sure the process object is alive if we have one (it might be
744        // created but we might not be launched yet).
745        Process *sb_process = m_opaque_sp->GetProcessSP().get();
746        if (sb_process && !sb_process->IsAlive())
747            sb_process = NULL;
748
749        if (sb_process)
750            sb_process->CalculateExecutionContext(exe_ctx);
751        else
752            m_opaque_sp->CalculateExecutionContext(exe_ctx);
753
754
755        StreamFile out_stream (out);
756
757        Disassembler::Disassemble (m_opaque_sp->GetDebugger(),
758                                   m_opaque_sp->GetArchitecture(),
759                                   exe_ctx,
760                                   ConstString (function_name),
761                                   module_sp.get(),
762                                   3,
763                                   false,
764                                   out_stream);
765    }
766}
767
768bool
769SBTarget::GetDescription (SBStream &description, lldb::DescriptionLevel description_level)
770{
771    if (m_opaque_sp)
772    {
773        description.ref();
774        m_opaque_sp->Dump (description.get(), description_level);
775    }
776    else
777        description.Printf ("No value");
778
779    return true;
780}
781
782bool
783SBTarget::GetDescription (SBStream &description, lldb::DescriptionLevel description_level) const
784{
785    if (m_opaque_sp)
786    {
787        description.ref();
788        m_opaque_sp->Dump (description.get(), description_level);
789    }
790    else
791        description.Printf ("No value");
792
793    return true;
794}
795