blob: 0f0e06d80fe8dd4780eb793b84f711fc3a2e22d9 [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"
Greg Clayton49ce8962012-08-29 21:13:06 +000018#include "lldb/Core/Module.h"
Chris Lattner24943d22010-06-08 16:52:24 +000019#include "lldb/Core/StreamString.h"
Sean Callanan3e80cd92011-10-12 02:08:07 +000020#include "lldb/Symbol/ClangNamespaceDecl.h"
Greg Clayton49ce8962012-08-29 21:13:06 +000021#include "lldb/Symbol/Block.h"
22#include "lldb/Symbol/Function.h"
23#include "lldb/Symbol/Symbol.h"
24#include "lldb/Symbol/SymbolContext.h"
Chris Lattner24943d22010-06-08 16:52:24 +000025
26using namespace lldb;
27using namespace lldb_private;
28
29BreakpointResolverName::BreakpointResolverName
30(
31 Breakpoint *bkpt,
32 const char *func_name,
Greg Clayton12bec712010-06-28 21:30:43 +000033 uint32_t func_name_type_mask,
Greg Clayton7dd98df2011-07-12 17:06:17 +000034 Breakpoint::MatchType type,
35 bool skip_prologue
Chris Lattner24943d22010-06-08 16:52:24 +000036) :
Johnny Chena62ad7c2010-10-28 17:27:46 +000037 BreakpointResolver (bkpt, BreakpointResolver::NameResolver),
Greg Clayton12bec712010-06-28 21:30:43 +000038 m_func_name_type_mask (func_name_type_mask),
39 m_class_name (),
Chris Lattner24943d22010-06-08 16:52:24 +000040 m_regex (),
Greg Clayton7dd98df2011-07-12 17:06:17 +000041 m_match_type (type),
42 m_skip_prologue (skip_prologue)
Chris Lattner24943d22010-06-08 16:52:24 +000043{
Jim Inghamc1053622012-03-03 02:05:11 +000044
Chris Lattner24943d22010-06-08 16:52:24 +000045 if (m_match_type == Breakpoint::Regexp)
46 {
Jim Inghamc1053622012-03-03 02:05:11 +000047 if (!m_regex.Compile (func_name))
Chris Lattner24943d22010-06-08 16:52:24 +000048 {
Greg Claytone005f2c2010-11-06 01:53:30 +000049 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
Chris Lattner24943d22010-06-08 16:52:24 +000050
51 if (log)
Jim Inghamc1053622012-03-03 02:05:11 +000052 log->Warning ("function name regexp: \"%s\" did not compile.", func_name);
Chris Lattner24943d22010-06-08 16:52:24 +000053 }
54 }
Jim Inghamc1053622012-03-03 02:05:11 +000055 else
56 {
57 m_func_names.push_back(ConstString(func_name));
58 }
59}
60
61BreakpointResolverName::BreakpointResolverName (Breakpoint *bkpt,
62 const char *names[],
63 size_t num_names,
64 uint32_t name_type_mask,
65 bool skip_prologue) :
66 BreakpointResolver (bkpt, BreakpointResolver::NameResolver),
67 m_func_name_type_mask (name_type_mask),
Jim Ingham4722b102012-03-06 00:37:27 +000068 m_match_type (Breakpoint::Exact),
Jim Inghamc1053622012-03-03 02:05:11 +000069 m_skip_prologue (skip_prologue)
70{
71 for (size_t i = 0; i < num_names; i++)
72 {
73 m_func_names.push_back (ConstString (names[i]));
74 }
Chris Lattner24943d22010-06-08 16:52:24 +000075}
76
Jim Ingham4722b102012-03-06 00:37:27 +000077BreakpointResolverName::BreakpointResolverName (Breakpoint *bkpt,
78 std::vector<std::string> names,
79 uint32_t name_type_mask,
80 bool skip_prologue) :
81 BreakpointResolver (bkpt, BreakpointResolver::NameResolver),
82 m_func_name_type_mask (name_type_mask),
83 m_match_type (Breakpoint::Exact),
84 m_skip_prologue (skip_prologue)
85{
86 size_t num_names = names.size();
87
88 for (size_t i = 0; i < num_names; i++)
89 {
90 m_func_names.push_back (ConstString (names[i].c_str()));
91 }
92}
93
Chris Lattner24943d22010-06-08 16:52:24 +000094BreakpointResolverName::BreakpointResolverName
95(
96 Breakpoint *bkpt,
Greg Clayton7dd98df2011-07-12 17:06:17 +000097 RegularExpression &func_regex,
98 bool skip_prologue
Chris Lattner24943d22010-06-08 16:52:24 +000099) :
Johnny Chena62ad7c2010-10-28 17:27:46 +0000100 BreakpointResolver (bkpt, BreakpointResolver::NameResolver),
Chris Lattner24943d22010-06-08 16:52:24 +0000101 m_class_name (NULL),
102 m_regex (func_regex),
Greg Clayton7dd98df2011-07-12 17:06:17 +0000103 m_match_type (Breakpoint::Regexp),
104 m_skip_prologue (skip_prologue)
Chris Lattner24943d22010-06-08 16:52:24 +0000105{
Chris Lattner24943d22010-06-08 16:52:24 +0000106}
107
108BreakpointResolverName::BreakpointResolverName
109(
110 Breakpoint *bkpt,
111 const char *class_name,
112 const char *method,
Greg Clayton7dd98df2011-07-12 17:06:17 +0000113 Breakpoint::MatchType type,
114 bool skip_prologue
Chris Lattner24943d22010-06-08 16:52:24 +0000115) :
Johnny Chena62ad7c2010-10-28 17:27:46 +0000116 BreakpointResolver (bkpt, BreakpointResolver::NameResolver),
Chris Lattner24943d22010-06-08 16:52:24 +0000117 m_class_name (class_name),
118 m_regex (),
Greg Clayton7dd98df2011-07-12 17:06:17 +0000119 m_match_type (type),
120 m_skip_prologue (skip_prologue)
Chris Lattner24943d22010-06-08 16:52:24 +0000121{
Jim Inghamc1053622012-03-03 02:05:11 +0000122 m_func_names.push_back(ConstString(method));
Chris Lattner24943d22010-06-08 16:52:24 +0000123}
124
125BreakpointResolverName::~BreakpointResolverName ()
126{
127}
128
129// FIXME: Right now we look at the module level, and call the module's "FindFunctions".
130// Greg says he will add function tables, maybe at the CompileUnit level to accelerate function
131// lookup. At that point, we should switch the depth to CompileUnit, and look in these tables.
132
133Searcher::CallbackReturn
134BreakpointResolverName::SearchCallback
135(
136 SearchFilter &filter,
137 SymbolContext &context,
138 Address *addr,
139 bool containing
140)
141{
142 SymbolContextList func_list;
143 SymbolContextList sym_list;
Greg Clayton12bec712010-06-28 21:30:43 +0000144
Chris Lattner24943d22010-06-08 16:52:24 +0000145 uint32_t i;
146 bool new_location;
147 SymbolContext sc;
148 Address break_addr;
149 assert (m_breakpoint != NULL);
Greg Clayton12bec712010-06-28 21:30:43 +0000150
Greg Claytone005f2c2010-11-06 01:53:30 +0000151 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
Greg Clayton12bec712010-06-28 21:30:43 +0000152
Chris Lattner24943d22010-06-08 16:52:24 +0000153 if (m_class_name)
154 {
155 if (log)
156 log->Warning ("Class/method function specification not supported yet.\n");
157 return Searcher::eCallbackReturnStop;
158 }
Greg Clayton12bec712010-06-28 21:30:43 +0000159
Greg Clayton28d5fcc2011-01-27 06:44:37 +0000160 const bool include_symbols = false;
Sean Callanan302d78c2012-02-10 22:52:19 +0000161 const bool include_inlines = true;
Jim Inghamc1053622012-03-03 02:05:11 +0000162 const bool append = true;
Jim Inghamd6d47972011-09-23 00:54:11 +0000163 bool filter_by_cu = (filter.GetFilterRequiredItems() & eSymbolContextCompUnit) != 0;
164
Chris Lattner24943d22010-06-08 16:52:24 +0000165 switch (m_match_type)
166 {
Greg Clayton12bec712010-06-28 21:30:43 +0000167 case Breakpoint::Exact:
168 if (context.module_sp)
169 {
Jim Inghamc1053622012-03-03 02:05:11 +0000170 size_t num_names = m_func_names.size();
Jason Molendabf41e192012-10-04 22:47:07 +0000171 for (int j = 0; j < num_names; j++)
Greg Claytond74270e2011-09-02 04:03:59 +0000172 {
Jason Molendabf41e192012-10-04 22:47:07 +0000173 uint32_t num_functions = context.module_sp->FindFunctions (m_func_names[j],
Jim Inghamc1053622012-03-03 02:05:11 +0000174 NULL,
175 m_func_name_type_mask,
176 include_symbols,
177 include_inlines,
178 append,
179 func_list);
180 // If the search filter specifies a Compilation Unit, then we don't need to bother to look in plain
181 // symbols, since all the ones from a set compilation unit will have been found above already.
182
183 if (num_functions == 0 && !filter_by_cu)
184 {
185 if (m_func_name_type_mask & (eFunctionNameTypeBase | eFunctionNameTypeFull | eFunctionNameTypeAuto))
Jason Molendabf41e192012-10-04 22:47:07 +0000186 context.module_sp->FindSymbolsWithNameAndType (m_func_names[j], eSymbolTypeCode, sym_list);
Jim Inghamc1053622012-03-03 02:05:11 +0000187 }
Greg Claytond74270e2011-09-02 04:03:59 +0000188 }
Greg Clayton12bec712010-06-28 21:30:43 +0000189 }
190 break;
191 case Breakpoint::Regexp:
192 if (context.module_sp)
193 {
Jim Inghamd6d47972011-09-23 00:54:11 +0000194 if (!filter_by_cu)
195 context.module_sp->FindSymbolsMatchingRegExAndType (m_regex, eSymbolTypeCode, sym_list);
Greg Clayton28d5fcc2011-01-27 06:44:37 +0000196 context.module_sp->FindFunctions (m_regex,
Sean Callanan302d78c2012-02-10 22:52:19 +0000197 include_symbols,
198 include_inlines,
Greg Clayton28d5fcc2011-01-27 06:44:37 +0000199 append,
200 func_list);
Greg Clayton12bec712010-06-28 21:30:43 +0000201 }
202 break;
203 case Breakpoint::Glob:
204 if (log)
205 log->Warning ("glob is not supported yet.");
206 break;
Chris Lattner24943d22010-06-08 16:52:24 +0000207 }
Jim Inghamd6d47972011-09-23 00:54:11 +0000208
209 // If the filter specifies a Compilation Unit, remove the ones that don't pass at this point.
210 if (filter_by_cu)
211 {
212 uint32_t num_functions = func_list.GetSize();
213
214 for (size_t idx = 0; idx < num_functions; idx++)
215 {
216 SymbolContext sc;
217 func_list.GetContextAtIndex(idx, sc);
218 if (!sc.comp_unit || !filter.CompUnitPasses(*sc.comp_unit))
219 {
220 func_list.RemoveContextAtIndex(idx);
221 num_functions--;
222 idx--;
223 }
224 }
225 }
Jim Inghamd6d47972011-09-23 00:54:11 +0000226
Chris Lattner24943d22010-06-08 16:52:24 +0000227 // Remove any duplicates between the funcion list and the symbol list
228 if (func_list.GetSize())
229 {
230 for (i = 0; i < func_list.GetSize(); i++)
231 {
232 if (func_list.GetContextAtIndex(i, sc) == false)
233 continue;
Greg Clayton12bec712010-06-28 21:30:43 +0000234
Chris Lattner24943d22010-06-08 16:52:24 +0000235 if (sc.function == NULL)
236 continue;
237 uint32_t j = 0;
238 while (j < sym_list.GetSize())
239 {
240 SymbolContext symbol_sc;
241 if (sym_list.GetContextAtIndex(j, symbol_sc))
242 {
Greg Clayton0c31d3d2012-03-07 21:03:09 +0000243 if (symbol_sc.symbol && symbol_sc.symbol->ValueIsAddress())
Chris Lattner24943d22010-06-08 16:52:24 +0000244 {
Greg Clayton0c31d3d2012-03-07 21:03:09 +0000245 if (sc.function->GetAddressRange().GetBaseAddress() == symbol_sc.symbol->GetAddress())
Chris Lattner24943d22010-06-08 16:52:24 +0000246 {
247 sym_list.RemoveContextAtIndex(j);
248 continue; // Don't increment j
249 }
250 }
251 }
Greg Clayton12bec712010-06-28 21:30:43 +0000252
Chris Lattner24943d22010-06-08 16:52:24 +0000253 j++;
254 }
255 }
Greg Clayton12bec712010-06-28 21:30:43 +0000256
Chris Lattner24943d22010-06-08 16:52:24 +0000257 for (i = 0; i < func_list.GetSize(); i++)
258 {
259 if (func_list.GetContextAtIndex(i, sc))
260 {
Greg Claytonfeb6e562010-11-14 00:22:48 +0000261 if (sc.block && sc.block->GetInlinedFunctionInfo())
262 {
263 if (!sc.block->GetStartAddress(break_addr))
264 break_addr.Clear();
265 }
266 else if (sc.function)
Chris Lattner24943d22010-06-08 16:52:24 +0000267 {
268 break_addr = sc.function->GetAddressRange().GetBaseAddress();
Greg Clayton7dd98df2011-07-12 17:06:17 +0000269 if (m_skip_prologue)
Chris Lattner24943d22010-06-08 16:52:24 +0000270 {
Greg Claytonfeb6e562010-11-14 00:22:48 +0000271 if (break_addr.IsValid())
272 {
273 const uint32_t prologue_byte_size = sc.function->GetPrologueByteSize();
274 if (prologue_byte_size)
275 break_addr.SetOffset(break_addr.GetOffset() + prologue_byte_size);
276 }
Chris Lattner24943d22010-06-08 16:52:24 +0000277 }
Greg Claytonfeb6e562010-11-14 00:22:48 +0000278 }
279
280 if (break_addr.IsValid())
281 {
Chris Lattner24943d22010-06-08 16:52:24 +0000282 if (filter.AddressPasses(break_addr))
283 {
284 BreakpointLocationSP bp_loc_sp (m_breakpoint->AddLocation(break_addr, &new_location));
285 if (bp_loc_sp && new_location && !m_breakpoint->IsInternal())
286 {
287 if (log)
288 {
289 StreamString s;
290 bp_loc_sp->GetDescription(&s, lldb::eDescriptionLevelVerbose);
291 log->Printf ("Added location: %s\n", s.GetData());
292 }
293 }
294 }
295 }
296 }
297 }
298 }
Greg Clayton12bec712010-06-28 21:30:43 +0000299
Chris Lattner24943d22010-06-08 16:52:24 +0000300 for (i = 0; i < sym_list.GetSize(); i++)
301 {
302 if (sym_list.GetContextAtIndex(i, sc))
303 {
Greg Clayton0c31d3d2012-03-07 21:03:09 +0000304 if (sc.symbol && sc.symbol->ValueIsAddress())
Chris Lattner24943d22010-06-08 16:52:24 +0000305 {
Greg Clayton0c31d3d2012-03-07 21:03:09 +0000306 break_addr = sc.symbol->GetAddress();
Greg Clayton12bec712010-06-28 21:30:43 +0000307
Greg Clayton7dd98df2011-07-12 17:06:17 +0000308 if (m_skip_prologue)
Chris Lattner24943d22010-06-08 16:52:24 +0000309 {
310 const uint32_t prologue_byte_size = sc.symbol->GetPrologueByteSize();
311 if (prologue_byte_size)
312 break_addr.SetOffset(break_addr.GetOffset() + prologue_byte_size);
313 }
Greg Clayton12bec712010-06-28 21:30:43 +0000314
Chris Lattner24943d22010-06-08 16:52:24 +0000315 if (filter.AddressPasses(break_addr))
316 {
317 BreakpointLocationSP bp_loc_sp (m_breakpoint->AddLocation(break_addr, &new_location));
318 if (bp_loc_sp && new_location && !m_breakpoint->IsInternal())
319 {
320 StreamString s;
321 bp_loc_sp->GetDescription(&s, lldb::eDescriptionLevelVerbose);
322 if (log)
323 log->Printf ("Added location: %s\n", s.GetData());
324 }
325 }
326 }
327 }
328 }
329 return Searcher::eCallbackReturnContinue;
330}
331
332Searcher::Depth
333BreakpointResolverName::GetDepth()
334{
335 return Searcher::eDepthModule;
336}
337
338void
339BreakpointResolverName::GetDescription (Stream *s)
340{
Chris Lattner24943d22010-06-08 16:52:24 +0000341 if (m_match_type == Breakpoint::Regexp)
Greg Clayton12bec712010-06-28 21:30:43 +0000342 s->Printf("regex = '%s'", m_regex.GetText());
Greg Clayton48fbdf72010-10-12 04:29:14 +0000343 else
Jim Inghamc1053622012-03-03 02:05:11 +0000344 {
345 size_t num_names = m_func_names.size();
346 if (num_names == 1)
347 s->Printf("name = '%s'", m_func_names[0].AsCString());
348 else
349 {
350 s->Printf("names = {");
351 for (size_t i = 0; i < num_names - 1; i++)
352 {
353 s->Printf ("'%s', ", m_func_names[i].AsCString());
354 }
355 s->Printf ("'%s'}", m_func_names[num_names - 1].AsCString());
356 }
357 }
Chris Lattner24943d22010-06-08 16:52:24 +0000358}
359
360void
361BreakpointResolverName::Dump (Stream *s) const
362{
363
364}
365