1 //===-- BreakpointSite.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_BREAKPOINTSITE_H 10 #define LLDB_BREAKPOINT_BREAKPOINTSITE_H 11 12 #include <list> 13 #include <mutex> 14 15 16 #include "lldb/Breakpoint/BreakpointLocationCollection.h" 17 #include "lldb/Breakpoint/StoppointSite.h" 18 #include "lldb/Utility/LLDBAssert.h" 19 #include "lldb/Utility/UserID.h" 20 #include "lldb/lldb-forward.h" 21 22 namespace lldb_private { 23 24 /// \class BreakpointSite BreakpointSite.h "lldb/Breakpoint/BreakpointSite.h" 25 /// Class that manages the actual breakpoint that will be inserted into the 26 /// running program. 27 /// 28 /// The BreakpointSite class handles the physical breakpoint that is actually 29 /// inserted in the target program. As such, it is also the one that gets 30 /// hit, when the program stops. It keeps a list of all BreakpointLocations 31 /// that share this physical site. When the breakpoint is hit, all the 32 /// locations are informed by the breakpoint site. Breakpoint sites are owned 33 /// by the process. 34 35 class BreakpointSite : public std::enable_shared_from_this<BreakpointSite>, 36 public StoppointSite { 37 public: 38 enum Type { 39 eSoftware, // Breakpoint opcode has been written to memory and 40 // m_saved_opcode 41 // and m_trap_opcode contain the saved and written opcode. 42 eHardware, // Breakpoint site is set as a hardware breakpoint 43 eExternal // Breakpoint site is managed by an external debug nub or 44 // debug interface where memory reads transparently will not 45 // display any breakpoint opcodes. 46 }; 47 48 typedef lldb::break_id_t SiteID; 49 typedef lldb::break_id_t ConstituentID; 50 51 ~BreakpointSite() override; 52 53 // This section manages the breakpoint traps 54 55 /// Returns the Opcode Bytes for this breakpoint 56 uint8_t *GetTrapOpcodeBytes(); 57 58 /// Returns the Opcode Bytes for this breakpoint - const version 59 const uint8_t *GetTrapOpcodeBytes() const; 60 61 /// Get the size of the trap opcode for this address 62 size_t GetTrapOpcodeMaxByteSize() const; 63 64 /// Sets the trap opcode 65 bool SetTrapOpcode(const uint8_t *trap_opcode, uint32_t trap_opcode_size); 66 67 /// Gets the original instruction bytes that were overwritten by the trap 68 uint8_t *GetSavedOpcodeBytes(); 69 70 /// Gets the original instruction bytes that were overwritten by the trap 71 /// const version 72 const uint8_t *GetSavedOpcodeBytes() const; 73 74 /// Says whether \a addr and size \a size intersects with the address \a 75 /// intersect_addr 76 bool IntersectsRange(lldb::addr_t addr, size_t size, 77 lldb::addr_t *intersect_addr, size_t *intersect_size, 78 size_t *opcode_offset) const; 79 80 /// Tells whether the current breakpoint site is enabled or not 81 /// 82 /// This is a low-level enable bit for the breakpoint sites. If a 83 /// breakpoint site has no enabled constituents, it should just get removed. 84 /// This enable/disable is for the low-level target code to enable and disable 85 /// breakpoint sites when single stepping, etc. 86 bool IsEnabled() const; 87 88 /// Sets whether the current breakpoint site is enabled or not 89 /// 90 /// \param[in] enabled 91 /// \b true if the breakpoint is enabled, \b false otherwise. 92 void SetEnabled(bool enabled); 93 94 /// Enquires of the breakpoint locations that produced this breakpoint site 95 /// whether we should stop at this location. 96 /// 97 /// \param[in] context 98 /// This contains the information about this stop. 99 /// 100 /// \return 101 /// \b true if we should stop, \b false otherwise. 102 bool ShouldStop(StoppointCallbackContext *context) override; 103 104 /// Standard Dump method 105 void Dump(Stream *s) const override; 106 107 /// The "Constituents" are the breakpoint locations that share this breakpoint 108 /// site. The method adds the \a constituent to this breakpoint site's 109 /// constituent list. 110 /// 111 /// \param[in] constituent 112 /// \a constituent is the Breakpoint Location to add. 113 void AddConstituent(const lldb::BreakpointLocationSP &constituent); 114 115 /// This method returns the number of breakpoint locations currently located 116 /// at this breakpoint site. 117 /// 118 /// \return 119 /// The number of constituents. 120 size_t GetNumberOfConstituents(); 121 122 /// This method returns the breakpoint location at index \a index located at 123 /// this breakpoint site. The constituents are listed ordinally from 0 to 124 /// GetNumberOfConstituents() - 1 so you can use this method to iterate over 125 /// the constituents 126 /// 127 /// \param[in] idx 128 /// The index in the list of constituents for which you wish the 129 /// constituent location. 130 /// 131 /// \return 132 /// A shared pointer to the breakpoint location at that index. 133 lldb::BreakpointLocationSP GetConstituentAtIndex(size_t idx); 134 135 /// This method copies the breakpoint site's constituents into a new 136 /// collection. It does this while the constituents mutex is locked. 137 /// 138 /// \param[out] out_collection 139 /// The BreakpointLocationCollection into which to put the constituents 140 /// of this breakpoint site. 141 /// 142 /// \return 143 /// The number of elements copied into out_collection. 144 size_t CopyConstituentsList(BreakpointLocationCollection &out_collection); 145 146 /// Check whether the constituents of this breakpoint site have any thread 147 /// specifiers, and if yes, is \a thread contained in any of these 148 /// specifiers. 149 /// 150 /// \param[in] thread 151 /// The thread against which to test. 152 /// 153 /// return 154 /// \b true if the collection contains at least one location that 155 /// would be valid for this thread, false otherwise. 156 bool ValidForThisThread(Thread &thread); 157 158 /// Print a description of this breakpoint site to the stream \a s. 159 /// GetDescription tells you about the breakpoint site's constituents. Use 160 /// BreakpointSite::Dump(Stream *) to get information about the breakpoint 161 /// site itself. 162 /// 163 /// \param[in] s 164 /// The stream to which to print the description. 165 /// 166 /// \param[in] level 167 /// The description level that indicates the detail level to 168 /// provide. 169 /// 170 /// \see lldb::DescriptionLevel 171 void GetDescription(Stream *s, lldb::DescriptionLevel level); 172 173 /// Tell whether a breakpoint has a location at this site. 174 /// 175 /// \param[in] bp_id 176 /// The breakpoint id to query. 177 /// 178 /// \result 179 /// \b true if bp_id has a location that is at this site, 180 /// \b false otherwise. 181 bool IsBreakpointAtThisSite(lldb::break_id_t bp_id); 182 183 /// Tell whether ALL the breakpoints in the location collection are 184 /// internal. 185 /// 186 /// \result 187 /// \b true if all breakpoint locations are owned by internal breakpoints, 188 /// \b false otherwise. 189 bool IsInternal() const; 190 191 bool IsHardware() const override { 192 lldbassert(BreakpointSite::Type::eHardware == GetType() || 193 !HardwareRequired()); 194 return BreakpointSite::Type::eHardware == GetType(); 195 } 196 197 BreakpointSite::Type GetType() const { return m_type; } 198 199 void SetType(BreakpointSite::Type type) { m_type = type; } 200 201 private: 202 friend class Process; 203 friend class BreakpointLocation; 204 // The StopInfoBreakpoint knows when it is processing a hit for a thread for 205 // a site, so let it be the one to manage setting the location hit count once 206 // and only once. 207 friend class StopInfoBreakpoint; 208 209 void BumpHitCounts(); 210 211 /// The method removes the constituent at \a break_loc_id from this breakpoint 212 /// list. 213 size_t RemoveConstituent(lldb::break_id_t break_id, 214 lldb::break_id_t break_loc_id); 215 216 BreakpointSite::Type m_type; ///< The type of this breakpoint site. 217 uint8_t m_saved_opcode[8]; ///< The saved opcode bytes if this breakpoint site 218 ///uses trap opcodes. 219 uint8_t m_trap_opcode[8]; ///< The opcode that was used to create the 220 ///breakpoint if it is a software breakpoint site. 221 bool 222 m_enabled; ///< Boolean indicating if this breakpoint site enabled or not. 223 224 // Consider adding an optimization where if there is only one constituent, we 225 // don't store a list. The usual case will be only one constituent... 226 BreakpointLocationCollection 227 m_constituents; ///< This has the BreakpointLocations 228 /// that share this breakpoint site. 229 std::recursive_mutex m_constituents_mutex; ///< This mutex protects the 230 ///< constituents collection. 231 232 static lldb::break_id_t GetNextID(); 233 234 // Only the Process can create breakpoint sites in 235 // Process::CreateBreakpointSite (lldb::BreakpointLocationSP &, bool). 236 BreakpointSite(const lldb::BreakpointLocationSP &constituent, 237 lldb::addr_t m_addr, bool use_hardware); 238 239 BreakpointSite(const BreakpointSite &) = delete; 240 const BreakpointSite &operator=(const BreakpointSite &) = delete; 241 }; 242 243 } // namespace lldb_private 244 245 #endif // LLDB_BREAKPOINT_BREAKPOINTSITE_H 246