//===-- SearchFilter.h ------------------------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #ifndef LLDB_CORE_SEARCHFILTER_H #define LLDB_CORE_SEARCHFILTER_H #include "lldb/Core/FileSpecList.h" #include "lldb/Utility/StructuredData.h" #include "lldb/Utility/FileSpec.h" #include "lldb/lldb-forward.h" #include namespace lldb_private { class Address; class Breakpoint; class CompileUnit; class Status; class Function; class ModuleList; class SearchFilter; class Stream; class SymbolContext; class Target; } namespace lldb_private { /// \class Searcher SearchFilter.h "lldb/Core/SearchFilter.h" Class that is /// driven by the SearchFilter to search the SymbolContext space of the target /// program. /// General Outline: /// Provides the callback and search depth for the SearchFilter search. class Searcher { public: enum CallbackReturn { eCallbackReturnStop = 0, // Stop the iteration eCallbackReturnContinue, // Continue the iteration eCallbackReturnPop // Pop one level up and continue iterating }; Searcher(); virtual ~Searcher(); virtual CallbackReturn SearchCallback(SearchFilter &filter, SymbolContext &context, Address *addr) = 0; virtual lldb::SearchDepth GetDepth() = 0; /// Prints a canonical description for the searcher to the stream \a s. /// /// \param[in] s /// Stream to which the output is copied. virtual void GetDescription(Stream *s); }; /// \class SearchFilter SearchFilter.h "lldb/Core/SearchFilter.h" Class /// descends through the SymbolContext space of the target, applying a filter /// at each stage till it reaches the depth specified by the GetDepth method /// of the searcher, and calls its callback at that point. /// General Outline: /// Provides the callback and search depth for the SearchFilter search. /// /// The search is done by cooperation between the search filter and the /// searcher. The search filter does the heavy work of recursing through the /// SymbolContext space of the target program's symbol space. The Searcher /// specifies the depth at which it wants its callback to be invoked. Note /// that since the resolution of the Searcher may be greater than that of the /// SearchFilter, before the Searcher qualifies an address it should pass it /// to "AddressPasses." The default implementation is "Everything Passes." class SearchFilter { public: /// The basic constructor takes a Target, which gives the space to search. /// /// \param[in] target_sp /// The Target that provides the module list to search. SearchFilter(const lldb::TargetSP &target_sp); SearchFilter(const lldb::TargetSP &target_sp, unsigned char filterType); virtual ~SearchFilter(); /// Call this method with a file spec to see if that spec passes the filter. /// /// \param[in] spec /// The file spec to check against the filter. /// \return /// \b true if \a spec passes, and \b false otherwise. /// /// \note the default implementation always returns \c true. virtual bool ModulePasses(const FileSpec &spec); /// Call this method with a Module to see if that module passes the filter. /// /// \param[in] module_sp /// The Module to check against the filter. /// /// \return /// \b true if \a module passes, and \b false otherwise. /// /// \note the default implementation always returns \c true. virtual bool ModulePasses(const lldb::ModuleSP &module_sp); /// Call this method with a Address to see if \a address passes the filter. /// /// \param[in] addr /// The address to check against the filter. /// /// \return /// \b true if \a address passes, and \b false otherwise. /// /// \note the default implementation always returns \c true. virtual bool AddressPasses(Address &addr); /// Call this method with a FileSpec to see if \a file spec passes the /// filter as the name of a compilation unit. /// /// \param[in] fileSpec /// The file spec to check against the filter. /// /// \return /// \b true if \a file spec passes, and \b false otherwise. /// /// \note the default implementation always returns \c true. virtual bool CompUnitPasses(FileSpec &fileSpec); /// Call this method with a CompileUnit to see if \a comp unit passes the /// filter. /// /// \param[in] compUnit /// The CompileUnit to check against the filter. /// /// \return /// \b true if \a Comp Unit passes, and \b false otherwise. /// /// \note the default implementation always returns \c true. virtual bool CompUnitPasses(CompileUnit &compUnit); /// Call this method with a Function to see if \a function passes the /// filter. /// /// \param[in] function /// The Functions to check against the filter. /// /// \return /// \b true if \a function passes, and \b false otherwise. virtual bool FunctionPasses(Function &function); /// Call this method to do the search using the Searcher. /// /// \param[in] searcher /// The searcher to drive with this search. /// virtual void Search(Searcher &searcher); /// Call this method to do the search using the Searcher in the module list /// \a modules. /// /// \param[in] searcher /// The searcher to drive with this search. /// /// \param[in] modules /// The module list within which to restrict the search. /// virtual void SearchInModuleList(Searcher &searcher, ModuleList &modules); /// This determines which items are REQUIRED for the filter to pass. For /// instance, if you are filtering by Compilation Unit, obviously symbols /// that have no compilation unit can't pass So return eSymbolContextCU and /// search callbacks can then short cut the search to avoid looking at /// things that obviously won't pass. /// /// \return /// The required elements for the search, which is an or'ed together /// set of lldb:SearchContextItem enum's. /// virtual uint32_t GetFilterRequiredItems(); /// Prints a canonical description for the search filter to the stream \a s. /// /// \param[in] s /// Stream to which the output is copied. virtual void GetDescription(Stream *s); /// Standard "Dump" method. At present it does nothing. virtual void Dump(Stream *s) const; lldb::SearchFilterSP CreateCopy(lldb::TargetSP& target_sp); static lldb::SearchFilterSP CreateFromStructuredData(const lldb::TargetSP& target_sp, const StructuredData::Dictionary &data_dict, Status &error); virtual StructuredData::ObjectSP SerializeToStructuredData() { return StructuredData::ObjectSP(); } static const char *GetSerializationKey() { return "SearchFilter"; } static const char *GetSerializationSubclassKey() { return "Type"; } static const char *GetSerializationSubclassOptionsKey() { return "Options"; } enum FilterTy { Unconstrained = 0, Exception, ByModule, ByModules, ByModulesAndCU, LastKnownFilterType = ByModulesAndCU, UnknownFilter }; static const char *g_ty_to_name[LastKnownFilterType + 2]; enum FilterTy GetFilterTy() { if (SubclassID > FilterTy::LastKnownFilterType) return FilterTy::UnknownFilter; else return (enum FilterTy)SubclassID; } const char *GetFilterName() { return FilterTyToName(GetFilterTy()); } static const char *FilterTyToName(enum FilterTy); static FilterTy NameToFilterTy(llvm::StringRef name); protected: // Serialization of SearchFilter options: enum OptionNames { ModList = 0, CUList, LanguageName, LastOptionName }; static const char *g_option_names[LastOptionName]; static const char *GetKey(enum OptionNames enum_value) { return g_option_names[enum_value]; } StructuredData::DictionarySP WrapOptionsDict(StructuredData::DictionarySP options_dict_sp); void SerializeFileSpecList(StructuredData::DictionarySP &options_dict_sp, OptionNames name, FileSpecList &file_list); // These are utility functions to assist with the search iteration. They are // used by the default Search method. Searcher::CallbackReturn DoModuleIteration(const SymbolContext &context, Searcher &searcher); Searcher::CallbackReturn DoModuleIteration(const lldb::ModuleSP &module_sp, Searcher &searcher); Searcher::CallbackReturn DoCUIteration(const lldb::ModuleSP &module_sp, const SymbolContext &context, Searcher &searcher); Searcher::CallbackReturn DoFunctionIteration(Function *function, const SymbolContext &context, Searcher &searcher); virtual lldb::SearchFilterSP DoCreateCopy() = 0; void SetTarget(lldb::TargetSP &target_sp) { m_target_sp = target_sp; } lldb::TargetSP m_target_sp; // Every filter has to be associated with // a target for now since you need a starting // place for the search. private: unsigned char SubclassID; }; /// \class SearchFilterForUnconstrainedSearches SearchFilter.h /// "lldb/Core/SearchFilter.h" This is a SearchFilter that searches through /// all modules. It also consults the /// Target::ModuleIsExcludedForUnconstrainedSearches. class SearchFilterForUnconstrainedSearches : public SearchFilter { public: SearchFilterForUnconstrainedSearches(const lldb::TargetSP &target_sp) : SearchFilter(target_sp, FilterTy::Unconstrained) {} ~SearchFilterForUnconstrainedSearches() override = default; bool ModulePasses(const FileSpec &module_spec) override; bool ModulePasses(const lldb::ModuleSP &module_sp) override; static lldb::SearchFilterSP CreateFromStructuredData(const lldb::TargetSP& target_sp, const StructuredData::Dictionary &data_dict, Status &error); StructuredData::ObjectSP SerializeToStructuredData() override; protected: lldb::SearchFilterSP DoCreateCopy() override; }; /// \class SearchFilterByModule SearchFilter.h "lldb/Core/SearchFilter.h" This /// is a SearchFilter that restricts the search to a given module. class SearchFilterByModule : public SearchFilter { public: /// The basic constructor takes a Target, which gives the space to search, /// and the module to restrict the search to. /// /// \param[in] targetSP /// The Target that provides the module list to search. /// /// \param[in] module /// The Module that limits the search. SearchFilterByModule(const lldb::TargetSP &targetSP, const FileSpec &module); ~SearchFilterByModule() override; bool ModulePasses(const lldb::ModuleSP &module_sp) override; bool ModulePasses(const FileSpec &spec) override; bool AddressPasses(Address &address) override; void GetDescription(Stream *s) override; uint32_t GetFilterRequiredItems() override; void Dump(Stream *s) const override; void Search(Searcher &searcher) override; static lldb::SearchFilterSP CreateFromStructuredData(const lldb::TargetSP& target_sp, const StructuredData::Dictionary &data_dict, Status &error); StructuredData::ObjectSP SerializeToStructuredData() override; protected: lldb::SearchFilterSP DoCreateCopy() override; private: FileSpec m_module_spec; }; class SearchFilterByModuleList : public SearchFilter { public: /// The basic constructor takes a Target, which gives the space to search, /// and the module list to restrict the search to. /// /// \param[in] targetSP /// The Target that provides the module list to search. /// /// \param[in] module_list /// The Module that limits the search. SearchFilterByModuleList(const lldb::TargetSP &targetSP, const FileSpecList &module_list); SearchFilterByModuleList(const lldb::TargetSP &targetSP, const FileSpecList &module_list, enum FilterTy filter_ty); ~SearchFilterByModuleList() override; bool ModulePasses(const lldb::ModuleSP &module_sp) override; bool ModulePasses(const FileSpec &spec) override; bool AddressPasses(Address &address) override; void GetDescription(Stream *s) override; uint32_t GetFilterRequiredItems() override; void Dump(Stream *s) const override; void Search(Searcher &searcher) override; static lldb::SearchFilterSP CreateFromStructuredData(const lldb::TargetSP& target_sp, const StructuredData::Dictionary &data_dict, Status &error); StructuredData::ObjectSP SerializeToStructuredData() override; void SerializeUnwrapped(StructuredData::DictionarySP &options_dict_sp); protected: lldb::SearchFilterSP DoCreateCopy() override; FileSpecList m_module_spec_list; }; class SearchFilterByModuleListAndCU : public SearchFilterByModuleList { public: /// The basic constructor takes a Target, which gives the space to search, /// and the module list to restrict the search to. SearchFilterByModuleListAndCU(const lldb::TargetSP &targetSP, const FileSpecList &module_list, const FileSpecList &cu_list); ~SearchFilterByModuleListAndCU() override; bool AddressPasses(Address &address) override; bool CompUnitPasses(FileSpec &fileSpec) override; bool CompUnitPasses(CompileUnit &compUnit) override; void GetDescription(Stream *s) override; uint32_t GetFilterRequiredItems() override; void Dump(Stream *s) const override; void Search(Searcher &searcher) override; static lldb::SearchFilterSP CreateFromStructuredData(const lldb::TargetSP& target_sp, const StructuredData::Dictionary &data_dict, Status &error); StructuredData::ObjectSP SerializeToStructuredData() override; protected: lldb::SearchFilterSP DoCreateCopy() override; private: FileSpecList m_cu_spec_list; }; } // namespace lldb_private #endif // LLDB_CORE_SEARCHFILTER_H