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