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-exception
6//
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's
32 /// DW_AT_LLVM_sysroot.
33 std::vector<llvm::StringRef> input_sdk_paths;
34
35 /// 'true' if we expect \ref GetSDKPathFromDebugInfo
36 /// to notify us about an SDK mismatch.
37 bool expect_mismatch;
38
39 /// 'true if the test expects the parsed SDK to
40 /// be an internal one.
41 bool expect_internal_sdk;
42
43 /// A substring that the final parsed sdk
44 /// is expected to contain.
45 llvm::StringRef expect_sdk_path_pattern;
46};
47
48struct SDKPathParsingMultiparamTests
49 : 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: 2
59 AddrSize: 8
60 AbbrevTableID: 0
61 AbbrOffset: 0x0
62 Entries:
63 - AbbrCode: 0x00000001
64 Values:
65 - Value: 0x000000000000000C
66 - CStr: {0}
67 - CStr: {1}
68 - AbbrCode: 0x00000000
69 )",
70 llvm::sys::path::filename(sdk_path, llvm::sys::path::Style::posix),
71 sdk_path));
72 }
73
74 return compile_units;
75 }
76};
77} // namespace
78
79TEST_F(XcodeSDKModuleTests, TestModuleGetXcodeSDK) {
80 const char *yamldata = R"(
81--- !ELF
82FileHeader:
83 Class: ELFCLASS64
84 Data: ELFDATA2LSB
85 Type: ET_EXEC
86 Machine: EM_386
87DWARF:
88 debug_str:
89 - MacOSX10.9.sdk
90 debug_abbrev:
91 - Table:
92 - Code: 0x00000001
93 Tag: DW_TAG_compile_unit
94 Children: DW_CHILDREN_no
95 Attributes:
96 - Attribute: DW_AT_language
97 Form: DW_FORM_data2
98 - Attribute: DW_AT_APPLE_sdk
99 Form: DW_FORM_strp
100 debug_info:
101 - Version: 2
102 AddrSize: 8
103 Entries:
104 - AbbrCode: 0x00000001
105 Values:
106 - Value: 0x000000000000000C
107 - Value: 0x0000000000000000
108 - AbbrCode: 0x00000000
109...
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--- !ELF
128FileHeader:
129 Class: ELFCLASS64
130 Data: ELFDATA2LSB
131 Type: ET_EXEC
132 Machine: EM_386
133DWARF:
134 debug_abbrev:
135 - Table:
136 - Code: 0x00000001
137 Tag: DW_TAG_compile_unit
138 Children: DW_CHILDREN_no
139 Attributes:
140 - Attribute: DW_AT_language
141 Form: DW_FORM_data2
142 - Attribute: DW_AT_APPLE_sdk
143 Form: DW_FORM_string
144 debug_info:
145 - Version: 2
146 AddrSize: 8
147 AbbrevTableID: 0
148 AbbrOffset: 0x0
149 Entries:
150 - AbbrCode: 0x00000001
151 Values:
152 - Value: 0x000000000000000C
153 - CStr: "1abc@defgh2"
154 - AbbrCode: 0x00000000
155...
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--- !ELF
174FileHeader:
175 Class: ELFCLASS64
176 Data: ELFDATA2LSB
177 Type: ET_EXEC
178 Machine: EM_386
179DWARF:
180 debug_abbrev:
181 - Table:
182 - Code: 0x00000001
183 Tag: DW_TAG_compile_unit
184 Children: DW_CHILDREN_no
185 Attributes:
186 - Attribute: DW_AT_language
187 Form: DW_FORM_data2
188 - Attribute: DW_AT_LLVM_sysroot
189 Form: DW_FORM_string
190 debug_info:
191 - Version: 2
192 AddrSize: 8
193 AbbrevTableID: 0
194 AbbrOffset: 0x0
195 Entries:
196 - AbbrCode: 0x00000001
197 Values:
198 - Value: 0x000000000000000C
199 - CStr: "/Library/Developer/CommandLineTools/SDKs/iPhoneOS14.0.Internal.sdk"
200 - AbbrCode: 0x00000000
201...
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 which
218 // points to an internal SDK, we should pick the internal SDK.
219
220 std::string yamldata = R"(
221--- !ELF
222FileHeader:
223 Class: ELFCLASS64
224 Data: ELFDATA2LSB
225 Type: ET_EXEC
226 Machine: EM_386
227DWARF:
228 debug_abbrev:
229 - Table:
230 - Code: 0x00000001
231 Tag: DW_TAG_compile_unit
232 Children: DW_CHILDREN_no
233 Attributes:
234 - Attribute: DW_AT_language
235 Form: DW_FORM_data2
236 - Attribute: DW_AT_APPLE_sdk
237 Form: DW_FORM_string
238 - Attribute: DW_AT_LLVM_sysroot
239 Form: DW_FORM_string
240 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 SDKs
279 {.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 SDK
289 {.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 SDK
296 {.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 each
303 {.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 each
311 {.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 SDK
318 {.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 SDK
326 {.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#endif
337

Provided by KDAB

Privacy Policy
Learn to use CMake with our Intro Training
Find out more

source code of lldb/unittests/SymbolFile/DWARF/XcodeSDKModuleTests.cpp