Index: COFF/PDB.cpp =================================================================== --- COFF/PDB.cpp +++ COFF/PDB.cpp @@ -218,6 +218,23 @@ }; } +static void pdbMakeAbsolute(SmallVectorImpl &FileName) { + if (sys::path::is_absolute(FileName, sys::path::Style::windows)) + return; + if (Config->PDBSourcePath.empty()) { + // FIXME: make_absolute() should accept sys::path::Style::windows. + // Then we should pass that here. + sys::fs::make_absolute(FileName); + return; + } + SmallString<128> AbsoluteFileName = Config->PDBSourcePath; + sys::path::append(AbsoluteFileName, sys::path::Style::windows, FileName); + sys::path::native(AbsoluteFileName, sys::path::Style::windows); + sys::path::remove_dots(AbsoluteFileName, /*remove_dot_dots=*/true, + sys::path::Style::windows); + FileName = std::move(AbsoluteFileName); +} + static SectionChunk *findByName(ArrayRef Sections, StringRef Name) { for (SectionChunk *C : Sections) @@ -984,13 +1001,7 @@ for (FileChecksumEntry &FC : Checksums) { SmallString<128> FileName = ExitOnErr(CVStrTab.getString(FC.FileNameOffset)); - if (!sys::path::is_absolute(FileName) && !Config->PDBSourcePath.empty()) { - SmallString<128> AbsoluteFileName = Config->PDBSourcePath; - sys::path::append(AbsoluteFileName, FileName); - sys::path::native(AbsoluteFileName); - sys::path::remove_dots(AbsoluteFileName, /*remove_dot_dots=*/true); - FileName = std::move(AbsoluteFileName); - } + pdbMakeAbsolute(FileName); ExitOnErr(Linker.Builder.getDbiBuilder().addModuleSourceFile( *File.ModuleDBI, FileName)); NewChecksums->addChecksum(FileName, FC.Kind, FC.Checksum); @@ -1005,7 +1016,7 @@ // absolute. bool InArchive = !File->ParentName.empty(); SmallString<128> Path = InArchive ? File->ParentName : File->getName(); - sys::fs::make_absolute(Path); + pdbMakeAbsolute(Path); sys::path::native(Path, sys::path::Style::windows); StringRef Name = InArchive ? File->getName() : StringRef(Path); @@ -1201,11 +1212,14 @@ std::string ArgStr = llvm::join(Args, " "); EBS.Fields.push_back("cwd"); SmallString<64> cwd; - sys::fs::current_path(cwd); + if (Config->PDBSourcePath.empty()) + sys::fs::current_path(cwd); + else + cwd = Config->PDBSourcePath; EBS.Fields.push_back(cwd); EBS.Fields.push_back("exe"); SmallString<64> exe = Config->Argv[0]; - llvm::sys::fs::make_absolute(exe); + pdbMakeAbsolute(exe); EBS.Fields.push_back(exe); EBS.Fields.push_back("pdb"); EBS.Fields.push_back(Path); @@ -1287,7 +1301,7 @@ // It's not entirely clear what this is, but the * Linker * module uses it. pdb::DbiStreamBuilder &DbiBuilder = Builder.getDbiBuilder(); NativePath = Config->PDBPath; - sys::fs::make_absolute(NativePath); + pdbMakeAbsolute(NativePath); sys::path::native(NativePath, sys::path::Style::windows); uint32_t PdbFilePathNI = DbiBuilder.addECName(NativePath); auto &LinkerModule = ExitOnErr(DbiBuilder.addModuleInfo("* Linker *")); Index: test/COFF/pdb-relative-source-lines.test =================================================================== --- test/COFF/pdb-relative-source-lines.test +++ test/COFF/pdb-relative-source-lines.test @@ -17,14 +17,26 @@ $ clang-cl -Xclang -fdebug-compilation-dir -Xclang . -c -Z7 pdb_lines*.c -RUN: yaml2obj %S/Inputs/pdb_lines_1_relative.yaml -o %t.pdb_lines_1_relative.obj -RUN: yaml2obj %S/Inputs/pdb_lines_2_relative.yaml -o %t.pdb_lines_2_relative.obj -RUN: rm -f %t.exe %t.pdb -RUN: lld-link -debug -pdbsourcepath:c:\\src -entry:main -nodefaultlib -out:%t.exe -pdb:%t.pdb %t.pdb_lines_1_relative.obj %t.pdb_lines_2_relative.obj -RUN: llvm-pdbutil pdb2yaml -modules -module-files -subsections=lines,fc %t.pdb | FileCheck %s +/pdbsourcepath: only sets the directory that relative paths are considered +relative to, so this test needs to pass relative paths to lld-link for: +1. The input obj files +2. The /pdb: switch +3. The lld-link invocation itself +To achieve this, put all inputs of the lld-link invocation (including lld-link +itself) in a temp directory that's cwd and then make sure to only use relative +arguments when calling ./lld-link below. +RUN: rm -rf %t +RUN: mkdir %t +RUN: cp lld-link %t/lld-link +RUN: cd %t -CHECK-LABEL: - Module: {{.*}}pdb_lines_1_relative.obj -CHECK-NEXT: ObjFile: {{.*}}pdb_lines_1_relative.obj +RUN: yaml2obj %S/Inputs/pdb_lines_1_relative.yaml -o %t/pdb_lines_1_relative.obj +RUN: yaml2obj %S/Inputs/pdb_lines_2_relative.yaml -o %t/pdb_lines_2_relative.obj +RUN: ./lld-link -debug -pdbsourcepath:c:\\src -entry:main -nodefaultlib -out:out.exe -pdb:out.pdb pdb_lines_1_relative.obj pdb_lines_2_relative.obj +RUN: llvm-pdbutil pdb2yaml -modules -module-files -module-syms -subsections=lines,fc %t/out.pdb | FileCheck %s + +CHECK-LABEL: - Module: 'c:\src\pdb_lines_1_relative.obj' +CHECK-NEXT: ObjFile: 'c:\src\pdb_lines_1_relative.obj' CHECK: SourceFiles: CHECK-NEXT: - 'c:{{[\\/]}}src{{[\\/]}}pdb_lines_1.c' CHECK-NEXT: - 'c:{{[\\/]}}src{{[\\/]}}foo.h' @@ -35,11 +47,23 @@ CHECK: - FileName: 'c:{{[\\/]}}src{{[\\/]}}pdb_lines_1.c' CHECK: - FileName: 'c:{{[\\/]}}src{{[\\/]}}foo.h' -CHECK-LABEL: - Module: {{.*}}pdb_lines_2_relative.obj -CHECK-NEXT: ObjFile: {{.*}}pdb_lines_2_relative.obj +CHECK-LABEL: - Module: 'c:\src\pdb_lines_2_relative.obj' +CHECK-NEXT: ObjFile: 'c:\src\pdb_lines_2_relative.obj' CHECK: SourceFiles: CHECK-NEXT: - 'c:{{[\\/]}}src{{[\\/]}}pdb_lines_2.c' CHECK: Subsections: CHECK: - FileName: 'c:{{[\\/]}}src{{[\\/]}}pdb_lines_2.c' CHECK: - !FileChecksums CHECK: - FileName: 'c:{{[\\/]}}src{{[\\/]}}pdb_lines_2.c' + +CHECK-LABEL: - Kind: S_ENVBLOCK +CHECK-NEXT: EnvBlockSym: +CHECK-NEXT: Entries: +CHECK-NEXT: - cwd +CHECK-NEXT: - 'c:\src' +CHECK-NEXT: - exe +CHECK-NEXT: - 'c:\src\lld-link' +CHECK-NEXT: - pdb +CHECK-NEXT: - 'c:\src\out.pdb' +CHECK-NEXT: - cmd +CHECK-NEXT: - '-debug -pdbsourcepath:c:\src -entry:main -nodefaultlib -out:out.exe -pdb:out.pdb pdb_lines_1_relative.obj pdb_lines_2_relative.obj'