blob: 293002ad517fd646fff4b8acb42bd6ff66f38426 [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"
Greg Clayton1f746072012-08-29 21:13:06 +000014#include "lldb/Core/Module.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000015#include "lldb/Core/StreamString.h"
Greg Clayton1f746072012-08-29 21:13:06 +000016#include "lldb/Symbol/Function.h"
17#include "lldb/Symbol/SymbolContext.h"
18#include "lldb/Symbol/Symbol.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000019
20using namespace lldb;
21using namespace lldb_private;
22
23AddressResolverName::AddressResolverName
24(
25 const char *func_name,
26 AddressResolver::MatchType type
27) :
28 AddressResolver (),
29 m_func_name (func_name),
30 m_class_name (NULL),
31 m_regex (),
32 m_match_type (type)
33{
34 if (m_match_type == AddressResolver::Regexp)
35 {
36 if (!m_regex.Compile (m_func_name.AsCString()))
37 {
Greg Clayton5160ce52013-03-27 23:08:40 +000038 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
Chris Lattner30fdc8d2010-06-08 16:52:24 +000039
40 if (log)
41 log->Warning ("function name regexp: \"%s\" did not compile.", m_func_name.AsCString());
42 }
43 }
44}
45
46AddressResolverName::AddressResolverName
47(
48 RegularExpression &func_regex
49) :
50 AddressResolver (),
51 m_func_name (NULL),
52 m_class_name (NULL),
53 m_regex (func_regex),
54 m_match_type (AddressResolver::Regexp)
55{
56
57}
58
59AddressResolverName::AddressResolverName
60(
61 const char *class_name,
62 const char *method,
63 AddressResolver::MatchType type
64) :
65 AddressResolver (),
66 m_func_name (method),
67 m_class_name (class_name),
68 m_regex (),
69 m_match_type (type)
70{
71
72}
73
74AddressResolverName::~AddressResolverName ()
75{
76}
77
78// FIXME: Right now we look at the module level, and call the module's "FindFunctions".
79// Greg says he will add function tables, maybe at the CompileUnit level to accelerate function
80// lookup. At that point, we should switch the depth to CompileUnit, and look in these tables.
81
82Searcher::CallbackReturn
83AddressResolverName::SearchCallback
84(
85 SearchFilter &filter,
86 SymbolContext &context,
87 Address *addr,
88 bool containing
89)
90{
91 SymbolContextList func_list;
92 SymbolContextList sym_list;
93
94 bool skip_prologue = true;
95 uint32_t i;
96 SymbolContext sc;
97 Address func_addr;
98
Greg Clayton5160ce52013-03-27 23:08:40 +000099 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000100
101 if (m_class_name)
102 {
103 if (log)
104 log->Warning ("Class/method function specification not supported yet.\n");
105 return Searcher::eCallbackReturnStop;
106 }
107
Greg Clayton931180e2011-01-27 06:44:37 +0000108 const bool include_symbols = false;
Sean Callanan9df05fb2012-02-10 22:52:19 +0000109 const bool include_inlines = true;
Greg Clayton931180e2011-01-27 06:44:37 +0000110 const bool append = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000111 switch (m_match_type)
112 {
Greg Clayton931180e2011-01-27 06:44:37 +0000113 case AddressResolver::Exact:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000114 if (context.module_sp)
115 {
Sean Callananb6d70eb2011-10-12 02:08:07 +0000116 context.module_sp->FindSymbolsWithNameAndType (m_func_name,
Greg Clayton0c5cd902010-06-28 21:30:43 +0000117 eSymbolTypeCode,
118 sym_list);
Sean Callananb6d70eb2011-10-12 02:08:07 +0000119 context.module_sp->FindFunctions (m_func_name,
120 NULL,
Greg Clayton6ecb2322013-05-18 00:11:21 +0000121 eFunctionNameTypeAuto,
Greg Clayton931180e2011-01-27 06:44:37 +0000122 include_symbols,
Sean Callanan9df05fb2012-02-10 22:52:19 +0000123 include_inlines,
Greg Clayton931180e2011-01-27 06:44:37 +0000124 append,
Greg Clayton0c5cd902010-06-28 21:30:43 +0000125 func_list);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000126 }
127 break;
Greg Clayton931180e2011-01-27 06:44:37 +0000128
129 case AddressResolver::Regexp:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000130 if (context.module_sp)
131 {
Greg Clayton0c5cd902010-06-28 21:30:43 +0000132 context.module_sp->FindSymbolsMatchingRegExAndType (m_regex,
133 eSymbolTypeCode,
134 sym_list);
135 context.module_sp->FindFunctions (m_regex,
Greg Clayton931180e2011-01-27 06:44:37 +0000136 include_symbols,
Sean Callanan9df05fb2012-02-10 22:52:19 +0000137 include_inlines,
Greg Clayton931180e2011-01-27 06:44:37 +0000138 append,
Greg Clayton0c5cd902010-06-28 21:30:43 +0000139 func_list);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000140 }
141 break;
Greg Clayton931180e2011-01-27 06:44:37 +0000142
143 case AddressResolver::Glob:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000144 if (log)
145 log->Warning ("glob is not supported yet.");
146 break;
147 }
148
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +0000149 // Remove any duplicates between the function list and the symbol list
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000150 if (func_list.GetSize())
151 {
152 for (i = 0; i < func_list.GetSize(); i++)
153 {
154 if (func_list.GetContextAtIndex(i, sc) == false)
155 continue;
156
157 if (sc.function == NULL)
158 continue;
159 uint32_t j = 0;
160 while (j < sym_list.GetSize())
161 {
162 SymbolContext symbol_sc;
163 if (sym_list.GetContextAtIndex(j, symbol_sc))
164 {
Greg Claytone7612132012-03-07 21:03:09 +0000165 if (symbol_sc.symbol && symbol_sc.symbol->ValueIsAddress())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000166 {
Greg Clayton358cf1e2015-06-25 21:46:34 +0000167 if (sc.function->GetAddressRange().GetBaseAddress() == symbol_sc.symbol->GetAddressRef())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000168 {
169 sym_list.RemoveContextAtIndex(j);
170 continue; // Don't increment j
171 }
172 }
173 }
174
175 j++;
176 }
177 }
178
179 for (i = 0; i < func_list.GetSize(); i++)
180 {
181 if (func_list.GetContextAtIndex(i, sc))
182 {
183 if (sc.function)
184 {
185 func_addr = sc.function->GetAddressRange().GetBaseAddress();
186 addr_t byte_size = sc.function->GetAddressRange().GetByteSize();
187 if (skip_prologue)
188 {
189 const uint32_t prologue_byte_size = sc.function->GetPrologueByteSize();
190 if (prologue_byte_size)
191 {
192 func_addr.SetOffset (func_addr.GetOffset() + prologue_byte_size);
193 byte_size -= prologue_byte_size;
194 }
195 }
196
197 if (filter.AddressPasses (func_addr))
198 {
199 AddressRange new_range (func_addr, byte_size);
200 m_address_ranges.push_back (new_range);
201 }
202 }
203 }
204 }
205 }
206
207 for (i = 0; i < sym_list.GetSize(); i++)
208 {
209 if (sym_list.GetContextAtIndex(i, sc))
210 {
Greg Claytone7612132012-03-07 21:03:09 +0000211 if (sc.symbol && sc.symbol->ValueIsAddress())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000212 {
Greg Clayton358cf1e2015-06-25 21:46:34 +0000213 func_addr = sc.symbol->GetAddressRef();
Greg Claytone7612132012-03-07 21:03:09 +0000214 addr_t byte_size = sc.symbol->GetByteSize();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000215
216 if (skip_prologue)
217 {
218 const uint32_t prologue_byte_size = sc.symbol->GetPrologueByteSize();
219 if (prologue_byte_size)
220 {
221 func_addr.SetOffset (func_addr.GetOffset() + prologue_byte_size);
222 byte_size -= prologue_byte_size;
223 }
224 }
225
226 if (filter.AddressPasses (func_addr))
227 {
228 AddressRange new_range (func_addr, byte_size);
229 m_address_ranges.push_back (new_range);
230 }
231 }
232 }
233 }
234 return Searcher::eCallbackReturnContinue;
235}
236
237Searcher::Depth
238AddressResolverName::GetDepth()
239{
240 return Searcher::eDepthModule;
241}
242
243void
244AddressResolverName::GetDescription (Stream *s)
245{
246 s->PutCString("Address by function name: ");
247
248 if (m_match_type == AddressResolver::Regexp)
249 s->Printf("'%s' (regular expression)", m_regex.GetText());
250 else
251 s->Printf("'%s'", m_func_name.AsCString());
252}
253