BreakpointResolver.h revision 360784
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
20namespace 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
35class BreakpointResolver : public Searcher {
36  friend class Breakpoint;
37
38public:
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
160protected:
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
189public:
190  static const char *GetKey(OptionNames enum_value) {
191    return g_option_names[static_cast<uint32_t>(enum_value)];
192  }
193
194protected:
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
215private:
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