LLDB mainline
PlatformDarwin.cpp
Go to the documentation of this file.
1//===-- PlatformDarwin.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 "PlatformDarwin.h"
10
11#include <cstring>
12
13#include <algorithm>
14#include <memory>
15#include <mutex>
16#include <optional>
17
20#include "lldb/Core/Debugger.h"
21#include "lldb/Core/Module.h"
24#include "lldb/Core/Section.h"
25#include "lldb/Host/Host.h"
26#include "lldb/Host/HostInfo.h"
27#include "lldb/Host/XML.h"
37#include "lldb/Target/Process.h"
38#include "lldb/Target/Target.h"
40#include "lldb/Utility/Log.h"
42#include "lldb/Utility/Status.h"
43#include "lldb/Utility/Timer.h"
44#include "llvm/ADT/STLExtras.h"
45#include "llvm/Support/FileSystem.h"
46#include "llvm/Support/Threading.h"
47#include "llvm/Support/VersionTuple.h"
48
49#if defined(__APPLE__)
50#include <TargetConditionals.h>
51#endif
52
53using namespace lldb;
54using namespace lldb_private;
55
56static Status ExceptionMaskValidator(const char *string, void *unused) {
58 llvm::StringRef str_ref(string);
59 llvm::SmallVector<llvm::StringRef> candidates;
60 str_ref.split(candidates, '|');
61 for (auto candidate : candidates) {
62 if (!(candidate == "EXC_BAD_ACCESS"
63 || candidate == "EXC_BAD_INSTRUCTION"
64 || candidate == "EXC_ARITHMETIC"
65 || candidate == "EXC_RESOURCE"
66 || candidate == "EXC_GUARD")) {
67 error.SetErrorStringWithFormat("invalid exception type: '%s'",
68 candidate.str().c_str());
69 return error;
70 }
71 }
72 return {};
73}
74
75/// Destructor.
76///
77/// The destructor is virtual since this class is designed to be
78/// inherited from by the plug-in instance.
80
81// Static Variables
83
86
87 if (g_initialize_count++ == 0) {
92 }
93}
94
96 if (g_initialize_count > 0) {
97 if (--g_initialize_count == 0) {
99 }
100 }
101
103}
104
106 return "Darwin platform plug-in.";
107}
108
109PlatformSP PlatformDarwin::CreateInstance(bool force, const ArchSpec *arch) {
110 // We only create subclasses of the PlatformDarwin plugin.
111 return PlatformSP();
112}
113
114#define LLDB_PROPERTIES_platformdarwin
115#include "PlatformMacOSXProperties.inc"
116
117#define LLDB_PROPERTIES_platformdarwin
118enum {
119#include "PlatformMacOSXPropertiesEnum.inc"
120};
121
123public:
125 static ConstString g_setting_name("darwin");
126 return g_setting_name;
127 }
128
130 m_collection_sp = std::make_shared<OptionValueProperties>(GetSettingName());
131 m_collection_sp->Initialize(g_platformdarwin_properties);
132 }
133
134 ~PlatformDarwinProperties() override = default;
135
136 const char *GetIgnoredExceptions() const {
137 const uint32_t idx = ePropertyIgnoredExceptions;
138 const OptionValueString *option_value =
139 m_collection_sp->GetPropertyAtIndexAsOptionValueString(nullptr, false,
140 idx);
141 assert(option_value);
142 return option_value->GetCurrentValue();
143 }
144
146 const uint32_t idx = ePropertyIgnoredExceptions;
147 OptionValueString *option_value =
148 m_collection_sp->GetPropertyAtIndexAsOptionValueString(nullptr, false,
149 idx);
150 assert(option_value);
151 return option_value;
152 }
153};
154
156 static PlatformDarwinProperties g_settings;
157 return g_settings;
158}
159
161 lldb_private::Debugger &debugger) {
164 const bool is_global_setting = false;
166 debugger, GetGlobalProperties().GetValueProperties(),
167 ConstString("Properties for the Darwin platform plug-in."),
168 is_global_setting);
169 OptionValueString *value = GetGlobalProperties().GetIgnoredExceptionValue();
171 }
172}
173
174Args
176 std::string ignored_exceptions
177 = GetGlobalProperties().GetIgnoredExceptions();
178 if (ignored_exceptions.empty())
179 return {};
180 Args ret_args;
181 std::string packet = "QSetIgnoredExceptions:";
182 packet.append(ignored_exceptions);
183 ret_args.AppendArgument(packet);
184 return ret_args;
185}
186
189 const lldb_private::FileSpec &destination, uint32_t uid,
190 uint32_t gid) {
191 // Unconditionally unlink the destination. If it is an executable,
192 // simply opening it and truncating its contents would invalidate
193 // its cached code signature.
194 Unlink(destination);
195 return PlatformPOSIX::PutFile(source, destination, uid, gid);
196}
197
199 Target *target, Module &module, Stream *feedback_stream) {
200 FileSpecList file_list;
201 if (target &&
203 // NB some extensions might be meaningful and should not be stripped -
204 // "this.binary.file"
205 // should not lose ".file" but GetFileNameStrippingExtension() will do
206 // precisely that. Ideally, we should have a per-platform list of
207 // extensions (".exe", ".app", ".dSYM", ".framework") which should be
208 // stripped while leaving "this.binary.file" as-is.
209
210 FileSpec module_spec = module.GetFileSpec();
211
212 if (module_spec) {
213 if (SymbolFile *symfile = module.GetSymbolFile()) {
214 ObjectFile *objfile = symfile->GetObjectFile();
215 if (objfile) {
216 FileSpec symfile_spec(objfile->GetFileSpec());
217 if (symfile_spec &&
218 llvm::StringRef(symfile_spec.GetPath())
219 .contains_insensitive(".dSYM/Contents/Resources/DWARF") &&
220 FileSystem::Instance().Exists(symfile_spec)) {
221 while (module_spec.GetFilename()) {
222 std::string module_basename(
223 module_spec.GetFilename().GetCString());
224 std::string original_module_basename(module_basename);
225
226 bool was_keyword = false;
227
228 // FIXME: for Python, we cannot allow certain characters in
229 // module
230 // filenames we import. Theoretically, different scripting
231 // languages may have different sets of forbidden tokens in
232 // filenames, and that should be dealt with by each
233 // ScriptInterpreter. For now, we just replace dots with
234 // underscores, but if we ever support anything other than
235 // Python we will need to rework this
236 std::replace(module_basename.begin(), module_basename.end(), '.',
237 '_');
238 std::replace(module_basename.begin(), module_basename.end(), ' ',
239 '_');
240 std::replace(module_basename.begin(), module_basename.end(), '-',
241 '_');
242 ScriptInterpreter *script_interpreter =
244 if (script_interpreter &&
245 script_interpreter->IsReservedWord(module_basename.c_str())) {
246 module_basename.insert(module_basename.begin(), '_');
247 was_keyword = true;
248 }
249
250 StreamString path_string;
251 StreamString original_path_string;
252 // for OSX we are going to be in
253 // .dSYM/Contents/Resources/DWARF/<basename> let us go to
254 // .dSYM/Contents/Resources/Python/<basename>.py and see if the
255 // file exists
256 path_string.Printf("%s/../Python/%s.py",
257 symfile_spec.GetDirectory().GetCString(),
258 module_basename.c_str());
259 original_path_string.Printf(
260 "%s/../Python/%s.py",
261 symfile_spec.GetDirectory().GetCString(),
262 original_module_basename.c_str());
263 FileSpec script_fspec(path_string.GetString());
264 FileSystem::Instance().Resolve(script_fspec);
265 FileSpec orig_script_fspec(original_path_string.GetString());
266 FileSystem::Instance().Resolve(orig_script_fspec);
267
268 // if we did some replacements of reserved characters, and a
269 // file with the untampered name exists, then warn the user
270 // that the file as-is shall not be loaded
271 if (feedback_stream) {
272 if (module_basename != original_module_basename &&
273 FileSystem::Instance().Exists(orig_script_fspec)) {
274 const char *reason_for_complaint =
275 was_keyword ? "conflicts with a keyword"
276 : "contains reserved characters";
277 if (FileSystem::Instance().Exists(script_fspec))
278 feedback_stream->Printf(
279 "warning: the symbol file '%s' contains a debug "
280 "script. However, its name"
281 " '%s' %s and as such cannot be loaded. LLDB will"
282 " load '%s' instead. Consider removing the file with "
283 "the malformed name to"
284 " eliminate this warning.\n",
285 symfile_spec.GetPath().c_str(),
286 original_path_string.GetData(), reason_for_complaint,
287 path_string.GetData());
288 else
289 feedback_stream->Printf(
290 "warning: the symbol file '%s' contains a debug "
291 "script. However, its name"
292 " %s and as such cannot be loaded. If you intend"
293 " to have this script loaded, please rename '%s' to "
294 "'%s' and retry.\n",
295 symfile_spec.GetPath().c_str(), reason_for_complaint,
296 original_path_string.GetData(), path_string.GetData());
297 }
298 }
299
300 if (FileSystem::Instance().Exists(script_fspec)) {
301 file_list.Append(script_fspec);
302 break;
303 }
304
305 // If we didn't find the python file, then keep stripping the
306 // extensions and try again
307 ConstString filename_no_extension(
308 module_spec.GetFileNameStrippingExtension());
309 if (module_spec.GetFilename() == filename_no_extension)
310 break;
311
312 module_spec.SetFilename(filename_no_extension);
313 }
314 }
315 }
316 }
317 }
318 }
319 return file_list;
320}
321
323 const ModuleSpec &sym_spec,
324 FileSpec &sym_file) {
325 sym_file = sym_spec.GetSymbolFileSpec();
326 if (FileSystem::Instance().IsDirectory(sym_file)) {
327 sym_file = Symbols::FindSymbolFileInBundle(sym_file, sym_spec.GetUUIDPtr(),
328 sym_spec.GetArchitecturePtr());
329 }
330 return {};
331}
332
334 const ModuleSpec &module_spec, Process *process, ModuleSP &module_sp,
335 const FileSpecList *module_search_paths_ptr,
336 llvm::SmallVectorImpl<ModuleSP> *old_modules, bool *did_create_ptr) {
338 module_sp.reset();
339
340 if (IsRemote()) {
341 // If we have a remote platform always, let it try and locate the shared
342 // module first.
344 error = m_remote_platform_sp->GetSharedModule(
345 module_spec, process, module_sp, module_search_paths_ptr, old_modules,
346 did_create_ptr);
347 }
348 }
349
350 if (!module_sp) {
351 // Fall back to the local platform and find the file locally
352 error = Platform::GetSharedModule(module_spec, process, module_sp,
353 module_search_paths_ptr, old_modules,
354 did_create_ptr);
355
356 const FileSpec &platform_file = module_spec.GetFileSpec();
357 if (!module_sp && module_search_paths_ptr && platform_file) {
358 // We can try to pull off part of the file path up to the bundle
359 // directory level and try any module search paths...
360 FileSpec bundle_directory;
361 if (Host::GetBundleDirectory(platform_file, bundle_directory)) {
362 if (platform_file == bundle_directory) {
363 ModuleSpec new_module_spec(module_spec);
364 new_module_spec.GetFileSpec() = bundle_directory;
365 if (Host::ResolveExecutableInBundle(new_module_spec.GetFileSpec())) {
367 new_module_spec, process, module_sp, nullptr, old_modules,
368 did_create_ptr));
369
370 if (module_sp)
371 return new_error;
372 }
373 } else {
374 char platform_path[PATH_MAX];
375 char bundle_dir[PATH_MAX];
376 platform_file.GetPath(platform_path, sizeof(platform_path));
377 const size_t bundle_directory_len =
378 bundle_directory.GetPath(bundle_dir, sizeof(bundle_dir));
379 char new_path[PATH_MAX];
380 size_t num_module_search_paths = module_search_paths_ptr->GetSize();
381 for (size_t i = 0; i < num_module_search_paths; ++i) {
382 const size_t search_path_len =
383 module_search_paths_ptr->GetFileSpecAtIndex(i).GetPath(
384 new_path, sizeof(new_path));
385 if (search_path_len < sizeof(new_path)) {
386 snprintf(new_path + search_path_len,
387 sizeof(new_path) - search_path_len, "/%s",
388 platform_path + bundle_directory_len);
389 FileSpec new_file_spec(new_path);
390 if (FileSystem::Instance().Exists(new_file_spec)) {
391 ModuleSpec new_module_spec(module_spec);
392 new_module_spec.GetFileSpec() = new_file_spec;
394 new_module_spec, process, module_sp, nullptr, old_modules,
395 did_create_ptr));
396
397 if (module_sp) {
398 module_sp->SetPlatformFileSpec(new_file_spec);
399 return new_error;
400 }
401 }
402 }
403 }
404 }
405 }
406 }
407 }
408 if (module_sp)
409 module_sp->SetPlatformFileSpec(module_spec.GetFileSpec());
410 return error;
411}
412
413size_t
415 BreakpointSite *bp_site) {
416 const uint8_t *trap_opcode = nullptr;
417 uint32_t trap_opcode_size = 0;
418 bool bp_is_thumb = false;
419
420 llvm::Triple::ArchType machine = target.GetArchitecture().GetMachine();
421 switch (machine) {
422 case llvm::Triple::aarch64_32:
423 case llvm::Triple::aarch64: {
424 // 'brk #0' or 0xd4200000 in BE byte order
425 static const uint8_t g_arm64_breakpoint_opcode[] = {0x00, 0x00, 0x20, 0xD4};
426 trap_opcode = g_arm64_breakpoint_opcode;
427 trap_opcode_size = sizeof(g_arm64_breakpoint_opcode);
428 } break;
429
430 case llvm::Triple::thumb:
431 bp_is_thumb = true;
432 [[fallthrough]];
433 case llvm::Triple::arm: {
434 static const uint8_t g_arm_breakpoint_opcode[] = {0xFE, 0xDE, 0xFF, 0xE7};
435 static const uint8_t g_thumb_breakpooint_opcode[] = {0xFE, 0xDE};
436
437 // Auto detect arm/thumb if it wasn't explicitly specified
438 if (!bp_is_thumb) {
439 lldb::BreakpointLocationSP bp_loc_sp(bp_site->GetOwnerAtIndex(0));
440 if (bp_loc_sp)
441 bp_is_thumb = bp_loc_sp->GetAddress().GetAddressClass() ==
443 }
444 if (bp_is_thumb) {
445 trap_opcode = g_thumb_breakpooint_opcode;
446 trap_opcode_size = sizeof(g_thumb_breakpooint_opcode);
447 break;
448 }
449 trap_opcode = g_arm_breakpoint_opcode;
450 trap_opcode_size = sizeof(g_arm_breakpoint_opcode);
451 } break;
452
453 case llvm::Triple::ppc:
454 case llvm::Triple::ppc64: {
455 static const uint8_t g_ppc_breakpoint_opcode[] = {0x7F, 0xC0, 0x00, 0x08};
456 trap_opcode = g_ppc_breakpoint_opcode;
457 trap_opcode_size = sizeof(g_ppc_breakpoint_opcode);
458 } break;
459
460 default:
461 return Platform::GetSoftwareBreakpointTrapOpcode(target, bp_site);
462 }
463
464 if (trap_opcode && trap_opcode_size) {
465 if (bp_site->SetTrapOpcode(trap_opcode, trap_opcode_size))
466 return trap_opcode_size;
467 }
468 return 0;
469}
470
472 lldb_private::Target &target, const lldb::ModuleSP &module_sp) {
473 if (!module_sp)
474 return false;
475
476 ObjectFile *obj_file = module_sp->GetObjectFile();
477 if (!obj_file)
478 return false;
479
480 ObjectFile::Type obj_type = obj_file->GetType();
481 return obj_type == ObjectFile::eTypeDynamicLinker;
482}
483
485 std::vector<ArchSpec> &archs) {
486 ArchSpec host_arch = HostInfo::GetArchitecture(HostInfo::eArchKindDefault);
487 archs.push_back(host_arch);
488
489 if (host_arch.GetCore() == ArchSpec::eCore_x86_64_x86_64h) {
490 archs.push_back(ArchSpec("x86_64-apple-macosx"));
491 archs.push_back(HostInfo::GetArchitecture(HostInfo::eArchKind32));
492 } else {
493 ArchSpec host_arch64 = HostInfo::GetArchitecture(HostInfo::eArchKind64);
494 if (host_arch.IsExactMatch(host_arch64))
495 archs.push_back(HostInfo::GetArchitecture(HostInfo::eArchKind32));
496 }
497}
498
499static llvm::ArrayRef<const char *> GetCompatibleArchs(ArchSpec::Core core) {
500 switch (core) {
501 default:
502 [[fallthrough]];
504 static const char *g_arm64e_compatible_archs[] = {
505 "arm64e", "arm64", "armv7", "armv7f", "armv7k", "armv7s",
506 "armv7m", "armv7em", "armv6m", "armv6", "armv5", "armv4",
507 "arm", "thumbv7", "thumbv7f", "thumbv7k", "thumbv7s", "thumbv7m",
508 "thumbv7em", "thumbv6m", "thumbv6", "thumbv5", "thumbv4t", "thumb",
509 };
510 return {g_arm64e_compatible_archs};
511 }
513 static const char *g_arm64_compatible_archs[] = {
514 "arm64", "armv7", "armv7f", "armv7k", "armv7s", "armv7m",
515 "armv7em", "armv6m", "armv6", "armv5", "armv4", "arm",
516 "thumbv7", "thumbv7f", "thumbv7k", "thumbv7s", "thumbv7m", "thumbv7em",
517 "thumbv6m", "thumbv6", "thumbv5", "thumbv4t", "thumb",
518 };
519 return {g_arm64_compatible_archs};
520 }
522 static const char *g_armv7_compatible_archs[] = {
523 "armv7", "armv6m", "armv6", "armv5", "armv4", "arm",
524 "thumbv7", "thumbv6m", "thumbv6", "thumbv5", "thumbv4t", "thumb",
525 };
526 return {g_armv7_compatible_archs};
527 }
529 static const char *g_armv7f_compatible_archs[] = {
530 "armv7f", "armv7", "armv6m", "armv6", "armv5",
531 "armv4", "arm", "thumbv7f", "thumbv7", "thumbv6m",
532 "thumbv6", "thumbv5", "thumbv4t", "thumb",
533 };
534 return {g_armv7f_compatible_archs};
535 }
537 static const char *g_armv7k_compatible_archs[] = {
538 "armv7k", "armv7", "armv6m", "armv6", "armv5",
539 "armv4", "arm", "thumbv7k", "thumbv7", "thumbv6m",
540 "thumbv6", "thumbv5", "thumbv4t", "thumb",
541 };
542 return {g_armv7k_compatible_archs};
543 }
545 static const char *g_armv7s_compatible_archs[] = {
546 "armv7s", "armv7", "armv6m", "armv6", "armv5",
547 "armv4", "arm", "thumbv7s", "thumbv7", "thumbv6m",
548 "thumbv6", "thumbv5", "thumbv4t", "thumb",
549 };
550 return {g_armv7s_compatible_archs};
551 }
553 static const char *g_armv7m_compatible_archs[] = {
554 "armv7m", "armv7", "armv6m", "armv6", "armv5",
555 "armv4", "arm", "thumbv7m", "thumbv7", "thumbv6m",
556 "thumbv6", "thumbv5", "thumbv4t", "thumb",
557 };
558 return {g_armv7m_compatible_archs};
559 }
561 static const char *g_armv7em_compatible_archs[] = {
562 "armv7em", "armv7", "armv6m", "armv6", "armv5",
563 "armv4", "arm", "thumbv7em", "thumbv7", "thumbv6m",
564 "thumbv6", "thumbv5", "thumbv4t", "thumb",
565 };
566 return {g_armv7em_compatible_archs};
567 }
569 static const char *g_armv6m_compatible_archs[] = {
570 "armv6m", "armv6", "armv5", "armv4", "arm",
571 "thumbv6m", "thumbv6", "thumbv5", "thumbv4t", "thumb",
572 };
573 return {g_armv6m_compatible_archs};
574 }
576 static const char *g_armv6_compatible_archs[] = {
577 "armv6", "armv5", "armv4", "arm",
578 "thumbv6", "thumbv5", "thumbv4t", "thumb",
579 };
580 return {g_armv6_compatible_archs};
581 }
583 static const char *g_armv5_compatible_archs[] = {
584 "armv5", "armv4", "arm", "thumbv5", "thumbv4t", "thumb",
585 };
586 return {g_armv5_compatible_archs};
587 }
589 static const char *g_armv4_compatible_archs[] = {
590 "armv4",
591 "arm",
592 "thumbv4t",
593 "thumb",
594 };
595 return {g_armv4_compatible_archs};
596 }
597 }
598 return {};
599}
600
601/// The architecture selection rules for arm processors These cpu subtypes have
602/// distinct names (e.g. armv7f) but armv7 binaries run fine on an armv7f
603/// processor.
605 std::vector<ArchSpec> &archs, std::optional<llvm::Triple::OSType> os) {
606 const ArchSpec system_arch = GetSystemArchitecture();
607 const ArchSpec::Core system_core = system_arch.GetCore();
608 for (const char *arch : GetCompatibleArchs(system_core)) {
609 llvm::Triple triple;
610 triple.setArchName(arch);
611 triple.setVendor(llvm::Triple::VendorType::Apple);
612 if (os)
613 triple.setOS(*os);
614 archs.push_back(ArchSpec(triple));
615 }
616}
617
619 static FileSpec g_xcode_select_filespec;
620
621 if (!g_xcode_select_filespec) {
622 FileSpec xcode_select_cmd("/usr/bin/xcode-select");
623 if (FileSystem::Instance().Exists(xcode_select_cmd)) {
624 int exit_status = -1;
625 int signo = -1;
626 std::string command_output;
627 Status status =
628 Host::RunShellCommand("/usr/bin/xcode-select --print-path",
629 FileSpec(), // current working directory
630 &exit_status, &signo, &command_output,
631 std::chrono::seconds(2), // short timeout
632 false); // don't run in a shell
633 if (status.Success() && exit_status == 0 && !command_output.empty()) {
634 size_t first_non_newline = command_output.find_last_not_of("\r\n");
635 if (first_non_newline != std::string::npos) {
636 command_output.erase(first_non_newline + 1);
637 }
638 g_xcode_select_filespec = FileSpec(command_output);
639 }
640 }
641 }
642
643 return g_xcode_select_filespec;
644}
645
647 BreakpointSP bp_sp;
648 static const char *g_bp_names[] = {
649 "start_wqthread", "_pthread_wqthread", "_pthread_start",
650 };
651
652 static const char *g_bp_modules[] = {"libsystem_c.dylib",
653 "libSystem.B.dylib"};
654
655 FileSpecList bp_modules;
656 for (size_t i = 0; i < std::size(g_bp_modules); i++) {
657 const char *bp_module = g_bp_modules[i];
658 bp_modules.EmplaceBack(bp_module);
659 }
660
661 bool internal = true;
662 bool hardware = false;
663 LazyBool skip_prologue = eLazyBoolNo;
664 bp_sp = target.CreateBreakpoint(&bp_modules, nullptr, g_bp_names,
665 std::size(g_bp_names), eFunctionNameTypeFull,
666 eLanguageTypeUnknown, 0, skip_prologue,
667 internal, hardware);
668 bp_sp->SetBreakpointKind("thread-creation");
669
670 return bp_sp;
671}
672
675 const FileSpec &shell = launch_info.GetShell();
676 if (!shell)
677 return 1;
678
679 std::string shell_string = shell.GetPath();
680 const char *shell_name = strrchr(shell_string.c_str(), '/');
681 if (shell_name == nullptr)
682 shell_name = shell_string.c_str();
683 else
684 shell_name++;
685
686 if (strcmp(shell_name, "sh") == 0) {
687 // /bin/sh re-exec's itself as /bin/bash requiring another resume. But it
688 // only does this if the COMMAND_MODE environment variable is set to
689 // "legacy".
690 if (launch_info.GetEnvironment().lookup("COMMAND_MODE") == "legacy")
691 return 2;
692 return 1;
693 } else if (strcmp(shell_name, "csh") == 0 ||
694 strcmp(shell_name, "tcsh") == 0 ||
695 strcmp(shell_name, "zsh") == 0) {
696 // csh and tcsh always seem to re-exec themselves.
697 return 2;
698 } else
699 return 1;
700}
701
703 Debugger &debugger, Target &target,
704 Status &error) {
705 ProcessSP process_sp;
706
707 if (IsHost()) {
708 // We are going to hand this process off to debugserver which will be in
709 // charge of setting the exit status. However, we still need to reap it
710 // from lldb. So, make sure we use a exit callback which does not set exit
711 // status.
712 launch_info.SetMonitorProcessCallback(
714 process_sp = Platform::DebugProcess(launch_info, debugger, target, error);
715 } else {
717 process_sp = m_remote_platform_sp->DebugProcess(launch_info, debugger,
718 target, error);
719 else
720 error.SetErrorString("the platform is not currently connected");
721 }
722 return process_sp;
723}
724
726 m_trap_handlers.push_back(ConstString("_sigtramp"));
727}
728
730 static FileSpec g_command_line_tools_filespec;
731
732 if (!g_command_line_tools_filespec) {
733 FileSpec command_line_tools_path(GetXcodeSelectPath());
734 command_line_tools_path.AppendPathComponent("Library");
735 if (FileSystem::Instance().Exists(command_line_tools_path)) {
736 g_command_line_tools_filespec = command_line_tools_path;
737 }
738 }
739
740 return g_command_line_tools_filespec;
741}
742
744 void *baton, llvm::sys::fs::file_type file_type, llvm::StringRef path) {
745 SDKEnumeratorInfo *enumerator_info = static_cast<SDKEnumeratorInfo *>(baton);
746
747 FileSpec spec(path);
748 if (XcodeSDK::SDKSupportsModules(enumerator_info->sdk_type, spec)) {
749 enumerator_info->found_path = spec;
751 }
752
754}
755
757 const FileSpec &sdks_spec) {
758 // Look inside Xcode for the required installed iOS SDK version
759
760 if (!FileSystem::Instance().IsDirectory(sdks_spec)) {
761 return FileSpec();
762 }
763
764 const bool find_directories = true;
765 const bool find_files = false;
766 const bool find_other = true; // include symlinks
767
768 SDKEnumeratorInfo enumerator_info;
769
770 enumerator_info.sdk_type = sdk_type;
771
773 sdks_spec.GetPath(), find_directories, find_files, find_other,
774 DirectoryEnumerator, &enumerator_info);
775
776 if (FileSystem::Instance().IsDirectory(enumerator_info.found_path))
777 return enumerator_info.found_path;
778 else
779 return FileSpec();
780}
781
783 FileSpec sdks_spec = HostInfo::GetXcodeContentsDirectory();
784 sdks_spec.AppendPathComponent("Developer");
785 sdks_spec.AppendPathComponent("Platforms");
786
787 switch (sdk_type) {
789 sdks_spec.AppendPathComponent("MacOSX.platform");
790 break;
792 sdks_spec.AppendPathComponent("iPhoneSimulator.platform");
793 break;
795 sdks_spec.AppendPathComponent("iPhoneOS.platform");
796 break;
798 sdks_spec.AppendPathComponent("WatchSimulator.platform");
799 break;
801 sdks_spec.AppendPathComponent("AppleTVSimulator.platform");
802 break;
803 default:
804 llvm_unreachable("unsupported sdk");
805 }
806
807 sdks_spec.AppendPathComponent("Developer");
808 sdks_spec.AppendPathComponent("SDKs");
809
810 if (sdk_type == XcodeSDK::Type::MacOSX) {
811 llvm::VersionTuple version = HostInfo::GetOSVersion();
812
813 if (!version.empty()) {
815 // If the Xcode SDKs are not available then try to use the
816 // Command Line Tools one which is only for MacOSX.
817 if (!FileSystem::Instance().Exists(sdks_spec)) {
818 sdks_spec = GetCommandLineToolsLibraryPath();
819 sdks_spec.AppendPathComponent("SDKs");
820 }
821
822 // We slightly prefer the exact SDK for this machine. See if it is
823 // there.
824
825 FileSpec native_sdk_spec = sdks_spec;
826 StreamString native_sdk_name;
827 native_sdk_name.Printf("MacOSX%u.%u.sdk", version.getMajor(),
828 version.getMinor().value_or(0));
829 native_sdk_spec.AppendPathComponent(native_sdk_name.GetString());
830
831 if (FileSystem::Instance().Exists(native_sdk_spec)) {
832 return native_sdk_spec;
833 }
834 }
835 }
836 }
837
838 return FindSDKInXcodeForModules(sdk_type, sdks_spec);
839}
840
841std::tuple<llvm::VersionTuple, llvm::StringRef>
843 llvm::StringRef build;
844 llvm::StringRef version_str;
845 llvm::StringRef build_str;
846 std::tie(version_str, build_str) = dir.split(' ');
847 llvm::VersionTuple version;
848 if (!version.tryParse(version_str) ||
849 build_str.empty()) {
850 if (build_str.consume_front("(")) {
851 size_t pos = build_str.find(')');
852 build = build_str.slice(0, pos);
853 }
854 }
855
856 return std::make_tuple(version, build);
857}
858
859llvm::Expected<StructuredData::DictionarySP>
861 StructuredData::DictionarySP extended_crash_info =
862 std::make_shared<StructuredData::Dictionary>();
863
865 if (annotations && annotations->GetSize())
866 extended_crash_info->AddItem("Crash-Info Annotations", annotations);
867
868 StructuredData::DictionarySP app_specific_info =
869 ExtractAppSpecificInfo(process);
870 if (app_specific_info && app_specific_info->GetSize())
871 extended_crash_info->AddItem("Application Specific Information",
872 app_specific_info);
873
874 return extended_crash_info->GetSize() ? extended_crash_info : nullptr;
875}
876
880
881 ConstString section_name("__crash_info");
882 Target &target = process.GetTarget();
883 StructuredData::ArraySP array_sp = std::make_shared<StructuredData::Array>();
884
885 for (ModuleSP module : target.GetImages().Modules()) {
886 SectionList *sections = module->GetSectionList();
887
888 std::string module_name = module->GetSpecificationDescription();
889
890 // The DYDL module is skipped since it's always loaded when running the
891 // binary.
892 if (module_name == "/usr/lib/dyld")
893 continue;
894
895 if (!sections) {
896 LLDB_LOG(log, "Module {0} doesn't have any section!", module_name);
897 continue;
898 }
899
900 SectionSP crash_info = sections->FindSectionByName(section_name);
901 if (!crash_info) {
902 LLDB_LOG(log, "Module {0} doesn't have section {1}!", module_name,
903 section_name);
904 continue;
905 }
906
907 addr_t load_addr = crash_info->GetLoadBaseAddress(&target);
908
909 if (load_addr == LLDB_INVALID_ADDRESS) {
910 LLDB_LOG(log, "Module {0} has an invalid '{1}' section load address: {2}",
911 module_name, section_name, load_addr);
912 continue;
913 }
914
916 CrashInfoAnnotations annotations;
917 size_t expected_size = sizeof(CrashInfoAnnotations);
918 size_t bytes_read = process.ReadMemoryFromInferior(load_addr, &annotations,
919 expected_size, error);
920
921 if (expected_size != bytes_read || error.Fail()) {
922 LLDB_LOG(log, "Failed to read {0} section from memory in module {1}: {2}",
923 section_name, module_name, error);
924 continue;
925 }
926
927 // initial support added for version 5
928 if (annotations.version < 5) {
929 LLDB_LOG(log,
930 "Annotation version lower than 5 unsupported! Module {0} has "
931 "version {1} instead.",
932 module_name, annotations.version);
933 continue;
934 }
935
936 if (!annotations.message) {
937 LLDB_LOG(log, "No message available for module {0}.", module_name);
938 continue;
939 }
940
941 std::string message;
942 bytes_read =
943 process.ReadCStringFromMemory(annotations.message, message, error);
944
945 if (message.empty() || bytes_read != message.size() || error.Fail()) {
946 LLDB_LOG(log, "Failed to read the message from memory in module {0}: {1}",
947 module_name, error);
948 continue;
949 }
950
951 // Remove trailing newline from message
952 if (message.back() == '\n')
953 message.pop_back();
954
955 if (!annotations.message2)
956 LLDB_LOG(log, "No message2 available for module {0}.", module_name);
957
958 std::string message2;
959 bytes_read =
960 process.ReadCStringFromMemory(annotations.message2, message2, error);
961
962 if (!message2.empty() && bytes_read == message2.size() && error.Success())
963 if (message2.back() == '\n')
964 message2.pop_back();
965
967 std::make_shared<StructuredData::Dictionary>();
968
969 entry_sp->AddStringItem("image", module->GetFileSpec().GetPath(false));
970 entry_sp->AddStringItem("uuid", module->GetUUID().GetAsString());
971 entry_sp->AddStringItem("message", message);
972 entry_sp->AddStringItem("message2", message2);
973 entry_sp->AddIntegerItem("abort-cause", annotations.abort_cause);
974
975 array_sp->AddItem(entry_sp);
976 }
977
978 return array_sp;
979}
980
983 StructuredData::DictionarySP metadata_sp = process.GetMetadata();
984
985 if (!metadata_sp || !metadata_sp->GetSize() || !metadata_sp->HasKey("asi"))
986 return {};
987
989 if (!metadata_sp->GetValueForKeyAsDictionary("asi", asi))
990 return {};
991
993 std::make_shared<StructuredData::Dictionary>();
994
995 auto flatten_asi_dict = [&dict_sp](ConstString key,
996 StructuredData::Object *val) -> bool {
997 if (!val)
998 return false;
999
1000 StructuredData::Array *arr = val->GetAsArray();
1001 if (!arr || !arr->GetSize())
1002 return false;
1003
1004 dict_sp->AddItem(key.AsCString(), arr->GetItemAtIndex(0));
1005 return true;
1006 };
1007
1008 asi->ForEach(flatten_asi_dict);
1009
1010 return dict_sp;
1011}
1012
1014 Target *target, std::vector<std::string> &options, XcodeSDK::Type sdk_type) {
1015 const std::vector<std::string> apple_arguments = {
1016 "-x", "objective-c++", "-fobjc-arc",
1017 "-fblocks", "-D_ISO646_H", "-D__ISO646_H",
1018 "-fgnuc-version=4.2.1"};
1019
1020 options.insert(options.end(), apple_arguments.begin(), apple_arguments.end());
1021
1022 StreamString minimum_version_option;
1023 bool use_current_os_version = false;
1024 // If the SDK type is for the host OS, use its version number.
1025 auto get_host_os = []() { return HostInfo::GetTargetTriple().getOS(); };
1026 switch (sdk_type) {
1028 use_current_os_version = get_host_os() == llvm::Triple::MacOSX;
1029 break;
1031 use_current_os_version = get_host_os() == llvm::Triple::IOS;
1032 break;
1034 use_current_os_version = get_host_os() == llvm::Triple::TvOS;
1035 break;
1037 use_current_os_version = get_host_os() == llvm::Triple::WatchOS;
1038 break;
1039 default:
1040 break;
1041 }
1042
1043 llvm::VersionTuple version;
1044 if (use_current_os_version)
1045 version = GetOSVersion();
1046 else if (target) {
1047 // Our OS doesn't match our executable so we need to get the min OS version
1048 // from the object file
1049 ModuleSP exe_module_sp = target->GetExecutableModule();
1050 if (exe_module_sp) {
1051 ObjectFile *object_file = exe_module_sp->GetObjectFile();
1052 if (object_file)
1053 version = object_file->GetMinimumOSVersion();
1054 }
1055 }
1056 // Only add the version-min options if we got a version from somewhere
1057 if (!version.empty() && sdk_type != XcodeSDK::Type::Linux) {
1058#define OPTION(PREFIX, NAME, VAR, ...) \
1059 llvm::StringRef opt_##VAR = NAME; \
1060 (void)opt_##VAR;
1061#include "clang/Driver/Options.inc"
1062#undef OPTION
1063 minimum_version_option << '-';
1064 switch (sdk_type) {
1066 minimum_version_option << opt_mmacos_version_min_EQ;
1067 break;
1069 minimum_version_option << opt_mios_simulator_version_min_EQ;
1070 break;
1072 minimum_version_option << opt_mios_version_min_EQ;
1073 break;
1075 minimum_version_option << opt_mtvos_simulator_version_min_EQ;
1076 break;
1078 minimum_version_option << opt_mtvos_version_min_EQ;
1079 break;
1081 minimum_version_option << opt_mwatchos_simulator_version_min_EQ;
1082 break;
1084 minimum_version_option << opt_mwatchos_version_min_EQ;
1085 break;
1089 if (Log *log = GetLog(LLDBLog::Host)) {
1090 XcodeSDK::Info info;
1091 info.type = sdk_type;
1092 LLDB_LOGF(log, "Clang modules on %s are not supported",
1093 XcodeSDK::GetCanonicalName(info).c_str());
1094 }
1095 return;
1096 }
1097 minimum_version_option << version.getAsString();
1098 options.emplace_back(std::string(minimum_version_option.GetString()));
1099 }
1100
1101 FileSpec sysroot_spec;
1102 // Scope for mutex locker below
1103 {
1104 std::lock_guard<std::mutex> guard(m_mutex);
1105 sysroot_spec = GetSDKDirectoryForModules(sdk_type);
1106 }
1107
1108 if (FileSystem::Instance().IsDirectory(sysroot_spec.GetPath())) {
1109 options.push_back("-isysroot");
1110 options.push_back(sysroot_spec.GetPath());
1111 }
1112}
1113
1115 if (basename.IsEmpty())
1116 return basename;
1117
1118 StreamString stream;
1119 stream.Printf("lib%s.dylib", basename.GetCString());
1120 return ConstString(stream.GetString());
1121}
1122
1123llvm::VersionTuple PlatformDarwin::GetOSVersion(Process *process) {
1124 if (process && GetPluginName().contains("-simulator")) {
1126 if (Host::GetProcessInfo(process->GetID(), proc_info)) {
1127 const Environment &env = proc_info.GetEnvironment();
1128
1129 llvm::VersionTuple result;
1130 if (!result.tryParse(env.lookup("SIMULATOR_RUNTIME_VERSION")))
1131 return result;
1132
1133 std::string dyld_root_path = env.lookup("DYLD_ROOT_PATH");
1134 if (!dyld_root_path.empty()) {
1135 dyld_root_path += "/System/Library/CoreServices/SystemVersion.plist";
1136 ApplePropertyList system_version_plist(dyld_root_path.c_str());
1137 std::string product_version;
1138 if (system_version_plist.GetValueAsString("ProductVersion",
1139 product_version)) {
1140 if (!result.tryParse(product_version))
1141 return result;
1142 }
1143 }
1144 }
1145 // For simulator platforms, do NOT call back through
1146 // Platform::GetOSVersion() as it might call Process::GetHostOSVersion()
1147 // which we don't want as it will be incorrect
1148 return llvm::VersionTuple();
1149 }
1150
1151 return Platform::GetOSVersion(process);
1152}
1153
1155 // A collection of SBFileSpec whose SBFileSpec.m_directory members are filled
1156 // in with any executable directories that should be searched.
1157 static std::vector<FileSpec> g_executable_dirs;
1158
1159 // Find the global list of directories that we will search for executables
1160 // once so we don't keep doing the work over and over.
1161 static llvm::once_flag g_once_flag;
1162 llvm::call_once(g_once_flag, []() {
1163
1164 // When locating executables, trust the DEVELOPER_DIR first if it is set
1165 FileSpec xcode_contents_dir = HostInfo::GetXcodeContentsDirectory();
1166 if (xcode_contents_dir) {
1167 FileSpec xcode_lldb_resources = xcode_contents_dir;
1168 xcode_lldb_resources.AppendPathComponent("SharedFrameworks");
1169 xcode_lldb_resources.AppendPathComponent("LLDB.framework");
1170 xcode_lldb_resources.AppendPathComponent("Resources");
1171 if (FileSystem::Instance().Exists(xcode_lldb_resources)) {
1172 FileSpec dir;
1173 dir.SetDirectory(xcode_lldb_resources.GetPathAsConstString());
1174 g_executable_dirs.push_back(dir);
1175 }
1176 }
1177 // Xcode might not be installed so we also check for the Command Line Tools.
1178 FileSpec command_line_tools_dir = GetCommandLineToolsLibraryPath();
1179 if (command_line_tools_dir) {
1180 FileSpec cmd_line_lldb_resources = command_line_tools_dir;
1181 cmd_line_lldb_resources.AppendPathComponent("PrivateFrameworks");
1182 cmd_line_lldb_resources.AppendPathComponent("LLDB.framework");
1183 cmd_line_lldb_resources.AppendPathComponent("Resources");
1184 if (FileSystem::Instance().Exists(cmd_line_lldb_resources)) {
1185 FileSpec dir;
1186 dir.SetDirectory(cmd_line_lldb_resources.GetPathAsConstString());
1187 g_executable_dirs.push_back(dir);
1188 }
1189 }
1190 });
1191
1192 // Now search the global list of executable directories for the executable we
1193 // are looking for
1194 for (const auto &executable_dir : g_executable_dirs) {
1195 FileSpec executable_file;
1196 executable_file.SetDirectory(executable_dir.GetDirectory());
1197 executable_file.SetFilename(basename);
1198 if (FileSystem::Instance().Exists(executable_file))
1199 return executable_file;
1200 }
1201
1202 return FileSpec();
1203}
1204
1207 // Starting in Fall 2016 OSes, NSLog messages only get mirrored to stderr if
1208 // the OS_ACTIVITY_DT_MODE environment variable is set. (It doesn't require
1209 // any specific value; rather, it just needs to exist). We will set it here
1210 // as long as the IDE_DISABLED_OS_ACTIVITY_DT_MODE flag is not set. Xcode
1211 // makes use of IDE_DISABLED_OS_ACTIVITY_DT_MODE to tell
1212 // LLDB *not* to muck with the OS_ACTIVITY_DT_MODE flag when they
1213 // specifically want it unset.
1214 const char *disable_env_var = "IDE_DISABLED_OS_ACTIVITY_DT_MODE";
1215 auto &env_vars = launch_info.GetEnvironment();
1216 if (!env_vars.count(disable_env_var)) {
1217 // We want to make sure that OS_ACTIVITY_DT_MODE is set so that we get
1218 // os_log and NSLog messages mirrored to the target process stderr.
1219 env_vars.try_emplace("OS_ACTIVITY_DT_MODE", "enable");
1220 }
1221
1222 // Let our parent class do the real launching.
1223 return PlatformPOSIX::LaunchProcess(launch_info);
1224}
1225
1227 const ModuleSpec &module_spec, Process *process, ModuleSP &module_sp,
1228 const FileSpecList *module_search_paths_ptr,
1229 llvm::SmallVectorImpl<ModuleSP> *old_modules, bool *did_create_ptr) {
1230 const FileSpec &platform_file = module_spec.GetFileSpec();
1231 // See if the file is present in any of the module_search_paths_ptr
1232 // directories.
1233 if (!module_sp && module_search_paths_ptr && platform_file) {
1234 // create a vector of all the file / directory names in platform_file e.g.
1235 // this might be
1236 // /System/Library/PrivateFrameworks/UIFoundation.framework/UIFoundation
1237 //
1238 // We'll need to look in the module_search_paths_ptr directories for both
1239 // "UIFoundation" and "UIFoundation.framework" -- most likely the latter
1240 // will be the one we find there.
1241
1242 FileSpec platform_pull_upart(platform_file);
1243 std::vector<std::string> path_parts;
1244 path_parts.push_back(
1245 platform_pull_upart.GetLastPathComponent().AsCString());
1246 while (platform_pull_upart.RemoveLastPathComponent()) {
1247 ConstString part = platform_pull_upart.GetLastPathComponent();
1248 path_parts.push_back(part.AsCString());
1249 }
1250 const size_t path_parts_size = path_parts.size();
1251
1252 size_t num_module_search_paths = module_search_paths_ptr->GetSize();
1253 for (size_t i = 0; i < num_module_search_paths; ++i) {
1254 Log *log_verbose = GetLog(LLDBLog::Host);
1255 LLDB_LOGF(
1256 log_verbose,
1257 "PlatformRemoteDarwinDevice::GetSharedModule searching for binary in "
1258 "search-path %s",
1259 module_search_paths_ptr->GetFileSpecAtIndex(i).GetPath().c_str());
1260 // Create a new FileSpec with this module_search_paths_ptr plus just the
1261 // filename ("UIFoundation"), then the parent dir plus filename
1262 // ("UIFoundation.framework/UIFoundation") etc - up to four names (to
1263 // handle "Foo.framework/Contents/MacOS/Foo")
1264
1265 for (size_t j = 0; j < 4 && j < path_parts_size - 1; ++j) {
1266 FileSpec path_to_try(module_search_paths_ptr->GetFileSpecAtIndex(i));
1267
1268 // Add the components backwards. For
1269 // .../PrivateFrameworks/UIFoundation.framework/UIFoundation path_parts
1270 // is
1271 // [0] UIFoundation
1272 // [1] UIFoundation.framework
1273 // [2] PrivateFrameworks
1274 //
1275 // and if 'j' is 2, we want to append path_parts[1] and then
1276 // path_parts[0], aka 'UIFoundation.framework/UIFoundation', to the
1277 // module_search_paths_ptr path.
1278
1279 for (int k = j; k >= 0; --k) {
1280 path_to_try.AppendPathComponent(path_parts[k]);
1281 }
1282
1283 if (FileSystem::Instance().Exists(path_to_try)) {
1284 ModuleSpec new_module_spec(module_spec);
1285 new_module_spec.GetFileSpec() = path_to_try;
1286 Status new_error(
1287 Platform::GetSharedModule(new_module_spec, process, module_sp,
1288 nullptr, old_modules, did_create_ptr));
1289
1290 if (module_sp) {
1291 module_sp->SetPlatformFileSpec(path_to_try);
1292 return new_error;
1293 }
1294 }
1295 }
1296 }
1297 }
1298 return Status();
1299}
1300
1301std::string PlatformDarwin::FindComponentInPath(llvm::StringRef path,
1302 llvm::StringRef component) {
1303 auto begin = llvm::sys::path::begin(path);
1304 auto end = llvm::sys::path::end(path);
1305 for (auto it = begin; it != end; ++it) {
1306 if (it->contains(component)) {
1307 llvm::SmallString<128> buffer;
1308 llvm::sys::path::append(buffer, begin, ++it,
1309 llvm::sys::path::Style::posix);
1310 return buffer.str().str();
1311 }
1312 }
1313 return {};
1314}
1315
1317 if (FileSpec fspec = HostInfo::GetShlibDir())
1318 return FileSpec(FindComponentInPath(fspec.GetPath(), ".xctoolchain"));
1319 return {};
1320}
1321
1323 if (FileSpec fspec = HostInfo::GetShlibDir())
1324 return FileSpec(FindComponentInPath(fspec.GetPath(), "CommandLineTools"));
1325 return {};
1326}
1327
1328llvm::Triple::OSType PlatformDarwin::GetHostOSType() {
1329#if !defined(__APPLE__)
1330 return llvm::Triple::MacOSX;
1331#else
1332#if TARGET_OS_OSX
1333 return llvm::Triple::MacOSX;
1334#elif TARGET_OS_IOS
1335 return llvm::Triple::IOS;
1336#elif TARGET_OS_WATCH
1337 return llvm::Triple::WatchOS;
1338#elif TARGET_OS_TV
1339 return llvm::Triple::TvOS;
1340#elif TARGET_OS_BRIDGE
1341 return llvm::Triple::BridgeOS;
1342#else
1343#error "LLDB being compiled for an unrecognized Darwin OS"
1344#endif
1345#endif // __APPLE__
1346}
static llvm::raw_ostream & error(Stream &strm)
static DynamicLoaderDarwinKernelProperties & GetGlobalProperties()
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
Definition: Log.h:337
#define LLDB_LOGF(log,...)
Definition: Log.h:344
static uint32_t g_initialize_count
static Status ExceptionMaskValidator(const char *string, void *unused)
static uint32_t g_initialize_count
static llvm::ArrayRef< const char * > GetCompatibleArchs(ArchSpec::Core core)
static FileSpec GetXcodeSelectPath()
static FileSpec GetCommandLineToolsLibraryPath()
static ConstString & GetSettingName()
OptionValueString * GetIgnoredExceptionValue()
const char * GetIgnoredExceptions() const
~PlatformDarwinProperties() override=default
lldb_private::Status PutFile(const lldb_private::FileSpec &source, const lldb_private::FileSpec &destination, uint32_t uid=UINT32_MAX, uint32_t gid=UINT32_MAX) override
bool GetValueAsString(const char *key, std::string &value) const
Definition: XML.cpp:402
An architecture specification class.
Definition: ArchSpec.h:32
bool IsExactMatch(const ArchSpec &rhs) const
Shorthand for IsMatch(rhs, ExactMatch).
Definition: ArchSpec.h:510
llvm::Triple::ArchType GetMachine() const
Returns a machine family for the current architecture.
Definition: ArchSpec.cpp:678
Core GetCore() const
Definition: ArchSpec.h:442
A command line argument class.
Definition: Args.h:33
void AppendArgument(llvm::StringRef arg_str, char quote_char='\0')
Appends a new argument to the end of the list argument list.
Definition: Args.cpp:323
Class that manages the actual breakpoint that will be inserted into the running program.
bool SetTrapOpcode(const uint8_t *trap_opcode, uint32_t trap_opcode_size)
Sets the trap opcode.
lldb::BreakpointLocationSP GetOwnerAtIndex(size_t idx)
This method returns the breakpoint location at index index located at this breakpoint site.
A uniqued constant string class.
Definition: ConstString.h:39
const char * AsCString(const char *value_if_empty=nullptr) const
Get the string value as a C string.
Definition: ConstString.h:192
bool IsEmpty() const
Test for empty string.
Definition: ConstString.h:303
const char * GetCString() const
Get the string value as a C string.
Definition: ConstString.h:215
A class to manage flag bits.
Definition: Debugger.h:78
lldb::ScriptLanguage GetScriptLanguage() const
Definition: Debugger.cpp:324
ScriptInterpreter * GetScriptInterpreter(bool can_create=true, std::optional< lldb::ScriptLanguage > language={})
Definition: Debugger.cpp:1560
A file utility class.
Definition: FileSpec.h:56
void AppendPathComponent(llvm::StringRef component)
Definition: FileSpec.cpp:453
void SetDirectory(ConstString directory)
Directory string set accessor.
Definition: FileSpec.cpp:334
const ConstString & GetFilename() const
Filename string const get accessor.
Definition: FileSpec.h:240
bool RemoveLastPathComponent()
Removes the last path component by replacing the current path with its parent.
Definition: FileSpec.cpp:464
ConstString GetLastPathComponent() const
Definition: FileSpec.cpp:433
const ConstString & GetDirectory() const
Directory string const get accessor.
Definition: FileSpec.h:223
ConstString GetFileNameStrippingExtension() const
Return the filename without the extension part.
Definition: FileSpec.cpp:407
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
Definition: FileSpec.cpp:366
ConstString GetPathAsConstString(bool denormalize=true) const
Get the full path as a ConstString.
Definition: FileSpec.cpp:382
void SetFilename(ConstString filename)
Filename string set accessor.
Definition: FileSpec.cpp:344
void Resolve(llvm::SmallVectorImpl< char > &path)
Resolve path to make it canonical.
void EnumerateDirectory(llvm::Twine path, bool find_directories, bool find_files, bool find_other, EnumerateDirectoryCallbackType callback, void *callback_baton)
@ eEnumerateDirectoryResultNext
Enumerate next entry in the current directory.
Definition: FileSystem.h:168
bool Exists(const FileSpec &file_spec) const
Returns whether the given file exists.
static FileSystem & Instance()
static bool ResolveExecutableInBundle(FileSpec &file)
When executable files may live within a directory, where the directory represents an executable bundl...
static Status RunShellCommand(llvm::StringRef command, const FileSpec &working_dir, int *status_ptr, int *signo_ptr, std::string *command_output, const Timeout< std::micro > &timeout, bool run_in_shell=true, bool hide_stderr=false)
Run a shell command.
static bool GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &proc_info)
static bool GetBundleDirectory(const FileSpec &file, FileSpec &bundle_directory)
If you have an executable that is in a bundle and want to get back to the bundle directory from the p...
ModuleIterable Modules() const
Definition: ModuleList.h:507
FileSpec & GetFileSpec()
Definition: ModuleSpec.h:53
FileSpec & GetSymbolFileSpec()
Definition: ModuleSpec.h:77
ArchSpec * GetArchitecturePtr()
Definition: ModuleSpec.h:81
A class that describes an executable image and its associated object and symbol files.
Definition: Module.h:88
virtual SymbolFile * GetSymbolFile(bool can_create=true, Stream *feedback_strm=nullptr)
Get the module's symbol file.
Definition: Module.cpp:1052
const FileSpec & GetFileSpec() const
Get const accessor for the module file specification.
Definition: Module.h:498
A plug-in interface definition class for object file parsers.
Definition: ObjectFile.h:62
@ eTypeDynamicLinker
The platform's dynamic linker executable.
Definition: ObjectFile.h:75
virtual llvm::VersionTuple GetMinimumOSVersion()
Get the minimum OS version this object file can run on.
Definition: ObjectFile.h:615
virtual FileSpec & GetFileSpec()
Get accessor to the object file specification.
Definition: ObjectFile.h:292
void SetValidator(ValidatorCallback validator, void *baton=nullptr)
const char * GetCurrentValue() const
StructuredData::ArraySP ExtractCrashInfoAnnotations(Process &process)
Extract the __crash_info annotations from each of of the target's modules.
static FileSpec GetCurrentCommandLineToolsDirectory()
Return the command line tools directory the current LLDB instance is located in.
llvm::Expected< StructuredData::DictionarySP > FetchExtendedCrashInformation(Process &process) override
Gather all of crash informations into a structured data dictionary.
~PlatformDarwin() override
Destructor.
FileSpecList LocateExecutableScriptingResources(Target *target, Module &module, Stream *feedback_stream) override
static FileSpec GetSDKDirectoryForModules(XcodeSDK::Type sdk_type)
Status ResolveSymbolFile(Target &target, const ModuleSpec &sym_spec, FileSpec &sym_file) override
Find a symbol file given a symbol file module specification.
void CalculateTrapHandlerSymbolNames() override
Ask the Platform subclass to fill in the list of trap handler names.
static FileSpec GetCurrentToolchainDirectory()
Return the toolchain directory the current LLDB instance is located in.
static std::tuple< llvm::VersionTuple, llvm::StringRef > ParseVersionBuildDir(llvm::StringRef str)
static lldb::PlatformSP CreateInstance(bool force, const ArchSpec *arch)
llvm::VersionTuple GetOSVersion(Process *process=nullptr) override
Get the OS version from a connected platform.
static FileSystem::EnumerateDirectoryResult DirectoryEnumerator(void *baton, llvm::sys::fs::file_type file_type, llvm::StringRef path)
static std::string FindComponentInPath(llvm::StringRef path, llvm::StringRef component)
static FileSpec FindSDKInXcodeForModules(XcodeSDK::Type sdk_type, const FileSpec &sdks_spec)
ConstString GetFullNameForDylib(ConstString basename) override
static void DebuggerInitialize(lldb_private::Debugger &debugger)
static llvm::StringRef GetPluginNameStatic()
static llvm::Triple::OSType GetHostOSType()
StructuredData::DictionarySP ExtractAppSpecificInfo(Process &process)
Extract the Application Specific Information messages from a crash report.
lldb::ProcessSP DebugProcess(ProcessLaunchInfo &launch_info, Debugger &debugger, Target &target, Status &error) override
Subclasses do not need to implement this function as it uses the Platform::LaunchProcess() followed b...
lldb::BreakpointSP SetThreadCreationBreakpoint(Target &target) override
static llvm::StringRef GetDescriptionStatic()
Status LaunchProcess(ProcessLaunchInfo &launch_info) override
Launch a new process on a platform, not necessarily for debugging, it could be just for running the p...
Status GetSharedModule(const ModuleSpec &module_spec, Process *process, lldb::ModuleSP &module_sp, const FileSpecList *module_search_paths_ptr, llvm::SmallVectorImpl< lldb::ModuleSP > *old_modules, bool *did_create_ptr) override
uint32_t GetResumeCountForLaunchInfo(ProcessLaunchInfo &launch_info) override
Status FindBundleBinaryInExecSearchPaths(const ModuleSpec &module_spec, Process *process, lldb::ModuleSP &module_sp, const FileSpecList *module_search_paths_ptr, llvm::SmallVectorImpl< lldb::ModuleSP > *old_modules, bool *did_create_ptr)
size_t GetSoftwareBreakpointTrapOpcode(Target &target, BreakpointSite *bp_site) override
void AddClangModuleCompilationOptionsForSDKType(Target *target, std::vector< std::string > &options, XcodeSDK::Type sdk_type)
Args GetExtraStartupCommands() override
Status PutFile(const FileSpec &source, const FileSpec &destination, uint32_t uid=UINT32_MAX, uint32_t gid=UINT32_MAX) override
FileSpec LocateExecutable(const char *basename) override
Find a support executable that may not live within in the standard locations related to LLDB.
void x86GetSupportedArchitectures(std::vector< ArchSpec > &archs)
bool ModuleIsExcludedForUnconstrainedSearches(Target &target, const lldb::ModuleSP &module_sp) override
void ARMGetSupportedArchitectures(std::vector< ArchSpec > &archs, std::optional< llvm::Triple::OSType > os={})
The architecture selection rules for arm processors These cpu subtypes have distinct names (e....
std::vector< ConstString > m_trap_handlers
Definition: Platform.h:926
virtual size_t GetSoftwareBreakpointTrapOpcode(Target &target, BreakpointSite *bp_site)
Definition: Platform.cpp:1831
virtual lldb::ProcessSP DebugProcess(ProcessLaunchInfo &launch_info, Debugger &debugger, Target &target, Status &error)
Subclasses do not need to implement this function as it uses the Platform::LaunchProcess() followed b...
Definition: Platform.cpp:1062
static void Terminate()
Definition: Platform.cpp:141
const ArchSpec & GetSystemArchitecture()
Definition: Platform.cpp:887
virtual llvm::VersionTuple GetOSVersion(Process *process=nullptr)
Get the OS version from a connected platform.
Definition: Platform.cpp:335
virtual Status LaunchProcess(ProcessLaunchInfo &launch_info)
Launch a new process on a platform, not necessarily for debugging, it could be just for running the p...
Definition: Platform.cpp:996
static void Initialize()
Definition: Platform.cpp:139
std::mutex m_mutex
Definition: Platform.h:916
virtual Status GetSharedModule(const ModuleSpec &module_spec, Process *process, lldb::ModuleSP &module_sp, const FileSpecList *module_search_paths_ptr, llvm::SmallVectorImpl< lldb::ModuleSP > *old_modules, bool *did_create_ptr)
Definition: Platform.cpp:201
bool IsRemote() const
Definition: Platform.h:425
bool IsHost() const
Definition: Platform.h:421
virtual llvm::StringRef GetPluginName()=0
static bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description, ABICreateInstance create_callback)
static lldb::OptionValuePropertiesSP GetSettingForPlatformPlugin(Debugger &debugger, ConstString setting_name)
static bool CreateSettingForPlatformPlugin(Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp, ConstString description, bool is_global_property)
static bool UnregisterPlugin(ABICreateInstance create_callback)
Environment & GetEnvironment()
Definition: ProcessInfo.h:87
const FileSpec & GetShell() const
static void NoOpMonitorCallback(lldb::pid_t pid, int signal, int status)
A Monitor callback which does not take any action on process events.
void SetMonitorProcessCallback(Host::MonitorChildProcessCallback callback)
A plug-in interface definition class for debugging a process.
Definition: Process.h:343
lldb::pid_t GetID() const
Returns the pid of the process or LLDB_INVALID_PROCESS_ID if there is no known pid.
Definition: Process.h:527
size_t ReadMemoryFromInferior(lldb::addr_t vm_addr, void *buf, size_t size, Status &error)
Read of memory from a process.
Definition: Process.cpp:2037
virtual StructuredData::DictionarySP GetMetadata()
Fetch process defined metadata.
Definition: Process.h:2456
size_t ReadCStringFromMemory(lldb::addr_t vm_addr, char *cstr, size_t cstr_max_len, Status &error)
Read a NULL terminated C string from memory.
Definition: Process.cpp:1991
Target & GetTarget()
Get the target object pointer for this module.
Definition: Process.h:1220
Status Unlink(const FileSpec &file_spec) override
virtual bool IsReservedWord(const char *word)
lldb::SectionSP FindSectionByName(ConstString section_dstr) const
Definition: Section.cpp:546
An error handling class.
Definition: Status.h:44
bool Success() const
Test for success condition.
Definition: Status.cpp:287
const char * GetData() const
Definition: StreamString.h:43
llvm::StringRef GetString() const
A stream class that can stream formatted output to a file.
Definition: Stream.h:28
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition: Stream.cpp:107
void AddItem(const ObjectSP &item)
ObjectSP GetItemAtIndex(size_t idx) const
void ForEach(std::function< bool(ConstString key, Object *object)> const &callback) const
std::shared_ptr< Dictionary > DictionarySP
std::shared_ptr< Array > ArraySP
Provides public interface for all SymbolFiles.
Definition: SymbolFile.h:48
static FileSpec FindSymbolFileInBundle(const FileSpec &dsym_bundle_fspec, const lldb_private::UUID *uuid, const ArchSpec *arch)
Debugger & GetDebugger()
Definition: Target.h:1031
lldb::ModuleSP GetExecutableModule()
Gets the module for the main executable.
Definition: Target.cpp:1371
lldb::BreakpointSP CreateBreakpoint(const FileSpecList *containingModules, const FileSpec &file, uint32_t line_no, uint32_t column, lldb::addr_t offset, LazyBool check_inlines, LazyBool skip_prologue, bool internal, bool request_hardware, LazyBool move_to_nearest_code)
Definition: Target.cpp:352
const ModuleList & GetImages() const
Get accessor for the images for this process.
Definition: Target.h:948
const ArchSpec & GetArchitecture() const
Definition: Target.h:990
Type
Different types of Xcode SDKs.
Definition: XcodeSDK.h:29
static std::string GetCanonicalName(Info info)
Return the canonical SDK name, such as "macosx" for the macOS SDK.
Definition: XcodeSDK.cpp:162
static bool SDKSupportsModules(Type type, llvm::VersionTuple version)
Whether LLDB feels confident importing Clang modules from this SDK.
Definition: XcodeSDK.cpp:202
#define LLDB_INVALID_ADDRESS
Definition: lldb-defines.h:74
A class that represents a running process on the host machine.
Definition: SBAttachInfo.h:14
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
Definition: Log.h:309
Definition: SBAddress.h:15
@ eScriptLanguagePython
@ eLanguageTypeUnknown
Unknown or invalid language value.
uint64_t addr_t
Definition: lldb-types.h:79
A parsed SDK directory name.
Definition: XcodeSDK.h:44
#define PATH_MAX