Author: jmolenda Date: Thu Aug 4 19:44:34 2016 New Revision: 277789 URL: http://llvm.org/viewvc/llvm-project?rev=277789&view=rev Log: Change the indexing done for kernel/kext directories to be recursive. Also re-write how most of the directory indexing is done - as it has grown over the years, it has become a bit of a mess and was overdue for a cleanup.
Most importantly, this allows you to specify a directory with the platform.plugin.darwin-kernel.kext-directories setting and now lldb will search for kexts and kernels in those directories recursively. <rdar://problem/20754467> Modified: lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.h Modified: lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp?rev=277789&r1=277788&r2=277789&view=diff ============================================================================== --- lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp (original) +++ lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp Thu Aug 4 19:44:34 2016 @@ -288,6 +288,7 @@ PlatformDarwinKernel::PlatformDarwinKern m_name_to_kext_path_map_with_dsyms(), m_name_to_kext_path_map_without_dsyms(), m_search_directories(), + m_search_directories_no_recursing(), m_kernel_binaries_with_dsyms(), m_kernel_binaries_without_dsyms(), m_ios_debug_session(is_ios_debug_session) @@ -296,8 +297,7 @@ PlatformDarwinKernel::PlatformDarwinKern if (GetGlobalProperties()->GetSearchForKexts()) { CollectKextAndKernelDirectories (); - IndexKextsInDirectories (); - IndexKernelsInDirectories (); + SearchForKextsAndKernelsRecursively (); } } @@ -322,17 +322,53 @@ PlatformDarwinKernel::GetStatus (Stream else if (m_ios_debug_session == eLazyBoolNo) strm.Printf ("Mac OS X kernel debugging\n"); else - strm.Printf ("unknown kernel debugging\n"); + strm.Printf ("unknown kernel debugging\n"); + + strm.Printf ("Directories searched recursively:\n"); const uint32_t num_kext_dirs = m_search_directories.size(); for (uint32_t i=0; i<num_kext_dirs; ++i) { - const FileSpec &kext_dir = m_search_directories[i]; - strm.Printf (" Kext directories: [%2u] \"%s\"\n", i, kext_dir.GetPath().c_str()); + strm.Printf ("[%d] %s\n", i, m_search_directories[i].GetPath().c_str()); } + + strm.Printf ("Directories not searched recursively:\n"); + const uint32_t num_kext_dirs_no_recursion = m_search_directories_no_recursing.size(); + for (uint32_t i = 0; i < num_kext_dirs_no_recursion; i++) + { + strm.Printf ("[%d] %s\n", i, m_search_directories_no_recursing[i].GetPath().c_str()); + } + strm.Printf (" Number of kexts with dSYMs indexed: %d\n", (int) m_name_to_kext_path_map_with_dsyms.size()); strm.Printf (" Number of kexts without dSYMs indexed: %d\n", (int) m_name_to_kext_path_map_without_dsyms.size()); strm.Printf (" Number of Kernel binaries with dSYMs indexed: %d\n", (int) m_kernel_binaries_with_dsyms.size()); strm.Printf (" Number of Kernel binaries without dSYMs indexed: %d\n", (int) m_kernel_binaries_without_dsyms.size()); + + Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_PLATFORM)); + if (log) + { + log->Printf("\nkexts with dSYMs"); + for (auto pos : m_name_to_kext_path_map_with_dsyms) + { + log->Printf ("%s", pos.second.GetPath().c_str()); + } + log->Printf("\nkexts without dSYMs"); + + for (auto pos : m_name_to_kext_path_map_without_dsyms) + { + log->Printf ("%s", pos.second.GetPath().c_str()); + } + log->Printf("\nkernels with dSYMS"); + for (auto fs : m_kernel_binaries_with_dsyms) + { + log->Printf ("%s", fs.GetPath().c_str()); + } + log->Printf("\nkernels without dSYMS"); + for (auto fs : m_kernel_binaries_without_dsyms) + { + log->Printf ("%s", fs.GetPath().c_str()); + } + log->Printf("\n"); + } } // Populate the m_search_directories vector with directories we should search @@ -345,367 +381,276 @@ PlatformDarwinKernel::CollectKextAndKern // kext bundles that won't be used in this debug session. If this is an ios kext debug // session, looking in /System/Library/Extensions is a waste of stat()s, for example. - // Build up a list of all SDKs we'll be searching for directories of kexts/kernels - // e.g. /Applications/Xcode.app//Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.Internal.sdk - std::vector<FileSpec> sdk_dirs; + // DeveloperDirectory is something like "/Applications/Xcode.app/Contents/Developer" + std::string developer_dir = GetDeveloperDirectory(); + if (developer_dir.empty()) + developer_dir = "/Applications/Xcode.app/Contents/Developer"; + if (m_ios_debug_session != eLazyBoolNo) { - GetiOSSDKDirectoriesToSearch (sdk_dirs); - GetAppleTVOSSDKDirectoriesToSearch (sdk_dirs); - GetWatchOSSDKDirectoriesToSearch (sdk_dirs); + AddSDKSubdirsToSearchPaths (developer_dir + "/Platforms/iPhoneOS.platform/Developer/SDKs"); + AddSDKSubdirsToSearchPaths (developer_dir + "/Platforms/AppleTVOS.platform/Developer/SDKs"); + AddSDKSubdirsToSearchPaths (developer_dir + "/Platforms/WatchOS.platform/Developer/SDKs"); } if (m_ios_debug_session != eLazyBoolYes) - GetMacSDKDirectoriesToSearch (sdk_dirs); - - GetGenericSDKDirectoriesToSearch (sdk_dirs); - - // Build up a list of directories that hold may kext bundles & kernels - // - // e.g. given /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/ - // find - // /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.Internal.sdk/ - // and - // /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.Internal.sdk/System/Library/Extensions + { + AddSDKSubdirsToSearchPaths (developer_dir + "/Platforms/MacOSX.platform/Developer/SDKs"); + } - std::vector<FileSpec> kext_dirs; - SearchSDKsForKextDirectories (sdk_dirs, kext_dirs); + AddSDKSubdirsToSearchPaths ("/Volumes/KernelDebugKit"); + AddSDKSubdirsToSearchPaths ("/AppleInternal/Developer/KDKs"); + // The KDKs distributed from Apple installed on external + // developer systems may be in directories like + // /Library/Developer/KDKs/KDK_10.10_14A298i.kdk + AddSDKSubdirsToSearchPaths ("/Library/Developer/KDKs"); if (m_ios_debug_session != eLazyBoolNo) - GetiOSDirectoriesToSearch (kext_dirs); + { + } if (m_ios_debug_session != eLazyBoolYes) - GetMacDirectoriesToSearch (kext_dirs); - - GetGenericDirectoriesToSearch (kext_dirs); + { + AddRootSubdirsToSearchPaths (this, "/"); + } - GetUserSpecifiedDirectoriesToSearch (kext_dirs); - GetKernelDirectoriesToSearch (kext_dirs); + GetUserSpecifiedDirectoriesToSearch (); - GetCurrentDirectoryToSearch (kext_dirs); + // Add simple directory /Applications/Xcode.app/Contents/Developer/../Symbols + FileSpec possible_dir (developer_dir + "/../Symbols", true); + if (possible_dir.Exists() && possible_dir.IsDirectory()) + m_search_directories.push_back (possible_dir); - // We now have a complete list of directories that we will search for kext bundles - m_search_directories = kext_dirs; + // Add simple directory of the current working directory + m_search_directories_no_recursing.push_back (FileSpec (".", true)); } void -PlatformDarwinKernel::GetiOSSDKDirectoriesToSearch (std::vector<lldb_private::FileSpec> &directories) +PlatformDarwinKernel::GetUserSpecifiedDirectoriesToSearch () { - // DeveloperDirectory is something like "/Applications/Xcode.app/Contents/Developer" - const char *developer_dir = GetDeveloperDirectory(); - if (developer_dir == NULL) - developer_dir = "/Applications/Xcode.app/Contents/Developer"; + FileSpecList user_dirs(GetGlobalProperties()->GetKextDirectories()); + std::vector<FileSpec> possible_sdk_dirs; - char pathbuf[PATH_MAX]; - ::snprintf (pathbuf, sizeof (pathbuf), "%s/Platforms/iPhoneOS.platform/Developer/SDKs", developer_dir); - FileSpec ios_sdk(pathbuf, true); - if (ios_sdk.Exists() && ios_sdk.IsDirectory()) + const uint32_t user_dirs_count = user_dirs.GetSize(); + for (uint32_t i = 0; i < user_dirs_count; i++) { - directories.push_back (ios_sdk); + FileSpec dir = user_dirs.GetFileSpecAtIndex (i); + dir.ResolvePath(); + if (dir.Exists() && dir.IsDirectory()) + { + m_search_directories.push_back (dir); + } } } void -PlatformDarwinKernel::GetAppleTVOSSDKDirectoriesToSearch (std::vector<lldb_private::FileSpec> &directories) +PlatformDarwinKernel::AddRootSubdirsToSearchPaths (PlatformDarwinKernel *thisp, const std::string &dir) { - // DeveloperDirectory is something like "/Applications/Xcode.app/Contents/Developer" - const char *developer_dir = GetDeveloperDirectory(); - if (developer_dir == NULL) - developer_dir = "/Applications/Xcode.app/Contents/Developer"; - - char pathbuf[PATH_MAX]; - ::snprintf (pathbuf, sizeof (pathbuf), "%s/Platforms/AppleTVOS.platform/Developer/SDKs", developer_dir); - FileSpec ios_sdk(pathbuf, true); - if (ios_sdk.Exists() && ios_sdk.IsDirectory()) + const char *subdirs[] = { + "/System/Library/Extensions", + "/Library/Extensions", + "/System/Library/Kernels", + "/System/Library/Extensions/KDK", // this one probably only exist in /AppleInternal/Developer/KDKs/*.kdk/... + nullptr + }; + for (int i = 0; subdirs[i] != nullptr; i++) { - directories.push_back (ios_sdk); + FileSpec testdir (dir + subdirs[i], true); + if (testdir.Exists() && testdir.IsDirectory()) + thisp->m_search_directories.push_back (testdir); } -} - -void -PlatformDarwinKernel::GetWatchOSSDKDirectoriesToSearch (std::vector<lldb_private::FileSpec> &directories) -{ - // DeveloperDirectory is something like "/Applications/Xcode.app/Contents/Developer" - const char *developer_dir = GetDeveloperDirectory(); - if (developer_dir == NULL) - developer_dir = "/Applications/Xcode.app/Contents/Developer"; - char pathbuf[PATH_MAX]; - ::snprintf (pathbuf, sizeof (pathbuf), "%s/Platforms/watchOS.platform/Developer/SDKs", developer_dir); - FileSpec ios_sdk(pathbuf, true); - if (ios_sdk.Exists() && ios_sdk.IsDirectory()) - { - directories.push_back (ios_sdk); - } - else - { - ::snprintf (pathbuf, sizeof (pathbuf), "%s/Platforms/WatchOS.platform/Developer/SDKs", developer_dir); - FileSpec alt_watch_sdk(pathbuf, true); - if (ios_sdk.Exists() && ios_sdk.IsDirectory()) - { - directories.push_back (ios_sdk); - } - } + // Look for kernel binaries in the top level directory, without any recursion + thisp->m_search_directories_no_recursing.push_back (FileSpec (dir + "/", false)); } - +// Given a directory path dir, look for any subdirs named *.kdk and *.sdk void -PlatformDarwinKernel::GetMacSDKDirectoriesToSearch (std::vector<lldb_private::FileSpec> &directories) +PlatformDarwinKernel::AddSDKSubdirsToSearchPaths (const std::string &dir) { - // DeveloperDirectory is something like "/Applications/Xcode.app/Contents/Developer" - const char *developer_dir = GetDeveloperDirectory(); - if (developer_dir == NULL) - developer_dir = "/Applications/Xcode.app/Contents/Developer"; - - char pathbuf[PATH_MAX]; - ::snprintf (pathbuf, sizeof (pathbuf), "%s/Platforms/MacOSX.platform/Developer/SDKs", developer_dir); - FileSpec mac_sdk(pathbuf, true); - if (mac_sdk.Exists() && mac_sdk.IsDirectory()) - { - directories.push_back (mac_sdk); - } + // Look for *.kdk and *.sdk in dir + const bool find_directories = true; + const bool find_files = false; + const bool find_other = false; + FileSpec::EnumerateDirectory (dir.c_str(), + find_directories, + find_files, + find_other, + FindKDKandSDKDirectoriesInDirectory, + this); } -void -PlatformDarwinKernel::GetGenericSDKDirectoriesToSearch (std::vector<lldb_private::FileSpec> &directories) +// Helper function to find *.sdk and *.kdk directories in a given directory. +FileSpec::EnumerateDirectoryResult +PlatformDarwinKernel::FindKDKandSDKDirectoriesInDirectory (void *baton, + FileSpec::FileType file_type, + const FileSpec &file_spec) { - FileSpec generic_sdk("/AppleInternal/Developer/KDKs", true); - if (generic_sdk.Exists() && generic_sdk.IsDirectory()) - { - directories.push_back (generic_sdk); - } + static ConstString g_sdk_suffix = ConstString ("sdk"); + static ConstString g_kdk_suffix = ConstString ("kdk"); - // The KDKs distributed from Apple installed on external - // developer systems may be in directories like - // /Library/Developer/KDKs/KDK_10.10_14A298i.kdk - FileSpec installed_kdks("/Library/Developer/KDKs", true); - if (installed_kdks.Exists() && installed_kdks.IsDirectory()) + PlatformDarwinKernel *thisp = (PlatformDarwinKernel *) baton; + if (file_type == FileSpec::eFileTypeDirectory + && (file_spec.GetFileNameExtension() == g_sdk_suffix + || file_spec.GetFileNameExtension() == g_kdk_suffix)) { - directories.push_back (installed_kdks); + AddRootSubdirsToSearchPaths (thisp, file_spec.GetPath()); } + return FileSpec::eEnumerateDirectoryResultNext; } +// Recursively search trough m_search_directories looking for +// kext and kernel binaries, adding files found to the appropriate +// lists. void -PlatformDarwinKernel::GetiOSDirectoriesToSearch (std::vector<lldb_private::FileSpec> &directories) -{ -} - -void -PlatformDarwinKernel::GetMacDirectoriesToSearch (std::vector<lldb_private::FileSpec> &directories) +PlatformDarwinKernel::SearchForKextsAndKernelsRecursively () { - FileSpec sle("/System/Library/Extensions", true); - if (sle.Exists() && sle.IsDirectory()) + const uint32_t num_dirs = m_search_directories.size(); + for (uint32_t i = 0; i < num_dirs; i++) { - directories.push_back(sle); + const FileSpec &dir = m_search_directories[i]; + const bool find_directories = true; + const bool find_files = true; + const bool find_other = true; // I think eFileTypeSymbolicLink are "other"s. + FileSpec::EnumerateDirectory (dir.GetPath().c_str(), + find_directories, + find_files, + find_other, + GetKernelsAndKextsInDirectoryWithRecursion, + this); } - - FileSpec le("/Library/Extensions", true); - if (le.Exists() && le.IsDirectory()) + const uint32_t num_dirs_no_recurse = m_search_directories_no_recursing.size(); + for (uint32_t i = 0; i < num_dirs_no_recurse; i++) { - directories.push_back(le); + const FileSpec &dir = m_search_directories_no_recursing[i]; + const bool find_directories = true; + const bool find_files = true; + const bool find_other = true; // I think eFileTypeSymbolicLink are "other"s. + FileSpec::EnumerateDirectory (dir.GetPath().c_str(), + find_directories, + find_files, + find_other, + GetKernelsAndKextsInDirectoryNoRecursion, + this); } - FileSpec kdk("/Volumes/KernelDebugKit", true); - if (kdk.Exists() && kdk.IsDirectory()) - { - directories.push_back(kdk); - } } -void -PlatformDarwinKernel::GetGenericDirectoriesToSearch (std::vector<lldb_private::FileSpec> &directories) -{ - // DeveloperDirectory is something like "/Applications/Xcode.app/Contents/Developer" - const char *developer_dir = GetDeveloperDirectory(); - if (developer_dir == NULL) - developer_dir = "/Applications/Xcode.app/Contents/Developer"; - - char pathbuf[PATH_MAX]; - ::snprintf (pathbuf, sizeof (pathbuf), "%s/../Symbols", developer_dir); - FileSpec symbols_dir (pathbuf, true); - if (symbols_dir.Exists() && symbols_dir.IsDirectory()) - { - directories.push_back (symbols_dir); - } -} +// We're only doing a filename match here. We won't try opening the file to see if it's really +// a kernel or not until we need to find a kernel of a given UUID. There's no cheap way to find +// the UUID of a file (or if it's a Mach-O binary at all) without creating a whole Module for +// the file and throwing it away if it's not wanted. +// +// Recurse into any subdirectories found. -void -PlatformDarwinKernel::GetKernelDirectoriesToSearch (std::vector<lldb_private::FileSpec> &directories) +FileSpec::EnumerateDirectoryResult +PlatformDarwinKernel::GetKernelsAndKextsInDirectoryWithRecursion (void *baton, + FileSpec::FileType file_type, + const FileSpec &file_spec) { - FileSpec system_library_kernels ("/System/Library/Kernels", true); - if (system_library_kernels.Exists() && system_library_kernels.IsDirectory()) - { - directories.push_back (system_library_kernels); - } - FileSpec slek("/System/Library/Extensions/KDK", true); - if (slek.Exists() && slek.IsDirectory()) - { - directories.push_back(slek); - } + return GetKernelsAndKextsInDirectoryHelper (baton, file_type, file_spec, true); } -void -PlatformDarwinKernel::GetCurrentDirectoryToSearch (std::vector<lldb_private::FileSpec> &directories) +FileSpec::EnumerateDirectoryResult +PlatformDarwinKernel::GetKernelsAndKextsInDirectoryNoRecursion (void *baton, + FileSpec::FileType file_type, + const FileSpec &file_spec) { - directories.push_back (FileSpec (".", true)); - - FileSpec sle_directory ("System/Library/Extensions", true); - if (sle_directory.Exists() && sle_directory.IsDirectory()) - { - directories.push_back (sle_directory); - } - - FileSpec le_directory ("Library/Extensions", true); - if (le_directory.Exists() && le_directory.IsDirectory()) - { - directories.push_back (le_directory); - } - - FileSpec slk_directory ("System/Library/Kernels", true); - if (slk_directory.Exists() && slk_directory.IsDirectory()) - { - directories.push_back (slk_directory); - } - FileSpec slek("System/Library/Extensions/KDK", true); - if (slek.Exists() && slek.IsDirectory()) - { - directories.push_back(slek); - } + return GetKernelsAndKextsInDirectoryHelper (baton, file_type, file_spec, false); } -void -PlatformDarwinKernel::GetUserSpecifiedDirectoriesToSearch (std::vector<lldb_private::FileSpec> &directories) -{ - FileSpecList user_dirs(GetGlobalProperties()->GetKextDirectories()); - std::vector<FileSpec> possible_sdk_dirs; +FileSpec::EnumerateDirectoryResult +PlatformDarwinKernel::GetKernelsAndKextsInDirectoryHelper (void *baton, + FileSpec::FileType file_type, + const FileSpec &file_spec, + bool recurse) +{ + static ConstString g_kext_suffix = ConstString ("kext"); + static ConstString g_dsym_suffix = ConstString ("dSYM"); + static ConstString g_bundle_suffix = ConstString ("Bundle"); + ConstString file_spec_extension = file_spec.GetFileNameExtension(); + + Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_PLATFORM)); + if (log) + log->Printf ("PlatformDarwinKernel examining %s", file_spec.GetPath().c_str()); - const uint32_t user_dirs_count = user_dirs.GetSize(); - for (uint32_t i = 0; i < user_dirs_count; i++) + PlatformDarwinKernel *thisp = (PlatformDarwinKernel *) baton; + if (file_type == FileSpec::eFileTypeRegular || file_type == FileSpec::eFileTypeSymbolicLink) { - FileSpec dir = user_dirs.GetFileSpecAtIndex (i); - dir.ResolvePath(); - if (dir.Exists() && dir.IsDirectory()) + ConstString filename = file_spec.GetFilename(); + if ((strncmp (filename.GetCString(), "kernel", 6) == 0 || strncmp (filename.GetCString(), "mach", 4) == 0) + && file_spec_extension != g_dsym_suffix) { - directories.push_back (dir); - possible_sdk_dirs.push_back (dir); // does this directory have a *.sdk or *.kdk that we should look in? - - // Is there a "System/Library/Extensions" subdir of this directory? - std::string dir_sle_path = dir.GetPath(); - dir_sle_path.append ("/System/Library/Extensions"); - FileSpec dir_sle(dir_sle_path.c_str(), true); - if (dir_sle.Exists() && dir_sle.IsDirectory()) - { - directories.push_back (dir_sle); - } - - // Is there a "System/Library/Kernels" subdir of this directory? - std::string dir_slk_path = dir.GetPath(); - dir_slk_path.append ("/System/Library/Kernels"); - FileSpec dir_slk(dir_slk_path.c_str(), true); - if (dir_slk.Exists() && dir_slk.IsDirectory()) - { - directories.push_back (dir_slk); - } - - // Is there a "System/Library/Extensions/KDK" subdir of this directory? - std::string dir_slek_path = dir.GetPath(); - dir_slek_path.append ("/System/Library/Kernels"); - FileSpec dir_slek(dir_slek_path.c_str(), true); - if (dir_slek.Exists() && dir_slek.IsDirectory()) + if (KernelHasdSYMSibling (file_spec)) + thisp->m_kernel_binaries_with_dsyms.push_back (file_spec); + else + thisp->m_kernel_binaries_without_dsyms.push_back (file_spec); + return FileSpec::eEnumerateDirectoryResultNext; + } + } + else if (file_type == FileSpec::eFileTypeDirectory && file_spec_extension == g_kext_suffix) + { + AddKextToMap (thisp, file_spec); + // Look to see if there is a PlugIns subdir with more kexts + FileSpec contents_plugins (file_spec.GetPath() + "/Contents/PlugIns", false); + std::string search_here_too; + if (contents_plugins.Exists() && contents_plugins.IsDirectory()) + { + search_here_too = contents_plugins.GetPath(); + } + else + { + FileSpec plugins (file_spec.GetPath() + "/PlugIns", false); + if (plugins.Exists() && plugins.IsDirectory()) { - directories.push_back (dir_slek); + search_here_too = plugins.GetPath(); } } - } - - SearchSDKsForKextDirectories (possible_sdk_dirs, directories); -} -// Scan through the SDK directories, looking for directories where kexts are likely. -// Add those directories to kext_dirs. -void -PlatformDarwinKernel::SearchSDKsForKextDirectories (std::vector<lldb_private::FileSpec> sdk_dirs, std::vector<lldb_private::FileSpec> &kext_dirs) -{ - const uint32_t num_sdks = sdk_dirs.size(); - for (uint32_t i = 0; i < num_sdks; i++) - { - const FileSpec &sdk_dir = sdk_dirs[i]; - std::string sdk_dir_path = sdk_dir.GetPath(); - if (!sdk_dir_path.empty()) + if (!search_here_too.empty()) { const bool find_directories = true; const bool find_files = false; const bool find_other = false; - FileSpec::EnumerateDirectory (sdk_dir_path.c_str(), + FileSpec::EnumerateDirectory (search_here_too.c_str(), find_directories, find_files, find_other, - GetKextDirectoriesInSDK, - &kext_dirs); + recurse ? GetKernelsAndKextsInDirectoryWithRecursion : GetKernelsAndKextsInDirectoryNoRecursion, + baton); } + return FileSpec::eEnumerateDirectoryResultNext; + } + // Don't recurse into dSYM/kext/bundle directories + if (recurse + && file_spec_extension != g_dsym_suffix + && file_spec_extension != g_kext_suffix + && file_spec_extension != g_bundle_suffix) + { + return FileSpec::eEnumerateDirectoryResultEnter; + } + else + { + return FileSpec::eEnumerateDirectoryResultNext; } } -// Callback for FileSpec::EnumerateDirectory(). -// Step through the entries in a directory like -// /Applications/Xcode.app//Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs -// looking for any subdirectories of the form MacOSX10.8.Internal.sdk/System/Library/Extensions -// Adds these to the vector of FileSpec's. - -FileSpec::EnumerateDirectoryResult -PlatformDarwinKernel::GetKextDirectoriesInSDK (void *baton, - FileSpec::FileType file_type, - const FileSpec &file_spec) +void +PlatformDarwinKernel::AddKextToMap (PlatformDarwinKernel *thisp, const FileSpec &file_spec) { - if (file_type == FileSpec::eFileTypeDirectory - && (file_spec.GetFileNameExtension() == ConstString("sdk") - || file_spec.GetFileNameExtension() == ConstString("kdk"))) + CFCBundle bundle (file_spec.GetPath().c_str()); + CFStringRef bundle_id (bundle.GetIdentifier()); + if (bundle_id && CFGetTypeID (bundle_id) == CFStringGetTypeID ()) { - std::string kext_directory_path = file_spec.GetPath(); - - // Append the raw directory path, e.g. /Library/Developer/KDKs/KDK_10.10_14A298i.kdk - // to the directory search list -- there may be kexts sitting directly - // in that directory instead of being in a System/Library/Extensions subdir. - ((std::vector<lldb_private::FileSpec> *)baton)->push_back(file_spec); - - // Check to see if there is a System/Library/Extensions subdir & add it if it exists - - std::string sle_kext_directory_path (kext_directory_path); - sle_kext_directory_path.append ("/System/Library/Extensions"); - FileSpec sle_kext_directory (sle_kext_directory_path.c_str(), true); - if (sle_kext_directory.Exists() && sle_kext_directory.IsDirectory()) - { - ((std::vector<lldb_private::FileSpec> *)baton)->push_back(sle_kext_directory); - } - - // Check to see if there is a Library/Extensions subdir & add it if it exists - - std::string le_kext_directory_path (kext_directory_path); - le_kext_directory_path.append ("/Library/Extensions"); - FileSpec le_kext_directory (le_kext_directory_path.c_str(), true); - if (le_kext_directory.Exists() && le_kext_directory.IsDirectory()) - { - ((std::vector<lldb_private::FileSpec> *)baton)->push_back(le_kext_directory); - } - - // Check to see if there is a System/Library/Kernels subdir & add it if it exists - std::string slk_kernel_path (kext_directory_path); - slk_kernel_path.append ("/System/Library/Kernels"); - FileSpec slk_kernel_directory (slk_kernel_path.c_str(), true); - if (slk_kernel_directory.Exists() && slk_kernel_directory.IsDirectory()) + char bundle_id_buf[PATH_MAX]; + if (CFStringGetCString (bundle_id, bundle_id_buf, sizeof (bundle_id_buf), kCFStringEncodingUTF8)) { - ((std::vector<lldb_private::FileSpec> *)baton)->push_back(slk_kernel_directory); - } - - // Check to see if there is a System/Library/Extensions/KDK subdir & add it if it exists - std::string slek_kernel_path (kext_directory_path); - slek_kernel_path.append ("/System/Library/Extensions/KDK"); - FileSpec slek_kernel_directory (slek_kernel_path.c_str(), true); - if (slek_kernel_directory.Exists() && slek_kernel_directory.IsDirectory()) - { - ((std::vector<lldb_private::FileSpec> *)baton)->push_back(slek_kernel_directory); + ConstString bundle_conststr(bundle_id_buf); + if (KextHasdSYMSibling (file_spec)) + thisp->m_name_to_kext_path_map_with_dsyms.insert(std::pair<ConstString, FileSpec>(bundle_conststr, file_spec)); + else + thisp->m_name_to_kext_path_map_without_dsyms.insert(std::pair<ConstString, FileSpec>(bundle_conststr, file_spec)); } } - return FileSpec::eEnumerateDirectoryResultNext; } // Given a FileSpec of /dir/dir/foo.kext @@ -767,151 +712,6 @@ PlatformDarwinKernel::KernelHasdSYMSibli return false; } -void -PlatformDarwinKernel::IndexKextsInDirectories () -{ - std::vector<FileSpec> kext_bundles; - - const uint32_t num_dirs = m_search_directories.size(); - for (uint32_t i = 0; i < num_dirs; i++) - { - const FileSpec &dir = m_search_directories[i]; - const bool find_directories = true; - const bool find_files = false; - const bool find_other = false; - FileSpec::EnumerateDirectory (dir.GetPath().c_str(), - find_directories, - find_files, - find_other, - GetKextsInDirectory, - &kext_bundles); - } - - const uint32_t num_kexts = kext_bundles.size(); - for (uint32_t i = 0; i < num_kexts; i++) - { - const FileSpec &kext = kext_bundles[i]; - CFCBundle bundle (kext.GetPath().c_str()); - CFStringRef bundle_id (bundle.GetIdentifier()); - if (bundle_id && CFGetTypeID (bundle_id) == CFStringGetTypeID ()) - { - char bundle_id_buf[PATH_MAX]; - if (CFStringGetCString (bundle_id, bundle_id_buf, sizeof (bundle_id_buf), kCFStringEncodingUTF8)) - { - ConstString bundle_conststr(bundle_id_buf); - if (KextHasdSYMSibling (kext)) - m_name_to_kext_path_map_with_dsyms.insert(std::pair<ConstString, FileSpec>(bundle_conststr, kext)); - else - m_name_to_kext_path_map_without_dsyms.insert(std::pair<ConstString, FileSpec>(bundle_conststr, kext)); - } - } - } -} - -// Callback for FileSpec::EnumerateDirectory(). -// Step through the entries in a directory like /System/Library/Extensions, find .kext bundles, add them -// to the vector of FileSpecs. -// If a .kext bundle has a Contents/PlugIns or PlugIns subdir, search for kexts in there too. - -FileSpec::EnumerateDirectoryResult -PlatformDarwinKernel::GetKextsInDirectory (void *baton, - FileSpec::FileType file_type, - const FileSpec &file_spec) -{ - if (file_type == FileSpec::eFileTypeDirectory && file_spec.GetFileNameExtension() == ConstString("kext")) - { - ((std::vector<lldb_private::FileSpec> *)baton)->push_back(file_spec); - std::string kext_bundle_path = file_spec.GetPath(); - std::string search_here_too; - std::string contents_plugins_path = kext_bundle_path + "/Contents/PlugIns"; - FileSpec contents_plugins (contents_plugins_path.c_str(), false); - if (contents_plugins.Exists() && contents_plugins.IsDirectory()) - { - search_here_too = contents_plugins_path; - } - else - { - std::string plugins_path = kext_bundle_path + "/PlugIns"; - FileSpec plugins (plugins_path.c_str(), false); - if (plugins.Exists() && plugins.IsDirectory()) - { - search_here_too = plugins_path; - } - } - - if (!search_here_too.empty()) - { - const bool find_directories = true; - const bool find_files = false; - const bool find_other = false; - FileSpec::EnumerateDirectory (search_here_too.c_str(), - find_directories, - find_files, - find_other, - GetKextsInDirectory, - baton); - } - } - return FileSpec::eEnumerateDirectoryResultNext; -} - -void -PlatformDarwinKernel::IndexKernelsInDirectories () -{ - std::vector<FileSpec> kernels; - - - const uint32_t num_dirs = m_search_directories.size(); - for (uint32_t i = 0; i < num_dirs; i++) - { - const FileSpec &dir = m_search_directories[i]; - const bool find_directories = false; - const bool find_files = true; - const bool find_other = true; // I think eFileTypeSymbolicLink are "other"s. - FileSpec::EnumerateDirectory (dir.GetPath().c_str(), - find_directories, - find_files, - find_other, - GetKernelsInDirectory, - &kernels); - } - - size_t kernels_size = kernels.size(); - for (size_t i = 0; i < kernels_size; i++) - { - if (KernelHasdSYMSibling (kernels[i])) - m_kernel_binaries_with_dsyms.push_back (kernels[i]); - else - m_kernel_binaries_without_dsyms.push_back (kernels[i]); - } -} - -// Callback for FileSpec::EnumerateDirectory(). -// Step through the entries in a directory like /System/Library/Kernels/, find kernel binaries, -// add them to m_kernel_binaries_with_dsyms and m_kernel_binaries_without_dsyms. - -// We're only doing a filename match here. We won't try opening the file to see if it's really -// a kernel or not until we need to find a kernel of a given UUID. There's no cheap way to find -// the UUID of a file (or if it's a Mach-O binary at all) without creating a whole Module for -// the file and throwing it away if it's not wanted. - -FileSpec::EnumerateDirectoryResult -PlatformDarwinKernel::GetKernelsInDirectory (void *baton, - FileSpec::FileType file_type, - const FileSpec &file_spec) -{ - if (file_type == FileSpec::eFileTypeRegular || file_type == FileSpec::eFileTypeSymbolicLink) - { - ConstString filename = file_spec.GetFilename(); - if (strncmp (filename.GetCString(), "kernel", 6) == 0 - || strncmp (filename.GetCString(), "mach", 4) == 0) - { - ((std::vector<lldb_private::FileSpec> *)baton)->push_back(file_spec); - } - } - return FileSpec::eEnumerateDirectoryResultNext; -} - Error PlatformDarwinKernel::GetSharedModule (const ModuleSpec &module_spec, Modified: lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.h?rev=277789&r1=277788&r2=277789&view=diff ============================================================================== --- lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.h (original) +++ lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.h Thu Aug 4 19:44:34 2016 @@ -115,100 +115,59 @@ protected: typedef DirectoriesSearchedCollection::iterator DirectoriesSearchedIterator; - static lldb_private::FileSpec::EnumerateDirectoryResult - GetKextDirectoriesInSDK (void *baton, - lldb_private::FileSpec::FileType file_type, - const lldb_private::FileSpec &file_spec); - - static lldb_private::FileSpec::EnumerateDirectoryResult - GetKextsInDirectory (void *baton, - lldb_private::FileSpec::FileType file_type, - const lldb_private::FileSpec &file_spec); - - // Populate m_search_directories vector of directories + // Populate m_search_directories and m_search_directories_no_recursing vectors of directories void CollectKextAndKernelDirectories (); - // Directories where we may find iOS SDKs with kext bundles in them void - GetiOSSDKDirectoriesToSearch (std::vector<lldb_private::FileSpec> &directories); + GetUserSpecifiedDirectoriesToSearch (); - // Directories where we may find AppleTVOS SDKs with kext bundles in them - void - GetAppleTVOSSDKDirectoriesToSearch (std::vector<lldb_private::FileSpec> &directories); + static void + AddRootSubdirsToSearchPaths (PlatformDarwinKernel *thisp, const std::string &dir); - // Directories where we may find WatchOS SDKs with kext bundles in them - void - GetWatchOSSDKDirectoriesToSearch (std::vector<lldb_private::FileSpec> &directories); - - // Directories where we may find Mac OS X SDKs with kext bundles in them - void - GetMacSDKDirectoriesToSearch (std::vector<lldb_private::FileSpec> &directories); - - // Directories where we may find Mac OS X or iOS SDKs with kext bundles in them - void - GetGenericSDKDirectoriesToSearch (std::vector<lldb_private::FileSpec> &directories); - - // Directories where we may find iOS kext bundles void - GetiOSDirectoriesToSearch (std::vector<lldb_private::FileSpec> &directories); + AddSDKSubdirsToSearchPaths (const std::string &dir); - // Directories where we may find MacOSX kext bundles - void - GetMacDirectoriesToSearch (std::vector<lldb_private::FileSpec> &directories); + static lldb_private::FileSpec::EnumerateDirectoryResult + FindKDKandSDKDirectoriesInDirectory (void *baton, lldb_private::FileSpec::FileType file_type, const lldb_private::FileSpec &file_spec); - // Directories where we may find iOS or MacOSX kext bundles void - GetGenericDirectoriesToSearch (std::vector<lldb_private::FileSpec> &directories); + SearchForKextsAndKernelsRecursively (); - // Directories specified via the "kext-directories" setting - maybe KDK/SDKs, may be plain directories - void - GetUserSpecifiedDirectoriesToSearch (std::vector<lldb_private::FileSpec> &directories); + static lldb_private::FileSpec::EnumerateDirectoryResult + GetKernelsAndKextsInDirectoryWithRecursion (void *baton, lldb_private::FileSpec::FileType file_type, const lldb_private::FileSpec &file_spec); - void - GetCurrentDirectoryToSearch (std::vector<lldb_private::FileSpec> &directories); + static lldb_private::FileSpec::EnumerateDirectoryResult + GetKernelsAndKextsInDirectoryNoRecursion (void *baton, lldb_private::FileSpec::FileType file_type, const lldb_private::FileSpec &file_spec); - // Directories where we may find kernels exclusively - void - GetKernelDirectoriesToSearch (std::vector<lldb_private::FileSpec> &directories); + static lldb_private::FileSpec::EnumerateDirectoryResult + GetKernelsAndKextsInDirectoryHelper (void *baton, lldb_private::FileSpec::FileType file_type, const lldb_private::FileSpec &file_spec, bool recurse); - // Search through a vector of SDK FileSpecs, add any directories that may contain kexts - // to the vector of kext dir FileSpecs - void - SearchSDKsForKextDirectories (std::vector<lldb_private::FileSpec> sdk_dirs, std::vector<lldb_private::FileSpec> &kext_dirs); + static void + AddKextToMap (PlatformDarwinKernel *thisp, const lldb_private::FileSpec &file_spec); // Returns true if there is a .dSYM bundle next to the kext, or next to the binary inside the kext. - bool + static bool KextHasdSYMSibling (const lldb_private::FileSpec &kext_bundle_filepath); // Returns true if there is a .dSYM bundle next to the kernel - bool + static bool KernelHasdSYMSibling (const lldb_private::FileSpec &kext_bundle_filepath); - // Search through all of the directories passed in, find all .kext bundles in those directories, - // get the CFBundleIDs out of the Info.plists and add the bundle ID and kext path to m_name_to_kext_path_map. - void - IndexKextsInDirectories (); - - // Search through all of the directories passed in, find all kernel binaries in those directories - // (look for "kernel*", "mach.*", assume those are kernels. False positives aren't a huge problem.) - void - IndexKernelsInDirectories (); - - // Callback which iterates over all the files in a given directory, looking for kernel binaries - static lldb_private::FileSpec::EnumerateDirectoryResult - GetKernelsInDirectory (void *baton, - lldb_private::FileSpec::FileType file_type, - const lldb_private::FileSpec &file_spec); - lldb_private::Error ExamineKextForMatchingUUID (const lldb_private::FileSpec &kext_bundle_path, const lldb_private::UUID &uuid, const lldb_private::ArchSpec &arch, lldb::ModuleSP &exe_module_sp); -private: + // Most of the ivars are assembled under FileSpec::EnumerateDirectory calls where the + // function being called for each file/directory must be static. We'll pass a this pointer + // as a baton and access the ivars directly. Toss-up whether this should just be a struct + // at this point. + +public: BundleIDToKextMap m_name_to_kext_path_map_with_dsyms; // multimap of CFBundleID to FileSpec on local filesystem, kexts with dSYMs next to them BundleIDToKextMap m_name_to_kext_path_map_without_dsyms; // multimap of CFBundleID to FileSpec on local filesystem, kexts without dSYMs next to them DirectoriesSearchedCollection m_search_directories; // list of directories we search for kexts/kernels + DirectoriesSearchedCollection m_search_directories_no_recursing; // list of directories we search for kexts/kernels, no recursion KernelBinaryCollection m_kernel_binaries_with_dsyms; // list of kernel binaries we found on local filesystem, without dSYMs next to them KernelBinaryCollection m_kernel_binaries_without_dsyms; // list of kernel binaries we found on local filesystem, with dSYMs next to them lldb_private::LazyBool m_ios_debug_session; _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits