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