diff --git a/lld/COFF/PDB.cpp b/lld/COFF/PDB.cpp --- a/lld/COFF/PDB.cpp +++ b/lld/COFF/PDB.cpp @@ -434,9 +434,6 @@ Expected ExpectedTpi = PDBFile.getPDBTpiStream(); if (auto E = ExpectedTpi.takeError()) fatal("Type server does not have TPI stream: " + toString(std::move(E))); - Expected ExpectedIpi = PDBFile.getPDBIpiStream(); - if (auto E = ExpectedIpi.takeError()) - fatal("Type server does not have TPI stream: " + toString(std::move(E))); if (Config->DebugGHashes) { // PDBs do not actually store global hashes, so when merging a type server @@ -445,8 +442,6 @@ // 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 EndPrecomp; // Merge TPI first, because the IPI stream will reference type indices. @@ -456,10 +451,20 @@ 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 (PDBFile.hasPDBIpiStream()) { + Expected ExpectedIpi = PDBFile.getPDBIpiStream(); + if (auto E = ExpectedIpi.takeError()) + fatal("Error getting type server IPI stream: " + + toString(std::move(E))); + + auto IpiHashes = + GloballyHashedType::hashIds(ExpectedIpi->typeArray(), TpiHashes); + + if (auto Err = mergeIdRecords(TMerger.GlobalIDTable, IndexMap.TPIMap, + IndexMap.IPIMap, ExpectedIpi->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,16 @@ 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 (PDBFile.hasPDBIpiStream()) { + Expected ExpectedIpi = PDBFile.getPDBIpiStream(); + if (auto E = ExpectedIpi.takeError()) + fatal("Error getting type server IPI stream: " + + toString(std::move(E))); + + if (auto Err = mergeIdRecords(TMerger.IDTable, IndexMap.TPIMap, + IndexMap.IPIMap, ExpectedIpi->typeArray())) + fatal("codeview::mergeIdRecords failed: " + toString(std::move(Err))); + } } return IndexMap; diff --git a/lld/test/COFF/Inputs/no-ipi-stream-obj.obj.yaml b/lld/test/COFF/Inputs/no-ipi-stream-obj.obj.yaml new file mode 100644 --- /dev/null +++ b/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: diff --git a/lld/test/COFF/Inputs/no-ipi-stream-pdb.pdb.yaml b/lld/test/COFF/Inputs/no-ipi-stream-pdb.pdb.yaml new file mode 100644 --- /dev/null +++ b/lld/test/COFF/Inputs/no-ipi-stream-pdb.pdb.yaml @@ -0,0 +1,2 @@ +PdbStream: + Guid: '{01234567-0123-0123-0123-0123456789AB}' diff --git a/lld/test/COFF/no-ipi-stream.test b/lld/test/COFF/no-ipi-stream.test new file mode 100644 --- /dev/null +++ b/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