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