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