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 23using namespace lldb; 24using namespace lldb_private; 25 26class lldb_private::SBLaunchInfoImpl : public ProcessLaunchInfo { 27public: 28 SBLaunchInfoImpl() : m_envp(GetEnvironment().getEnvp()) {} 29 30 const char *const *GetEnvp() const { return m_envp; } 31 void RegenerateEnvp() { m_envp = GetEnvironment().getEnvp(); } 32 33 SBLaunchInfoImpl &operator=(const ProcessLaunchInfo &rhs) { 34 ProcessLaunchInfo::operator=(rhs); 35 RegenerateEnvp(); 36 return *this; 37 } 38 39private: 40 Environment::Envp m_envp; 41}; 42 43SBLaunchInfo::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 52SBLaunchInfo::SBLaunchInfo(const SBLaunchInfo &rhs) { 53 LLDB_INSTRUMENT_VA(this, rhs); 54 55 m_opaque_sp = rhs.m_opaque_sp; 56} 57 58SBLaunchInfo &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 65SBLaunchInfo::~SBLaunchInfo() = default; 66 67const lldb_private::ProcessLaunchInfo &SBLaunchInfo::ref() const { 68 return *m_opaque_sp; 69} 70 71void SBLaunchInfo::set_ref(const ProcessLaunchInfo &info) { 72 *m_opaque_sp = info; 73} 74 75lldb::pid_t SBLaunchInfo::GetProcessID() { 76 LLDB_INSTRUMENT_VA(this); 77 78 return m_opaque_sp->GetProcessID(); 79} 80 81uint32_t SBLaunchInfo::GetUserID() { 82 LLDB_INSTRUMENT_VA(this); 83 84 return m_opaque_sp->GetUserID(); 85} 86 87uint32_t SBLaunchInfo::GetGroupID() { 88 LLDB_INSTRUMENT_VA(this); 89 90 return m_opaque_sp->GetGroupID(); 91} 92 93bool SBLaunchInfo::UserIDIsValid() { 94 LLDB_INSTRUMENT_VA(this); 95 96 return m_opaque_sp->UserIDIsValid(); 97} 98 99bool SBLaunchInfo::GroupIDIsValid() { 100 LLDB_INSTRUMENT_VA(this); 101 102 return m_opaque_sp->GroupIDIsValid(); 103} 104 105void SBLaunchInfo::SetUserID(uint32_t uid) { 106 LLDB_INSTRUMENT_VA(this, uid); 107 108 m_opaque_sp->SetUserID(uid); 109} 110 111void SBLaunchInfo::SetGroupID(uint32_t gid) { 112 LLDB_INSTRUMENT_VA(this, gid); 113 114 m_opaque_sp->SetGroupID(gid); 115} 116 117SBFileSpec SBLaunchInfo::GetExecutableFile() { 118 LLDB_INSTRUMENT_VA(this); 119 120 return SBFileSpec(m_opaque_sp->GetExecutableFile()); 121} 122 123void 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 130SBListener SBLaunchInfo::GetListener() { 131 LLDB_INSTRUMENT_VA(this); 132 133 return SBListener(m_opaque_sp->GetListener()); 134} 135 136void SBLaunchInfo::SetListener(SBListener &listener) { 137 LLDB_INSTRUMENT_VA(this, listener); 138 139 m_opaque_sp->SetListener(listener.GetSP()); 140} 141 142uint32_t SBLaunchInfo::GetNumArguments() { 143 LLDB_INSTRUMENT_VA(this); 144 145 return m_opaque_sp->GetArguments().GetArgumentCount(); 146} 147 148const 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 155void 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 169uint32_t SBLaunchInfo::GetNumEnvironmentEntries() { 170 LLDB_INSTRUMENT_VA(this); 171 172 return m_opaque_sp->GetEnvironment().size(); 173} 174 175const 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 183void SBLaunchInfo::SetEnvironmentEntries(const char **envp, bool append) { 184 LLDB_INSTRUMENT_VA(this, envp, append); 185 SetEnvironment(SBEnvironment(Environment(envp)), append); 186} 187 188void 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 199SBEnvironment SBLaunchInfo::GetEnvironment() { 200 LLDB_INSTRUMENT_VA(this); 201 return SBEnvironment(Environment(m_opaque_sp->GetEnvironment())); 202} 203 204void SBLaunchInfo::Clear() { 205 LLDB_INSTRUMENT_VA(this); 206 207 m_opaque_sp->Clear(); 208} 209 210const char *SBLaunchInfo::GetWorkingDirectory() const { 211 LLDB_INSTRUMENT_VA(this); 212 213 return m_opaque_sp->GetWorkingDirectory().GetPathAsConstString().AsCString(); 214} 215 216void SBLaunchInfo::SetWorkingDirectory(const char *working_dir) { 217 LLDB_INSTRUMENT_VA(this, working_dir); 218 219 m_opaque_sp->SetWorkingDirectory(FileSpec(working_dir)); 220} 221 222uint32_t SBLaunchInfo::GetLaunchFlags() { 223 LLDB_INSTRUMENT_VA(this); 224 225 return m_opaque_sp->GetFlags().Get(); 226} 227 228void SBLaunchInfo::SetLaunchFlags(uint32_t flags) { 229 LLDB_INSTRUMENT_VA(this, flags); 230 231 m_opaque_sp->GetFlags().Reset(flags); 232} 233 234const char *SBLaunchInfo::GetProcessPluginName() { 235 LLDB_INSTRUMENT_VA(this); 236 237 return ConstString(m_opaque_sp->GetProcessPluginName()).GetCString(); 238} 239 240void SBLaunchInfo::SetProcessPluginName(const char *plugin_name) { 241 LLDB_INSTRUMENT_VA(this, plugin_name); 242 243 return m_opaque_sp->SetProcessPluginName(plugin_name); 244} 245 246const 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 255void SBLaunchInfo::SetShell(const char *path) { 256 LLDB_INSTRUMENT_VA(this, path); 257 258 m_opaque_sp->SetShell(FileSpec(path)); 259} 260 261bool SBLaunchInfo::GetShellExpandArguments() { 262 LLDB_INSTRUMENT_VA(this); 263 264 return m_opaque_sp->GetShellExpandArguments(); 265} 266 267void SBLaunchInfo::SetShellExpandArguments(bool expand) { 268 LLDB_INSTRUMENT_VA(this, expand); 269 270 m_opaque_sp->SetShellExpandArguments(expand); 271} 272 273uint32_t SBLaunchInfo::GetResumeCount() { 274 LLDB_INSTRUMENT_VA(this); 275 276 return m_opaque_sp->GetResumeCount(); 277} 278 279void SBLaunchInfo::SetResumeCount(uint32_t c) { 280 LLDB_INSTRUMENT_VA(this, c); 281 282 m_opaque_sp->SetResumeCount(c); 283} 284 285bool SBLaunchInfo::AddCloseFileAction(int fd) { 286 LLDB_INSTRUMENT_VA(this, fd); 287 288 return m_opaque_sp->AppendCloseFileAction(fd); 289} 290 291bool 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 297bool 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 304bool 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 310void SBLaunchInfo::SetLaunchEventData(const char *data) { 311 LLDB_INSTRUMENT_VA(this, data); 312 313 m_opaque_sp->SetLaunchEventData(data); 314} 315 316const char *SBLaunchInfo::GetLaunchEventData() const { 317 LLDB_INSTRUMENT_VA(this); 318 319 return ConstString(m_opaque_sp->GetLaunchEventData()).GetCString(); 320} 321 322void SBLaunchInfo::SetDetachOnError(bool enable) { 323 LLDB_INSTRUMENT_VA(this, enable); 324 325 m_opaque_sp->SetDetachOnError(enable); 326} 327 328bool SBLaunchInfo::GetDetachOnError() const { 329 LLDB_INSTRUMENT_VA(this); 330 331 return m_opaque_sp->GetDetachOnError(); 332} 333 334const 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 348void 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 357lldb::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 372void 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 393SBListener 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 402void 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