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