blob: 9b958c4066f8a1d60c3d0e834cf2e3ba275aaaae [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;
Sean Callanan302d78c2012-02-10 22:52:19 +0000123 const bool include_inlines = true;
Greg Clayton28d5fcc2011-01-27 06:44:37 +0000124 const bool append = false;
Jim Inghamd6d47972011-09-23 00:54:11 +0000125 bool filter_by_cu = (filter.GetFilterRequiredItems() & eSymbolContextCompUnit) != 0;
126
Chris Lattner24943d22010-06-08 16:52:24 +0000127 switch (m_match_type)
128 {
Greg Clayton12bec712010-06-28 21:30:43 +0000129 case Breakpoint::Exact:
130 if (context.module_sp)
131 {
Jim Inghamd6d47972011-09-23 00:54:11 +0000132 uint32_t num_functions = context.module_sp->FindFunctions (m_func_name,
Sean Callanan3e80cd92011-10-12 02:08:07 +0000133 NULL,
134 m_func_name_type_mask,
Sean Callanan302d78c2012-02-10 22:52:19 +0000135 include_symbols,
136 include_inlines,
Sean Callanan3e80cd92011-10-12 02:08:07 +0000137 append,
138 func_list);
Jim Inghamd6d47972011-09-23 00:54:11 +0000139 // If the search filter specifies a Compilation Unit, then we don't need to bother to look in plain
140 // symbols, since all the ones from a set compilation unit will have been found above already.
141
142 if (num_functions == 0 && !filter_by_cu)
Greg Claytond74270e2011-09-02 04:03:59 +0000143 {
Jim Ingham8b7b2272011-10-07 22:23:45 +0000144 if (m_func_name_type_mask & (eFunctionNameTypeBase | eFunctionNameTypeFull | eFunctionNameTypeAuto))
Sean Callananaa4a5532011-10-13 16:49:47 +0000145 context.module_sp->FindSymbolsWithNameAndType (m_func_name, eSymbolTypeCode, sym_list);
Greg Claytond74270e2011-09-02 04:03:59 +0000146 }
Greg Clayton12bec712010-06-28 21:30:43 +0000147 }
148 break;
149 case Breakpoint::Regexp:
150 if (context.module_sp)
151 {
Jim Inghamd6d47972011-09-23 00:54:11 +0000152 if (!filter_by_cu)
153 context.module_sp->FindSymbolsMatchingRegExAndType (m_regex, eSymbolTypeCode, sym_list);
Greg Clayton28d5fcc2011-01-27 06:44:37 +0000154 context.module_sp->FindFunctions (m_regex,
Sean Callanan302d78c2012-02-10 22:52:19 +0000155 include_symbols,
156 include_inlines,
Greg Clayton28d5fcc2011-01-27 06:44:37 +0000157 append,
158 func_list);
Greg Clayton12bec712010-06-28 21:30:43 +0000159 }
160 break;
161 case Breakpoint::Glob:
162 if (log)
163 log->Warning ("glob is not supported yet.");
164 break;
Chris Lattner24943d22010-06-08 16:52:24 +0000165 }
Jim Inghamd6d47972011-09-23 00:54:11 +0000166
167 // If the filter specifies a Compilation Unit, remove the ones that don't pass at this point.
168 if (filter_by_cu)
169 {
170 uint32_t num_functions = func_list.GetSize();
171
172 for (size_t idx = 0; idx < num_functions; idx++)
173 {
174 SymbolContext sc;
175 func_list.GetContextAtIndex(idx, sc);
176 if (!sc.comp_unit || !filter.CompUnitPasses(*sc.comp_unit))
177 {
178 func_list.RemoveContextAtIndex(idx);
179 num_functions--;
180 idx--;
181 }
182 }
183 }
Jim Inghamd6d47972011-09-23 00:54:11 +0000184
Chris Lattner24943d22010-06-08 16:52:24 +0000185 // Remove any duplicates between the funcion list and the symbol list
186 if (func_list.GetSize())
187 {
188 for (i = 0; i < func_list.GetSize(); i++)
189 {
190 if (func_list.GetContextAtIndex(i, sc) == false)
191 continue;
Greg Clayton12bec712010-06-28 21:30:43 +0000192
Chris Lattner24943d22010-06-08 16:52:24 +0000193 if (sc.function == NULL)
194 continue;
195 uint32_t j = 0;
196 while (j < sym_list.GetSize())
197 {
198 SymbolContext symbol_sc;
199 if (sym_list.GetContextAtIndex(j, symbol_sc))
200 {
201 if (symbol_sc.symbol && symbol_sc.symbol->GetAddressRangePtr())
202 {
203 if (sc.function->GetAddressRange().GetBaseAddress() == symbol_sc.symbol->GetAddressRangePtr()->GetBaseAddress())
204 {
205 sym_list.RemoveContextAtIndex(j);
206 continue; // Don't increment j
207 }
208 }
209 }
Greg Clayton12bec712010-06-28 21:30:43 +0000210
Chris Lattner24943d22010-06-08 16:52:24 +0000211 j++;
212 }
213 }
Greg Clayton12bec712010-06-28 21:30:43 +0000214
Chris Lattner24943d22010-06-08 16:52:24 +0000215 for (i = 0; i < func_list.GetSize(); i++)
216 {
217 if (func_list.GetContextAtIndex(i, sc))
218 {
Greg Claytonfeb6e562010-11-14 00:22:48 +0000219 if (sc.block && sc.block->GetInlinedFunctionInfo())
220 {
221 if (!sc.block->GetStartAddress(break_addr))
222 break_addr.Clear();
223 }
224 else if (sc.function)
Chris Lattner24943d22010-06-08 16:52:24 +0000225 {
226 break_addr = sc.function->GetAddressRange().GetBaseAddress();
Greg Clayton7dd98df2011-07-12 17:06:17 +0000227 if (m_skip_prologue)
Chris Lattner24943d22010-06-08 16:52:24 +0000228 {
Greg Claytonfeb6e562010-11-14 00:22:48 +0000229 if (break_addr.IsValid())
230 {
231 const uint32_t prologue_byte_size = sc.function->GetPrologueByteSize();
232 if (prologue_byte_size)
233 break_addr.SetOffset(break_addr.GetOffset() + prologue_byte_size);
234 }
Chris Lattner24943d22010-06-08 16:52:24 +0000235 }
Greg Claytonfeb6e562010-11-14 00:22:48 +0000236 }
237
238 if (break_addr.IsValid())
239 {
Chris Lattner24943d22010-06-08 16:52:24 +0000240 if (filter.AddressPasses(break_addr))
241 {
242 BreakpointLocationSP bp_loc_sp (m_breakpoint->AddLocation(break_addr, &new_location));
243 if (bp_loc_sp && new_location && !m_breakpoint->IsInternal())
244 {
245 if (log)
246 {
247 StreamString s;
248 bp_loc_sp->GetDescription(&s, lldb::eDescriptionLevelVerbose);
249 log->Printf ("Added location: %s\n", s.GetData());
250 }
251 }
252 }
253 }
254 }
255 }
256 }
Greg Clayton12bec712010-06-28 21:30:43 +0000257
Chris Lattner24943d22010-06-08 16:52:24 +0000258 for (i = 0; i < sym_list.GetSize(); i++)
259 {
260 if (sym_list.GetContextAtIndex(i, sc))
261 {
262 if (sc.symbol && sc.symbol->GetAddressRangePtr())
263 {
264 break_addr = sc.symbol->GetAddressRangePtr()->GetBaseAddress();
Greg Clayton12bec712010-06-28 21:30:43 +0000265
Greg Clayton7dd98df2011-07-12 17:06:17 +0000266 if (m_skip_prologue)
Chris Lattner24943d22010-06-08 16:52:24 +0000267 {
268 const uint32_t prologue_byte_size = sc.symbol->GetPrologueByteSize();
269 if (prologue_byte_size)
270 break_addr.SetOffset(break_addr.GetOffset() + prologue_byte_size);
271 }
Greg Clayton12bec712010-06-28 21:30:43 +0000272
Chris Lattner24943d22010-06-08 16:52:24 +0000273 if (filter.AddressPasses(break_addr))
274 {
275 BreakpointLocationSP bp_loc_sp (m_breakpoint->AddLocation(break_addr, &new_location));
276 if (bp_loc_sp && new_location && !m_breakpoint->IsInternal())
277 {
278 StreamString s;
279 bp_loc_sp->GetDescription(&s, lldb::eDescriptionLevelVerbose);
280 if (log)
281 log->Printf ("Added location: %s\n", s.GetData());
282 }
283 }
284 }
285 }
286 }
287 return Searcher::eCallbackReturnContinue;
288}
289
290Searcher::Depth
291BreakpointResolverName::GetDepth()
292{
293 return Searcher::eDepthModule;
294}
295
296void
297BreakpointResolverName::GetDescription (Stream *s)
298{
Chris Lattner24943d22010-06-08 16:52:24 +0000299 if (m_match_type == Breakpoint::Regexp)
Greg Clayton12bec712010-06-28 21:30:43 +0000300 s->Printf("regex = '%s'", m_regex.GetText());
Greg Clayton48fbdf72010-10-12 04:29:14 +0000301 else
Jim Ingham8b7b2272011-10-07 22:23:45 +0000302 s->Printf("name = '%s'", m_func_name.AsCString());
Chris Lattner24943d22010-06-08 16:52:24 +0000303}
304
305void
306BreakpointResolverName::Dump (Stream *s) const
307{
308
309}
310