blob: 7b7e7a4f8d02dbc98b35e75751b657ff17854099 [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),
Greg Clayton12bec712010-06-28 21:30:43 +000034 m_func_name_type_mask (func_name_type_mask),
35 m_class_name (),
Chris Lattner24943d22010-06-08 16:52:24 +000036 m_regex (),
Greg Clayton7dd98df2011-07-12 17:06:17 +000037 m_match_type (type),
38 m_skip_prologue (skip_prologue)
Chris Lattner24943d22010-06-08 16:52:24 +000039{
Jim Inghamc1053622012-03-03 02:05:11 +000040
Chris Lattner24943d22010-06-08 16:52:24 +000041 if (m_match_type == Breakpoint::Regexp)
42 {
Jim Inghamc1053622012-03-03 02:05:11 +000043 if (!m_regex.Compile (func_name))
Chris Lattner24943d22010-06-08 16:52:24 +000044 {
Greg Claytone005f2c2010-11-06 01:53:30 +000045 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
Chris Lattner24943d22010-06-08 16:52:24 +000046
47 if (log)
Jim Inghamc1053622012-03-03 02:05:11 +000048 log->Warning ("function name regexp: \"%s\" did not compile.", func_name);
Chris Lattner24943d22010-06-08 16:52:24 +000049 }
50 }
Jim Inghamc1053622012-03-03 02:05:11 +000051 else
52 {
53 m_func_names.push_back(ConstString(func_name));
54 }
55}
56
57BreakpointResolverName::BreakpointResolverName (Breakpoint *bkpt,
58 const char *names[],
59 size_t num_names,
60 uint32_t name_type_mask,
61 bool skip_prologue) :
62 BreakpointResolver (bkpt, BreakpointResolver::NameResolver),
63 m_func_name_type_mask (name_type_mask),
64 m_skip_prologue (skip_prologue)
65{
66 for (size_t i = 0; i < num_names; i++)
67 {
68 m_func_names.push_back (ConstString (names[i]));
69 }
Chris Lattner24943d22010-06-08 16:52:24 +000070}
71
72BreakpointResolverName::BreakpointResolverName
73(
74 Breakpoint *bkpt,
Greg Clayton7dd98df2011-07-12 17:06:17 +000075 RegularExpression &func_regex,
76 bool skip_prologue
Chris Lattner24943d22010-06-08 16:52:24 +000077) :
Johnny Chena62ad7c2010-10-28 17:27:46 +000078 BreakpointResolver (bkpt, BreakpointResolver::NameResolver),
Chris Lattner24943d22010-06-08 16:52:24 +000079 m_class_name (NULL),
80 m_regex (func_regex),
Greg Clayton7dd98df2011-07-12 17:06:17 +000081 m_match_type (Breakpoint::Regexp),
82 m_skip_prologue (skip_prologue)
Chris Lattner24943d22010-06-08 16:52:24 +000083{
Chris Lattner24943d22010-06-08 16:52:24 +000084}
85
86BreakpointResolverName::BreakpointResolverName
87(
88 Breakpoint *bkpt,
89 const char *class_name,
90 const char *method,
Greg Clayton7dd98df2011-07-12 17:06:17 +000091 Breakpoint::MatchType type,
92 bool skip_prologue
Chris Lattner24943d22010-06-08 16:52:24 +000093) :
Johnny Chena62ad7c2010-10-28 17:27:46 +000094 BreakpointResolver (bkpt, BreakpointResolver::NameResolver),
Chris Lattner24943d22010-06-08 16:52:24 +000095 m_class_name (class_name),
96 m_regex (),
Greg Clayton7dd98df2011-07-12 17:06:17 +000097 m_match_type (type),
98 m_skip_prologue (skip_prologue)
Chris Lattner24943d22010-06-08 16:52:24 +000099{
Jim Inghamc1053622012-03-03 02:05:11 +0000100 m_func_names.push_back(ConstString(method));
Chris Lattner24943d22010-06-08 16:52:24 +0000101}
102
103BreakpointResolverName::~BreakpointResolverName ()
104{
105}
106
107// FIXME: Right now we look at the module level, and call the module's "FindFunctions".
108// Greg says he will add function tables, maybe at the CompileUnit level to accelerate function
109// lookup. At that point, we should switch the depth to CompileUnit, and look in these tables.
110
111Searcher::CallbackReturn
112BreakpointResolverName::SearchCallback
113(
114 SearchFilter &filter,
115 SymbolContext &context,
116 Address *addr,
117 bool containing
118)
119{
120 SymbolContextList func_list;
121 SymbolContextList sym_list;
Greg Clayton12bec712010-06-28 21:30:43 +0000122
Chris Lattner24943d22010-06-08 16:52:24 +0000123 uint32_t i;
124 bool new_location;
125 SymbolContext sc;
126 Address break_addr;
127 assert (m_breakpoint != NULL);
Greg Clayton12bec712010-06-28 21:30:43 +0000128
Greg Claytone005f2c2010-11-06 01:53:30 +0000129 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
Greg Clayton12bec712010-06-28 21:30:43 +0000130
Chris Lattner24943d22010-06-08 16:52:24 +0000131 if (m_class_name)
132 {
133 if (log)
134 log->Warning ("Class/method function specification not supported yet.\n");
135 return Searcher::eCallbackReturnStop;
136 }
Greg Clayton12bec712010-06-28 21:30:43 +0000137
Greg Clayton28d5fcc2011-01-27 06:44:37 +0000138 const bool include_symbols = false;
Sean Callanan302d78c2012-02-10 22:52:19 +0000139 const bool include_inlines = true;
Jim Inghamc1053622012-03-03 02:05:11 +0000140 const bool append = true;
Jim Inghamd6d47972011-09-23 00:54:11 +0000141 bool filter_by_cu = (filter.GetFilterRequiredItems() & eSymbolContextCompUnit) != 0;
142
Chris Lattner24943d22010-06-08 16:52:24 +0000143 switch (m_match_type)
144 {
Greg Clayton12bec712010-06-28 21:30:43 +0000145 case Breakpoint::Exact:
146 if (context.module_sp)
147 {
Jim Inghamc1053622012-03-03 02:05:11 +0000148 size_t num_names = m_func_names.size();
149 for (int i = 0; i < num_names; i++)
Greg Claytond74270e2011-09-02 04:03:59 +0000150 {
Jim Inghamc1053622012-03-03 02:05:11 +0000151 uint32_t num_functions = context.module_sp->FindFunctions (m_func_names[i],
152 NULL,
153 m_func_name_type_mask,
154 include_symbols,
155 include_inlines,
156 append,
157 func_list);
158 // If the search filter specifies a Compilation Unit, then we don't need to bother to look in plain
159 // symbols, since all the ones from a set compilation unit will have been found above already.
160
161 if (num_functions == 0 && !filter_by_cu)
162 {
163 if (m_func_name_type_mask & (eFunctionNameTypeBase | eFunctionNameTypeFull | eFunctionNameTypeAuto))
164 context.module_sp->FindSymbolsWithNameAndType (m_func_names[i], eSymbolTypeCode, sym_list);
165 }
Greg Claytond74270e2011-09-02 04:03:59 +0000166 }
Greg Clayton12bec712010-06-28 21:30:43 +0000167 }
168 break;
169 case Breakpoint::Regexp:
170 if (context.module_sp)
171 {
Jim Inghamd6d47972011-09-23 00:54:11 +0000172 if (!filter_by_cu)
173 context.module_sp->FindSymbolsMatchingRegExAndType (m_regex, eSymbolTypeCode, sym_list);
Greg Clayton28d5fcc2011-01-27 06:44:37 +0000174 context.module_sp->FindFunctions (m_regex,
Sean Callanan302d78c2012-02-10 22:52:19 +0000175 include_symbols,
176 include_inlines,
Greg Clayton28d5fcc2011-01-27 06:44:37 +0000177 append,
178 func_list);
Greg Clayton12bec712010-06-28 21:30:43 +0000179 }
180 break;
181 case Breakpoint::Glob:
182 if (log)
183 log->Warning ("glob is not supported yet.");
184 break;
Chris Lattner24943d22010-06-08 16:52:24 +0000185 }
Jim Inghamd6d47972011-09-23 00:54:11 +0000186
187 // If the filter specifies a Compilation Unit, remove the ones that don't pass at this point.
188 if (filter_by_cu)
189 {
190 uint32_t num_functions = func_list.GetSize();
191
192 for (size_t idx = 0; idx < num_functions; idx++)
193 {
194 SymbolContext sc;
195 func_list.GetContextAtIndex(idx, sc);
196 if (!sc.comp_unit || !filter.CompUnitPasses(*sc.comp_unit))
197 {
198 func_list.RemoveContextAtIndex(idx);
199 num_functions--;
200 idx--;
201 }
202 }
203 }
Jim Inghamd6d47972011-09-23 00:54:11 +0000204
Chris Lattner24943d22010-06-08 16:52:24 +0000205 // Remove any duplicates between the funcion list and the symbol list
206 if (func_list.GetSize())
207 {
208 for (i = 0; i < func_list.GetSize(); i++)
209 {
210 if (func_list.GetContextAtIndex(i, sc) == false)
211 continue;
Greg Clayton12bec712010-06-28 21:30:43 +0000212
Chris Lattner24943d22010-06-08 16:52:24 +0000213 if (sc.function == NULL)
214 continue;
215 uint32_t j = 0;
216 while (j < sym_list.GetSize())
217 {
218 SymbolContext symbol_sc;
219 if (sym_list.GetContextAtIndex(j, symbol_sc))
220 {
221 if (symbol_sc.symbol && symbol_sc.symbol->GetAddressRangePtr())
222 {
223 if (sc.function->GetAddressRange().GetBaseAddress() == symbol_sc.symbol->GetAddressRangePtr()->GetBaseAddress())
224 {
225 sym_list.RemoveContextAtIndex(j);
226 continue; // Don't increment j
227 }
228 }
229 }
Greg Clayton12bec712010-06-28 21:30:43 +0000230
Chris Lattner24943d22010-06-08 16:52:24 +0000231 j++;
232 }
233 }
Greg Clayton12bec712010-06-28 21:30:43 +0000234
Chris Lattner24943d22010-06-08 16:52:24 +0000235 for (i = 0; i < func_list.GetSize(); i++)
236 {
237 if (func_list.GetContextAtIndex(i, sc))
238 {
Greg Claytonfeb6e562010-11-14 00:22:48 +0000239 if (sc.block && sc.block->GetInlinedFunctionInfo())
240 {
241 if (!sc.block->GetStartAddress(break_addr))
242 break_addr.Clear();
243 }
244 else if (sc.function)
Chris Lattner24943d22010-06-08 16:52:24 +0000245 {
246 break_addr = sc.function->GetAddressRange().GetBaseAddress();
Greg Clayton7dd98df2011-07-12 17:06:17 +0000247 if (m_skip_prologue)
Chris Lattner24943d22010-06-08 16:52:24 +0000248 {
Greg Claytonfeb6e562010-11-14 00:22:48 +0000249 if (break_addr.IsValid())
250 {
251 const uint32_t prologue_byte_size = sc.function->GetPrologueByteSize();
252 if (prologue_byte_size)
253 break_addr.SetOffset(break_addr.GetOffset() + prologue_byte_size);
254 }
Chris Lattner24943d22010-06-08 16:52:24 +0000255 }
Greg Claytonfeb6e562010-11-14 00:22:48 +0000256 }
257
258 if (break_addr.IsValid())
259 {
Chris Lattner24943d22010-06-08 16:52:24 +0000260 if (filter.AddressPasses(break_addr))
261 {
262 BreakpointLocationSP bp_loc_sp (m_breakpoint->AddLocation(break_addr, &new_location));
263 if (bp_loc_sp && new_location && !m_breakpoint->IsInternal())
264 {
265 if (log)
266 {
267 StreamString s;
268 bp_loc_sp->GetDescription(&s, lldb::eDescriptionLevelVerbose);
269 log->Printf ("Added location: %s\n", s.GetData());
270 }
271 }
272 }
273 }
274 }
275 }
276 }
Greg Clayton12bec712010-06-28 21:30:43 +0000277
Chris Lattner24943d22010-06-08 16:52:24 +0000278 for (i = 0; i < sym_list.GetSize(); i++)
279 {
280 if (sym_list.GetContextAtIndex(i, sc))
281 {
282 if (sc.symbol && sc.symbol->GetAddressRangePtr())
283 {
284 break_addr = sc.symbol->GetAddressRangePtr()->GetBaseAddress();
Greg Clayton12bec712010-06-28 21:30:43 +0000285
Greg Clayton7dd98df2011-07-12 17:06:17 +0000286 if (m_skip_prologue)
Chris Lattner24943d22010-06-08 16:52:24 +0000287 {
288 const uint32_t prologue_byte_size = sc.symbol->GetPrologueByteSize();
289 if (prologue_byte_size)
290 break_addr.SetOffset(break_addr.GetOffset() + prologue_byte_size);
291 }
Greg Clayton12bec712010-06-28 21:30:43 +0000292
Chris Lattner24943d22010-06-08 16:52:24 +0000293 if (filter.AddressPasses(break_addr))
294 {
295 BreakpointLocationSP bp_loc_sp (m_breakpoint->AddLocation(break_addr, &new_location));
296 if (bp_loc_sp && new_location && !m_breakpoint->IsInternal())
297 {
298 StreamString s;
299 bp_loc_sp->GetDescription(&s, lldb::eDescriptionLevelVerbose);
300 if (log)
301 log->Printf ("Added location: %s\n", s.GetData());
302 }
303 }
304 }
305 }
306 }
307 return Searcher::eCallbackReturnContinue;
308}
309
310Searcher::Depth
311BreakpointResolverName::GetDepth()
312{
313 return Searcher::eDepthModule;
314}
315
316void
317BreakpointResolverName::GetDescription (Stream *s)
318{
Chris Lattner24943d22010-06-08 16:52:24 +0000319 if (m_match_type == Breakpoint::Regexp)
Greg Clayton12bec712010-06-28 21:30:43 +0000320 s->Printf("regex = '%s'", m_regex.GetText());
Greg Clayton48fbdf72010-10-12 04:29:14 +0000321 else
Jim Inghamc1053622012-03-03 02:05:11 +0000322 {
323 size_t num_names = m_func_names.size();
324 if (num_names == 1)
325 s->Printf("name = '%s'", m_func_names[0].AsCString());
326 else
327 {
328 s->Printf("names = {");
329 for (size_t i = 0; i < num_names - 1; i++)
330 {
331 s->Printf ("'%s', ", m_func_names[i].AsCString());
332 }
333 s->Printf ("'%s'}", m_func_names[num_names - 1].AsCString());
334 }
335 }
Chris Lattner24943d22010-06-08 16:52:24 +0000336}
337
338void
339BreakpointResolverName::Dump (Stream *s) const
340{
341
342}
343