1 //===-- SBLaunchInfo.cpp --------------------------------------------------===//
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 #include "lldb/API/SBLaunchInfo.h"
10 #include "lldb/Utility/Instrumentation.h"
11 
12 #include "lldb/API/SBEnvironment.h"
13 #include "lldb/API/SBError.h"
14 #include "lldb/API/SBFileSpec.h"
15 #include "lldb/API/SBListener.h"
16 #include "lldb/API/SBStream.h"
17 #include "lldb/API/SBStructuredData.h"
18 #include "lldb/Core/StructuredDataImpl.h"
19 #include "lldb/Host/ProcessLaunchInfo.h"
20 #include "lldb/Utility/Listener.h"
21 #include "lldb/Utility/ScriptedMetadata.h"
22 
23 using namespace lldb;
24 using namespace lldb_private;
25 
26 class lldb_private::SBLaunchInfoImpl : public ProcessLaunchInfo {
27 public:
SBLaunchInfoImpl()28   SBLaunchInfoImpl() : m_envp(GetEnvironment().getEnvp()) {}
29 
GetEnvp() const30   const char *const *GetEnvp() const { return m_envp; }
RegenerateEnvp()31   void RegenerateEnvp() { m_envp = GetEnvironment().getEnvp(); }
32 
operator =(const ProcessLaunchInfo & rhs)33   SBLaunchInfoImpl &operator=(const ProcessLaunchInfo &rhs) {
34     ProcessLaunchInfo::operator=(rhs);
35     RegenerateEnvp();
36     return *this;
37   }
38 
39 private:
40   Environment::Envp m_envp;
41 };
42 
SBLaunchInfo(const char ** argv)43 SBLaunchInfo::SBLaunchInfo(const char **argv)
44     : m_opaque_sp(new SBLaunchInfoImpl()) {
45   LLDB_INSTRUMENT_VA(this, argv);
46 
47   m_opaque_sp->GetFlags().Reset(eLaunchFlagDebug | eLaunchFlagDisableASLR);
48   if (argv && argv[0])
49     m_opaque_sp->GetArguments().SetArguments(argv);
50 }
51 
SBLaunchInfo(const SBLaunchInfo & rhs)52 SBLaunchInfo::SBLaunchInfo(const SBLaunchInfo &rhs) {
53   LLDB_INSTRUMENT_VA(this, rhs);
54 
55   m_opaque_sp = rhs.m_opaque_sp;
56 }
57 
operator =(const SBLaunchInfo & rhs)58 SBLaunchInfo &SBLaunchInfo::operator=(const SBLaunchInfo &rhs) {
59   LLDB_INSTRUMENT_VA(this, rhs);
60 
61   m_opaque_sp = rhs.m_opaque_sp;
62   return *this;
63 }
64 
65 SBLaunchInfo::~SBLaunchInfo() = default;
66 
ref() const67 const lldb_private::ProcessLaunchInfo &SBLaunchInfo::ref() const {
68   return *m_opaque_sp;
69 }
70 
set_ref(const ProcessLaunchInfo & info)71 void SBLaunchInfo::set_ref(const ProcessLaunchInfo &info) {
72   *m_opaque_sp = info;
73 }
74 
GetProcessID()75 lldb::pid_t SBLaunchInfo::GetProcessID() {
76   LLDB_INSTRUMENT_VA(this);
77 
78   return m_opaque_sp->GetProcessID();
79 }
80 
GetUserID()81 uint32_t SBLaunchInfo::GetUserID() {
82   LLDB_INSTRUMENT_VA(this);
83 
84   return m_opaque_sp->GetUserID();
85 }
86 
GetGroupID()87 uint32_t SBLaunchInfo::GetGroupID() {
88   LLDB_INSTRUMENT_VA(this);
89 
90   return m_opaque_sp->GetGroupID();
91 }
92 
UserIDIsValid()93 bool SBLaunchInfo::UserIDIsValid() {
94   LLDB_INSTRUMENT_VA(this);
95 
96   return m_opaque_sp->UserIDIsValid();
97 }
98 
GroupIDIsValid()99 bool SBLaunchInfo::GroupIDIsValid() {
100   LLDB_INSTRUMENT_VA(this);
101 
102   return m_opaque_sp->GroupIDIsValid();
103 }
104 
SetUserID(uint32_t uid)105 void SBLaunchInfo::SetUserID(uint32_t uid) {
106   LLDB_INSTRUMENT_VA(this, uid);
107 
108   m_opaque_sp->SetUserID(uid);
109 }
110 
SetGroupID(uint32_t gid)111 void SBLaunchInfo::SetGroupID(uint32_t gid) {
112   LLDB_INSTRUMENT_VA(this, gid);
113 
114   m_opaque_sp->SetGroupID(gid);
115 }
116 
GetExecutableFile()117 SBFileSpec SBLaunchInfo::GetExecutableFile() {
118   LLDB_INSTRUMENT_VA(this);
119 
120   return SBFileSpec(m_opaque_sp->GetExecutableFile());
121 }
122 
SetExecutableFile(SBFileSpec exe_file,bool add_as_first_arg)123 void SBLaunchInfo::SetExecutableFile(SBFileSpec exe_file,
124                                      bool add_as_first_arg) {
125   LLDB_INSTRUMENT_VA(this, exe_file, add_as_first_arg);
126 
127   m_opaque_sp->SetExecutableFile(exe_file.ref(), add_as_first_arg);
128 }
129 
GetListener()130 SBListener SBLaunchInfo::GetListener() {
131   LLDB_INSTRUMENT_VA(this);
132 
133   return SBListener(m_opaque_sp->GetListener());
134 }
135 
SetListener(SBListener & listener)136 void SBLaunchInfo::SetListener(SBListener &listener) {
137   LLDB_INSTRUMENT_VA(this, listener);
138 
139   m_opaque_sp->SetListener(listener.GetSP());
140 }
141 
GetNumArguments()142 uint32_t SBLaunchInfo::GetNumArguments() {
143   LLDB_INSTRUMENT_VA(this);
144 
145   return m_opaque_sp->GetArguments().GetArgumentCount();
146 }
147 
GetArgumentAtIndex(uint32_t idx)148 const char *SBLaunchInfo::GetArgumentAtIndex(uint32_t idx) {
149   LLDB_INSTRUMENT_VA(this, idx);
150 
151   return ConstString(m_opaque_sp->GetArguments().GetArgumentAtIndex(idx))
152       .GetCString();
153 }
154 
SetArguments(const char ** argv,bool append)155 void SBLaunchInfo::SetArguments(const char **argv, bool append) {
156   LLDB_INSTRUMENT_VA(this, argv, append);
157 
158   if (append) {
159     if (argv)
160       m_opaque_sp->GetArguments().AppendArguments(argv);
161   } else {
162     if (argv)
163       m_opaque_sp->GetArguments().SetArguments(argv);
164     else
165       m_opaque_sp->GetArguments().Clear();
166   }
167 }
168 
GetNumEnvironmentEntries()169 uint32_t SBLaunchInfo::GetNumEnvironmentEntries() {
170   LLDB_INSTRUMENT_VA(this);
171 
172   return m_opaque_sp->GetEnvironment().size();
173 }
174 
GetEnvironmentEntryAtIndex(uint32_t idx)175 const char *SBLaunchInfo::GetEnvironmentEntryAtIndex(uint32_t idx) {
176   LLDB_INSTRUMENT_VA(this, idx);
177 
178   if (idx > GetNumEnvironmentEntries())
179     return nullptr;
180   return ConstString(m_opaque_sp->GetEnvp()[idx]).GetCString();
181 }
182 
SetEnvironmentEntries(const char ** envp,bool append)183 void SBLaunchInfo::SetEnvironmentEntries(const char **envp, bool append) {
184   LLDB_INSTRUMENT_VA(this, envp, append);
185   SetEnvironment(SBEnvironment(Environment(envp)), append);
186 }
187 
SetEnvironment(const SBEnvironment & env,bool append)188 void SBLaunchInfo::SetEnvironment(const SBEnvironment &env, bool append) {
189   LLDB_INSTRUMENT_VA(this, env, append);
190   Environment &refEnv = env.ref();
191   if (append) {
192     for (auto &KV : refEnv)
193       m_opaque_sp->GetEnvironment().insert_or_assign(KV.first(), KV.second);
194   } else
195     m_opaque_sp->GetEnvironment() = refEnv;
196   m_opaque_sp->RegenerateEnvp();
197 }
198 
GetEnvironment()199 SBEnvironment SBLaunchInfo::GetEnvironment() {
200   LLDB_INSTRUMENT_VA(this);
201   return SBEnvironment(Environment(m_opaque_sp->GetEnvironment()));
202 }
203 
Clear()204 void SBLaunchInfo::Clear() {
205   LLDB_INSTRUMENT_VA(this);
206 
207   m_opaque_sp->Clear();
208 }
209 
GetWorkingDirectory() const210 const char *SBLaunchInfo::GetWorkingDirectory() const {
211   LLDB_INSTRUMENT_VA(this);
212 
213   return m_opaque_sp->GetWorkingDirectory().GetPathAsConstString().AsCString();
214 }
215 
SetWorkingDirectory(const char * working_dir)216 void SBLaunchInfo::SetWorkingDirectory(const char *working_dir) {
217   LLDB_INSTRUMENT_VA(this, working_dir);
218 
219   m_opaque_sp->SetWorkingDirectory(FileSpec(working_dir));
220 }
221 
GetLaunchFlags()222 uint32_t SBLaunchInfo::GetLaunchFlags() {
223   LLDB_INSTRUMENT_VA(this);
224 
225   return m_opaque_sp->GetFlags().Get();
226 }
227 
SetLaunchFlags(uint32_t flags)228 void SBLaunchInfo::SetLaunchFlags(uint32_t flags) {
229   LLDB_INSTRUMENT_VA(this, flags);
230 
231   m_opaque_sp->GetFlags().Reset(flags);
232 }
233 
GetProcessPluginName()234 const char *SBLaunchInfo::GetProcessPluginName() {
235   LLDB_INSTRUMENT_VA(this);
236 
237   return ConstString(m_opaque_sp->GetProcessPluginName()).GetCString();
238 }
239 
SetProcessPluginName(const char * plugin_name)240 void SBLaunchInfo::SetProcessPluginName(const char *plugin_name) {
241   LLDB_INSTRUMENT_VA(this, plugin_name);
242 
243   return m_opaque_sp->SetProcessPluginName(plugin_name);
244 }
245 
GetShell()246 const char *SBLaunchInfo::GetShell() {
247   LLDB_INSTRUMENT_VA(this);
248 
249   // Constify this string so that it is saved in the string pool.  Otherwise it
250   // would be freed when this function goes out of scope.
251   ConstString shell(m_opaque_sp->GetShell().GetPath().c_str());
252   return shell.AsCString();
253 }
254 
SetShell(const char * path)255 void SBLaunchInfo::SetShell(const char *path) {
256   LLDB_INSTRUMENT_VA(this, path);
257 
258   m_opaque_sp->SetShell(FileSpec(path));
259 }
260 
GetShellExpandArguments()261 bool SBLaunchInfo::GetShellExpandArguments() {
262   LLDB_INSTRUMENT_VA(this);
263 
264   return m_opaque_sp->GetShellExpandArguments();
265 }
266 
SetShellExpandArguments(bool expand)267 void SBLaunchInfo::SetShellExpandArguments(bool expand) {
268   LLDB_INSTRUMENT_VA(this, expand);
269 
270   m_opaque_sp->SetShellExpandArguments(expand);
271 }
272 
GetResumeCount()273 uint32_t SBLaunchInfo::GetResumeCount() {
274   LLDB_INSTRUMENT_VA(this);
275 
276   return m_opaque_sp->GetResumeCount();
277 }
278 
SetResumeCount(uint32_t c)279 void SBLaunchInfo::SetResumeCount(uint32_t c) {
280   LLDB_INSTRUMENT_VA(this, c);
281 
282   m_opaque_sp->SetResumeCount(c);
283 }
284 
AddCloseFileAction(int fd)285 bool SBLaunchInfo::AddCloseFileAction(int fd) {
286   LLDB_INSTRUMENT_VA(this, fd);
287 
288   return m_opaque_sp->AppendCloseFileAction(fd);
289 }
290 
AddDuplicateFileAction(int fd,int dup_fd)291 bool SBLaunchInfo::AddDuplicateFileAction(int fd, int dup_fd) {
292   LLDB_INSTRUMENT_VA(this, fd, dup_fd);
293 
294   return m_opaque_sp->AppendDuplicateFileAction(fd, dup_fd);
295 }
296 
AddOpenFileAction(int fd,const char * path,bool read,bool write)297 bool SBLaunchInfo::AddOpenFileAction(int fd, const char *path, bool read,
298                                      bool write) {
299   LLDB_INSTRUMENT_VA(this, fd, path, read, write);
300 
301   return m_opaque_sp->AppendOpenFileAction(fd, FileSpec(path), read, write);
302 }
303 
AddSuppressFileAction(int fd,bool read,bool write)304 bool SBLaunchInfo::AddSuppressFileAction(int fd, bool read, bool write) {
305   LLDB_INSTRUMENT_VA(this, fd, read, write);
306 
307   return m_opaque_sp->AppendSuppressFileAction(fd, read, write);
308 }
309 
SetLaunchEventData(const char * data)310 void SBLaunchInfo::SetLaunchEventData(const char *data) {
311   LLDB_INSTRUMENT_VA(this, data);
312 
313   m_opaque_sp->SetLaunchEventData(data);
314 }
315 
GetLaunchEventData() const316 const char *SBLaunchInfo::GetLaunchEventData() const {
317   LLDB_INSTRUMENT_VA(this);
318 
319   return ConstString(m_opaque_sp->GetLaunchEventData()).GetCString();
320 }
321 
SetDetachOnError(bool enable)322 void SBLaunchInfo::SetDetachOnError(bool enable) {
323   LLDB_INSTRUMENT_VA(this, enable);
324 
325   m_opaque_sp->SetDetachOnError(enable);
326 }
327 
GetDetachOnError() const328 bool SBLaunchInfo::GetDetachOnError() const {
329   LLDB_INSTRUMENT_VA(this);
330 
331   return m_opaque_sp->GetDetachOnError();
332 }
333 
GetScriptedProcessClassName() const334 const char *SBLaunchInfo::GetScriptedProcessClassName() const {
335   LLDB_INSTRUMENT_VA(this);
336 
337   ScriptedMetadataSP metadata_sp = m_opaque_sp->GetScriptedMetadata();
338 
339   if (!metadata_sp || !*metadata_sp)
340     return nullptr;
341 
342   // Constify this string so that it is saved in the string pool.  Otherwise it
343   // would be freed when this function goes out of scope.
344   ConstString class_name(metadata_sp->GetClassName().data());
345   return class_name.AsCString();
346 }
347 
SetScriptedProcessClassName(const char * class_name)348 void SBLaunchInfo::SetScriptedProcessClassName(const char *class_name) {
349   LLDB_INSTRUMENT_VA(this, class_name);
350   ScriptedMetadataSP metadata_sp = m_opaque_sp->GetScriptedMetadata();
351   StructuredData::DictionarySP dict_sp =
352       metadata_sp ? metadata_sp->GetArgsSP() : nullptr;
353   metadata_sp = std::make_shared<ScriptedMetadata>(class_name, dict_sp);
354   m_opaque_sp->SetScriptedMetadata(metadata_sp);
355 }
356 
GetScriptedProcessDictionary() const357 lldb::SBStructuredData SBLaunchInfo::GetScriptedProcessDictionary() const {
358   LLDB_INSTRUMENT_VA(this);
359 
360   ScriptedMetadataSP metadata_sp = m_opaque_sp->GetScriptedMetadata();
361 
362   SBStructuredData data;
363   if (!metadata_sp)
364     return data;
365 
366   lldb_private::StructuredData::DictionarySP dict_sp = metadata_sp->GetArgsSP();
367   data.m_impl_up->SetObjectSP(dict_sp);
368 
369   return data;
370 }
371 
SetScriptedProcessDictionary(lldb::SBStructuredData dict)372 void SBLaunchInfo::SetScriptedProcessDictionary(lldb::SBStructuredData dict) {
373   LLDB_INSTRUMENT_VA(this, dict);
374   if (!dict.IsValid() || !dict.m_impl_up)
375     return;
376 
377   StructuredData::ObjectSP obj_sp = dict.m_impl_up->GetObjectSP();
378 
379   if (!obj_sp)
380     return;
381 
382   StructuredData::DictionarySP dict_sp =
383       std::make_shared<StructuredData::Dictionary>(obj_sp);
384   if (!dict_sp || dict_sp->GetType() == lldb::eStructuredDataTypeInvalid)
385     return;
386 
387   ScriptedMetadataSP metadata_sp = m_opaque_sp->GetScriptedMetadata();
388   llvm::StringRef class_name = metadata_sp ? metadata_sp->GetClassName() : "";
389   metadata_sp = std::make_shared<ScriptedMetadata>(class_name, dict_sp);
390   m_opaque_sp->SetScriptedMetadata(metadata_sp);
391 }
392 
GetShadowListener()393 SBListener SBLaunchInfo::GetShadowListener() {
394   LLDB_INSTRUMENT_VA(this);
395 
396   lldb::ListenerSP shadow_sp = m_opaque_sp->GetShadowListener();
397   if (!shadow_sp)
398     return SBListener();
399   return SBListener(shadow_sp);
400 }
401 
SetShadowListener(SBListener & listener)402 void SBLaunchInfo::SetShadowListener(SBListener &listener) {
403   LLDB_INSTRUMENT_VA(this, listener);
404 
405   ListenerSP listener_sp = listener.GetSP();
406   if (listener_sp && listener.IsValid())
407     listener_sp->SetShadow(true);
408   else
409     listener_sp = nullptr;
410 
411   m_opaque_sp->SetShadowListener(listener_sp);
412 }
413