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