aboutsummaryrefslogtreecommitdiff
path: root/include/lldb/Breakpoint/BreakpointSite.h
blob: 1d2cbea18f9ffe659c841a12704038d7c07a8f98 (plain) (blame)
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
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
//===-- BreakpointSite.h ----------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#ifndef liblldb_BreakpointSite_h_
#define liblldb_BreakpointSite_h_

// C Includes

// C++ Includes
#include <list>

// Other libraries and framework includes

// Project includes
#include "lldb/lldb-private.h"
#include "lldb/Host/Mutex.h"
#include "lldb/Core/UserID.h"
#include "lldb/Breakpoint/StoppointLocation.h"
#include "lldb/Breakpoint/BreakpointLocationCollection.h"

namespace lldb_private {

//----------------------------------------------------------------------
/// @class BreakpointSite BreakpointSite.h "lldb/Breakpoint/BreakpointSite.h"
/// @brief Class that manages the actual breakpoint that will be inserted
/// into the running program.
///
/// The BreakpointSite class handles the physical breakpoint that is
/// actually inserted in the target program.  As such, it is also the
/// one that  gets hit, when the program stops. It keeps a list of all
/// BreakpointLocations that share this physical site. When the
/// breakpoint is hit, all the locations are informed by the breakpoint
/// site. Breakpoint sites are owned by the process.
//----------------------------------------------------------------------

class BreakpointSite : 
    public std::enable_shared_from_this<BreakpointSite>,
    public StoppointLocation
{
public:

    enum Type
    {
        eSoftware,  // Breakpoint opcode has been written to memory and m_saved_opcode
                    // and m_trap_opcode contain the saved and written opcode.
        eHardware,  // Breakpoint site is set as a hardware breakpoint
        eExternal   // Breakpoint site is managed by an external debug nub or
                    // debug interface where memory reads transparently will not
                    // display any breakpoint opcodes.
    };

    virtual ~BreakpointSite ();

    //----------------------------------------------------------------------
    // This section manages the breakpoint traps
    //----------------------------------------------------------------------

    //------------------------------------------------------------------
    /// Returns the Opcode Bytes for this breakpoint
    //------------------------------------------------------------------
    uint8_t *
    GetTrapOpcodeBytes ();

    //------------------------------------------------------------------
    /// Returns the Opcode Bytes for this breakpoint - const version
    //------------------------------------------------------------------
    const uint8_t *
    GetTrapOpcodeBytes () const;

    //------------------------------------------------------------------
    /// Get the size of the trap opcode for this address
    //------------------------------------------------------------------
    size_t
    GetTrapOpcodeMaxByteSize () const;

    //------------------------------------------------------------------
    /// Sets the trap opcode
    //------------------------------------------------------------------
    bool
    SetTrapOpcode (const uint8_t *trap_opcode,
                   uint32_t trap_opcode_size);

    //------------------------------------------------------------------
    /// Gets the original instruction bytes that were overwritten by the trap
    //------------------------------------------------------------------
    uint8_t *
    GetSavedOpcodeBytes ();

    //------------------------------------------------------------------
    /// Gets the original instruction bytes that were overwritten by the trap const version
    //------------------------------------------------------------------
    const uint8_t *
    GetSavedOpcodeBytes () const;

    //------------------------------------------------------------------
    /// Says whether \a addr and size \a size intersects with the address \a intersect_addr
    //------------------------------------------------------------------
    bool
    IntersectsRange (lldb::addr_t addr,
                     size_t size,
                     lldb::addr_t *intersect_addr,
                     size_t *intersect_size,
                     size_t *opcode_offset) const;

    //------------------------------------------------------------------
    /// Tells whether the current breakpoint site is enabled or not
    ///
    /// This is a low-level enable bit for the breakpoint sites.  If a
    /// breakpoint site has no enabled owners, it should just get
    /// removed.  This enable/disable is for the low-level target code
    /// to enable and disable breakpoint sites when single stepping,
    /// etc.
    //------------------------------------------------------------------
    bool
    IsEnabled () const;

    //------------------------------------------------------------------
    /// Sets whether the current breakpoint site is enabled or not
    ///
    /// @param[in] enabled
    ///    \b true if the breakpoint is enabled, \b false otherwise.
    //------------------------------------------------------------------
    void
    SetEnabled (bool enabled);

    //------------------------------------------------------------------
    /// Enquires of the breakpoint locations that produced this breakpoint site whether
    /// we should stop at this location.
    ///
    /// @param[in] context
    ///    This contains the information about this stop.
    ///
    /// @return
    ///    \b true if we should stop, \b false otherwise.
    //------------------------------------------------------------------
    virtual bool
    ShouldStop (StoppointCallbackContext *context);

    //------------------------------------------------------------------
    /// Standard Dump method
    ///
    /// @param[in] context
    ///    The stream to dump this output.
    //------------------------------------------------------------------
    void
    Dump (Stream *s) const;

    //------------------------------------------------------------------
    /// The "Owners" are the breakpoint locations that share this
    /// breakpoint site. The method adds the \a owner to this breakpoint
    /// site's owner list.
    ///
    /// @param[in] context
    ///    \a owner is the Breakpoint Location to add.
    //------------------------------------------------------------------
    void
    AddOwner (const lldb::BreakpointLocationSP &owner);

    //------------------------------------------------------------------
    /// This method returns the number of breakpoint locations currently
    /// located at this breakpoint site.
    ///
    /// @return
    ///    The number of owners.
    //------------------------------------------------------------------
    size_t
    GetNumberOfOwners ();

    //------------------------------------------------------------------
    /// This method returns the breakpoint location at index \a index
    /// located at this breakpoint site.  The owners are listed ordinally
    /// from 0 to GetNumberOfOwners() - 1 so you can use this method to iterate
    /// over the owners
    ///
    /// @param[in] index
    ///     The index in the list of owners for which you wish the owner location.
    /// @return
    ///    A shared pointer to the breakpoint location at that index.
    //------------------------------------------------------------------
    lldb::BreakpointLocationSP
    GetOwnerAtIndex (size_t idx);
    
    //------------------------------------------------------------------
    /// Check whether the owners of this breakpoint site have any
    /// thread specifiers, and if yes, is \a thread contained in any
    /// of these specifiers.
    ///
    /// @param[in] thread
    ///     The thread against which to test.
    ///
    /// return
    ///     \b true if the collection contains at least one location that
    ///     would be valid for this thread, false otherwise.
    //------------------------------------------------------------------
    bool 
    ValidForThisThread (Thread *thread);


    //------------------------------------------------------------------
    /// Print a description of this breakpoint site to the stream \a s.
    /// GetDescription tells you about the breakpoint site's owners.
    /// Use BreakpointSite::Dump(Stream *) to get information about the
    /// breakpoint site itself.
    ///
    /// @param[in] s
    ///     The stream to which to print the description.
    ///
    /// @param[in] level
    ///     The description level that indicates the detail level to
    ///     provide.
    ///
    /// @see lldb::DescriptionLevel
    //------------------------------------------------------------------
    void
    GetDescription (Stream *s,
                    lldb::DescriptionLevel level);

    //------------------------------------------------------------------
    /// Tell whether a breakpoint has a location at this site.
    ///
    /// @param[in] bp_id
    ///     The breakpoint id to query.
    ///
    /// @result
    ///     \b true if bp_id has a location that is at this site,
    ///     \b false otherwise.
    //------------------------------------------------------------------
    bool
    IsBreakpointAtThisSite (lldb::break_id_t bp_id);

    //------------------------------------------------------------------
    /// Tell whether ALL the breakpoints in the location collection are internal.
    ///
    /// @result
    ///     \b true if all breakpoint locations are owned by internal breakpoints,
    ///     \b false otherwise.
    //------------------------------------------------------------------
    bool
    IsInternal () const;
    
    BreakpointSite::Type
    GetType () const
    {
        return m_type;
    }

    void
    SetType (BreakpointSite::Type type)
    {
        m_type = type;
    }

private:
    friend class Process;
    friend class BreakpointLocation;

    //------------------------------------------------------------------
    /// The method removes the owner at \a break_loc_id from this breakpoint list.
    ///
    /// @param[in] context
    ///    \a break_loc_id is the Breakpoint Location to remove.
    //------------------------------------------------------------------
    size_t
    RemoveOwner (lldb::break_id_t break_id,
                 lldb::break_id_t break_loc_id);

    BreakpointSite::Type m_type;///< The type of this breakpoint site.
    uint8_t m_saved_opcode[8];  ///< The saved opcode bytes if this breakpoint site uses trap opcodes.
    uint8_t m_trap_opcode[8];   ///< The opcode that was used to create the breakpoint if it is a software breakpoint site.
    bool m_enabled;             ///< Boolean indicating if this breakpoint site enabled or not.

    // Consider adding an optimization where if there is only one
    // owner, we don't store a list.  The usual case will be only one owner...
    BreakpointLocationCollection m_owners; ///< This has the BreakpointLocations that share this breakpoint site.
    Mutex m_owners_mutex;      ///< This mutex protects the owners collection. 

    static lldb::break_id_t
    GetNextID();

    // Only the Process can create breakpoint sites in
    // Process::CreateBreakpointSite (lldb::BreakpointLocationSP &, bool).
    BreakpointSite (BreakpointSiteList *list,
                    const lldb::BreakpointLocationSP& owner,
                    lldb::addr_t m_addr,
                    bool use_hardware);

    DISALLOW_COPY_AND_ASSIGN(BreakpointSite);
};

} // namespace lldb_private

#endif  // liblldb_BreakpointSite_h_