337 lines · cpp
1//===-- XcodeSDKModuleTests.cpp -------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "Plugins/Platform/MacOSX/PlatformMacOSX.h"10#include "Plugins/SymbolFile/DWARF/DWARFCompileUnit.h"11#include "Plugins/SymbolFile/DWARF/DWARFDIE.h"12#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"13#include "TestingSupport/Symbol/YAMLModuleTester.h"14#include "lldb/Core/PluginManager.h"15#include "llvm/Support/Error.h"16#include "llvm/Support/Path.h"17#include "gmock/gmock.h"18#include "gtest/gtest.h"19 20using namespace lldb;21using namespace lldb_private;22using namespace lldb_private::plugin::dwarf;23 24#ifdef __APPLE__25namespace {26class XcodeSDKModuleTests : public testing::Test {27 SubsystemRAII<HostInfoBase, PlatformMacOSX> subsystems;28};29 30struct SDKPathParsingTestData {31 /// Each path will be put into a new CU's32 /// DW_AT_LLVM_sysroot.33 std::vector<llvm::StringRef> input_sdk_paths;34 35 /// 'true' if we expect \ref GetSDKPathFromDebugInfo36 /// to notify us about an SDK mismatch.37 bool expect_mismatch;38 39 /// 'true if the test expects the parsed SDK to40 /// be an internal one.41 bool expect_internal_sdk;42 43 /// A substring that the final parsed sdk44 /// is expected to contain.45 llvm::StringRef expect_sdk_path_pattern;46};47 48struct SDKPathParsingMultiparamTests49 : public XcodeSDKModuleTests,50 public testing::WithParamInterface<SDKPathParsingTestData> {51 std::vector<std::string>52 createCompileUnits(std::vector<llvm::StringRef> const &sdk_paths) {53 std::vector<std::string> compile_units;54 55 for (auto sdk_path : sdk_paths) {56 compile_units.emplace_back(llvm::formatv(57 R"(58 - Version: 259 AddrSize: 860 AbbrevTableID: 061 AbbrOffset: 0x062 Entries:63 - AbbrCode: 0x0000000164 Values:65 - Value: 0x000000000000000C66 - CStr: {0}67 - CStr: {1}68 - AbbrCode: 0x0000000069 )",70 llvm::sys::path::filename(sdk_path, llvm::sys::path::Style::posix),71 sdk_path));72 }73 74 return compile_units;75 }76};77} // namespace78 79TEST_F(XcodeSDKModuleTests, TestModuleGetXcodeSDK) {80 const char *yamldata = R"(81--- !ELF82FileHeader:83 Class: ELFCLASS6484 Data: ELFDATA2LSB85 Type: ET_EXEC86 Machine: EM_38687DWARF:88 debug_str:89 - MacOSX10.9.sdk90 debug_abbrev:91 - Table:92 - Code: 0x0000000193 Tag: DW_TAG_compile_unit94 Children: DW_CHILDREN_no95 Attributes:96 - Attribute: DW_AT_language97 Form: DW_FORM_data298 - Attribute: DW_AT_APPLE_sdk99 Form: DW_FORM_strp100 debug_info:101 - Version: 2102 AddrSize: 8103 Entries:104 - AbbrCode: 0x00000001105 Values:106 - Value: 0x000000000000000C107 - Value: 0x0000000000000000108 - AbbrCode: 0x00000000109...110)";111 112 YAMLModuleTester t(yamldata);113 DWARFUnit *dwarf_unit = t.GetDwarfUnit();114 auto *dwarf_cu = llvm::cast<DWARFCompileUnit>(dwarf_unit);115 ASSERT_TRUE(static_cast<bool>(dwarf_cu));116 SymbolFileDWARF &sym_file = dwarf_cu->GetSymbolFileDWARF();117 CompUnitSP comp_unit = sym_file.GetCompileUnitAtIndex(0);118 ASSERT_TRUE(static_cast<bool>(comp_unit.get()));119 XcodeSDK sdk = sym_file.ParseXcodeSDK(*comp_unit);120 ASSERT_EQ(sdk.GetType(), XcodeSDK::Type::MacOSX);121}122 123TEST_F(XcodeSDKModuleTests, TestSDKPathFromDebugInfo_InvalidSDKPath) {124 // Tests that parsing a CU with an invalid SDK directory name fails.125 126 const char *yamldata = R"(127--- !ELF128FileHeader:129 Class: ELFCLASS64130 Data: ELFDATA2LSB131 Type: ET_EXEC132 Machine: EM_386133DWARF:134 debug_abbrev:135 - Table:136 - Code: 0x00000001137 Tag: DW_TAG_compile_unit138 Children: DW_CHILDREN_no139 Attributes:140 - Attribute: DW_AT_language141 Form: DW_FORM_data2142 - Attribute: DW_AT_APPLE_sdk143 Form: DW_FORM_string144 debug_info:145 - Version: 2146 AddrSize: 8147 AbbrevTableID: 0148 AbbrOffset: 0x0149 Entries:150 - AbbrCode: 0x00000001151 Values:152 - Value: 0x000000000000000C153 - CStr: "1abc@defgh2"154 - AbbrCode: 0x00000000155...156)";157 158 YAMLModuleTester t(yamldata);159 ModuleSP module = t.GetModule();160 ASSERT_NE(module, nullptr);161 162 auto platform_sp = Platform::GetHostPlatform();163 ASSERT_TRUE(platform_sp);164 auto path_or_err = platform_sp->ResolveSDKPathFromDebugInfo(*module);165 EXPECT_FALSE(static_cast<bool>(path_or_err));166 llvm::consumeError(path_or_err.takeError());167}168 169TEST_F(XcodeSDKModuleTests, TestSDKPathFromDebugInfo_No_DW_AT_APPLE_sdk) {170 // Tests that parsing a CU without a DW_AT_APPLE_sdk fails.171 172 const char *yamldata = R"(173--- !ELF174FileHeader:175 Class: ELFCLASS64176 Data: ELFDATA2LSB177 Type: ET_EXEC178 Machine: EM_386179DWARF:180 debug_abbrev:181 - Table:182 - Code: 0x00000001183 Tag: DW_TAG_compile_unit184 Children: DW_CHILDREN_no185 Attributes:186 - Attribute: DW_AT_language187 Form: DW_FORM_data2188 - Attribute: DW_AT_LLVM_sysroot189 Form: DW_FORM_string190 debug_info:191 - Version: 2192 AddrSize: 8193 AbbrevTableID: 0194 AbbrOffset: 0x0195 Entries:196 - AbbrCode: 0x00000001197 Values:198 - Value: 0x000000000000000C199 - CStr: "/Library/Developer/CommandLineTools/SDKs/iPhoneOS14.0.Internal.sdk"200 - AbbrCode: 0x00000000201...202)";203 204 YAMLModuleTester t(yamldata);205 ModuleSP module = t.GetModule();206 ASSERT_NE(module, nullptr);207 208 auto platform_sp = Platform::GetHostPlatform();209 ASSERT_TRUE(platform_sp);210 auto path_or_err = platform_sp->ResolveSDKPathFromDebugInfo(*module);211 EXPECT_FALSE(static_cast<bool>(path_or_err));212 llvm::consumeError(path_or_err.takeError());213}214 215TEST_P(SDKPathParsingMultiparamTests, TestSDKPathFromDebugInfo) {216 // Tests that we can parse the SDK path from debug-info.217 // In the presence of multiple compile units, one of which218 // points to an internal SDK, we should pick the internal SDK.219 220 std::string yamldata = R"(221--- !ELF222FileHeader:223 Class: ELFCLASS64224 Data: ELFDATA2LSB225 Type: ET_EXEC226 Machine: EM_386227DWARF:228 debug_abbrev:229 - Table:230 - Code: 0x00000001231 Tag: DW_TAG_compile_unit232 Children: DW_CHILDREN_no233 Attributes:234 - Attribute: DW_AT_language235 Form: DW_FORM_data2236 - Attribute: DW_AT_APPLE_sdk237 Form: DW_FORM_string238 - Attribute: DW_AT_LLVM_sysroot239 Form: DW_FORM_string240 debug_info:241)";242 243 auto [input_sdk_paths, expect_mismatch, expect_internal_sdk,244 expect_sdk_path_pattern] = GetParam();245 246 for (auto &&sdk : createCompileUnits(input_sdk_paths))247 yamldata += std::move(sdk);248 249 YAMLModuleTester t(yamldata);250 DWARFUnit *dwarf_unit = t.GetDwarfUnit();251 auto *dwarf_cu = llvm::cast<DWARFCompileUnit>(dwarf_unit);252 ASSERT_TRUE(static_cast<bool>(dwarf_cu));253 SymbolFileDWARF &sym_file = dwarf_cu->GetSymbolFileDWARF();254 ASSERT_EQ(sym_file.GetNumCompileUnits(), input_sdk_paths.size());255 ModuleSP module = t.GetModule();256 ASSERT_NE(module, nullptr);257 258 auto platform_sp = Platform::GetHostPlatform();259 ASSERT_TRUE(platform_sp);260 auto sdk_or_err = platform_sp->GetSDKPathFromDebugInfo(*module);261 ASSERT_TRUE(static_cast<bool>(sdk_or_err));262 263 auto [sdk, found_mismatch] = *sdk_or_err;264 265 EXPECT_EQ(found_mismatch, expect_mismatch);266 EXPECT_EQ(sdk.IsAppleInternalSDK(), expect_internal_sdk);267 EXPECT_NE(sdk.GetString().find(expect_sdk_path_pattern), std::string::npos);268 269 {270 auto sdk_or_err =271 platform_sp->GetSDKPathFromDebugInfo(*dwarf_cu->GetLLDBCompUnit());272 ASSERT_TRUE(static_cast<bool>(sdk_or_err));273 EXPECT_EQ(sdk.IsAppleInternalSDK(), expect_internal_sdk);274 }275}276 277SDKPathParsingTestData sdkPathParsingTestCases[] = {278 /// Multiple CUs with a mix of internal and public SDKs279 {.input_sdk_paths =280 {"/Library/Developer/CommandLineTools/SDKs/MacOSX10.9.sdk",281 "/invalid/path/to/something.invalid.sdk",282 "/Library/Developer/CommandLineTools/SDKs/iPhoneOS14.0.Internal.sdk",283 "/Library/Developer/CommandLineTools/SDKs/MacOSX10.9.sdk"},284 .expect_mismatch = true,285 .expect_internal_sdk = true,286 .expect_sdk_path_pattern = "Internal.sdk"},287 288 /// Single CU with a public SDK289 {.input_sdk_paths =290 {"/Library/Developer/CommandLineTools/SDKs/MacOSX10.9.sdk"},291 .expect_mismatch = false,292 .expect_internal_sdk = false,293 .expect_sdk_path_pattern = "MacOSX10.9.sdk"},294 295 /// Single CU with an internal SDK296 {.input_sdk_paths =297 {"/Library/Developer/CommandLineTools/SDKs/iPhoneOS14.0.Internal.sdk"},298 .expect_mismatch = false,299 .expect_internal_sdk = true,300 .expect_sdk_path_pattern = "Internal.sdk"},301 302 /// Two CUs with an internal SDK each303 {.input_sdk_paths =304 {"/Library/Developer/CommandLineTools/SDKs/iPhoneOS14.0.Internal.sdk",305 "/Library/Developer/CommandLineTools/SDKs/iPhoneOS12.9.Internal.sdk"},306 .expect_mismatch = false,307 .expect_internal_sdk = true,308 .expect_sdk_path_pattern = "Internal.sdk"},309 310 /// Two CUs with a public (non-CommandLineTools) SDK each311 {.input_sdk_paths = {"/Path/To/SDKs/iPhoneOS14.1.sdk",312 "/Path/To/SDKs/MacOSX11.3.sdk"},313 .expect_mismatch = false,314 .expect_internal_sdk = false,315 .expect_sdk_path_pattern = "iPhoneOS14.1.sdk"},316 317 /// One CU with CommandLineTools and the other a public SDK318 {.input_sdk_paths =319 {"/Library/Developer/CommandLineTools/SDKs/iPhoneOS14.1.sdk",320 "/Path/To/SDKs/MacOSX11.3.sdk"},321 .expect_mismatch = false,322 .expect_internal_sdk = false,323 .expect_sdk_path_pattern = "iPhoneOS14.1.sdk"},324 325 /// One CU with CommandLineTools and the other an internal SDK326 {.input_sdk_paths =327 {"/Library/Developer/CommandLineTools/SDKs/iPhoneOS14.1.sdk",328 "/Path/To/SDKs/MacOSX11.3.Internal.sdk"},329 .expect_mismatch = true,330 .expect_internal_sdk = true,331 .expect_sdk_path_pattern = "iPhoneOS14.1.Internal.sdk"},332};333 334INSTANTIATE_TEST_SUITE_P(SDKPathParsingTests, SDKPathParsingMultiparamTests,335 ::testing::ValuesIn(sdkPathParsingTestCases));336#endif337