LLDB  mainline
SearchFilter.cpp
Go to the documentation of this file.
1 //===-- SearchFilter.cpp --------------------------------------------------===//
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"
16 #include "lldb/Symbol/SymbolFile.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() = default;
76 
78  const lldb::TargetSP& target_sp,
79  const StructuredData::Dictionary &filter_dict,
80  Status &error) {
81  SearchFilterSP result_sp;
82  if (!filter_dict.IsValid()) {
83  error.SetErrorString("Can't deserialize from an invalid data object.");
84  return result_sp;
85  }
86 
87  llvm::StringRef subclass_name;
88 
89  bool success = filter_dict.GetValueForKeyAsString(
90  GetSerializationSubclassKey(), subclass_name);
91  if (!success) {
92  error.SetErrorStringWithFormat("Filter data missing subclass key");
93  return result_sp;
94  }
95 
96  FilterTy filter_type = NameToFilterTy(subclass_name);
97  if (filter_type == UnknownFilter) {
98  error.SetErrorStringWithFormatv("Unknown filter type: {0}.", subclass_name);
99  return result_sp;
100  }
101 
102  StructuredData::Dictionary *subclass_options = nullptr;
103  success = filter_dict.GetValueForKeyAsDictionary(
104  GetSerializationSubclassOptionsKey(), subclass_options);
105  if (!success || !subclass_options || !subclass_options->IsValid()) {
106  error.SetErrorString("Filter data missing subclass options key.");
107  return result_sp;
108  }
109 
110  switch (filter_type) {
111  case Unconstrained:
113  target_sp, *subclass_options, error);
114  break;
115  case ByModule:
117  target_sp, *subclass_options, error);
118  break;
119  case ByModules:
121  target_sp, *subclass_options, error);
122  break;
123  case ByModulesAndCU:
125  target_sp, *subclass_options, error);
126  break;
127  case Exception:
128  error.SetErrorString("Can't serialize exception breakpoints yet.");
129  break;
130  default:
131  llvm_unreachable("Should never get an uresolvable filter type.");
132  }
133 
134  return result_sp;
135 }
136 
137 bool SearchFilter::ModulePasses(const FileSpec &spec) { return true; }
138 
139 bool SearchFilter::ModulePasses(const ModuleSP &module_sp) { return true; }
140 
141 bool SearchFilter::AddressPasses(Address &address) { return true; }
142 
143 bool SearchFilter::CompUnitPasses(FileSpec &fileSpec) { return true; }
144 
145 bool SearchFilter::CompUnitPasses(CompileUnit &compUnit) { return true; }
146 
148  // This is a slightly cheesy job, but since we don't have finer grained
149  // filters yet, just checking that the start address passes is probably
150  // good enough for the base class behavior.
151  Address addr = function.GetAddressRange().GetBaseAddress();
152  return AddressPasses(addr);
153 }
154 
155 
157  return (lldb::SymbolContextItem)0;
158 }
159 
161 
162 void SearchFilter::Dump(Stream *s) const {}
163 
164 lldb::SearchFilterSP SearchFilter::CreateCopy(lldb::TargetSP& target_sp) {
165  SearchFilterSP ret_sp = DoCreateCopy();
166  ret_sp->SetTarget(target_sp);
167  return ret_sp;
168 }
169 
170 // Helper functions for serialization.
171 
174  if (!options_dict_sp || !options_dict_sp->IsValid())
176 
177  auto type_dict_sp = std::make_shared<StructuredData::Dictionary>();
178  type_dict_sp->AddStringItem(GetSerializationSubclassKey(), GetFilterName());
179  type_dict_sp->AddItem(GetSerializationSubclassOptionsKey(), options_dict_sp);
180 
181  return type_dict_sp;
182 }
183 
185  StructuredData::DictionarySP &options_dict_sp, OptionNames name,
186  FileSpecList &file_list) {
187  size_t num_modules = file_list.GetSize();
188 
189  // Don't serialize empty lists.
190  if (num_modules == 0)
191  return;
192 
193  auto module_array_sp = std::make_shared<StructuredData::Array>();
194  for (size_t i = 0; i < num_modules; i++) {
195  module_array_sp->AddItem(std::make_shared<StructuredData::String>(
196  file_list.GetFileSpecAtIndex(i).GetPath()));
197  }
198  options_dict_sp->AddItem(GetKey(name), module_array_sp);
199 }
200 
201 // UTILITY Functions to help iterate down through the elements of the
202 // SymbolContext.
203 
205  SymbolContext empty_sc;
206 
207  if (!m_target_sp)
208  return;
209  empty_sc.target_sp = m_target_sp;
210 
211  if (searcher.GetDepth() == lldb::eSearchDepthTarget) {
212  searcher.SearchCallback(*this, empty_sc, nullptr);
213  return;
214  }
215 
216  DoModuleIteration(empty_sc, searcher);
217 }
218 
220  SymbolContext empty_sc;
221 
222  if (!m_target_sp)
223  return;
224  empty_sc.target_sp = m_target_sp;
225 
226  if (searcher.GetDepth() == lldb::eSearchDepthTarget) {
227  searcher.SearchCallback(*this, empty_sc, nullptr);
228  return;
229  }
230 
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  continue;
238  if (DoModuleIteration(module_sp, searcher) == Searcher::eCallbackReturnStop)
239  return;
240  }
241 }
242 
244 SearchFilter::DoModuleIteration(const lldb::ModuleSP &module_sp,
245  Searcher &searcher) {
246  SymbolContext matchingContext(m_target_sp, module_sp);
247  return DoModuleIteration(matchingContext, searcher);
248 }
249 
252  Searcher &searcher) {
253  if (searcher.GetDepth() < lldb::eSearchDepthModule)
255 
256  if (context.module_sp) {
257  if (searcher.GetDepth() != lldb::eSearchDepthModule)
258  return DoCUIteration(context.module_sp, context, searcher);
259 
260  SymbolContext matchingContext(context.module_sp.get());
261  searcher.SearchCallback(*this, matchingContext, nullptr);
263  }
264 
265  const ModuleList &target_images = m_target_sp->GetImages();
266  std::lock_guard<std::recursive_mutex> guard(target_images.GetMutex());
267 
268  size_t n_modules = target_images.GetSize();
269  for (size_t i = 0; i < n_modules; i++) {
270  // If this is the last level supplied, then call the callback directly,
271  // otherwise descend.
272  ModuleSP module_sp(target_images.GetModuleAtIndexUnlocked(i));
273  if (!ModulePasses(module_sp))
274  continue;
275 
276  if (searcher.GetDepth() == lldb::eSearchDepthModule) {
277  SymbolContext matchingContext(m_target_sp, module_sp);
278 
279  Searcher::CallbackReturn shouldContinue =
280  searcher.SearchCallback(*this, matchingContext, nullptr);
281  if (shouldContinue == Searcher::eCallbackReturnStop ||
282  shouldContinue == Searcher::eCallbackReturnPop)
283  return shouldContinue;
284  } else {
285  Searcher::CallbackReturn shouldContinue =
286  DoCUIteration(module_sp, context, searcher);
287  if (shouldContinue == Searcher::eCallbackReturnStop)
288  return shouldContinue;
289  else if (shouldContinue == Searcher::eCallbackReturnPop)
290  continue;
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  if (CompUnitPasses(*context.comp_unit)) {
303  SymbolContext matchingContext(m_target_sp, module_sp, context.comp_unit);
304  return searcher.SearchCallback(*this, matchingContext, nullptr);
305  }
307  }
308 
309  const size_t num_comp_units = module_sp->GetNumCompileUnits();
310  for (size_t i = 0; i < num_comp_units; i++) {
311  CompUnitSP cu_sp(module_sp->GetCompileUnitAtIndex(i));
312  if (!cu_sp)
313  continue;
314  if (!CompUnitPasses(*(cu_sp.get())))
315  continue;
316 
317  if (searcher.GetDepth() == lldb::eSearchDepthCompUnit) {
318  SymbolContext matchingContext(m_target_sp, module_sp, cu_sp.get());
319 
320  shouldContinue = searcher.SearchCallback(*this, matchingContext, nullptr);
321 
322  if (shouldContinue == Searcher::eCallbackReturnPop)
324  else if (shouldContinue == Searcher::eCallbackReturnStop)
325  return shouldContinue;
326  continue;
327  }
328 
329  // First make sure this compile unit's functions are parsed
330  // since CompUnit::ForeachFunction only iterates over already
331  // parsed functions.
332  SymbolFile *sym_file = module_sp->GetSymbolFile();
333  if (!sym_file)
334  continue;
335  if (!sym_file->ParseFunctions(*cu_sp))
336  continue;
337  // If we got any functions, use ForeachFunction to do the iteration.
338  cu_sp->ForeachFunction([&](const FunctionSP &func_sp) {
339  if (!FunctionPasses(*func_sp.get()))
340  return false; // Didn't pass the filter, just keep going.
341  if (searcher.GetDepth() == lldb::eSearchDepthFunction) {
342  SymbolContext matchingContext(m_target_sp, module_sp, cu_sp.get(),
343  func_sp.get());
344  shouldContinue =
345  searcher.SearchCallback(*this, matchingContext, nullptr);
346  } else {
347  shouldContinue = DoFunctionIteration(func_sp.get(), context, searcher);
348  }
349  return shouldContinue != Searcher::eCallbackReturnContinue;
350  });
351  }
353 }
354 
356  Function *function, const SymbolContext &context, Searcher &searcher) {
357  // FIXME: Implement...
359 }
360 
361 // SearchFilterForUnconstrainedSearches:
362 // Selects a shared library matching a given file spec, consulting the targets
363 // "black list".
365  const lldb::TargetSP& target_sp,
366  const StructuredData::Dictionary &data_dict,
367  Status &error) {
368  // No options for an unconstrained search.
369  return std::make_shared<SearchFilterForUnconstrainedSearches>(target_sp);
370 }
371 
374  // The options dictionary is an empty dictionary:
375  auto result_sp = std::make_shared<StructuredData::Dictionary>();
376  return WrapOptionsDict(result_sp);
377 }
378 
380  const FileSpec &module_spec) {
381  return !m_target_sp->ModuleIsExcludedForUnconstrainedSearches(module_spec);
382 }
383 
385  const lldb::ModuleSP &module_sp) {
386  if (!module_sp)
387  return true;
388  else if (m_target_sp->ModuleIsExcludedForUnconstrainedSearches(module_sp))
389  return false;
390  return true;
391 }
392 
394  return std::make_shared<SearchFilterForUnconstrainedSearches>(*this);
395 }
396 
397 // SearchFilterByModule:
398 // Selects a shared library matching a given file spec
399 
400 SearchFilterByModule::SearchFilterByModule(const lldb::TargetSP &target_sp,
401  const FileSpec &module)
402  : SearchFilter(target_sp, FilterTy::ByModule), m_module_spec(module) {}
403 
405 
406 bool SearchFilterByModule::ModulePasses(const ModuleSP &module_sp) {
407  return (module_sp &&
408  FileSpec::Match(m_module_spec, module_sp->GetFileSpec()));
409 }
410 
412  return FileSpec::Match(m_module_spec, spec);
413 }
414 
416  // FIXME: Not yet implemented
417  return true;
418 }
419 
421  if (!m_target_sp)
422  return;
423 
424  if (searcher.GetDepth() == lldb::eSearchDepthTarget) {
425  SymbolContext empty_sc;
426  empty_sc.target_sp = m_target_sp;
427  searcher.SearchCallback(*this, empty_sc, nullptr);
428  }
429 
430  // If the module file spec is a full path, then we can just find the one
431  // filespec that passes. Otherwise, we need to go through all modules and
432  // find the ones that match the file name.
433 
434  const ModuleList &target_modules = m_target_sp->GetImages();
435  std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
436 
437  const size_t num_modules = target_modules.GetSize();
438  for (size_t i = 0; i < num_modules; i++) {
439  Module *module = target_modules.GetModulePointerAtIndexUnlocked(i);
440  if (FileSpec::Match(m_module_spec, module->GetFileSpec())) {
441  SymbolContext matchingContext(m_target_sp, module->shared_from_this());
442  Searcher::CallbackReturn shouldContinue;
443 
444  shouldContinue = DoModuleIteration(matchingContext, searcher);
445  if (shouldContinue == Searcher::eCallbackReturnStop)
446  return;
447  }
448  }
449 }
450 
452  s->PutCString(", module = ");
453  s->PutCString(m_module_spec.GetFilename().AsCString("<Unknown>"));
454 }
455 
457  return eSymbolContextModule;
458 }
459 
461 
463  return std::make_shared<SearchFilterByModule>(*this);
464 }
465 
467  const lldb::TargetSP& target_sp,
468  const StructuredData::Dictionary &data_dict,
469  Status &error) {
470  StructuredData::Array *modules_array;
471  bool success = data_dict.GetValueForKeyAsArray(GetKey(OptionNames::ModList),
472  modules_array);
473  if (!success) {
474  error.SetErrorString("SFBM::CFSD: Could not find the module list key.");
475  return nullptr;
476  }
477 
478  size_t num_modules = modules_array->GetSize();
479  if (num_modules > 1) {
480  error.SetErrorString(
481  "SFBM::CFSD: Only one modules allowed for SearchFilterByModule.");
482  return nullptr;
483  }
484 
485  llvm::StringRef module;
486  success = modules_array->GetItemAtIndexAsString(0, module);
487  if (!success) {
488  error.SetErrorString("SFBM::CFSD: filter module item not a string.");
489  return nullptr;
490  }
491  FileSpec module_spec(module);
492 
493  return std::make_shared<SearchFilterByModule>(target_sp, module_spec);
494 }
495 
497  auto options_dict_sp = std::make_shared<StructuredData::Dictionary>();
498  auto module_array_sp = std::make_shared<StructuredData::Array>();
499  module_array_sp->AddItem(
500  std::make_shared<StructuredData::String>(m_module_spec.GetPath()));
501  options_dict_sp->AddItem(GetKey(OptionNames::ModList), module_array_sp);
502  return WrapOptionsDict(options_dict_sp);
503 }
504 
505 // SearchFilterByModuleList:
506 // Selects a shared library matching a given file spec
507 
509  const lldb::TargetSP &target_sp, const FileSpecList &module_list)
510  : SearchFilter(target_sp, FilterTy::ByModules),
511  m_module_spec_list(module_list) {}
512 
514  const lldb::TargetSP &target_sp, const FileSpecList &module_list,
515  enum FilterTy filter_ty)
516  : SearchFilter(target_sp, filter_ty), m_module_spec_list(module_list) {}
517 
519 
520 bool SearchFilterByModuleList::ModulePasses(const ModuleSP &module_sp) {
521  if (m_module_spec_list.GetSize() == 0)
522  return true;
523 
524  return module_sp && m_module_spec_list.FindFileIndex(
525  0, module_sp->GetFileSpec(), false) != UINT32_MAX;
526 }
527 
529  if (m_module_spec_list.GetSize() == 0)
530  return true;
531 
532  return m_module_spec_list.FindFileIndex(0, spec, true) != UINT32_MAX;
533 }
534 
536  // FIXME: Not yet implemented
537  return true;
538 }
539 
541  if (!m_target_sp)
542  return;
543 
544  if (searcher.GetDepth() == lldb::eSearchDepthTarget) {
545  SymbolContext empty_sc;
546  empty_sc.target_sp = m_target_sp;
547  searcher.SearchCallback(*this, empty_sc, nullptr);
548  }
549 
550  // If the module file spec is a full path, then we can just find the one
551  // filespec that passes. Otherwise, we need to go through all modules and
552  // find the ones that match the file name.
553 
554  const ModuleList &target_modules = m_target_sp->GetImages();
555  std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
556 
557  const size_t num_modules = target_modules.GetSize();
558  for (size_t i = 0; i < num_modules; i++) {
559  Module *module = target_modules.GetModulePointerAtIndexUnlocked(i);
560  if (m_module_spec_list.FindFileIndex(0, module->GetFileSpec(), false) ==
561  UINT32_MAX)
562  continue;
563  SymbolContext matchingContext(m_target_sp, module->shared_from_this());
564  Searcher::CallbackReturn shouldContinue;
565 
566  shouldContinue = DoModuleIteration(matchingContext, searcher);
567  if (shouldContinue == Searcher::eCallbackReturnStop)
568  return;
569  }
570 }
571 
573  size_t num_modules = m_module_spec_list.GetSize();
574  if (num_modules == 1) {
575  s->Printf(", module = ");
576  s->PutCString(
577  m_module_spec_list.GetFileSpecAtIndex(0).GetFilename().AsCString(
578  "<Unknown>"));
579  return;
580  }
581 
582  s->Printf(", modules(%" PRIu64 ") = ", (uint64_t)num_modules);
583  for (size_t i = 0; i < num_modules; i++) {
584  s->PutCString(
585  m_module_spec_list.GetFileSpecAtIndex(i).GetFilename().AsCString(
586  "<Unknown>"));
587  if (i != num_modules - 1)
588  s->PutCString(", ");
589  }
590 }
591 
593  return eSymbolContextModule;
594 }
595 
597 
599  return std::make_shared<SearchFilterByModuleList>(*this);
600 }
601 
603  const lldb::TargetSP& target_sp,
604  const StructuredData::Dictionary &data_dict,
605  Status &error) {
606  StructuredData::Array *modules_array;
607  bool success = data_dict.GetValueForKeyAsArray(GetKey(OptionNames::ModList),
608  modules_array);
609 
610  if (!success)
611  return std::make_shared<SearchFilterByModuleList>(target_sp,
612  FileSpecList{});
613  FileSpecList modules;
614  size_t num_modules = modules_array->GetSize();
615  for (size_t i = 0; i < num_modules; i++) {
616  llvm::StringRef module;
617  success = modules_array->GetItemAtIndexAsString(i, module);
618  if (!success) {
620  "SFBM::CFSD: filter module item %zu not a string.", i);
621  return nullptr;
622  }
623  modules.EmplaceBack(module);
624  }
625  return std::make_shared<SearchFilterByModuleList>(target_sp, modules);
626 }
627 
629  StructuredData::DictionarySP &options_dict_sp) {
630  SerializeFileSpecList(options_dict_sp, OptionNames::ModList,
632 }
633 
635  auto options_dict_sp = std::make_shared<StructuredData::Dictionary>();
636  SerializeUnwrapped(options_dict_sp);
637  return WrapOptionsDict(options_dict_sp);
638 }
639 
640 // SearchFilterByModuleListAndCU:
641 // Selects a shared library matching a given file spec
642 
644  const lldb::TargetSP &target_sp, const FileSpecList &module_list,
645  const FileSpecList &cu_list)
646  : SearchFilterByModuleList(target_sp, module_list,
648  m_cu_spec_list(cu_list) {}
649 
651 
653  const lldb::TargetSP& target_sp,
654  const StructuredData::Dictionary &data_dict,
655  Status &error) {
656  StructuredData::Array *modules_array = nullptr;
657  SearchFilterSP result_sp;
658  bool success = data_dict.GetValueForKeyAsArray(GetKey(OptionNames::ModList),
659  modules_array);
660  FileSpecList modules;
661  if (success) {
662  size_t num_modules = modules_array->GetSize();
663  for (size_t i = 0; i < num_modules; i++) {
664  llvm::StringRef module;
665  success = modules_array->GetItemAtIndexAsString(i, module);
666  if (!success) {
668  "SFBM::CFSD: filter module item %zu not a string.", i);
669  return result_sp;
670  }
671  modules.EmplaceBack(module);
672  }
673  }
674 
675  StructuredData::Array *cus_array = nullptr;
676  success =
677  data_dict.GetValueForKeyAsArray(GetKey(OptionNames::CUList), cus_array);
678  if (!success) {
679  error.SetErrorString("SFBM::CFSD: Could not find the CU list key.");
680  return result_sp;
681  }
682 
683  size_t num_cus = cus_array->GetSize();
684  FileSpecList cus;
685  for (size_t i = 0; i < num_cus; i++) {
686  llvm::StringRef cu;
687  success = cus_array->GetItemAtIndexAsString(i, cu);
688  if (!success) {
690  "SFBM::CFSD: filter CU item %zu not a string.", i);
691  return nullptr;
692  }
693  cus.EmplaceBack(cu);
694  }
695 
696  return std::make_shared<SearchFilterByModuleListAndCU>(
697  target_sp, modules, cus);
698 }
699 
702  auto options_dict_sp = std::make_shared<StructuredData::Dictionary>();
704  SerializeFileSpecList(options_dict_sp, OptionNames::CUList, m_cu_spec_list);
705  return WrapOptionsDict(options_dict_sp);
706 }
707 
709  SymbolContext sym_ctx;
710  address.CalculateSymbolContext(&sym_ctx, eSymbolContextEverything);
711  if (!sym_ctx.comp_unit) {
712  if (m_cu_spec_list.GetSize() != 0)
713  return false; // Has no comp_unit so can't pass the file check.
714  }
715  FileSpec cu_spec;
716  if (sym_ctx.comp_unit)
717  cu_spec = sym_ctx.comp_unit->GetPrimaryFile();
718  if (m_cu_spec_list.FindFileIndex(0, cu_spec, false) == UINT32_MAX)
719  return false; // Fails the file check
721 }
722 
724  return m_cu_spec_list.FindFileIndex(0, fileSpec, false) != UINT32_MAX;
725 }
726 
728  bool in_cu_list = m_cu_spec_list.FindFileIndex(0, compUnit.GetPrimaryFile(),
729  false) != UINT32_MAX;
730  if (!in_cu_list)
731  return false;
732 
733  ModuleSP module_sp(compUnit.GetModule());
734  if (!module_sp)
735  return true;
736 
737  return SearchFilterByModuleList::ModulePasses(module_sp);
738 }
739 
741  if (!m_target_sp)
742  return;
743 
744  if (searcher.GetDepth() == lldb::eSearchDepthTarget) {
745  SymbolContext empty_sc;
746  empty_sc.target_sp = m_target_sp;
747  searcher.SearchCallback(*this, empty_sc, nullptr);
748  }
749 
750  // If the module file spec is a full path, then we can just find the one
751  // filespec that passes. Otherwise, we need to go through all modules and
752  // find the ones that match the file name.
753 
754  ModuleList matching_modules;
755  const ModuleList &target_images = m_target_sp->GetImages();
756  std::lock_guard<std::recursive_mutex> guard(target_images.GetMutex());
757 
758  const size_t num_modules = target_images.GetSize();
759  bool no_modules_in_filter = m_module_spec_list.GetSize() == 0;
760  for (size_t i = 0; i < num_modules; i++) {
761  lldb::ModuleSP module_sp = target_images.GetModuleAtIndexUnlocked(i);
762  if (!no_modules_in_filter &&
763  m_module_spec_list.FindFileIndex(0, module_sp->GetFileSpec(), false) ==
764  UINT32_MAX)
765  continue;
766 
767  SymbolContext matchingContext(m_target_sp, module_sp);
768  Searcher::CallbackReturn shouldContinue;
769 
770  if (searcher.GetDepth() == lldb::eSearchDepthModule) {
771  shouldContinue = DoModuleIteration(matchingContext, searcher);
772  if (shouldContinue == Searcher::eCallbackReturnStop)
773  return;
774  continue;
775  }
776 
777  const size_t num_cu = module_sp->GetNumCompileUnits();
778  for (size_t cu_idx = 0; cu_idx < num_cu; cu_idx++) {
779  CompUnitSP cu_sp = module_sp->GetCompileUnitAtIndex(cu_idx);
780  matchingContext.comp_unit = cu_sp.get();
781  if (!matchingContext.comp_unit)
782  continue;
783  if (m_cu_spec_list.FindFileIndex(
784  0, matchingContext.comp_unit->GetPrimaryFile(), false) ==
785  UINT32_MAX)
786  continue;
787  shouldContinue = DoCUIteration(module_sp, matchingContext, searcher);
788  if (shouldContinue == Searcher::eCallbackReturnStop)
789  return;
790  }
791  }
792 }
793 
795  size_t num_modules = m_module_spec_list.GetSize();
796  if (num_modules == 1) {
797  s->Printf(", module = ");
798  s->PutCString(
799  m_module_spec_list.GetFileSpecAtIndex(0).GetFilename().AsCString(
800  "<Unknown>"));
801  } else if (num_modules > 0) {
802  s->Printf(", modules(%" PRIu64 ") = ", static_cast<uint64_t>(num_modules));
803  for (size_t i = 0; i < num_modules; i++) {
804  s->PutCString(
805  m_module_spec_list.GetFileSpecAtIndex(i).GetFilename().AsCString(
806  "<Unknown>"));
807  if (i != num_modules - 1)
808  s->PutCString(", ");
809  }
810  }
811 }
812 
814  return eSymbolContextModule | eSymbolContextCompUnit;
815 }
816 
818 
820  return std::make_shared<SearchFilterByModuleListAndCU>(*this);
821 }
static lldb::SearchFilterSP CreateFromStructuredData(const lldb::TargetSP &target_sp, const StructuredData::Dictionary &data_dict, Status &error)
ConstString & GetFilename()
Filename string get accessor.
Definition: FileSpec.cpp:341
size_t PutCString(llvm::StringRef cstr)
Output a C string to the stream.
Definition: Stream.cpp:62
lldb::TargetSP target_sp
The Target for a given query.
uint32_t GetFilterRequiredItems() override
This determines which items are REQUIRED for the filter to pass.
A class that represents a running process on the host machine.
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:223
static lldb::SearchFilterSP CreateFromStructuredData(const lldb::TargetSP &target_sp, const StructuredData::Dictionary &data_dict, Status &error)
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:795
A stream class that can stream formatted output to a file.
Definition: Stream.h:28
static bool Match(const FileSpec &pattern, const FileSpec &file)
Match FileSpec pattern against FileSpec file.
Definition: FileSpec.cpp:302
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:465
Defines a symbol context baton that can be handed other debug core functions.
Definition: SymbolContext.h:33
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:56
void Dump(Stream *s) const override
Standard "Dump" method. At present it does nothing.
lldb::SearchFilterSP DoCreateCopy() override
void Search(Searcher &searcher) override
Call this method to do the search using the Searcher.
A class that describes a function.
Definition: Function.h:390
CompileUnit * comp_unit
The CompileUnit for a given query.
StructuredData::ObjectSP SerializeToStructuredData() override
lldb::SearchFilterSP DoCreateCopy() override
virtual lldb::SearchDepth GetDepth()=0
static lldb::SearchFilterSP CreateFromStructuredData(const lldb::TargetSP &target_sp, const StructuredData::Dictionary &data_dict, Status &error)
void Dump(Stream *s) const override
Standard "Dump" method. At present it does nothing.
lldb::ModuleSP GetModule() const
Get const accessor for the module pointer.
Definition: ModuleChild.cpp:24
A class that describes a compilation unit.
Definition: CompileUnit.h:37
lldb::SearchFilterSP DoCreateCopy() override
bool GetValueForKeyAsDictionary(llvm::StringRef key, Dictionary *&result) const
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:347
#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
Module * GetModulePointerAtIndexUnlocked(size_t idx) const
Get the module pointer for the module at index idx without acquiring the ModuleList mutex...
Definition: ModuleList.cpp:336
void GetDescription(Stream *s) override
Prints a canonical description for the search filter to the stream s.
A collection class for Module objects.
Definition: ModuleList.h:71
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:75
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:83
void SetErrorString(llvm::StringRef err_str)
Set the current error string to err_str.
Definition: Status.cpp:242
General Outline: Provides the callback and search depth for the SearchFilter search.
Definition: SearchFilter.h:42
static const char * g_ty_to_name[LastKnownFilterType+2]
Definition: SearchFilter.h:227
virtual CallbackReturn SearchCallback(SearchFilter &filter, SymbolContext &context, Address *addr)=0
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
A section + offset based address class.
Definition: Address.h:59
bool GetItemAtIndexAsString(size_t idx, llvm::StringRef &result) const
lldb::TargetSP m_target_sp
Definition: SearchFilter.h:278
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 bool FunctionPasses(Function &function)
Call this method with a Function to see if function passes the filter.
static lldb::SearchFilterSP CreateFromStructuredData(const lldb::TargetSP &target_sp, const StructuredData::Dictionary &data_dict, Status &error)
virtual size_t ParseFunctions(CompileUnit &comp_unit)=0
StructuredData::ObjectSP SerializeToStructuredData() override
StructuredData::DictionarySP WrapOptionsDict(StructuredData::DictionarySP options_dict_sp)
static const char * g_option_names[LastOptionName]
Definition: SearchFilter.h:245
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:584
bool AddressPasses(Address &address) override
Call this method with a Address to see if address passes the filter.
static const char * FilterTyToName(enum FilterTy)
lldb::ModuleSP module_sp
The Module for a given query.
Definition: SBAddress.h:15
lldb::SearchFilterSP DoCreateCopy() override
std::shared_ptr< Object > ObjectSP
const FileSpec & GetPrimaryFile() const
Return the primary source file associated with this compile unit.
Definition: CompileUnit.h:226
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:247
virtual void GetDescription(Stream *s)
Prints a canonical description for the search filter to the stream s.
static lldb::SearchFilterSP CreateFromStructuredData(const lldb::TargetSP &target_sp, const StructuredData::Dictionary &data_dict, Status &error)
void SetErrorStringWithFormatv(const char *format, Args &&... args)
Definition: Status.h:173
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:256
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:192
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:348
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.
lldb::SearchFilterSP CreateCopy(lldb::TargetSP &target_sp)
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