Author: jmolenda
Date: Thu Jan 29 00:20:05 2015
New Revision: 227419

URL: http://llvm.org/viewvc/llvm-project?rev=227419&view=rev
Log:
When starting a kernel debug session (PlatformDarwinKernel), scan
for executable binaries on the local filesystem so the user doesn't
need to provide the path to the correct binary manually.

Also have lldb search for kexts/the kernel in the current working
directory in addition to all the usual places.

<rdar://problem/18126501> 


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=227419&r1=227418&r2=227419&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp 
(original)
+++ lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp Thu Jan 
29 00:20:05 2015
@@ -250,13 +250,16 @@ PlatformDarwinKernel::DebuggerInitialize
 PlatformDarwinKernel::PlatformDarwinKernel (lldb_private::LazyBool 
is_ios_debug_session) :
     PlatformDarwin (false),    // This is a remote platform
     m_name_to_kext_path_map(),
-    m_directories_searched(),
+    m_search_directories(),
+    m_kernel_binaries(),
     m_ios_debug_session(is_ios_debug_session)
 
 {
     if (GetGlobalProperties()->GetSearchForKexts())
     {
-        SearchForKexts ();
+        CollectKextAndKernelDirectories ();
+        IndexKextsInDirectories ();
+        IndexKernelsInDirectories ();
     }
 }
 
@@ -282,23 +285,26 @@ PlatformDarwinKernel::GetStatus (Stream
         strm.Printf ("Mac OS X kernel debugging\n");
     else
             strm.Printf ("unknown kernel debugging\n");
-    const uint32_t num_kext_dirs = m_directories_searched.size();
+    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_directories_searched[i];
+        const FileSpec &kext_dir = m_search_directories[i];
         strm.Printf (" Kext directories: [%2u] \"%s\"\n", i, 
kext_dir.GetPath().c_str());
     }
     strm.Printf (" Total number of kexts indexed: %d\n", (int) 
m_name_to_kext_path_map.size());
 }
 
+// Populate the m_search_directories vector with directories we should search
+// for kernel & kext binaries.
+
 void
-PlatformDarwinKernel::SearchForKexts ()
+PlatformDarwinKernel::CollectKextAndKernelDirectories ()
 {
     // Differentiate between "ios debug session" and "mac debug session" so we 
don't index
     // 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
+    // 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;
     if (m_ios_debug_session != eLazyBoolNo)
@@ -308,8 +314,14 @@ PlatformDarwinKernel::SearchForKexts ()
 
     GetGenericSDKDirectoriesToSearch (sdk_dirs);
 
-    // Build up a list of directories that hold kext bundles on the system
-    // e.g. 
/Applications/Xcode.app//Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.Internal.sdk/System/Library/Extensions
+    // 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
+
     std::vector<FileSpec> kext_dirs;
     SearchSDKsForKextDirectories (sdk_dirs, kext_dirs);
 
@@ -322,10 +334,12 @@ PlatformDarwinKernel::SearchForKexts ()
 
     GetUserSpecifiedDirectoriesToSearch (kext_dirs);
 
-    // We now have a complete list of directories that we will search for kext 
bundles
-    m_directories_searched = kext_dirs;
+    GetKernelDirectoriesToSearch (kext_dirs);
 
-    IndexKextsInDirectories (kext_dirs);
+    GetCurrentDirectoryToSearch (kext_dirs);
+
+    // We now have a complete list of directories that we will search for kext 
bundles
+    m_search_directories = kext_dirs;
 }
 
 void
@@ -379,7 +393,6 @@ PlatformDarwinKernel::GetGenericSDKDirec
     {
         directories.push_back (installed_kdks);
     }
-
 }
 
 void
@@ -427,6 +440,50 @@ PlatformDarwinKernel::GetGenericDirector
 }
 
 void
+PlatformDarwinKernel::GetKernelDirectoriesToSearch 
(std::vector<lldb_private::FileSpec> &directories)
+{
+    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);
+    }
+}
+
+void
+PlatformDarwinKernel::GetCurrentDirectoryToSearch 
(std::vector<lldb_private::FileSpec> &directories)
+{
+    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);
+    }
+}
+
+void
 PlatformDarwinKernel::GetUserSpecifiedDirectoriesToSearch 
(std::vector<lldb_private::FileSpec> &directories)
 {
     FileSpecList user_dirs(GetGlobalProperties()->GetKextDirectories());
@@ -450,6 +507,24 @@ PlatformDarwinKernel::GetUserSpecifiedDi
             {
                 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())
+            {
+                directories.push_back (dir_slek);
+            }
         }
     }
 
@@ -523,19 +598,36 @@ PlatformDarwinKernel::GetKextDirectories
             ((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())
+        {
+            ((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);
+        }
     }
     return FileSpec::eEnumerateDirectoryResultNext;
 }
 
 void
