]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - contrib/llvm/tools/lldb/source/Breakpoint/BreakpointSite.cpp
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / contrib / llvm / tools / lldb / source / Breakpoint / BreakpointSite.cpp
1 //===-- BreakpointSite.cpp --------------------------------------*- 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 #include "lldb/Breakpoint/BreakpointSite.h"
11
12 // C Includes
13 // C++ Includes
14 // Other libraries and framework includes
15 // Project includes
16 #include "lldb/Breakpoint/Breakpoint.h"
17 #include "lldb/Breakpoint/BreakpointLocation.h"
18 #include "lldb/Breakpoint/BreakpointSiteList.h"
19
20 using namespace lldb;
21 using namespace lldb_private;
22
23 BreakpointSite::BreakpointSite
24 (
25     BreakpointSiteList *list,
26     const BreakpointLocationSP& owner,
27     lldb::addr_t addr,
28     bool use_hardware
29 ) :
30     StoppointLocation(GetNextID(), addr, 0, use_hardware),
31     m_type (eSoftware), // Process subclasses need to set this correctly using SetType()
32     m_saved_opcode(),
33     m_trap_opcode(),
34     m_enabled(false), // Need to create it disabled, so the first enable turns it on.
35     m_owners()
36 {
37     m_owners.Add(owner);
38 }
39
40 BreakpointSite::~BreakpointSite()
41 {
42     BreakpointLocationSP bp_loc_sp;
43     const size_t owner_count = m_owners.GetSize();
44     for (size_t i = 0; i < owner_count; i++)
45     {
46         m_owners.GetByIndex(i)->ClearBreakpointSite();
47     }
48 }
49
50 break_id_t
51 BreakpointSite::GetNextID()
52 {
53     static break_id_t g_next_id = 0;
54     return ++g_next_id;
55 }
56
57 // RETURNS - true if we should stop at this breakpoint, false if we
58 // should continue.
59
60 bool
61 BreakpointSite::ShouldStop (StoppointCallbackContext *context)
62 {
63     IncrementHitCount();
64     return m_owners.ShouldStop (context);
65 }
66
67 bool
68 BreakpointSite::IsBreakpointAtThisSite (lldb::break_id_t bp_id)
69 {
70     const size_t owner_count = m_owners.GetSize();
71     for (size_t i = 0; i < owner_count; i++)
72     {
73         if (m_owners.GetByIndex(i)->GetBreakpoint().GetID() == bp_id)
74             return true;
75     }
76     return false;
77 }
78
79 void
80 BreakpointSite::Dump(Stream *s) const
81 {
82     if (s == NULL)
83         return;
84
85     s->Printf("BreakpointSite %u: addr = 0x%8.8" PRIx64 "  type = %s breakpoint  hw_index = %i  hit_count = %-4u",
86             GetID(),
87             (uint64_t)m_addr,
88             IsHardware() ? "hardware" : "software",
89             GetHardwareIndex(),
90             GetHitCount());
91 }
92
93 void
94 BreakpointSite::GetDescription (Stream *s, lldb::DescriptionLevel level)
95 {
96     if (level != lldb::eDescriptionLevelBrief)
97         s->Printf ("breakpoint site: %d at 0x%8.8" PRIx64, GetID(), GetLoadAddress());
98     m_owners.GetDescription (s, level);
99 }
100
101 bool
102 BreakpointSite::IsInternal() const
103 {
104     return m_owners.IsInternal();
105 }
106
107 uint8_t *
108 BreakpointSite::GetTrapOpcodeBytes()
109 {
110     return &m_trap_opcode[0];
111 }
112
113 const uint8_t *
114 BreakpointSite::GetTrapOpcodeBytes() const
115 {
116     return &m_trap_opcode[0];
117 }
118
119 size_t
120 BreakpointSite::GetTrapOpcodeMaxByteSize() const
121 {
122     return sizeof(m_trap_opcode);
123 }
124
125 bool
126 BreakpointSite::SetTrapOpcode (const uint8_t *trap_opcode, uint32_t trap_opcode_size)
127 {
128     if (trap_opcode_size > 0 && trap_opcode_size <= sizeof(m_trap_opcode))
129     {
130         m_byte_size = trap_opcode_size;
131         ::memcpy (m_trap_opcode, trap_opcode, trap_opcode_size);
132         return true;
133     }
134     m_byte_size = 0;
135     return false;
136 }
137
138 uint8_t *
139 BreakpointSite::GetSavedOpcodeBytes()
140 {
141     return &m_saved_opcode[0];
142 }
143
144 const uint8_t *
145 BreakpointSite::GetSavedOpcodeBytes() const
146 {
147     return &m_saved_opcode[0];
148 }
149
150 bool
151 BreakpointSite::IsEnabled () const
152 {
153     return m_enabled;
154 }
155
156 void
157 BreakpointSite::SetEnabled (bool enabled)
158 {
159     m_enabled = enabled;
160 }
161
162 void
163 BreakpointSite::AddOwner (const BreakpointLocationSP &owner)
164 {
165     m_owners.Add(owner);
166 }
167
168 size_t
169 BreakpointSite::RemoveOwner (lldb::break_id_t break_id, lldb::break_id_t break_loc_id)
170 {
171     m_owners.Remove(break_id, break_loc_id);
172     return m_owners.GetSize();
173 }
174
175 size_t
176 BreakpointSite::GetNumberOfOwners ()
177 {
178     return m_owners.GetSize();
179 }
180
181 BreakpointLocationSP
182 BreakpointSite::GetOwnerAtIndex (size_t index)
183 {
184     return m_owners.GetByIndex (index);
185 }
186
187 bool
188 BreakpointSite::ValidForThisThread (Thread *thread)
189 {
190     return m_owners.ValidForThisThread(thread);
191 }
192
193 bool
194 BreakpointSite::IntersectsRange(lldb::addr_t addr, size_t size, lldb::addr_t *intersect_addr, size_t *intersect_size, size_t *opcode_offset) const
195 {
196     // We only use software traps for software breakpoints
197     if (!IsHardware())
198     {
199         if (m_byte_size > 0)
200         {
201             const lldb::addr_t bp_end_addr = m_addr + m_byte_size;
202             const lldb::addr_t end_addr = addr + size;
203             // Is the breakpoint end address before the passed in start address?
204             if (bp_end_addr <= addr)
205                 return false;
206             // Is the breakpoint start address after passed in end address?
207             if (end_addr <= m_addr)
208                 return false;
209             if (intersect_addr || intersect_size || opcode_offset)
210             {
211                 if (m_addr < addr)
212                 {
213                     if (intersect_addr)
214                         *intersect_addr = addr;
215                     if (intersect_size)
216                         *intersect_size = std::min<lldb::addr_t>(bp_end_addr, end_addr) - addr;
217                     if (opcode_offset)
218                         *opcode_offset = addr - m_addr;
219                 }
220                 else
221                 {
222                     if (intersect_addr)
223                         *intersect_addr = m_addr;
224                     if (intersect_size)
225                         *intersect_size = std::min<lldb::addr_t>(bp_end_addr, end_addr) - m_addr;
226                     if (opcode_offset)
227                         *opcode_offset = 0;
228                 }
229             }
230             return true;
231         }
232     }
233     return false;
234 }