blob: 616307a0906d28d581f57b69570c3760ddaccb5f [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),
Jim Ingham4722b102012-03-06 00:37:27 +000064 m_match_type (Breakpoint::Exact),
Jim Inghamc1053622012-03-03 02:05:11 +000065 m_skip_prologue (skip_prologue)
66{
67 for (size_t i = 0; i < num_names; i++)
68 {
69 m_func_names.push_back (ConstString (names[i]));
70 }
Chris Lattner24943d22010-06-08 16:52:24 +000071}
72
Jim Ingham4722b102012-03-06 00:37:27 +000073BreakpointResolverName::BreakpointResolverName (Breakpoint *bkpt,
74 std::vector<std::string> names,
75 uint32_t name_type_mask,
76 bool skip_prologue) :
77 BreakpointResolver (bkpt, BreakpointResolver::NameResolver),
78 m_func_name_type_mask (name_type_mask),
79 m_match_type (Breakpoint::Exact),
80 m_skip_prologue (skip_prologue)
81{
82 size_t num_names = names.size();
83
84 for (size_t i = 0; i < num_names; i++)
85 {
86 m_func_names.push_back (ConstString (names[i].c_str()));
87 }
88}
89
Chris Lattner24943d22010-06-08 16:52:24 +000090BreakpointResolverName::BreakpointResolverName
91(
92 Breakpoint *bkpt,
Greg Clayton7dd98df2011-07-12 17:06:17 +000093 RegularExpression &func_regex,
94 bool skip_prologue
Chris Lattner24943d22010-06-08 16:52:24 +000095) :
Johnny Chena62ad7c2010-10-28 17:27:46 +000096 BreakpointResolver (bkpt, BreakpointResolver::NameResolver),
Chris Lattner24943d22010-06-08 16:52:24 +000097 m_class_name (NULL),
98 m_regex (func_regex),
Greg Clayton7dd98df2011-07-12 17:06:17 +000099 m_match_type (Breakpoint::Regexp),
100 m_skip_prologue (skip_prologue)
Chris Lattner24943d22010-06-08 16:52:24 +0000101{
Chris Lattner24943d22010-06-08 16:52:24 +0000102}
103
104BreakpointResolverName::BreakpointResolverName
105(
106 Breakpoint *bkpt,
107 const char *class_name,
108 const char *method,
Greg Clayton7dd98df2011-07-12 17:06:17 +0000109 Breakpoint::MatchType type,
110 bool skip_prologue
Chris Lattner24943d22010-06-08 16:52:24 +0000111) :
Johnny Chena62ad7c2010-10-28 17:27:46 +0000112 BreakpointResolver (bkpt, BreakpointResolver::NameResolver),
Chris Lattner24943d22010-06-08 16:52:24 +0000113 m_class_name (class_name),
114 m_regex (),
Greg Clayton7dd98df2011-07-12 17:06:17 +0000115 m_match_type (type),
116 m_skip_prologue (skip_prologue)
Chris Lattner24943d22010-06-08 16:52:24 +0000117{
Jim Inghamc1053622012-03-03 02:05:11 +0000118 m_func_names.push_back(ConstString(method));
Chris Lattner24943d22010-06-08 16:52:24 +0000119}
120
121BreakpointResolverName::~BreakpointResolverName ()
122{
123}
124
125// FIXME: Right now we look at the module level, and call the module's "FindFunctions".
126// Greg says he will add function tables, maybe at the CompileUnit level to accelerate function
127// lookup. At that point, we should switch the depth to CompileUnit, and look in these tables.
128
129Searcher::CallbackReturn
130BreakpointResolverName::SearchCallback
131(
132 SearchFilter &filter,
133 SymbolContext &context,
134 Address *addr,
135 bool containing
136)
137{
138 SymbolContextList func_list;
139 SymbolContextList sym_list;
Greg Clayton12bec712010-06-28 21:30:43 +0000140
Chris Lattner24943d22010-06-08 16:52:24 +0000141 uint32_t i;
142 bool new_location;
143 SymbolContext sc;
144 Address break_addr;
145 assert (m_breakpoint != NULL);
Greg Clayton12bec712010-06-28 21:30:43 +0000146
Greg Claytone005f2c2010-11-06 01:53:30 +0000147 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
Greg Clayton12bec712010-06-28 21:30:43 +0000148
Chris Lattner24943d22010-06-08 16:52:24 +0000149 if (m_class_name)
150 {
151 if (log)
152 log->Warning ("Class/method function specification not supported yet.\n");
153 return Searcher::eCallbackReturnStop;
154 }
Greg Clayton12bec712010-06-28 21:30:43 +0000155
Greg Clayton28d5fcc2011-01-27 06:44:37 +0000156 const bool include_symbols = false;
Sean Callanan302d78c2012-02-10 22:52:19 +0000157 const bool include_inlines = true;
Jim Inghamc1053622012-03-03 02:05:11 +0000158 const bool append = true;
Jim Inghamd6d47972011-09-23 00:54:11 +0000159 bool filter_by_cu = (filter.GetFilterRequiredItems() & eSymbolContextCompUnit) != 0;
160
Chris Lattner24943d22010-06-08 16:52:24 +0000161 switch (m_match_type)
162 {
Greg Clayton12bec712010-06-28 21:30:43 +0000163 case Breakpoint::Exact:
164 if (context.module_sp)
165 {
Jim Inghamc1053622012-03-03 02:05:11 +0000166 size_t num_names = m_func_names.size();
167 for (int i = 0; i < num_names; i++)
Greg Claytond74270e2011-09-02 04:03:59 +0000168 {
Jim Inghamc1053622012-03-03 02:05:11 +0000169 uint32_t num_functions = context.module_sp->FindFunctions (m_func_names[i],
170 NULL,
171 m_func_name_type_mask,
172 include_symbols,
173 include_inlines,
174 append,
175 func_list);
176 // If the search filter specifies a Compilation Unit, then we don't need to bother to look in plain
177 // symbols, since all the ones from a set compilation unit will have been found above already.
178
179 if (num_functions == 0 && !filter_by_cu)
180 {
181 if (m_func_name_type_mask & (eFunctionNameTypeBase | eFunctionNameTypeFull | eFunctionNameTypeAuto))
182 context.module_sp->FindSymbolsWithNameAndType (m_func_names[i], eSymbolTypeCode, sym_list);
183 }
Greg Claytond74270e2011-09-02 04:03:59 +0000184 }
Greg Clayton12bec712010-06-28 21:30:43 +0000185 }
186 break;
187 case Breakpoint::Regexp:
188 if (context.module_sp)
189 {
Jim Inghamd6d47972011-09-23 00:54:11 +0000190 if (!filter_by_cu)
191 context.module_sp->FindSymbolsMatchingRegExAndType (m_regex, eSymbolTypeCode, sym_list);
Greg Clayton28d5fcc2011-01-27 06:44:37 +0000192 context.module_sp->FindFunctions (m_regex,
Sean Callanan302d78c2012-02-10 22:52:19 +0000193 include_symbols,
194 include_inlines,
Greg Clayton28d5fcc2011-01-27 06:44:37 +0000195 append,
196 func_list);
Greg Clayton12bec712010-06-28 21:30:43 +0000197 }
198 break;
199 case Breakpoint::Glob:
200 if (log)
201 log->Warning ("glob is not supported yet.");
202 break;
Chris Lattner24943d22010-06-08 16:52:24 +0000203 }
Jim Inghamd6d47972011-09-23 00:54:11 +0000204
205 // If the filter specifies a Compilation Unit, remove the ones that don't pass at this point.
206 if (filter_by_cu)
207 {
208 uint32_t num_functions = func_list.GetSize();
209
210 for (size_t idx = 0; idx < num_functions; idx++)
211 {
212 SymbolContext sc;
213 func_list.GetContextAtIndex(idx, sc);
214 if (!sc.comp_unit || !filter.CompUnitPasses(*sc.comp_unit))
215 {
216 func_list.RemoveContextAtIndex(idx);
217 num_functions--;
218 idx--;
219 }
220 }
221 }
Jim Inghamd6d47972011-09-23 00:54:11 +0000222
Chris Lattner24943d22010-06-08 16:52:24 +0000223 // Remove any duplicates between the funcion list and the symbol list
224 if (func_list.GetSize())
225 {
226 for (i = 0; i < func_list.GetSize(); i++)
227 {
228 if (func_list.GetContextAtIndex(i, sc) == false)
229 continue;
Greg Clayton12bec712010-06-28 21:30:43 +0000230
Chris Lattner24943d22010-06-08 16:52:24 +0000231 if (sc.function == NULL)
232 continue;
233 uint32_t j = 0;
234 while (j < sym_list.GetSize())
235 {
236 SymbolContext symbol_sc;
237 if (sym_list.GetContextAtIndex(j, symbol_sc))
238 {
239 if (symbol_sc.symbol && symbol_sc.symbol->GetAddressRangePtr())
240 {
241 if (sc.function->GetAddressRange().GetBaseAddress() == symbol_sc.symbol->GetAddressRangePtr()->GetBaseAddress())
242 {
243 sym_list.RemoveContextAtIndex(j);
244 continue; // Don't increment j
245 }
246 }
247 }
Greg Clayton12bec712010-06-28 21:30:43 +0000248
Chris Lattner24943d22010-06-08 16:52:24 +0000249 j++;
250 }
251 }
Greg Clayton12bec712010-06-28 21:30:43 +0000252
Chris Lattner24943d22010-06-08 16:52:24 +0000253 for (i = 0; i < func_list.GetSize(); i++)
254 {
255 if (func_list.GetContextAtIndex(i, sc))
256 {
Greg Claytonfeb6e562010-11-14 00:22:48 +0000257 if (sc.block && sc.block->GetInlinedFunctionInfo())
258 {
259 if (!sc.block->GetStartAddress(break_addr))
260 break_addr.Clear();
261 }
262 else if (sc.function)
Chris Lattner24943d22010-06-08 16:52:24 +0000263 {
264 break_addr = sc.function->GetAddressRange().GetBaseAddress();
Greg Clayton7dd98df2011-07-12 17:06:17 +0000265 if (m_skip_prologue)
Chris Lattner24943d22010-06-08 16:52:24 +0000266 {
Greg Claytonfeb6e562010-11-14 00:22:48 +0000267 if (break_addr.IsValid())
268 {
269 const uint32_t prologue_byte_size = sc.function->GetPrologueByteSize();
270 if (prologue_byte_size)
271 break_addr.SetOffset(break_addr.GetOffset() + prologue_byte_size);
272 }
Chris Lattner24943d22010-06-08 16:52:24 +0000273 }
Greg Claytonfeb6e562010-11-14 00:22:48 +0000274 }
275
276 if (break_addr.IsValid())
277 {
Chris Lattner24943d22010-06-08 16:52:24 +0000278 if (filter.AddressPasses(break_addr))
279 {
280 BreakpointLocationSP bp_loc_sp (m_breakpoint->AddLocation(break_addr, &new_location));
281 if (bp_loc_sp && new_location && !m_breakpoint->IsInternal())
282 {
283 if (log)
284 {
285 StreamString s;
286 bp_loc_sp->GetDescription(&s, lldb::eDescriptionLevelVerbose);
287 log->Printf ("Added location: %s\n", s.GetData());
288 }
289 }
290 }
291 }
292 }
293 }
294 }
Greg Clayton12bec712010-06-28 21:30:43 +0000295
Chris Lattner24943d22010-06-08 16:52:24 +0000296 for (i = 0; i < sym_list.GetSize(); i++)
297 {
298 if (sym_list.GetContextAtIndex(i, sc))
299 {
300 if (sc.symbol && sc.symbol->GetAddressRangePtr())
301 {
302 break_addr = sc.symbol->GetAddressRangePtr()->GetBaseAddress();
Greg Clayton12bec712010-06-28 21:30:43 +0000303
Greg Clayton7dd98df2011-07-12 17:06:17 +0000304 if (m_skip_prologue)
Chris Lattner24943d22010-06-08 16:52:24 +0000305 {
306 const uint32_t prologue_byte_size = sc.symbol->GetPrologueByteSize();
307 if (prologue_byte_size)
308 break_addr.SetOffset(break_addr.GetOffset() + prologue_byte_size);
309 }
Greg Clayton12bec712010-06-28 21:30:43 +0000310
Chris Lattner24943d22010-06-08 16:52:24 +0000311 if (filter.AddressPasses(break_addr))
312 {
313 BreakpointLocationSP bp_loc_sp (m_breakpoint->AddLocation(break_addr, &new_location));
314 if (bp_loc_sp && new_location && !m_breakpoint->IsInternal())
315 {
316 StreamString s;
317 bp_loc_sp->GetDescription(&s, lldb::eDescriptionLevelVerbose);
318 if (log)
319 log->Printf ("Added location: %s\n", s.GetData());
320 }
321 }
322 }
323 }
324 }
325 return Searcher::eCallbackReturnContinue;
326}
327
328Searcher::Depth
329BreakpointResolverName::GetDepth()
330{
331 return Searcher::eDepthModule;
332}
333
334void
335BreakpointResolverName::GetDescription (Stream *s)
336{
Chris Lattner24943d22010-06-08 16:52:24 +0000337 if (m_match_type == Breakpoint::Regexp)
Greg Clayton12bec712010-06-28 21:30:43 +0000338 s->Printf("regex = '%s'", m_regex.GetText());
Greg Clayton48fbdf72010-10-12 04:29:14 +0000339 else
Jim Inghamc1053622012-03-03 02:05:11 +0000340 {
341 size_t num_names = m_func_names.size();
342 if (num_names == 1)
343 s->Printf("name = '%s'", m_func_names[0].AsCString());
344 else
345 {
346 s->Printf("names = {");
347 for (size_t i = 0; i < num_names - 1; i++)
348 {
349 s->Printf ("'%s', ", m_func_names[i].AsCString());
350 }
351 s->Printf ("'%s'}", m_func_names[num_names - 1].AsCString());
352 }
353 }
Chris Lattner24943d22010-06-08 16:52:24 +0000354}
355
356void
357BreakpointResolverName::Dump (Stream *s) const
358{
359
360}
361