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 // C Includes 13 // C++ Includes 14 // Other libraries and framework includes 15 // Project includes 16 #include "lldb/Core/Log.h" 17 #include "lldb/Core/Module.h" 18 #include "lldb/Core/StreamString.h" 19 #include "lldb/Symbol/Function.h" 20 #include "lldb/Symbol/SymbolContext.h" 21 #include "lldb/Symbol/Symbol.h" 22 23 using namespace lldb; 24 using namespace lldb_private; 25 26 AddressResolverName::AddressResolverName(const char *func_name, 27 AddressResolver::MatchType type) : 28 AddressResolver(), 29 m_func_name(func_name), 30 m_class_name(nullptr), 31 m_regex(), 32 m_match_type(type) 33 { 34 if (m_match_type == AddressResolver::Regexp) 35 { 36 if (!m_regex.Compile (m_func_name.AsCString())) 37 { 38 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS)); 39 40 if (log) 41 log->Warning ("function name regexp: \"%s\" did not compile.", m_func_name.AsCString()); 42 } 43 } 44 } 45 46 AddressResolverName::AddressResolverName(RegularExpression &func_regex) : 47 AddressResolver(), 48 m_func_name(nullptr), 49 m_class_name(nullptr), 50 m_regex(func_regex), 51 m_match_type(AddressResolver::Regexp) 52 { 53 } 54 55 AddressResolverName::AddressResolverName(const char *class_name, 56 const char *method, 57 AddressResolver::MatchType type) : 58 AddressResolver (), 59 m_func_name (method), 60 m_class_name (class_name), 61 m_regex (), 62 m_match_type (type) 63 { 64 } 65 66 AddressResolverName::~AddressResolverName() = default; 67 68 // FIXME: Right now we look at the module level, and call the module's "FindFunctions". 69 // Greg says he will add function tables, maybe at the CompileUnit level to accelerate function 70 // lookup. At that point, we should switch the depth to CompileUnit, and look in these tables. 71 72 Searcher::CallbackReturn 73 AddressResolverName::SearchCallback(SearchFilter &filter, 74 SymbolContext &context, 75 Address *addr, 76 bool containing) 77 { 78 SymbolContextList func_list; 79 SymbolContextList sym_list; 80 81 bool skip_prologue = true; 82 uint32_t i; 83 SymbolContext sc; 84 Address func_addr; 85 86 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS)); 87 88 if (m_class_name) 89 { 90 if (log) 91 log->Warning ("Class/method function specification not supported yet.\n"); 92 return Searcher::eCallbackReturnStop; 93 } 94 95 const bool include_symbols = false; 96 const bool include_inlines = true; 97 const bool append = false; 98 switch (m_match_type) 99 { 100 case AddressResolver::Exact: 101 if (context.module_sp) 102 { 103 context.module_sp->FindSymbolsWithNameAndType (m_func_name, 104 eSymbolTypeCode, 105 sym_list); 106 context.module_sp->FindFunctions(m_func_name, 107 nullptr, 108 eFunctionNameTypeAuto, 109 include_symbols, 110 include_inlines, 111 append, 112 func_list); 113 } 114 break; 115 116 case AddressResolver::Regexp: 117 if (context.module_sp) 118 { 119 context.module_sp->FindSymbolsMatchingRegExAndType (m_regex, 120 eSymbolTypeCode, 121 sym_list); 122 context.module_sp->FindFunctions (m_regex, 123 include_symbols, 124 include_inlines, 125 append, 126 func_list); 127 } 128 break; 129 130 case AddressResolver::Glob: 131 if (log) 132 log->Warning ("glob is not supported yet."); 133 break; 134 } 135 136 // Remove any duplicates between the function list and the symbol list 137 if (func_list.GetSize()) 138 { 139 for (i = 0; i < func_list.GetSize(); i++) 140 { 141 if (!func_list.GetContextAtIndex(i, sc)) 142 continue; 143 144 if (sc.function == nullptr) 145 continue; 146 uint32_t j = 0; 147 while (j < sym_list.GetSize()) 148 { 149 SymbolContext symbol_sc; 150 if (sym_list.GetContextAtIndex(j, symbol_sc)) 151 { 152 if (symbol_sc.symbol && symbol_sc.symbol->ValueIsAddress()) 153 { 154 if (sc.function->GetAddressRange().GetBaseAddress() == symbol_sc.symbol->GetAddressRef()) 155 { 156 sym_list.RemoveContextAtIndex(j); 157 continue; // Don't increment j 158 } 159 } 160 } 161 162 j++; 163 } 164 } 165 166 for (i = 0; i < func_list.GetSize(); i++) 167 { 168 if (func_list.GetContextAtIndex(i, sc)) 169 { 170 if (sc.function) 171 { 172 func_addr = sc.function->GetAddressRange().GetBaseAddress(); 173 addr_t byte_size = sc.function->GetAddressRange().GetByteSize(); 174 if (skip_prologue) 175 { 176 const uint32_t prologue_byte_size = sc.function->GetPrologueByteSize(); 177 if (prologue_byte_size) 178 { 179 func_addr.SetOffset (func_addr.GetOffset() + prologue_byte_size); 180 byte_size -= prologue_byte_size; 181 } 182 } 183 184 if (filter.AddressPasses (func_addr)) 185 { 186 AddressRange new_range (func_addr, byte_size); 187 m_address_ranges.push_back (new_range); 188 } 189 } 190 } 191 } 192 } 193 194 for (i = 0; i < sym_list.GetSize(); i++) 195 { 196 if (sym_list.GetContextAtIndex(i, sc)) 197 { 198 if (sc.symbol && sc.symbol->ValueIsAddress()) 199 { 200 func_addr = sc.symbol->GetAddressRef(); 201 addr_t byte_size = sc.symbol->GetByteSize(); 202 203 if (skip_prologue) 204 { 205 const uint32_t prologue_byte_size = sc.symbol->GetPrologueByteSize(); 206 if (prologue_byte_size) 207 { 208 func_addr.SetOffset (func_addr.GetOffset() + prologue_byte_size); 209 byte_size -= prologue_byte_size; 210 } 211 } 212 213 if (filter.AddressPasses (func_addr)) 214 { 215 AddressRange new_range (func_addr, byte_size); 216 m_address_ranges.push_back (new_range); 217 } 218 } 219 } 220 } 221 return Searcher::eCallbackReturnContinue; 222 } 223 224 Searcher::Depth 225 AddressResolverName::GetDepth() 226 { 227 return Searcher::eDepthModule; 228 } 229 230 void 231 AddressResolverName::GetDescription (Stream *s) 232 { 233 s->PutCString("Address by function name: "); 234 235 if (m_match_type == AddressResolver::Regexp) 236 s->Printf("'%s' (regular expression)", m_regex.GetText()); 237 else 238 s->Printf("'%s'", m_func_name.AsCString()); 239 } 240