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