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-public.h"
13 
14 #include "lldb/API/SBDebugger.h"
15 #include "lldb/API/SBBreakpoint.h"
16 #include "lldb/API/SBFileSpec.h"
17 #include "lldb/API/SBListener.h"
18 #include "lldb/API/SBModule.h"
19 #include "lldb/API/SBProcess.h"
20 #include "lldb/API/SBStream.h"
21 #include "lldb/API/SBSymbolContextList.h"
22 #include "lldb/Breakpoint/BreakpointID.h"
23 #include "lldb/Breakpoint/BreakpointIDList.h"
24 #include "lldb/Breakpoint/BreakpointList.h"
25 #include "lldb/Breakpoint/BreakpointLocation.h"
26 #include "lldb/Core/Address.h"
27 #include "lldb/Core/AddressResolver.h"
28 #include "lldb/Core/AddressResolverName.h"
29 #include "lldb/Core/ArchSpec.h"
30 #include "lldb/Core/Debugger.h"
31 #include "lldb/Core/Disassembler.h"
32 #include "lldb/Core/Log.h"
33 #include "lldb/Core/RegularExpression.h"
34 #include "lldb/Core/SearchFilter.h"
35 #include "lldb/Core/STLUtils.h"
36 #include "lldb/Core/ValueObjectList.h"
37 #include "lldb/Core/ValueObjectVariable.h"
38 #include "lldb/Host/FileSpec.h"
39 #include "lldb/Host/Host.h"
40 #include "lldb/Interpreter/Args.h"
41 #include "lldb/Symbol/VariableList.h"
42 #include "lldb/Target/Process.h"
43 #include "lldb/Target/Target.h"
44 #include "lldb/Target/TargetList.h"
45 
46 #include "lldb/Interpreter/CommandReturnObject.h"
47 #include "../source/Commands/CommandObjectBreakpoint.h"
48 
49 
50 using namespace lldb;
51 using namespace lldb_private;
52 
53 #define DEFAULT_DISASM_BYTE_SIZE 32
54 
55 //----------------------------------------------------------------------
56 // SBTarget constructor
57 //----------------------------------------------------------------------
58 SBTarget::SBTarget () :
59     m_opaque_sp ()
60 {
61 }
62 
63 SBTarget::SBTarget (const SBTarget& rhs) :
64     m_opaque_sp (rhs.m_opaque_sp)
65 {
66 }
67 
68 SBTarget::SBTarget(const TargetSP& target_sp) :
69     m_opaque_sp (target_sp)
70 {
71 }
72 
73 const SBTarget&
74 SBTarget::operator = (const SBTarget& rhs)
75 {
76     if (this != &rhs)
77         m_opaque_sp = rhs.m_opaque_sp;
78     return *this;
79 }
80 
81 //----------------------------------------------------------------------
82 // Destructor
83 //----------------------------------------------------------------------
84 SBTarget::~SBTarget()
85 {
86 }
87 
88 bool
89 SBTarget::IsValid () const
90 {
91     return m_opaque_sp.get() != NULL;
92 }
93 
94 SBProcess
95 SBTarget::GetProcess ()
96 {
97 
98     SBProcess sb_process;
99     if (m_opaque_sp)
100     {
101         Mutex::Locker api_locker (m_opaque_sp->GetAPIMutex());
102         sb_process.SetProcess (m_opaque_sp->GetProcessSP());
103     }
104 
105     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
106     if (log)
107     {
108         log->Printf ("SBTarget(%p)::GetProcess () => SBProcess(%p)",
109                      m_opaque_sp.get(), sb_process.get());
110     }
111 
112     return sb_process;
113 }
114 
115 SBDebugger
116 SBTarget::GetDebugger () const
117 {
118     SBDebugger debugger;
119     if (m_opaque_sp)
120         debugger.reset (m_opaque_sp->GetDebugger().GetSP());
121     return debugger;
122 }
123 
124 SBProcess
125 SBTarget::LaunchSimple
126 (
127     char const **argv,
128     char const **envp,
129     const char *working_directory
130 )
131 {
132     char *stdin_path = NULL;
133     char *stdout_path = NULL;
134     char *stderr_path = NULL;
135     uint32_t launch_flags = 0;
136     bool stop_at_entry = false;
137     SBError error;
138     SBListener listener = GetDebugger().GetListener();
139     return Launch (listener,
140                    argv,
141                    envp,
142                    stdin_path,
143                    stdout_path,
144                    stderr_path,
145                    working_directory,
146                    launch_flags,
147                    stop_at_entry,
148                    error);
149 }
150 
151 SBProcess
152 SBTarget::Launch
153 (
154     SBListener &listener,
155     char const **argv,
156     char const **envp,
157     const char *stdin_path,
158     const char *stdout_path,
159     const char *stderr_path,
160     const char *working_directory,
161     uint32_t launch_flags,   // See LaunchFlags
162     bool stop_at_entry,
163     lldb::SBError& error
164 )
165 {
166     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
167 
168     if (log)
169     {
170         log->Printf ("SBTarget(%p)::Launch (argv=%p, envp=%p, stdin=%s, stdout=%s, stderr=%s, working-dir=%s, launch_flags=0x%x, stop_at_entry=%i, &error (%p))...",
171                      m_opaque_sp.get(),
172                      argv,
173                      envp,
174                      stdin_path ? stdin_path : "NULL",
175                      stdout_path ? stdout_path : "NULL",
176                      stderr_path ? stderr_path : "NULL",
177                      working_directory ? working_directory : "NULL",
178                      launch_flags,
179                      stop_at_entry,
180                      error.get());
181     }
182     SBProcess sb_process;
183     if (m_opaque_sp)
184     {
185         Mutex::Locker api_locker (m_opaque_sp->GetAPIMutex());
186 
187         if (getenv("LLDB_LAUNCH_FLAG_DISABLE_ASLR"))
188             launch_flags |= eLaunchFlagDisableASLR;
189 
190         StateType state = eStateInvalid;
191         sb_process.SetProcess (m_opaque_sp->GetProcessSP());
192         if (sb_process.IsValid())
193         {
194             state = sb_process->GetState();
195 
196             if (sb_process->IsAlive() && state != eStateConnected)
197             {
198                 if (state == eStateAttaching)
199                     error.SetErrorString ("process attach is in progress");
200                 else
201                     error.SetErrorString ("a process is already being debugged");
202                 sb_process.Clear();
203                 return sb_process;
204             }
205         }
206 
207         if (state == eStateConnected)
208         {
209             // If we are already connected, then we have already specified the
210             // listener, so if a valid listener is supplied, we need to error out
211             // to let the client know.
212             if (listener.IsValid())
213             {
214                 error.SetErrorString ("process is connected and already has a listener, pass empty listener");
215                 sb_process.Clear();
216                 return sb_process;
217             }
218         }
219         else
220         {
221             if (listener.IsValid())
222                 sb_process.SetProcess (m_opaque_sp->CreateProcess (listener.ref()));
223             else
224                 sb_process.SetProcess (m_opaque_sp->CreateProcess (m_opaque_sp->GetDebugger().GetListener()));
225         }
226 
227         if (sb_process.IsValid())
228         {
229             if (getenv("LLDB_LAUNCH_FLAG_DISABLE_STDIO"))
230                 launch_flags |= eLaunchFlagDisableSTDIO;
231 
232             error.SetError (sb_process->Launch (argv, envp, launch_flags, stdin_path, stdout_path, stderr_path, working_directory));
233             if (error.Success())
234             {
235                 // We we are stopping at the entry point, we can return now!
236                 if (stop_at_entry)
237                     return sb_process;
238 
239                 // Make sure we are stopped at the entry
240                 StateType state = sb_process->WaitForProcessToStop (NULL);
241                 if (state == eStateStopped)
242                 {
243                     // resume the process to skip the entry point
244                     error.SetError (sb_process->Resume());
245                     if (error.Success())
246                     {
247                         // If we are doing synchronous mode, then wait for the
248                         // process to stop yet again!
249                         if (m_opaque_sp->GetDebugger().GetAsyncExecution () == false)
250                             sb_process->WaitForProcessToStop (NULL);
251                     }
252                 }
253             }
254         }
255         else
256         {
257             error.SetErrorString ("unable to create lldb_private::Process");
258         }
259     }
260     else
261     {
262         error.SetErrorString ("SBTarget is invalid");
263     }
264 
265     log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API);
266     if (log)
267     {
268         log->Printf ("SBTarget(%p)::Launch (...) => SBProceess(%p)",
269                      m_opaque_sp.get(), sb_process.get());
270     }
271 
272     return sb_process;
273 }
274 
275 
276 lldb::SBProcess
277 SBTarget::AttachToProcessWithID
278 (
279     SBListener &listener,
280     lldb::pid_t pid,// The process ID to attach to
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         Mutex::Locker api_locker (m_opaque_sp->GetAPIMutex());
288 
289         StateType state = eStateInvalid;
290         sb_process.SetProcess (m_opaque_sp->GetProcessSP());
291         if (sb_process.IsValid())
292         {
293             state = sb_process->GetState();
294 
295             if (sb_process->IsAlive() && state != eStateConnected)
296             {
297                 if (state == eStateAttaching)
298                     error.SetErrorString ("process attach is in progress");
299                 else
300                     error.SetErrorString ("a process is already being debugged");
301                 sb_process.Clear();
302                 return sb_process;
303             }
304         }
305 
306         if (state == eStateConnected)
307         {
308             // If we are already connected, then we have already specified the
309             // listener, so if a valid listener is supplied, we need to error out
310             // to let the client know.
311             if (listener.IsValid())
312             {
313                 error.SetErrorString ("process is connected and already has a listener, pass empty listener");
314                 sb_process.Clear();
315                 return sb_process;
316             }
317         }
318         else
319         {
320             if (listener.IsValid())
321                 sb_process.SetProcess (m_opaque_sp->CreateProcess (listener.ref()));
322             else
323                 sb_process.SetProcess (m_opaque_sp->CreateProcess (m_opaque_sp->GetDebugger().GetListener()));
324         }
325 
326         if (sb_process.IsValid())
327         {
328             error.SetError (sb_process->Attach (pid));
329             // If we are doing synchronous mode, then wait for the
330             // process to stop!
331             if (m_opaque_sp->GetDebugger().GetAsyncExecution () == false)
332                 sb_process->WaitForProcessToStop (NULL);
333         }
334         else
335         {
336             error.SetErrorString ("unable to create lldb_private::Process");
337         }
338     }
339     else
340     {
341         error.SetErrorString ("SBTarget is invalid");
342     }
343     return sb_process;
344 
345 }
346 
347 lldb::SBProcess
348 SBTarget::AttachToProcessWithName
349 (
350     SBListener &listener,
351     const char *name,   // basename of process to attach to
352     bool wait_for,      // if true wait for a new instance of "name" to be launched
353     SBError& error      // An error explaining what went wrong if attach fails
354 )
355 {
356     SBProcess sb_process;
357     if (m_opaque_sp)
358     {
359         Mutex::Locker api_locker (m_opaque_sp->GetAPIMutex());
360 
361         StateType state = eStateInvalid;
362         sb_process.SetProcess (m_opaque_sp->GetProcessSP());
363         if (sb_process.IsValid())
364         {
365             state = sb_process->GetState();
366 
367             if (sb_process->IsAlive() && state != eStateConnected)
368             {
369                 if (state == eStateAttaching)
370                     error.SetErrorString ("process attach is in progress");
371                 else
372                     error.SetErrorString ("a process is already being debugged");
373                 sb_process.Clear();
374                 return sb_process;
375             }
376         }
377 
378         if (state == eStateConnected)
379         {
380             // If we are already connected, then we have already specified the
381             // listener, so if a valid listener is supplied, we need to error out
382             // to let the client know.
383             if (listener.IsValid())
384             {
385                 error.SetErrorString ("process is connected and already has a listener, pass empty listener");
386                 sb_process.Clear();
387                 return sb_process;
388             }
389         }
390         else
391         {
392             if (listener.IsValid())
393                 sb_process.SetProcess (m_opaque_sp->CreateProcess (listener.ref()));
394             else
395                 sb_process.SetProcess (m_opaque_sp->CreateProcess (m_opaque_sp->GetDebugger().GetListener()));
396         }
397 
398         if (sb_process.IsValid())
399         {
400             error.SetError (sb_process->Attach (name, wait_for));
401             // If we are doing synchronous mode, then wait for the
402             // process to stop!
403             if (m_opaque_sp->GetDebugger().GetAsyncExecution () == false)
404                 sb_process->WaitForProcessToStop (NULL);
405         }
406         else
407         {
408             error.SetErrorString ("unable to create lldb_private::Process");
409         }
410     }
411     else
412     {
413         error.SetErrorString ("SBTarget is invalid");
414     }
415     return sb_process;
416 
417 }
418 
419 lldb::SBProcess
420 SBTarget::ConnectRemote
421 (
422     SBListener &listener,
423     const char *url,
424     const char *plugin_name,
425     SBError& error
426 )
427 {
428     SBProcess sb_process;
429     if (m_opaque_sp)
430     {
431         Mutex::Locker api_locker (m_opaque_sp->GetAPIMutex());
432         if (listener.IsValid())
433             sb_process.SetProcess (m_opaque_sp->CreateProcess (listener.ref(), plugin_name));
434         else
435             sb_process.SetProcess (m_opaque_sp->CreateProcess (m_opaque_sp->GetDebugger().GetListener(), plugin_name));
436 
437 
438         if (sb_process.IsValid())
439         {
440             error.SetError (sb_process->ConnectRemote (url));
441         }
442         else
443         {
444             error.SetErrorString ("unable to create lldb_private::Process");
445         }
446     }
447     else
448     {
449         error.SetErrorString ("SBTarget is invalid");
450     }
451     return sb_process;
452 }
453 
454 SBFileSpec
455 SBTarget::GetExecutable ()
456 {
457 
458     SBFileSpec exe_file_spec;
459     if (m_opaque_sp)
460     {
461         ModuleSP exe_module_sp (m_opaque_sp->GetExecutableModule ());
462         if (exe_module_sp)
463             exe_file_spec.SetFileSpec (exe_module_sp->GetFileSpec());
464     }
465 
466     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
467     if (log)
468     {
469         log->Printf ("SBTarget(%p)::GetExecutable () => SBFileSpec(%p)",
470                      m_opaque_sp.get(), exe_file_spec.get());
471     }
472 
473     return exe_file_spec;
474 }
475 
476 bool
477 SBTarget::operator == (const SBTarget &rhs) const
478 {
479     return m_opaque_sp.get() == rhs.m_opaque_sp.get();
480 }
481 
482 bool
483 SBTarget::operator != (const SBTarget &rhs) const
484 {
485     return m_opaque_sp.get() != rhs.m_opaque_sp.get();
486 }
487 
488 lldb_private::Target *
489 SBTarget::operator ->() const
490 {
491     return m_opaque_sp.get();
492 }
493 
494 lldb_private::Target *
495 SBTarget::get() const
496 {
497     return m_opaque_sp.get();
498 }
499 
500 void
501 SBTarget::reset (const lldb::TargetSP& target_sp)
502 {
503     m_opaque_sp = target_sp;
504 }
505 
506 bool
507 SBTarget::ResolveLoadAddress (lldb::addr_t vm_addr,
508                               lldb::SBAddress& addr)
509 {
510     if (m_opaque_sp && addr.IsValid())
511     {
512         Mutex::Locker api_locker (m_opaque_sp->GetAPIMutex());
513         return m_opaque_sp->GetSectionLoadList().ResolveLoadAddress (vm_addr, *addr);
514     }
515 
516     if (addr.IsValid())
517         addr->Clear();
518     return false;
519 }
520 
521 SBSymbolContext
522 SBTarget::ResolveSymbolContextForAddress (const SBAddress& addr, uint32_t resolve_scope)
523 {
524     SBSymbolContext sc;
525     if (m_opaque_sp && addr.IsValid())
526         m_opaque_sp->GetImages().ResolveSymbolContextForAddress (*addr, resolve_scope, sc.ref());
527     return sc;
528 }
529 
530 
531 SBBreakpoint
532 SBTarget::BreakpointCreateByLocation (const char *file, uint32_t line)
533 {
534     return SBBreakpoint(BreakpointCreateByLocation (SBFileSpec (file, false), line));
535 }
536 
537 SBBreakpoint
538 SBTarget::BreakpointCreateByLocation (const SBFileSpec &sb_file_spec, uint32_t line)
539 {
540     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
541 
542     SBBreakpoint sb_bp;
543     if (m_opaque_sp.get() && line != 0)
544     {
545         Mutex::Locker api_locker (m_opaque_sp->GetAPIMutex());
546         *sb_bp = m_opaque_sp->CreateBreakpoint (NULL, *sb_file_spec, line, true, false);
547     }
548 
549     if (log)
550     {
551         SBStream sstr;
552         sb_bp.GetDescription (sstr);
553         char path[PATH_MAX];
554         sb_file_spec->GetPath (path, sizeof(path));
555         log->Printf ("SBTarget(%p)::BreakpointCreateByLocation ( %s:%u ) => SBBreakpoint(%p): %s",
556                      m_opaque_sp.get(),
557                      path,
558                      line,
559                      sb_bp.get(),
560                      sstr.GetData());
561     }
562 
563     return sb_bp;
564 }
565 
566 SBBreakpoint
567 SBTarget::BreakpointCreateByName (const char *symbol_name, const char *module_name)
568 {
569     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
570 
571     SBBreakpoint sb_bp;
572     if (m_opaque_sp.get() && symbol_name && symbol_name[0])
573     {
574         Mutex::Locker api_locker (m_opaque_sp->GetAPIMutex());
575         if (module_name && module_name[0])
576         {
577             FileSpec module_file_spec(module_name, false);
578             *sb_bp = m_opaque_sp->CreateBreakpoint (&module_file_spec, symbol_name, eFunctionNameTypeFull | eFunctionNameTypeBase, false);
579         }
580         else
581         {
582             *sb_bp = m_opaque_sp->CreateBreakpoint (NULL, symbol_name, eFunctionNameTypeFull | eFunctionNameTypeBase, false);
583         }
584     }
585 
586     if (log)
587     {
588         log->Printf ("SBTarget(%p)::BreakpointCreateByName (symbol=\"%s\", module=\"%s\") => SBBreakpoint(%p)",
589                      m_opaque_sp.get(), symbol_name, module_name, sb_bp.get());
590     }
591 
592     return sb_bp;
593 }
594 
595 SBBreakpoint
596 SBTarget::BreakpointCreateByRegex (const char *symbol_name_regex, const char *module_name)
597 {
598     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
599 
600     SBBreakpoint sb_bp;
601     if (m_opaque_sp.get() && symbol_name_regex && symbol_name_regex[0])
602     {
603         Mutex::Locker api_locker (m_opaque_sp->GetAPIMutex());
604         RegularExpression regexp(symbol_name_regex);
605 
606         if (module_name && module_name[0])
607         {
608             FileSpec module_file_spec(module_name, false);
609 
610             *sb_bp = m_opaque_sp->CreateBreakpoint (&module_file_spec, regexp, false);
611         }
612         else
613         {
614             *sb_bp = m_opaque_sp->CreateBreakpoint (NULL, regexp, false);
615         }
616     }
617 
618     if (log)
619     {
620         log->Printf ("SBTarget(%p)::BreakpointCreateByRegex (symbol_regex=\"%s\", module_name=\"%s\") => SBBreakpoint(%p)",
621                      m_opaque_sp.get(), symbol_name_regex, module_name, sb_bp.get());
622     }
623 
624     return sb_bp;
625 }
626 
627 
628 
629 SBBreakpoint
630 SBTarget::BreakpointCreateByAddress (addr_t address)
631 {
632     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
633 
634     SBBreakpoint sb_bp;
635     if (m_opaque_sp.get())
636     {
637         Mutex::Locker api_locker (m_opaque_sp->GetAPIMutex());
638         *sb_bp = m_opaque_sp->CreateBreakpoint (address, false);
639     }
640 
641     if (log)
642     {
643         log->Printf ("SBTarget(%p)::BreakpointCreateByAddress (%p, address=%p) => SBBreakpoint(%p)", m_opaque_sp.get(), address, sb_bp.get());
644     }
645 
646     return sb_bp;
647 }
648 
649 SBBreakpoint
650 SBTarget::FindBreakpointByID (break_id_t bp_id)
651 {
652     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
653 
654     SBBreakpoint sb_breakpoint;
655     if (m_opaque_sp && bp_id != LLDB_INVALID_BREAK_ID)
656     {
657         Mutex::Locker api_locker (m_opaque_sp->GetAPIMutex());
658         *sb_breakpoint = m_opaque_sp->GetBreakpointByID (bp_id);
659     }
660 
661     if (log)
662     {
663         log->Printf ("SBTarget(%p)::FindBreakpointByID (bp_id=%d) => SBBreakpoint(%p)",
664                      m_opaque_sp.get(), (uint32_t) bp_id, sb_breakpoint.get());
665     }
666 
667     return sb_breakpoint;
668 }
669 
670 uint32_t
671 SBTarget::GetNumBreakpoints () const
672 {
673     if (m_opaque_sp)
674     {
675         // The breakpoint list is thread safe, no need to lock
676         return m_opaque_sp->GetBreakpointList().GetSize();
677     }
678     return 0;
679 }
680 
681 SBBreakpoint
682 SBTarget::GetBreakpointAtIndex (uint32_t idx) const
683 {
684     SBBreakpoint sb_breakpoint;
685     if (m_opaque_sp)
686     {
687         // The breakpoint list is thread safe, no need to lock
688         *sb_breakpoint = m_opaque_sp->GetBreakpointList().GetBreakpointAtIndex(idx);
689     }
690     return sb_breakpoint;
691 }
692 
693 bool
694 SBTarget::BreakpointDelete (break_id_t bp_id)
695 {
696     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
697 
698     bool result = false;
699     if (m_opaque_sp)
700     {
701         Mutex::Locker api_locker (m_opaque_sp->GetAPIMutex());
702         result = m_opaque_sp->RemoveBreakpointByID (bp_id);
703     }
704 
705     if (log)
706     {
707         log->Printf ("SBTarget(%p)::BreakpointDelete (bp_id=%d) => %i", m_opaque_sp.get(), (uint32_t) bp_id, result);
708     }
709 
710     return result;
711 }
712 
713 bool
714 SBTarget::EnableAllBreakpoints ()
715 {
716     if (m_opaque_sp)
717     {
718         Mutex::Locker api_locker (m_opaque_sp->GetAPIMutex());
719         m_opaque_sp->EnableAllBreakpoints ();
720         return true;
721     }
722     return false;
723 }
724 
725 bool
726 SBTarget::DisableAllBreakpoints ()
727 {
728     if (m_opaque_sp)
729     {
730         Mutex::Locker api_locker (m_opaque_sp->GetAPIMutex());
731         m_opaque_sp->DisableAllBreakpoints ();
732         return true;
733     }
734     return false;
735 }
736 
737 bool
738 SBTarget::DeleteAllBreakpoints ()
739 {
740     if (m_opaque_sp)
741     {
742         Mutex::Locker api_locker (m_opaque_sp->GetAPIMutex());
743         m_opaque_sp->RemoveAllBreakpoints ();
744         return true;
745     }
746     return false;
747 }
748 
749 
750 uint32_t
751 SBTarget::GetNumModules () const
752 {
753     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
754 
755     uint32_t num = 0;
756     if (m_opaque_sp)
757     {
758         // The module list is thread safe, no need to lock
759         num = m_opaque_sp->GetImages().GetSize();
760     }
761 
762     if (log)
763         log->Printf ("SBTarget(%p)::GetNumModules () => %d", m_opaque_sp.get(), num);
764 
765     return num;
766 }
767 
768 void
769 SBTarget::Clear ()
770 {
771     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
772 
773     if (log)
774         log->Printf ("SBTarget(%p)::Clear ()", m_opaque_sp.get());
775 
776     m_opaque_sp.reset();
777 }
778 
779 
780 SBModule
781 SBTarget::FindModule (const SBFileSpec &sb_file_spec)
782 {
783     SBModule sb_module;
784     if (m_opaque_sp && sb_file_spec.IsValid())
785     {
786         // The module list is thread safe, no need to lock
787         sb_module.SetModule (m_opaque_sp->GetImages().FindFirstModuleForFileSpec (*sb_file_spec, NULL, NULL));
788     }
789     return sb_module;
790 }
791 
792 SBModule
793 SBTarget::GetModuleAtIndex (uint32_t idx)
794 {
795     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
796 
797     SBModule sb_module;
798     if (m_opaque_sp)
799     {
800         // The module list is thread safe, no need to lock
801         sb_module.SetModule(m_opaque_sp->GetImages().GetModuleAtIndex(idx));
802     }
803 
804     if (log)
805     {
806         log->Printf ("SBTarget(%p)::GetModuleAtIndex (idx=%d) => SBModule(%p)",
807                      m_opaque_sp.get(), idx, sb_module.get());
808     }
809 
810     return sb_module;
811 }
812 
813 
814 SBBroadcaster
815 SBTarget::GetBroadcaster () const
816 {
817     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
818 
819     SBBroadcaster broadcaster(m_opaque_sp.get(), false);
820 
821     if (log)
822         log->Printf ("SBTarget(%p)::GetBroadcaster () => SBBroadcaster(%p)",
823                      m_opaque_sp.get(), broadcaster.get());
824 
825     return broadcaster;
826 }
827 
828 
829 bool
830 SBTarget::GetDescription (SBStream &description, lldb::DescriptionLevel description_level)
831 {
832     if (m_opaque_sp)
833     {
834         description.ref();
835         m_opaque_sp->Dump (description.get(), description_level);
836     }
837     else
838         description.Printf ("No value");
839 
840     return true;
841 }
842 
843 bool
844 SBTarget::GetDescription (SBStream &description, lldb::DescriptionLevel description_level) const
845 {
846     if (m_opaque_sp)
847     {
848         description.ref();
849         m_opaque_sp->Dump (description.get(), description_level);
850     }
851     else
852         description.Printf ("No value");
853 
854     return true;
855 }
856 
857 
858 uint32_t
859 SBTarget::FindFunctions (const char *name,
860                          uint32_t name_type_mask,
861                          bool append,
862                          lldb::SBSymbolContextList& sc_list)
863 {
864     if (!append)
865         sc_list.Clear();
866     if (m_opaque_sp)
867     {
868         const bool symbols_ok = true;
869         return m_opaque_sp->GetImages().FindFunctions (ConstString(name),
870                                                        name_type_mask,
871                                                        symbols_ok,
872                                                        append,
873                                                        *sc_list);
874     }
875     return 0;
876 }
877 
878 SBValueList
879 SBTarget::FindGlobalVariables (const char *name, uint32_t max_matches)
880 {
881     SBValueList sb_value_list;
882 
883     if (m_opaque_sp)
884     {
885         VariableList variable_list;
886         const bool append = true;
887         const uint32_t match_count = m_opaque_sp->GetImages().FindGlobalVariables (ConstString (name),
888                                                                                    append,
889                                                                                    max_matches,
890                                                                                    variable_list);
891 
892         if (match_count > 0)
893         {
894             ExecutionContextScope *exe_scope = m_opaque_sp->GetProcessSP().get();
895             if (exe_scope == NULL)
896                 exe_scope = m_opaque_sp.get();
897             ValueObjectList &value_object_list = sb_value_list.ref();
898             for (uint32_t i=0; i<match_count; ++i)
899             {
900                 lldb::ValueObjectSP valobj_sp (ValueObjectVariable::Create (exe_scope, variable_list.GetVariableAtIndex(i)));
901                 if (valobj_sp)
902                     value_object_list.Append(valobj_sp);
903             }
904         }
905     }
906 
907     return sb_value_list;
908 }
909 
910