1 //===-- BreakpointResolverName.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/Breakpoint/BreakpointResolverName.h" 11 12 // C Includes 13 // C++ Includes 14 // Other libraries and framework includes 15 // Project includes 16 #include "lldb/Breakpoint/BreakpointLocation.h" 17 #include "lldb/Core/Log.h" 18 #include "lldb/Core/Module.h" 19 #include "lldb/Core/StreamString.h" 20 #include "lldb/Symbol/ClangNamespaceDecl.h" 21 #include "lldb/Symbol/Block.h" 22 #include "lldb/Symbol/Function.h" 23 #include "lldb/Symbol/Symbol.h" 24 #include "lldb/Symbol/SymbolContext.h" 25 #include "lldb/Target/ObjCLanguageRuntime.h" 26 27 using namespace lldb; 28 using namespace lldb_private; 29 30 BreakpointResolverName::BreakpointResolverName 31 ( 32 Breakpoint *bkpt, 33 const char *func_name, 34 uint32_t func_name_type_mask, 35 Breakpoint::MatchType type, 36 bool skip_prologue 37 ) : 38 BreakpointResolver (bkpt, BreakpointResolver::NameResolver), 39 m_func_name_type_mask (func_name_type_mask), 40 m_class_name (), 41 m_regex (), 42 m_match_type (type), 43 m_skip_prologue (skip_prologue) 44 { 45 46 if (m_match_type == Breakpoint::Regexp) 47 { 48 if (!m_regex.Compile (func_name)) 49 { 50 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS)); 51 52 if (log) 53 log->Warning ("function name regexp: \"%s\" did not compile.", func_name); 54 } 55 } 56 else 57 { 58 const bool append = true; 59 ObjCLanguageRuntime::MethodName objc_name(func_name, false); 60 if (objc_name.IsValid(false)) 61 objc_name.GetFullNames(m_func_names, append); 62 else 63 m_func_names.push_back(ConstString(func_name)); 64 } 65 } 66 67 BreakpointResolverName::BreakpointResolverName (Breakpoint *bkpt, 68 const char *names[], 69 size_t num_names, 70 uint32_t name_type_mask, 71 bool skip_prologue) : 72 BreakpointResolver (bkpt, BreakpointResolver::NameResolver), 73 m_func_name_type_mask (name_type_mask), 74 m_match_type (Breakpoint::Exact), 75 m_skip_prologue (skip_prologue) 76 { 77 const bool append = true; 78 for (size_t i = 0; i < num_names; i++) 79 { 80 ObjCLanguageRuntime::MethodName objc_name(names[i], false); 81 if (objc_name.IsValid(false)) 82 objc_name.GetFullNames(m_func_names, append); 83 else 84 m_func_names.push_back (ConstString (names[i])); 85 } 86 } 87 88 BreakpointResolverName::BreakpointResolverName (Breakpoint *bkpt, 89 std::vector<std::string> names, 90 uint32_t name_type_mask, 91 bool skip_prologue) : 92 BreakpointResolver (bkpt, BreakpointResolver::NameResolver), 93 m_func_name_type_mask (name_type_mask), 94 m_match_type (Breakpoint::Exact), 95 m_skip_prologue (skip_prologue) 96 { 97 size_t num_names = names.size(); 98 const bool append = true; 99 for (size_t i = 0; i < num_names; i++) 100 { 101 ObjCLanguageRuntime::MethodName objc_name(names[i].c_str(), false); 102 if (objc_name.IsValid(false)) 103 objc_name.GetFullNames(m_func_names, append); 104 else 105 m_func_names.push_back (ConstString (names[i].c_str())); 106 } 107 } 108 109 BreakpointResolverName::BreakpointResolverName 110 ( 111 Breakpoint *bkpt, 112 RegularExpression &func_regex, 113 bool skip_prologue 114 ) : 115 BreakpointResolver (bkpt, BreakpointResolver::NameResolver), 116 m_class_name (NULL), 117 m_regex (func_regex), 118 m_match_type (Breakpoint::Regexp), 119 m_skip_prologue (skip_prologue) 120 { 121 } 122 123 BreakpointResolverName::BreakpointResolverName 124 ( 125 Breakpoint *bkpt, 126 const char *class_name, 127 const char *method, 128 Breakpoint::MatchType type, 129 bool skip_prologue 130 ) : 131 BreakpointResolver (bkpt, BreakpointResolver::NameResolver), 132 m_class_name (class_name), 133 m_regex (), 134 m_match_type (type), 135 m_skip_prologue (skip_prologue) 136 { 137 m_func_names.push_back(ConstString(method)); 138 } 139 140 BreakpointResolverName::~BreakpointResolverName () 141 { 142 } 143 144 // FIXME: Right now we look at the module level, and call the module's "FindFunctions". 145 // Greg says he will add function tables, maybe at the CompileUnit level to accelerate function 146 // lookup. At that point, we should switch the depth to CompileUnit, and look in these tables. 147 148 Searcher::CallbackReturn 149 BreakpointResolverName::SearchCallback 150 ( 151 SearchFilter &filter, 152 SymbolContext &context, 153 Address *addr, 154 bool containing 155 ) 156 { 157 SymbolContextList func_list; 158 SymbolContextList sym_list; 159 160 uint32_t i; 161 bool new_location; 162 SymbolContext sc; 163 Address break_addr; 164 assert (m_breakpoint != NULL); 165 166 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS)); 167 168 if (m_class_name) 169 { 170 if (log) 171 log->Warning ("Class/method function specification not supported yet.\n"); 172 return Searcher::eCallbackReturnStop; 173 } 174 175 const bool include_symbols = false; 176 const bool include_inlines = true; 177 const bool append = true; 178 bool filter_by_cu = (filter.GetFilterRequiredItems() & eSymbolContextCompUnit) != 0; 179 180 switch (m_match_type) 181 { 182 case Breakpoint::Exact: 183 if (context.module_sp) 184 { 185 size_t num_names = m_func_names.size(); 186 for (int j = 0; j < num_names; j++) 187 { 188 size_t num_functions = context.module_sp->FindFunctions (m_func_names[j], 189 NULL, 190 m_func_name_type_mask, 191 include_symbols, 192 include_inlines, 193 append, 194 func_list); 195 // If the search filter specifies a Compilation Unit, then we don't need to bother to look in plain 196 // symbols, since all the ones from a set compilation unit will have been found above already. 197 198 if (num_functions == 0 && !filter_by_cu) 199 { 200 context.module_sp->FindFunctionSymbols (m_func_names[j], m_func_name_type_mask, sym_list); 201 } 202 } 203 } 204 break; 205 case Breakpoint::Regexp: 206 if (context.module_sp) 207 { 208 if (!filter_by_cu) 209 context.module_sp->FindSymbolsMatchingRegExAndType (m_regex, eSymbolTypeCode, sym_list); 210 context.module_sp->FindFunctions (m_regex, 211 include_symbols, 212 include_inlines, 213 append, 214 func_list); 215 } 216 break; 217 case Breakpoint::Glob: 218 if (log) 219 log->Warning ("glob is not supported yet."); 220 break; 221 } 222 223 // If the filter specifies a Compilation Unit, remove the ones that don't pass at this point. 224 if (filter_by_cu) 225 { 226 uint32_t num_functions = func_list.GetSize(); 227 228 for (size_t idx = 0; idx < num_functions; idx++) 229 { 230 SymbolContext sc; 231 func_list.GetContextAtIndex(idx, sc); 232 if (!sc.comp_unit || !filter.CompUnitPasses(*sc.comp_unit)) 233 { 234 func_list.RemoveContextAtIndex(idx); 235 num_functions--; 236 idx--; 237 } 238 } 239 } 240 241 // Remove any duplicates between the funcion list and the symbol list 242 if (func_list.GetSize()) 243 { 244 for (i = 0; i < func_list.GetSize(); i++) 245 { 246 if (func_list.GetContextAtIndex(i, sc) == false) 247 continue; 248 249 if (sc.function == NULL) 250 continue; 251 uint32_t j = 0; 252 while (j < sym_list.GetSize()) 253 { 254 SymbolContext symbol_sc; 255 if (sym_list.GetContextAtIndex(j, symbol_sc)) 256 { 257 if (symbol_sc.symbol && symbol_sc.symbol->ValueIsAddress()) 258 { 259 if (sc.function->GetAddressRange().GetBaseAddress() == symbol_sc.symbol->GetAddress()) 260 { 261 sym_list.RemoveContextAtIndex(j); 262 continue; // Don't increment j 263 } 264 } 265 } 266 267 j++; 268 } 269 } 270 271 for (i = 0; i < func_list.GetSize(); i++) 272 { 273 if (func_list.GetContextAtIndex(i, sc)) 274 { 275 if (sc.block && sc.block->GetInlinedFunctionInfo()) 276 { 277 if (!sc.block->GetStartAddress(break_addr)) 278 break_addr.Clear(); 279 } 280 else if (sc.function) 281 { 282 break_addr = sc.function->GetAddressRange().GetBaseAddress(); 283 if (m_skip_prologue) 284 { 285 if (break_addr.IsValid()) 286 { 287 const uint32_t prologue_byte_size = sc.function->GetPrologueByteSize(); 288 if (prologue_byte_size) 289 break_addr.SetOffset(break_addr.GetOffset() + prologue_byte_size); 290 } 291 } 292 } 293 294 if (break_addr.IsValid()) 295 { 296 if (filter.AddressPasses(break_addr)) 297 { 298 BreakpointLocationSP bp_loc_sp (m_breakpoint->AddLocation(break_addr, &new_location)); 299 if (bp_loc_sp && new_location && !m_breakpoint->IsInternal()) 300 { 301 if (log) 302 { 303 StreamString s; 304 bp_loc_sp->GetDescription(&s, lldb::eDescriptionLevelVerbose); 305 log->Printf ("Added location: %s\n", s.GetData()); 306 } 307 } 308 } 309 } 310 } 311 } 312 } 313 314 for (i = 0; i < sym_list.GetSize(); i++) 315 { 316 if (sym_list.GetContextAtIndex(i, sc)) 317 { 318 if (sc.symbol && sc.symbol->ValueIsAddress()) 319 { 320 break_addr = sc.symbol->GetAddress(); 321 322 if (m_skip_prologue) 323 { 324 const uint32_t prologue_byte_size = sc.symbol->GetPrologueByteSize(); 325 if (prologue_byte_size) 326 break_addr.SetOffset(break_addr.GetOffset() + prologue_byte_size); 327 } 328 329 if (filter.AddressPasses(break_addr)) 330 { 331 BreakpointLocationSP bp_loc_sp (m_breakpoint->AddLocation(break_addr, &new_location)); 332 if (bp_loc_sp && new_location && !m_breakpoint->IsInternal()) 333 { 334 StreamString s; 335 bp_loc_sp->GetDescription(&s, lldb::eDescriptionLevelVerbose); 336 if (log) 337 log->Printf ("Added location: %s\n", s.GetData()); 338 } 339 } 340 } 341 } 342 } 343 return Searcher::eCallbackReturnContinue; 344 } 345 346 Searcher::Depth 347 BreakpointResolverName::GetDepth() 348 { 349 return Searcher::eDepthModule; 350 } 351 352 void 353 BreakpointResolverName::GetDescription (Stream *s) 354 { 355 if (m_match_type == Breakpoint::Regexp) 356 s->Printf("regex = '%s'", m_regex.GetText()); 357 else 358 { 359 size_t num_names = m_func_names.size(); 360 if (num_names == 1) 361 s->Printf("name = '%s'", m_func_names[0].AsCString()); 362 else 363 { 364 s->Printf("names = {"); 365 for (size_t i = 0; i < num_names - 1; i++) 366 { 367 s->Printf ("'%s', ", m_func_names[i].AsCString()); 368 } 369 s->Printf ("'%s'}", m_func_names[num_names - 1].AsCString()); 370 } 371 } 372 } 373 374 void 375 BreakpointResolverName::Dump (Stream *s) const 376 { 377 378 } 379 380