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