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/Error.h"
46#include "llvm/Support/FileSystem.h"
47#include "llvm/Support/Threading.h"
48#include "llvm/Support/VersionTuple.h"
49
50#if defined(__APPLE__)
51#include <TargetConditionals.h>
52#endif
53
54using namespace lldb;
55using namespace lldb_private;
56
57#define OPTTABLE_STR_TABLE_CODE
58#include "clang/Driver/Options.inc"
59#undef OPTTABLE_STR_TABLE_CODE
60
61static Status ExceptionMaskValidator(const char *string, void *unused) {
63 llvm::StringRef str_ref(string);
64 llvm::SmallVector<llvm::StringRef> candidates;
65 str_ref.split(candidates, '|');
66 for (auto candidate : candidates) {
67 if (!(candidate == "EXC_BAD_ACCESS"
68 || candidate == "EXC_BAD_INSTRUCTION"
69 || candidate == "EXC_ARITHMETIC"
70 || candidate == "EXC_RESOURCE"
71 || candidate == "EXC_GUARD"
72 || candidate == "EXC_SYSCALL")) {
73 error = Status::FromErrorStringWithFormat("invalid exception type: '%s'",
74 candidate.str().c_str());
75 return error;
76 }
77 }
78 return {};
79}
80
81/// Destructor.
82///
83/// The destructor is virtual since this class is designed to be
84/// inherited from by the plug-in instance.
86
87// Static Variables
88static uint32_t g_initialize_count = 0;
89
92
93 if (g_initialize_count++ == 0) {
98 }
99}
100
102 if (g_initialize_count > 0) {
103 if (--g_initialize_count == 0) {
105 }
106 }
107
109}
110
112 return "Darwin platform plug-in.";
113}
114
116 // We only create subclasses of the PlatformDarwin plugin.
117 return PlatformSP();
118}
119
120#define LLDB_PROPERTIES_platformdarwin
121#include "PlatformMacOSXProperties.inc"
122
123#define LLDB_PROPERTIES_platformdarwin
124enum {
125#include "PlatformMacOSXPropertiesEnum.inc"
126};
127
129public:
130 static llvm::StringRef GetSettingName() {
131 static constexpr llvm::StringLiteral g_setting_name("darwin");
132 return g_setting_name;
133 }
134
136 m_collection_sp = std::make_shared<OptionValueProperties>(GetSettingName());
137 m_collection_sp->Initialize(g_platformdarwin_properties);
138 }
139
140 ~PlatformDarwinProperties() override = default;
141
142 const char *GetIgnoredExceptions() const {
143 const uint32_t idx = ePropertyIgnoredExceptions;
144 const OptionValueString *option_value =
145 m_collection_sp->GetPropertyAtIndexAsOptionValueString(idx);
146 assert(option_value);
147 return option_value->GetCurrentValue();
148 }
149
151 const uint32_t idx = ePropertyIgnoredExceptions;
152 OptionValueString *option_value =
153 m_collection_sp->GetPropertyAtIndexAsOptionValueString(idx);
154 assert(option_value);
155 return option_value;
156 }
157};
158
160 static PlatformDarwinProperties g_settings;
161 return g_settings;
162}
163
165 lldb_private::Debugger &debugger) {
168 const bool is_global_setting = false;
170 debugger, GetGlobalProperties().GetValueProperties(),
171 "Properties for the Darwin platform plug-in.", is_global_setting);
172 OptionValueString *value = GetGlobalProperties().GetIgnoredExceptionValue();
174 }
175}
176
177Args
179 std::string ignored_exceptions
180 = GetGlobalProperties().GetIgnoredExceptions();
181 if (ignored_exceptions.empty())
182 return {};
183 Args ret_args;
184 std::string packet = "QSetIgnoredExceptions:";
185 packet.append(ignored_exceptions);
186 ret_args.AppendArgument(packet);
187 return ret_args;
188}
189
192 const lldb_private::FileSpec &destination, uint32_t uid,
193 uint32_t gid) {
194 // Unconditionally unlink the destination. If it is an executable,
195 // simply opening it and truncating its contents would invalidate
196 // its cached code signature.
197 Unlink(destination);
198 return PlatformPOSIX::PutFile(source, destination, uid, gid);
199}
200
202 Target *target, Module &module, Stream &feedback_stream) {
203 FileSpecList file_list;
204 if (target &&
206 // NB some extensions might be meaningful and should not be stripped -
207 // "this.binary.file"
208 // should not lose ".file" but GetFileNameStrippingExtension() will do
209 // precisely that. Ideally, we should have a per-platform list of
210 // extensions (".exe", ".app", ".dSYM", ".framework") which should be
211 // stripped while leaving "this.binary.file" as-is.
212
213 FileSpec module_spec = module.GetFileSpec();
214
215 if (module_spec) {
216 if (SymbolFile *symfile = module.GetSymbolFile()) {
217 ObjectFile *objfile = symfile->GetObjectFile();
218 if (objfile) {
219 FileSpec symfile_spec(objfile->GetFileSpec());
220 if (symfile_spec &&
221 llvm::StringRef(symfile_spec.GetPath())
222 .contains_insensitive(".dSYM/Contents/Resources/DWARF") &&
223 FileSystem::Instance().Exists(symfile_spec)) {
224 while (module_spec.GetFilename()) {
225 std::string module_basename(
226 module_spec.GetFilename().GetCString());
227 std::string original_module_basename(module_basename);
228
229 bool was_keyword = false;
230
231 // FIXME: for Python, we cannot allow certain characters in
232 // module
233 // filenames we import. Theoretically, different scripting
234 // languages may have different sets of forbidden tokens in
235 // filenames, and that should be dealt with by each
236 // ScriptInterpreter. For now, we just replace dots with
237 // underscores, but if we ever support anything other than
238 // Python we will need to rework this
239 std::replace(module_basename.begin(), module_basename.end(), '.',
240 '_');
241 std::replace(module_basename.begin(), module_basename.end(), ' ',
242 '_');
243 std::replace(module_basename.begin(), module_basename.end(), '-',
244 '_');
245 ScriptInterpreter *script_interpreter =
247 if (script_interpreter &&
248 script_interpreter->IsReservedWord(module_basename.c_str())) {
249 module_basename.insert(module_basename.begin(), '_');
250 was_keyword = true;
251 }
252
253 StreamString path_string;
254 StreamString original_path_string;
255 // for OSX we are going to be in
256 // .dSYM/Contents/Resources/DWARF/<basename> let us go to
257 // .dSYM/Contents/Resources/Python/<basename>.py and see if the
258 // file exists
259 path_string.Printf("%s/../Python/%s.py",
260 symfile_spec.GetDirectory().GetCString(),
261 module_basename.c_str());
262 original_path_string.Printf(
263 "%s/../Python/%s.py",
264 symfile_spec.GetDirectory().GetCString(),
265 original_module_basename.c_str());
266 FileSpec script_fspec(path_string.GetString());
267 FileSystem::Instance().Resolve(script_fspec);
268 FileSpec orig_script_fspec(original_path_string.GetString());
269 FileSystem::Instance().Resolve(orig_script_fspec);
270
271 // if we did some replacements of reserved characters, and a
272 // file with the untampered name exists, then warn the user
273 // that the file as-is shall not be loaded
274 if (module_basename != original_module_basename &&
275 FileSystem::Instance().Exists(orig_script_fspec)) {
276 const char *reason_for_complaint =
277 was_keyword ? "conflicts with a keyword"
278 : "contains reserved characters";
279 if (FileSystem::Instance().Exists(script_fspec))
280 feedback_stream.Printf(
281 "warning: the symbol file '%s' contains a debug "
282 "script. However, its name"
283 " '%s' %s and as such cannot be loaded. LLDB will"
284 " load '%s' instead. Consider removing the file with "
285 "the malformed name to"
286 " eliminate this warning.\n",
287 symfile_spec.GetPath().c_str(),
288 original_path_string.GetData(), reason_for_complaint,
289 path_string.GetData());
290 else
291 feedback_stream.Printf(
292 "warning: the symbol file '%s' contains a debug "
293 "script. However, its name"
294 " %s and as such cannot be loaded. If you intend"
295 " to have this script loaded, please rename '%s' to "
296 "'%s' and retry.\n",
297 symfile_spec.GetPath().c_str(), reason_for_complaint,
298 original_path_string.GetData(), path_string.GetData());
299 }
300
301 if (FileSystem::Instance().Exists(script_fspec)) {
302 file_list.Append(script_fspec);
303 break;
304 }
305
306 // If we didn't find the python file, then keep stripping the
307 // extensions and try again
308 ConstString filename_no_extension(
309 module_spec.GetFileNameStrippingExtension());
310 if (module_spec.GetFilename() == filename_no_extension)
311 break;
312
313 module_spec.SetFilename(filename_no_extension);
314 }
315 }
316 }
317 }
318 }
319 }
320 return file_list;
321}
322
324 const ModuleSpec &sym_spec,
325 FileSpec &sym_file) {
326 sym_file = sym_spec.GetSymbolFileSpec();
327 if (FileSystem::Instance().IsDirectory(sym_file)) {
329 sym_file, sym_spec.GetUUIDPtr(), sym_spec.GetArchitecturePtr());
330 }
331 return {};
332}
333
335 const ModuleSpec &module_spec, Process *process, ModuleSP &module_sp,
336 const FileSpecList *module_search_paths_ptr,
337 llvm::SmallVectorImpl<ModuleSP> *old_modules, bool *did_create_ptr) {
339 module_sp.reset();
340
341 if (IsRemote()) {
342 // If we have a remote platform always, let it try and locate the shared
343 // module first.
345 error = m_remote_platform_sp->GetSharedModule(
346 module_spec, process, module_sp, module_search_paths_ptr, old_modules,
347 did_create_ptr);
348 }
349 }
350
351 if (!module_sp) {
352 // Fall back to the local platform and find the file locally
353 error = Platform::GetSharedModule(module_spec, process, module_sp,
354 module_search_paths_ptr, old_modules,
355 did_create_ptr);
356
357 const FileSpec &platform_file = module_spec.GetFileSpec();
358 if (!module_sp && module_search_paths_ptr && platform_file) {
359 // We can try to pull off part of the file path up to the bundle
360 // directory level and try any module search paths...
361 FileSpec bundle_directory;
362 if (Host::GetBundleDirectory(platform_file, bundle_directory)) {
363 if (platform_file == bundle_directory) {
364 ModuleSpec new_module_spec(module_spec);
365 new_module_spec.GetFileSpec() = bundle_directory;
366 if (Host::ResolveExecutableInBundle(new_module_spec.GetFileSpec())) {
368 new_module_spec, process, module_sp, nullptr, old_modules,
369 did_create_ptr));
370
371 if (module_sp)
372 return new_error;
373 }
374 } else {
375 char platform_path[PATH_MAX];
376 char bundle_dir[PATH_MAX];
377 platform_file.GetPath(platform_path, sizeof(platform_path));
378 const size_t bundle_directory_len =
379 bundle_directory.GetPath(bundle_dir, sizeof(bundle_dir));
380 char new_path[PATH_MAX];
381 size_t num_module_search_paths = module_search_paths_ptr->GetSize();
382 for (size_t i = 0; i < num_module_search_paths; ++i) {
383 const size_t search_path_len =
384 module_search_paths_ptr->GetFileSpecAtIndex(i).GetPath(
385 new_path, sizeof(new_path));
386 if (search_path_len < sizeof(new_path)) {
387 snprintf(new_path + search_path_len,
388 sizeof(new_path) - search_path_len, "/%s",
389 platform_path + bundle_directory_len);
390 FileSpec new_file_spec(new_path);
391 if (FileSystem::Instance().Exists(new_file_spec)) {
392 ModuleSpec new_module_spec(module_spec);
393 new_module_spec.GetFileSpec() = new_file_spec;
395 new_module_spec, process, module_sp, nullptr, old_modules,
396 did_create_ptr));
397
398 if (module_sp) {
399 module_sp->SetPlatformFileSpec(new_file_spec);
400 return new_error;
401 }
402 }
403 }
404 }
405 }
406 }
407 }
408 }
409 if (module_sp)
410 module_sp->SetPlatformFileSpec(module_spec.GetFileSpec());
411 return error;
412}
413
414size_t
416 BreakpointSite *bp_site) {
417 const uint8_t *trap_opcode = nullptr;
418 uint32_t trap_opcode_size = 0;
419 bool bp_is_thumb = false;
420
421 llvm::Triple::ArchType machine = target.GetArchitecture().GetMachine();
422 switch (machine) {
423 case llvm::Triple::aarch64_32:
424 case llvm::Triple::aarch64: {
425 // 'brk #0' or 0xd4200000 in BE byte order
426 static const uint8_t g_arm64_breakpoint_opcode[] = {0x00, 0x00, 0x20, 0xD4};
427 trap_opcode = g_arm64_breakpoint_opcode;
428 trap_opcode_size = sizeof(g_arm64_breakpoint_opcode);
429 } break;
430
431 case llvm::Triple::thumb:
432 bp_is_thumb = true;
433 [[fallthrough]];
434 case llvm::Triple::arm: {
435 static const uint8_t g_arm_breakpoint_opcode[] = {0xFE, 0xDE, 0xFF, 0xE7};
436 static const uint8_t g_thumb_breakpooint_opcode[] = {0xFE, 0xDE};
437
438 // Auto detect arm/thumb if it wasn't explicitly specified
439 if (!bp_is_thumb) {
441 if (bp_loc_sp)
442 bp_is_thumb = bp_loc_sp->GetAddress().GetAddressClass() ==
444 }
445 if (bp_is_thumb) {
446 trap_opcode = g_thumb_breakpooint_opcode;
447 trap_opcode_size = sizeof(g_thumb_breakpooint_opcode);
448 break;
449 }
450 trap_opcode = g_arm_breakpoint_opcode;
451 trap_opcode_size = sizeof(g_arm_breakpoint_opcode);
452 } break;
453
454 case llvm::Triple::ppc:
455 case llvm::Triple::ppc64: {
456 static const uint8_t g_ppc_breakpoint_opcode[] = {0x7F, 0xC0, 0x00, 0x08};
457 trap_opcode = g_ppc_breakpoint_opcode;
458 trap_opcode_size = sizeof(g_ppc_breakpoint_opcode);
459 } break;
460
461 default:
462 return Platform::GetSoftwareBreakpointTrapOpcode(target, bp_site);
463 }
464
465 if (trap_opcode && trap_opcode_size) {
466 if (bp_site->SetTrapOpcode(trap_opcode, trap_opcode_size))
467 return trap_opcode_size;
468 }
469 return 0;
470}
471
473 lldb_private::Target &target, const lldb::ModuleSP &module_sp) {
474 if (!module_sp)
475 return false;
476
477 ObjectFile *obj_file = module_sp->GetObjectFile();
478 if (!obj_file)
479 return false;
480
481 ObjectFile::Type obj_type = obj_file->GetType();
482 return obj_type == ObjectFile::eTypeDynamicLinker;
483}
484
486 std::vector<ArchSpec> &archs) {
487 ArchSpec host_arch = HostInfo::GetArchitecture(HostInfo::eArchKindDefault);
488 archs.push_back(host_arch);
489
490 if (host_arch.GetCore() == ArchSpec::eCore_x86_64_x86_64h) {
491 archs.push_back(ArchSpec("x86_64-apple-macosx"));
492 archs.push_back(HostInfo::GetArchitecture(HostInfo::eArchKind32));
493 } else {
494 ArchSpec host_arch64 = HostInfo::GetArchitecture(HostInfo::eArchKind64);
495 if (host_arch.IsExactMatch(host_arch64))
496 archs.push_back(HostInfo::GetArchitecture(HostInfo::eArchKind32));
497 }
498}
499
500static llvm::ArrayRef<const char *> GetCompatibleArchs(ArchSpec::Core core) {
501 switch (core) {
502 default:
503 [[fallthrough]];
505 static const char *g_arm64e_compatible_archs[] = {
506 "arm64e", "arm64", "armv7", "armv7f", "armv7k", "armv7s",
507 "armv7m", "armv7em", "armv6m", "armv6", "armv5", "armv4",
508 "arm", "thumbv7", "thumbv7f", "thumbv7k", "thumbv7s", "thumbv7m",
509 "thumbv7em", "thumbv6m", "thumbv6", "thumbv5", "thumbv4t", "thumb",
510 };
511 return {g_arm64e_compatible_archs};
512 }
514 static const char *g_arm64_compatible_archs[] = {
515 "arm64", "armv7", "armv7f", "armv7k", "armv7s", "armv7m",
516 "armv7em", "armv6m", "armv6", "armv5", "armv4", "arm",
517 "thumbv7", "thumbv7f", "thumbv7k", "thumbv7s", "thumbv7m", "thumbv7em",
518 "thumbv6m", "thumbv6", "thumbv5", "thumbv4t", "thumb",
519 };
520 return {g_arm64_compatible_archs};
521 }
523 static const char *g_armv7_compatible_archs[] = {
524 "armv7", "armv6m", "armv6", "armv5", "armv4", "arm",
525 "thumbv7", "thumbv6m", "thumbv6", "thumbv5", "thumbv4t", "thumb",
526 };
527 return {g_armv7_compatible_archs};
528 }
530 static const char *g_armv7f_compatible_archs[] = {
531 "armv7f", "armv7", "armv6m", "armv6", "armv5",
532 "armv4", "arm", "thumbv7f", "thumbv7", "thumbv6m",
533 "thumbv6", "thumbv5", "thumbv4t", "thumb",
534 };
535 return {g_armv7f_compatible_archs};
536 }
538 static const char *g_armv7k_compatible_archs[] = {
539 "armv7k", "armv7", "armv6m", "armv6", "armv5",
540 "armv4", "arm", "thumbv7k", "thumbv7", "thumbv6m",
541 "thumbv6", "thumbv5", "thumbv4t", "thumb",
542 };
543 return {g_armv7k_compatible_archs};
544 }
546 static const char *g_armv7s_compatible_archs[] = {
547 "armv7s", "armv7", "armv6m", "armv6", "armv5",
548 "armv4", "arm", "thumbv7s", "thumbv7", "thumbv6m",
549 "thumbv6", "thumbv5", "thumbv4t", "thumb",
550 };
551 return {g_armv7s_compatible_archs};
552 }
554 static const char *g_armv7m_compatible_archs[] = {
555 "armv7m", "armv7", "armv6m", "armv6", "armv5",
556 "armv4", "arm", "thumbv7m", "thumbv7", "thumbv6m",
557 "thumbv6", "thumbv5", "thumbv4t", "thumb",
558 };
559 return {g_armv7m_compatible_archs};
560 }
562 static const char *g_armv7em_compatible_archs[] = {
563 "armv7em", "armv7", "armv6m", "armv6", "armv5",
564 "armv4", "arm", "thumbv7em", "thumbv7", "thumbv6m",
565 "thumbv6", "thumbv5", "thumbv4t", "thumb",
566 };
567 return {g_armv7em_compatible_archs};
568 }
570 static const char *g_armv6m_compatible_archs[] = {
571 "armv6m", "armv6", "armv5", "armv4", "arm",
572 "thumbv6m", "thumbv6", "thumbv5", "thumbv4t", "thumb",
573 };
574 return {g_armv6m_compatible_archs};
575 }
577 static const char *g_armv6_compatible_archs[] = {
578 "armv6", "armv5", "armv4", "arm",
579 "thumbv6", "thumbv5", "thumbv4t", "thumb",
580 };
581 return {g_armv6_compatible_archs};
582 }
584 static const char *g_armv5_compatible_archs[] = {
585 "armv5", "armv4", "arm", "thumbv5", "thumbv4t", "thumb",
586 };
587 return {g_armv5_compatible_archs};
588 }
590 static const char *g_armv4_compatible_archs[] = {
591 "armv4",
592 "arm",
593 "thumbv4t",
594 "thumb",
595 };
596 return {g_armv4_compatible_archs};
597 }
598 }
599 return {};
600}
601
602/// The architecture selection rules for arm processors These cpu subtypes have
603/// distinct names (e.g. armv7f) but armv7 binaries run fine on an armv7f
604/// processor.
606 std::vector<ArchSpec> &archs, std::optional<llvm::Triple::OSType> os) {
607 const ArchSpec system_arch = GetSystemArchitecture();
608 const ArchSpec::Core system_core = system_arch.GetCore();
609 for (const char *arch : GetCompatibleArchs(system_core)) {
610 llvm::Triple triple;
611 triple.setArchName(arch);
612 triple.setVendor(llvm::Triple::VendorType::Apple);
613 if (os)
614 triple.setOS(*os);
615 archs.push_back(ArchSpec(triple));
616 }
617}
618
620 static FileSpec g_xcode_select_filespec;
621
622 if (!g_xcode_select_filespec) {
623 FileSpec xcode_select_cmd("/usr/bin/xcode-select");
624 if (FileSystem::Instance().Exists(xcode_select_cmd)) {
625 int exit_status = -1;
626 int signo = -1;
627 std::string command_output;
628 Status status =
629 Host::RunShellCommand("/usr/bin/xcode-select --print-path",
630 FileSpec(), // current working directory
631 &exit_status, &signo, &command_output,
632 std::chrono::seconds(2), // short timeout
633 false); // don't run in a shell
634 if (status.Success() && exit_status == 0 && !command_output.empty()) {
635 size_t first_non_newline = command_output.find_last_not_of("\r\n");
636 if (first_non_newline != std::string::npos) {
637 command_output.erase(first_non_newline + 1);
638 }
639 g_xcode_select_filespec = FileSpec(command_output);
640 }
641 }
642 }
643
644 return g_xcode_select_filespec;
645}
646
648 BreakpointSP bp_sp;
649 static const char *g_bp_names[] = {
650 "start_wqthread", "_pthread_wqthread", "_pthread_start",
651 };
652
653 static const char *g_bp_modules[] = {"libsystem_c.dylib",
654 "libSystem.B.dylib"};
655
656 FileSpecList bp_modules;
657 for (size_t i = 0; i < std::size(g_bp_modules); i++) {
658 const char *bp_module = g_bp_modules[i];
659 bp_modules.EmplaceBack(bp_module);
660 }
661
662 bool internal = true;
663 bool hardware = false;
664 LazyBool skip_prologue = eLazyBoolNo;
665 bp_sp = target.CreateBreakpoint(&bp_modules, nullptr, g_bp_names,
666 std::size(g_bp_names), eFunctionNameTypeFull,
667 eLanguageTypeUnknown, 0, skip_prologue,
668 internal, hardware);
669 bp_sp->SetBreakpointKind("thread-creation");
670
671 return bp_sp;
672}
673
674uint32_t
676 const FileSpec &shell = launch_info.GetShell();
677 if (!shell)
678 return 1;
679
680 std::string shell_string = shell.GetPath();
681 const char *shell_name = strrchr(shell_string.c_str(), '/');
682 if (shell_name == nullptr)
683 shell_name = shell_string.c_str();
684 else
685 shell_name++;
686
687 if (strcmp(shell_name, "sh") == 0) {
688 // /bin/sh re-exec's itself as /bin/bash requiring another resume. But it
689 // only does this if the COMMAND_MODE environment variable is set to
690 // "legacy".
691 if (launch_info.GetEnvironment().lookup("COMMAND_MODE") == "legacy")
692 return 2;
693 return 1;
694 } else if (strcmp(shell_name, "csh") == 0 ||
695 strcmp(shell_name, "tcsh") == 0 ||
696 strcmp(shell_name, "zsh") == 0) {
697 // csh and tcsh always seem to re-exec themselves.
698 return 2;
699 } else
700 return 1;
701}
702
704 Debugger &debugger, Target &target,
705 Status &error) {
706 ProcessSP process_sp;
707
708 if (IsHost()) {
709 // We are going to hand this process off to debugserver which will be in
710 // charge of setting the exit status. However, we still need to reap it
711 // from lldb. So, make sure we use a exit callback which does not set exit
712 // status.
713 launch_info.SetMonitorProcessCallback(
715 process_sp = Platform::DebugProcess(launch_info, debugger, target, error);
716 } else {
718 process_sp = m_remote_platform_sp->DebugProcess(launch_info, debugger,
719 target, error);
720 else
721 error =
722 Status::FromErrorString("the platform is not currently connected");
723 }
724 return process_sp;
725}
726
728 m_trap_handlers.push_back(ConstString("_sigtramp"));
729}
730
732 static FileSpec g_command_line_tools_filespec;
733
734 if (!g_command_line_tools_filespec) {
735 FileSpec command_line_tools_path(GetXcodeSelectPath());
736 command_line_tools_path.AppendPathComponent("Library");
737 if (FileSystem::Instance().Exists(command_line_tools_path)) {
738 g_command_line_tools_filespec = command_line_tools_path;
739 }
740 }
741
742 return g_command_line_tools_filespec;
743}
744
746 void *baton, llvm::sys::fs::file_type file_type, llvm::StringRef path) {
747 SDKEnumeratorInfo *enumerator_info = static_cast<SDKEnumeratorInfo *>(baton);
748
749 FileSpec spec(path);
750 if (XcodeSDK::SDKSupportsModules(enumerator_info->sdk_type, spec)) {
751 enumerator_info->found_path = spec;
753 }
754
756}
757
759 const FileSpec &sdks_spec) {
760 // Look inside Xcode for the required installed iOS SDK version
761
762 if (!FileSystem::Instance().IsDirectory(sdks_spec)) {
763 return FileSpec();
764 }
765
766 const bool find_directories = true;
767 const bool find_files = false;
768 const bool find_other = true; // include symlinks
769
770 SDKEnumeratorInfo enumerator_info;
771
772 enumerator_info.sdk_type = sdk_type;
773
775 sdks_spec.GetPath(), find_directories, find_files, find_other,
776 DirectoryEnumerator, &enumerator_info);
777
778 if (FileSystem::Instance().IsDirectory(enumerator_info.found_path))
779 return enumerator_info.found_path;
780 else
781 return FileSpec();
782}
783
785 FileSpec sdks_spec = HostInfo::GetXcodeContentsDirectory();
786 sdks_spec.AppendPathComponent("Developer");
787 sdks_spec.AppendPathComponent("Platforms");
788
789 switch (sdk_type) {
791 sdks_spec.AppendPathComponent("MacOSX.platform");
792 break;
794 sdks_spec.AppendPathComponent("iPhoneSimulator.platform");
795 break;
797 sdks_spec.AppendPathComponent("iPhoneOS.platform");
798 break;
800 sdks_spec.AppendPathComponent("WatchSimulator.platform");
801 break;
803 sdks_spec.AppendPathComponent("AppleTVSimulator.platform");
804 break;
806 sdks_spec.AppendPathComponent("XRSimulator.platform");
807 break;
808 default:
809 llvm_unreachable("unsupported sdk");
810 }
811
812 sdks_spec.AppendPathComponent("Developer");
813 sdks_spec.AppendPathComponent("SDKs");
814
815 if (sdk_type == XcodeSDK::Type::MacOSX) {
816 llvm::VersionTuple version = HostInfo::GetOSVersion();
817
818 if (!version.empty()) {
820 // If the Xcode SDKs are not available then try to use the
821 // Command Line Tools one which is only for MacOSX.
822 if (!FileSystem::Instance().Exists(sdks_spec)) {
823 sdks_spec = GetCommandLineToolsLibraryPath();
824 sdks_spec.AppendPathComponent("SDKs");
825 }
826
827 // We slightly prefer the exact SDK for this machine. See if it is
828 // there.
829
830 FileSpec native_sdk_spec = sdks_spec;
831 StreamString native_sdk_name;
832 native_sdk_name.Printf("MacOSX%u.%u.sdk", version.getMajor(),
833 version.getMinor().value_or(0));
834 native_sdk_spec.AppendPathComponent(native_sdk_name.GetString());
835
836 if (FileSystem::Instance().Exists(native_sdk_spec)) {
837 return native_sdk_spec;
838 }
839 }
840 }
841 }
842
843 return FindSDKInXcodeForModules(sdk_type, sdks_spec);
844}
845
846std::tuple<llvm::VersionTuple, llvm::StringRef>
848 llvm::StringRef build;
849 llvm::StringRef version_str;
850 llvm::StringRef build_str;
851 std::tie(version_str, build_str) = dir.split(' ');
852 llvm::VersionTuple version;
853 if (!version.tryParse(version_str) ||
854 build_str.empty()) {
855 if (build_str.consume_front("(")) {
856 size_t pos = build_str.find(')');
857 build = build_str.slice(0, pos);
858 }
859 }
860
861 return std::make_tuple(version, build);
862}
863
864llvm::Expected<StructuredData::DictionarySP>
866 static constexpr llvm::StringLiteral crash_info_key("Crash-Info Annotations");
867 static constexpr llvm::StringLiteral asi_info_key(
868 "Application Specific Information");
869
870 // We cache the information we find in the process extended info dict:
871 StructuredData::DictionarySP process_dict_sp =
872 process.GetExtendedCrashInfoDict();
873 StructuredData::Array *annotations = nullptr;
874 StructuredData::ArraySP new_annotations_sp;
875 if (!process_dict_sp->GetValueForKeyAsArray(crash_info_key, annotations)) {
876 new_annotations_sp = ExtractCrashInfoAnnotations(process);
877 if (new_annotations_sp && new_annotations_sp->GetSize()) {
878 process_dict_sp->AddItem(crash_info_key, new_annotations_sp);
879 annotations = new_annotations_sp.get();
880 }
881 }
882
883 StructuredData::Dictionary *app_specific_info;
884 StructuredData::DictionarySP new_app_specific_info_sp;
885 if (!process_dict_sp->GetValueForKeyAsDictionary(asi_info_key,
886 app_specific_info)) {
887 new_app_specific_info_sp = ExtractAppSpecificInfo(process);
888 if (new_app_specific_info_sp && new_app_specific_info_sp->GetSize()) {
889 process_dict_sp->AddItem(asi_info_key, new_app_specific_info_sp);
890 app_specific_info = new_app_specific_info_sp.get();
891 }
892 }
893
894 // Now get anything else that was in the process info dict, and add it to the
895 // return here:
896 return process_dict_sp->GetSize() ? process_dict_sp : nullptr;
897}
898
902
903 ConstString section_name("__crash_info");
904 Target &target = process.GetTarget();
905 StructuredData::ArraySP array_sp = std::make_shared<StructuredData::Array>();
906
907 for (ModuleSP module : target.GetImages().Modules()) {
908 SectionList *sections = module->GetSectionList();
909
910 std::string module_name = module->GetSpecificationDescription();
911
912 // The DYDL module is skipped since it's always loaded when running the
913 // binary.
914 if (module_name == "/usr/lib/dyld")
915 continue;
916
917 if (!sections) {
918 LLDB_LOG(log, "Module {0} doesn't have any section!", module_name);
919 continue;
920 }
921
922 SectionSP crash_info = sections->FindSectionByName(section_name);
923 if (!crash_info) {
924 LLDB_LOG(log, "Module {0} doesn't have section {1}!", module_name,
925 section_name);
926 continue;
927 }
928
929 addr_t load_addr = crash_info->GetLoadBaseAddress(&target);
930
931 if (load_addr == LLDB_INVALID_ADDRESS) {
932 LLDB_LOG(log, "Module {0} has an invalid '{1}' section load address: {2}",
933 module_name, section_name, load_addr);
934 continue;
935 }
936
938 CrashInfoAnnotations annotations;
939 size_t expected_size = sizeof(CrashInfoAnnotations);
940 size_t bytes_read = process.ReadMemoryFromInferior(load_addr, &annotations,
941 expected_size, error);
942
943 if (expected_size != bytes_read || error.Fail()) {
944 LLDB_LOG(log, "Failed to read {0} section from memory in module {1}: {2}",
945 section_name, module_name, error);
946 continue;
947 }
948
949 // initial support added for version 5
950 if (annotations.version < 5) {
951 LLDB_LOG(log,
952 "Annotation version lower than 5 unsupported! Module {0} has "
953 "version {1} instead.",
954 module_name, annotations.version);
955 continue;
956 }
957
958 if (!annotations.message) {
959 LLDB_LOG(log, "No message available for module {0}.", module_name);
960 continue;
961 }
962
963 std::string message;
964 bytes_read =
965 process.ReadCStringFromMemory(annotations.message, message, error);
966
967 if (message.empty() || bytes_read != message.size() || error.Fail()) {
968 LLDB_LOG(log, "Failed to read the message from memory in module {0}: {1}",
969 module_name, error);
970 continue;
971 }
972
973 // Remove trailing newline from message
974 if (message.back() == '\n')
975 message.pop_back();
976
977 if (!annotations.message2)
978 LLDB_LOG(log, "No message2 available for module {0}.", module_name);
979
980 std::string message2;
981 bytes_read =
982 process.ReadCStringFromMemory(annotations.message2, message2, error);
983
984 if (!message2.empty() && bytes_read == message2.size() && error.Success())
985 if (message2.back() == '\n')
986 message2.pop_back();
987
989 std::make_shared<StructuredData::Dictionary>();
990
991 entry_sp->AddStringItem("image", module->GetFileSpec().GetPath(false));
992 entry_sp->AddStringItem("uuid", module->GetUUID().GetAsString());
993 entry_sp->AddStringItem("message", message);
994 entry_sp->AddStringItem("message2", message2);
995 entry_sp->AddIntegerItem("abort-cause", annotations.abort_cause);
996
997 array_sp->AddItem(entry_sp);
998 }
999
1000 return array_sp;
1001}
1002
1005 StructuredData::DictionarySP metadata_sp = process.GetMetadata();
1006
1007 if (!metadata_sp || !metadata_sp->GetSize() || !metadata_sp->HasKey("asi"))
1008 return {};
1009
1011 if (!metadata_sp->GetValueForKeyAsDictionary("asi", asi))
1012 return {};
1013
1015 std::make_shared<StructuredData::Dictionary>();
1016
1017 auto flatten_asi_dict = [&dict_sp](llvm::StringRef key,
1018 StructuredData::Object *val) -> bool {
1019 if (!val)
1020 return false;
1021
1022 StructuredData::Array *arr = val->GetAsArray();
1023 if (!arr || !arr->GetSize())
1024 return false;
1025
1026 dict_sp->AddItem(key, arr->GetItemAtIndex(0));
1027 return true;
1028 };
1029
1030 asi->ForEach(flatten_asi_dict);
1031
1032 return dict_sp;
1033}
1034
1036 Target *target, std::vector<std::string> &options, XcodeSDK::Type sdk_type) {
1037 const std::vector<std::string> apple_arguments = {
1038 "-x", "objective-c++", "-fobjc-arc",
1039 "-fblocks", "-D_ISO646_H", "-D__ISO646_H",
1040 "-fgnuc-version=4.2.1"};
1041
1042 options.insert(options.end(), apple_arguments.begin(), apple_arguments.end());
1043
1044 StreamString minimum_version_option;
1045 bool use_current_os_version = false;
1046 // If the SDK type is for the host OS, use its version number.
1047 auto get_host_os = []() { return HostInfo::GetTargetTriple().getOS(); };
1048 switch (sdk_type) {
1050 use_current_os_version = get_host_os() == llvm::Triple::MacOSX;
1051 break;
1053 use_current_os_version = get_host_os() == llvm::Triple::IOS;
1054 break;
1056 use_current_os_version = get_host_os() == llvm::Triple::TvOS;
1057 break;
1059 use_current_os_version = get_host_os() == llvm::Triple::WatchOS;
1060 break;
1062 use_current_os_version = get_host_os() == llvm::Triple::XROS;
1063 break;
1064 default:
1065 break;
1066 }
1067
1068 llvm::VersionTuple version;
1069 if (use_current_os_version)
1070 version = GetOSVersion();
1071 else if (target) {
1072 // Our OS doesn't match our executable so we need to get the min OS version
1073 // from the object file
1074 ModuleSP exe_module_sp = target->GetExecutableModule();
1075 if (exe_module_sp) {
1076 ObjectFile *object_file = exe_module_sp->GetObjectFile();
1077 if (object_file)
1078 version = object_file->GetMinimumOSVersion();
1079 }
1080 }
1081 // Only add the version-min options if we got a version from somewhere.
1082 // clang has no version-min clang flag for XROS.
1083 if (!version.empty() && sdk_type != XcodeSDK::Type::Linux &&
1084 sdk_type != XcodeSDK::Type::XROS) {
1085#define OPTION(PREFIX_OFFSET, NAME_OFFSET, VAR, ...) \
1086 llvm::StringRef opt_##VAR = &OptionStrTable[NAME_OFFSET]; \
1087 (void)opt_##VAR;
1088#include "clang/Driver/Options.inc"
1089#undef OPTION
1090 minimum_version_option << '-';
1091 switch (sdk_type) {
1093 minimum_version_option << opt_mmacos_version_min_EQ;
1094 break;
1096 minimum_version_option << opt_mios_simulator_version_min_EQ;
1097 break;
1099 minimum_version_option << opt_mios_version_min_EQ;
1100 break;
1102 minimum_version_option << opt_mtvos_simulator_version_min_EQ;
1103 break;
1105 minimum_version_option << opt_mtvos_version_min_EQ;
1106 break;
1108 minimum_version_option << opt_mwatchos_simulator_version_min_EQ;
1109 break;
1111 minimum_version_option << opt_mwatchos_version_min_EQ;
1112 break;
1115 // FIXME: Pass the right argument once it exists.
1119 if (Log *log = GetLog(LLDBLog::Host)) {
1120 XcodeSDK::Info info;
1121 info.type = sdk_type;
1122 LLDB_LOGF(log, "Clang modules on %s are not supported",
1123 XcodeSDK::GetCanonicalName(info).c_str());
1124 }
1125 return;
1126 }
1127 minimum_version_option << version.getAsString();
1128 options.emplace_back(std::string(minimum_version_option.GetString()));
1129 }
1130
1131 FileSpec sysroot_spec;
1132
1133 if (target) {
1134 if (ModuleSP exe_module_sp = target->GetExecutableModule()) {
1135 auto path_or_err = ResolveSDKPathFromDebugInfo(*exe_module_sp);
1136 if (path_or_err) {
1137 sysroot_spec = FileSpec(*path_or_err);
1138 } else {
1140 path_or_err.takeError(),
1141 "Failed to resolve SDK path: {0}");
1142 }
1143 }
1144 }
1145
1146 if (!FileSystem::Instance().IsDirectory(sysroot_spec.GetPath())) {
1147 std::lock_guard<std::mutex> guard(m_mutex);
1148 sysroot_spec = GetSDKDirectoryForModules(sdk_type);
1149 }
1150
1151 if (FileSystem::Instance().IsDirectory(sysroot_spec.GetPath())) {
1152 options.push_back("-isysroot");
1153 options.push_back(sysroot_spec.GetPath());
1154 }
1155}
1156
1158 if (basename.IsEmpty())
1159 return basename;
1160
1161 StreamString stream;
1162 stream.Printf("lib%s.dylib", basename.GetCString());
1163 return ConstString(stream.GetString());
1164}
1165
1166llvm::VersionTuple PlatformDarwin::GetOSVersion(Process *process) {
1167 if (process && GetPluginName().contains("-simulator")) {
1169 if (Host::GetProcessInfo(process->GetID(), proc_info)) {
1170 const Environment &env = proc_info.GetEnvironment();
1171
1172 llvm::VersionTuple result;
1173 if (!result.tryParse(env.lookup("SIMULATOR_RUNTIME_VERSION")))
1174 return result;
1175
1176 std::string dyld_root_path = env.lookup("DYLD_ROOT_PATH");
1177 if (!dyld_root_path.empty()) {
1178 dyld_root_path += "/System/Library/CoreServices/SystemVersion.plist";
1179 ApplePropertyList system_version_plist(dyld_root_path.c_str());
1180 std::string product_version;
1181 if (system_version_plist.GetValueAsString("ProductVersion",
1182 product_version)) {
1183 if (!result.tryParse(product_version))
1184 return result;
1185 }
1186 }
1187 }
1188 // For simulator platforms, do NOT call back through
1189 // Platform::GetOSVersion() as it might call Process::GetHostOSVersion()
1190 // which we don't want as it will be incorrect
1191 return llvm::VersionTuple();
1192 }
1193
1194 return Platform::GetOSVersion(process);
1195}
1196
1198 // A collection of SBFileSpec whose SBFileSpec.m_directory members are filled
1199 // in with any executable directories that should be searched.
1200 static std::vector<FileSpec> g_executable_dirs;
1201
1202 // Find the global list of directories that we will search for executables
1203 // once so we don't keep doing the work over and over.
1204 static llvm::once_flag g_once_flag;
1205 llvm::call_once(g_once_flag, []() {
1206
1207 // When locating executables, trust the DEVELOPER_DIR first if it is set
1208 FileSpec xcode_contents_dir = HostInfo::GetXcodeContentsDirectory();
1209 if (xcode_contents_dir) {
1210 FileSpec xcode_lldb_resources = xcode_contents_dir;
1211 xcode_lldb_resources.AppendPathComponent("SharedFrameworks");
1212 xcode_lldb_resources.AppendPathComponent("LLDB.framework");
1213 xcode_lldb_resources.AppendPathComponent("Resources");
1214 if (FileSystem::Instance().Exists(xcode_lldb_resources)) {
1215 FileSpec dir;
1216 dir.SetDirectory(xcode_lldb_resources.GetPathAsConstString());
1217 g_executable_dirs.push_back(dir);
1218 }
1219 }
1220 // Xcode might not be installed so we also check for the Command Line Tools.
1221 FileSpec command_line_tools_dir = GetCommandLineToolsLibraryPath();
1222 if (command_line_tools_dir) {
1223 FileSpec cmd_line_lldb_resources = command_line_tools_dir;
1224 cmd_line_lldb_resources.AppendPathComponent("PrivateFrameworks");
1225 cmd_line_lldb_resources.AppendPathComponent("LLDB.framework");
1226 cmd_line_lldb_resources.AppendPathComponent("Resources");
1227 if (FileSystem::Instance().Exists(cmd_line_lldb_resources)) {
1228 FileSpec dir;
1229 dir.SetDirectory(cmd_line_lldb_resources.GetPathAsConstString());
1230 g_executable_dirs.push_back(dir);
1231 }
1232 }
1233 });
1234
1235 // Now search the global list of executable directories for the executable we
1236 // are looking for
1237 for (const auto &executable_dir : g_executable_dirs) {
1238 FileSpec executable_file;
1239 executable_file.SetDirectory(executable_dir.GetDirectory());
1240 executable_file.SetFilename(basename);
1241 if (FileSystem::Instance().Exists(executable_file))
1242 return executable_file;
1243 }
1244
1245 return FileSpec();
1246}
1247
1250 // Starting in Fall 2016 OSes, NSLog messages only get mirrored to stderr if
1251 // the OS_ACTIVITY_DT_MODE environment variable is set. (It doesn't require
1252 // any specific value; rather, it just needs to exist). We will set it here
1253 // as long as the IDE_DISABLED_OS_ACTIVITY_DT_MODE flag is not set. Xcode
1254 // makes use of IDE_DISABLED_OS_ACTIVITY_DT_MODE to tell
1255 // LLDB *not* to muck with the OS_ACTIVITY_DT_MODE flag when they
1256 // specifically want it unset.
1257 const char *disable_env_var = "IDE_DISABLED_OS_ACTIVITY_DT_MODE";
1258 auto &env_vars = launch_info.GetEnvironment();
1259 if (!env_vars.count(disable_env_var)) {
1260 // We want to make sure that OS_ACTIVITY_DT_MODE is set so that we get
1261 // os_log and NSLog messages mirrored to the target process stderr.
1262 env_vars.try_emplace("OS_ACTIVITY_DT_MODE", "enable");
1263 }
1264
1265 // Let our parent class do the real launching.
1266 return PlatformPOSIX::LaunchProcess(launch_info);
1267}
1268
1270 const ModuleSpec &module_spec, Process *process, ModuleSP &module_sp,
1271 const FileSpecList *module_search_paths_ptr,
1272 llvm::SmallVectorImpl<ModuleSP> *old_modules, bool *did_create_ptr) {
1273 const FileSpec &platform_file = module_spec.GetFileSpec();
1274 // See if the file is present in any of the module_search_paths_ptr
1275 // directories.
1276 if (!module_sp && module_search_paths_ptr && platform_file) {
1277 // create a vector of all the file / directory names in platform_file e.g.
1278 // this might be
1279 // /System/Library/PrivateFrameworks/UIFoundation.framework/UIFoundation
1280 //
1281 // We'll need to look in the module_search_paths_ptr directories for both
1282 // "UIFoundation" and "UIFoundation.framework" -- most likely the latter
1283 // will be the one we find there.
1284
1285 std::vector<llvm::StringRef> path_parts = platform_file.GetComponents();
1286 // We want the components in reverse order.
1287 std::reverse(path_parts.begin(), path_parts.end());
1288 const size_t path_parts_size = path_parts.size();
1289
1290 size_t num_module_search_paths = module_search_paths_ptr->GetSize();
1291 for (size_t i = 0; i < num_module_search_paths; ++i) {
1292 Log *log_verbose = GetLog(LLDBLog::Host);
1293 LLDB_LOGF(
1294 log_verbose,
1295 "PlatformRemoteDarwinDevice::GetSharedModule searching for binary in "
1296 "search-path %s",
1297 module_search_paths_ptr->GetFileSpecAtIndex(i).GetPath().c_str());
1298 // Create a new FileSpec with this module_search_paths_ptr plus just the
1299 // filename ("UIFoundation"), then the parent dir plus filename
1300 // ("UIFoundation.framework/UIFoundation") etc - up to four names (to
1301 // handle "Foo.framework/Contents/MacOS/Foo")
1302
1303 for (size_t j = 0; j < 4 && j < path_parts_size - 1; ++j) {
1304 FileSpec path_to_try(module_search_paths_ptr->GetFileSpecAtIndex(i));
1305
1306 // Add the components backwards. For
1307 // .../PrivateFrameworks/UIFoundation.framework/UIFoundation path_parts
1308 // is
1309 // [0] UIFoundation
1310 // [1] UIFoundation.framework
1311 // [2] PrivateFrameworks
1312 //
1313 // and if 'j' is 2, we want to append path_parts[1] and then
1314 // path_parts[0], aka 'UIFoundation.framework/UIFoundation', to the
1315 // module_search_paths_ptr path.
1316
1317 for (int k = j; k >= 0; --k) {
1318 path_to_try.AppendPathComponent(path_parts[k]);
1319 }
1320
1321 if (FileSystem::Instance().Exists(path_to_try)) {
1322 ModuleSpec new_module_spec(module_spec);
1323 new_module_spec.GetFileSpec() = path_to_try;
1324 Status new_error(
1325 Platform::GetSharedModule(new_module_spec, process, module_sp,
1326 nullptr, old_modules, did_create_ptr));
1327
1328 if (module_sp) {
1329 module_sp->SetPlatformFileSpec(path_to_try);
1330 return new_error;
1331 }
1332 }
1333 }
1334 }
1335 }
1336 return Status();
1337}
1338
1339std::string PlatformDarwin::FindComponentInPath(llvm::StringRef path,
1340 llvm::StringRef component) {
1341 auto begin = llvm::sys::path::begin(path);
1342 auto end = llvm::sys::path::end(path);
1343 for (auto it = begin; it != end; ++it) {
1344 if (it->contains(component)) {
1345 llvm::SmallString<128> buffer;
1346 llvm::sys::path::append(buffer, begin, ++it,
1347 llvm::sys::path::Style::posix);
1348 return buffer.str().str();
1349 }
1350 }
1351 return {};
1352}
1353
1355 if (FileSpec fspec = HostInfo::GetShlibDir())
1356 return FileSpec(FindComponentInPath(fspec.GetPath(), ".xctoolchain"));
1357 return {};
1358}
1359
1361 if (FileSpec fspec = HostInfo::GetShlibDir())
1362 return FileSpec(FindComponentInPath(fspec.GetPath(), "CommandLineTools"));
1363 return {};
1364}
1365
1366llvm::Triple::OSType PlatformDarwin::GetHostOSType() {
1367#if !defined(__APPLE__)
1368 return llvm::Triple::MacOSX;
1369#else
1370#if TARGET_OS_OSX
1371 return llvm::Triple::MacOSX;
1372#elif TARGET_OS_IOS
1373 return llvm::Triple::IOS;
1374#elif TARGET_OS_WATCH
1375 return llvm::Triple::WatchOS;
1376#elif TARGET_OS_TV
1377 return llvm::Triple::TvOS;
1378#elif TARGET_OS_BRIDGE
1379 return llvm::Triple::BridgeOS;
1380#elif TARGET_OS_XR
1381 return llvm::Triple::XROS;
1382#else
1383#error "LLDB being compiled for an unrecognized Darwin OS"
1384#endif
1385#endif // __APPLE__
1386}
1387
1388llvm::Expected<std::pair<XcodeSDK, bool>>
1390 SymbolFile *sym_file = module.GetSymbolFile();
1391 if (!sym_file)
1392 return llvm::createStringError(
1393 llvm::inconvertibleErrorCode(),
1394 llvm::formatv("No symbol file available for module '{0}'",
1395 module.GetFileSpec().GetFilename().AsCString("")));
1396
1397 bool found_public_sdk = false;
1398 bool found_internal_sdk = false;
1399 XcodeSDK merged_sdk;
1400 for (unsigned i = 0; i < sym_file->GetNumCompileUnits(); ++i) {
1401 if (auto cu_sp = sym_file->GetCompileUnitAtIndex(i)) {
1402 auto cu_sdk = sym_file->ParseXcodeSDK(*cu_sp);
1403 bool is_internal_sdk = cu_sdk.IsAppleInternalSDK();
1404 found_public_sdk |= !is_internal_sdk;
1405 found_internal_sdk |= is_internal_sdk;
1406
1407 merged_sdk.Merge(cu_sdk);
1408 }
1409 }
1410
1411 const bool found_mismatch = found_internal_sdk && found_public_sdk;
1412
1413 return std::pair{std::move(merged_sdk), found_mismatch};
1414}
1415
1416llvm::Expected<std::string>
1418 auto sdk_or_err = GetSDKPathFromDebugInfo(module);
1419 if (!sdk_or_err)
1420 return llvm::createStringError(
1421 llvm::inconvertibleErrorCode(),
1422 llvm::formatv("Failed to parse SDK path from debug-info: {0}",
1423 llvm::toString(sdk_or_err.takeError())));
1424
1425 auto [sdk, _] = std::move(*sdk_or_err);
1426
1427 auto path_or_err = HostInfo::GetSDKRoot(HostInfo::SDKOptions{sdk});
1428 if (!path_or_err)
1429 return llvm::createStringError(
1430 llvm::inconvertibleErrorCode(),
1431 llvm::formatv("Error while searching for SDK (XcodeSDK '{0}'): {1}",
1432 sdk.GetString(),
1433 llvm::toString(path_or_err.takeError())));
1434
1435 return path_or_err->str();
1436}
1437
1438llvm::Expected<XcodeSDK>
1440 ModuleSP module_sp = unit.CalculateSymbolContextModule();
1441 if (!module_sp)
1442 return llvm::createStringError("compile unit has no module");
1443 SymbolFile *sym_file = module_sp->GetSymbolFile();
1444 if (!sym_file)
1445 return llvm::createStringError(
1446 llvm::formatv("No symbol file available for module '{0}'",
1447 module_sp->GetFileSpec().GetFilename()));
1448
1449 return sym_file->ParseXcodeSDK(unit);
1450}
1451
1452llvm::Expected<std::string>
1454 auto sdk_or_err = GetSDKPathFromDebugInfo(unit);
1455 if (!sdk_or_err)
1456 return llvm::createStringError(
1457 llvm::inconvertibleErrorCode(),
1458 llvm::formatv("Failed to parse SDK path from debug-info: {0}",
1459 llvm::toString(sdk_or_err.takeError())));
1460
1461 auto sdk = std::move(*sdk_or_err);
1462
1463 auto path_or_err = HostInfo::GetSDKRoot(HostInfo::SDKOptions{sdk});
1464 if (!path_or_err)
1465 return llvm::createStringError(
1466 llvm::inconvertibleErrorCode(),
1467 llvm::formatv("Error while searching for SDK (XcodeSDK '{0}'): {1}",
1468 sdk.GetString(),
1469 llvm::toString(path_or_err.takeError())));
1470
1471 return path_or_err->str();
1472}
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:369
#define LLDB_LOGF(log,...)
Definition: Log.h:376
#define LLDB_LOG_ERROR(log, error,...)
Definition: Log.h:392
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 uint32_t g_initialize_count
static llvm::StringRef 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:404
An architecture specification class.
Definition: ArchSpec.h:31
bool IsExactMatch(const ArchSpec &rhs) const
Shorthand for IsMatch(rhs, ExactMatch).
Definition: ArchSpec.h:508
llvm::Triple::ArchType GetMachine() const
Returns a machine family for the current architecture.
Definition: ArchSpec.cpp:701
Core GetCore() const
Definition: ArchSpec.h:440
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:332
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 GetConstituentAtIndex(size_t idx)
This method returns the breakpoint location at index index located at this breakpoint site.
A class that describes a compilation unit.
Definition: CompileUnit.h:43
lldb::ModuleSP CalculateSymbolContextModule() override
Definition: CompileUnit.cpp:49
A uniqued constant string class.
Definition: ConstString.h:40
const char * AsCString(const char *value_if_empty=nullptr) const
Get the string value as a C string.
Definition: ConstString.h:188
bool IsEmpty() const
Test for empty string.
Definition: ConstString.h:304
const char * GetCString() const
Get the string value as a C string.
Definition: ConstString.h:216
A class to manage flag bits.
Definition: Debugger.h:80
lldb::ScriptLanguage GetScriptLanguage() const
Definition: Debugger.cpp:345
ScriptInterpreter * GetScriptInterpreter(bool can_create=true, std::optional< lldb::ScriptLanguage > language={})
Definition: Debugger.cpp:1719
A file collection class.
Definition: FileSpecList.h:91
const FileSpec & GetFileSpecAtIndex(size_t idx) const
Get file at index.
void EmplaceBack(Args &&...args)
Inserts a new FileSpec into the FileSpecList constructed in-place with the given arguments.
Definition: FileSpecList.h:152
void Append(const FileSpec &file)
Append a FileSpec object to the list.
size_t GetSize() const
Get the number of files in the file list.
A file utility class.
Definition: FileSpec.h:56
void AppendPathComponent(llvm::StringRef component)
Definition: FileSpec.cpp:447
void SetDirectory(ConstString directory)
Directory string set accessor.
Definition: FileSpec.cpp:335
const ConstString & GetFilename() const
Filename string const get accessor.
Definition: FileSpec.h:240
std::vector< llvm::StringRef > GetComponents() const
Gets the components of the FileSpec's path.
Definition: FileSpec.cpp:468
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:367
ConstString GetPathAsConstString(bool denormalize=true) const
Get the full path as a ConstString.
Definition: FileSpec.cpp:383
void SetFilename(ConstString filename)
Filename string set accessor.
Definition: FileSpec.cpp:345
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:178
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:527
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:89
virtual SymbolFile * GetSymbolFile(bool can_create=true, Stream *feedback_strm=nullptr)
Get the module's symbol file.
Definition: Module.cpp:999
const FileSpec & GetFileSpec() const
Get const accessor for the module file specification.
Definition: Module.h:453
A plug-in interface definition class for object file parsers.
Definition: ObjectFile.h:44
@ eTypeDynamicLinker
The platform's dynamic linker executable.
Definition: ObjectFile.h:57
virtual llvm::VersionTuple GetMinimumOSVersion()
Get the minimum OS version this object file can run on.
Definition: ObjectFile.h:622
virtual FileSpec & GetFileSpec()
Get accessor to the object file specification.
Definition: ObjectFile.h:275
void SetValidator(ValidatorCallback validator, void *baton=nullptr)
const char * GetCurrentValue() const
StructuredData::ArraySP ExtractCrashInfoAnnotations(Process &process)
Extract the __crash_info annotations from each 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.
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)
FileSpecList LocateExecutableScriptingResources(Target *target, Module &module, Stream &feedback_stream) override
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)
llvm::Expected< std::string > ResolveSDKPathFromDebugInfo(Module &module) override
Returns the full path of the most appropriate SDK for the specified 'module'.
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)
llvm::Expected< std::pair< XcodeSDK, bool > > GetSDKPathFromDebugInfo(Module &module) override
Search each CU associated with the specified 'module' for the SDK paths the CUs were compiled against...
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:1021
virtual size_t GetSoftwareBreakpointTrapOpcode(Target &target, BreakpointSite *bp_site)
Definition: Platform.cpp:1954
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:1002
static void Terminate()
Definition: Platform.cpp:138
const ArchSpec & GetSystemArchitecture()
Definition: Platform.cpp:817
virtual llvm::VersionTuple GetOSVersion(Process *process=nullptr)
Get the OS version from a connected platform.
Definition: Platform.cpp:297
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:934
static void Initialize()
Definition: Platform.cpp:136
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:164
bool IsRemote() const
Definition: Platform.h:506
bool IsHost() const
Definition: Platform.h:502
virtual llvm::StringRef GetPluginName()=0
static bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description, ABICreateInstance create_callback)
static lldb::OptionValuePropertiesSP GetSettingForPlatformPlugin(Debugger &debugger, llvm::StringRef setting_name)
static bool CreateSettingForPlatformPlugin(Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp, llvm::StringRef description, bool is_global_property)
static bool UnregisterPlugin(ABICreateInstance create_callback)
static FileSpec FindSymbolFileInBundle(const FileSpec &dsym_bundle_fspec, const UUID *uuid, const ArchSpec *arch)
Environment & GetEnvironment()
Definition: ProcessInfo.h:88
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:542
size_t ReadMemoryFromInferior(lldb::addr_t vm_addr, void *buf, size_t size, Status &error)
Read of memory from a process.
Definition: Process.cpp:2188
virtual StructuredData::DictionarySP GetMetadata()
Fetch process defined metadata.
Definition: Process.h:2538
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:2142
StructuredData::DictionarySP GetExtendedCrashInfoDict()
Fetch extended crash information held by the process.
Definition: Process.h:2543
Target & GetTarget()
Get the target object pointer for this module.
Definition: Process.h:1246
Status Unlink(const FileSpec &file_spec) override
virtual bool IsReservedWord(const char *word)
lldb::SectionSP FindSectionByName(ConstString section_dstr) const
Definition: Section.cpp:558
An error handling class.
Definition: Status.h:118
static Status FromErrorStringWithFormat(const char *format,...) __attribute__((format(printf
Definition: Status.cpp:106
static Status FromErrorString(const char *str)
Definition: Status.h:141
bool Success() const
Test for success condition.
Definition: Status.cpp:304
const char * GetData() const
Definition: StreamString.h:45
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:134
void AddItem(const ObjectSP &item)
ObjectSP GetItemAtIndex(size_t idx) const
void ForEach(std::function< bool(llvm::StringRef 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:50
virtual XcodeSDK ParseXcodeSDK(CompileUnit &comp_unit)
Return the Xcode SDK comp_unit was compiled against.
Definition: SymbolFile.h:151
virtual uint32_t GetNumCompileUnits()=0
virtual lldb::CompUnitSP GetCompileUnitAtIndex(uint32_t idx)=0
Debugger & GetDebugger()
Definition: Target.h:1080
lldb::ModuleSP GetExecutableModule()
Gets the module for the main executable.
Definition: Target.cpp:1504
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:472
const ModuleList & GetImages() const
Get accessor for the images for this process.
Definition: Target.h:997
const ArchSpec & GetArchitecture() const
Definition: Target.h:1039
An abstraction for Xcode-style SDKs that works like ArchSpec.
Definition: XcodeSDK.h:24
Type
Different types of Xcode SDKs.
Definition: XcodeSDK.h:29
void Merge(const XcodeSDK &other)
The merge function follows a strict order to maintain monotonicity:
Definition: XcodeSDK.cpp:155
static std::string GetCanonicalName(Info info)
Return the canonical SDK name, such as "macosx" for the macOS SDK.
Definition: XcodeSDK.cpp:170
bool IsAppleInternalSDK() const
Definition: XcodeSDK.cpp:125
static bool SDKSupportsModules(Type type, llvm::VersionTuple version)
Whether LLDB feels confident importing Clang modules from this SDK.
Definition: XcodeSDK.cpp:216
#define LLDB_INVALID_ADDRESS
Definition: lldb-defines.h:82
A class that represents a running process on the host machine.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
Definition: Log.h:332
Definition: SBAddress.h:15
@ eScriptLanguagePython
std::shared_ptr< lldb_private::BreakpointLocation > BreakpointLocationSP
Definition: lldb-forward.h:324
std::shared_ptr< lldb_private::Platform > PlatformSP
Definition: lldb-forward.h:388
@ eLanguageTypeUnknown
Unknown or invalid language value.
std::shared_ptr< lldb_private::Breakpoint > BreakpointSP
Definition: lldb-forward.h:321
std::shared_ptr< lldb_private::Process > ProcessSP
Definition: lldb-forward.h:389
std::shared_ptr< lldb_private::Section > SectionSP
Definition: lldb-forward.h:418
uint64_t addr_t
Definition: lldb-types.h:80
std::shared_ptr< lldb_private::Module > ModuleSP
Definition: lldb-forward.h:373
A parsed SDK directory name.
Definition: XcodeSDK.h:46
#define PATH_MAX