diff options
Diffstat (limited to 'llvm/lib/DebugInfo/PDB/Native')
-rw-r--r-- | llvm/lib/DebugInfo/PDB/Native/DbiStream.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/PDB/Native/PDBFile.cpp | 9 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/PDB/Native/PDBFileBuilder.cpp | 21 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/PDB/Native/PDBStringTable.cpp | 94 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/PDB/Native/PDBStringTableBuilder.cpp | 101 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/PDB/Native/StringTableStreamBuilder.cpp | 123 |
6 files changed, 87 insertions, 263 deletions
diff --git a/llvm/lib/DebugInfo/PDB/Native/DbiStream.cpp b/llvm/lib/DebugInfo/PDB/Native/DbiStream.cpp index db703809f7c..4802cc6e819 100644 --- a/llvm/lib/DebugInfo/PDB/Native/DbiStream.cpp +++ b/llvm/lib/DebugInfo/PDB/Native/DbiStream.cpp @@ -146,7 +146,7 @@ Error DbiStream::reload() { if (ECSubstream.getLength() > 0) { BinaryStreamReader ECReader(ECSubstream); - if (auto EC = ECNames.reload(ECReader)) + if (auto EC = ECNames.load(ECReader)) return EC; } diff --git a/llvm/lib/DebugInfo/PDB/Native/PDBFile.cpp b/llvm/lib/DebugInfo/PDB/Native/PDBFile.cpp index 859295d2c7d..f158c5c5386 100644 --- a/llvm/lib/DebugInfo/PDB/Native/PDBFile.cpp +++ b/llvm/lib/DebugInfo/PDB/Native/PDBFile.cpp @@ -338,7 +338,7 @@ Expected<SymbolStream &> PDBFile::getPDBSymbolStream() { } Expected<PDBStringTable &> PDBFile::getStringTable() { - if (!Strings) { + if (!Strings || !PDBStringTableStream) { auto IS = getPDBInfoStream(); if (!IS) return IS.takeError(); @@ -350,13 +350,12 @@ Expected<PDBStringTable &> PDBFile::getStringTable() { if (!NS) return NS.takeError(); - auto N = llvm::make_unique<PDBStringTable>(); BinaryStreamReader Reader(**NS); - if (auto EC = N->reload(Reader)) + auto N = llvm::make_unique<PDBStringTable>(); + if (auto EC = N->load(Reader)) return std::move(EC); - assert(Reader.bytesRemaining() == 0); - StringTableStream = std::move(*NS); Strings = std::move(N); + PDBStringTableStream = std::move(*NS); } return *Strings; } diff --git a/llvm/lib/DebugInfo/PDB/Native/PDBFileBuilder.cpp b/llvm/lib/DebugInfo/PDB/Native/PDBFileBuilder.cpp index 4dd965c6907..972c995bf4b 100644 --- a/llvm/lib/DebugInfo/PDB/Native/PDBFileBuilder.cpp +++ b/llvm/lib/DebugInfo/PDB/Native/PDBFileBuilder.cpp @@ -80,9 +80,9 @@ Error PDBFileBuilder::addNamedStream(StringRef Name, uint32_t Size) { } Expected<msf::MSFLayout> PDBFileBuilder::finalizeMsfLayout() { - uint32_t StringsLen = Strings.calculateSerializedSize(); + uint32_t PDBStringTableSize = Strings.finalize(); - if (auto EC = addNamedStream("/names", StringsLen)) + if (auto EC = addNamedStream("/names", PDBStringTableSize)) return std::move(EC); if (auto EC = addNamedStream("/LinkInfo", 0)) return std::move(EC); @@ -109,13 +109,6 @@ Expected<msf::MSFLayout> PDBFileBuilder::finalizeMsfLayout() { return Msf->build(); } -Expected<uint32_t> PDBFileBuilder::getNamedStreamIndex(StringRef Name) const { - uint32_t SN = 0; - if (!NamedStreams.get(Name, SN)) - return llvm::make_error<pdb::RawError>(raw_error_code::no_stream); - return SN; -} - Error PDBFileBuilder::commit(StringRef Filename) { auto ExpectedLayout = finalizeMsfLayout(); if (!ExpectedLayout) @@ -153,12 +146,12 @@ Error PDBFileBuilder::commit(StringRef Filename) { return EC; } - auto ExpectedSN = getNamedStreamIndex("/names"); - if (!ExpectedSN) - return ExpectedSN.takeError(); + uint32_t PDBStringTableStreamNo = 0; + if (!NamedStreams.get("/names", PDBStringTableStreamNo)) + return llvm::make_error<pdb::RawError>(raw_error_code::no_stream); - auto NS = WritableMappedBlockStream::createIndexedStream(Layout, Buffer, - *ExpectedSN); + auto NS = WritableMappedBlockStream::createIndexedStream( + Layout, Buffer, PDBStringTableStreamNo); BinaryStreamWriter NSWriter(*NS); if (auto EC = Strings.commit(NSWriter)) return EC; diff --git a/llvm/lib/DebugInfo/PDB/Native/PDBStringTable.cpp b/llvm/lib/DebugInfo/PDB/Native/PDBStringTable.cpp index ee32f61f16f..fd3e69db86f 100644 --- a/llvm/lib/DebugInfo/PDB/Native/PDBStringTable.cpp +++ b/llvm/lib/DebugInfo/PDB/Native/PDBStringTable.cpp @@ -1,4 +1,5 @@ -//===- PDBStringTable.cpp - PDB String Table ---------------------*- C++-*-===// +//===- PDBStringTable.cpp - PDB String Table -----------------------*- C++ +//-*-===// // // The LLVM Compiler Infrastructure // @@ -10,7 +11,6 @@ #include "llvm/DebugInfo/PDB/Native/PDBStringTable.h" #include "llvm/ADT/ArrayRef.h" -#include "llvm/DebugInfo/MSF/MappedBlockStream.h" #include "llvm/DebugInfo/PDB/Native/Hash.h" #include "llvm/DebugInfo/PDB/Native/RawError.h" #include "llvm/DebugInfo/PDB/Native/RawTypes.h" @@ -21,91 +21,71 @@ using namespace llvm; using namespace llvm::support; using namespace llvm::pdb; -uint32_t PDBStringTable::getByteSize() const { return ByteSize; } -uint32_t PDBStringTable::getNameCount() const { return NameCount; } -uint32_t PDBStringTable::getHashVersion() const { return Header->HashVersion; } -uint32_t PDBStringTable::getSignature() const { return Header->Signature; } +PDBStringTable::PDBStringTable() {} + +Error PDBStringTable::load(BinaryStreamReader &Stream) { + ByteSize = Stream.getLength(); -Error PDBStringTable::readHeader(BinaryStreamReader &Reader) { - if (auto EC = Reader.readObject(Header)) + const PDBStringTableHeader *H; + if (auto EC = Stream.readObject(H)) return EC; - if (Header->Signature != PDBStringTableSignature) + if (H->Signature != PDBStringTableSignature) return make_error<RawError>(raw_error_code::corrupt_file, "Invalid hash table signature"); - if (Header->HashVersion != 1 && Header->HashVersion != 2) + if (H->HashVersion != 1 && H->HashVersion != 2) return make_error<RawError>(raw_error_code::corrupt_file, "Unsupported hash version"); - assert(Reader.bytesRemaining() == 0); - return Error::success(); -} - -Error PDBStringTable::readStrings(BinaryStreamReader &Reader) { - if (auto EC = Strings.initialize(Reader)) { + Signature = H->Signature; + HashVersion = H->HashVersion; + if (auto EC = Stream.readStreamRef(NamesBuffer, H->ByteSize)) return joinErrors(std::move(EC), make_error<RawError>(raw_error_code::corrupt_file, "Invalid hash table byte length")); - } - - assert(Reader.bytesRemaining() == 0); - return Error::success(); -} -Error PDBStringTable::readHashTable(BinaryStreamReader &Reader) { const support::ulittle32_t *HashCount; - if (auto EC = Reader.readObject(HashCount)) + if (auto EC = Stream.readObject(HashCount)) return EC; - if (auto EC = Reader.readArray(IDs, *HashCount)) { + if (auto EC = Stream.readArray(IDs, *HashCount)) return joinErrors(std::move(EC), make_error<RawError>(raw_error_code::corrupt_file, "Could not read bucket array")); - } - return Error::success(); -} - -Error PDBStringTable::readEpilogue(BinaryStreamReader &Reader) { - if (auto EC = Reader.readInteger(NameCount)) - return EC; - - assert(Reader.bytesRemaining() == 0); - return Error::success(); -} - -Error PDBStringTable::reload(BinaryStreamReader &Reader) { - - BinaryStreamReader SectionReader; - - std::tie(SectionReader, Reader) = Reader.split(sizeof(PDBStringTableHeader)); - if (auto EC = readHeader(SectionReader)) - return EC; - - std::tie(SectionReader, Reader) = Reader.split(Header->ByteSize); - if (auto EC = readStrings(SectionReader)) - return EC; + if (Stream.bytesRemaining() < sizeof(support::ulittle32_t)) + return make_error<RawError>(raw_error_code::corrupt_file, + "Missing name count"); - // We don't know how long the hash table is until we parse it, so let the - // function responsible for doing that figure it out. - if (auto EC = readHashTable(Reader)) + if (auto EC = Stream.readInteger(NameCount)) return EC; - std::tie(SectionReader, Reader) = Reader.split(sizeof(uint32_t)); - if (auto EC = readEpilogue(SectionReader)) - return EC; + if (Stream.bytesRemaining() > 0) + return make_error<RawError>(raw_error_code::stream_too_long, + "Unexpected bytes found in string table"); - assert(Reader.bytesRemaining() == 0); return Error::success(); } +uint32_t PDBStringTable::getByteSize() const { return ByteSize; } + StringRef PDBStringTable::getStringForID(uint32_t ID) const { - return Strings.getString(ID); + if (ID == IDs[0]) + return StringRef(); + + // NamesBuffer is a buffer of null terminated strings back to back. ID is + // the starting offset of the string we're looking for. So just seek into + // the desired offset and a read a null terminated stream from that offset. + StringRef Result; + BinaryStreamReader NameReader(NamesBuffer); + NameReader.setOffset(ID); + if (auto EC = NameReader.readCString(Result)) + consumeError(std::move(EC)); + return Result; } uint32_t PDBStringTable::getIDForString(StringRef Str) const { - uint32_t Hash = - (Header->HashVersion == 1) ? hashStringV1(Str) : hashStringV2(Str); + uint32_t Hash = (HashVersion == 1) ? hashStringV1(Str) : hashStringV2(Str); size_t Count = IDs.size(); uint32_t Start = Hash % Count; for (size_t I = 0; I < Count; ++I) { diff --git a/llvm/lib/DebugInfo/PDB/Native/PDBStringTableBuilder.cpp b/llvm/lib/DebugInfo/PDB/Native/PDBStringTableBuilder.cpp index a472181a489..4add6ead212 100644 --- a/llvm/lib/DebugInfo/PDB/Native/PDBStringTableBuilder.cpp +++ b/llvm/lib/DebugInfo/PDB/Native/PDBStringTableBuilder.cpp @@ -8,23 +8,31 @@ //===----------------------------------------------------------------------===// #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) { - return Strings.insert(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; } static uint32_t computeBucketCount(uint32_t NumStrings) { @@ -36,52 +44,49 @@ static uint32_t computeBucketCount(uint32_t NumStrings) { return (NumStrings + 1) * 1.25; } -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()); - - return Size; -} - -uint32_t PDBStringTableBuilder::calculateSerializedSize() const { +uint32_t PDBStringTableBuilder::finalize() { uint32_t Size = 0; Size += sizeof(PDBStringTableHeader); - Size += Strings.calculateSerializedSize(); - Size += calculateHashTableSize(); - Size += sizeof(uint32_t); // The /names stream ends with the string count. + Size += StringSize; + Size += sizeof(uint32_t); // Hash table begins with 4-byte size field. + + uint32_t BucketCount = computeBucketCount(Strings.size()); + Size += BucketCount * sizeof(uint32_t); + + Size += + sizeof(uint32_t); // The /names stream ends with the number of strings. return Size; } -Error PDBStringTableBuilder::writeHeader(BinaryStreamWriter &Writer) const { +Error PDBStringTableBuilder::commit(BinaryStreamWriter &Writer) const { // Write a header PDBStringTableHeader H; H.Signature = PDBStringTableSignature; H.HashVersion = 1; - H.ByteSize = Strings.calculateSerializedSize(); + H.ByteSize = StringSize; if (auto EC = Writer.writeObject(H)) return EC; - assert(Writer.bytesRemaining() == 0); - return Error::success(); -} -Error PDBStringTableBuilder::writeStrings(BinaryStreamWriter &Writer) const { - if (auto EC = Strings.commit(Writer)) - 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::writeHashTable(BinaryStreamWriter &Writer) const { // Write a hash table. uint32_t BucketCount = computeBucketCount(Strings.size()); if (auto EC = Writer.writeInteger(BucketCount)) return EC; std::vector<ulittle32_t> Buckets(BucketCount); - for (auto &Pair : Strings) { - StringRef S = Pair.getKey(); - uint32_t Offset = Pair.getValue(); + for (auto Pair : Strings) { + StringRef S = Pair.first; + uint32_t Offset = Pair.second; uint32_t Hash = hashStringV1(S); for (uint32_t I = 0; I != BucketCount; ++I) { @@ -97,37 +102,7 @@ Error PDBStringTableBuilder::writeHashTable(BinaryStreamWriter &Writer) const { if (auto EC = Writer.writeArray(ArrayRef<ulittle32_t>(Buckets))) return EC; - - assert(Writer.bytesRemaining() == 0); - return Error::success(); -} - -Error PDBStringTableBuilder::writeEpilogue(BinaryStreamWriter &Writer) const { - if (auto EC = Writer.writeInteger<uint32_t>(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)) + if (auto EC = Writer.writeInteger(static_cast<uint32_t>(Strings.size()))) 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(); } diff --git a/llvm/lib/DebugInfo/PDB/Native/StringTableStreamBuilder.cpp b/llvm/lib/DebugInfo/PDB/Native/StringTableStreamBuilder.cpp deleted file mode 100644 index b19440961bc..00000000000 --- a/llvm/lib/DebugInfo/PDB/Native/StringTableStreamBuilder.cpp +++ /dev/null @@ -1,123 +0,0 @@ -//===- StringTableStreamBuilder.cpp - PDB String Table ----------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "llvm/DebugInfo/PDB/Native/StringTableStreamBuilder.h" -#include "llvm/ADT/ArrayRef.h" -#include "llvm/DebugInfo/PDB/Native/Hash.h" -#include "llvm/DebugInfo/PDB/Native/RawTypes.h" -#include "llvm/Support/BinaryStreamWriter.h" -#include "llvm/Support/Endian.h" - -using namespace llvm; -using namespace llvm::support; -using namespace llvm::support::endian; -using namespace llvm::pdb; - -uint32_t StringTableStreamBuilder::insert(StringRef S) { - return Strings.insert(S); -} - -static uint32_t computeBucketCount(uint32_t NumStrings) { - // The /names stream is basically an on-disk open-addressing hash table. - // Hash collisions are resolved by linear probing. We cannot make - // utilization 100% because it will make the linear probing extremely - // slow. But lower utilization wastes disk space. As a reasonable - // load factor, we choose 80%. We need +1 because slot 0 is reserved. - return (NumStrings + 1) * 1.25; -} - -uint32_t StringTableStreamBuilder::hashTableSize() const { - uint32_t Size = sizeof(uint32_t); // Hash table begins with 4-byte size field. - - Size += computeBucketCount(Strings.size()) * sizeof(uint32_t); - return Size; -} - -uint32_t StringTableStreamBuilder::calculateSerializedSize() const { - uint32_t Size = 0; - Size += sizeof(StringTableHeader); - Size += Strings.calculateSerializedSize(); - Size += hashTableSize(); - Size += sizeof(uint32_t); // The table ends with the number of strings. - return Size; -} - -Error StringTableStreamBuilder::writeHeader(BinaryStreamWriter &Writer) const { - // Write a header - StringTableHeader H; - H.Signature = StringTableSignature; - H.HashVersion = 1; - H.ByteSize = Strings.calculateSerializedSize(); - if (auto EC = Writer.writeObject(H)) - return EC; - - assert(Writer.bytesRemaining() == 0); - return Error::success(); -} - -Error StringTableStreamBuilder::writeStrings(BinaryStreamWriter &Writer) const { - if (auto EC = Strings.commit(Writer)) - return EC; - - assert(Writer.bytesRemaining() == 0); - return Error::success(); -} - -Error StringTableStreamBuilder::writeHashTable( - BinaryStreamWriter &Writer) const { - // Write a hash table. - uint32_t BucketCount = computeBucketCount(Strings.size()); - if (auto EC = Writer.writeInteger(BucketCount)) - return EC; - - std::vector<ulittle32_t> Buckets(BucketCount); - - 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) { - uint32_t Slot = (Hash + I) % BucketCount; - if (Slot == 0) - continue; // Skip reserved slot - if (Buckets[Slot] != 0) - continue; - Buckets[Slot] = Offset; - break; - } - } - - if (auto EC = Writer.writeArray(makeArrayRef(Buckets))) - return EC; - assert(Writer.bytesRemaining() == 0); - return Error::success(); -} - -Error StringTableStreamBuilder::commit(BinaryStreamWriter &Writer) const { - BinaryStreamWriter Section; - - std::tie(Section, Writer) = Writer.split(sizeof(StringTableHeader)); - if (auto EC = writeHeader(Section)) - return EC; - - std::tie(Section, Writer) = Writer.split(Strings.calculateSerializedSize()); - if (auto EC = writeStrings(Section)) - return EC; - - std::tie(Section, Writer) = Writer.split(hashTableSize()); - if (auto EC = writeHashTable(Section)) - return EC; - - if (auto EC = Writer.writeInteger<uint32_t>(Strings.size())) - return EC; - - assert(Writer.bytesRemaining() == 0); - return Error::success(); -} |