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