1 //===-- BreakpointResolver.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_BreakpointResolver_h_ 10 #define liblldb_BreakpointResolver_h_ 11 12 #include "lldb/Breakpoint/Breakpoint.h" 13 #include "lldb/Core/Address.h" 14 #include "lldb/Core/SearchFilter.h" 15 #include "lldb/Utility/ConstString.h" 16 #include "lldb/Utility/FileSpec.h" 17 #include "lldb/Utility/RegularExpression.h" 18 #include "lldb/lldb-private.h" 19 20 namespace lldb_private { 21 22 /// \class BreakpointResolver BreakpointResolver.h 23 /// "lldb/Breakpoint/BreakpointResolver.h" This class works with SearchFilter 24 /// to resolve logical breakpoints to their of concrete breakpoint locations. 25 26 /// General Outline: 27 /// The BreakpointResolver is a Searcher. In that protocol, the SearchFilter 28 /// asks the question "At what depth of the symbol context descent do you want 29 /// your callback to get called?" of the filter. The resolver answers this 30 /// question (in the GetDepth method) and provides the resolution callback. 31 /// Each Breakpoint has a BreakpointResolver, and it calls either 32 /// ResolveBreakpoint or ResolveBreakpointInModules to tell it to look for new 33 /// breakpoint locations. 34 35 class BreakpointResolver : public Searcher { 36 friend class Breakpoint; 37 38 public: 39 /// The breakpoint resolver need to have a breakpoint for "ResolveBreakpoint 40 /// to make sense. It can be constructed without a breakpoint, but you have 41 /// to call SetBreakpoint before ResolveBreakpoint. 42 /// 43 /// \param[in] bkpt 44 /// The breakpoint that owns this resolver. 45 /// \param[in] resolverType 46 /// The concrete breakpoint resolver type for this breakpoint. 47 BreakpointResolver(Breakpoint *bkpt, unsigned char resolverType, 48 lldb::addr_t offset = 0); 49 50 /// The Destructor is virtual, all significant breakpoint resolvers derive 51 /// from this class. 52 ~BreakpointResolver() override; 53 54 /// This sets the breakpoint for this resolver. 55 /// 56 /// \param[in] bkpt 57 /// The breakpoint that owns this resolver. 58 void SetBreakpoint(Breakpoint *bkpt); 59 60 /// This updates the offset for this breakpoint. All the locations 61 /// currently set for this breakpoint will have their offset adjusted when 62 /// this is called. 63 /// 64 /// \param[in] offset 65 /// The offset to add to all locations. 66 void SetOffset(lldb::addr_t offset); 67 68 /// This updates the offset for this breakpoint. All the locations 69 /// currently set for this breakpoint will have their offset adjusted when 70 /// this is called. 71 /// 72 /// \param[in] offset 73 /// The offset to add to all locations. 74 lldb::addr_t GetOffset() const { return m_offset; } 75 76 /// In response to this method the resolver scans all the modules in the 77 /// breakpoint's target, and adds any new locations it finds. 78 /// 79 /// \param[in] filter 80 /// The filter that will manage the search for this resolver. 81 virtual void ResolveBreakpoint(SearchFilter &filter); 82 83 /// In response to this method the resolver scans the modules in the module 84 /// list \a modules, and adds any new locations it finds. 85 /// 86 /// \param[in] filter 87 /// The filter that will manage the search for this resolver. 88 virtual void ResolveBreakpointInModules(SearchFilter &filter, 89 ModuleList &modules); 90 91 /// Prints a canonical description for the breakpoint to the stream \a s. 92 /// 93 /// \param[in] s 94 /// Stream to which the output is copied. 95 void GetDescription(Stream *s) override = 0; 96 97 /// Standard "Dump" method. At present it does nothing. 98 virtual void Dump(Stream *s) const = 0; 99 100 /// This section handles serializing and deserializing from StructuredData 101 /// objects. 102 103 static lldb::BreakpointResolverSP 104 CreateFromStructuredData(const StructuredData::Dictionary &resolver_dict, 105 Status &error); 106 107 virtual StructuredData::ObjectSP SerializeToStructuredData() { 108 return StructuredData::ObjectSP(); 109 } 110 111 static const char *GetSerializationKey() { return "BKPTResolver"; } 112 113 static const char *GetSerializationSubclassKey() { return "Type"; } 114 115 static const char *GetSerializationSubclassOptionsKey() { return "Options"; } 116 117 StructuredData::DictionarySP 118 WrapOptionsDict(StructuredData::DictionarySP options_dict_sp); 119 120 /// An enumeration for keeping track of the concrete subclass that is 121 /// actually instantiated. Values of this enumeration are kept in the 122 /// BreakpointResolver's SubclassID field. They are used for concrete type 123 /// identification. 124 enum ResolverTy { 125 FileLineResolver = 0, // This is an instance of BreakpointResolverFileLine 126 AddressResolver, // This is an instance of BreakpointResolverAddress 127 NameResolver, // This is an instance of BreakpointResolverName 128 FileRegexResolver, 129 PythonResolver, 130 ExceptionResolver, 131 LastKnownResolverType = ExceptionResolver, 132 UnknownResolver 133 }; 134 135 // Translate the Ty to name for serialization, the "+2" is one for size vrs. 136 // index, and one for UnknownResolver. 137 static const char *g_ty_to_name[LastKnownResolverType + 2]; 138 139 /// getResolverID - Return an ID for the concrete type of this object. This 140 /// is used to implement the LLVM classof checks. This should not be used 141 /// for any other purpose, as the values may change as LLDB evolves. 142 unsigned getResolverID() const { return SubclassID; } 143 144 enum ResolverTy GetResolverTy() { 145 if (SubclassID > ResolverTy::LastKnownResolverType) 146 return ResolverTy::UnknownResolver; 147 else 148 return (enum ResolverTy)SubclassID; 149 } 150 151 const char *GetResolverName() { return ResolverTyToName(GetResolverTy()); } 152 153 static const char *ResolverTyToName(enum ResolverTy); 154 155 static ResolverTy NameToResolverTy(llvm::StringRef name); 156 157 virtual lldb::BreakpointResolverSP 158 CopyForBreakpoint(Breakpoint &breakpoint) = 0; 159 160 protected: 161 // Used for serializing resolver options: 162 // The options in this enum and the strings in the g_option_names must be 163 // kept in sync. 164 enum class OptionNames : uint32_t { 165 AddressOffset = 0, 166 ExactMatch, 167 FileName, 168 Inlines, 169 LanguageName, 170 LineNumber, 171 Column, 172 ModuleName, 173 NameMaskArray, 174 Offset, 175 PythonClassName, 176 RegexString, 177 ScriptArgs, 178 SectionName, 179 SearchDepth, 180 SkipPrologue, 181 SymbolNameArray, 182 LastOptionName 183 }; 184 static const char 185 *g_option_names[static_cast<uint32_t>(OptionNames::LastOptionName)]; 186 187 virtual void NotifyBreakpointSet() {}; 188 189 public: 190 static const char *GetKey(OptionNames enum_value) { 191 return g_option_names[static_cast<uint32_t>(enum_value)]; 192 } 193 194 protected: 195 /// Takes a symbol context list of matches which supposedly represent the 196 /// same file and line number in a CU, and find the nearest actual line 197 /// number that matches, and then filter down the matching addresses to 198 /// unique entries, and skip the prologue if asked to do so, and then set 199 /// breakpoint locations in this breakpoint for all the resultant addresses. 200 /// When \p column is nonzero the \p line and \p column args are used to 201 /// filter the results to find the first breakpoint >= (line, column). 202 void SetSCMatchesByLine(SearchFilter &filter, SymbolContextList &sc_list, 203 bool skip_prologue, llvm::StringRef log_ident, 204 uint32_t line = 0, uint32_t column = 0); 205 void SetSCMatchesByLine(SearchFilter &, SymbolContextList &, bool, 206 const char *) = delete; 207 208 lldb::BreakpointLocationSP AddLocation(Address loc_addr, 209 bool *new_location = nullptr); 210 211 Breakpoint *m_breakpoint; // This is the breakpoint we add locations to. 212 lldb::addr_t m_offset; // A random offset the user asked us to add to any 213 // breakpoints we set. 214 215 private: 216 /// Helper for \p SetSCMatchesByLine. 217 void AddLocation(SearchFilter &filter, const SymbolContext &sc, 218 bool skip_prologue, llvm::StringRef log_ident); 219 220 // Subclass identifier (for llvm isa/dyn_cast) 221 const unsigned char SubclassID; 222 DISALLOW_COPY_AND_ASSIGN(BreakpointResolver); 223 }; 224 225 } // namespace lldb_private 226 227 #endif // liblldb_BreakpointResolver_h_ 228