Skip to content

Commit f0d83f1

Browse files
adrian-prantlronlieb
authored andcommitted
Fix the dsymutil heuristic for excluding system interfaces. (llvm#93745)
The function was meant to find the Developer/ dir, but it found a Developer directory nested deep inside the top-level Developer dir. The new implementation rejects everything in Xcode.app/Developer in broad strokes. rdar: //128571037 Change-Id: Ieab957577601374237eea95dd07db01c131912d8
1 parent e9fc178 commit f0d83f1

File tree

2 files changed

+55
-8
lines changed

2 files changed

+55
-8
lines changed

llvm/include/llvm/DWARFLinker/Utils.h

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -36,17 +36,42 @@ inline Error finiteLoop(function_ref<Expected<bool>()> Iteration,
3636
return createStringError(std::errc::invalid_argument, "Infinite recursion");
3737
}
3838

39+
/// Make a best effort to guess the
3940
/// Xcode.app/Contents/Developer path from an SDK path.
4041
inline StringRef guessDeveloperDir(StringRef SysRoot) {
41-
// Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk
4242
SmallString<128> Result;
43-
StringRef Base = sys::path::parent_path(SysRoot);
44-
if (sys::path::filename(Base) != "SDKs")
45-
return Result;
46-
Base = sys::path::parent_path(Base);
47-
Result = Base;
48-
Result += "/Toolchains";
49-
return Result;
43+
// Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk
44+
auto it = sys::path::rbegin(SysRoot);
45+
auto end = sys::path::rend(SysRoot);
46+
if (it == end || !it->ends_with(".sdk"))
47+
return {};
48+
++it;
49+
// Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs
50+
if (it == end || *it != "SDKs")
51+
return {};
52+
auto developerEnd = it;
53+
++it;
54+
while (it != end) {
55+
// Contents/Developer/Platforms/MacOSX.platform/Developer
56+
if (*it != "Developer")
57+
return {};
58+
++it;
59+
if (it == end)
60+
return {};
61+
if (*it == "Contents")
62+
return StringRef(SysRoot.data(),
63+
developerEnd - sys::path::rend(SysRoot) - 1);
64+
// Contents/Developer/Platforms/MacOSX.platform
65+
if (!it->ends_with(".platform"))
66+
return {};
67+
++it;
68+
// Contents/Developer/Platforms
69+
if (it == end || *it != "Platforms")
70+
return {};
71+
developerEnd = it;
72+
++it;
73+
}
74+
return {};
5075
}
5176

5277
/// Make a best effort to determine whether Path is inside a toolchain.

llvm/unittests/DWARFLinkerParallel/DWARFLinkerTest.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,25 @@
55
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
66
//
77
//===----------------------------------------------------------------------===//
8+
9+
#include "llvm/DWARFLinker/Utils.h"
10+
#include "gtest/gtest.h"
11+
12+
using namespace llvm;
13+
using namespace dwarf_linker;
14+
15+
#define DEVELOPER_DIR "/Applications/Xcode.app/Contents/Developer"
16+
17+
namespace {
18+
19+
TEST(DWARFLinker, PathTest) {
20+
EXPECT_EQ(guessDeveloperDir("/Foo"), "");
21+
EXPECT_EQ(guessDeveloperDir("Foo.sdk"), "");
22+
EXPECT_EQ(guessDeveloperDir(
23+
DEVELOPER_DIR
24+
"/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.4.sdk"),
25+
DEVELOPER_DIR);
26+
EXPECT_EQ(guessDeveloperDir(DEVELOPER_DIR "/SDKs/MacOSX.sdk"), DEVELOPER_DIR);
27+
}
28+
29+
} // anonymous namespace

0 commit comments

Comments
 (0)