1 //===-- ScriptInterpreter.h -------------------------------------*- 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 #ifndef liblldb_ScriptInterpreter_h_
11 #define liblldb_ScriptInterpreter_h_
12 
13 #include "lldb/lldb-private.h"
14 
15 #include "lldb/Breakpoint/BreakpointOptions.h"
16 #include "lldb/Core/PluginInterface.h"
17 #include "lldb/Core/SearchFilter.h"
18 #include "lldb/Utility/Broadcaster.h"
19 #include "lldb/Utility/Status.h"
20 #include "lldb/Utility/StructuredData.h"
21 
22 #include "lldb/Host/PseudoTerminal.h"
23 
24 namespace lldb_private {
25 
26 class ScriptInterpreterLocker {
27 public:
28   ScriptInterpreterLocker() = default;
29 
30   virtual ~ScriptInterpreterLocker() = default;
31 
32 private:
33   DISALLOW_COPY_AND_ASSIGN(ScriptInterpreterLocker);
34 };
35 
36 class ScriptInterpreter : public PluginInterface {
37 public:
38   typedef enum {
39     eScriptReturnTypeCharPtr,
40     eScriptReturnTypeBool,
41     eScriptReturnTypeShortInt,
42     eScriptReturnTypeShortIntUnsigned,
43     eScriptReturnTypeInt,
44     eScriptReturnTypeIntUnsigned,
45     eScriptReturnTypeLongInt,
46     eScriptReturnTypeLongIntUnsigned,
47     eScriptReturnTypeLongLong,
48     eScriptReturnTypeLongLongUnsigned,
49     eScriptReturnTypeFloat,
50     eScriptReturnTypeDouble,
51     eScriptReturnTypeChar,
52     eScriptReturnTypeCharStrOrNone,
53     eScriptReturnTypeOpaqueObject
54   } ScriptReturnType;
55 
56   ScriptInterpreter(CommandInterpreter &interpreter,
57                     lldb::ScriptLanguage script_lang);
58 
59   ~ScriptInterpreter() override;
60 
61   struct ExecuteScriptOptions {
62   public:
ExecuteScriptOptionsExecuteScriptOptions63     ExecuteScriptOptions()
64         : m_enable_io(true), m_set_lldb_globals(true), m_maskout_errors(true) {}
65 
GetEnableIOExecuteScriptOptions66     bool GetEnableIO() const { return m_enable_io; }
67 
GetSetLLDBGlobalsExecuteScriptOptions68     bool GetSetLLDBGlobals() const { return m_set_lldb_globals; }
69 
GetMaskoutErrorsExecuteScriptOptions70     bool GetMaskoutErrors() const { return m_maskout_errors; }
71 
SetEnableIOExecuteScriptOptions72     ExecuteScriptOptions &SetEnableIO(bool enable) {
73       m_enable_io = enable;
74       return *this;
75     }
76 
SetSetLLDBGlobalsExecuteScriptOptions77     ExecuteScriptOptions &SetSetLLDBGlobals(bool set) {
78       m_set_lldb_globals = set;
79       return *this;
80     }
81 
SetMaskoutErrorsExecuteScriptOptions82     ExecuteScriptOptions &SetMaskoutErrors(bool maskout) {
83       m_maskout_errors = maskout;
84       return *this;
85     }
86 
87   private:
88     bool m_enable_io;
89     bool m_set_lldb_globals;
90     bool m_maskout_errors;
91   };
92 
Interrupt()93   virtual bool Interrupt() { return false; }
94 
95   virtual bool ExecuteOneLine(
96       llvm::StringRef command, CommandReturnObject *result,
97       const ExecuteScriptOptions &options = ExecuteScriptOptions()) = 0;
98 
99   virtual void ExecuteInterpreterLoop() = 0;
100 
101   virtual bool ExecuteOneLineWithReturn(
102       llvm::StringRef in_string, ScriptReturnType return_type, void *ret_value,
103       const ExecuteScriptOptions &options = ExecuteScriptOptions()) {
104     return true;
105   }
106 
107   virtual Status ExecuteMultipleLines(
108       const char *in_string,
109       const ExecuteScriptOptions &options = ExecuteScriptOptions()) {
110     Status error;
111     error.SetErrorString("not implemented");
112     return error;
113   }
114 
115   virtual Status
ExportFunctionDefinitionToInterpreter(StringList & function_def)116   ExportFunctionDefinitionToInterpreter(StringList &function_def) {
117     Status error;
118     error.SetErrorString("not implemented");
119     return error;
120   }
121 
GenerateBreakpointCommandCallbackData(StringList & input,std::string & output)122   virtual Status GenerateBreakpointCommandCallbackData(StringList &input,
123                                                        std::string &output) {
124     Status error;
125     error.SetErrorString("not implemented");
126     return error;
127   }
128 
GenerateWatchpointCommandCallbackData(StringList & input,std::string & output)129   virtual bool GenerateWatchpointCommandCallbackData(StringList &input,
130                                                      std::string &output) {
131     return false;
132   }
133 
134   virtual bool GenerateTypeScriptFunction(const char *oneliner,
135                                           std::string &output,
136                                           const void *name_token = nullptr) {
137     return false;
138   }
139 
140   virtual bool GenerateTypeScriptFunction(StringList &input,
141                                           std::string &output,
142                                           const void *name_token = nullptr) {
143     return false;
144   }
145 
GenerateScriptAliasFunction(StringList & input,std::string & output)146   virtual bool GenerateScriptAliasFunction(StringList &input,
147                                            std::string &output) {
148     return false;
149   }
150 
151   virtual bool GenerateTypeSynthClass(StringList &input, std::string &output,
152                                       const void *name_token = nullptr) {
153     return false;
154   }
155 
156   virtual bool GenerateTypeSynthClass(const char *oneliner, std::string &output,
157                                       const void *name_token = nullptr) {
158     return false;
159   }
160 
161   virtual StructuredData::ObjectSP
CreateSyntheticScriptedProvider(const char * class_name,lldb::ValueObjectSP valobj)162   CreateSyntheticScriptedProvider(const char *class_name,
163                                   lldb::ValueObjectSP valobj) {
164     return StructuredData::ObjectSP();
165   }
166 
167   virtual StructuredData::GenericSP
CreateScriptCommandObject(const char * class_name)168   CreateScriptCommandObject(const char *class_name) {
169     return StructuredData::GenericSP();
170   }
171 
172   virtual StructuredData::GenericSP
CreateFrameRecognizer(const char * class_name)173   CreateFrameRecognizer(const char *class_name) {
174     return StructuredData::GenericSP();
175   }
176 
GetRecognizedArguments(const StructuredData::ObjectSP & implementor,lldb::StackFrameSP frame_sp)177   virtual lldb::ValueObjectListSP GetRecognizedArguments(
178       const StructuredData::ObjectSP &implementor,
179       lldb::StackFrameSP frame_sp) {
180     return lldb::ValueObjectListSP();
181   }
182 
183   virtual StructuredData::GenericSP
OSPlugin_CreatePluginObject(const char * class_name,lldb::ProcessSP process_sp)184   OSPlugin_CreatePluginObject(const char *class_name,
185                               lldb::ProcessSP process_sp) {
186     return StructuredData::GenericSP();
187   }
188 
189   virtual StructuredData::DictionarySP
OSPlugin_RegisterInfo(StructuredData::ObjectSP os_plugin_object_sp)190   OSPlugin_RegisterInfo(StructuredData::ObjectSP os_plugin_object_sp) {
191     return StructuredData::DictionarySP();
192   }
193 
194   virtual StructuredData::ArraySP
OSPlugin_ThreadsInfo(StructuredData::ObjectSP os_plugin_object_sp)195   OSPlugin_ThreadsInfo(StructuredData::ObjectSP os_plugin_object_sp) {
196     return StructuredData::ArraySP();
197   }
198 
199   virtual StructuredData::StringSP
OSPlugin_RegisterContextData(StructuredData::ObjectSP os_plugin_object_sp,lldb::tid_t thread_id)200   OSPlugin_RegisterContextData(StructuredData::ObjectSP os_plugin_object_sp,
201                                lldb::tid_t thread_id) {
202     return StructuredData::StringSP();
203   }
204 
205   virtual StructuredData::DictionarySP
OSPlugin_CreateThread(StructuredData::ObjectSP os_plugin_object_sp,lldb::tid_t tid,lldb::addr_t context)206   OSPlugin_CreateThread(StructuredData::ObjectSP os_plugin_object_sp,
207                         lldb::tid_t tid, lldb::addr_t context) {
208     return StructuredData::DictionarySP();
209   }
210 
211   virtual StructuredData::ObjectSP
CreateScriptedThreadPlan(const char * class_name,lldb::ThreadPlanSP thread_plan_sp)212   CreateScriptedThreadPlan(const char *class_name,
213                            lldb::ThreadPlanSP thread_plan_sp) {
214     return StructuredData::ObjectSP();
215   }
216 
217   virtual bool
ScriptedThreadPlanExplainsStop(StructuredData::ObjectSP implementor_sp,Event * event,bool & script_error)218   ScriptedThreadPlanExplainsStop(StructuredData::ObjectSP implementor_sp,
219                                  Event *event, bool &script_error) {
220     script_error = true;
221     return true;
222   }
223 
224   virtual bool
ScriptedThreadPlanShouldStop(StructuredData::ObjectSP implementor_sp,Event * event,bool & script_error)225   ScriptedThreadPlanShouldStop(StructuredData::ObjectSP implementor_sp,
226                                Event *event, bool &script_error) {
227     script_error = true;
228     return true;
229   }
230 
231   virtual bool
ScriptedThreadPlanIsStale(StructuredData::ObjectSP implementor_sp,bool & script_error)232   ScriptedThreadPlanIsStale(StructuredData::ObjectSP implementor_sp,
233                             bool &script_error) {
234     script_error = true;
235     return true;
236   }
237 
238   virtual lldb::StateType
ScriptedThreadPlanGetRunState(StructuredData::ObjectSP implementor_sp,bool & script_error)239   ScriptedThreadPlanGetRunState(StructuredData::ObjectSP implementor_sp,
240                                 bool &script_error) {
241     script_error = true;
242     return lldb::eStateStepping;
243   }
244 
245   virtual StructuredData::GenericSP
CreateScriptedBreakpointResolver(const char * class_name,StructuredDataImpl * args_data,lldb::BreakpointSP & bkpt_sp)246   CreateScriptedBreakpointResolver(const char *class_name,
247                                    StructuredDataImpl *args_data,
248                                    lldb::BreakpointSP &bkpt_sp) {
249     return StructuredData::GenericSP();
250   }
251 
252   virtual bool
ScriptedBreakpointResolverSearchCallback(StructuredData::GenericSP implementor_sp,SymbolContext * sym_ctx)253   ScriptedBreakpointResolverSearchCallback(StructuredData::GenericSP implementor_sp,
254                                            SymbolContext *sym_ctx)
255   {
256     return false;
257   }
258 
259   virtual lldb::SearchDepth
ScriptedBreakpointResolverSearchDepth(StructuredData::GenericSP implementor_sp)260   ScriptedBreakpointResolverSearchDepth(StructuredData::GenericSP implementor_sp)
261   {
262     return lldb::eSearchDepthModule;
263   }
264 
265   virtual StructuredData::ObjectSP
LoadPluginModule(const FileSpec & file_spec,lldb_private::Status & error)266   LoadPluginModule(const FileSpec &file_spec, lldb_private::Status &error) {
267     return StructuredData::ObjectSP();
268   }
269 
270   virtual StructuredData::DictionarySP
GetDynamicSettings(StructuredData::ObjectSP plugin_module_sp,Target * target,const char * setting_name,lldb_private::Status & error)271   GetDynamicSettings(StructuredData::ObjectSP plugin_module_sp, Target *target,
272                      const char *setting_name, lldb_private::Status &error) {
273     return StructuredData::DictionarySP();
274   }
275 
GenerateFunction(const char * signature,const StringList & input)276   virtual Status GenerateFunction(const char *signature,
277                                   const StringList &input) {
278     Status error;
279     error.SetErrorString("unimplemented");
280     return error;
281   }
282 
283   virtual void CollectDataForBreakpointCommandCallback(
284       std::vector<BreakpointOptions *> &options, CommandReturnObject &result);
285 
286   virtual void
287   CollectDataForWatchpointCommandCallback(WatchpointOptions *wp_options,
288                                           CommandReturnObject &result);
289 
290   /// Set the specified text as the callback for the breakpoint.
291   Status
292   SetBreakpointCommandCallback(std::vector<BreakpointOptions *> &bp_options_vec,
293                                const char *callback_text);
294 
SetBreakpointCommandCallback(BreakpointOptions * bp_options,const char * callback_text)295   virtual Status SetBreakpointCommandCallback(BreakpointOptions *bp_options,
296                                               const char *callback_text) {
297     Status error;
298     error.SetErrorString("unimplemented");
299     return error;
300   }
301 
302   /// This one is for deserialization:
SetBreakpointCommandCallback(BreakpointOptions * bp_options,std::unique_ptr<BreakpointOptions::CommandData> & data_up)303   virtual Status SetBreakpointCommandCallback(
304       BreakpointOptions *bp_options,
305       std::unique_ptr<BreakpointOptions::CommandData> &data_up) {
306     Status error;
307     error.SetErrorString("unimplemented");
308     return error;
309   }
310 
311   void SetBreakpointCommandCallbackFunction(
312       std::vector<BreakpointOptions *> &bp_options_vec,
313       const char *function_name);
314 
315   /// Set a one-liner as the callback for the breakpoint.
316   virtual void
SetBreakpointCommandCallbackFunction(BreakpointOptions * bp_options,const char * function_name)317   SetBreakpointCommandCallbackFunction(BreakpointOptions *bp_options,
318                                        const char *function_name) {}
319 
320   /// Set a one-liner as the callback for the watchpoint.
SetWatchpointCommandCallback(WatchpointOptions * wp_options,const char * oneliner)321   virtual void SetWatchpointCommandCallback(WatchpointOptions *wp_options,
322                                             const char *oneliner) {}
323 
GetScriptedSummary(const char * function_name,lldb::ValueObjectSP valobj,StructuredData::ObjectSP & callee_wrapper_sp,const TypeSummaryOptions & options,std::string & retval)324   virtual bool GetScriptedSummary(const char *function_name,
325                                   lldb::ValueObjectSP valobj,
326                                   StructuredData::ObjectSP &callee_wrapper_sp,
327                                   const TypeSummaryOptions &options,
328                                   std::string &retval) {
329     return false;
330   }
331 
Clear()332   virtual void Clear() {
333     // Clean up any ref counts to SBObjects that might be in global variables
334   }
335 
336   virtual size_t
CalculateNumChildren(const StructuredData::ObjectSP & implementor,uint32_t max)337   CalculateNumChildren(const StructuredData::ObjectSP &implementor,
338                        uint32_t max) {
339     return 0;
340   }
341 
342   virtual lldb::ValueObjectSP
GetChildAtIndex(const StructuredData::ObjectSP & implementor,uint32_t idx)343   GetChildAtIndex(const StructuredData::ObjectSP &implementor, uint32_t idx) {
344     return lldb::ValueObjectSP();
345   }
346 
347   virtual int
GetIndexOfChildWithName(const StructuredData::ObjectSP & implementor,const char * child_name)348   GetIndexOfChildWithName(const StructuredData::ObjectSP &implementor,
349                           const char *child_name) {
350     return UINT32_MAX;
351   }
352 
353   virtual bool
UpdateSynthProviderInstance(const StructuredData::ObjectSP & implementor)354   UpdateSynthProviderInstance(const StructuredData::ObjectSP &implementor) {
355     return false;
356   }
357 
MightHaveChildrenSynthProviderInstance(const StructuredData::ObjectSP & implementor)358   virtual bool MightHaveChildrenSynthProviderInstance(
359       const StructuredData::ObjectSP &implementor) {
360     return true;
361   }
362 
363   virtual lldb::ValueObjectSP
GetSyntheticValue(const StructuredData::ObjectSP & implementor)364   GetSyntheticValue(const StructuredData::ObjectSP &implementor) {
365     return nullptr;
366   }
367 
368   virtual ConstString
GetSyntheticTypeName(const StructuredData::ObjectSP & implementor)369   GetSyntheticTypeName(const StructuredData::ObjectSP &implementor) {
370     return ConstString();
371   }
372 
373   virtual bool
RunScriptBasedCommand(const char * impl_function,llvm::StringRef args,ScriptedCommandSynchronicity synchronicity,lldb_private::CommandReturnObject & cmd_retobj,Status & error,const lldb_private::ExecutionContext & exe_ctx)374   RunScriptBasedCommand(const char *impl_function, llvm::StringRef args,
375                         ScriptedCommandSynchronicity synchronicity,
376                         lldb_private::CommandReturnObject &cmd_retobj,
377                         Status &error,
378                         const lldb_private::ExecutionContext &exe_ctx) {
379     return false;
380   }
381 
RunScriptBasedCommand(StructuredData::GenericSP impl_obj_sp,llvm::StringRef args,ScriptedCommandSynchronicity synchronicity,lldb_private::CommandReturnObject & cmd_retobj,Status & error,const lldb_private::ExecutionContext & exe_ctx)382   virtual bool RunScriptBasedCommand(
383       StructuredData::GenericSP impl_obj_sp, llvm::StringRef args,
384       ScriptedCommandSynchronicity synchronicity,
385       lldb_private::CommandReturnObject &cmd_retobj, Status &error,
386       const lldb_private::ExecutionContext &exe_ctx) {
387     return false;
388   }
389 
RunScriptFormatKeyword(const char * impl_function,Process * process,std::string & output,Status & error)390   virtual bool RunScriptFormatKeyword(const char *impl_function,
391                                       Process *process, std::string &output,
392                                       Status &error) {
393     error.SetErrorString("unimplemented");
394     return false;
395   }
396 
RunScriptFormatKeyword(const char * impl_function,Thread * thread,std::string & output,Status & error)397   virtual bool RunScriptFormatKeyword(const char *impl_function, Thread *thread,
398                                       std::string &output, Status &error) {
399     error.SetErrorString("unimplemented");
400     return false;
401   }
402 
RunScriptFormatKeyword(const char * impl_function,Target * target,std::string & output,Status & error)403   virtual bool RunScriptFormatKeyword(const char *impl_function, Target *target,
404                                       std::string &output, Status &error) {
405     error.SetErrorString("unimplemented");
406     return false;
407   }
408 
RunScriptFormatKeyword(const char * impl_function,StackFrame * frame,std::string & output,Status & error)409   virtual bool RunScriptFormatKeyword(const char *impl_function,
410                                       StackFrame *frame, std::string &output,
411                                       Status &error) {
412     error.SetErrorString("unimplemented");
413     return false;
414   }
415 
RunScriptFormatKeyword(const char * impl_function,ValueObject * value,std::string & output,Status & error)416   virtual bool RunScriptFormatKeyword(const char *impl_function,
417                                       ValueObject *value, std::string &output,
418                                       Status &error) {
419     error.SetErrorString("unimplemented");
420     return false;
421   }
422 
GetDocumentationForItem(const char * item,std::string & dest)423   virtual bool GetDocumentationForItem(const char *item, std::string &dest) {
424     dest.clear();
425     return false;
426   }
427 
428   virtual bool
GetShortHelpForCommandObject(StructuredData::GenericSP cmd_obj_sp,std::string & dest)429   GetShortHelpForCommandObject(StructuredData::GenericSP cmd_obj_sp,
430                                std::string &dest) {
431     dest.clear();
432     return false;
433   }
434 
435   virtual uint32_t
GetFlagsForCommandObject(StructuredData::GenericSP cmd_obj_sp)436   GetFlagsForCommandObject(StructuredData::GenericSP cmd_obj_sp) {
437     return 0;
438   }
439 
GetLongHelpForCommandObject(StructuredData::GenericSP cmd_obj_sp,std::string & dest)440   virtual bool GetLongHelpForCommandObject(StructuredData::GenericSP cmd_obj_sp,
441                                            std::string &dest) {
442     dest.clear();
443     return false;
444   }
445 
CheckObjectExists(const char * name)446   virtual bool CheckObjectExists(const char *name) { return false; }
447 
448   virtual bool
449   LoadScriptingModule(const char *filename, bool can_reload, bool init_session,
450                       lldb_private::Status &error,
451                       StructuredData::ObjectSP *module_sp = nullptr) {
452     error.SetErrorString("loading unimplemented");
453     return false;
454   }
455 
IsReservedWord(const char * word)456   virtual bool IsReservedWord(const char *word) { return false; }
457 
458   virtual std::unique_ptr<ScriptInterpreterLocker> AcquireInterpreterLock();
459 
460   const char *GetScriptInterpreterPtyName();
461 
462   int GetMasterFileDescriptor();
463 
464   CommandInterpreter &GetCommandInterpreter();
465 
466   static std::string LanguageToString(lldb::ScriptLanguage language);
467 
468   static lldb::ScriptLanguage StringToLanguage(const llvm::StringRef &string);
469 
ResetOutputFileHandle(FILE * new_fh)470   virtual void ResetOutputFileHandle(FILE *new_fh) {} // By default, do nothing.
471 
GetLanguage()472   lldb::ScriptLanguage GetLanguage() { return m_script_lang; }
473 
474 protected:
475   CommandInterpreter &m_interpreter;
476   lldb::ScriptLanguage m_script_lang;
477 };
478 
479 } // namespace lldb_private
480 
481 #endif // liblldb_ScriptInterpreter_h_
482