AddressResolverName.cpp revision 3e80cd9c9e6ae50ff54537551e2fe3ed5319b9b4
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 append = false; 108 switch (m_match_type) 109 { 110 case AddressResolver::Exact: 111 if (context.module_sp) 112 { 113 context.module_sp->FindSymbolsWithNameAndType (m_func_name, 114 NULL, 115 eSymbolTypeCode, 116 sym_list); 117 context.module_sp->FindFunctions (m_func_name, 118 NULL, 119 eFunctionNameTypeBase | eFunctionNameTypeFull | eFunctionNameTypeMethod | eFunctionNameTypeSelector, 120 include_symbols, 121 append, 122 func_list); 123 } 124 break; 125 126 case AddressResolver::Regexp: 127 if (context.module_sp) 128 { 129 context.module_sp->FindSymbolsMatchingRegExAndType (m_regex, 130 eSymbolTypeCode, 131 sym_list); 132 context.module_sp->FindFunctions (m_regex, 133 include_symbols, 134 append, 135 func_list); 136 } 137 break; 138 139 case AddressResolver::Glob: 140 if (log) 141 log->Warning ("glob is not supported yet."); 142 break; 143 } 144 145 // Remove any duplicates between the funcion list and the symbol list 146 if (func_list.GetSize()) 147 { 148 for (i = 0; i < func_list.GetSize(); i++) 149 { 150 if (func_list.GetContextAtIndex(i, sc) == false) 151 continue; 152 153 if (sc.function == NULL) 154 continue; 155 uint32_t j = 0; 156 while (j < sym_list.GetSize()) 157 { 158 SymbolContext symbol_sc; 159 if (sym_list.GetContextAtIndex(j, symbol_sc)) 160 { 161 if (symbol_sc.symbol && symbol_sc.symbol->GetAddressRangePtr()) 162 { 163 if (sc.function->GetAddressRange().GetBaseAddress() == symbol_sc.symbol->GetAddressRangePtr()->GetBaseAddress()) 164 { 165 sym_list.RemoveContextAtIndex(j); 166 continue; // Don't increment j 167 } 168 } 169 } 170 171 j++; 172 } 173 } 174 175 for (i = 0; i < func_list.GetSize(); i++) 176 { 177 if (func_list.GetContextAtIndex(i, sc)) 178 { 179 if (sc.function) 180 { 181 func_addr = sc.function->GetAddressRange().GetBaseAddress(); 182 addr_t byte_size = sc.function->GetAddressRange().GetByteSize(); 183 if (skip_prologue) 184 { 185 const uint32_t prologue_byte_size = sc.function->GetPrologueByteSize(); 186 if (prologue_byte_size) 187 { 188 func_addr.SetOffset (func_addr.GetOffset() + prologue_byte_size); 189 byte_size -= prologue_byte_size; 190 } 191 } 192 193 if (filter.AddressPasses (func_addr)) 194 { 195 AddressRange new_range (func_addr, byte_size); 196 m_address_ranges.push_back (new_range); 197 } 198 } 199 } 200 } 201 } 202 203 for (i = 0; i < sym_list.GetSize(); i++) 204 { 205 if (sym_list.GetContextAtIndex(i, sc)) 206 { 207 if (sc.symbol && sc.symbol->GetAddressRangePtr()) 208 { 209 func_addr = sc.symbol->GetAddressRangePtr()->GetBaseAddress(); 210 addr_t byte_size = sc.symbol->GetAddressRangePtr()->GetByteSize(); 211 212 if (skip_prologue) 213 { 214 const uint32_t prologue_byte_size = sc.symbol->GetPrologueByteSize(); 215 if (prologue_byte_size) 216 { 217 func_addr.SetOffset (func_addr.GetOffset() + prologue_byte_size); 218 byte_size -= prologue_byte_size; 219 } 220 } 221 222 if (filter.AddressPasses (func_addr)) 223 { 224 AddressRange new_range (func_addr, byte_size); 225 m_address_ranges.push_back (new_range); 226 } 227 } 228 } 229 } 230 return Searcher::eCallbackReturnContinue; 231} 232 233Searcher::Depth 234AddressResolverName::GetDepth() 235{ 236 return Searcher::eDepthModule; 237} 238 239void 240AddressResolverName::GetDescription (Stream *s) 241{ 242 s->PutCString("Address by function name: "); 243 244 if (m_match_type == AddressResolver::Regexp) 245 s->Printf("'%s' (regular expression)", m_regex.GetText()); 246 else 247 s->Printf("'%s'", m_func_name.AsCString()); 248} 249 250