11 #if defined(__APPLE__) // This Plugin uses the Mac-specific
35 #include "llvm/Support/FileSystem.h"
37 #include <CoreFoundation/CoreFoundation.h>
50 void PlatformDarwinKernel::Initialize() {
51 PlatformDarwin::Initialize();
54 PluginManager::RegisterPlugin(PlatformDarwinKernel::GetPluginNameStatic(),
55 PlatformDarwinKernel::GetDescriptionStatic(),
56 PlatformDarwinKernel::CreateInstance,
57 PlatformDarwinKernel::DebuggerInitialize);
61 void PlatformDarwinKernel::Terminate() {
64 PluginManager::UnregisterPlugin(PlatformDarwinKernel::CreateInstance);
68 PlatformDarwin::Terminate();
71 PlatformSP PlatformDarwinKernel::CreateInstance(
bool force,
75 const char *arch_name;
81 const char *triple_cstr =
82 arch ? arch->
GetTriple().getTriple().c_str() :
"<null>";
84 LLDB_LOGF(log,
"PlatformDarwinKernel::%s(force=%s, arch={%s,%s})",
85 __FUNCTION__, force ?
"true" :
"false", arch_name, triple_cstr);
94 "PlatformDarwinKernel::%s() aborting creation of platform "
95 "because force == false",
103 if (!create && arch && arch->
IsValid()) {
104 const llvm::Triple &triple = arch->
GetTriple();
105 switch (triple.getVendor()) {
106 case llvm::Triple::Apple:
112 case llvm::Triple::UnknownVendor:
120 switch (triple.getOS()) {
121 case llvm::Triple::Darwin:
122 case llvm::Triple::MacOSX:
123 case llvm::Triple::IOS:
124 case llvm::Triple::WatchOS:
125 case llvm::Triple::TvOS:
130 case llvm::Triple::UnknownOS:
141 case llvm::Triple::x86:
142 case llvm::Triple::x86_64:
143 case llvm::Triple::ppc:
144 case llvm::Triple::ppc64:
147 case llvm::Triple::arm:
148 case llvm::Triple::aarch64:
149 case llvm::Triple::thumb:
158 LLDB_LOGF(log,
"PlatformDarwinKernel::%s() creating platform",
164 LLDB_LOGF(log,
"PlatformDarwinKernel::%s() aborting creation of platform",
170 llvm::StringRef PlatformDarwinKernel::GetDescriptionStatic() {
171 return "Darwin Kernel platform plug-in.";
176 #define LLDB_PROPERTIES_platformdarwinkernel
177 #include "PlatformMacOSXProperties.inc"
180 #define LLDB_PROPERTIES_platformdarwinkernel
181 #include "PlatformMacOSXPropertiesEnum.inc"
184 class PlatformDarwinKernelProperties :
public Properties {
187 static ConstString g_setting_name(
"darwin-kernel");
188 return g_setting_name;
191 PlatformDarwinKernelProperties() :
Properties() {
192 m_collection_sp = std::make_shared<OptionValueProperties>(GetSettingName());
193 m_collection_sp->Initialize(g_platformdarwinkernel_properties);
196 ~PlatformDarwinKernelProperties()
override =
default;
198 FileSpecList GetKextDirectories()
const {
199 const uint32_t idx = ePropertyKextDirectories;
201 m_collection_sp->GetPropertyAtIndexAsOptionValueFileSpecList(
203 assert(option_value);
209 static PlatformDarwinKernelProperties g_settings;
213 void PlatformDarwinKernel::DebuggerInitialize(
215 if (!PluginManager::GetSettingForPlatformPlugin(
216 debugger, PlatformDarwinKernelProperties::GetSettingName())) {
217 const bool is_global_setting =
true;
218 PluginManager::CreateSettingForPlatformPlugin(
220 ConstString(
"Properties for the PlatformDarwinKernel plug-in."),
226 PlatformDarwinKernel::PlatformDarwinKernel(
229 m_name_to_kext_path_map_with_dsyms(),
230 m_name_to_kext_path_map_without_dsyms(), m_search_directories(),
231 m_search_directories_no_recursing(), m_kernel_binaries_with_dsyms(),
232 m_kernel_binaries_without_dsyms(), m_kernel_dsyms_no_binaries(),
233 m_kernel_dsyms_yaas(), m_ios_debug_session(is_ios_debug_session)
236 CollectKextAndKernelDirectories();
237 SearchForKextsAndKernelsRecursively();
244 PlatformDarwinKernel::~PlatformDarwinKernel() =
default;
246 void PlatformDarwinKernel::GetStatus(
Stream &strm) {
248 strm.
Printf(
" Debug session type: ");
250 strm.
Printf(
"iOS kernel debugging\n");
252 strm.
Printf(
"Mac OS X kernel debugging\n");
254 strm.
Printf(
"unknown kernel debugging\n");
256 strm.
Printf(
"Directories searched recursively:\n");
257 const uint32_t num_kext_dirs = m_search_directories.size();
258 for (
uint32_t i = 0; i < num_kext_dirs; ++i) {
259 strm.
Printf(
"[%d] %s\n", i, m_search_directories[i].GetPath().c_str());
262 strm.
Printf(
"Directories not searched recursively:\n");
263 const uint32_t num_kext_dirs_no_recursion =
264 m_search_directories_no_recursing.size();
265 for (
uint32_t i = 0; i < num_kext_dirs_no_recursion; i++) {
266 strm.
Printf(
"[%d] %s\n", i,
267 m_search_directories_no_recursing[i].GetPath().c_str());
270 strm.
Printf(
" Number of kexts with dSYMs indexed: %d\n",
271 (
int)m_name_to_kext_path_map_with_dsyms.size());
272 strm.
Printf(
" Number of kexts without dSYMs indexed: %d\n",
273 (
int)m_name_to_kext_path_map_without_dsyms.size());
274 strm.
Printf(
" Number of Kernel binaries with dSYMs indexed: %d\n",
275 (
int)m_kernel_binaries_with_dsyms.size());
276 strm.
Printf(
" Number of Kernel binaries without dSYMs indexed: %d\n",
277 (
int)m_kernel_binaries_without_dsyms.size());
278 strm.
Printf(
" Number of Kernel dSYMs with no binaries indexed: %d\n",
279 (
int)m_kernel_dsyms_no_binaries.size());
280 strm.
Printf(
" Number of Kernel dSYM.yaa's indexed: %d\n",
281 (
int)m_kernel_dsyms_yaas.size());
286 for (
auto pos : m_name_to_kext_path_map_with_dsyms) {
287 LLDB_LOGF(log,
"%s", pos.second.GetPath().c_str());
291 for (
auto pos : m_name_to_kext_path_map_without_dsyms) {
292 LLDB_LOGF(log,
"%s", pos.second.GetPath().c_str());
294 LLDB_LOGF(log,
"\nkernel binaries with dSYMS");
295 for (
auto fs : m_kernel_binaries_with_dsyms) {
296 LLDB_LOGF(log,
"%s", fs.GetPath().c_str());
298 LLDB_LOGF(log,
"\nkernel binaries without dSYMS");
299 for (
auto fs : m_kernel_binaries_without_dsyms) {
300 LLDB_LOGF(log,
"%s", fs.GetPath().c_str());
302 LLDB_LOGF(log,
"\nkernel dSYMS with no binaries");
303 for (
auto fs : m_kernel_dsyms_no_binaries) {
304 LLDB_LOGF(log,
"%s", fs.GetPath().c_str());
307 for (
auto fs : m_kernel_dsyms_yaas) {
308 LLDB_LOGF(log,
"%s", fs.GetPath().c_str());
317 void PlatformDarwinKernel::CollectKextAndKernelDirectories() {
325 std::string developer_dir = HostInfo::GetXcodeDeveloperDirectory().GetPath();
326 if (developer_dir.empty())
327 developer_dir =
"/Applications/Xcode.app/Contents/Developer";
330 AddSDKSubdirsToSearchPaths(developer_dir +
331 "/Platforms/iPhoneOS.platform/Developer/SDKs");
332 AddSDKSubdirsToSearchPaths(developer_dir +
333 "/Platforms/AppleTVOS.platform/Developer/SDKs");
334 AddSDKSubdirsToSearchPaths(developer_dir +
335 "/Platforms/WatchOS.platform/Developer/SDKs");
336 AddSDKSubdirsToSearchPaths(developer_dir +
337 "/Platforms/BridgeOS.platform/Developer/SDKs");
340 AddSDKSubdirsToSearchPaths(developer_dir +
341 "/Platforms/MacOSX.platform/Developer/SDKs");
344 AddSDKSubdirsToSearchPaths(
"/Volumes/KernelDebugKit");
345 AddSDKSubdirsToSearchPaths(
"/AppleInternal/Developer/KDKs");
348 AddSDKSubdirsToSearchPaths(
"/Library/Developer/KDKs");
353 AddRootSubdirsToSearchPaths(
this,
"/");
356 GetUserSpecifiedDirectoriesToSearch();
359 FileSpec possible_dir(developer_dir +
"/../Symbols");
362 m_search_directories.push_back(possible_dir);
367 m_search_directories_no_recursing.push_back(cwd);
370 void PlatformDarwinKernel::GetUserSpecifiedDirectoriesToSearch() {
372 std::vector<FileSpec> possible_sdk_dirs;
374 const uint32_t user_dirs_count = user_dirs.GetSize();
375 for (
uint32_t i = 0; i < user_dirs_count; i++) {
376 FileSpec dir = user_dirs.GetFileSpecAtIndex(i);
379 m_search_directories.push_back(dir);
384 void PlatformDarwinKernel::AddRootSubdirsToSearchPaths(
386 const char *subdirs[] = {
387 "/System/Library/Extensions",
"/Library/Extensions",
388 "/System/Library/Kernels",
389 "/System/Library/Extensions/KDK",
392 for (
int i = 0; subdirs[i] !=
nullptr; i++) {
396 thisp->m_search_directories.push_back(testdir);
400 thisp->m_search_directories_no_recursing.push_back(
FileSpec(dir +
"/"));
404 void PlatformDarwinKernel::AddSDKSubdirsToSearchPaths(
const std::string &dir) {
406 const bool find_directories =
true;
407 const bool find_files =
false;
408 const bool find_other =
false;
410 dir.c_str(), find_directories, find_files, find_other,
411 FindKDKandSDKDirectoriesInDirectory,
this);
416 PlatformDarwinKernel::FindKDKandSDKDirectoriesInDirectory(
417 void *baton, llvm::sys::fs::file_type ft, llvm::StringRef path) {
423 if (ft == llvm::sys::fs::file_type::directory_file &&
424 (file_spec.GetFileNameExtension() == g_sdk_suffix ||
425 file_spec.GetFileNameExtension() == g_kdk_suffix)) {
426 AddRootSubdirsToSearchPaths(thisp, file_spec.GetPath());
433 void PlatformDarwinKernel::SearchForKextsAndKernelsRecursively() {
434 const uint32_t num_dirs = m_search_directories.size();
435 for (
uint32_t i = 0; i < num_dirs; i++) {
436 const FileSpec &dir = m_search_directories[i];
437 const bool find_directories =
true;
438 const bool find_files =
true;
439 const bool find_other =
true;
441 dir.
GetPath().c_str(), find_directories, find_files, find_other,
442 GetKernelsAndKextsInDirectoryWithRecursion,
this);
444 const uint32_t num_dirs_no_recurse = m_search_directories_no_recursing.size();
445 for (
uint32_t i = 0; i < num_dirs_no_recurse; i++) {
446 const FileSpec &dir = m_search_directories_no_recursing[i];
447 const bool find_directories =
true;
448 const bool find_files =
true;
449 const bool find_other =
true;
451 dir.
GetPath().c_str(), find_directories, find_files, find_other,
452 GetKernelsAndKextsInDirectoryNoRecursion,
this);
465 PlatformDarwinKernel::GetKernelsAndKextsInDirectoryWithRecursion(
466 void *baton, llvm::sys::fs::file_type ft, llvm::StringRef path) {
467 return GetKernelsAndKextsInDirectoryHelper(baton, ft, path,
true);
471 PlatformDarwinKernel::GetKernelsAndKextsInDirectoryNoRecursion(
472 void *baton, llvm::sys::fs::file_type ft, llvm::StringRef path) {
473 return GetKernelsAndKextsInDirectoryHelper(baton, ft, path,
false);
477 PlatformDarwinKernel::GetKernelsAndKextsInDirectoryHelper(
478 void *baton, llvm::sys::fs::file_type ft, llvm::StringRef path,
485 ConstString file_spec_extension = file_spec.GetFileNameExtension();
489 LLDB_LOGV(log,
"PlatformDarwinKernel examining '{0}'", file_spec);
493 llvm::StringRef filename = file_spec.GetFilename().GetStringRef();
494 bool is_kernel_filename =
495 filename.startswith(
"kernel") || filename.startswith(
"mach");
496 bool is_dsym_yaa = filename.endswith(
".dSYM.yaa");
498 if (ft == llvm::sys::fs::file_type::regular_file ||
499 ft == llvm::sys::fs::file_type::symlink_file) {
500 if (is_kernel_filename) {
501 if (file_spec_extension != g_dsym_suffix && !is_dsym_yaa) {
502 if (KernelHasdSYMSibling(file_spec)) {
504 "PlatformDarwinKernel registering kernel binary '%s' with "
506 file_spec.GetPath().c_str());
507 thisp->m_kernel_binaries_with_dsyms.push_back(file_spec);
511 "PlatformDarwinKernel registering kernel binary '%s', no dSYM",
512 file_spec.GetPath().c_str());
513 thisp->m_kernel_binaries_without_dsyms.push_back(file_spec);
517 LLDB_LOGF(log,
"PlatformDarwinKernel registering kernel .dSYM.yaa '%s'",
518 file_spec.GetPath().c_str());
519 thisp->m_kernel_dsyms_yaas.push_back(file_spec);
524 if (ft == llvm::sys::fs::file_type::directory_file) {
525 if (file_spec_extension == g_kext_suffix) {
526 AddKextToMap(thisp, file_spec);
528 FileSpec contents_plugins(file_spec.GetPath() +
"/Contents/PlugIns");
531 search_here_too = contents_plugins.GetPath();
533 FileSpec plugins(file_spec.GetPath() +
"/PlugIns");
535 search_here_too = plugins.GetPath();
539 if (!search_here_too.empty()) {
540 const bool find_directories =
true;
541 const bool find_files =
false;
542 const bool find_other =
false;
544 search_here_too.c_str(), find_directories, find_files, find_other,
545 recurse ? GetKernelsAndKextsInDirectoryWithRecursion
546 : GetKernelsAndKextsInDirectoryNoRecursion,
552 if (is_kernel_filename && file_spec_extension == g_dsym_suffix) {
553 if (KerneldSYMHasNoSiblingBinary(file_spec)) {
555 "PlatformDarwinKernel registering kernel dSYM '%s' with "
557 file_spec.GetPath().c_str());
558 thisp->m_kernel_dsyms_no_binaries.push_back(file_spec);
566 if (recurse && file_spec_extension != g_dsym_suffix &&
567 file_spec_extension != g_kext_suffix &&
568 file_spec_extension != g_bundle_suffix) {
569 LLDB_LOGV(log,
"PlatformDarwinKernel descending into directory '{0}'",
581 CFStringRef bundle_id(bundle.GetIdentifier());
582 if (bundle_id && CFGetTypeID(bundle_id) == CFStringGetTypeID()) {
584 if (CFStringGetCString(bundle_id, bundle_id_buf,
sizeof(bundle_id_buf),
585 kCFStringEncodingUTF8)) {
587 if (KextHasdSYMSibling(file_spec))
590 "PlatformDarwinKernel registering kext binary '%s' with dSYM "
593 thisp->m_name_to_kext_path_map_with_dsyms.insert(
594 std::pair<ConstString, FileSpec>(bundle_conststr, file_spec));
599 "PlatformDarwinKernel registering kext binary '%s', no dSYM",
601 thisp->m_name_to_kext_path_map_without_dsyms.insert(
602 std::pair<ConstString, FileSpec>(bundle_conststr, file_spec));
613 bool PlatformDarwinKernel::KextHasdSYMSibling(
614 const FileSpec &kext_bundle_filepath) {
615 FileSpec dsym_fspec = kext_bundle_filepath;
629 kext_bundle_filepath.
GetPath() +
"/Contents/MacOS/";
630 deep_bundle_str += executable_name.
AsCString();
631 deep_bundle_str +=
".dSYM";
632 dsym_fspec.
SetFile(deep_bundle_str, FileSpec::Style::native);
641 shallow_bundle_str += executable_name.
AsCString();
642 shallow_bundle_str +=
".dSYM";
643 dsym_fspec.
SetFile(shallow_bundle_str, FileSpec::Style::native);
651 bool PlatformDarwinKernel::KernelHasdSYMSibling(
const FileSpec &kernel_binary) {
652 FileSpec kernel_dsym = kernel_binary;
664 bool PlatformDarwinKernel::KerneldSYMHasNoSiblingBinary(
671 FileSpec binary_filespec = kernel_dsym;
683 if (GetDWARFBinaryInDSYMBundle(kernel_dsym).size() > 0)
694 std::vector<FileSpec>
695 PlatformDarwinKernel::GetDWARFBinaryInDSYMBundle(
FileSpec dsym_bundle) {
696 std::vector<FileSpec> results;
707 binary_filepath +=
"/Contents/Resources/DWARF/";
708 binary_filepath += filename;
710 FileSpec binary_fspec(binary_filepath);
712 results.push_back(binary_fspec);
716 Status PlatformDarwinKernel::GetSharedModule(
718 const FileSpecList *module_search_paths_ptr,
729 if (kext_bundle_id ==
"mach_kernel") {
730 return GetSharedModuleKernel(module_spec, process, module_sp,
731 module_search_paths_ptr, old_modules,
734 return GetSharedModuleKext(module_spec, process, module_sp,
735 module_search_paths_ptr, old_modules,
742 module_search_paths_ptr, old_modules,
747 Status PlatformDarwinKernel::GetSharedModuleKext(
749 const FileSpecList *module_search_paths_ptr,
759 if (m_name_to_kext_path_map_with_dsyms.count(kext_bundle) > 0) {
760 for (BundleIDToKextIterator it = m_name_to_kext_path_map_with_dsyms.begin();
761 it != m_name_to_kext_path_map_with_dsyms.end(); ++it) {
762 if (it->first == kext_bundle) {
763 error = ExamineKextForMatchingUUID(it->second, module_spec.
GetUUID(),
766 if (module_sp.get()) {
776 module_search_paths_ptr, old_modules,
778 if (
error.Success() && module_sp.get()) {
785 Status PlatformDarwinKernel::GetSharedModuleKernel(
787 const FileSpecList *module_search_paths_ptr,
793 for (
auto possible_kernel : m_kernel_binaries_with_dsyms) {
796 kern_spec.GetUUID() = module_spec.
GetUUID();
797 module_sp.reset(
new Module(kern_spec));
798 if (module_sp && module_sp->GetObjectFile() &&
799 module_sp->MatchesModuleSpec(kern_spec)) {
808 if (module_sp && module_sp->GetObjectFile() &&
809 module_sp->GetObjectFile()->GetType() !=
810 ObjectFile::Type::eTypeCoreFile) {
821 for (
auto possible_kernel_dsym : m_kernel_dsyms_no_binaries) {
822 std::vector<FileSpec> objfile_names =
823 GetDWARFBinaryInDSYMBundle(possible_kernel_dsym);
824 for (
FileSpec objfile : objfile_names) {
826 kern_spec.GetUUID() = module_spec.
GetUUID();
827 kern_spec.GetSymbolFileSpec() = possible_kernel_dsym;
829 module_sp.reset(
new Module(kern_spec));
830 if (module_sp && module_sp->GetObjectFile() &&
831 module_sp->MatchesModuleSpec(kern_spec)) {
840 if (module_sp && module_sp->GetObjectFile() &&
841 module_sp->GetObjectFile()->GetType() !=
842 ObjectFile::Type::eTypeCoreFile) {
854 module_search_paths_ptr, old_modules,
856 if (
error.Success() && module_sp.get()) {
863 std::vector<lldb_private::FileSpec>
864 PlatformDarwinKernel::SearchForExecutablesRecursively(
const std::string &dir) {
865 std::vector<FileSpec> executables;
867 for (llvm::sys::fs::recursive_directory_iterator it(dir.c_str(), EC),
869 it != end && !EC; it.increment(EC)) {
870 auto status = it->status();
873 if (llvm::sys::fs::is_regular_file(*status) &&
874 llvm::sys::fs::can_execute(it->path()))
875 executables.emplace_back(it->path());
880 Status PlatformDarwinKernel::ExamineKextForMatchingUUID(
882 const ArchSpec &arch, ModuleSP &exe_module_sp) {
883 for (
const auto &exe_file :
884 SearchForExecutablesRecursively(kext_bundle_path.
GetPath())) {
887 exe_spec.GetUUID() = uuid;
889 exe_spec.GetArchitecture() = arch;
896 ModuleSP module_sp(
new Module(exe_spec));
897 if (module_sp && module_sp->GetObjectFile() &&
898 module_sp->MatchesModuleSpec(exe_spec)) {
901 if (exe_module_sp && exe_module_sp->GetObjectFile()) {
905 exe_module_sp.reset();
912 std::vector<ArchSpec> PlatformDarwinKernel::GetSupportedArchitectures(
913 const ArchSpec &process_host_arch) {
914 std::vector<ArchSpec> result;
915 #if defined(__arm__) || defined(__arm64__) || defined(__aarch64__)
916 ARMGetSupportedArchitectures(result);
918 x86GetSupportedArchitectures(result);
923 void PlatformDarwinKernel::CalculateTrapHandlerSymbolNames() {
924 m_trap_handlers.push_back(
ConstString(
"trap_from_kernel"));
925 m_trap_handlers.push_back(
ConstString(
"hndl_machine_check"));
926 m_trap_handlers.push_back(
ConstString(
"hndl_double_fault"));
927 m_trap_handlers.push_back(
ConstString(
"hndl_allintrs"));
928 m_trap_handlers.push_back(
ConstString(
"hndl_alltraps"));
929 m_trap_handlers.push_back(
ConstString(
"interrupt"));
930 m_trap_handlers.push_back(
ConstString(
"fleh_prefabt"));
931 m_trap_handlers.push_back(
ConstString(
"ExceptionVectorsBase"));
932 m_trap_handlers.push_back(
ConstString(
"ExceptionVectorsTable"));
933 m_trap_handlers.push_back(
ConstString(
"fleh_undef"));
934 m_trap_handlers.push_back(
ConstString(
"fleh_dataabt"));
935 m_trap_handlers.push_back(
ConstString(
"fleh_irq"));
936 m_trap_handlers.push_back(
ConstString(
"fleh_decirq"));
937 m_trap_handlers.push_back(
ConstString(
"fleh_fiq_generic"));
938 m_trap_handlers.push_back(
ConstString(
"fleh_dec"));