[lld] Fix type server merging with PDBs without IPI stream
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
This commit is contained in:
parent
efc01eac17
commit
5584ab89a8
@ -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
|
||||
@ -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 =
|
||||
@ -456,10 +457,14 @@ 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,
|
||||
@ -467,9 +472,11 @@ Expected<const CVIndexMap &> PDBLinker::maybeMergeTypeServerPDB(ObjFile *File) {
|
||||
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;
|
||||
|
13
lld/test/COFF/Inputs/no-ipi-stream-obj.obj.yaml
Normal file
13
lld/test/COFF/Inputs/no-ipi-stream-obj.obj.yaml
Normal file
@ -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
lld/test/COFF/Inputs/no-ipi-stream-pdb.pdb.yaml
Normal file
2
lld/test/COFF/Inputs/no-ipi-stream-pdb.pdb.yaml
Normal file
@ -0,0 +1,2 @@
|
||||
PdbStream:
|
||||
Guid: '{01234567-0123-0123-0123-0123456789AB}'
|
4
lld/test/COFF/no-ipi-stream.test
Normal file
4
lld/test/COFF/no-ipi-stream.test
Normal file
@ -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
|
Loading…
x
Reference in New Issue
Block a user