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