};
}
+// Visual Studio's debugger requires absolute paths in various places in the
+// PDB to work without additional configuration:
+// https://docs.microsoft.com/en-us/visualstudio/debugger/debug-source-files-common-properties-solution-property-pages-dialog-box
+static void pdbMakeAbsolute(SmallVectorImpl<char> &FileName) {
+ if (sys::path::is_absolute(FileName, sys::path::Style::windows))
+ return;
+ if (Config->PDBSourcePath.empty()) {
+ // Debuggers generally want that PDB files contain absolute, Windows-style
+ // paths. On POSIX hosts, this here will produce an absolute POSIX-style
+ // path, which is weird -- but it's not clear what else to do.
+ // People doing cross builds should probably just always pass
+ // /pbdsourcepath: and make sure paths to input obj files and to lld-link
+ // itself are relative.
+ sys::fs::make_absolute(FileName);
+ return;
+ }
+ // Using /pdbsourcepath: with absolute POSIX paths will prepend
+ // PDBSourcePath to the absolute POSIX path. Since absolute POSIX paths
+ // don't make sense in PDB files anyways, this is gargabe-in-garbage-out.
+ 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<SectionChunk *> Sections,
StringRef Name) {
for (SectionChunk *C : Sections)
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);
// 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);
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);
// 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 *"));
$ 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'
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'