aboutsummaryrefslogtreecommitdiff
path: root/lld
diff options
context:
space:
mode:
authorGkvJwa <gkvjwa@gmail.com>2024-06-17 23:20:06 +0800
committerGitHub <noreply@github.com>2024-06-17 11:20:06 -0400
commitc11677eedb2c302df0392af4bf21fb2f4978669b (patch)
tree3ac49ffb7f47aca35d9cde4c706a62a809a98ddb /lld
parentf06575832aac0682c4d7383de34d2a9c20aa5837 (diff)
downloadllvm-c11677eedb2c302df0392af4bf21fb2f4978669b.zip
llvm-c11677eedb2c302df0392af4bf21fb2f4978669b.tar.gz
llvm-c11677eedb2c302df0392af4bf21fb2f4978669b.tar.bz2
[LLD][COFF] Support finding pdb files from outputpath (#94153)
In addition to looking for dependent (input) PDB files next to the associated .OBJ file, we now also look into the output folder as well. This mimics MSVC link.exe behavior. Fixes #94152
Diffstat (limited to 'lld')
-rw-r--r--lld/COFF/InputFiles.cpp45
-rw-r--r--lld/test/COFF/pdb-type-server-simple.test7
2 files changed, 32 insertions, 20 deletions
diff --git a/lld/COFF/InputFiles.cpp b/lld/COFF/InputFiles.cpp
index 037fae4..c334074 100644
--- a/lld/COFF/InputFiles.cpp
+++ b/lld/COFF/InputFiles.cpp
@@ -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-type-server-simple.test b/lld/test/COFF/pdb-type-server-simple.test
index e9757d1..93d66cd 100644
--- a/lld/test/COFF/pdb-type-server-simple.test
+++ b/lld/test/COFF/pdb-type-server-simple.test
@@ -27,6 +27,10 @@ Re-run with /DEBUG:GHASH
RUN: lld-link a.obj b.obj -entry:main -debug:ghash -out:t.exe -pdb:t.pdb -nodefaultlib -summary -verbose
RUN: llvm-pdbutil dump -symbols -types -ids -globals %t/t.pdb | FileCheck %s
+Re-run with pdb from outputpath
+RUN: mkdir -p libs
+RUN: cp a.obj libs/a.obj && cp b.obj libs/b.obj
+RUN: lld-link libs/a.obj libs/b.obj -entry:main -debug:ghash -out:t.exe -pdb:t.pdb -nodefaultlib -summary 2>&1 | FileCheck %s -check-prefix FAILURE-MISSING-PDBFILE
CHECK-LABEL: Types (TPI Stream)
CHECK: ============================================================
@@ -125,3 +129,6 @@ SUMMARY-NEXT: index total bytes count size
SUMMARY-NEXT: 0x1006: 256 = 1 * 256
SUMMARY: Run llvm-pdbutil to print details about a particular record:
SUMMARY-NEXT: llvm-pdbutil dump -ids -id-index 0x1006 t.pdb
+
+FAILURE-MISSING-PDBFILE-NOT: Cannot use debug info for '{{.*}}.obj'
+FAILURE-MISSING-PDBFILE-NOT: failed to load reference '{{.*}}.pdb': no such file or directory