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