[llvm] Fix the dsymutil heuristic for excluding system interfaces. (PR #93745)
Adrian Prantl via llvm-commits
llvm-commits at lists.llvm.org
Thu May 30 09:43:58 PDT 2024
https://github.com/adrian-prantl updated https://github.com/llvm/llvm-project/pull/93745
>From ad3dce49a5880811686dd5118c9ac0fd41948172 Mon Sep 17 00:00:00 2001
From: Adrian Prantl <aprantl at apple.com>
Date: Wed, 29 May 2024 16:08:01 -0700
Subject: [PATCH] Fix the dsymutil heuristic for excluding system interfaces.
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
---
llvm/include/llvm/DWARFLinker/Utils.h | 35 ++++++++++++++-----
llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp | 4 +--
.../Parallel/DWARFLinkerCompileUnit.cpp | 4 +--
.../DWARFLinkerParallel/DWARFLinkerTest.cpp | 22 ++++++++++++
4 files changed, 52 insertions(+), 13 deletions(-)
diff --git a/llvm/include/llvm/DWARFLinker/Utils.h b/llvm/include/llvm/DWARFLinker/Utils.h
index 23e59c967011a..693bb45abd840 100644
--- a/llvm/include/llvm/DWARFLinker/Utils.h
+++ b/llvm/include/llvm/DWARFLinker/Utils.h
@@ -37,17 +37,34 @@ inline Error finiteLoop(function_ref<Expected<bool>()> Iteration,
}
/// Make a best effort to guess the
-/// Xcode.app/Contents/Developer/Toolchains/ path from an SDK path.
-inline SmallString<128> guessToolchainBaseDir(StringRef SysRoot) {
+/// Xcode.app/Contents/Developer path from an SDK path.
+inline StringRef guessDeveloperDir(StringRef SysRoot) {
SmallString<128> Result;
// Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk
- StringRef Base = sys::path::parent_path(SysRoot);
- if (sys::path::filename(Base) != "SDKs")
- return Result;
- Base = sys::path::parent_path(Base);
- Result = Base;
- Result += "/Toolchains";
- return Result;
+ auto it = sys::path::rbegin(SysRoot);
+ if (!it->ends_with(".sdk"))
+ return {};
+ ++it;
+ if (*it != "SDKs")
+ return {};
+ auto developerEnd = it;
+ ++it;
+ while (it != sys::path::rend(SysRoot)) {
+ if (*it != "Developer")
+ return {};
+ ++it;
+ if (*it == "Contents")
+ return StringRef(SysRoot.data(),
+ developerEnd - sys::path::rend(SysRoot) - 1);
+ if (!it->ends_with(".platform"))
+ return {};
+ ++it;
+ if (*it != "Platforms")
+ return {};
+ developerEnd = it;
+ ++it;
+ }
+ return {};
}
inline bool isPathAbsoluteOnWindowsOrPosix(const Twine &Path) {
diff --git a/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp b/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp
index 3149d9b1d6624..84bbdfb5c3947 100644
--- a/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp
+++ b/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp
@@ -201,8 +201,8 @@ static void analyzeImportedModule(
return;
// Don't track interfaces that are part of the toolchain.
// For example: Swift, _Concurrency, ...
- SmallString<128> Toolchain = guessToolchainBaseDir(SysRoot);
- if (!Toolchain.empty() && Path.starts_with(Toolchain))
+ StringRef DeveloperDir = guessDeveloperDir(SysRoot);
+ if (!DeveloperDir.empty() && Path.starts_with(DeveloperDir))
return;
std::optional<const char *> Name =
dwarf::toString(DIE.find(dwarf::DW_AT_name));
diff --git a/llvm/lib/DWARFLinker/Parallel/DWARFLinkerCompileUnit.cpp b/llvm/lib/DWARFLinker/Parallel/DWARFLinkerCompileUnit.cpp
index 8c52040fdbc92..b50ea9ab49c1b 100644
--- a/llvm/lib/DWARFLinker/Parallel/DWARFLinkerCompileUnit.cpp
+++ b/llvm/lib/DWARFLinker/Parallel/DWARFLinkerCompileUnit.cpp
@@ -270,8 +270,8 @@ void CompileUnit::analyzeImportedModule(const DWARFDebugInfoEntry *DieEntry) {
return;
// Don't track interfaces that are part of the toolchain.
// For example: Swift, _Concurrency, ...
- SmallString<128> Toolchain = guessToolchainBaseDir(SysRoot);
- if (!Toolchain.empty() && Path.starts_with(Toolchain))
+ StringRef DeveloperDir = guessDeveloperDir(SysRoot);
+ if (!DeveloperDir.empty() && Path.starts_with(DeveloperDir))
return;
if (std::optional<DWARFFormValue> Val = find(DieEntry, dwarf::DW_AT_name)) {
Expected<const char *> Name = Val->getAsCString();
diff --git a/llvm/unittests/DWARFLinkerParallel/DWARFLinkerTest.cpp b/llvm/unittests/DWARFLinkerParallel/DWARFLinkerTest.cpp
index 0eb83d4b4fc9b..6439bf2cbc5f8 100644
--- a/llvm/unittests/DWARFLinkerParallel/DWARFLinkerTest.cpp
+++ b/llvm/unittests/DWARFLinkerParallel/DWARFLinkerTest.cpp
@@ -5,3 +5,25 @@
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
+
+#include "llvm/DWARFLinker/Utils.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+using namespace dwarf_linker;
+
+#define DEVELOPER_DIR "/Applications/Xcode.app/Contents/Developer"
+
+namespace {
+
+TEST(DWARFLinker, PathTest) {
+ EXPECT_EQ(guessDeveloperDir("/Foo"), "");
+ EXPECT_EQ(guessDeveloperDir("Foo.sdk"), "");
+ EXPECT_EQ(guessDeveloperDir(
+ DEVELOPER_DIR
+ "/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.4.sdk"),
+ DEVELOPER_DIR);
+ EXPECT_EQ(guessDeveloperDir(DEVELOPER_DIR "/SDKs/MacOSX.sdk"), DEVELOPER_DIR);
+}
+
+} // anonymous namespace
More information about the llvm-commits
mailing list