[lld] Support finding pdb files from outputpath (PR #94153)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Jun 5 08:20:35 PDT 2024
https://github.com/GkvJwa updated https://github.com/llvm/llvm-project/pull/94153
>From 59a2b4b700449fd39626b72d53326915e2c48b18 Mon Sep 17 00:00:00 2001
From: GkvJwa <gkvjwa at gmail.com>
Date: Wed, 5 Jun 2024 23:20:12 +0800
Subject: [PATCH] Support finding pdb files from outputpath
---
lld/COFF/InputFiles.cpp | 49 ++++++++++++++------------
lld/test/COFF/pdb-from-outputpath.test | 34 ++++++++++++++++++
2 files changed, 61 insertions(+), 22 deletions(-)
create mode 100644 lld/test/COFF/pdb-from-outputpath.test
diff --git a/lld/COFF/InputFiles.cpp b/lld/COFF/InputFiles.cpp
index 037fae45242c6..66b73c78d92ba 100644
--- a/lld/COFF/InputFiles.cpp
+++ b/lld/COFF/InputFiles.cpp
@@ -735,8 +735,8 @@ void ObjFile::initializeFlags() {
(cs.Flags & CompileSym3Flags::HotPatch) != CompileSym3Flags::None;
}
if (sym->kind() == SymbolKind::S_OBJNAME) {
- auto objName = cantFail(SymbolDeserializer::deserializeAs<ObjNameSym>(
- sym.get()));
+ auto objName =
+ cantFail(SymbolDeserializer::deserializeAs<ObjNameSym>(sym.get()));
if (objName.Signature)
pchSignature = objName.Signature;
}
@@ -818,19 +818,6 @@ void ObjFile::initializeDependencies() {
debugTypesObj = makeTpiSource(ctx, this);
}
-// Make a PDB path assuming the PDB is in the same folder as the OBJ
-static std::string getPdbBaseName(ObjFile *file, StringRef tSPath) {
- StringRef localPath =
- !file->parentName.empty() ? file->parentName : file->getName();
- SmallString<128> path = sys::path::parent_path(localPath);
-
- // Currently, type server PDBs are only created by MSVC cl, which only runs
- // on Windows, so we can assume type server paths are Windows style.
- sys::path::append(path,
- sys::path::filename(tSPath, sys::path::Style::windows));
- return std::string(path);
-}
-
// The casing of the PDB path stamped in the OBJ can differ from the actual path
// on disk. With this, we ensure to always use lowercase as a key for the
// pdbInputFileInstances map, at least on Windows.
@@ -843,17 +830,35 @@ static std::string normalizePdbPath(StringRef path) {
}
// If existing, return the actual PDB path on disk.
-static std::optional<std::string> findPdbPath(StringRef pdbPath,
- ObjFile *dependentFile) {
+static std::optional<std::string>
+findPdbPath(StringRef pdbPath, ObjFile *dependentFile, StringRef outputPath) {
// Ensure the file exists before anything else. In some cases, if the path
// points to a removable device, Driver::enqueuePath() would fail with an
// error (EAGAIN, "resource unavailable try again") which we want to skip
// silently.
if (llvm::sys::fs::exists(pdbPath))
return normalizePdbPath(pdbPath);
- std::string ret = getPdbBaseName(dependentFile, pdbPath);
- if (llvm::sys::fs::exists(ret))
- return normalizePdbPath(ret);
+
+ StringRef objPath = !dependentFile->parentName.empty()
+ ? dependentFile->parentName
+ : dependentFile->getName();
+
+ // Currently, type server PDBs are only created by MSVC cl, which only runs
+ // on Windows, so we can assume type server paths are Windows style.
+ StringRef pdbName = sys::path::filename(pdbPath, sys::path::Style::windows);
+
+ // Check if the PDB is in the same folder as the OBJ.
+ SmallString<128> path;
+ sys::path::append(path, sys::path::parent_path(objPath), pdbName);
+ if (llvm::sys::fs::exists(path))
+ return normalizePdbPath(path);
+
+ // Check if the PDB is in the output folder.
+ path.clear();
+ sys::path::append(path, sys::path::parent_path(outputPath), pdbName);
+ if (llvm::sys::fs::exists(path))
+ return normalizePdbPath(path);
+
return std::nullopt;
}
@@ -865,7 +870,7 @@ PDBInputFile::~PDBInputFile() = default;
PDBInputFile *PDBInputFile::findFromRecordPath(const COFFLinkerContext &ctx,
StringRef path,
ObjFile *fromFile) {
- auto p = findPdbPath(path.str(), fromFile);
+ auto p = findPdbPath(path.str(), fromFile, ctx.config.outputFile);
if (!p)
return nullptr;
auto it = ctx.pdbInputFileInstances.find(*p);
@@ -931,7 +936,7 @@ std::optional<DILineInfo> ObjFile::getDILineInfo(uint32_t offset,
}
void ObjFile::enqueuePdbFile(StringRef path, ObjFile *fromFile) {
- auto p = findPdbPath(path.str(), fromFile);
+ auto p = findPdbPath(path.str(), fromFile, ctx.config.outputFile);
if (!p)
return;
auto it = ctx.pdbInputFileInstances.emplace(*p, nullptr);
diff --git a/lld/test/COFF/pdb-from-outputpath.test b/lld/test/COFF/pdb-from-outputpath.test
new file mode 100644
index 0000000000000..878e6cb2d4e33
--- /dev/null
+++ b/lld/test/COFF/pdb-from-outputpath.test
@@ -0,0 +1,34 @@
+Replicate this scenario:
+
+$ cat a.c
+struct Foo { int x; };
+int g(struct Foo *p);
+int main() {
+ struct Foo f = {42};
+ return g(&f);
+}
+
+$ cat b.c
+struct Foo { int x; };
+int g(struct Foo *p) { return p->x; }
+
+$ cl -c a.c b.c -Zi -Fdts.pdb
+
+$ lld-link a.obj b.obj -debug -entry:main -nodefaultlib -out:t.exe
+
+RUN: rm -rf %t && mkdir -p %t && mkdir -p %t/lib && cd %t
+
+RUN: yaml2obj %S/Inputs/pdb-type-server-simple-a.yaml -o lib/a.obj
+RUN: yaml2obj %S/Inputs/pdb-type-server-simple-b.yaml -o lib/b.obj
+RUN: llvm-pdbutil yaml2pdb %S/Inputs/pdb-type-server-simple-ts.yaml -pdb ts.pdb
+
+RUN: lld-link lib/a.obj lib/b.obj -debug -entry:main -nodefaultlib -out:t.exe
+RUN: llvm-pdbutil dump -l t.pdb | FileCheck %s
+
+CHECK: Lines
+CHECK: ============================================================
+CHECK-LABEL: Mod 0000 | `{{.*}}a.obj`:
+CHECK: {{.*}} (MD5: BF69E7E933074E1B7ED1FE8FB395965B)
+CHECK-LABEL: Mod 0001 | `{{.*}}b.obj`:
+CHECK: {{.*}} (MD5: DDF8FD35CD67990C5D4147516BE10D0C)
+CHECK-LABEL: Mod 0002 | `* Linker *`:
More information about the llvm-commits
mailing list