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