Michael137 updated this revision to Diff 543967. Michael137 marked an inline comment as not done. Michael137 added a comment.
- Update unit-tests - Expand function docs Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D156020/new/ https://reviews.llvm.org/D156020 Files: lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h lldb/unittests/SymbolFile/DWARF/XcodeSDKModuleTests.cpp
Index: lldb/unittests/SymbolFile/DWARF/XcodeSDKModuleTests.cpp =================================================================== --- lldb/unittests/SymbolFile/DWARF/XcodeSDKModuleTests.cpp +++ lldb/unittests/SymbolFile/DWARF/XcodeSDKModuleTests.cpp @@ -12,6 +12,7 @@ #include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include "TestingSupport/Symbol/YAMLModuleTester.h" #include "lldb/Core/PluginManager.h" +#include "llvm/Support/Error.h" #include "gmock/gmock.h" #include "gtest/gtest.h" @@ -72,4 +73,181 @@ ASSERT_EQ(sdk.GetType(), XcodeSDK::Type::MacOSX); ASSERT_EQ(module->GetSourceMappingList().GetSize(), 1u); } + +TEST_F(XcodeSDKModuleTests, TestSDKPathFromDebugInfo_InternalAndPublicSDK) { + // Tests that we can parse the SDK path from debug-info. + // In the presence of multiple compile units, one of which + // points to an internal SDK, we should pick the internal SDK. + + const char *yamldata = R"( +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_EXEC + Machine: EM_386 +DWARF: + debug_abbrev: + - Table: + - Code: 0x00000001 + Tag: DW_TAG_compile_unit + Children: DW_CHILDREN_no + Attributes: + - Attribute: DW_AT_language + Form: DW_FORM_data2 + - Attribute: DW_AT_APPLE_sdk + Form: DW_FORM_string + - Attribute: DW_AT_LLVM_sysroot + Form: DW_FORM_string + debug_info: + - Version: 2 + AddrSize: 8 + AbbrevTableID: 0 + AbbrOffset: 0x0 + Entries: + - AbbrCode: 0x00000001 + Values: + - Value: 0x000000000000000C + - CStr: "MacOSX10.9.sdk" + - CStr: "/Library/Developer/CommandLineTools/SDKs/MacOSX10.9.sdk" + - AbbrCode: 0x00000000 + - Version: 2 + AddrSize: 8 + AbbrevTableID: 0 + AbbrOffset: 0x0 + Entries: + - AbbrCode: 0x00000001 + Values: + - Value: 0x0000000000000010 + - CStr: "something.invalid.sdk" + - CStr: "/invalid/path/to/something.invalid.sdk" + - AbbrCode: 0x00000000 + - Version: 2 + AddrSize: 8 + AbbrevTableID: 0 + AbbrOffset: 0x0 + Entries: + - AbbrCode: 0x00000001 + Values: + - Value: 0x0000000000000010 + - CStr: "iPhoneOS14.0.Internal.sdk" + - CStr: "/Library/Developer/CommandLineTools/SDKs/iPhoneOS14.0.Internal.sdk" + - AbbrCode: 0x00000000 + - Version: 2 + AddrSize: 8 + AbbrevTableID: 0 + AbbrOffset: 0x0 + Entries: + - AbbrCode: 0x00000001 + Values: + - Value: 0x000000000000000C + - CStr: "MacOSX10.9.sdk" + - CStr: "/Library/Developer/CommandLineTools/SDKs/MacOSX10.9.sdk" + - AbbrCode: 0x00000000 +... +)"; + + YAMLModuleTester t(yamldata); + DWARFUnit *dwarf_unit = t.GetDwarfUnit(); + auto *dwarf_cu = llvm::cast<DWARFCompileUnit>(dwarf_unit); + ASSERT_TRUE(static_cast<bool>(dwarf_cu)); + SymbolFileDWARF &sym_file = dwarf_cu->GetSymbolFileDWARF(); + ASSERT_EQ(sym_file.GetNumCompileUnits(), 4U); + ModuleSP module = t.GetModule(); + ASSERT_NE(module, nullptr); + + auto sdk_or_err = PlatformDarwin::GetSDKPathFromDebugInfo(*module); + ASSERT_TRUE(static_cast<bool>(sdk_or_err)); + + ASSERT_TRUE(sdk_or_err->IsAppleInternalSDK()); + ASSERT_NE(sdk_or_err->GetString().find("Internal.sdk"), std::string::npos); +} + +TEST_F(XcodeSDKModuleTests, TestSDKPathFromDebugInfo_InvalidSDKPath) { + // Tests that parsing a CU with an invalid SDK directory name fails. + + const char *yamldata = R"( +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_EXEC + Machine: EM_386 +DWARF: + debug_abbrev: + - Table: + - Code: 0x00000001 + Tag: DW_TAG_compile_unit + Children: DW_CHILDREN_no + Attributes: + - Attribute: DW_AT_language + Form: DW_FORM_data2 + - Attribute: DW_AT_APPLE_sdk + Form: DW_FORM_string + debug_info: + - Version: 2 + AddrSize: 8 + AbbrevTableID: 0 + AbbrOffset: 0x0 + Entries: + - AbbrCode: 0x00000001 + Values: + - Value: 0x000000000000000C + - CStr: "1abc@defgh2" + - AbbrCode: 0x00000000 +... +)"; + + YAMLModuleTester t(yamldata); + ModuleSP module = t.GetModule(); + ASSERT_NE(module, nullptr); + + auto path_or_err = PlatformDarwin::ResolveSDKPathFromDebugInfo(*module); + ASSERT_FALSE(static_cast<bool>(path_or_err)); + llvm::consumeError(path_or_err.takeError()); +} + +TEST_F(XcodeSDKModuleTests, TestSDKPathFromDebugInfo_No_DW_AT_APPLE_sdk) { + // Tests that parsing a CU without a DW_AT_APPLE_sdk fails. + + const char *yamldata = R"( +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_EXEC + Machine: EM_386 +DWARF: + debug_abbrev: + - Table: + - Code: 0x00000001 + Tag: DW_TAG_compile_unit + Children: DW_CHILDREN_no + Attributes: + - Attribute: DW_AT_language + Form: DW_FORM_data2 + - Attribute: DW_AT_LLVM_sysroot + Form: DW_FORM_string + debug_info: + - Version: 2 + AddrSize: 8 + AbbrevTableID: 0 + AbbrOffset: 0x0 + Entries: + - AbbrCode: 0x00000001 + Values: + - Value: 0x000000000000000C + - CStr: "/Library/Developer/CommandLineTools/SDKs/iPhoneOS14.0.Internal.sdk" + - AbbrCode: 0x00000000 +... +)"; + + YAMLModuleTester t(yamldata); + ModuleSP module = t.GetModule(); + ASSERT_NE(module, nullptr); + + auto path_or_err = PlatformDarwin::ResolveSDKPathFromDebugInfo(*module); + ASSERT_FALSE(static_cast<bool>(path_or_err)); + llvm::consumeError(path_or_err.takeError()); +} #endif Index: lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h =================================================================== --- lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h +++ lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h @@ -124,6 +124,29 @@ /// located in. static FileSpec GetCurrentCommandLineToolsDirectory(); + /// Search each CU associated with the specified 'module' for + /// the SDK paths the CUs were compiled against. In the presence + /// of different SDKs, we try to pick the most appropriate one + /// using \ref XcodeSDK::Merge. + /// + /// \param[in] module Module whose debug-info CUs to parse for + /// which SDK they were compiled against. + /// + /// \returns If successful, returns a parsed XcodeSDK object. + static llvm::Expected<XcodeSDK> GetSDKPathFromDebugInfo(Module &module); + + /// Returns the full path of the most appropriate SDK for the + /// specified 'module'. This function gets this path by parsing + /// debug-info (see \ref `GetSDKPathFromDebugInfo`). + /// + /// \param[in] module Module whose debug-info to parse for + /// which SDK it was compiled against. + /// + /// \returns If successful, returns the full path to an + /// Xcode SDK. + static llvm::Expected<std::string> + ResolveSDKPathFromDebugInfo(Module &module); + protected: static const char *GetCompatibleArch(ArchSpec::Core core, size_t idx); Index: lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp =================================================================== --- lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp +++ lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp @@ -42,6 +42,7 @@ #include "lldb/Utility/Status.h" #include "lldb/Utility/Timer.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/Support/Error.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/Threading.h" #include "llvm/Support/VersionTuple.h" @@ -1095,8 +1096,21 @@ } FileSpec sysroot_spec; - // Scope for mutex locker below - { + + if (target) { + if (ModuleSP exe_module_sp = target->GetExecutableModule()) { + auto path_or_err = ResolveSDKPathFromDebugInfo(*exe_module_sp); + if (path_or_err) { + sysroot_spec = FileSpec(*path_or_err); + } else { + LLDB_LOG_ERROR(GetLog(LLDBLog::Types | LLDBLog::Host), + path_or_err.takeError(), + "Failed to resolve SDK path: {0}"); + } + } + } + + if (!FileSystem::Instance().IsDirectory(sysroot_spec.GetPath())) { std::lock_guard<std::mutex> guard(m_mutex); sysroot_spec = GetSDKDirectoryForModules(sdk_type); } @@ -1335,3 +1349,41 @@ #endif #endif // __APPLE__ } + +llvm::Expected<XcodeSDK> +PlatformDarwin::GetSDKPathFromDebugInfo(Module &module) { + SymbolFile *sym_file = module.GetSymbolFile(); + if (!sym_file) + return llvm::createStringError( + llvm::inconvertibleErrorCode(), + llvm::formatv("No symbol file available for module '{0}'", + module.GetFileSpec().GetFilename().AsCString(""))); + + XcodeSDK sdk; + for (unsigned i = 0; i < sym_file->GetNumCompileUnits(); ++i) + if (auto cu_sp = sym_file->GetCompileUnitAtIndex(i)) + sdk.Merge(sym_file->ParseXcodeSDK(*cu_sp)); + + return sdk; +} + +llvm::Expected<std::string> +PlatformDarwin::ResolveSDKPathFromDebugInfo(Module &module) { + auto sdk_or_err = GetSDKPathFromDebugInfo(module); + if (!sdk_or_err) + return llvm::createStringError( + llvm::inconvertibleErrorCode(), + llvm::formatv("Failed to parse SDK path from debug-info: {0}", + llvm::toString(sdk_or_err.takeError()))); + + auto path_or_err = + HostInfo::GetSDKRoot(HostInfo::SDKOptions{std::move(*sdk_or_err)}); + if (!path_or_err) + return llvm::createStringError( + llvm::inconvertibleErrorCode(), + llvm::formatv("Error while searching for SDK (XcodeSDK '{0}'): {1}", + sdk_or_err->GetString(), + llvm::toString(path_or_err.takeError()))); + + return path_or_err->str(); +}
_______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits