[lld] r346403 - [LLD] Fix Microsoft precompiled headers cross-compile on Linux

Alexandre Ganea via llvm-commits llvm-commits at lists.llvm.org
Thu Nov 8 06:42:38 PST 2018


Author: aganea
Date: Thu Nov  8 06:42:37 2018
New Revision: 346403

URL: http://llvm.org/viewvc/llvm-project?rev=346403&view=rev
Log:
[LLD] Fix Microsoft precompiled headers cross-compile on Linux

Differential revision: https://reviews.llvm.org/D54122

Modified:
    lld/trunk/COFF/PDB.cpp
    lld/trunk/COFF/SymbolTable.cpp
    lld/trunk/test/COFF/precomp-link.test

Modified: lld/trunk/COFF/PDB.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/PDB.cpp?rev=346403&r1=346402&r2=346403&view=diff
==============================================================================
--- lld/trunk/COFF/PDB.cpp (original)
+++ lld/trunk/COFF/PDB.cpp Thu Nov  8 06:42:37 2018
@@ -645,7 +645,7 @@ PDBLinker::mergeInPrecompHeaderObj(ObjFi
 
   auto E = aquirePrecompObj(File, Precomp);
   if (!E)
-    return createFileError(Precomp.getPrecompFilePath().str(), E.takeError());
+    return E.takeError();
 
   const CVIndexMap &PrecompIndexMap = *E;
   assert(PrecompIndexMap.IsPrecompiledTypeMap);
@@ -670,28 +670,18 @@ static bool equals_path(StringRef path1,
 #endif
 }
 
-// Find an OBJ provided on the command line, either by name or full path
-static Optional<std::pair<ObjFile *, std::string>>
-findObjByName(StringRef NameOrPath) {
+// Find by name an OBJ provided on the command line
+static ObjFile *findObjByName(StringRef FileNameOnly) {
   SmallString<128> CurrentPath;
 
-  StringRef FileNameOnly = sys::path::filename(NameOrPath);
-
   for (ObjFile *F : ObjFile::Instances) {
-    CurrentPath = F->getName();
-    sys::fs::make_absolute(CurrentPath);
-
-    // First compare with the full path name
-    if (equals_path(CurrentPath, NameOrPath))
-      return std::make_pair(F, CurrentPath.str().str());
+    StringRef CurrentFileName = sys::path::filename(F->getName());
 
-    StringRef CurrentFileName = sys::path::filename(CurrentPath);
-
-    // Otherwise compare based solely on the file name (link.exe behavior)
+    // Compare based solely on the file name (link.exe behavior)
     if (equals_path(CurrentFileName, FileNameOnly))
-      return std::make_pair(F, CurrentPath.str().str());
+      return F;
   }
-  return {};
+  return nullptr;
 }
 
 std::pair<CVIndexMap &, bool /*already there*/>
@@ -715,29 +705,29 @@ PDBLinker::aquirePrecompObj(ObjFile *Fil
 
   CVIndexMap &IndexMap = R.first;
 
-  SmallString<128> PrecompPath = Precomp.getPrecompFilePath();
-  sys::fs::make_absolute(PrecompPath);
-
   // Cross-compile warning: given that Clang doesn't generate LF_PRECOMP
   // records, we assume the OBJ comes from a Windows build of cl.exe. Thusly,
   // the paths embedded in the OBJs are in the Windows format.
-  sys::path::native(PrecompPath, sys::path::Style::windows);
+  SmallString<128> PrecompFileName = sys::path::filename(
+      Precomp.getPrecompFilePath(), sys::path::Style::windows);
 
   // link.exe requires that a precompiled headers object must always be provided
   // on the command-line, even if that's not necessary.
-  auto PrecompFilePath = findObjByName(PrecompPath);
-  if (!PrecompFilePath)
-    return errorCodeToError(std::error_code(ENOENT, std::generic_category()));
-
-  ObjFile *CurrentFile = PrecompFilePath->first;
-
-  addObjFile(CurrentFile, &IndexMap);
-
-  if (!CurrentFile->EndPrecomp)
-    fatal(PrecompFilePath->second + " is not a precompiled headers object");
-
-  if (Precomp.getSignature() != CurrentFile->EndPrecomp->getSignature())
-    return make_error<pdb::PDBError>(pdb::pdb_error_code::signature_out_of_date);
+  auto PrecompFile = findObjByName(PrecompFileName);
+  if (!PrecompFile)
+    return createFileError(
+        PrecompFileName.str(),
+        make_error<pdb::PDBError>(pdb::pdb_error_code::external_cmdline_ref));
+
+  addObjFile(PrecompFile, &IndexMap);
+
+  if (!PrecompFile->EndPrecomp)
+    fatal(PrecompFile->getName() + " is not a precompiled headers object");
+
+  if (Precomp.getSignature() != PrecompFile->EndPrecomp->getSignature())
+    return createFileError(
+        Precomp.getPrecompFilePath().str(),
+        make_error<pdb::PDBError>(pdb::pdb_error_code::signature_out_of_date));
 
   return IndexMap;
 }

Modified: lld/trunk/COFF/SymbolTable.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/SymbolTable.cpp?rev=346403&r1=346402&r2=346403&view=diff
==============================================================================
--- lld/trunk/COFF/SymbolTable.cpp (original)
+++ lld/trunk/COFF/SymbolTable.cpp Thu Nov  8 06:42:37 2018
@@ -241,6 +241,11 @@ void SymbolTable::reportRemainingUndefin
       }
     }
 
