003 File Manager
Current Path:
/usr/src/contrib/llvm-project/llvm/lib/DebugInfo/PDB/Native
usr
/
src
/
contrib
/
llvm-project
/
llvm
/
lib
/
DebugInfo
/
PDB
/
Native
/
📁
..
📄
DbiModuleDescriptor.cpp
(2.5 KB)
📄
DbiModuleDescriptorBuilder.cpp
(6.63 KB)
📄
DbiModuleList.cpp
(8.3 KB)
📄
DbiStream.cpp
(12.8 KB)
📄
DbiStreamBuilder.cpp
(14.82 KB)
📄
EnumTables.cpp
(1.33 KB)
📄
GSIStreamBuilder.cpp
(17.23 KB)
📄
GlobalsStream.cpp
(6.56 KB)
📄
Hash.cpp
(2.39 KB)
📄
HashTable.cpp
(2.55 KB)
📄
InfoStream.cpp
(3.94 KB)
📄
InfoStreamBuilder.cpp
(2.67 KB)
📄
InjectedSourceStream.cpp
(2.31 KB)
📄
ModuleDebugStream.cpp
(4.74 KB)
📄
NamedStreamMap.cpp
(4.2 KB)
📄
NativeCompilandSymbol.cpp
(2.22 KB)
📄
NativeEnumGlobals.cpp
(1.87 KB)
📄
NativeEnumInjectedSources.cpp
(4.05 KB)
📄
NativeEnumLineNumbers.cpp
(1.44 KB)
📄
NativeEnumModules.cpp
(1.36 KB)
📄
NativeEnumTypes.cpp
(2.62 KB)
📄
NativeExeSymbol.cpp
(3.25 KB)
📄
NativeFunctionSymbol.cpp
(2.12 KB)
📄
NativeLineNumber.cpp
(1.88 KB)
📄
NativePublicSymbol.cpp
(1.92 KB)
📄
NativeRawSymbol.cpp
(14.98 KB)
📄
NativeSession.cpp
(12.36 KB)
📄
NativeSourceFile.cpp
(1.47 KB)
📄
NativeSymbolEnumerator.cpp
(4.24 KB)
📄
NativeTypeArray.cpp
(2.6 KB)
📄
NativeTypeBuiltin.cpp
(1.67 KB)
📄
NativeTypeEnum.cpp
(12.55 KB)
📄
NativeTypeFunctionSig.cpp
(7.3 KB)
📄
NativeTypePointer.cpp
(6.41 KB)
📄
NativeTypeTypedef.cpp
(1.05 KB)
📄
NativeTypeUDT.cpp
(6.93 KB)
📄
NativeTypeVTShape.cpp
(1.42 KB)
📄
PDBFile.cpp
(16.2 KB)
📄
PDBFileBuilder.cpp
(11 KB)
📄
PDBStringTable.cpp
(4.53 KB)
📄
PDBStringTableBuilder.cpp
(6.88 KB)
📄
PublicsStream.cpp
(3.89 KB)
📄
RawError.cpp
(2.13 KB)
📄
SymbolCache.cpp
(22.39 KB)
📄
SymbolStream.cpp
(1.4 KB)
📄
TpiHashing.cpp
(4.32 KB)
📄
TpiStream.cpp
(7.85 KB)
📄
TpiStreamBuilder.cpp
(6.32 KB)
Editing: TpiStreamBuilder.cpp
//===- TpiStreamBuilder.cpp - -------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #include "llvm/DebugInfo/PDB/Native/TpiStreamBuilder.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/STLExtras.h" #include "llvm/DebugInfo/CodeView/TypeIndex.h" #include "llvm/DebugInfo/CodeView/TypeRecord.h" #include "llvm/DebugInfo/MSF/MSFBuilder.h" #include "llvm/DebugInfo/MSF/MappedBlockStream.h" #include "llvm/DebugInfo/PDB/Native/PDBFile.h" #include "llvm/DebugInfo/PDB/Native/RawError.h" #include "llvm/DebugInfo/PDB/Native/RawTypes.h" #include "llvm/Support/Allocator.h" #include "llvm/Support/BinaryByteStream.h" #include "llvm/Support/BinaryStreamArray.h" #include "llvm/Support/BinaryStreamReader.h" #include "llvm/Support/BinaryStreamWriter.h" #include "llvm/Support/Endian.h" #include "llvm/Support/Error.h" #include <algorithm> #include <cstdint> using namespace llvm; using namespace llvm::msf; using namespace llvm::pdb; using namespace llvm::support; TpiStreamBuilder::TpiStreamBuilder(MSFBuilder &Msf, uint32_t StreamIdx) : Msf(Msf), Allocator(Msf.getAllocator()), Header(nullptr), Idx(StreamIdx) { } TpiStreamBuilder::~TpiStreamBuilder() = default; void TpiStreamBuilder::setVersionHeader(PdbRaw_TpiVer Version) { VerHeader = Version; } void TpiStreamBuilder::addTypeRecord(ArrayRef<uint8_t> Record, Optional<uint32_t> Hash) { // If we just crossed an 8KB threshold, add a type index offset. assert(((Record.size() & 3) == 0) && "The type record's size is not a multiple of 4 bytes which will " "cause misalignment in the output TPI stream!"); size_t NewSize = TypeRecordBytes + Record.size(); constexpr size_t EightKB = 8 * 1024; if (NewSize / EightKB > TypeRecordBytes / EightKB || TypeRecords.empty()) { TypeIndexOffsets.push_back( {codeview::TypeIndex(codeview::TypeIndex::FirstNonSimpleIndex + TypeRecords.size()), ulittle32_t(TypeRecordBytes)}); } TypeRecordBytes = NewSize; TypeRecords.push_back(Record); if (Hash) TypeHashes.push_back(*Hash); } Error TpiStreamBuilder::finalize() { if (Header) return Error::success(); TpiStreamHeader *H = Allocator.Allocate<TpiStreamHeader>(); uint32_t Count = TypeRecords.size(); H->Version = VerHeader; H->HeaderSize = sizeof(TpiStreamHeader); H->TypeIndexBegin = codeview::TypeIndex::FirstNonSimpleIndex; H->TypeIndexEnd = H->TypeIndexBegin + Count; H->TypeRecordBytes = TypeRecordBytes; H->HashStreamIndex = HashStreamIndex; H->HashAuxStreamIndex = kInvalidStreamIndex; H->HashKeySize = sizeof(ulittle32_t); H->NumHashBuckets = MaxTpiHashBuckets - 1; // Recall that hash values go into a completely different stream identified by // the `HashStreamIndex` field of the `TpiStreamHeader`. Therefore, the data // begins at offset 0 of this independent stream. H->HashValueBuffer.Off = 0; H->HashValueBuffer.Length = calculateHashBufferSize(); // We never write any adjustments into our PDBs, so this is usually some // offset with zero length. H->HashAdjBuffer.Off = H->HashValueBuffer.Off + H->HashValueBuffer.Length; H->HashAdjBuffer.Length = 0; H->IndexOffsetBuffer.Off = H->HashAdjBuffer.Off + H->HashAdjBuffer.Length; H->IndexOffsetBuffer.Length = calculateIndexOffsetSize(); Header = H; return Error::success(); } uint32_t TpiStreamBuilder::calculateSerializedLength() { return sizeof(TpiStreamHeader) + TypeRecordBytes; } uint32_t TpiStreamBuilder::calculateHashBufferSize() const { assert((TypeRecords.size() == TypeHashes.size() || TypeHashes.empty()) && "either all or no type records should have hashes"); return TypeHashes.size() * sizeof(ulittle32_t); } uint32_t TpiStreamBuilder::calculateIndexOffsetSize() const { return TypeIndexOffsets.size() * sizeof(codeview::TypeIndexOffset); } Error TpiStreamBuilder::finalizeMsfLayout() { uint32_t Length = calculateSerializedLength(); if (auto EC = Msf.setStreamSize(Idx, Length)) return EC; uint32_t HashStreamSize = calculateHashBufferSize() + calculateIndexOffsetSize(); if (HashStreamSize == 0) return Error::success(); auto ExpectedIndex = Msf.addStream(HashStreamSize); if (!ExpectedIndex) return ExpectedIndex.takeError(); HashStreamIndex = *ExpectedIndex; if (!TypeHashes.empty()) { ulittle32_t *H = Allocator.Allocate<ulittle32_t>(TypeHashes.size()); MutableArrayRef<ulittle32_t> HashBuffer(H, TypeHashes.size()); for (uint32_t I = 0; I < TypeHashes.size(); ++I) { HashBuffer[I] = TypeHashes[I] % (MaxTpiHashBuckets - 1); } ArrayRef<uint8_t> Bytes( reinterpret_cast<const uint8_t *>(HashBuffer.data()), calculateHashBufferSize()); HashValueStream = std::make_unique<BinaryByteStream>(Bytes, llvm::support::little); } return Error::success(); } Error TpiStreamBuilder::commit(const msf::MSFLayout &Layout, WritableBinaryStreamRef Buffer) { if (auto EC = finalize()) return EC; auto InfoS = WritableMappedBlockStream::createIndexedStream(Layout, Buffer, Idx, Allocator); BinaryStreamWriter Writer(*InfoS); if (auto EC = Writer.writeObject(*Header)) return EC; for (auto Rec : TypeRecords) { assert(!Rec.empty() && "Attempting to write an empty type record shifts " "all offsets in the TPI stream!"); assert(((Rec.size() & 3) == 0) && "The type record's size is not a multiple of 4 bytes which will " "cause misalignment in the output TPI stream!"); if (auto EC = Writer.writeBytes(Rec)) return EC; } if (HashStreamIndex != kInvalidStreamIndex) { auto HVS = WritableMappedBlockStream::createIndexedStream( Layout, Buffer, HashStreamIndex, Allocator); BinaryStreamWriter HW(*HVS); if (HashValueStream) { if (auto EC = HW.writeStreamRef(*HashValueStream)) return EC; } for (auto &IndexOffset : TypeIndexOffsets) { if (auto EC = HW.writeObject(IndexOffset)) return EC; } } return Error::success(); }
Upload File
Create Folder