blob: 821870041998aa0b32254c2fce3803109edd2cdc [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,
Greg Clayton0c5cd902010-06-28 21:30:43 +0000114 eSymbolTypeCode,
115 sym_list);
Sean Callananb6d70eb2011-10-12 02:08:07 +0000116 context.module_sp->FindFunctions (m_func_name,
117 NULL,
Greg Clayton0c5cd902010-06-28 21:30:43 +0000118 eFunctionNameTypeBase | eFunctionNameTypeFull | eFunctionNameTypeMethod | eFunctionNameTypeSelector,
Greg Clayton931180e2011-01-27 06:44:37 +0000119 include_symbols,
120 append,
Greg Clayton0c5cd902010-06-28 21:30:43 +0000121 func_list);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000122 }
123 break;
Greg Clayton931180e2011-01-27 06:44:37 +0000124
125 case AddressResolver::Regexp:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000126 if (context.module_sp)
127 {
Greg Clayton0c5cd902010-06-28 21:30:43 +0000128 context.module_sp->FindSymbolsMatchingRegExAndType (m_regex,
129 eSymbolTypeCode,
130 sym_list);
131 context.module_sp->FindFunctions (m_regex,
Greg Clayton931180e2011-01-27 06:44:37 +0000132 include_symbols,
133 append,
Greg Clayton0c5cd902010-06-28 21:30:43 +0000134 func_list);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000135 }
136 break;
Greg Clayton931180e2011-01-27 06:44:37 +0000137
138 case AddressResolver::Glob:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000139 if (log)
140 log->Warning ("glob is not supported yet.");
141 break;
142 }
143
144 // Remove any duplicates between the funcion list and the symbol list
145 if (func_list.GetSize())
146 {
147 for (i = 0; i < func_list.GetSize(); i++)
148 {
149 if (func_list.GetContextAtIndex(i, sc) == false)
150 continue;
151
152 if (sc.function == NULL)
153 continue;
154 uint32_t j = 0;
155 while (j < sym_list.GetSize())
156 {
157 SymbolContext symbol_sc;
158 if (sym_list.GetContextAtIndex(j, symbol_sc))
159 {
160 if (symbol_sc.symbol && symbol_sc.symbol->GetAddressRangePtr())
161 {
162 if (sc.function->GetAddressRange().GetBaseAddress() == symbol_sc.symbol->GetAddressRangePtr()->GetBaseAddress())
163 {
164 sym_list.RemoveContextAtIndex(j);
165 continue; // Don't increment j
166 }
167 }
168 }
169
170 j++;
171 }
172 }
173
174 for (i = 0; i < func_list.GetSize(); i++)
175 {
176 if (func_list.GetContextAtIndex(i, sc))
177 {
178 if (sc.function)
179 {
180 func_addr = sc.function->GetAddressRange().GetBaseAddress();
181 addr_t byte_size = sc.function->GetAddressRange().GetByteSize();
182 if (skip_prologue)
183 {
184 const uint32_t prologue_byte_size = sc.function->GetPrologueByteSize();
185 if (prologue_byte_size)
186 {
187 func_addr.SetOffset (func_addr.GetOffset() + prologue_byte_size);
188 byte_size -= prologue_byte_size;
189 }
190 }
191
192 if (filter.AddressPasses (func_addr))
193 {
194 AddressRange new_range (func_addr, byte_size);
195 m_address_ranges.push_back (new_range);
196 }
197 }
198 }
199 }
200 }
201
202 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 func_addr = sc.symbol->GetAddressRangePtr()->GetBaseAddress();
209 addr_t byte_size = sc.symbol->GetAddressRangePtr()->GetByteSize();
210
211 if (skip_prologue)
212 {
213 const uint32_t prologue_byte_size = sc.symbol->GetPrologueByteSize();
214 if (prologue_byte_size)
215 {
216 func_addr.SetOffset (func_addr.GetOffset() + prologue_byte_size);
217 byte_size -= prologue_byte_size;
218 }
219 }
220
221 if (filter.AddressPasses (func_addr))
222 {
223 AddressRange new_range (func_addr, byte_size);
224 m_address_ranges.push_back (new_range);
225 }
226 }
227 }
228 }
229 return Searcher::eCallbackReturnContinue;
230}
231
232Searcher::Depth
233AddressResolverName::GetDepth()
234{
235 return Searcher::eDepthModule;
236}
237
238void
239AddressResolverName::GetDescription (Stream *s)
240{
241 s->PutCString("Address by function name: ");
242
243 if (m_match_type == AddressResolver::Regexp)
244 s->Printf("'%s' (regular expression)", m_regex.GetText());
245 else
246 s->Printf("'%s'", m_func_name.AsCString());
247}
248