summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexandre Ganea <alexandre.ganea@ubisoft.com>2018-11-08 14:42:37 +0000
committerAlexandre Ganea <alexandre.ganea@ubisoft.com>2018-11-08 14:42:37 +0000
commit4b2957243bca25b584373fdd8594a308df102368 (patch)
tree6d707081b319b504552335c3e5c8c7ed41d51b63
parentb917740ac3caa9e627a2497a2c9db318eaa63188 (diff)
downloadbcm5719-llvm-4b2957243bca25b584373fdd8594a308df102368.tar.gz
bcm5719-llvm-4b2957243bca25b584373fdd8594a308df102368.zip
[LLD] Fix Microsoft precompiled headers cross-compile on Linux
Differential revision: https://reviews.llvm.org/D54122 llvm-svn: 346403
-rw-r--r--lld/COFF/PDB.cpp52
-rw-r--r--lld/COFF/SymbolTable.cpp5
-rw-r--r--lld/test/COFF/precomp-link.test7
-rw-r--r--llvm/include/llvm/DebugInfo/PDB/GenericError.h1
-rw-r--r--llvm/lib/DebugInfo/PDB/GenericError.cpp2
5 files changed, 34 insertions, 33 deletions
diff --git a/lld/COFF/PDB.cpp b/lld/COFF/PDB.cpp
index ed69cfca7f1..1afae488300 100644
--- a/lld/COFF/PDB.cpp
+++ b/lld/COFF/PDB.cpp
@@ -645,7 +645,7 @@ PDBLinker::mergeInPrecompHeaderObj(ObjFile *File, const CVType &FirstType,
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, StringRef path2) {
#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(CurrentPath);
+ StringRef CurrentFileName = sys::path::filename(F->getName());
- // 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 *File, PrecompRecord Precomp) {
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;
+ auto PrecompFile = findObjByName(PrecompFileName);
+ if (!PrecompFile)
+ return createFileError(
+ PrecompFileName.str(),
+ make_error<pdb::PDBError>(pdb::pdb_error_code::external_cmdline_ref));
- addObjFile(CurrentFile, &IndexMap);
+ addObjFile(PrecompFile, &IndexMap);
- if (!CurrentFile->EndPrecomp)
- fatal(PrecompFilePath->second + " is not a precompiled headers object");
+ if (!PrecompFile->EndPrecomp)
+ fatal(PrecompFile->getName() + " 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);
+ 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;
}
diff --git a/lld/COFF/SymbolTable.cpp b/lld/COFF/SymbolTable.cpp
index 2e5f00af3c4..3edd98febee 100644
--- a/lld/COFF/SymbolTable.cpp
+++ b/lld/COFF/SymbolTable.cpp
@@ -241,6 +241,11 @@ void SymbolTable::reportRemainingUndefines() {
}
}
+ // 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;
diff --git a/lld/test/COFF/precomp-link.test b/lld/test/COFF/precomp-link.test
index e3cf6858191..f7be26c8779 100644
--- a/lld/test/COFF/precomp-link.test
+++ b/lld/test/COFF/precomp-link.test
@@ -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 | FileCheck %s
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
diff --git a/llvm/include/llvm/DebugInfo/PDB/GenericError.h b/llvm/include/llvm/DebugInfo/PDB/GenericError.h
index 7b5a8529596..997f13f5f30 100644
--- a/llvm/include/llvm/DebugInfo/PDB/GenericError.h
+++ b/llvm/include/llvm/DebugInfo/PDB/GenericError.h
@@ -21,6 +21,7 @@ enum class pdb_error_code {
dia_sdk_not_present,
dia_failed_loading,
signature_out_of_date,
+ external_cmdline_ref,
unspecified,
};
} // namespace pdb
diff --git a/llvm/lib/DebugInfo/PDB/GenericError.cpp b/llvm/lib/DebugInfo/PDB/GenericError.cpp
index 5f5ff69fe3f..256952073e8 100644
--- a/llvm/lib/DebugInfo/PDB/GenericError.cpp
+++ b/llvm/lib/DebugInfo/PDB/GenericError.cpp
@@ -34,6 +34,8 @@ public:
return "The PDB file path is an invalid UTF8 sequence.";
case pdb_error_code::signature_out_of_date:
return "The signature does not match; the file(s) might be out of date.";
+ case pdb_error_code::external_cmdline_ref:
+ return "The path to this file must be provided on the command-line.";
}
llvm_unreachable("Unrecognized generic_error_code");
}
OpenPOWER on IntegriCloud