LLDB  mainline
SearchFilter.cpp
Go to the documentation of this file.
1 //===-- SearchFilter.cpp ----------------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
10 
12 #include "lldb/Core/Module.h"
13 #include "lldb/Core/ModuleList.h"
17 #include "lldb/Target/Target.h"
19 #include "lldb/Utility/Status.h"
20 #include "lldb/Utility/Stream.h"
21 #include "lldb/lldb-enumerations.h"
22 
23 #include "llvm/ADT/StringRef.h"
24 #include "llvm/Support/ErrorHandling.h"
25 
26 #include <memory>
27 #include <mutex>
28 #include <string>
29 
30 #include <inttypes.h>
31 #include <string.h>
32 
33 namespace lldb_private {
34 class Address;
35 }
36 namespace lldb_private {
37 class Function;
38 }
39 
40 using namespace lldb;
41 using namespace lldb_private;
42 
43 const char *SearchFilter::g_ty_to_name[] = {"Unconstrained", "Exception",
44  "Module", "Modules",
45  "ModulesAndCU", "Unknown"};
46 
47 const char
48  *SearchFilter::g_option_names[SearchFilter::OptionNames::LastOptionName] = {
49  "ModuleList", "CUList"};
50 
51 const char *SearchFilter::FilterTyToName(enum FilterTy type) {
52  if (type > LastKnownFilterType)
53  return g_ty_to_name[UnknownFilter];
54 
55  return g_ty_to_name[type];
56 }
57 
59  for (size_t i = 0; i <= LastKnownFilterType; i++) {
60  if (name == g_ty_to_name[i])
61  return (FilterTy)i;
62  }
63  return UnknownFilter;
64 }
65 
66 Searcher::Searcher() = default;
67 
68 Searcher::~Searcher() = default;
69 
71 
72 SearchFilter::SearchFilter(const TargetSP &target_sp, unsigned char filterType)
73  : m_target_sp(target_sp), SubclassID(filterType) {}
74 
75 SearchFilter::SearchFilter(const SearchFilter &rhs) = default;
76 
78 
79 SearchFilter::~SearchFilter() = default;
80 
82  Target &target, const StructuredData::Dictionary &filter_dict,
83  Status &error) {
84  SearchFilterSP result_sp;
85  if (!filter_dict.IsValid()) {
86  error.SetErrorString("Can't deserialize from an invalid data object.");
87  return result_sp;
88  }
89 
90  llvm::StringRef subclass_name;
91 
92  bool success = filter_dict.GetValueForKeyAsString(
93  GetSerializationSubclassKey(), subclass_name);
94  if (!success) {
95  error.SetErrorStringWithFormat("Filter data missing subclass key");
96  return result_sp;
97  }
98 
99  FilterTy filter_type = NameToFilterTy(subclass_name);
100  if (filter_type == UnknownFilter) {
101  error.SetErrorStringWithFormatv("Unknown filter type: {0}.", subclass_name);
102  return result_sp;
103  }
104 
105  StructuredData::Dictionary *subclass_options = nullptr;
106  success = filter_dict.GetValueForKeyAsDictionary(
107  GetSerializationSubclassOptionsKey(), subclass_options);
108  if (!success || !subclass_options || !subclass_options->IsValid()) {
109  error.SetErrorString("Filter data missing subclass options key.");
110  return result_sp;
111  }
112 
113  switch (filter_type) {
114  case Unconstrained:
116  target, *subclass_options, error);
117  break;
118  case ByModule:
120  target, *subclass_options, error);
121  break;
122  case ByModules:
124  target, *subclass_options, error);
125  break;
126  case ByModulesAndCU:
128  target, *subclass_options, error);
129  break;
130  case Exception:
131  error.SetErrorString("Can't serialize exception breakpoints yet.");
132  break;
133  default:
134  llvm_unreachable("Should never get an uresolvable filter type.");
135  }
136 
137  return result_sp;
138 }
139 
140 bool SearchFilter::ModulePasses(const FileSpec &spec) { return true; }
141 
142 bool SearchFilter::ModulePasses(const ModuleSP &module_sp) { return true; }
143 
144 bool SearchFilter::AddressPasses(Address &address) { return true; }
145 
146 bool SearchFilter::CompUnitPasses(FileSpec &fileSpec) { return true; }
147 
148 bool SearchFilter::CompUnitPasses(CompileUnit &compUnit) { return true; }
149 
151  // This is a slightly cheesy job, but since we don't have finer grained
152  // filters yet, just checking that the start address passes is probably
153  // good enough for the base class behavior.
154  Address addr = function.GetAddressRange().GetBaseAddress();
155  return AddressPasses(addr);
156 }
157 
158 
160  return (lldb::SymbolContextItem)0;
161 }
162 
164 
165 void SearchFilter::Dump(Stream *s) const {}
166 
167 lldb::SearchFilterSP SearchFilter::CopyForBreakpoint(Breakpoint &breakpoint) {
168  SearchFilterSP ret_sp = DoCopyForBreakpoint(breakpoint);
169  TargetSP target_sp = breakpoint.GetTargetSP();
170  ret_sp->SetTarget(target_sp);
171  return ret_sp;
172 }
173 
174 // Helper functions for serialization.
175 
178  if (!options_dict_sp || !options_dict_sp->IsValid())
180 
181  auto type_dict_sp = std::make_shared<StructuredData::Dictionary>();
182  type_dict_sp->AddStringItem(GetSerializationSubclassKey(), GetFilterName());
183  type_dict_sp->AddItem(GetSerializationSubclassOptionsKey(), options_dict_sp);
184 
185  return type_dict_sp;
186 }
187 
189  StructuredData::DictionarySP &options_dict_sp, OptionNames name,
190  FileSpecList &file_list) {
191  size_t num_modules = file_list.GetSize();
192 
193  // Don't serialize empty lists.
194  if (num_modules == 0)
195  return;
196 
197  auto module_array_sp = std::make_shared<StructuredData::Array>();
198  for (size_t i = 0; i < num_modules; i++) {
199  module_array_sp->AddItem(std::make_shared<StructuredData::String>(
200  file_list.GetFileSpecAtIndex(i).GetPath()));
201  }
202  options_dict_sp->AddItem(GetKey(name), module_array_sp);
203 }
204 
205 // UTILITY Functions to help iterate down through the elements of the
206 // SymbolContext.
207 
209  SymbolContext empty_sc;
210 
211  if (!m_target_sp)
212  return;
213  empty_sc.target_sp = m_target_sp;
214 
215  if (searcher.GetDepth() == lldb::eSearchDepthTarget)
216  searcher.SearchCallback(*this, empty_sc, nullptr, false);
217  else
218  DoModuleIteration(empty_sc, searcher);
219 }
220 
222  SymbolContext empty_sc;
223 
224  if (!m_target_sp)
225  return;
226  empty_sc.target_sp = m_target_sp;
227 
228  if (searcher.GetDepth() == lldb::eSearchDepthTarget)
229  searcher.SearchCallback(*this, empty_sc, nullptr, false);
230  else {
231  std::lock_guard<std::recursive_mutex> guard(modules.GetMutex());
232  const size_t numModules = modules.GetSize();
233 
234  for (size_t i = 0; i < numModules; i++) {
235  ModuleSP module_sp(modules.GetModuleAtIndexUnlocked(i));
236  if (ModulePasses(module_sp)) {
237  if (DoModuleIteration(module_sp, searcher) ==
239  return;
240  }
241  }
242  }
243 }
244 
246 SearchFilter::DoModuleIteration(const lldb::ModuleSP &module_sp,
247  Searcher &searcher) {
248  SymbolContext matchingContext(m_target_sp, module_sp);
249  return DoModuleIteration(matchingContext, searcher);
250 }
251 
254  Searcher &searcher) {
255  if (searcher.GetDepth() >= lldb::eSearchDepthModule) {
256  if (context.module_sp) {
257  if (searcher.GetDepth() == lldb::eSearchDepthModule) {
258  SymbolContext matchingContext(context.module_sp.get());
259  searcher.SearchCallback(*this, matchingContext, nullptr, false);
260  } else {
261  return DoCUIteration(context.module_sp, context, searcher);
262  }
263  } else {
264  const ModuleList &target_images = m_target_sp->GetImages();
265  std::lock_guard<std::recursive_mutex> guard(target_images.GetMutex());
266 
267  size_t n_modules = target_images.GetSize();
268  for (size_t i = 0; i < n_modules; i++) {
269  // If this is the last level supplied, then call the callback directly,
270  // otherwise descend.
271  ModuleSP module_sp(target_images.GetModuleAtIndexUnlocked(i));
272  if (!ModulePasses(module_sp))
273  continue;
274 
275  if (searcher.GetDepth() == lldb::eSearchDepthModule) {
276  SymbolContext matchingContext(m_target_sp, module_sp);
277 
278  Searcher::CallbackReturn shouldContinue =
279  searcher.SearchCallback(*this, matchingContext, nullptr, false);
280  if (shouldContinue == Searcher::eCallbackReturnStop ||
281  shouldContinue == Searcher::eCallbackReturnPop)
282  return shouldContinue;
283  } else {
284  Searcher::CallbackReturn shouldContinue =
285  DoCUIteration(module_sp, context, searcher);
286  if (shouldContinue == Searcher::eCallbackReturnStop)
287  return shouldContinue;
288  else if (shouldContinue == Searcher::eCallbackReturnPop)
289  continue;
290  }
291  }
292  }
293  }
295 }
296 
298 SearchFilter::DoCUIteration(const ModuleSP &module_sp,
299  const SymbolContext &context, Searcher &searcher) {
300  Searcher::CallbackReturn shouldContinue;
301  if (context.comp_unit == nullptr) {
302  const size_t num_comp_units = module_sp->GetNumCompileUnits();
303  for (size_t i = 0; i < num_comp_units; i++) {
304  CompUnitSP cu_sp(module_sp->GetCompileUnitAtIndex(i));
305  if (cu_sp) {
306  if (!CompUnitPasses(*(cu_sp.get())))
307  continue;
308 
309  if (searcher.GetDepth() == lldb::eSearchDepthCompUnit) {
310  SymbolContext matchingContext(m_target_sp, module_sp, cu_sp.get());
311 
312  shouldContinue =
313  searcher.SearchCallback(*this, matchingContext, nullptr, false);
314 
315  if (shouldContinue == Searcher::eCallbackReturnPop)
317  else if (shouldContinue == Searcher::eCallbackReturnStop)
318  return shouldContinue;
319  } else {
320  // First make sure this compile unit's functions are parsed
321  // since CompUnit::ForeachFunction only iterates over already
322  // parsed functions.
323  SymbolVendor *sym_vendor = module_sp->GetSymbolVendor();
324  if (!sym_vendor)
325  continue;
326  if (!sym_vendor->ParseFunctions(*cu_sp))
327  continue;
328  // If we got any functions, use ForeachFunction to do the iteration.
329  cu_sp->ForeachFunction([&](const FunctionSP &func_sp) {
330  if (!FunctionPasses(*func_sp.get()))
331  return false; // Didn't pass the filter, just keep going.
332  if (searcher.GetDepth() == lldb::eSearchDepthFunction) {
333  SymbolContext matchingContext(m_target_sp, module_sp,
334  cu_sp.get(), func_sp.get());
335  shouldContinue = searcher.SearchCallback(*this,
336  matchingContext,
337  nullptr, false);
338  } else {
339  shouldContinue = DoFunctionIteration(func_sp.get(), context,
340  searcher);
341  }
342  return shouldContinue != Searcher::eCallbackReturnContinue;
343  });
344  }
345  }
346  }
347  } else {
348  if (CompUnitPasses(*context.comp_unit)) {
349  SymbolContext matchingContext(m_target_sp, module_sp, context.comp_unit);
350  return searcher.SearchCallback(*this, matchingContext, nullptr, false);
351  }
352  }
354 }
355 
357  Function *function, const SymbolContext &context, Searcher &searcher) {
358  // FIXME: Implement...
360 }
361 
362 // SearchFilterForUnconstrainedSearches:
363 // Selects a shared library matching a given file spec, consulting the targets
364 // "black list".
366  Target &target, const StructuredData::Dictionary &data_dict,
367  Status &error) {
368  // No options for an unconstrained search.
369  return std::make_shared<SearchFilterForUnconstrainedSearches>(
370  target.shared_from_this());
371 }
372 
375  // The options dictionary is an empty dictionary:
376  auto result_sp = std::make_shared<StructuredData::Dictionary>();
377  return WrapOptionsDict(result_sp);
378 }
379 
381  const FileSpec &module_spec) {
382  return !m_target_sp->ModuleIsExcludedForUnconstrainedSearches(module_spec);
383 }
384 
386  const lldb::ModuleSP &module_sp) {
387  if (!module_sp)
388  return true;
389  else if (m_target_sp->ModuleIsExcludedForUnconstrainedSearches(module_sp))
390  return false;
391  else
392  return true;
393 }
394 
396  Breakpoint &breakpoint) {
397  return std::make_shared<SearchFilterForUnconstrainedSearches>(*this);
398 }
399 
400 // SearchFilterByModule:
401 // Selects a shared library matching a given file spec
402 
403 SearchFilterByModule::SearchFilterByModule(const lldb::TargetSP &target_sp,
404  const FileSpec &module)
405  : SearchFilter(target_sp, FilterTy::ByModule), m_module_spec(module) {}
406 
408  default;
409 
412  m_target_sp = rhs.m_target_sp;
413  m_module_spec = rhs.m_module_spec;
414  return *this;
415 }
416 
418 
419 bool SearchFilterByModule::ModulePasses(const ModuleSP &module_sp) {
420  return (module_sp &&
421  FileSpec::Equal(module_sp->GetFileSpec(), m_module_spec, false));
422 }
423 
425  // Do a full match only if "spec" has a directory
426  const bool full_match = (bool)spec.GetDirectory();
427  return FileSpec::Equal(spec, m_module_spec, full_match);
428 }
429 
431  // FIXME: Not yet implemented
432  return true;
433 }
434 
435 bool SearchFilterByModule::CompUnitPasses(FileSpec &fileSpec) { return true; }
436 
438  return true;
439 }
440 
442  if (!m_target_sp)
443  return;
444 
445  if (searcher.GetDepth() == lldb::eSearchDepthTarget) {
446  SymbolContext empty_sc;
447  empty_sc.target_sp = m_target_sp;
448  searcher.SearchCallback(*this, empty_sc, nullptr, false);
449  }
450 
451  // If the module file spec is a full path, then we can just find the one
452  // filespec that passes. Otherwise, we need to go through all modules and
453  // find the ones that match the file name.
454 
455  const ModuleList &target_modules = m_target_sp->GetImages();
456  std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
457 
458  const size_t num_modules = target_modules.GetSize();
459  for (size_t i = 0; i < num_modules; i++) {
460  Module *module = target_modules.GetModulePointerAtIndexUnlocked(i);
461  const bool full_match = (bool)m_module_spec.GetDirectory();
462  if (FileSpec::Equal(m_module_spec, module->GetFileSpec(), full_match)) {
463  SymbolContext matchingContext(m_target_sp, module->shared_from_this());
464  Searcher::CallbackReturn shouldContinue;
465 
466  shouldContinue = DoModuleIteration(matchingContext, searcher);
467  if (shouldContinue == Searcher::eCallbackReturnStop)
468  return;
469  }
470  }
471 }
472 
474  s->PutCString(", module = ");
475  s->PutCString(m_module_spec.GetFilename().AsCString("<Unknown>"));
476 }
477 
479  return eSymbolContextModule;
480 }
481 
483 
484 lldb::SearchFilterSP
486  return std::make_shared<SearchFilterByModule>(*this);
487 }
488 
490  Target &target, const StructuredData::Dictionary &data_dict,
491  Status &error) {
492  StructuredData::Array *modules_array;
493  bool success = data_dict.GetValueForKeyAsArray(GetKey(OptionNames::ModList),
494  modules_array);
495  if (!success) {
496  error.SetErrorString("SFBM::CFSD: Could not find the module list key.");
497  return nullptr;
498  }
499 
500  size_t num_modules = modules_array->GetSize();
501  if (num_modules > 1) {
502  error.SetErrorString(
503  "SFBM::CFSD: Only one modules allowed for SearchFilterByModule.");
504  return nullptr;
505  }
506 
507  llvm::StringRef module;
508  success = modules_array->GetItemAtIndexAsString(0, module);
509  if (!success) {
510  error.SetErrorString("SFBM::CFSD: filter module item not a string.");
511  return nullptr;
512  }
513  FileSpec module_spec(module);
514 
515  return std::make_shared<SearchFilterByModule>(target.shared_from_this(),
516  module_spec);
517 }
518 
520  auto options_dict_sp = std::make_shared<StructuredData::Dictionary>();
521  auto module_array_sp = std::make_shared<StructuredData::Array>();
522  module_array_sp->AddItem(
523  std::make_shared<StructuredData::String>(m_module_spec.GetPath()));
524  options_dict_sp->AddItem(GetKey(OptionNames::ModList), module_array_sp);
525  return WrapOptionsDict(options_dict_sp);
526 }
527 
528 // SearchFilterByModuleList:
529 // Selects a shared library matching a given file spec
530 
532  const lldb::TargetSP &target_sp, const FileSpecList &module_list)
533  : SearchFilter(target_sp, FilterTy::ByModules),
534  m_module_spec_list(module_list) {}
535 
537  const lldb::TargetSP &target_sp, const FileSpecList &module_list,
538  enum FilterTy filter_ty)
539  : SearchFilter(target_sp, filter_ty), m_module_spec_list(module_list) {}
540 
542  const SearchFilterByModuleList &rhs) = default;
543 
546  m_target_sp = rhs.m_target_sp;
548  return *this;
549 }
550 
552 
553 bool SearchFilterByModuleList::ModulePasses(const ModuleSP &module_sp) {
554  if (m_module_spec_list.GetSize() == 0)
555  return true;
556 
557  return module_sp && m_module_spec_list.FindFileIndex(
558  0, module_sp->GetFileSpec(), false) != UINT32_MAX;
559 }
560 
562  if (m_module_spec_list.GetSize() == 0)
563  return true;
564 
565  return m_module_spec_list.FindFileIndex(0, spec, true) != UINT32_MAX;
566 }
567 
569  // FIXME: Not yet implemented
570  return true;
571 }
572 
574  return true;
575 }
576 
578  return true;
579 }
580 
582  if (!m_target_sp)
583  return;
584 
585  if (searcher.GetDepth() == lldb::eSearchDepthTarget) {
586  SymbolContext empty_sc;
587  empty_sc.target_sp = m_target_sp;
588  searcher.SearchCallback(*this, empty_sc, nullptr, false);
589  }
590 
591  // If the module file spec is a full path, then we can just find the one
592  // filespec that passes. Otherwise, we need to go through all modules and
593  // find the ones that match the file name.
594 
595  const ModuleList &target_modules = m_target_sp->GetImages();
596  std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
597 
598  const size_t num_modules = target_modules.GetSize();
599  for (size_t i = 0; i < num_modules; i++) {
600  Module *module = target_modules.GetModulePointerAtIndexUnlocked(i);
601  if (m_module_spec_list.FindFileIndex(0, module->GetFileSpec(), false) !=
602  UINT32_MAX) {
603  SymbolContext matchingContext(m_target_sp, module->shared_from_this());
604  Searcher::CallbackReturn shouldContinue;
605 
606  shouldContinue = DoModuleIteration(matchingContext, searcher);
607  if (shouldContinue == Searcher::eCallbackReturnStop)
608  return;
609  }
610  }
611 }
612 
614  size_t num_modules = m_module_spec_list.GetSize();
615  if (num_modules == 1) {
616  s->Printf(", module = ");
617  s->PutCString(
618  m_module_spec_list.GetFileSpecAtIndex(0).GetFilename().AsCString(
619  "<Unknown>"));
620  } else {
621  s->Printf(", modules(%" PRIu64 ") = ", (uint64_t)num_modules);
622  for (size_t i = 0; i < num_modules; i++) {
623  s->PutCString(
624  m_module_spec_list.GetFileSpecAtIndex(i).GetFilename().AsCString(
625  "<Unknown>"));
626  if (i != num_modules - 1)
627  s->PutCString(", ");
628  }
629  }
630 }
631 
633  return eSymbolContextModule;
634 }
635 
637 
638 lldb::SearchFilterSP
640  return std::make_shared<SearchFilterByModuleList>(*this);
641 }
642 
644  Target &target, const StructuredData::Dictionary &data_dict,
645  Status &error) {
646  StructuredData::Array *modules_array;
647  bool success = data_dict.GetValueForKeyAsArray(GetKey(OptionNames::ModList),
648  modules_array);
649  FileSpecList modules;
650  if (success) {
651  size_t num_modules = modules_array->GetSize();
652  for (size_t i = 0; i < num_modules; i++) {
653  llvm::StringRef module;
654  success = modules_array->GetItemAtIndexAsString(i, module);
655  if (!success) {
657  "SFBM::CFSD: filter module item %zu not a string.", i);
658  return nullptr;
659  }
660  modules.Append(FileSpec(module));
661  }
662  }
663 
664  return std::make_shared<SearchFilterByModuleList>(target.shared_from_this(),
665  modules);
666 }
667 
669  StructuredData::DictionarySP &options_dict_sp) {
670  SerializeFileSpecList(options_dict_sp, OptionNames::ModList,
672 }
673 
675  auto options_dict_sp = std::make_shared<StructuredData::Dictionary>();
676  SerializeUnwrapped(options_dict_sp);
677  return WrapOptionsDict(options_dict_sp);
678 }
679 
680 // SearchFilterByModuleListAndCU:
681 // Selects a shared library matching a given file spec
682 
684  const lldb::TargetSP &target_sp, const FileSpecList &module_list,
685  const FileSpecList &cu_list)
686  : SearchFilterByModuleList(target_sp, module_list,
688  m_cu_spec_list(cu_list) {}
689 
691  const SearchFilterByModuleListAndCU &rhs) = default;
692 
695  if (&rhs != this) {
696  m_target_sp = rhs.m_target_sp;
698  m_cu_spec_list = rhs.m_cu_spec_list;
699  }
700  return *this;
701 }
702 
704 
706  Target &target, const StructuredData::Dictionary &data_dict,
707  Status &error) {
708  StructuredData::Array *modules_array = nullptr;
709  SearchFilterSP result_sp;
710  bool success = data_dict.GetValueForKeyAsArray(GetKey(OptionNames::ModList),
711  modules_array);
712  FileSpecList modules;
713  if (success) {
714  size_t num_modules = modules_array->GetSize();
715  for (size_t i = 0; i < num_modules; i++) {
716  llvm::StringRef module;
717  success = modules_array->GetItemAtIndexAsString(i, module);
718  if (!success) {
720  "SFBM::CFSD: filter module item %zu not a string.", i);
721  return result_sp;
722  }
723  modules.Append(FileSpec(module));
724  }
725  }
726 
727  StructuredData::Array *cus_array = nullptr;
728  success =
729  data_dict.GetValueForKeyAsArray(GetKey(OptionNames::CUList), cus_array);
730  if (!success) {
731  error.SetErrorString("SFBM::CFSD: Could not find the CU list key.");
732  return result_sp;
733  }
734 
735  size_t num_cus = cus_array->GetSize();
736  FileSpecList cus;
737  for (size_t i = 0; i < num_cus; i++) {
738  llvm::StringRef cu;
739  success = cus_array->GetItemAtIndexAsString(i, cu);
740  if (!success) {
742  "SFBM::CFSD: filter cu item %zu not a string.", i);
743  return nullptr;
744  }
745  cus.Append(FileSpec(cu));
746  }
747 
748  return std::make_shared<SearchFilterByModuleListAndCU>(
749  target.shared_from_this(), modules, cus);
750 }
751 
754  auto options_dict_sp = std::make_shared<StructuredData::Dictionary>();
756  SerializeFileSpecList(options_dict_sp, OptionNames::CUList, m_cu_spec_list);
757  return WrapOptionsDict(options_dict_sp);
758 }
759 
761  SymbolContext sym_ctx;
762  address.CalculateSymbolContext(&sym_ctx, eSymbolContextEverything);
763  if (!sym_ctx.comp_unit) {
764  if (m_cu_spec_list.GetSize() != 0)
765  return false; // Has no comp_unit so can't pass the file check.
766  }
767  if (m_cu_spec_list.FindFileIndex(0, sym_ctx.comp_unit, false) == UINT32_MAX)
768  return false; // Fails the file check
770 }
771 
773  return m_cu_spec_list.FindFileIndex(0, fileSpec, false) != UINT32_MAX;
774 }
775 
777  bool in_cu_list =
778  m_cu_spec_list.FindFileIndex(0, compUnit, false) != UINT32_MAX;
779  if (in_cu_list) {
780  ModuleSP module_sp(compUnit.GetModule());
781  if (module_sp) {
782  bool module_passes = SearchFilterByModuleList::ModulePasses(module_sp);
783  return module_passes;
784  } else
785  return true;
786  } else
787  return false;
788 }
789 
791  if (!m_target_sp)
792  return;
793 
794  if (searcher.GetDepth() == lldb::eSearchDepthTarget) {
795  SymbolContext empty_sc;
796  empty_sc.target_sp = m_target_sp;
797  searcher.SearchCallback(*this, empty_sc, nullptr, false);
798  }
799 
800  // If the module file spec is a full path, then we can just find the one
801  // filespec that passes. Otherwise, we need to go through all modules and
802  // find the ones that match the file name.
803 
804  ModuleList matching_modules;
805  const ModuleList &target_images = m_target_sp->GetImages();
806  std::lock_guard<std::recursive_mutex> guard(target_images.GetMutex());
807 
808  const size_t num_modules = target_images.GetSize();
809  bool no_modules_in_filter = m_module_spec_list.GetSize() == 0;
810  for (size_t i = 0; i < num_modules; i++) {
811  lldb::ModuleSP module_sp = target_images.GetModuleAtIndexUnlocked(i);
812  if (no_modules_in_filter ||
813  m_module_spec_list.FindFileIndex(0, module_sp->GetFileSpec(), false) !=
814  UINT32_MAX) {
815  SymbolContext matchingContext(m_target_sp, module_sp);
816  Searcher::CallbackReturn shouldContinue;
817 
818  if (searcher.GetDepth() == lldb::eSearchDepthModule) {
819  shouldContinue = DoModuleIteration(matchingContext, searcher);
820  if (shouldContinue == Searcher::eCallbackReturnStop)
821  return;
822  } else {
823  const size_t num_cu = module_sp->GetNumCompileUnits();
824  for (size_t cu_idx = 0; cu_idx < num_cu; cu_idx++) {
825  CompUnitSP cu_sp = module_sp->GetCompileUnitAtIndex(cu_idx);
826  matchingContext.comp_unit = cu_sp.get();
827  if (matchingContext.comp_unit) {
828  if (m_cu_spec_list.FindFileIndex(0, *matchingContext.comp_unit,
829  false) != UINT32_MAX) {
830  shouldContinue =
831  DoCUIteration(module_sp, matchingContext, searcher);
832  if (shouldContinue == Searcher::eCallbackReturnStop)
833  return;
834  }
835  }
836  }
837  }
838  }
839  }
840 }
841 
843  size_t num_modules = m_module_spec_list.GetSize();
844  if (num_modules == 1) {
845  s->Printf(", module = ");
846  s->PutCString(
847  m_module_spec_list.GetFileSpecAtIndex(0).GetFilename().AsCString(
848  "<Unknown>"));
849  } else if (num_modules > 0) {
850  s->Printf(", modules(%" PRIu64 ") = ", static_cast<uint64_t>(num_modules));
851  for (size_t i = 0; i < num_modules; i++) {
852  s->PutCString(
853  m_module_spec_list.GetFileSpecAtIndex(i).GetFilename().AsCString(
854  "<Unknown>"));
855  if (i != num_modules - 1)
856  s->PutCString(", ");
857  }
858  }
859 }
860 
862  return eSymbolContextModule | eSymbolContextCompUnit;
863 }
864 
866 
867 lldb::SearchFilterSP
869  return std::make_shared<SearchFilterByModuleListAndCU>(*this);
870 }
ConstString & GetFilename()
Filename string get accessor.
Definition: FileSpec.cpp:369
static lldb::SearchFilterSP CreateFromStructuredData(Target &target, const StructuredData::Dictionary &data_dict, Status &error)
size_t PutCString(llvm::StringRef cstr)
Output a C string to the stream.
Definition: Stream.cpp:61
lldb::TargetSP target_sp
The Target for a given query.
const lldb::TargetSP GetTargetSP()
Definition: Breakpoint.cpp:247
uint32_t GetFilterRequiredItems() override
This determines which items are REQUIRED for the filter to pass.
Enumerations for broadcasting.
Definition: SBLaunchInfo.h:14
lldb::SearchFilterSP CopyForBreakpoint(Breakpoint &breakpoint)
virtual uint32_t GetFilterRequiredItems()
This determines which items are REQUIRED for the filter to pass.
const char * AsCString(const char *value_if_empty=nullptr) const
Get the string value as a C string.
Definition: ConstString.h:224
static FilterTy NameToFilterTy(llvm::StringRef name)
uint32_t CalculateSymbolContext(SymbolContext *sc, lldb::SymbolContextItem resolve_scope=lldb::eSymbolContextEverything) const
Reconstruct a symbol context from an address.
Definition: Address.cpp:782
A stream class that can stream formatted output to a file.
Definition: Stream.h:28
bool CompUnitPasses(FileSpec &fileSpec) override
Call this method with a FileSpec to see if file spec passes the filter as the name of a compilation u...
virtual bool CompUnitPasses(FileSpec &fileSpec)
Call this method with a FileSpec to see if file spec passes the filter as the name of a compilation u...
const FileSpec & GetFileSpec() const
Get const accessor for the module file specification.
Definition: Module.h:531
lldb::SearchFilterSP DoCopyForBreakpoint(Breakpoint &breakpoint) override
Defines a symbol context baton that can be handed other debug core functions.
Definition: SymbolContext.h:33
This is a SearchFilter that restricts the search to a given module.
Definition: SearchFilter.h:326
General Outline: A breakpoint has four main parts, a filter, a resolver, the list of breakpoint locat...
Definition: Breakpoint.h:78
uint32_t GetFilterRequiredItems() override
This determines which items are REQUIRED for the filter to pass.
virtual void Dump(Stream *s) const
Standard "Dump" method. At present it does nothing.
A file utility class.
Definition: FileSpec.h:55
void Dump(Stream *s) const override
Standard "Dump" method. At present it does nothing.
void Search(Searcher &searcher) override
Call this method to do the search using the Searcher.
A class that describes a function.
Definition: Function.h:323
CompileUnit * comp_unit
The CompileUnit for a given query.
StructuredData::ObjectSP SerializeToStructuredData() override
virtual lldb::SearchDepth GetDepth()=0
void Dump(Stream *s) const override
Standard "Dump" method. At present it does nothing.
static lldb::SearchFilterSP CreateFromStructuredData(Target &target, const StructuredData::Dictionary &data_dict, Status &error)
lldb::ModuleSP GetModule() const
Get const accessor for the module pointer.
Definition: ModuleChild.cpp:27
A class that describes a compilation unit.
Definition: CompileUnit.h:35
bool GetValueForKeyAsDictionary(llvm::StringRef key, Dictionary *&result) const
SearchFilterByModule & operator=(const SearchFilterByModule &rhs)
void SerializeFileSpecList(StructuredData::DictionarySP &options_dict_sp, OptionNames name, FileSpecList &file_list)
virtual bool ModulePasses(const FileSpec &spec)
Call this method with a file spec to see if that spec passes the filter.
bool ModulePasses(const FileSpec &module_spec) override
Call this method with a file spec to see if that spec passes the filter.
std::shared_ptr< Dictionary > DictionarySP
lldb::ModuleSP GetModuleAtIndexUnlocked(size_t idx) const
Get the module shared pointer for the module at index idx without acquiring the ModuleList mutex...
Definition: ModuleList.cpp:331
#define UINT32_MAX
Definition: lldb-defines.h:31
SearchFilter(const lldb::TargetSP &target_sp)
The basic constructor takes a Target, which gives the space to search.
void GetDescription(Stream *s) override
Prints a canonical description for the search filter to the stream s.
bool GetValueForKeyAsArray(llvm::StringRef key, Array *&result) const
lldb::SearchFilterSP DoCopyForBreakpoint(Breakpoint &breakpoint) override
Module * GetModulePointerAtIndexUnlocked(size_t idx) const
Get the module pointer for the module at index idx without acquiring the ModuleList mutex...
Definition: ModuleList.cpp:320
void GetDescription(Stream *s) override
Prints a canonical description for the search filter to the stream s.
lldb::SearchFilterSP DoCopyForBreakpoint(Breakpoint &breakpoint) override
A collection class for Module objects.
Definition: ModuleList.h:91
SearchFilter & operator=(const SearchFilter &rhs)
Searcher::CallbackReturn DoModuleIteration(const SymbolContext &context, Searcher &searcher)
A class that describes an executable image and its associated object and symbol files.
Definition: Module.h:109
virtual void Search(Searcher &searcher)
Call this method to do the search using the Searcher.
bool CompUnitPasses(FileSpec &fileSpec) override
Call this method with a FileSpec to see if file spec passes the filter as the name of a compilation u...
virtual void SearchInModuleList(Searcher &searcher, ModuleList &modules)
Call this method to do the search using the Searcher in the module list modules.
void GetDescription(Stream *s) override
Prints a canonical description for the search filter to the stream s.
General Outline: Provides the callback and search depth for the SearchFilter search.
Definition: SearchFilter.h:101
static lldb::SearchFilterSP CreateFromStructuredData(Target &target, const StructuredData::Dictionary &data_dict, Status &error)
void SetErrorString(llvm::StringRef err_str)
Set the current error string to err_str.
Definition: Status.cpp:241
General Outline: Provides the callback and search depth for the SearchFilter search.
Definition: SearchFilter.h:60
SearchFilterByModuleListAndCU & operator=(const SearchFilterByModuleListAndCU &rhs)
static const char * g_ty_to_name[LastKnownFilterType+2]
Definition: SearchFilter.h:239
bool AddressPasses(Address &address) override
Call this method with a Address to see if address passes the filter.
Searcher::CallbackReturn DoFunctionIteration(Function *function, const SymbolContext &context, Searcher &searcher)
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition: Stream.cpp:106
virtual size_t ParseFunctions(CompileUnit &comp_unit)
A section + offset based address class.
Definition: Address.h:80
bool GetItemAtIndexAsString(size_t idx, llvm::StringRef &result) const
lldb::TargetSP m_target_sp
Definition: SearchFilter.h:291
SearchFilterByModule(const lldb::TargetSP &targetSP, const FileSpec &module)
The basic constructor takes a Target, which gives the space to search, and the module to restrict the...
virtual CallbackReturn SearchCallback(SearchFilter &filter, SymbolContext &context, Address *addr, bool complete)=0
virtual bool FunctionPasses(Function &function)
Call this method with a Function to see if function passes the filter.
static lldb::SearchFilterSP CreateFromStructuredData(Target &target, const StructuredData::Dictionary &data_dict, Status &error)
bool CompUnitPasses(FileSpec &fileSpec) override
Call this method with a FileSpec to see if file spec passes the filter as the name of a compilation u...
ConstString & GetDirectory()
Directory string get accessor.
Definition: FileSpec.cpp:363
StructuredData::ObjectSP SerializeToStructuredData() override
StructuredData::DictionarySP WrapOptionsDict(StructuredData::DictionarySP options_dict_sp)
static const char * g_option_names[LastOptionName]
Definition: SearchFilter.h:257
Searcher::CallbackReturn DoCUIteration(const lldb::ModuleSP &module_sp, const SymbolContext &context, Searcher &searcher)
virtual void GetDescription(Stream *s)
Prints a canonical description for the searcher to the stream s.
void Search(Searcher &searcher) override
Call this method to do the search using the Searcher.
size_t GetSize() const
Gets the size of the module list.
Definition: ModuleList.cpp:611
SearchFilterByModuleList & operator=(const SearchFilterByModuleList &rhs)
bool AddressPasses(Address &address) override
Call this method with a Address to see if address passes the filter.
static const char * FilterTyToName(enum FilterTy)
static bool Equal(const FileSpec &a, const FileSpec &b, bool full)
Definition: FileSpec.cpp:319
lldb::ModuleSP module_sp
The Module for a given query.
Definition: SBAddress.h:15
lldb::SearchFilterSP DoCopyForBreakpoint(Breakpoint &breakpoint) override
std::shared_ptr< Object > ObjectSP
bool ModulePasses(const lldb::ModuleSP &module_sp) override
Call this method with a Module to see if that module passes the filter.
static const char * GetKey(enum OptionNames enum_value)
Definition: SearchFilter.h:259
virtual void GetDescription(Stream *s)
Prints a canonical description for the search filter to the stream s.
void SetErrorStringWithFormatv(const char *format, Args &&... args)
Definition: Status.h:185
bool AddressPasses(Address &address) override
Call this method with a Address to see if address passes the filter.
bool ModulePasses(const lldb::ModuleSP &module_sp) override
Call this method with a Module to see if that module passes the filter.
void Dump(Stream *s) const override
Standard "Dump" method. At present it does nothing.
int SetErrorStringWithFormat(const char *format,...) __attribute__((format(printf
Set the current error string to a formatted error string.
Definition: Status.cpp:255
SearchFilterByModuleList(const lldb::TargetSP &targetSP, const FileSpecList &module_list)
The basic constructor takes a Target, which gives the space to search, and the module list to restric...
std::recursive_mutex & GetMutex() const
Definition: ModuleList.h:214
static lldb::SearchFilterSP CreateFromStructuredData(Target &target, const StructuredData::Dictionary &data_dict, Status &error)
virtual bool AddressPasses(Address &addr)
Call this method with a Address to see if address passes the filter.
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
Definition: FileSpec.cpp:376
void SerializeUnwrapped(StructuredData::DictionarySP &options_dict_sp)
SearchFilterByModuleListAndCU(const lldb::TargetSP &targetSP, const FileSpecList &module_list, const FileSpecList &cu_list)
The basic constructor takes a Target, which gives the space to search, and the module list to restric...
uint32_t GetFilterRequiredItems() override
This determines which items are REQUIRED for the filter to pass.
StructuredData::ObjectSP SerializeToStructuredData() override
void Search(Searcher &searcher) override
Call this method to do the search using the Searcher.
StructuredData::ObjectSP SerializeToStructuredData() override
bool GetValueForKeyAsString(llvm::StringRef key, llvm::StringRef &result) const
An error handling class.
Definition: Status.h:44