diff options
Diffstat (limited to 'source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp')
-rw-r--r-- | source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp | 1567 |
1 files changed, 701 insertions, 866 deletions
diff --git a/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp b/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp index d3c1c805a83b..f4fd9c694000 100644 --- a/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp +++ b/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp @@ -1,4 +1,5 @@ -//===-- PlatformDarwinKernel.cpp -----------------------------------*- C++ -*-===// +//===-- PlatformDarwinKernel.cpp -----------------------------------*- C++ +//-*-===// // // The LLVM Compiler Infrastructure // @@ -9,8 +10,8 @@ #include "PlatformDarwinKernel.h" -#if defined (__APPLE__) // This Plugin uses the Mac-specific source/Host/macosx/cfcpp utilities - +#if defined(__APPLE__) // This Plugin uses the Mac-specific + // source/Host/macosx/cfcpp utilities // C Includes // C++ Includes @@ -50,253 +51,223 @@ static uint32_t g_initialize_count = 0; //------------------------------------------------------------------ // Static Functions //------------------------------------------------------------------ -void -PlatformDarwinKernel::Initialize () -{ - PlatformDarwin::Initialize (); - - if (g_initialize_count++ == 0) - { - PluginManager::RegisterPlugin (PlatformDarwinKernel::GetPluginNameStatic(), - PlatformDarwinKernel::GetDescriptionStatic(), - PlatformDarwinKernel::CreateInstance, - PlatformDarwinKernel::DebuggerInitialize); - } +void PlatformDarwinKernel::Initialize() { + PlatformDarwin::Initialize(); + + if (g_initialize_count++ == 0) { + PluginManager::RegisterPlugin(PlatformDarwinKernel::GetPluginNameStatic(), + PlatformDarwinKernel::GetDescriptionStatic(), + PlatformDarwinKernel::CreateInstance, + PlatformDarwinKernel::DebuggerInitialize); + } } -void -PlatformDarwinKernel::Terminate () -{ - if (g_initialize_count > 0) - { - if (--g_initialize_count == 0) - { - PluginManager::UnregisterPlugin (PlatformDarwinKernel::CreateInstance); - } +void PlatformDarwinKernel::Terminate() { + if (g_initialize_count > 0) { + if (--g_initialize_count == 0) { + PluginManager::UnregisterPlugin(PlatformDarwinKernel::CreateInstance); } + } - PlatformDarwin::Terminate (); + PlatformDarwin::Terminate(); } -PlatformSP -PlatformDarwinKernel::CreateInstance (bool force, const ArchSpec *arch) -{ - Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_PLATFORM)); +PlatformSP PlatformDarwinKernel::CreateInstance(bool force, + const ArchSpec *arch) { + Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); + if (log) { + const char *arch_name; + if (arch && arch->GetArchitectureName()) + arch_name = arch->GetArchitectureName(); + else + arch_name = "<null>"; + + const char *triple_cstr = + arch ? arch->GetTriple().getTriple().c_str() : "<null>"; + + log->Printf("PlatformDarwinKernel::%s(force=%s, arch={%s,%s})", + __FUNCTION__, force ? "true" : "false", arch_name, triple_cstr); + } + + // This is a special plugin that we don't want to activate just based on an + // ArchSpec for normal + // userland debugging. It is only useful in kernel debug sessions and the + // DynamicLoaderDarwinPlugin + // (or a user doing 'platform select') will force the creation of this + // Platform plugin. + if (force == false) { if (log) - { - const char *arch_name; - if (arch && arch->GetArchitectureName ()) - arch_name = arch->GetArchitectureName (); - else - arch_name = "<null>"; - - const char *triple_cstr = arch ? arch->GetTriple ().getTriple ().c_str() : "<null>"; - - log->Printf ("PlatformDarwinKernel::%s(force=%s, arch={%s,%s})", __FUNCTION__, force ? "true" : "false", arch_name, triple_cstr); - } - - // This is a special plugin that we don't want to activate just based on an ArchSpec for normal - // userland debugging. It is only useful in kernel debug sessions and the DynamicLoaderDarwinPlugin - // (or a user doing 'platform select') will force the creation of this Platform plugin. - if (force == false) - { - if (log) - log->Printf ("PlatformDarwinKernel::%s() aborting creation of platform because force == false", __FUNCTION__); - return PlatformSP(); - } - - bool create = force; - LazyBool is_ios_debug_session = eLazyBoolCalculate; - - if (create == false && arch && arch->IsValid()) - { - const llvm::Triple &triple = arch->GetTriple(); - switch (triple.getVendor()) - { - case llvm::Triple::Apple: - create = true; - break; - - // Only accept "unknown" for vendor if the host is Apple and - // it "unknown" wasn't specified (it was just returned because it - // was NOT specified) - case llvm::Triple::UnknownArch: - create = !arch->TripleVendorWasSpecified(); - break; - default: - break; - } - - if (create) - { - switch (triple.getOS()) - { - case llvm::Triple::Darwin: - case llvm::Triple::MacOSX: - case llvm::Triple::IOS: - case llvm::Triple::WatchOS: - case llvm::Triple::TvOS: - break; - // Only accept "vendor" for vendor if the host is Apple and - // it "unknown" wasn't specified (it was just returned because it - // was NOT specified) - case llvm::Triple::UnknownOS: - create = !arch->TripleOSWasSpecified(); - break; - default: - create = false; - break; - } - } - } - if (arch && arch->IsValid()) - { - switch (arch->GetMachine()) - { - case llvm::Triple::x86: - case llvm::Triple::x86_64: - case llvm::Triple::ppc: - case llvm::Triple::ppc64: - is_ios_debug_session = eLazyBoolNo; - break; - case llvm::Triple::arm: - case llvm::Triple::aarch64: - case llvm::Triple::thumb: - is_ios_debug_session = eLazyBoolYes; - break; - default: - is_ios_debug_session = eLazyBoolCalculate; - break; - } - } - if (create) - { - if (log) - log->Printf ("PlatformDarwinKernel::%s() creating platform", __FUNCTION__); + log->Printf("PlatformDarwinKernel::%s() aborting creation of platform " + "because force == false", + __FUNCTION__); + return PlatformSP(); + } + + bool create = force; + LazyBool is_ios_debug_session = eLazyBoolCalculate; + + if (create == false && arch && arch->IsValid()) { + const llvm::Triple &triple = arch->GetTriple(); + switch (triple.getVendor()) { + case llvm::Triple::Apple: + create = true; + break; + + // Only accept "unknown" for vendor if the host is Apple and + // it "unknown" wasn't specified (it was just returned because it + // was NOT specified) + case llvm::Triple::UnknownArch: + create = !arch->TripleVendorWasSpecified(); + break; + default: + break; + } + + if (create) { + switch (triple.getOS()) { + case llvm::Triple::Darwin: + case llvm::Triple::MacOSX: + case llvm::Triple::IOS: + case llvm::Triple::WatchOS: + case llvm::Triple::TvOS: + break; + // Only accept "vendor" for vendor if the host is Apple and + // it "unknown" wasn't specified (it was just returned because it + // was NOT specified) + case llvm::Triple::UnknownOS: + create = !arch->TripleOSWasSpecified(); + break; + default: + create = false; + break; + } + } + } + if (arch && arch->IsValid()) { + switch (arch->GetMachine()) { + case llvm::Triple::x86: + case llvm::Triple::x86_64: + case llvm::Triple::ppc: + case llvm::Triple::ppc64: + is_ios_debug_session = eLazyBoolNo; + break; + case llvm::Triple::arm: + case llvm::Triple::aarch64: + case llvm::Triple::thumb: + is_ios_debug_session = eLazyBoolYes; + break; + default: + is_ios_debug_session = eLazyBoolCalculate; + break; + } + } + if (create) { + if (log) + log->Printf("PlatformDarwinKernel::%s() creating platform", __FUNCTION__); - return PlatformSP(new PlatformDarwinKernel (is_ios_debug_session)); - } + return PlatformSP(new PlatformDarwinKernel(is_ios_debug_session)); + } - if (log) - log->Printf ("PlatformDarwinKernel::%s() aborting creation of platform", __FUNCTION__); + if (log) + log->Printf("PlatformDarwinKernel::%s() aborting creation of platform", + __FUNCTION__); - return PlatformSP(); + return PlatformSP(); } - -lldb_private::ConstString -PlatformDarwinKernel::GetPluginNameStatic () -{ - static ConstString g_name("darwin-kernel"); - return g_name; +lldb_private::ConstString PlatformDarwinKernel::GetPluginNameStatic() { + static ConstString g_name("darwin-kernel"); + return g_name; } -const char * -PlatformDarwinKernel::GetDescriptionStatic() -{ - return "Darwin Kernel platform plug-in."; +const char *PlatformDarwinKernel::GetDescriptionStatic() { + return "Darwin Kernel platform plug-in."; } //------------------------------------------------------------------ /// Code to handle the PlatformDarwinKernel settings //------------------------------------------------------------------ -static PropertyDefinition -g_properties[] = -{ - { "search-locally-for-kexts" , OptionValue::eTypeBoolean, true, true, NULL, NULL, "Automatically search for kexts on the local system when doing kernel debugging." }, - { "kext-directories", OptionValue::eTypeFileSpecList, false, 0, NULL, NULL, "Directories/KDKs to search for kexts in when starting a kernel debug session." }, - { NULL , OptionValue::eTypeInvalid, false, 0 , NULL, NULL, NULL } -}; - -enum { - ePropertySearchForKexts = 0, - ePropertyKextDirectories -}; - +static PropertyDefinition g_properties[] = { + {"search-locally-for-kexts", OptionValue::eTypeBoolean, true, true, NULL, + NULL, "Automatically search for kexts on the local system when doing " + "kernel debugging."}, + {"kext-directories", OptionValue::eTypeFileSpecList, false, 0, NULL, NULL, + "Directories/KDKs to search for kexts in when starting a kernel debug " + "session."}, + {NULL, OptionValue::eTypeInvalid, false, 0, NULL, NULL, NULL}}; +enum { ePropertySearchForKexts = 0, ePropertyKextDirectories }; -class PlatformDarwinKernelProperties : public Properties -{ +class PlatformDarwinKernelProperties : public Properties { public: - - static ConstString & - GetSettingName () - { - static ConstString g_setting_name("darwin-kernel"); - return g_setting_name; - } - - PlatformDarwinKernelProperties() : - Properties () - { - m_collection_sp.reset (new OptionValueProperties(GetSettingName())); - m_collection_sp->Initialize(g_properties); - } - - virtual - ~PlatformDarwinKernelProperties() - { - } - - bool - GetSearchForKexts() const - { - const uint32_t idx = ePropertySearchForKexts; - return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0); - } - - FileSpecList & - GetKextDirectories() const - { - const uint32_t idx = ePropertyKextDirectories; - OptionValueFileSpecList *option_value = m_collection_sp->GetPropertyAtIndexAsOptionValueFileSpecList (NULL, false, idx); - assert(option_value); - return option_value->GetCurrentValue(); - } + static ConstString &GetSettingName() { + static ConstString g_setting_name("darwin-kernel"); + return g_setting_name; + } + + PlatformDarwinKernelProperties() : Properties() { + m_collection_sp.reset(new OptionValueProperties(GetSettingName())); + m_collection_sp->Initialize(g_properties); + } + + virtual ~PlatformDarwinKernelProperties() {} + + bool GetSearchForKexts() const { + const uint32_t idx = ePropertySearchForKexts; + return m_collection_sp->GetPropertyAtIndexAsBoolean( + NULL, idx, g_properties[idx].default_uint_value != 0); + } + + FileSpecList &GetKextDirectories() const { + const uint32_t idx = ePropertyKextDirectories; + OptionValueFileSpecList *option_value = + m_collection_sp->GetPropertyAtIndexAsOptionValueFileSpecList( + NULL, false, idx); + assert(option_value); + return option_value->GetCurrentValue(); + } }; -typedef std::shared_ptr<PlatformDarwinKernelProperties> PlatformDarwinKernelPropertiesSP; +typedef std::shared_ptr<PlatformDarwinKernelProperties> + PlatformDarwinKernelPropertiesSP; -static const PlatformDarwinKernelPropertiesSP & -GetGlobalProperties() -{ - static PlatformDarwinKernelPropertiesSP g_settings_sp; - if (!g_settings_sp) - g_settings_sp.reset (new PlatformDarwinKernelProperties ()); - return g_settings_sp; +static const PlatformDarwinKernelPropertiesSP &GetGlobalProperties() { + static PlatformDarwinKernelPropertiesSP g_settings_sp; + if (!g_settings_sp) + g_settings_sp.reset(new PlatformDarwinKernelProperties()); + return g_settings_sp; } -void -PlatformDarwinKernel::DebuggerInitialize (lldb_private::Debugger &debugger) -{ - if (!PluginManager::GetSettingForPlatformPlugin (debugger, PlatformDarwinKernelProperties::GetSettingName())) - { - const bool is_global_setting = true; - PluginManager::CreateSettingForPlatformPlugin (debugger, - GetGlobalProperties()->GetValueProperties(), - ConstString ("Properties for the PlatformDarwinKernel plug-in."), - is_global_setting); - } +void PlatformDarwinKernel::DebuggerInitialize( + lldb_private::Debugger &debugger) { + if (!PluginManager::GetSettingForPlatformPlugin( + debugger, PlatformDarwinKernelProperties::GetSettingName())) { + const bool is_global_setting = true; + PluginManager::CreateSettingForPlatformPlugin( + debugger, GetGlobalProperties()->GetValueProperties(), + ConstString("Properties for the PlatformDarwinKernel plug-in."), + is_global_setting); + } } //------------------------------------------------------------------ /// Default Constructor //------------------------------------------------------------------ -PlatformDarwinKernel::PlatformDarwinKernel (lldb_private::LazyBool is_ios_debug_session) : - PlatformDarwin (false), // This is a remote platform - m_name_to_kext_path_map(), - m_search_directories(), - m_kernel_binaries(), - m_ios_debug_session(is_ios_debug_session) +PlatformDarwinKernel::PlatformDarwinKernel( + lldb_private::LazyBool is_ios_debug_session) + : PlatformDarwin(false), // This is a remote platform + 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) { - if (GetGlobalProperties()->GetSearchForKexts()) - { - CollectKextAndKernelDirectories (); - IndexKextsInDirectories (); - IndexKernelsInDirectories (); - } + if (GetGlobalProperties()->GetSearchForKexts()) { + CollectKextAndKernelDirectories(); + SearchForKextsAndKernelsRecursively(); + } } //------------------------------------------------------------------ @@ -305,688 +276,552 @@ PlatformDarwinKernel::PlatformDarwinKernel (lldb_private::LazyBool is_ios_debug_ /// The destructor is virtual since this class is designed to be /// inherited from by the plug-in instance. //------------------------------------------------------------------ -PlatformDarwinKernel::~PlatformDarwinKernel() -{ -} - - -void -PlatformDarwinKernel::GetStatus (Stream &strm) -{ - Platform::GetStatus (strm); - strm.Printf (" Debug session type: "); - if (m_ios_debug_session == eLazyBoolYes) - strm.Printf ("iOS kernel debugging\n"); - else if (m_ios_debug_session == eLazyBoolNo) - strm.Printf ("Mac OS X kernel debugging\n"); - else - strm.Printf ("unknown kernel debugging\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 (" Total number of kexts indexed: %d\n", (int) m_name_to_kext_path_map.size()); +PlatformDarwinKernel::~PlatformDarwinKernel() {} + +void PlatformDarwinKernel::GetStatus(Stream &strm) { + Platform::GetStatus(strm); + strm.Printf(" Debug session type: "); + if (m_ios_debug_session == eLazyBoolYes) + strm.Printf("iOS kernel debugging\n"); + else if (m_ios_debug_session == eLazyBoolNo) + strm.Printf("Mac OS X kernel debugging\n"); + else + 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) { + 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 // for kernel & kext binaries. -void -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/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) - { - GetiOSSDKDirectoriesToSearch (sdk_dirs); - GetAppleTVOSSDKDirectoriesToSearch (sdk_dirs); - GetWatchOSSDKDirectoriesToSearch (sdk_dirs); - } - 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 - - std::vector<FileSpec> kext_dirs; - SearchSDKsForKextDirectories (sdk_dirs, kext_dirs); - - if (m_ios_debug_session != eLazyBoolNo) - GetiOSDirectoriesToSearch (kext_dirs); - if (m_ios_debug_session != eLazyBoolYes) - GetMacDirectoriesToSearch (kext_dirs); - - GetGenericDirectoriesToSearch (kext_dirs); - - GetUserSpecifiedDirectoriesToSearch (kext_dirs); - - GetKernelDirectoriesToSearch (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 -PlatformDarwinKernel::GetiOSSDKDirectoriesToSearch (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/iPhoneOS.platform/Developer/SDKs", developer_dir); - FileSpec ios_sdk(pathbuf, true); - if (ios_sdk.Exists() && ios_sdk.IsDirectory()) - { - directories.push_back (ios_sdk); - } -} - -void -PlatformDarwinKernel::GetAppleTVOSSDKDirectoriesToSearch (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/AppleTVOS.platform/Developer/SDKs", developer_dir); - FileSpec ios_sdk(pathbuf, true); - if (ios_sdk.Exists() && ios_sdk.IsDirectory()) - { - directories.push_back (ios_sdk); - } -} - -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); - } - } -} - - -void -PlatformDarwinKernel::GetMacSDKDirectoriesToSearch (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/MacOSX.platform/Developer/SDKs", developer_dir); - FileSpec mac_sdk(pathbuf, true); - if (mac_sdk.Exists() && mac_sdk.IsDirectory()) - { - directories.push_back (mac_sdk); - } -} - -void -PlatformDarwinKernel::GetGenericSDKDirectoriesToSearch (std::vector<lldb_private::FileSpec> &directories) -{ - FileSpec generic_sdk("/AppleInternal/Developer/KDKs", true); - if (generic_sdk.Exists() && generic_sdk.IsDirectory()) - { - directories.push_back (generic_sdk); - } - - // 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()) - { - directories.push_back (installed_kdks); - } -} - -void -PlatformDarwinKernel::GetiOSDirectoriesToSearch (std::vector<lldb_private::FileSpec> &directories) -{ -} - -void -PlatformDarwinKernel::GetMacDirectoriesToSearch (std::vector<lldb_private::FileSpec> &directories) -{ - FileSpec sle("/System/Library/Extensions", true); - if (sle.Exists() && sle.IsDirectory()) - { - directories.push_back(sle); - } - - FileSpec le("/Library/Extensions", true); - if (le.Exists() && le.IsDirectory()) - { - directories.push_back(le); - } - - 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); - } -} - -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()); - std::vector<FileSpec> possible_sdk_dirs; - - const uint32_t user_dirs_count = user_dirs.GetSize(); - for (uint32_t i = 0; i < user_dirs_count; i++) - { - FileSpec dir = user_dirs.GetFileSpecAtIndex (i); - dir.ResolvePath(); - if (dir.Exists() && dir.IsDirectory()) - { - 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()) - { - directories.push_back (dir_slek); - } - } - } - - 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()) - { - const bool find_directories = true; - const bool find_files = false; - const bool find_other = false; - FileSpec::EnumerateDirectory (sdk_dir_path.c_str(), - find_directories, - find_files, - find_other, - GetKextDirectoriesInSDK, - &kext_dirs); - } - } -} - -// 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. - +void 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. + + // 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) { + 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) { + AddSDKSubdirsToSearchPaths(developer_dir + + "/Platforms/MacOSX.platform/Developer/SDKs"); + } + + 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) { + } + if (m_ios_debug_session != eLazyBoolYes) { + AddRootSubdirsToSearchPaths(this, "/"); + } + + GetUserSpecifiedDirectoriesToSearch(); + + // 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); + + // Add simple directory of the current working directory + m_search_directories_no_recursing.push_back(FileSpec(".", true)); +} + +void PlatformDarwinKernel::GetUserSpecifiedDirectoriesToSearch() { + FileSpecList user_dirs(GetGlobalProperties()->GetKextDirectories()); + std::vector<FileSpec> possible_sdk_dirs; + + const uint32_t user_dirs_count = user_dirs.GetSize(); + for (uint32_t i = 0; i < user_dirs_count; i++) { + FileSpec dir = user_dirs.GetFileSpecAtIndex(i); + dir.ResolvePath(); + if (dir.Exists() && dir.IsDirectory()) { + m_search_directories.push_back(dir); + } + } +} + +void PlatformDarwinKernel::AddRootSubdirsToSearchPaths( + PlatformDarwinKernel *thisp, const std::string &dir) { + 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++) { + FileSpec testdir(dir + subdirs[i], true); + if (testdir.Exists() && testdir.IsDirectory()) + thisp->m_search_directories.push_back(testdir); + } + + // 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::AddSDKSubdirsToSearchPaths(const std::string &dir) { + // 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); +} + +// Helper function to find *.sdk and *.kdk directories in a given directory. FileSpec::EnumerateDirectoryResult -PlatformDarwinKernel::GetKextDirectoriesInSDK (void *baton, - FileSpec::FileType file_type, - const FileSpec &file_spec) -{ - if (file_type == FileSpec::eFileTypeDirectory - && (file_spec.GetFileNameExtension() == ConstString("sdk") - || file_spec.GetFileNameExtension() == ConstString("kdk"))) - { - 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()) - { - ((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<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); - m_name_to_kext_path_map.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. +PlatformDarwinKernel::FindKDKandSDKDirectoriesInDirectory( + void *baton, FileSpec::FileType file_type, const FileSpec &file_spec) { + static ConstString g_sdk_suffix = ConstString("sdk"); + static ConstString g_kdk_suffix = ConstString("kdk"); + + PlatformDarwinKernel *thisp = (PlatformDarwinKernel *)baton; + if (file_type == FileSpec::eFileTypeDirectory && + (file_spec.GetFileNameExtension() == g_sdk_suffix || + file_spec.GetFileNameExtension() == g_kdk_suffix)) { + 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::SearchForKextsAndKernelsRecursively() { + 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 = 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); + } + const uint32_t num_dirs_no_recurse = m_search_directories_no_recursing.size(); + for (uint32_t i = 0; i < num_dirs_no_recurse; i++) { + 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); + } +} + +// 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. 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; +PlatformDarwinKernel::GetKernelsAndKextsInDirectoryWithRecursion( + void *baton, FileSpec::FileType file_type, const FileSpec &file_spec) { + return GetKernelsAndKextsInDirectoryHelper(baton, file_type, file_spec, true); } -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); - } +FileSpec::EnumerateDirectoryResult +PlatformDarwinKernel::GetKernelsAndKextsInDirectoryNoRecursion( + void *baton, FileSpec::FileType file_type, const FileSpec &file_spec) { + return GetKernelsAndKextsInDirectoryHelper(baton, file_type, file_spec, + false); } -// 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", 4) == 0) - { - // This is m_kernel_binaries but we're in a class method here - ((std::vector<lldb_private::FileSpec> *)baton)->push_back(file_spec); - } +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()); + + PlatformDarwinKernel *thisp = (PlatformDarwinKernel *)baton; + 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) && + file_spec_extension != g_dsym_suffix) { + 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()) { + search_here_too = plugins.GetPath(); + } + } + + 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, + recurse ? GetKernelsAndKextsInDirectoryWithRecursion + : GetKernelsAndKextsInDirectoryNoRecursion, + baton); } return FileSpec::eEnumerateDirectoryResultNext; -} - - -Error -PlatformDarwinKernel::GetSharedModule (const ModuleSpec &module_spec, - Process *process, - ModuleSP &module_sp, - const FileSpecList *module_search_paths_ptr, - ModuleSP *old_module_sp_ptr, - bool *did_create_ptr) -{ - Error error; - module_sp.reset(); - const FileSpec &platform_file = module_spec.GetFileSpec(); - - // Treat the file's path as a kext bundle ID (e.g. "com.apple.driver.AppleIRController") and search our kext index. - std::string kext_bundle_id = platform_file.GetPath(); - if (!kext_bundle_id.empty()) - { - ConstString kext_bundle_cs(kext_bundle_id.c_str()); - if (m_name_to_kext_path_map.count(kext_bundle_cs) > 0) - { - for (BundleIDToKextIterator it = m_name_to_kext_path_map.begin (); it != m_name_to_kext_path_map.end (); ++it) - { - if (it->first == kext_bundle_cs) - { - error = ExamineKextForMatchingUUID (it->second, module_spec.GetUUID(), module_spec.GetArchitecture(), module_sp); - if (module_sp.get()) - { - return error; - } - } - } + } + // 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; + } +} + +void PlatformDarwinKernel::AddKextToMap(PlatformDarwinKernel *thisp, + const FileSpec &file_spec) { + CFCBundle bundle(file_spec.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(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)); + } + } +} + +// Given a FileSpec of /dir/dir/foo.kext +// Return true if any of these exist: +// /dir/dir/foo.kext.dSYM +// /dir/dir/foo.kext/Contents/MacOS/foo.dSYM +// /dir/dir/foo.kext/foo.dSYM +bool PlatformDarwinKernel::KextHasdSYMSibling( + const FileSpec &kext_bundle_filepath) { + FileSpec dsym_fspec = kext_bundle_filepath; + std::string filename = dsym_fspec.GetFilename().AsCString(); + filename += ".dSYM"; + dsym_fspec.GetFilename() = ConstString(filename); + if (dsym_fspec.Exists() && dsym_fspec.IsDirectory()) { + return true; + } + // Should probably get the CFBundleExecutable here or call + // CFBundleCopyExecutableURL + + // Look for a deep bundle foramt + ConstString executable_name = + kext_bundle_filepath.GetFileNameStrippingExtension(); + std::string deep_bundle_str = + kext_bundle_filepath.GetPath() + "/Contents/MacOS/"; + deep_bundle_str += executable_name.AsCString(); + deep_bundle_str += ".dSYM"; + dsym_fspec.SetFile(deep_bundle_str, true); + if (dsym_fspec.Exists() && dsym_fspec.IsDirectory()) { + return true; + } + + // look for a shallow bundle format + // + std::string shallow_bundle_str = kext_bundle_filepath.GetPath() + "/"; + shallow_bundle_str += executable_name.AsCString(); + shallow_bundle_str += ".dSYM"; + dsym_fspec.SetFile(shallow_bundle_str, true); + if (dsym_fspec.Exists() && dsym_fspec.IsDirectory()) { + return true; + } + return false; +} + +// Given a FileSpec of /dir/dir/mach.development.t7004 +// Return true if a dSYM exists next to it: +// /dir/dir/mach.development.t7004.dSYM +bool PlatformDarwinKernel::KernelHasdSYMSibling(const FileSpec &kernel_binary) { + FileSpec kernel_dsym = kernel_binary; + std::string filename = kernel_binary.GetFilename().AsCString(); + filename += ".dSYM"; + kernel_dsym.GetFilename() = ConstString(filename); + if (kernel_dsym.Exists() && kernel_dsym.IsDirectory()) { + return true; + } + return false; +} + +Error PlatformDarwinKernel::GetSharedModule( + const ModuleSpec &module_spec, Process *process, ModuleSP &module_sp, + const FileSpecList *module_search_paths_ptr, ModuleSP *old_module_sp_ptr, + bool *did_create_ptr) { + Error error; + module_sp.reset(); + const FileSpec &platform_file = module_spec.GetFileSpec(); + + // Treat the file's path as a kext bundle ID (e.g. + // "com.apple.driver.AppleIRController") and search our kext index. + std::string kext_bundle_id = platform_file.GetPath(); + if (!kext_bundle_id.empty()) { + ConstString kext_bundle_cs(kext_bundle_id.c_str()); + + // First look through the kext bundles that had a dsym next to them + if (m_name_to_kext_path_map_with_dsyms.count(kext_bundle_cs) > 0) { + for (BundleIDToKextIterator it = + m_name_to_kext_path_map_with_dsyms.begin(); + it != m_name_to_kext_path_map_with_dsyms.end(); ++it) { + if (it->first == kext_bundle_cs) { + error = ExamineKextForMatchingUUID(it->second, module_spec.GetUUID(), + module_spec.GetArchitecture(), + module_sp); + if (module_sp.get()) { + 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)) - { - // module_sp is an actual kernel binary we want to add. - if (process) - { - process->GetTarget().GetImages().AppendIfNeeded (module_sp); - error.Clear(); - return error; - } - else - { - error = ModuleList::GetSharedModule (kern_spec, module_sp, NULL, NULL, NULL); - if (module_sp - && module_sp->GetObjectFile() - && module_sp->GetObjectFile()->GetType() != ObjectFile::Type::eTypeCoreFile) - { - return error; - } - module_sp.reset(); - } - } - } + } + } + + // Second look through the kext binarys without dSYMs + if (m_name_to_kext_path_map_without_dsyms.count(kext_bundle_cs) > 0) { + for (BundleIDToKextIterator it = + m_name_to_kext_path_map_without_dsyms.begin(); + it != m_name_to_kext_path_map_without_dsyms.end(); ++it) { + if (it->first == kext_bundle_cs) { + error = ExamineKextForMatchingUUID(it->second, module_spec.GetUUID(), + module_spec.GetArchitecture(), + module_sp); + if (module_sp.get()) { + 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, process, module_sp, module_search_paths_ptr, old_module_sp_ptr, did_create_ptr); -} - -Error -PlatformDarwinKernel::ExamineKextForMatchingUUID (const FileSpec &kext_bundle_path, const lldb_private::UUID &uuid, const ArchSpec &arch, ModuleSP &exe_module_sp) -{ - Error error; - FileSpec exe_file = kext_bundle_path; - Host::ResolveExecutableInBundle (exe_file); - if (exe_file.Exists()) - { - ModuleSpec exe_spec (exe_file); - exe_spec.GetUUID() = uuid; - if (!uuid.IsValid()) - { - exe_spec.GetArchitecture() = arch; + } + } + } + + if (kext_bundle_id.compare("mach_kernel") == 0 && + module_spec.GetUUID().IsValid()) { + // First try all kernel binaries that have a dSYM next to them + for (auto possible_kernel : m_kernel_binaries_with_dsyms) { + 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)) { + // module_sp is an actual kernel binary we want to add. + if (process) { + process->GetTarget().GetImages().AppendIfNeeded(module_sp); + error.Clear(); + return error; + } else { + error = ModuleList::GetSharedModule(kern_spec, module_sp, NULL, + NULL, NULL); + if (module_sp && module_sp->GetObjectFile() && + module_sp->GetObjectFile()->GetType() != + ObjectFile::Type::eTypeCoreFile) { + return error; + } + module_sp.reset(); + } } - - // First try to create a ModuleSP with the file / arch and see if the UUID matches. - // If that fails (this exec file doesn't have the correct uuid), don't call GetSharedModule - // (which may call in to the DebugSymbols framework and therefore can be slow.) - ModuleSP module_sp (new Module (exe_spec)); - if (module_sp && module_sp->GetObjectFile() && module_sp->MatchesModuleSpec (exe_spec)) - { - error = ModuleList::GetSharedModule (exe_spec, exe_module_sp, NULL, NULL, NULL); - if (exe_module_sp && exe_module_sp->GetObjectFile()) - { - return error; + } + } + // Second try all kernel binaries that don't have a dSYM + for (auto possible_kernel : m_kernel_binaries_without_dsyms) { + 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)) { + // module_sp is an actual kernel binary we want to add. + if (process) { + process->GetTarget().GetImages().AppendIfNeeded(module_sp); + error.Clear(); + return error; + } else { + error = ModuleList::GetSharedModule(kern_spec, module_sp, NULL, + NULL, NULL); + if (module_sp && module_sp->GetObjectFile() && + module_sp->GetObjectFile()->GetType() != + ObjectFile::Type::eTypeCoreFile) { + return error; } + module_sp.reset(); + } } - exe_module_sp.reset(); - } - return error; -} - -bool -PlatformDarwinKernel::GetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch) -{ -#if defined (__arm__) || defined (__arm64__) || defined (__aarch64__) - return ARMGetSupportedArchitectureAtIndex (idx, arch); + } + } + } + + // Else fall back to treating the file's path as an actual file path - defer + // to PlatformDarwin's GetSharedModule. + return PlatformDarwin::GetSharedModule(module_spec, process, module_sp, + module_search_paths_ptr, + old_module_sp_ptr, did_create_ptr); +} + +Error PlatformDarwinKernel::ExamineKextForMatchingUUID( + const FileSpec &kext_bundle_path, const lldb_private::UUID &uuid, + const ArchSpec &arch, ModuleSP &exe_module_sp) { + Error error; + FileSpec exe_file = kext_bundle_path; + Host::ResolveExecutableInBundle(exe_file); + if (exe_file.Exists()) { + ModuleSpec exe_spec(exe_file); + exe_spec.GetUUID() = uuid; + if (!uuid.IsValid()) { + exe_spec.GetArchitecture() = arch; + } + + // First try to create a ModuleSP with the file / arch and see if the UUID + // matches. + // If that fails (this exec file doesn't have the correct uuid), don't call + // GetSharedModule + // (which may call in to the DebugSymbols framework and therefore can be + // slow.) + ModuleSP module_sp(new Module(exe_spec)); + if (module_sp && module_sp->GetObjectFile() && + module_sp->MatchesModuleSpec(exe_spec)) { + error = ModuleList::GetSharedModule(exe_spec, exe_module_sp, NULL, NULL, + NULL); + if (exe_module_sp && exe_module_sp->GetObjectFile()) { + return error; + } + } + exe_module_sp.reset(); + } + return error; +} + +bool PlatformDarwinKernel::GetSupportedArchitectureAtIndex(uint32_t idx, + ArchSpec &arch) { +#if defined(__arm__) || defined(__arm64__) || defined(__aarch64__) + return ARMGetSupportedArchitectureAtIndex(idx, arch); #else - return x86GetSupportedArchitectureAtIndex (idx, arch); + return x86GetSupportedArchitectureAtIndex(idx, arch); #endif } -void -PlatformDarwinKernel::CalculateTrapHandlerSymbolNames () -{ - m_trap_handlers.push_back(ConstString ("trap_from_kernel")); - m_trap_handlers.push_back(ConstString ("hndl_machine_check")); - m_trap_handlers.push_back(ConstString ("hndl_double_fault")); - m_trap_handlers.push_back(ConstString ("hndl_allintrs")); - m_trap_handlers.push_back(ConstString ("hndl_alltraps")); - m_trap_handlers.push_back(ConstString ("interrupt")); - m_trap_handlers.push_back(ConstString ("fleh_prefabt")); - m_trap_handlers.push_back(ConstString ("ExceptionVectorsBase")); - m_trap_handlers.push_back(ConstString ("ExceptionVectorsTable")); - m_trap_handlers.push_back(ConstString ("fleh_undef")); - m_trap_handlers.push_back(ConstString ("fleh_dataabt")); - m_trap_handlers.push_back(ConstString ("fleh_irq")); - m_trap_handlers.push_back(ConstString ("fleh_decirq")); - m_trap_handlers.push_back(ConstString ("fleh_fiq_generic")); - m_trap_handlers.push_back(ConstString ("fleh_dec")); - +void PlatformDarwinKernel::CalculateTrapHandlerSymbolNames() { + m_trap_handlers.push_back(ConstString("trap_from_kernel")); + m_trap_handlers.push_back(ConstString("hndl_machine_check")); + m_trap_handlers.push_back(ConstString("hndl_double_fault")); + m_trap_handlers.push_back(ConstString("hndl_allintrs")); + m_trap_handlers.push_back(ConstString("hndl_alltraps")); + m_trap_handlers.push_back(ConstString("interrupt")); + m_trap_handlers.push_back(ConstString("fleh_prefabt")); + m_trap_handlers.push_back(ConstString("ExceptionVectorsBase")); + m_trap_handlers.push_back(ConstString("ExceptionVectorsTable")); + m_trap_handlers.push_back(ConstString("fleh_undef")); + m_trap_handlers.push_back(ConstString("fleh_dataabt")); + m_trap_handlers.push_back(ConstString("fleh_irq")); + m_trap_handlers.push_back(ConstString("fleh_decirq")); + m_trap_handlers.push_back(ConstString("fleh_fiq_generic")); + m_trap_handlers.push_back(ConstString("fleh_dec")); } -#else // __APPLE__ +#else // __APPLE__ // Since DynamicLoaderDarwinKernel is compiled in for all systems, and relies on -// PlatformDarwinKernel for the plug-in name, we compile just the plug-in name in -// here to avoid issues. We are tracking an internal bug to resolve this issue by -// either not compiling in DynamicLoaderDarwinKernel for non-apple builds, or to make -// PlatformDarwinKernel build on all systems. PlatformDarwinKernel is currently not +// PlatformDarwinKernel for the plug-in name, we compile just the plug-in name +// in +// here to avoid issues. We are tracking an internal bug to resolve this issue +// by +// either not compiling in DynamicLoaderDarwinKernel for non-apple builds, or to +// make +// PlatformDarwinKernel build on all systems. PlatformDarwinKernel is currently +// not // compiled on other platforms due to the use of the Mac-specific // source/Host/macosx/cfcpp utilities. -lldb_private::ConstString -PlatformDarwinKernel::GetPluginNameStatic () -{ - static lldb_private::ConstString g_name("darwin-kernel"); - return g_name; +lldb_private::ConstString PlatformDarwinKernel::GetPluginNameStatic() { + static lldb_private::ConstString g_name("darwin-kernel"); + return g_name; } #endif // __APPLE__ |