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