xref: /llvm-project/lldb/unittests/SymbolFile/DWARF/XcodeSDKModuleTests.cpp (revision 01d8e0fc75a897a6a9c2ce634645457a895ed505)
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