From c504ae3cefc0fab043bb76f992045c9770ef87c1 Mon Sep 17 00:00:00 2001 From: Zachary Turner Date: Wed, 3 May 2017 15:58:37 +0000 Subject: Resubmit r301986 and r301987 "Add codeview::StringTable" This was reverted due to a "missing" file, but in reality what happened was that I renamed a file, and then due to a merge conflict both the old file and the new file got added to the repository. This led to an unused cpp file being in the repo and not referenced by any CMakeLists.txt but #including a .h file that wasn't in the repo. In an even more unfortunate coincidence, CMake didn't report the unused cpp file because it was in a subdirectory of the folder with the CMakeLists.txt, and not in the same directory as any CMakeLists.txt. The presence of the unused file was then breaking certain tools that determine file lists by globbing rather than by what's specified in CMakeLists.txt In any case, the fix is to just remove the unused file from the patch set. llvm-svn: 302042 --- .../DebugInfo/PDB/Native/PDBStringTableBuilder.cpp | 101 +++++++++++++-------- 1 file changed, 63 insertions(+), 38 deletions(-) (limited to 'llvm/lib/DebugInfo/PDB/Native/PDBStringTableBuilder.cpp') diff --git a/llvm/lib/DebugInfo/PDB/Native/PDBStringTableBuilder.cpp b/llvm/lib/DebugInfo/PDB/Native/PDBStringTableBuilder.cpp index 4add6ead212..a472181a489 100644 --- a/llvm/lib/DebugInfo/PDB/Native/PDBStringTableBuilder.cpp +++ b/llvm/lib/DebugInfo/PDB/Native/PDBStringTableBuilder.cpp @@ -8,31 +8,23 @@ //===----------------------------------------------------------------------===// #include "llvm/DebugInfo/PDB/Native/PDBStringTableBuilder.h" + #include "llvm/ADT/ArrayRef.h" +#include "llvm/DebugInfo/MSF/MappedBlockStream.h" #include "llvm/DebugInfo/PDB/Native/Hash.h" +#include "llvm/DebugInfo/PDB/Native/PDBFileBuilder.h" #include "llvm/DebugInfo/PDB/Native/RawTypes.h" #include "llvm/Support/BinaryStreamWriter.h" #include "llvm/Support/Endian.h" using namespace llvm; +using namespace llvm::msf; using namespace llvm::support; using namespace llvm::support::endian; using namespace llvm::pdb; uint32_t PDBStringTableBuilder::insert(StringRef S) { - auto P = Strings.insert({S, StringSize}); - - // If a given string didn't exist in the string table, we want to increment - // the string table size. - if (P.second) - StringSize += S.size() + 1; // +1 for '\0' - return P.first->second; -} - -uint32_t PDBStringTableBuilder::getStringIndex(StringRef S) { - auto Iter = Strings.find(S); - assert(Iter != Strings.end()); - return Iter->second; + return Strings.insert(S); } static uint32_t computeBucketCount(uint32_t NumStrings) { @@ -44,49 +36,52 @@ static uint32_t computeBucketCount(uint32_t NumStrings) { return (NumStrings + 1) * 1.25; } -uint32_t PDBStringTableBuilder::finalize() { - uint32_t Size = 0; - Size += sizeof(PDBStringTableHeader); - Size += StringSize; - Size += sizeof(uint32_t); // Hash table begins with 4-byte size field. +uint32_t PDBStringTableBuilder::calculateHashTableSize() const { + uint32_t Size = sizeof(uint32_t); // Hash table begins with 4-byte size field. + Size += sizeof(uint32_t) * computeBucketCount(Strings.size()); - uint32_t BucketCount = computeBucketCount(Strings.size()); - Size += BucketCount * sizeof(uint32_t); + return Size; +} - Size += - sizeof(uint32_t); // The /names stream ends with the number of strings. +uint32_t PDBStringTableBuilder::calculateSerializedSize() const { + uint32_t Size = 0; + Size += sizeof(PDBStringTableHeader); + Size += Strings.calculateSerializedSize(); + Size += calculateHashTableSize(); + Size += sizeof(uint32_t); // The /names stream ends with the string count. return Size; } -Error PDBStringTableBuilder::commit(BinaryStreamWriter &Writer) const { +Error PDBStringTableBuilder::writeHeader(BinaryStreamWriter &Writer) const { // Write a header PDBStringTableHeader H; H.Signature = PDBStringTableSignature; H.HashVersion = 1; - H.ByteSize = StringSize; + H.ByteSize = Strings.calculateSerializedSize(); if (auto EC = Writer.writeObject(H)) return EC; + assert(Writer.bytesRemaining() == 0); + return Error::success(); +} - // Write a string table. - uint32_t StringStart = Writer.getOffset(); - for (auto Pair : Strings) { - StringRef S = Pair.first; - uint32_t Offset = Pair.second; - Writer.setOffset(StringStart + Offset); - if (auto EC = Writer.writeCString(S)) - return EC; - } - Writer.setOffset(StringStart + StringSize); +Error PDBStringTableBuilder::writeStrings(BinaryStreamWriter &Writer) const { + if (auto EC = Strings.commit(Writer)) + return EC; + + assert(Writer.bytesRemaining() == 0); + return Error::success(); +} +Error PDBStringTableBuilder::writeHashTable(BinaryStreamWriter &Writer) const { // Write a hash table. uint32_t BucketCount = computeBucketCount(Strings.size()); if (auto EC = Writer.writeInteger(BucketCount)) return EC; std::vector Buckets(BucketCount); - for (auto Pair : Strings) { - StringRef S = Pair.first; - uint32_t Offset = Pair.second; + for (auto &Pair : Strings) { + StringRef S = Pair.getKey(); + uint32_t Offset = Pair.getValue(); uint32_t Hash = hashStringV1(S); for (uint32_t I = 0; I != BucketCount; ++I) { @@ -102,7 +97,37 @@ Error PDBStringTableBuilder::commit(BinaryStreamWriter &Writer) const { if (auto EC = Writer.writeArray(ArrayRef(Buckets))) return EC; - if (auto EC = Writer.writeInteger(static_cast(Strings.size()))) + + assert(Writer.bytesRemaining() == 0); + return Error::success(); +} + +Error PDBStringTableBuilder::writeEpilogue(BinaryStreamWriter &Writer) const { + if (auto EC = Writer.writeInteger(Strings.size())) + return EC; + assert(Writer.bytesRemaining() == 0); + return Error::success(); +} + +Error PDBStringTableBuilder::commit(BinaryStreamWriter &Writer) const { + BinaryStreamWriter SectionWriter; + + std::tie(SectionWriter, Writer) = Writer.split(sizeof(PDBStringTableHeader)); + if (auto EC = writeHeader(SectionWriter)) + return EC; + + std::tie(SectionWriter, Writer) = + Writer.split(Strings.calculateSerializedSize()); + if (auto EC = writeStrings(SectionWriter)) return EC; + + std::tie(SectionWriter, Writer) = Writer.split(calculateHashTableSize()); + if (auto EC = writeHashTable(SectionWriter)) + return EC; + + std::tie(SectionWriter, Writer) = Writer.split(sizeof(uint32_t)); + if (auto EC = writeEpilogue(SectionWriter)) + return EC; + return Error::success(); } -- cgit v1.2.3