summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorAlexandre Ganea <alexandre.ganea@ubisoft.com>2019-02-07 15:24:18 +0000
committerAlexandre Ganea <alexandre.ganea@ubisoft.com>2019-02-07 15:24:18 +0000
commit120366edc733ac85ba71e45ecb96edfa9ce9b9d3 (patch)
tree8fea50ae302f46fd965b105df265ea11a5d1f09d /llvm/lib
parent892e63319497bfbea7c93d763c43a1944d6d7ab4 (diff)
downloadbcm5719-llvm-120366edc733ac85ba71e45ecb96edfa9ce9b9d3.tar.gz
bcm5719-llvm-120366edc733ac85ba71e45ecb96edfa9ce9b9d3.zip
[CodeView] Fix cycles in debug info when merging Types with global hashes
When type streams with forward references were merged using GHashes, cycles were introduced in the debug info. This was caused by GlobalTypeTableBuilder::insertRecordAs() not inserting the record on the second pass, thus yielding an empty ArrayRef at that record slot. Later on, upon PDB emission, TpiStreamBuilder::commit() would skip that empty record, thus offseting all indices that came after in the stream. This solution comes in two steps: 1. Fix the hash calculation, by doing a multiple-step resolution, iff there are forward references in the input stream. 2. Fix merge by resolving with multiple passes, therefore moving records with forward references at the end of the stream. This patch also adds support for llvm-readoj --codeview-ghash. Finally, fix dumpCodeViewMergedTypes() which previously could reference deleted memory. Fixes PR40221 Differential Revision: https://reviews.llvm.org/D57790 llvm-svn: 353412
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/DebugInfo/CodeView/TypeHashing.cpp8
-rw-r--r--llvm/lib/DebugInfo/PDB/Native/TpiStreamBuilder.cpp5
2 files changed, 11 insertions, 2 deletions
diff --git a/llvm/lib/DebugInfo/CodeView/TypeHashing.cpp b/llvm/lib/DebugInfo/CodeView/TypeHashing.cpp
index 612399ddbff..2dbc11a84f0 100644
--- a/llvm/lib/DebugInfo/CodeView/TypeHashing.cpp
+++ b/llvm/lib/DebugInfo/CodeView/TypeHashing.cpp
@@ -54,10 +54,16 @@ GloballyHashedType::hashType(ArrayRef<uint8_t> RecordData,
reinterpret_cast<const TypeIndex *>(RefData.data()), Ref.Count);
for (TypeIndex TI : Indices) {
ArrayRef<uint8_t> BytesToHash;
- if (TI.isSimple() || TI.isNoneType() || TI.toArrayIndex() >= Prev.size()) {
+ if (TI.isSimple() || TI.isNoneType()) {
const uint8_t *IndexBytes = reinterpret_cast<const uint8_t *>(&TI);
BytesToHash = makeArrayRef(IndexBytes, sizeof(TypeIndex));
} else {
+ if (TI.toArrayIndex() >= Prev.size() ||
+ Prev[TI.toArrayIndex()].empty()) {
+ // There are references to yet-unhashed records. Suspend hashing for
+ // this record until all the other records are processed.
+ return {};
+ }
BytesToHash = Prev[TI.toArrayIndex()].Hash;
}
S.update(BytesToHash);
diff --git a/llvm/lib/DebugInfo/PDB/Native/TpiStreamBuilder.cpp b/llvm/lib/DebugInfo/PDB/Native/TpiStreamBuilder.cpp
index f2a5dcb93d6..6b308453c2d 100644
--- a/llvm/lib/DebugInfo/PDB/Native/TpiStreamBuilder.cpp
+++ b/llvm/lib/DebugInfo/PDB/Native/TpiStreamBuilder.cpp
@@ -152,9 +152,12 @@ Error TpiStreamBuilder::commit(const msf::MSFLayout &Layout,
if (auto EC = Writer.writeObject(*Header))
return EC;
- for (auto Rec : TypeRecords)
+ for (auto Rec : TypeRecords) {
+ assert(!Rec.empty()); // An empty record will not write anything, but it
+ // would shift all offsets from here on.
if (auto EC = Writer.writeBytes(Rec))
return EC;
+ }
if (HashStreamIndex != kInvalidStreamIndex) {
auto HVS = WritableMappedBlockStream::createIndexedStream(
OpenPOWER on IntegriCloud