blob: 9df1dd73334d5df6e1e026003e9e4340949a19ae [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"
Greg Clayton17cd9952011-04-22 03:55:06 +000019#include "lldb/Target/Target.h"
Chris Lattner24943d22010-06-08 16:52:24 +000020
21using namespace lldb;
22using namespace lldb_private;
23
24BreakpointResolverName::BreakpointResolverName
25(
26 Breakpoint *bkpt,
27 const char *func_name,
Greg Clayton12bec712010-06-28 21:30:43 +000028 uint32_t func_name_type_mask,
Greg Clayton7dd98df2011-07-12 17:06:17 +000029 Breakpoint::MatchType type,
30 bool skip_prologue
Chris Lattner24943d22010-06-08 16:52:24 +000031) :
Johnny Chena62ad7c2010-10-28 17:27:46 +000032 BreakpointResolver (bkpt, BreakpointResolver::NameResolver),
Jim Ingham8b7b2272011-10-07 22:23:45 +000033 m_func_name (func_name),
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{
Greg Clayton48fbdf72010-10-12 04:29:14 +000040
Chris Lattner24943d22010-06-08 16:52:24 +000041 if (m_match_type == Breakpoint::Regexp)
42 {
43 if (!m_regex.Compile (m_func_name.AsCString()))
44 {
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)
48 log->Warning ("function name regexp: \"%s\" did not compile.", m_func_name.AsCString());
49 }
50 }
51}
52
53BreakpointResolverName::BreakpointResolverName
54(
55 Breakpoint *bkpt,
Greg Clayton7dd98df2011-07-12 17:06:17 +000056 RegularExpression &func_regex,
57 bool skip_prologue
Chris Lattner24943d22010-06-08 16:52:24 +000058) :
Johnny Chena62ad7c2010-10-28 17:27:46 +000059 BreakpointResolver (bkpt, BreakpointResolver::NameResolver),
Chris Lattner24943d22010-06-08 16:52:24 +000060 m_func_name (NULL),
61 m_class_name (NULL),
62 m_regex (func_regex),
Greg Clayton7dd98df2011-07-12 17:06:17 +000063 m_match_type (Breakpoint::Regexp),
64 m_skip_prologue (skip_prologue)
Chris Lattner24943d22010-06-08 16:52:24 +000065{
Chris Lattner24943d22010-06-08 16:52:24 +000066}
67
68BreakpointResolverName::BreakpointResolverName
69(
70 Breakpoint *bkpt,
71 const char *class_name,
72 const char *method,
Greg Clayton7dd98df2011-07-12 17:06:17 +000073 Breakpoint::MatchType type,
74 bool skip_prologue
Chris Lattner24943d22010-06-08 16:52:24 +000075) :
Johnny Chena62ad7c2010-10-28 17:27:46 +000076 BreakpointResolver (bkpt, BreakpointResolver::NameResolver),
Chris Lattner24943d22010-06-08 16:52:24 +000077 m_func_name (method),
78 m_class_name (class_name),
79 m_regex (),
Greg Clayton7dd98df2011-07-12 17:06:17 +000080 m_match_type (type),
81 m_skip_prologue (skip_prologue)
Chris Lattner24943d22010-06-08 16:52:24 +000082{
83
84}
85
86BreakpointResolverName::~BreakpointResolverName ()
87{
88}
89
90// FIXME: Right now we look at the module level, and call the module's "FindFunctions".
91// Greg says he will add function tables, maybe at the CompileUnit level to accelerate function
92// lookup. At that point, we should switch the depth to CompileUnit, and look in these tables.
93
94Searcher::CallbackReturn
95BreakpointResolverName::SearchCallback
96(
97 SearchFilter &filter,
98 SymbolContext &context,
99 Address *addr,
100 bool containing
101)
102{
103 SymbolContextList func_list;
104 SymbolContextList sym_list;
Greg Clayton12bec712010-06-28 21:30:43 +0000105
Chris Lattner24943d22010-06-08 16:52:24 +0000106 uint32_t i;
107 bool new_location;
108 SymbolContext sc;
109 Address break_addr;
110 assert (m_breakpoint != NULL);
Greg Clayton12bec712010-06-28 21:30:43 +0000111
Greg Claytone005f2c2010-11-06 01:53:30 +0000112 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
Greg Clayton12bec712010-06-28 21:30:43 +0000113
Chris Lattner24943d22010-06-08 16:52:24 +0000114 if (m_class_name)
115 {
116 if (log)
117 log->Warning ("Class/method function specification not supported yet.\n");
118 return Searcher::eCallbackReturnStop;
119 }
Greg Clayton12bec712010-06-28 21:30:43 +0000120
Greg Clayton28d5fcc2011-01-27 06:44:37 +0000121 const bool include_symbols = false;
122 const bool append = false;
Jim Inghamd6d47972011-09-23 00:54:11 +0000123 bool filter_by_cu = (filter.GetFilterRequiredItems() & eSymbolContextCompUnit) != 0;
124
Chris Lattner24943d22010-06-08 16:52:24 +0000125 switch (m_match_type)
126 {
Greg Clayton12bec712010-06-28 21:30:43 +0000127 case Breakpoint::Exact:
128 if (context.module_sp)
129 {
Jim Inghamd6d47972011-09-23 00:54:11 +0000130 uint32_t num_functions = context.module_sp->FindFunctions (m_func_name,
Greg Claytond74270e2011-09-02 04:03:59 +0000131 m_func_name_type_mask,
132 include_symbols,
133 append,
Jim Inghamd6d47972011-09-23 00:54:11 +0000134 func_list);
135 // If the search filter specifies a Compilation Unit, then we don't need to bother to look in plain
136 // symbols, since all the ones from a set compilation unit will have been found above already.
137
138 if (num_functions == 0 && !filter_by_cu)
Greg Claytond74270e2011-09-02 04:03:59 +0000139 {
Jim Ingham8b7b2272011-10-07 22:23:45 +0000140 if (m_func_name_type_mask & (eFunctionNameTypeBase | eFunctionNameTypeFull | eFunctionNameTypeAuto))
Greg Claytond74270e2011-09-02 04:03:59 +0000141 context.module_sp->FindSymbolsWithNameAndType (m_func_name, eSymbolTypeCode, sym_list);
142 }
Greg Clayton12bec712010-06-28 21:30:43 +0000143 }
144 break;
145 case Breakpoint::Regexp:
146 if (context.module_sp)
147 {
Jim Inghamd6d47972011-09-23 00:54:11 +0000148 if (!filter_by_cu)
149 context.module_sp->FindSymbolsMatchingRegExAndType (m_regex, eSymbolTypeCode, sym_list);
Greg Clayton28d5fcc2011-01-27 06:44:37 +0000150 context.module_sp->FindFunctions (m_regex,
151 include_symbols,
152 append,
153 func_list);
Greg Clayton12bec712010-06-28 21:30:43 +0000154 }
155 break;
156 case Breakpoint::Glob:
157 if (log)
158 log->Warning ("glob is not supported yet.");
159 break;
Chris Lattner24943d22010-06-08 16:52:24 +0000160 }
Jim Inghamd6d47972011-09-23 00:54:11 +0000161
162 // If the filter specifies a Compilation Unit, remove the ones that don't pass at this point.
163 if (filter_by_cu)
164 {
165 uint32_t num_functions = func_list.GetSize();
166
167 for (size_t idx = 0; idx < num_functions; idx++)
168 {
169 SymbolContext sc;
170 func_list.GetContextAtIndex(idx, sc);
171 if (!sc.comp_unit || !filter.CompUnitPasses(*sc.comp_unit))
172 {
173 func_list.RemoveContextAtIndex(idx);
174 num_functions--;
175 idx--;
176 }
177 }
178 }
Jim Inghamd6d47972011-09-23 00:54:11 +0000179
Chris Lattner24943d22010-06-08 16:52:24 +0000180 // Remove any duplicates between the funcion list and the symbol list
181 if (func_list.GetSize())
182 {
183 for (i = 0; i < func_list.GetSize(); i++)
184 {
185 if (func_list.GetContextAtIndex(i, sc) == false)
186 continue;
Greg Clayton12bec712010-06-28 21:30:43 +0000187
Chris Lattner24943d22010-06-08 16:52:24 +0000188 if (sc.function == NULL)
189 continue;
190 uint32_t j = 0;
191 while (j < sym_list.GetSize())
192 {
193 SymbolContext symbol_sc;
194 if (sym_list.GetContextAtIndex(j, symbol_sc))
195 {
196 if (symbol_sc.symbol && symbol_sc.symbol->GetAddressRangePtr())
197 {
198 if (sc.function->GetAddressRange().GetBaseAddress() == symbol_sc.symbol->GetAddressRangePtr()->GetBaseAddress())
199 {
200 sym_list.RemoveContextAtIndex(j);
201 continue; // Don't increment j
202 }
203 }
204 }
Greg Clayton12bec712010-06-28 21:30:43 +0000205
Chris Lattner24943d22010-06-08 16:52:24 +0000206 j++;
207 }
208 }
Greg Clayton12bec712010-06-28 21:30:43 +0000209
Chris Lattner24943d22010-06-08 16:52:24 +0000210 for (i = 0; i < func_list.GetSize(); i++)
211 {
212 if (func_list.GetContextAtIndex(i, sc))
213 {
Greg Claytonfeb6e562010-11-14 00:22:48 +0000214 if (sc.block && sc.block->GetInlinedFunctionInfo())
215 {
216 if (!sc.block->GetStartAddress(break_addr))
217 break_addr.Clear();
218 }
219 else if (sc.function)
Chris Lattner24943d22010-06-08 16:52:24 +0000220 {
221 break_addr = sc.function->GetAddressRange().GetBaseAddress();
Greg Clayton7dd98df2011-07-12 17:06:17 +0000222 if (m_skip_prologue)
Chris Lattner24943d22010-06-08 16:52:24 +0000223 {
Greg Claytonfeb6e562010-11-14 00:22:48 +0000224 if (break_addr.IsValid())
225 {
226 const uint32_t prologue_byte_size = sc.function->GetPrologueByteSize();
227 if (prologue_byte_size)
228 break_addr.SetOffset(break_addr.GetOffset() + prologue_byte_size);
229 }
Chris Lattner24943d22010-06-08 16:52:24 +0000230 }
Greg Claytonfeb6e562010-11-14 00:22:48 +0000231 }
232
233 if (break_addr.IsValid())
234 {
Chris Lattner24943d22010-06-08 16:52:24 +0000235 if (filter.AddressPasses(break_addr))
236 {
237 BreakpointLocationSP bp_loc_sp (m_breakpoint->AddLocation(break_addr, &new_location));
238 if (bp_loc_sp && new_location && !m_breakpoint->IsInternal())
239 {
240 if (log)
241 {
242 StreamString s;
243 bp_loc_sp->GetDescription(&s, lldb::eDescriptionLevelVerbose);
244 log->Printf ("Added location: %s\n", s.GetData());
245 }
246 }
247 }
248 }
249 }
250 }
251 }
Greg Clayton12bec712010-06-28 21:30:43 +0000252
Chris Lattner24943d22010-06-08 16:52:24 +0000253 for (i = 0; i < sym_list.GetSize(); i++)
254 {
255 if (sym_list.GetContextAtIndex(i, sc))
256 {
257 if (sc.symbol && sc.symbol->GetAddressRangePtr())
258 {
259 break_addr = sc.symbol->GetAddressRangePtr()->GetBaseAddress();
Greg Clayton12bec712010-06-28 21:30:43 +0000260
Greg Clayton7dd98df2011-07-12 17:06:17 +0000261 if (m_skip_prologue)
Chris Lattner24943d22010-06-08 16:52:24 +0000262 {
263 const uint32_t prologue_byte_size = sc.symbol->GetPrologueByteSize();
264 if (prologue_byte_size)
265 break_addr.SetOffset(break_addr.GetOffset() + prologue_byte_size);
266 }
Greg Clayton12bec712010-06-28 21:30:43 +0000267
Chris Lattner24943d22010-06-08 16:52:24 +0000268 if (filter.AddressPasses(break_addr))
269 {
270 BreakpointLocationSP bp_loc_sp (m_breakpoint->AddLocation(break_addr, &new_location));
271 if (bp_loc_sp && new_location && !m_breakpoint->IsInternal())
272 {
273 StreamString s;
274 bp_loc_sp->GetDescription(&s, lldb::eDescriptionLevelVerbose);
275 if (log)
276 log->Printf ("Added location: %s\n", s.GetData());
277 }
278 }
279 }
280 }
281 }
282 return Searcher::eCallbackReturnContinue;
283}
284
285Searcher::Depth
286BreakpointResolverName::GetDepth()
287{
288 return Searcher::eDepthModule;
289}
290
291void
292BreakpointResolverName::GetDescription (Stream *s)
293{
Chris Lattner24943d22010-06-08 16:52:24 +0000294 if (m_match_type == Breakpoint::Regexp)
Greg Clayton12bec712010-06-28 21:30:43 +0000295 s->Printf("regex = '%s'", m_regex.GetText());
Greg Clayton48fbdf72010-10-12 04:29:14 +0000296 else
Jim Ingham8b7b2272011-10-07 22:23:45 +0000297 s->Printf("name = '%s'", m_func_name.AsCString());
Chris Lattner24943d22010-06-08 16:52:24 +0000298}
299
300void
301BreakpointResolverName::Dump (Stream *s) const
302{
303
304}
305