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