1*969795f1SJim Ingham //===-- BreakpointResolverFileRegex.cpp --------------------------*- C++ -*-===// 2*969795f1SJim Ingham // 3*969795f1SJim Ingham // The LLVM Compiler Infrastructure 4*969795f1SJim Ingham // 5*969795f1SJim Ingham // This file is distributed under the University of Illinois Open Source 6*969795f1SJim Ingham // License. See LICENSE.TXT for details. 7*969795f1SJim Ingham // 8*969795f1SJim Ingham //===----------------------------------------------------------------------===// 9*969795f1SJim Ingham 10*969795f1SJim Ingham #include "lldb/Breakpoint/BreakpointResolverFileRegex.h" 11*969795f1SJim Ingham 12*969795f1SJim Ingham // C Includes 13*969795f1SJim Ingham // C++ Includes 14*969795f1SJim Ingham // Other libraries and framework includes 15*969795f1SJim Ingham // Project includes 16*969795f1SJim Ingham #include "lldb/Breakpoint/BreakpointLocation.h" 17*969795f1SJim Ingham #include "lldb/Core/SourceManager.h" 18*969795f1SJim Ingham #include "lldb/Core/Log.h" 19*969795f1SJim Ingham #include "lldb/Core/StreamString.h" 20*969795f1SJim Ingham #include "lldb/Target/Target.h" 21*969795f1SJim Ingham #include "lldb/lldb-private-log.h" 22*969795f1SJim Ingham 23*969795f1SJim Ingham using namespace lldb; 24*969795f1SJim Ingham using namespace lldb_private; 25*969795f1SJim Ingham 26*969795f1SJim Ingham //---------------------------------------------------------------------- 27*969795f1SJim Ingham // BreakpointResolverFileRegex: 28*969795f1SJim Ingham //---------------------------------------------------------------------- 29*969795f1SJim Ingham BreakpointResolverFileRegex::BreakpointResolverFileRegex 30*969795f1SJim Ingham ( 31*969795f1SJim Ingham Breakpoint *bkpt, 32*969795f1SJim Ingham const FileSpec &file_spec, 33*969795f1SJim Ingham RegularExpression ®ex 34*969795f1SJim Ingham ) : 35*969795f1SJim Ingham BreakpointResolver (bkpt, BreakpointResolver::FileLineResolver), 36*969795f1SJim Ingham m_file_spec (file_spec), 37*969795f1SJim Ingham m_regex (regex) 38*969795f1SJim Ingham { 39*969795f1SJim Ingham } 40*969795f1SJim Ingham 41*969795f1SJim Ingham BreakpointResolverFileRegex::~BreakpointResolverFileRegex () 42*969795f1SJim Ingham { 43*969795f1SJim Ingham } 44*969795f1SJim Ingham 45*969795f1SJim Ingham Searcher::CallbackReturn 46*969795f1SJim Ingham BreakpointResolverFileRegex::SearchCallback 47*969795f1SJim Ingham ( 48*969795f1SJim Ingham SearchFilter &filter, 49*969795f1SJim Ingham SymbolContext &context, 50*969795f1SJim Ingham Address *addr, 51*969795f1SJim Ingham bool containing 52*969795f1SJim Ingham ) 53*969795f1SJim Ingham { 54*969795f1SJim Ingham 55*969795f1SJim Ingham assert (m_breakpoint != NULL); 56*969795f1SJim Ingham if (!context.target_sp) 57*969795f1SJim Ingham return eCallbackReturnContinue; 58*969795f1SJim Ingham 59*969795f1SJim Ingham LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS)); 60*969795f1SJim Ingham 61*969795f1SJim Ingham CompileUnit *cu = context.comp_unit; 62*969795f1SJim Ingham FileSpec cu_file_spec = *(static_cast<FileSpec *>(cu)); 63*969795f1SJim Ingham if (cu_file_spec == m_file_spec 64*969795f1SJim Ingham || (!m_file_spec.GetDirectory() && cu_file_spec.GetFilename() == m_file_spec.GetFilename())) 65*969795f1SJim Ingham { 66*969795f1SJim Ingham std::vector<uint32_t> line_matches; 67*969795f1SJim Ingham context.target_sp->GetSourceManager().FindLinesMatchingRegex(cu_file_spec, m_regex, 1, UINT32_MAX, line_matches); 68*969795f1SJim Ingham uint32_t num_matches = line_matches.size(); 69*969795f1SJim Ingham for (int i = 0; i < num_matches; i++) 70*969795f1SJim Ingham { 71*969795f1SJim Ingham uint32_t start_idx = 0; 72*969795f1SJim Ingham while (1) 73*969795f1SJim Ingham { 74*969795f1SJim Ingham LineEntry line_entry; 75*969795f1SJim Ingham 76*969795f1SJim Ingham // Cycle through all the line entries that might match this one: 77*969795f1SJim Ingham start_idx = cu->FindLineEntry (start_idx, line_matches[i], NULL, &line_entry); 78*969795f1SJim Ingham if (start_idx == UINT32_MAX) 79*969795f1SJim Ingham break; 80*969795f1SJim Ingham start_idx++; 81*969795f1SJim Ingham 82*969795f1SJim Ingham Address line_start = line_entry.range.GetBaseAddress(); 83*969795f1SJim Ingham if (line_start.IsValid()) 84*969795f1SJim Ingham { 85*969795f1SJim Ingham if (filter.AddressPasses(line_start)) 86*969795f1SJim Ingham { 87*969795f1SJim Ingham BreakpointLocationSP bp_loc_sp (m_breakpoint->AddLocation(line_start)); 88*969795f1SJim Ingham if (log && bp_loc_sp && !m_breakpoint->IsInternal()) 89*969795f1SJim Ingham { 90*969795f1SJim Ingham StreamString s; 91*969795f1SJim Ingham bp_loc_sp->GetDescription (&s, lldb::eDescriptionLevelVerbose); 92*969795f1SJim Ingham log->Printf ("Added location: %s\n", s.GetData()); 93*969795f1SJim Ingham } 94*969795f1SJim Ingham } 95*969795f1SJim Ingham else if (log) 96*969795f1SJim Ingham { 97*969795f1SJim Ingham log->Printf ("Breakpoint at file address 0x%llx for %s:%d didn't pass filter.\n", 98*969795f1SJim Ingham line_start.GetFileAddress(), 99*969795f1SJim Ingham m_file_spec.GetFilename().AsCString("<Unknown>"), 100*969795f1SJim Ingham line_matches[i]); 101*969795f1SJim Ingham } 102*969795f1SJim Ingham } 103*969795f1SJim Ingham else 104*969795f1SJim Ingham { 105*969795f1SJim Ingham if (log) 106*969795f1SJim Ingham log->Printf ("error: Unable to set breakpoint at file address 0x%llx for %s:%d\n", 107*969795f1SJim Ingham line_start.GetFileAddress(), 108*969795f1SJim Ingham m_file_spec.GetFilename().AsCString("<Unknown>"), 109*969795f1SJim Ingham line_matches[i]); 110*969795f1SJim Ingham } 111*969795f1SJim Ingham 112*969795f1SJim Ingham } 113*969795f1SJim Ingham } 114*969795f1SJim Ingham assert (m_breakpoint != NULL); 115*969795f1SJim Ingham LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS)); 116*969795f1SJim Ingham 117*969795f1SJim Ingham 118*969795f1SJim Ingham } 119*969795f1SJim Ingham return Searcher::eCallbackReturnContinue; 120*969795f1SJim Ingham } 121*969795f1SJim Ingham 122*969795f1SJim Ingham Searcher::Depth 123*969795f1SJim Ingham BreakpointResolverFileRegex::GetDepth() 124*969795f1SJim Ingham { 125*969795f1SJim Ingham return Searcher::eDepthCompUnit; 126*969795f1SJim Ingham } 127*969795f1SJim Ingham 128*969795f1SJim Ingham void 129*969795f1SJim Ingham BreakpointResolverFileRegex::GetDescription (Stream *s) 130*969795f1SJim Ingham { 131*969795f1SJim Ingham s->Printf ("file ='%s', regular expression = \"%s\"", m_file_spec.GetFilename().AsCString(), m_regex.GetText()); 132*969795f1SJim Ingham } 133*969795f1SJim Ingham 134*969795f1SJim Ingham void 135*969795f1SJim Ingham BreakpointResolverFileRegex::Dump (Stream *s) const 136*969795f1SJim Ingham { 137*969795f1SJim Ingham 138*969795f1SJim Ingham } 139*969795f1SJim Ingham 140