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