+    // We don't want to report missing Microsoft precompiled headers symbols.
+    // A proper message will be emitted instead in PDBLinker::aquirePrecompObj
+    if (Name.contains("_PchSym_"))
+      continue;
+
     if (Config->MinGW && handleMinGWAutomaticImport(Sym, Name))
       continue;
 

Modified: lld/trunk/test/COFF/precomp-link.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/precomp-link.test?rev=346403&r1=346402&r2=346403&view=diff
==============================================================================
--- lld/trunk/test/COFF/precomp-link.test (original)
+++ lld/trunk/test/COFF/precomp-link.test Thu Nov  8 06:42:37 2018
@@ -1,5 +1,3 @@
-REQUIRES: system-windows
-
 RUN: lld-link %S/Inputs/precomp-a.obj %S/Inputs/precomp-b.obj %S/Inputs/precomp.obj /nodefaultlib /entry:main /debug /pdb:%t.pdb /out:%t.exe /opt:ref /opt:icf
 RUN: llvm-pdbutil dump -types %t.pdb | FileCheck %s
 
@@ -8,9 +6,14 @@ RUN: llvm-pdbutil dump -types %t.pdb | F
 
 RUN: lld-link %S/Inputs/precomp-a.obj %S/Inputs/precomp-invalid.obj %S/Inputs/precomp.obj /nodefaultlib /entry:main /debug /pdb:%t.pdb /out:%t.exe /opt:ref /opt:icf 2>&1 | FileCheck %s -check-prefix FAILURE
 
+RUN: not lld-link %S/Inputs/precomp-a.obj %S/Inputs/precomp-b.obj /nodefaultlib /entry:main /debug /pdb:%t.pdb /out:%t.exe /opt:ref /opt:icf 2>&1 | FileCheck %s -check-prefix FAILURE-MISSING-PRECOMPOBJ
+
 FAILURE: warning: Cannot use debug info for 'precomp-invalid.obj'
 FAILURE-NEXT: failed to load reference '{{.*}}precomp.obj': The signature does not match; the file(s) might be out of date.
 
+FAILURE-MISSING-PRECOMPOBJ: warning: Cannot use debug info for 'precomp-a.obj'
+FAILURE-MISSING-PRECOMPOBJ-NEXT: failed to load reference 'precomp.obj': The path to this file must be provided on the command-line
+
 CHECK: Types (TPI Stream)
 CHECK-NOT: LF_PRECOMP
 CHECK-NOT: LF_ENDPRECOMP




More information about the llvm-commits mailing list