1*e19adf54SJim Ingham //===-- BreakpointResolverScripted.cpp ---------------------------*- C++ -*-===// 2*e19adf54SJim Ingham // 3*e19adf54SJim Ingham // The LLVM Compiler Infrastructure 4*e19adf54SJim Ingham // 5*e19adf54SJim Ingham // This file is distributed under the University of Illinois Open Source 6*e19adf54SJim Ingham // License. See LICENSE.TXT for details. 7*e19adf54SJim Ingham // 8*e19adf54SJim Ingham //===----------------------------------------------------------------------===// 9*e19adf54SJim Ingham 10*e19adf54SJim Ingham #include "lldb/Breakpoint/BreakpointResolverScripted.h" 11*e19adf54SJim Ingham 12*e19adf54SJim Ingham // C Includes 13*e19adf54SJim Ingham // C++ Includes 14*e19adf54SJim Ingham // Other libraries and framework includes 15*e19adf54SJim Ingham // Project includes 16*e19adf54SJim Ingham 17*e19adf54SJim Ingham #include "lldb/Breakpoint/BreakpointLocation.h" 18*e19adf54SJim Ingham #include "lldb/Core/Debugger.h" 19*e19adf54SJim Ingham #include "lldb/Core/Module.h" 20*e19adf54SJim Ingham #include "lldb/Core/Section.h" 21*e19adf54SJim Ingham #include "lldb/Core/StructuredDataImpl.h" 22*e19adf54SJim Ingham #include "lldb/Interpreter/CommandInterpreter.h" 23*e19adf54SJim Ingham #include "lldb/Interpreter/ScriptInterpreter.h" 24*e19adf54SJim Ingham #include "lldb/Target/Process.h" 25*e19adf54SJim Ingham #include "lldb/Target/Target.h" 26*e19adf54SJim Ingham #include "lldb/Utility/Log.h" 27*e19adf54SJim Ingham #include "lldb/Utility/StreamString.h" 28*e19adf54SJim Ingham 29*e19adf54SJim Ingham using namespace lldb; 30*e19adf54SJim Ingham using namespace lldb_private; 31*e19adf54SJim Ingham 32*e19adf54SJim Ingham //---------------------------------------------------------------------- 33*e19adf54SJim Ingham // BreakpointResolverScripted: 34*e19adf54SJim Ingham //---------------------------------------------------------------------- 35*e19adf54SJim Ingham BreakpointResolverScripted::BreakpointResolverScripted( 36*e19adf54SJim Ingham Breakpoint *bkpt, 37*e19adf54SJim Ingham const llvm::StringRef class_name, 38*e19adf54SJim Ingham lldb::SearchDepth depth, 39*e19adf54SJim Ingham StructuredDataImpl *args_data, 40*e19adf54SJim Ingham ScriptInterpreter &script_interp) 41*e19adf54SJim Ingham : BreakpointResolver(bkpt, BreakpointResolver::PythonResolver), 42*e19adf54SJim Ingham m_class_name(class_name), m_depth(depth), m_args_ptr(args_data) { 43*e19adf54SJim Ingham CreateImplementationIfNeeded(); 44*e19adf54SJim Ingham } 45*e19adf54SJim Ingham 46*e19adf54SJim Ingham void BreakpointResolverScripted::CreateImplementationIfNeeded() { 47*e19adf54SJim Ingham if (m_implementation_sp) 48*e19adf54SJim Ingham return; 49*e19adf54SJim Ingham 50*e19adf54SJim Ingham if (m_class_name.empty()) 51*e19adf54SJim Ingham return; 52*e19adf54SJim Ingham 53*e19adf54SJim Ingham if (m_breakpoint) { 54*e19adf54SJim Ingham TargetSP target_sp = m_breakpoint->GetTargetSP(); 55*e19adf54SJim Ingham ScriptInterpreter *script_interp = target_sp->GetDebugger() 56*e19adf54SJim Ingham .GetCommandInterpreter() 57*e19adf54SJim Ingham .GetScriptInterpreter(); 58*e19adf54SJim Ingham if (!script_interp) 59*e19adf54SJim Ingham return; 60*e19adf54SJim Ingham lldb::BreakpointSP bkpt_sp(m_breakpoint->shared_from_this()); 61*e19adf54SJim Ingham m_implementation_sp = script_interp->CreateScriptedBreakpointResolver( 62*e19adf54SJim Ingham m_class_name.c_str(), m_args_ptr, bkpt_sp); 63*e19adf54SJim Ingham } 64*e19adf54SJim Ingham } 65*e19adf54SJim Ingham 66*e19adf54SJim Ingham void BreakpointResolverScripted::NotifyBreakpointSet() { 67*e19adf54SJim Ingham CreateImplementationIfNeeded(); 68*e19adf54SJim Ingham } 69*e19adf54SJim Ingham 70*e19adf54SJim Ingham BreakpointResolverScripted::~BreakpointResolverScripted() {} 71*e19adf54SJim Ingham 72*e19adf54SJim Ingham BreakpointResolver * 73*e19adf54SJim Ingham BreakpointResolverScripted::CreateFromStructuredData( 74*e19adf54SJim Ingham Breakpoint *bkpt, const StructuredData::Dictionary &options_dict, 75*e19adf54SJim Ingham Status &error) { 76*e19adf54SJim Ingham llvm::StringRef class_name; 77*e19adf54SJim Ingham bool success; 78*e19adf54SJim Ingham 79*e19adf54SJim Ingham if (!bkpt) 80*e19adf54SJim Ingham return nullptr; 81*e19adf54SJim Ingham 82*e19adf54SJim Ingham success = options_dict.GetValueForKeyAsString( 83*e19adf54SJim Ingham GetKey(OptionNames::PythonClassName), class_name); 84*e19adf54SJim Ingham if (!success) { 85*e19adf54SJim Ingham error.SetErrorString("BRFL::CFSD: Couldn't find class name entry."); 86*e19adf54SJim Ingham return nullptr; 87*e19adf54SJim Ingham } 88*e19adf54SJim Ingham lldb::SearchDepth depth; 89*e19adf54SJim Ingham int depth_as_int; 90*e19adf54SJim Ingham success = options_dict.GetValueForKeyAsInteger( 91*e19adf54SJim Ingham GetKey(OptionNames::SearchDepth), depth_as_int); 92*e19adf54SJim Ingham if (!success) { 93*e19adf54SJim Ingham error.SetErrorString("BRFL::CFSD: Couldn't find class name entry."); 94*e19adf54SJim Ingham return nullptr; 95*e19adf54SJim Ingham } 96*e19adf54SJim Ingham if (depth_as_int >= (int) OptionNames::LastOptionName) { 97*e19adf54SJim Ingham error.SetErrorString("BRFL::CFSD: Invalid value for search depth."); 98*e19adf54SJim Ingham return nullptr; 99*e19adf54SJim Ingham } 100*e19adf54SJim Ingham depth = (lldb::SearchDepth) depth_as_int; 101*e19adf54SJim Ingham 102*e19adf54SJim Ingham StructuredDataImpl *args_data_impl = new StructuredDataImpl(); 103*e19adf54SJim Ingham StructuredData::Dictionary *args_dict = new StructuredData::Dictionary(); 104*e19adf54SJim Ingham success = options_dict.GetValueForKeyAsDictionary( 105*e19adf54SJim Ingham GetKey(OptionNames::ScriptArgs), args_dict); 106*e19adf54SJim Ingham if (success) { 107*e19adf54SJim Ingham // FIXME: The resolver needs a copy of the ARGS dict that it can own, 108*e19adf54SJim Ingham // so I need to make a copy constructor for the Dictionary so I can pass 109*e19adf54SJim Ingham // that to it here. For now the args are empty. 110*e19adf54SJim Ingham //StructuredData::Dictionary *dict_copy = new StructuredData::Dictionary(args_dict); 111*e19adf54SJim Ingham 112*e19adf54SJim Ingham } 113*e19adf54SJim Ingham ScriptInterpreter *script_interp = bkpt->GetTarget() 114*e19adf54SJim Ingham .GetDebugger() 115*e19adf54SJim Ingham .GetCommandInterpreter() 116*e19adf54SJim Ingham .GetScriptInterpreter(); 117*e19adf54SJim Ingham return new BreakpointResolverScripted(bkpt, class_name, depth, args_data_impl, 118*e19adf54SJim Ingham *script_interp); 119*e19adf54SJim Ingham } 120*e19adf54SJim Ingham 121*e19adf54SJim Ingham StructuredData::ObjectSP 122*e19adf54SJim Ingham BreakpointResolverScripted::SerializeToStructuredData() { 123*e19adf54SJim Ingham StructuredData::DictionarySP options_dict_sp( 124*e19adf54SJim Ingham new StructuredData::Dictionary()); 125*e19adf54SJim Ingham 126*e19adf54SJim Ingham options_dict_sp->AddStringItem(GetKey(OptionNames::PythonClassName), 127*e19adf54SJim Ingham m_class_name); 128*e19adf54SJim Ingham return WrapOptionsDict(options_dict_sp); 129*e19adf54SJim Ingham } 130*e19adf54SJim Ingham 131*e19adf54SJim Ingham ScriptInterpreter *BreakpointResolverScripted::GetScriptInterpreter() { 132*e19adf54SJim Ingham return m_breakpoint->GetTarget().GetDebugger().GetCommandInterpreter() 133*e19adf54SJim Ingham .GetScriptInterpreter(); 134*e19adf54SJim Ingham } 135*e19adf54SJim Ingham 136*e19adf54SJim Ingham Searcher::CallbackReturn 137*e19adf54SJim Ingham BreakpointResolverScripted::SearchCallback(SearchFilter &filter, 138*e19adf54SJim Ingham SymbolContext &context, Address *addr, 139*e19adf54SJim Ingham bool containing) { 140*e19adf54SJim Ingham assert(m_breakpoint != NULL); 141*e19adf54SJim Ingham bool should_continue = true; 142*e19adf54SJim Ingham if (!m_implementation_sp) 143*e19adf54SJim Ingham return Searcher::eCallbackReturnStop; 144*e19adf54SJim Ingham 145*e19adf54SJim Ingham ScriptInterpreter *interp = GetScriptInterpreter(); 146*e19adf54SJim Ingham should_continue = interp->ScriptedBreakpointResolverSearchCallback( 147*e19adf54SJim Ingham m_implementation_sp, 148*e19adf54SJim Ingham &context); 149*e19adf54SJim Ingham if (should_continue) 150*e19adf54SJim Ingham return Searcher::eCallbackReturnContinue; 151*e19adf54SJim Ingham else 152*e19adf54SJim Ingham return Searcher::eCallbackReturnStop; 153*e19adf54SJim Ingham } 154*e19adf54SJim Ingham 155*e19adf54SJim Ingham lldb::SearchDepth 156*e19adf54SJim Ingham BreakpointResolverScripted::GetDepth() { 157*e19adf54SJim Ingham assert(m_breakpoint != NULL); 158*e19adf54SJim Ingham lldb::SearchDepth depth = lldb::eSearchDepthModule; 159*e19adf54SJim Ingham if (m_implementation_sp) { 160*e19adf54SJim Ingham ScriptInterpreter *interp = GetScriptInterpreter(); 161*e19adf54SJim Ingham depth = interp->ScriptedBreakpointResolverSearchDepth( 162*e19adf54SJim Ingham m_implementation_sp); 163*e19adf54SJim Ingham } 164*e19adf54SJim Ingham return depth; 165*e19adf54SJim Ingham } 166*e19adf54SJim Ingham 167*e19adf54SJim Ingham void BreakpointResolverScripted::GetDescription(Stream *s) { 168*e19adf54SJim Ingham StructuredData::GenericSP generic_sp; 169*e19adf54SJim Ingham std::string short_help; 170*e19adf54SJim Ingham 171*e19adf54SJim Ingham if (m_implementation_sp) { 172*e19adf54SJim Ingham ScriptInterpreter *interp = GetScriptInterpreter(); 173*e19adf54SJim Ingham interp->GetShortHelpForCommandObject(m_implementation_sp, 174*e19adf54SJim Ingham short_help); 175*e19adf54SJim Ingham } 176*e19adf54SJim Ingham if (!short_help.empty()) 177*e19adf54SJim Ingham s->PutCString(short_help.c_str()); 178*e19adf54SJim Ingham else 179*e19adf54SJim Ingham s->Printf("python class = %s", m_class_name.c_str()); 180*e19adf54SJim Ingham } 181*e19adf54SJim Ingham 182*e19adf54SJim Ingham void BreakpointResolverScripted::Dump(Stream *s) const {} 183*e19adf54SJim Ingham 184*e19adf54SJim Ingham lldb::BreakpointResolverSP 185*e19adf54SJim Ingham BreakpointResolverScripted::CopyForBreakpoint(Breakpoint &breakpoint) { 186*e19adf54SJim Ingham ScriptInterpreter *script_interp = GetScriptInterpreter(); 187*e19adf54SJim Ingham // FIXME: Have to make a copy of the arguments from the m_args_ptr and then 188*e19adf54SJim Ingham // pass that to the new resolver. 189*e19adf54SJim Ingham lldb::BreakpointResolverSP ret_sp( 190*e19adf54SJim Ingham new BreakpointResolverScripted(&breakpoint, m_class_name, 191*e19adf54SJim Ingham m_depth, nullptr, *script_interp)); 192*e19adf54SJim Ingham return ret_sp; 193*e19adf54SJim Ingham } 194