1312b43daSMed Ismail Bennani //===-- ScriptedProcess.cpp -----------------------------------------------===//
2312b43daSMed Ismail Bennani //
3312b43daSMed Ismail Bennani // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4312b43daSMed Ismail Bennani // See https://llvm.org/LICENSE.txt for license information.
5312b43daSMed Ismail Bennani // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6312b43daSMed Ismail Bennani //
7312b43daSMed Ismail Bennani //===----------------------------------------------------------------------===//
8312b43daSMed Ismail Bennani 
9312b43daSMed Ismail Bennani #include "ScriptedProcess.h"
10312b43daSMed Ismail Bennani 
11312b43daSMed Ismail Bennani #include "lldb/Core/Debugger.h"
12312b43daSMed Ismail Bennani #include "lldb/Core/Module.h"
13312b43daSMed Ismail Bennani #include "lldb/Core/PluginManager.h"
14312b43daSMed Ismail Bennani 
15312b43daSMed Ismail Bennani #include "lldb/Host/OptionParser.h"
16312b43daSMed Ismail Bennani #include "lldb/Host/ThreadLauncher.h"
17312b43daSMed Ismail Bennani #include "lldb/Interpreter/CommandInterpreter.h"
18312b43daSMed Ismail Bennani #include "lldb/Interpreter/OptionArgParser.h"
19312b43daSMed Ismail Bennani #include "lldb/Interpreter/OptionGroupBoolean.h"
20312b43daSMed Ismail Bennani #include "lldb/Interpreter/ScriptInterpreter.h"
21312b43daSMed Ismail Bennani #include "lldb/Target/MemoryRegionInfo.h"
22312b43daSMed Ismail Bennani #include "lldb/Target/RegisterContext.h"
23312b43daSMed Ismail Bennani 
24312b43daSMed Ismail Bennani #include "lldb/Utility/State.h"
25312b43daSMed Ismail Bennani 
26312b43daSMed Ismail Bennani #include <mutex>
27312b43daSMed Ismail Bennani 
28312b43daSMed Ismail Bennani LLDB_PLUGIN_DEFINE(ScriptedProcess)
29312b43daSMed Ismail Bennani 
30312b43daSMed Ismail Bennani using namespace lldb;
31312b43daSMed Ismail Bennani using namespace lldb_private;
32312b43daSMed Ismail Bennani 
33312b43daSMed Ismail Bennani ConstString ScriptedProcess::GetPluginNameStatic() {
34312b43daSMed Ismail Bennani   static ConstString g_name("ScriptedProcess");
35312b43daSMed Ismail Bennani   return g_name;
36312b43daSMed Ismail Bennani }
37312b43daSMed Ismail Bennani 
38312b43daSMed Ismail Bennani const char *ScriptedProcess::GetPluginDescriptionStatic() {
39312b43daSMed Ismail Bennani   return "Scripted Process plug-in.";
40312b43daSMed Ismail Bennani }
41312b43daSMed Ismail Bennani 
42312b43daSMed Ismail Bennani static constexpr lldb::ScriptLanguage g_supported_script_languages[] = {
43312b43daSMed Ismail Bennani     ScriptLanguage::eScriptLanguagePython,
44312b43daSMed Ismail Bennani };
45312b43daSMed Ismail Bennani 
46312b43daSMed Ismail Bennani bool ScriptedProcess::IsScriptLanguageSupported(lldb::ScriptLanguage language) {
47312b43daSMed Ismail Bennani   llvm::ArrayRef<lldb::ScriptLanguage> supported_languages =
48312b43daSMed Ismail Bennani       llvm::makeArrayRef(g_supported_script_languages);
49312b43daSMed Ismail Bennani 
50312b43daSMed Ismail Bennani   return llvm::is_contained(supported_languages, language);
51312b43daSMed Ismail Bennani }
52312b43daSMed Ismail Bennani 
53312b43daSMed Ismail Bennani void ScriptedProcess::CheckInterpreterAndScriptObject() const {
54312b43daSMed Ismail Bennani   lldbassert(m_interpreter && "Invalid Script Interpreter.");
55312b43daSMed Ismail Bennani   lldbassert(m_script_object_sp && "Invalid Script Object.");
56312b43daSMed Ismail Bennani }
57312b43daSMed Ismail Bennani 
58312b43daSMed Ismail Bennani lldb::ProcessSP ScriptedProcess::CreateInstance(lldb::TargetSP target_sp,
59312b43daSMed Ismail Bennani                                                 lldb::ListenerSP listener_sp,
60312b43daSMed Ismail Bennani                                                 const FileSpec *file,
61312b43daSMed Ismail Bennani                                                 bool can_connect) {
62312b43daSMed Ismail Bennani   if (!target_sp ||
63312b43daSMed Ismail Bennani       !IsScriptLanguageSupported(target_sp->GetDebugger().GetScriptLanguage()))
64312b43daSMed Ismail Bennani     return nullptr;
65312b43daSMed Ismail Bennani 
66312b43daSMed Ismail Bennani   Status error;
67312b43daSMed Ismail Bennani   ScriptedProcess::ScriptedProcessInfo scripted_process_info(
68312b43daSMed Ismail Bennani       target_sp->GetProcessLaunchInfo());
69312b43daSMed Ismail Bennani 
70312b43daSMed Ismail Bennani   auto process_sp = std::make_shared<ScriptedProcess>(
71312b43daSMed Ismail Bennani       target_sp, listener_sp, scripted_process_info, error);
72312b43daSMed Ismail Bennani 
73312b43daSMed Ismail Bennani   if (error.Fail() || !process_sp || !process_sp->m_script_object_sp ||
74312b43daSMed Ismail Bennani       !process_sp->m_script_object_sp->IsValid()) {
75312b43daSMed Ismail Bennani     LLDB_LOGF(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS), "%s",
76312b43daSMed Ismail Bennani               error.AsCString());
77312b43daSMed Ismail Bennani     return nullptr;
78312b43daSMed Ismail Bennani   }
79312b43daSMed Ismail Bennani 
80312b43daSMed Ismail Bennani   return process_sp;
81312b43daSMed Ismail Bennani }
82312b43daSMed Ismail Bennani 
83312b43daSMed Ismail Bennani bool ScriptedProcess::CanDebug(lldb::TargetSP target_sp,
84312b43daSMed Ismail Bennani                                bool plugin_specified_by_name) {
85312b43daSMed Ismail Bennani   return true;
86312b43daSMed Ismail Bennani }
87312b43daSMed Ismail Bennani 
88312b43daSMed Ismail Bennani ScriptedProcess::ScriptedProcess(
89312b43daSMed Ismail Bennani     lldb::TargetSP target_sp, lldb::ListenerSP listener_sp,
90312b43daSMed Ismail Bennani     const ScriptedProcess::ScriptedProcessInfo &scripted_process_info,
91312b43daSMed Ismail Bennani     Status &error)
92312b43daSMed Ismail Bennani     : Process(target_sp, listener_sp),
93312b43daSMed Ismail Bennani       m_scripted_process_info(scripted_process_info) {
94312b43daSMed Ismail Bennani 
95312b43daSMed Ismail Bennani   if (!target_sp) {
96312b43daSMed Ismail Bennani     error.SetErrorStringWithFormat("ScriptedProcess::%s () - ERROR: %s",
97312b43daSMed Ismail Bennani                                    __FUNCTION__, "Invalid target");
98312b43daSMed Ismail Bennani     return;
99312b43daSMed Ismail Bennani   }
100312b43daSMed Ismail Bennani 
101312b43daSMed Ismail Bennani   m_interpreter = target_sp->GetDebugger().GetScriptInterpreter();
102312b43daSMed Ismail Bennani 
103312b43daSMed Ismail Bennani   if (!m_interpreter) {
104312b43daSMed Ismail Bennani     error.SetErrorStringWithFormat("ScriptedProcess::%s () - ERROR: %s",
105312b43daSMed Ismail Bennani                                    __FUNCTION__,
106312b43daSMed Ismail Bennani                                    "Debugger has no Script Interpreter");
107312b43daSMed Ismail Bennani     return;
108312b43daSMed Ismail Bennani   }
109312b43daSMed Ismail Bennani 
1103925204cSMed Ismail Bennani   ExecutionContext exe_ctx(target_sp, /*get_process=*/false);
1113925204cSMed Ismail Bennani 
1123925204cSMed Ismail Bennani   StructuredData::GenericSP object_sp = GetInterface().CreatePluginObject(
1133925204cSMed Ismail Bennani       m_scripted_process_info.GetClassName().c_str(), exe_ctx,
114312b43daSMed Ismail Bennani       m_scripted_process_info.GetDictionarySP());
115312b43daSMed Ismail Bennani 
116312b43daSMed Ismail Bennani   if (!object_sp || !object_sp->IsValid()) {
117312b43daSMed Ismail Bennani     error.SetErrorStringWithFormat("ScriptedProcess::%s () - ERROR: %s",
118312b43daSMed Ismail Bennani                                    __FUNCTION__,
119312b43daSMed Ismail Bennani                                    "Failed to create valid script object");
120312b43daSMed Ismail Bennani     return;
121312b43daSMed Ismail Bennani   }
122312b43daSMed Ismail Bennani 
123312b43daSMed Ismail Bennani   m_script_object_sp = object_sp;
124312b43daSMed Ismail Bennani }
125312b43daSMed Ismail Bennani 
126312b43daSMed Ismail Bennani ScriptedProcess::~ScriptedProcess() {
127312b43daSMed Ismail Bennani   Clear();
128312b43daSMed Ismail Bennani   // We need to call finalize on the process before destroying ourselves to
129312b43daSMed Ismail Bennani   // make sure all of the broadcaster cleanup goes as planned. If we destruct
130312b43daSMed Ismail Bennani   // this class, then Process::~Process() might have problems trying to fully
131312b43daSMed Ismail Bennani   // destroy the broadcaster.
132312b43daSMed Ismail Bennani   Finalize();
133312b43daSMed Ismail Bennani }
134312b43daSMed Ismail Bennani 
135312b43daSMed Ismail Bennani void ScriptedProcess::Initialize() {
136312b43daSMed Ismail Bennani   static llvm::once_flag g_once_flag;
137312b43daSMed Ismail Bennani 
138312b43daSMed Ismail Bennani   llvm::call_once(g_once_flag, []() {
139312b43daSMed Ismail Bennani     PluginManager::RegisterPlugin(GetPluginNameStatic(),
140312b43daSMed Ismail Bennani                                   GetPluginDescriptionStatic(), CreateInstance);
141312b43daSMed Ismail Bennani   });
142312b43daSMed Ismail Bennani }
143312b43daSMed Ismail Bennani 
144312b43daSMed Ismail Bennani void ScriptedProcess::Terminate() {
145312b43daSMed Ismail Bennani   PluginManager::UnregisterPlugin(ScriptedProcess::CreateInstance);
146312b43daSMed Ismail Bennani }
147312b43daSMed Ismail Bennani 
148312b43daSMed Ismail Bennani ConstString ScriptedProcess::GetPluginName() { return GetPluginNameStatic(); }
149312b43daSMed Ismail Bennani 
150312b43daSMed Ismail Bennani Status ScriptedProcess::DoLoadCore() {
151312b43daSMed Ismail Bennani   ProcessLaunchInfo launch_info = GetTarget().GetProcessLaunchInfo();
152312b43daSMed Ismail Bennani 
153312b43daSMed Ismail Bennani   return DoLaunch(nullptr, launch_info);
154312b43daSMed Ismail Bennani }
155312b43daSMed Ismail Bennani 
156312b43daSMed Ismail Bennani Status ScriptedProcess::DoLaunch(Module *exe_module,
157312b43daSMed Ismail Bennani                                  ProcessLaunchInfo &launch_info) {
158312b43daSMed Ismail Bennani   CheckInterpreterAndScriptObject();
159312b43daSMed Ismail Bennani 
160312b43daSMed Ismail Bennani   /* FIXME: This doesn't reflect how lldb actually launches a process.
161312b43daSMed Ismail Bennani            In reality, it attaches to debugserver, then resume the process. */
162312b43daSMed Ismail Bennani   Status error = GetInterface().Launch();
163312b43daSMed Ismail Bennani   SetPrivateState(eStateRunning);
164312b43daSMed Ismail Bennani 
165312b43daSMed Ismail Bennani   if (error.Fail())
166312b43daSMed Ismail Bennani     return error;
167312b43daSMed Ismail Bennani 
168312b43daSMed Ismail Bennani   // TODO: Fetch next state from stopped event queue then send stop event
169312b43daSMed Ismail Bennani   //  const StateType state = SetThreadStopInfo(response);
170312b43daSMed Ismail Bennani   //  if (state != eStateInvalid) {
171312b43daSMed Ismail Bennani   //    SetPrivateState(state);
172312b43daSMed Ismail Bennani 
173312b43daSMed Ismail Bennani   SetPrivateState(eStateStopped);
174312b43daSMed Ismail Bennani 
175312b43daSMed Ismail Bennani   UpdateThreadListIfNeeded();
176312b43daSMed Ismail Bennani   GetThreadList();
177312b43daSMed Ismail Bennani 
178312b43daSMed Ismail Bennani   return {};
179312b43daSMed Ismail Bennani }
180312b43daSMed Ismail Bennani 
181312b43daSMed Ismail Bennani void ScriptedProcess::DidLaunch() {
182312b43daSMed Ismail Bennani   CheckInterpreterAndScriptObject();
183312b43daSMed Ismail Bennani   m_pid = GetInterface().GetProcessID();
184312b43daSMed Ismail Bennani }
185312b43daSMed Ismail Bennani 
186312b43daSMed Ismail Bennani Status ScriptedProcess::DoResume() {
187312b43daSMed Ismail Bennani   CheckInterpreterAndScriptObject();
188312b43daSMed Ismail Bennani 
189312b43daSMed Ismail Bennani   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
190312b43daSMed Ismail Bennani   // FIXME: Fetch data from thread.
191312b43daSMed Ismail Bennani   const StateType thread_resume_state = eStateRunning;
192312b43daSMed Ismail Bennani   LLDB_LOGF(log, "ScriptedProcess::%s thread_resume_state = %s", __FUNCTION__,
193312b43daSMed Ismail Bennani             StateAsCString(thread_resume_state));
194312b43daSMed Ismail Bennani 
195312b43daSMed Ismail Bennani   bool resume = (thread_resume_state == eStateRunning);
196312b43daSMed Ismail Bennani   assert(thread_resume_state == eStateRunning && "invalid thread resume state");
197312b43daSMed Ismail Bennani 
198312b43daSMed Ismail Bennani   Status error;
199312b43daSMed Ismail Bennani   if (resume) {
200312b43daSMed Ismail Bennani     LLDB_LOGF(log, "ScriptedProcess::%s sending resume", __FUNCTION__);
201312b43daSMed Ismail Bennani 
202312b43daSMed Ismail Bennani     SetPrivateState(eStateRunning);
203312b43daSMed Ismail Bennani     SetPrivateState(eStateStopped);
204312b43daSMed Ismail Bennani     error = GetInterface().Resume();
205312b43daSMed Ismail Bennani   }
206312b43daSMed Ismail Bennani 
207312b43daSMed Ismail Bennani   return error;
208312b43daSMed Ismail Bennani }
209312b43daSMed Ismail Bennani 
210312b43daSMed Ismail Bennani Status ScriptedProcess::DoStop() {
211312b43daSMed Ismail Bennani   CheckInterpreterAndScriptObject();
212312b43daSMed Ismail Bennani 
213312b43daSMed Ismail Bennani   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
214312b43daSMed Ismail Bennani 
215312b43daSMed Ismail Bennani   if (GetInterface().ShouldStop()) {
216312b43daSMed Ismail Bennani     SetPrivateState(eStateStopped);
217312b43daSMed Ismail Bennani     LLDB_LOGF(log, "ScriptedProcess::%s Immediate stop", __FUNCTION__);
218312b43daSMed Ismail Bennani     return {};
219312b43daSMed Ismail Bennani   }
220312b43daSMed Ismail Bennani 
221312b43daSMed Ismail Bennani   LLDB_LOGF(log, "ScriptedProcess::%s Delayed stop", __FUNCTION__);
222312b43daSMed Ismail Bennani   return GetInterface().Stop();
223312b43daSMed Ismail Bennani }
224312b43daSMed Ismail Bennani 
225312b43daSMed Ismail Bennani Status ScriptedProcess::DoDestroy() { return Status(); }
226312b43daSMed Ismail Bennani 
227312b43daSMed Ismail Bennani bool ScriptedProcess::IsAlive() {
228312b43daSMed Ismail Bennani   if (m_interpreter && m_script_object_sp)
229312b43daSMed Ismail Bennani     return GetInterface().IsAlive();
230312b43daSMed Ismail Bennani   return false;
231312b43daSMed Ismail Bennani }
232312b43daSMed Ismail Bennani 
233312b43daSMed Ismail Bennani size_t ScriptedProcess::DoReadMemory(lldb::addr_t addr, void *buf, size_t size,
234312b43daSMed Ismail Bennani                                      Status &error) {
235312b43daSMed Ismail Bennani   if (!m_interpreter)
236*88a941baSMed Ismail Bennani     return GetInterface().ErrorWithMessage<size_t>(LLVM_PRETTY_FUNCTION,
23759d8dd79SMed Ismail Bennani                                                    "No interpreter.", error);
238312b43daSMed Ismail Bennani 
239312b43daSMed Ismail Bennani   lldb::DataExtractorSP data_extractor_sp =
240312b43daSMed Ismail Bennani       GetInterface().ReadMemoryAtAddress(addr, size, error);
241312b43daSMed Ismail Bennani 
242a758c9f7SMed Ismail Bennani   if (!data_extractor_sp || !data_extractor_sp->GetByteSize() || error.Fail())
243312b43daSMed Ismail Bennani     return 0;
244312b43daSMed Ismail Bennani 
245312b43daSMed Ismail Bennani   offset_t bytes_copied = data_extractor_sp->CopyByteOrderedData(
246312b43daSMed Ismail Bennani       0, data_extractor_sp->GetByteSize(), buf, size, GetByteOrder());
247312b43daSMed Ismail Bennani 
248312b43daSMed Ismail Bennani   if (!bytes_copied || bytes_copied == LLDB_INVALID_OFFSET)
24959d8dd79SMed Ismail Bennani     return GetInterface().ErrorWithMessage<size_t>(
250*88a941baSMed Ismail Bennani         LLVM_PRETTY_FUNCTION, "Failed to copy read memory to buffer.", error);
251312b43daSMed Ismail Bennani 
252312b43daSMed Ismail Bennani   return size;
253312b43daSMed Ismail Bennani }
254312b43daSMed Ismail Bennani 
255312b43daSMed Ismail Bennani ArchSpec ScriptedProcess::GetArchitecture() {
256312b43daSMed Ismail Bennani   return GetTarget().GetArchitecture();
257312b43daSMed Ismail Bennani }
258312b43daSMed Ismail Bennani 
259312b43daSMed Ismail Bennani Status ScriptedProcess::GetMemoryRegionInfo(lldb::addr_t load_addr,
260312b43daSMed Ismail Bennani                                             MemoryRegionInfo &region) {
261a758c9f7SMed Ismail Bennani   CheckInterpreterAndScriptObject();
262a758c9f7SMed Ismail Bennani 
263a758c9f7SMed Ismail Bennani   Status error;
264a758c9f7SMed Ismail Bennani   if (auto region_or_err =
265a758c9f7SMed Ismail Bennani           GetInterface().GetMemoryRegionContainingAddress(load_addr, error))
266a758c9f7SMed Ismail Bennani     region = *region_or_err;
267a758c9f7SMed Ismail Bennani 
268a758c9f7SMed Ismail Bennani   return error;
269312b43daSMed Ismail Bennani }
270312b43daSMed Ismail Bennani 
271312b43daSMed Ismail Bennani Status ScriptedProcess::GetMemoryRegions(MemoryRegionInfos &region_list) {
272312b43daSMed Ismail Bennani   CheckInterpreterAndScriptObject();
273312b43daSMed Ismail Bennani 
274a758c9f7SMed Ismail Bennani   Status error;
275312b43daSMed Ismail Bennani   lldb::addr_t address = 0;
276312b43daSMed Ismail Bennani 
277a758c9f7SMed Ismail Bennani   while (auto region_or_err =
278a758c9f7SMed Ismail Bennani              GetInterface().GetMemoryRegionContainingAddress(address, error)) {
279a758c9f7SMed Ismail Bennani     if (error.Fail())
280a758c9f7SMed Ismail Bennani       break;
281a758c9f7SMed Ismail Bennani 
282a758c9f7SMed Ismail Bennani     MemoryRegionInfo &mem_region = *region_or_err;
283a758c9f7SMed Ismail Bennani     auto range = mem_region.GetRange();
284312b43daSMed Ismail Bennani     address += range.GetRangeBase() + range.GetByteSize();
285a758c9f7SMed Ismail Bennani     region_list.push_back(mem_region);
286312b43daSMed Ismail Bennani   }
287312b43daSMed Ismail Bennani 
288a758c9f7SMed Ismail Bennani   return error;
289312b43daSMed Ismail Bennani }
290312b43daSMed Ismail Bennani 
291312b43daSMed Ismail Bennani void ScriptedProcess::Clear() { Process::m_thread_list.Clear(); }
292312b43daSMed Ismail Bennani 
293312b43daSMed Ismail Bennani bool ScriptedProcess::DoUpdateThreadList(ThreadList &old_thread_list,
294312b43daSMed Ismail Bennani                                          ThreadList &new_thread_list) {
295312b43daSMed Ismail Bennani   // TODO: Implement
296312b43daSMed Ismail Bennani   // This is supposed to get the current set of threads, if any of them are in
297312b43daSMed Ismail Bennani   // old_thread_list then they get copied to new_thread_list, and then any
298312b43daSMed Ismail Bennani   // actually new threads will get added to new_thread_list.
29959d8dd79SMed Ismail Bennani 
30059d8dd79SMed Ismail Bennani   CheckInterpreterAndScriptObject();
30159d8dd79SMed Ismail Bennani 
30259d8dd79SMed Ismail Bennani   Status error;
30359d8dd79SMed Ismail Bennani   ScriptLanguage language = m_interpreter->GetLanguage();
30459d8dd79SMed Ismail Bennani 
30559d8dd79SMed Ismail Bennani   if (language != eScriptLanguagePython)
30659d8dd79SMed Ismail Bennani     return GetInterface().ErrorWithMessage<bool>(
307*88a941baSMed Ismail Bennani         LLVM_PRETTY_FUNCTION,
30859d8dd79SMed Ismail Bennani         llvm::Twine("ScriptInterpreter language (" +
30959d8dd79SMed Ismail Bennani                     llvm::Twine(m_interpreter->LanguageToString(language)) +
31059d8dd79SMed Ismail Bennani                     llvm::Twine(") not supported."))
31159d8dd79SMed Ismail Bennani             .str(),
31259d8dd79SMed Ismail Bennani         error);
31359d8dd79SMed Ismail Bennani 
31459d8dd79SMed Ismail Bennani   lldb::ThreadSP thread_sp;
31559d8dd79SMed Ismail Bennani   thread_sp = std::make_shared<ScriptedThread>(*this, error);
31659d8dd79SMed Ismail Bennani 
31759d8dd79SMed Ismail Bennani   if (!thread_sp || error.Fail())
318*88a941baSMed Ismail Bennani     return GetInterface().ErrorWithMessage<bool>(LLVM_PRETTY_FUNCTION,
31959d8dd79SMed Ismail Bennani                                                  error.AsCString(), error);
32059d8dd79SMed Ismail Bennani 
32159d8dd79SMed Ismail Bennani   new_thread_list.AddThread(thread_sp);
32259d8dd79SMed Ismail Bennani 
323312b43daSMed Ismail Bennani   return new_thread_list.GetSize(false) > 0;
324312b43daSMed Ismail Bennani }
325312b43daSMed Ismail Bennani 
326312b43daSMed Ismail Bennani bool ScriptedProcess::GetProcessInfo(ProcessInstanceInfo &info) {
327312b43daSMed Ismail Bennani   info.Clear();
328312b43daSMed Ismail Bennani   info.SetProcessID(GetID());
329312b43daSMed Ismail Bennani   info.SetArchitecture(GetArchitecture());
330312b43daSMed Ismail Bennani   lldb::ModuleSP module_sp = GetTarget().GetExecutableModule();
331312b43daSMed Ismail Bennani   if (module_sp) {
332312b43daSMed Ismail Bennani     const bool add_exe_file_as_first_arg = false;
333312b43daSMed Ismail Bennani     info.SetExecutableFile(GetTarget().GetExecutableModule()->GetFileSpec(),
334312b43daSMed Ismail Bennani                            add_exe_file_as_first_arg);
335312b43daSMed Ismail Bennani   }
336312b43daSMed Ismail Bennani   return true;
337312b43daSMed Ismail Bennani }
338312b43daSMed Ismail Bennani 
339312b43daSMed Ismail Bennani ScriptedProcessInterface &ScriptedProcess::GetInterface() const {
340312b43daSMed Ismail Bennani   return m_interpreter->GetScriptedProcessInterface();
341312b43daSMed Ismail Bennani }
342