diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/DebugInfo/CodeView/TypeStreamMerger.cpp | 49 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/CodeView/TypeTableBuilder.cpp | 25 |
2 files changed, 36 insertions, 38 deletions
diff --git a/llvm/lib/DebugInfo/CodeView/TypeStreamMerger.cpp b/llvm/lib/DebugInfo/CodeView/TypeStreamMerger.cpp index 06f819df7ec..465f01aab9d 100644 --- a/llvm/lib/DebugInfo/CodeView/TypeStreamMerger.cpp +++ b/llvm/lib/DebugInfo/CodeView/TypeStreamMerger.cpp @@ -83,6 +83,8 @@ private: bool remapTypeIndex(TypeIndex &Idx); bool remapItemIndex(TypeIndex &Idx); + ArrayRef<uint8_t> serializeRemapped(const RemappedType &Record); + bool remapIndices(RemappedType &Record, ArrayRef<TiReference> Refs); bool remapIndex(TypeIndex &Idx, ArrayRef<TypeIndex> Map); @@ -96,15 +98,6 @@ private: return llvm::make_error<CodeViewError>(cv_error_code::corrupt_record); } - Error writeRecord(TypeTableBuilder &Dest, const RemappedType &Record, - bool RemapSuccess) { - TypeIndex DestIdx = Untranslated; - if (RemapSuccess) - DestIdx = Dest.insertRecord(Record); - addMapping(DestIdx); - return Error::success(); - } - Optional<Error> LastError; bool IsSecondPass = false; @@ -123,10 +116,35 @@ private: /// Map from source type index to destination type index. Indexed by source /// type index minus 0x1000. SmallVectorImpl<TypeIndex> &IndexMap; + + /// Temporary storage that we use to copy a record's data while re-writing + /// its type indices. + SmallVector<uint8_t, 256> RemapStorage; }; } // end anonymous namespace +ArrayRef<uint8_t> +TypeStreamMerger::serializeRemapped(const RemappedType &Record) { + TypeIndex TI; + ArrayRef<uint8_t> OriginalData = Record.OriginalRecord.RecordData; + if (Record.Mappings.empty()) + return OriginalData; + + // At least one type index was remapped. We copy the full record bytes, + // re-write each type index, then return that. + RemapStorage.resize(OriginalData.size()); + ::memcpy(&RemapStorage[0], OriginalData.data(), OriginalData.size()); + uint8_t *ContentBegin = RemapStorage.data() + sizeof(RecordPrefix); + for (const auto &M : Record.Mappings) { + // First 4 bytes of every record are the record prefix, but the mapping + // offset is relative to the content which starts after. + *(TypeIndex *)(ContentBegin + M.first) = M.second; + } + auto RemapRef = makeArrayRef(RemapStorage); + return RemapRef; +} + const TypeIndex TypeStreamMerger::Untranslated(SimpleTypeKind::NotTranslated); static bool isIdRecord(TypeLeafKind K) { @@ -268,14 +286,19 @@ Error TypeStreamMerger::remapAllTypes(const CVTypeArray &Types) { } Error TypeStreamMerger::remapType(const CVType &Type) { + TypeTableBuilder &Dest = + isIdRecord(Type.kind()) ? *DestIdStream : *DestTypeStream; + RemappedType R(Type); SmallVector<TiReference, 32> Refs; discoverTypeIndices(Type.RecordData, Refs); bool MappedAllIndices = remapIndices(R, Refs); - TypeTableBuilder &Dest = - isIdRecord(Type.kind()) ? *DestIdStream : *DestTypeStream; - if (auto EC = writeRecord(Dest, R, MappedAllIndices)) - return EC; + ArrayRef<uint8_t> Data = serializeRemapped(R); + + TypeIndex DestIdx = Untranslated; + if (MappedAllIndices) + DestIdx = Dest.insertRecordBytes(Data); + addMapping(DestIdx); ++CurIndex; assert((IsSecondPass || IndexMap.size() == slotForIndex(CurIndex)) && diff --git a/llvm/lib/DebugInfo/CodeView/TypeTableBuilder.cpp b/llvm/lib/DebugInfo/CodeView/TypeTableBuilder.cpp index 2559b47e804..ad61b0b220b 100644 --- a/llvm/lib/DebugInfo/CodeView/TypeTableBuilder.cpp +++ b/llvm/lib/DebugInfo/CodeView/TypeTableBuilder.cpp @@ -205,31 +205,6 @@ TypeIndex TypeTableBuilder::insertRecordBytes(ArrayRef<uint8_t> &Record) { return NewTI; } -TypeIndex TypeTableBuilder::insertRecord(const RemappedType &Record) { - TypeIndex TI; - ArrayRef<uint8_t> OriginalData = Record.OriginalRecord.RecordData; - if (Record.Mappings.empty()) { - // This record did not remap any type indices. Just write it. - return insertRecordBytes(OriginalData); - } - - // At least one type index was remapped. Before we can hash it we have to - // copy the full record bytes, re-write each type index, then hash the copy. - // We do this in temporary storage since only the DenseMap can decide whether - // this record already exists, and if it does we don't want the memory to - // stick around. - RemapStorage.resize(OriginalData.size()); - ::memcpy(&RemapStorage[0], OriginalData.data(), OriginalData.size()); - uint8_t *ContentBegin = RemapStorage.data() + sizeof(RecordPrefix); - for (const auto &M : Record.Mappings) { - // First 4 bytes of every record are the record prefix, but the mapping - // offset is relative to the content which starts after. - *(TypeIndex *)(ContentBegin + M.first) = M.second; - } - auto RemapRef = makeArrayRef(RemapStorage); - return insertRecordBytes(RemapRef); -} - TypeIndex TypeTableBuilder::insertRecord(ContinuationRecordBuilder &Builder) { TypeIndex TI; auto Fragments = Builder.end(nextTypeIndex()); |