blob: 7a9593b7cb2bfa259722d3e6804e2a6e7d964434 [file] [log] [blame]
Chris Lattner24943d22010-06-08 16:52:24 +00001//===-- BreakpointResolverName.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/BreakpointResolverName.h"
11
12// C Includes
13// C++ Includes
14// Other libraries and framework includes
15// Project includes
16#include "lldb/Breakpoint/BreakpointLocation.h"
17#include "lldb/Core/Log.h"
18#include "lldb/Core/StreamString.h"
Sean Callanan3e80cd92011-10-12 02:08:07 +000019#include "lldb/Symbol/ClangNamespaceDecl.h"
Greg Clayton17cd9952011-04-22 03:55:06 +000020#include "lldb/Target/Target.h"
Chris Lattner24943d22010-06-08 16:52:24 +000021
22using namespace lldb;
23using namespace lldb_private;
24
25BreakpointResolverName::BreakpointResolverName
26(
27 Breakpoint *bkpt,
28 const char *func_name,
Greg Clayton12bec712010-06-28 21:30:43 +000029 uint32_t func_name_type_mask,
Greg Clayton7dd98df2011-07-12 17:06:17 +000030 Breakpoint::MatchType type,
31 bool skip_prologue
Chris Lattner24943d22010-06-08 16:52:24 +000032) :
Johnny Chena62ad7c2010-10-28 17:27:46 +000033 BreakpointResolver (bkpt, BreakpointResolver::NameResolver),
Jim Ingham8b7b2272011-10-07 22:23:45 +000034 m_func_name (func_name),
Greg Clayton12bec712010-06-28 21:30:43 +000035 m_func_name_type_mask (func_name_type_mask),
36 m_class_name (),
Chris Lattner24943d22010-06-08 16:52:24 +000037 m_regex (),
Greg Clayton7dd98df2011-07-12 17:06:17 +000038 m_match_type (type),
39 m_skip_prologue (skip_prologue)
Chris Lattner24943d22010-06-08 16:52:24 +000040{
Greg Clayton48fbdf72010-10-12 04:29:14 +000041
Chris Lattner24943d22010-06-08 16:52:24 +000042 if (m_match_type == Breakpoint::Regexp)
43 {
44 if (!m_regex.Compile (m_func_name.AsCString()))
45 {
Greg Claytone005f2c2010-11-06 01:53:30 +000046 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
Chris Lattner24943d22010-06-08 16:52:24 +000047
48 if (log)
49 log->Warning ("function name regexp: \"%s\" did not compile.", m_func_name.AsCString());
50 }
51 }
52}
53
54BreakpointResolverName::BreakpointResolverName
55(
56 Breakpoint *bkpt,
Greg Clayton7dd98df2011-07-12 17:06:17 +000057 RegularExpression &func_regex,
58 bool skip_prologue
Chris Lattner24943d22010-06-08 16:52:24 +000059) :
Johnny Chena62ad7c2010-10-28 17:27:46 +000060 BreakpointResolver (bkpt, BreakpointResolver::NameResolver),
Chris Lattner24943d22010-06-08 16:52:24 +000061 m_func_name (NULL),
62 m_class_name (NULL),
63 m_regex (func_regex),
Greg Clayton7dd98df2011-07-12 17:06:17 +000064 m_match_type (Breakpoint::Regexp),
65 m_skip_prologue (skip_prologue)
Chris Lattner24943d22010-06-08 16:52:24 +000066{
Chris Lattner24943d22010-06-08 16:52:24 +000067}
68
69BreakpointResolverName::BreakpointResolverName
70(
71 Breakpoint *bkpt,
72 const char *class_name,
73 const char *method,
Greg Clayton7dd98df2011-07-12 17:06:17 +000074 Breakpoint::MatchType type,
75 bool skip_prologue
Chris Lattner24943d22010-06-08 16:52:24 +000076) :
Johnny Chena62ad7c2010-10-28 17:27:46 +000077 BreakpointResolver (bkpt, BreakpointResolver::NameResolver),
Chris Lattner24943d22010-06-08 16:52:24 +000078 m_func_name (method),
79 m_class_name (class_name),
80 m_regex (),
Greg Clayton7dd98df2011-07-12 17:06:17 +000081 m_match_type (type),
82 m_skip_prologue (skip_prologue)
Chris Lattner24943d22010-06-08 16:52:24 +000083{
84
85}
86
87BreakpointResolverName::~BreakpointResolverName ()
88{
89}
90
91// FIXME: Right now we look at the module level, and call the module's "FindFunctions".
92// Greg says he will add function tables, maybe at the CompileUnit level to accelerate function
93// lookup. At that point, we should switch the depth to CompileUnit, and look in these tables.
94
95Searcher::CallbackReturn
96BreakpointResolverName::SearchCallback
97(
98 SearchFilter &filter,
99 SymbolContext &context,
100 Address *addr,
101 bool containing
102)
103{
104 SymbolContextList func_list;
105 SymbolContextList sym_list;
Greg Clayton12bec712010-06-28 21:30:43 +0000106
Chris Lattner24943d22010-06-08 16:52:24 +0000107 uint32_t i;
108 bool new_location;
109 SymbolContext sc;
110 Address break_addr;
111 assert (m_breakpoint != NULL);
Greg Clayton12bec712010-06-28 21:30:43 +0000112
Greg Claytone005f2c2010-11-06 01:53:30 +0000113 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
Greg Clayton12bec712010-06-28 21:30:43 +0000114
Chris Lattner24943d22010-06-08 16:52:24 +0000115 if (m_class_name)
116 {
117 if (log)
118 log->Warning ("Class/method function specification not supported yet.\n");
119 return Searcher::eCallbackReturnStop;
120 }
Greg Clayton12bec712010-06-28 21:30:43 +0000121
Greg Clayton28d5fcc2011-01-27 06:44:37 +0000122 const bool include_symbols = false;
123 const bool append = false;
Jim Inghamd6d47972011-09-23 00:54:11 +0000124 bool filter_by_cu = (filter.GetFilterRequiredItems() & eSymbolContextCompUnit) != 0;
125
Chris Lattner24943d22010-06-08 16:52:24 +0000126 switch (m_match_type)
127 {
Greg Clayton12bec712010-06-28 21:30:43 +0000128 case Breakpoint::Exact:
129 if (context.module_sp)
130 {
Jim Inghamd6d47972011-09-23 00:54:11 +0000131 uint32_t num_functions = context.module_sp->FindFunctions (m_func_name,
Sean Callanan3e80cd92011-10-12 02:08:07 +0000132 NULL,
133 m_func_name_type_mask,
134 include_symbols,
135 append,
136 func_list);
Jim Inghamd6d47972011-09-23 00:54:11 +0000137 // If the search filter specifies a Compilation Unit, then we don't need to bother to look in plain
138 // symbols, since all the ones from a set compilation unit will have been found above already.
139
140 if (num_functions == 0 && !filter_by_cu)
Greg Claytond74270e2011-09-02 04:03:59 +0000141 {
Jim Ingham8b7b2272011-10-07 22:23:45 +0000142 if (m_func_name_type_mask & (eFunctionNameTypeBase | eFunctionNameTypeFull | eFunctionNameTypeAuto))
Sean Callanan3e80cd92011-10-12 02:08:07 +0000143 context.module_sp->FindSymbolsWithNameAndType (m_func_name, NULL, eSymbolTypeCode, sym_list);
Greg Claytond74270e2011-09-02 04:03:59 +0000144 }
Greg Clayton12bec712010-06-28 21:30:43 +0000145 }
146 break;
147 case Breakpoint::Regexp:
148 if (context.module_sp)
149 {
Jim Inghamd6d47972011-09-23 00:54:11 +0000150 if (!filter_by_cu)
151 context.module_sp->FindSymbolsMatchingRegExAndType (m_regex, eSymbolTypeCode, sym_list);
Greg Clayton28d5fcc2011-01-27 06:44:37 +0000152 context.module_sp->FindFunctions (m_regex,
153 include_symbols,
154 append,
155 func_list);
Greg Clayton12bec712010-06-28 21:30:43 +0000156 }
157 break;
158 case Breakpoint::Glob:
159 if (log)
160 log->Warning ("glob is not supported yet.");
161 break;
Chris Lattner24943d22010-06-08 16:52:24 +0000162 }
Jim Inghamd6d47972011-09-23 00:54:11 +0000163
164 // If the filter specifies a Compilation Unit, remove the ones that don't pass at this point.
165 if (filter_by_cu)
166 {
167 uint32_t num_functions = func_list.GetSize();
168
169 for (size_t idx = 0; idx < num_functions; idx++)
170 {
171 SymbolContext sc;
172 func_list.GetContextAtIndex(idx, sc);
173 if (!sc.comp_unit || !filter.CompUnitPasses(*sc.comp_unit))
174 {
175 func_list.RemoveContextAtIndex(idx);
176 num_functions--;
177 idx--;
178 }
179 }
180 }
Jim Inghamd6d47972011-09-23 00:54:11 +0000181
Chris Lattner24943d22010-06-08 16:52:24 +0000182 // Remove any duplicates between the funcion list and the symbol list
183 if (func_list.GetSize())
184 {
185 for (i = 0; i < func_list.GetSize(); i++)
186 {
187 if (func_list.GetContextAtIndex(i, sc) == false)
188 continue;
Greg Clayton12bec712010-06-28 21:30:43 +0000189
Chris Lattner24943d22010-06-08 16:52:24 +0000190 if (sc.function == NULL)
191 continue;
192 uint32_t j = 0;
193 while (j < sym_list.GetSize())
194 {
195 SymbolContext symbol_sc;
196 if (sym_list.GetContextAtIndex(j, symbol_sc))
197 {
198 if (symbol_sc.symbol && symbol_sc.symbol->GetAddressRangePtr())
199 {
200 if (sc.function->GetAddressRange().GetBaseAddress() == symbol_sc.symbol->GetAddressRangePtr()->GetBaseAddress())
201 {
202 sym_list.RemoveContextAtIndex(j);
203 continue; // Don't increment j
204 }
205 }
206 }
Greg Clayton12bec712010-06-28 21:30:43 +0000207
Chris Lattner24943d22010-06-08 16:52:24 +0000208 j++;
209 }
210 }
Greg Clayton12bec712010-06-28 21:30:43 +0000211
Chris Lattner24943d22010-06-08 16:52:24 +0000212 for (i = 0; i < func_list.GetSize(); i++)
213 {
214 if (func_list.GetContextAtIndex(i, sc))
215 {
Greg Claytonfeb6e562010-11-14 00:22:48 +0000216 if (sc.block && sc.block->GetInlinedFunctionInfo())
217 {
218 if (!sc.block->GetStartAddress(break_addr))
219 break_addr.Clear();
220 }
221 else if (sc.function)
Chris Lattner24943d22010-06-08 16:52:24 +0000222 {
223 break_addr = sc.function->GetAddressRange().GetBaseAddress();
Greg Clayton7dd98df2011-07-12 17:06:17 +0000224 if (m_skip_prologue)
Chris Lattner24943d22010-06-08 16:52:24 +0000225 {
Greg Claytonfeb6e562010-11-14 00:22:48 +0000226 if (break_addr.IsValid())
227 {
228 const uint32_t prologue_byte_size = sc.function->GetPrologueByteSize();
229 if (prologue_byte_size)
230 break_addr.SetOffset(break_addr.GetOffset() + prologue_byte_size);
231 }
Chris Lattner24943d22010-06-08 16:52:24 +0000232 }
Greg Claytonfeb6e562010-11-14 00:22:48 +0000233 }
234
235 if (break_addr.IsValid())
236 {
Chris Lattner24943d22010-06-08 16:52:24 +0000237 if (filter.AddressPasses(break_addr))
238 {
239 BreakpointLocationSP bp_loc_sp (m_breakpoint->AddLocation(break_addr, &new_location));
240 if (bp_loc_sp && new_location && !m_breakpoint->IsInternal())
241 {
242 if (log)
243 {
244 StreamString s;
245 bp_loc_sp->GetDescription(&s, lldb::eDescriptionLevelVerbose);
246 log->Printf ("Added location: %s\n", s.GetData());
247 }
248 }
249 }
250 }
251 }
252 }
253 }
Greg Clayton12bec712010-06-28 21:30:43 +0000254
Chris Lattner24943d22010-06-08 16:52:24 +0000255 for (i = 0; i < sym_list.GetSize(); i++)
256 {
257 if (sym_list.GetContextAtIndex(i, sc))
258 {
259 if (sc.symbol && sc.symbol->GetAddressRangePtr())
260 {
261 break_addr = sc.symbol->GetAddressRangePtr()->GetBaseAddress();
Greg Clayton12bec712010-06-28 21:30:43 +0000262
Greg Clayton7dd98df2011-07-12 17:06:17 +0000263 if (m_skip_prologue)
Chris Lattner24943d22010-06-08 16:52:24 +0000264 {
265 const uint32_t prologue_byte_size = sc.symbol->GetPrologueByteSize();
266 if (prologue_byte_size)
267 break_addr.SetOffset(break_addr.GetOffset() + prologue_byte_size);
268 }
Greg Clayton12bec712010-06-28 21:30:43 +0000269
Chris Lattner24943d22010-06-08 16:52:24 +0000270 if (filter.AddressPasses(break_addr))
271 {
272 BreakpointLocationSP bp_loc_sp (m_breakpoint->AddLocation(break_addr, &new_location));
273 if (bp_loc_sp && new_location && !m_breakpoint->IsInternal())
274 {
275 StreamString s;
276 bp_loc_sp->GetDescription(&s, lldb::eDescriptionLevelVerbose);
277 if (log)
278 log->Printf ("Added location: %s\n", s.GetData());
279 }
280 }
281 }
282 }
283 }
284 return Searcher::eCallbackReturnContinue;
285}
286
287Searcher::Depth
288BreakpointResolverName::GetDepth()
289{
290 return Searcher::eDepthModule;
291}
292
293void
294BreakpointResolverName::GetDescription (Stream *s)
295{
Chris Lattner24943d22010-06-08 16:52:24 +0000296 if (m_match_type == Breakpoint::Regexp)
Greg Clayton12bec712010-06-28 21:30:43 +0000297 s->Printf("regex = '%s'", m_regex.GetText());
Greg Clayton48fbdf72010-10-12 04:29:14 +0000298 else
Jim Ingham8b7b2272011-10-07 22:23:45 +0000299 s->Printf("name = '%s'", m_func_name.AsCString());
Chris Lattner24943d22010-06-08 16:52:24 +0000300}
301
302void
303BreakpointResolverName::Dump (Stream *s) const
304{
305
306}
307