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