summaryrefslogtreecommitdiffstats
path: root/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp')
-rw-r--r--lldb/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp194
1 files changed, 179 insertions, 15 deletions
diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp
index 8170275c765..919c10fcad5 100644
--- a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp
+++ b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp
@@ -250,13 +250,16 @@ PlatformDarwinKernel::DebuggerInitialize (lldb_private::Debugger &debugger)
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)
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::GetGenericSDKDirectoriesToSearch (std::vector<lldb_private
{
directories.push_back (installed_kdks);
}
-
}
void
@@ -427,6 +440,50 @@ PlatformDarwinKernel::GetGenericDirectoriesToSearch (std::vector<lldb_private::F
}
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::GetUserSpecifiedDirectoriesToSearch (std::vector<lldb_priv
{
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::GetKextDirectoriesInSDK (void *baton,
((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::GetKextsInDirectory (void *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,
+ &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,
@@ -644,6 +786,28 @@ PlatformDarwinKernel::GetSharedModule (const ModuleSpec &module_spec,
}
}
+ 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;
+ }
+ }
+ }
+ }
+ }
+
// Else fall back to treating the file's path as an actual file path - defer to PlatformDarwin's GetSharedModule.
return PlatformDarwin::GetSharedModule (module_spec, module_sp, module_search_paths_ptr, old_module_sp_ptr, did_create_ptr);
}
OpenPOWER on IntegriCloud