AddressResolverName.cpp revision 24943d2ee8bfaa7cf5893e4709143924157a5c1e
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            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
232