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
21namespace 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
36class BreakpointResolver : public Searcher {
37 friend class Breakpoint;
38
39public:
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.
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
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
111 virtual StructuredData::ObjectSP SerializeToStructuredData() {
112 return StructuredData::ObjectSP();
113 }
114
115 static const char *GetSerializationKey() { return "BKPTResolver"; }
116
117 static const char *GetSerializationSubclassKey() { return "Type"; }
118
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.
146 unsigned getResolverID() const { return SubclassID; }
147
148 enum ResolverTy GetResolverTy() {
149 if (SubclassID > ResolverTy::LastKnownResolverType)
150 return ResolverTy::UnknownResolver;
151 return (enum ResolverTy)SubclassID;
152 }
153
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
163protected:
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
190 virtual void NotifyBreakpointSet() {};
191
192public:
193 static const char *GetKey(OptionNames enum_value) {
194 return g_option_names[static_cast<uint32_t>(enum_value)];
195 }
196
197protected:
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,
208 std::optional<uint16_t> column = std::nullopt);
209 void SetSCMatchesByLine(SearchFilter &, SymbolContextList &, bool,
210 const char *) = delete;
211
212 lldb::BreakpointLocationSP AddLocation(Address loc_addr,
213 bool *new_location = nullptr);
214
215private:
216 /// Helper for \p SetSCMatchesByLine.
217 void AddLocation(SearchFilter &filter, const SymbolContext &sc,
218 bool skip_prologue, llvm::StringRef log_ident);
219
220 lldb::BreakpointWP m_breakpoint; // This is the breakpoint we add locations to.
221 lldb::addr_t m_offset; // A random offset the user asked us to add to any
222 // breakpoints we set.
223
224 // Subclass identifier (for llvm isa/dyn_cast)
225 const unsigned char SubclassID;
226 BreakpointResolver(const BreakpointResolver &) = delete;
227 const BreakpointResolver &operator=(const BreakpointResolver &) = delete;
228};
229
230} // namespace lldb_private
231
232#endif // LLDB_BREAKPOINT_BREAKPOINTRESOLVER_H
233

source code of lldb/include/lldb/Breakpoint/BreakpointResolver.h