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