reference, declarationdefinition
definition → references, declarations, derived classes, virtual overrides
reference to multiple definitions → definitions
unreferenced
    1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109
  110
  111
  112
  113
  114
  115
  116
  117
  118
  119
  120
  121
  122
  123
  124
  125
  126
  127
  128
  129
  130
  131
  132
  133
  134
  135
  136
  137
  138
  139
  140
  141
  142
  143
  144
  145
  146
  147
  148
  149
  150
  151
  152
  153
  154
  155
  156
  157
  158
  159
  160
  161
  162
  163
  164
  165
  166
  167
  168
  169
  170
  171
  172
  173
  174
  175
  176
  177
  178
  179
  180
  181
  182
  183
  184
  185
  186
  187
  188
  189
  190
  191
  192
  193
  194
  195
  196
  197
  198
  199
  200
  201
  202
  203
  204
  205
  206
  207
  208
  209
  210
  211
  212
  213
  214
  215
  216
  217
  218
  219
  220
  221
  222
  223
  224
  225
  226
  227
  228
  229
  230
//===-- BreakpointResolver.h ------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef liblldb_BreakpointResolver_h_
#define liblldb_BreakpointResolver_h_

#include "lldb/Breakpoint/Breakpoint.h"
#include "lldb/Core/Address.h"
#include "lldb/Core/SearchFilter.h"
#include "lldb/Utility/ConstString.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/RegularExpression.h"
#include "lldb/lldb-private.h"

namespace lldb_private {

/// \class BreakpointResolver BreakpointResolver.h
/// "lldb/Breakpoint/BreakpointResolver.h" This class works with SearchFilter
/// to resolve logical breakpoints to their of concrete breakpoint locations.

/// General Outline:
/// The BreakpointResolver is a Searcher.  In that protocol, the SearchFilter
/// asks the question "At what depth of the symbol context descent do you want
/// your callback to get called?" of the filter.  The resolver answers this
/// question (in the GetDepth method) and provides the resolution callback.
/// Each Breakpoint has a BreakpointResolver, and it calls either
/// ResolveBreakpoint or ResolveBreakpointInModules to tell it to look for new
/// breakpoint locations.

class BreakpointResolver : public Searcher {
  friend class Breakpoint;

public:
  /// The breakpoint resolver need to have a breakpoint for "ResolveBreakpoint
  /// to make sense.  It can be constructed without a breakpoint, but you have
  /// to call SetBreakpoint before ResolveBreakpoint.
  ///
  /// \param[in] bkpt
  ///   The breakpoint that owns this resolver.
  /// \param[in] resolverType
  ///   The concrete breakpoint resolver type for this breakpoint.
  ///
  /// \result
  ///   Returns breakpoint location id.
  BreakpointResolver(Breakpoint *bkpt, unsigned char resolverType,
                     lldb::addr_t offset = 0);

  /// The Destructor is virtual, all significant breakpoint resolvers derive
  /// from this class.
  ~BreakpointResolver() override;

  /// This sets the breakpoint for this resolver.
  ///
  /// \param[in] bkpt
  ///   The breakpoint that owns this resolver.
  void SetBreakpoint(Breakpoint *bkpt);

  /// This updates the offset for this breakpoint.  All the locations
  /// currently set for this breakpoint will have their offset adjusted when
  /// this is called.
  ///
  /// \param[in] offset
  ///   The offset to add to all locations.
  void SetOffset(lldb::addr_t offset);

  /// This updates the offset for this breakpoint.  All the locations
  /// currently set for this breakpoint will have their offset adjusted when
  /// this is called.
  ///
  /// \param[in] offset
  ///   The offset to add to all locations.
  lldb::addr_t GetOffset() const { return m_offset; }

  /// In response to this method the resolver scans all the modules in the
  /// breakpoint's target, and adds any new locations it finds.
  ///
  /// \param[in] filter
  ///   The filter that will manage the search for this resolver.
  virtual void ResolveBreakpoint(SearchFilter &filter);

  /// In response to this method the resolver scans the modules in the module
  /// list \a modules, and adds any new locations it finds.
  ///
  /// \param[in] filter
  ///   The filter that will manage the search for this resolver.
  virtual void ResolveBreakpointInModules(SearchFilter &filter,
                                          ModuleList &modules);

  /// Prints a canonical description for the breakpoint to the stream \a s.
  ///
  /// \param[in] s
  ///   Stream to which the output is copied.
  void GetDescription(Stream *s) override = 0;

  /// Standard "Dump" method.  At present it does nothing.
  virtual void Dump(Stream *s) const = 0;

  /// This section handles serializing and deserializing from StructuredData
  /// objects.

