• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===-- SearchFilter.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 
15 #include "lldb/lldb-private.h"
16 #include "lldb/Core/SearchFilter.h"
17 #include "lldb/Core/Module.h"
18 #include "lldb/Symbol/CompileUnit.h"
19 #include "lldb/Target/Target.h"
20 
21 using namespace lldb;
22 using namespace lldb_private;
23 
24 //----------------------------------------------------------------------
25 // SearchFilter constructor
26 //----------------------------------------------------------------------
Searcher()27 Searcher::Searcher ()
28 {
29 
30 }
31 
~Searcher()32 Searcher::~Searcher ()
33 {
34 
35 }
36 
37 void
GetDescription(Stream * s)38 Searcher::GetDescription (Stream *s)
39 {
40 }
41 
42 //----------------------------------------------------------------------
43 // SearchFilter constructor
44 //----------------------------------------------------------------------
SearchFilter(const TargetSP & target_sp)45 SearchFilter::SearchFilter(const TargetSP &target_sp) :
46     m_target_sp (target_sp)
47 {
48 }
49 
50 //----------------------------------------------------------------------
51 // SearchFilter copy constructor
52 //----------------------------------------------------------------------
SearchFilter(const SearchFilter & rhs)53 SearchFilter::SearchFilter(const SearchFilter& rhs) :
54     m_target_sp (rhs.m_target_sp)
55 {
56 }
57 
58 //----------------------------------------------------------------------
59 // SearchFilter assignment operator
60 //----------------------------------------------------------------------
61 const SearchFilter&
operator =(const SearchFilter & rhs)62 SearchFilter::operator=(const SearchFilter& rhs)
63 {
64     m_target_sp = rhs.m_target_sp;
65     return *this;
66 }
67 
68 //----------------------------------------------------------------------
69 // Destructor
70 //----------------------------------------------------------------------
~SearchFilter()71 SearchFilter::~SearchFilter()
72 {
73 }
74 
75 bool
ModulePasses(const FileSpec & spec)76 SearchFilter::ModulePasses (const FileSpec &spec)
77 {
78     return true;
79 }
80 
81 bool
ModulePasses(const ModuleSP & module_sp)82 SearchFilter::ModulePasses (const ModuleSP &module_sp)
83 {
84     return true;
85 }
86 
87 bool
AddressPasses(Address & address)88 SearchFilter::AddressPasses (Address &address)
89 {
90     return true;
91 }
92 
93 bool
CompUnitPasses(FileSpec & fileSpec)94 SearchFilter::CompUnitPasses (FileSpec &fileSpec)
95 {
96     return true;
97 }
98 
99 bool
CompUnitPasses(CompileUnit & compUnit)100 SearchFilter::CompUnitPasses (CompileUnit &compUnit)
101 {
102     return true;
103 }
104 
105 uint32_t
GetFilterRequiredItems()106 SearchFilter::GetFilterRequiredItems()
107 {
108     return (lldb::SymbolContextItem) 0;
109 }
110 
111 void
GetDescription(Stream * s)112 SearchFilter::GetDescription (Stream *s)
113 {
114 }
115 
116 void
Dump(Stream * s) const117 SearchFilter::Dump (Stream *s) const
118 {
119 
120 }
121 
122 //----------------------------------------------------------------------
123 // UTILITY Functions to help iterate down through the elements of the
124 // SymbolContext.
125 //----------------------------------------------------------------------
126 
127 void
Search(Searcher & searcher)128 SearchFilter::Search (Searcher &searcher)
129 {
130     SymbolContext empty_sc;
131 
132     if (!m_target_sp)
133         return;
134     empty_sc.target_sp = m_target_sp;
135 
136     if (searcher.GetDepth() == Searcher::eDepthTarget)
137         searcher.SearchCallback (*this, empty_sc, NULL, false);
138     else
139         DoModuleIteration(empty_sc, searcher);
140 }
141 
142 void
SearchInModuleList(Searcher & searcher,ModuleList & modules)143 SearchFilter::SearchInModuleList (Searcher &searcher, ModuleList &modules)
144 {
145     SymbolContext empty_sc;
146 
147     if (!m_target_sp)
148         return;
149     empty_sc.target_sp = m_target_sp;
150 
151     if (searcher.GetDepth() == Searcher::eDepthTarget)
152         searcher.SearchCallback (*this, empty_sc, NULL, false);
153     else
154     {
155         Mutex::Locker modules_locker(modules.GetMutex());
156         const size_t numModules = modules.GetSize();
157 
158         for (size_t i = 0; i < numModules; i++)
159         {
160             ModuleSP module_sp(modules.GetModuleAtIndexUnlocked(i));
161             if (ModulePasses(module_sp))
162             {
163                 if (DoModuleIteration(module_sp, searcher) == Searcher::eCallbackReturnStop)
164                     return;
165             }
166         }
167     }
168 }
169 
170 
171 Searcher::CallbackReturn
DoModuleIteration(const lldb::ModuleSP & module_sp,Searcher & searcher)172 SearchFilter::DoModuleIteration (const lldb::ModuleSP& module_sp, Searcher &searcher)
173 {
174     SymbolContext matchingContext (m_target_sp, module_sp);
175     return DoModuleIteration(matchingContext, searcher);
176 }
177 
178 Searcher::CallbackReturn
DoModuleIteration(const SymbolContext & context,Searcher & searcher)179 SearchFilter::DoModuleIteration (const SymbolContext &context, Searcher &searcher)
180 {
181     if (searcher.GetDepth () >= Searcher::eDepthModule)
182     {
183         if (context.module_sp)
184         {
185             if (searcher.GetDepth () == Searcher::eDepthModule)
186             {
187                 SymbolContext matchingContext(context.module_sp.get());
188                 searcher.SearchCallback (*this, matchingContext, NULL, false);
189             }
190             else
191             {
192                 return DoCUIteration(context.module_sp, context, searcher);
193             }
194         }
195         else
196         {
197             const ModuleList &target_images = m_target_sp->GetImages();
198             Mutex::Locker modules_locker(target_images.GetMutex());
199 
200             size_t n_modules = target_images.GetSize();
201             for (size_t i = 0; i < n_modules; i++)
202             {
203                 // If this is the last level supplied, then call the callback directly,
204                 // otherwise descend.
205                 ModuleSP module_sp(target_images.GetModuleAtIndexUnlocked (i));
206                 if (!ModulePasses (module_sp))
207                     continue;
208 
209                 if (searcher.GetDepth () == Searcher::eDepthModule)
210                 {
211                     SymbolContext matchingContext(m_target_sp, module_sp);
212 
213                     Searcher::CallbackReturn shouldContinue = searcher.SearchCallback (*this, matchingContext, NULL, false);
214                     if (shouldContinue == Searcher::eCallbackReturnStop
215                         || shouldContinue == Searcher::eCallbackReturnPop)
216                         return shouldContinue;
217                 }
218                 else
219                 {
220                     Searcher::CallbackReturn shouldContinue = DoCUIteration(module_sp, context, searcher);
221                     if (shouldContinue == Searcher::eCallbackReturnStop)
222                         return shouldContinue;
223                     else if (shouldContinue == Searcher::eCallbackReturnPop)
224                         continue;
225                 }
226             }
227         }
228     }
229     return Searcher::eCallbackReturnContinue;
230 }
231 
232 Searcher::CallbackReturn
DoCUIteration(const ModuleSP & module_sp,const SymbolContext & context,Searcher & searcher)233 SearchFilter::DoCUIteration (const ModuleSP &module_sp, const SymbolContext &context, Searcher &searcher)
234 {
235     Searcher::CallbackReturn shouldContinue;
236     if (context.comp_unit == NULL)
237     {
238         const size_t num_comp_units = module_sp->GetNumCompileUnits();
239         for (size_t i = 0; i < num_comp_units; i++)
240         {
241             CompUnitSP cu_sp (module_sp->GetCompileUnitAtIndex (i));
242             if (cu_sp)
243             {
244                 if (!CompUnitPasses (*(cu_sp.get())))
245                     continue;
246 
247                 if (searcher.GetDepth () == Searcher::eDepthCompUnit)
248                 {
249                     SymbolContext matchingContext(m_target_sp, module_sp, cu_sp.get());
250 
251                     shouldContinue = searcher.SearchCallback (*this, matchingContext, NULL, false);
252 
253                     if (shouldContinue == Searcher::eCallbackReturnPop)
254                         return Searcher::eCallbackReturnContinue;
255                     else if (shouldContinue == Searcher::eCallbackReturnStop)
256                         return shouldContinue;
257                 }
258                 else
259                 {
260                     // FIXME Descend to block.
261                 }
262             }
263         }
264     }
265     else
266     {
267         if (CompUnitPasses(*context.comp_unit))
268         {
269             SymbolContext matchingContext (m_target_sp, module_sp, context.comp_unit);
270             return searcher.SearchCallback (*this, matchingContext, NULL, false);
271         }
272     }
273     return Searcher::eCallbackReturnContinue;
274 }
275 
276 Searcher::CallbackReturn
DoFunctionIteration(Function * function,const SymbolContext & context,Searcher & searcher)277 SearchFilter::DoFunctionIteration (Function *function, const SymbolContext &context, Searcher &searcher)
278 {
279     // FIXME: Implement...
280     return Searcher::eCallbackReturnContinue;
281 }
282 
283 //----------------------------------------------------------------------
284 //  SearchFilterForNonModuleSpecificSearches:
285 //  Selects a shared library matching a given file spec, consulting the targets "black list".
286 //----------------------------------------------------------------------
287 
288     bool
ModulePasses(const FileSpec & module_spec)289     SearchFilterForNonModuleSpecificSearches::ModulePasses (const FileSpec &module_spec)
290     {
291         if (m_target_sp->ModuleIsExcludedForNonModuleSpecificSearches (module_spec))
292             return false;
293         else
294             return true;
295     }
296 
297     bool
ModulePasses(const lldb::ModuleSP & module_sp)298     SearchFilterForNonModuleSpecificSearches::ModulePasses (const lldb::ModuleSP &module_sp)
299     {
300         if (!module_sp)
301             return true;
302         else if (m_target_sp->ModuleIsExcludedForNonModuleSpecificSearches (module_sp))
303             return false;
304         else
305             return true;
306     }
307 
308 //----------------------------------------------------------------------
309 //  SearchFilterByModule:
310 //  Selects a shared library matching a given file spec
311 //----------------------------------------------------------------------
312 
313 //----------------------------------------------------------------------
314 // SearchFilterByModule constructors
315 //----------------------------------------------------------------------
316 
SearchFilterByModule(const lldb::TargetSP & target_sp,const FileSpec & module)317 SearchFilterByModule::SearchFilterByModule (const lldb::TargetSP &target_sp, const FileSpec &module) :
318     SearchFilter (target_sp),
319     m_module_spec (module)
320 {
321 }
322 
323 
324 //----------------------------------------------------------------------
325 // SearchFilterByModule copy constructor
326 //----------------------------------------------------------------------
SearchFilterByModule(const SearchFilterByModule & rhs)327 SearchFilterByModule::SearchFilterByModule(const SearchFilterByModule& rhs) :
328     SearchFilter (rhs),
329     m_module_spec (rhs.m_module_spec)
330 {
331 }
332 
333 //----------------------------------------------------------------------
334 // SearchFilterByModule assignment operator
335 //----------------------------------------------------------------------
336 const SearchFilterByModule&
operator =(const SearchFilterByModule & rhs)337 SearchFilterByModule::operator=(const SearchFilterByModule& rhs)
338 {
339     m_target_sp = rhs.m_target_sp;
340     m_module_spec = rhs.m_module_spec;
341     return *this;
342 }
343 
344 //----------------------------------------------------------------------
345 // Destructor
346 //----------------------------------------------------------------------
~SearchFilterByModule()347 SearchFilterByModule::~SearchFilterByModule()
348 {
349 }
350 
351 bool
ModulePasses(const ModuleSP & module_sp)352 SearchFilterByModule::ModulePasses (const ModuleSP &module_sp)
353 {
354     if (module_sp && FileSpec::Equal(module_sp->GetFileSpec(), m_module_spec, false))
355         return true;
356     else
357         return false;
358 }
359 
360 bool
ModulePasses(const FileSpec & spec)361 SearchFilterByModule::ModulePasses (const FileSpec &spec)
362 {
363     // Do a full match only if "spec" has a directory
364     const bool full_match = spec.GetDirectory();
365     return FileSpec::Equal(spec, m_module_spec, full_match);
366 }
367 
368 bool
AddressPasses(Address & address)369 SearchFilterByModule::AddressPasses (Address &address)
370 {
371     // FIXME: Not yet implemented
372     return true;
373 }
374 
375 
376 bool
CompUnitPasses(FileSpec & fileSpec)377 SearchFilterByModule::CompUnitPasses (FileSpec &fileSpec)
378 {
379     return true;
380 }
381 
382 bool
CompUnitPasses(CompileUnit & compUnit)383 SearchFilterByModule::CompUnitPasses (CompileUnit &compUnit)
384 {
385     return true;
386 }
387 
388 void
Search(Searcher & searcher)389 SearchFilterByModule::Search (Searcher &searcher)
390 {
391     if (!m_target_sp)
392         return;
393 
394     if (searcher.GetDepth() == Searcher::eDepthTarget)
395     {
396         SymbolContext empty_sc;
397         empty_sc.target_sp = m_target_sp;
398         searcher.SearchCallback (*this, empty_sc, NULL, false);
399     }
400 
401     // If the module file spec is a full path, then we can just find the one
402     // filespec that passes.  Otherwise, we need to go through all modules and
403     // find the ones that match the file name.
404 
405     const ModuleList &target_modules = m_target_sp->GetImages();
406     Mutex::Locker modules_locker (target_modules.GetMutex());
407 
408     const size_t num_modules = target_modules.GetSize ();
409     for (size_t i = 0; i < num_modules; i++)
410     {
411         Module* module = target_modules.GetModulePointerAtIndexUnlocked(i);
412         const bool full_match = m_module_spec.GetDirectory();
413         if (FileSpec::Equal (m_module_spec, module->GetFileSpec(), full_match))
414         {
415             SymbolContext matchingContext(m_target_sp, module->shared_from_this());
416             Searcher::CallbackReturn shouldContinue;
417 
418             shouldContinue = DoModuleIteration(matchingContext, searcher);
419             if (shouldContinue == Searcher::eCallbackReturnStop)
420                 return;
421         }
422     }
423 }
424 
425 void
GetDescription(Stream * s)426 SearchFilterByModule::GetDescription (Stream *s)
427 {
428     s->PutCString(", module = ");
429     if (s->GetVerbose())
430     {
431         char buffer[2048];
432         m_module_spec.GetPath(buffer, 2047);
433         s->PutCString(buffer);
434     }
435     else
436     {
437         s->PutCString(m_module_spec.GetFilename().AsCString("<unknown>"));
438     }
439 }
440 
441 uint32_t
GetFilterRequiredItems()442 SearchFilterByModule::GetFilterRequiredItems()
443 {
444     return eSymbolContextModule;
445 }
446 
447 void
Dump(Stream * s) const448 SearchFilterByModule::Dump (Stream *s) const
449 {
450 
451 }
452 //----------------------------------------------------------------------
453 //  SearchFilterByModuleList:
454 //  Selects a shared library matching a given file spec
455 //----------------------------------------------------------------------
456 
457 //----------------------------------------------------------------------
458 // SearchFilterByModuleList constructors
459 //----------------------------------------------------------------------
460 
SearchFilterByModuleList(const lldb::TargetSP & target_sp,const FileSpecList & module_list)461 SearchFilterByModuleList::SearchFilterByModuleList (const lldb::TargetSP &target_sp, const FileSpecList &module_list) :
462     SearchFilter (target_sp),
463     m_module_spec_list (module_list)
464 {
465 }
466 
467 
468 //----------------------------------------------------------------------
469 // SearchFilterByModuleList copy constructor
470 //----------------------------------------------------------------------
SearchFilterByModuleList(const SearchFilterByModuleList & rhs)471 SearchFilterByModuleList::SearchFilterByModuleList(const SearchFilterByModuleList& rhs) :
472     SearchFilter (rhs),
473     m_module_spec_list (rhs.m_module_spec_list)
474 {
475 }
476 
477 //----------------------------------------------------------------------
478 // SearchFilterByModuleList assignment operator
479 //----------------------------------------------------------------------
480 const SearchFilterByModuleList&
operator =(const SearchFilterByModuleList & rhs)481 SearchFilterByModuleList::operator=(const SearchFilterByModuleList& rhs)
482 {
483     m_target_sp = rhs.m_target_sp;
484     m_module_spec_list = rhs.m_module_spec_list;
485     return *this;
486 }
487 
488 //----------------------------------------------------------------------
489 // Destructor
490 //----------------------------------------------------------------------
~SearchFilterByModuleList()491 SearchFilterByModuleList::~SearchFilterByModuleList()
492 {
493 }
494 
495 bool
ModulePasses(const ModuleSP & module_sp)496 SearchFilterByModuleList::ModulePasses (const ModuleSP &module_sp)
497 {
498     if (m_module_spec_list.GetSize() == 0)
499         return true;
500 
501     if (module_sp && m_module_spec_list.FindFileIndex(0, module_sp->GetFileSpec(), false) != UINT32_MAX)
502         return true;
503     else
504         return false;
505 }
506 
507 bool
ModulePasses(const FileSpec & spec)508 SearchFilterByModuleList::ModulePasses (const FileSpec &spec)
509 {
510     if (m_module_spec_list.GetSize() == 0)
511         return true;
512 
513     if (m_module_spec_list.FindFileIndex(0, spec, true) != UINT32_MAX)
514         return true;
515     else
516         return false;
517 }
518 
519 bool
AddressPasses(Address & address)520 SearchFilterByModuleList::AddressPasses (Address &address)
521 {
522     // FIXME: Not yet implemented
523     return true;
524 }
525 
526 
527 bool
CompUnitPasses(FileSpec & fileSpec)528 SearchFilterByModuleList::CompUnitPasses (FileSpec &fileSpec)
529 {
530     return true;
531 }
532 
533 bool
CompUnitPasses(CompileUnit & compUnit)534 SearchFilterByModuleList::CompUnitPasses (CompileUnit &compUnit)
535 {
536     return true;
537 }
538 
539 void
Search(Searcher & searcher)540 SearchFilterByModuleList::Search (Searcher &searcher)
541 {
542     if (!m_target_sp)
543         return;
544 
545     if (searcher.GetDepth() == Searcher::eDepthTarget)
546     {
547         SymbolContext empty_sc;
548         empty_sc.target_sp = m_target_sp;
549         searcher.SearchCallback (*this, empty_sc, NULL, false);
550     }
551 
552     // If the module file spec is a full path, then we can just find the one
553     // filespec that passes.  Otherwise, we need to go through all modules and
554     // find the ones that match the file name.
555 
556     const ModuleList &target_modules = m_target_sp->GetImages();
557     Mutex::Locker modules_locker (target_modules.GetMutex());
558 
559     const size_t num_modules = target_modules.GetSize ();
560     for (size_t i = 0; i < num_modules; i++)
561     {
562         Module* module = target_modules.GetModulePointerAtIndexUnlocked(i);
563         if (m_module_spec_list.FindFileIndex(0, module->GetFileSpec(), false) != UINT32_MAX)
564         {
565             SymbolContext matchingContext(m_target_sp, module->shared_from_this());
566             Searcher::CallbackReturn shouldContinue;
567 
568             shouldContinue = DoModuleIteration(matchingContext, searcher);
569             if (shouldContinue == Searcher::eCallbackReturnStop)
570                 return;
571         }
572     }
573 }
574 
575 void
GetDescription(Stream * s)576 SearchFilterByModuleList::GetDescription (Stream *s)
577 {
578     size_t num_modules = m_module_spec_list.GetSize();
579     if (num_modules == 1)
580     {
581         s->Printf (", module = ");
582         if (s->GetVerbose())
583         {
584             char buffer[2048];
585             m_module_spec_list.GetFileSpecAtIndex(0).GetPath(buffer, 2047);
586             s->PutCString(buffer);
587         }
588         else
589         {
590             s->PutCString(m_module_spec_list.GetFileSpecAtIndex(0).GetFilename().AsCString("<unknown>"));
591         }
592     }
593     else
594     {
595         s->Printf (", modules(%zu) = ", num_modules);
596         for (size_t i = 0; i < num_modules; i++)
597         {
598             if (s->GetVerbose())
599             {
600                 char buffer[2048];
601                 m_module_spec_list.GetFileSpecAtIndex(i).GetPath(buffer, 2047);
602                 s->PutCString(buffer);
603             }
604             else
605             {
606                 s->PutCString(m_module_spec_list.GetFileSpecAtIndex(i).GetFilename().AsCString("<unknown>"));
607             }
608             if (i != num_modules - 1)
609                 s->PutCString (", ");
610         }
611     }
612 }
613 
614 uint32_t
GetFilterRequiredItems()615 SearchFilterByModuleList::GetFilterRequiredItems()
616 {
617     return eSymbolContextModule;
618 }
619 
620 void
Dump(Stream * s) const621 SearchFilterByModuleList::Dump (Stream *s) const
622 {
623 
624 }
625 
626 //----------------------------------------------------------------------
627 //  SearchFilterByModuleListAndCU:
628 //  Selects a shared library matching a given file spec
629 //----------------------------------------------------------------------
630 
631 //----------------------------------------------------------------------
632 // SearchFilterByModuleListAndCU constructors
633 //----------------------------------------------------------------------
634 
SearchFilterByModuleListAndCU(const lldb::TargetSP & target_sp,const FileSpecList & module_list,const FileSpecList & cu_list)635 SearchFilterByModuleListAndCU::SearchFilterByModuleListAndCU (const lldb::TargetSP &target_sp,
636                                                               const FileSpecList &module_list,
637                                                               const FileSpecList &cu_list) :
638     SearchFilterByModuleList (target_sp, module_list),
639     m_cu_spec_list (cu_list)
640 {
641 }
642 
643 
644 //----------------------------------------------------------------------
645 // SearchFilterByModuleListAndCU copy constructor
646 //----------------------------------------------------------------------
SearchFilterByModuleListAndCU(const SearchFilterByModuleListAndCU & rhs)647 SearchFilterByModuleListAndCU::SearchFilterByModuleListAndCU(const SearchFilterByModuleListAndCU& rhs) :
648     SearchFilterByModuleList (rhs),
649     m_cu_spec_list (rhs.m_cu_spec_list)
650 {
651 }
652 
653 //----------------------------------------------------------------------
654 // SearchFilterByModuleListAndCU assignment operator
655 //----------------------------------------------------------------------
656 const SearchFilterByModuleListAndCU&
operator =(const SearchFilterByModuleListAndCU & rhs)657 SearchFilterByModuleListAndCU::operator=(const SearchFilterByModuleListAndCU& rhs)
658 {
659     if (&rhs != this)
660     {
661         m_target_sp = rhs.m_target_sp;
662         m_module_spec_list = rhs.m_module_spec_list;
663         m_cu_spec_list = rhs.m_cu_spec_list;
664     }
665     return *this;
666 }
667 
668 //----------------------------------------------------------------------
669 // Destructor
670 //----------------------------------------------------------------------
~SearchFilterByModuleListAndCU()671 SearchFilterByModuleListAndCU::~SearchFilterByModuleListAndCU()
672 {
673 }
674 
675 bool
AddressPasses(Address & address)676 SearchFilterByModuleListAndCU::AddressPasses (Address &address)
677 {
678     return true;
679 }
680 
681 
682 bool
CompUnitPasses(FileSpec & fileSpec)683 SearchFilterByModuleListAndCU::CompUnitPasses (FileSpec &fileSpec)
684 {
685     return m_cu_spec_list.FindFileIndex(0, fileSpec, false) != UINT32_MAX;
686 }
687 
688 bool
CompUnitPasses(CompileUnit & compUnit)689 SearchFilterByModuleListAndCU::CompUnitPasses (CompileUnit &compUnit)
690 {
691     bool in_cu_list = m_cu_spec_list.FindFileIndex(0, compUnit, false) != UINT32_MAX;
692     if (in_cu_list)
693     {
694         ModuleSP module_sp(compUnit.GetModule());
695         if (module_sp)
696         {
697             bool module_passes = SearchFilterByModuleList::ModulePasses(module_sp);
698             return module_passes;
699         }
700         else
701             return true;
702     }
703     else
704         return false;
705 }
706 
707 void
Search(Searcher & searcher)708 SearchFilterByModuleListAndCU::Search (Searcher &searcher)
709 {
710     if (!m_target_sp)
711         return;
712 
713     if (searcher.GetDepth() == Searcher::eDepthTarget)
714     {
715         SymbolContext empty_sc;
716         empty_sc.target_sp = m_target_sp;
717         searcher.SearchCallback (*this, empty_sc, NULL, false);
718     }
719 
720     // If the module file spec is a full path, then we can just find the one
721     // filespec that passes.  Otherwise, we need to go through all modules and
722     // find the ones that match the file name.
723 
724     ModuleList matching_modules;
725     const ModuleList &target_images = m_target_sp->GetImages();
726     Mutex::Locker modules_locker(target_images.GetMutex());
727 
728     const size_t num_modules = target_images.GetSize ();
729     bool no_modules_in_filter = m_module_spec_list.GetSize() == 0;
730     for (size_t i = 0; i < num_modules; i++)
731     {
732         lldb::ModuleSP module_sp = target_images.GetModuleAtIndexUnlocked(i);
733         if (no_modules_in_filter || m_module_spec_list.FindFileIndex(0, module_sp->GetFileSpec(), false) != UINT32_MAX)
734         {
735             SymbolContext matchingContext(m_target_sp, module_sp);
736             Searcher::CallbackReturn shouldContinue;
737 
738             if (searcher.GetDepth() == Searcher::eDepthModule)
739             {
740                 shouldContinue = DoModuleIteration(matchingContext, searcher);
741                 if (shouldContinue == Searcher::eCallbackReturnStop)
742                     return;
743             }
744             else
745             {
746                 const size_t num_cu = module_sp->GetNumCompileUnits();
747                 for (size_t cu_idx = 0; cu_idx < num_cu; cu_idx++)
748                 {
749                     CompUnitSP cu_sp = module_sp->GetCompileUnitAtIndex(cu_idx);
750                     matchingContext.comp_unit = cu_sp.get();
751                     if (matchingContext.comp_unit)
752                     {
753                         if (m_cu_spec_list.FindFileIndex(0, *matchingContext.comp_unit, false) != UINT32_MAX)
754                         {
755                             shouldContinue = DoCUIteration(module_sp, matchingContext, searcher);
756                             if (shouldContinue == Searcher::eCallbackReturnStop)
757                                 return;
758                         }
759                     }
760                 }
761             }
762         }
763     }
764 }
765 
766 void
GetDescription(Stream * s)767 SearchFilterByModuleListAndCU::GetDescription (Stream *s)
768 {
769     size_t num_modules = m_module_spec_list.GetSize();
770     if (num_modules == 1)
771     {
772         s->Printf (", module = ");
773         if (s->GetVerbose())
774         {
775             char buffer[2048];
776             m_module_spec_list.GetFileSpecAtIndex(0).GetPath(buffer, 2047);
777             s->PutCString(buffer);
778         }
779         else
780         {
781             s->PutCString(m_module_spec_list.GetFileSpecAtIndex(0).GetFilename().AsCString("<unknown>"));
782         }
783     }
784     else if (num_modules > 0)
785     {
786         s->Printf (", modules(%zd) = ", num_modules);
787         for (size_t i = 0; i < num_modules; i++)
788         {
789             if (s->GetVerbose())
790             {
791                 char buffer[2048];
792                 m_module_spec_list.GetFileSpecAtIndex(i).GetPath(buffer, 2047);
793                 s->PutCString(buffer);
794             }
795             else
796             {
797                 s->PutCString(m_module_spec_list.GetFileSpecAtIndex(i).GetFilename().AsCString("<unknown>"));
798             }
799             if (i != num_modules - 1)
800                 s->PutCString (", ");
801         }
802     }
803 }
804 
805 uint32_t
GetFilterRequiredItems()806 SearchFilterByModuleListAndCU::GetFilterRequiredItems()
807 {
808     return eSymbolContextModule | eSymbolContextCompUnit;
809 }
810 
811 void
Dump(Stream * s) const812 SearchFilterByModuleListAndCU::Dump (Stream *s) const
813 {
814 
815 }
816 
817