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