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