]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Host/common/NativeBreakpointList.cpp
Merge ^/head r274961 through r276342.
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / source / Host / common / NativeBreakpointList.cpp
1 //===-- NativeBreakpointList.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 #include "NativeBreakpointList.h"
11
12 #include "lldb/Core/Log.h"
13
14 #include "NativeBreakpoint.h"
15
16 using namespace lldb;
17 using namespace lldb_private;
18
19 NativeBreakpointList::NativeBreakpointList () :
20     m_mutex (Mutex::eMutexTypeRecursive)
21 {
22 }
23
24 Error
25 NativeBreakpointList::AddRef (lldb::addr_t addr, size_t size_hint, bool hardware, CreateBreakpointFunc create_func)
26 {
27     Log *log (GetLogIfAnyCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
28     if (log)
29         log->Printf ("NativeBreakpointList::%s addr = 0x%" PRIx64 ", size_hint = %lu, hardware = %s", __FUNCTION__, addr, size_hint, hardware ? "true" : "false");
30
31     Mutex::Locker locker (m_mutex);
32
33     // Check if the breakpoint is already set.
34     auto iter = m_breakpoints.find (addr);
35     if (iter != m_breakpoints.end ())
36     {
37         // Yes - bump up ref count.
38         if (log)
39             log->Printf ("NativeBreakpointList::%s addr = 0x%" PRIx64 " -- already enabled, upping ref count", __FUNCTION__, addr);
40
41         iter->second->AddRef ();
42         return Error ();
43     }
44
45     // Create a new breakpoint using the given create func.
46     if (log)
47         log->Printf ("NativeBreakpointList::%s creating breakpoint for addr = 0x%" PRIx64 ", size_hint = %lu, hardware = %s", __FUNCTION__, addr, size_hint, hardware ? "true" : "false");
48
49     NativeBreakpointSP breakpoint_sp;
50     Error error = create_func (addr, size_hint, hardware, breakpoint_sp);
51     if (error.Fail ())
52     {
53         if (log)
54             log->Printf ("NativeBreakpointList::%s creating breakpoint for addr = 0x%" PRIx64 ", size_hint = %lu, hardware = %s -- FAILED: %s", __FUNCTION__, addr, size_hint, hardware ? "true" : "false", error.AsCString ());
55         return error;
56     }
57
58     // Remember the breakpoint.
59     assert (breakpoint_sp && "NativeBreakpoint create function succeeded but returned NULL breakpoint");
60     m_breakpoints.insert (BreakpointMap::value_type (addr, breakpoint_sp));
61
62     return error;
63 }
64
65 Error
66 NativeBreakpointList::DecRef (lldb::addr_t addr)
67 {
68     Error error;
69
70     Log *log (GetLogIfAnyCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
71     if (log)
72         log->Printf ("NativeBreakpointList::%s addr = 0x%" PRIx64, __FUNCTION__, addr);
73
74     Mutex::Locker locker (m_mutex);
75
76     // Check if the breakpoint is already set.
77     auto iter = m_breakpoints.find (addr);
78     if (iter == m_breakpoints.end ())
79     {
80         // Not found!
81         if (log)
82             log->Printf ("NativeBreakpointList::%s addr = 0x%" PRIx64 " -- NOT FOUND", __FUNCTION__, addr);
83         error.SetErrorString ("breakpoint not found");
84         return error;
85     }
86
87     // Decrement ref count.
88     const int32_t new_ref_count = iter->second->DecRef ();
89     assert (new_ref_count >= 0 && "NativeBreakpoint ref count went negative");
90
91     if (new_ref_count > 0)
92     {
93         // Still references to this breakpoint.  Leave it alone.
94         if (log)
95             log->Printf ("NativeBreakpointList::%s addr = 0x%" PRIx64 " -- new breakpoint ref count %" PRIu32, __FUNCTION__, addr, new_ref_count);
96         return error;
97     }
98
99     // Breakpoint has no more references.  Disable it if it's not
100     // already disabled.
101     if (log)
102         log->Printf ("NativeBreakpointList::%s addr = 0x%" PRIx64 " -- removing due to no remaining references", __FUNCTION__, addr);
103
104     // If it's enabled, we need to disable it.
105     if (iter->second->IsEnabled ())
106     {
107         if (log)
108             log->Printf ("NativeBreakpointList::%s addr = 0x%" PRIx64 " -- currently enabled, now disabling", __FUNCTION__, addr);
109         error = iter->second->Disable ();
110         if (error.Fail ())
111         {
112             if (log)
113                 log->Printf ("NativeBreakpointList::%s addr = 0x%" PRIx64 " -- removal FAILED: %s", __FUNCTION__, addr, error.AsCString ());
114             // Continue since we still want to take it out of the breakpoint list.
115         }
116     }
117     else
118     {
119         if (log)
120             log->Printf ("NativeBreakpointList::%s addr = 0x%" PRIx64 " -- already disabled, nothing to do", __FUNCTION__, addr);
121     }
122
123     // Take the breakpoint out of the list.
124     if (log)
125         log->Printf ("NativeBreakpointList::%s addr = 0x%" PRIx64 " -- removed from breakpoint map", __FUNCTION__, addr);
126
127     m_breakpoints.erase (iter);
128     return error;
129 }
130
131 Error
132 NativeBreakpointList::EnableBreakpoint (lldb::addr_t addr)
133 {
134     Log *log (GetLogIfAnyCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
135     if (log)
136         log->Printf ("NativeBreakpointList::%s addr = 0x%" PRIx64, __FUNCTION__, addr);
137
138     Mutex::Locker locker (m_mutex);
139
140     // Ensure we have said breakpoint.
141     auto iter = m_breakpoints.find (addr);
142     if (iter == m_breakpoints.end ())
143     {
144         // Not found!
145         if (log)
146             log->Printf ("NativeBreakpointList::%s addr = 0x%" PRIx64 " -- NOT FOUND", __FUNCTION__, addr);
147         return Error ("breakpoint not found");
148     }
149
150     // Enable it.
151     return iter->second->Enable ();
152 }
153
154 Error
155 NativeBreakpointList::DisableBreakpoint (lldb::addr_t addr)
156 {
157     Log *log (GetLogIfAnyCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
158     if (log)
159         log->Printf ("NativeBreakpointList::%s addr = 0x%" PRIx64, __FUNCTION__, addr);
160
161     Mutex::Locker locker (m_mutex);
162
163     // Ensure we have said breakpoint.
164     auto iter = m_breakpoints.find (addr);
165     if (iter == m_breakpoints.end ())
166     {
167         // Not found!
168         if (log)
169             log->Printf ("NativeBreakpointList::%s addr = 0x%" PRIx64 " -- NOT FOUND", __FUNCTION__, addr);
170         return Error ("breakpoint not found");
171     }
172
173     // Disable it.
174     return iter->second->Disable ();
175 }
176
177 Error
178 NativeBreakpointList::GetBreakpoint (lldb::addr_t addr, NativeBreakpointSP &breakpoint_sp)
179 {
180     Log *log (GetLogIfAnyCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
181     if (log)
182         log->Printf ("NativeBreakpointList::%s addr = 0x%" PRIx64, __FUNCTION__, addr);
183
184     Mutex::Locker locker (m_mutex);
185
186     // Ensure we have said breakpoint.
187     auto iter = m_breakpoints.find (addr);
188     if (iter == m_breakpoints.end ())
189     {
190         // Not found!
191         breakpoint_sp.reset ();
192         return Error ("breakpoint not found");
193     }
194
195     // Disable it.
196     breakpoint_sp = iter->second;
197     return Error ();
198 }
199