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