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 StructuredData::DictionarySP extended_crash_info =
861 std::make_shared<StructuredData::Dictionary>();
862
864 if (annotations && annotations->GetSize())
865 extended_crash_info->AddItem("Crash-Info Annotations", annotations);
866
867 StructuredData::DictionarySP app_specific_info =
868 ExtractAppSpecificInfo(process);
869 if (app_specific_info && app_specific_info->GetSize())
870 extended_crash_info->AddItem("Application Specific Information",
871 app_specific_info);
872
873 return extended_crash_info->GetSize() ? extended_crash_info : nullptr;
874}
875
879
880 ConstString section_name("__crash_info");
881 Target &target = process.GetTarget();
882 StructuredData::ArraySP array_sp = std::make_shared<StructuredData::Array>();
883
884 for (ModuleSP module : target.GetImages().Modules()) {
885 SectionList *sections = module->GetSectionList();
886
887 std::string module_name = module->GetSpecificationDescription();
888
889 // The DYDL module is skipped since it's always loaded when running the
890 // binary.
891 if (module_name == "/usr/lib/dyld")
892 continue;
893
894 if (!sections) {
895 LLDB_LOG(log, "Module {0} doesn't have any section!", module_name);
896 continue;
897 }
898
899 SectionSP crash_info = sections->FindSectionByName(section_name);
900 if (!crash_info) {
901 LLDB_LOG(log, "Module {0} doesn't have section {1}!", module_name,
902 section_name);
903 continue;
904 }
905
906 addr_t load_addr = crash_info->GetLoadBaseAddress(&target);
907
908 if (load_addr == LLDB_INVALID_ADDRESS) {
909 LLDB_LOG(log, "Module {0} has an invalid '{1}' section load address: {2}",
910 module_name, section_name, load_addr);
911 continue;
912 }
913
915 CrashInfoAnnotations annotations;
916 size_t expected_size = sizeof(CrashInfoAnnotations);
917 size_t bytes_read = process.ReadMemoryFromInferior(load_addr, &annotations,
918 expected_size, error);
919
920 if (expected_size != bytes_read || error.Fail()) {
921 LLDB_LOG(log, "Failed to read {0} section from memory in module {1}: {2}",
922 section_name, module_name, error);
923 continue;
924 }
925
926 // initial support added for version 5
927 if (annotations.version < 5) {
928 LLDB_LOG(log,
929 "Annotation version lower than 5 unsupported! Module {0} has "
930 "version {1} instead.",
931 module_name, annotations.version);
932 continue;
933 }
934
935 if (!annotations.message) {
936 LLDB_LOG(log, "No message available for module {0}.", module_name);
937 continue;
938 }
939
940 std::string message;
941 bytes_read =
942 process.ReadCStringFromMemory(annotations.message, message, error);
943
944 if (message.empty() || bytes_read != message.size() || error.Fail()) {
945 LLDB_LOG(log, "Failed to read the message from memory in module {0}: {1}",
946 module_name, error);
947 continue;
948 }
949
950 // Remove trailing newline from message
951 if (message.back() == '\n')
952 message.pop_back();
953
954 if (!annotations.message2)
955 LLDB_LOG(log, "No message2 available for module {0}.", module_name);
956
957 std::string message2;
958 bytes_read =
959 process.ReadCStringFromMemory(annotations.message2, message2, error);
960
961 if (!message2.empty() && bytes_read == message2.size() && error.Success())
962 if (message2.back() == '\n')
963 message2.pop_back();
964
966 std::make_shared<StructuredData::Dictionary>();
967
968 entry_sp->AddStringItem("image", module->GetFileSpec().GetPath(false));
969 entry_sp->AddStringItem("uuid", module->GetUUID().GetAsString());
970 entry_sp->AddStringItem("message", message);
971 entry_sp->AddStringItem("message2", message2);
972 entry_sp->AddIntegerItem("abort-cause", annotations.abort_cause);
973
974 array_sp->AddItem(entry_sp);
975 }
976
977 return array_sp;
978}
979
982 StructuredData::DictionarySP metadata_sp = process.GetMetadata();
983
984 if (!metadata_sp || !metadata_sp->GetSize() || !metadata_sp->HasKey("asi"))
985 return {};
986
988 if (!metadata_sp->GetValueForKeyAsDictionary("asi", asi))
989 return {};
990
992 std::make_shared<StructuredData::Dictionary>();
993
994 auto flatten_asi_dict = [&dict_sp](llvm::StringRef key,
995 StructuredData::Object *val) -> bool {
996 if (!val)
997 return false;
998
999 StructuredData::Array *arr = val->GetAsArray();
1000 if (!arr || !arr->GetSize())
1001 return false;
1002
1003 dict_sp->AddItem(key, arr->GetItemAtIndex(0));
1004 return true;
1005 };
1006
1007 asi->ForEach(flatten_asi_dict);
1008
1009 return dict_sp;
1010}
1011
1013 Target *target, std::vector<std::string> &options, XcodeSDK::Type sdk_type) {
1014 const std::vector<std::string> apple_arguments = {
1015 "-x", "objective-c++", "-fobjc-arc",
1016 "-fblocks", "-D_ISO646_H", "-D__ISO646_H",
1017 "-fgnuc-version=4.2.1"};
1018
1019 options.insert(options.end(), apple_arguments.begin(), apple_arguments.end());
1020
1021 StreamString minimum_version_option;
1022 bool use_current_os_version = false;
1023 // If the SDK type is for the host OS, use its version number.
1024 auto get_host_os = []() { return HostInfo::GetTargetTriple().getOS(); };
1025 switch (sdk_type) {
1027 use_current_os_version = get_host_os() == llvm::Triple::MacOSX;
1028 break;
1030 use_current_os_version = get_host_os() == llvm::Triple::IOS;
1031 break;
1033 use_current_os_version = get_host_os() == llvm::Triple::TvOS;
1034 break;
1036 use_current_os_version = get_host_os() == llvm::Triple::WatchOS;
1037 break;
1039 use_current_os_version = get_host_os() == llvm::Triple::XROS;
1040 break;
1041 default:
1042 break;
1043 }
1044
1045 llvm::VersionTuple version;
1046 if (use_current_os_version)
1047 version = GetOSVersion();
1048 else if (target) {
1049 // Our OS doesn't match our executable so we need to get the min OS version
1050 // from the object file
1051 ModuleSP exe_module_sp = target->GetExecutableModule();
1052 if (exe_module_sp) {
1053 ObjectFile *object_file = exe_module_sp->GetObjectFile();
1054 if (object_file)
1055 version = object_file->GetMinimumOSVersion();
1056 }
1057 }
1058 // Only add the version-min options if we got a version from somewhere.
1059 // clang has no version-min clang flag for XROS.
1060 if (!version.empty() && sdk_type != XcodeSDK::Type::Linux &&
1061 sdk_type != XcodeSDK::Type::XROS) {
1062#define OPTION(PREFIX, NAME, VAR, ...) \
1063 llvm::StringRef opt_##VAR = NAME; \
1064 (void)opt_##VAR;
1065#include "clang/Driver/Options.inc"
1066#undef OPTION
1067 minimum_version_option << '-';
1068 switch (sdk_type) {
1070 minimum_version_option << opt_mmacos_version_min_EQ;
1071 break;
1073 minimum_version_option << opt_mios_simulator_version_min_EQ;
1074 break;
1076 minimum_version_option << opt_mios_version_min_EQ;
1077 break;
1079 minimum_version_option << opt_mtvos_simulator_version_min_EQ;
1080 break;
1082 minimum_version_option << opt_mtvos_version_min_EQ;
1083 break;
1085 minimum_version_option << opt_mwatchos_simulator_version_min_EQ;
1086 break;
1088 minimum_version_option << opt_mwatchos_version_min_EQ;
1089 break;
1092 // FIXME: Pass the right argument once it exists.
1096 if (Log *log = GetLog(LLDBLog::Host)) {
1097 XcodeSDK::Info info;
1098 info.type = sdk_type;
1099 LLDB_LOGF(log, "Clang modules on %s are not supported",
1100 XcodeSDK::GetCanonicalName(info).c_str());
1101 }
1102 return;
1103 }
1104 minimum_version_option << version.getAsString();
1105 options.emplace_back(std::string(minimum_version_option.GetString()));
1106 }
1107
1108 FileSpec sysroot_spec;
1109
1110 if (target) {
1111 if (ModuleSP exe_module_sp = target->GetExecutableModule()) {
1112 auto path_or_err = ResolveSDKPathFromDebugInfo(*exe_module_sp);
1113 if (path_or_err) {
1114 sysroot_spec = FileSpec(*path_or_err);
1115 } else {
1117 path_or_err.takeError(),
1118 "Failed to resolve SDK path: {0}");
1119 }
1120 }
1121 }
1122
1123 if (!FileSystem::Instance().IsDirectory(sysroot_spec.GetPath())) {
1124 std::lock_guard<std::mutex> guard(m_mutex);
1125 sysroot_spec = GetSDKDirectoryForModules(sdk_type);
1126 }
1127
1128 if (FileSystem::Instance().IsDirectory(sysroot_spec.GetPath())) {
1129 options.push_back("-isysroot");
1130 options.push_back(sysroot_spec.GetPath());
1131 }
1132}
1133
1135 if (basename.IsEmpty())
1136 return basename;
1137
1138 StreamString stream;
1139 stream.Printf("lib%s.dylib", basename.GetCString());
1140 return ConstString(stream.GetString());
1141}
1142
1143llvm::VersionTuple PlatformDarwin::GetOSVersion(Process *process) {
1144 if (process && GetPluginName().contains("-simulator")) {
1146 if (Host::GetProcessInfo(process->GetID(), proc_info)) {
1147 const Environment &env = proc_info.GetEnvironment();
1148
1149 llvm::VersionTuple result;
1150 if (!result.tryParse(env.lookup("SIMULATOR_RUNTIME_VERSION")))
1151 return result;
1152
1153 std::string dyld_root_path = env.lookup("DYLD_ROOT_PATH");
1154 if (!dyld_root_path.empty()) {
1155 dyld_root_path += "/System/Library/CoreServices/SystemVersion.plist";
1156 ApplePropertyList system_version_plist(dyld_root_path.c_str());
1157 std::string product_version;
1158 if (system_version_plist.GetValueAsString("ProductVersion",
1159 product_version)) {
1160 if (!result.tryParse(product_version))
1161 return result;
1162 }
1163 }
1164 }
1165 // For simulator platforms, do NOT call back through
1166 // Platform::GetOSVersion() as it might call Process::GetHostOSVersion()
1167 // which we don't want as it will be incorrect
1168 return llvm::VersionTuple();
1169 }
1170
1171 return Platform::GetOSVersion(process);
1172}
1173
1175 // A collection of SBFileSpec whose SBFileSpec.m_directory members are filled
1176 // in with any executable directories that should be searched.
1177 static std::vector<FileSpec> g_executable_dirs;
1178
1179 // Find the global list of directories that we will search for executables
1180 // once so we don't keep doing the work over and over.
1181 static llvm::once_flag g_once_flag;
1182 llvm::call_once(g_once_flag, []() {
1183
1184 // When locating executables, trust the DEVELOPER_DIR first if it is set
1185 FileSpec xcode_contents_dir = HostInfo::GetXcodeContentsDirectory();
1186 if (xcode_contents_dir) {
1187 FileSpec xcode_lldb_resources = xcode_contents_dir;
1188 xcode_lldb_resources.AppendPathComponent("SharedFrameworks");
1189 xcode_lldb_resources.AppendPathComponent("LLDB.framework");
1190 xcode_lldb_resources.AppendPathComponent("Resources");
1191 if (FileSystem::Instance().Exists(xcode_lldb_resources)) {
1192 FileSpec dir;
1193 dir.SetDirectory(xcode_lldb_resources.GetPathAsConstString());
1194 g_executable_dirs.push_back(dir);
1195 }
1196 }
1197 // Xcode might not be installed so we also check for the Command Line Tools.
1198 FileSpec command_line_tools_dir = GetCommandLineToolsLibraryPath();
1199 if (command_line_tools_dir) {
1200 FileSpec cmd_line_lldb_resources = command_line_tools_dir;
1201 cmd_line_lldb_resources.AppendPathComponent("PrivateFrameworks");
1202 cmd_line_lldb_resources.AppendPathComponent("LLDB.framework");
1203 cmd_line_lldb_resources.AppendPathComponent("Resources");
1204 if (FileSystem::Instance().Exists(cmd_line_lldb_resources)) {
1205 FileSpec dir;
1206 dir.SetDirectory(cmd_line_lldb_resources.GetPathAsConstString());
1207 g_executable_dirs.push_back(dir);
1208 }
1209 }
1210 });
1211
1212 // Now search the global list of executable directories for the executable we
1213 // are looking for
1214 for (const auto &executable_dir : g_executable_dirs) {
1215 FileSpec executable_file;
1216 executable_file.SetDirectory(executable_dir.GetDirectory());
1217 executable_file.SetFilename(basename);
1218 if (FileSystem::Instance().Exists(executable_file))
1219 return executable_file;
1220 }
1221
1222 return FileSpec();
1223}
1224
1227 // Starting in Fall 2016 OSes, NSLog messages only get mirrored to stderr if
1228 // the OS_ACTIVITY_DT_MODE environment variable is set. (It doesn't require
1229 // any specific value; rather, it just needs to exist). We will set it here
1230 // as long as the IDE_DISABLED_OS_ACTIVITY_DT_MODE flag is not set. Xcode
1231 // makes use of IDE_DISABLED_OS_ACTIVITY_DT_MODE to tell
1232 // LLDB *not* to muck with the OS_ACTIVITY_DT_MODE flag when they
1233 // specifically want it unset.
1234 const char *disable_env_var = "IDE_DISABLED_OS_ACTIVITY_DT_MODE";
1235 auto &env_vars = launch_info.GetEnvironment();
1236 if (!env_vars.count(disable_env_var)) {
1237 // We want to make sure that OS_ACTIVITY_DT_MODE is set so that we get
1238 // os_log and NSLog messages mirrored to the target process stderr.
1239 env_vars.try_emplace("OS_ACTIVITY_DT_MODE", "enable");
1240 }
1241
1242 // Let our parent class do the real launching.
1243 return PlatformPOSIX::LaunchProcess(launch_info);
1244}
1245
1247 const ModuleSpec &module_spec, Process *process, ModuleSP &module_sp,
1248 const FileSpecList *module_search_paths_ptr,
1249 llvm::SmallVectorImpl<ModuleSP> *old_modules, bool *did_create_ptr) {
1250 const FileSpec &platform_file = module_spec.GetFileSpec();
1251 // See if the file is present in any of the module_search_paths_ptr
1252 // directories.
1253 if (!module_sp && module_search_paths_ptr && platform_file) {
1254 // create a vector of all the file / directory names in platform_file e.g.
1255 // this might be
1256 // /System/Library/PrivateFrameworks/UIFoundation.framework/UIFoundation
1257 //
1258 // We'll need to look in the module_search_paths_ptr directories for both
1259 // "UIFoundation" and "UIFoundation.framework" -- most likely the latter
1260 // will be the one we find there.
1261
1262 std::vector<llvm::StringRef> path_parts = platform_file.GetComponents();
1263 // We want the components in reverse order.
1264 std::reverse(path_parts.begin(), path_parts.end());
1265 const size_t path_parts_size = path_parts.size();
1266
1267 size_t num_module_search_paths = module_search_paths_ptr->GetSize();
1268 for (size_t i = 0; i < num_module_search_paths; ++i) {
1269 Log *log_verbose = GetLog(LLDBLog::Host);
1270 LLDB_LOGF(
1271 log_verbose,
1272 "PlatformRemoteDarwinDevice::GetSharedModule searching for binary in "
1273 "search-path %s",
1274 module_search_paths_ptr->GetFileSpecAtIndex(i).GetPath().c_str());
1275 // Create a new FileSpec with this module_search_paths_ptr plus just the
1276 // filename ("UIFoundation"), then the parent dir plus filename
1277 // ("UIFoundation.framework/UIFoundation") etc - up to four names (to
1278 // handle "Foo.framework/Contents/MacOS/Foo")
1279
1280 for (size_t j = 0; j < 4 && j < path_parts_size - 1; ++j) {
1281 FileSpec path_to_try(module_search_paths_ptr->GetFileSpecAtIndex(i));
1282
1283 // Add the components backwards. For
1284 // .../PrivateFrameworks/UIFoundation.framework/UIFoundation path_parts
1285 // is
1286 // [0] UIFoundation
1287 // [1] UIFoundation.framework
1288 // [2] PrivateFrameworks
1289 //
1290 // and if 'j' is 2, we want to append path_parts[1] and then
1291 // path_parts[0], aka 'UIFoundation.framework/UIFoundation', to the
1292 // module_search_paths_ptr path.
1293
1294 for (int k = j; k >= 0; --k) {
1295 path_to_try.AppendPathComponent(path_parts[k]);
1296 }
1297
1298 if (FileSystem::Instance().Exists(path_to_try)) {
1299 ModuleSpec new_module_spec(module_spec);
1300 new_module_spec.GetFileSpec() = path_to_try;
1301 Status new_error(
1302 Platform::GetSharedModule(new_module_spec, process, module_sp,
1303 nullptr, old_modules, did_create_ptr));
1304
1305 if (module_sp) {
1306 module_sp->SetPlatformFileSpec(path_to_try);
1307 return new_error;
1308 }
1309 }
1310 }
1311 }
1312 }
1313 return Status();
1314}
1315
1316std::string PlatformDarwin::FindComponentInPath(llvm::StringRef path,
1317 llvm::StringRef component) {
1318 auto begin = llvm::sys::path::begin(path);
1319 auto end = llvm::sys::path::end(path);
1320 for (auto it = begin; it != end; ++it) {
1321 if (it->contains(component)) {
1322 llvm::SmallString<128> buffer;
1323 llvm::sys::path::append(buffer, begin, ++it,
1324 llvm::sys::path::Style::posix);
1325 return buffer.str().str();
1326 }
1327 }
1328 return {};
1329}
1330
1332 if (FileSpec fspec = HostInfo::GetShlibDir())
1333 return FileSpec(FindComponentInPath(fspec.GetPath(), ".xctoolchain"));
1334 return {};
1335}
1336
1338 if (FileSpec fspec = HostInfo::GetShlibDir())
1339 return FileSpec(FindComponentInPath(fspec.GetPath(), "CommandLineTools"));
1340 return {};
1341}
1342
1343llvm::Triple::OSType PlatformDarwin::GetHostOSType() {
1344#if !defined(__APPLE__)
1345 return llvm::Triple::MacOSX;
1346#else
1347#if TARGET_OS_OSX
1348 return llvm::Triple::MacOSX;
1349#elif TARGET_OS_IOS
1350 return llvm::Triple::IOS;
1351#elif TARGET_OS_WATCH
1352 return llvm::Triple::WatchOS;
1353#elif TARGET_OS_TV
1354 return llvm::Triple::TvOS;
1355#elif TARGET_OS_BRIDGE
1356 return llvm::Triple::BridgeOS;
1357#elif TARGET_OS_XR
1358 return llvm::Triple::XROS;
1359#else
1360#error "LLDB being compiled for an unrecognized Darwin OS"
1361#endif
1362#endif // __APPLE__
1363}
1364
1365llvm::Expected<std::pair<XcodeSDK, bool>>
1367 SymbolFile *sym_file = module.GetSymbolFile();
1368 if (!sym_file)
1369 return llvm::createStringError(
1370 llvm::inconvertibleErrorCode(),
1371 llvm::formatv("No symbol file available for module '{0}'",
1372 module.GetFileSpec().GetFilename().AsCString("")));
1373
1374 bool found_public_sdk = false;
1375 bool found_internal_sdk = false;
1376 XcodeSDK merged_sdk;
1377 for (unsigned i = 0; i < sym_file->GetNumCompileUnits(); ++i) {
1378 if (auto cu_sp = sym_file->GetCompileUnitAtIndex(i)) {
1379 auto cu_sdk = sym_file->ParseXcodeSDK(*cu_sp);
1380 bool is_internal_sdk = cu_sdk.IsAppleInternalSDK();
1381 found_public_sdk |= !is_internal_sdk;
1382 found_internal_sdk |= is_internal_sdk;
1383
1384 merged_sdk.Merge(cu_sdk);
1385 }
1386 }
1387
1388 const bool found_mismatch = found_internal_sdk && found_public_sdk;
1389
1390 return std::pair{std::move(merged_sdk), found_mismatch};
1391}
1392
1393llvm::Expected<std::string>
1395 auto sdk_or_err = GetSDKPathFromDebugInfo(module);
1396 if (!sdk_or_err)
1397 return llvm::createStringError(
1398 llvm::inconvertibleErrorCode(),
1399 llvm::formatv("Failed to parse SDK path from debug-info: {0}",
1400 llvm::toString(sdk_or_err.takeError())));
1401
1402 auto [sdk, _] = std::move(*sdk_or_err);
1403
1404 auto path_or_err = HostInfo::GetSDKRoot(HostInfo::SDKOptions{sdk});
1405 if (!path_or_err)
1406 return llvm::createStringError(
1407 llvm::inconvertibleErrorCode(),
1408 llvm::formatv("Error while searching for SDK (XcodeSDK '{0}'): {1}",
1409 sdk.GetString(),
1410 llvm::toString(path_or_err.takeError())));
1411
1412 return path_or_err->str();
1413}
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:342
#define LLDB_LOGF(log,...)
Definition: Log.h:349
#define LLDB_LOG_ERROR(log, error,...)
Definition: Log.h:365
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:302
const char * GetCString() const
Get the string value as a C string.
Definition: ConstString.h:214
A class to manage flag bits.
Definition: Debugger.h:79
lldb::ScriptLanguage GetScriptLanguage() const
Definition: Debugger.cpp:345
ScriptInterpreter * GetScriptInterpreter(bool can_create=true, std::optional< lldb::ScriptLanguage > language={})
Definition: Debugger.cpp:1652
A file collection class.
Definition: FileSpecList.h:85
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:146
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:992
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:621
virtual FileSpec & GetFileSpec()
Get accessor to the object file specification.
Definition: ObjectFile.h:274
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.
static llvm::Expected< std::pair< XcodeSDK, bool > > GetSDKPathFromDebugInfo(Module &module)
Search each CU associated with the specified 'module' for the SDK paths the CUs were compiled against...
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)
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.
static llvm::Expected< std::string > ResolveSDKPathFromDebugInfo(Module &module)
Returns the full path of the most appropriate SDK for the specified 'module'.
void x86GetSupportedArchitectures(std::vector< ArchSpec > &archs)
bool ModuleIsExcludedForUnconstrainedSearches(Target &target, const lldb::ModuleSP &module_sp) override
void ARMGetSupportedArchitectures(std::vector< ArchSpec > &archs, std::optional< llvm::Triple::OSType > os={})
The architecture selection rules for arm processors These cpu subtypes have distinct names (e....
std::vector< ConstString > m_trap_handlers
Definition: Platform.h:976
virtual size_t GetSoftwareBreakpointTrapOpcode(Target &target, BreakpointSite *bp_site)
Definition: Platform.cpp:1989
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:1066
static void Terminate()
Definition: Platform.cpp:138
const ArchSpec & GetSystemArchitecture()
Definition: Platform.cpp:883
virtual llvm::VersionTuple GetOSVersion(Process *process=nullptr)
Get the OS version from a connected platform.
Definition: Platform.cpp:331
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:1000
static void Initialize()
Definition: Platform.cpp:136
std::mutex m_mutex
Definition: Platform.h:966
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:198
bool IsRemote() const
Definition: Platform.h:460
bool IsHost() const
Definition: Platform.h:456
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:87
const FileSpec & GetShell() const
static void NoOpMonitorCallback(lldb::pid_t pid, int signal, int status)
A Monitor callback which does not take any action on process events.
void SetMonitorProcessCallback(Host::MonitorChildProcessCallback callback)
A plug-in interface definition class for debugging a process.
Definition: Process.h:340
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:537
size_t ReadMemoryFromInferior(lldb::addr_t vm_addr, void *buf, size_t size, Status &error)
Read of memory from a process.
Definition: Process.cpp:2050
virtual StructuredData::DictionarySP GetMetadata()
Fetch process defined metadata.
Definition: Process.h:2568
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:2004
Target & GetTarget()
Get the target object pointer for this module.
Definition: Process.h:1276
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:279
const char * GetData() const
Definition: StreamString.h:43
llvm::StringRef GetString() const
A stream class that can stream formatted output to a file.
Definition: Stream.h:28
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition: Stream.cpp: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:1055
lldb::ModuleSP GetExecutableModule()
Gets the module for the main executable.
Definition: Target.cpp:1422
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:395
const ModuleList & GetImages() const
Get accessor for the images for this process.
Definition: Target.h:972
const ArchSpec & GetArchitecture() const
Definition: Target.h:1014
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.
Definition: SBAttachInfo.h:14
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
Definition: Log.h:314
Definition: SBAddress.h:15
@ eScriptLanguagePython
std::shared_ptr< lldb_private::BreakpointLocation > BreakpointLocationSP
Definition: lldb-forward.h:316
std::shared_ptr< lldb_private::Platform > PlatformSP
Definition: lldb-forward.h:380
@ eLanguageTypeUnknown
Unknown or invalid language value.
std::shared_ptr< lldb_private::Breakpoint > BreakpointSP
Definition: lldb-forward.h:313
std::shared_ptr< lldb_private::Process > ProcessSP
Definition: lldb-forward.h:381
std::shared_ptr< lldb_private::Section > SectionSP
Definition: lldb-forward.h:406
uint64_t addr_t
Definition: lldb-types.h:79
std::shared_ptr< lldb_private::Module > ModuleSP
Definition: lldb-forward.h:365
A parsed SDK directory name.
Definition: XcodeSDK.h:46
#define PATH_MAX