-PlatformDarwinKernel::IndexKextsInDirectories 
(std::vector<lldb_private::FileSpec> kext_dirs)
+PlatformDarwinKernel::IndexKextsInDirectories ()
 {
     std::vector<FileSpec> kext_bundles;
 
-    const uint32_t num_dirs = kext_dirs.size();
+    const uint32_t num_dirs = m_search_directories.size();
     for (uint32_t i = 0; i < num_dirs; i++)
     {
-        const FileSpec &dir = kext_dirs[i];
+        const FileSpec &dir = m_search_directories[i];
         const bool find_directories = true;
         const bool find_files = false;
         const bool find_other = false;
@@ -612,6 +704,56 @@ PlatformDarwinKernel::GetKextsInDirector
     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,
+                                      &m_kernel_binaries);
+    }
+}
+
+// Callback for FileSpec::EnumerateDirectory().
+// Step through the entries in a directory like /System/Library/Kernels/, find 
kernel binaries,
+// add them to m_kernel_binaries.
+
+// 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.", 5) == 0)
+        {
+            // This is m_kernel_binaries but we're in a class method here
+            ((std::vector<lldb_private::FileSpec> 
*)baton)->push_back(file_spec);
+        }
+    }
+    return FileSpec::eEnumerateDirectoryResultNext;
+}
+
+
 Error
 PlatformDarwinKernel::GetSharedModule (const ModuleSpec &module_spec,
                                        ModuleSP &module_sp,
@@ -639,6 +781,28 @@ PlatformDarwinKernel::GetSharedModule (c
                     {
                         return error;
                     }
+                }
+            }
+        }
+    }
+
+    if (kext_bundle_id.compare("mach_kernel") == 0 && 
module_spec.GetUUID().IsValid())
+    {
+        for (auto possible_kernel : m_kernel_binaries)
+        {
+            if (possible_kernel.Exists())
+            {
+                ModuleSpec kern_spec (possible_kernel);
+                kern_spec.GetUUID() = module_spec.GetUUID();
+                ModuleSP module_sp (new Module (kern_spec));
+                if (module_sp && module_sp->GetObjectFile() && 
module_sp->MatchesModuleSpec (kern_spec))
+                {
+                    Error error;
+                    error = ModuleList::GetSharedModule (kern_spec, module_sp, 
NULL, NULL, NULL);
+                    if (module_sp && module_sp->GetObjectFile())
+                    {
+                        return error;
+                    }
                 }
             }
         }

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=227419&r1=227418&r2=227419&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.h (original)
+++ lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.h Thu Jan 29 
00:20:05 2015
@@ -66,7 +66,7 @@ public:
     }
 
     virtual uint32_t
-    GetPluginVersion()  override
+    GetPluginVersion() override
     {
         return 1;
     }
@@ -88,7 +88,7 @@ public:
                      lldb::ModuleSP &module_sp,
                      const lldb_private::FileSpecList *module_search_paths_ptr,
                      lldb::ModuleSP *old_module_sp_ptr,
-                     bool *did_create_ptr)  override;
+                     bool *did_create_ptr) override;
 
     bool
     GetSupportedArchitectureAtIndex (uint32_t idx, 
@@ -100,7 +100,6 @@ public:
     void
     CalculateTrapHandlerSymbolNames () override;
 
-
 protected:
 
     // Map from kext bundle ID ("com.apple.filesystems.exfat") to FileSpec for 
the kext bundle on 
@@ -108,6 +107,7 @@ protected:
     typedef std::multimap<lldb_private::ConstString, lldb_private::FileSpec> 
BundleIDToKextMap;
     typedef BundleIDToKextMap::iterator BundleIDToKextIterator;
 
+    typedef std::vector<lldb_private::FileSpec> KernelBinaryCollection;
     
     // Array of directories that were searched for kext bundles (used only for 
reporting to user)
     typedef std::vector<lldb_private::FileSpec> DirectoriesSearchedCollection;
@@ -124,8 +124,9 @@ protected:
                          lldb_private::FileSpec::FileType file_type,
                          const lldb_private::FileSpec &file_spec);
 
+    // Populate m_search_directories vector of directories
     void
-    SearchForKexts();
+    CollectKextAndKernelDirectories ();
 
     // Directories where we may find iOS SDKs with kext bundles in them
     void
@@ -155,6 +156,13 @@ protected:
     void
     GetUserSpecifiedDirectoriesToSearch (std::vector<lldb_private::FileSpec> 
&directories);
 
+    void
+    GetCurrentDirectoryToSearch (std::vector<lldb_private::FileSpec> 
&directories);
+
+    // Directories where we may find kernels exclusively
+    void
+    GetKernelDirectoriesToSearch (std::vector<lldb_private::FileSpec> 
&directories);
+
     // Search through a vector of SDK FileSpecs, add any directories that may 
contain kexts
     // to the vector of kext dir FileSpecs
     void
@@ -163,16 +171,28 @@ protected:
     // 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 (std::vector<lldb_private::FileSpec> kext_dirs);
+    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:
 
-    BundleIDToKextMap m_name_to_kext_path_map; 
-    DirectoriesSearchedCollection m_directories_searched;
-    lldb_private::LazyBool m_ios_debug_session;
+    BundleIDToKextMap             m_name_to_kext_path_map; // multimap of 
CFBundleID to FileSpec on local filesystem
+    DirectoriesSearchedCollection m_search_directories;    // list of 
directories we search for kexts/kernels
+    KernelBinaryCollection        m_kernel_binaries;       // list of kernel 
binaries we found on local filesystem
+    lldb_private::LazyBool        m_ios_debug_session;
 
     DISALLOW_COPY_AND_ASSIGN (PlatformDarwinKernel);
 


_______________________________________________
lldb-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/lldb-commits

Reply via email to