1 //===-- SearchFilter.h ------------------------------------------*- 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 
9 #ifndef liblldb_SearchFilter_h_
10 #define liblldb_SearchFilter_h_
11 
12 #include "lldb/Core/FileSpecList.h"
13 #include "lldb/Utility/StructuredData.h"
14 
15 #include "lldb/Utility/FileSpec.h"
16 #include "lldb/lldb-forward.h"
17 
18 #include <stdint.h>
19 
20 namespace lldb_private {
21 class Address;
22 class Breakpoint;
23 class CompileUnit;
24 class Status;
25 class Function;
26 class ModuleList;
27 class SearchFilter;
28 class Stream;
29 class SymbolContext;
30 class Target;
31 }
32 
33 namespace lldb_private {
34 
35 /// \class Searcher SearchFilter.h "lldb/Core/SearchFilter.h" Class that is
36 /// driven by the SearchFilter to search the SymbolContext space of the target
37 /// program.
38 
39 /// General Outline:
40 /// Provides the callback and search depth for the SearchFilter search.
41 
42 class Searcher {
43 public:
44   enum CallbackReturn {
45     eCallbackReturnStop = 0, // Stop the iteration
46     eCallbackReturnContinue, // Continue the iteration
47     eCallbackReturnPop       // Pop one level up and continue iterating
48   };
49 
50   Searcher();
51 
52   virtual ~Searcher();
53 
54   virtual CallbackReturn SearchCallback(SearchFilter &filter,
55                                         SymbolContext &context,
56                                         Address *addr) = 0;
57 
58   virtual lldb::SearchDepth GetDepth() = 0;
59 
60   /// Prints a canonical description for the searcher to the stream \a s.
61   ///
62   /// \param[in] s
63   ///   Stream to which the output is copied.
64   virtual void GetDescription(Stream *s);
65 };
66 
67 /// \class SearchFilter SearchFilter.h "lldb/Core/SearchFilter.h" Class
68 /// descends through the SymbolContext space of the target, applying a filter
69 /// at each stage till it reaches the depth specified by the GetDepth method
70 /// of the searcher, and calls its callback at that point.
71 
72 /// General Outline:
73 /// Provides the callback and search depth for the SearchFilter search.
74 ///
75 /// The search is done by cooperation between the search filter and the
76 /// searcher. The search filter does the heavy work of recursing through the
77 /// SymbolContext space of the target program's symbol space.  The Searcher
78 /// specifies the depth at which it wants its callback to be invoked.  Note
79 /// that since the resolution of the Searcher may be greater than that of the
80 /// SearchFilter, before the Searcher qualifies an address it should pass it
81 /// to "AddressPasses." The default implementation is "Everything Passes."
82 
83 class SearchFilter {
84 public:
85   /// The basic constructor takes a Target, which gives the space to search.
86   ///
87   /// \param[in] target_sp
88   ///    The Target that provides the module list to search.
89   SearchFilter(const lldb::TargetSP &target_sp);
90 
91   SearchFilter(const lldb::TargetSP &target_sp, unsigned char filterType);
92 
93   virtual ~SearchFilter();
94 
95   /// Call this method with a file spec to see if that spec passes the filter.
96   ///
97   /// \param[in] spec
98   ///    The file spec to check against the filter.
99   /// \return
100   ///    \b true if \a spec passes, and \b false otherwise.
101   virtual bool ModulePasses(const FileSpec &spec);
102 
103   /// Call this method with a Module to see if that module passes the filter.
104   ///
105   /// \param[in] module_sp
106   ///    The Module to check against the filter.
107   ///
108   /// \return
109   ///    \b true if \a module passes, and \b false otherwise.
110   virtual bool ModulePasses(const lldb::ModuleSP &module_sp);
111 
112   /// Call this method with a Address to see if \a address passes the filter.
113   ///
114   /// \param[in] addr
115   ///    The address to check against the filter.
116   ///
117   /// \return
118   ///    \b true if \a address passes, and \b false otherwise.
119   virtual bool AddressPasses(Address &addr);
120 
121   /// Call this method with a FileSpec to see if \a file spec passes the
122   /// filter as the name of a compilation unit.
123   ///
124   /// \param[in] fileSpec
125   ///    The file spec to check against the filter.
126   ///
127   /// \return
128   ///    \b true if \a file spec passes, and \b false otherwise.
129   virtual bool CompUnitPasses(FileSpec &fileSpec);
130 
131   /// Call this method with a CompileUnit to see if \a comp unit passes the
132   /// filter.
133   ///
134   /// \param[in] compUnit
135   ///    The CompileUnit to check against the filter.
136   ///
137   /// \return
138   ///    \b true if \a Comp Unit passes, and \b false otherwise.
139   virtual bool CompUnitPasses(CompileUnit &compUnit);
140 
141   /// Call this method with a Function to see if \a function passes the
142   /// filter.
143   ///
144   /// \param[in] function
145   ///    The Functions to check against the filter.
146   ///
147   /// \return
148   ///    \b true if \a function passes, and \b false otherwise.
149   virtual bool FunctionPasses(Function &function);
150 
151   /// Call this method to do the search using the Searcher.
152   ///
153   /// \param[in] searcher
154   ///    The searcher to drive with this search.
155   ///
156   virtual void Search(Searcher &searcher);
157 
158   /// Call this method to do the search using the Searcher in the module list
159   /// \a modules.
160   ///
161   /// \param[in] searcher
162   ///    The searcher to drive with this search.
163   ///
164   /// \param[in] modules
165   ///    The module list within which to restrict the search.
166   ///
167   virtual void SearchInModuleList(Searcher &searcher, ModuleList &modules);
168 
169   /// This determines which items are REQUIRED for the filter to pass. For
170   /// instance, if you are filtering by Compilation Unit, obviously symbols
171   /// that have no compilation unit can't pass  So return eSymbolContextCU and
172   /// search callbacks can then short cut the search to avoid looking at
173   /// things that obviously won't pass.
174   ///
175   /// \return
176   ///    The required elements for the search, which is an or'ed together
177   ///    set of lldb:SearchContextItem enum's.
178   ///
179   virtual uint32_t GetFilterRequiredItems();
180 
181   /// Prints a canonical description for the search filter to the stream \a s.
182   ///
183   /// \param[in] s
184   ///   Stream to which the output is copied.
185   virtual void GetDescription(Stream *s);
186 
187   /// Standard "Dump" method.  At present it does nothing.
188   virtual void Dump(Stream *s) const;
189 
190   lldb::SearchFilterSP CopyForBreakpoint(Breakpoint &breakpoint);
191 
192   static lldb::SearchFilterSP
193   CreateFromStructuredData(Target &target,
194                            const StructuredData::Dictionary &data_dict,
195                            Status &error);
196 
197   virtual StructuredData::ObjectSP SerializeToStructuredData() {
198     return StructuredData::ObjectSP();
199   }
200 
201   static const char *GetSerializationKey() { return "SearchFilter"; }
202 
203   static const char *GetSerializationSubclassKey() { return "Type"; }
204 
205   static const char *GetSerializationSubclassOptionsKey() { return "Options"; }
206 
207   enum FilterTy {
208     Unconstrained = 0,
209     Exception,
210     ByModule,
211     ByModules,
212     ByModulesAndCU,
213     LastKnownFilterType = ByModulesAndCU,
214     UnknownFilter
215   };
216 
217   static const char *g_ty_to_name[LastKnownFilterType + 2];
218 
219   enum FilterTy GetFilterTy() {
220     if (SubclassID > FilterTy::LastKnownFilterType)
221       return FilterTy::UnknownFilter;
222     else
223       return (enum FilterTy)SubclassID;
224   }
225 
226   const char *GetFilterName() { return FilterTyToName(GetFilterTy()); }
227 
228   static const char *FilterTyToName(enum FilterTy);
229 
230   static FilterTy NameToFilterTy(llvm::StringRef name);
231 
232 protected:
233   // Serialization of SearchFilter options:
234   enum OptionNames { ModList = 0, CUList, LanguageName, LastOptionName };
235   static const char *g_option_names[LastOptionName];
236 
237   static const char *GetKey(enum OptionNames enum_value) {
238     return g_option_names[enum_value];
239   }
240 
241   StructuredData::DictionarySP
242   WrapOptionsDict(StructuredData::DictionarySP options_dict_sp);
243 
244   void SerializeFileSpecList(StructuredData::DictionarySP &options_dict_sp,
245                              OptionNames name, FileSpecList &file_list);
246 
247   // These are utility functions to assist with the search iteration.  They are
248   // used by the default Search method.
249 
250   Searcher::CallbackReturn DoModuleIteration(const SymbolContext &context,
251                                              Searcher &searcher);
252 
253   Searcher::CallbackReturn DoModuleIteration(const lldb::ModuleSP &module_sp,
254                                              Searcher &searcher);
255 
256   Searcher::CallbackReturn DoCUIteration(const lldb::ModuleSP &module_sp,
257                                          const SymbolContext &context,
258                                          Searcher &searcher);
259 
260   Searcher::CallbackReturn DoFunctionIteration(Function *function,
261                                                const SymbolContext &context,
262                                                Searcher &searcher);
263 
264   virtual lldb::SearchFilterSP DoCopyForBreakpoint(Breakpoint &breakpoint) = 0;
265 
266   void SetTarget(lldb::TargetSP &target_sp) { m_target_sp = target_sp; }
267 
268   lldb::TargetSP
269       m_target_sp; // Every filter has to be associated with a target for
270                    // now since you need a starting place for the search.
271 private:
272   unsigned char SubclassID;
273 };
274 
275 /// \class SearchFilterForUnconstrainedSearches SearchFilter.h
276 /// "lldb/Core/SearchFilter.h" This is a SearchFilter that searches through
277 /// all modules.  It also consults the
278 /// Target::ModuleIsExcludedForUnconstrainedSearches.
279 class SearchFilterForUnconstrainedSearches : public SearchFilter {
280 public:
281   SearchFilterForUnconstrainedSearches(const lldb::TargetSP &target_sp)
282       : SearchFilter(target_sp, FilterTy::Unconstrained) {}
283 
284   ~SearchFilterForUnconstrainedSearches() override = default;
285 
286   bool ModulePasses(const FileSpec &module_spec) override;
287 
288   bool ModulePasses(const lldb::ModuleSP &module_sp) override;
289 
290   static lldb::SearchFilterSP
291   CreateFromStructuredData(Target &target,
292                            const StructuredData::Dictionary &data_dict,
293                            Status &error);
294 
295   StructuredData::ObjectSP SerializeToStructuredData() override;
296 
297 protected:
298   lldb::SearchFilterSP DoCopyForBreakpoint(Breakpoint &breakpoint) override;
299 };
300 
301 /// \class SearchFilterByModule SearchFilter.h "lldb/Core/SearchFilter.h" This
302 /// is a SearchFilter that restricts the search to a given module.
303 
304 class SearchFilterByModule : public SearchFilter {
305 public:
306   /// The basic constructor takes a Target, which gives the space to search,
307   /// and the module to restrict the search to.
308   ///
309   /// \param[in] targetSP
310   ///    The Target that provides the module list to search.
311   ///
312   /// \param[in] module
313   ///    The Module that limits the search.
314   SearchFilterByModule(const lldb::TargetSP &targetSP, const FileSpec &module);
315 
316   ~SearchFilterByModule() override;
317 
318   bool ModulePasses(const lldb::ModuleSP &module_sp) override;
319 
320   bool ModulePasses(const FileSpec &spec) override;
321 
322   bool AddressPasses(Address &address) override;
323 
324   bool CompUnitPasses(FileSpec &fileSpec) override;
325 
326   bool CompUnitPasses(CompileUnit &compUnit) override;
327 
328   void GetDescription(Stream *s) override;
329 
330   uint32_t GetFilterRequiredItems() override;
331 
332   void Dump(Stream *s) const override;
333 
334   void Search(Searcher &searcher) override;
335 
336   static lldb::SearchFilterSP
337   CreateFromStructuredData(Target &target,
338                            const StructuredData::Dictionary &data_dict,
339                            Status &error);
340 
341   StructuredData::ObjectSP SerializeToStructuredData() override;
342 
343 protected:
344   lldb::SearchFilterSP DoCopyForBreakpoint(Breakpoint &breakpoint) override;
345 
346 private:
347   FileSpec m_module_spec;
348 };
349 
350 class SearchFilterByModuleList : public SearchFilter {
351 public:
352   /// The basic constructor takes a Target, which gives the space to search,
353   /// and the module list to restrict the search to.
354   ///
355   /// \param[in] targetSP
356   ///    The Target that provides the module list to search.
357   ///
358   /// \param[in] module_list
359   ///    The Module that limits the search.
360   SearchFilterByModuleList(const lldb::TargetSP &targetSP,
361                            const FileSpecList &module_list);
362 
363   SearchFilterByModuleList(const lldb::TargetSP &targetSP,
364                            const FileSpecList &module_list,
365                            enum FilterTy filter_ty);
366 
367   ~SearchFilterByModuleList() override;
368 
369   bool ModulePasses(const lldb::ModuleSP &module_sp) override;
370 
371   bool ModulePasses(const FileSpec &spec) override;
372 
373   bool AddressPasses(Address &address) override;
374 
375   bool CompUnitPasses(FileSpec &fileSpec) override;
376 
377   bool CompUnitPasses(CompileUnit &compUnit) override;
378 
379   void GetDescription(Stream *s) override;
380 
381   uint32_t GetFilterRequiredItems() override;
382 
383   void Dump(Stream *s) const override;
384 
385   void Search(Searcher &searcher) override;
386 
387   static lldb::SearchFilterSP
388   CreateFromStructuredData(Target &target,
389                            const StructuredData::Dictionary &data_dict,
390                            Status &error);
391 
392   StructuredData::ObjectSP SerializeToStructuredData() override;
393 
394   void SerializeUnwrapped(StructuredData::DictionarySP &options_dict_sp);
395 
396 protected:
397   lldb::SearchFilterSP DoCopyForBreakpoint(Breakpoint &breakpoint) override;
398 
399 protected:
400   FileSpecList m_module_spec_list;
401 };
402 
403 class SearchFilterByModuleListAndCU : public SearchFilterByModuleList {
404 public:
405   /// The basic constructor takes a Target, which gives the space to search,
406   /// and the module list to restrict the search to.
407   SearchFilterByModuleListAndCU(const lldb::TargetSP &targetSP,
408                                 const FileSpecList &module_list,
409                                 const FileSpecList &cu_list);
410 
411   ~SearchFilterByModuleListAndCU() override;
412 
413   bool AddressPasses(Address &address) override;
414 
415   bool CompUnitPasses(FileSpec &fileSpec) override;
416 
417   bool CompUnitPasses(CompileUnit &compUnit) override;
418 
419   void GetDescription(Stream *s) override;
420 
421   uint32_t GetFilterRequiredItems() override;
422 
423   void Dump(Stream *s) const override;
424 
425   void Search(Searcher &searcher) override;
426 
427   static lldb::SearchFilterSP
428   CreateFromStructuredData(Target &target,
429                            const StructuredData::Dictionary &data_dict,
430                            Status &error);
431 
432   StructuredData::ObjectSP SerializeToStructuredData() override;
433 
434 protected:
435   lldb::SearchFilterSP DoCopyForBreakpoint(Breakpoint &breakpoint) override;
436 
437 private:
438   FileSpecList m_cu_spec_list;
439 };
440 
441 } // namespace lldb_private
442 
443 #endif // liblldb_SearchFilter_h_
444