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