blob: 14424205f421af69d583340c0e6a03d5ebf92d85 [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
Eugene Zelenko896ddd02016-03-02 01:09:03 +000012// C Includes
13// C++ Includes
14// Other libraries and framework includes
Chris Lattner30fdc8d2010-06-08 16:52:24 +000015// Project includes
Greg Clayton1f746072012-08-29 21:13:06 +000016#include "lldb/Core/Module.h"
Greg Clayton1f746072012-08-29 21:13:06 +000017#include "lldb/Symbol/Function.h"
Greg Clayton1f746072012-08-29 21:13:06 +000018#include "lldb/Symbol/Symbol.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000019#include "lldb/Symbol/SymbolContext.h"
Zachary Turner6f9e6902017-03-03 20:56:28 +000020#include "lldb/Utility/Log.h"
Zachary Turnerbf9a7732017-02-02 21:39:50 +000021#include "lldb/Utility/StreamString.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000022
23using namespace lldb;
24using namespace lldb_private;
25
Eugene Zelenko896ddd02016-03-02 01:09:03 +000026AddressResolverName::AddressResolverName(const char *func_name,
Kate Stoneb9c1b512016-09-06 20:57:50 +000027 AddressResolver::MatchType type)
28 : AddressResolver(), m_func_name(func_name), m_class_name(nullptr),
29 m_regex(), m_match_type(type) {
30 if (m_match_type == AddressResolver::Regexp) {
Zachary Turner95eae422016-09-21 16:01:28 +000031 if (!m_regex.Compile(m_func_name.GetStringRef())) {
Kate Stoneb9c1b512016-09-06 20:57:50 +000032 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
Chris Lattner30fdc8d2010-06-08 16:52:24 +000033
Kate Stoneb9c1b512016-09-06 20:57:50 +000034 if (log)
35 log->Warning("function name regexp: \"%s\" did not compile.",
36 m_func_name.AsCString());
Chris Lattner30fdc8d2010-06-08 16:52:24 +000037 }
Kate Stoneb9c1b512016-09-06 20:57:50 +000038 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +000039}
40
Kate Stoneb9c1b512016-09-06 20:57:50 +000041AddressResolverName::AddressResolverName(RegularExpression &func_regex)
42 : AddressResolver(), m_func_name(nullptr), m_class_name(nullptr),
43 m_regex(func_regex), m_match_type(AddressResolver::Regexp) {}
Chris Lattner30fdc8d2010-06-08 16:52:24 +000044
Eugene Zelenko896ddd02016-03-02 01:09:03 +000045AddressResolverName::AddressResolverName(const char *class_name,
46 const char *method,
Kate Stoneb9c1b512016-09-06 20:57:50 +000047 AddressResolver::MatchType type)
48 : AddressResolver(), m_func_name(method), m_class_name(class_name),
49 m_regex(), m_match_type(type) {}
Chris Lattner30fdc8d2010-06-08 16:52:24 +000050
Eugene Zelenko896ddd02016-03-02 01:09:03 +000051AddressResolverName::~AddressResolverName() = default;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000052
Kate Stoneb9c1b512016-09-06 20:57:50 +000053// FIXME: Right now we look at the module level, and call the module's
54// "FindFunctions".
55// Greg says he will add function tables, maybe at the CompileUnit level to
56// accelerate function
57// lookup. At that point, we should switch the depth to CompileUnit, and look
58// in these tables.
Chris Lattner30fdc8d2010-06-08 16:52:24 +000059
60Searcher::CallbackReturn
Eugene Zelenko896ddd02016-03-02 01:09:03 +000061AddressResolverName::SearchCallback(SearchFilter &filter,
Kate Stoneb9c1b512016-09-06 20:57:50 +000062 SymbolContext &context, Address *addr,
63 bool containing) {
64 SymbolContextList func_list;
65 SymbolContextList sym_list;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000066
Kate Stoneb9c1b512016-09-06 20:57:50 +000067 bool skip_prologue = true;
68 uint32_t i;
69 SymbolContext sc;
70 Address func_addr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000071
Kate Stoneb9c1b512016-09-06 20:57:50 +000072 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
Chris Lattner30fdc8d2010-06-08 16:52:24 +000073
Kate Stoneb9c1b512016-09-06 20:57:50 +000074 if (m_class_name) {
75 if (log)
76 log->Warning("Class/method function specification not supported yet.\n");
77 return Searcher::eCallbackReturnStop;
78 }
79
80 const bool include_symbols = false;
81 const bool include_inlines = true;
82 const bool append = false;
83 switch (m_match_type) {
84 case AddressResolver::Exact:
85 if (context.module_sp) {
86 context.module_sp->FindSymbolsWithNameAndType(m_func_name,
87 eSymbolTypeCode, sym_list);
88 context.module_sp->FindFunctions(m_func_name, nullptr,
89 eFunctionNameTypeAuto, include_symbols,
90 include_inlines, append, func_list);
Chris Lattner30fdc8d2010-06-08 16:52:24 +000091 }
Kate Stoneb9c1b512016-09-06 20:57:50 +000092 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000093
Kate Stoneb9c1b512016-09-06 20:57:50 +000094 case AddressResolver::Regexp:
95 if (context.module_sp) {
96 context.module_sp->FindSymbolsMatchingRegExAndType(
97 m_regex, eSymbolTypeCode, sym_list);
98 context.module_sp->FindFunctions(m_regex, include_symbols,
99 include_inlines, append, func_list);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000100 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000101 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000102
Kate Stoneb9c1b512016-09-06 20:57:50 +0000103 case AddressResolver::Glob:
104 if (log)
105 log->Warning("glob is not supported yet.");
106 break;
107 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000108
Kate Stoneb9c1b512016-09-06 20:57:50 +0000109 // Remove any duplicates between the function list and the symbol list
110 if (func_list.GetSize()) {
111 for (i = 0; i < func_list.GetSize(); i++) {
112 if (!func_list.GetContextAtIndex(i, sc))
113 continue;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000114
Kate Stoneb9c1b512016-09-06 20:57:50 +0000115 if (sc.function == nullptr)
116 continue;
117 uint32_t j = 0;
118 while (j < sym_list.GetSize()) {
119 SymbolContext symbol_sc;
120 if (sym_list.GetContextAtIndex(j, symbol_sc)) {
121 if (symbol_sc.symbol && symbol_sc.symbol->ValueIsAddress()) {
122 if (sc.function->GetAddressRange().GetBaseAddress() ==
123 symbol_sc.symbol->GetAddressRef()) {
124 sym_list.RemoveContextAtIndex(j);
125 continue; // Don't increment j
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000126 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000127 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000128 }
129
Kate Stoneb9c1b512016-09-06 20:57:50 +0000130 j++;
131 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000132 }
133
Kate Stoneb9c1b512016-09-06 20:57:50 +0000134 for (i = 0; i < func_list.GetSize(); i++) {
135 if (func_list.GetContextAtIndex(i, sc)) {
136 if (sc.function) {
137 func_addr = sc.function->GetAddressRange().GetBaseAddress();
138 addr_t byte_size = sc.function->GetAddressRange().GetByteSize();
139 if (skip_prologue) {
140 const uint32_t prologue_byte_size =
141 sc.function->GetPrologueByteSize();
142 if (prologue_byte_size) {
143 func_addr.SetOffset(func_addr.GetOffset() + prologue_byte_size);
144 byte_size -= prologue_byte_size;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000145 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000146 }
147
148 if (filter.AddressPasses(func_addr)) {
149 AddressRange new_range(func_addr, byte_size);
150 m_address_ranges.push_back(new_range);
151 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000152 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000153 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000154 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000155 }
156
157 for (i = 0; i < sym_list.GetSize(); i++) {
158 if (sym_list.GetContextAtIndex(i, sc)) {
159 if (sc.symbol && sc.symbol->ValueIsAddress()) {
160 func_addr = sc.symbol->GetAddressRef();
161 addr_t byte_size = sc.symbol->GetByteSize();
162
163 if (skip_prologue) {
164 const uint32_t prologue_byte_size = sc.symbol->GetPrologueByteSize();
165 if (prologue_byte_size) {
166 func_addr.SetOffset(func_addr.GetOffset() + prologue_byte_size);
167 byte_size -= prologue_byte_size;
168 }
169 }
170
171 if (filter.AddressPasses(func_addr)) {
172 AddressRange new_range(func_addr, byte_size);
173 m_address_ranges.push_back(new_range);
174 }
175 }
176 }
177 }
178 return Searcher::eCallbackReturnContinue;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000179}
180
Kate Stoneb9c1b512016-09-06 20:57:50 +0000181Searcher::Depth AddressResolverName::GetDepth() {
182 return Searcher::eDepthModule;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000183}
184
Kate Stoneb9c1b512016-09-06 20:57:50 +0000185void AddressResolverName::GetDescription(Stream *s) {
186 s->PutCString("Address by function name: ");
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000187
Kate Stoneb9c1b512016-09-06 20:57:50 +0000188 if (m_match_type == AddressResolver::Regexp)
Zachary Turner95eae422016-09-21 16:01:28 +0000189 s->Printf("'%s' (regular expression)", m_regex.GetText().str().c_str());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000190 else
191 s->Printf("'%s'", m_func_name.AsCString());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000192}