blob: f1874202fec28827b51ba68251e89618f398a74c [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;
Sean Callanan9df05fb2012-02-10 22:52:19 +0000107 const bool include_inlines = true;
Greg Clayton931180e2011-01-27 06:44:37 +0000108 const bool append = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000109 switch (m_match_type)
110 {
Greg Clayton931180e2011-01-27 06:44:37 +0000111 case AddressResolver::Exact:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000112 if (context.module_sp)
113 {
Sean Callananb6d70eb2011-10-12 02:08:07 +0000114 context.module_sp->FindSymbolsWithNameAndType (m_func_name,
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,
Sean Callanan9df05fb2012-02-10 22:52:19 +0000121 include_inlines,
Greg Clayton931180e2011-01-27 06:44:37 +0000122 append,
Greg Clayton0c5cd902010-06-28 21:30:43 +0000123 func_list);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000124 }
125 break;
Greg Clayton931180e2011-01-27 06:44:37 +0000126
127 case AddressResolver::Regexp:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000128 if (context.module_sp)
129 {
Greg Clayton0c5cd902010-06-28 21:30:43 +0000130 context.module_sp->FindSymbolsMatchingRegExAndType (m_regex,
131 eSymbolTypeCode,
132 sym_list);
133 context.module_sp->FindFunctions (m_regex,
Greg Clayton931180e2011-01-27 06:44:37 +0000134 include_symbols,
Sean Callanan9df05fb2012-02-10 22:52:19 +0000135 include_inlines,
Greg Clayton931180e2011-01-27 06:44:37 +0000136 append,
Greg Clayton0c5cd902010-06-28 21:30:43 +0000137 func_list);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000138 }
139 break;
Greg Clayton931180e2011-01-27 06:44:37 +0000140
141 case AddressResolver::Glob:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000142 if (log)
143 log->Warning ("glob is not supported yet.");
144 break;
145 }
146
147 // Remove any duplicates between the funcion list and the symbol list
148 if (func_list.GetSize())
149 {
150 for (i = 0; i < func_list.GetSize(); i++)
151 {
152 if (func_list.GetContextAtIndex(i, sc) == false)
153 continue;
154
155 if (sc.function == NULL)
156 continue;
157 uint32_t j = 0;
158 while (j < sym_list.GetSize())
159 {
160 SymbolContext symbol_sc;
161 if (sym_list.GetContextAtIndex(j, symbol_sc))
162 {
Greg Claytone7612132012-03-07 21:03:09 +0000163 if (symbol_sc.symbol && symbol_sc.symbol->ValueIsAddress())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000164 {
Greg Claytone7612132012-03-07 21:03:09 +0000165 if (sc.function->GetAddressRange().GetBaseAddress() == symbol_sc.symbol->GetAddress())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000166 {
167 sym_list.RemoveContextAtIndex(j);
168 continue; // Don't increment j
169 }
170 }
171 }
172
173 j++;
174 }
175 }
176
177 for (i = 0; i < func_list.GetSize(); i++)
178 {
179 if (func_list.GetContextAtIndex(i, sc))
180 {
181 if (sc.function)
182 {
183 func_addr = sc.function->GetAddressRange().GetBaseAddress();
184 addr_t byte_size = sc.function->GetAddressRange().GetByteSize();
185 if (skip_prologue)
186 {
187 const uint32_t prologue_byte_size = sc.function->GetPrologueByteSize();
188 if (prologue_byte_size)
189 {
190 func_addr.SetOffset (func_addr.GetOffset() + prologue_byte_size);
191 byte_size -= prologue_byte_size;
192 }
193 }
194
195 if (filter.AddressPasses (func_addr))
196 {
197 AddressRange new_range (func_addr, byte_size);
198 m_address_ranges.push_back (new_range);
199 }
200 }
201 }
202 }
203 }
204
205 for (i = 0; i < sym_list.GetSize(); i++)
206 {
207 if (sym_list.GetContextAtIndex(i, sc))
208 {
Greg Claytone7612132012-03-07 21:03:09 +0000209 if (sc.symbol && sc.symbol->ValueIsAddress())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000210 {
Greg Claytone7612132012-03-07 21:03:09 +0000211 func_addr = sc.symbol->GetAddress();
212 addr_t byte_size = sc.symbol->GetByteSize();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000213
214 if (skip_prologue)
215 {
216 const uint32_t prologue_byte_size = sc.symbol->GetPrologueByteSize();
217 if (prologue_byte_size)
218 {
219 func_addr.SetOffset (func_addr.GetOffset() + prologue_byte_size);
220 byte_size -= prologue_byte_size;
221 }
222 }
223
224 if (filter.AddressPasses (func_addr))
225 {
226 AddressRange new_range (func_addr, byte_size);
227 m_address_ranges.push_back (new_range);
228 }
229 }
230 }
231 }
232 return Searcher::eCallbackReturnContinue;
233}
234
235Searcher::Depth
236AddressResolverName::GetDepth()
237{
238 return Searcher::eDepthModule;
239}
240
241void
242AddressResolverName::GetDescription (Stream *s)
243{
244 s->PutCString("Address by function name: ");
245
246 if (m_match_type == AddressResolver::Regexp)
247 s->Printf("'%s' (regular expression)", m_regex.GetText());
248 else
249 s->Printf("'%s'", m_func_name.AsCString());
250}
251