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 LLDB_CORE_SEARCHFILTER_H
10 #define LLDB_CORE_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   ///
102   /// \note the default implementation always returns \c true.
103   virtual bool ModulePasses(const FileSpec &spec);
104 
105   /// Call this method with a Module to see if that module passes the filter.
106   ///
107   /// \param[in] module_sp
108   ///    The Module to check against the filter.
109   ///
110   /// \return
111   ///    \b true if \a module passes, and \b false otherwise.
112   ///
113   /// \note the default implementation always returns \c true.
114   virtual bool ModulePasses(const lldb::ModuleSP &module_sp);
115 
116   /// Call this method with a Address to see if \a address passes the filter.
117   ///
118   /// \param[in] addr
119   ///    The address to check against the filter.
120   ///
121   /// \return
122   ///    \b true if \a address passes, and \b false otherwise.
123   ///
124   /// \note the default implementation always returns \c true.
125   virtual bool AddressPasses(Address &addr);
126 
127   /// Call this method with a FileSpec to see if \a file spec passes the
128   /// filter as the name of a compilation unit.
129   ///
130   /// \param[in] fileSpec
131   ///    The file spec to check against the filter.
132   ///
133   /// \return
134   ///    \b true if \a file spec passes, and \b false otherwise.
135   ///
136   /// \note the default implementation always returns \c true.
137   virtual bool CompUnitPasses(FileSpec &fileSpec);
138 
139   /// Call this method with a CompileUnit to see if \a comp unit passes the
140   /// filter.
141   ///
142   /// \param[in] compUnit
143   ///    The CompileUnit to check against the filter.
144   ///
145   /// \return
146   ///    \b true if \a Comp Unit passes, and \b false otherwise.
147   ///
148   /// \note the default implementation always returns \c true.
149   virtual bool CompUnitPasses(CompileUnit &compUnit);
150 
151   /// Call this method with a Function to see if \a function passes the
152   /// filter.
153   ///
154   /// \param[in] function
155   ///    The Functions to check against the filter.
156   ///
157   /// \return
158   ///    \b true if \a function passes, and \b false otherwise.
159   virtual bool FunctionPasses(Function &function);
160 
161   /// Call this method to do the search using the Searcher.
162   ///
163   /// \param[in] searcher
164   ///    The searcher to drive with this search.
165   ///
166   virtual void Search(Searcher &searcher);
167 
168   /// Call this method to do the search using the Searcher in the module list
169   /// \a modules.
170   ///
171   /// \param[in] searcher
172   ///    The searcher to drive with this search.
173   ///
174   /// \param[in] modules
175   ///    The module list within which to restrict the search.
176   ///
177   virtual void SearchInModuleList(Searcher &searcher, ModuleList &modules);
178 
179   /// This determines which items are REQUIRED for the filter to pass. For
180   /// instance, if you are filtering by Compilation Unit, obviously symbols
181   /// that have no compilation unit can't pass  So return eSymbolContextCU and
182   /// search callbacks can then short cut the search to avoid looking at
183   /// things that obviously won't pass.
184   ///
185   /// \return
186   ///    The required elements for the search, which is an or'ed together
187   ///    set of lldb:SearchContextItem enum's.
188   ///
189   virtual uint32_t GetFilterRequiredItems();
190 
191   /// Prints a canonical description for the search filter to the stream \a s.
192   ///
193   /// \param[in] s
194   ///   Stream to which the output is copied.
195   virtual void GetDescription(Stream *s);
196 
197   /// Standard "Dump" method.  At present it does nothing.
198   virtual void Dump(Stream *s) const;
199 
200   lldb::SearchFilterSP CreateCopy(lldb::TargetSP& target_sp);
201 
202   static lldb::SearchFilterSP
203   CreateFromStructuredData(const lldb::TargetSP& target_sp,
204                            const StructuredData::Dictionary &data_dict,
205                            Status &error);
206 
207   virtual StructuredData::ObjectSP SerializeToStructuredData() {
208     return StructuredData::ObjectSP();
209   }
210 
211   static const char *GetSerializationKey() { return "SearchFilter"; }
212 
213   static const char *GetSerializationSubclassKey() { return "Type"; }
214 
215   static const char *GetSerializationSubclassOptionsKey() { return "Options"; }
216 
217   enum FilterTy {
218     Unconstrained = 0,
219     Exception,
220     ByModule,
221     ByModules,
222     ByModulesAndCU,
223     LastKnownFilterType = ByModulesAndCU,
224     UnknownFilter
225   };
226 
227   static const char *g_ty_to_name[LastKnownFilterType + 2];
228 
229   enum FilterTy GetFilterTy() {
230     if (SubclassID > FilterTy::LastKnownFilterType)
231       return FilterTy::UnknownFilter;
232     else
233       return (enum FilterTy)SubclassID;
234   }
235 
236   const char *GetFilterName() { return FilterTyToName(GetFilterTy()); }
237 
238   static const char *FilterTyToName(enum FilterTy);
239 
240   static FilterTy NameToFilterTy(llvm::StringRef name);
241 
242 protected:
243   // Serialization of SearchFilter options:
244   enum OptionNames { ModList = 0, CUList, LanguageName, LastOptionName };
245   static const char *g_option_names[LastOptionName];
246 
247   static const char *GetKey(enum OptionNames enum_value) {
248     return g_option_names[enum_value];
249   }
250 
251   StructuredData::DictionarySP
252   WrapOptionsDict(StructuredData::DictionarySP options_dict_sp);
253 
254   void SerializeFileSpecList(StructuredData::DictionarySP &options_dict_sp,
255                              OptionNames name, FileSpecList &file_list);
256 
257   // These are utility functions to assist with the search iteration.  They are
258   // used by the default Search method.
259 
260   Searcher::CallbackReturn DoModuleIteration(const SymbolContext &context,
261                                              Searcher &searcher);
262 
263   Searcher::CallbackReturn DoModuleIteration(const lldb::ModuleSP &module_sp,
264                                              Searcher &searcher);
265 
266   Searcher::CallbackReturn DoCUIteration(const lldb::ModuleSP &module_sp,
267                                          const SymbolContext &context,
268                                          Searcher &searcher);
269 
270   Searcher::CallbackReturn DoFunctionIteration(Function *function,
271                                                const SymbolContext &context,
272                                                Searcher &searcher);
273 
274   virtual lldb::SearchFilterSP DoCreateCopy() = 0;
275 
276   void SetTarget(lldb::TargetSP &target_sp) { m_target_sp = target_sp; }
277 
278   lldb::TargetSP m_target_sp; // Every filter has to be associated with
279                               // a target for now since you need a starting
280                               // place for the search.
281 private:
282   unsigned char SubclassID;
283 };
284 
285 /// \class SearchFilterForUnconstrainedSearches SearchFilter.h
286 /// "lldb/Core/SearchFilter.h" This is a SearchFilter that searches through
287 /// all modules.  It also consults the
288 /// Target::ModuleIsExcludedForUnconstrainedSearches.
289 class SearchFilterForUnconstrainedSearches : public SearchFilter {
290 public:
291   SearchFilterForUnconstrainedSearches(const lldb::TargetSP &target_sp)
292       : SearchFilter(target_sp, FilterTy::Unconstrained) {}
293 
294   ~SearchFilterForUnconstrainedSearches() override = default;
295 
296   bool ModulePasses(const FileSpec &module_spec) override;
297 
298   bool ModulePasses(const lldb::ModuleSP &module_sp) override;
299 
300   static lldb::SearchFilterSP
301   CreateFromStructuredData(const lldb::TargetSP& target_sp,
302                            const StructuredData::Dictionary &data_dict,
303                            Status &error);
304 
305   StructuredData::ObjectSP SerializeToStructuredData() override;
306 
307 protected:
308   lldb::SearchFilterSP DoCreateCopy() override;
309 };
310 
311 /// \class SearchFilterByModule SearchFilter.h "lldb/Core/SearchFilter.h" This
312 /// is a SearchFilter that restricts the search to a given module.
313 
314 class SearchFilterByModule : public SearchFilter {
315 public:
316   /// The basic constructor takes a Target, which gives the space to search,
317   /// and the module to restrict the search to.
318   ///
319   /// \param[in] targetSP
320   ///    The Target that provides the module list to search.
321   ///
322   /// \param[in] module
323   ///    The Module that limits the search.
324   SearchFilterByModule(const lldb::TargetSP &targetSP, const FileSpec &module);
325 
326   ~SearchFilterByModule() override;
327 
328   bool ModulePasses(const lldb::ModuleSP &module_sp) override;
329 
330   bool ModulePasses(const FileSpec &spec) override;
331 
332   bool AddressPasses(Address &address) override;
333 
334   void GetDescription(Stream *s) override;
335 
336   uint32_t GetFilterRequiredItems() override;
337 
338   void Dump(Stream *s) const override;
339 
340   void Search(Searcher &searcher) override;
341 
342   static lldb::SearchFilterSP
343   CreateFromStructuredData(const lldb::TargetSP& target_sp,
344                            const StructuredData::Dictionary &data_dict,
345                            Status &error);
346 
347   StructuredData::ObjectSP SerializeToStructuredData() override;
348 
349 protected:
350   lldb::SearchFilterSP DoCreateCopy() override;
351 
352 private:
353   FileSpec m_module_spec;
354 };
355 
356 class SearchFilterByModuleList : public SearchFilter {
357 public:
358   /// The basic constructor takes a Target, which gives the space to search,
359   /// and the module list to restrict the search to.
360   ///
361   /// \param[in] targetSP
362   ///    The Target that provides the module list to search.
363   ///
364   /// \param[in] module_list
365   ///    The Module that limits the search.
366   SearchFilterByModuleList(const lldb::TargetSP &targetSP,
367                            const FileSpecList &module_list);
368 
369   SearchFilterByModuleList(const lldb::TargetSP &targetSP,
370                            const FileSpecList &module_list,
371                            enum FilterTy filter_ty);
372 
373   ~SearchFilterByModuleList() override;
374 
375   bool ModulePasses(const lldb::ModuleSP &module_sp) override;
376 
377   bool ModulePasses(const FileSpec &spec) override;
378 
379   bool AddressPasses(Address &address) override;
380 
381   void GetDescription(Stream *s) override;
382 
383   uint32_t GetFilterRequiredItems() override;
384 
385   void Dump(Stream *s) const override;
386 
387   void Search(Searcher &searcher) override;
388 
389   static lldb::SearchFilterSP
390   CreateFromStructuredData(const lldb::TargetSP& target_sp,
391                            const StructuredData::Dictionary &data_dict,
392                            Status &error);
393 
394   StructuredData::ObjectSP SerializeToStructuredData() override;
395 
396   void SerializeUnwrapped(StructuredData::DictionarySP &options_dict_sp);
397 
398 protected:
399   lldb::SearchFilterSP DoCreateCopy() override;
400 
401   FileSpecList m_module_spec_list;
402 };
403 
404 class SearchFilterByModuleListAndCU : public SearchFilterByModuleList {
405 public:
406   /// The basic constructor takes a Target, which gives the space to search,
407   /// and the module list to restrict the search to.
408   SearchFilterByModuleListAndCU(const lldb::TargetSP &targetSP,
409                                 const FileSpecList &module_list,
410                                 const FileSpecList &cu_list);
411 
412   ~SearchFilterByModuleListAndCU() override;
413 
414   bool AddressPasses(Address &address) override;
415 
416   bool CompUnitPasses(FileSpec &fileSpec) override;
417 
418   bool CompUnitPasses(CompileUnit &compUnit) override;
419 
420   void GetDescription(Stream *s) override;
421 
422   uint32_t GetFilterRequiredItems() override;
423 
424   void Dump(Stream *s) const override;
425 
426   void Search(Searcher &searcher) override;
427 
428   static lldb::SearchFilterSP
429   CreateFromStructuredData(const lldb::TargetSP& target_sp,
430                            const StructuredData::Dictionary &data_dict,
431                            Status &error);
432 
433   StructuredData::ObjectSP SerializeToStructuredData() override;
434 
435 protected:
436   lldb::SearchFilterSP DoCreateCopy() override;
437 
438 private:
439   FileSpecList m_cu_spec_list;
440 };
441 
442 } // namespace lldb_private
443 
444 #endif // LLDB_CORE_SEARCHFILTER_H
445