blob: f25910de565b2da2fb86b2ffdfc1d08e8f19b9ac [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"
19#include "lldb/lldb-private-log.h"
20
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,
Chris Lattner24943d22010-06-08 16:52:24 +000029 Breakpoint::MatchType type
30) :
31 BreakpointResolver (bkpt),
32 m_func_name (func_name),
Greg Clayton12bec712010-06-28 21:30:43 +000033 m_func_name_type_mask (func_name_type_mask),
34 m_class_name (),
Chris Lattner24943d22010-06-08 16:52:24 +000035 m_regex (),
36 m_match_type (type)
37{
38 if (m_match_type == Breakpoint::Regexp)
39 {
40 if (!m_regex.Compile (m_func_name.AsCString()))
41 {
42 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS);
43
44 if (log)
45 log->Warning ("function name regexp: \"%s\" did not compile.", m_func_name.AsCString());
46 }
47 }
48}
49
50BreakpointResolverName::BreakpointResolverName
51(
52 Breakpoint *bkpt,
53 RegularExpression &func_regex
54) :
55 BreakpointResolver (bkpt),
56 m_func_name (NULL),
57 m_class_name (NULL),
58 m_regex (func_regex),
59 m_match_type (Breakpoint::Regexp)
60{
61
62}
63
64BreakpointResolverName::BreakpointResolverName
65(
66 Breakpoint *bkpt,
67 const char *class_name,
68 const char *method,
69 Breakpoint::MatchType type
70) :
71 BreakpointResolver (bkpt),
72 m_func_name (method),
73 m_class_name (class_name),
74 m_regex (),
75 m_match_type (type)
76{
77
78}
79
80BreakpointResolverName::~BreakpointResolverName ()
81{
82}
83
84// FIXME: Right now we look at the module level, and call the module's "FindFunctions".
85// Greg says he will add function tables, maybe at the CompileUnit level to accelerate function
86// lookup. At that point, we should switch the depth to CompileUnit, and look in these tables.
87
88Searcher::CallbackReturn
89BreakpointResolverName::SearchCallback
90(
91 SearchFilter &filter,
92 SymbolContext &context,
93 Address *addr,
94 bool containing
95)
96{
97 SymbolContextList func_list;
98 SymbolContextList sym_list;
Greg Clayton12bec712010-06-28 21:30:43 +000099
Chris Lattner24943d22010-06-08 16:52:24 +0000100 bool skip_prologue = true;
101 uint32_t i;
102 bool new_location;
103 SymbolContext sc;
104 Address break_addr;
105 assert (m_breakpoint != NULL);
Greg Clayton12bec712010-06-28 21:30:43 +0000106
Chris Lattner24943d22010-06-08 16:52:24 +0000107 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS);
Greg Clayton12bec712010-06-28 21:30:43 +0000108
Chris Lattner24943d22010-06-08 16:52:24 +0000109 if (m_class_name)
110 {
111 if (log)
112 log->Warning ("Class/method function specification not supported yet.\n");
113 return Searcher::eCallbackReturnStop;
114 }
Greg Clayton12bec712010-06-28 21:30:43 +0000115
Chris Lattner24943d22010-06-08 16:52:24 +0000116 switch (m_match_type)
117 {
Greg Clayton12bec712010-06-28 21:30:43 +0000118 case Breakpoint::Exact:
119 if (context.module_sp)
120 {
121 if (m_func_name_type_mask & (eFunctionNameTypeBase | eFunctionNameTypeFull))
122 context.module_sp->FindSymbolsWithNameAndType (m_func_name, eSymbolTypeCode, sym_list);
123 context.module_sp->FindFunctions (m_func_name, m_func_name_type_mask, false, func_list);
124 }
125 break;
126 case Breakpoint::Regexp:
127 if (context.module_sp)
128 {
129 if (m_func_name_type_mask & (eFunctionNameTypeBase | eFunctionNameTypeFull))
130 context.module_sp->FindSymbolsMatchingRegExAndType (m_regex, eSymbolTypeCode, sym_list);
131 context.module_sp->FindFunctions (m_regex, true, func_list);
132 }
133 break;
134 case Breakpoint::Glob:
135 if (log)
136 log->Warning ("glob is not supported yet.");
137 break;
Chris Lattner24943d22010-06-08 16:52:24 +0000138 }
Greg Clayton12bec712010-06-28 21:30:43 +0000139
Chris Lattner24943d22010-06-08 16:52:24 +0000140 // Remove any duplicates between the funcion list and the symbol list
141 if (func_list.GetSize())
142 {
143 for (i = 0; i < func_list.GetSize(); i++)
144 {
145 if (func_list.GetContextAtIndex(i, sc) == false)
146 continue;
Greg Clayton12bec712010-06-28 21:30:43 +0000147
Chris Lattner24943d22010-06-08 16:52:24 +0000148 if (sc.function == NULL)
149 continue;
150 uint32_t j = 0;
151 while (j < sym_list.GetSize())
152 {
153 SymbolContext symbol_sc;
154 if (sym_list.GetContextAtIndex(j, symbol_sc))
155 {
156 if (symbol_sc.symbol && symbol_sc.symbol->GetAddressRangePtr())
157 {
158 if (sc.function->GetAddressRange().GetBaseAddress() == symbol_sc.symbol->GetAddressRangePtr()->GetBaseAddress())
159 {
160 sym_list.RemoveContextAtIndex(j);
161 continue; // Don't increment j
162 }
163 }
164 }
Greg Clayton12bec712010-06-28 21:30:43 +0000165
Chris Lattner24943d22010-06-08 16:52:24 +0000166 j++;
167 }
168 }
Greg Clayton12bec712010-06-28 21:30:43 +0000169
Chris Lattner24943d22010-06-08 16:52:24 +0000170 for (i = 0; i < func_list.GetSize(); i++)
171 {
172 if (func_list.GetContextAtIndex(i, sc))
173 {
174 if (sc.function)
175 {
176 break_addr = sc.function->GetAddressRange().GetBaseAddress();
177 if (skip_prologue)
178 {
179 const uint32_t prologue_byte_size = sc.function->GetPrologueByteSize();
180 if (prologue_byte_size)
181 break_addr.SetOffset(break_addr.GetOffset() + prologue_byte_size);
182 }
Greg Clayton12bec712010-06-28 21:30:43 +0000183
Chris Lattner24943d22010-06-08 16:52:24 +0000184 if (filter.AddressPasses(break_addr))
185 {
186 BreakpointLocationSP bp_loc_sp (m_breakpoint->AddLocation(break_addr, &new_location));
187 if (bp_loc_sp && new_location && !m_breakpoint->IsInternal())
188 {
189 if (log)
190 {
191 StreamString s;
192 bp_loc_sp->GetDescription(&s, lldb::eDescriptionLevelVerbose);
193 log->Printf ("Added location: %s\n", s.GetData());
194 }
195 }
196 }
197 }
198 }
199 }
200 }
Greg Clayton12bec712010-06-28 21:30:43 +0000201
Chris Lattner24943d22010-06-08 16:52:24 +0000202 for (i = 0; i < sym_list.GetSize(); i++)
203 {
204 if (sym_list.GetContextAtIndex(i, sc))
205 {
206 if (sc.symbol && sc.symbol->GetAddressRangePtr())
207 {
208 break_addr = sc.symbol->GetAddressRangePtr()->GetBaseAddress();
Greg Clayton12bec712010-06-28 21:30:43 +0000209
Chris Lattner24943d22010-06-08 16:52:24 +0000210 if (skip_prologue)
211 {
212 const uint32_t prologue_byte_size = sc.symbol->GetPrologueByteSize();
213 if (prologue_byte_size)
214 break_addr.SetOffset(break_addr.GetOffset() + prologue_byte_size);
215 }
Greg Clayton12bec712010-06-28 21:30:43 +0000216
Chris Lattner24943d22010-06-08 16:52:24 +0000217 if (filter.AddressPasses(break_addr))
218 {
219 BreakpointLocationSP bp_loc_sp (m_breakpoint->AddLocation(break_addr, &new_location));
220 if (bp_loc_sp && new_location && !m_breakpoint->IsInternal())
221 {
222 StreamString s;
223 bp_loc_sp->GetDescription(&s, lldb::eDescriptionLevelVerbose);
224 if (log)
225 log->Printf ("Added location: %s\n", s.GetData());
226 }
227 }
228 }
229 }
230 }
231 return Searcher::eCallbackReturnContinue;
232}
233
234Searcher::Depth
235BreakpointResolverName::GetDepth()
236{
237 return Searcher::eDepthModule;
238}
239
240void
241BreakpointResolverName::GetDescription (Stream *s)
242{
Chris Lattner24943d22010-06-08 16:52:24 +0000243 if (m_match_type == Breakpoint::Regexp)
Greg Clayton12bec712010-06-28 21:30:43 +0000244 s->Printf("regex = '%s'", m_regex.GetText());
Chris Lattner24943d22010-06-08 16:52:24 +0000245 else
Greg Clayton12bec712010-06-28 21:30:43 +0000246 s->Printf("name = '%s'", m_func_name.AsCString());
Chris Lattner24943d22010-06-08 16:52:24 +0000247}
248
249void
250BreakpointResolverName::Dump (Stream *s) const
251{
252
253}
254