forked from OSchip/llvm-project
[LLD][PDB] Implement FIXME: Warn on missing TypeServer PDB rather than error
Summary: Instead of fatal-ing out when missing a type server PDB, insead warn and cache the miss. Reviewers: rnk, zturner Reviewed By: rnk Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D42188 llvm-svn: 323893
This commit is contained in:
parent
790baeed37
commit
b9b6ed9ae6
|
@ -107,10 +107,11 @@ public:
|
|||
/// If the object does not use a type server PDB (compiled with /Z7), we merge
|
||||
/// all the type and item records from the .debug$S stream and fill in the
|
||||
/// caller-provided ObjectIndexMap.
|
||||
const CVIndexMap &mergeDebugT(ObjFile *File, CVIndexMap &ObjectIndexMap);
|
||||
Expected<const CVIndexMap&> mergeDebugT(ObjFile *File,
|
||||
CVIndexMap &ObjectIndexMap);
|
||||
|
||||
const CVIndexMap &maybeMergeTypeServerPDB(ObjFile *File,
|
||||
TypeServer2Record &TS);
|
||||
Expected<const CVIndexMap&> maybeMergeTypeServerPDB(ObjFile *File,
|
||||
TypeServer2Record &TS);
|
||||
|
||||
/// Add the section map and section contributions to the PDB.
|
||||
void addSections(ArrayRef<OutputSection *> OutputSections,
|
||||
|
@ -151,6 +152,10 @@ private:
|
|||
|
||||
/// Type index mappings of type server PDBs that we've loaded so far.
|
||||
std::map<GUID, CVIndexMap> TypeServerIndexMappings;
|
||||
|
||||
/// List of TypeServer PDBs which cannot be loaded.
|
||||
/// Cached to prevent repeated load attempts.
|
||||
std::set<GUID> MissingTypeServerPDBs;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -241,8 +246,8 @@ maybeReadTypeServerRecord(CVTypeArray &Types) {
|
|||
return std::move(TS);
|
||||
}
|
||||
|
||||
const CVIndexMap &PDBLinker::mergeDebugT(ObjFile *File,
|
||||
CVIndexMap &ObjectIndexMap) {
|
||||
Expected<const CVIndexMap&> PDBLinker::mergeDebugT(ObjFile *File,
|
||||
CVIndexMap &ObjectIndexMap) {
|
||||
ScopedTimer T(TypeMergingTimer);
|
||||
|
||||
ArrayRef<uint8_t> Data = getDebugSection(File, ".debug$T");
|
||||
|
@ -317,11 +322,19 @@ tryToLoadPDB(const GUID &GuidFromObj, StringRef TSPath) {
|
|||
return std::move(NS);
|
||||
}
|
||||
|
||||
const CVIndexMap &PDBLinker::maybeMergeTypeServerPDB(ObjFile *File,
|
||||
TypeServer2Record &TS) {
|
||||
// First, check if we already loaded a PDB with this GUID. Return the type
|
||||
Expected<const CVIndexMap&> PDBLinker::maybeMergeTypeServerPDB(ObjFile *File,
|
||||
TypeServer2Record &TS) {
|
||||
const GUID& TSId = TS.getGuid();
|
||||
StringRef TSPath = TS.getName();
|
||||
|
||||
// First, check if the PDB has previously failed to load.
|
||||
if (MissingTypeServerPDBs.count(TSId))
|
||||
return make_error<pdb::GenericError>(
|
||||
pdb::generic_error_code::type_server_not_found, TSPath);
|
||||
|
||||
// Second, check if we already loaded a PDB with this GUID. Return the type
|
||||
// index mapping if we have it.
|
||||
auto Insertion = TypeServerIndexMappings.insert({TS.getGuid(), CVIndexMap()});
|
||||
auto Insertion = TypeServerIndexMappings.insert({TSId, CVIndexMap()});
|
||||
CVIndexMap &IndexMap = Insertion.first->second;
|
||||
if (!Insertion.second)
|
||||
return IndexMap;
|
||||
|
@ -332,18 +345,21 @@ const CVIndexMap &PDBLinker::maybeMergeTypeServerPDB(ObjFile *File,
|
|||
// Check for a PDB at:
|
||||
// 1. The given file path
|
||||
// 2. Next to the object file or archive file
|
||||
auto ExpectedSession = tryToLoadPDB(TS.getGuid(), TS.getName());
|
||||
auto ExpectedSession = tryToLoadPDB(TSId, TSPath);
|
||||
if (!ExpectedSession) {
|
||||
consumeError(ExpectedSession.takeError());
|
||||
StringRef LocalPath =
|
||||
!File->ParentName.empty() ? File->ParentName : File->getName();
|
||||
SmallString<128> Path = sys::path::parent_path(LocalPath);
|
||||
sys::path::append(
|
||||
Path, sys::path::filename(TS.getName(), sys::path::Style::windows));
|
||||
ExpectedSession = tryToLoadPDB(TS.getGuid(), Path);
|
||||
Path, sys::path::filename(TSPath, sys::path::Style::windows));
|
||||
ExpectedSession = tryToLoadPDB(TSId, Path);
|
||||
}
|
||||
if (auto E = ExpectedSession.takeError()) {
|
||||
TypeServerIndexMappings.erase(TSId);
|
||||
MissingTypeServerPDBs.emplace(TSId);
|
||||
return std::move(E);
|
||||
}
|
||||
if (auto E = ExpectedSession.takeError())
|
||||
fatal("Type server PDB was not found: " + toString(std::move(E)));
|
||||
|
||||
auto ExpectedTpi = (*ExpectedSession)->getPDBFile().getPDBTpiStream();
|
||||
if (auto E = ExpectedTpi.takeError())
|
||||
|
@ -764,7 +780,16 @@ void PDBLinker::addObjFile(ObjFile *File) {
|
|||
// the PDB first, so that we can get the map from object file type and item
|
||||
// indices to PDB type and item indices.
|
||||
CVIndexMap ObjectIndexMap;
|
||||
const CVIndexMap &IndexMap = mergeDebugT(File, ObjectIndexMap);
|
||||
auto IndexMapResult = mergeDebugT(File, ObjectIndexMap);
|
||||
|
||||
// If the .debug$T sections fail to merge, assume there is no debug info.
|
||||
if (!IndexMapResult) {
|
||||
warn("Type server PDB for " + Name + " is invalid, ignoring debug info. " +
|
||||
toString(IndexMapResult.takeError()));
|
||||
return;
|
||||
}
|
||||
|
||||
const CVIndexMap &IndexMap = *IndexMapResult;
|
||||
|
||||
ScopedTimer T(SymbolMergingTimer);
|
||||
|
||||
|
|
|
@ -1,13 +1,10 @@
|
|||
# This is an object compiled with /Zi (see the LF_TYPESERVER2 record) without an
|
||||
# adjacent type server PDB. Test that LLD fails gracefully on it.
|
||||
|
||||
# FIXME: Ideally we'd do what MSVC does, which is to warn and drop all debug
|
||||
# info in the object with the missing PDB.
|
||||
|
||||
# RUN: yaml2obj %s -o %t.obj
|
||||
# RUN: not lld-link %t.obj -out:%t.exe -debug -pdb:%t.pdb -nodefaultlib -entry:main 2>&1 | FileCheck %s
|
||||
# RUN: lld-link %t.obj -out:%t.exe -debug -pdb:%t.pdb -nodefaultlib -entry:main 2>&1 | FileCheck %s
|
||||
|
||||
# CHECK: error: Type server PDB was not found
|
||||
# CHECK: warning: Type server PDB was not found
|
||||
|
||||
--- !COFF
|
||||
header:
|
||||
|
|
Loading…
Reference in New Issue