1 //===-- SBCommandInterpreter.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/lldb-python.h"
11 
12 #include "lldb/lldb-types.h"
13 #include "lldb/Core/SourceManager.h"
14 #include "lldb/Core/Listener.h"
15 #include "lldb/Interpreter/CommandInterpreter.h"
16 #include "lldb/Interpreter/CommandObjectMultiword.h"
17 #include "lldb/Interpreter/CommandReturnObject.h"
18 #include "lldb/Target/Target.h"
19 
20 #include "lldb/API/SBBroadcaster.h"
21 #include "lldb/API/SBCommandReturnObject.h"
22 #include "lldb/API/SBCommandInterpreter.h"
23 #include "lldb/API/SBProcess.h"
24 #include "lldb/API/SBTarget.h"
25 #include "lldb/API/SBListener.h"
26 #include "lldb/API/SBStream.h"
27 #include "lldb/API/SBStringList.h"
28 
29 using namespace lldb;
30 using namespace lldb_private;
31 
32 class CommandPluginInterfaceImplementation : public CommandObjectParsed
33 {
34 public:
35     CommandPluginInterfaceImplementation (CommandInterpreter &interpreter,
36                                           const char *name,
37                                           lldb::SBCommandPluginInterface* backend,
38                                           const char *help = NULL,
39                                           const char *syntax = NULL,
40                                           uint32_t flags = 0) :
41     CommandObjectParsed (interpreter, name, help, syntax, flags),
42     m_backend(backend) {}
43 
44     virtual bool
45     IsRemovable() const { return true; }
46 
47 protected:
48     virtual bool
49     DoExecute (Args& command, CommandReturnObject &result)
50     {
51         SBCommandReturnObject sb_return(&result);
52         SBCommandInterpreter sb_interpreter(&m_interpreter);
53         SBDebugger debugger_sb(m_interpreter.GetDebugger().shared_from_this());
54         bool ret = m_backend->DoExecute (debugger_sb,(char**)command.GetArgumentVector(), sb_return);
55         sb_return.Release();
56         return ret;
57     }
58     lldb::SBCommandPluginInterface* m_backend;
59 };
60 
61 SBCommandInterpreter::SBCommandInterpreter (CommandInterpreter *interpreter) :
62     m_opaque_ptr (interpreter)
63 {
64     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
65 
66     if (log)
67         log->Printf ("SBCommandInterpreter::SBCommandInterpreter (interpreter=%p)"
68                      " => SBCommandInterpreter(%p)",
69                      static_cast<void*>(interpreter),
70                      static_cast<void*>(m_opaque_ptr));
71 }
72 
73 SBCommandInterpreter::SBCommandInterpreter(const SBCommandInterpreter &rhs) :
74     m_opaque_ptr (rhs.m_opaque_ptr)
75 {
76 }
77 
78 const SBCommandInterpreter &
79 SBCommandInterpreter::operator = (const SBCommandInterpreter &rhs)
80 {
81     m_opaque_ptr = rhs.m_opaque_ptr;
82     return *this;
83 }
84 
85 SBCommandInterpreter::~SBCommandInterpreter ()
86 {
87 }
88 
89 bool
90 SBCommandInterpreter::IsValid() const
91 {
92     return m_opaque_ptr != NULL;
93 }
94 
95 
96 bool
97 SBCommandInterpreter::CommandExists (const char *cmd)
98 {
99     if (cmd && m_opaque_ptr)
100         return m_opaque_ptr->CommandExists (cmd);
101     return false;
102 }
103 
104 bool
105 SBCommandInterpreter::AliasExists (const char *cmd)
106 {
107     if (cmd && m_opaque_ptr)
108         return m_opaque_ptr->AliasExists (cmd);
109     return false;
110 }
111 
112 bool
113 SBCommandInterpreter::IsActive ()
114 {
115     if (m_opaque_ptr)
116         return m_opaque_ptr->IsActive ();
117     return false;
118 }
119 
120 const char *
121 SBCommandInterpreter::GetIOHandlerControlSequence(char ch)
122 {
123     if (m_opaque_ptr)
124         return m_opaque_ptr->GetDebugger().GetTopIOHandlerControlSequence (ch).GetCString();
125     return NULL;
126 }
127 
128 lldb::ReturnStatus
129 SBCommandInterpreter::HandleCommand (const char *command_line, SBCommandReturnObject &result, bool add_to_history)
130 {
131     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
132 
133     if (log)
134         log->Printf ("SBCommandInterpreter(%p)::HandleCommand (command=\"%s\", SBCommandReturnObject(%p), add_to_history=%i)",
135                      static_cast<void*>(m_opaque_ptr), command_line,
136                      static_cast<void*>(result.get()), add_to_history);
137 
138     result.Clear();
139     if (command_line && m_opaque_ptr)
140     {
141         result.ref().SetInteractive(false);
142         m_opaque_ptr->HandleCommand (command_line, add_to_history ? eLazyBoolYes : eLazyBoolNo, result.ref());
143     }
144     else
145     {
146         result->AppendError ("SBCommandInterpreter or the command line is not valid");
147         result->SetStatus (eReturnStatusFailed);
148     }
149 
150     // We need to get the value again, in case the command disabled the log!
151     log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API);
152     if (log)
153     {
154         SBStream sstr;
155         result.GetDescription (sstr);
156         log->Printf ("SBCommandInterpreter(%p)::HandleCommand (command=\"%s\", SBCommandReturnObject(%p): %s, add_to_history=%i) => %i",
157                      static_cast<void*>(m_opaque_ptr), command_line,
158                      static_cast<void*>(result.get()), sstr.GetData(),
159                      add_to_history, result.GetStatus());
160     }
161 
162     return result.GetStatus();
163 }
164 
165 int
166 SBCommandInterpreter::HandleCompletion (const char *current_line,
167                                         const char *cursor,
168                                         const char *last_char,
169                                         int match_start_point,
170                                         int max_return_elements,
171                                         SBStringList &matches)
172 {
173     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
174     int num_completions = 0;
175 
176     // Sanity check the arguments that are passed in:
177     // cursor & last_char have to be within the current_line.
178     if (current_line == NULL || cursor == NULL || last_char == NULL)
179         return 0;
180 
181     if (cursor < current_line || last_char < current_line)
182         return 0;
183 
184     size_t current_line_size = strlen (current_line);
185     if (cursor - current_line > static_cast<ptrdiff_t>(current_line_size) ||
186         last_char - current_line > static_cast<ptrdiff_t>(current_line_size))
187         return 0;
188 
189     if (log)
190         log->Printf ("SBCommandInterpreter(%p)::HandleCompletion (current_line=\"%s\", cursor at: %" PRId64 ", last char at: %" PRId64 ", match_start_point: %d, max_return_elements: %d)",
191                      static_cast<void*>(m_opaque_ptr), current_line,
192                      static_cast<uint64_t>(cursor - current_line),
193                      static_cast<uint64_t>(last_char - current_line),
194                      match_start_point, max_return_elements);
195 
196     if (m_opaque_ptr)
197     {
198         lldb_private::StringList lldb_matches;
199         num_completions =  m_opaque_ptr->HandleCompletion (current_line, cursor, last_char, match_start_point,
200                                                            max_return_elements, lldb_matches);
201 
202         SBStringList temp_list (&lldb_matches);
203         matches.AppendList (temp_list);
204     }
205     if (log)
206         log->Printf ("SBCommandInterpreter(%p)::HandleCompletion - Found %d completions.",
207                      static_cast<void*>(m_opaque_ptr), num_completions);
208 
209     return num_completions;
210 }
211 
212 int
213 SBCommandInterpreter::HandleCompletion (const char *current_line,
214                   uint32_t cursor_pos,
215                   int match_start_point,
216                   int max_return_elements,
217                   lldb::SBStringList &matches)
218 {
219     const char *cursor = current_line + cursor_pos;
220     const char *last_char = current_line + strlen (current_line);
221     return HandleCompletion (current_line, cursor, last_char, match_start_point, max_return_elements, matches);
222 }
223 
224 bool
225 SBCommandInterpreter::HasCommands ()
226 {
227     if (m_opaque_ptr)
228         return m_opaque_ptr->HasCommands();
229     return false;
230 }
231 
232 bool
233 SBCommandInterpreter::HasAliases ()
234 {
235     if (m_opaque_ptr)
236         return m_opaque_ptr->HasAliases();
237     return false;
238 }
239 
240 bool
241 SBCommandInterpreter::HasAliasOptions ()
242 {
243     if (m_opaque_ptr)
244         return m_opaque_ptr->HasAliasOptions ();
245     return false;
246 }
247 
248 SBProcess
249 SBCommandInterpreter::GetProcess ()
250 {
251     SBProcess sb_process;
252     ProcessSP process_sp;
253     if (m_opaque_ptr)
254     {
255         TargetSP target_sp(m_opaque_ptr->GetDebugger().GetSelectedTarget());
256         if (target_sp)
257         {
258             Mutex::Locker api_locker(target_sp->GetAPIMutex());
259             process_sp = target_sp->GetProcessSP();
260             sb_process.SetSP(process_sp);
261         }
262     }
263     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
264 
265     if (log)
266         log->Printf ("SBCommandInterpreter(%p)::GetProcess () => SBProcess(%p)",
267                      static_cast<void*>(m_opaque_ptr),
268                      static_cast<void*>(process_sp.get()));
269 
270     return sb_process;
271 }
272 
273 SBDebugger
274 SBCommandInterpreter::GetDebugger ()
275 {
276     SBDebugger sb_debugger;
277     if (m_opaque_ptr)
278         sb_debugger.reset(m_opaque_ptr->GetDebugger().shared_from_this());
279     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
280 
281     if (log)
282         log->Printf ("SBCommandInterpreter(%p)::GetDebugger () => SBDebugger(%p)",
283                      static_cast<void*>(m_opaque_ptr),
284                      static_cast<void*>(sb_debugger.get()));
285 
286     return sb_debugger;
287 }
288 
289 CommandInterpreter *
290 SBCommandInterpreter::get ()
291 {
292     return m_opaque_ptr;
293 }
294 
295 CommandInterpreter &
296 SBCommandInterpreter::ref ()
297 {
298     assert (m_opaque_ptr);
299     return *m_opaque_ptr;
300 }
301 
302 void
303 SBCommandInterpreter::reset (lldb_private::CommandInterpreter *interpreter)
304 {
305     m_opaque_ptr = interpreter;
306 }
307 
308 void
309 SBCommandInterpreter::SourceInitFileInHomeDirectory (SBCommandReturnObject &result)
310 {
311     result.Clear();
312     if (m_opaque_ptr)
313     {
314         TargetSP target_sp(m_opaque_ptr->GetDebugger().GetSelectedTarget());
315         Mutex::Locker api_locker;
316         if (target_sp)
317             api_locker.Lock(target_sp->GetAPIMutex());
318         m_opaque_ptr->SourceInitFile (false, result.ref());
319     }
320     else
321     {
322         result->AppendError ("SBCommandInterpreter is not valid");
323         result->SetStatus (eReturnStatusFailed);
324     }
325     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
326 
327     if (log)
328         log->Printf ("SBCommandInterpreter(%p)::SourceInitFileInHomeDirectory (&SBCommandReturnObject(%p))",
329                      static_cast<void*>(m_opaque_ptr),
330                      static_cast<void*>(result.get()));
331 }
332 
333 void
334 SBCommandInterpreter::SourceInitFileInCurrentWorkingDirectory (SBCommandReturnObject &result)
335 {
336     result.Clear();
337     if (m_opaque_ptr)
338     {
339         TargetSP target_sp(m_opaque_ptr->GetDebugger().GetSelectedTarget());
340         Mutex::Locker api_locker;
341         if (target_sp)
342             api_locker.Lock(target_sp->GetAPIMutex());
343         m_opaque_ptr->SourceInitFile (true, result.ref());
344     }
345     else
346     {
347         result->AppendError ("SBCommandInterpreter is not valid");
348         result->SetStatus (eReturnStatusFailed);
349     }
350     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
351 
352     if (log)
353         log->Printf ("SBCommandInterpreter(%p)::SourceInitFileInCurrentWorkingDirectory (&SBCommandReturnObject(%p))",
354                      static_cast<void*>(m_opaque_ptr),
355                      static_cast<void*>(result.get()));
356 }
357 
358 SBBroadcaster
359 SBCommandInterpreter::GetBroadcaster ()
360 {
361     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
362 
363     SBBroadcaster broadcaster (m_opaque_ptr, false);
364 
365     if (log)
366         log->Printf ("SBCommandInterpreter(%p)::GetBroadcaster() => SBBroadcaster(%p)",
367                      static_cast<void*>(m_opaque_ptr), static_cast<void*>(broadcaster.get()));
368 
369     return broadcaster;
370 }
371 
372 const char *
373 SBCommandInterpreter::GetBroadcasterClass ()
374 {
375     return Communication::GetStaticBroadcasterClass().AsCString();
376 }
377 
378 const char *
379 SBCommandInterpreter::GetArgumentTypeAsCString (const lldb::CommandArgumentType arg_type)
380 {
381     return CommandObject::GetArgumentTypeAsCString (arg_type);
382 }
383 
384 const char *
385 SBCommandInterpreter::GetArgumentDescriptionAsCString (const lldb::CommandArgumentType arg_type)
386 {
387     return CommandObject::GetArgumentDescriptionAsCString (arg_type);
388 }
389 
390 bool
391 SBCommandInterpreter::SetCommandOverrideCallback (const char *command_name,
392                                                   lldb::CommandOverrideCallback callback,
393                                                   void *baton)
394 {
395     if (command_name && command_name[0] && m_opaque_ptr)
396     {
397         std::string command_name_str (command_name);
398         CommandObject *cmd_obj = m_opaque_ptr->GetCommandObjectForCommand(command_name_str);
399         if (cmd_obj)
400         {
401             assert(command_name_str.empty());
402             cmd_obj->SetOverrideCallback (callback, baton);
403             return true;
404         }
405     }
406     return false;
407 }
408 
409 #ifndef LLDB_DISABLE_PYTHON
410 
411 // Defined in the SWIG source file
412 extern "C" void
413 init_lldb(void);
414 
415 // these are the Pythonic implementations of the required callbacks
416 // these are scripting-language specific, which is why they belong here
417 // we still need to use function pointers to them instead of relying
418 // on linkage-time resolution because the SWIG stuff and this file
419 // get built at different times
420 extern "C" bool
421 LLDBSwigPythonBreakpointCallbackFunction (const char *python_function_name,
422                                           const char *session_dictionary_name,
423                                           const lldb::StackFrameSP& sb_frame,
424                                           const lldb::BreakpointLocationSP& sb_bp_loc);
425 
426 extern "C" bool
427 LLDBSwigPythonWatchpointCallbackFunction (const char *python_function_name,
428                                           const char *session_dictionary_name,
429                                           const lldb::StackFrameSP& sb_frame,
430                                           const lldb::WatchpointSP& sb_wp);
431 
432 extern "C" bool
433 LLDBSwigPythonCallTypeScript (const char *python_function_name,
434                               void *session_dictionary,
435                               const lldb::ValueObjectSP& valobj_sp,
436                               void** pyfunct_wrapper,
437                               std::string& retval);
438 
439 extern "C" void*
440 LLDBSwigPythonCreateSyntheticProvider (const char *python_class_name,
441                                        const char *session_dictionary_name,
442                                        const lldb::ValueObjectSP& valobj_sp);
443 
444 
445 extern "C" void*
446 LLDBSwigPythonCreateScriptedThreadPlan (const char *python_class_name,
447                                         const char *session_dictionary_name,
448                                         const lldb::ThreadPlanSP& thread_plan_sp);
449 
450 extern "C" bool
451 LLDBSWIGPythonCallThreadPlan (void *implementor,
452                               const char *method_name,
453                               Event *event_sp,
454                               bool &got_error);
455 
456 extern "C" uint32_t
457 LLDBSwigPython_CalculateNumChildren (void *implementor);
458 
459 extern "C" void *
460 LLDBSwigPython_GetChildAtIndex (void *implementor, uint32_t idx);
461 
462 extern "C" int
463 LLDBSwigPython_GetIndexOfChildWithName (void *implementor, const char* child_name);
464 
465 extern "C" void *
466 LLDBSWIGPython_CastPyObjectToSBValue (void* data);
467 
468 extern lldb::ValueObjectSP
469 LLDBSWIGPython_GetValueObjectSPFromSBValue (void* data);
470 
471 extern "C" bool
472 LLDBSwigPython_UpdateSynthProviderInstance (void* implementor);
473 
474 extern "C" bool
475 LLDBSwigPython_MightHaveChildrenSynthProviderInstance (void* implementor);
476 
477 extern "C" void *
478 LLDBSwigPython_GetValueSynthProviderInstance (void* implementor);
479 
480 extern "C" bool
481 LLDBSwigPythonCallCommand (const char *python_function_name,
482                            const char *session_dictionary_name,
483                            lldb::DebuggerSP& debugger,
484                            const char* args,
485                            lldb_private::CommandReturnObject &cmd_retobj,
486                            lldb::ExecutionContextRefSP exe_ctx_ref_sp);
487 
488 extern "C" bool
489 LLDBSwigPythonCallModuleInit (const char *python_module_name,
490                               const char *session_dictionary_name,
491                               lldb::DebuggerSP& debugger);
492 
493 extern "C" void*
494 LLDBSWIGPythonCreateOSPlugin (const char *python_class_name,
495                               const char *session_dictionary_name,
496                               const lldb::ProcessSP& process_sp);
497 
498 extern "C" bool
499 LLDBSWIGPythonRunScriptKeywordProcess (const char* python_function_name,
500                                        const char* session_dictionary_name,
501                                        lldb::ProcessSP& process,
502                                        std::string& output);
503 
504 extern "C" bool
505 LLDBSWIGPythonRunScriptKeywordThread (const char* python_function_name,
506                                       const char* session_dictionary_name,
507                                       lldb::ThreadSP& thread,
508                                       std::string& output);
509 
510 extern "C" bool
511 LLDBSWIGPythonRunScriptKeywordTarget (const char* python_function_name,
512                                       const char* session_dictionary_name,
513                                       lldb::TargetSP& target,
514                                       std::string& output);
515 
516 extern "C" bool
517 LLDBSWIGPythonRunScriptKeywordFrame (const char* python_function_name,
518                                      const char* session_dictionary_name,
519                                      lldb::StackFrameSP& frame,
520                                      std::string& output);
521 
522 extern "C" void*
523 LLDBSWIGPython_GetDynamicSetting (void* module,
524                                   const char* setting,
525                                   const lldb::TargetSP& target_sp);
526 
527 
528 #endif
529 
530 void
531 SBCommandInterpreter::InitializeSWIG ()
532 {
533     static bool g_initialized = false;
534     if (!g_initialized)
535     {
536         g_initialized = true;
537 #ifndef LLDB_DISABLE_PYTHON
538         ScriptInterpreter::InitializeInterpreter (init_lldb,
539                                                   LLDBSwigPythonBreakpointCallbackFunction,
540                                                   LLDBSwigPythonWatchpointCallbackFunction,
541                                                   LLDBSwigPythonCallTypeScript,
542                                                   LLDBSwigPythonCreateSyntheticProvider,
543                                                   LLDBSwigPython_CalculateNumChildren,
544                                                   LLDBSwigPython_GetChildAtIndex,
545                                                   LLDBSwigPython_GetIndexOfChildWithName,
546                                                   LLDBSWIGPython_CastPyObjectToSBValue,
547                                                   LLDBSWIGPython_GetValueObjectSPFromSBValue,
548                                                   LLDBSwigPython_UpdateSynthProviderInstance,
549                                                   LLDBSwigPython_MightHaveChildrenSynthProviderInstance,
550                                                   LLDBSwigPython_GetValueSynthProviderInstance,
551                                                   LLDBSwigPythonCallCommand,
552                                                   LLDBSwigPythonCallModuleInit,
553                                                   LLDBSWIGPythonCreateOSPlugin,
554                                                   LLDBSWIGPythonRunScriptKeywordProcess,
555                                                   LLDBSWIGPythonRunScriptKeywordThread,
556                                                   LLDBSWIGPythonRunScriptKeywordTarget,
557                                                   LLDBSWIGPythonRunScriptKeywordFrame,
558                                                   LLDBSWIGPython_GetDynamicSetting,
559                                                   LLDBSwigPythonCreateScriptedThreadPlan,
560                                                   LLDBSWIGPythonCallThreadPlan);
561 #endif
562     }
563 }
564 
565 lldb::SBCommand
566 SBCommandInterpreter::AddMultiwordCommand (const char* name, const char* help)
567 {
568     CommandObjectMultiword *new_command = new CommandObjectMultiword(*m_opaque_ptr,name,help);
569     new_command->SetRemovable (true);
570     lldb::CommandObjectSP new_command_sp(new_command);
571     if (new_command_sp && m_opaque_ptr->AddUserCommand(name, new_command_sp, true))
572         return lldb::SBCommand(new_command_sp);
573     return lldb::SBCommand();
574 }
575 
576 lldb::SBCommand
577 SBCommandInterpreter::AddCommand (const char* name, lldb::SBCommandPluginInterface* impl, const char* help)
578 {
579     lldb::CommandObjectSP new_command_sp;
580     new_command_sp.reset(new CommandPluginInterfaceImplementation(*m_opaque_ptr,name,impl,help));
581 
582     if (new_command_sp && m_opaque_ptr->AddUserCommand(name, new_command_sp, true))
583         return lldb::SBCommand(new_command_sp);
584     return lldb::SBCommand();
585 }
586 
587 SBCommand::SBCommand ()
588 {}
589 
590 SBCommand::SBCommand (lldb::CommandObjectSP cmd_sp) : m_opaque_sp (cmd_sp)
591 {}
592 
593 bool
594 SBCommand::IsValid ()
595 {
596     return (bool)m_opaque_sp;
597 }
598 
599 const char*
600 SBCommand::GetName ()
601 {
602     if (IsValid ())
603         return m_opaque_sp->GetCommandName ();
604     return NULL;
605 }
606 
607 const char*
608 SBCommand::GetHelp ()
609 {
610     if (IsValid ())
611         return m_opaque_sp->GetHelp ();
612     return NULL;
613 }
614 
615 lldb::SBCommand
616 SBCommand::AddMultiwordCommand (const char* name, const char* help)
617 {
618     if (!IsValid ())
619         return lldb::SBCommand();
620     if (m_opaque_sp->IsMultiwordObject() == false)
621         return lldb::SBCommand();
622     CommandObjectMultiword *new_command = new CommandObjectMultiword(m_opaque_sp->GetCommandInterpreter(),name,help);
623     new_command->SetRemovable (true);
624     lldb::CommandObjectSP new_command_sp(new_command);
625     if (new_command_sp && m_opaque_sp->LoadSubCommand(name,new_command_sp))
626         return lldb::SBCommand(new_command_sp);
627     return lldb::SBCommand();
628 }
629 
630 lldb::SBCommand
631 SBCommand::AddCommand (const char* name, lldb::SBCommandPluginInterface *impl, const char* help)
632 {
633     if (!IsValid ())
634         return lldb::SBCommand();
635     if (m_opaque_sp->IsMultiwordObject() == false)
636         return lldb::SBCommand();
637     lldb::CommandObjectSP new_command_sp;
638     new_command_sp.reset(new CommandPluginInterfaceImplementation(m_opaque_sp->GetCommandInterpreter(),name,impl,help));
639     if (new_command_sp && m_opaque_sp->LoadSubCommand(name,new_command_sp))
640         return lldb::SBCommand(new_command_sp);
641     return lldb::SBCommand();
642 }
643 
644