Skip to content

Commit c11677e

Browse files
authored
[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
1 parent f065758 commit c11677e

File tree

2 files changed

+32
-20
lines changed

2 files changed

+32
-20
lines changed

lld/COFF/InputFiles.cpp

Lines changed: 25 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -818,19 +818,6 @@ void ObjFile::initializeDependencies() {
818818
debugTypesObj = makeTpiSource(ctx, this);
819819
}
820820

821-
// Make a PDB path assuming the PDB is in the same folder as the OBJ
822-
static std::string getPdbBaseName(ObjFile *file, StringRef tSPath) {
823-
StringRef localPath =
824-
!file->parentName.empty() ? file->parentName : file->getName();
825-
SmallString<128> path = sys::path::parent_path(localPath);
826-
827-
// Currently, type server PDBs are only created by MSVC cl, which only runs
828-
// on Windows, so we can assume type server paths are Windows style.
829-
sys::path::append(path,
830-
sys::path::filename(tSPath, sys::path::Style::windows));
831-
return std::string(path);
832-
}
833-
834821
// The casing of the PDB path stamped in the OBJ can differ from the actual path
835822
// on disk. With this, we ensure to always use lowercase as a key for the
836823
// pdbInputFileInstances map, at least on Windows.
@@ -843,17 +830,35 @@ static std::string normalizePdbPath(StringRef path) {
843830
}
844831

845832
// If existing, return the actual PDB path on disk.
846-
static std::optional<std::string> findPdbPath(StringRef pdbPath,
847-
ObjFile *dependentFile) {
833+
static std::optional<std::string>
834+
findPdbPath(StringRef pdbPath, ObjFile *dependentFile, StringRef outputPath) {
848835
// Ensure the file exists before anything else. In some cases, if the path
849836
// points to a removable device, Driver::enqueuePath() would fail with an
850837
// error (EAGAIN, "resource unavailable try again") which we want to skip
851838
// silently.
852839
if (llvm::sys::fs::exists(pdbPath))
853840
return normalizePdbPath(pdbPath);
854-
std::string ret = getPdbBaseName(dependentFile, pdbPath);
855-
if (llvm::sys::fs::exists(ret))
856-
return normalizePdbPath(ret);
841+
842+
StringRef objPath = !dependentFile->parentName.empty()
843+
? dependentFile->parentName
844+
: dependentFile->getName();
845+
846+
// Currently, type server PDBs are only created by MSVC cl, which only runs
847+
// on Windows, so we can assume type server paths are Windows style.
848+
StringRef pdbName = sys::path::filename(pdbPath, sys::path::Style::windows);
849+
850+
// Check if the PDB is in the same folder as the OBJ.
851+
SmallString<128> path;
852+
sys::path::append(path, sys::path::parent_path(objPath), pdbName);
853+
if (llvm::sys::fs::exists(path))
854+
return normalizePdbPath(path);
855+
856+
// Check if the PDB is in the output folder.
857+
path.clear();
858+
sys::path::append(path, sys::path::parent_path(outputPath), pdbName);
859+
if (llvm::sys::fs::exists(path))
860+
return normalizePdbPath(path);
861+
857862
return std::nullopt;
858863
}
859864

@@ -865,7 +870,7 @@ PDBInputFile::~PDBInputFile() = default;
865870
PDBInputFile *PDBInputFile::findFromRecordPath(const COFFLinkerContext &ctx,
866871
StringRef path,
867872
ObjFile *fromFile) {
868-
auto p = findPdbPath(path.str(), fromFile);
873+
auto p = findPdbPath(path.str(), fromFile, ctx.config.outputFile);
869874
if (!p)
870875
return nullptr;
871876
auto it = ctx.pdbInputFileInstances.find(*p);
@@ -931,7 +936,7 @@ std::optional<DILineInfo> ObjFile::getDILineInfo(uint32_t offset,
931936
}
932937

933938
void ObjFile::enqueuePdbFile(StringRef path, ObjFile *fromFile) {
934-
auto p = findPdbPath(path.str(), fromFile);
939+
auto p = findPdbPath(path.str(), fromFile, ctx.config.outputFile);
935940
if (!p)
936941
return;
937942
auto it = ctx.pdbInputFileInstances.emplace(*p, nullptr);

lld/test/COFF/pdb-type-server-simple.test

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ Re-run with /DEBUG:GHASH
2727
RUN: lld-link a.obj b.obj -entry:main -debug:ghash -out:t.exe -pdb:t.pdb -nodefaultlib -summary -verbose
2828
RUN: llvm-pdbutil dump -symbols -types -ids -globals %t/t.pdb | FileCheck %s
2929

30+
Re-run with pdb from outputpath
31+
RUN: mkdir -p libs
32+
RUN: cp a.obj libs/a.obj && cp b.obj libs/b.obj
33+
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
3034

3135
CHECK-LABEL: Types (TPI Stream)
3236
CHECK: ============================================================
@@ -125,3 +129,6 @@ SUMMARY-NEXT: index total bytes count size
125129
SUMMARY-NEXT: 0x1006: 256 = 1 * 256
126130
SUMMARY: Run llvm-pdbutil to print details about a particular record:
127131
SUMMARY-NEXT: llvm-pdbutil dump -ids -id-index 0x1006 t.pdb
132+
133+
FAILURE-MISSING-PDBFILE-NOT: Cannot use debug info for '{{.*}}.obj'
134+
FAILURE-MISSING-PDBFILE-NOT: failed to load reference '{{.*}}.pdb': no such file or directory

0 commit comments

Comments
 (0)