diff options
author | Zachary Turner <zturner@google.com> | 2016-09-09 17:46:17 +0000 |
---|---|---|
committer | Zachary Turner <zturner@google.com> | 2016-09-09 17:46:17 +0000 |
commit | c6d54da891b5b7f6634d41a1c59eab4d5e226711 (patch) | |
tree | 5d14cccb65e640255902a1280afc4ff91ee13245 /llvm/lib/DebugInfo/PDB/Raw/TpiStreamBuilder.cpp | |
parent | d938dfb308fe288605c6a24773ab77db8334c54a (diff) | |
download | llvm-c6d54da891b5b7f6634d41a1c59eab4d5e226711.zip llvm-c6d54da891b5b7f6634d41a1c59eab4d5e226711.tar.gz llvm-c6d54da891b5b7f6634d41a1c59eab4d5e226711.tar.bz2 |
[pdb] Write PDB TPI Stream from Yaml.
This writes the full sequence of type records described in
Yaml to the TPI stream of the PDB file.
Reviewed By: rnk
Differential Revision: https://reviews.llvm.org/D24316
llvm-svn: 281063
Diffstat (limited to 'llvm/lib/DebugInfo/PDB/Raw/TpiStreamBuilder.cpp')
-rw-r--r-- | llvm/lib/DebugInfo/PDB/Raw/TpiStreamBuilder.cpp | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/llvm/lib/DebugInfo/PDB/Raw/TpiStreamBuilder.cpp b/llvm/lib/DebugInfo/PDB/Raw/TpiStreamBuilder.cpp new file mode 100644 index 0000000..5591df59 --- /dev/null +++ b/llvm/lib/DebugInfo/PDB/Raw/TpiStreamBuilder.cpp @@ -0,0 +1,95 @@ +#include "llvm/DebugInfo/PDB/Raw/TpiStreamBuilder.h" + +#include "llvm/DebugInfo/CodeView/TypeIndex.h" +#include "llvm/DebugInfo/CodeView/TypeRecord.h" +#include "llvm/DebugInfo/MSF/MappedBlockStream.h" +#include "llvm/DebugInfo/MSF/StreamWriter.h" +#include "llvm/DebugInfo/PDB/Raw/PDBFile.h" +#include "llvm/DebugInfo/PDB/Raw/RawError.h" +#include "llvm/DebugInfo/PDB/Raw/TpiStream.h" +#include "llvm/Support/Allocator.h" + +using namespace llvm; +using namespace llvm::msf; +using namespace llvm::pdb; +using namespace llvm::support; + +TpiStreamBuilder::TpiStreamBuilder(BumpPtrAllocator &Allocator) + : Allocator(Allocator), Header(nullptr) {} + +TpiStreamBuilder::~TpiStreamBuilder() {} + +void TpiStreamBuilder::setVersionHeader(PdbRaw_TpiVer Version) { + VerHeader = Version; +} + +void TpiStreamBuilder::addTypeRecord(const codeview::CVType &Record) { + TypeRecords.push_back(Record); + TypeRecordStream.setItems(TypeRecords); +} + +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 = TypeRecordStream.getLength(); + + H->HashStreamIndex = kInvalidStreamIndex; + H->HashAuxStreamIndex = kInvalidStreamIndex; + H->HashKeySize = sizeof(ulittle32_t); + H->NumHashBuckets = MinTpiHashBuckets; + + H->HashValueBuffer.Length = 0; + H->HashAdjBuffer.Length = 0; + H->IndexOffsetBuffer.Length = 0; + + Header = H; + return Error::success(); +} + +uint32_t TpiStreamBuilder::calculateSerializedLength() const { + return sizeof(TpiStreamHeader) + TypeRecordStream.getLength(); +} + +Expected<std::unique_ptr<TpiStream>> +TpiStreamBuilder::build(PDBFile &File, const msf::WritableStream &Buffer) { + if (!VerHeader.hasValue()) + return make_error<RawError>(raw_error_code::unspecified, + "Missing TPI Stream Version"); + if (auto EC = finalize()) + return std::move(EC); + + auto StreamData = MappedBlockStream::createIndexedStream(File.getMsfLayout(), + Buffer, StreamTPI); + auto Tpi = llvm::make_unique<TpiStream>(File, std::move(StreamData)); + Tpi->Header = Header; + Tpi->TypeRecords = VarStreamArray<codeview::CVType>(TypeRecordStream); + return std::move(Tpi); +} + +Error TpiStreamBuilder::commit(const msf::MSFLayout &Layout, + const msf::WritableStream &Buffer) { + if (auto EC = finalize()) + return EC; + + auto InfoS = + WritableMappedBlockStream::createIndexedStream(Layout, Buffer, StreamTPI); + + StreamWriter Writer(*InfoS); + if (auto EC = Writer.writeObject(*Header)) + return EC; + + auto RecordArray = VarStreamArray<codeview::CVType>(TypeRecordStream); + if (auto EC = Writer.writeArray(RecordArray)) + return EC; + + return Error::success(); +} |