106e4f69bSAdrian Prantl //===-- XcodeSDKModuleTests.cpp -------------------------------------------===// 206e4f69bSAdrian Prantl // 306e4f69bSAdrian Prantl // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 406e4f69bSAdrian Prantl // See https://llvm.org/LICENSE.txt for license information. 506e4f69bSAdrian Prantl // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 606e4f69bSAdrian Prantl // 706e4f69bSAdrian Prantl //===----------------------------------------------------------------------===// 806e4f69bSAdrian Prantl 9a0919ac0SAdrian Prantl #include "Plugins/Platform/MacOSX/PlatformMacOSX.h" 1006e4f69bSAdrian Prantl #include "Plugins/SymbolFile/DWARF/DWARFCompileUnit.h" 1106e4f69bSAdrian Prantl #include "Plugins/SymbolFile/DWARF/DWARFDIE.h" 12a0919ac0SAdrian Prantl #include "Plugins/TypeSystem/Clang/TypeSystemClang.h" 1306e4f69bSAdrian Prantl #include "TestingSupport/Symbol/YAMLModuleTester.h" 14a0919ac0SAdrian Prantl #include "lldb/Core/PluginManager.h" 15b0b2b6baSMichael Buch #include "llvm/Support/Error.h" 16b0b2b6baSMichael Buch #include "llvm/Support/Path.h" 1706e4f69bSAdrian Prantl #include "gmock/gmock.h" 1806e4f69bSAdrian Prantl #include "gtest/gtest.h" 1906e4f69bSAdrian Prantl 2006e4f69bSAdrian Prantl using namespace lldb; 2106e4f69bSAdrian Prantl using namespace lldb_private; 22a669a237Swalter erquinigo using namespace lldb_private::plugin::dwarf; 2306e4f69bSAdrian Prantl 24a0919ac0SAdrian Prantl #ifdef __APPLE__ 2506e4f69bSAdrian Prantl namespace { 2606e4f69bSAdrian Prantl class XcodeSDKModuleTests : public testing::Test { 27c462048cSRaphael Isemann SubsystemRAII<HostInfoBase, PlatformMacOSX> subsystems; 2806e4f69bSAdrian Prantl }; 2906e4f69bSAdrian Prantl 30b0b2b6baSMichael Buch struct SDKPathParsingTestData { 31b0b2b6baSMichael Buch /// Each path will be put into a new CU's 32b0b2b6baSMichael Buch /// DW_AT_LLVM_sysroot. 33b0b2b6baSMichael Buch std::vector<llvm::StringRef> input_sdk_paths; 34b0b2b6baSMichael Buch 35b0b2b6baSMichael Buch /// 'true' if we expect \ref GetSDKPathFromDebugInfo 36b0b2b6baSMichael Buch /// to notify us about an SDK mismatch. 37b0b2b6baSMichael Buch bool expect_mismatch; 38b0b2b6baSMichael Buch 39b0b2b6baSMichael Buch /// 'true if the test expects the parsed SDK to 40b0b2b6baSMichael Buch /// be an internal one. 41b0b2b6baSMichael Buch bool expect_internal_sdk; 42b0b2b6baSMichael Buch 43b0b2b6baSMichael Buch /// A substring that the final parsed sdk 44b0b2b6baSMichael Buch /// is expected to contain. 45b0b2b6baSMichael Buch llvm::StringRef expect_sdk_path_pattern; 46b0b2b6baSMichael Buch }; 47b0b2b6baSMichael Buch 48b0b2b6baSMichael Buch struct SDKPathParsingMultiparamTests 49b0b2b6baSMichael Buch : public XcodeSDKModuleTests, 50b0b2b6baSMichael Buch public testing::WithParamInterface<SDKPathParsingTestData> { 51b0b2b6baSMichael Buch std::vector<std::string> 52b0b2b6baSMichael Buch createCompileUnits(std::vector<llvm::StringRef> const &sdk_paths) { 53b0b2b6baSMichael Buch std::vector<std::string> compile_units; 54b0b2b6baSMichael Buch 55b0b2b6baSMichael Buch for (auto sdk_path : sdk_paths) { 56b0b2b6baSMichael Buch compile_units.emplace_back(llvm::formatv( 57b0b2b6baSMichael Buch R"( 58b0b2b6baSMichael Buch - Version: 2 59b0b2b6baSMichael Buch AddrSize: 8 60b0b2b6baSMichael Buch AbbrevTableID: 0 61b0b2b6baSMichael Buch AbbrOffset: 0x0 62b0b2b6baSMichael Buch Entries: 63b0b2b6baSMichael Buch - AbbrCode: 0x00000001 64b0b2b6baSMichael Buch Values: 65b0b2b6baSMichael Buch - Value: 0x000000000000000C 66b0b2b6baSMichael Buch - CStr: {0} 67b0b2b6baSMichael Buch - CStr: {1} 68b0b2b6baSMichael Buch - AbbrCode: 0x00000000 69b0b2b6baSMichael Buch )", 70b0b2b6baSMichael Buch llvm::sys::path::filename(sdk_path, llvm::sys::path::Style::posix), 71b0b2b6baSMichael Buch sdk_path)); 72b0b2b6baSMichael Buch } 73b0b2b6baSMichael Buch 74b0b2b6baSMichael Buch return compile_units; 75b0b2b6baSMichael Buch } 76b0b2b6baSMichael Buch }; 77b0b2b6baSMichael Buch } // namespace 7806e4f69bSAdrian Prantl 7906e4f69bSAdrian Prantl TEST_F(XcodeSDKModuleTests, TestModuleGetXcodeSDK) { 8006e4f69bSAdrian Prantl const char *yamldata = R"( 81136d0674SJonas Devlieghere --- !ELF 82136d0674SJonas Devlieghere FileHeader: 83136d0674SJonas Devlieghere Class: ELFCLASS64 84136d0674SJonas Devlieghere Data: ELFDATA2LSB 85136d0674SJonas Devlieghere Type: ET_EXEC 86136d0674SJonas Devlieghere Machine: EM_386 87136d0674SJonas Devlieghere DWARF: 8806e4f69bSAdrian Prantl debug_str: 8906e4f69bSAdrian Prantl - MacOSX10.9.sdk 9006e4f69bSAdrian Prantl debug_abbrev: 91290e399fSXing GUO - Table: 9206e4f69bSAdrian Prantl - Code: 0x00000001 9306e4f69bSAdrian Prantl Tag: DW_TAG_compile_unit 9406e4f69bSAdrian Prantl Children: DW_CHILDREN_no 9506e4f69bSAdrian Prantl Attributes: 9606e4f69bSAdrian Prantl - Attribute: DW_AT_language 9706e4f69bSAdrian Prantl Form: DW_FORM_data2 9806e4f69bSAdrian Prantl - Attribute: DW_AT_APPLE_sdk 9906e4f69bSAdrian Prantl Form: DW_FORM_strp 10006e4f69bSAdrian Prantl debug_info: 1011d01fc10SXing GUO - Version: 2 10206e4f69bSAdrian Prantl AddrSize: 8 10306e4f69bSAdrian Prantl Entries: 10406e4f69bSAdrian Prantl - AbbrCode: 0x00000001 10506e4f69bSAdrian Prantl Values: 10606e4f69bSAdrian Prantl - Value: 0x000000000000000C 10706e4f69bSAdrian Prantl - Value: 0x0000000000000000 10806e4f69bSAdrian Prantl - AbbrCode: 0x00000000 10906e4f69bSAdrian Prantl ... 11006e4f69bSAdrian Prantl )"; 11106e4f69bSAdrian Prantl 112136d0674SJonas Devlieghere YAMLModuleTester t(yamldata); 113136d0674SJonas Devlieghere DWARFUnit *dwarf_unit = t.GetDwarfUnit(); 114136d0674SJonas Devlieghere auto *dwarf_cu = llvm::cast<DWARFCompileUnit>(dwarf_unit); 115136d0674SJonas Devlieghere ASSERT_TRUE(static_cast<bool>(dwarf_cu)); 1165935227eSAdrian Prantl SymbolFileDWARF &sym_file = dwarf_cu->GetSymbolFileDWARF(); 1175935227eSAdrian Prantl CompUnitSP comp_unit = sym_file.GetCompileUnitAtIndex(0); 118136d0674SJonas Devlieghere ASSERT_TRUE(static_cast<bool>(comp_unit.get())); 11901fc85dcSAdrian Prantl ModuleSP module = t.GetModule(); 12001fc85dcSAdrian Prantl ASSERT_EQ(module->GetSourceMappingList().GetSize(), 0u); 1215935227eSAdrian Prantl XcodeSDK sdk = sym_file.ParseXcodeSDK(*comp_unit); 12206e4f69bSAdrian Prantl ASSERT_EQ(sdk.GetType(), XcodeSDK::Type::MacOSX); 12301fc85dcSAdrian Prantl ASSERT_EQ(module->GetSourceMappingList().GetSize(), 1u); 12406e4f69bSAdrian Prantl } 125b0b2b6baSMichael Buch 126b0b2b6baSMichael Buch TEST_F(XcodeSDKModuleTests, TestSDKPathFromDebugInfo_InvalidSDKPath) { 127b0b2b6baSMichael Buch // Tests that parsing a CU with an invalid SDK directory name fails. 128b0b2b6baSMichael Buch 129b0b2b6baSMichael Buch const char *yamldata = R"( 130b0b2b6baSMichael Buch --- !ELF 131b0b2b6baSMichael Buch FileHeader: 132b0b2b6baSMichael Buch Class: ELFCLASS64 133b0b2b6baSMichael Buch Data: ELFDATA2LSB 134b0b2b6baSMichael Buch Type: ET_EXEC 135b0b2b6baSMichael Buch Machine: EM_386 136b0b2b6baSMichael Buch DWARF: 137b0b2b6baSMichael Buch debug_abbrev: 138b0b2b6baSMichael Buch - Table: 139b0b2b6baSMichael Buch - Code: 0x00000001 140b0b2b6baSMichael Buch Tag: DW_TAG_compile_unit 141b0b2b6baSMichael Buch Children: DW_CHILDREN_no 142b0b2b6baSMichael Buch Attributes: 143b0b2b6baSMichael Buch - Attribute: DW_AT_language 144b0b2b6baSMichael Buch Form: DW_FORM_data2 145b0b2b6baSMichael Buch - Attribute: DW_AT_APPLE_sdk 146b0b2b6baSMichael Buch Form: DW_FORM_string 147b0b2b6baSMichael Buch debug_info: 148b0b2b6baSMichael Buch - Version: 2 149b0b2b6baSMichael Buch AddrSize: 8 150b0b2b6baSMichael Buch AbbrevTableID: 0 151b0b2b6baSMichael Buch AbbrOffset: 0x0 152b0b2b6baSMichael Buch Entries: 153b0b2b6baSMichael Buch - AbbrCode: 0x00000001 154b0b2b6baSMichael Buch Values: 155b0b2b6baSMichael Buch - Value: 0x000000000000000C 156b0b2b6baSMichael Buch - CStr: "1abc@defgh2" 157b0b2b6baSMichael Buch - AbbrCode: 0x00000000 158b0b2b6baSMichael Buch ... 159b0b2b6baSMichael Buch )"; 160b0b2b6baSMichael Buch 161b0b2b6baSMichael Buch YAMLModuleTester t(yamldata); 162b0b2b6baSMichael Buch ModuleSP module = t.GetModule(); 163b0b2b6baSMichael Buch ASSERT_NE(module, nullptr); 164b0b2b6baSMichael Buch 1654bb13962SMichael Buch auto platform_sp = Platform::GetHostPlatform(); 1664bb13962SMichael Buch ASSERT_TRUE(platform_sp); 1674bb13962SMichael Buch auto path_or_err = platform_sp->ResolveSDKPathFromDebugInfo(*module); 168b0b2b6baSMichael Buch EXPECT_FALSE(static_cast<bool>(path_or_err)); 169b0b2b6baSMichael Buch llvm::consumeError(path_or_err.takeError()); 170b0b2b6baSMichael Buch } 171b0b2b6baSMichael Buch 172b0b2b6baSMichael Buch TEST_F(XcodeSDKModuleTests, TestSDKPathFromDebugInfo_No_DW_AT_APPLE_sdk) { 173b0b2b6baSMichael Buch // Tests that parsing a CU without a DW_AT_APPLE_sdk fails. 174b0b2b6baSMichael Buch 175b0b2b6baSMichael Buch const char *yamldata = R"( 176b0b2b6baSMichael Buch --- !ELF 177b0b2b6baSMichael Buch FileHeader: 178b0b2b6baSMichael Buch Class: ELFCLASS64 179b0b2b6baSMichael Buch Data: ELFDATA2LSB 180b0b2b6baSMichael Buch Type: ET_EXEC 181b0b2b6baSMichael Buch Machine: EM_386 182b0b2b6baSMichael Buch DWARF: 183b0b2b6baSMichael Buch debug_abbrev: 184b0b2b6baSMichael Buch - Table: 185b0b2b6baSMichael Buch - Code: 0x00000001 186b0b2b6baSMichael Buch Tag: DW_TAG_compile_unit 187b0b2b6baSMichael Buch Children: DW_CHILDREN_no 188b0b2b6baSMichael Buch Attributes: 189b0b2b6baSMichael Buch - Attribute: DW_AT_language 190b0b2b6baSMichael Buch Form: DW_FORM_data2 191b0b2b6baSMichael Buch - Attribute: DW_AT_LLVM_sysroot 192b0b2b6baSMichael Buch Form: DW_FORM_string 193b0b2b6baSMichael Buch debug_info: 194b0b2b6baSMichael Buch - Version: 2 195b0b2b6baSMichael Buch AddrSize: 8 196b0b2b6baSMichael Buch AbbrevTableID: 0 197b0b2b6baSMichael Buch AbbrOffset: 0x0 198b0b2b6baSMichael Buch Entries: 199b0b2b6baSMichael Buch - AbbrCode: 0x00000001 200b0b2b6baSMichael Buch Values: 201b0b2b6baSMichael Buch - Value: 0x000000000000000C 202b0b2b6baSMichael Buch - CStr: "/Library/Developer/CommandLineTools/SDKs/iPhoneOS14.0.Internal.sdk" 203b0b2b6baSMichael Buch - AbbrCode: 0x00000000 204b0b2b6baSMichael Buch ... 205b0b2b6baSMichael Buch )"; 206b0b2b6baSMichael Buch 207b0b2b6baSMichael Buch YAMLModuleTester t(yamldata); 208b0b2b6baSMichael Buch ModuleSP module = t.GetModule(); 209b0b2b6baSMichael Buch ASSERT_NE(module, nullptr); 210b0b2b6baSMichael Buch 2114bb13962SMichael Buch auto platform_sp = Platform::GetHostPlatform(); 2124bb13962SMichael Buch ASSERT_TRUE(platform_sp); 2134bb13962SMichael Buch auto path_or_err = platform_sp->ResolveSDKPathFromDebugInfo(*module); 214b0b2b6baSMichael Buch EXPECT_FALSE(static_cast<bool>(path_or_err)); 215b0b2b6baSMichael Buch llvm::consumeError(path_or_err.takeError()); 216b0b2b6baSMichael Buch } 217b0b2b6baSMichael Buch 218b0b2b6baSMichael Buch TEST_P(SDKPathParsingMultiparamTests, TestSDKPathFromDebugInfo) { 219b0b2b6baSMichael Buch // Tests that we can parse the SDK path from debug-info. 220b0b2b6baSMichael Buch // In the presence of multiple compile units, one of which 221b0b2b6baSMichael Buch // points to an internal SDK, we should pick the internal SDK. 222b0b2b6baSMichael Buch 223b0b2b6baSMichael Buch std::string yamldata = R"( 224b0b2b6baSMichael Buch --- !ELF 225b0b2b6baSMichael Buch FileHeader: 226b0b2b6baSMichael Buch Class: ELFCLASS64 227b0b2b6baSMichael Buch Data: ELFDATA2LSB 228b0b2b6baSMichael Buch Type: ET_EXEC 229b0b2b6baSMichael Buch Machine: EM_386 230b0b2b6baSMichael Buch DWARF: 231b0b2b6baSMichael Buch debug_abbrev: 232b0b2b6baSMichael Buch - Table: 233b0b2b6baSMichael Buch - Code: 0x00000001 234b0b2b6baSMichael Buch Tag: DW_TAG_compile_unit 235b0b2b6baSMichael Buch Children: DW_CHILDREN_no 236b0b2b6baSMichael Buch Attributes: 237b0b2b6baSMichael Buch - Attribute: DW_AT_language 238b0b2b6baSMichael Buch Form: DW_FORM_data2 239b0b2b6baSMichael Buch - Attribute: DW_AT_APPLE_sdk 240b0b2b6baSMichael Buch Form: DW_FORM_string 241b0b2b6baSMichael Buch - Attribute: DW_AT_LLVM_sysroot 242b0b2b6baSMichael Buch Form: DW_FORM_string 243b0b2b6baSMichael Buch debug_info: 244b0b2b6baSMichael Buch )"; 245b0b2b6baSMichael Buch 246b0b2b6baSMichael Buch auto [input_sdk_paths, expect_mismatch, expect_internal_sdk, 247b0b2b6baSMichael Buch expect_sdk_path_pattern] = GetParam(); 248b0b2b6baSMichael Buch 249b0b2b6baSMichael Buch for (auto &&sdk : createCompileUnits(input_sdk_paths)) 250b0b2b6baSMichael Buch yamldata += std::move(sdk); 251b0b2b6baSMichael Buch 252b0b2b6baSMichael Buch YAMLModuleTester t(yamldata); 253b0b2b6baSMichael Buch DWARFUnit *dwarf_unit = t.GetDwarfUnit(); 254b0b2b6baSMichael Buch auto *dwarf_cu = llvm::cast<DWARFCompileUnit>(dwarf_unit); 255b0b2b6baSMichael Buch ASSERT_TRUE(static_cast<bool>(dwarf_cu)); 256b0b2b6baSMichael Buch SymbolFileDWARF &sym_file = dwarf_cu->GetSymbolFileDWARF(); 257b0b2b6baSMichael Buch ASSERT_EQ(sym_file.GetNumCompileUnits(), input_sdk_paths.size()); 258b0b2b6baSMichael Buch ModuleSP module = t.GetModule(); 259b0b2b6baSMichael Buch ASSERT_NE(module, nullptr); 260b0b2b6baSMichael Buch 2614bb13962SMichael Buch auto platform_sp = Platform::GetHostPlatform(); 2624bb13962SMichael Buch ASSERT_TRUE(platform_sp); 2634bb13962SMichael Buch auto sdk_or_err = platform_sp->GetSDKPathFromDebugInfo(*module); 264b0b2b6baSMichael Buch ASSERT_TRUE(static_cast<bool>(sdk_or_err)); 265b0b2b6baSMichael Buch 266b0b2b6baSMichael Buch auto [sdk, found_mismatch] = *sdk_or_err; 267b0b2b6baSMichael Buch 268b0b2b6baSMichael Buch EXPECT_EQ(found_mismatch, expect_mismatch); 269b0b2b6baSMichael Buch EXPECT_EQ(sdk.IsAppleInternalSDK(), expect_internal_sdk); 270b0b2b6baSMichael Buch EXPECT_NE(sdk.GetString().find(expect_sdk_path_pattern), std::string::npos); 271*01d8e0fcSAdrian Prantl 272*01d8e0fcSAdrian Prantl { 273*01d8e0fcSAdrian Prantl auto sdk_or_err = 274*01d8e0fcSAdrian Prantl platform_sp->GetSDKPathFromDebugInfo(*dwarf_cu->GetLLDBCompUnit()); 275*01d8e0fcSAdrian Prantl ASSERT_TRUE(static_cast<bool>(sdk_or_err)); 276*01d8e0fcSAdrian Prantl EXPECT_EQ(sdk.IsAppleInternalSDK(), expect_internal_sdk); 277*01d8e0fcSAdrian Prantl } 278b0b2b6baSMichael Buch } 279b0b2b6baSMichael Buch 280b0b2b6baSMichael Buch SDKPathParsingTestData sdkPathParsingTestCases[] = { 281b0b2b6baSMichael Buch /// Multiple CUs with a mix of internal and public SDKs 282b0b2b6baSMichael Buch {.input_sdk_paths = 283b0b2b6baSMichael Buch {"/Library/Developer/CommandLineTools/SDKs/MacOSX10.9.sdk", 284b0b2b6baSMichael Buch "/invalid/path/to/something.invalid.sdk", 285b0b2b6baSMichael Buch "/Library/Developer/CommandLineTools/SDKs/iPhoneOS14.0.Internal.sdk", 286b0b2b6baSMichael Buch "/Library/Developer/CommandLineTools/SDKs/MacOSX10.9.sdk"}, 287b0b2b6baSMichael Buch .expect_mismatch = true, 288b0b2b6baSMichael Buch .expect_internal_sdk = true, 289b0b2b6baSMichael Buch .expect_sdk_path_pattern = "Internal.sdk"}, 290b0b2b6baSMichael Buch 291b0b2b6baSMichael Buch /// Single CU with a public SDK 292b0b2b6baSMichael Buch {.input_sdk_paths = 293b0b2b6baSMichael Buch {"/Library/Developer/CommandLineTools/SDKs/MacOSX10.9.sdk"}, 294b0b2b6baSMichael Buch .expect_mismatch = false, 295b0b2b6baSMichael Buch .expect_internal_sdk = false, 296b0b2b6baSMichael Buch .expect_sdk_path_pattern = "MacOSX10.9.sdk"}, 297b0b2b6baSMichael Buch 298b0b2b6baSMichael Buch /// Single CU with an internal SDK 299b0b2b6baSMichael Buch {.input_sdk_paths = 300b0b2b6baSMichael Buch {"/Library/Developer/CommandLineTools/SDKs/iPhoneOS14.0.Internal.sdk"}, 301b0b2b6baSMichael Buch .expect_mismatch = false, 302b0b2b6baSMichael Buch .expect_internal_sdk = true, 303b0b2b6baSMichael Buch .expect_sdk_path_pattern = "Internal.sdk"}, 304b0b2b6baSMichael Buch 305b0b2b6baSMichael Buch /// Two CUs with an internal SDK each 306b0b2b6baSMichael Buch {.input_sdk_paths = 307b0b2b6baSMichael Buch {"/Library/Developer/CommandLineTools/SDKs/iPhoneOS14.0.Internal.sdk", 308b0b2b6baSMichael Buch "/Library/Developer/CommandLineTools/SDKs/iPhoneOS12.9.Internal.sdk"}, 309b0b2b6baSMichael Buch .expect_mismatch = false, 310b0b2b6baSMichael Buch .expect_internal_sdk = true, 311b0b2b6baSMichael Buch .expect_sdk_path_pattern = "Internal.sdk"}, 312b0b2b6baSMichael Buch 313b0b2b6baSMichael Buch /// Two CUs with an internal SDK each 314b0b2b6baSMichael Buch {.input_sdk_paths = 315b0b2b6baSMichael Buch {"/Library/Developer/CommandLineTools/SDKs/iPhoneOS14.1.sdk", 316b0b2b6baSMichael Buch "/Library/Developer/CommandLineTools/SDKs/MacOSX11.3.sdk"}, 317b0b2b6baSMichael Buch .expect_mismatch = false, 318b0b2b6baSMichael Buch .expect_internal_sdk = false, 319b0b2b6baSMichael Buch .expect_sdk_path_pattern = "iPhoneOS14.1.sdk"}, 320b0b2b6baSMichael Buch }; 321b0b2b6baSMichael Buch 322f33b5b79SJonas Devlieghere INSTANTIATE_TEST_SUITE_P(SDKPathParsingTests, SDKPathParsingMultiparamTests, 323b0b2b6baSMichael Buch ::testing::ValuesIn(sdkPathParsingTestCases)); 32406e4f69bSAdrian Prantl #endif 325