[lld] r344061 - lld-link: Use /pdbsourcepath: for more places when present.

Nico Weber via llvm-commits llvm-commits at lists.llvm.org
Tue Oct 9 10:52:25 PDT 2018


Author: nico
Date: Tue Oct  9 10:52:25 2018
New Revision: 344061

URL: http://llvm.org/viewvc/llvm-project?rev=344061&view=rev
Log:
lld-link: Use /pdbsourcepath: for more places when present.

/pdbsourcepath: was added in https://reviews.llvm.org/D48882 to make it
possible to have relative paths in the debug info that clang-cl writes.
lld-link then makes the paths absolute at link time, which debuggers require.
This way, clang-cl's output is independent of the absolute path of the build
directory, which is useful for cacheability in distcc-like systems.

This patch extends /pdbsourcepath: (if passed) to also be used for:

1. The "cwd" stored in the env block in the pdb is /pdbsourcepath: if present
2. The "exe" stored in the env block in the pdb is made absolute relative
   to /pdbsourcepath: instead of the cwd
3. The "pdb" stored in the env block in the pdb is made absolute relative
   to /pdbsourcepath: instead of the cwd
4. For making absolute paths to .obj files referenced from the pdb

/pdbsourcepath: is now useful in three scenarios (the first one already working
before this change):

1. When building with full debug info, passing the real build dir to
   /pdbsourcepath: allows having clang-cl's output to be independent
   of the build directory path. This patch effectively doesn't change
   behavior for this use case (assuming the cwd is the build dir).

2. When building without compile-time debug info but linking with /debug,
   a fake fixed /pdbsourcepath: can be passed to get symbolized stacks
   while making the pdb and exe independent of the current build dir.
   For this two work, lld-link needs to be invoked with relative paths for
   the lld-link invocation itself (for "exe"), for the pdb output name, the exe
   output name (for "pdb"), and the obj input files, and no absolute path
   must appear on the link command (for "cmd" in the pdb's env block).
   Since no full debug info is present, it doesn't matter that the absolute
   path doesn't exist on disk -- we only get symbols in stacks.

3. When building production builds with full debug info that don't have
   local changes, and that get source indexed and their pdbs get uploaded
   to a symbol server. /pdbsourcepath: again makes the build output independent
   of the current directory, and the fixed path passed to /pdbsourcepath: can
   be given the source indexing transform so that it gets mapped to a
   repository path. This has the same requirements as 2.

This patch also makes it possible to create PDB files containing Windows-style
absolute paths when cross-compiling on a POSIX system.

Differential Revision: https://reviews.llvm.org/D53021

Modified:
    lld/trunk/COFF/PDB.cpp
    lld/trunk/test/COFF/pdb-relative-source-lines.test

Modified: lld/trunk/COFF/PDB.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/PDB.cpp?rev=344061&r1=344060&r2=344061&view=diff
==============================================================================
--- lld/trunk/COFF/PDB.cpp (original)
+++ lld/trunk/COFF/PDB.cpp Tue Oct  9 10:52:25 2018
@@ -218,6 +218,33 @@ public:
 };
 }
 
+// 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)
@@ -984,13 +1011,7 @@ void DebugSHandler::finish() {
   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 +1026,7 @@ void PDBLinker::addObjFile(ObjFile *File
   // 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 +1222,14 @@ static void addCommonLinkerModuleSymbols
   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 +1311,7 @@ void PDBLinker::addSections(ArrayRef<Out
   // 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 *"));

Modified: lld/trunk/test/COFF/pdb-relative-source-lines.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/pdb-relative-source-lines.test?rev=344061&r1=344060&r2=344061&view=diff
==============================================================================
--- lld/trunk/test/COFF/pdb-relative-source-lines.test (original)
+++ lld/trunk/test/COFF/pdb-relative-source-lines.test Tue Oct  9 10:52:25 2018
@@ -17,14 +17,26 @@ void bar(void) {
 
 $ 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:            - !FileChecksums
 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'




More information about the llvm-commits mailing list