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