  static lldb::BreakpointResolverSP
  CreateFromStructuredData(const StructuredData::Dictionary &resolver_dict,
                           Status &error);

  virtual StructuredData::ObjectSP SerializeToStructuredData() {
    return StructuredData::ObjectSP();
  }

  static const char *GetSerializationKey() { return "BKPTResolver"; }

  static const char *GetSerializationSubclassKey() { return "Type"; }

  static const char *GetSerializationSubclassOptionsKey() { return "Options"; }

  StructuredData::DictionarySP
  WrapOptionsDict(StructuredData::DictionarySP options_dict_sp);

  /// An enumeration for keeping track of the concrete subclass that is
  /// actually instantiated. Values of this enumeration are kept in the
  /// BreakpointResolver's SubclassID field. They are used for concrete type
  /// identification.
  enum ResolverTy {
    FileLineResolver = 0, // This is an instance of BreakpointResolverFileLine
    AddressResolver,      // This is an instance of BreakpointResolverAddress
    NameResolver,         // This is an instance of BreakpointResolverName
    FileRegexResolver,
    PythonResolver,
    ExceptionResolver,
    LastKnownResolverType = ExceptionResolver,
    UnknownResolver
  };

  // Translate the Ty to name for serialization, the "+2" is one for size vrs.
  // index, and one for UnknownResolver.
  static const char *g_ty_to_name[LastKnownResolverType + 2];

  /// getResolverID - Return an ID for the concrete type of this object.  This
  /// is used to implement the LLVM classof checks.  This should not be used
  /// for any other purpose, as the values may change as LLDB evolves.
  unsigned getResolverID() const { return SubclassID; }

  enum ResolverTy GetResolverTy() {
    if (SubclassID > ResolverTy::LastKnownResolverType)
      return ResolverTy::UnknownResolver;
    else
      return (enum ResolverTy)SubclassID;
  }

  const char *GetResolverName() { return ResolverTyToName(GetResolverTy()); }

  static const char *ResolverTyToName(enum ResolverTy);

  static ResolverTy NameToResolverTy(llvm::StringRef name);

  virtual lldb::BreakpointResolverSP
  CopyForBreakpoint(Breakpoint &breakpoint) = 0;

protected:
  // Used for serializing resolver options:
  // The options in this enum and the strings in the g_option_names must be
  // kept in sync.
  enum class OptionNames : uint32_t {
    AddressOffset = 0,
    ExactMatch,
    FileName,
    Inlines,
    LanguageName,
    LineNumber,
    Column,
    ModuleName,
    NameMaskArray,
    Offset,
    PythonClassName,
    RegexString,
    ScriptArgs,
    SectionName,
    SearchDepth,
    SkipPrologue,
    SymbolNameArray,
    LastOptionName
  };
  static const char
      *g_option_names[static_cast<uint32_t>(OptionNames::LastOptionName)];
  
  virtual void NotifyBreakpointSet() {};

public:
  static const char *GetKey(OptionNames enum_value) {
    return g_option_names[static_cast<uint32_t>(enum_value)];
  }

protected:
  /// Takes a symbol context list of matches which supposedly represent the
  /// same file and line number in a CU, and find the nearest actual line
  /// number that matches, and then filter down the matching addresses to
  /// unique entries, and skip the prologue if asked to do so, and then set
  /// breakpoint locations in this breakpoint for all the resultant addresses.
  /// When \p column is nonzero the \p line and \p column args are used to
  /// filter the results to find the first breakpoint >= (line, column).
  void SetSCMatchesByLine(SearchFilter &filter, SymbolContextList &sc_list,
                          bool skip_prologue, llvm::StringRef log_ident,
                          uint32_t line = 0, uint32_t column = 0);
  void SetSCMatchesByLine(SearchFilter &, SymbolContextList &, bool,
                          const char *) = delete;

  lldb::BreakpointLocationSP AddLocation(Address loc_addr,
                                         bool *new_location = nullptr);

  Breakpoint *m_breakpoint; // This is the breakpoint we add locations to.
  lldb::addr_t m_offset;    // A random offset the user asked us to add to any
                            // breakpoints we set.

private:
  /// Helper for \p SetSCMatchesByLine.
  void AddLocation(SearchFilter &filter, const SymbolContext &sc,
                   bool skip_prologue, llvm::StringRef log_ident);

  // Subclass identifier (for llvm isa/dyn_cast)
  const unsigned char SubclassID;
  DISALLOW_COPY_AND_ASSIGN(BreakpointResolver);
};

} // namespace lldb_private

#endif // liblldb_BreakpointResolver_h_