Skip to content

Commit

Permalink
[lld] Fix type server merging with PDBs without IPI stream
Browse files Browse the repository at this point in the history
PDBs may not necessarily contain an IPI stream. Handle this case
gracefully.

The test case was verified to work with MS link.exe.

Patch by Vladimir Panteleev, with a small simplification

Reviewed By: rnk

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

llvm-svn: 363213
  • Loading branch information
rnk committed Jun 12, 2019
1 parent efc01ea commit 5584ab8
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 13 deletions.
33 changes: 20 additions & 13 deletions lld/COFF/PDB.cpp
Expand Up @@ -434,9 +434,13 @@ Expected<const CVIndexMap &> PDBLinker::maybeMergeTypeServerPDB(ObjFile *File) {
Expected<pdb::TpiStream &> ExpectedTpi = PDBFile.getPDBTpiStream();
if (auto E = ExpectedTpi.takeError())
fatal("Type server does not have TPI stream: " + toString(std::move(E)));
Expected<pdb::TpiStream &> ExpectedIpi = PDBFile.getPDBIpiStream();
if (auto E = ExpectedIpi.takeError())
fatal("Type server does not have TPI stream: " + toString(std::move(E)));
pdb::TpiStream *MaybeIpi = nullptr;
if (PDBFile.hasPDBIpiStream()) {
Expected<pdb::TpiStream &> ExpectedIpi = PDBFile.getPDBIpiStream();
if (auto E = ExpectedIpi.takeError())
fatal("Error getting type server IPI stream: " + toString(std::move(E)));
MaybeIpi = &*ExpectedIpi;
}

if (Config->DebugGHashes) {
// PDBs do not actually store global hashes, so when merging a type server
Expand All @@ -445,9 +449,6 @@ Expected<const CVIndexMap &> PDBLinker::maybeMergeTypeServerPDB(ObjFile *File) {
// synthesize hashes for the IPI stream, using the hashes for the TPI stream
// as inputs.
auto TpiHashes = GloballyHashedType::hashTypes(ExpectedTpi->typeArray());
auto IpiHashes =
GloballyHashedType::hashIds(ExpectedIpi->typeArray(), TpiHashes);

Optional<uint32_t> EndPrecomp;
// Merge TPI first, because the IPI stream will reference type indices.
if (auto Err =
Expand All @@ -456,20 +457,26 @@ Expected<const CVIndexMap &> PDBLinker::maybeMergeTypeServerPDB(ObjFile *File) {
fatal("codeview::mergeTypeRecords failed: " + toString(std::move(Err)));

// Merge IPI.
if (auto Err = mergeIdRecords(TMerger.GlobalIDTable, IndexMap.TPIMap,
IndexMap.IPIMap, ExpectedIpi->typeArray(),
IpiHashes))
fatal("codeview::mergeIdRecords failed: " + toString(std::move(Err)));
if (MaybeIpi) {
auto IpiHashes =
GloballyHashedType::hashIds(MaybeIpi->typeArray(), TpiHashes);
if (auto Err =
mergeIdRecords(TMerger.GlobalIDTable, IndexMap.TPIMap,
IndexMap.IPIMap, MaybeIpi->typeArray(), IpiHashes))
fatal("codeview::mergeIdRecords failed: " + toString(std::move(Err)));
}
} else {
// Merge TPI first, because the IPI stream will reference type indices.
if (auto Err = mergeTypeRecords(TMerger.TypeTable, IndexMap.TPIMap,
ExpectedTpi->typeArray()))
fatal("codeview::mergeTypeRecords failed: " + toString(std::move(Err)));

// Merge IPI.
if (auto Err = mergeIdRecords(TMerger.IDTable, IndexMap.TPIMap,
IndexMap.IPIMap, ExpectedIpi->typeArray()))
fatal("codeview::mergeIdRecords failed: " + toString(std::move(Err)));
if (MaybeIpi) {
if (auto Err = mergeIdRecords(TMerger.IDTable, IndexMap.TPIMap,
IndexMap.IPIMap, MaybeIpi->typeArray()))
fatal("codeview::mergeIdRecords failed: " + toString(std::move(Err)));
}
}

return IndexMap;
Expand Down
13 changes: 13 additions & 0 deletions lld/test/COFF/Inputs/no-ipi-stream-obj.obj.yaml
@@ -0,0 +1,13 @@
--- !COFF
header:
Machine: IMAGE_FILE_MACHINE_I386
sections:
- Name: '.debug$T'
Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
Types:
- Kind: LF_TYPESERVER2
TypeServer2:
Guid: '{01234567-0123-0123-0123-0123456789AB}'
Age: 1
Name: 'no-ipi-stream-pdb.pdb'
symbols:
2 changes: 2 additions & 0 deletions lld/test/COFF/Inputs/no-ipi-stream-pdb.pdb.yaml
@@ -0,0 +1,2 @@
PdbStream:
Guid: '{01234567-0123-0123-0123-0123456789AB}'
4 changes: 4 additions & 0 deletions lld/test/COFF/no-ipi-stream.test
@@ -0,0 +1,4 @@
# RUN: rm -rf %t && mkdir %t
# RUN: yaml2obj < %p/Inputs/no-ipi-stream-obj.obj.yaml > %t/no-ipi-stream-obj.obj
# RUN: llvm-pdbutil yaml2pdb %p/Inputs/no-ipi-stream-pdb.pdb.yaml -pdb=%t/no-ipi-stream-pdb.pdb
# RUN: lld-link /dll /noentry /debug %t/no-ipi-stream-obj.obj

0 comments on commit 5584ab8

Please sign in to comment.