blob: c3dab6d108103089453100423a0fb357466ff9c1 [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
Zachary Turner2f3df612017-04-06 21:28:29 +000012#include "lldb/Core/Address.h" // for Address, operator==
13#include "lldb/Core/AddressRange.h" // for AddressRange
Greg Clayton1f746072012-08-29 21:13:06 +000014#include "lldb/Core/Module.h"
Greg Clayton1f746072012-08-29 21:13:06 +000015#include "lldb/Symbol/Function.h"
Greg Clayton1f746072012-08-29 21:13:06 +000016#include "lldb/Symbol/Symbol.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000017#include "lldb/Symbol/SymbolContext.h"
Zachary Turner6f9e6902017-03-03 20:56:28 +000018#include "lldb/Utility/Log.h"
Zachary Turner2f3df612017-04-06 21:28:29 +000019#include "lldb/Utility/Logging.h" // for GetLogIfAllCategoriesSet, LIB...
20#include "lldb/Utility/Stream.h" // for Stream
21#include "lldb/lldb-enumerations.h" // for SymbolType::eSymbolTypeCode
22#include "lldb/lldb-forward.h" // for ModuleSP
23#include "lldb/lldb-types.h" // for addr_t
24#include "llvm/ADT/StringRef.h" // for StringRef
25
26#include <memory> // for shared_ptr
27#include <string> // for string
28#include <vector> // for vector
29
30#include <stdint.h> // for uint32_t
Chris Lattner30fdc8d2010-06-08 16:52:24 +000031
32using namespace lldb;
33using namespace lldb_private;
34
Eugene Zelenko896ddd02016-03-02 01:09:03 +000035AddressResolverName::AddressResolverName(const char *func_name,
Kate Stoneb9c1b512016-09-06 20:57:50 +000036 AddressResolver::MatchType type)
37 : AddressResolver(), m_func_name(func_name), m_class_name(nullptr),
38 m_regex(), m_match_type(type) {
39 if (m_match_type == AddressResolver::Regexp) {
Zachary Turner95eae422016-09-21 16:01:28 +000040 if (!m_regex.Compile(m_func_name.GetStringRef())) {
Kate Stoneb9c1b512016-09-06 20:57:50 +000041 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
Chris Lattner30fdc8d2010-06-08 16:52:24 +000042
Kate Stoneb9c1b512016-09-06 20:57:50 +000043 if (log)
44 log->Warning("function name regexp: \"%s\" did not compile.",
45 m_func_name.AsCString());
Chris Lattner30fdc8d2010-06-08 16:52:24 +000046 }
Kate Stoneb9c1b512016-09-06 20:57:50 +000047 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +000048}
49
Kate Stoneb9c1b512016-09-06 20:57:50 +000050AddressResolverName::AddressResolverName(RegularExpression &func_regex)
51 : AddressResolver(), m_func_name(nullptr), m_class_name(nullptr),
52 m_regex(func_regex), m_match_type(AddressResolver::Regexp) {}
Chris Lattner30fdc8d2010-06-08 16:52:24 +000053
Eugene Zelenko896ddd02016-03-02 01:09:03 +000054AddressResolverName::AddressResolverName(const char *class_name,
55 const char *method,
Kate Stoneb9c1b512016-09-06 20:57:50 +000056 AddressResolver::MatchType type)
57 : AddressResolver(), m_func_name(method), m_class_name(class_name),
58 m_regex(), m_match_type(type) {}
Chris Lattner30fdc8d2010-06-08 16:52:24 +000059
Eugene Zelenko896ddd02016-03-02 01:09:03 +000060AddressResolverName::~AddressResolverName() = default;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000061
Kate Stoneb9c1b512016-09-06 20:57:50 +000062// FIXME: Right now we look at the module level, and call the module's
63// "FindFunctions".
64// Greg says he will add function tables, maybe at the CompileUnit level to
Adrian Prantl05097242018-04-30 16:49:04 +000065// accelerate function lookup. At that point, we should switch the depth to
66// CompileUnit, and look in these tables.
Chris Lattner30fdc8d2010-06-08 16:52:24 +000067
68Searcher::CallbackReturn
Eugene Zelenko896ddd02016-03-02 01:09:03 +000069AddressResolverName::SearchCallback(SearchFilter &filter,
Kate Stoneb9c1b512016-09-06 20:57:50 +000070 SymbolContext &context, Address *addr,
71 bool containing) {
72 SymbolContextList func_list;
73 SymbolContextList sym_list;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000074
Kate Stoneb9c1b512016-09-06 20:57:50 +000075 bool skip_prologue = true;
76 uint32_t i;
77 SymbolContext sc;
78 Address func_addr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000079
Kate Stoneb9c1b512016-09-06 20:57:50 +000080 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
Chris Lattner30fdc8d2010-06-08 16:52:24 +000081
Kate Stoneb9c1b512016-09-06 20:57:50 +000082 if (m_class_name) {
83 if (log)
84 log->Warning("Class/method function specification not supported yet.\n");
85 return Searcher::eCallbackReturnStop;
86 }
87
88 const bool include_symbols = false;
89 const bool include_inlines = true;
90 const bool append = false;
91 switch (m_match_type) {
92 case AddressResolver::Exact:
93 if (context.module_sp) {
94 context.module_sp->FindSymbolsWithNameAndType(m_func_name,
95 eSymbolTypeCode, sym_list);
96 context.module_sp->FindFunctions(m_func_name, nullptr,
97 eFunctionNameTypeAuto, include_symbols,
98 include_inlines, append, func_list);
Chris Lattner30fdc8d2010-06-08 16:52:24 +000099 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000100 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000101
Kate Stoneb9c1b512016-09-06 20:57:50 +0000102 case AddressResolver::Regexp:
103 if (context.module_sp) {
104 context.module_sp->FindSymbolsMatchingRegExAndType(
105 m_regex, eSymbolTypeCode, sym_list);
106 context.module_sp->FindFunctions(m_regex, include_symbols,
107 include_inlines, append, func_list);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000108 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000109 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000110
Kate Stoneb9c1b512016-09-06 20:57:50 +0000111 case AddressResolver::Glob:
112 if (log)
113 log->Warning("glob is not supported yet.");
114 break;
115 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000116
Kate Stoneb9c1b512016-09-06 20:57:50 +0000117 // Remove any duplicates between the function list and the symbol list
118 if (func_list.GetSize()) {
119 for (i = 0; i < func_list.GetSize(); i++) {
120 if (!func_list.GetContextAtIndex(i, sc))
121 continue;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000122
Kate Stoneb9c1b512016-09-06 20:57:50 +0000123 if (sc.function == nullptr)
124 continue;
125 uint32_t j = 0;
126 while (j < sym_list.GetSize()) {
127 SymbolContext symbol_sc;
128 if (sym_list.GetContextAtIndex(j, symbol_sc)) {
129 if (symbol_sc.symbol && symbol_sc.symbol->ValueIsAddress()) {
130 if (sc.function->GetAddressRange().GetBaseAddress() ==
131 symbol_sc.symbol->GetAddressRef()) {
132 sym_list.RemoveContextAtIndex(j);
133 continue; // Don't increment j
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000134 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000135 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000136 }
137
Kate Stoneb9c1b512016-09-06 20:57:50 +0000138 j++;
139 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000140 }
141
Kate Stoneb9c1b512016-09-06 20:57:50 +0000142 for (i = 0; i < func_list.GetSize(); i++) {
143 if (func_list.GetContextAtIndex(i, sc)) {
144 if (sc.function) {
145 func_addr = sc.function->GetAddressRange().GetBaseAddress();
146 addr_t byte_size = sc.function->GetAddressRange().GetByteSize();
147 if (skip_prologue) {
148 const uint32_t prologue_byte_size =
149 sc.function->GetPrologueByteSize();
150 if (prologue_byte_size) {
151 func_addr.SetOffset(func_addr.GetOffset() + prologue_byte_size);
152 byte_size -= prologue_byte_size;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000153 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000154 }
155
156 if (filter.AddressPasses(func_addr)) {
157 AddressRange new_range(func_addr, byte_size);
158 m_address_ranges.push_back(new_range);
159 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000160 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000161 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000162 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000163 }
164
165 for (i = 0; i < sym_list.GetSize(); i++) {
166 if (sym_list.GetContextAtIndex(i, sc)) {
167 if (sc.symbol && sc.symbol->ValueIsAddress()) {
168 func_addr = sc.symbol->GetAddressRef();
169 addr_t byte_size = sc.symbol->GetByteSize();
170
171 if (skip_prologue) {
172 const uint32_t prologue_byte_size = sc.symbol->GetPrologueByteSize();
173 if (prologue_byte_size) {
174 func_addr.SetOffset(func_addr.GetOffset() + prologue_byte_size);
175 byte_size -= prologue_byte_size;
176 }
177 }
178
179 if (filter.AddressPasses(func_addr)) {
180 AddressRange new_range(func_addr, byte_size);
181 m_address_ranges.push_back(new_range);
182 }
183 }
184 }
185 }
186 return Searcher::eCallbackReturnContinue;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000187}
188
Kate Stoneb9c1b512016-09-06 20:57:50 +0000189Searcher::Depth AddressResolverName::GetDepth() {
190 return Searcher::eDepthModule;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000191}
192
Kate Stoneb9c1b512016-09-06 20:57:50 +0000193void AddressResolverName::GetDescription(Stream *s) {
194 s->PutCString("Address by function name: ");
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000195
Kate Stoneb9c1b512016-09-06 20:57:50 +0000196 if (m_match_type == AddressResolver::Regexp)
Zachary Turner95eae422016-09-21 16:01:28 +0000197 s->Printf("'%s' (regular expression)", m_regex.GetText().str().c_str());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000198 else
199 s->Printf("'%s'", m_func_name.AsCString());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000200}