[Lldb-commits] [lldb] r277789 - Change the indexing done for kernel/kext directories to be recursive.

Jason Molenda via lldb-commits lldb-commits at lists.llvm.org
Thu Aug 4 17:44:34 PDT 2016


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;




More information about the lldb-commits mailing list