blob: 490fc4643484e8227aaa708e84fad765ad4336bb [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 {
35 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS);
36
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
96 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS);
97
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
105 switch (m_match_type)
106 {
107 case AddressResolver::Exact:
108 if (context.module_sp)
109 {
Greg Clayton0c5cd902010-06-28 21:30:43 +0000110 context.module_sp->FindSymbolsWithNameAndType (m_func_name,
111 eSymbolTypeCode,
112 sym_list);
113 context.module_sp->FindFunctions (m_func_name,
114 eFunctionNameTypeBase | eFunctionNameTypeFull | eFunctionNameTypeMethod | eFunctionNameTypeSelector,
115 false,
116 func_list);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000117 }
118 break;
119 case AddressResolver::Regexp:
120 if (context.module_sp)
121 {
Greg Clayton0c5cd902010-06-28 21:30:43 +0000122 context.module_sp->FindSymbolsMatchingRegExAndType (m_regex,
123 eSymbolTypeCode,
124 sym_list);
125 context.module_sp->FindFunctions (m_regex,
126 true,
127 func_list);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000128 }
129 break;
130 case AddressResolver::Glob:
131 if (log)
132 log->Warning ("glob is not supported yet.");
133 break;
134 }
135
136 // Remove any duplicates between the funcion list and the symbol list
137 if (func_list.GetSize())
138 {
139 for (i = 0; i < func_list.GetSize(); i++)
140 {
141 if (func_list.GetContextAtIndex(i, sc) == false)
142 continue;
143
144 if (sc.function == NULL)
145 continue;
146 uint32_t j = 0;
147 while (j < sym_list.GetSize())
148 {
149 SymbolContext symbol_sc;
150 if (sym_list.GetContextAtIndex(j, symbol_sc))
151 {
152 if (symbol_sc.symbol && symbol_sc.symbol->GetAddressRangePtr())
153 {
154 if (sc.function->GetAddressRange().GetBaseAddress() == symbol_sc.symbol->GetAddressRangePtr()->GetBaseAddress())
155 {
156 sym_list.RemoveContextAtIndex(j);
157 continue; // Don't increment j
158 }
159 }
160 }
161
162 j++;
163 }
164 }
165
166 for (i = 0; i < func_list.GetSize(); i++)
167 {
168 if (func_list.GetContextAtIndex(i, sc))
169 {
170 if (sc.function)
171 {
172 func_addr = sc.function->GetAddressRange().GetBaseAddress();
173 addr_t byte_size = sc.function->GetAddressRange().GetByteSize();
174 if (skip_prologue)
175 {
176 const uint32_t prologue_byte_size = sc.function->GetPrologueByteSize();
177 if (prologue_byte_size)
178 {
179 func_addr.SetOffset (func_addr.GetOffset() + prologue_byte_size);
180 byte_size -= prologue_byte_size;
181 }
182 }
183
184 if (filter.AddressPasses (func_addr))
185 {
186 AddressRange new_range (func_addr, byte_size);
187 m_address_ranges.push_back (new_range);
188 }
189 }
190 }
191 }
192 }
193
194 for (i = 0; i < sym_list.GetSize(); i++)
195 {
196 if (sym_list.GetContextAtIndex(i, sc))
197 {
198 if (sc.symbol && sc.symbol->GetAddressRangePtr())
199 {
200 func_addr = sc.symbol->GetAddressRangePtr()->GetBaseAddress();
201 addr_t byte_size = sc.symbol->GetAddressRangePtr()->GetByteSize();
202
203 if (skip_prologue)
204 {
205 const uint32_t prologue_byte_size = sc.symbol->GetPrologueByteSize();
206 if (prologue_byte_size)
207 {
208 func_addr.SetOffset (func_addr.GetOffset() + prologue_byte_size);
209 byte_size -= prologue_byte_size;
210 }
211 }
212
213 if (filter.AddressPasses (func_addr))
214 {
215 AddressRange new_range (func_addr, byte_size);
216 m_address_ranges.push_back (new_range);
217 }
218 }
219 }
220 }
221 return Searcher::eCallbackReturnContinue;
222}
223
224Searcher::Depth
225AddressResolverName::GetDepth()
226{
227 return Searcher::eDepthModule;
228}
229
230void
231AddressResolverName::GetDescription (Stream *s)
232{
233 s->PutCString("Address by function name: ");
234
235 if (m_match_type == AddressResolver::Regexp)
236 s->Printf("'%s' (regular expression)", m_regex.GetText());
237 else
238 s->Printf("'%s'", m_func_name.AsCString());
239}
240