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