blob: 040a862185571a798ac873533413f36e8e37441b [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- AddressResolverName.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/Core/AddressResolverName.h"
11
12// Project includes
13#include "lldb/Core/Log.h"
14#include "lldb/Core/StreamString.h"
15#include "lldb/lldb-private-log.h"
16
17using namespace lldb;
18using namespace lldb_private;
19
20AddressResolverName::AddressResolverName
21(
22 const char *func_name,
23 AddressResolver::MatchType type
24) :
25 AddressResolver (),
26 m_func_name (func_name),
27 m_class_name (NULL),
28 m_regex (),
29 m_match_type (type)
30{
31 if (m_match_type == AddressResolver::Regexp)
32 {
33 if (!m_regex.Compile (m_func_name.AsCString()))
34 {
Greg Clayton2d4edfb2010-11-06 01:53:30 +000035 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
Chris Lattner30fdc8d2010-06-08 16:52:24 +000036
37 if (log)
38 log->Warning ("function name regexp: \"%s\" did not compile.", m_func_name.AsCString());
39 }
40 }
41}
42
43AddressResolverName::AddressResolverName
44(
45 RegularExpression &func_regex
46) :
47 AddressResolver (),
48 m_func_name (NULL),
49 m_class_name (NULL),
50 m_regex (func_regex),
51 m_match_type (AddressResolver::Regexp)
52{
53
54}
55
56AddressResolverName::AddressResolverName
57(
58 const char *class_name,
59 const char *method,
60 AddressResolver::MatchType type
61) :
62 AddressResolver (),
63 m_func_name (method),
64 m_class_name (class_name),
65 m_regex (),
66 m_match_type (type)
67{
68
69}
70
71AddressResolverName::~AddressResolverName ()
72{
73}
74
75// FIXME: Right now we look at the module level, and call the module's "FindFunctions".
76// Greg says he will add function tables, maybe at the CompileUnit level to accelerate function
77// lookup. At that point, we should switch the depth to CompileUnit, and look in these tables.
78
79Searcher::CallbackReturn
80AddressResolverName::SearchCallback
81(
82 SearchFilter &filter,
83 SymbolContext &context,
84 Address *addr,
85 bool containing
86)
87{
88 SymbolContextList func_list;
89 SymbolContextList sym_list;
90
91 bool skip_prologue = true;
92 uint32_t i;
93 SymbolContext sc;
94 Address func_addr;
95
Greg Clayton2d4edfb2010-11-06 01:53:30 +000096 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
Chris Lattner30fdc8d2010-06-08 16:52:24 +000097
98 if (m_class_name)
99 {
100 if (log)
101 log->Warning ("Class/method function specification not supported yet.\n");
102 return Searcher::eCallbackReturnStop;
103 }
104
Greg Clayton931180e2011-01-27 06:44:37 +0000105 const bool include_symbols = false;
106 const bool append = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000107 switch (m_match_type)
108 {
Greg Clayton931180e2011-01-27 06:44:37 +0000109 case AddressResolver::Exact:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000110 if (context.module_sp)
111 {
Greg Clayton0c5cd902010-06-28 21:30:43 +0000112 context.module_sp->FindSymbolsWithNameAndType (m_func_name,
113 eSymbolTypeCode,
114 sym_list);
115 context.module_sp->FindFunctions (m_func_name,
116 eFunctionNameTypeBase | eFunctionNameTypeFull | eFunctionNameTypeMethod | eFunctionNameTypeSelector,
Greg Clayton931180e2011-01-27 06:44:37 +0000117 include_symbols,
118 append,
Greg Clayton0c5cd902010-06-28 21:30:43 +0000119 func_list);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000120 }
121 break;
Greg Clayton931180e2011-01-27 06:44:37 +0000122
123 case AddressResolver::Regexp:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000124 if (context.module_sp)
125 {
Greg Clayton0c5cd902010-06-28 21:30:43 +0000126 context.module_sp->FindSymbolsMatchingRegExAndType (m_regex,
127 eSymbolTypeCode,
128 sym_list);
129 context.module_sp->FindFunctions (m_regex,
Greg Clayton931180e2011-01-27 06:44:37 +0000130 include_symbols,
131 append,
Greg Clayton0c5cd902010-06-28 21:30:43 +0000132 func_list);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000133 }
134 break;
Greg Clayton931180e2011-01-27 06:44:37 +0000135
136 case AddressResolver::Glob:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000137 if (log)
138 log->Warning ("glob is not supported yet.");
139 break;
140 }
141
142 // Remove any duplicates between the funcion list and the symbol list
143 if (func_list.GetSize())
144 {
145 for (i = 0; i < func_list.GetSize(); i++)
146 {
147 if (func_list.GetContextAtIndex(i, sc) == false)
148 continue;
149
150 if (sc.function == NULL)
151 continue;
152 uint32_t j = 0;
153 while (j < sym_list.GetSize())
154 {
155 SymbolContext symbol_sc;
156 if (sym_list.GetContextAtIndex(j, symbol_sc))
157 {
158 if (symbol_sc.symbol && symbol_sc.symbol->GetAddressRangePtr())
159 {
160 if (sc.function->GetAddressRange().GetBaseAddress() == symbol_sc.symbol->GetAddressRangePtr()->GetBaseAddress())
161 {
162 sym_list.RemoveContextAtIndex(j);
163 continue; // Don't increment j
164 }
165 }
166 }
167
168 j++;
169 }
170 }
171
172 for (i = 0; i < func_list.GetSize(); i++)
173 {
174 if (func_list.GetContextAtIndex(i, sc))
175 {
176 if (sc.function)
177 {
178 func_addr = sc.function->GetAddressRange().GetBaseAddress();
179 addr_t byte_size = sc.function->GetAddressRange().GetByteSize();
180 if (skip_prologue)
181 {
182 const uint32_t prologue_byte_size = sc.function->GetPrologueByteSize();
183 if (prologue_byte_size)
184 {
185 func_addr.SetOffset (func_addr.GetOffset() + prologue_byte_size);
186 byte_size -= prologue_byte_size;
187 }
188 }
189
190 if (filter.AddressPasses (func_addr))
191 {
192 AddressRange new_range (func_addr, byte_size);
193 m_address_ranges.push_back (new_range);
194 }
195 }
196 }
197 }
198 }
199
200 for (i = 0; i < sym_list.GetSize(); i++)
201 {
202 if (sym_list.GetContextAtIndex(i, sc))
203 {
204 if (sc.symbol && sc.symbol->GetAddressRangePtr())
205 {
206 func_addr = sc.symbol->GetAddressRangePtr()->GetBaseAddress();
207 addr_t byte_size = sc.symbol->GetAddressRangePtr()->GetByteSize();
208
209 if (skip_prologue)
210 {
211 const uint32_t prologue_byte_size = sc.symbol->GetPrologueByteSize();
212 if (prologue_byte_size)
213 {
214 func_addr.SetOffset (func_addr.GetOffset() + prologue_byte_size);
215 byte_size -= prologue_byte_size;
216 }
217 }
218
219 if (filter.AddressPasses (func_addr))
220 {
221 AddressRange new_range (func_addr, byte_size);
222 m_address_ranges.push_back (new_range);
223 }
224 }
225 }
226 }
227 return Searcher::eCallbackReturnContinue;
228}
229
230Searcher::Depth
231AddressResolverName::GetDepth()
232{
233 return Searcher::eDepthModule;
234}
235
236void
237AddressResolverName::GetDescription (Stream *s)
238{
239 s->PutCString("Address by function name: ");
240
241 if (m_match_type == AddressResolver::Regexp)
242 s->Printf("'%s' (regular expression)", m_regex.GetText());
243 else
244 s->Printf("'%s'", m_func_name.AsCString());
245}
246