diff --git a/lld/COFF/DebugTypes.h b/lld/COFF/DebugTypes.h --- a/lld/COFF/DebugTypes.h +++ b/lld/COFF/DebugTypes.h @@ -72,7 +72,7 @@ void remapRecord(MutableArrayRef rec, ArrayRef typeRefs); - void mergeTypeRecord(llvm::codeview::CVType ty); + void mergeTypeRecord(TypeIndex curIndex, llvm::codeview::CVType ty); // Merge the type records listed in uniqueTypes. beginIndex is the TypeIndex // of the first record in this source, typically 0x1000. When PCHs are @@ -164,7 +164,7 @@ /// When ghashing is used, record the mapping from LF_[M]FUNC_ID to function /// type index here. Both indices are PDB indices, not object type indexes. - llvm::DenseMap funcIdToType; + std::vector> funcIdToType; /// Indicates if a type record is an item index or a type index. llvm::BitVector isItemIndex; diff --git a/lld/COFF/DebugTypes.cpp b/lld/COFF/DebugTypes.cpp --- a/lld/COFF/DebugTypes.cpp +++ b/lld/COFF/DebugTypes.cpp @@ -525,9 +525,6 @@ precompSrc->tpiMap.begin() + precompDependency.getTypesCount()); - if (config->debugGHashes) - funcIdToType = precompSrc->funcIdToType; // FIXME: Save copy - return Error::success(); } @@ -612,7 +609,7 @@ }); } -void TpiSource::mergeTypeRecord(CVType ty) { +void TpiSource::mergeTypeRecord(TypeIndex curIndex, CVType ty) { // Decide if the merged type goes into TPI or IPI. bool isItem = isIdRecord(ty.kind()); MergedInfo &merged = isItem ? mergedIpi : mergedTpi; @@ -637,6 +634,25 @@ uint32_t pdbHash = check(pdb::hashTypeRecord(CVType(newRec))); merged.recSizes.push_back(static_cast(newSize)); merged.recHashes.push_back(pdbHash); + + // Retain a mapping from PDB function id to PDB function type. This mapping is + // used during symbol procesing to rewrite S_GPROC32_ID symbols to S_GPROC32 + // symbols. + if (ty.kind() == LF_FUNC_ID || ty.kind() == LF_MFUNC_ID) { + bool success = ty.length() >= 12; + TypeIndex funcId = curIndex; + if (success) + success &= remapTypeIndex(funcId, TiRefKind::IndexRef); + TypeIndex funcType = + *reinterpret_cast(&newRec.data()[8]); + if (success) { + funcIdToType.push_back({funcId, funcType}); + } else { + StringRef fname = file ? file->getName() : ""; + warn("corrupt LF_[M]FUNC_ID record 0x" + utohexstr(curIndex.getIndex()) + + " in " + fname); + } + } } void TpiSource::mergeUniqueTypeRecords(ArrayRef typeRecords, @@ -655,27 +671,9 @@ forEachTypeChecked(typeRecords, [&](const CVType &ty) { if (nextUniqueIndex != uniqueTypes.end() && *nextUniqueIndex == ghashIndex) { - mergeTypeRecord(ty); + mergeTypeRecord(beginIndex + ghashIndex, ty); ++nextUniqueIndex; } - if (ty.kind() == LF_FUNC_ID || ty.kind() == LF_MFUNC_ID) { - bool success = ty.length() >= 12; - TypeIndex srcFuncIdIndex = beginIndex + ghashIndex; - TypeIndex funcId = srcFuncIdIndex; - TypeIndex funcType; - if (success) { - funcType = *reinterpret_cast(&ty.data()[8]); - success &= remapTypeIndex(funcId, TiRefKind::IndexRef); - success &= remapTypeIndex(funcType, TiRefKind::TypeRef); - } - if (success) { - funcIdToType.insert({funcId, funcType}); - } else { - StringRef fname = file ? file->getName() : ""; - warn("corrupt LF_[M]FUNC_ID record 0x" + - utohexstr(srcFuncIdIndex.getIndex()) + " in " + fname); - } - } ++ghashIndex; }); assert(nextUniqueIndex == uniqueTypes.end() && @@ -758,7 +756,6 @@ ipiSrc->tpiMap = tpiMap; ipiSrc->ipiMap = ipiMap; ipiSrc->mergeUniqueTypeRecords(typeArrayToBytes(ipi.typeArray())); - funcIdToType = ipiSrc->funcIdToType; // FIXME: Save copy } } @@ -775,7 +772,6 @@ TypeServerSource *tsSrc = *maybeTsSrc; tpiMap = tsSrc->tpiMap; ipiMap = tsSrc->ipiMap; - funcIdToType = tsSrc->funcIdToType; // FIXME: Save copy } void PrecompSource::loadGHashes() { @@ -1102,6 +1098,13 @@ source->remapTpiWithGHashes(&ghashState); }); + // Build a global map of from function ID to function type. + for (TpiSource *source : TpiSource::instances) { + for (auto idToType : source->funcIdToType) + funcIdToType.insert(idToType); + source->funcIdToType.clear(); + } + TpiSource::clearGHashes(); } diff --git a/lld/COFF/PDB.cpp b/lld/COFF/PDB.cpp --- a/lld/COFF/PDB.cpp +++ b/lld/COFF/PDB.cpp @@ -334,8 +334,8 @@ // in both cases we just need the second type index. if (!ti->isSimple() && !ti->isNoneType()) { if (config->debugGHashes) { - auto idToType = source->funcIdToType.find(*ti); - if (idToType == source->funcIdToType.end()) { + auto idToType = tMerger.funcIdToType.find(*ti); + if (idToType == tMerger.funcIdToType.end()) { warn(formatv("S_[GL]PROC32_ID record in {0} refers to PDB item " "index {1:X} which is not a LF_[M]FUNC_ID record", source->file->getName(), ti->getIndex())); diff --git a/lld/COFF/TypeMerger.h b/lld/COFF/TypeMerger.h --- a/lld/COFF/TypeMerger.h +++ b/lld/COFF/TypeMerger.h @@ -45,6 +45,10 @@ /// indices in each TpiSource. void mergeTypesWithGHash(); + /// Map from PDB function id type indexes to PDB function type indexes. + /// Populated after mergeTypesWithGHash. + llvm::DenseMap funcIdToType; + /// Type records that will go into the PDB TPI stream. llvm::codeview::MergingTypeTableBuilder typeTable;